* 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
-#define __STDC_FORMAT_MACROS 1
-#define __STDC_CONSTANT_MACROS 1
#include <inttypes.h>
-#include <vlc/vlc.h>
+#include <vlc_common.h>
+#include <vlc_plugin.h>
#ifdef HAVE_TIME_H
# include <time.h> /* time() */
#include <vlc_codecs.h> /* BITMAPINFOHEADER, WAVEFORMATEX */
-#include "iso_lang.h"
+#include <vlc_iso_lang.h>
#include "vlc_meta.h"
#include <vlc_charset.h>
#include <vlc_input.h>
vlc_module_begin();
set_shortname( "Matroska" );
- set_description( _("Matroska stream demuxer" ) );
+ set_description( N_("Matroska stream demuxer" ) );
set_capability( "demux", 50 );
set_callbacks( Open, Close );
set_category( CAT_INPUT );
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 );
}
{
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 );
,b_pci_packet_set(false)
,p_ev(NULL)
{
- vlc_mutex_init( &demuxer, &lock_demuxer );
+ vlc_mutex_init( &lock_demuxer );
}
virtual ~demux_sys_t()
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* );
{
(*ppp_title)[i] = vlc_input_title_Duplicate( p_sys->titles[i] );
}
-
return VLC_SUCCESS;
}
return VLC_EGENERIC;
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" ) )
{
#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
}
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' );
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 );
}
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 )
{
}
/* 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 );
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 !" );
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
{
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 );
}
}
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 ) )
{
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 ) )
{
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 ) )
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 ) )
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 );
}
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;
}
/*****************************************************************************
- * Divers
+ * Misc
*****************************************************************************/
void matroska_segment_c::IndexAppendCluster( KaxCluster *cluster )
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 );
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() ) )