]> git.sesse.net Git - vlc/blob - modules/demux/mkv/chapters.cpp
MKV: remove trailing spaces
[vlc] / modules / demux / mkv / chapters.cpp
1 /*****************************************************************************
2  * chapters.cpp : matroska demuxer
3  *****************************************************************************
4  * Copyright (C) 2003-2004 VLC authors and VideoLAN
5  * $Id$
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *          Steve Lhomme <steve.lhomme@free.fr>
9  *
10  * This program is free software; you can redistribute it and/or modify it
11  * under the terms of the GNU Lesser General Public License as published by
12  * the Free Software Foundation; either version 2.1 of the License, or
13  * (at your option) any later version.
14  *
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 Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this program; if not, write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 #include "chapters.hpp"
26
27 #include "chapter_command.hpp"
28
29 chapter_item_c::~chapter_item_c()
30 {
31     if( p_segment_uid )
32         delete p_segment_uid;
33     if( p_segment_edition_uid )
34         delete p_segment_edition_uid;
35     vlc_delete_all( codecs );
36     vlc_delete_all( sub_chapters );
37 }
38
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 ),
41                                     const void *p_cookie,
42                                     size_t i_cookie_size )
43 {
44     VLC_UNUSED( codec_id );
45     // this chapter
46     std::vector<chapter_codec_cmds_c*>::const_iterator index = codecs.begin();
47     while ( index != codecs.end() )
48     {
49         if ( match( **index ,p_cookie, i_cookie_size ) )
50             return this;
51         ++index;
52     }
53     return NULL;
54 }
55
56 void chapter_item_c::Append( const chapter_item_c & chapter )
57 {
58     // we are appending content for the same chapter UID
59     size_t i;
60     chapter_item_c *p_chapter;
61
62     for ( i=0; i<chapter.sub_chapters.size(); i++ )
63     {
64         p_chapter = FindChapter( chapter.sub_chapters[i]->i_uid );
65         if ( p_chapter != NULL )
66         {
67             p_chapter->Append( *chapter.sub_chapters[i] );
68         }
69         else
70         {
71             sub_chapters.push_back( chapter.sub_chapters[i] );
72         }
73     }
74 }
75
76 chapter_item_c * chapter_item_c::FindChapter( int64_t i_find_uid )
77 {
78     size_t i;
79     chapter_item_c *p_result = NULL;
80
81     if ( i_uid == i_find_uid )
82         return this;
83
84     for ( i=0; i<sub_chapters.size(); i++)
85     {
86         p_result = sub_chapters[i]->FindChapter( i_find_uid );
87         if ( p_result != NULL )
88             break;
89     }
90     return p_result;
91 }
92
93 std::string chapter_item_c::GetCodecName( bool f_for_title ) const
94 {
95     std::string result;
96
97     std::vector<chapter_codec_cmds_c*>::const_iterator index = codecs.begin();
98     while ( index != codecs.end() )
99     {
100         result = (*index)->GetCodecName( f_for_title );
101         if ( result != "" )
102             break;
103         ++index;
104     }
105
106     return result;
107 }
108
109 int16 chapter_item_c::GetTitleNumber( ) const
110 {
111     int result = -1;
112
113     std::vector<chapter_codec_cmds_c*>::const_iterator index = codecs.begin();
114     while ( index != codecs.end() )
115     {
116         result = (*index)->GetTitleNumber( );
117         if ( result >= 0 )
118             break;
119         ++index;
120     }
121
122     return result;
123 }
124
125 bool chapter_item_c::ParentOf( const chapter_item_c & item ) const
126 {
127     if ( &item == this )
128         return true;
129
130     std::vector<chapter_item_c*>::const_iterator index = sub_chapters.begin();
131     while ( index != sub_chapters.end() )
132     {
133         if ( (*index)->ParentOf( item ) )
134             return true;
135         ++index;
136     }
137
138     return false;
139 }
140
141 bool chapter_item_c::Enter( bool b_do_subs )
142 {
143     bool f_result = false;
144     std::vector<chapter_codec_cmds_c*>::iterator index = codecs.begin();
145     while ( index != codecs.end() )
146     {
147         f_result |= (*index)->Enter();
148         ++index;
149     }
150
151     if ( b_do_subs )
152     {
153         // sub chapters
154         std::vector<chapter_item_c*>::iterator index_ = sub_chapters.begin();
155         while ( index_ != sub_chapters.end() )
156         {
157             f_result |= (*index_)->Enter( true );
158             ++index_;
159         }
160     }
161     return f_result;
162 }
163
164 bool chapter_item_c::Leave( bool b_do_subs )
165 {
166     bool f_result = false;
167     b_is_leaving = true;
168     std::vector<chapter_codec_cmds_c*>::iterator index = codecs.begin();
169     while ( index != codecs.end() )
170     {
171         f_result |= (*index)->Leave();
172         ++index;
173     }
174
175     if ( b_do_subs )
176     {
177         // sub chapters
178         std::vector<chapter_item_c*>::iterator index_ = sub_chapters.begin();
179         while ( index_ != sub_chapters.end() )
180         {
181             f_result |= (*index_)->Leave( true );
182             ++index_;
183         }
184     }
185     b_is_leaving = false;
186     return f_result;
187 }
188
189 bool chapter_item_c::EnterAndLeave( chapter_item_c *p_item, bool b_final_enter )
190 {
191     chapter_item_c *p_common_parent = p_item;
192
193     // leave, up to a common parent
194     while ( p_common_parent != NULL && !p_common_parent->ParentOf( *this ) )
195     {
196         if ( !p_common_parent->b_is_leaving && p_common_parent->Leave( false ) )
197             return true;
198         p_common_parent = p_common_parent->p_parent;
199     }
200
201     // enter from the parent to <this>
202     if ( p_common_parent != NULL )
203     {
204         do
205         {
206             if ( p_common_parent == this )
207                 return Enter( true );
208
209             for ( size_t i = 0; i<p_common_parent->sub_chapters.size(); i++ )
210             {
211                 if ( p_common_parent->sub_chapters[i]->ParentOf( *this ) )
212                 {
213                     p_common_parent = p_common_parent->sub_chapters[i];
214                     if ( p_common_parent != this )
215                         if ( p_common_parent->Enter( false ) )
216                             return true;
217
218                     break;
219                 }
220             }
221         } while ( 1 );
222     }
223
224     if ( b_final_enter )
225         return Enter( true );
226     else
227         return false;
228 }
229
230
231
232 /* Chapter Edition Class */
233 std::string chapter_edition_c::GetMainName() const
234 {
235     if ( sub_chapters.size() )
236     {
237         return sub_chapters[0]->GetCodecName( true );
238     }
239     return "";
240 }
241