[FFmpeg-devel] [PATCH] make stream-switching work with MOV demuxer
Baptiste Coudurier
baptiste.coudurier
Tue Jun 23 20:59:21 CEST 2009
Reimar D?ffinger wrote:
> On Tue, Jun 23, 2009 at 11:17:02AM -0700, Baptiste Coudurier wrote:
>> Reimar D?ffinger wrote:
>>> Hello,
>>> currently the MOV demuxer does not even keep track of the "current"
>>> position of streams set to AVDISCARD_ALL.
>>> This means that when removing AVDISCARD_ALL, that stream will start
>>> playing from the beginning.
>>> Now, the current behaviour may be valid, but it is at least inconsistent
>>> with most other demuxers, and at least with the current seeking API I
>>> can not see how else it should be possible to seamlessly switch between
>>> e.g. different audio streams.
>>> Since it duplicates code, attached patch is hardly acceptable, but it
>>> fixes the issue...
>> Just do like the stream wasn't discarded, just don't read the sample,
>> and retry. It should avoid code duplication I think.
>
> Yes, that is possible, it still seems a bit ugly and messy.
A lot better than previous patch.
> I also thought about moving the whole pts calculation etc. up, but
> that does not work because dv_produce_packet would then overwrite the
> values.
>
>
> ------------------------------------------------------------------------
>
> Index: libavformat/mov.c
> ===================================================================
> --- libavformat/mov.c (revision 19256)
> +++ libavformat/mov.c (working copy)
> @@ -1981,14 +1981,16 @@
> {
> MOVContext *mov = s->priv_data;
> MOVStreamContext *sc = 0;
> - AVIndexEntry *sample = 0;
> + AVIndexEntry *sample;
> int64_t best_dts = INT64_MAX;
> + int discard = 0;
> int i, ret;
> retry:
> + sample = NULL;
> for (i = 0; i < s->nb_streams; i++) {
> AVStream *st = s->streams[i];
> MOVStreamContext *msc = st->priv_data;
> - if (st->discard != AVDISCARD_ALL && msc->pb && msc->current_sample < st->nb_index_entries) {
> + if (msc->pb && msc->current_sample < st->nb_index_entries) {
> AVIndexEntry *current_sample = &st->index_entries[msc->current_sample];
> int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
> dprintf(s, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
> @@ -2000,6 +2002,7 @@
> sample = current_sample;
> best_dts = dts;
> sc = msc;
> + discard = st->discard == AVDISCARD_ALL;
I think discard variable can be avoided by checking
s->streams[sc->ffindex]->discard.
We could even declare AVStream *st = s->streams[sc->ffindex] when sample
is found and factore because it is already done when computing duration.
We could even get rid of sc->ffindex by choosing AVStream in the loop
and use ->priv_data, but well that can be done separately.
--
Baptiste COUDURIER GnuPG Key Id: 0x5C1ABAAA
Key fingerprint 8D77134D20CC9220201FC5DB0AC9325C5C1ABAAA
FFmpeg maintainer http://www.ffmpeg.org
More information about the ffmpeg-devel
mailing list