1 /*****************************************************************************
2 * mkv.cpp : matroska demuxer
3 *****************************************************************************
4 * Copyright (C) 2001 VideoLAN
5 * $Id: mkv.cpp,v 1.3 2003/06/22 14:36:34 fenrir Exp $
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
27 #include <stdlib.h> /* malloc(), free() */
31 #include <vlc/input.h>
33 #include <codecs.h> /* BITMAPINFOHEADER, WAVEFORMATEX */
39 /* libebml and matroska */
40 #include "ebml/EbmlHead.h"
41 #include "ebml/EbmlSubHead.h"
42 #include "ebml/EbmlStream.h"
43 #include "ebml/EbmlContexts.h"
44 #include "ebml/EbmlVersion.h"
45 #include "ebml/EbmlVoid.h"
47 #include "matroska/FileKax.h"
48 #include "matroska/KaxAttachements.h"
49 #include "matroska/KaxBlock.h"
50 #include "matroska/KaxBlockData.h"
51 #include "matroska/KaxChapters.h"
52 #include "matroska/KaxCluster.h"
53 #include "matroska/KaxClusterData.h"
54 #include "matroska/KaxContexts.h"
55 #include "matroska/KaxCues.h"
56 #include "matroska/KaxCuesData.h"
57 #include "matroska/KaxInfo.h"
58 #include "matroska/KaxInfoData.h"
59 #include "matroska/KaxSeekHead.h"
60 #include "matroska/KaxSegment.h"
61 #include "matroska/KaxTag.h"
62 #include "matroska/KaxTracks.h"
63 #include "matroska/KaxTrackAudio.h"
64 #include "matroska/KaxTrackVideo.h"
66 #include "ebml/StdIOCallback.h"
68 using namespace LIBMATROSKA_NAMESPACE;
72 /*****************************************************************************
74 *****************************************************************************/
75 static int Activate ( vlc_object_t * );
76 static void Deactivate( vlc_object_t * );
77 static int Demux ( input_thread_t * );
79 /*****************************************************************************
81 *****************************************************************************/
83 add_category_hint( N_("mkv-demuxer"), NULL, VLC_TRUE );
84 add_bool( "mkv-index", 0, NULL,
85 N_("Create index if no cues found"),
86 N_("Create index if no cues found"), VLC_TRUE );
87 set_description( _("mka/mkv stream demuxer" ) );
88 set_capability( "demux", 50 );
89 set_callbacks( Activate, Deactivate );
90 add_shortcut( "mka" );
91 add_shortcut( "mkv" );
95 /*****************************************************************************
97 *****************************************************************************/
98 class vlc_stream_io_callback: public IOCallback
101 input_thread_t *p_input;
104 vlc_stream_io_callback( input_thread_t * );
106 virtual uint32_t read ( void *p_buffer, size_t i_size);
107 virtual void setFilePointer ( int64_t i_offset, seek_mode mode = seek_beginning );
108 virtual size_t write ( const void *p_buffer, size_t i_size);
109 virtual uint64_t getFilePointer ( void );
110 virtual void close ( void );
114 vlc_stream_io_callback::vlc_stream_io_callback( input_thread_t *p_input_ )
119 uint32_t vlc_stream_io_callback::read( void *p_buffer, size_t i_size )
121 data_packet_t *p_data;
134 i_count = input_SplitBuffer(p_input, &p_data, __MIN( i_size, 10240 ) );
139 memcpy( p_buffer, p_data->p_payload_start, i_count );
140 input_DeletePacket( p_input->p_method_data, p_data );
142 (uint8_t*)p_buffer += i_count;
152 void vlc_stream_io_callback::setFilePointer(int64_t i_offset, seek_mode mode )
156 vlc_mutex_lock( &p_input->stream.stream_lock );
163 i_pos = p_input->stream.p_selected_area->i_size - i_offset;
166 i_pos= p_input->stream.p_selected_area->i_tell + i_offset;
169 if( i_pos < 0 || i_pos > p_input->stream.p_selected_area->i_size )
171 msg_Err( p_input, "seeking to wrong place (i_pos=%lld)", i_pos );
172 vlc_mutex_unlock( &p_input->stream.stream_lock );
175 vlc_mutex_unlock( &p_input->stream.stream_lock );
177 input_AccessReinit( p_input );
178 p_input->pf_seek( p_input, i_pos );
181 size_t vlc_stream_io_callback::write( const void *p_buffer, size_t i_size )
186 uint64_t vlc_stream_io_callback::getFilePointer( void )
190 vlc_mutex_lock( &p_input->stream.stream_lock );
191 i_pos= p_input->stream.p_selected_area->i_tell;
192 vlc_mutex_unlock( &p_input->stream.stream_lock );
197 void vlc_stream_io_callback::close( void )
202 /*****************************************************************************
204 *****************************************************************************/
208 EbmlParser( EbmlStream *es, EbmlElement *el_start );
212 EbmlElement *Get( void );
215 int GetLevel( void );
221 EbmlElement *m_el[6];
230 EbmlParser::EbmlParser( EbmlStream *es, EbmlElement *el_start )
238 for( i = 1; i < 6; i++ )
247 EbmlParser::~EbmlParser( void )
251 for( i = 1; i < mi_level; i++ )
261 void EbmlParser::Up( void )
263 if( mi_user_level == mi_level )
265 fprintf( stderr," arrrrrrrrrrrrrg Up cannot escape itself\n" );
271 void EbmlParser::Down( void )
277 void EbmlParser::Keep( void )
282 int EbmlParser::GetLevel( void )
284 return mi_user_level;
287 EbmlElement *EbmlParser::Get( void )
291 if( mi_user_level != mi_level )
297 EbmlElement *ret = m_got;
305 m_el[mi_level]->SkipData( *m_es, m_el[mi_level]->Generic().Context );
308 delete m_el[mi_level];
313 m_el[mi_level] = m_es->FindNextElement( m_el[mi_level - 1]->Generic().Context, i_ulev, 0xFFFFFFFFL, true, 1 );
324 delete m_el[mi_level - 1];
325 m_got = m_el[mi_level -1] = m_el[mi_level];
326 m_el[mi_level] = NULL;
333 else if( m_el[mi_level] == NULL )
335 fprintf( stderr," m_el[mi_level] == NULL\n" );
338 return m_el[mi_level];
341 /*****************************************************************************
342 * Some functions to manipulate memory
343 *****************************************************************************/
344 #define GetWLE( p ) __GetWLE( (uint8_t*)p )
345 #define GetDWLE( p ) __GetDWLE( (uint8_t*)p )
346 #define GetFOURCC( p ) __GetFOURCC( (uint8_t*)p )
347 static uint16_t __GetWLE( uint8_t *p )
349 return (uint16_t)p[0] | ( ((uint16_t)p[1]) << 8 );
351 static uint32_t __GetDWLE( uint8_t *p )
353 return (uint32_t)p[0] | ( ((uint32_t)p[1]) << 8 ) |
354 ( ((uint32_t)p[2]) << 16 ) | ( ((uint32_t)p[3]) << 24 );
356 static vlc_fourcc_t __GetFOURCC( uint8_t *p )
358 return VLC_FOURCC( p[0], p[1], p[2], p[3] );
362 /*****************************************************************************
363 * definitions of structures and functions used by this plugins
364 *****************************************************************************/
368 vlc_bool_t b_default;
372 uint8_t *p_extra_data;
377 vlc_fourcc_t i_codec;
379 uint64_t i_default_duration;
384 int i_display_height;
393 es_descriptor_t *p_es;
398 /* data to be send first */
400 uint8_t *p_data_init;
402 /* hack : it's for seek */
403 vlc_bool_t b_search_keyframe;
419 vlc_stream_io_callback *in;
424 uint64_t i_timescale;
426 /* duration of the segment */
434 int64_t i_cues_position;
435 int64_t i_chapters_position;
448 #define MKVD_TIMECODESCALE 1000000
450 /*****************************************************************************
451 * Activate: initializes matroska demux structures
452 *****************************************************************************/
453 static int Activate( vlc_object_t * p_this )
455 input_thread_t *p_input = (input_thread_t *)p_this;
460 vlc_bool_t b_audio_selected;
461 int i_spu_channel, i_audio_channel;
463 EbmlElement *el = NULL, *el1 = NULL, *el2 = NULL, *el3 = NULL, *el4 = NULL;
465 /* Initialize access plug-in structures. */
466 if( p_input->i_mtu == 0 )
469 p_input->i_bufsize = INPUT_DEFAULT_BUFSIZE;
472 /* Set the demux function */
473 p_input->pf_demux = Demux;
475 /* peek the begining */
476 if( input_Peek( p_input, &p_peek, 4 ) < 4 )
478 msg_Warn( p_input, "cannot peek" );
482 /* is a valid file */
483 if( p_peek[0] != 0x1a || p_peek[1] != 0x45 || p_peek[2] != 0xdf || p_peek[3] != 0xa3 )
485 msg_Warn( p_input, "matroska module discarded (invalid header)" );
489 if( p_input->stream.i_method != INPUT_METHOD_FILE || !p_input->stream.b_seekable )
491 msg_Err( p_input, "can only read matroska over seekable file yet" );
495 p_input->p_demux_data = p_sys = (demux_sys_t*)malloc( sizeof( demux_sys_t ) );
496 memset( p_sys, 0, sizeof( demux_sys_t ) );
498 p_sys->in = new vlc_stream_io_callback( p_input );
499 p_sys->es = new EbmlStream( *p_sys->in );
500 p_sys->f_duration = -1;
501 p_sys->i_timescale = MKVD_TIMECODESCALE;
503 p_sys->track = (mkv_track_t*)malloc( sizeof( mkv_track_t ) );
505 p_sys->i_cues_position = -1;
506 p_sys->i_chapters_position = -1;
509 p_sys->i_index_max = 1024;
510 p_sys->index = (mkv_index_t*)malloc( sizeof( mkv_index_t ) * p_sys->i_index_max );
512 if( p_sys->es == NULL )
514 msg_Err( p_input, "failed to create EbmlStream" );
519 /* Find the EbmlHead element */
520 el = p_sys->es->FindNextID(EbmlHead::ClassInfos, 0xFFFFFFFFL);
523 msg_Err( p_input, "cannot find EbmlHead" );
526 msg_Dbg( p_input, "EbmlHead" );
528 el->SkipData( *p_sys->es, el->Generic().Context );
532 el = p_sys->es->FindNextID( KaxSegment::ClassInfos, 0xFFFFFFFFL);
535 msg_Err( p_input, "cannot find KaxSegment" );
538 msg_Dbg( p_input, "+ Segment" );
539 p_sys->segment = (KaxSegment*)el;
540 p_sys->cluster = NULL;
542 p_sys->ep = new EbmlParser( p_sys->es, el );
544 while( ( el1 = p_sys->ep->Get() ) != NULL )
546 if( EbmlId( *el1 ) == KaxInfo::ClassInfos.GlobalId )
548 msg_Dbg( p_input, "| + Informations" );
551 while( ( el2 = p_sys->ep->Get() ) != NULL )
553 if( EbmlId( *el2 ) == KaxTimecodeScale::ClassInfos.GlobalId )
555 KaxTimecodeScale &tcs = *(KaxTimecodeScale*)el2;
557 tcs.ReadData( p_sys->es->I_O() );
558 p_sys->i_timescale = uint64(tcs);
560 msg_Dbg( p_input, "| | + TimecodeScale=%lld", p_sys->i_timescale );
562 else if( EbmlId( *el2 ) == KaxDuration::ClassInfos.GlobalId )
564 KaxDuration &dur = *(KaxDuration*)el2;
566 dur.ReadData( p_sys->es->I_O() );
567 p_sys->f_duration = float(dur);
569 msg_Dbg( p_input, "| | + Duration=%f", p_sys->f_duration );
573 msg_Dbg( p_input, "| | + Unknow (%s)", typeid(*el2).name() );
578 else if( EbmlId( *el1 ) == KaxTracks::ClassInfos.GlobalId )
580 msg_Dbg( p_input, "| + Tracks" );
583 while( ( el2 = p_sys->ep->Get() ) != NULL )
585 if( EbmlId( *el2 ) == KaxTrackEntry::ClassInfos.GlobalId )
587 msg_Dbg( p_input, "| | + Track Entry" );
590 p_sys->track = (mkv_track_t*)realloc( p_sys->track, sizeof( mkv_track_t ) * (p_sys->i_track + 1 ) );
591 #define tk p_sys->track[p_sys->i_track - 1]
592 memset( &tk, 0, sizeof( mkv_track_t ) );
593 tk.i_cat = UNKNOWN_ES;
594 tk.b_default = VLC_FALSE;
595 tk.i_number = p_sys->i_track - 1;
597 tk.p_extra_data = NULL;
600 tk.psz_language = NULL;
601 tk.i_default_duration = 0;
603 tk.b_inited = VLC_FALSE;
605 tk.p_data_init = NULL;
609 while( ( el3 = p_sys->ep->Get() ) != NULL )
611 if( EbmlId( *el3 ) == KaxTrackNumber::ClassInfos.GlobalId )
613 KaxTrackNumber &tnum = *(KaxTrackNumber*)el3;
614 tnum.ReadData( p_sys->es->I_O() );
616 tk.i_number = uint32( tnum );
617 msg_Dbg( p_input, "| | | + Track Number=%u", uint32( tnum ) );
619 else if( EbmlId( *el3 ) == KaxTrackUID::ClassInfos.GlobalId )
621 KaxTrackUID &tuid = *(KaxTrackUID*)el3;
622 tuid.ReadData( p_sys->es->I_O() );
624 msg_Dbg( p_input, "| | | + Track UID=%u", uint32( tuid ) );
626 else if( EbmlId( *el3 ) == KaxTrackDefaultDuration::ClassInfos.GlobalId )
628 KaxTrackDefaultDuration &defd = *(KaxTrackDefaultDuration*)el3;
629 defd.ReadData( p_sys->es->I_O() );
631 tk.i_default_duration = uint64(defd);
632 msg_Dbg( p_input, "| | | + Track Default Duration=%lld", uint64(defd) );
634 else if( EbmlId( *el3 ) == KaxTrackType::ClassInfos.GlobalId )
637 KaxTrackType &ttype = *(KaxTrackType*)el3;
638 ttype.ReadData( p_sys->es->I_O() );
639 switch( uint8(ttype) )
650 psz_type = "subtitle";
654 psz_type = "unknown";
655 tk.i_cat = UNKNOWN_ES;
659 msg_Dbg( p_input, "| | | + Track Type=%s", psz_type );
661 else if( EbmlId( *el3 ) == KaxTrackAudio::ClassInfos.GlobalId )
663 msg_Dbg( p_input, "| | | + Track Audio" );
666 tk.i_bitspersample = 0;
670 while( ( el4 = p_sys->ep->Get() ) != NULL )
672 if( EbmlId( *el4 ) == KaxAudioSamplingFreq::ClassInfos.GlobalId )
674 KaxAudioSamplingFreq &afreq = *(KaxAudioSamplingFreq*)el4;
675 afreq.ReadData( p_sys->es->I_O() );
677 tk.i_samplerate = (int)float( afreq );
678 msg_Dbg( p_input, "| | | | + afreq=%d", tk.i_samplerate );
680 else if( EbmlId( *el4 ) == KaxAudioChannels::ClassInfos.GlobalId )
682 KaxAudioChannels &achan = *(KaxAudioChannels*)el4;
683 achan.ReadData( p_sys->es->I_O() );
685 tk.i_channels = uint8( achan );
686 msg_Dbg( p_input, "| | | | + achan=%u", uint8( achan ) );
688 else if( EbmlId( *el4 ) == KaxAudioBitDepth::ClassInfos.GlobalId )
690 KaxAudioBitDepth &abits = *(KaxAudioBitDepth*)el4;
691 abits.ReadData( p_sys->es->I_O() );
693 tk.i_bitspersample = uint8( abits );
694 msg_Dbg( p_input, "| | | | + abits=%u", uint8( abits ) );
698 msg_Dbg( p_input, "| | | | + Unknow (%s)", typeid(*el4).name() );
703 else if( EbmlId( *el3 ) == KaxTrackVideo::ClassInfos.GlobalId )
705 msg_Dbg( p_input, "| | | + Track Video" );
708 tk.i_display_width = 0;
709 tk.i_display_height = 0;
714 while( ( el4 = p_sys->ep->Get() ) != NULL )
716 if( EbmlId( *el4 ) == KaxVideoPixelWidth::ClassInfos.GlobalId )
718 KaxVideoPixelWidth &vwidth = *(KaxVideoPixelWidth*)el4;
719 vwidth.ReadData( p_sys->es->I_O() );
721 tk.i_width = uint16( vwidth );
722 msg_Dbg( p_input, "| | | | + width=%d", uint16( vwidth ) );
724 else if( EbmlId( *el4 ) == KaxVideoPixelHeight::ClassInfos.GlobalId )
726 KaxVideoPixelWidth &vheight = *(KaxVideoPixelWidth*)el4;
727 vheight.ReadData( p_sys->es->I_O() );
729 tk.i_height = uint16( vheight );
730 msg_Dbg( p_input, "| | | | + height=%d", uint16( vheight ) );
732 else if( EbmlId( *el4 ) == KaxVideoDisplayWidth::ClassInfos.GlobalId )
734 KaxVideoDisplayWidth &vwidth = *(KaxVideoDisplayWidth*)el4;
735 vwidth.ReadData( p_sys->es->I_O() );
737 tk.i_display_width = uint16( vwidth );
738 msg_Dbg( p_input, "| | | | + display width=%d", uint16( vwidth ) );
740 else if( EbmlId( *el4 ) == KaxVideoDisplayHeight::ClassInfos.GlobalId )
742 KaxVideoDisplayWidth &vheight = *(KaxVideoDisplayWidth*)el4;
743 vheight.ReadData( p_sys->es->I_O() );
745 tk.i_display_height = uint16( vheight );
746 msg_Dbg( p_input, "| | | | + display height=%d", uint16( vheight ) );
748 else if( EbmlId( *el4 ) == KaxVideoFrameRate::ClassInfos.GlobalId )
750 KaxVideoFrameRate &vfps = *(KaxVideoFrameRate*)el4;
751 vfps.ReadData( p_sys->es->I_O() );
753 tk.f_fps = float( vfps );
754 msg_Dbg( p_input, " | | | + fps=%f", float( vfps ) );
758 msg_Dbg( p_input, "| | | | + Unknow (%s)", typeid(*el4).name() );
763 else if( EbmlId( *el3 ) == KaxCodecID::ClassInfos.GlobalId )
765 KaxCodecID &codecid = *(KaxCodecID*)el3;
766 codecid.ReadData( p_sys->es->I_O() );
768 tk.psz_codec = strdup( string( codecid ).c_str() );
769 msg_Dbg( p_input, "| | | + Track CodecId=%s", string( codecid ).c_str() );
771 else if( EbmlId( *el3 ) == KaxCodecPrivate::ClassInfos.GlobalId )
773 KaxCodecPrivate &cpriv = *(KaxCodecPrivate*)el3;
774 cpriv.ReadData( p_sys->es->I_O() );
776 tk.i_extra_data = cpriv.GetSize();
777 if( tk.i_extra_data > 0 )
779 tk.p_extra_data = (uint8_t*)malloc( tk.i_extra_data );
780 memcpy( tk.p_extra_data, cpriv.GetBuffer(), tk.i_extra_data );
782 msg_Dbg( p_input, "| | | + Track CodecPrivate size=%lld", cpriv.GetSize() );
784 else if( EbmlId( *el3 ) == KaxTrackFlagDefault::ClassInfos.GlobalId )
786 KaxTrackFlagDefault &fdef = *(KaxTrackFlagDefault*)el3;
787 fdef.ReadData( p_sys->es->I_O() );
789 tk.b_default = uint32( fdef );
790 msg_Dbg( p_input, "| | | + Track Default=%u", uint32( fdef ) );
792 else if( EbmlId( *el3 ) == KaxTrackLanguage::ClassInfos.GlobalId )
794 KaxTrackLanguage &lang = *(KaxTrackLanguage*)el3;
796 lang.ReadData( p_sys->es->I_O() );
798 tk.psz_language = strdup( string( lang ).c_str() );
799 msg_Dbg( p_input, "| | | + Track Language=`%s'", string( lang ).c_str() );
801 else if( EbmlId( *el3 ) == KaxTrackFlagLacing::ClassInfos.GlobalId )
803 KaxTrackFlagLacing &lac = *(KaxTrackFlagLacing*)el3;
804 lac.ReadData( p_sys->es->I_O() );
806 msg_Dbg( p_input, "| | | + Track Lacing=%d", uint32( lac ) );
808 else if( EbmlId( *el3 ) == KaxTrackMinCache::ClassInfos.GlobalId )
810 KaxTrackMinCache &cmin = *(KaxTrackMinCache*)el3;
811 cmin.ReadData( p_sys->es->I_O() );
813 msg_Dbg( p_input, "| | | + Track MinCache=%d", uint32( cmin ) );
815 else if( EbmlId( *el3 ) == KaxTrackMaxCache::ClassInfos.GlobalId )
817 KaxTrackMaxCache &cmax = *(KaxTrackMaxCache*)el3;
818 cmax.ReadData( p_sys->es->I_O() );
820 msg_Dbg( p_input, "| | | + Track MaxCache=%d", uint32( cmax ) );
824 msg_Dbg( p_input, "| | | + Unknow (%s)", typeid(*el3).name() );
831 msg_Dbg( p_input, "| | + Unknow (%s)", typeid(*el2).name() );
837 else if( EbmlId( *el1 ) == KaxSeekHead::ClassInfos.GlobalId )
839 msg_Dbg( p_input, "| + Seek head" );
841 while( ( el = p_sys->ep->Get() ) != NULL )
843 if( EbmlId( *el ) == KaxSeek::ClassInfos.GlobalId )
845 EbmlId id = EbmlVoid::ClassInfos.GlobalId;
848 //msg_Dbg( p_input, "| | + Seek" );
850 while( ( el = p_sys->ep->Get() ) != NULL )
852 if( EbmlId( *el ) == KaxSeekID::ClassInfos.GlobalId )
854 KaxSeekID &sid = *(KaxSeekID*)el;
856 sid.ReadData( p_sys->es->I_O() );
858 id = EbmlId( sid.GetBuffer(), sid.GetSize() );
860 else if( EbmlId( *el ) == KaxSeekPosition::ClassInfos.GlobalId )
862 KaxSeekPosition &spos = *(KaxSeekPosition*)el;
864 spos.ReadData( p_sys->es->I_O() );
866 i_pos = uint64( spos );
870 msg_Dbg( p_input, "| | | + Unknow (%s)", typeid(*el).name() );
877 if( id == KaxCues::ClassInfos.GlobalId )
879 msg_Dbg( p_input, "| | | = cues at %lld", i_pos );
880 p_sys->i_cues_position = p_sys->segment->GetGlobalPosition( i_pos );
882 else if( id == KaxChapters::ClassInfos.GlobalId )
884 msg_Dbg( p_input, "| | | = chapters at %lld", i_pos );
885 p_sys->i_chapters_position = p_sys->segment->GetGlobalPosition( i_pos );
891 msg_Dbg( p_input, "| | + Unknow (%s)", typeid(*el).name() );
896 else if( EbmlId( *el1 ) == KaxCues::ClassInfos.GlobalId )
898 msg_Dbg( p_input, "| + Cues" );
900 else if( EbmlId( *el1 ) == KaxCluster::ClassInfos.GlobalId )
902 msg_Dbg( p_input, "| + Cluster" );
903 p_sys->cluster = (KaxCluster*)el1;
906 /* stop parsing the stream */
909 else if( EbmlId( *el1 ) == KaxAttachements::ClassInfos.GlobalId )
911 msg_Dbg( p_input, "| + Attachements FIXME TODO (but probably never supported)" );
913 else if( EbmlId( *el1 ) == KaxChapters::ClassInfos.GlobalId )
915 msg_Dbg( p_input, "| + Chapters FIXME TODO" );
917 else if( EbmlId( *el1 ) == KaxTag::ClassInfos.GlobalId )
919 msg_Dbg( p_input, "| + Tags FIXME TODO" );
923 msg_Dbg( p_input, "| + Unknow (%s)", typeid(*el1).name() );
927 if( p_sys->cluster == NULL )
929 msg_Err( p_input, "cannot find any cluster, damaged file ?" );
933 if( p_sys->i_chapters_position >= 0 )
935 msg_Warn( p_input, "chapters unsupported" );
939 if( p_sys->i_cues_position == -1 && config_GetInt( p_input, "mkv-index" ) != 0 )
941 int64_t i_sav_position = p_sys->in->getFilePointer();
944 /* parse to find cues gathering info on all clusters */
945 msg_Dbg( p_input, "no cues referenced, looking for one" );
947 /* ugly but like easier */
948 p_sys->in->setFilePointer( p_sys->cluster->GetElementPosition(), seek_beginning );
950 ep = new EbmlParser( p_sys->es, p_sys->segment );
951 while( ( el = ep->Get() ) != NULL )
953 if( EbmlId( *el ) == KaxCluster::ClassInfos.GlobalId )
955 int64_t i_pos = el->GetElementPosition();
957 msg_Dbg( p_input, "found a cluster at %lld", i_pos );
959 else if( EbmlId( *el ) == KaxCues::ClassInfos.GlobalId )
961 msg_Dbg( p_input, "found a Cues !" );
965 msg_Dbg( p_input, "lookind done." );
967 p_sys->in->setFilePointer( i_sav_position, seek_beginning );
971 /* *** Load the cue if found *** */
972 if( p_sys->i_cues_position >= 0 )
974 int64_t i_sav_position = p_sys->in->getFilePointer();
978 msg_Dbg( p_input, "loading cues" );
979 p_sys->in->setFilePointer( p_sys->i_cues_position, seek_beginning );
980 cues = p_sys->es->FindNextID( KaxCues::ClassInfos, 0xFFFFFFFFL);
982 ep = new EbmlParser( p_sys->es, cues );
983 while( ( el = ep->Get() ) != NULL )
985 if( EbmlId( *el ) == KaxCuePoint::ClassInfos.GlobalId )
987 #define idx p_sys->index[p_sys->i_index]
990 idx.i_block_number= -1;
993 idx.b_key = VLC_TRUE;
996 while( ( el = ep->Get() ) != NULL )
998 if( EbmlId( *el ) == KaxCueTime::ClassInfos.GlobalId )
1000 KaxCueTime &ctime = *(KaxCueTime*)el;
1002 ctime.ReadData( p_sys->es->I_O() );
1004 idx.i_time = uint64( ctime ) * (mtime_t)1000000000 / p_sys->i_timescale;
1006 else if( EbmlId( *el ) == KaxCueTrackPositions::ClassInfos.GlobalId )
1009 while( ( el = ep->Get() ) != NULL )
1011 if( EbmlId( *el ) == KaxCueTrack::ClassInfos.GlobalId )
1013 KaxCueTrack &ctrack = *(KaxCueTrack*)el;
1015 ctrack.ReadData( p_sys->es->I_O() );
1016 idx.i_track = uint16( ctrack );
1018 else if( EbmlId( *el ) == KaxCueClusterPosition::ClassInfos.GlobalId )
1020 KaxCueClusterPosition &ccpos = *(KaxCueClusterPosition*)el;
1022 ccpos.ReadData( p_sys->es->I_O() );
1023 idx.i_position = p_sys->segment->GetGlobalPosition( uint64( ccpos ) );
1025 else if( EbmlId( *el ) == KaxCueBlockNumber::ClassInfos.GlobalId )
1027 KaxCueBlockNumber &cbnum = *(KaxCueBlockNumber*)el;
1029 cbnum.ReadData( p_sys->es->I_O() );
1030 idx.i_block_number = uint32( cbnum );
1034 msg_Dbg( p_input, " * Unknow (%s)", typeid(*el).name() );
1041 msg_Dbg( p_input, " * Unknow (%s)", typeid(*el).name() );
1046 msg_Dbg( p_input, " * added time=%lld pos=%lld track=%d bnum=%d",
1047 idx.i_time, idx.i_position, idx.i_track, idx.i_block_number );
1050 if( p_sys->i_index >= p_sys->i_index_max )
1052 p_sys->i_index_max += 1024;
1053 p_sys->index = (mkv_index_t*)realloc( p_sys->index, sizeof( mkv_index_t ) * p_sys->i_index_max );
1059 msg_Dbg( p_input, " * Unknow (%s)", typeid(*el).name() );
1065 msg_Dbg( p_input, "loading cues done." );
1066 p_sys->in->setFilePointer( i_sav_position, seek_beginning );
1069 if( p_sys->i_index <= 0 )
1071 /* FIXME FIXME FIXME */
1072 msg_Warn( p_input, "no cues found -> unseekable stream for now FIXME" );
1073 p_input->stream.b_seekable = VLC_FALSE;
1074 /* FIXME FIXME FIXME */
1077 /* Create one program */
1078 vlc_mutex_lock( &p_input->stream.stream_lock );
1079 if( input_InitStream( p_input, 0 ) == -1)
1081 vlc_mutex_unlock( &p_input->stream.stream_lock );
1082 msg_Err( p_input, "cannot init stream" );
1085 if( input_AddProgram( p_input, 0, 0) == NULL )
1087 vlc_mutex_unlock( &p_input->stream.stream_lock );
1088 msg_Err( p_input, "cannot add program" );
1091 p_input->stream.p_selected_program = p_input->stream.pp_programs[0];
1092 if( p_sys->f_duration > 1001.0 )
1094 mtime_t i_duration = (mtime_t)( p_sys->f_duration / 1000.0 );
1095 p_input->stream.i_mux_rate = p_input->stream.p_selected_area->i_size / 50 / i_duration;
1099 p_input->stream.i_mux_rate = 0;
1101 vlc_mutex_unlock( &p_input->stream.stream_lock );
1104 msg_Dbg( p_input, "found %d es", p_sys->i_track );
1105 for( i_track = 0; i_track < p_sys->i_track; i_track++ )
1107 #define tk p_sys->track[i_track]
1108 if( tk.i_cat == UNKNOWN_ES )
1110 msg_Warn( p_input, "invalid track[%d, n=%d]", i_track, tk.i_number );
1114 tk.p_es = input_AddES( p_input,
1115 p_input->stream.p_selected_program,
1118 tk.psz_language, 0 );
1119 if( !strcmp( tk.psz_codec, "V_MS/VFW/FOURCC" ) )
1121 if( tk.i_extra_data < (int)sizeof( BITMAPINFOHEADER ) )
1123 msg_Err( p_input, "missing/invalid BITMAPINFOHEADER" );
1124 tk.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
1128 BITMAPINFOHEADER *p_bih = (BITMAPINFOHEADER*)tk.p_extra_data;
1130 p_bih->biSize = GetDWLE( &p_bih->biSize );
1131 p_bih->biWidth = GetDWLE( &p_bih->biWidth );
1132 p_bih->biHeight = GetDWLE( &p_bih->biHeight );
1133 p_bih->biPlanes = GetWLE( &p_bih->biPlanes );
1134 p_bih->biBitCount = GetWLE( &p_bih->biBitCount );
1135 p_bih->biCompression = GetFOURCC( &p_bih->biCompression );
1136 p_bih->biSizeImage = GetDWLE( &p_bih->biSizeImage );
1137 p_bih->biXPelsPerMeter = GetDWLE( &p_bih->biXPelsPerMeter );
1138 p_bih->biYPelsPerMeter = GetDWLE( &p_bih->biYPelsPerMeter );
1139 p_bih->biClrUsed = GetDWLE( &p_bih->biClrUsed );
1140 p_bih->biClrImportant = GetDWLE( &p_bih->biClrImportant );
1143 tk.i_codec = p_bih->biCompression;
1144 tk.p_es->p_bitmapinfoheader = p_bih;
1147 else if( !strcmp( tk.psz_codec, "V_MPEG1" ) ||
1148 !strcmp( tk.psz_codec, "V_MPEG2" ) )
1150 tk.i_codec = VLC_FOURCC( 'm', 'p', 'g', 'v' );
1152 else if( !strncmp( tk.psz_codec, "V_MPEG4", 7 ) )
1154 BITMAPINFOHEADER *p_bih;
1156 tk.i_extra_data = sizeof( BITMAPINFOHEADER );
1157 tk.p_extra_data = (uint8_t*)malloc( tk.i_extra_data );
1159 p_bih = (BITMAPINFOHEADER*)tk.p_extra_data;
1160 memset( p_bih, 0, sizeof( BITMAPINFOHEADER ) );
1161 p_bih->biSize = sizeof( BITMAPINFOHEADER );
1162 p_bih->biWidth = tk.i_width;
1163 p_bih->biHeight= tk.i_height;
1165 if( !strcmp( tk.psz_codec, "V_MPEG4/MS/V3" ) )
1167 tk.i_codec = VLC_FOURCC( 'D', 'I', 'V', '3' );
1171 tk.i_codec = VLC_FOURCC( 'm', 'p', '4', 'v' );
1174 else if( !strcmp( tk.psz_codec, "A_MS/ACM" ) )
1176 if( tk.i_extra_data < (int)sizeof( WAVEFORMATEX ) )
1178 msg_Err( p_input, "missing/invalid WAVEFORMATEX" );
1179 tk.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
1183 WAVEFORMATEX *p_wf = (WAVEFORMATEX*)tk.p_extra_data;
1185 p_wf->wFormatTag = GetWLE( &p_wf->wFormatTag );
1186 p_wf->nChannels = GetWLE( &p_wf->nChannels );
1187 p_wf->nSamplesPerSec = GetDWLE( &p_wf->nSamplesPerSec );
1188 p_wf->nAvgBytesPerSec = GetDWLE( &p_wf->nAvgBytesPerSec );
1189 p_wf->nBlockAlign = GetWLE( &p_wf->nBlockAlign );
1190 p_wf->wBitsPerSample = GetWLE( &p_wf->wBitsPerSample );
1191 p_wf->cbSize = GetWLE( &p_wf->cbSize );
1193 switch( p_wf->wFormatTag )
1195 case WAVE_FORMAT_PCM:
1196 tk.i_codec = VLC_FOURCC( 'a', 'r', 'a', 'w' );
1198 case WAVE_FORMAT_ADPCM:
1199 tk.i_codec = VLC_FOURCC( 'm', 's', 0x00, 0x02 );
1201 case WAVE_FORMAT_ALAW:
1202 tk.i_codec = VLC_FOURCC( 'a', 'l', 'a', 'w' );
1204 case WAVE_FORMAT_MULAW:
1205 tk.i_codec = VLC_FOURCC( 'm', 'l', 'a', 'w' );
1207 case WAVE_FORMAT_IMA_ADPCM:
1208 tk.i_codec = VLC_FOURCC( 'm', 's', 0x00, 0x11 );
1210 case WAVE_FORMAT_MPEG:
1211 case WAVE_FORMAT_MPEGLAYER3:
1212 tk.i_codec = VLC_FOURCC( 'm', 'p', 'g', 'a' );
1214 case WAVE_FORMAT_A52:
1215 tk.i_codec = VLC_FOURCC( 'a', '5', '2', ' ' );
1217 case WAVE_FORMAT_WMA1:
1218 tk.i_codec = VLC_FOURCC( 'w', 'm', 'a', '1' );
1220 case WAVE_FORMAT_WMA2:
1221 tk.i_codec = VLC_FOURCC( 'w', 'm', 'a', '2' );
1223 case WAVE_FORMAT_WMA3:
1224 tk.i_codec = VLC_FOURCC( 'w', 'm', 'a', '3' );
1227 msg_Err( p_input, "unknown wFormatTag=0x%x", p_wf->wFormatTag );
1228 tk.i_codec = VLC_FOURCC( 'm', 's', p_wf->wFormatTag >> 8, p_wf->wFormatTag&0xff );
1231 tk.p_es->p_waveformatex = p_wf;
1234 else if( !strcmp( tk.psz_codec, "A_MPEG/L3" ) ||
1235 !strcmp( tk.psz_codec, "A_MPEG/L2" ) ||
1236 !strcmp( tk.psz_codec, "A_MPEG/L1" ) )
1238 tk.i_codec = VLC_FOURCC( 'm', 'p', 'g', 'a' );
1240 else if( !strcmp( tk.psz_codec, "A_AC3" ) )
1242 tk.i_codec = VLC_FOURCC( 'a', '5', '2', ' ' );
1244 else if( !strcmp( tk.psz_codec, "A_DTS" ) )
1246 tk.i_codec = VLC_FOURCC( 'd', 't', 's', ' ' );
1248 else if( !strcmp( tk.psz_codec, "A_VORBIS" ) )
1250 tk.i_codec = VLC_FOURCC( 'v', 'o', 'r', 'b' );
1251 tk.i_data_init = tk.i_extra_data;
1252 tk.p_data_init = tk.p_extra_data;
1254 else if( !strncmp( tk.psz_codec, "A_AAC/MPEG2/", strlen( "A_AAC/MPEG2/" ) ) ||
1255 !strncmp( tk.psz_codec, "A_AAC/MPEG4/", strlen( "A_AAC/MPEG4/" ) ) )
1257 int i_profile, i_srate;
1258 static int i_sample_rates[] =
1260 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
1261 16000, 12000, 11025, 8000, 7350, 0, 0, 0
1265 tk.i_codec = VLC_FOURCC( 'm', 'p', '4', 'a' );
1266 /* create data for faad (MP4DecSpecificDescrTag)*/
1268 if( !strcmp( &tk.psz_codec[12], "MAIN" ) )
1272 else if( !strcmp( &tk.psz_codec[12], "LC" ) )
1276 else if( !strcmp( &tk.psz_codec[12], "SSR" ) )
1285 for( i_srate = 0; i_srate < 13; i_srate++ )
1287 if( i_sample_rates[i_srate] == tk.i_samplerate )
1292 msg_Dbg( p_input, "profile=%d srate=%d", i_profile, i_srate );
1294 tk.i_extra_data = sizeof( WAVEFORMATEX ) + 2;
1295 tk.p_extra_data = (uint8_t*)malloc( tk.i_extra_data );
1296 p_wf = (WAVEFORMATEX*)tk.p_extra_data;
1298 p_wf->wFormatTag = WAVE_FORMAT_UNKNOWN;
1299 p_wf->nChannels = tk.i_channels;
1300 p_wf->nSamplesPerSec = tk.i_samplerate;
1301 p_wf->nAvgBytesPerSec = 0;
1302 p_wf->nBlockAlign = 0;
1303 p_wf->wBitsPerSample = 0;
1306 tk.p_extra_data[sizeof( WAVEFORMATEX )+ 0] = ((i_profile + 1) << 3) | ((i_srate&0xe) >> 1);
1307 tk.p_extra_data[sizeof( WAVEFORMATEX )+ 1] = ((i_srate & 0x1) << 7) | (tk.i_channels << 3);
1309 tk.p_es->p_waveformatex = p_wf;
1311 else if( !strcmp( tk.psz_codec, "A_PCM/INT/BIG" ) ||
1312 !strcmp( tk.psz_codec, "A_PCM/INT/LIT" ) ||
1313 !strcmp( tk.psz_codec, "A_PCM/FLOAT/IEEE" ) )
1317 tk.i_extra_data = sizeof( WAVEFORMATEX );
1318 tk.p_extra_data = (uint8_t*)malloc( tk.i_extra_data );
1320 p_wf = (WAVEFORMATEX*)tk.p_extra_data;
1322 if( !strncmp( &tk.psz_codec[6], "INT", 3 ) )
1324 p_wf->wFormatTag = WAVE_FORMAT_PCM;
1328 p_wf->wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
1330 p_wf->nChannels = tk.i_channels;
1331 p_wf->nSamplesPerSec = tk.i_samplerate;
1332 p_wf->nAvgBytesPerSec = 0;
1333 p_wf->nBlockAlign = ( tk.i_bitspersample + 7 ) / 8 * tk.i_channels;
1334 p_wf->wBitsPerSample = tk.i_bitspersample;
1337 tk.p_es->p_waveformatex = p_wf;
1339 if( !strcmp( tk.psz_codec, "A_PCM/INT/BIG" ) )
1341 tk.i_codec = VLC_FOURCC( 't', 'w', 'o', 's' );
1345 tk.i_codec = VLC_FOURCC( 'a', 'r', 'a', 'w' );
1348 else if( !strcmp( tk.psz_codec, "S_TEXT/UTF8" ) )
1350 tk.i_codec = VLC_FOURCC( 's', 'u', 'b', 't' );
1354 msg_Err( p_input, "unknow codec id=`%s'", tk.psz_codec );
1355 tk.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
1358 tk.p_es->i_fourcc = tk.i_codec;
1362 /* select track all video, one audio, no spu TODO : improve */
1363 b_audio_selected = VLC_FALSE;
1364 i_audio_channel = 0;
1366 for( i_track = 0; i_track < p_sys->i_track; i_track++ )
1368 #define tk p_sys->track[i_track]
1372 vlc_mutex_lock( &p_input->stream.stream_lock );
1373 input_SelectES( p_input, tk.p_es );
1374 vlc_mutex_unlock( &p_input->stream.stream_lock );
1378 if( ( !b_audio_selected && config_GetInt( p_input, "audio-channel" ) < 0 ) ||
1379 i_audio_channel == config_GetInt( p_input, "audio-channel" ) )
1381 vlc_mutex_lock( &p_input->stream.stream_lock );
1382 input_SelectES( p_input, tk.p_es );
1383 vlc_mutex_unlock( &p_input->stream.stream_lock );
1385 b_audio_selected = tk.p_es->p_decoder_fifo ? VLC_TRUE : VLC_FALSE;
1390 if( i_spu_channel == config_GetInt( p_input, "spu-channel" ) )
1392 vlc_mutex_lock( &p_input->stream.stream_lock );
1393 input_SelectES( p_input, tk.p_es );
1394 vlc_mutex_unlock( &p_input->stream.stream_lock );
1402 if( !b_audio_selected )
1404 msg_Warn( p_input, "cannot find/select audio track" );
1413 return VLC_EGENERIC;
1416 /*****************************************************************************
1417 * Deactivate: frees unused data
1418 *****************************************************************************/
1419 static void Deactivate( vlc_object_t *p_this )
1421 input_thread_t *p_input = (input_thread_t *)p_this;
1422 demux_sys_t *p_sys = p_input->p_demux_data;
1426 for( i_track = 0; i_track < p_sys->i_track; i_track++ )
1428 #define tk p_sys->track[i_track]
1431 free( tk.psz_codec );
1433 if( tk.psz_language )
1435 free( tk.psz_language );
1439 free( p_sys->track );
1448 static int BlockGet( input_thread_t *p_input, KaxBlock **pp_block, int64_t *pi_ref1, int64_t *pi_ref2, int64_t *pi_duration )
1450 demux_sys_t *p_sys = p_input->p_demux_data;
1461 if( p_input->b_die )
1463 return VLC_EGENERIC;
1466 el = p_sys->ep->Get();
1467 i_level = p_sys->ep->GetLevel();
1469 if( el == NULL && *pp_block != NULL )
1476 if( p_sys->ep->GetLevel() > 1 )
1481 msg_Warn( p_input, "EOF" );
1482 return VLC_EGENERIC;
1488 if( EbmlId( *el ) == KaxCluster::ClassInfos.GlobalId )
1490 p_sys->cluster = (KaxCluster*)el;
1493 else if( EbmlId( *el ) == KaxCues::ClassInfos.GlobalId )
1495 msg_Warn( p_input, "find KaxCues FIXME" );
1496 return VLC_EGENERIC;
1500 msg_Dbg( p_input, "unknown (%s)", typeid( el ).name() );
1503 else if( i_level == 2 )
1505 if( EbmlId( *el ) == KaxClusterTimecode::ClassInfos.GlobalId )
1507 KaxClusterTimecode &ctc = *(KaxClusterTimecode*)el;
1509 ctc.ReadData( p_sys->es->I_O() );
1510 p_sys->cluster->InitTimecode( uint64( ctc ), p_sys->i_timescale );
1512 else if( EbmlId( *el ) == KaxBlockGroup::ClassInfos.GlobalId )
1517 else if( i_level == 3 )
1519 if( EbmlId( *el ) == KaxBlock::ClassInfos.GlobalId )
1521 *pp_block = (KaxBlock*)el;
1523 (*pp_block)->ReadData( p_sys->es->I_O() );
1524 (*pp_block)->SetParent( *p_sys->cluster );
1528 else if( EbmlId( *el ) == KaxBlockDuration::ClassInfos.GlobalId )
1530 KaxBlockDuration &dur = *(KaxBlockDuration*)el;
1532 dur.ReadData( p_sys->es->I_O() );
1533 *pi_duration = uint64( dur );
1535 else if( EbmlId( *el ) == KaxReferenceBlock::ClassInfos.GlobalId )
1537 KaxReferenceBlock &ref = *(KaxReferenceBlock*)el;
1539 ref.ReadData( p_sys->es->I_O() );
1540 if( *pi_ref1 == -1 )
1542 *pi_ref1 = int64( ref );
1546 *pi_ref2 = int64( ref );
1552 msg_Err( p_input, "invalid level = %d", i_level );
1553 return VLC_EGENERIC;
1558 static void BlockDecode( input_thread_t *p_input, KaxBlock *block, mtime_t i_pts, mtime_t i_duration )
1560 demux_sys_t *p_sys = p_input->p_demux_data;
1563 pes_packet_t *p_pes;
1566 #define tk p_sys->track[i_track]
1567 for( i_track = 0; i_track < p_sys->i_track; i_track++ )
1569 if( tk.i_number == block->TrackNum() )
1575 if( i_track >= p_sys->i_track )
1577 msg_Err( p_input, "invalid track number=%d", block->TrackNum() );
1583 if( tk.p_es->p_decoder_fifo == NULL )
1589 if( ( p_pes = input_NewPES( p_input->p_method_data ) ) == NULL )
1591 msg_Err( p_input, "cannot allocate PES" );
1595 p_pes->i_pts = i_pts;
1596 p_pes->i_dts = i_pts;
1597 if( tk.i_cat == SPU_ES )
1599 /* special case : dts mean end of display */
1600 if( i_duration > 0 )
1602 /* FIXME not sure about that */
1603 p_pes->i_dts += i_duration * 1000;// * (mtime_t) 1000 / p_sys->i_timescale;
1612 p_pes->p_first = p_pes->p_last = NULL;
1613 p_pes->i_nb_data = 0;
1614 p_pes->i_pes_size = 0;
1616 for( i = 0; i < block->NumberFrames(); i++ )
1618 data_packet_t *p_data = NULL;
1619 DataBuffer &data = block->GetBuffer(i);
1621 if( ( p_data = input_NewPacket( p_input->p_method_data, data.Size() ) ) != NULL )
1623 memcpy( p_data->p_payload_start, data.Buffer(), data.Size() );
1625 p_data->p_payload_end = p_data->p_payload_start + data.Size();
1627 if( p_pes->p_first == NULL )
1629 p_pes->p_first = p_data;
1633 p_pes->p_last->p_next = p_data;
1636 p_pes->i_pes_size += data.Size();
1637 p_pes->p_last = p_data;
1640 if( tk.i_cat == SPU_ES && p_pes->p_first && p_pes->i_pes_size > 0 )
1642 p_pes->p_first->p_payload_end[-1] = '\0';
1645 if( !tk.b_inited && tk.i_data_init > 0 )
1647 pes_packet_t *p_init;
1648 data_packet_t *p_data;
1650 msg_Dbg( p_input, "sending header (%d bytes)", tk.i_data_init );
1652 p_init = input_NewPES( p_input->p_method_data );
1654 p_data = input_NewPacket( p_input->p_method_data, tk.i_data_init );
1655 memcpy( p_data->p_payload_start, tk.p_data_init, tk.i_data_init );
1656 p_data->p_payload_end = p_data->p_payload_start + tk.i_data_init;
1658 p_init->p_first = p_init->p_last = p_data;
1659 p_init->i_nb_data = 1;
1660 p_init->i_pes_size = tk.i_data_init;
1662 input_DecodePES( tk.p_es->p_decoder_fifo, p_init );
1664 tk.b_inited = VLC_TRUE;
1666 input_DecodePES( tk.p_es->p_decoder_fifo, p_pes );
1671 static void Seek( input_thread_t *p_input, mtime_t i_date, int i_percent)
1673 demux_sys_t *p_sys = p_input->p_demux_data;
1676 int64_t i_block_duration;
1677 int64_t i_block_ref1;
1678 int64_t i_block_ref2;
1681 int i_track_skipping;
1684 msg_Dbg( p_input, "seek request to %lld (%d%%)", i_date, i_percent );
1686 for( i_index = 0; i_index < p_sys->i_index; i_index++ )
1688 if( p_sys->index[i_index].i_time >= i_date )
1699 msg_Dbg( p_input, "seek got %lld (%d%%)",
1700 p_sys->index[i_index].i_time, (int)(100 * p_sys->index[i_index].i_position /p_input->stream.p_selected_area->i_size ) );
1704 p_sys->in->setFilePointer( p_sys->index[i_index].i_position, seek_beginning );
1706 p_sys->ep = new EbmlParser( p_sys->es, p_sys->segment );
1708 /* now parse until key frame */
1709 #define tk p_sys->track[i_track]
1710 i_track_skipping = 0;
1711 for( i_track = 0; i_track < p_sys->i_track; i_track++ )
1713 if( tk.i_cat == VIDEO_ES )
1715 tk.b_search_keyframe = VLC_TRUE;
1721 while( i_track_skipping > 0 )
1723 if( BlockGet( p_input, &block, &i_block_ref1, &i_block_ref2, &i_block_duration ) )
1725 msg_Warn( p_input, "cannot get block EOF?" );
1730 p_sys->i_pts = block->GlobalTimecode() * (mtime_t) 1000 / p_sys->i_timescale;
1732 for( i_track = 0; i_track < p_sys->i_track; i_track++ )
1734 if( tk.i_number == block->TrackNum() )
1740 if( i_track < p_sys->i_track )
1742 if( tk.i_cat == VIDEO_ES && i_block_ref1 == -1 && tk.b_search_keyframe )
1744 tk.b_search_keyframe = VLC_FALSE;
1747 if( tk.i_cat == VIDEO_ES && !tk.b_search_keyframe )
1749 BlockDecode( p_input, block, 0, 0 );
1758 /*****************************************************************************
1759 * Demux: reads and demuxes data packets
1760 *****************************************************************************
1761 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
1762 *****************************************************************************/
1763 static int Demux( input_thread_t * p_input )
1765 demux_sys_t *p_sys = p_input->p_demux_data;
1766 mtime_t i_start_pts;
1768 int64_t i_block_duration;
1769 int64_t i_block_ref1;
1770 int64_t i_block_ref2;
1772 if( p_input->stream.p_selected_program->i_synchro_state == SYNCHRO_REINIT )
1774 mtime_t i_duration = (mtime_t)( p_sys->f_duration / 1000 );
1778 i_date = (mtime_t)1000000 *
1779 (mtime_t)i_duration*
1780 (mtime_t)p_sys->in->getFilePointer() /
1781 (mtime_t)p_input->stream.p_selected_area->i_size;
1783 i_percent = 100 * p_sys->in->getFilePointer() /
1784 p_input->stream.p_selected_area->i_size;
1786 Seek( p_input, i_date, i_percent);
1789 i_start_pts = p_sys->i_pts;
1795 if( BlockGet( p_input, &block, &i_block_ref1, &i_block_ref2, &i_block_duration ) )
1797 msg_Warn( p_input, "cannot get block EOF?" );
1802 p_sys->i_pts = block->GlobalTimecode() * (mtime_t) 1000 / p_sys->i_timescale;
1804 if( p_sys->i_pts > 0 )
1806 input_ClockManageRef( p_input,
1807 p_input->stream.p_selected_program,
1808 p_sys->i_pts * 9 / 100 );
1811 i_pts = input_ClockGetTS( p_input,
1812 p_input->stream.p_selected_program,
1813 p_sys->i_pts * 9 / 100 );
1815 BlockDecode( p_input, block, i_pts, i_block_duration );
1819 if( i_start_pts == -1 )
1821 i_start_pts = p_sys->i_pts;
1823 else if( p_sys->i_pts > i_start_pts + (mtime_t)100000)