[vlc-devel] [PATCH 5/8] mkv: store a unique_ptr version of the mkv_track_t in the track list

Steve Lhomme robux4 at videolabs.io
Mon Jul 31 15:02:57 CEST 2017


The next step is to provide a destructor so the tracks_map_t can deal with the
lifecycle of the mkv_track_t.
---
 modules/demux/mkv/matroska_segment.cpp       | 30 +++++++++---------
 modules/demux/mkv/matroska_segment.hpp       |  3 +-
 modules/demux/mkv/matroska_segment_parse.cpp | 46 +++++++++++++++-------------
 modules/demux/mkv/mkv.cpp                    |  8 ++---
 modules/demux/mkv/virtual_segment.cpp        |  8 ++---
 5 files changed, 50 insertions(+), 45 deletions(-)

diff --git a/modules/demux/mkv/matroska_segment.cpp b/modules/demux/mkv/matroska_segment.cpp
index b7b8667ef2..f4061d60ba 100644
--- a/modules/demux/mkv/matroska_segment.cpp
+++ b/modules/demux/mkv/matroska_segment.cpp
@@ -67,7 +67,7 @@ matroska_segment_c::~matroska_segment_c()
 {
     for( tracks_map_t::iterator it = tracks.begin(); it != tracks.end(); ++it)
     {
-        tracks_map_t::mapped_type& track = it->second;
+        mkv_track_t & track = *it->second;
 
         es_format_Clean( &track.fmt );
         delete track.p_compression_data;
@@ -819,7 +819,7 @@ bool matroska_segment_c::Seek( mtime_t i_absolute_mk_date, mtime_t i_mk_time_off
 
     for( tracks_map_t::iterator it = tracks.begin(); it != tracks.end(); ++it )
     {
-        mkv_track_t& track = it->second;
+        mkv_track_t &track = *it->second;
 
         track.i_skip_until_fpos = -1;
         if( track.i_last_dts > VLC_TS_INVALID )
@@ -848,8 +848,8 @@ bool matroska_segment_c::Seek( mtime_t i_absolute_mk_date, mtime_t i_mk_time_off
             i_mk_seek_time  = it->second.pts;
         }
 
-        tracks.at( it->first ).i_skip_until_fpos = it->second.fpos;
-        tracks.at( it->first ).i_last_dts        = it->second.pts;
+        tracks.at( it->first )->i_skip_until_fpos = it->second.fpos;
+        tracks.at( it->first )->i_last_dts        = it->second.pts;
 
         msg_Dbg( &sys.demuxer, "seek: preroll{ track: %u, pts: %" PRId64 ", fpos: %" PRIu64 " } ",
           it->first, it->second.pts, it->second.fpos );
@@ -904,7 +904,7 @@ void matroska_segment_c::ComputeTrackPriority()
     for( tracks_map_t::const_iterator it = tracks.begin(); it != tracks.end();
          ++it )
     {
-        const tracks_map_t::mapped_type& track = it->second;
+        mkv_track_t &track = *it->second;
 
         bool flag = track.b_enabled && ( track.b_default || track.b_forced );
 
@@ -918,8 +918,8 @@ void matroska_segment_c::ComputeTrackPriority()
 
     for( tracks_map_t::iterator it = tracks.begin(); it != tracks.end(); ++it )
     {
-        tracks_map_t::key_type     track_id = it->first;
-        tracks_map_t::mapped_type& track    = it->second;
+        tracks_map_t::key_type track_id = it->first;
+        mkv_track_t          & track    = *it->second;
 
         if( unlikely( track.fmt.i_cat == UNKNOWN_ES || track.codec.empty() ) )
         {
@@ -960,7 +960,7 @@ void matroska_segment_c::ComputeTrackPriority()
         {
             int track_score = -1;
 
-            switch( it->second.fmt.i_cat )
+            switch( it->second->fmt.i_cat )
             {
                 case VIDEO_ES: ++track_score;
                 case AUDIO_ES: ++track_score;
@@ -968,7 +968,7 @@ void matroska_segment_c::ComputeTrackPriority()
                 default:
                   if( score < track_score )
                   {
-                      es_type = it->second.fmt.i_cat;
+                      es_type = it->second->fmt.i_cat;
                       score   = track_score;
                   }
             }
@@ -976,7 +976,7 @@ void matroska_segment_c::ComputeTrackPriority()
 
         for( tracks_map_t::const_iterator it = this->tracks.begin(); it != this->tracks.end(); ++it )
         {
-            if( it->second.fmt.i_cat == es_type )
+            if( it->second->fmt.i_cat == es_type )
                 priority_tracks.push_back( it->first );
         }
     }
@@ -1085,8 +1085,8 @@ bool matroska_segment_c::ESCreate()
 
     for( tracks_map_t::iterator it = tracks.begin(); it != tracks.end(); ++it )
     {
-        tracks_map_t::key_type     track_id = it->first;
-        tracks_map_t::mapped_type& track    = it->second;
+        tracks_map_t::key_type   track_id = it->first;
+        mkv_track_t            & track    = *it->second;
 
         if( unlikely( track.fmt.i_cat == UNKNOWN_ES || track.codec.empty() ) )
         {
@@ -1118,7 +1118,7 @@ void matroska_segment_c::ESDestroy( )
 
     for( tracks_map_t::iterator it = tracks.begin(); it != tracks.end(); ++it )
     {
-        tracks_map_t::mapped_type& track = it->second;
+        mkv_track_t & track = *it->second;
 
         if( track.p_es != NULL )
         {
@@ -1229,7 +1229,7 @@ int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_s
             vars.block->ReadData( vars.obj->es.I_O() );
             vars.block->SetParent( *vars.obj->cluster );
 
-            if( vars.obj->tracks.at( kblock.TrackNum() ).fmt.i_cat == SPU_ES )
+            if( vars.obj->tracks.at( kblock.TrackNum() )->fmt.i_cat == SPU_ES )
             {
                 vars.obj->_seeker.add_seekpoint( kblock.TrackNum(), SegmentSeeker::Seekpoint::TRUSTED, kblock.GetElementPosition(), kblock.GlobalTimecode() / 1000 );
             }
@@ -1308,7 +1308,7 @@ int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_s
             /* We have block group let's check if the picture is a keyframe */
             else if( *pb_key_picture )
             {
-                if( track_it->second.fmt.i_codec == VLC_CODEC_THEORA )
+                if( track_it->second->fmt.i_codec == VLC_CODEC_THEORA )
                 {
                     DataBuffer *    p_data = &pp_block->GetBuffer(0);
                     const uint8_t * p_buff = p_data->Buffer();
diff --git a/modules/demux/mkv/matroska_segment.hpp b/modules/demux/mkv/matroska_segment.hpp
index b2116b7c36..cd36f1c89a 100644
--- a/modules/demux/mkv/matroska_segment.hpp
+++ b/modules/demux/mkv/matroska_segment.hpp
@@ -32,6 +32,7 @@
 
 #include <map>
 #include <set>
+#include <memory>
 
 class EbmlParser;
 
@@ -74,7 +75,7 @@ public:
 class matroska_segment_c
 {
 public:
-    typedef std::map<mkv_track_t::track_id_t, mkv_track_t> tracks_map_t;
+    typedef std::map<mkv_track_t::track_id_t, std::unique_ptr<mkv_track_t>> tracks_map_t;
     typedef std::vector<Tag>            tags_t;
 
     matroska_segment_c( demux_sys_t & demuxer, EbmlStream & estream );
diff --git a/modules/demux/mkv/matroska_segment_parse.cpp b/modules/demux/mkv/matroska_segment_parse.cpp
index 71c174155b..c581fd99c2 100644
--- a/modules/demux/mkv/matroska_segment_parse.cpp
+++ b/modules/demux/mkv/matroska_segment_parse.cpp
@@ -230,7 +230,7 @@ void matroska_segment_c::ParseTrackEntry( const KaxTrackEntry *m )
     }
 
     /* Init the track */
-    mkv_track_t track( es_cat );
+    mkv_track_t *p_track = new mkv_track_t(es_cat);
 
     MkvTree( sys.demuxer, 2, "Track Entry" );
 
@@ -251,7 +251,7 @@ void matroska_segment_c::ParseTrackEntry( const KaxTrackEntry *m )
       } track_video_info;
 
     } metadata_payload = {
-      this, &track, &sys.demuxer, bSupported, 3, { }
+      this, p_track, &sys.demuxer, bSupported, 3, { }
     };
 
     MKV_SWITCH_CREATE( EbmlTypeDispatcher, MetaDataHandlers, MetaDataCapture )
@@ -670,43 +670,47 @@ void matroska_segment_c::ParseTrackEntry( const KaxTrackEntry *m )
 
     MetaDataHandlers::Dispatcher().iterate ( m->begin(), m->end(), MetaDataHandlers::Payload( metadata_payload ) );
 
-    if( track.i_number == 0 )
+    if( p_track->i_number == 0 )
     {
         msg_Warn( &sys.demuxer, "Missing KaxTrackNumber, discarding track!" );
-        es_format_Clean( &track.fmt );
-        free(track.p_extra_data);
+        es_format_Clean( &p_track->fmt );
+        free(p_track->p_extra_data);
+        delete p_track;
         return;
     }
 
     if ( bSupported )
     {
 #ifdef HAVE_ZLIB_H
-        if( track.i_compression_type == MATROSKA_COMPRESSION_ZLIB &&
-            track.i_encoding_scope & MATROSKA_ENCODING_SCOPE_PRIVATE &&
-            track.i_extra_data && track.p_extra_data &&
-            zlib_decompress_extra( &sys.demuxer, track ) )
-        {
-            msg_Err(&sys.demuxer, "Couldn't handle the track %u compression", track.i_number );
-            es_format_Clean( &track.fmt );
-            free(track.p_extra_data);
+        if( p_track->i_compression_type == MATROSKA_COMPRESSION_ZLIB &&
+            p_track->i_encoding_scope & MATROSKA_ENCODING_SCOPE_PRIVATE &&
+            p_track->i_extra_data && p_track->p_extra_data &&
+            zlib_decompress_extra( &sys.demuxer, *p_track ) )
+        {
+            msg_Err(&sys.demuxer, "Couldn't handle the track %u compression", p_track->i_number );
+            es_format_Clean( &p_track->fmt );
+            free(p_track->p_extra_data);
+            delete p_track;
             return;
         }
 #endif
-        if( !TrackInit( &track ) )
+        if( !TrackInit( p_track ) )
         {
-            msg_Err(&sys.demuxer, "Couldn't init track %u", track.i_number );
-            es_format_Clean( &track.fmt );
-            free(track.p_extra_data);
+            msg_Err(&sys.demuxer, "Couldn't init track %u", p_track->i_number );
+            es_format_Clean( &p_track->fmt );
+            free(p_track->p_extra_data);
+            delete p_track;
             return;
         }
 
-        tracks.insert( std::make_pair( track.i_number, track ) ); // TODO: add warning if two tracks have the same key
+        tracks.insert( std::make_pair( p_track->i_number, std::unique_ptr<mkv_track_t>(p_track) ) ); // TODO: add warning if two tracks have the same key
     }
     else
     {
-        msg_Err( &sys.demuxer, "Track Entry %u not supported", track.i_number );
-        es_format_Clean( &track.fmt );
-        free(track.p_extra_data);
+        msg_Err( &sys.demuxer, "Track Entry %u not supported", p_track->i_number );
+        es_format_Clean( &p_track->fmt );
+        free(p_track->p_extra_data);
+        delete p_track;
     }
 }
 
diff --git a/modules/demux/mkv/mkv.cpp b/modules/demux/mkv/mkv.cpp
index 6155708e65..bee64053e9 100644
--- a/modules/demux/mkv/mkv.cpp
+++ b/modules/demux/mkv/mkv.cpp
@@ -431,7 +431,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
                 const matroska_segment_c *p_segment = p_sys->p_current_vsegment->CurrentSegment();
                 for( tracks_map_t::const_iterator it = p_segment->tracks.begin(); it != p_segment->tracks.end(); ++it )
                 {
-                    tracks_map_t::mapped_type const& track = it->second;
+                    const mkv_track_t &track = *it->second;
 
                     if( track.fmt.i_cat == VIDEO_ES && track.fmt.video.i_frame_rate_base > 0 )
                     {
@@ -511,7 +511,7 @@ void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock
         return;
     }
 
-    tracks_map_t::mapped_type& track = track_it->second;
+    mkv_track_t &track = *track_it->second;
 
     if( track.fmt.i_cat != NAV_ES && track.p_es == NULL )
     {
@@ -726,7 +726,7 @@ static int Demux( demux_t *p_demux)
             return 0;
         }
 
-        matroska_segment_c::tracks_map_t::mapped_type& track = track_it->second;
+        mkv_track_t &track = *track_it->second;
 
 
         if( track.i_skip_until_fpos != std::numeric_limits<uint64_t>::max() ) {
@@ -754,7 +754,7 @@ static int Demux( demux_t *p_demux)
 
         for( tracks_map_t::iterator it = p_segment->tracks.begin(); it != p_segment->tracks.end(); ++it )
         {
-            tracks_map_t::mapped_type& track = it->second;
+            mkv_track_t &track = *it->second;
 
             if( track.i_last_dts == VLC_TS_INVALID )
                 continue;
diff --git a/modules/demux/mkv/virtual_segment.cpp b/modules/demux/mkv/virtual_segment.cpp
index ee9a385497..6f523a35a5 100644
--- a/modules/demux/mkv/virtual_segment.cpp
+++ b/modules/demux/mkv/virtual_segment.cpp
@@ -695,7 +695,7 @@ void virtual_segment_c::KeepTrackSelection( matroska_segment_c & old, matroska_s
     char *sub_lang = NULL, *aud_lang = NULL;
     for( tracks_map_t::iterator it = old.tracks.begin(); it != old.tracks.end(); ++it )
     {
-        tracks_map_t::mapped_type& track = it->second;
+        mkv_track_t &track = *it->second;
         if( track.p_es )
         {
             bool state = false;
@@ -711,8 +711,8 @@ void virtual_segment_c::KeepTrackSelection( matroska_segment_c & old, matroska_s
     }
     for( tracks_map_t::iterator it = next.tracks.begin(); it != next.tracks.end(); ++it )
     {
-        tracks_map_t::mapped_type& new_track = it->second;
-        es_format_t &              new_fmt   = new_track.fmt;
+        mkv_track_t & new_track = *it->second;
+        es_format_t & new_fmt   = new_track.fmt;
 
         /* Let's only do that for audio and video for now */
         if( new_fmt.i_cat == AUDIO_ES || new_fmt.i_cat == VIDEO_ES )
@@ -720,7 +720,7 @@ void virtual_segment_c::KeepTrackSelection( matroska_segment_c & old, matroska_s
             /* check for a similar elementary stream */
             for( tracks_map_t::iterator old_it = old.tracks.begin(); old_it != old.tracks.end(); ++old_it )
             {
-                tracks_map_t::mapped_type& old_track = old_it->second;
+                mkv_track_t& old_track = *old_it->second;
                 es_format_t& old_fmt = old_track.fmt;
 
                 if( !old_track.p_es )
-- 
2.12.1



More information about the vlc-devel mailing list