目录
- 1.avcodec_alloc_context3
FFmpeg相关记录:
示例工程:
【FFmpeg】调用ffmpeg库实现264软编
【FFmpeg】调用ffmpeg库实现264软解
【FFmpeg】调用ffmpeg库进行RTMP推流和拉流
【FFmpeg】调用ffmpeg库进行SDL2解码后渲染
流程分析:
【FFmpeg】编码链路上主要函数的简单分析
【FFmpeg】解码链路上主要函数的简单分析
结构体分析:
【FFmpeg】AVCodec结构体
【FFmpeg】AVCodecContext结构体
【FFmpeg】AVStream结构体
【FFmpeg】AVFormatContext结构体
【FFmpeg】AVIOContext结构体
【FFmpeg】AVPacket结构体
函数分析:
【通用】
【FFmpeg】avcodec_find_encoder和avcodec_find_decoder
【推流】
【FFmpeg】avformat_open_input函数
【FFmpeg】avformat_find_stream_info函数
【FFmpeg】avformat_alloc_output_context2函数
【FFmpeg】avio_open2函数
【FFmpeg】avformat_write_header函数
【FFmpeg】av_write_frame函数
1.avcodec_alloc_context3
该函数根据输入的AVCodec* codec来初始化一个AVCodecContext,先分配空间,随后调用init_context_defaults进行默认的初始化操作
AVCodecContext *avcodec_alloc_context3(const AVCodec *codec)
{
AVCodecContext *avctx= av_malloc(sizeof(AVCodecContext));
if (!avctx)
return NULL;
if (init_context_defaults(avctx, codec) < 0) {
av_free(avctx);
return NULL;
}
return avctx;
}
init_context_defaults的定义如下
static int init_context_defaults(AVCodecContext *s, const AVCodec *codec)
{
const FFCodec *const codec2 = ffcodec(codec);
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;
// 将所有AVOption字段的值设置为默认值。只有(opt->flags & mask)==flags的AVOption字段才会将其默认值应用于s
av_opt_set_defaults2(s, flags, flags);
// 音频中声道数的初始化
av_channel_layout_uninit(&s->ch_layout);
s->time_base = (AVRational){0,1};
s->framerate = (AVRational){ 0, 1 };
s->pkt_timebase = (AVRational){ 0, 1 };
// 用于获取buffer
s->get_buffer2 = avcodec_default_get_buffer2;
s->get_format = avcodec_default_get_format;
// 用于获取编码buffer
// 如果在进行视频编解码或需要更多的灵活性和控制权,get_buffer2更好
// 如果是专注于视频编码并追求性能优化的情况,优先考虑get_encode_buffer
s->get_encode_buffer = avcodec_default_get_encode_buffer;
s->execute = avcodec_default_execute;
s->execute2 = avcodec_default_execute2;
s->sample_aspect_ratio = (AVRational){0,1};
s->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
s->pix_fmt = AV_PIX_FMT_NONE;
// software pix fmt: 软编的pix fmt
s->sw_pix_fmt = AV_PIX_FMT_NONE;
// 音频的采样格式
s->sample_fmt = AV_SAMPLE_FMT_NONE;
// 私有数据,更多的关注于编解码器内部管理的状态
if(codec && codec2->priv_data_size){
s->priv_data = av_mallocz(codec2->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 && codec2->defaults) {
int ret;
const FFCodecDefault *d = codec2->defaults;
while (d->key) {
ret = av_opt_set(s, d->key, d->value, 0);
av_assert0(ret >= 0);
d++;
}
}
return 0;
}
CSDN : https://blog.csdn.net/weixin_42877471
Github : https://github.com/DoFulangChen