X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fdemux%2Fmkv.cpp;h=39408e7136067eced09e36c085f97d0e1e1746e8;hb=61c5ccdf303006a25fda9a60fffd8b91093a0b49;hp=8fd724ad469da2820c22965505a2554a65694e87;hpb=449fd28aaf007c6411251dae9d0dbfdc65b135d1;p=vlc diff --git a/modules/demux/mkv.cpp b/modules/demux/mkv.cpp index 8fd724ad46..39408e7136 100644 --- a/modules/demux/mkv.cpp +++ b/modules/demux/mkv.cpp @@ -26,11 +26,19 @@ * Preamble *****************************************************************************/ +/* config.h may include inttypes.h, so make sure we define that option + * early enough. */ +#define __STDC_FORMAT_MACROS 1 +#define __STDC_CONSTANT_MACROS 1 + #ifdef HAVE_CONFIG_H # include "config.h" #endif -#include +#include + +#include +#include #ifdef HAVE_TIME_H # include /* time() */ @@ -38,7 +46,7 @@ #include /* BITMAPINFOHEADER, WAVEFORMATEX */ -#include "iso_lang.h" +#include #include "vlc_meta.h" #include #include @@ -397,8 +405,8 @@ static void Close( vlc_object_t * ); vlc_module_begin(); set_shortname( "Matroska" ); - set_description( _("Matroska stream demuxer" ) ); - set_capability( "demux2", 50 ); + set_description( N_("Matroska stream demuxer" ) ); + set_capability( "demux", 50 ); set_callbacks( Open, Close ); set_category( CAT_INPUT ); set_subcategory( SUBCAT_INPUT_DEMUX ); @@ -498,7 +506,7 @@ static void MkvTree( demux_t & demuxer, int i_level, const char *psz_format, ... psz_foo2[ 4 * i_level ] = '+'; psz_foo2[ 4 * i_level + 1 ] = ' '; strcpy( &psz_foo2[ 4 * i_level + 2 ], psz_format ); - __msg_GenericVa( VLC_OBJECT(&demuxer), MSG_QUEUE_NORMAL, VLC_MSG_DBG, "mkv", psz_foo2, args ); + __msg_GenericVa( VLC_OBJECT(&demuxer),VLC_MSG_DBG, "mkv", psz_foo2, args ); free( psz_foo2 ); va_end( args ); } @@ -1043,10 +1051,7 @@ public: { for( size_t i_track = 0; i_track < tracks.size(); i_track++ ) { - if ( tracks[i_track]->p_compression_data ) - { - delete tracks[i_track]->p_compression_data; - } + delete tracks[i_track]->p_compression_data; es_format_Clean( &tracks[i_track]->fmt ); free( tracks[i_track]->p_extra_data ); free( tracks[i_track]->psz_codec ); @@ -1322,7 +1327,7 @@ public: ,b_pci_packet_set(false) ,p_ev(NULL) { - vlc_mutex_init( &demuxer, &lock_demuxer ); + vlc_mutex_init( &lock_demuxer ); } virtual ~demux_sys_t() @@ -1678,7 +1683,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) return VLC_SUCCESS; case DEMUX_GET_TITLE_INFO: - if( p_sys->titles.size() ) + if( p_sys->titles.size() > 1 || ( p_sys->titles.size() == 1 && p_sys->titles[0]->i_seekpoint > 0 ) ) { input_title_t ***ppp_title = (input_title_t***)va_arg( args, input_title_t*** ); int *pi_int = (int*)va_arg( args, int* ); @@ -1690,7 +1695,6 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) { (*ppp_title)[i] = vlc_input_title_Duplicate( p_sys->titles[i] ); } - return VLC_SUCCESS; } return VLC_EGENERIC; @@ -2055,7 +2059,7 @@ static void BlockDecode( demux_t *p_demux, KaxBlock *block, mtime_t i_pts, tk->i_last_dts = p_block->i_dts; #if 0 -msg_Dbg( p_demux, "block i_dts: "I64Fd" / i_pts: "I64Fd, p_block->i_dts, p_block->i_pts); +msg_Dbg( p_demux, "block i_dts: %"PRId64" / i_pts: %"PRId64, p_block->i_dts, p_block->i_pts); #endif if( strcmp( tk->psz_codec, "S_VOBSUB" ) ) { @@ -2100,13 +2104,13 @@ matroska_stream_c *demux_sys_t::AnalyseAllSegmentsFound( demux_t *p_demux, EbmlS #if LIBMATROSKA_VERSION >= 0x000800 if (uint64(doc_read_version) > 2) { - msg_Err( p_demux, "This matroska file is needs version "I64Fd" and this VLC only supports version 1 & 2", uint64(doc_read_version)); + msg_Err( p_demux, "This matroska file is needs version %"PRId64" and this VLC only supports version 1 & 2", uint64(doc_read_version)); return NULL; } #else if (uint64(doc_read_version) != 1) { - msg_Err( p_demux, "This matroska file is needs version "I64Fd" and this VLC only supports version 1", uint64(doc_read_version)); + msg_Err( p_demux, "This matroska file is needs version %"PRId64" and this VLC only supports version 1", uint64(doc_read_version)); return NULL; } #endif @@ -2546,6 +2550,56 @@ bool matroska_segment_c::Select( mtime_t i_start_time ) } tracks[i_track]->fmt.audio.i_blockalign = ( tracks[i_track]->fmt.audio.i_bitspersample + 7 ) / 8 * tracks[i_track]->fmt.audio.i_channels; } + /* disabled due to the potential "S_KATE" namespace issue */ + else if( !strcmp( tracks[i_track]->psz_codec, "S_KATE" ) ) + { + int i, i_offset = 1, *i_size, i_extra, num_headers, size_so_far; + uint8_t *p_extra; + + tracks[i_track]->fmt.i_codec = VLC_FOURCC( 'k', 'a', 't', 'e' ); + tracks[i_track]->fmt.subs.psz_encoding = strdup( "UTF-8" ); + + /* Recover the number of headers to expect */ + num_headers = tracks[i_track]->p_extra_data[0]+1; + msg_Dbg( &sys.demuxer, "kate in mkv detected: %d headers in %u bytes", + num_headers, tracks[i_track]->i_extra_data); + + /* this won't overflow the stack as is can allocate only 1020 bytes max */ + i_size = (int*)alloca(num_headers*sizeof(int)); + + /* Split the headers */ + size_so_far = 0; + for( i = 0; i < num_headers-1; i++ ) + { + i_size[i] = 0; + while( i_offset < tracks[i_track]->i_extra_data ) + { + i_size[i] += tracks[i_track]->p_extra_data[i_offset]; + if( tracks[i_track]->p_extra_data[i_offset++] != 0xff ) break; + } + msg_Dbg( &sys.demuxer, "kate header %d is %d bytes", i, i_size[i]); + size_so_far += i_size[i]; + } + i_size[num_headers-1] = tracks[i_track]->i_extra_data - (size_so_far+i_offset); + msg_Dbg( &sys.demuxer, "kate last header (%d) is %d bytes", num_headers-1, i_size[num_headers-1]); + + tracks[i_track]->fmt.i_extra = 1 + num_headers * 2 + size_so_far + i_size[num_headers-1]; + tracks[i_track]->fmt.p_extra = malloc( tracks[i_track]->fmt.i_extra ); + + p_extra = (uint8_t *)tracks[i_track]->fmt.p_extra; + i_extra = 0; + *(p_extra++) = num_headers; + ++i_extra; + for( i = 0; i < num_headers; i++ ) + { + *(p_extra++) = i_size[i] >> 8; + *(p_extra++) = i_size[i] & 0xFF; + memcpy( p_extra, tracks[i_track]->p_extra_data + i_offset + i_extra-1, + i_size[i] ); + p_extra += i_size[i]; + i_extra += i_size[i]; + } + } else if( !strcmp( tracks[i_track]->psz_codec, "S_TEXT/UTF8" ) ) { tracks[i_track]->fmt.i_codec = VLC_FOURCC( 's', 'u', 'b', 't' ); @@ -2663,7 +2717,7 @@ void demux_sys_t::StartUiThread() p_ev = (event_thread_t *) vlc_object_create( &demuxer, sizeof( event_thread_t ) ); p_ev->p_demux = &demuxer; p_ev->b_die = false; - vlc_mutex_init( p_ev, &p_ev->lock ); + vlc_mutex_init( &p_ev->lock ); vlc_thread_create( p_ev, "mkv event thread handler", EventThread, VLC_THREAD_PRIORITY_LOW, false ); } @@ -2738,7 +2792,7 @@ int demux_sys_t::EventThread( vlc_object_t *p_this ) var_AddCallback( p_ev->p_libvlc, "key-action", EventKey, p_ev ); /* main loop */ - while( !p_ev->b_die ) + while( vlc_object_alive (p_ev) ) { if ( !p_sys->b_pci_packet_set ) { @@ -2996,7 +3050,7 @@ int demux_sys_t::EventThread( vlc_object_t *p_this ) } /* VOUT part */ - if( p_vout && p_vout->b_die ) + if( p_vout && !vlc_object_alive (p_vout) ) { var_DelCallback( p_vout, "mouse-moved", EventMouse, p_ev ); var_DelCallback( p_vout, "mouse-clicked", EventMouse, p_ev ); @@ -3369,7 +3423,7 @@ static void Seek( demux_t *p_demux, mtime_t i_date, double f_percent, chapter_it int i_index; - msg_Dbg( p_demux, "seek request to "I64Fd" (%f%%)", i_date, f_percent ); + msg_Dbg( p_demux, "seek request to %"PRId64" (%f%%)", i_date, f_percent ); if( i_date < 0 && f_percent < 0 ) { msg_Warn( p_demux, "cannot seek nowhere !" ); @@ -3944,7 +3998,7 @@ void matroska_segment_c::LoadCues( ) ep->Up(); #if 0 - msg_Dbg( &sys.demuxer, " * added time="I64Fd" pos="I64Fd + msg_Dbg( &sys.demuxer, " * added time=%"PRId64" pos=%"PRId64 " track=%d bnum=%d", idx.i_time, idx.i_position, idx.i_track, idx.i_block_number ); #endif @@ -4143,17 +4197,17 @@ void matroska_segment_c::ParseSeekHead( KaxSeekHead *seekhead ) { if( id == KaxCues::ClassInfos.GlobalId ) { - msg_Dbg( &sys.demuxer, "| | | = cues at "I64Fd, i_pos ); + msg_Dbg( &sys.demuxer, "| | | = cues at %"PRId64, i_pos ); i_cues_position = segment->GetGlobalPosition( i_pos ); } else if( id == KaxChapters::ClassInfos.GlobalId ) { - msg_Dbg( &sys.demuxer, "| | | = chapters at "I64Fd, i_pos ); + msg_Dbg( &sys.demuxer, "| | | = chapters at %"PRId64, i_pos ); i_chapters_position = segment->GetGlobalPosition( i_pos ); } else if( id == KaxTags::ClassInfos.GlobalId ) { - msg_Dbg( &sys.demuxer, "| | | = tags at "I64Fd, i_pos ); + msg_Dbg( &sys.demuxer, "| | | = tags at %"PRId64, i_pos ); i_tags_position = segment->GetGlobalPosition( i_pos ); } } @@ -4294,7 +4348,7 @@ void matroska_segment_c::ParseTrackEntry( KaxTrackEntry *m ) KaxTrackDefaultDuration &defd = *(KaxTrackDefaultDuration*)l; tk->i_default_duration = uint64(defd); - msg_Dbg( &sys.demuxer, "| | | + Track Default Duration="I64Fd, uint64(defd) ); + msg_Dbg( &sys.demuxer, "| | | + Track Default Duration=%"PRId64, uint64(defd) ); } else if( MKV_IS_ID( l, KaxTrackTimecodeScale ) ) { @@ -4337,7 +4391,7 @@ void matroska_segment_c::ParseTrackEntry( KaxTrackEntry *m ) tk->p_extra_data = (uint8_t*)malloc( tk->i_extra_data ); memcpy( tk->p_extra_data, cpriv.GetBuffer(), tk->i_extra_data ); } - msg_Dbg( &sys.demuxer, "| | | + Track CodecPrivate size="I64Fd, cpriv.GetSize() ); + msg_Dbg( &sys.demuxer, "| | | + Track CodecPrivate size=%"PRId64, cpriv.GetSize() ); } else if( MKV_IS_ID( l, KaxCodecName ) ) { @@ -4724,7 +4778,7 @@ void matroska_segment_c::ParseInfo( KaxInfo *info ) i_timescale = uint64(tcs); - msg_Dbg( &sys.demuxer, "| | + TimecodeScale="I64Fd, + msg_Dbg( &sys.demuxer, "| | + TimecodeScale=%"PRId64, i_timescale ); } else if( MKV_IS_ID( l, KaxDuration ) ) @@ -4733,7 +4787,7 @@ void matroska_segment_c::ParseInfo( KaxInfo *info ) i_duration = mtime_t( double( dur ) ); - msg_Dbg( &sys.demuxer, "| | + Duration="I64Fd, + msg_Dbg( &sys.demuxer, "| | + Duration=%"PRId64, i_duration ); } else if( MKV_IS_ID( l, KaxMuxingApp ) ) @@ -4864,14 +4918,14 @@ void matroska_segment_c::ParseChapterAtom( int i_level, KaxChapterAtom *ca, chap else if( MKV_IS_ID( l, KaxChapterTimeStart ) ) { KaxChapterTimeStart &start =*(KaxChapterTimeStart*)l; - chapters.i_start_time = uint64( start ) / I64C(1000); + chapters.i_start_time = uint64( start ) / INT64_C(1000); msg_Dbg( &sys.demuxer, "| | | | + ChapterTimeStart: %lld", chapters.i_start_time ); } else if( MKV_IS_ID( l, KaxChapterTimeEnd ) ) { KaxChapterTimeEnd &end =*(KaxChapterTimeEnd*)l; - chapters.i_end_time = uint64( end ) / I64C(1000); + chapters.i_end_time = uint64( end ) / INT64_C(1000); msg_Dbg( &sys.demuxer, "| | | | + ChapterTimeEnd: %lld", chapters.i_end_time ); } @@ -5076,7 +5130,7 @@ void matroska_segment_c::ParseChapters( KaxChapters *chapters ) if ( stored_editions.size() != 0 && stored_editions[i_default_edition]->b_ordered ) { /* update the duration of the segment according to the sum of all sub chapters */ - i_dur = stored_editions[i_default_edition]->Duration() / I64C(1000); + i_dur = stored_editions[i_default_edition]->Duration() / INT64_C(1000); if (i_dur > 0) i_duration = i_dur; } @@ -5160,7 +5214,7 @@ void matroska_segment_c::InformationCreate( ) /***************************************************************************** - * Divers + * Misc *****************************************************************************/ void matroska_segment_c::IndexAppendCluster( KaxCluster *cluster ) @@ -5729,7 +5783,7 @@ void matroska_segment_c::Seek( mtime_t i_date, mtime_t i_time_offset ) i_seek_time = p_indexes[i_idx].i_time; } - msg_Dbg( &sys.demuxer, "seek got "I64Fd" (%d%%)", + msg_Dbg( &sys.demuxer, "seek got %"PRId64" (%d%%)", i_seek_time, (int)( 100 * i_seek_position / stream_Size( sys.demuxer.s ) ) ); es.I_O().setFilePointer( i_seek_position, seek_beginning ); @@ -6653,7 +6707,7 @@ bool matroska_script_interpretor_c::Interpret( const binary * p_command, size_t chapter_item_c *p_chapter = sys.FindChapter( i_chapter_uid, p_segment ); if ( p_chapter == NULL ) - msg_Dbg( &sys.demuxer, "Chapter "I64Fd" not found", i_chapter_uid); + msg_Dbg( &sys.demuxer, "Chapter %"PRId64" not found", i_chapter_uid); else { if ( !p_chapter->EnterAndLeave( sys.p_current_segment->CurrentChapter() ) )