if ((ret = av_opt_set_dict(s, &tmp)) < 0)
goto fail;
+ av_strlcpy(s->filename, filename ? filename : "", sizeof(s->filename));
if ((ret = init_input(s, filename, &tmp)) < 0)
goto fail;
s->probe_score = ret;
}
s->duration = s->start_time = AV_NOPTS_VALUE;
- av_strlcpy(s->filename, filename ? filename : "", sizeof(s->filename));
/* Allocate private data. */
if (s->iformat->priv_data_size > 0) {
static int determinable_frame_size(AVCodecContext *avctx)
{
- if (/*avctx->codec_id == AV_CODEC_ID_AAC ||*/
- avctx->codec_id == AV_CODEC_ID_MP1 ||
- avctx->codec_id == AV_CODEC_ID_MP2 ||
- avctx->codec_id == AV_CODEC_ID_MP3/* ||
- avctx->codec_id == AV_CODEC_ID_CELT*/)
+ switch(avctx->codec_id) {
+ case AV_CODEC_ID_MP1:
+ case AV_CODEC_ID_MP2:
+ case AV_CODEC_ID_MP3:
return 1;
+ }
+
return 0;
}
}
}
+static int extract_extradata_check(AVStream *st)
+{
+ const AVBitStreamFilter *f;
+
+ f = av_bsf_get_by_name("extract_extradata");
+ if (!f)
+ return 0;
+
+ if (f->codec_ids) {
+ const enum AVCodecID *ids;
+ for (ids = f->codec_ids; *ids != AV_CODEC_ID_NONE; ids++)
+ if (*ids == st->codecpar->codec_id)
+ return 1;
+ }
+
+ return 0;
+}
+
+static int extract_extradata_init(AVStream *st)
+{
+ AVStreamInternal *i = st->internal;
+ const AVBitStreamFilter *f;
+ int ret;
+
+ f = av_bsf_get_by_name("extract_extradata");
+ if (!f)
+ goto finish;
+
+ /* check that the codec id is supported */
+ ret = extract_extradata_check(st);
+ if (!ret)
+ goto finish;
+
+ i->extract_extradata.pkt = av_packet_alloc();
+ if (!i->extract_extradata.pkt)
+ return AVERROR(ENOMEM);
+
+ ret = av_bsf_alloc(f, &i->extract_extradata.bsf);
+ if (ret < 0)
+ goto fail;
+
+ ret = avcodec_parameters_copy(i->extract_extradata.bsf->par_in,
+ st->codecpar);
+ if (ret < 0)
+ goto fail;
+
+ i->extract_extradata.bsf->time_base_in = st->time_base;
+
+ /* if init fails here, we assume extracting extradata is just not
+ * supported for this codec, so we return success */
+ ret = av_bsf_init(i->extract_extradata.bsf);
+ if (ret < 0) {
+ av_bsf_free(&i->extract_extradata.bsf);
+ ret = 0;
+ }
+
+finish:
+ i->extract_extradata.inited = 1;
+
+ return 0;
+fail:
+ av_bsf_free(&i->extract_extradata.bsf);
+ av_packet_free(&i->extract_extradata.pkt);
+ return ret;
+}
+
+static int extract_extradata(AVStream *st, AVPacket *pkt)
+{
+ AVStreamInternal *i = st->internal;
+ AVPacket *pkt_ref;
+ int ret;
+
+ if (!i->extract_extradata.inited) {
+ ret = extract_extradata_init(st);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (i->extract_extradata.inited && !i->extract_extradata.bsf)
+ return 0;
+
+ pkt_ref = i->extract_extradata.pkt;
+ ret = av_packet_ref(pkt_ref, pkt);
+ if (ret < 0)
+ return ret;
+
+ ret = av_bsf_send_packet(i->extract_extradata.bsf, pkt_ref);
+ if (ret < 0) {
+ av_packet_unref(pkt_ref);
+ return ret;
+ }
+
+ while (ret >= 0 && !i->avctx->extradata) {
+ int extradata_size;
+ uint8_t *extradata;
+
+ ret = av_bsf_receive_packet(i->extract_extradata.bsf, pkt_ref);
+ if (ret < 0) {
+ if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
+ return ret;
+ continue;
+ }
+
+ extradata = av_packet_get_side_data(pkt_ref, AV_PKT_DATA_NEW_EXTRADATA,
+ &extradata_size);
+
+ if (extradata) {
+ i->avctx->extradata = av_mallocz(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!i->avctx->extradata) {
+ av_packet_unref(pkt_ref);
+ return AVERROR(ENOMEM);
+ }
+ memcpy(i->avctx->extradata, extradata, extradata_size);
+ i->avctx->extradata_size = extradata_size;
+ }
+ av_packet_unref(pkt_ref);
+ }
+
+ return 0;
+}
+
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
{
int i, count = 0, ret = 0, j;
if (count < fps_analyze_framecount)
break;
}
- if (st->parser && st->parser->parser->split &&
- !st->internal->avctx->extradata)
+ if (!st->internal->avctx->extradata &&
+ (!st->internal->extract_extradata.inited ||
+ st->internal->extract_extradata.bsf) &&
+ extract_extradata_check(st))
break;
if (st->first_dts == AV_NOPTS_VALUE &&
!(ic->iformat->flags & AVFMT_NOTIMESTAMPS) &&
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
ff_rfps_add_frame(ic, st, pkt->dts);
#endif
- if (st->parser && st->parser->parser->split && !avctx->extradata) {
- int i = st->parser->parser->split(avctx, pkt->data, pkt->size);
- if (i > 0 && i < FF_MAX_EXTRADATA_SIZE) {
- avctx->extradata_size = i;
- avctx->extradata = av_mallocz(avctx->extradata_size +
- AV_INPUT_BUFFER_PADDING_SIZE);
- if (!avctx->extradata)
- return AVERROR(ENOMEM);
- memcpy(avctx->extradata, pkt->data,
- avctx->extradata_size);
- }
+ if (!st->internal->avctx->extradata) {
+ ret = extract_extradata(st, pkt);
+ if (ret < 0)
+ goto find_stream_info_err;
}
/* If still no information, we try to open the codec and to
st->info->codec_info_duration) {
int best_fps = 0;
double best_error = 0.01;
+ AVRational codec_frame_rate = avctx->framerate;
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 ||
best_error = error;
best_fps = std_fps.num;
}
+
+ if (ic->internal->prefer_codec_framerate && codec_frame_rate.num > 0 && codec_frame_rate.den > 0) {
+ error = fabs(av_q2d(codec_frame_rate) /
+ av_q2d(std_fps) - 1);
+ if (error < best_error) {
+ best_error = error;
+ best_fps = std_fps.num;
+ }
+ }
}
if (best_fps)
av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
if (st->info)
av_freep(&st->info->duration_error);
av_freep(&ic->streams[i]->info);
+ av_bsf_free(&ic->streams[i]->internal->extract_extradata.bsf);
+ av_packet_free(&ic->streams[i]->internal->extract_extradata.pkt);
}
if (ic->pb)
av_log(ic, AV_LOG_DEBUG, "After avformat_find_stream_info() pos: %"PRId64" bytes read:%"PRId64" seeks:%d frames:%d\n",
AVCodec **decoder_ret, int flags)
{
int i, nb_streams = ic->nb_streams;
- int ret = AVERROR_STREAM_NOT_FOUND, best_count = -1, best_bitrate = -1, best_multiframe = -1, count, bitrate, multiframe;
+ int ret = AVERROR_STREAM_NOT_FOUND;
+ int best_count = -1, best_multiframe = -1, best_disposition = -1;
+ int count, multiframe, disposition;
+ int64_t best_bitrate = -1;
+ int64_t bitrate;
unsigned *program = NULL;
const AVCodec *decoder = NULL, *best_decoder = NULL;
continue;
if (wanted_stream_nb >= 0 && real_stream_index != wanted_stream_nb)
continue;
- if (wanted_stream_nb != real_stream_index &&
- st->disposition & (AV_DISPOSITION_HEARING_IMPAIRED |
- AV_DISPOSITION_VISUAL_IMPAIRED))
- continue;
if (type == AVMEDIA_TYPE_AUDIO && !(par->channels && par->sample_rate))
continue;
if (decoder_ret) {
continue;
}
}
+ disposition = !(st->disposition & (AV_DISPOSITION_HEARING_IMPAIRED | AV_DISPOSITION_VISUAL_IMPAIRED));
count = st->codec_info_nb_frames;
bitrate = par->bit_rate;
multiframe = FFMIN(5, count);
- if ((best_multiframe > multiframe) ||
- (best_multiframe == multiframe && best_bitrate > bitrate) ||
- (best_multiframe == multiframe && best_bitrate == bitrate && best_count >= count))
+ if ((best_disposition > disposition) ||
+ (best_disposition == disposition && best_multiframe > multiframe) ||
+ (best_disposition == disposition && best_multiframe == multiframe && best_bitrate > bitrate) ||
+ (best_disposition == disposition && best_multiframe == multiframe && best_bitrate == bitrate && best_count >= count))
continue;
+ best_disposition = disposition;
best_count = count;
best_bitrate = bitrate;
best_multiframe = multiframe;
av_bsf_free(&st->internal->bsfcs[i]);
av_freep(&st->internal->bsfcs);
}
+ av_bsf_free(&st->internal->extract_extradata.bsf);
+ av_packet_free(&st->internal->extract_extradata.pkt);
}
av_freep(&st->internal);
av_freep(&st->index_entries);
#if FF_API_LAVF_AVCTX
FF_DISABLE_DEPRECATION_WARNINGS
- av_freep(&st->codec->extradata);
- av_freep(&st->codec->subtitle_header);
- av_freep(&st->codec);
+ avcodec_free_context(&st->codec);
FF_ENABLE_DEPRECATION_WARNINGS
#endif
av_freep(&st->priv_data);