结构体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;
}