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