3

I am trying to figure out hardware decoding in ffmpeg in c ++. I get about the same errors on any api. Here is the initialization code:


    AVHWDeviceType devType = av_hwdevice_find_type_by_name(HW_DECODER_NAME);

    for (int i = 0;; i++)
    {
        const AVCodecHWConfig *config = avcodec_get_hw_config(av_codec, i);
        if (!config)
        {
            fprintf(stderr, "Decoder %s does not support device type %s.\n",
                    av_codec->name, av_hwdevice_get_type_name(devType));
            return false;
        }

        if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX && config->device_type == devType)
        {
            hw_pix_fmt = config->pix_fmt;
            break;
        }
    }

    hw_device_ctx = av_hwdevice_ctx_alloc(devType);

    *av_codec_ctx = avcodec_alloc_context3(av_codec);
    if (!av_codec_ctx)
    {
        printf("Couldn't create AVCodecContext\n");
        return false;
    }

    if (avcodec_parameters_to_context(*av_codec_ctx, av_codec_params) < 0)
    {
        printf("Couldn't initialize AVCodecContext\n");
        return false;
    }

    (*av_codec_ctx)->get_format  = get_hw_format;

    //Initialize hardware context
    int err = 0;
    if ((err = av_hwdevice_ctx_create(&hw_device_ctx, devType, NULL, NULL, 0)) < 0)
    {
        fprintf(stderr, "Failed to create specified HW device.\n");
        return false;
    }

    (*av_codec_ctx)->hw_device_ctx = av_buffer_ref(hw_device_ctx);

    if (avcodec_open2(*av_codec_ctx, av_codec, NULL) < 0)
    {
        printf("Couldn't open codec\n");
        return false;
    }

    b_is_initialized = true;

Here is the decoder code:

int response;

    response = avcodec_send_packet(av_codec_ctx, av_packet);
    if (response < 0)
    {
        printf("Couldn't send video frame to decoder.\n");
        print_error(response);
        return false;
    }

    realloc_frame(&av_frame);

    response = avcodec_receive_frame(av_codec_ctx, av_frame);
    if (response == AVERROR(EAGAIN) || response == AVERROR_EOF)
    {
        av_frame_free(&av_frame);
        return false;
    }
    else if (response < 0)
    {
        print_error(response);
        return false;
    }

    if(hwdecoder.is_initialized())
    {
        if(!hwdecoder.decode(av_packet, &av_frame))
        {
            printf("Failed while decoding frame on gpu.\n");
        }
    }

    pts = av_frame->pts;

    // Set up sws scaler
    if (!sws_scaler_ctx)
    {
        auto source_pix_fmt = correct_for_deprecated_pixel_format((AVPixelFormat)av_frame->format);
        //Send here frame params
        sws_scaler_ctx = sws_getContext(width, height, source_pix_fmt,
                                        width, height, AV_PIX_FMT_RGB0,
                                        SWS_BICUBIC, NULL, NULL, NULL);

Decoding on the processor works without problems, but when I decode on the gpu, it turns out to decode some part of the video and then during avcodec_send_packet I get the Invalid data found when processing the input error. Help please, I have been suffering for the second week.

EDIT

OP forgot about hwdecoder.decode method.

int ret = 0; 
realloc_frame(&sw_frame);      
if ((*av_frame)->format == hw_pix_fmt)
{         
  if ((ret = av_hwframe_transfer_data(sw_frame, *av_frame, 0)) < 0)          
  {             
     fprintf(stderr, "Error transferring the data to system memory\n");               
     av_frame_free(&sw_frame);             
     return false;         
  } 
} 

Error log:

Couldn't send video frame to decoder.
Invalid data found when processing input
[AVHWFramesContext @ 000001E44F6EC8C0] Static surface pool size exceeded.
[h264 @ 000001E445D60940] get_buffer() failed
[h264 @ 000001E445D60940] thread_get_buffer() failed
[h264 @ 000001E445D60940] decode_slice_header error
[h264 @ 000001E445D60940] no frame!

My code based on this example: https://ffmpeg.org/doxygen/4.0/hw_decode_8c-example.html

On windows i used dxva2 device, configure project with cmake 3.9, and build with MSVC amd64. On linux i used vdpau device, compiled from source ffmpeg libs, project was configured with cmake 3.9 and build with gcc 10

UPDATE

This code working well with cuda, but with another api's i still have problems.

AdamFull
  • 31
  • 1
  • 4
  • Please provide [A minimal Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example). Please include also the complete error log and the method of compiling (and running?) the program. – zkoza Apr 29 '21 at 00:01
  • Have you had a look at this GitHub page: https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/hw_decode.c Here you can find a lot of examples to see how to configure the different codecs. – Attis Apr 29 '21 at 08:41
  • I have the exact same problem as you, my code works fine when using cuda or software decoding but dxva2 or d3d11 give invalid data error on sending key frames. The data is definitely valid as it works with other decoders. Did you ever find a solution to this problem or did you report it anywhere else? – grill2010 Apr 30 '23 at 18:58

0 Answers0