[FFmpeg-devel] [PATCH][RFC] Interpretation of duration field in AVI super index chunk

Tobias Rapp t.rapp at noa-audio.com
Wed Feb 25 17:35:33 CET 2015

On 24.02.2015 16:33, Tobias Rapp wrote:
> Hi,
> I am currently trying to interpret the index data of HuffYuv/PCM AVI
> files written by FFmpeg. If the file is larger than 2GiB an "AVIX" RIFF
> chunk is added for each 2GiB-block, each of these blocks gets an OpenDML
> chunk index "ix00" and an OpenDML super index chunk "indx" is written
> for each stream that contains the file offset of the according chunk
> indexes together with its size and total duration.
> For this super index "duration" entry the documentation I have found
> states that it shall be the "time span in stream ticks" [1]. FFmpeg
> seems to write the chunk count instead which is correct for video
> streams where one data chunk "00dc" corresponds to one frame. For audio
> streams one data chunk "01wb" usually contains multiple samples.
> I guess for audio streams the "duration" should be multiplied by the
> samples-per-chunk factor in avienc.c to allow third-party applications
> to jump to the correct AVIX RIFF segment based on a given timestamp.
> Any comments?

To illustrate my issue I have attached a patch that makes the OpenDML 
super index chunk consistent with my interpretation of the specs. A test 
with VirtualDub 1.10.4 shows that it also writes the audio duration 
using sample count instead of packet count.

Using sample count allows to seek the audio stream to the right RIFF 
segment without reading through all OpenDML standard "ix01" chunks.

Please comment,
-------------- next part --------------
>From 3a8e15598fa3e044f3ef65b5063c633cb4b3afed Mon Sep 17 00:00:00 2001
From: Tobias Rapp <t.rapp at noa-audio.com>
Date: Wed, 25 Feb 2015 17:10:13 +0100
Subject: [PATCH] libavformat/avienc: Fix duration for audio stream OpenDML
 super index

Fixes the duration field of the OpenDML super index "indx" chunk to
contain the number of samples instead of the number of packets for
(linear/PCM) audio streams.

This matches the OpenDML V1.02 standard text which states that the
duration field shall contain "time span in stream ticks".
 libavformat/avienc.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/libavformat/avienc.c b/libavformat/avienc.c
index 53c2fe7..b77b295 100644
--- a/libavformat/avienc.c
+++ b/libavformat/avienc.c
@@ -49,6 +49,7 @@ typedef struct AVIIentry {
 typedef struct AVIIndex {
     int64_t     indx_start;
+    int64_t     audio_strm_offset;
     int         entry;
     int         ents_allocated;
     AVIIentry** cluster;
@@ -91,6 +92,7 @@ static int64_t avi_start_new_riff(AVFormatContext *s, AVIOContext *pb,
     for (i = 0; i < s->nb_streams; i++) {
         AVIStream *avist = s->streams[i]->priv_data;
+        avist->indexes.audio_strm_offset = avist->audio_strm_length;
         avist->indexes.entry = 0;
@@ -476,6 +478,7 @@ static int avi_write_ix(AVFormatContext *s)
     for (i = 0; i < s->nb_streams; i++) {
         AVIStream *avist = s->streams[i]->priv_data;
         int64_t ix, pos;
+        int au_byterate, au_ssize, au_scale;
         avi_stream2fourcc(tag, i, s->streams[i]->codec->codec_type);
         ix_tag[3] = '0' + i;
@@ -511,7 +514,11 @@ static int avi_write_ix(AVFormatContext *s)
         avio_skip(pb, 16 * avi->riff_id);
         avio_wl64(pb, ix);                    /* qwOffset */
         avio_wl32(pb, pos - ix);              /* dwSize */
-        avio_wl32(pb, avist->indexes.entry);  /* dwDuration */
+        ff_parse_specific_params(s->streams[i], &au_byterate, &au_ssize, &au_scale);
+        if (au_ssize == 0)
+            avio_wl32(pb, avist->indexes.entry);  /* dwDuration (packet count) */
+        else
+            avio_wl32(pb, (avist->audio_strm_length - avist->indexes.audio_strm_offset) / au_ssize);  /* dwDuration (sample count) */
         avio_seek(pb, pos, SEEK_SET);

More information about the ffmpeg-devel mailing list