Commit 0c782cba authored by Frédéric Yhuel's avatar Frédéric Yhuel Committed by 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.zipSigned-off-by: default avatarJean-Baptiste Kempf <jb@videolan.org>
parent 8bce50f4
...@@ -497,6 +497,68 @@ static int MP4_ReadBox_mfhd( stream_t *p_stream, MP4_Box_t *p_box ) ...@@ -497,6 +497,68 @@ static int MP4_ReadBox_mfhd( stream_t *p_stream, MP4_Box_t *p_box )
MP4_READBOX_EXIT( 1 ); 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 ) static int MP4_ReadBox_tfhd( stream_t *p_stream, MP4_Box_t *p_box )
{ {
MP4_READBOX_ENTER( MP4_Box_data_tfhd_t ); MP4_READBOX_ENTER( MP4_Box_data_tfhd_t );
...@@ -3216,6 +3278,7 @@ static const struct ...@@ -3216,6 +3278,7 @@ static const struct
{ ATOM_traf, MP4_ReadBoxContainer, MP4_FreeBox_Common }, { ATOM_traf, MP4_ReadBoxContainer, MP4_FreeBox_Common },
{ ATOM_mfra, MP4_ReadBoxContainer, MP4_FreeBox_Common }, { ATOM_mfra, MP4_ReadBoxContainer, MP4_FreeBox_Common },
{ ATOM_mfhd, MP4_ReadBox_mfhd, 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_tfhd, MP4_ReadBox_tfhd, MP4_FreeBox_Common },
{ ATOM_trun, MP4_ReadBox_trun, MP4_FreeBox_trun }, { ATOM_trun, MP4_ReadBox_trun, MP4_FreeBox_trun },
{ ATOM_trex, MP4_ReadBox_trex, MP4_FreeBox_Common }, { ATOM_trex, MP4_ReadBox_trex, MP4_FreeBox_Common },
......
...@@ -78,6 +78,7 @@ ...@@ -78,6 +78,7 @@
#define ATOM_mehd VLC_FOURCC( 'm', 'e', 'h', 'd' ) #define ATOM_mehd VLC_FOURCC( 'm', 'e', 'h', 'd' )
#define ATOM_mfhd VLC_FOURCC( 'm', 'f', 'h', 'd' ) #define ATOM_mfhd VLC_FOURCC( 'm', 'f', 'h', 'd' )
#define ATOM_traf VLC_FOURCC( 't', 'r', 'a', 'f' ) #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_tfhd VLC_FOURCC( 't', 'f', 'h', 'd' )
#define ATOM_trun VLC_FOURCC( 't', 'r', 'u', 'n' ) #define ATOM_trun VLC_FOURCC( 't', 'r', 'u', 'n' )
#define ATOM_cprt VLC_FOURCC( 'c', 'p', 'r', 't' ) #define ATOM_cprt VLC_FOURCC( 'c', 'p', 'r', 't' )
...@@ -837,6 +838,32 @@ typedef struct MP4_Box_data_mfhd_s ...@@ -837,6 +838,32 @@ typedef struct MP4_Box_data_mfhd_s
} MP4_Box_data_mfhd_t; } 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_BASE_DATA_OFFSET (1LL<<0)
#define MP4_TFHD_SAMPLE_DESC_INDEX (1LL<<1) #define MP4_TFHD_SAMPLE_DESC_INDEX (1LL<<1)
#define MP4_TFHD_DFLT_SAMPLE_DURATION (1LL<<3) #define MP4_TFHD_DFLT_SAMPLE_DURATION (1LL<<3)
...@@ -1063,6 +1090,7 @@ typedef union MP4_Box_data_s ...@@ -1063,6 +1090,7 @@ typedef union MP4_Box_data_s
MP4_Box_data_ftyp_t *p_ftyp; MP4_Box_data_ftyp_t *p_ftyp;
MP4_Box_data_mvhd_t *p_mvhd; MP4_Box_data_mvhd_t *p_mvhd;
MP4_Box_data_mfhd_t *p_mfhd; MP4_Box_data_mfhd_t *p_mfhd;
MP4_Box_data_sidx_t *p_sidx;
MP4_Box_data_tfhd_t *p_tfhd; MP4_Box_data_tfhd_t *p_tfhd;
MP4_Box_data_trun_t *p_trun; MP4_Box_data_trun_t *p_trun;
MP4_Box_data_tkhd_t *p_tkhd; MP4_Box_data_tkhd_t *p_tkhd;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment