FFmpeg源代码分析

int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) { int i, count, ret = 0, j; int64_t read_size; AVStream *st; AVPacket pkt1, *pkt;

int64_t old_offset = avio_tell(ic->pb); // 可能会出现新的流,那些没有选项 int orig_nb_streams = ic->nb_streams;

int flush_codecs; int64_t max_analyze_duration = ic->max_analyze_duration2; int64_tprobesize = ic->probesize2; 如果(!max_analyze_duration)max_analyze_duration = ic->max_analyze_duration;

如果(ic->probesize)probesize = ic->probesize; flush_codecs = 探针大小 > 0; av_opt_set(ic, "skip_clear", "1", AV_OPT_SEARCH_CHILDREN); if (!max_analyze_duration) { if (!strcmp(ic->iformat->name, "flv") && !(ic-> ctx_flags & AVFMTCTX_NOHEADER)) { max_analyze_duration = 10*AV_TIME_BASE; } else max_analyze_duration = 5*AV_TIME_BASE; } if (ic->pb) av_log(ic, AV_LOG_DEBUG, "Before avformat_find_stream_info() pos:

%"PRId64" bytes read:%"PRId64" seeks:%d ", avio_tell(ic->pb), ic->pb ->bytes_read, ic->pb->seek_count); for (i = 0; i < ic->nb_streams; i++) { const AVCodec *codec;

AVDictionary *thread_opt = NULL; st = ic->streams[i]; if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO || st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE)

{ /* if (!st->time_base.num) st->time_base = */ if (!st- >codec->time_base.num) st-> 编解码器->time_base = st->time_base; } // 仅用于拆分内容 if (!st->parser && !(ic->flags & AVFMT_FLAG_NOPARSE)) { st->parser = av_parser_init(st->codec->codec_id); if (st->parser) { if (st->need_pa​​rsing == AVSTREAM_PARSE_HEADERS) { st->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES; } else if (st->need_pa​​rsing == AVSTREAM_PARSE_FULL_RAW)

{ st->parser->flags |= PARSER_FLAG_USE_CODEC_TS; } } else if (st->need_pa​​rsing) { av_log(ic, AV_LOG_VERBOSE, "

avcodec_get_name(st->codec->codec_id)); } } codec = find_decoder(ic, st, st->codec->codec_id); /*

*/ av_dict_set(options ? &options[i] : &thread_opt, "threads", "1", 0); if (ic->codec_whitelist) av_dict_set(options ? &options[i] : &thread_opt, "codec_whitelist", ic->codec_whitelist, 0);

/* 确保subtitle_header 设置正确。*/ if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE && codec && !st->codec->codec) { if (avcodec_open2(st->codec, codec, options ? &options[i]

: &thread_opt) < 0) av_log(ic, AV_LOG_WARNING, "在av_find_stream_info中打开编解码器失败"); } // 尝试只打开解码器,以防这足以获取参数。if (!has_codec_parameters(st, NULL) && st->request_probe <= 0) { if (codec && !st->codec->codec) if (avcodec_open2(st->codec, codec, options ? &options[i] : &thread_opt) < 0) av_log(ic, AV_LOG_WARNING, "av_find_stream_info 中的编解码器打开失败"); } if (!options) av_dict_free(&thread_opt);

} for (i = 0; i < ic->nb_streams; i++) { #if FF_API_R_FRAME_RATE ic->streams[i]->info->last_dts = AV_NOPTS_VALUE; #endif ic->streams[i]->info->fps_first_dts = AV_NOPTS_VALUE;

ic->streams[i]->info->fps_last_dts = AV_NOPTS_VALUE; } 计数 = 0; 读取大小 = 0; for (;;) { if (ff_check_interrupt(&ic->interrupt_callback)) { ret = AVERROR_EXIT; av_log(ic, AV_LOG_DEBUG, */ for (i = 0; i < ic->nb_streams; i++) { int fps_analyze_framecount = 20; st = ic->streams[i]; if (!has_codec_parameters(st, NULL)) 

。*/ 如果 (av_q2d(st->time_base) > 0。0005)fps_analyze_framecount *= 2;如果 (!tb_unreliable(st->codec)) fps_analyze_framecount = 0;

如果 (ic->fps_probe_size >= 0) fps_analyze_framecount = ic->fps_probe_size; if (st->disposition & AV_DISPOSITION_ATTACHED_PIC) fps_analyze_framecount = 0; /*  fps */ if (!(st->r_frame_rate.num && st->avg_frame_rate.num) && st->info->duration_count < fps_analyze_framecount && st->codec->codec_type = = AVMEDIA_TYPE_VIDEO) 中断;if (st->parser && st->parser->parser->split && !st->codec->extradata) 中断;

if (st->first_dts == AV_NOPTS_VALUE && !(ic->iformat->flags & AVFMT_NOTIMESTAMPS) && st->codec_info_nb_frames < ic->max_ts_probe && (st->codec->codec_type == AVMEDIA_TYPE->codec || ->codec_type == AVMEDIA_TYPE_AUDIO)) 中断;} if (i == ic->nb_streams)*/ if (!(ic->ctx_flags & AVFMTCTX_NOHEADER))

*/ if (read_size >=probesize) { ret = count; av_log(ic, AV_LOG_DEBUG, "已达到 %"PRId64",probesize); for (i = 0; i < ic->nb_streams; i++) if (!ic->streams[i]->r_frame_rate.num && ic->streams[i]->info->duration_count <= 1 && ic- >streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO && strcmp(ic->iformat->name, "image2")) av_log(ic, AV_LOG_WARNING, "Stream #%d: 

*/ ret = read_frame_internal(ic, &pkt1); if (ret == AVERROR(EAGAIN)) 继续;if (ret < 0) { /* EOF 或错误 */ break;

} if (ic->flags & AVFMT_FLAG_NOBUFFER) free_packet_buffer(&ic->packet_buffer, &ic->packet_buffer_end); { pkt = add_to_pktbuf(&ic->packet_buffer, &pkt1, &ic->packet_buffer_end);

if (!pkt) { ret = AVERROR(ENOMEM); 转到 find_stream_info_err; } if ((ret = av_dup_packet(pkt)) < 0) 转到 find_stream_info_err; st = ic->streams[pkt->stream_index]; if (!(st->disposition & AV_DISPOSITION_ATTACHED_PIC)) read_size += pkt->size; if (pkt->dts != AV_NOPTS_VALUE && st->codec_info_nb_frames > 1) { /* 检查非增加的 dts */ if (st->info->fps_last_dts != AV_NOPTS_VALUE && st->info->fps_last_dts pkt->dts) { av_log(ic, AV_LOG_DEBUG,

"流 %d 中的非增加 DTS: 数据包 %d 与 DTS " "%"PRId64", 数据包 %d 与 DTS %"PRId64" ", st->index, st->信息->fps_last_dts_idx,st->info->fps_last_dts、st->codec_info_nb_frames、pkt->dts);

st->info->fps_first_dts = st->info->fps_last_dts = AV_NOPTS_VALUE;} /*。*/ 如果 (st->info->fps_last_dts != AV_NOPTS_VALUE && st->info->fps_last_dts_idx > st->info->fps_first_dts_idx && (pkt->dts - st->info->fps_last_dts) / 1000 ->info->fps_last_dts - st->info->fps_first_dts) / (st->info->fps_last_dts_idx - st->info-> fps_first_dts_idx)) { av_log(ic, AV_LOG_WARNING, "流 %d 中的 DTS  ",st->index,st->info ->fps_last_dts_idx,st->info->fps_last_dts,st->codec_info_nb_frames,pkt->dts);st->info->fps_first_dts = st->info->fps_last_dts = AV_NOPTS_VALUE;} /*  */ if (st->info->fps_first_dts == AV_NOPTS_VALUE) { st->info->fps_first_dts = pkt->dts; st->info->fps_first_dts_idx = st->codec_info_nb_frames; } st-> 信息-> fps_last_dts = pkt->dts;

st->info->fps_last_dts_idx = st->codec_info_nb_frames; } if (st->codec_info_nb_frames>1) { int64_t t = 0; if (st->time_base.den > 0) t = av_rescale_q(st->info->codec_info_duration, st->time_base, AV_TIME_BASE_Q); if (st->avg_frame_rate.num > 0) t = FFMAX(t, av_rescale_q(st->codec_info_nb_frames, av_inv_q(st->avg_frame_rate), AV_TIME_BASE_Q)); if ( t == 0 && st->codec_info_nb_frames>30 && st->info->fps_first_dts != AV_NOPTS_VALUE && st->info->fps_last_dts != AV_NOPTS_VALUE) t = FFMAX(t, av_>rescale_q(st) fps_last_dts - st->信息-> fps_first_dts, st->time_base, AV_TIME_BASE_Q)); if (t >= max_analyze_duration) { av_log(ic, AV_LOG_VERBOSE, "max_analyze_duration %"PRId64" 达到 %"PRId64" 微秒 ", max_analyze_duration, t); if (ic->flags & AVFMT_FLAG_NOBUFFER) av_packet_unref(pkt); 打破; } if (pkt->duration) { st->info->codec_info_duration += pkt->duration;

st->info->codec_info_duration_fields += st->parser && st->need_pa​​rsing && st->codec->ticks_per_frame ==2 ? st->parser->repeat_pict + 1 : 2; } } #if FF_API_R_FRAME_RATE if (st->codec-> codec_type == AVMEDIA_TYPE_VIDEO) ff_rfps_add_frame(ic, st, pkt->dts); #endif if (st->parser && st->parser->parser->split && !st->codec->extradata) { int i = st->parser->parser->split(st->codec, pkt -> 数据,pkt-> 大小);if (i > 0 && i < FF_MAX_EXTRADATA_SIZE) {

if (ff_alloc_extradata(st->codec, i)) return AVERROR(ENOMEM); memcpy(st->codec->extradata,pkt->data,st->codec->extradata_size); } } /** *  CODEC_CAP_CHANNEL_CONF,

*/ try_decode_frame(ic, st, pkt, (options && i < orig_nb_streams) ? &options[i] : NULL); if (ic->flags & AVFMT_FLAG_NOBUFFER) av_packet_unref(pkt); st->codec_info_nb_frames++;计数++;} if (flush_codecs) { AVPacket empty_pkt = { 0 }; 内部错误 = 0; av_init_packet(&empty_pkt);

for (i = 0; i < ic->nb_streams; i++) { st = ic->streams[i]; /*  */ if (st->info->found_decoder == 1) { do { err = try_decode_frame(ic, st, &empty_pkt, (options && i < orig_nb_streams) ?

&options[i] : NULL); } while (err > 0 && !has_codec_parameters(st, NULL)); if (err < 0) { av_log(ic, AV_LOG_INFO, " st->index); } } } } // 关闭在 try_decode_frame()  for (i = 0; i < ic->nb_streams; i++) { st = ic->streams[i]; avcodec_close(st->codec); ff_rfps_calculate(ic); for (i = 0; i < ic->nb_streams; i++) { st = ic->streams[i]; if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)

{ if (st->codec->codec_id == AV_CODEC_ID_RAWVIDEO && !st->codec->codec_tag && !st->codec->bits_per_coded_sample) { uint32_t tagpix_tcodec_f_codec_f (st->codec->pix_fmt); 如果 (avpriv_find_pix_fmt(avpriv_get_raw_pix_fmt_tags(), tag) == st->codec->pix_fmt) st->codec->codec_tag= tag; }

if (st->info->codec_info_duration_fields && !st->avg_frame_rate.num && st->info->codec_info_duration) { int best_fps = 0; 双最佳_误差 = 0.01; if (st->info->codec_info_duration >= INT64_MAX / st->time_base.num / 2|| st->info->codec_info_duration_fields >= INT64_MAX / st->time_base.den || st->info->codec_info_duration < 0) 继续;

av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den, st->info->codec_info_duration_fields * (int64_t) st->time_base.den, st->info->codec_info_duration * 2 * (int64_t) st-> time_base.num, 60000); /* 如果猜测的帧率在原始估计的 1% 以内,则将其舍入为“标准”帧率。*/ for (j = 0; j < MAX_STD_TIMEBASES; j++) { AVRational std_fps = { get_std_framerate(j), 12 * 1001 };

双重错误 = fabs(av_q2d(st->avg_frame_rate) / av_q2d(std_fps) - 1); if (error < best_error) { best_error = 错误;best_fps = std_fps.num; } } if (best_fps) av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den, best_fps, 12 * 1001, INT_MAX); } if (!st->r_frame_rate.num) { if (st->codec->time_base.den * (int64_t) st->time_base.num <= st->codec->time_base.num * st->codec- > ticks_per_frame * (int64_t) st->time_base.den) { st->r_frame_rate.num = st->codec->time_base.den; st->r_frame_rate.den = st->codec->time_base.num * st->codec->ticks_per_frame; } else { st->r_frame_rate.num = st->time_base.den; st->r_frame_rate.den = st->time_base.num;

} } } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { if (!st->codec->bits_per_coded_sample) st->codec->bits_per_coded_sample = av_get_bits_per_sample(st->codec->codec_id); // (st->codec-> audio_service_type) { case AV_AUDIO_SERVICE_TYPE_EFFECTS: st->disposition = AV_DISPOSITION_CLEAN_EFFECTS;  AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED: st->disposition = AV_DISPOSITION_VISUAL_IMPAIRED; 打破; 案例 AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED: st->disposition = AV_DISPOSITION_HEARING_IMPAIRED;

打破; 案例 AV_AUDIO_SERVICE_TYPE_COMMENTARY: st->disposition = AV_DISPOSITION_COMMENT;  AV_AUDIO_SERVICE_TYPE_KARAOKE: st->disposition = AV_DISPOSITION_KARAOKE; 打破; if (probesize)estimating_timings(ic, old_offset); av_opt_set(ic, "skip_clear", "0", AV_OPT_SEARCH_CHILDREN); if (ret >= 0 && ic->nb_streams) /* 我们不可能在 EOF 。*/ ret = ⑴; for (i = 0; i < ic->nb_streams; i++) { const char *errmsg; st = ic->streams[i]; if (!has_codec_parameters(st, &errmsg)) { char buf[256]; avcodec_string(buf, sizeof(buf), st->codec, 0); av_log(ic, AV_LOG_WARNING,

"Could not find codec parameters for stream %d (%s): %s "  'analyzeduration', buf, errmsg); } else { ret = 0; 计算章节结束(IC)

;find_stream_info_err: for (i = 0; i < ic->nb_streams; i++) { st = ic->streams[i]; if (ic->streams[i]->codec->codec_type != AVMEDIA_TYPE_AUDIO) ic->streams[i]->codec->thread_count =

0; if (st->info) av_freep(&st->info->duration_error); av_freep(&ic->streams[i]->info); } if (ic->pb) av_log(ic, AV_LOG_DEBUG, "After avformat_find_stream_info() pos: %"PRId64" bytes read:%"PRId64" seeks:%d frames:%d ", avio_tell(ic->pb), ic->pb->bytes_read, ic->pb->seek_count, count); 返回 ret; } 信息) av_freep(&st->info->duration_error); av_freep(&ic->streams[i]->info);

} if (ic->pb) av_log(ic, AV_LOG_DEBUG, "After avformat_find_stream_info() pos: %"PRId64" bytes read:%"PRId64" seeks:%d frames:%d ", avio_tell(ic->pb), ic->pb->bytes_read, ic->pb->seek_count, count); 返回 ret; } 信息) av_freep(&st->info->duration_error); av_freep(&ic->streams[i]->info); } if (ic->pb) av_log(ic, AV_LOG_DEBUG, "After avformat_find_stream_info() pos: %"PRId64" bytes read:%"PRId64" seeks:%d frames:%d ", avio_tell(ic->pb), ic->pb->bytes_read, ic->pb->seek_count, count); 返回 ret; }

posted @ 2021-08-24 09:28  v17166570219  阅读(267)  评论(0)    收藏  举报