matroska_segment.cpp
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:50k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * mkv.cpp : matroska demuxer
  3.  *****************************************************************************
  4.  * Copyright (C) 2003-2004 the VideoLAN team
  5.  * $Id: e5101880fa115e40139e107211f377624257cc40 $
  6.  *
  7.  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  8.  *          Steve Lhomme <steve.lhomme@free.fr>
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  23.  *****************************************************************************/
  24. #include "matroska_segment.hpp"
  25. #include "chapters.hpp"
  26. #include "demux.hpp"
  27. /* GetFourCC helper */
  28. #define GetFOURCC( p )  __GetFOURCC( (uint8_t*)p )
  29. static vlc_fourcc_t __GetFOURCC( uint8_t *p )
  30. {
  31.     return VLC_FOURCC( p[0], p[1], p[2], p[3] );
  32. }
  33. /* Destructor */
  34. matroska_segment_c::~matroska_segment_c()
  35. {
  36.     for( size_t i_track = 0; i_track < tracks.size(); i_track++ )
  37.     {
  38.         delete tracks[i_track]->p_compression_data;
  39.         es_format_Clean( &tracks[i_track]->fmt );
  40.         free( tracks[i_track]->p_extra_data );
  41.         free( tracks[i_track]->psz_codec );
  42.         delete tracks[i_track];
  43.     }
  44.     free( psz_writing_application );
  45.     free( psz_muxing_application );
  46.     free( psz_segment_filename );
  47.     free( psz_title );
  48.     free( psz_date_utc );
  49.     free( p_indexes );
  50.     delete ep;
  51.     delete segment;
  52.     delete p_segment_uid;
  53.     delete p_prev_segment_uid;
  54.     delete p_next_segment_uid;
  55.     std::vector<chapter_edition_c*>::iterator index = stored_editions.begin();
  56.     while ( index != stored_editions.end() )
  57.     {
  58.         delete (*index);
  59.         index++;
  60.     }
  61.     std::vector<chapter_translation_c*>::iterator indext = translations.begin();
  62.     while ( indext != translations.end() )
  63.     {
  64.         delete (*indext);
  65.         indext++;
  66.     }
  67.     std::vector<KaxSegmentFamily*>::iterator indexf = families.begin();
  68.     while ( indexf != families.end() )
  69.     {
  70.         delete (*indexf);
  71.         indexf++;
  72.    }
  73. }
  74. /*****************************************************************************
  75.  * Tools
  76.  *  * LoadCues : load the cues element and update index
  77.  *
  78.  *  * LoadTags : load ... the tags element
  79.  *
  80.  *  * InformationCreate : create all information, load tags if present
  81.  *
  82.  *****************************************************************************/
  83. void matroska_segment_c::LoadCues( KaxCues *cues )
  84. {
  85.     EbmlParser  *ep;
  86.     EbmlElement *el;
  87.     if( b_cues )
  88.     {
  89.         msg_Err( &sys.demuxer, "There can be only 1 Cues per section." );
  90.         return;
  91.     }
  92.     ep = new EbmlParser( &es, cues, &sys.demuxer );
  93.     while( ( el = ep->Get() ) != NULL )
  94.     {
  95.         if( MKV_IS_ID( el, KaxCuePoint ) )
  96.         {
  97. #define idx p_indexes[i_index]
  98.             idx.i_track       = -1;
  99.             idx.i_block_number= -1;
  100.             idx.i_position    = -1;
  101.             idx.i_time        = 0;
  102.             idx.b_key         = true;
  103.             ep->Down();
  104.             while( ( el = ep->Get() ) != NULL )
  105.             {
  106.                 if( MKV_IS_ID( el, KaxCueTime ) )
  107.                 {
  108.                     KaxCueTime &ctime = *(KaxCueTime*)el;
  109.                     ctime.ReadData( es.I_O() );
  110.                     idx.i_time = uint64( ctime ) * i_timescale / (mtime_t)1000;
  111.                 }
  112.                 else if( MKV_IS_ID( el, KaxCueTrackPositions ) )
  113.                 {
  114.                     ep->Down();
  115.                     while( ( el = ep->Get() ) != NULL )
  116.                     {
  117.                         if( MKV_IS_ID( el, KaxCueTrack ) )
  118.                         {
  119.                             KaxCueTrack &ctrack = *(KaxCueTrack*)el;
  120.                             ctrack.ReadData( es.I_O() );
  121.                             idx.i_track = uint16( ctrack );
  122.                         }
  123.                         else if( MKV_IS_ID( el, KaxCueClusterPosition ) )
  124.                         {
  125.                             KaxCueClusterPosition &ccpos = *(KaxCueClusterPosition*)el;
  126.                             ccpos.ReadData( es.I_O() );
  127.                             idx.i_position = segment->GetGlobalPosition( uint64( ccpos ) );
  128.                         }
  129.                         else if( MKV_IS_ID( el, KaxCueBlockNumber ) )
  130.                         {
  131.                             KaxCueBlockNumber &cbnum = *(KaxCueBlockNumber*)el;
  132.                             cbnum.ReadData( es.I_O() );
  133.                             idx.i_block_number = uint32( cbnum );
  134.                         }
  135.                         else
  136.                         {
  137.                             msg_Dbg( &sys.demuxer, "         * Unknown (%s)", typeid(*el).name() );
  138.                         }
  139.                     }
  140.                     ep->Up();
  141.                 }
  142.                 else
  143.                 {
  144.                     msg_Dbg( &sys.demuxer, "     * Unknown (%s)", typeid(*el).name() );
  145.                 }
  146.             }
  147.             ep->Up();
  148. #if 0
  149.             msg_Dbg( &sys.demuxer, " * added time=%"PRId64" pos=%"PRId64
  150.                      " track=%d bnum=%d", idx.i_time, idx.i_position,
  151.                      idx.i_track, idx.i_block_number );
  152. #endif
  153.             i_index++;
  154.             if( i_index >= i_index_max )
  155.             {
  156.                 i_index_max += 1024;
  157.                 p_indexes = (mkv_index_t*)realloc( p_indexes, sizeof( mkv_index_t ) * i_index_max );
  158.             }
  159. #undef idx
  160.         }
  161.         else
  162.         {
  163.             msg_Dbg( &sys.demuxer, " * Unknown (%s)", typeid(*el).name() );
  164.         }
  165.     }
  166.     delete ep;
  167.     b_cues = true;
  168.     msg_Dbg( &sys.demuxer, "|   - loading cues done." );
  169. }
  170. void matroska_segment_c::LoadTags( KaxTags *tags )
  171. {
  172.     EbmlParser  *ep;
  173.     EbmlElement *el;
  174.     /* Master elements */
  175.     ep = new EbmlParser( &es, tags, &sys.demuxer );
  176.     while( ( el = ep->Get() ) != NULL )
  177.     {
  178.         if( MKV_IS_ID( el, KaxTag ) )
  179.         {
  180.             msg_Dbg( &sys.demuxer, "+ Tag" );
  181.             ep->Down();
  182.             while( ( el = ep->Get() ) != NULL )
  183.             {
  184.                 if( MKV_IS_ID( el, KaxTagTargets ) )
  185.                 {
  186.                     msg_Dbg( &sys.demuxer, "|   + Targets" );
  187.                     ep->Down();
  188.                     while( ( el = ep->Get() ) != NULL )
  189.                     {
  190.                         msg_Dbg( &sys.demuxer, "|   |   + Unknown (%s)", typeid( *el ).name() );
  191.                     }
  192.                     ep->Up();
  193.                 }
  194.                 else if( MKV_IS_ID( el, KaxTagGeneral ) )
  195.                 {
  196.                     msg_Dbg( &sys.demuxer, "|   + General" );
  197.                     ep->Down();
  198.                     while( ( el = ep->Get() ) != NULL )
  199.                     {
  200.                         msg_Dbg( &sys.demuxer, "|   |   + Unknown (%s)", typeid( *el ).name() );
  201.                     }
  202.                     ep->Up();
  203.                 }
  204.                 else if( MKV_IS_ID( el, KaxTagGenres ) )
  205.                 {
  206.                     msg_Dbg( &sys.demuxer, "|   + Genres" );
  207.                     ep->Down();
  208.                     while( ( el = ep->Get() ) != NULL )
  209.                     {
  210.                         msg_Dbg( &sys.demuxer, "|   |   + Unknown (%s)", typeid( *el ).name() );
  211.                     }
  212.                     ep->Up();
  213.                 }
  214.                 else if( MKV_IS_ID( el, KaxTagAudioSpecific ) )
  215.                 {
  216.                     msg_Dbg( &sys.demuxer, "|   + Audio Specific" );
  217.                     ep->Down();
  218.                     while( ( el = ep->Get() ) != NULL )
  219.                     {
  220.                         msg_Dbg( &sys.demuxer, "|   |   + Unknown (%s)", typeid( *el ).name() );
  221.                     }
  222.                     ep->Up();
  223.                 }
  224.                 else if( MKV_IS_ID( el, KaxTagImageSpecific ) )
  225.                 {
  226.                     msg_Dbg( &sys.demuxer, "|   + Images Specific" );
  227.                     ep->Down();
  228.                     while( ( el = ep->Get() ) != NULL )
  229.                     {
  230.                         msg_Dbg( &sys.demuxer, "|   |   + Unknown (%s)", typeid( *el ).name() );
  231.                     }
  232.                     ep->Up();
  233.                 }
  234.                 else if( MKV_IS_ID( el, KaxTagMultiComment ) )
  235.                 {
  236.                     msg_Dbg( &sys.demuxer, "|   + Multi Comment" );
  237.                 }
  238.                 else if( MKV_IS_ID( el, KaxTagMultiCommercial ) )
  239.                 {
  240.                     msg_Dbg( &sys.demuxer, "|   + Multi Commercial" );
  241.                 }
  242.                 else if( MKV_IS_ID( el, KaxTagMultiDate ) )
  243.                 {
  244.                     msg_Dbg( &sys.demuxer, "|   + Multi Date" );
  245.                 }
  246.                 else if( MKV_IS_ID( el, KaxTagMultiEntity ) )
  247.                 {
  248.                     msg_Dbg( &sys.demuxer, "|   + Multi Entity" );
  249.                 }
  250.                 else if( MKV_IS_ID( el, KaxTagMultiIdentifier ) )
  251.                 {
  252.                     msg_Dbg( &sys.demuxer, "|   + Multi Identifier" );
  253.                 }
  254.                 else if( MKV_IS_ID( el, KaxTagMultiLegal ) )
  255.                 {
  256.                     msg_Dbg( &sys.demuxer, "|   + Multi Legal" );
  257.                 }
  258.                 else if( MKV_IS_ID( el, KaxTagMultiTitle ) )
  259.                 {
  260.                     msg_Dbg( &sys.demuxer, "|   + Multi Title" );
  261.                 }
  262.                 else
  263.                 {
  264.                     msg_Dbg( &sys.demuxer, "|   + LoadTag Unknown (%s)", typeid( *el ).name() );
  265.                 }
  266.             }
  267.             ep->Up();
  268.         }
  269.         else
  270.         {
  271.             msg_Dbg( &sys.demuxer, "+ Unknown (%s)", typeid( *el ).name() );
  272.         }
  273.     }
  274.     delete ep;
  275.     msg_Dbg( &sys.demuxer, "loading tags done." );
  276. }
  277. /*****************************************************************************
  278.  * InformationCreate:
  279.  *****************************************************************************/
  280. void matroska_segment_c::InformationCreate( )
  281. {
  282.     sys.meta = vlc_meta_New();
  283.     if( psz_title )
  284.     {
  285.         vlc_meta_SetTitle( sys.meta, psz_title );
  286.     }
  287.     if( psz_date_utc )
  288.     {
  289.         vlc_meta_SetDate( sys.meta, psz_date_utc );
  290.     }
  291. #if 0
  292.     if( psz_segment_filename )
  293.     {
  294.         fprintf( stderr, "***** WARNING: Unhandled meta - Use customn" );
  295.     }
  296.     if( psz_muxing_application )
  297.     {
  298.         fprintf( stderr, "***** WARNING: Unhandled meta - Use customn" );
  299.     }
  300.     if( psz_writing_application )
  301.     {
  302.         fprintf( stderr, "***** WARNING: Unhandled meta - Use customn" );
  303.     }
  304.     for( size_t i_track = 0; i_track < tracks.size(); i_track++ )
  305.     {
  306. //        mkv_track_t *tk = tracks[i_track];
  307. //        vlc_meta_t *mtk = vlc_meta_New();
  308.         fprintf( stderr, "***** WARNING: Unhandled child metan");
  309.     }
  310. #endif
  311. #if 0
  312.     if( i_tags_position >= 0 )
  313.     {
  314.         bool b_seekable;
  315.         stream_Control( sys.demuxer.s, STREAM_CAN_FASTSEEK, &b_seekable );
  316.         if( b_seekable )
  317.         {
  318.             LoadTags( );
  319.         }
  320.     }
  321. #endif
  322. }
  323. /*****************************************************************************
  324.  * Misc
  325.  *****************************************************************************/
  326. void matroska_segment_c::IndexAppendCluster( KaxCluster *cluster )
  327. {
  328. #define idx p_indexes[i_index]
  329.     idx.i_track       = -1;
  330.     idx.i_block_number= -1;
  331.     idx.i_position    = cluster->GetElementPosition();
  332.     idx.i_time        = -1;
  333.     idx.b_key         = true;
  334.     i_index++;
  335.     if( i_index >= i_index_max )
  336.     {
  337.         i_index_max += 1024;
  338.         p_indexes = (mkv_index_t*)realloc( p_indexes, sizeof( mkv_index_t ) * i_index_max );
  339.     }
  340. #undef idx
  341. }
  342. bool matroska_segment_c::PreloadFamily( const matroska_segment_c & of_segment )
  343. {
  344.     if ( b_preloaded )
  345.         return false;
  346.     for (size_t i=0; i<families.size(); i++)
  347.     {
  348.         for (size_t j=0; j<of_segment.families.size(); j++)
  349.         {
  350.             if ( *(families[i]) == *(of_segment.families[j]) )
  351.                 return Preload( );
  352.         }
  353.     }
  354.     return false;
  355. }
  356. bool matroska_segment_c::CompareSegmentUIDs( const matroska_segment_c * p_item_a, const matroska_segment_c * p_item_b )
  357. {
  358.     EbmlBinary *p_tmp;
  359.     if ( p_item_a == NULL || p_item_b == NULL )
  360.         return false;
  361.     p_tmp = (EbmlBinary *)p_item_a->p_segment_uid;
  362.     if ( p_item_b->p_prev_segment_uid != NULL
  363.           && *p_tmp == *p_item_b->p_prev_segment_uid )
  364.         return true;
  365.     p_tmp = (EbmlBinary *)p_item_a->p_next_segment_uid;
  366.     if ( !p_tmp )
  367.         return false;
  368.  
  369.     if ( p_item_b->p_segment_uid != NULL
  370.           && *p_tmp == *p_item_b->p_segment_uid )
  371.         return true;
  372.     if ( p_item_b->p_prev_segment_uid != NULL
  373.           && *p_tmp == *p_item_b->p_prev_segment_uid )
  374.         return true;
  375.     return false;
  376. }
  377. bool matroska_segment_c::Preload( )
  378. {
  379.     if ( b_preloaded )
  380.         return false;
  381.     EbmlElement *el = NULL;
  382.     ep->Reset( &sys.demuxer );
  383.     while( ( el = ep->Get() ) != NULL )
  384.     {
  385.         if( MKV_IS_ID( el, KaxSeekHead ) )
  386.         {
  387.             /* Multiple allowed */
  388.             /* We bail at 10, to prevent possible recursion */
  389.             msg_Dbg(  &sys.demuxer, "|   + Seek head" );
  390.             if( i_seekhead_count < 10 )
  391.             {
  392.                 i_seekhead_position = (int64_t) es.I_O().getFilePointer();
  393.                 ParseSeekHead( static_cast<KaxSeekHead*>( el ) );
  394.             }
  395.         }
  396.         else if( MKV_IS_ID( el, KaxInfo ) )
  397.         {
  398.             /* Multiple allowed, mandatory */
  399.             msg_Dbg(  &sys.demuxer, "|   + Information" );
  400.             if( i_info_position < 0 ) // FIXME
  401.                 ParseInfo( static_cast<KaxInfo*>( el ) );
  402.             i_info_position = (int64_t) es.I_O().getFilePointer();
  403.         }
  404.         else if( MKV_IS_ID( el, KaxTracks ) )
  405.         {
  406.             /* Multiple allowed */
  407.             msg_Dbg(  &sys.demuxer, "|   + Tracks" );
  408.             if( i_tracks_position < 0 ) // FIXME
  409.                 ParseTracks( static_cast<KaxTracks*>( el ) );
  410.             if ( tracks.size() == 0 )
  411.             {
  412.                 msg_Err( &sys.demuxer, "No tracks supported" );
  413.                 return false;
  414.             }
  415.             i_tracks_position = (int64_t) es.I_O().getFilePointer();
  416.         }
  417.         else if( MKV_IS_ID( el, KaxCues ) )
  418.         {
  419.             msg_Dbg(  &sys.demuxer, "|   + Cues" );
  420.             if( i_cues_position < 0 )
  421.                 LoadCues( static_cast<KaxCues*>( el ) );
  422.             i_cues_position = (int64_t) es.I_O().getFilePointer();
  423.         }
  424.         else if( MKV_IS_ID( el, KaxCluster ) )
  425.         {
  426.             msg_Dbg( &sys.demuxer, "|   + Cluster" );
  427.             cluster = (KaxCluster*)el;
  428.             i_cluster_pos = i_start_pos = cluster->GetElementPosition();
  429.             ParseCluster( );
  430.             ep->Down();
  431.             /* stop pre-parsing the stream */
  432.             break;
  433.         }
  434.         else if( MKV_IS_ID( el, KaxAttachments ) )
  435.         {
  436.             msg_Dbg( &sys.demuxer, "|   + Attachments" );
  437.             if( i_attachments_position < 0 )
  438.                 ParseAttachments( static_cast<KaxAttachments*>( el ) );
  439.             i_attachments_position = (int64_t) es.I_O().getFilePointer();
  440.         }
  441.         else if( MKV_IS_ID( el, KaxChapters ) )
  442.         {
  443.             msg_Dbg( &sys.demuxer, "|   + Chapters" );
  444.             if( i_chapters_position < 0 )
  445.                 ParseChapters( static_cast<KaxChapters*>( el ) );
  446.             i_chapters_position = (int64_t) es.I_O().getFilePointer();
  447.         }
  448.         else if( MKV_IS_ID( el, KaxTag ) )
  449.         {
  450.             msg_Dbg( &sys.demuxer, "|   + Tags" );
  451.             if( i_tags_position < 0) // FIXME
  452.                 ;//LoadTags( static_cast<KaxTags*>( el ) );
  453.             i_tags_position = (int64_t) es.I_O().getFilePointer();
  454.         }
  455.         else
  456.             msg_Dbg( &sys.demuxer, "|   + Preload Unknown (%s)", typeid(*el).name() );
  457.     }
  458.     b_preloaded = true;
  459.     return true;
  460. }
  461. /* Here we try to load elements that were found in Seek Heads, but not yet parsed */
  462. bool matroska_segment_c::LoadSeekHeadItem( const EbmlCallbacks & ClassInfos, int64_t i_element_position )
  463. {
  464.     int64_t     i_sav_position = (int64_t)es.I_O().getFilePointer();
  465.     EbmlElement *el;
  466.     es.I_O().setFilePointer( i_element_position, seek_beginning );
  467.     el = es.FindNextID( ClassInfos, 0xFFFFFFFFL);
  468.     if( el == NULL )
  469.     {
  470.         msg_Err( &sys.demuxer, "cannot load some cues/chapters/tags etc. (broken seekhead or file)" );
  471.         es.I_O().setFilePointer( i_sav_position, seek_beginning );
  472.         return false;
  473.     }
  474.     if( MKV_IS_ID( el, KaxSeekHead ) )
  475.     {
  476.         /* Multiple allowed */
  477.         msg_Dbg( &sys.demuxer, "|   + Seek head" );
  478.         if( i_seekhead_count < 10 )
  479.         {
  480.             i_seekhead_position = i_element_position;
  481.             ParseSeekHead( static_cast<KaxSeekHead*>( el ) );
  482.         }
  483.     }
  484.     else if( MKV_IS_ID( el, KaxInfo ) ) // FIXME
  485.     {
  486.         /* Multiple allowed, mandatory */
  487.         msg_Dbg( &sys.demuxer, "|   + Information" );
  488.         if( i_info_position < 0 )
  489.             ParseInfo( static_cast<KaxInfo*>( el ) );
  490.         i_info_position = i_element_position;
  491.     }
  492.     else if( MKV_IS_ID( el, KaxTracks ) ) // FIXME
  493.     {
  494.         /* Multiple allowed */
  495.         msg_Dbg( &sys.demuxer, "|   + Tracks" );
  496.         if( i_tracks_position < 0 )
  497.             ParseTracks( static_cast<KaxTracks*>( el ) );
  498.         if ( tracks.size() == 0 )
  499.         {
  500.             msg_Err( &sys.demuxer, "No tracks supported" );
  501.             delete el;
  502.             es.I_O().setFilePointer( i_sav_position, seek_beginning );
  503.             return false;
  504.         }
  505.         i_tracks_position = i_element_position;
  506.     }
  507.     else if( MKV_IS_ID( el, KaxCues ) )
  508.     {
  509.         msg_Dbg( &sys.demuxer, "|   + Cues" );
  510.         if( i_cues_position < 0 )
  511.             LoadCues( static_cast<KaxCues*>( el ) );
  512.         i_cues_position = i_element_position;
  513.     }
  514.     else if( MKV_IS_ID( el, KaxAttachments ) )
  515.     {
  516.         msg_Dbg( &sys.demuxer, "|   + Attachments" );
  517.         if( i_attachments_position < 0 )
  518.             ParseAttachments( static_cast<KaxAttachments*>( el ) );
  519.         i_attachments_position = i_element_position;
  520.     }
  521.     else if( MKV_IS_ID( el, KaxChapters ) )
  522.     {
  523.         msg_Dbg( &sys.demuxer, "|   + Chapters" );
  524.         if( i_chapters_position < 0 )
  525.             ParseChapters( static_cast<KaxChapters*>( el ) );
  526.         i_chapters_position = i_element_position;
  527.     }
  528.     else if( MKV_IS_ID( el, KaxTag ) ) // FIXME
  529.     {
  530.         msg_Dbg( &sys.demuxer, "|   + Tags" );
  531.         if( i_tags_position < 0 )
  532.             ;//LoadTags( static_cast<KaxTags*>( el ) );
  533.         i_tags_position = i_element_position;
  534.     }
  535.     else
  536.     {
  537.         msg_Dbg( &sys.demuxer, "|   + LoadSeekHeadItem Unknown (%s)", typeid(*el).name() );
  538.     }
  539.     delete el;
  540.     es.I_O().setFilePointer( i_sav_position, seek_beginning );
  541.     return true;
  542. }
  543. int matroska_segment_c::BlockFindTrackIndex( size_t *pi_track,
  544.                                              const KaxBlock *p_block, const KaxSimpleBlock *p_simpleblock )
  545. {
  546.     size_t          i_track;
  547.     for( i_track = 0; i_track < tracks.size(); i_track++ )
  548.     {
  549.         const mkv_track_t *tk = tracks[i_track];
  550.         if( ( p_block != NULL && tk->i_number == p_block->TrackNum() ) ||
  551.             ( p_simpleblock != NULL && tk->i_number == p_simpleblock->TrackNum() ) )
  552.         {
  553.             break;
  554.         }
  555.     }
  556.     if( i_track >= tracks.size() )
  557.         return VLC_EGENERIC;
  558.     if( pi_track )
  559.         *pi_track = i_track;
  560.     return VLC_SUCCESS;
  561. }
  562. bool matroska_segment_c::Select( mtime_t i_start_time )
  563. {
  564.     size_t i_track;
  565.     /* add all es */
  566.     msg_Dbg( &sys.demuxer, "found %d es", (int)tracks.size() );
  567.     sys.b_pci_packet_set = false;
  568.     for( i_track = 0; i_track < tracks.size(); i_track++ )
  569.     {
  570.         mkv_track_t *p_tk = tracks[i_track];
  571.         es_format_t *p_fmt = &p_tk->fmt;
  572.         if( tracks[i_track]->fmt.i_cat == UNKNOWN_ES )
  573.         {
  574.             msg_Warn( &sys.demuxer, "invalid track[%d, n=%d]", (int)i_track, tracks[i_track]->i_number );
  575.             tracks[i_track]->p_es = NULL;
  576.             continue;
  577.         }
  578.         if( !strcmp( tracks[i_track]->psz_codec, "V_MS/VFW/FOURCC" ) )
  579.         {
  580.             if( tracks[i_track]->i_extra_data < (int)sizeof( BITMAPINFOHEADER ) )
  581.             {
  582.                 msg_Err( &sys.demuxer, "missing/invalid BITMAPINFOHEADER" );
  583.                 tracks[i_track]->fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
  584.             }
  585.             else
  586.             {
  587.                 BITMAPINFOHEADER *p_bih = (BITMAPINFOHEADER*)tracks[i_track]->p_extra_data;
  588.                 tracks[i_track]->fmt.video.i_width = GetDWLE( &p_bih->biWidth );
  589.                 tracks[i_track]->fmt.video.i_height= GetDWLE( &p_bih->biHeight );
  590.                 tracks[i_track]->fmt.i_codec       = GetFOURCC( &p_bih->biCompression );
  591.                 tracks[i_track]->fmt.i_extra       = GetDWLE( &p_bih->biSize ) - sizeof( BITMAPINFOHEADER );
  592.                 if( tracks[i_track]->fmt.i_extra > 0 )
  593.                 {
  594.                     tracks[i_track]->fmt.p_extra = malloc( tracks[i_track]->fmt.i_extra );
  595.                     memcpy( tracks[i_track]->fmt.p_extra, &p_bih[1], tracks[i_track]->fmt.i_extra );
  596.                 }
  597.             }
  598.             p_tk->b_dts_only = true;
  599.         }
  600.         else if( !strcmp( tracks[i_track]->psz_codec, "V_MPEG1" ) ||
  601.                  !strcmp( tracks[i_track]->psz_codec, "V_MPEG2" ) )
  602.         {
  603.             tracks[i_track]->fmt.i_codec = VLC_FOURCC( 'm', 'p', 'g', 'v' );
  604.         }
  605.         else if( !strncmp( tracks[i_track]->psz_codec, "V_THEORA", 8 ) )
  606.         {
  607.             uint8_t *p_data = tracks[i_track]->p_extra_data;
  608.             tracks[i_track]->fmt.i_codec = VLC_FOURCC( 't', 'h', 'e', 'o' );
  609.             if( tracks[i_track]->i_extra_data >= 4 ) {
  610.                 if( p_data[0] == 2 ) {
  611.                     int i = 1;
  612.                     int i_size1 = 0, i_size2 = 0;
  613.                     p_data++;
  614.                     /* read size of first header packet */
  615.                     while( *p_data == 0xFF &&
  616.                            i < tracks[i_track]->i_extra_data )
  617.                     {
  618.                         i_size1 += *p_data;
  619.                         p_data++;
  620.                         i++;
  621.                     }
  622.                     i_size1 += *p_data;
  623.                     p_data++;
  624.                     i++;
  625.                     msg_Dbg( &sys.demuxer, "first theora header size %d", i_size1 );
  626.                     /* read size of second header packet */
  627.                     while( *p_data == 0xFF &&
  628.                            i < tracks[i_track]->i_extra_data )
  629.                     {
  630.                         i_size2 += *p_data;
  631.                         p_data++;
  632.                         i++;
  633.                     }
  634.                     i_size2 += *p_data;
  635.                     p_data++;
  636.                     i++;
  637.                     int i_size3 = tracks[i_track]->i_extra_data - i - i_size1
  638.                         - i_size2;
  639.                     msg_Dbg( &sys.demuxer, "second theora header size %d", i_size2 );
  640.                     msg_Dbg( &sys.demuxer, "third theora header size %d", i_size3 );
  641.                     tracks[i_track]->fmt.i_extra = i_size1 + i_size2 + i_size3
  642.                         + 6;
  643.                     if( i_size1 > 0 && i_size2 > 0 && i_size3 > 0  ) {
  644.                         tracks[i_track]->fmt.p_extra =
  645.                             malloc( tracks[i_track]->fmt.i_extra );
  646.                         uint8_t *p_out = (uint8_t*)tracks[i_track]->fmt.p_extra;
  647.                         *p_out++ = (i_size1>>8) & 0xFF;
  648.                         *p_out++ = i_size1 & 0xFF;
  649.                         memcpy( p_out, p_data, i_size1 );
  650.                         p_data += i_size1;
  651.                         p_out += i_size1;
  652.  
  653.                         *p_out++ = (i_size2>>8) & 0xFF;
  654.                         *p_out++ = i_size2 & 0xFF;
  655.                         memcpy( p_out, p_data, i_size2 );
  656.                         p_data += i_size2;
  657.                         p_out += i_size2;
  658.                         *p_out++ = (i_size3>>8) & 0xFF;
  659.                         *p_out++ = i_size3 & 0xFF;
  660.                         memcpy( p_out, p_data, i_size3 );
  661.                         p_data += i_size3;
  662.                         p_out += i_size3;
  663.                     }
  664.                     else
  665.                     {
  666.                         msg_Err( &sys.demuxer, "inconsistant theora extradata" );
  667.                     }
  668.                 }
  669.                 else {
  670.                     msg_Err( &sys.demuxer, "Wrong number of ogg packets with theora headers (%d)", p_data[0] + 1 );
  671.                 }
  672.             }
  673.         }
  674.         else if( !strncmp( tracks[i_track]->psz_codec, "V_REAL/RV", 9 ) )
  675.         {
  676.             if( !strcmp( p_tk->psz_codec, "V_REAL/RV10" ) )
  677.                 p_fmt->i_codec = VLC_FOURCC( 'R', 'V', '1', '0' );
  678.             else if( !strcmp( p_tk->psz_codec, "V_REAL/RV20" ) )
  679.                 p_fmt->i_codec = VLC_FOURCC( 'R', 'V', '2', '0' );
  680.             else if( !strcmp( p_tk->psz_codec, "V_REAL/RV30" ) )
  681.                 p_fmt->i_codec = VLC_FOURCC( 'R', 'V', '3', '0' );
  682.             else if( !strcmp( p_tk->psz_codec, "V_REAL/RV40" ) )
  683.                 p_fmt->i_codec = VLC_FOURCC( 'R', 'V', '4', '0' );
  684.             if( p_tk->i_extra_data > 26 )
  685.             {
  686.                 p_fmt->p_extra = malloc( p_tk->i_extra_data - 26 );
  687.                 if( p_fmt->p_extra )
  688.                 {
  689.                     p_fmt->i_extra = p_tk->i_extra_data - 26;
  690.                     memcpy( p_fmt->p_extra, &p_tk->p_extra_data[26], p_fmt->i_extra );
  691.                 }
  692.             }
  693.             p_tk->b_dts_only = true;
  694.         }
  695.         else if( !strncmp( tracks[i_track]->psz_codec, "V_DIRAC", 7 ) )
  696.         {
  697.             tracks[i_track]->fmt.i_codec = VLC_FOURCC('d', 'r', 'a', 'c' );
  698.         }
  699.         else if( !strncmp( tracks[i_track]->psz_codec, "V_MPEG4", 7 ) )
  700.         {
  701.             if( !strcmp( tracks[i_track]->psz_codec, "V_MPEG4/MS/V3" ) )
  702.             {
  703.                 tracks[i_track]->fmt.i_codec = VLC_FOURCC( 'D', 'I', 'V', '3' );
  704.             }
  705.             else if( !strncmp( tracks[i_track]->psz_codec, "V_MPEG4/ISO", 11 ) )
  706.             {
  707.                 /* A MPEG 4 codec, SP, ASP, AP or AVC */
  708.                 if( !strcmp( tracks[i_track]->psz_codec, "V_MPEG4/ISO/AVC" ) )
  709.                     tracks[i_track]->fmt.i_codec = VLC_FOURCC( 'a', 'v', 'c', '1' );
  710.                 else
  711.                     tracks[i_track]->fmt.i_codec = VLC_FOURCC( 'm', 'p', '4', 'v' );
  712.                 tracks[i_track]->fmt.i_extra = tracks[i_track]->i_extra_data;
  713.                 tracks[i_track]->fmt.p_extra = malloc( tracks[i_track]->i_extra_data );
  714.                 memcpy( tracks[i_track]->fmt.p_extra,tracks[i_track]->p_extra_data, tracks[i_track]->i_extra_data );
  715.             }
  716.         }
  717.         else if( !strcmp( tracks[i_track]->psz_codec, "V_QUICKTIME" ) )
  718.         {
  719.             MP4_Box_t *p_box = (MP4_Box_t*)malloc( sizeof( MP4_Box_t ) );
  720.             stream_t *p_mp4_stream = stream_MemoryNew( VLC_OBJECT(&sys.demuxer),
  721.                                                        tracks[i_track]->p_extra_data,
  722.                                                        tracks[i_track]->i_extra_data,
  723.                                                        true );
  724.             if( MP4_ReadBoxCommon( p_mp4_stream, p_box ) &&
  725.                 MP4_ReadBox_sample_vide( p_mp4_stream, p_box ) )
  726.             {
  727.                 tracks[i_track]->fmt.i_codec = p_box->i_type;
  728.                 tracks[i_track]->fmt.video.i_width = p_box->data.p_sample_vide->i_width;
  729.                 tracks[i_track]->fmt.video.i_height = p_box->data.p_sample_vide->i_height;
  730.                 tracks[i_track]->fmt.i_extra = p_box->data.p_sample_vide->i_qt_image_description;
  731.                 tracks[i_track]->fmt.p_extra = malloc( tracks[i_track]->fmt.i_extra );
  732.                 memcpy( tracks[i_track]->fmt.p_extra, p_box->data.p_sample_vide->p_qt_image_description, tracks[i_track]->fmt.i_extra );
  733.                 MP4_FreeBox_sample_vide( p_box );
  734.             }
  735.             else
  736.             {
  737.                 free( p_box );
  738.             }
  739.             stream_Delete( p_mp4_stream );
  740.         }
  741.         else if( !strcmp( tracks[i_track]->psz_codec, "A_MS/ACM" ) )
  742.         {
  743.             if( tracks[i_track]->i_extra_data < (int)sizeof( WAVEFORMATEX ) )
  744.             {
  745.                 msg_Err( &sys.demuxer, "missing/invalid WAVEFORMATEX" );
  746.                 tracks[i_track]->fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
  747.             }
  748.             else
  749.             {
  750.                 WAVEFORMATEX *p_wf = (WAVEFORMATEX*)tracks[i_track]->p_extra_data;
  751.                 wf_tag_to_fourcc( GetWLE( &p_wf->wFormatTag ), &tracks[i_track]->fmt.i_codec, NULL );
  752.                 tracks[i_track]->fmt.audio.i_channels   = GetWLE( &p_wf->nChannels );
  753.                 tracks[i_track]->fmt.audio.i_rate = GetDWLE( &p_wf->nSamplesPerSec );
  754.                 tracks[i_track]->fmt.i_bitrate    = GetDWLE( &p_wf->nAvgBytesPerSec ) * 8;
  755.                 tracks[i_track]->fmt.audio.i_blockalign = GetWLE( &p_wf->nBlockAlign );;
  756.                 tracks[i_track]->fmt.audio.i_bitspersample = GetWLE( &p_wf->wBitsPerSample );
  757.                 tracks[i_track]->fmt.i_extra            = GetWLE( &p_wf->cbSize );
  758.                 if( tracks[i_track]->fmt.i_extra > 0 )
  759.                 {
  760.                     tracks[i_track]->fmt.p_extra = malloc( tracks[i_track]->fmt.i_extra );
  761.                     memcpy( tracks[i_track]->fmt.p_extra, &p_wf[1], tracks[i_track]->fmt.i_extra );
  762.                 }
  763.             }
  764.         }
  765.         else if( !strcmp( tracks[i_track]->psz_codec, "A_MPEG/L3" ) ||
  766.                  !strcmp( tracks[i_track]->psz_codec, "A_MPEG/L2" ) ||
  767.                  !strcmp( tracks[i_track]->psz_codec, "A_MPEG/L1" ) )
  768.         {
  769.             tracks[i_track]->fmt.i_codec = VLC_FOURCC( 'm', 'p', 'g', 'a' );
  770.         }
  771.         else if( !strcmp( tracks[i_track]->psz_codec, "A_AC3" ) )
  772.         {
  773.             tracks[i_track]->fmt.i_codec = VLC_FOURCC( 'a', '5', '2', ' ' );
  774.         }
  775.         else if( !strcmp( tracks[i_track]->psz_codec, "A_EAC3" ) )
  776.         {
  777.             tracks[i_track]->fmt.i_codec = VLC_FOURCC( 'e', 'a', 'c', '3' );
  778.         }
  779.         else if( !strcmp( tracks[i_track]->psz_codec, "A_DTS" ) )
  780.         {
  781.             tracks[i_track]->fmt.i_codec = VLC_FOURCC( 'd', 't', 's', ' ' );
  782.         }
  783.         else if( !strcmp( tracks[i_track]->psz_codec, "A_MLP" ) )
  784.         {
  785.             tracks[i_track]->fmt.i_codec = VLC_FOURCC('m', 'l', 'p', ' ' );
  786.         }
  787.         else if( !strcmp( tracks[i_track]->psz_codec, "A_TRUEHD" ) )
  788.         {
  789.             /* FIXME when more samples arrive */
  790.             tracks[i_track]->fmt.i_codec = VLC_FOURCC('t', 'r', 'h', 'd' );
  791.             p_fmt->b_packetized = false;
  792.         }
  793.         else if( !strcmp( tracks[i_track]->psz_codec, "A_FLAC" ) )
  794.         {
  795.             tracks[i_track]->fmt.i_codec = VLC_FOURCC( 'f', 'l', 'a', 'c' );
  796.             tracks[i_track]->fmt.i_extra = tracks[i_track]->i_extra_data;
  797.             tracks[i_track]->fmt.p_extra = malloc( tracks[i_track]->i_extra_data );
  798.             memcpy( tracks[i_track]->fmt.p_extra,tracks[i_track]->p_extra_data, tracks[i_track]->i_extra_data );
  799.         }
  800.         else if( !strcmp( tracks[i_track]->psz_codec, "A_VORBIS" ) )
  801.         {
  802.             int i, i_offset = 1, i_size[3], i_extra;
  803.             uint8_t *p_extra;
  804.             tracks[i_track]->fmt.i_codec = VLC_FOURCC( 'v', 'o', 'r', 'b' );
  805.             /* Split the 3 headers */
  806.             if( tracks[i_track]->p_extra_data[0] != 0x02 )
  807.                 msg_Err( &sys.demuxer, "invalid vorbis header" );
  808.             for( i = 0; i < 2; i++ )
  809.             {
  810.                 i_size[i] = 0;
  811.                 while( i_offset < tracks[i_track]->i_extra_data )
  812.                 {
  813.                     i_size[i] += tracks[i_track]->p_extra_data[i_offset];
  814.                     if( tracks[i_track]->p_extra_data[i_offset++] != 0xff ) break;
  815.                 }
  816.             }
  817.             i_size[0] = __MIN(i_size[0], tracks[i_track]->i_extra_data - i_offset);
  818.             i_size[1] = __MIN(i_size[1], tracks[i_track]->i_extra_data -i_offset -i_size[0]);
  819.             i_size[2] = tracks[i_track]->i_extra_data - i_offset - i_size[0] - i_size[1];
  820.             tracks[i_track]->fmt.i_extra = 3 * 2 + i_size[0] + i_size[1] + i_size[2];
  821.             tracks[i_track]->fmt.p_extra = malloc( tracks[i_track]->fmt.i_extra );
  822.             p_extra = (uint8_t *)tracks[i_track]->fmt.p_extra; i_extra = 0;
  823.             for( i = 0; i < 3; i++ )
  824.             {
  825.                 *(p_extra++) = i_size[i] >> 8;
  826.                 *(p_extra++) = i_size[i] & 0xFF;
  827.                 memcpy( p_extra, tracks[i_track]->p_extra_data + i_offset + i_extra,
  828.                         i_size[i] );
  829.                 p_extra += i_size[i];
  830.                 i_extra += i_size[i];
  831.             }
  832.         }
  833.         else if( !strncmp( tracks[i_track]->psz_codec, "A_AAC/MPEG2/", strlen( "A_AAC/MPEG2/" ) ) ||
  834.                  !strncmp( tracks[i_track]->psz_codec, "A_AAC/MPEG4/", strlen( "A_AAC/MPEG4/" ) ) )
  835.         {
  836.             int i_profile, i_srate, sbr = 0;
  837.             static const unsigned int i_sample_rates[] =
  838.             {
  839.                     96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
  840.                         16000, 12000, 11025, 8000,  7350,  0,     0,     0
  841.             };
  842.             tracks[i_track]->fmt.i_codec = VLC_FOURCC( 'm', 'p', '4', 'a' );
  843.             /* create data for faad (MP4DecSpecificDescrTag)*/
  844.             if( !strcmp( &tracks[i_track]->psz_codec[12], "MAIN" ) )
  845.             {
  846.                 i_profile = 0;
  847.             }
  848.             else if( !strcmp( &tracks[i_track]->psz_codec[12], "LC" ) )
  849.             {
  850.                 i_profile = 1;
  851.             }
  852.             else if( !strcmp( &tracks[i_track]->psz_codec[12], "SSR" ) )
  853.             {
  854.                 i_profile = 2;
  855.             }
  856.             else if( !strcmp( &tracks[i_track]->psz_codec[12], "LC/SBR" ) )
  857.             {
  858.                 i_profile = 1;
  859.                 sbr = 1;
  860.             }
  861.             else
  862.             {
  863.                 i_profile = 3;
  864.             }
  865.             for( i_srate = 0; i_srate < 13; i_srate++ )
  866.             {
  867.                 if( i_sample_rates[i_srate] == tracks[i_track]->i_original_rate )
  868.                 {
  869.                     break;
  870.                 }
  871.             }
  872.             msg_Dbg( &sys.demuxer, "profile=%d srate=%d", i_profile, i_srate );
  873.             tracks[i_track]->fmt.i_extra = sbr ? 5 : 2;
  874.             tracks[i_track]->fmt.p_extra = malloc( tracks[i_track]->fmt.i_extra );
  875.             ((uint8_t*)tracks[i_track]->fmt.p_extra)[0] = ((i_profile + 1) << 3) | ((i_srate&0xe) >> 1);
  876.             ((uint8_t*)tracks[i_track]->fmt.p_extra)[1] = ((i_srate & 0x1) << 7) | (tracks[i_track]->fmt.audio.i_channels << 3);
  877.             if (sbr != 0)
  878.             {
  879.                 int syncExtensionType = 0x2B7;
  880.                 int iDSRI;
  881.                 for (iDSRI=0; iDSRI<13; iDSRI++)
  882.                     if( i_sample_rates[iDSRI] == tracks[i_track]->fmt.audio.i_rate )
  883.                         break;
  884.                 ((uint8_t*)tracks[i_track]->fmt.p_extra)[2] = (syncExtensionType >> 3) & 0xFF;
  885.                 ((uint8_t*)tracks[i_track]->fmt.p_extra)[3] = ((syncExtensionType & 0x7) << 5) | 5;
  886.                 ((uint8_t*)tracks[i_track]->fmt.p_extra)[4] = ((1 & 0x1) << 7) | (iDSRI << 3);
  887.             }
  888.         }
  889.         else if( !strcmp( tracks[i_track]->psz_codec, "A_AAC" ) )
  890.         {
  891.             tracks[i_track]->fmt.i_codec = VLC_FOURCC( 'm', 'p', '4', 'a' );
  892.             tracks[i_track]->fmt.i_extra = tracks[i_track]->i_extra_data;
  893.             tracks[i_track]->fmt.p_extra = malloc( tracks[i_track]->i_extra_data );
  894.             memcpy( tracks[i_track]->fmt.p_extra, tracks[i_track]->p_extra_data, tracks[i_track]->i_extra_data );
  895.         }
  896.         else if( !strcmp( tracks[i_track]->psz_codec, "A_WAVPACK4" ) )
  897.         {
  898.             tracks[i_track]->fmt.i_codec = VLC_FOURCC( 'W', 'V', 'P', 'K' );
  899.             tracks[i_track]->fmt.i_extra = tracks[i_track]->i_extra_data;
  900.             tracks[i_track]->fmt.p_extra = malloc( tracks[i_track]->i_extra_data );
  901.             memcpy( tracks[i_track]->fmt.p_extra, tracks[i_track]->p_extra_data, tracks[i_track]->i_extra_data );
  902.         }
  903.         else if( !strcmp( tracks[i_track]->psz_codec, "A_TTA1" ) )
  904.         {
  905.             p_fmt->i_codec = VLC_FOURCC( 'T', 'T', 'A', '1' );
  906.             p_fmt->i_extra = p_tk->i_extra_data;
  907.             if( p_fmt->i_extra > 0 )
  908.             {
  909.                 p_fmt->p_extra = malloc( p_tk->i_extra_data );
  910.                 if( !p_fmt->p_extra )
  911.                     abort();
  912.                 memcpy( p_fmt->p_extra, p_tk->p_extra_data, p_tk->i_extra_data );
  913.             }
  914.             else
  915.             {
  916.                 p_fmt->i_extra = 30;
  917.                 p_fmt->p_extra = malloc( p_fmt->i_extra );
  918.                 if( !p_fmt->p_extra )
  919.                     abort();
  920.                 uint8_t *p_extra = (uint8_t*)p_fmt->p_extra;
  921.                 memcpy( &p_extra[ 0], "TTA1", 4 );
  922.                 SetWLE( &p_extra[ 4], 1 );
  923.                 SetWLE( &p_extra[ 6], p_fmt->audio.i_channels );
  924.                 SetWLE( &p_extra[ 8], p_fmt->audio.i_bitspersample );
  925.                 SetDWLE( &p_extra[10], p_fmt->audio.i_rate );
  926.                 SetDWLE( &p_extra[14], 0xffffffff );
  927.                 memset( &p_extra[18], 0, 30  - 18 );
  928.             }
  929.         }
  930.         else if( !strcmp( tracks[i_track]->psz_codec, "A_PCM/INT/BIG" ) ||
  931.                  !strcmp( tracks[i_track]->psz_codec, "A_PCM/INT/LIT" ) ||
  932.                  !strcmp( tracks[i_track]->psz_codec, "A_PCM/FLOAT/IEEE" ) )
  933.         {
  934.             if( !strcmp( tracks[i_track]->psz_codec, "A_PCM/INT/BIG" ) )
  935.             {
  936.                 tracks[i_track]->fmt.i_codec = VLC_FOURCC( 't', 'w', 'o', 's' );
  937.             }
  938.             else
  939.             {
  940.                 tracks[i_track]->fmt.i_codec = VLC_FOURCC( 'a', 'r', 'a', 'w' );
  941.             }
  942.             tracks[i_track]->fmt.audio.i_blockalign = ( tracks[i_track]->fmt.audio.i_bitspersample + 7 ) / 8 * tracks[i_track]->fmt.audio.i_channels;
  943.         }
  944.         /* disabled due to the potential "S_KATE" namespace issue */
  945.         else if( !strcmp( tracks[i_track]->psz_codec, "S_KATE" ) )
  946.         {
  947.             int i, i_offset = 1, i_extra, num_headers, size_so_far;
  948.             uint8_t *p_extra;
  949.             tracks[i_track]->fmt.i_codec = VLC_FOURCC( 'k', 'a', 't', 'e' );
  950.             tracks[i_track]->fmt.subs.psz_encoding = strdup( "UTF-8" );
  951.             /* Recover the number of headers to expect */
  952.             num_headers = tracks[i_track]->p_extra_data[0]+1;
  953.             msg_Dbg( &sys.demuxer, "kate in mkv detected: %d headers in %u bytes",
  954.                 num_headers, tracks[i_track]->i_extra_data);
  955.             /* this won't overflow the stack as is can allocate only 1020 bytes max */
  956.             uint16_t pi_size[num_headers];
  957.             /* Split the headers */
  958.             size_so_far = 0;
  959.             for( i = 0; i < num_headers-1; i++ )
  960.             {
  961.                 pi_size[i] = 0;
  962.                 while( i_offset < tracks[i_track]->i_extra_data )
  963.                 {
  964.                     pi_size[i] += tracks[i_track]->p_extra_data[i_offset];
  965.                     if( tracks[i_track]->p_extra_data[i_offset++] != 0xff ) break;
  966.                 }
  967.                 msg_Dbg( &sys.demuxer, "kate header %d is %d bytes", i, pi_size[i]);
  968.                 size_so_far += pi_size[i];
  969.             }
  970.             pi_size[num_headers-1] = tracks[i_track]->i_extra_data - (size_so_far+i_offset);
  971.             msg_Dbg( &sys.demuxer, "kate last header (%d) is %d bytes", num_headers-1, pi_size[num_headers-1]);
  972.             tracks[i_track]->fmt.i_extra = 1 + num_headers * 2 + size_so_far + pi_size[num_headers-1];
  973.             tracks[i_track]->fmt.p_extra = malloc( tracks[i_track]->fmt.i_extra );
  974.             p_extra = (uint8_t *)tracks[i_track]->fmt.p_extra;
  975.             i_extra = 0;
  976.             *(p_extra++) = num_headers;
  977.             ++i_extra;
  978.             for( i = 0; i < num_headers; i++ )
  979.             {
  980.                 *(p_extra++) = pi_size[i] >> 8;
  981.                 *(p_extra++) = pi_size[i] & 0xFF;
  982.                 memcpy( p_extra, tracks[i_track]->p_extra_data + i_offset + i_extra-1,
  983.                         pi_size[i] );
  984.                 p_extra += pi_size[i];
  985.                 i_extra += pi_size[i];
  986.             }
  987.         }
  988.         else if( !strcmp( tracks[i_track]->psz_codec, "S_TEXT/ASCII" ) )
  989.         {
  990.             p_fmt->i_codec = VLC_FOURCC( 's', 'u', 'b', 't' );
  991.             p_fmt->subs.psz_encoding = NULL; /* Is there a place where it is stored ? */
  992.         }
  993.         else if( !strcmp( tracks[i_track]->psz_codec, "S_TEXT/UTF8" ) )
  994.         {
  995.             tracks[i_track]->fmt.i_codec = VLC_FOURCC( 's', 'u', 'b', 't' );
  996.             tracks[i_track]->fmt.subs.psz_encoding = strdup( "UTF-8" );
  997.         }
  998.         else if( !strcmp( tracks[i_track]->psz_codec, "S_TEXT/USF" ) )
  999.         {
  1000.             tracks[i_track]->fmt.i_codec = VLC_FOURCC( 'u', 's', 'f', ' ' );
  1001.             tracks[i_track]->fmt.subs.psz_encoding = strdup( "UTF-8" );
  1002.             if( tracks[i_track]->i_extra_data )
  1003.             {
  1004.                 tracks[i_track]->fmt.i_extra = tracks[i_track]->i_extra_data;
  1005.                 tracks[i_track]->fmt.p_extra = malloc( tracks[i_track]->i_extra_data );
  1006.                 memcpy( tracks[i_track]->fmt.p_extra, tracks[i_track]->p_extra_data, tracks[i_track]->i_extra_data );
  1007.             }
  1008.         }
  1009.         else if( !strcmp( tracks[i_track]->psz_codec, "S_TEXT/SSA" ) ||
  1010.                  !strcmp( tracks[i_track]->psz_codec, "S_TEXT/ASS" ) ||
  1011.                  !strcmp( tracks[i_track]->psz_codec, "S_SSA" ) ||
  1012.                  !strcmp( tracks[i_track]->psz_codec, "S_ASS" ))
  1013.         {
  1014.             tracks[i_track]->fmt.i_codec = VLC_FOURCC( 's', 's', 'a', ' ' );
  1015.             tracks[i_track]->fmt.subs.psz_encoding = strdup( "UTF-8" );
  1016.             if( tracks[i_track]->i_extra_data )
  1017.             {
  1018.                 tracks[i_track]->fmt.i_extra = tracks[i_track]->i_extra_data;
  1019.                 tracks[i_track]->fmt.p_extra = malloc( tracks[i_track]->i_extra_data );
  1020.                 memcpy( tracks[i_track]->fmt.p_extra, tracks[i_track]->p_extra_data, tracks[i_track]->i_extra_data );
  1021.             }
  1022.         }
  1023.         else if( !strcmp( tracks[i_track]->psz_codec, "S_VOBSUB" ) )
  1024.         {
  1025.             tracks[i_track]->fmt.i_codec = VLC_FOURCC( 's','p','u',' ' );
  1026.             if( tracks[i_track]->i_extra_data )
  1027.             {
  1028.                 char *p_start;
  1029.                 char *p_buf = (char *)malloc( tracks[i_track]->i_extra_data + 1);
  1030.                 memcpy( p_buf, tracks[i_track]->p_extra_data , tracks[i_track]->i_extra_data );
  1031.                 p_buf[tracks[i_track]->i_extra_data] = '';
  1032.  
  1033.                 p_start = strstr( p_buf, "size:" );
  1034.                 if( sscanf( p_start, "size: %dx%d",
  1035.                         &tracks[i_track]->fmt.subs.spu.i_original_frame_width, &tracks[i_track]->fmt.subs.spu.i_original_frame_height ) == 2 )
  1036.                 {
  1037.                     msg_Dbg( &sys.demuxer, "original frame size vobsubs: %dx%d", tracks[i_track]->fmt.subs.spu.i_original_frame_width, tracks[i_track]->fmt.subs.spu.i_original_frame_height );
  1038.                 }
  1039.                 else
  1040.                 {
  1041.                     msg_Warn( &sys.demuxer, "reading original frame size for vobsub failed" );
  1042.                 }
  1043.                 free( p_buf );
  1044.             }
  1045.         }
  1046.         else if( !strcmp( tracks[i_track]->psz_codec, "B_VOBBTN" ) )
  1047.         {
  1048.             tracks[i_track]->fmt.i_cat = NAV_ES;
  1049.             continue;
  1050.         }
  1051.         else if( !strcmp( p_tk->psz_codec, "A_REAL/14_4" ) )
  1052.         {
  1053.             p_fmt->i_codec = VLC_FOURCC( '1', '4', '_', '4');
  1054.             p_fmt->audio.i_channels = 1;
  1055.             p_fmt->audio.i_rate = 8000;
  1056.             p_fmt->audio.i_blockalign = 0x14;
  1057.         }
  1058.         else
  1059.         {
  1060.             msg_Err( &sys.demuxer, "unknown codec id=`%s'", tracks[i_track]->psz_codec );
  1061.             tracks[i_track]->fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
  1062.         }
  1063.         if( tracks[i_track]->b_default )
  1064.         {
  1065.             tracks[i_track]->fmt.i_priority = 1000;
  1066.         }
  1067.         tracks[i_track]->p_es = es_out_Add( sys.demuxer.out, &tracks[i_track]->fmt );
  1068.         /* Turn on a subtitles track if it has been flagged as default -
  1069.          * but only do this if no subtitles track has already been engaged,
  1070.          * either by an earlier 'default track' (??) or by default
  1071.          * language choice behaviour.
  1072.          */
  1073.         if( tracks[i_track]->b_default )
  1074.         {
  1075.             es_out_Control( sys.demuxer.out,
  1076.                             ES_OUT_SET_ES_DEFAULT,
  1077.                             tracks[i_track]->p_es );
  1078.         }
  1079.     }
  1080.     es_out_Control( sys.demuxer.out, ES_OUT_SET_NEXT_DISPLAY_TIME, i_start_time );
  1081.  
  1082.     sys.i_start_pts = i_start_time;
  1083.     // reset the stream reading to the first cluster of the segment used
  1084.     es.I_O().setFilePointer( i_start_pos );
  1085.     delete ep;
  1086.     ep = new EbmlParser( &es, segment, &sys.demuxer );
  1087.     return true;
  1088. }
  1089. void matroska_segment_c::UnSelect( )
  1090. {
  1091.     size_t i_track;
  1092.     for( i_track = 0; i_track < tracks.size(); i_track++ )
  1093.     {
  1094.         if ( tracks[i_track]->p_es != NULL )
  1095.         {
  1096. //            es_format_Clean( &tracks[i_track]->fmt );
  1097.             es_out_Del( sys.demuxer.out, tracks[i_track]->p_es );
  1098.             tracks[i_track]->p_es = NULL;
  1099.         }
  1100.     }
  1101.     delete ep;
  1102.     ep = NULL;
  1103. }
  1104. int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_simpleblock, int64_t *pi_ref1, int64_t *pi_ref2, int64_t *pi_duration )
  1105. {
  1106.     pp_simpleblock = NULL;
  1107.     pp_block = NULL;
  1108.     *pi_ref1  = 0;
  1109.     *pi_ref2  = 0;
  1110.     for( ;; )
  1111.     {
  1112.         EbmlElement *el = NULL;
  1113.         int         i_level;
  1114.         if ( ep == NULL )
  1115.             return VLC_EGENERIC;
  1116.         if( pp_simpleblock != NULL || ((el = ep->Get()) == NULL && pp_block != NULL) )
  1117.         {
  1118.             /* Check blocks validity to protect againts broken files */
  1119.             if( BlockFindTrackIndex( NULL, pp_block , pp_simpleblock ) )
  1120.             {
  1121.                 delete pp_block;
  1122.                 pp_simpleblock = NULL;
  1123.                 pp_block = NULL;
  1124.                 continue;
  1125.             }
  1126.             /* update the index */
  1127. #define idx p_indexes[i_index - 1]
  1128.             if( i_index > 0 && idx.i_time == -1 )
  1129.             {
  1130.                 if ( pp_simpleblock != NULL )
  1131.                     idx.i_time        = pp_simpleblock->GlobalTimecode() / (mtime_t)1000;
  1132.                 else
  1133.                     idx.i_time        = (*pp_block).GlobalTimecode() / (mtime_t)1000;
  1134.                 idx.b_key         = *pi_ref1 == 0 ? true : false;
  1135.             }
  1136. #undef idx
  1137.             return VLC_SUCCESS;
  1138.         }
  1139.         i_level = ep->GetLevel();
  1140.         if( el == NULL )
  1141.         {
  1142.             if( i_level > 1 )
  1143.             {
  1144.                 ep->Up();
  1145.                 continue;
  1146.             }
  1147.             msg_Warn( &sys.demuxer, "EOF" );
  1148.             return VLC_EGENERIC;
  1149.         }
  1150.         /* Verify that we are still inside our cluster
  1151.          * It can happens whith broken files and when seeking
  1152.          * without index */
  1153.         if( i_level > 1 )
  1154.         {
  1155.             if( cluster && !ep->IsTopPresent( cluster ) )
  1156.             {
  1157.                 msg_Warn( &sys.demuxer, "Unexpected escape from current cluster" );
  1158.                 cluster = NULL;
  1159.             }
  1160.             if( !cluster )
  1161.                 continue;
  1162.         }
  1163.         /* do parsing */
  1164.         switch ( i_level )
  1165.         {
  1166.         case 1:
  1167.             if( MKV_IS_ID( el, KaxCluster ) )
  1168.             {
  1169.                 cluster = (KaxCluster*)el;
  1170.                 i_cluster_pos = cluster->GetElementPosition();
  1171.                 /* add it to the index */
  1172.                 if( i_index == 0 ||
  1173.                     ( i_index > 0 && p_indexes[i_index - 1].i_position < (int64_t)cluster->GetElementPosition() ) )
  1174.                 {
  1175.                     IndexAppendCluster( cluster );
  1176.                 }
  1177.                 // reset silent tracks
  1178.                 for (size_t i=0; i<tracks.size(); i++)
  1179.                 {
  1180.                     tracks[i]->b_silent = false;
  1181.                 }
  1182.                 ep->Down();
  1183.             }
  1184.             else if( MKV_IS_ID( el, KaxCues ) )
  1185.             {
  1186.                 msg_Warn( &sys.demuxer, "find KaxCues FIXME" );
  1187.                 return VLC_EGENERIC;
  1188.             }
  1189.             else
  1190.             {
  1191.                 msg_Dbg( &sys.demuxer, "unknown (%s)", typeid( el ).name() );
  1192.             }
  1193.             break;
  1194.         case 2:
  1195.             if( MKV_IS_ID( el, KaxClusterTimecode ) )
  1196.             {
  1197.                 KaxClusterTimecode &ctc = *(KaxClusterTimecode*)el;
  1198.                 ctc.ReadData( es.I_O(), SCOPE_ALL_DATA );
  1199.                 cluster->InitTimecode( uint64( ctc ), i_timescale );
  1200.             }
  1201.             else if( MKV_IS_ID( el, KaxClusterSilentTracks ) )
  1202.             {
  1203.                 ep->Down();
  1204.             }
  1205.             else if( MKV_IS_ID( el, KaxBlockGroup ) )
  1206.             {
  1207.                 i_block_pos = el->GetElementPosition();
  1208.                 ep->Down();
  1209.             }
  1210.             else if( MKV_IS_ID( el, KaxSimpleBlock ) )
  1211.             {
  1212.                 pp_simpleblock = (KaxSimpleBlock*)el;
  1213.                 pp_simpleblock->ReadData( es.I_O() );
  1214.                 pp_simpleblock->SetParent( *cluster );
  1215.             }
  1216.             break;
  1217.         case 3:
  1218.             if( MKV_IS_ID( el, KaxBlock ) )
  1219.             {
  1220.                 pp_block = (KaxBlock*)el;
  1221.                 pp_block->ReadData( es.I_O() );
  1222.                 pp_block->SetParent( *cluster );
  1223.                 ep->Keep();
  1224.             }
  1225.             else if( MKV_IS_ID( el, KaxBlockDuration ) )
  1226.             {
  1227.                 KaxBlockDuration &dur = *(KaxBlockDuration*)el;
  1228.                 dur.ReadData( es.I_O() );
  1229.                 *pi_duration = uint64( dur );
  1230.             }
  1231.             else if( MKV_IS_ID( el, KaxReferenceBlock ) )
  1232.             {
  1233.                 KaxReferenceBlock &ref = *(KaxReferenceBlock*)el;
  1234.                 ref.ReadData( es.I_O() );
  1235.                 if( *pi_ref1 == 0 )
  1236.                 {
  1237.                     *pi_ref1 = int64( ref ) * cluster->GlobalTimecodeScale();
  1238.                 }
  1239.                 else if( *pi_ref2 == 0 )
  1240.                 {
  1241.                     *pi_ref2 = int64( ref ) * cluster->GlobalTimecodeScale();
  1242.                 }
  1243.             }
  1244.             else if( MKV_IS_ID( el, KaxClusterSilentTrackNumber ) )
  1245.             {
  1246.                 KaxClusterSilentTrackNumber &track_num = *(KaxClusterSilentTrackNumber*)el;
  1247.                 track_num.ReadData( es.I_O() );
  1248.                 // find the track
  1249.                 for (size_t i=0; i<tracks.size(); i++)
  1250.                 {
  1251.                     if ( tracks[i]->i_number == uint32(track_num))
  1252.                     {
  1253.                         tracks[i]->b_silent = true;
  1254.                         break;
  1255.                     }
  1256.                 }
  1257.             }
  1258.             break;
  1259.         default:
  1260.             msg_Err( &sys.demuxer, "invalid level = %d", i_level );
  1261.             return VLC_EGENERIC;
  1262.         }
  1263.     }
  1264. }