[FFmpeg-devel] [PATCH] rmdec.c: parse INDX chunk

Kostya kostya.shishkov
Wed Mar 11 06:40:42 CET 2009


On Wed, Mar 11, 2009 at 01:00:45AM -0400, Ronald S. Bultje wrote:
> Hi,
> 
> attached patch adds support for index parsing.
> 
> Ronald

> Index: ffmpeg-svn/libavformat/rmdec.c
> ===================================================================
> --- ffmpeg-svn.orig/libavformat/rmdec.c	2009-03-09 23:22:13.000000000 -0400
> +++ ffmpeg-svn/libavformat/rmdec.c	2009-03-09 23:24:22.000000000 -0400
> @@ -292,6 +292,51 @@
>      return 0;
>  }
>  
> +/** this function assumes that the demuxer has already seeked to the start
> + * of the INDX chunk, and will bail out if not. */
> +static int rm_read_index(AVFormatContext *s)
> +{
> +    ByteIOContext *pb = s->pb;
> +    unsigned int size, n_pkts, str_id, next_off, n, pos, pts;
> +    AVStream *st;
> +
> +    do {
> +        if (get_le32(pb) != MKTAG('I','N','D','X'))
> +            return -1;
> +        size     = get_be32(pb);
> +        if (size < 20)
> +            return -1;
> +        url_fskip(pb, 2);
> +        n_pkts   = get_be32(pb);
> +        str_id   = get_be16(pb);
> +        next_off = get_be32(pb);
> +        if (size > 20)
> +            url_fskip(pb, size - 20);

err, what happens when somebody decides to follow spec and include size of index
entries into header size?

> +        for (n = 0; n < s->nb_streams; n++)
> +            if (s->streams[n]->id == str_id) {
> +                st = s->streams[n];
> +                break;
> +            }
> +        if (n == s->nb_streams)
> +            goto skip;
> +        for (n = 0; n < n_pkts; n++) {
> +            url_fskip(pb, 2);
> +            pts = get_be32(pb);
> +            pos = get_be32(pb);
> +            url_fskip(pb, 4); /* packet no. */
> +
> +            av_add_index_entry(st, pos, pts, 0, 0, AVINDEX_KEYFRAME);
> +        }
> +
> +skip:
> +        if (url_ftell(pb) != next_off &&
> +            url_fseek(pb, next_off, SEEK_SET) < 0)
> +            return -1;

this condition should be changed since it does not take into account streamed
data, for which we should read or skip only this index chunk

> +    } while (next_off);
> +
> +    return 0;
> +}
>  
>  static int rm_read_header_old(AVFormatContext *s, AVFormatParameters *ap)
>  {
> @@ -314,6 +359,7 @@
>      unsigned int tag;
>      int tag_size;
>      unsigned int start_time, duration;
> +    unsigned int data_off = 0, indx_off = 0;
>      char buf[128];
>      int flags = 0;
>  
> @@ -357,8 +403,8 @@
>              get_be32(pb); /* nb packets */
>              get_be32(pb); /* duration */
>              get_be32(pb); /* preroll */
> -            get_be32(pb); /* index offset */
> -            get_be32(pb); /* data offset */
> +            indx_off = get_be32(pb); /* index offset */
> +            data_off = get_be32(pb); /* data offset */
>              get_be16(pb); /* nb streams */
>              flags = get_be16(pb); /* flags */
>              break;
> @@ -400,6 +446,14 @@
>      if (!rm->nb_packets && (flags & 4))
>          rm->nb_packets = 3600 * 25;
>      get_be32(pb); /* next data header */
> +
> +    if (!data_off)
> +        data_off = url_ftell(pb) - 14;
> +    if (indx_off && url_fseek(pb, indx_off, SEEK_SET) >= 0) {
> +        rm_read_index(s);
> +        url_fseek(pb, data_off + 14, SEEK_SET);
> +    }
> +
>      return 0;
>  }
  
after that someone has to write rm_read_seek() ;)




More information about the ffmpeg-devel mailing list