1 /*****************************************************************************
2 * mkv.cpp : matroska demuxer
3 *****************************************************************************
4 * Copyright (C) 2003-2005, 2008, 2010 VLC authors and VideoLAN
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 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.
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.
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 *****************************************************************************/
28 #include "matroska_segment.hpp"
31 #include "chapters.hpp"
32 #include "Ebml_parser.hpp"
34 #include "stream_io_callback.hpp"
41 /*****************************************************************************
43 *****************************************************************************/
44 static int Open ( vlc_object_t
* );
45 static void Close( vlc_object_t
* );
48 set_shortname( "Matroska" )
49 set_description( N_("Matroska stream demuxer" ) )
50 set_capability( "demux", 50 )
51 set_callbacks( Open
, Close
)
52 set_category( CAT_INPUT
)
53 set_subcategory( SUBCAT_INPUT_DEMUX
)
55 add_bool( "mkv-use-ordered-chapters", true,
56 N_("Respect ordered chapters"),
57 N_("Play chapters in the order specified in the segment."), false );
59 add_bool( "mkv-use-chapter-codec", true,
61 N_("Use chapter codecs found in the segment."), true );
63 add_bool( "mkv-preload-local-dir", true,
64 N_("Preload MKV files in the same directory"),
65 N_("Preload matroska files in the same directory to find linked segments (not good for broken files)."), false );
67 add_bool( "mkv-seek-percent", false,
68 N_("Seek based on percent not time"),
69 N_("Seek based on percent not time."), true );
71 add_bool( "mkv-use-dummy", false,
73 N_("Read and discard unknown EBML elements (not good for broken files)."), true );
75 add_bool( "mkv-preload-clusters", false,
76 N_("Preload clusters"),
77 N_("Find all cluster positions by jumping cluster-to-cluster before playback"), true );
79 add_shortcut( "mka", "mkv" )
84 static int Demux ( demux_t
* );
85 static int Control( demux_t
*, int, va_list );
86 static int Seek ( demux_t
*, mtime_t i_mk_date
, double f_percent
, virtual_chapter_c
*p_vchapter
, bool b_precise
= true );
88 /*****************************************************************************
89 * Open: initializes matroska demux structures
90 *****************************************************************************/
91 static int Open( vlc_object_t
* p_this
)
93 demux_t
*p_demux
= (demux_t
*)p_this
;
95 matroska_stream_c
*p_stream
;
96 matroska_segment_c
*p_segment
;
97 const uint8_t *p_peek
;
98 std::string s_path
, s_filename
;
99 vlc_stream_io_callback
*p_io_callback
;
100 EbmlStream
*p_io_stream
;
101 bool b_need_preload
= false;
103 /* peek the begining */
104 if( vlc_stream_Peek( p_demux
->s
, &p_peek
, 4 ) < 4 ) return VLC_EGENERIC
;
106 /* is a valid file */
107 if( p_peek
[0] != 0x1a || p_peek
[1] != 0x45 ||
108 p_peek
[2] != 0xdf || p_peek
[3] != 0xa3 ) return VLC_EGENERIC
;
110 /* Set the demux function */
111 p_demux
->pf_demux
= Demux
;
112 p_demux
->pf_control
= Control
;
113 p_demux
->p_sys
= p_sys
= new demux_sys_t( *p_demux
);
115 p_io_callback
= new vlc_stream_io_callback( p_demux
->s
, false );
116 p_io_stream
= new (std::nothrow
) EbmlStream( *p_io_callback
);
118 if( p_io_stream
== NULL
)
120 msg_Err( p_demux
, "failed to create EbmlStream" );
121 delete p_io_callback
;
126 p_stream
= p_sys
->AnalyseAllSegmentsFound( p_demux
, p_io_stream
, true );
127 if( p_stream
== NULL
)
129 msg_Err( p_demux
, "cannot find KaxSegment or missing mandatory KaxInfo" );
131 delete p_io_callback
;
134 p_sys
->streams
.push_back( p_stream
);
136 p_stream
->p_io_callback
= p_io_callback
;
137 p_stream
->p_estream
= p_io_stream
;
139 for (size_t i
=0; i
<p_stream
->segments
.size(); i
++)
141 p_stream
->segments
[i
]->Preload();
142 b_need_preload
|= p_stream
->segments
[i
]->b_ref_external_segments
;
143 if ( p_stream
->segments
[i
]->translations
.size() &&
144 p_stream
->segments
[i
]->translations
[0]->codec_id
== MATROSKA_CHAPTER_CODEC_DVD
&&
145 p_stream
->segments
[i
]->families
.size() )
146 b_need_preload
= true;
149 p_segment
= p_stream
->segments
[0];
150 if( p_segment
->cluster
== NULL
&& p_segment
->stored_editions
.size() == 0 )
152 msg_Err( p_demux
, "cannot find any cluster or chapter, damaged file ?" );
156 if (b_need_preload
&& var_InheritBool( p_demux
, "mkv-preload-local-dir" ))
158 msg_Dbg( p_demux
, "Preloading local dir" );
159 /* get the files from the same dir from the same family (based on p_demux->psz_path) */
160 if ( p_demux
->psz_filepath
&& !strncasecmp( p_demux
->psz_url
, "file:", 5 ) )
162 // assume it's a regular file
163 // get the directory path
164 s_path
= p_demux
->psz_filepath
;
165 if (s_path
.at(s_path
.length() - 1) == DIR_SEP_CHAR
)
167 s_path
= s_path
.substr(0,s_path
.length()-1);
171 if (s_path
.find_last_of(DIR_SEP_CHAR
) > 0)
173 s_path
= s_path
.substr(0,s_path
.find_last_of(DIR_SEP_CHAR
));
177 DIR *p_src_dir
= vlc_opendir(s_path
.c_str());
179 if (p_src_dir
!= NULL
)
181 const char *psz_file
;
182 while ((psz_file
= vlc_readdir(p_src_dir
)) != NULL
)
184 if (strlen(psz_file
) > 4)
186 s_filename
= s_path
+ DIR_SEP_CHAR
+ psz_file
;
188 #if defined(_WIN32) || defined(__OS2__)
189 if (!strcasecmp(s_filename
.c_str(), p_demux
->psz_filepath
))
191 if (!s_filename
.compare(p_demux
->psz_filepath
))
194 continue; // don't reuse the original opened file
197 if (!strcasecmp(s_filename
.c_str() + s_filename
.length() - 4, ".mkv") ||
198 !strcasecmp(s_filename
.c_str() + s_filename
.length() - 4, ".mka"))
200 // test whether this file belongs to our family
201 const uint8_t *p_peek
;
202 bool file_ok
= false;
203 char *psz_url
= vlc_path2uri( s_filename
.c_str(), "file" );
204 stream_t
*p_file_stream
= vlc_stream_NewURL(
207 /* peek the begining */
209 vlc_stream_Peek( p_file_stream
, &p_peek
, 4 ) >= 4
210 && p_peek
[0] == 0x1a && p_peek
[1] == 0x45 &&
211 p_peek
[2] == 0xdf && p_peek
[3] == 0xa3 ) file_ok
= true;
215 vlc_stream_io_callback
*p_file_io
= new vlc_stream_io_callback( p_file_stream
, true );
216 EbmlStream
*p_estream
= new EbmlStream(*p_file_io
);
218 p_stream
= p_sys
->AnalyseAllSegmentsFound( p_demux
, p_estream
);
220 if ( p_stream
== NULL
)
222 msg_Dbg( p_demux
, "the file '%s' will not be used", s_filename
.c_str() );
228 p_stream
->p_io_callback
= p_file_io
;
229 p_stream
->p_estream
= p_estream
;
230 p_sys
->streams
.push_back( p_stream
);
235 if( p_file_stream
) {
236 vlc_stream_Delete( p_file_stream
);
238 msg_Dbg( p_demux
, "the file '%s' cannot be opened", s_filename
.c_str() );
244 closedir( p_src_dir
);
248 p_sys
->PreloadFamily( *p_segment
);
250 else if (b_need_preload
)
251 msg_Warn( p_demux
, "This file references other files, you may want to enable the preload of local directory");
253 if ( !p_sys
->PreloadLinked() ||
254 !p_sys
->PreparePlayback( *p_sys
->p_current_vsegment
, 0 ) )
256 msg_Err( p_demux
, "cannot use the segment" );
271 /*****************************************************************************
272 * Close: frees unused data
273 *****************************************************************************/
274 static void Close( vlc_object_t
*p_this
)
276 demux_t
*p_demux
= reinterpret_cast<demux_t
*>( p_this
);
277 demux_sys_t
*p_sys
= p_demux
->p_sys
;
278 virtual_segment_c
*p_vsegment
= p_sys
->p_current_vsegment
;
281 matroska_segment_c
*p_segment
= p_vsegment
->CurrentSegment();
283 p_segment
->ESDestroy();
289 /*****************************************************************************
291 *****************************************************************************/
292 static int Control( demux_t
*p_demux
, int i_query
, va_list args
)
294 demux_sys_t
*p_sys
= p_demux
->p_sys
;
302 input_attachment_t
***ppp_attach
;
308 return vlc_stream_vaControl( p_demux
->s
, i_query
, args
);
310 case DEMUX_GET_ATTACHMENTS
:
311 ppp_attach
= va_arg( args
, input_attachment_t
*** );
312 pi_int
= va_arg( args
, int * );
314 if( p_sys
->stored_attachments
.size() <= 0 )
317 *pi_int
= p_sys
->stored_attachments
.size();
318 *ppp_attach
= static_cast<input_attachment_t
**>( vlc_alloc( p_sys
->stored_attachments
.size(),
319 sizeof(input_attachment_t
*) ) );
322 for( size_t i
= 0; i
< p_sys
->stored_attachments
.size(); i
++ )
324 attachment_c
*a
= p_sys
->stored_attachments
[i
];
325 (*ppp_attach
)[i
] = vlc_input_attachment_New( a
->fileName(), a
->mimeType(), NULL
,
326 a
->p_data
, a
->size() );
327 if( !(*ppp_attach
)[i
] )
336 p_meta
= va_arg( args
, vlc_meta_t
* );
337 vlc_meta_Merge( p_meta
, p_sys
->meta
);
340 case DEMUX_GET_LENGTH
:
341 pi64
= va_arg( args
, int64_t * );
342 if( p_sys
->f_duration
> 0.0 )
344 *pi64
= static_cast<int64_t>( p_sys
->f_duration
* 1000 );
349 case DEMUX_GET_POSITION
:
350 pf
= va_arg( args
, double * );
351 if ( p_sys
->f_duration
> 0.0 )
352 *pf
= static_cast<double> (p_sys
->i_pcr
>= p_sys
->i_start_pts
? p_sys
->i_pcr
: p_sys
->i_start_pts
) / (1000.0 * p_sys
->f_duration
);
355 case DEMUX_SET_POSITION
:
356 if( p_sys
->f_duration
> 0.0 )
358 f
= va_arg( args
, double );
359 b
= va_arg( args
, int ); /* precise? */
360 return Seek( p_demux
, -1, f
, NULL
, b
);
365 pi64
= va_arg( args
, int64_t * );
366 *pi64
= p_sys
->i_pcr
;
369 case DEMUX_GET_TITLE_INFO
:
370 if( p_sys
->titles
.size() > 1 || ( p_sys
->titles
.size() == 1 && p_sys
->titles
[0]->i_seekpoint
> 0 ) )
372 input_title_t
***ppp_title
= va_arg( args
, input_title_t
*** );
373 int *pi_int
= va_arg( args
, int* );
375 *pi_int
= p_sys
->titles
.size();
376 *ppp_title
= static_cast<input_title_t
**>( vlc_alloc( p_sys
->titles
.size(), sizeof( input_title_t
* ) ) );
378 for( size_t i
= 0; i
< p_sys
->titles
.size(); i
++ )
379 (*ppp_title
)[i
] = vlc_input_title_Duplicate( p_sys
->titles
[i
] );
384 case DEMUX_SET_TITLE
:
385 /* handle editions as titles */
386 i_idx
= va_arg( args
, int );
387 if(i_idx
< p_sys
->titles
.size() && p_sys
->titles
[i_idx
]->i_seekpoint
)
389 const int i_edition
= p_sys
->p_current_vsegment
->i_current_edition
;
390 const int i_title
= p_sys
->i_current_title
;
391 p_sys
->p_current_vsegment
->i_current_edition
= i_idx
;
392 p_sys
->i_current_title
= i_idx
;
394 Seek( p_demux
, static_cast<int64_t>( p_sys
->titles
[i_idx
]->seekpoint
[0]->i_time_offset
), -1, NULL
) )
396 p_demux
->info
.i_update
|= INPUT_UPDATE_SEEKPOINT
|INPUT_UPDATE_TITLE
;
397 p_sys
->i_current_seekpoint
= 0;
398 p_sys
->f_duration
= (float) p_sys
->titles
[i_idx
]->i_length
/ 1000.f
;
403 p_sys
->p_current_vsegment
->i_current_edition
= i_edition
;
404 p_sys
->i_current_title
= i_title
;
409 case DEMUX_SET_SEEKPOINT
:
410 i_skp
= va_arg( args
, int );
412 // TODO change the way it works with the << & >> buttons on the UI (+1/-1 instead of a number)
413 if( p_sys
->titles
.size() && i_skp
< p_sys
->titles
[p_sys
->i_current_title
]->i_seekpoint
)
415 int i_ret
= Seek( p_demux
, static_cast<int64_t>( p_sys
->titles
[p_sys
->i_current_title
]->seekpoint
[i_skp
]->i_time_offset
), -1, NULL
);
416 if( i_ret
== VLC_SUCCESS
)
418 p_demux
->info
.i_update
|= INPUT_UPDATE_SEEKPOINT
;
419 p_sys
->i_current_seekpoint
= i_skp
;
425 case DEMUX_GET_TITLE
:
426 *va_arg( args
, int * ) = p_sys
->i_current_title
;
429 case DEMUX_GET_SEEKPOINT
:
430 *va_arg( args
, int * ) = p_sys
->i_current_seekpoint
;
434 pf
= va_arg( args
, double * );
436 if( p_sys
->p_current_vsegment
&& p_sys
->p_current_vsegment
->CurrentSegment() )
438 typedef matroska_segment_c::tracks_map_t tracks_map_t
;
440 const matroska_segment_c
*p_segment
= p_sys
->p_current_vsegment
->CurrentSegment();
441 for( tracks_map_t::const_iterator it
= p_segment
->tracks
.begin(); it
!= p_segment
->tracks
.end(); ++it
)
443 const mkv_track_t
&track
= *it
->second
;
445 if( track
.fmt
.i_cat
== VIDEO_ES
&& track
.fmt
.video
.i_frame_rate_base
> 0 )
447 *pf
= (double)track
.fmt
.video
.i_frame_rate
/ track
.fmt
.video
.i_frame_rate_base
;
455 i64
= va_arg( args
, int64_t );
456 b
= va_arg( args
, int ); /* precise? */
457 msg_Dbg(p_demux
,"SET_TIME to %" PRId64
, i64
);
458 return Seek( p_demux
, i64
, -1, NULL
, b
);
465 static int Seek( demux_t
*p_demux
, mtime_t i_mk_date
, double f_percent
, virtual_chapter_c
*p_vchapter
, bool b_precise
)
467 demux_sys_t
*p_sys
= p_demux
->p_sys
;
468 virtual_segment_c
*p_vsegment
= p_sys
->p_current_vsegment
;
469 matroska_segment_c
*p_segment
= p_vsegment
->CurrentSegment();
471 if( f_percent
< 0 ) msg_Dbg( p_demux
, "seek request to i_pos = %" PRId64
, i_mk_date
);
472 else msg_Dbg( p_demux
, "seek request to %.2f%%", f_percent
* 100 );
474 if( i_mk_date
< 0 && f_percent
< 0 )
476 msg_Warn( p_demux
, "cannot seek nowhere!" );
479 if( f_percent
> 1.0 )
481 msg_Warn( p_demux
, "cannot seek so far!" );
484 if( p_sys
->f_duration
< 0 )
486 msg_Warn( p_demux
, "cannot seek without duration!");
491 msg_Warn( p_demux
, "cannot seek without valid segment position");
495 /* seek without index or without date */
496 if( f_percent
>= 0 && (var_InheritBool( p_demux
, "mkv-seek-percent" ) || i_mk_date
< 0 ))
498 i_mk_date
= int64_t( f_percent
* p_sys
->f_duration
* 1000.0 );
500 return p_vsegment
->Seek( *p_demux
, i_mk_date
, p_vchapter
, b_precise
) ? VLC_SUCCESS
: VLC_EGENERIC
;
503 /* Needed by matroska_segment::Seek() and Seek */
504 void BlockDecode( demux_t
*p_demux
, KaxBlock
*block
, KaxSimpleBlock
*simpleblock
,
505 mtime_t i_pts
, mtime_t i_duration
, bool b_key_picture
,
506 bool b_discardable_picture
)
508 demux_sys_t
*p_sys
= p_demux
->p_sys
;
509 matroska_segment_c
*p_segment
= p_sys
->p_current_vsegment
->CurrentSegment();
511 if( !p_segment
) return;
513 mkv_track_t
*p_track
= p_segment
->FindTrackByBlock( block
, simpleblock
);
514 if( p_track
== NULL
)
516 msg_Err( p_demux
, "invalid track number" );
520 mkv_track_t
&track
= *p_track
;
522 if( track
.fmt
.i_cat
!= DATA_ES
&& track
.p_es
== NULL
)
524 msg_Err( p_demux
, "unknown track number" );
528 i_pts
-= track
.i_codec_delay
;
530 if ( track
.fmt
.i_cat
!= DATA_ES
)
533 es_out_Control( p_demux
->out
, ES_OUT_GET_ES_STATE
, track
.p_es
, &b
);
537 if( track
.fmt
.i_cat
== VIDEO_ES
|| track
.fmt
.i_cat
== AUDIO_ES
)
538 track
.i_last_dts
= VLC_TS_INVALID
;
543 size_t frame_size
= 0;
544 size_t block_size
= 0;
546 if( simpleblock
!= NULL
)
547 block_size
= simpleblock
->GetSize();
549 block_size
= block
->GetSize();
551 const unsigned int i_number_frames
= block
!= NULL
? block
->NumberFrames() :
552 ( simpleblock
!= NULL
? simpleblock
->NumberFrames() : 0 );
554 for( unsigned int i_frame
= 0; i_frame
< i_number_frames
; i_frame
++ )
558 if( simpleblock
!= NULL
)
560 data
= &simpleblock
->GetBuffer(i_frame
);
564 data
= &block
->GetBuffer(i_frame
);
566 frame_size
+= data
->Size();
567 if( !data
->Buffer() || data
->Size() > frame_size
|| frame_size
> block_size
)
569 msg_Warn( p_demux
, "Cannot read frame (too long or no frame)" );
573 if( track
.i_compression_type
== MATROSKA_COMPRESSION_HEADER
&&
574 track
.p_compression_data
!= NULL
&&
575 track
.i_encoding_scope
& MATROSKA_ENCODING_SCOPE_ALL_FRAMES
)
576 p_block
= MemToBlock( data
->Buffer(), data
->Size(), track
.p_compression_data
->GetSize() );
577 else if( unlikely( track
.fmt
.i_codec
== VLC_CODEC_WAVPACK
) )
578 p_block
= packetize_wavpack( track
, data
->Buffer(), data
->Size() );
580 p_block
= MemToBlock( data
->Buffer(), data
->Size(), 0 );
582 if( p_block
== NULL
)
587 #if defined(HAVE_ZLIB_H)
588 if( track
.i_compression_type
== MATROSKA_COMPRESSION_ZLIB
&&
589 track
.i_encoding_scope
& MATROSKA_ENCODING_SCOPE_ALL_FRAMES
)
591 p_block
= block_zlib_decompress( VLC_OBJECT(p_demux
), p_block
);
592 if( p_block
== NULL
)
597 if( track
.i_compression_type
== MATROSKA_COMPRESSION_HEADER
&&
598 track
.i_encoding_scope
& MATROSKA_ENCODING_SCOPE_ALL_FRAMES
)
600 memcpy( p_block
->p_buffer
, track
.p_compression_data
->GetBuffer(), track
.p_compression_data
->GetSize() );
604 p_block
->i_flags
|= BLOCK_FLAG_TYPE_I
;
606 switch( track
.fmt
.i_codec
)
609 case VLC_CODEC_ATRAC3
:
611 handle_real_audio(p_demux
, &track
, p_block
, i_pts
);
612 block_Release(p_block
);
613 i_pts
= ( track
.i_default_duration
)?
614 i_pts
+ ( mtime_t
)track
.i_default_duration
:
619 case VLC_CODEC_WEBVTT
:
621 p_block
= block_Realloc( p_block
, 16, p_block
->i_buffer
);
624 SetDWBE( p_block
->p_buffer
, p_block
->i_buffer
);
625 memcpy( &p_block
->p_buffer
[4], "vttc", 4 );
626 SetDWBE( &p_block
->p_buffer
[8], p_block
->i_buffer
- 8 );
627 memcpy( &p_block
->p_buffer
[12], "payl", 4 );
632 mtime_t i_length
= i_duration
* track
. f_timecodescale
*
633 (double) p_segment
->i_timescale
/ 1000.0;
634 if ( i_length
< 0 ) i_length
= 0;
635 p_block
->i_nb_samples
= i_length
* track
.fmt
.audio
.i_rate
640 if( track
.fmt
.i_cat
!= VIDEO_ES
)
642 if ( track
.fmt
.i_cat
== DATA_ES
)
644 // TODO handle the start/stop times of this packet
645 p_sys
->p_ev
->SetPci( (const pci_t
*)&p_block
->p_buffer
[1]);
646 block_Release( p_block
);
649 p_block
->i_dts
= p_block
->i_pts
= i_pts
;
653 // correct timestamping when B frames are used
654 if( track
.b_dts_only
)
656 p_block
->i_pts
= VLC_TS_INVALID
;
657 p_block
->i_dts
= i_pts
;
659 else if( track
.b_pts_only
)
661 p_block
->i_pts
= i_pts
;
662 p_block
->i_dts
= i_pts
;
666 p_block
->i_pts
= i_pts
;
667 // condition when the DTS is correct (keyframe or B frame == NOT P frame)
668 if ( b_key_picture
|| b_discardable_picture
)
669 p_block
->i_dts
= p_block
->i_pts
;
670 else if ( track
.i_last_dts
== VLC_TS_INVALID
)
671 p_block
->i_dts
= i_pts
;
673 p_block
->i_dts
= std::min( i_pts
, track
.i_last_dts
+ ( mtime_t
)track
.i_default_duration
);
677 send_Block( p_demux
, &track
, p_block
, i_number_frames
, i_duration
);
679 /* use time stamp only for first block */
680 i_pts
= ( track
.i_default_duration
)?
681 i_pts
+ ( mtime_t
)track
.i_default_duration
:
682 ( track
.fmt
.b_packetized
) ? VLC_TS_INVALID
: i_pts
+ 1;
686 /*****************************************************************************
687 * Demux: reads and demuxes data packets
688 *****************************************************************************
689 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
690 *****************************************************************************/
691 static int Demux( demux_t
*p_demux
)
693 demux_sys_t
*p_sys
= p_demux
->p_sys
;
695 vlc_mutex_locker
demux_lock ( &p_sys
->lock_demuxer
);
697 virtual_segment_c
*p_vsegment
= p_sys
->p_current_vsegment
;
699 if( p_sys
->i_pts
>= p_sys
->i_start_pts
)
701 if ( p_vsegment
->UpdateCurrentToChapter( *p_demux
) )
703 p_vsegment
= p_sys
->p_current_vsegment
;
706 matroska_segment_c
*p_segment
= p_vsegment
->CurrentSegment();
707 if ( p_segment
== NULL
)
711 KaxSimpleBlock
*simpleblock
;
712 int64_t i_block_duration
= 0;
714 bool b_discardable_picture
;
716 if( p_segment
->BlockGet( block
, simpleblock
, &b_key_picture
, &b_discardable_picture
, &i_block_duration
) )
718 if ( p_vsegment
->CurrentEdition() && p_vsegment
->CurrentEdition()->b_ordered
)
720 const virtual_chapter_c
*p_chap
= p_vsegment
->CurrentChapter();
721 // check if there are more chapters to read
722 if ( p_chap
!= NULL
)
724 /* TODO handle successive chapters with the same user_start_time/user_end_time
726 p_sys
->i_pts
= p_chap
->i_mk_virtual_stop_time
+ VLC_TS_0
;
727 p_sys
->i_pts
++; // trick to avoid staying on segments with no duration and no content
733 msg_Warn( p_demux
, "cannot get block EOF?" );
738 mkv_track_t
*p_track
= p_segment
->FindTrackByBlock( block
, simpleblock
);
740 if( p_track
== NULL
)
742 msg_Err( p_demux
, "invalid track number" );
747 mkv_track_t
&track
= *p_track
;
750 if( track
.i_skip_until_fpos
!= std::numeric_limits
<uint64_t>::max() ) {
752 uint64_t block_fpos
= 0;
754 if( block
) block_fpos
= block
->GetElementPosition();
755 else block_fpos
= simpleblock
->GetElementPosition();
757 if ( track
.i_skip_until_fpos
> block_fpos
)
760 return 1; // this block shall be ignored
763 track
.i_skip_until_fpos
= -1;
769 int64_t i_pcr
= VLC_TS_INVALID
;
771 typedef matroska_segment_c::tracks_map_t tracks_map_t
;
773 for( tracks_map_t::const_iterator it
= p_segment
->tracks
.begin(); it
!= p_segment
->tracks
.end(); ++it
)
775 mkv_track_t
&track
= *it
->second
;
777 if( track
.i_last_dts
== VLC_TS_INVALID
)
780 if( track
.fmt
.i_cat
!= VIDEO_ES
&& track
.fmt
.i_cat
!= AUDIO_ES
)
783 if( track
.i_last_dts
< i_pcr
|| i_pcr
<= VLC_TS_INVALID
)
785 i_pcr
= track
.i_last_dts
;
789 if( i_pcr
> VLC_TS_INVALID
&& i_pcr
> p_sys
->i_pcr
)
791 if( es_out_SetPCR( p_demux
->out
, i_pcr
) )
793 msg_Err( p_demux
, "ES_OUT_SET_PCR failed, aborting." );
797 p_sys
->i_pcr
= i_pcr
;
803 p_sys
->i_pts
= p_sys
->i_mk_chapter_time
+ VLC_TS_0
;
805 if( simpleblock
!= NULL
) p_sys
->i_pts
+= simpleblock
->GlobalTimecode() / INT64_C( 1000 );
806 else p_sys
->i_pts
+= block
->GlobalTimecode() / INT64_C( 1000 );
809 if ( p_vsegment
->CurrentEdition() &&
810 p_vsegment
->CurrentEdition()->b_ordered
&&
811 p_vsegment
->CurrentChapter() == NULL
)
813 /* nothing left to read in this ordered edition */
818 BlockDecode( p_demux
, block
, simpleblock
, p_sys
->i_pts
, i_block_duration
, b_key_picture
, b_discardable_picture
);
825 mkv_track_t::mkv_track_t(enum es_format_category_e es_cat
) :
834 ,b_no_duration(false)
835 ,i_default_duration(0)
836 ,f_timecodescale(1.0)
838 ,i_skip_until_fpos(-1)
842 ,i_chans_to_reorder(0)
844 ,b_discontinuity(false)
845 ,i_compression_type(MATROSKA_COMPRESSION_NONE
)
846 ,i_encoding_scope(MATROSKA_ENCODING_SCOPE_ALL_FRAMES
)
847 ,p_compression_data(NULL
)
851 std::memset( &pi_chan_table
, 0, sizeof( pi_chan_table
) );
853 es_format_Init(&fmt
, es_cat
, 0);
858 fmt
.audio
.i_channels
= 1;
859 fmt
.audio
.i_rate
= 8000;
863 fmt
.psz_language
= strdup("English");
866 // no language needed
871 mkv_track_t::~mkv_track_t()
873 es_format_Clean( &fmt
);
874 assert(p_es
== NULL
); // did we leak an ES ?
878 delete p_compression_data
;