avformat_close_input分析

该函数对应打开输入流函数,这个函数会检测ps == NULL,如果是true的话,则分配内存。因此它的释放函数也包括释放ps内存的部分。

int avformat_open_input(AVFormatContext **ps, const char *url, ff_const59 AVInputFormat *fmt, AVDictionary **options);

分析该函数分为三部分
第一部分,调用AVInputFormat的read_close()方法关闭输入流
关闭输入:比如从海康读取rtsp流时,会给摄像机发送本地停止接收流的信号。

第二部分,调用avformat_free_context()释放AVFormatContext
这个上面有提到。
avformat_free_context(s)
该函数的核心就是释放申请创建的视频和音频的流
for (i = s->nb_streams - 1; i >= 0; i–)
ff_free_stream(s, s->streams[i]);

第三部分,调用avio_close()关闭并且释放AVIOContext
看下关于AVFormatContext的另一个函数

int avformat_alloc_output_context2(AVFormatContext **avctx, AVOutputFormat *oformat,
      const char *format, const char *filename)

这个函数的源码中,会直接把*avctx = NULL,然后再给它分配内存,因此没必要在外给avctx分配内存,会造成内存泄露(后附源码)。
在ffmpeg4.3中实测,avctx并不会内存泄露,在执行

AVFormatContext *ic = NULL;
ic = avformat_alloc_context();
printf("ic_b = %d\n", ic);
int re = avformat_open_input(&ic, URL, NULL, NULL);
if (re != 0)
{
    printf("open input error = %d\n", re);
    ErrorFunc(re);
}
printf("ic_a = %d\n", ic);

打印如下:

ic_b = 30900544
ic_a = 30900544

libavformat\mux.c

int avformat_alloc_output_context2(AVFormatContext **avctx, AVOutputFormat *oformat,
      const char *format, const char *filename)
{
    
    
    AVFormatContext *s = avformat_alloc_context();
    int ret = 0;
 
 
    *avctx = NULL;
    if (!s)
        goto nomem;
 
 
    if (!oformat) {
    
    
        if (format) {
    
    
            oformat = av_guess_format(format, NULL, NULL);
            if (!oformat) {
    
    
                av_log(s, AV_LOG_ERROR, "Requested output format '%s' is not a suitable output format\n", format);
                ret = AVERROR(EINVAL);
                goto error;
            }
        } else {
    
    
            oformat = av_guess_format(NULL, filename, NULL);
            if (!oformat) {
    
    
                ret = AVERROR(EINVAL);
                av_log(s, AV_LOG_ERROR, "Unable to find a suitable output format for '%s'\n",
                       filename);
                goto error;
            }
        }
    }
 
 
    s->oformat = oformat;
    if (s->oformat->priv_data_size > 0) {
    
    
        s->priv_data = av_mallocz(s->oformat->priv_data_size);
        if (!s->priv_data)
            goto nomem;
        if (s->oformat->priv_class) {
    
    
            *(const AVClass**)s->priv_data= s->oformat->priv_class;
            av_opt_set_defaults(s->priv_data);
        }
    } else
        s->priv_data = NULL;
 
 
    if (filename)
        av_strlcpy(s->filename, filename, sizeof(s->filename));
    *avctx = s;
    return 0;
nomem:
    av_log(s, AV_LOG_ERROR, "Out of memory\n");
    ret = AVERROR(ENOMEM);
error:
    avformat_free_context(s);
    return ret;
}

哎呦喂ヾ(✿゚▽゚)ノ~路长馆小,雪轻帘薄,酒热乎,这位爷~您ヾ(✿゚▽゚)ノ~ 里面坐~
本公众号专注分享C++,ffmpeg,opencv等相关音视频知识
webrtc,udp,tcp,rtsp,rtmp,srt/nginx+rtmp等流媒体协议和服务器
同时也会有大厂音视频技术专家不定期直播分享…
国人开发流媒体srs服务器,及yangrtc(国人版的webrtc)协议新动向
偶尔分享下程序员梦呓碎碎念(๑•॒̀ ູ॒•́๑)啦啦啦
目前刚刚开通,接受读者的优质投稿…
鉴于国内音视频圈子小,起步晚,以致分享少,门槛高,特开通分享,一起扇动这阵风吧!
微信扫描下方二维码,关注公众号,赶快进入音视频开发者社区吧!

猜你喜欢

转载自blog.csdn.net/weixin_43466192/article/details/121486550