+ return stream_Read( s, p_buffer, i_size );
+}
+void vlc_stream_io_callback::setFilePointer(int64_t i_offset, seek_mode mode )
+{
+ int64_t i_pos;
+
+ switch( mode )
+ {
+ case seek_beginning:
+ i_pos = i_offset;
+ break;
+ case seek_end:
+ i_pos = stream_Size( s ) - i_offset;
+ break;
+ default:
+ i_pos= stream_Tell( s ) + i_offset;
+ break;
+ }
+
+ if( i_pos < 0 || i_pos >= stream_Size( s ) )
+ {
+ mb_eof = VLC_TRUE;
+ return;
+ }
+
+ mb_eof = VLC_FALSE;
+ if( stream_Seek( s, i_pos ) )
+ {
+ mb_eof = VLC_TRUE;
+ }
+ return;
+}
+size_t vlc_stream_io_callback::write( const void *p_buffer, size_t i_size )
+{
+ return 0;
+}
+uint64 vlc_stream_io_callback::getFilePointer( void )
+{
+ if ( s == NULL )
+ return 0;
+ return stream_Tell( s );
+}
+void vlc_stream_io_callback::close( void )
+{
+ return;
+}
+
+
+/*****************************************************************************
+ * Ebml Stream parser
+ *****************************************************************************/
+EbmlParser::EbmlParser( EbmlStream *es, EbmlElement *el_start, demux_t *p_demux )
+{
+ int i;
+
+ m_es = es;
+ m_got = NULL;
+ m_el[0] = el_start;
+ mi_remain_size[0] = el_start->GetSize();
+
+ for( i = 1; i < 6; i++ )
+ {
+ m_el[i] = NULL;
+ }
+ mi_level = 1;
+ mi_user_level = 1;
+ mb_keep = VLC_FALSE;
+ mb_dummy = config_GetInt( p_demux, "mkv-use-dummy" );
+}
+
+EbmlParser::~EbmlParser( void )
+{
+ int i;
+
+ for( i = 1; i < mi_level; i++ )
+ {
+ if( !mb_keep )
+ {
+ delete m_el[i];
+ }
+ mb_keep = VLC_FALSE;
+ }
+}
+
+EbmlElement* EbmlParser::UnGet( uint64 i_block_pos, uint64 i_cluster_pos )
+{
+ if ( mi_user_level > mi_level )
+ {
+ while ( mi_user_level != mi_level )
+ {
+ delete m_el[mi_user_level];
+ m_el[mi_user_level] = NULL;
+ mi_user_level--;
+ }
+ }
+ m_got = NULL;
+ mb_keep = VLC_FALSE;
+ if ( m_el[1]->GetElementPosition() == i_cluster_pos )
+ {
+ m_es->I_O().setFilePointer( i_block_pos, seek_beginning );
+ return (EbmlMaster*) m_el[1];
+ }
+ else
+ {
+ // seek to the previous Cluster
+ m_es->I_O().setFilePointer( i_cluster_pos, seek_beginning );
+ mi_level--;
+ mi_user_level--;
+ delete m_el[mi_level];
+ m_el[mi_level] = NULL;
+ return NULL;
+ }
+}
+
+void EbmlParser::Up( void )
+{
+ if( mi_user_level == mi_level )
+ {
+ fprintf( stderr," arrrrrrrrrrrrrg Up cannot escape itself\n" );
+ }
+
+ mi_user_level--;
+}
+
+void EbmlParser::Down( void )
+{
+ mi_user_level++;
+ mi_level++;
+}
+
+void EbmlParser::Keep( void )
+{
+ mb_keep = VLC_TRUE;
+}
+
+int EbmlParser::GetLevel( void )
+{
+ return mi_user_level;
+}
+
+void EbmlParser::Reset( demux_t *p_demux )
+{
+ while ( mi_level > 0)
+ {
+ delete m_el[mi_level];
+ m_el[mi_level] = NULL;
+ mi_level--;
+ }
+ mi_user_level = mi_level = 1;
+#if LIBEBML_VERSION >= 0x000704
+ // a little faster and cleaner
+ m_es->I_O().setFilePointer( static_cast<KaxSegment*>(m_el[0])->GetGlobalPosition(0) );
+#else
+ m_es->I_O().setFilePointer( m_el[0]->GetElementPosition() + m_el[0]->ElementSize(true) - m_el[0]->GetSize() );
+#endif
+ mb_dummy = config_GetInt( p_demux, "mkv-use-dummy" );
+}
+
+EbmlElement *EbmlParser::Get( void )
+{
+ int i_ulev = 0;
+
+ if( mi_user_level != mi_level )
+ {
+ return NULL;
+ }
+ if( m_got )
+ {
+ EbmlElement *ret = m_got;
+ m_got = NULL;
+
+ return ret;
+ }
+
+ if( m_el[mi_level] )
+ {
+ m_el[mi_level]->SkipData( *m_es, m_el[mi_level]->Generic().Context );
+ if( !mb_keep )
+ {
+ delete m_el[mi_level];
+ }
+ mb_keep = VLC_FALSE;
+ }
+
+ m_el[mi_level] = m_es->FindNextElement( m_el[mi_level - 1]->Generic().Context, i_ulev, 0xFFFFFFFFL, mb_dummy != 0, 1 );
+// mi_remain_size[mi_level] = m_el[mi_level]->GetSize();
+ if( i_ulev > 0 )
+ {
+ while( i_ulev > 0 )
+ {
+ if( mi_level == 1 )
+ {
+ mi_level = 0;
+ return NULL;
+ }
+
+ delete m_el[mi_level - 1];
+ m_got = m_el[mi_level -1] = m_el[mi_level];
+ m_el[mi_level] = NULL;
+
+ mi_level--;
+ i_ulev--;
+ }
+ return NULL;
+ }
+ else if( m_el[mi_level] == NULL )
+ {
+ fprintf( stderr," m_el[mi_level] == NULL\n" );
+ }
+
+ return m_el[mi_level];
+}
+
+
+/*****************************************************************************
+ * Tools
+ * * LoadCues : load the cues element and update index
+ *
+ * * LoadTags : load ... the tags element
+ *
+ * * InformationCreate : create all information, load tags if present
+ *
+ *****************************************************************************/
+void matroska_segment_c::LoadCues( )
+{
+ int64_t i_sav_position = es.I_O().getFilePointer();
+ EbmlParser *ep;
+ EbmlElement *el, *cues;
+
+ /* *** Load the cue if found *** */
+ if( i_cues_position < 0 )
+ {
+ msg_Warn( &sys.demuxer, "no cues/empty cues found->seek won't be precise" );
+
+// IndexAppendCluster( cluster );
+ }
+
+ vlc_bool_t b_seekable;
+
+ stream_Control( sys.demuxer.s, STREAM_CAN_FASTSEEK, &b_seekable );
+ if( !b_seekable )
+ return;
+
+ msg_Dbg( &sys.demuxer, "loading cues" );
+ es.I_O().setFilePointer( i_cues_position, seek_beginning );
+ cues = es.FindNextID( KaxCues::ClassInfos, 0xFFFFFFFFL);
+
+ if( cues == NULL )
+ {
+ msg_Err( &sys.demuxer, "cannot load cues (broken seekhead or file)" );
+ es.I_O().setFilePointer( i_sav_position, seek_beginning );
+ return;
+ }
+
+ ep = new EbmlParser( &es, cues, &sys.demuxer );
+ while( ( el = ep->Get() ) != NULL )
+ {
+ if( MKV_IS_ID( el, KaxCuePoint ) )
+ {
+#define idx p_indexes[i_index]
+
+ idx.i_track = -1;
+ idx.i_block_number= -1;
+ idx.i_position = -1;
+ idx.i_time = 0;
+ idx.b_key = VLC_TRUE;
+
+ ep->Down();
+ while( ( el = ep->Get() ) != NULL )
+ {
+ if( MKV_IS_ID( el, KaxCueTime ) )
+ {
+ KaxCueTime &ctime = *(KaxCueTime*)el;
+
+ ctime.ReadData( es.I_O() );
+
+ idx.i_time = uint64( ctime ) * i_timescale / (mtime_t)1000;
+ }
+ else if( MKV_IS_ID( el, KaxCueTrackPositions ) )
+ {
+ ep->Down();
+ while( ( el = ep->Get() ) != NULL )
+ {
+ if( MKV_IS_ID( el, KaxCueTrack ) )
+ {
+ KaxCueTrack &ctrack = *(KaxCueTrack*)el;
+
+ ctrack.ReadData( es.I_O() );
+ idx.i_track = uint16( ctrack );
+ }
+ else if( MKV_IS_ID( el, KaxCueClusterPosition ) )
+ {
+ KaxCueClusterPosition &ccpos = *(KaxCueClusterPosition*)el;
+
+ ccpos.ReadData( es.I_O() );
+ idx.i_position = segment->GetGlobalPosition( uint64( ccpos ) );
+ }
+ else if( MKV_IS_ID( el, KaxCueBlockNumber ) )
+ {
+ KaxCueBlockNumber &cbnum = *(KaxCueBlockNumber*)el;
+
+ cbnum.ReadData( es.I_O() );
+ idx.i_block_number = uint32( cbnum );
+ }
+ else
+ {
+ msg_Dbg( &sys.demuxer, " * Unknown (%s)", typeid(*el).name() );
+ }
+ }
+ ep->Up();
+ }
+ else
+ {
+ msg_Dbg( &sys.demuxer, " * Unknown (%s)", typeid(*el).name() );
+ }
+ }
+ ep->Up();
+
+#if 0
+ msg_Dbg( &sys.demuxer, " * added time="I64Fd" pos="I64Fd
+ " track=%d bnum=%d", idx.i_time, idx.i_position,
+ idx.i_track, idx.i_block_number );
+#endif
+
+ i_index++;
+ if( i_index >= i_index_max )
+ {
+ i_index_max += 1024;
+ p_indexes = (mkv_index_t*)realloc( p_indexes, sizeof( mkv_index_t ) * i_index_max );
+ }
+#undef idx
+ }
+ else
+ {
+ msg_Dbg( &sys.demuxer, " * Unknown (%s)", typeid(*el).name() );
+ }
+ }
+ delete ep;
+ delete cues;
+
+ b_cues = VLC_TRUE;
+
+ msg_Dbg( &sys.demuxer, "loading cues done." );
+ es.I_O().setFilePointer( i_sav_position, seek_beginning );
+}
+
+void matroska_segment_c::LoadTags( )
+{
+ int64_t i_sav_position = es.I_O().getFilePointer();
+ EbmlParser *ep;
+ EbmlElement *el, *tags;
+
+ msg_Dbg( &sys.demuxer, "loading tags" );
+ es.I_O().setFilePointer( i_tags_position, seek_beginning );
+ tags = es.FindNextID( KaxTags::ClassInfos, 0xFFFFFFFFL);
+
+ if( tags == NULL )
+ {
+ msg_Err( &sys.demuxer, "cannot load tags (broken seekhead or file)" );
+ es.I_O().setFilePointer( i_sav_position, seek_beginning );
+ return;
+ }
+
+ msg_Dbg( &sys.demuxer, "Tags" );
+ ep = new EbmlParser( &es, tags, &sys.demuxer );
+ while( ( el = ep->Get() ) != NULL )
+ {
+ if( MKV_IS_ID( el, KaxTag ) )
+ {
+ msg_Dbg( &sys.demuxer, "+ Tag" );
+ ep->Down();
+ while( ( el = ep->Get() ) != NULL )
+ {
+ if( MKV_IS_ID( el, KaxTagTargets ) )
+ {
+ msg_Dbg( &sys.demuxer, "| + Targets" );
+ ep->Down();
+ while( ( el = ep->Get() ) != NULL )
+ {
+ msg_Dbg( &sys.demuxer, "| | + Unknown (%s)", typeid( *el ).name() );
+ }
+ ep->Up();
+ }
+ else if( MKV_IS_ID( el, KaxTagGeneral ) )
+ {
+ msg_Dbg( &sys.demuxer, "| + General" );
+ ep->Down();
+ while( ( el = ep->Get() ) != NULL )
+ {
+ msg_Dbg( &sys.demuxer, "| | + Unknown (%s)", typeid( *el ).name() );
+ }
+ ep->Up();
+ }
+ else if( MKV_IS_ID( el, KaxTagGenres ) )
+ {
+ msg_Dbg( &sys.demuxer, "| + Genres" );
+ ep->Down();
+ while( ( el = ep->Get() ) != NULL )
+ {
+ msg_Dbg( &sys.demuxer, "| | + Unknown (%s)", typeid( *el ).name() );
+ }
+ ep->Up();
+ }
+ else if( MKV_IS_ID( el, KaxTagAudioSpecific ) )
+ {
+ msg_Dbg( &sys.demuxer, "| + Audio Specific" );
+ ep->Down();
+ while( ( el = ep->Get() ) != NULL )
+ {
+ msg_Dbg( &sys.demuxer, "| | + Unknown (%s)", typeid( *el ).name() );
+ }
+ ep->Up();
+ }
+ else if( MKV_IS_ID( el, KaxTagImageSpecific ) )
+ {
+ msg_Dbg( &sys.demuxer, "| + Images Specific" );
+ ep->Down();
+ while( ( el = ep->Get() ) != NULL )
+ {
+ msg_Dbg( &sys.demuxer, "| | + Unknown (%s)", typeid( *el ).name() );
+ }
+ ep->Up();
+ }
+ else if( MKV_IS_ID( el, KaxTagMultiComment ) )
+ {
+ msg_Dbg( &sys.demuxer, "| + Multi Comment" );
+ }
+ else if( MKV_IS_ID( el, KaxTagMultiCommercial ) )
+ {
+ msg_Dbg( &sys.demuxer, "| + Multi Commercial" );
+ }
+ else if( MKV_IS_ID( el, KaxTagMultiDate ) )
+ {
+ msg_Dbg( &sys.demuxer, "| + Multi Date" );
+ }
+ else if( MKV_IS_ID( el, KaxTagMultiEntity ) )
+ {
+ msg_Dbg( &sys.demuxer, "| + Multi Entity" );
+ }
+ else if( MKV_IS_ID( el, KaxTagMultiIdentifier ) )
+ {
+ msg_Dbg( &sys.demuxer, "| + Multi Identifier" );
+ }
+ else if( MKV_IS_ID( el, KaxTagMultiLegal ) )
+ {
+ msg_Dbg( &sys.demuxer, "| + Multi Legal" );
+ }
+ else if( MKV_IS_ID( el, KaxTagMultiTitle ) )
+ {
+ msg_Dbg( &sys.demuxer, "| + Multi Title" );
+ }
+ else
+ {
+ msg_Dbg( &sys.demuxer, "| + Unknown (%s)", typeid( *el ).name() );
+ }
+ }
+ ep->Up();
+ }
+ else
+ {
+ msg_Dbg( &sys.demuxer, "+ Unknown (%s)", typeid( *el ).name() );
+ }
+ }
+ delete ep;
+ delete tags;
+
+ msg_Dbg( &sys.demuxer, "loading tags done." );
+ es.I_O().setFilePointer( i_sav_position, seek_beginning );
+}
+
+/*****************************************************************************
+ * ParseSeekHead:
+ *****************************************************************************/
+void matroska_segment_c::ParseSeekHead( KaxSeekHead *seekhead )
+{
+ EbmlElement *el;
+ size_t i, j;
+ int i_upper_level = 0;
+
+ msg_Dbg( &sys.demuxer, "| + Seek head" );
+
+ /* Master elements */
+ seekhead->Read( es, seekhead->Generic().Context, i_upper_level, el, true );
+
+ for( i = 0; i < seekhead->ListSize(); i++ )
+ {
+ EbmlElement *l = (*seekhead)[i];
+
+ if( MKV_IS_ID( l, KaxSeek ) )
+ {
+ EbmlMaster *sk = static_cast<EbmlMaster *>(l);
+ EbmlId id = EbmlVoid::ClassInfos.GlobalId;
+ int64_t i_pos = -1;
+
+ for( j = 0; j < sk->ListSize(); j++ )
+ {
+ EbmlElement *l = (*sk)[j];
+
+ if( MKV_IS_ID( l, KaxSeekID ) )
+ {
+ KaxSeekID &sid = *(KaxSeekID*)l;
+ id = EbmlId( sid.GetBuffer(), sid.GetSize() );
+ }
+ else if( MKV_IS_ID( l, KaxSeekPosition ) )
+ {
+ KaxSeekPosition &spos = *(KaxSeekPosition*)l;
+ i_pos = uint64( spos );
+ }
+ else
+ {
+ msg_Dbg( &sys.demuxer, "| | | + Unknown (%s)", typeid(*l).name() );
+ }
+ }
+
+ if( i_pos >= 0 )
+ {
+ if( id == KaxCues::ClassInfos.GlobalId )
+ {
+ msg_Dbg( &sys.demuxer, "| | | = cues at "I64Fd, i_pos );
+ i_cues_position = segment->GetGlobalPosition( i_pos );
+ }
+ else if( id == KaxChapters::ClassInfos.GlobalId )
+ {
+ msg_Dbg( &sys.demuxer, "| | | = chapters at "I64Fd, i_pos );
+ i_chapters_position = segment->GetGlobalPosition( i_pos );
+ }
+ else if( id == KaxTags::ClassInfos.GlobalId )
+ {
+ msg_Dbg( &sys.demuxer, "| | | = tags at "I64Fd, i_pos );
+ i_tags_position = segment->GetGlobalPosition( i_pos );
+ }
+ }
+ }
+ else
+ {
+ msg_Dbg( &sys.demuxer, "| | + Unknown (%s)", typeid(*l).name() );
+ }
+ }
+}
+
+/*****************************************************************************
+ * ParseTrackEntry:
+ *****************************************************************************/
+void matroska_segment_c::ParseTrackEntry( KaxTrackEntry *m )
+{
+ size_t i, j, k, n;
+ bool bSupported = true;
+
+ mkv_track_t *tk;
+
+ msg_Dbg( &sys.demuxer, "| | + Track Entry" );
+
+ tk = new mkv_track_t();
+
+ /* Init the track */
+ memset( tk, 0, sizeof( mkv_track_t ) );
+
+ es_format_Init( &tk->fmt, UNKNOWN_ES, 0 );
+ tk->fmt.psz_language = strdup("English");
+ tk->fmt.psz_description = NULL;
+
+ tk->b_default = VLC_TRUE;
+ tk->b_enabled = VLC_TRUE;
+ tk->b_silent = VLC_FALSE;
+ tk->i_number = tracks.size() - 1;
+ tk->i_extra_data = 0;
+ tk->p_extra_data = NULL;
+ tk->psz_codec = NULL;
+ tk->i_default_duration = 0;
+ tk->f_timecodescale = 1.0;
+
+ tk->b_inited = VLC_FALSE;
+ tk->i_data_init = 0;
+ tk->p_data_init = NULL;
+
+ tk->psz_codec_name = NULL;
+ tk->psz_codec_settings = NULL;
+ tk->psz_codec_info_url = NULL;
+ tk->psz_codec_download_url = NULL;
+
+ tk->i_compression_type = MATROSKA_COMPRESSION_NONE;
+ tk->p_compression_data = NULL;
+
+ for( i = 0; i < m->ListSize(); i++ )
+ {
+ EbmlElement *l = (*m)[i];
+
+ if( MKV_IS_ID( l, KaxTrackNumber ) )
+ {
+ KaxTrackNumber &tnum = *(KaxTrackNumber*)l;
+
+ tk->i_number = uint32( tnum );
+ msg_Dbg( &sys.demuxer, "| | | + Track Number=%u", uint32( tnum ) );
+ }
+ else if( MKV_IS_ID( l, KaxTrackUID ) )
+ {
+ KaxTrackUID &tuid = *(KaxTrackUID*)l;
+
+ msg_Dbg( &sys.demuxer, "| | | + Track UID=%u", uint32( tuid ) );
+ }
+ else if( MKV_IS_ID( l, KaxTrackType ) )
+ {
+ const char *psz_type;
+ KaxTrackType &ttype = *(KaxTrackType*)l;
+
+ switch( uint8(ttype) )
+ {
+ case track_audio:
+ psz_type = "audio";
+ tk->fmt.i_cat = AUDIO_ES;
+ break;
+ case track_video:
+ psz_type = "video";
+ tk->fmt.i_cat = VIDEO_ES;
+ break;
+ case track_subtitle:
+ psz_type = "subtitle";
+ tk->fmt.i_cat = SPU_ES;
+ break;
+ case track_buttons:
+ psz_type = "buttons";
+ tk->fmt.i_cat = SPU_ES;
+ break;
+ default:
+ psz_type = "unknown";
+ tk->fmt.i_cat = UNKNOWN_ES;
+ break;
+ }
+
+ msg_Dbg( &sys.demuxer, "| | | + Track Type=%s", psz_type );
+ }
+// else if( EbmlId( *l ) == KaxTrackFlagEnabled::ClassInfos.GlobalId )
+// {
+// KaxTrackFlagEnabled &fenb = *(KaxTrackFlagEnabled*)l;
+
+// tk->b_enabled = uint32( fenb );
+// msg_Dbg( &sys.demuxer, "| | | + Track Enabled=%u",
+// uint32( fenb ) );
+// }
+ else if( MKV_IS_ID( l, KaxTrackFlagDefault ) )
+ {
+ KaxTrackFlagDefault &fdef = *(KaxTrackFlagDefault*)l;
+
+ tk->b_default = uint32( fdef );
+ msg_Dbg( &sys.demuxer, "| | | + Track Default=%u", uint32( fdef ) );
+ }
+ else if( MKV_IS_ID( l, KaxTrackFlagLacing ) )
+ {
+ KaxTrackFlagLacing &lac = *(KaxTrackFlagLacing*)l;
+
+ msg_Dbg( &sys.demuxer, "| | | + Track Lacing=%d", uint32( lac ) );
+ }
+ else if( MKV_IS_ID( l, KaxTrackMinCache ) )
+ {
+ KaxTrackMinCache &cmin = *(KaxTrackMinCache*)l;
+
+ msg_Dbg( &sys.demuxer, "| | | + Track MinCache=%d", uint32( cmin ) );
+ }
+ else if( MKV_IS_ID( l, KaxTrackMaxCache ) )
+ {
+ KaxTrackMaxCache &cmax = *(KaxTrackMaxCache*)l;
+
+ msg_Dbg( &sys.demuxer, "| | | + Track MaxCache=%d", uint32( cmax ) );
+ }
+ else if( MKV_IS_ID( l, KaxTrackDefaultDuration ) )
+ {
+ KaxTrackDefaultDuration &defd = *(KaxTrackDefaultDuration*)l;
+
+ tk->i_default_duration = uint64(defd);
+ msg_Dbg( &sys.demuxer, "| | | + Track Default Duration="I64Fd, uint64(defd) );
+ }
+ else if( MKV_IS_ID( l, KaxTrackTimecodeScale ) )
+ {
+ KaxTrackTimecodeScale &ttcs = *(KaxTrackTimecodeScale*)l;
+
+ tk->f_timecodescale = float( ttcs );
+ msg_Dbg( &sys.demuxer, "| | | + Track TimeCodeScale=%f", tk->f_timecodescale );
+ }
+ else if( MKV_IS_ID( l, KaxTrackName ) )
+ {
+ KaxTrackName &tname = *(KaxTrackName*)l;
+
+ tk->fmt.psz_description = ToUTF8( UTFstring( tname ) );
+ msg_Dbg( &sys.demuxer, "| | | + Track Name=%s", tk->fmt.psz_description );
+ }
+ else if( MKV_IS_ID( l, KaxTrackLanguage ) )
+ {
+ KaxTrackLanguage &lang = *(KaxTrackLanguage*)l;
+
+ if ( tk->fmt.psz_language != NULL )
+ free( tk->fmt.psz_language );
+ tk->fmt.psz_language = strdup( string( lang ).c_str() );
+ msg_Dbg( &sys.demuxer,
+ "| | | + Track Language=`%s'", tk->fmt.psz_language );
+ }
+ else if( MKV_IS_ID( l, KaxCodecID ) )
+ {
+ KaxCodecID &codecid = *(KaxCodecID*)l;
+
+ tk->psz_codec = strdup( string( codecid ).c_str() );
+ msg_Dbg( &sys.demuxer, "| | | + Track CodecId=%s", string( codecid ).c_str() );
+ }
+ else if( MKV_IS_ID( l, KaxCodecPrivate ) )
+ {
+ KaxCodecPrivate &cpriv = *(KaxCodecPrivate*)l;
+
+ tk->i_extra_data = cpriv.GetSize();
+ if( tk->i_extra_data > 0 )
+ {
+ 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() );
+ }
+ else if( MKV_IS_ID( l, KaxCodecName ) )
+ {
+ KaxCodecName &cname = *(KaxCodecName*)l;
+
+ tk->psz_codec_name = ToUTF8( UTFstring( cname ) );
+ msg_Dbg( &sys.demuxer, "| | | + Track Codec Name=%s", tk->psz_codec_name );
+ }
+ else if( MKV_IS_ID( l, KaxContentEncodings ) )
+ {
+ EbmlMaster *cencs = static_cast<EbmlMaster*>(l);
+ MkvTree( sys.demuxer, 3, "Content Encodings" );
+ if ( cencs->ListSize() > 1 )
+ {
+ msg_Err( &sys.demuxer, "Multiple Compression method not supported" );
+ bSupported = false;
+ }
+ for( j = 0; j < cencs->ListSize(); j++ )
+ {
+ EbmlElement *l2 = (*cencs)[j];
+ if( MKV_IS_ID( l2, KaxContentEncoding ) )
+ {
+ MkvTree( sys.demuxer, 4, "Content Encoding" );
+ EbmlMaster *cenc = static_cast<EbmlMaster*>(l2);
+ for( k = 0; k < cenc->ListSize(); k++ )
+ {
+ EbmlElement *l3 = (*cenc)[k];
+ if( MKV_IS_ID( l3, KaxContentEncodingOrder ) )
+ {
+ KaxContentEncodingOrder &encord = *(KaxContentEncodingOrder*)l3;
+ MkvTree( sys.demuxer, 5, "Order: %i", uint32( encord ) );
+ }
+ else if( MKV_IS_ID( l3, KaxContentEncodingScope ) )
+ {
+ KaxContentEncodingScope &encscope = *(KaxContentEncodingScope*)l3;
+ MkvTree( sys.demuxer, 5, "Scope: %i", uint32( encscope ) );
+ }
+ else if( MKV_IS_ID( l3, KaxContentEncodingType ) )
+ {
+ KaxContentEncodingType &enctype = *(KaxContentEncodingType*)l3;
+ MkvTree( sys.demuxer, 5, "Type: %i", uint32( enctype ) );
+ }
+ else if( MKV_IS_ID( l3, KaxContentCompression ) )
+ {
+ EbmlMaster *compr = static_cast<EbmlMaster*>(l3);
+ MkvTree( sys.demuxer, 5, "Content Compression" );
+ for( n = 0; n < compr->ListSize(); n++ )
+ {
+ EbmlElement *l4 = (*compr)[n];
+ if( MKV_IS_ID( l4, KaxContentCompAlgo ) )
+ {
+ KaxContentCompAlgo &compalg = *(KaxContentCompAlgo*)l4;
+ MkvTree( sys.demuxer, 6, "Compression Algorithm: %i", uint32(compalg) );
+ tk->i_compression_type = uint32( compalg );
+ if ( ( tk->i_compression_type != MATROSKA_COMPRESSION_ZLIB ) &&
+ ( tk->i_compression_type != MATROSKA_COMPRESSION_HEADER ) )
+ {
+ msg_Err( &sys.demuxer, "Track Compression method %d not supported", tk->i_compression_type );
+ bSupported = false;
+ }
+ }
+ else if( MKV_IS_ID( l4, KaxContentCompSettings ) )
+ {
+ tk->p_compression_data = new KaxContentCompSettings( *(KaxContentCompSettings*)l4 );
+ }
+ else
+ {
+ MkvTree( sys.demuxer, 6, "Unknown (%s)", typeid(*l4).name() );
+ }
+ }
+ }
+ else
+ {
+ MkvTree( sys.demuxer, 5, "Unknown (%s)", typeid(*l3).name() );
+ }
+ }
+ }
+ else
+ {
+ MkvTree( sys.demuxer, 4, "Unknown (%s)", typeid(*l2).name() );
+ }
+ }
+ }
+// else if( EbmlId( *l ) == KaxCodecSettings::ClassInfos.GlobalId )
+// {
+// KaxCodecSettings &cset = *(KaxCodecSettings*)l;
+
+// tk->psz_codec_settings = ToUTF8( UTFstring( cset ) );
+// msg_Dbg( &sys.demuxer, "| | | + Track Codec Settings=%s", tk->psz_codec_settings );
+// }
+// else if( EbmlId( *l ) == KaxCodecInfoURL::ClassInfos.GlobalId )
+// {
+// KaxCodecInfoURL &ciurl = *(KaxCodecInfoURL*)l;
+
+// tk->psz_codec_info_url = strdup( string( ciurl ).c_str() );
+// msg_Dbg( &sys.demuxer, "| | | + Track Codec Info URL=%s", tk->psz_codec_info_url );
+// }
+// else if( EbmlId( *l ) == KaxCodecDownloadURL::ClassInfos.GlobalId )
+// {
+// KaxCodecDownloadURL &cdurl = *(KaxCodecDownloadURL*)l;
+
+// tk->psz_codec_download_url = strdup( string( cdurl ).c_str() );
+// msg_Dbg( &sys.demuxer, "| | | + Track Codec Info URL=%s", tk->psz_codec_download_url );
+// }
+// else if( EbmlId( *l ) == KaxCodecDecodeAll::ClassInfos.GlobalId )
+// {
+// KaxCodecDecodeAll &cdall = *(KaxCodecDecodeAll*)l;
+
+// msg_Dbg( &sys.demuxer, "| | | + Track Codec Decode All=%u <== UNUSED", uint8( cdall ) );
+// }
+// else if( EbmlId( *l ) == KaxTrackOverlay::ClassInfos.GlobalId )
+// {
+// KaxTrackOverlay &tovr = *(KaxTrackOverlay*)l;