欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

使用说明:FFmpeg中的avcodec_flush_buffers函数的调用方法

最编程 2024-01-09 22:02:54
...

1)代码展示

/**
 * Reset the internal decoder state / flush internal buffers. Should be called
 * e.g. when seeking or when switching to a different stream.
 *
 * @note when refcounted frames are not used (i.e. avctx->refcounted_frames is 0),
 * this invalidates the frames previously returned from the decoder. When
 * refcounted frames are used, the decoder just releases any references it might
 * keep internally, but the caller's reference remains valid.
 */
void avcodec_flush_buffers(AVCodecContext *avctx);

说明:回放过程中跳转播放,或者切换到一个不同的流,调用此函数,清空内部缓存的帧数据

实际应用场景:在网络环境中,传输数据用UDP经常有丢包,而丢包很容易造成FFmpeg解码器缓冲的帧数增加,可以在一段时间内清空解码器缓存

切记:应该在接收到I帧的时候,清空缓存,否则出现画面不连续或者马赛克的情况

 

void avcodec_flush_buffers(AVCodecContext *avctx)
{
    avctx->internal->draining      = 0;
    avctx->internal->draining_done = 0;
    avctx->internal->nb_draining_errors = 0;
    av_frame_unref(avctx->internal->buffer_frame);
    av_frame_unref(avctx->internal->compat_decode_frame);
    av_packet_unref(avctx->internal->buffer_pkt);
    avctx->internal->buffer_pkt_valid = 0;

    av_packet_unref(avctx->internal->ds.in_pkt);

    if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME)
        ff_thread_flush(avctx);
    else if (avctx->codec->flush)
        avctx->codec->flush(avctx);

    avctx->pts_correction_last_pts =
    avctx->pts_correction_last_dts = INT64_MIN;

    ff_decode_bsfs_uninit(avctx);

    if (!avctx->refcounted_frames)
        av_frame_unref(avctx->internal->to_free);
}

2)申请上述缓存的函数

int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);

{

    avctx->internal = av_mallocz(sizeof(*avctx->internal));
    if (!avctx->internal) {
        ret = AVERROR(ENOMEM);
        goto end;
    }

    avctx->internal->pool = av_mallocz(sizeof(*avctx->internal->pool));
    if (!avctx->internal->pool) {
        ret = AVERROR(ENOMEM);
        goto free_and_end;
    }

    avctx->internal->to_free = av_frame_alloc();
    if (!avctx->internal->to_free) {
        ret = AVERROR(ENOMEM);
        goto free_and_end;
    }

    avctx->internal->compat_decode_frame = av_frame_alloc();
    if (!avctx->internal->compat_decode_frame) {
        ret = AVERROR(ENOMEM);
        goto free_and_end;
    }

    avctx->internal->buffer_frame = av_frame_alloc();
    if (!avctx->internal->buffer_frame) {
        ret = AVERROR(ENOMEM);
        goto free_and_end;
    }

    avctx->internal->buffer_pkt = av_packet_alloc();
    if (!avctx->internal->buffer_pkt) {
        ret = AVERROR(ENOMEM);
        goto free_and_end;
    }

    avctx->internal->ds.in_pkt = av_packet_alloc();
    if (!avctx->internal->ds.in_pkt) {
        ret = AVERROR(ENOMEM);
        goto free_and_end;
    }

    avctx->internal->last_pkt_props = av_packet_alloc();
    if (!avctx->internal->last_pkt_props) {
        ret = AVERROR(ENOMEM);
        goto free_and_end;
    }

}

推荐阅读