FFmpeg源代码简单分析:avcodec_close()

本文简单分析FFmpeg的avcodec_close()函数。该函数用于关闭编码器。avcodec_close()函数的声明位于libavcodec\avcodec.h,如下所示

/**
 * 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);

该函数只有一个参数,就是需要关闭的编码器的AVCodecContext。

函数调用关系图

函数的调用关系图如下所示。
在这里插入图片描述

avcodec_close()

avcodec_close()的定义位于libavcodec\avcodec.c,如下所示。

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 (avctx->codec && avctx->codec->close)
            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);
        av_packet_unref(avci->last_pkt_props);
        while (av_fifo_size(avci->pkt_props) >= sizeof(*avci->last_pkt_props)) {
            av_fifo_generic_read(avci->pkt_props, avci->last_pkt_props,
                                 sizeof(*avci->last_pkt_props), NULL);
            av_packet_unref(avci->last_pkt_props);
        }
        av_packet_free(&avci->last_pkt_props);
        av_fifo_freep(&avci->pkt_props);

        av_packet_free(&avci->ds.in_pkt);
        av_frame_free(&avci->es.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_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->codec = NULL;
    avctx->active_thread_type = 0;

    return 0;
}

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

AVCodec->close()

AVCodec的close()是一个函数指针,指向了特定编码器的关闭函数。在这里我们以libx264为例,看一下它对应的AVCodec的结构体的定义,如下所示。

AVCodec ff_libx264_encoder = {
    .name             = "libx264",
    .long_name        = NULL_IF_CONFIG_SMALL("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
    .type             = AVMEDIA_TYPE_VIDEO,
    .id               = AV_CODEC_ID_H264,
    .priv_data_size   = sizeof(X264Context),
    .init             = X264_init,
    .encode2          = X264_frame,
    .close            = X264_close,
    .capabilities     = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS |
                        AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
    .caps_internal    = FF_CODEC_CAP_AUTO_THREADS,
    .priv_class       = &x264_class,
    .defaults         = x264_defaults,
    .init_static_data = X264_init_static,
    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_AUTO_THREADS,
    .wrapper_name     = "libx264",
};

从ff_libx264_encoder的定义可以看出:close()函数对应的是X264_close()函数。继续看一下X264_close()函数的定义,如下所示。

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

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

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

    return 0;
}

从X264_close()的定义可以看出,该函数调用了libx264的x264_encoder_close()关闭了libx264编码器。

参考文献

1、https://blog.csdn.net/leixiaohua1020/article/details/44206699

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值