[Libav-user] Using buffersrc and buffersink for full hardware accelerated pipeline

Tomislav Timic tomislavtimic98 at gmail.com
Sat Jun 7 17:02:12 EEST 2025


Hello,
I am having problem implementing logic for transcoding with nvdec and nvenc
codecs with buffersrc and buffersink.
Without buffersrc and buffersink it works, but when i put those 2 in frames
get stuck in buffersrc or sink I cannot figure it out. This is how i create
buffersrc and buffersink.

AVFilterContext *buffersink_ctx;
AVFilterContext *buffersrc_ctx;
AVFilterGraph *filter_graph;

AVRational input_framerate = av_guess_frame_rate(decoder->avfc,
decoder->video_avs, NULL);
const AVFilter *vbuffersrc = avfilter_get_by_name("buffer");
const AVFilter *vbuffersink = avfilter_get_by_name("buffersink");
AVRational time_base = decoder->avfc->streams[decoder->video_index]->time_base;

AVBufferSrcParameters *input_par;
input_par = av_buffersrc_parameters_alloc();
if (!input_par)
{
    fprintf(stderr, "Could not allocate input_par \n");
    return -2;
}
input_par->hw_frames_ctx = av_buffer_ref(decoder->hwFramesRef);
input_par->time_base = time_base;
input_par->width = 1920;
input_par->height = 1080;
input_par->sample_aspect_ratio = (AVRational) {1, 1};
input_par->frame_rate = (AVRational) {25, 1};
input_par->format = AV_PIX_FMT_CUDA;

char args[512];
snprintf(args, sizeof(args),
         "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
         decoder->video_avcc->width, decoder->video_avcc->height,
AV_PIX_FMT_CUDA,
         time_base.num, time_base.den,
         decoder->video_avcc->sample_aspect_ratio.num,
decoder->video_avcc->sample_aspect_ratio.den);

fprintf(stderr, "args = %s\n", args);

int error = avfilter_graph_create_filter(&vbuffersrc_ctx, vbuffersrc,
"in", args, NULL, vfilter_graph);
if (error < 0)
{
    fprintf(stderr, "Cannot create buffer source\n");
    return error;
}

vbuffersrc_ctx->hw_device_ctx = av_buffer_ref(decoder->hwDevCtx);


error = av_buffersrc_parameters_set(vbuffersrc_ctx, input_par);
av_freep(&input_par);
if (error < 0)
{
    fprintf(stderr, "Could not allocate buffersrc parameters, error:
%s\n", av_err2str(error));
    return error;
}

error = avfilter_graph_create_filter(&vbuffersink_ctx1, vbuffersink,
NULL, NULL, NULL, vfilter_graph);
if (error < 0)
{
    fprintf(stderr, "Cannot create buffer sink\n");
    return error;
}

vbuffersink_ctx1->hw_device_ctx = av_buffer_ref(decoder->hwDevCtx);

avfilter_link(vbuffersrc_ctx, 0, vbuffersink_ctx1, 0);

if ((error = avfilter_graph_config(vfilter_graph, NULL)) < 0)
{
    fprintf(stderr, "Error while configuring filter graph\n");
    return error;
}

and this is the trascode video function

int error;
error = avcodec_send_packet(decoder->video_avcc, input_packet);
if (error < 0)
{
    av_log(NULL, AV_LOG_ERROR, "Error while sending a packet to the
decoder %s\n", av_err2str(error));
    return error;
}

while (error >= 0)
{
    error = avcodec_receive_frame(decoder->video_avcc, input_frame);
    if (error == AVERROR(EAGAIN) || error == AVERROR_EOF)
    {
        break;
    } else if (error < 0)
    {
        av_log(NULL, AV_LOG_ERROR, "Error while receiving a frame from
the decoder\n");
        return -1;
    }

    input_frame->pts = input_frame->best_effort_timestamp;


    if (av_buffersrc_add_frame_flags(buffersrc_ctx,
                                     input_frame,
                                     AV_BUFFERSRC_FLAG_KEEP_REF) < 0)
    {
        av_log(NULL, AV_LOG_ERROR, "Error while feeding the audio
filtergraph\n");
        continue;
    }

    av_frame_unref(input_frame);

    while (true)
    {
        error = av_buffersink_get_frame(buffersink_ctx, filt_frame);
        if (error == AVERROR(EAGAIN) || error == AVERROR_EOF)
            break;
        if (error < 0)
            return -1;

        filt_frame->time_base = av_buffersink_get_time_base(buffersink_ctx);;
        filt_frame->pict_type = AV_PICTURE_TYPE_NONE;

        AVPacket *output_packet = av_packet_alloc();
        if (!output_packet)
        {
            fprintf(stderr, "could not allocate memory for output packet\n");
            return -1;
        }

        int response = avcodec_send_frame(encoder->video_avcc, filt_frame);

        while (response >= 0)
        {
            response = avcodec_receive_packet(encoder->video_avcc,
output_packet);
            if (response == AVERROR(EAGAIN) || response == AVERROR_EOF)
            {
                break;
            } else if (response < 0)
            {
                fprintf(stderr, "Error while receiving packet from
encoder: %s\n", av_err2str(response));
                return -1;
            }

            output_packet->stream_index = encoder->video_avs->index;

            av_packet_rescale_ts(output_packet,
                                 encoder->video_avcc->time_base,
                                 encoder->video_avs->time_base);

            if (output_packet->pts != AV_NOPTS_VALUE)
            {
                output_packet->pts = av_rescale_q(output_packet->pts,

decoder->avfc->streams[decoder->video_index]->time_base,

encoder->avfc->streams[decoder->video_index]->time_base);
            }

            if (output_packet->dts != AV_NOPTS_VALUE)
            {
                output_packet->dts = av_rescale_q(output_packet->dts,

decoder->avfc->streams[decoder->video_index]->time_base,

encoder->avfc->streams[decoder->video_index]->time_base);
            }

            response = av_interleaved_write_frame(encoder->avfc, output_packet);
            if (response != 0)
            {
                fprintf(stderr, "Error %d writing interleaved frame:
%s\n", response,
                        av_err2str(response));
                continue;
            }

            av_frame_unref(filt_frame);
        }

        av_packet_unref(output_packet);
        av_packet_free(&output_packet);
    }


    av_frame_unref(input_frame);
}
return 0;
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://ffmpeg.org/pipermail/libav-user/attachments/20250607/011bac5f/attachment.htm>


More information about the Libav-user mailing list