X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=modules%2Fdemux%2Fmkv%2Fmatroska_segment.cpp;h=50ccba9e5e8e944217df53b69454aade5ede2676;hb=c2773039dfc3dc1e133d1608e07b420d5a47377a;hp=beac06958bc6203c3adda84676bee269e36972d2;hpb=22c24d5aaf7a41f8f0a3beb49039ec8415767263;p=vlc diff --git a/modules/demux/mkv/matroska_segment.cpp b/modules/demux/mkv/matroska_segment.cpp index beac06958b..50ccba9e5e 100644 --- a/modules/demux/mkv/matroska_segment.cpp +++ b/modules/demux/mkv/matroska_segment.cpp @@ -285,6 +285,7 @@ void matroska_segment_c::ParseSimpleTags( KaxTagSimple *tag ) goto done; } } + msg_Dbg( &sys.demuxer, "| | + %s: %s", k, v); vlc_meta_AddExtra( sys.meta, k, v ); done: free( k ); @@ -371,8 +372,8 @@ void matroska_segment_c::LoadTags( KaxTags *tags ) *****************************************************************************/ void matroska_segment_c::InformationCreate( ) { -#if 0 - sys.meta = vlc_meta_New(); + if( !sys.meta ) + sys.meta = vlc_meta_New(); if( psz_title ) { @@ -382,6 +383,7 @@ void matroska_segment_c::InformationCreate( ) { vlc_meta_SetDate( sys.meta, psz_date_utc ); } +#if 0 if( psz_segment_filename ) { @@ -691,6 +693,7 @@ void matroska_segment_c::Seek( mtime_t i_date, mtime_t i_time_offset, int64_t i_ spoint *p_first = NULL; spoint *p_last = NULL; int i_cat; + bool b_has_key = false; if( i_global_position >= 0 ) { @@ -717,7 +720,7 @@ void matroska_segment_c::Seek( mtime_t i_date, mtime_t i_time_offset, int64_t i_ ( i_index > 0 && p_indexes[i_index - 1].i_position < (int64_t)cluster->GetElementPosition() ) ) { - ParseCluster(); + ParseCluster(false); IndexAppendCluster( cluster ); } if( es.I_O().getFilePointer() >= (unsigned) i_global_position ) @@ -744,9 +747,9 @@ void matroska_segment_c::Seek( mtime_t i_date, mtime_t i_time_offset, int64_t i_ } #endif + int i_idx = 0; if ( i_index > 0 ) { - int i_idx = 0; for( ; i_idx < i_index; i_idx++ ) if( p_indexes[i_idx].i_time + i_time_offset > i_date ) @@ -773,9 +776,9 @@ void matroska_segment_c::Seek( mtime_t i_date, mtime_t i_time_offset, int64_t i_ es_out_Control( sys.demuxer.out, ES_OUT_SET_NEXT_DISPLAY_TIME, i_date ); /* now parse until key frame */ - const int es[3] = { VIDEO_ES, AUDIO_ES, SPU_ES }; - i_cat = es[0]; - for( int i = 0; i < 2; i_cat = es[++i] ) + const int es_types[3] = { VIDEO_ES, AUDIO_ES, SPU_ES }; + i_cat = es_types[0]; + for( int i = 0; i < 2; i_cat = es_types[++i] ) { for( i_track = 0; i_track < tracks.size(); i_track++ ) { @@ -811,49 +814,63 @@ void matroska_segment_c::Seek( mtime_t i_date, mtime_t i_time_offset, int64_t i_ if( unlikely( !p_first ) ) return; - while( i_pts < i_date ) + for(;;) { - bool b_key_picture; - bool b_discardable_picture; - if( BlockGet( block, simpleblock, &b_key_picture, &b_discardable_picture, &i_block_duration ) ) - { - msg_Warn( &sys.demuxer, "cannot get block EOF?" ); - - return; - } - - /* check if block's track is in our list */ - for( i_track = 0; i_track < tracks.size(); i_track++ ) + while( i_pts < i_date ) { - if( (simpleblock && tracks[i_track]->i_number == simpleblock->TrackNum()) || - (block && tracks[i_track]->i_number == block->TrackNum()) ) - break; - } + bool b_key_picture; + bool b_discardable_picture; + if( BlockGet( block, simpleblock, &b_key_picture, &b_discardable_picture, &i_block_duration ) ) + { + msg_Warn( &sys.demuxer, "cannot get block EOF?" ); + return; + } - if( simpleblock ) - i_pts = sys.i_chapter_time + simpleblock->GlobalTimecode() / (mtime_t) 1000; - else - i_pts = sys.i_chapter_time + block->GlobalTimecode() / (mtime_t) 1000; - if( i_track < tracks.size() ) - { - if( tracks[i_track]->fmt.i_cat == i_cat && b_key_picture ) + /* check if block's track is in our list */ + for( i_track = 0; i_track < tracks.size(); i_track++ ) { - /* get the seekpoint */ - spoint * sp; - for( sp = p_first; sp; sp = sp->p_next ) - if( sp->i_track == i_track ) - break; + if( (simpleblock && tracks[i_track]->i_number == simpleblock->TrackNum()) || + (block && tracks[i_track]->i_number == block->TrackNum()) ) + break; + } - sp->i_date = i_pts; - if( simpleblock ) - sp->i_seek_pos = simpleblock->GetElementPosition(); - else - sp->i_seek_pos = i_block_pos; - sp->i_cluster_pos = i_cluster_pos; + if( simpleblock ) + i_pts = sys.i_chapter_time + simpleblock->GlobalTimecode() / (mtime_t) 1000; + else + i_pts = sys.i_chapter_time + block->GlobalTimecode() / (mtime_t) 1000; + if( i_track < tracks.size() ) + { + if( tracks[i_track]->fmt.i_cat == i_cat && b_key_picture ) + { + /* get the seekpoint */ + spoint * sp; + for( sp = p_first; sp; sp = sp->p_next ) + if( sp->i_track == i_track ) + break; + + sp->i_date = i_pts; + if( simpleblock ) + sp->i_seek_pos = simpleblock->GetElementPosition(); + else + sp->i_seek_pos = i_block_pos; + sp->i_cluster_pos = i_cluster_pos; + b_has_key = true; + } } + + delete block; } + if( b_has_key || !i_idx ) + break; - delete block; + /* No key picture was found in the cluster seek to previous seekpoint */ + i_date = i_time_offset + p_indexes[i_idx].i_time; + i_idx--; + i_pts = 0; + es.I_O().setFilePointer( p_indexes[i_idx].i_position ); + delete ep; + ep = new EbmlParser( &es, segment, &sys.demuxer ); + cluster = NULL; } /* rewind to the last I img */ @@ -866,7 +883,6 @@ void matroska_segment_c::Seek( mtime_t i_date, mtime_t i_time_offset, int64_t i_ es_out_Control( sys.demuxer.out, ES_OUT_SET_PCR, VLC_TS_0 + sys.i_pcr ); cluster = (KaxCluster *) ep->UnGet( p_min->i_seek_pos, p_min->i_cluster_pos ); - /* hack use BlockGet to get the cluster then goto the wanted block */ if ( !cluster ) { @@ -979,7 +995,7 @@ bool matroska_segment_c::Select( mtime_t i_start_time ) { /* Very unlikely yet possible: bug #5659*/ size_t maxlen = p_tk->i_extra_data - sizeof( VLC_BITMAPINFOHEADER ); - p_tk->fmt.i_extra = ( p_tk->fmt.i_extra < maxlen )? + p_tk->fmt.i_extra = ( (unsigned)p_tk->fmt.i_extra < maxlen )? p_tk->fmt.i_extra : maxlen; p_tk->fmt.p_extra = xmalloc( p_tk->fmt.i_extra ); @@ -1094,6 +1110,8 @@ bool matroska_segment_c::Select( mtime_t i_start_time ) wf_tag_to_fourcc( GetWLE( &p_wf->wFormatTag ), &p_tk->fmt.i_codec, NULL ); + if( p_tk->fmt.i_codec == VLC_FOURCC( 'u', 'n', 'd', 'f' ) ) + msg_Err( &sys.demuxer, "Unrecognized wf tag: 0x%x", GetWLE( &p_wf->wFormatTag ) ); p_tk->fmt.audio.i_channels = GetWLE( &p_wf->nChannels ); p_tk->fmt.audio.i_rate = GetDWLE( &p_wf->nSamplesPerSec ); p_tk->fmt.i_bitrate = GetDWLE( &p_wf->nAvgBytesPerSec ) * 8; @@ -1253,21 +1271,32 @@ bool matroska_segment_c::Select( mtime_t i_start_time ) } else if( !strncmp( p_tk->psz_codec, "A_REAL/", 7 ) ) { - if( !strcmp( p_tk->psz_codec, "A_REAL/COOK" ) ) - p_tk->fmt.i_codec = VLC_CODEC_COOK; - else if( !strcmp( p_tk->psz_codec, "A_REAL/ATRC" ) ) - p_tk->fmt.i_codec = VLC_CODEC_ATRAC3; - else if( !strcmp( p_tk->psz_codec, "A_REAL/28_8" ) ) - p_tk->fmt.i_codec = VLC_CODEC_RA_288; - /* FIXME 14_4, RALF and SIPR */ - fill_extra_data( p_tk, p_tk->fmt.i_codec == VLC_CODEC_RA_288 ? 0 : 0 /*78 - FIXME need to implement reading support for cook */ ); - } - else if( !strcmp( p_tk->psz_codec, "A_REAL/14_4" ) ) - { - p_fmt->i_codec = VLC_CODEC_RA_144; - p_fmt->audio.i_channels = 1; - p_fmt->audio.i_rate = 8000; - p_fmt->audio.i_blockalign = 0x14; + if( !strcmp( p_tk->psz_codec, "A_REAL/14_4" ) ) + { + p_fmt->i_codec = VLC_CODEC_RA_144; + p_fmt->audio.i_channels = 1; + p_fmt->audio.i_rate = 8000; + p_fmt->audio.i_blockalign = 0x14; + } + else if( p_tk->i_extra_data > 28 ) + { + uint8_t *p = p_tk->p_extra_data; + if( memcmp( p, ".ra", 3 ) ) { + msg_Err( &sys.demuxer, "Invalid Real ExtraData 0x%4.4s", (char *)p ); + p_tk->fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' ); + } + else { + if( !strcmp( p_tk->psz_codec, "A_REAL/COOK" ) ) + p_tk->fmt.i_codec = VLC_CODEC_COOK; + else if( !strcmp( p_tk->psz_codec, "A_REAL/ATRC" ) ) + p_tk->fmt.i_codec = VLC_CODEC_ATRAC3; + else if( !strcmp( p_tk->psz_codec, "A_REAL/28_8" ) ) + p_tk->fmt.i_codec = VLC_CODEC_RA_288; + /* FIXME RALF and SIPR */ + + fill_extra_data( p_tk, p_tk->fmt.i_codec == VLC_CODEC_RA_288 ? 0 : 78); + } + } } else if( !strcmp( p_tk->psz_codec, "S_KATE" ) ) {