ffmpeg之avcodec_alloc_context3

结构体AVCodecContext

点击这里查看AVCodecContext

结构体AVCodec

点击这里查看AVCodec

函数声明avcodec_alloc_context3

/**
 * Allocate an AVCodecContext and set its fields to default values. The
 * resulting struct should be freed with avcodec_free_context().
 * 为AVCodecContext结构体分配内存,并将各字段设置为默认值,结果返回的结构体需要使用avcodec_free_context()进行释放内存
 * 
 * @param codec if non-NULL, allocate private data and initialize defaults
 *              for the given codec. It is illegal to then call avcodec_open2()
 *              with a different codec.
 * 参数codec非空,这利用codec的指定参数初始化AVCodecContext,
 * avio_open2绑定编码器codec_a与利用编码器codec_b初始化的ctx是非法的。
 *              If NULL, then the codec-specific defaults won't be initialized,
 *              which may result in suboptimal default settings (this is
 *              important mainly for encoders, e.g. libx264).
 * 如果codec为空,则不初始化ctx的特定编码器参数ctx->codec,这个参数很重要
 * @return An AVCodecContext filled with default values or NULL on failure.
 * 函数执行成功这返回ctx,失败则返回nullptr
 */
AVCodecContext *avcodec_alloc_context3(const AVCodec *codec);

函数实现

AVCodecContext *avcodec_alloc_context3(const AVCodec *codec)
{
    // 为avctx分配内存
    AVCodecContext *avctx= av_malloc(sizeof(AVCodecContext));

    // 失败返回null
    if (!avctx)
        return NULL;

    // 利用codec初始化avctx
    if (init_context_defaults(avctx, codec) < 0) {
        av_free(avctx);
        return NULL;
    }

    // 成功返回avctx
    return avctx;
}


static int init_context_defaults(AVCodecContext *s, const AVCodec *codec)
{
    int flags=0;
    // ctx内存清零
    memset(s, 0, sizeof(AVCodecContext));

    s->av_class = &av_codec_context_class;

    // 编码类型,audio,video,subtitle等
    s->codec_type = codec ? codec->type : AVMEDIA_TYPE_UNKNOWN;
    if (codec) {
        s->codec = codec;
        s->codec_id = codec->id;
    }

    // 初始化参数
    if(s->codec_type == AVMEDIA_TYPE_AUDIO)
        flags= AV_OPT_FLAG_AUDIO_PARAM;
    else if(s->codec_type == AVMEDIA_TYPE_VIDEO)
        flags= AV_OPT_FLAG_VIDEO_PARAM;
    else if(s->codec_type == AVMEDIA_TYPE_SUBTITLE)
        flags= AV_OPT_FLAG_SUBTITLE_PARAM;
    av_opt_set_defaults2(s, flags, flags);

    s->time_base           = (AVRational){0,1};
    s->framerate           = (AVRational){ 0, 1 };
    s->pkt_timebase        = (AVRational){ 0, 1 };
    s->get_buffer2         = avcodec_default_get_buffer2;
    s->get_format          = avcodec_default_get_format;
    s->execute             = avcodec_default_execute;
    s->execute2            = avcodec_default_execute2;
    s->sample_aspect_ratio = (AVRational){0,1};
    s->pix_fmt             = AV_PIX_FMT_NONE;
    s->sw_pix_fmt          = AV_PIX_FMT_NONE;
    s->sample_fmt          = AV_SAMPLE_FMT_NONE;

    s->reordered_opaque    = AV_NOPTS_VALUE;
    if(codec && codec->priv_data_size){
        if(!s->priv_data){
            s->priv_data= av_mallocz(codec->priv_data_size);
            if (!s->priv_data) {
                return AVERROR(ENOMEM);
            }
        }
        if(codec->priv_class){
            *(const AVClass**)s->priv_data = codec->priv_class;
            av_opt_set_defaults(s->priv_data);
        }
    }
    if (codec && codec->defaults) {
        int ret;
        const AVCodecDefault *d = codec->defaults;
        while (d->key) {
            ret = av_opt_set(s, d->key, d->value, 0);
            av_assert0(ret >= 0);
            d++;
        }
    }
    return 0;
}
posted @ 2021-12-12 14:45  flxx  阅读(2640)  评论(0编辑  收藏  举报