1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
|
/*****************************************************************************
* virtual_segment.hpp : virtual segment implementation in the MKV demuxer
*****************************************************************************
* Copyright © 2003-2011 VideoLAN and VLC authors
* $Id: c901e44e8996b3e825fc24ab7f929126a7ac5b08 $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Steve Lhomme <steve.lhomme@free.fr>
* Denis Charmet <typx@dinauz.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef _VIRTUAL_SEGMENT_HPP_
#define _VIRTUAL_SEGMENT_HPP_
#include "mkv.hpp"
#include "matroska_segment.hpp"
#include "chapters.hpp"
/* virtual classes don't own anything but virtual elements so they shouldn't have to delete anything */
class virtual_chapter_c
{
public:
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 )
{
return ( itemA->i_virtual_start_time < itemB->i_virtual_start_time );
}
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
};
// 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;
inline virtual_edition_c * CurrentEdition()
{
if( i_current_edition >= 0 && (size_t) i_current_edition < editions.size() )
return editions[i_current_edition];
return NULL;
}
virtual_chapter_c * CurrentChapter() const
{
return p_current_chapter;
}
matroska_segment_c * CurrentSegment() const
{
if ( !p_current_chapter )
return NULL;
return p_current_chapter->p_segment;
}
inline int64_t Duration()
{
return editions[i_current_edition]->i_duration / 1000;
}
inline std::vector<virtual_edition_c*>* Editions() { return &editions; }
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 );
virtual_chapter_c * FindChapter( int64_t i_find_uid );
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 );
private:
void ChangeSegment( matroska_segment_c * p_old, matroska_segment_c * p_new, mtime_t i_start_time );
};
#endif
|