[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