分配解码器上下文
/** * Allocate an AVCodecContext and set its fields to default values. The * resulting struct should be freed with 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. * 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). * * @return An AVCodecContext filled with default values or NULL on failure. */ AVCodecContext *avcodec_alloc_context3(const AVCodec *codec);
实现
AVCodecContext *avcodec_alloc_context3(const AVCodec *codec) { // 1.分配编解码器上下文 AVCodecContext *avctx= av_malloc(sizeof(AVCodecContext)); if (!avctx) return NULL; // 2.初始化 if (init_context_defaults(avctx, codec) < 0) { av_free(avctx); return NULL; } return avctx; }
static int init_context_defaults(AVCodecContext *s, const AVCodec *codec) { // 1.默认参数设置 int flags=0; memset(s, 0, sizeof(AVCodecContext)); s->av_class = &av_codec_context_class; 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; }
这个比较简单,就做了两件事:
- 新建AVCodecContext
- 基于编码器初始化AVCodecContext