前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ffmpeg中AVCodec是否需要手动销毁?

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

作者头像
手撕代码八百里
发布2024-05-24 13:13:13
720
发布2024-05-24 13:13:13
举报
文章被收录于专栏:猿计划猿计划

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

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

代码语言:javascript
复制
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:

代码语言:javascript
复制
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的结构体变量:

代码语言:javascript
复制
typedef struct FFCodec {
    /**
     * The public AVCodec. See codec.h for it.
     */
    AVCodec p;
    ...
}

再来看下avcodec_alloc_context3函数:

libavcodec/options.c #avcodec_alloc_context3:

代码语言:javascript
复制
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,然后返回的:

代码语言:javascript
复制
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;
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-05-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档