]> git.sesse.net Git - vlc/blobdiff - modules/demux/mkv/virtual_segment.hpp
MKV: Virtual segment rewrite
[vlc] / modules / demux / mkv / virtual_segment.hpp
index 1f10a3ce47cda699f2e2c69618e19e82591734ca..bbdc2fa8488a1c0ac2bf38540d6a5fdc3f507282 100644 (file)
@@ -1,4 +1,3 @@
-
 /*****************************************************************************
  * mkv.cpp : matroska demuxer
  *****************************************************************************
 #include "matroska_segment.hpp"
 #include "chapters.hpp"
 
-// class holding hard-linked segment together in the playback order
-class virtual_segment_c
+/* virtual classes don't own anything but virtual elements so they shouldn't have to delete anything */
+
+class virtual_chapter_c
 {
 public:
-    virtual_segment_c( matroska_segment_c *p_segment )
-        :i_sys_title(0)
-        ,i_current_segment(0)
-        ,i_current_edition(-1)
-        ,p_current_chapter(NULL)
-        ,p_editions(NULL)
+    virtual_chapter_c( matroska_segment_c *p_seg, chapter_item_c *p_chap, int64_t start, int64_t stop ):
+        p_segment(p_seg), p_chapter(p_chap),
+        i_virtual_start_time(start), i_virtual_stop_time(stop)
+    {}
+    ~virtual_chapter_c();
+
+    static virtual_chapter_c * CreateVirtualChapter( chapter_item_c * p_chap,
+                                                     matroska_segment_c * p_main_segment,
+                                                     std::vector<matroska_segment_c*> * segments,
+                                                     int64_t * usertime_offset, bool b_ordered );
+
+    virtual_chapter_c* getSubChapterbyTimecode( int64_t time );
+    bool EnterAndLeave( virtual_chapter_c *p_item, bool b_enter = true );
+    virtual_chapter_c * FindChapter( int64_t i_find_uid );
+    int PublishChapters( input_title_t & title, int & i_user_chapters, int i_level );
+
+    virtual_chapter_c * BrowseCodecPrivate( unsigned int codec_id,
+                                            bool (*match)( const chapter_codec_cmds_c &data,
+                                                           const void *p_cookie,
+                                                           size_t i_cookie_size ),
+                                            const void *p_cookie,
+                                            size_t i_cookie_size );
+    bool Enter( bool b_do_subs );
+    bool Leave( bool b_do_subs );
+
+    static bool CompareTimecode( const virtual_chapter_c * itemA, const virtual_chapter_c * itemB )
     {
-        linked_segments.push_back( p_segment );
-
-        AppendUID( p_segment->p_segment_uid );
-        AppendUID( p_segment->p_prev_segment_uid );
-        AppendUID( p_segment->p_next_segment_uid );
+        return ( itemA->i_virtual_start_time < itemB->i_virtual_start_time ||
+                ( itemA->i_virtual_start_time == itemB->i_virtual_start_time &&
+                  itemA->i_virtual_stop_time < itemB->i_virtual_stop_time ) );
     }
 
-    void AddSegments( std::vector<matroska_segment_c*> segments );
+    matroska_segment_c  *p_segment;
+    chapter_item_c      *p_chapter;
+    int64_t             i_virtual_start_time;
+    int64_t             i_virtual_stop_time;
+    int                 i_seekpoint_num;
+    std::vector<virtual_chapter_c *> sub_chapters;
+#if MKV_DEBUG
+    void print();
+#endif
+};
+
+class virtual_edition_c
+{
+public:
+    virtual_edition_c( chapter_edition_c * p_edition, std::vector<matroska_segment_c*> *opened_segments );
+    ~virtual_edition_c();
+    std::vector<virtual_chapter_c*> chapters;
+
+    virtual_chapter_c* getChapterbyTimecode( int64_t time );
+    std::string GetMainName();
+    int PublishChapters( input_title_t & title, int & i_user_chapters, int i_level );
+    virtual_chapter_c * BrowseCodecPrivate( unsigned int codec_id,
+                                            bool (*match)( const chapter_codec_cmds_c &data,
+                                                           const void *p_cookie,
+                                                           size_t i_cookie_size ),
+                                             const void *p_cookie, size_t i_cookie_size );
+
+    bool                b_ordered;
+    int64_t             i_duration;
+    chapter_edition_c   *p_edition;
+    int                 i_seekpoint_num;
+
+private:
+    void retimeChapters();
+    void retimeSubChapters( virtual_chapter_c * p_vchap );
+#if MKV_DEBUG
+    void print(){ for( size_t i = 0; i<chapters.size(); i++ ) chapters[i]->print(); }
+#endif
+
+};
 
-    void Seek( demux_t & demuxer, mtime_t i_date, mtime_t i_time_offset, chapter_item_c *psz_chapter, int64_t i_global_position );
+// class holding hard-linked segment together in the playback order
+class virtual_segment_c
+{
+public:
+    virtual_segment_c( std::vector<matroska_segment_c*> * opened_segments );
+    ~virtual_segment_c();
+    std::vector<virtual_edition_c*> editions;
+    int                             i_current_edition;
+    virtual_chapter_c               *p_current_chapter;
+    int                             i_sys_title;
 
-    mtime_t Duration() const;
 
-    inline chapter_edition_c *CurrentEdition()
+    inline virtual_edition_c * CurrentEdition()
     {
-        if ( i_current_edition >= 0 && size_t(i_current_edition) < p_editions->size() )
-            return (*p_editions)[i_current_edition];
+        if( i_current_edition >= 0 && (size_t) i_current_edition < editions.size() )
+            return editions[i_current_edition];
         return NULL;
     }
-    std::vector<chapter_edition_c*>*  Editions() const { return p_editions; };
 
-    matroska_segment_c * CurrentSegment() const
+    virtual_chapter_c * CurrentChapter() const
     {
-        if ( linked_segments.size() == 0 || i_current_segment >= linked_segments.size() )
-            return NULL;
-        return linked_segments[i_current_segment];
+        return p_current_chapter;
     }
 
-    chapter_item_c *CurrentChapter() { return p_current_chapter; }
-
-    bool SelectNext()
+    matroska_segment_c * CurrentSegment() const
     {
-        if ( i_current_segment < linked_segments.size()-1 )
-        {
-            i_current_segment++;
-            return true;
-        }
-        return false;
+        if ( !p_current_chapter )
+            return NULL;
+        return p_current_chapter->p_segment;
     }
 
-    bool FindUID( KaxSegmentUID & uid ) const
+    inline int64_t Duration()
     {
-        for ( size_t i=0; i<linked_uids.size(); i++ )
-        {
-            if ( linked_uids[i] == uid )
-                return true;
-        }
-        return false;
+        return editions[i_current_edition]->i_duration / 1000;
     }
 
-    chapter_item_c *FindChapter( int64_t i_find_uid );
+    inline std::vector<virtual_edition_c*>* Editions() { return &editions; }
 
-    bool UpdateCurrentToChapter( demux_t & demux );
-
-    chapter_item_c *BrowseCodecPrivate( unsigned int codec_id,
-                                        bool (*match)(const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size ),
-                                        const void *p_cookie,
-                                        size_t i_cookie_size );
-
-    int                              i_sys_title;
-
-protected:
-    std::vector<matroska_segment_c*> linked_segments;
-    std::vector<KaxSegmentUID>       linked_uids;
-    size_t                           i_current_segment;
+    virtual_chapter_c *BrowseCodecPrivate( unsigned int codec_id,
+                                           bool (*match)( const chapter_codec_cmds_c &data,
+                                                          const void *p_cookie,
+                                                          size_t i_cookie_size ),
+                                           const void *p_cookie,
+                                           size_t i_cookie_size );
 
-    int                              i_current_edition;
-    chapter_item_c                   *p_current_chapter;
+    virtual_chapter_c * FindChapter( int64_t i_find_uid );
 
-    std::vector<chapter_edition_c*>  *p_editions;
-
-    void                             AppendUID( const EbmlBinary * UID );
-
-private:
-    void Sort();
-    size_t AddSegment( matroska_segment_c *p_segment );
-    void PreloadLinked( );
-    void PrepareChapters( );
+    bool UpdateCurrentToChapter( demux_t & demux );
+    void Seek( demux_t & demuxer, mtime_t i_date, mtime_t i_time_offset,
+               virtual_chapter_c *p_chapter, int64_t i_global_position );
 };
 
 #endif