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
_______________________________________________
vlc-commits mailing list
vlc-commits@videolan.org
https://mailman.videolan.org/listinfo/vlc-commits

Reply via email to