ffmpeg中AVCodec是否需要手动销毁?

ffmpeg中AVCodec是否需要手动销毁?

码农世界 2024-05-23 前端 69 次浏览 0个评论

在开发到退出一个视频播放功能时,看到对AVCodec*这个指针做了初始化,但是突然有一个好奇的疑问,这个AVCodec到底是否需要人工手动销毁?

我在初始化的时候这样用的:

const AVCodec *v_codec = NULL;
AVCodecContext *v_decode_ctx = NULL;
*v_index = av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO, -1,0,&v_codec,0);
//alloc video decode ctx
v_decode_ctx = avcodec_alloc_context3(v_codec);

可以看到在av_find_best_stream内部针对const AVCodec *指针做了初始化,然后把初始化后的AVCodec传递给了avcodec_alloc_context3()函数,对AVCodecContext *指针做初始化。

先来看下av_find_best_stream如何对AVCodec进行初始化的:

libavformat/avformat.c #av_find_best_stream:

av_find_best_stream->
decoder = ff_find_decoder(ic, st, par->codec_id); ->
在该函数中,判断是否存在,如何存在的话,就直接返回了,不存在就按照codec_id继续查找:
const AVCodec *ff_find_decoder(AVFormatContext *s, const AVStream *st,
                               enum AVCodecID codec_id)
{
    switch (st->codecpar->codec_type) {
    case AVMEDIA_TYPE_VIDEO:
        if (s->video_codec)    return s->video_codec;
        break;
    case AVMEDIA_TYPE_AUDIO:
        if (s->audio_codec)    return s->audio_codec;
        break;
    case AVMEDIA_TYPE_SUBTITLE:
        if (s->subtitle_codec) return s->subtitle_codec;
        break;
    }
    return avcodec_find_decoder(codec_id);
}
avcodec_find_decoder(codec_id);--->
find_codec(id, av_codec_is_decoder);--->

最终会调用到av_codec_iterate:

在av_codec_iterate函数中可以看到是对一个结构体做了&取地址,然后返回的:

p就是AVCodec的结构体变量:

typedef struct FFCodec {
    /**
     * The public AVCodec. See codec.h for it.
     */
    AVCodec p;
    ...
}

再来看下avcodec_alloc_context3函数:

libavcodec/options.c #avcodec_alloc_context3:

AVCodecContext *avcodec_alloc_context3(const AVCodec *codec);
AVCodecContext *avcodec_alloc_context3(const AVCodec *codec)
{
    AVCodecContext *avctx= av_malloc(sizeof(AVCodecContext));
    if (!avctx)
        return NULL;
    if (init_context_defaults(avctx, codec) < 0) {
        av_free(avctx);
        return NULL;
    }
    return avctx;
}

调用了init_context_defaults,在init_context_defaults函数中对codec进行了赋值:

在avcodec_alloc_context3函数中可以看到malloc了一个AVCodecContext,然后返回的:

AVCodecContext *avctx= av_malloc(sizeof(AVCodecContext));

所以这个AVCodecContext指针是必定要free的。

为了一探究竟,AVCodec到底是否需要销毁?我们再追一下销毁AVCodecContext的函数avcodec_free_context:

libavcodec/options.c #avcodec_free_context:

再看avcodec_close函数:

调用了AVCodec的close函数,最后把AVCodecContext中的codec赋值为了NULL

拿flv的encoder来说:最终AVCodecContext中的codec就长下面这样:

可以看到在封装的close函数中做了很多free的操作:

所以真香大白了,总的来说:

  • 1、AVCodec不需要单独的销毁;
  • 2、销毁的地方主要是:
  • (1)在avcodec_close函数中会调用在AVCodec的close函数;
  • (2)在avcodec_close函数中close后赋值为了NULL;

转载请注明来自码农世界,本文标题:《ffmpeg中AVCodec是否需要手动销毁?》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,69人围观)参与讨论

还没有评论,来说两句吧...

Top