1 /***************************************************************************** 2 * virtual_segment.hpp : virtual segment implementation in the MKV demuxer 3 ***************************************************************************** 4 * Copyright © 2003-2011 VideoLAN and VLC authors 5 * $Id: 53d297f2cb1b8be7a7106840de4c1299497299b9 $ 6 * 7 * Authors: Laurent Aimar <fenrir@via.ecp.fr> 8 * Steve Lhomme <steve.lhomme@free.fr> 9 * Denis Charmet <typx@dinauz.org> 10 * 11 * This program is free software; you can redistribute it and/or modify it 12 * under the terms of the GNU Lesser General Public License as published by 13 * the Free Software Foundation; either version 2.1 of the License, or 14 * (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU Lesser General Public License for more details. 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * along with this program; if not, write to the Free Software Foundation, 23 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. 24 *****************************************************************************/ 25 26 #ifndef VLC_MKV_VIRTUAL_SEGMENT_HPP_ 27 #define VLC_MKV_VIRTUAL_SEGMENT_HPP_ 28 29 #include "mkv.hpp" 30 31 #include "matroska_segment.hpp" 32 #include "chapters.hpp" 33 34 /* virtual classes don't own anything but virtual elements so they shouldn't have to delete anything */ 35 36 class virtual_chapter_c 37 { 38 public: virtual_chapter_c(matroska_segment_c & seg,chapter_item_c * p_chap,int64_t start,int64_t stop,std::vector<virtual_chapter_c * > & sub_chaps)39 virtual_chapter_c( matroska_segment_c &seg, chapter_item_c *p_chap, int64_t start, int64_t stop, std::vector<virtual_chapter_c *> & sub_chaps ): 40 segment(seg), p_chapter(p_chap), 41 i_mk_virtual_start_time(start), i_mk_virtual_stop_time(stop), 42 sub_vchapters(sub_chaps) 43 {} 44 ~virtual_chapter_c(); 45 46 static virtual_chapter_c * CreateVirtualChapter( chapter_item_c * p_chap, 47 matroska_segment_c & main_segment, 48 std::vector<matroska_segment_c*> & segments, 49 int64_t & usertime_offset, bool b_ordered ); 50 51 virtual_chapter_c* getSubChapterbyTimecode( int64_t time ); 52 bool Leave( ); 53 bool EnterAndLeave( virtual_chapter_c *p_leaving_vchapter, bool b_enter = true ); 54 virtual_chapter_c * FindChapter( int64_t i_find_uid ); 55 int PublishChapters( input_title_t & title, int & i_user_chapters, int i_level, bool allow_no_name ); 56 57 virtual_chapter_c * BrowseCodecPrivate( unsigned int codec_id, 58 bool (*match)( const chapter_codec_cmds_c &data, 59 const void *p_cookie, 60 size_t i_cookie_size ), 61 const void *p_cookie, 62 size_t i_cookie_size ); 63 bool Enter( bool b_do_subs ); 64 bool Leave( bool b_do_subs ); 65 CompareTimecode(const virtual_chapter_c * itemA,const virtual_chapter_c * itemB)66 static bool CompareTimecode( const virtual_chapter_c * itemA, const virtual_chapter_c * itemB ) 67 { 68 return ( itemA->i_mk_virtual_start_time < itemB->i_mk_virtual_start_time ); 69 } 70 71 bool ContainsTimestamp( mtime_t i_pts ); 72 73 matroska_segment_c &segment; 74 chapter_item_c *p_chapter; 75 mtime_t i_mk_virtual_start_time; 76 mtime_t i_mk_virtual_stop_time; 77 int i_seekpoint_num; 78 std::vector<virtual_chapter_c *> sub_vchapters; 79 #ifdef MKV_DEBUG 80 void print(); 81 #endif 82 }; 83 84 class virtual_edition_c 85 { 86 public: 87 virtual_edition_c( chapter_edition_c * p_edition, matroska_segment_c & main_segment, std::vector<matroska_segment_c*> & opened_segments ); 88 ~virtual_edition_c(); 89 std::vector<virtual_chapter_c*> vchapters; 90 91 virtual_chapter_c* getChapterbyTimecode( int64_t time ); 92 std::string GetMainName(); 93 int PublishChapters( input_title_t & title, int & i_user_chapters, int i_level ); 94 virtual_chapter_c * BrowseCodecPrivate( unsigned int codec_id, 95 bool (*match)( const chapter_codec_cmds_c &data, 96 const void *p_cookie, 97 size_t i_cookie_size ), 98 const void *p_cookie, size_t i_cookie_size ); 99 100 bool b_ordered; 101 mtime_t i_duration; 102 chapter_edition_c *p_edition; 103 int i_seekpoint_num; 104 105 private: 106 void retimeChapters(); 107 void retimeSubChapters( virtual_chapter_c * p_vchap ); 108 #ifdef MKV_DEBUG print()109 void print(){ for( size_t i = 0; i<chapters.size(); i++ ) chapters[i]->print(); } 110 #endif 111 112 }; 113 114 // class holding hard-linked segment together in the playback order 115 class virtual_segment_c 116 { 117 public: 118 virtual_segment_c( matroska_segment_c & segment, std::vector<matroska_segment_c*> & opened_segments ); 119 ~virtual_segment_c(); 120 std::vector<virtual_edition_c*> veditions; 121 std::vector<virtual_edition_c*>::size_type i_current_edition; 122 virtual_chapter_c *p_current_vchapter; 123 bool b_current_vchapter_entered; 124 int i_sys_title; 125 126 CurrentEdition()127 inline virtual_edition_c * CurrentEdition() 128 { 129 if( i_current_edition < veditions.size() ) 130 return veditions[i_current_edition]; 131 return NULL; 132 } 133 CurrentChapter() const134 virtual_chapter_c * CurrentChapter() const 135 { 136 return p_current_vchapter; 137 } 138 CurrentSegment() const139 matroska_segment_c * CurrentSegment() const 140 { 141 if ( !p_current_vchapter ) 142 return NULL; 143 return &p_current_vchapter->segment; 144 } 145 Duration()146 inline int64_t Duration() 147 { 148 return veditions[i_current_edition]->i_duration / 1000; 149 } 150 Editions()151 inline std::vector<virtual_edition_c*>* Editions() { return &veditions; } 152 153 virtual_chapter_c *BrowseCodecPrivate( unsigned int codec_id, 154 bool (*match)( const chapter_codec_cmds_c &data, 155 const void *p_cookie, 156 size_t i_cookie_size ), 157 const void *p_cookie, 158 size_t i_cookie_size ); 159 160 virtual_chapter_c * FindChapter( int64_t i_find_uid ); 161 162 bool UpdateCurrentToChapter( demux_t & demux ); 163 bool Seek( demux_t & demuxer, mtime_t i_mk_date, virtual_chapter_c *p_vchapter, bool b_precise = true ); 164 private: 165 void KeepTrackSelection( matroska_segment_c & old, matroska_segment_c & next ); 166 }; 167 168 #endif 169