在开发到退出一个视频播放功能时,看到对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;
还没有评论,来说两句吧...