[vlc-commits] demux/mp4: add parsing of sidx box

Frédéric Yhuel git at videolan.org
Fri Mar 16 11:29:39 CET 2012


vlc | branch: master | Frédéric Yhuel <fyhuel at viotech.net> | Fri Mar 16 10:31:24 2012 +0100| [0c782cba4fa2516d3cce6367ed5d08ad20f79575] | committer: Jean-Baptiste Kempf

demux/mp4: add parsing of sidx box

This is a DASH specific box. See [1] for its definition.
It will probably be useful in a near future, and I will use it at a
workaround to get fragment duration when tfhd and trun boxes don't give
(default) sample duration(s).

[1] http://www.3gpp.org/ftp/Inbox/LSs_from_external_bodies/ISO_IEC_JTC1_SG29_WG11/29n12310.zip

Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=0c782cba4fa2516d3cce6367ed5d08ad20f79575
---

 modules/demux/mp4/libmp4.c |   63 ++++++++++++++++++++++++++++++++++++++++++++
 modules/demux/mp4/libmp4.h |   28 +++++++++++++++++++
 2 files changed, 91 insertions(+), 0 deletions(-)

diff --git a/modules/demux/mp4/libmp4.c b/modules/demux/mp4/libmp4.c
index 600c171..6964b0a 100644
--- a/modules/demux/mp4/libmp4.c
+++ b/modules/demux/mp4/libmp4.c
@@ -497,6 +497,68 @@ static int MP4_ReadBox_mfhd(  stream_t *p_stream, MP4_Box_t *p_box )
     MP4_READBOX_EXIT( 1 );
 }
 
+static int MP4_ReadBox_sidx(  stream_t *p_stream, MP4_Box_t *p_box )
+{
+    MP4_READBOX_ENTER( MP4_Box_data_sidx_t );
+
+    MP4_Box_data_sidx_t *p_sidx_data = p_box->data.p_sidx;
+    MP4_GETVERSIONFLAGS( p_sidx_data );
+
+    MP4_GET4BYTES( p_sidx_data->i_reference_ID );
+    MP4_GET4BYTES( p_sidx_data->i_timescale );
+
+    if( p_sidx_data->i_version == 0 )
+    {
+        MP4_GET4BYTES( p_sidx_data->i_earliest_presentation_time );
+        MP4_GET4BYTES( p_sidx_data->i_first_offset );
+    }
+    else
+    {
+        MP4_GET8BYTES( p_sidx_data->i_earliest_presentation_time );
+        MP4_GET8BYTES( p_sidx_data->i_first_offset );
+    }
+
+    uint16_t i_reserved;
+    MP4_GET2BYTES( i_reserved );
+    MP4_GET2BYTES( p_sidx_data->i_reference_count );
+    uint16_t i_count = p_sidx_data->i_reference_count;
+
+    p_sidx_data->p_items = calloc( i_count, sizeof( MP4_Box_sidx_item_t ) );
+    uint32_t tmp;
+    for( unsigned i = 0; i < i_count; i++ )
+    {
+        MP4_GET4BYTES( tmp );
+        p_sidx_data->p_items[i].b_reference_type = (bool)((tmp & 0x80000000)>>24);
+        p_sidx_data->p_items[i].i_referenced_size = tmp & 0x7fffffff;
+        MP4_GET4BYTES( p_sidx_data->p_items[i].i_subsegment_duration );
+
+        MP4_GET4BYTES( tmp );
+        p_sidx_data->p_items[i].b_starts_with_SAP = (bool)((tmp & 0x80000000)>>24);
+        p_sidx_data->p_items[i].i_SAP_type = (tmp & 0x70000000)>>24;
+        p_sidx_data->p_items[i].i_SAP_delta_time = tmp & 0xfffffff;
+    }
+
+#ifdef MP4_VERBOSE
+    msg_Dbg( p_stream, "read box: \"sidx\" version %d, flags 0x%x, "\
+            "ref_ID %"PRIu32", timescale %"PRIu32", ref_count %"PRIu16", "\
+            "first subsegmt duration %"PRIu32,
+                p_sidx_data->i_version,
+                p_sidx_data->i_flags,
+                p_sidx_data->i_reference_ID,
+                p_sidx_data->i_timescale,
+                p_sidx_data->i_reference_count,
+                p_sidx_data->p_items[0].i_subsegment_duration
+           );
+#endif
+
+    MP4_READBOX_EXIT( 1 );
+}
+
+static void MP4_FreeBox_sidx( MP4_Box_t *p_box )
+{
+    FREENULL( p_box->data.p_sidx->p_items );
+}
+
 static int MP4_ReadBox_tfhd(  stream_t *p_stream, MP4_Box_t *p_box )
 {
     MP4_READBOX_ENTER( MP4_Box_data_tfhd_t );
@@ -3216,6 +3278,7 @@ static const struct
     { ATOM_traf,    MP4_ReadBoxContainer,     MP4_FreeBox_Common },
     { ATOM_mfra,    MP4_ReadBoxContainer,     MP4_FreeBox_Common },
     { ATOM_mfhd,    MP4_ReadBox_mfhd,         MP4_FreeBox_Common },
+    { ATOM_sidx,    MP4_ReadBox_sidx,         MP4_FreeBox_sidx },
     { ATOM_tfhd,    MP4_ReadBox_tfhd,         MP4_FreeBox_Common },
     { ATOM_trun,    MP4_ReadBox_trun,         MP4_FreeBox_trun },
     { ATOM_trex,    MP4_ReadBox_trex,         MP4_FreeBox_Common },
diff --git a/modules/demux/mp4/libmp4.h b/modules/demux/mp4/libmp4.h
index 99c81c9..5b6b106 100644
--- a/modules/demux/mp4/libmp4.h
+++ b/modules/demux/mp4/libmp4.h
@@ -78,6 +78,7 @@
 #define ATOM_mehd VLC_FOURCC( 'm', 'e', 'h', 'd' )
 #define ATOM_mfhd VLC_FOURCC( 'm', 'f', 'h', 'd' )
 #define ATOM_traf VLC_FOURCC( 't', 'r', 'a', 'f' )
+#define ATOM_sidx VLC_FOURCC( 's', 'i', 'd', 'x' )
 #define ATOM_tfhd VLC_FOURCC( 't', 'f', 'h', 'd' )
 #define ATOM_trun VLC_FOURCC( 't', 'r', 'u', 'n' )
 #define ATOM_cprt VLC_FOURCC( 'c', 'p', 'r', 't' )
@@ -837,6 +838,32 @@ typedef struct MP4_Box_data_mfhd_s
 
 } MP4_Box_data_mfhd_t;
 
+typedef struct MP4_Box_sidx_item_s
+{
+    bool     b_reference_type;
+    uint32_t i_referenced_size;
+    uint32_t i_subsegment_duration;
+    bool     b_starts_with_SAP;
+    uint8_t  i_SAP_type;
+    uint32_t i_SAP_delta_time;
+
+} MP4_Box_sidx_item_t;
+
+typedef struct MP4_Box_data_sidx_s
+{
+    uint8_t  i_version;
+    uint32_t i_flags;
+
+    uint32_t i_reference_ID;
+    uint32_t i_timescale;
+    uint64_t i_earliest_presentation_time;
+    uint64_t i_first_offset;
+    uint16_t i_reference_count;
+
+    MP4_Box_sidx_item_t *p_items;
+
+} MP4_Box_data_sidx_t;
+
 #define MP4_TFHD_BASE_DATA_OFFSET     (1LL<<0)
 #define MP4_TFHD_SAMPLE_DESC_INDEX    (1LL<<1)
 #define MP4_TFHD_DFLT_SAMPLE_DURATION (1LL<<3)
@@ -1063,6 +1090,7 @@ typedef union MP4_Box_data_s
     MP4_Box_data_ftyp_t *p_ftyp;
     MP4_Box_data_mvhd_t *p_mvhd;
     MP4_Box_data_mfhd_t *p_mfhd;
+    MP4_Box_data_sidx_t *p_sidx;
     MP4_Box_data_tfhd_t *p_tfhd;
     MP4_Box_data_trun_t *p_trun;
     MP4_Box_data_tkhd_t *p_tkhd;



More information about the vlc-commits mailing list