+static int MP4_ReadBox_iods( stream_t *p_stream, MP4_Box_t *p_box )
+{
+ char i_unused;
+
+ MP4_READBOX_ENTER( MP4_Box_data_iods_t );
+ MP4_GETVERSIONFLAGS( p_box->data.p_iods );
+
+ MP4_GET1BYTE( i_unused ); /* tag */
+ MP4_GET1BYTE( i_unused ); /* length */
+
+ MP4_GET2BYTES( p_box->data.p_iods->i_object_descriptor ); /* 10bits, 6 other bits
+ are used for other flags */
+ MP4_GET1BYTE( p_box->data.p_iods->i_OD_profile_level );
+ MP4_GET1BYTE( p_box->data.p_iods->i_scene_profile_level );
+ MP4_GET1BYTE( p_box->data.p_iods->i_audio_profile_level );
+ MP4_GET1BYTE( p_box->data.p_iods->i_visual_profile_level );
+ MP4_GET1BYTE( p_box->data.p_iods->i_graphics_profile_level );
+
+#ifdef MP4_VERBOSE
+ msg_Dbg( p_stream,
+ "read box: \"iods\" objectDescriptorId: %i, OD: %i, scene: %i, audio: %i, "
+ "visual: %i, graphics: %i",
+ p_box->data.p_iods->i_object_descriptor >> 6,
+ p_box->data.p_iods->i_OD_profile_level,
+ p_box->data.p_iods->i_scene_profile_level,
+ p_box->data.p_iods->i_audio_profile_level,
+ p_box->data.p_iods->i_visual_profile_level,
+ p_box->data.p_iods->i_graphics_profile_level );
+#endif
+
+ MP4_READBOX_EXIT( 1 );
+}
+
+static int MP4_ReadBox_pasp( stream_t *p_stream, MP4_Box_t *p_box )
+{
+ MP4_READBOX_ENTER( MP4_Box_data_pasp_t );
+
+ MP4_GET4BYTES( p_box->data.p_pasp->i_horizontal_spacing );
+ MP4_GET4BYTES( p_box->data.p_pasp->i_vertical_spacing );
+
+#ifdef MP4_VERBOSE
+ msg_Dbg( p_stream,
+ "read box: \"paps\" %dx%d",
+ p_box->data.p_pasp->i_horizontal_spacing,
+ p_box->data.p_pasp->i_vertical_spacing);
+#endif
+
+ MP4_READBOX_EXIT( 1 );
+}
+
+static int MP4_ReadBox_mehd( stream_t *p_stream, MP4_Box_t *p_box )
+{
+ MP4_READBOX_ENTER( MP4_Box_data_mehd_t );
+
+ MP4_GETVERSIONFLAGS( p_box->data.p_mehd );
+ if( p_box->data.p_mehd->i_version == 1 )
+ MP4_GET8BYTES( p_box->data.p_mehd->i_fragment_duration );
+ else /* version == 0 */
+ MP4_GET4BYTES( p_box->data.p_mehd->i_fragment_duration );
+
+#ifdef MP4_VERBOSE
+ msg_Dbg( p_stream,
+ "read box: \"mehd\" frag dur. %"PRIu64"",
+ p_box->data.p_mehd->i_fragment_duration );
+#endif
+
+ MP4_READBOX_EXIT( 1 );
+}
+
+static int MP4_ReadBox_trex( stream_t *p_stream, MP4_Box_t *p_box )
+{
+ MP4_READBOX_ENTER( MP4_Box_data_trex_t );
+ MP4_GETVERSIONFLAGS( p_box->data.p_trex );
+
+ MP4_GET4BYTES( p_box->data.p_trex->i_track_ID );
+ MP4_GET4BYTES( p_box->data.p_trex->i_default_sample_description_index );
+ MP4_GET4BYTES( p_box->data.p_trex->i_default_sample_duration );
+ MP4_GET4BYTES( p_box->data.p_trex->i_default_sample_size );
+ MP4_GET4BYTES( p_box->data.p_trex->i_default_sample_flags );
+
+#ifdef MP4_VERBOSE
+ msg_Dbg( p_stream,
+ "read box: \"trex\" trackID: %"PRIu32"",
+ p_box->data.p_trex->i_track_ID );
+#endif
+
+ MP4_READBOX_EXIT( 1 );
+}
+
+static int MP4_ReadBox_sdtp( stream_t *p_stream, MP4_Box_t *p_box )
+{
+ uint32_t i_sample_count;
+ MP4_READBOX_ENTER( MP4_Box_data_sdtp_t );
+ MP4_Box_data_sdtp_t *p_sdtp = p_box->data.p_sdtp;
+ MP4_GETVERSIONFLAGS( p_box->data.p_sdtp );
+ i_sample_count = i_read;
+
+ p_sdtp->p_sample_table = calloc( i_sample_count, 1 );
+
+ if( !p_sdtp->p_sample_table )
+ MP4_READBOX_EXIT( 0 );
+
+ for( uint32_t i = 0; i < i_sample_count; i++ )
+ MP4_GET1BYTE( p_sdtp->p_sample_table[i] );
+
+#ifdef MP4_VERBOSE
+ msg_Info( p_stream, "i_sample_count is %"PRIu32"", i_sample_count );
+ msg_Dbg( p_stream,
+ "read box: \"sdtp\" head: %"PRIx8" %"PRIx8" %"PRIx8" %"PRIx8"",
+ p_sdtp->p_sample_table[0],
+ p_sdtp->p_sample_table[1],
+ p_sdtp->p_sample_table[2],
+ p_sdtp->p_sample_table[3] );
+#endif
+
+ MP4_READBOX_EXIT( 1 );
+}
+
+static void MP4_FreeBox_sdtp( MP4_Box_t *p_box )
+{
+ FREENULL( p_box->data.p_sdtp->p_sample_table );
+}
+
+static int MP4_ReadBox_mfro( stream_t *p_stream, MP4_Box_t *p_box )
+{
+ MP4_READBOX_ENTER( MP4_Box_data_mfro_t );
+
+ MP4_GETVERSIONFLAGS( p_box->data.p_mfro );
+ MP4_GET4BYTES( p_box->data.p_mfro->i_size );
+
+#ifdef MP4_VERBOSE
+ msg_Dbg( p_stream,
+ "read box: \"mfro\" size: %"PRIu32"",
+ p_box->data.p_mfro->i_size);
+#endif
+
+ MP4_READBOX_EXIT( 1 );
+}
+
+static int MP4_ReadBox_tfra( stream_t *p_stream, MP4_Box_t *p_box )
+{
+ uint32_t i_number_of_entries;
+ MP4_READBOX_ENTER( MP4_Box_data_tfra_t );
+ MP4_Box_data_tfra_t *p_tfra = p_box->data.p_tfra;
+ MP4_GETVERSIONFLAGS( p_box->data.p_tfra );
+
+ MP4_GET4BYTES( p_tfra->i_track_ID );
+ uint32_t i_lengths = 0;
+ MP4_GET4BYTES( i_lengths );
+ MP4_GET4BYTES( p_tfra->i_number_of_entries );
+ i_number_of_entries = p_tfra->i_number_of_entries;
+ p_tfra->i_length_size_of_traf_num = i_lengths >> 4;
+ p_tfra->i_length_size_of_trun_num = ( i_lengths & 0x0c ) >> 2;
+ p_tfra->i_length_size_of_sample_num = i_lengths & 0x03;
+
+ size_t size = 4 + 4*p_tfra->i_version; /* size in {4, 8} */
+ p_tfra->p_time = calloc( i_number_of_entries, size );
+ p_tfra->p_moof_offset = calloc( i_number_of_entries, size );
+
+ size = 1 + p_tfra->i_length_size_of_traf_num; /* size in [|1, 4|] */
+ p_tfra->p_traf_number = calloc( i_number_of_entries, size );
+ size = 1 + p_tfra->i_length_size_of_trun_num;
+ p_tfra->p_trun_number = calloc( i_number_of_entries, size );
+ size = 1 + p_tfra->i_length_size_of_sample_num;
+ p_tfra->p_sample_number = calloc( i_number_of_entries, size );
+
+ if( !p_tfra->p_time || !p_tfra->p_moof_offset || !p_tfra->p_traf_number
+ || !p_tfra->p_trun_number || !p_tfra->p_sample_number )
+ goto error;
+
+ for( uint32_t i = 0; i < i_number_of_entries; i++ )
+ {
+ if( p_tfra->i_version == 1 )
+ {
+ MP4_GET8BYTES( p_tfra->p_time[i*2] );
+ MP4_GET8BYTES( p_tfra->p_moof_offset[i*2] );
+ }
+ else
+ {
+ MP4_GET4BYTES( p_tfra->p_time[i] );
+ MP4_GET4BYTES( p_tfra->p_moof_offset[i] );
+ }
+ switch (p_tfra->i_length_size_of_traf_num)
+ {
+ case 0:
+ MP4_GET1BYTE( p_tfra->p_traf_number[i] );
+ break;
+ case 1:
+ MP4_GET2BYTES( p_tfra->p_traf_number[i*2] );
+ break;
+ case 2:
+ MP4_GET3BYTES( p_tfra->p_traf_number[i*3] );
+ break;
+ case 3:
+ MP4_GET4BYTES( p_tfra->p_traf_number[i*4] );
+ break;
+ default:
+ goto error;
+ }
+
+ switch (p_tfra->i_length_size_of_trun_num)
+ {
+ case 0:
+ MP4_GET1BYTE( p_tfra->p_trun_number[i] );
+ break;
+ case 1:
+ MP4_GET2BYTES( p_tfra->p_trun_number[i*2] );
+ break;
+ case 2:
+ MP4_GET3BYTES( p_tfra->p_trun_number[i*3] );
+ break;
+ case 3:
+ MP4_GET4BYTES( p_tfra->p_trun_number[i*4] );
+ break;
+ default:
+ goto error;
+ }
+
+ switch (p_tfra->i_length_size_of_sample_num)
+ {
+ case 0:
+ MP4_GET1BYTE( p_tfra->p_sample_number[i] );
+ break;
+ case 1:
+ MP4_GET2BYTES( p_tfra->p_sample_number[i*2] );
+ break;
+ case 2:
+ MP4_GET3BYTES( p_tfra->p_sample_number[i*3] );
+ break;
+ case 3:
+ MP4_GET4BYTES( p_tfra->p_sample_number[i*4] );
+ break;
+ default:
+ goto error;
+ }
+ }
+
+#ifdef MP4_VERBOSE
+ if( p_tfra->i_version == 0 )
+ {
+ msg_Dbg( p_stream, "time[0]: %"PRIu32", moof_offset[0]: %"PRIx32"",
+ p_tfra->p_time[0], p_tfra->p_moof_offset[0] );
+
+ msg_Dbg( p_stream, "time[1]: %"PRIu32", moof_offset[1]: %"PRIx32"",
+ p_tfra->p_time[1], p_tfra->p_moof_offset[1] );
+ }
+ else
+ {
+ msg_Dbg( p_stream, "time[0]: %"PRIu64", moof_offset[0]: %"PRIx64"",
+ ((uint64_t *)(p_tfra->p_time))[0],
+ ((uint64_t *)(p_tfra->p_moof_offset))[0] );
+
+ msg_Dbg( p_stream, "time[1]: %"PRIu64", moof_offset[1]: %"PRIx64"",
+ ((uint64_t *)(p_tfra->p_time))[1],
+ ((uint64_t *)(p_tfra->p_moof_offset))[1] );
+ }
+
+ msg_Info( p_stream, "number_of_entries is %"PRIu32"", i_number_of_entries );
+ msg_Info( p_stream, "track ID is: %"PRIu32"", p_tfra->i_track_ID );
+#endif
+
+ MP4_READBOX_EXIT( 1 );
+error:
+ MP4_READBOX_EXIT( 0 );
+}
+
+static void MP4_FreeBox_tfra( MP4_Box_t *p_box )
+{
+ FREENULL( p_box->data.p_tfra->p_time );
+ FREENULL( p_box->data.p_tfra->p_moof_offset );
+ FREENULL( p_box->data.p_tfra->p_traf_number );
+ FREENULL( p_box->data.p_tfra->p_trun_number );
+ FREENULL( p_box->data.p_tfra->p_sample_number );
+}
+
+