@ -418,13 +418,16 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
* pf = 0.0 ;
if ( p_sys - > p_current_vsegment & & p_sys - > p_current_vsegment - > CurrentSegment ( ) )
{
typedef matroska_segment_c : : tracks_map_t tracks_map_t ;
const matroska_segment_c * p_segment = p_sys - > p_current_vsegment - > CurrentSegment ( ) ;
for ( size_t i = 0 ; i < p_segment - > tracks . size ( ) ; i + + )
for ( tracks_map_t : : const_iterator it = p_segment - > tracks . begin ( ) ; it ! = p_segment - > tracks . end ( ) ; + + it )
{
mkv_track_t * tk = p_segment - > tracks [ i ] ;
if ( tk - > fmt . i_cat = = VIDEO_ES & & tk - > fmt . video . i_frame_rate_base > 0 )
tracks_map_t : : mapped_type const & track = it - > second ;
if ( track . fmt . i_cat = = VIDEO_ES & & track . fmt . video . i_frame_rate_base > 0 )
{
* pf = ( double ) tk - > fmt . video . i_frame_rate / tk - > fmt . video . i_frame_rate_base ;
* pf = ( double ) track . fmt . video . i_frame_rate / track . fmt . video . i_frame_rate_base ;
break ;
}
}
@ -491,53 +494,56 @@ void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock
mtime_t i_pts , mtime_t i_duration , bool b_key_picture ,
bool b_discardable_picture )
{
typedef matroska_segment_c : : tracks_map_t tracks_map_t ;
demux_sys_t * p_sys = p_demux - > p_sys ;
matroska_segment_c * p_segment = p_sys - > p_current_vsegment - > CurrentSegment ( ) ;
if ( ! p_segment ) return ;
size_t i_track ;
if ( p_segment - > BlockFindTrackIndex ( & i_track , block , simpleblock ) )
tracks_map_t : : iterator track_it ;
if ( p_segment - > FindTrackByBlock ( & track_it , block , simpleblock ) )
{
msg_Err ( p_demux , " invalid track number " ) ;
return ;
}
mkv_track_t * tk = p_segment - > tracks [ i_track ] ;
tracks_map_t : : mapped_type & track = track_it - > second ;
if ( tk - > fmt . i_cat ! = NAV_ES & & tk - > p_es = = NULL )
if ( track . fmt . i_cat ! = NAV_ES & & track . p_es = = NULL )
{
msg_Err ( p_demux , " unknown track number " ) ;
return ;
}
i_pts - = tk - > i_codec_delay ;
i_pts - = track . i_codec_delay ;
if ( tk - > fmt . i_cat ! = NAV_ES )
if ( track . fmt . i_cat ! = NAV_ES )
{
bool b ;
es_out_Control ( p_demux - > out , ES_OUT_GET_ES_STATE , tk - > p_es , & b ) ;
es_out_Control ( p_demux - > out , ES_OUT_GET_ES_STATE , track . p_es , & b ) ;
if ( ! b )
{
tk - > b_inited = false ;
if ( tk - > fmt . i_cat = = VIDEO_ES | | tk - > fmt . i_cat = = AUDIO_ES )
tk - > i_last_dts = VLC_TS_INVALID ;
track . b_inited = false ;
if ( track . fmt . i_cat = = VIDEO_ES | | track . fmt . i_cat = = AUDIO_ES )
track . i_last_dts = VLC_TS_INVALID ;
return ;
}
}
/* First send init data */
if ( ! tk - > b_inited & & tk - > i_data_init > 0 )
if ( ! track . b_inited & & track . i_data_init > 0 )
{
block_t * p_init ;
msg_Dbg ( p_demux , " sending header (%d bytes) " , tk - > i_data_init ) ;
p_init = MemToBlock ( tk - > p_data_init , tk - > i_data_init , 0 ) ;
if ( p_init ) send_Block ( p_demux , tk , p_init , 1 , 0 ) ;
msg_Dbg ( p_demux , " sending header (%d bytes) " , track . i_data_init ) ;
p_init = MemToBlock ( track . p_data_init , track . i_data_init , 0 ) ;
if ( p_init ) send_Block ( p_demux , & trac k , p_init , 1 , 0 ) ;
}
tk - > b_inited = true ;
track . b_inited = true ;
size_t frame_size = 0 ;
@ -569,12 +575,12 @@ void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock
break ;
}
if ( tk - > i_compression_type = = MATROSKA_COMPRESSION_HEADER & &
tk - > p_compression_data ! = NULL & &
tk - > i_encoding_scope & MATROSKA_ENCODING_SCOPE_ALL_FRAMES )
p_block = MemToBlock ( data - > Buffer ( ) , data - > Size ( ) , tk - > p_compression_data - > GetSize ( ) ) ;
else if ( unlikely ( tk - > fmt . i_codec = = VLC_CODEC_WAVPACK ) )
p_block = packetize_wavpack ( tk , data - > Buffer ( ) , data - > Size ( ) ) ;
if ( track . i_compression_type = = MATROSKA_COMPRESSION_HEADER & &
track . p_compression_data ! = NULL & &
track . i_encoding_scope & MATROSKA_ENCODING_SCOPE_ALL_FRAMES )
p_block = MemToBlock ( data - > Buffer ( ) , data - > Size ( ) , track . p_compression_data - > GetSize ( ) ) ;
else if ( unlikely ( track . fmt . i_codec = = VLC_CODEC_WAVPACK ) )
p_block = packetize_wavpack ( & trac k , data - > Buffer ( ) , data - > Size ( ) ) ;
else
p_block = MemToBlock ( data - > Buffer ( ) , data - > Size ( ) , 0 ) ;
@ -584,8 +590,8 @@ void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock
}
# if defined(HAVE_ZLIB_H)
if ( tk - > i_compression_type = = MATROSKA_COMPRESSION_ZLIB & &
tk - > i_encoding_scope & MATROSKA_ENCODING_SCOPE_ALL_FRAMES )
if ( track . i_compression_type = = MATROSKA_COMPRESSION_ZLIB & &
track . i_encoding_scope & MATROSKA_ENCODING_SCOPE_ALL_FRAMES )
{
p_block = block_zlib_decompress ( VLC_OBJECT ( p_demux ) , p_block ) ;
if ( p_block = = NULL )
@ -593,24 +599,24 @@ void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock
}
else
# endif
if ( tk - > i_compression_type = = MATROSKA_COMPRESSION_HEADER & &
tk - > i_encoding_scope & MATROSKA_ENCODING_SCOPE_ALL_FRAMES )
if ( track . i_compression_type = = MATROSKA_COMPRESSION_HEADER & &
track . i_encoding_scope & MATROSKA_ENCODING_SCOPE_ALL_FRAMES )
{
memcpy ( p_block - > p_buffer , tk - > p_compression_data - > GetBuffer ( ) , tk - > p_compression_data - > GetSize ( ) ) ;
memcpy ( p_block - > p_buffer , track . p_compression_data - > GetBuffer ( ) , track . p_compression_data - > GetSize ( ) ) ;
}
if ( b_key_picture )
p_block - > i_flags | = BLOCK_FLAG_TYPE_I ;
switch ( tk - > fmt . i_codec )
switch ( track . fmt . i_codec )
{
case VLC_CODEC_COOK :
case VLC_CODEC_ATRAC3 :
{
handle_real_audio ( p_demux , tk , p_block , i_pts ) ;
handle_real_audio ( p_demux , & trac k , p_block , i_pts ) ;
block_Release ( p_block ) ;
i_pts = ( tk - > i_default_duration ) ?
i_pts + ( mtime_t ) tk - > i_default_duration :
i_pts = ( track . i_default_duration ) ?
i_pts + ( mtime_t ) track . i_default_duration :
VLC_TS_INVALID ;
continue ;
}
@ -629,17 +635,17 @@ void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock
break ;
case VLC_CODEC_OPUS :
mtime_t i_length = i_duration * tk - > f_timecodescale *
mtime_t i_length = i_duration * track . f_timecodescale *
( double ) p_segment - > i_timescale / 1000.0 ;
if ( i_length < 0 ) i_length = 0 ;
p_block - > i_nb_samples = i_length * tk - > fmt . audio . i_rate
p_block - > i_nb_samples = i_length * track . fmt . audio . i_rate
/ CLOCK_FREQ ;
break ;
}
if ( tk - > fmt . i_cat ! = VIDEO_ES )
if ( track . fmt . i_cat ! = VIDEO_ES )
{
if ( tk - > fmt . i_cat = = NAV_ES )
if ( track . fmt . i_cat = = NAV_ES )
{
// TODO handle the start/stop times of this packet
p_sys - > p_ev - > SetPci ( ( const pci_t * ) & p_block - > p_buffer [ 1 ] ) ;
@ -651,12 +657,12 @@ void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock
else
{
// correct timestamping when B frames are used
if ( tk - > b_dts_only )
if ( track . b_dts_only )
{
p_block - > i_pts = VLC_TS_INVALID ;
p_block - > i_dts = i_pts ;
}
else if ( tk - > b_pts_only )
else if ( track . b_pts_only )
{
p_block - > i_pts = i_pts ;
p_block - > i_dts = i_pts ;
@ -666,20 +672,20 @@ void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock
p_block - > i_pts = i_pts ;
// condition when the DTS is correct (keyframe or B frame == NOT P frame)
if ( b_key_picture | | b_discardable_picture )
p_block - > i_dts = p_block - > i_pts ;
else if ( tk - > i_last_dts = = VLC_TS_INVALID )
p_block - > i_dts = p_block - > i_pts ;
else if ( track . i_last_dts = = VLC_TS_INVALID )
p_block - > i_dts = i_pts ;
else
p_block - > i_dts = std : : min ( i_pts , tk - > i_last_dts + ( mtime_t ) tk - > i_default_duration ) ;
p_block - > i_dts = std : : min ( i_pts , track . i_last_dts + ( mtime_t ) track . i_default_duration ) ;
}
}
send_Block ( p_demux , tk , p_block , i_number_frames , i_duration ) ;
send_Block ( p_demux , & trac k , p_block , i_number_frames , i_duration ) ;
/* use time stamp only for first block */
i_pts = ( tk - > i_default_duration ) ?
i_pts + ( mtime_t ) tk - > i_default_duration :
( tk - > fmt . b_packetized ) ? VLC_TS_INVALID : i_pts + 1 ;
i_pts = ( track . i_default_duration ) ?
i_pts + ( mtime_t ) track . i_default_duration :
( track . fmt . b_packetized ) ? VLC_TS_INVALID : i_pts + 1 ;
}
}
@ -739,16 +745,40 @@ static int Demux( demux_t *p_demux)
p_sys - > i_pts = ( mtime_t ) block - > GlobalTimecode ( ) / INT64_C ( 1000 ) ;
p_sys - > i_pts + = p_sys - > i_mk_chapter_time + VLC_TS_0 ;
mtime_t i_pcr = VLC_TS_INVALID ;
for ( size_t i = 0 ; i < p_segment - > tracks . size ( ) ; i + + )
if ( p_segment - > tracks [ i ] - > i_last_dts > VLC_TS_INVALID & &
( p_segment - > tracks [ i ] - > i_last_dts < i_pcr | | i_pcr = = VLC_TS_INVALID ) )
i_pcr = p_segment - > tracks [ i ] - > i_last_dts ;
if ( i_pcr > p_sys - > i_pcr + 300000 )
/* update pcr */
{
es_out_Control ( p_demux - > out , ES_OUT_SET_PCR , VLC_TS_0 + p_sys - > i_pcr ) ;
p_sys - > i_pcr = i_pcr ;
int64_t i_pcr = VLC_TS_INVALID ;
typedef matroska_segment_c : : tracks_map_t tracks_map_t ;
for ( tracks_map_t : : iterator it = p_segment - > tracks . begin ( ) ; it ! = p_segment - > tracks . end ( ) ; + + it )
{
tracks_map_t : : mapped_type & track = it - > second ;
if ( track . i_last_dts = = VLC_TS_INVALID )
continue ;
if ( track . fmt . i_cat ! = VIDEO_ES & & track . fmt . i_cat ! = AUDIO_ES )
continue ;
if ( track . i_last_dts < i_pcr | | i_pcr < = VLC_TS_INVALID )
{
i_pcr = track . i_last_dts ;
}
}
if ( i_pcr > VLC_TS_INVALID & & i_pcr > p_sys - > i_pcr )
{
if ( es_out_Control ( p_demux - > out , ES_OUT_SET_PCR , i_pcr ) )
{
msg_Err ( p_demux , " ES_OUT_SET_PCR failed, aborting. " ) ;
return 0 ;
}
p_sys - > i_pcr = i_pcr ;
}
}
if ( p_vsegment - > CurrentEdition ( ) & &