avformat_new_stream 在 AVFormatContext 中创建 Stream 通道。
AVFormatContext :
unsigned int nb_streams; 记录stream通道数目。
AVStream **streams; 存储stream通道。
AVStream :
int index; 在AVFormatContext 中所处的通道索引
二:分析
AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c)
{
AVStream *st;
int i;
AVStream **streams;
//创建AVStream
if (s->nb_streams >= INT_MAX/sizeof(*streams))
return NULL;
streams = av_realloc_array(s->streams, s->nb_streams + 1, sizeof(*streams));
if (!streams)
return NULL;
s->streams = streams;
st = av_mallocz(sizeof(AVStream));
if (!st)
return NULL;
if (!(st->info = av_mallocz(sizeof(*st->info)))) {
av_free(st);
return NULL;
}
st->info->last_dts = AV_NOPTS_VALUE;
//ffmpeg 3.1.4版本codec 已经废除了
#if FF_API_LAVF_AVCTX
FF_DISABLE_DEPRECATION_WARNINGS
st->codec = avcodec_alloc_context3(c);
if (!st->codec) {
av_free(st->info);
av_free(st);
return NULL;
}
FF_ENABLE_DEPRECATION_WARNINGS
#endif
//internal 部分为avformat内部使用,主要是备份一些数据,无需管它
st->internal = av_mallocz(sizeof(*st->internal));
if (!st->internal)
goto fail;
//
//通道记录的流的编码参数的默认设置
//注: AVCodecParameters codecpar 替换原先的CodecContext codec
st->codecpar = avcodec_parameters_alloc();
if (!st->codecpar)
goto fail;
st->internal->avctx = avcodec_alloc_context3(NULL);
if (!st->internal->avctx)
goto fail;
if (s->iformat) {
#if FF_API_LAVF_AVCTX
FF_DISABLE_DEPRECATION_WARNINGS
/* no default bitrate if decoding */
st->codec->bit_rate = 0;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
/* default pts setting is MPEG-like */
avpriv_set_pts_info(st, 33, 1, 90000);
/* we set the current DTS to 0 so that formats without any timestamps
* but durations get some timestamps, formats with some unknown
* timestamps have their first few packets buffered and the
* timestamps corrected before they are returned to the user */
st->cur_dts = RELATIVE_TS_BASE;
} else {
st->cur_dts = AV_NOPTS_VALUE;
}
st->index = s->nb_streams;
st->start_time = AV_NOPTS_VALUE;
st->duration = AV_NOPTS_VALUE;
st->first_dts = AV_NOPTS_VALUE;
st->probe_packets = MAX_PROBE_PACKETS;
st->pts_wrap_reference = AV_NOPTS_VALUE;
st->pts_wrap_behavior = AV_PTS_WRAP_IGNORE;
st->last_IP_pts = AV_NOPTS_VALUE;
st->last_dts_for_order_check = AV_NOPTS_VALUE;
for (i = 0; i < MAX_REORDER_DELAY + 1; i++)
st->pts_buffer[i] = AV_NOPTS_VALUE;
st->sample_aspect_ratio = (AVRational) { 0, 1 };
#if FF_API_R_FRAME_RATE
st->info->last_dts = AV_NOPTS_VALUE;
#endif
st->info->fps_first_dts = AV_NOPTS_VALUE;
st->info->fps_last_dts = AV_NOPTS_VALUE;
st->inject_global_side_data = s->internal->inject_global_side_data;
st->internal->need_context_update = 1;
s->streams[s->nb_streams++] = st;
return st;
fail:
free_stream(&st);
return NULL;
}
avformat_new_stream之后便在 AVFormatContext 里增加了 AVStream 通道(相关的index已经被设置了)。之后,我们就可以自行设置 AVStream 的一些参数信息。例如 : codec_id , format ,bit_rate ,width , height ... ...