avformat_close_input分析

简介: 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;
}


thxchtb3wcn3k_d11fc1ff3db9431d8ad7575e9297ae48.png

相关文章
|
1月前
|
固态存储 SDN
编写input()和output()函数输入
编写input()和output()函数输入。
23 2
input type=file过滤图片
input type=file过滤图片
59 0
|
编解码
av_read_frame返回值为-5 Input/output error
av_read_frame返回值为-5 Input/output error
160 0
base64转图片的时候Can't read input file!
如果不去掉编码中的图片头信息,就会报Can't read input file!。 一开始还以为是文件路径格式有问题,然后看了看我之前用的,就有一个区别就是没有去头信息。
ADI
|
JavaScript 前端开发 API
[记录] input[type=file]属性详解
[记录] input[type=file]属性详解
ADI
319 0
|
应用服务中间件 Linux PHP