FFmpeg源代码简单分析-通用-avcodec_close()

参考链接

avcodec_close()

  • 该函数用于关闭编码器
  • avcodec_close()函数的声明位于libavcodec\avcodec.h,如下所示。 ​
  • 该函数只有一个参数,就是需要关闭的编码器的AVCodecContext。
/**
 * Close a given AVCodecContext and free all the data associated with it
 * (but not the AVCodecContext itself).
 *
 * Calling this function on an AVCodecContext that hasn't been opened will free
 * the codec-specific data allocated in avcodec_alloc_context3() with a non-NULL
 * codec. Subsequent calls will do nothing.
 *
 * @note Do not use this function. Use avcodec_free_context() to destroy a
 * codec context (either open or closed). Opening and closing a codec context
 * multiple times is not supported anymore -- use multiple codec contexts
 * instead.
 */
int avcodec_close(AVCodecContext *avctx);
av_cold int avcodec_close(AVCodecContext *avctx)
{
    int i;

    if (!avctx)
        return 0;

    if (avcodec_is_open(avctx)) {
        AVCodecInternal *avci = avctx->internal;

        if (CONFIG_FRAME_THREAD_ENCODER &&
            avci->frame_thread_encoder && avctx->thread_count > 1) {
            ff_frame_thread_encoder_free(avctx);
        }
        if (HAVE_THREADS && avci->thread_ctx)
            ff_thread_free(avctx);
        if (avci->needs_close && ffcodec(avctx->codec)->close)
            ffcodec(avctx->codec)->close(avctx);
        avci->byte_buffer_size = 0;
        av_freep(&avci->byte_buffer);
        av_frame_free(&avci->buffer_frame);
        av_packet_free(&avci->buffer_pkt);
        if (avci->pkt_props) {
            while (av_fifo_can_read(avci->pkt_props)) {
                av_packet_unref(avci->last_pkt_props);
                av_fifo_read(avci->pkt_props, avci->last_pkt_props, 1);
            }
            av_fifo_freep2(&avci->pkt_props);
        }
        av_packet_free(&avci->last_pkt_props);

        av_packet_free(&avci->in_pkt);
        av_frame_free(&avci->in_frame);

        av_buffer_unref(&avci->pool);

        if (avctx->hwaccel && avctx->hwaccel->uninit)
            avctx->hwaccel->uninit(avctx);
        av_freep(&avci->hwaccel_priv_data);

        av_bsf_free(&avci->bsf);

        av_channel_layout_uninit(&avci->initial_ch_layout);

        av_freep(&avctx->internal);
    }

    for (i = 0; i < avctx->nb_coded_side_data; i++)
        av_freep(&avctx->coded_side_data[i].data);
    av_freep(&avctx->coded_side_data);
    avctx->nb_coded_side_data = 0;

    av_buffer_unref(&avctx->hw_frames_ctx);
    av_buffer_unref(&avctx->hw_device_ctx);

    if (avctx->priv_data && avctx->codec && avctx->codec->priv_class)
        av_opt_free(avctx->priv_data);
    av_opt_free(avctx);
    av_freep(&avctx->priv_data);
    if (av_codec_is_encoder(avctx->codec)) {
        av_freep(&avctx->extradata);
        avctx->extradata_size = 0;
    } else if (av_codec_is_decoder(avctx->codec))
        av_freep(&avctx->subtitle_header);

    avctx->codec = NULL;
    avctx->active_thread_type = 0;

    return 0;
}
  • 从avcodec_close()的定义可以看出,该函数释放AVCodecContext中有关的变量
  • 并且调用了AVCodec的close()关闭了解码器

AVCodec->close()

  • AVCodec的close()是一个函数指针,指向了特定编码器的关闭函数。
  • 在这里我们以libx264为例,看一下它对应的AVCodec的结构体的定义,如下所示。
#if X264_BUILD >= 153
const
#endif
FFCodec ff_libx264_encoder = {
    .p.name           = "libx264",
    .p.long_name      = NULL_IF_CONFIG_SMALL("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
    .p.type           = AVMEDIA_TYPE_VIDEO,
    .p.id             = AV_CODEC_ID_H264,
    .p.capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
                        AV_CODEC_CAP_OTHER_THREADS |
                        AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
    .p.priv_class     = &x264_class,
    .p.wrapper_name   = "libx264",
    .priv_data_size   = sizeof(X264Context),
    .init             = X264_init,
    FF_CODEC_ENCODE_CB(X264_frame),
    .close            = X264_close,
    .defaults         = x264_defaults,
#if X264_BUILD < 153
    .init_static_data = X264_init_static,
#else
    .p.pix_fmts       = pix_fmts_all,
#endif
    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_AUTO_THREADS
#if X264_BUILD >= 158
                      | FF_CODEC_CAP_INIT_THREADSAFE
#endif
                      ,
};
#endif
  • 从ff_libx264_encoder的定义可以看出:close()函数对应的是X264_close()函数。
  • 继续看一下X264_close()函数的定义,如下所示
  • 从X264_close()的定义可以看出,该函数调用了libx264的x264_encoder_close()关闭了libx264编码器

static av_cold int X264_close(AVCodecContext *avctx)
{
    X264Context *x4 = avctx->priv_data;

    av_freep(&x4->sei);
    av_freep(&x4->reordered_opaque);

#if X264_BUILD >= 161
    x264_param_cleanup(&x4->params);
#endif

    if (x4->enc) {
        x264_encoder_close(x4->enc);
        x4->enc = NULL;
    }

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值