[vlc-commits] [Git][videolan/vlc][master] 3 commits: demux: mp4: use single alloc for sgbp
François Cartegnie (@fcartegnie)
gitlab at videolan.org
Wed Feb 8 22:35:59 UTC 2023
François Cartegnie pushed to branch master at VideoLAN / VLC
Commits:
c4a2bd32 by Francois Cartegnie at 2023-02-08T22:18:43+00:00
demux: mp4: use single alloc for sgbp
- - - - -
4675cd54 by Francois Cartegnie at 2023-02-08T22:18:43+00:00
demux: mp4: refactor matching group info
- - - - -
6ad2b572 by Francois Cartegnie at 2023-02-08T22:18:43+00:00
demux: mp4: stss is not a subset of RAP sync table
- - - - -
3 changed files:
- modules/demux/mp4/libmp4.c
- modules/demux/mp4/libmp4.h
- modules/demux/mp4/mp4.c
Changes:
=====================================
modules/demux/mp4/libmp4.c
=====================================
@@ -2132,8 +2132,7 @@ static int MP4_ReadBox_ASF( stream_t *p_stream, MP4_Box_t *p_box )
static void MP4_FreeBox_sbgp( MP4_Box_t *p_box )
{
MP4_Box_data_sbgp_t *p_sbgp = p_box->data.p_sbgp;
- free( p_sbgp->entries.pi_sample_count );
- free( p_sbgp->entries.pi_group_description_index );
+ free( p_sbgp->p_entries );
}
static int MP4_ReadBox_sbgp( stream_t *p_stream, MP4_Box_t *p_box )
@@ -2163,10 +2162,8 @@ static int MP4_ReadBox_sbgp( stream_t *p_stream, MP4_Box_t *p_box )
if( p_sbgp->i_entry_count > i_read / (4 + 4) )
p_sbgp->i_entry_count = i_read / (4 + 4);
- p_sbgp->entries.pi_sample_count = vlc_alloc( p_sbgp->i_entry_count, sizeof(uint32_t) );
- p_sbgp->entries.pi_group_description_index = vlc_alloc( p_sbgp->i_entry_count, sizeof(uint32_t) );
-
- if( !p_sbgp->entries.pi_sample_count || !p_sbgp->entries.pi_group_description_index )
+ p_sbgp->p_entries = vlc_alloc( p_sbgp->i_entry_count, sizeof(*p_sbgp->p_entries) );
+ if( !p_sbgp->p_entries )
{
MP4_FreeBox_sbgp( p_box );
MP4_READBOX_EXIT( 0 );
@@ -2174,8 +2171,8 @@ static int MP4_ReadBox_sbgp( stream_t *p_stream, MP4_Box_t *p_box )
for( uint32_t i=0; i<p_sbgp->i_entry_count; i++ )
{
- MP4_GET4BYTES( p_sbgp->entries.pi_sample_count[i] );
- MP4_GET4BYTES( p_sbgp->entries.pi_group_description_index[i] );
+ MP4_GET4BYTES( p_sbgp->p_entries[i].i_sample_count );
+ MP4_GET4BYTES( p_sbgp->p_entries[i].i_group_description_index );
}
#ifdef MP4_VERBOSE
@@ -2184,8 +2181,8 @@ static int MP4_ReadBox_sbgp( stream_t *p_stream, MP4_Box_t *p_box )
#ifdef MP4_ULTRA_VERBOSE
for (uint32_t i = 0; i < p_sbgp->i_entry_count; i++)
msg_Dbg( p_stream, "\t samples %" PRIu32 " group %" PRIu32,
- p_sbgp->entries.pi_sample_count[i],
- p_sbgp->entries.pi_group_description_index[i] );
+ p_sbgp->entries[i].i_sample_count,
+ p_sbgp->entries[i].i_group_description_index );
#endif
#endif
=====================================
modules/demux/mp4/libmp4.h
=====================================
@@ -1358,33 +1358,41 @@ typedef struct
uint8_t i_stream_number;
} MP4_Box_data_ASF_t;
+typedef union
+{
+ struct
+ {
+ uint8_t i_num_leading_samples_known;
+ uint8_t i_num_leading_samples;
+ } rap;
+ struct
+ {
+ int16_t i_roll_distance;
+ } roll;
+} MP4_Box_data_sgpd_entry_t;
+
typedef struct
{
uint8_t i_version;
uint32_t i_grouping_type;
uint32_t i_default_sample_description_index;
uint32_t i_entry_count;
- union
- {
- struct
- {
- uint8_t i_num_leading_samples_known;
- uint8_t i_num_leading_samples;
- } rap;
- } *p_entries;
+ MP4_Box_data_sgpd_entry_t *p_entries;
} MP4_Box_data_sgpd_t;
+typedef struct
+{
+ uint32_t i_sample_count;
+ uint32_t i_group_description_index;
+} MP4_Box_data_sbgp_entry_t;
+
typedef struct
{
uint8_t i_version;
uint32_t i_grouping_type;
uint32_t i_grouping_type_parameter;
uint32_t i_entry_count;
- struct
- {
- uint32_t *pi_sample_count;
- uint32_t *pi_group_description_index;
- } entries;
+ MP4_Box_data_sbgp_entry_t *p_entries;
} MP4_Box_data_sbgp_t;
typedef struct
=====================================
modules/demux/mp4/mp4.c
=====================================
@@ -336,6 +336,111 @@ static MP4_Box_t * MP4_GetTrafByTrackID( MP4_Box_t *p_moof, const uint32_t i_id
return p_traf;
}
+static const MP4_Box_t * MP4_GroupDescriptionByType( const MP4_Box_t *p_node,
+ uint32_t i_grouping_type )
+{
+ for( const MP4_Box_t *p_sgpd = MP4_BoxGet( p_node, "sgpd" );
+ p_sgpd; p_sgpd = p_sgpd->p_next )
+ {
+ const MP4_Box_data_sgpd_t *p_sgpd_data = BOXDATA(p_sgpd);
+ if( p_sgpd->i_type != ATOM_sgpd || !p_sgpd_data ||
+ p_sgpd_data->i_grouping_type != i_grouping_type )
+ continue;
+ return p_sgpd;
+ }
+ return NULL;
+}
+
+enum SampleGroupMatch
+{
+ SAMPLE_GROUP_MATCH_EXACT = 0,
+ SAMPLE_GROUP_MATCH_LAST_VALID = 1,
+};
+
+static const MP4_Box_data_sbgp_entry_t *
+ MP4_SampleToGroupInfo( const MP4_Box_t *p_node, uint32_t i_sample,
+ uint32_t i_grouping_type,
+ uint32_t i_grouping_type_parameter,
+ uint32_t *pi_group_sample,
+ enum SampleGroupMatch match,
+ const MP4_Box_data_sgpd_entry_t **pp_descentry )
+{
+ const MP4_Box_t *p_sbgp = MP4_BoxGet( p_node, "sbgp" );
+ const MP4_Box_data_sbgp_t *p_sbgp_data;
+ for( ; p_sbgp; p_sbgp = p_sbgp->p_next )
+ {
+ p_sbgp_data = BOXDATA(p_sbgp);
+ if( p_sbgp->i_type == ATOM_sbgp && p_sbgp_data &&
+ p_sbgp_data->i_grouping_type == i_grouping_type &&
+ (i_grouping_type_parameter == 0 ||
+ p_sbgp_data->i_grouping_type_parameter == i_grouping_type_parameter) )
+ break;
+ }
+
+ if( !p_sbgp )
+ return NULL;
+
+ const MP4_Box_data_sbgp_entry_t *p_sampleentry = NULL;
+ uint32_t i_entry_start_sample = 0;
+ for ( uint32_t i=0; i<p_sbgp_data->i_entry_count; i++ )
+ {
+ const uint32_t next_entry_start_sample = i_entry_start_sample +
+ p_sbgp_data->p_entries[i].i_sample_count;
+ if( i_sample >= next_entry_start_sample )
+ {
+ if( match == SAMPLE_GROUP_MATCH_LAST_VALID &&
+ p_sbgp_data->p_entries[i].i_group_description_index != 0 )
+ {
+ p_sampleentry = &p_sbgp_data->p_entries[i];
+ if( pi_group_sample )
+ *pi_group_sample = i_entry_start_sample;
+ }
+ i_entry_start_sample = next_entry_start_sample;
+ continue;
+ }
+
+ /* Sample has meaning for group */
+ if( p_sbgp_data->p_entries[i].i_group_description_index != 0 )
+ {
+ p_sampleentry = &p_sbgp_data->p_entries[i];
+ if( pi_group_sample )
+ *pi_group_sample = i_entry_start_sample;
+ }
+ break;
+ }
+
+ /* No meaning found for sample */
+ if( p_sampleentry == NULL )
+ return NULL;
+
+ /* We have a sample entry in the group and maybe a description */
+ if( pp_descentry == NULL )
+ return p_sampleentry;
+
+ /* Lookup designated group description */
+ const MP4_Box_t *p_sgpd = MP4_GroupDescriptionByType( p_node, i_grouping_type );
+ if( p_sgpd )
+ {
+ const MP4_Box_data_sgpd_t *p_descdata = BOXDATA(p_sgpd);
+ if( p_sampleentry &&
+ p_sampleentry->i_group_description_index <= p_descdata->i_entry_count )
+ {
+ *pp_descentry = &p_descdata->
+ p_entries[p_sampleentry->i_group_description_index - 1];
+ }
+ else if( p_sampleentry == NULL &&
+ p_descdata->i_version >= 2 &&
+ p_descdata->i_default_sample_description_index &&
+ p_descdata->i_default_sample_description_index <= p_descdata->i_entry_count )
+ {
+ *pp_descentry = &p_descdata->
+ p_entries[p_descdata->i_default_sample_description_index - 1];
+ }
+ }
+
+ return p_sampleentry;
+}
+
static es_out_id_t * MP4_CreateES( es_out_t *out, const es_format_t *p_fmt,
bool b_forced_spu )
{
@@ -3065,9 +3170,10 @@ static int TrackGetNearestSeekPoint( demux_t *p_demux, mp4_track_t *p_track,
uint32_t i_sample, uint32_t *pi_sync_sample )
{
int i_ret = VLC_EGENERIC;
- *pi_sync_sample = 0;
+ *pi_sync_sample = i_sample;
const MP4_Box_t *p_stss;
+ /* try sync points without recovery roll */
if( ( p_stss = MP4_BoxGet( p_track->p_stbl, "stss" ) ) )
{
const MP4_Box_data_stss_t *p_stss_data = BOXDATA(p_stss);
@@ -3087,44 +3193,17 @@ static int TrackGetNearestSeekPoint( demux_t *p_demux, mp4_track_t *p_track,
}
}
- /* try rap samples groups */
- const MP4_Box_t *p_sbgp = MP4_BoxGet( p_track->p_stbl, "sbgp" );
- for( ; p_sbgp; p_sbgp = p_sbgp->p_next )
+ /* try or refine using RAP with recovery roll info */
+ uint32_t i_alternative_sync_sample = i_sample;
+ if( MP4_SampleToGroupInfo( p_track->p_stbl, i_sample, SAMPLEGROUP_rap,
+ 0, &i_alternative_sync_sample, true, NULL ) )
{
- const MP4_Box_data_sbgp_t *p_sbgp_data = BOXDATA(p_sbgp);
- if( p_sbgp->i_type != ATOM_sbgp || !p_sbgp_data )
- continue;
-
- if( p_sbgp_data->i_grouping_type == SAMPLEGROUP_rap )
- {
- uint32_t i_group_sample = 0;
- for ( uint32_t i=0; i<p_sbgp_data->i_entry_count; i++ )
- {
- /* Sample belongs to rap group ? */
- if( p_sbgp_data->entries.pi_group_description_index[i] != 0 )
- {
- if( i_sample < i_group_sample )
- {
- msg_Dbg( p_demux, "sbgp lookup failed %" PRIu32 " (sample number)",
- i_sample );
- break;
- }
- else if ( i_sample >= i_group_sample &&
- *pi_sync_sample < i_group_sample )
- {
- *pi_sync_sample = i_group_sample;
- i_ret = VLC_SUCCESS;
- }
- }
- i_group_sample += p_sbgp_data->entries.pi_sample_count[i];
- }
-
- if( i_ret == VLC_SUCCESS && *pi_sync_sample )
- {
- msg_Dbg( p_demux, "sbgp gives %d --> %" PRIu32 " (sample number)",
- i_sample, *pi_sync_sample );
- }
- }
+ i_ret = VLC_SUCCESS;
+ msg_Dbg( p_demux, "tk %u sbgp gives %d --> %" PRIu32 " (sample number)",
+ p_track->i_track_ID, i_sample, i_alternative_sync_sample );
+ if( i_alternative_sync_sample > *pi_sync_sample &&
+ i_alternative_sync_sample < i_sample )
+ *pi_sync_sample = i_alternative_sync_sample;
}
return i_ret;
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/1927b0b6ab10c49741851429522dea3ddeb00b08...6ad2b5720196e56bc9fd75b3f5fa42c0f2b59811
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/1927b0b6ab10c49741851429522dea3ddeb00b08...6ad2b5720196e56bc9fd75b3f5fa42c0f2b59811
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list