avformat_alloc_output_context2() 参数AVFormatContext 为什么可以用NULL?

436 阅读1分钟

看看源码 : ffmpeg/libavformat/mux.c


int avformat_alloc_output_context2(AVFormatContext **avctx, const AVOutputFormat *oformat,
                                   const char *format, const char *filename)
{
    // 自己申请一个 AVFormatContext
    AVFormatContext *s = avformat_alloc_context();
    int ret = 0;

     // 还是将 AVFormatContext 设置为NULL
    *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) {
        if (!(s->url = av_strdup(filename)))
            goto nomem;

    }
    // 将自己的新建的AVFormatContext 赋值给 外部传的*avctx 参数;
    *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;
}

核心操作

  • AVFormatContext *s = avformat_alloc_context();
  • avctx = NULL;
  • avctx = s;