]> git.sesse.net Git - vlc/blob - modules/demux/mkv/virtual_segment.cpp
MKV: Use the appropriate time value to avoid loops
[vlc] / modules / demux / mkv / virtual_segment.cpp
1 /*****************************************************************************
2  * virtual_segment.cpp : virtual segment implementation in the MKV demuxer
3  *****************************************************************************
4  * Copyright © 2003-2011 VideoLAN and VLC authors
5  * $Id$
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
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 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 General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24  *****************************************************************************/
25 #include <vector>
26
27 #include "demux.hpp"
28
29 /* FIXME move this */
30 matroska_segment_c * getSegmentbyUID( KaxSegmentUID * p_uid, std::vector<matroska_segment_c*> *segments )
31 {
32     for( size_t i = 0; i < (*segments).size(); i++ )
33     {
34         if( *p_uid == *((*segments)[i]->p_segment_uid) )
35             return (*segments)[i];
36     }
37     return NULL;
38 }
39
40 virtual_chapter_c * virtual_chapter_c::CreateVirtualChapter( chapter_item_c * p_chap,
41                                                              matroska_segment_c * p_main_segment,
42                                                              std::vector<matroska_segment_c*> * segments,
43                                                              int64_t * usertime_offset, bool b_ordered)
44 {
45     matroska_segment_c * p_segment = p_main_segment;
46
47     if( !p_chap )
48     {
49         /* Dummy chapter use the whole segment */
50         return new virtual_chapter_c( p_segment, NULL, 0, p_segment->i_duration*1000 );
51     }
52
53     int64_t start = ( b_ordered )? *usertime_offset : p_chap->i_start_time;
54     int64_t stop = ( b_ordered )? ( *usertime_offset + p_chap->i_end_time - p_chap->i_start_time ) : p_chap->i_end_time;
55
56     if( p_chap->p_segment_uid && 
57        ( !( p_segment = getSegmentbyUID( (KaxSegmentUID*) p_chap->p_segment_uid,segments ) ) || !b_ordered ) )
58     {
59         msg_Warn( &p_main_segment->sys.demuxer,
60                   "Couldn't find segment 0x%x or not ordered... - ignoring chapter %s",
61                   *( (uint32_t *) p_chap->p_segment_uid->GetBuffer() ),p_chap->psz_name.c_str() );
62         return NULL;
63     }
64
65     /* Preload segment */
66     if ( !p_segment->b_preloaded )
67         p_segment->Preload();
68
69     virtual_chapter_c * p_vchap = new virtual_chapter_c( p_segment, p_chap, start, stop );
70
71     if( !p_vchap )
72         return NULL;
73
74     int64_t tmp = *usertime_offset;
75
76     for( size_t i = 0; i < p_chap->sub_chapters.size(); i++ )
77     {
78         virtual_chapter_c * p_vsubchap = CreateVirtualChapter( p_chap->sub_chapters[i], p_segment, segments, &tmp, b_ordered );
79
80         if( p_vsubchap )
81             p_vchap->sub_chapters.push_back( p_vsubchap );
82     }
83
84     if( tmp == *usertime_offset )
85         *usertime_offset += p_chap->i_end_time - p_chap->i_start_time;
86     else
87         *usertime_offset = tmp;
88
89     msg_Dbg( &p_main_segment->sys.demuxer,
90              "Virtual chapter %s from %"PRId64" to %"PRId64" - " ,
91              p_chap->psz_name.c_str(), p_vchap->i_virtual_start_time, p_vchap->i_virtual_stop_time );
92
93     return p_vchap;
94 }
95
96 virtual_chapter_c::~virtual_chapter_c()
97 {
98     for( size_t i = 0 ; i < sub_chapters.size(); i++ )
99         delete sub_chapters[i];
100 }
101
102
103 virtual_edition_c::virtual_edition_c( chapter_edition_c * p_edit, std::vector<matroska_segment_c*> *opened_segments)
104 {
105     bool b_fake_ordered = false;
106     matroska_segment_c *p_main_segment = (*opened_segments)[0];
107     p_edition = p_edit;
108     b_ordered = false;
109
110     int64_t usertime_offset = 0;
111
112     /* ordered chapters */
113     if( p_edition && p_edition->b_ordered )
114     {
115         b_ordered = true;
116         for( size_t i = 0; i < p_edition->sub_chapters.size(); i++ )
117         {
118             virtual_chapter_c * p_vchap = virtual_chapter_c::CreateVirtualChapter( p_edition->sub_chapters[i],
119                                                                                    p_main_segment, opened_segments,
120                                                                                    &usertime_offset, b_ordered );
121             if( p_vchap )
122                 chapters.push_back( p_vchap );
123         }
124         i_duration = chapters[ chapters.size() - 1 ]->i_virtual_stop_time;
125     }
126     else /* Not ordered or no edition at all */
127     {
128         matroska_segment_c * p_cur = p_main_segment;
129         virtual_chapter_c * p_vchap = NULL;
130         int64_t tmp = 0;
131
132         /* check for prev linked segments */
133         /* FIXME to avoid infinite recursion we limit to 10 prev should be better as parameter */
134         for( int limit = 0; limit < 10 && p_cur->p_prev_segment_uid ; limit++ )
135         {
136             matroska_segment_c * p_prev = NULL;
137             if( ( p_prev = getSegmentbyUID( p_cur->p_prev_segment_uid, opened_segments ) ) )
138             {
139                 tmp = 0;
140                 msg_Dbg( &p_main_segment->sys.demuxer, "Prev segment 0x%x found\n",
141                          *(int32_t*)p_cur->p_prev_segment_uid->GetBuffer() );
142
143                 /* Preload segment */
144                 if ( !p_prev->b_preloaded )
145                     p_prev->Preload();
146
147                 /* Create virtual_chapter from the first edition if any */
148                 chapter_item_c * p_chap = ( p_prev->stored_editions.size() > 0 )? ((chapter_item_c *)p_prev->stored_editions[0]) : NULL;
149
150                 p_vchap = virtual_chapter_c::CreateVirtualChapter( p_chap, p_prev, opened_segments, &tmp, b_ordered );
151
152                 if( p_vchap )
153                     chapters.insert( chapters.begin(), p_vchap );
154
155                 p_cur = p_prev;
156                 b_fake_ordered = true;
157             }
158             else /* segment not found */
159                 break;
160         }
161
162         tmp = 0;
163
164         /* Append the main segment */
165         p_vchap = virtual_chapter_c::CreateVirtualChapter( (chapter_item_c*) p_edit, p_main_segment,
166                                                            opened_segments, &tmp, b_ordered );
167         if( p_vchap )
168             chapters.push_back( p_vchap );
169
170         /* Append next linked segments */
171         for( int limit = 0; limit < 10 && p_cur->p_next_segment_uid; limit++ )
172         {
173             matroska_segment_c * p_next = NULL;
174             if( ( p_next = getSegmentbyUID( p_cur->p_next_segment_uid, opened_segments ) ) )
175             {
176                 tmp = 0;
177                 msg_Dbg( &p_main_segment->sys.demuxer, "Next segment 0x%x found\n",
178                          *(int32_t*) p_cur->p_next_segment_uid->GetBuffer() );
179
180                 /* Preload segment */
181                 if ( !p_next->b_preloaded )
182                     p_next->Preload();
183
184                 /* Create virtual_chapter from the first edition if any */
185                 chapter_item_c * p_chap = ( p_next->stored_editions.size() > 0 )?( (chapter_item_c *)p_next->stored_editions[0] ) : NULL;
186
187                  p_vchap = virtual_chapter_c::CreateVirtualChapter( p_chap, p_next, opened_segments, &tmp, b_ordered );
188
189                 if( p_vchap )
190                     chapters.push_back( p_vchap );
191
192
193                 p_cur = p_next;
194                 b_fake_ordered = true;
195             }
196             else /* segment not found */
197                 break;
198         }
199
200         /* Retime chapters */
201         retimeChapters();
202         if(b_fake_ordered)
203             b_ordered = true;
204     }
205
206 #if MKV_DEBUG
207     msg_Dbg( &p_main_segment->sys.demuxer, "-- RECAP-BEGIN --" );
208     print();
209     msg_Dbg( &p_main_segment->sys.demuxer, "-- RECAP-END --" );
210 #endif
211 }
212
213 virtual_edition_c::~virtual_edition_c()
214 {
215     for( size_t i = 0; i < chapters.size(); i++ )
216         delete chapters[i];
217 }
218
219 void virtual_edition_c::retimeSubChapters( virtual_chapter_c * p_vchap )
220 {
221     int64_t stop_time = p_vchap->i_virtual_stop_time;
222     for( size_t i = p_vchap->sub_chapters.size(); i-- > 0; )
223     {
224         virtual_chapter_c * p_vsubchap = p_vchap->sub_chapters[i];
225         p_vsubchap->i_virtual_start_time += p_vchap->i_virtual_start_time;
226
227         /*FIXME we artificially extend stop time if they were there before...*/
228         /* Just for comfort*/
229         p_vsubchap->i_virtual_stop_time = stop_time;
230         stop_time = p_vsubchap->i_virtual_start_time;
231
232         retimeSubChapters( p_vsubchap );
233     }
234 }
235
236 void virtual_edition_c::retimeChapters()
237 {
238     /* This function is just meant to be used on unordered chapters */
239     if( b_ordered )
240         return;
241
242     i_duration = 0;
243
244     /* On non ordered editions we have one top chapter == one segment */
245     for( size_t i = 0; i < chapters.size(); i++ )
246     {
247         virtual_chapter_c * p_vchap = chapters[i];
248
249         p_vchap->i_virtual_start_time = i_duration;
250         i_duration += p_vchap->p_segment->i_duration * 1000;
251         p_vchap->i_virtual_stop_time = i_duration;
252
253         retimeSubChapters( p_vchap );
254     }
255 }
256
257 virtual_segment_c::virtual_segment_c( std::vector<matroska_segment_c*> * p_opened_segments )
258 {
259     /* Main segment */
260     matroska_segment_c *p_segment = (*p_opened_segments)[0];
261     i_current_edition = 0;
262     i_sys_title = 0;
263     p_current_chapter = NULL;
264
265     for( size_t i = 0; i < p_segment->stored_editions.size(); i++ )
266     {
267         /* Get the default edition, if non use the first one */
268         if( p_segment->stored_editions[i]->b_default )
269             i_current_edition = i;
270
271         /* Create a virtual edition from opened */
272         virtual_edition_c * p_vedition = new virtual_edition_c( p_segment->stored_editions[i], p_opened_segments );
273
274         /*FIXME if p_vedition failed...*/
275
276         editions.push_back( p_vedition );
277     }
278     /*if we don't have edition create a dummy one*/
279     if( !p_segment->stored_editions.size() )
280     {
281         virtual_edition_c * p_vedition = new virtual_edition_c( NULL, p_opened_segments );
282         editions.push_back( p_vedition );
283     }
284
285     /* Set current chapter */
286     p_current_chapter = editions[i_current_edition]->getChapterbyTimecode(0);
287
288 }
289
290 virtual_segment_c::~virtual_segment_c()
291 {
292     for( size_t i = 0; i < editions.size(); i++ )
293         delete editions[i];
294 }
295
296 virtual_chapter_c *virtual_segment_c::BrowseCodecPrivate( unsigned int codec_id,
297                                     bool (*match)(const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size ),
298                                     const void *p_cookie,
299                                     size_t i_cookie_size )
300 {
301     virtual_edition_c * p_ved = CurrentEdition();
302     if( p_ved )
303         return p_ved->BrowseCodecPrivate( codec_id, match, p_cookie, i_cookie_size );
304
305     return NULL;
306 }
307
308
309 virtual_chapter_c * virtual_edition_c::BrowseCodecPrivate( unsigned int codec_id,
310                                     bool (*match)(const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size ),
311                                     const void *p_cookie,
312                                     size_t i_cookie_size )
313 {
314     if( !p_edition )
315         return NULL;
316
317     for( size_t i = 0; i < chapters.size(); i++ )
318     {
319         virtual_chapter_c * p_result = chapters[i]->BrowseCodecPrivate( codec_id, match, p_cookie, i_cookie_size );
320         if( p_result )
321             return p_result;
322     }
323     return NULL;
324 }
325
326
327
328 virtual_chapter_c * virtual_chapter_c::BrowseCodecPrivate( unsigned int codec_id,
329                                     bool (*match)(const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size ),
330                                     const void *p_cookie,
331                                     size_t i_cookie_size )
332 {
333     if( !p_chapter )
334         return NULL;
335
336     if( p_chapter->BrowseCodecPrivate( codec_id, match, p_cookie, i_cookie_size ) )
337         return this;
338
339     for( size_t i = 0; i < sub_chapters.size(); i++ )
340     {
341         virtual_chapter_c * p_result = sub_chapters[i]->BrowseCodecPrivate( codec_id, match, p_cookie, i_cookie_size );
342         if( p_result )
343             return p_result;
344     }
345     return NULL;
346 }
347
348 virtual_chapter_c* virtual_chapter_c::getSubChapterbyTimecode( int64_t time )
349 {
350     for( size_t i = 0; i < sub_chapters.size(); i++ )
351     {
352         if( time >= sub_chapters[i]->i_virtual_start_time && time < sub_chapters[i]->i_virtual_stop_time )
353             return sub_chapters[i]->getSubChapterbyTimecode( time );
354     }
355
356     return this;
357 }
358
359 virtual_chapter_c* virtual_edition_c::getChapterbyTimecode( int64_t time )
360 {
361     for( size_t i = 0; i < chapters.size(); i++ )
362     {
363         if( time >= chapters[i]->i_virtual_start_time &&
364             ( chapters[i]->i_virtual_stop_time < 0 || time < chapters[i]->i_virtual_stop_time ) )
365             /*with the current implementation only the last chapter can have a negative virtual_stop_time*/
366             return chapters[i]->getSubChapterbyTimecode( time );
367     }
368
369     return NULL;
370 }
371
372 bool virtual_segment_c::UpdateCurrentToChapter( demux_t & demux )
373 {
374     demux_sys_t & sys = *demux.p_sys;
375     virtual_chapter_c *p_cur_chapter;
376     virtual_edition_c * p_cur_edition = editions[ i_current_edition ];
377
378     bool b_has_seeked = false;
379
380     p_cur_chapter = p_cur_edition->getChapterbyTimecode( sys.i_pts );
381
382     /* we have moved to a new chapter */
383     if ( p_cur_chapter != NULL && p_current_chapter != p_cur_chapter )
384         {
385             msg_Dbg( &demux, "NEW CHAPTER %"PRId64, sys.i_pts );
386             if ( p_cur_edition->b_ordered )
387             {
388                 /* FIXME EnterAndLeave has probably been broken for a long time */
389                 // Leave/Enter up to the link point
390                 b_has_seeked = p_cur_chapter->EnterAndLeave( p_current_chapter );
391                 if ( !b_has_seeked )
392                 {
393                     // only physically seek if necessary
394                     if ( p_current_chapter == NULL ||
395                         ( p_current_chapter && p_current_chapter->p_segment != p_cur_chapter->p_segment ) ||
396                         ( p_current_chapter->p_chapter->i_end_time != p_cur_chapter->p_chapter->i_start_time ))
397                     {
398                         Seek( demux, p_cur_chapter->i_virtual_start_time, 0, p_cur_chapter, -1 );
399                         return true;
400                     }
401                 }
402                 sys.i_start_pts = p_cur_chapter->i_virtual_start_time;;
403             }
404
405             p_current_chapter = p_cur_chapter;
406             if ( p_cur_chapter->i_seekpoint_num > 0 )
407             {
408                 demux.info.i_update |= INPUT_UPDATE_TITLE | INPUT_UPDATE_SEEKPOINT;
409                 demux.info.i_title = sys.i_current_title = i_sys_title;
410                 demux.info.i_seekpoint = p_cur_chapter->i_seekpoint_num - 1;
411             }
412
413             return b_has_seeked;
414         }
415         else if ( p_cur_chapter == NULL )
416         {
417             /* out of the scope of the data described by chapters, leave the edition */
418             if ( p_cur_edition->b_ordered && p_current_chapter != NULL )
419             {
420                 /* TODO */
421                 if ( !p_cur_edition->p_edition->EnterAndLeave( p_current_chapter->p_chapter, false ) )
422                     p_current_chapter = NULL;
423                 else
424                     return true;
425             }
426         }
427     return false;
428 }
429
430 bool virtual_chapter_c::EnterAndLeave( virtual_chapter_c *p_item, bool b_enter )
431 {
432     if( !p_chapter )
433         return false;
434
435     return p_chapter->EnterAndLeave( p_item->p_chapter, b_enter );
436 }
437
438 void virtual_segment_c::Seek( demux_t & demuxer, mtime_t i_date, mtime_t i_time_offset, 
439                               virtual_chapter_c *p_chapter, int64_t i_global_position )
440 {
441     demux_sys_t *p_sys = demuxer.p_sys;
442
443
444     /* find the actual time for an ordered edition */
445     if ( p_chapter == NULL )
446         /* 1st, we need to know in which chapter we are */
447         p_chapter = editions[ i_current_edition ]->getChapterbyTimecode( i_date );
448
449     if ( p_chapter != NULL )
450     {
451         i_time_offset = p_chapter->i_virtual_start_time - ( ( p_chapter->p_chapter )? p_chapter->p_chapter->i_start_time : 0 );
452         p_sys->i_chapter_time = i_time_offset - p_chapter->p_segment->i_start_time;
453         if ( p_chapter->p_chapter && p_chapter->i_seekpoint_num > 0 )
454         {
455             demuxer.info.i_update |= INPUT_UPDATE_TITLE | INPUT_UPDATE_SEEKPOINT;
456             demuxer.info.i_title = p_sys->i_current_title = i_sys_title;
457             demuxer.info.i_seekpoint = p_chapter->i_seekpoint_num - 1;
458         }
459
460         if( p_current_chapter->p_segment != p_chapter->p_segment )
461         {
462             p_chapter->p_segment->Select( i_date );
463             p_current_chapter->p_segment->UnSelect();
464         }
465         p_current_chapter = p_chapter;
466
467         p_chapter->p_segment->Seek( i_date, i_time_offset, i_global_position );
468     }
469 }
470
471 virtual_chapter_c * virtual_chapter_c::FindChapter( int64_t i_find_uid )
472 {
473     if( p_chapter && ( p_chapter->i_uid == i_find_uid ) )
474         return this;
475
476     for( size_t i = 0; i < sub_chapters.size(); i++ )
477     {
478         virtual_chapter_c * p_res = sub_chapters[i]->FindChapter( i_find_uid );
479         if( p_res )
480             return p_res;
481     }
482
483     return NULL;
484 }
485
486 virtual_chapter_c * virtual_segment_c::FindChapter( int64_t i_find_uid )
487 {
488     virtual_edition_c * p_edition = editions[i_current_edition];
489
490     for( size_t i = 0; p_edition->chapters.size(); i++ )
491     {
492         virtual_chapter_c * p_chapter = p_edition->chapters[i]->FindChapter( i_find_uid );
493         if( p_chapter )
494             return p_chapter;
495     }
496     return NULL;
497 }
498
499 int virtual_chapter_c::PublishChapters( input_title_t & title, int & i_user_chapters, int i_level )
500 {
501     if ( p_chapter && ( !p_chapter->b_display_seekpoint || p_chapter->psz_name == "" ) )
502     {
503         p_chapter->psz_name = p_chapter->GetCodecName();
504         if ( p_chapter->psz_name != "" )
505             p_chapter->b_display_seekpoint = true;
506     }
507
508     if ( ( p_chapter && p_chapter->b_display_seekpoint &&
509          ( ( sub_chapters.size() > 0 && i_virtual_start_time != sub_chapters[0]->i_virtual_start_time) ||
510            sub_chapters.size() == 0 ) ) || !p_chapter )
511     {
512         seekpoint_t *sk = vlc_seekpoint_New();
513
514         sk->i_time_offset = i_virtual_start_time;
515         if( p_chapter )
516             sk->psz_name = strdup( p_chapter->psz_name.c_str() );
517         else
518             sk->psz_name = strdup("dummy chapter");
519
520         /* A start time of '0' is ok. A missing ChapterTime element is ok, too, because '0' is its default value. */
521         title.i_seekpoint++;
522         title.seekpoint = (seekpoint_t**)xrealloc( title.seekpoint,
523                                  title.i_seekpoint * sizeof( seekpoint_t* ) );
524         title.seekpoint[title.i_seekpoint-1] = sk;
525
526         if ( (p_chapter && p_chapter->b_user_display ) ||  !p_chapter )
527             i_user_chapters++;
528     }
529     i_seekpoint_num = i_user_chapters;
530
531     for( size_t i = 0; i < sub_chapters.size(); i++ )
532         sub_chapters[i]->PublishChapters( title, i_user_chapters, i_level + 1 );
533
534     return i_user_chapters;
535 }
536
537
538 int virtual_edition_c::PublishChapters( input_title_t & title, int & i_user_chapters, int i_level )
539 {
540
541     /* HACK for now don't expose edition as a seekpoint if its start time is the same than it's first chapter */
542     if( chapters.size() > 0 &&
543         chapters[0]->i_virtual_start_time && p_edition )
544     {
545         seekpoint_t *sk = vlc_seekpoint_New();
546
547         sk->i_time_offset = 0;
548         sk->psz_name = strdup( p_edition->psz_name.c_str() );
549
550         title.i_seekpoint++;
551         title.seekpoint = (seekpoint_t**)xrealloc( title.seekpoint,
552                              title.i_seekpoint * sizeof( seekpoint_t* ) );
553         title.seekpoint[title.i_seekpoint - 1] = sk;
554         i_level++;
555
556         i_user_chapters++;
557         i_seekpoint_num = i_user_chapters;
558     }
559
560 //    if( chapters.size() > 1 )
561         for( size_t i = 0; i < chapters.size(); i++ )
562             chapters[i]->PublishChapters( title, i_user_chapters, i_level );
563
564     return i_user_chapters;
565 }
566
567 std::string virtual_edition_c::GetMainName()
568 {
569     if( p_edition )
570         return p_edition->GetMainName();
571
572     return std::string("");
573 }
574
575 bool virtual_chapter_c::Enter( bool b_do_subs )
576 {
577     if( p_chapter )
578         return p_chapter->Enter( b_do_subs );
579     return false;
580 }
581
582 bool virtual_chapter_c::Leave( bool b_do_subs )
583 {
584     if( p_chapter )
585         return p_chapter->Leave( b_do_subs );
586     return false;
587 }
588
589 #if MKV_DEBUG
590 void virtual_chapter_c::print() 
591 {
592     msg_Dbg( &p_segment->sys.demuxer, "*** chapter %"PRId64" - %"PRId64" (%u)",
593              i_virtual_start_time, i_virtual_stop_time, sub_chapters.size() );
594     for( size_t i = 0; i < sub_chapters.size(); i++ )
595         sub_chapters[i]->print();
596 }
597 #endif