1

I got the latest version binaries of ffmpeg from here. When I examine CPU and GPU usages when I play a video by its ffplay, I see that GPU is used during play. Not much using of CPU also indicates it. But when I get the latest version sources from the original site, I can't use GPU. To clarify, I include a player test program I wrote until now. When I uncomment the line which includes avcodec_find_decoder_by_name("h264_cuvid"), I get error -1. The error happens in avcodec_open2 with the description of Operation not permitted.

CString format(const char *fmt, ...) 
{ 
    va_list ap;
    va_start(ap, fmt);
    char buf[512];
    vsnprintf(buf, sizeof(buf), fmt, ap);
    va_end(ap);
    return buf;
}

int CplayerDlg::play()
{
    FILE *fp = fopen("video_files/1010.brf", "rb");
    if (!fp)
    {
        AfxMessageBox("can't open video file");
        return -1;
    }
    RecordFrame frame;
    RecordHeader hdr;
    fread(&frame, sizeof(frame), 1, fp);
    if (frame.frameType != FRAME_TYPE_HEADER)
    {
        AfxMessageBox("record file doesn't begin with header");
        return -1;
    }
    fread(&hdr, sizeof(hdr), 1, fp);
    GetDlgItem(IDC_DIM)->SetWindowText(format("%dx%d", hdr.width, hdr.height));
    GetDlgItem(IDC_CODEC_ID)->SetWindowText(format("%d", hdr.codecId));
    GetDlgItem(IDC_PIXEL_FORMAT)->SetWindowText(format("%d", hdr.pixelFormat));
    GetDlgItem(IDC_TIMEBASE)->SetWindowText(format("%d/%d", hdr.timebaseNum, hdr.timebaseDen));
    AVCodec *pCodec;

#if 0
#define CHECK(decoder)\
    pCodec = avcodec_find_decoder_by_name(#decoder);\
    AfxMessageBox(pCodec ? #decoder " found" : "can't find " #decoder);

    CHECK(h264_cuvid);

#undef CHECK
#endif

    pCodec = avcodec_find_decoder(AV_CODEC_ID_H264);
    //pCodec = avcodec_find_decoder_by_name("h264_cuvid");
    if (!pCodec)
    {
        AfxMessageBox("can't find h264 decoder");
        return -1;
    }

    AVCodecContext *pCodecContext = avcodec_alloc_context3(pCodec);
    if (!pCodecContext)
    {
        AfxMessageBox("can't allocate codec context");
        return -1;
    }

#if 0
// enumerating available codecs
    //av_register_all();
    avcodec_register_all();

    AVCodec *current_codec = av_codec_next(NULL);
    while (current_codec != NULL)
    {
        TRACE("%s\n", current_codec->name);
        current_codec = av_codec_next(current_codec);
    }
#endif

    int err = avcodec_open2(pCodecContext, pCodec, NULL);
    if (err != 0)
    {
        char buf[AV_ERROR_MAX_STRING_SIZE];
        av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, err);
        char buf2[AV_ERROR_MAX_STRING_SIZE];
        sprintf(buf2, "%d (%x): %s\n", err, err, buf);
        AfxMessageBox(buf2);
        return -1;
    }
    AfxMessageBox("operation completed successfully");
    fclose(fp);
    return 0;
}
hamidi
  • 1,611
  • 1
  • 15
  • 28
  • Did you try to compile using `--enable-nvenc` option ? See [this thread](https://stackoverflow.com/a/44518572/1887976) for more info. – Antwane Jan 28 '19 at 13:10
  • As I said, I didn't configure ffmpeg nor made it. I use ready-to-use binaries. But enumerating the available codes lists h264_nvenc, venc nvenc_h264, nvenc_hevc, etc. – hamidi Jan 28 '19 at 13:51
  • Notes that my video card may not be nVidia, although the error is the same on nVidia. I need my program to be run on any video cards. My idea is that DirectX is enabled in all Windows environments. – hamidi Jan 28 '19 at 13:51
  • Ok, I was confused by your words `when I get the latest version sources`. I understand now, you are comparing binaries downloaded from ffmpeg.zeranoe.com and the ones downloaded from ffmpeg.org. Am I right ? Maybe you could clarify your question ? – Antwane Jan 28 '19 at 13:53
  • Sorry if I couldn't describe better. No, indeed I think both are the same. Someone in Zeranoe has git cloned the original ffmpeg sources as I did and has made the DLL's I use. Since just having the binaries (DLL's) is not enough and I need header files too, I had to do the git clone too. What I meant was that the binaries belong to the same header files and there should be no mismatch to cause the problem. – hamidi Jan 28 '19 at 14:01
  • See https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/hw_decode.c – Gyan Jan 28 '19 at 16:02
  • Thanks @Gyan for introducing the link. I could run it at last on Ubuntu and Windows. I couldn't use dxva2 on Linux. Maybe it's because DirectX is not enabled on Linux. It's not my problem though. But in Windows I could run it and get it worked. :) But, both CPU and GPU usages increase. Is it natural? I need such a sample code not to increase CPU usage. What can I do? – hamidi Jan 30 '19 at 18:06
  • Besides, the output file is so big and is not playable. – hamidi Jan 30 '19 at 18:09
  • By commenting lines 110 to 140 of hw_decode.c, the part which begins with av_hwframe_transfer_data to where it writes the result in file by fwrite, I could reduce CPU usage and get what I wanted. Now, how can I make it show the decoded packet to the hardware surface? I need the result to be rendered directly on screen. – hamidi Feb 05 '19 at 10:57

0 Answers0