参考链接
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;
}