1 /*****************************************************************************
2 * chapters.cpp : matroska demuxer
3 *****************************************************************************
4 * Copyright (C) 2003-2004 the VideoLAN team
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8 * Steve Lhomme <steve.lhomme@free.fr>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 #include "chapters.hpp"
27 #include "chapter_command.hpp"
29 chapter_item_c::~chapter_item_c()
33 if( p_segment_edition_uid )
34 delete p_segment_edition_uid;
35 vlc_delete_all( codecs );
36 vlc_delete_all( sub_chapters );
39 chapter_item_c *chapter_item_c::BrowseCodecPrivate( unsigned int codec_id,
40 bool (*match)(const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size ),
42 size_t i_cookie_size )
44 VLC_UNUSED( codec_id );
46 std::vector<chapter_codec_cmds_c*>::const_iterator index = codecs.begin();
47 while ( index != codecs.end() )
49 if ( match( **index ,p_cookie, i_cookie_size ) )
56 void chapter_item_c::Append( const chapter_item_c & chapter )
58 // we are appending content for the same chapter UID
60 chapter_item_c *p_chapter;
62 for ( i=0; i<chapter.sub_chapters.size(); i++ )
64 p_chapter = FindChapter( chapter.sub_chapters[i]->i_uid );
65 if ( p_chapter != NULL )
67 p_chapter->Append( *chapter.sub_chapters[i] );
71 sub_chapters.push_back( chapter.sub_chapters[i] );
76 chapter_item_c * chapter_item_c::FindChapter( int64_t i_find_uid )
79 chapter_item_c *p_result = NULL;
81 if ( i_uid == i_find_uid )
84 for ( i=0; i<sub_chapters.size(); i++)
86 p_result = sub_chapters[i]->FindChapter( i_find_uid );
87 if ( p_result != NULL )
93 std::string chapter_item_c::GetCodecName( bool f_for_title ) const
97 std::vector<chapter_codec_cmds_c*>::const_iterator index = codecs.begin();
98 while ( index != codecs.end() )
100 result = (*index)->GetCodecName( f_for_title );
109 int16 chapter_item_c::GetTitleNumber( ) const
113 std::vector<chapter_codec_cmds_c*>::const_iterator index = codecs.begin();
114 while ( index != codecs.end() )
116 result = (*index)->GetTitleNumber( );
125 bool chapter_item_c::ParentOf( const chapter_item_c & item ) const
130 std::vector<chapter_item_c*>::const_iterator index = sub_chapters.begin();
131 while ( index != sub_chapters.end() )
133 if ( (*index)->ParentOf( item ) )
141 bool chapter_item_c::Enter( bool b_do_subs )
143 bool f_result = false;
144 std::vector<chapter_codec_cmds_c*>::iterator index = codecs.begin();
145 while ( index != codecs.end() )
147 f_result |= (*index)->Enter();
154 std::vector<chapter_item_c*>::iterator index_ = sub_chapters.begin();
155 while ( index_ != sub_chapters.end() )
157 f_result |= (*index_)->Enter( true );
164 bool chapter_item_c::Leave( bool b_do_subs )
166 bool f_result = false;
168 std::vector<chapter_codec_cmds_c*>::iterator index = codecs.begin();
169 while ( index != codecs.end() )
171 f_result |= (*index)->Leave();
178 std::vector<chapter_item_c*>::iterator index_ = sub_chapters.begin();
179 while ( index_ != sub_chapters.end() )
181 f_result |= (*index_)->Leave( true );
185 b_is_leaving = false;
189 bool chapter_item_c::EnterAndLeave( chapter_item_c *p_item, bool b_final_enter )
191 chapter_item_c *p_common_parent = p_item;
193 // leave, up to a common parent
194 while ( p_common_parent != NULL && !p_common_parent->ParentOf( *this ) )
196 if ( !p_common_parent->b_is_leaving && p_common_parent->Leave( false ) )
198 p_common_parent = p_common_parent->p_parent;
201 // enter from the parent to <this>
202 if ( p_common_parent != NULL )
206 if ( p_common_parent == this )
207 return Enter( true );
209 for ( size_t i = 0; i<p_common_parent->sub_chapters.size(); i++ )
211 if ( p_common_parent->sub_chapters[i]->ParentOf( *this ) )
213 p_common_parent = p_common_parent->sub_chapters[i];
214 if ( p_common_parent != this )
215 if ( p_common_parent->Enter( false ) )
225 return Enter( true );
232 /* Chapter Edition Class */
233 std::string chapter_edition_c::GetMainName() const
235 if ( sub_chapters.size() )
237 return sub_chapters[0]->GetCodecName( true );