mkv.cpp
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:83k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * mkv.cpp : matroska demuxer
  3.  *****************************************************************************
  4.  * Copyright (C) 2003-2004 VideoLAN
  5.  * $Id: mkv.cpp 8892 2004-10-02 20:07:35Z hartman $
  6.  *
  7.  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  8.  *
  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.
  13.  *
  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.
  18.  *
  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.  *****************************************************************************/
  23. /*****************************************************************************
  24.  * Preamble
  25.  *****************************************************************************/
  26. #include <stdlib.h>                                      /* malloc(), free() */
  27. #include <vlc/vlc.h>
  28. #ifdef HAVE_TIME_H
  29. #   include <time.h>                                               /* time() */
  30. #endif
  31. #include <vlc/input.h>
  32. #include <codecs.h>                        /* BITMAPINFOHEADER, WAVEFORMATEX */
  33. #include "iso_lang.h"
  34. #include "vlc_meta.h"
  35. #include <iostream>
  36. #include <cassert>
  37. #include <typeinfo>
  38. /* libebml and matroska */
  39. #include "ebml/EbmlHead.h"
  40. #include "ebml/EbmlSubHead.h"
  41. #include "ebml/EbmlStream.h"
  42. #include "ebml/EbmlContexts.h"
  43. #include "ebml/EbmlVersion.h"
  44. #include "ebml/EbmlVoid.h"
  45. #include "matroska/FileKax.h"
  46. #include "matroska/KaxAttachments.h"
  47. #include "matroska/KaxBlock.h"
  48. #include "matroska/KaxBlockData.h"
  49. #include "matroska/KaxChapters.h"
  50. #include "matroska/KaxCluster.h"
  51. #include "matroska/KaxClusterData.h"
  52. #include "matroska/KaxContexts.h"
  53. #include "matroska/KaxCues.h"
  54. #include "matroska/KaxCuesData.h"
  55. #include "matroska/KaxInfo.h"
  56. #include "matroska/KaxInfoData.h"
  57. #include "matroska/KaxSeekHead.h"
  58. #include "matroska/KaxSegment.h"
  59. #include "matroska/KaxTag.h"
  60. #include "matroska/KaxTags.h"
  61. #include "matroska/KaxTagMulti.h"
  62. #include "matroska/KaxTracks.h"
  63. #include "matroska/KaxTrackAudio.h"
  64. #include "matroska/KaxTrackVideo.h"
  65. #include "matroska/KaxTrackEntryData.h"
  66. #include "matroska/KaxContentEncoding.h"
  67. #include "ebml/StdIOCallback.h"
  68. extern "C" {
  69.    #include "mp4/libmp4.h"
  70. }
  71. #ifdef HAVE_ZLIB_H
  72. #   include <zlib.h>
  73. #endif
  74. #define MATROSKA_COMPRESSION_NONE 0
  75. #define MATROSKA_COMPRESSION_ZLIB 1
  76. using namespace LIBMATROSKA_NAMESPACE;
  77. using namespace std;
  78. /*****************************************************************************
  79.  * Module descriptor
  80.  *****************************************************************************/
  81. static int  Open ( vlc_object_t * );
  82. static void Close( vlc_object_t * );
  83. vlc_module_begin();
  84.     set_description( _("Matroska stream demuxer" ) );
  85.     set_capability( "demux2", 50 );
  86.     set_callbacks( Open, Close );
  87.     add_bool( "mkv-seek-percent", 1, NULL,
  88.             N_("Seek based on percent not time"),
  89.             N_("Seek based on percent not time"), VLC_TRUE );
  90.     add_shortcut( "mka" );
  91.     add_shortcut( "mkv" );
  92. vlc_module_end();
  93. /*****************************************************************************
  94.  * Local prototypes
  95.  *****************************************************************************/
  96. static int  Demux  ( demux_t * );
  97. static int  Control( demux_t *, int, va_list );
  98. static void Seek   ( demux_t *, mtime_t i_date, int i_percent );
  99. #ifdef HAVE_ZLIB_H
  100. block_t *block_zlib_decompress( vlc_object_t *p_this, block_t *p_in_block ) {
  101.     int result, dstsize, n;
  102.     unsigned char *dst;
  103.     block_t *p_block;
  104.     z_stream d_stream;
  105.     d_stream.zalloc = (alloc_func)0;
  106.     d_stream.zfree = (free_func)0;
  107.     d_stream.opaque = (voidpf)0;
  108.     result = inflateInit(&d_stream);
  109.     if( result != Z_OK )
  110.     {
  111.         msg_Dbg( p_this, "inflateInit() failed. Result: %d", result );
  112.         return NULL;
  113.     }
  114.     d_stream.next_in = (Bytef *)p_in_block->p_buffer;
  115.     d_stream.avail_in = p_in_block->i_buffer;
  116.     n = 0;
  117.     p_block = block_New( p_this, 0 );
  118.     dst = NULL;
  119.     do
  120.     {
  121.         n++;
  122.         p_block = block_Realloc( p_block, 0, n * 1000 );
  123.         dst = (unsigned char *)p_block->p_buffer;
  124.         d_stream.next_out = (Bytef *)&dst[(n - 1) * 1000];
  125.         d_stream.avail_out = 1000;
  126.         result = inflate(&d_stream, Z_NO_FLUSH);
  127.         if( ( result != Z_OK ) && ( result != Z_STREAM_END ) )
  128.         {
  129.             msg_Dbg( p_this, "Zlib decompression failed. Result: %d", result );
  130.             return NULL;
  131.         }
  132.     }
  133.     while( ( d_stream.avail_out == 0 ) && ( d_stream.avail_in != 0 ) &&
  134.            ( result != Z_STREAM_END ) );
  135.     dstsize = d_stream.total_out;
  136.     inflateEnd( &d_stream );
  137.     p_block = block_Realloc( p_block, 0, dstsize );
  138.     p_block->i_buffer = dstsize;
  139.     block_Release( p_in_block );
  140.     return p_block;
  141. }
  142. #endif
  143. /**
  144.  * Helper function to print the mkv parse tree
  145.  */
  146. static void MkvTree( demux_t *p_this, int i_level, char *psz_format, ... )
  147. {
  148.     va_list args;
  149.     if( i_level > 9 )
  150.     {
  151.         msg_Err( p_this, "too deep tree" );
  152.         return;
  153.     }
  154.     va_start( args, psz_format );
  155.     static char *psz_foo = "|   |   |   |   |   |   |   |   |   |";
  156.     char *psz_foo2 = (char*)malloc( ( i_level * 4 + 3 + strlen( psz_format ) ) * sizeof(char) );
  157.     strncpy( psz_foo2, psz_foo, 4 * i_level );
  158.     psz_foo2[ 4 * i_level ] = '+';
  159.     psz_foo2[ 4 * i_level + 1 ] = ' ';
  160.     strcpy( &psz_foo2[ 4 * i_level + 2 ], psz_format );
  161.     __msg_GenericVa( VLC_OBJECT(p_this), VLC_MSG_DBG, "mkv", psz_foo2, args );
  162.     free( psz_foo2 );
  163.     va_end( args );
  164. }
  165.     
  166. /*****************************************************************************
  167.  * Stream managment
  168.  *****************************************************************************/
  169. class vlc_stream_io_callback: public IOCallback
  170. {
  171.   private:
  172.     stream_t       *s;
  173.     vlc_bool_t     mb_eof;
  174.   public:
  175.     vlc_stream_io_callback( stream_t * );
  176.     virtual uint32   read            ( void *p_buffer, size_t i_size);
  177.     virtual void     setFilePointer  ( int64_t i_offset, seek_mode mode = seek_beginning );
  178.     virtual size_t   write           ( const void *p_buffer, size_t i_size);
  179.     virtual uint64   getFilePointer  ( void );
  180.     virtual void     close           ( void );
  181. };
  182. /*****************************************************************************
  183.  * Ebml Stream parser
  184.  *****************************************************************************/
  185. class EbmlParser
  186. {
  187.   public:
  188.     EbmlParser( EbmlStream *es, EbmlElement *el_start );
  189.     ~EbmlParser( void );
  190.     void Up( void );
  191.     void Down( void );
  192.     EbmlElement *Get( void );
  193.     void        Keep( void );
  194.     int GetLevel( void );
  195.   private:
  196.     EbmlStream  *m_es;
  197.     int         mi_level;
  198.     EbmlElement *m_el[10];
  199.     EbmlElement *m_got;
  200.     int         mi_user_level;
  201.     vlc_bool_t  mb_keep;
  202. };
  203. /*****************************************************************************
  204.  * Some functions to manipulate memory
  205.  *****************************************************************************/
  206. #define GetFOURCC( p )  __GetFOURCC( (uint8_t*)p )
  207. static vlc_fourcc_t __GetFOURCC( uint8_t *p )
  208. {
  209.     return VLC_FOURCC( p[0], p[1], p[2], p[3] );
  210. }
  211. /*****************************************************************************
  212.  * definitions of structures and functions used by this plugins
  213.  *****************************************************************************/
  214. typedef struct
  215. {
  216.     vlc_bool_t  b_default;
  217.     vlc_bool_t  b_enabled;
  218.     int         i_number;
  219.     int         i_extra_data;
  220.     uint8_t     *p_extra_data;
  221.     char         *psz_codec;
  222.     uint64_t     i_default_duration;
  223.     float        f_timecodescale;
  224.     /* video */
  225.     es_format_t fmt;
  226.     float       f_fps;
  227.     es_out_id_t *p_es;
  228.     vlc_bool_t      b_inited;
  229.     /* data to be send first */
  230.     int             i_data_init;
  231.     uint8_t         *p_data_init;
  232.     /* hack : it's for seek */
  233.     vlc_bool_t      b_search_keyframe;
  234.     /* informative */
  235.     char         *psz_codec_name;
  236.     char         *psz_codec_settings;
  237.     char         *psz_codec_info_url;
  238.     char         *psz_codec_download_url;
  239.     
  240.     /* encryption/compression */
  241.     int           i_compression_type;
  242. } mkv_track_t;
  243. typedef struct
  244. {
  245.     int     i_track;
  246.     int     i_block_number;
  247.     int64_t i_position;
  248.     int64_t i_time;
  249.     vlc_bool_t b_key;
  250. } mkv_index_t;
  251. struct demux_sys_t
  252. {
  253.     vlc_stream_io_callback  *in;
  254.     EbmlStream              *es;
  255.     EbmlParser              *ep;
  256.     /* time scale */
  257.     uint64_t                i_timescale;
  258.     /* duration of the segment */
  259.     float                   f_duration;
  260.     /* all tracks */
  261.     int                     i_track;
  262.     mkv_track_t             *track;
  263.     /* from seekhead */
  264.     int64_t                 i_cues_position;
  265.     int64_t                 i_chapters_position;
  266.     int64_t                 i_tags_position;
  267.     /* current data */
  268.     KaxSegment              *segment;
  269.     KaxCluster              *cluster;
  270.     mtime_t                 i_pts;
  271.     vlc_bool_t              b_cues;
  272.     int                     i_index;
  273.     int                     i_index_max;
  274.     mkv_index_t             *index;
  275.     /* info */
  276.     char                    *psz_muxing_application;
  277.     char                    *psz_writing_application;
  278.     char                    *psz_segment_filename;
  279.     char                    *psz_title;
  280.     char                    *psz_date_utc;
  281.     vlc_meta_t              *meta;
  282.     input_title_t           *title;
  283. };
  284. #define MKVD_TIMECODESCALE 1000000
  285. #define MKV_IS_ID( el, C ) ( EbmlId( (*el) ) == C::ClassInfos.GlobalId )
  286. static void IndexAppendCluster  ( demux_t *p_demux, KaxCluster *cluster );
  287. static char *UTF8ToStr          ( const UTFstring &u );
  288. static void LoadCues            ( demux_t * );
  289. static void InformationCreate  ( demux_t * );
  290. static void ParseInfo( demux_t *, EbmlElement *info );
  291. static void ParseTracks( demux_t *, EbmlElement *tracks );
  292. static void ParseSeekHead( demux_t *, EbmlElement *seekhead );
  293. static void ParseChapters( demux_t *, EbmlElement *chapters );
  294. /*****************************************************************************
  295.  * Open: initializes matroska demux structures
  296.  *****************************************************************************/
  297. static int Open( vlc_object_t * p_this )
  298. {
  299.     demux_t     *p_demux = (demux_t*)p_this;
  300.     demux_sys_t *p_sys;
  301.     uint8_t     *p_peek;
  302.     int          i_track;
  303.     EbmlElement *el = NULL, *el1 = NULL;
  304.     /* peek the begining */
  305.     if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 )
  306.     {
  307.         msg_Warn( p_demux, "cannot peek" );
  308.         return VLC_EGENERIC;
  309.     }
  310.     /* is a valid file */
  311.     if( p_peek[0] != 0x1a || p_peek[1] != 0x45 ||
  312.         p_peek[2] != 0xdf || p_peek[3] != 0xa3 )
  313.     {
  314.         msg_Warn( p_demux, "matroska module discarded "
  315.                            "(invalid header 0x%.2x%.2x%.2x%.2x)",
  316.                            p_peek[0], p_peek[1], p_peek[2], p_peek[3] );
  317.         return VLC_EGENERIC;
  318.     }
  319.     /* Set the demux function */
  320.     p_demux->pf_demux   = Demux;
  321.     p_demux->pf_control = Control;
  322.     p_demux->p_sys      = p_sys = (demux_sys_t*)malloc(sizeof( demux_sys_t ));
  323.     memset( p_sys, 0, sizeof( demux_sys_t ) );
  324.     p_sys->in = new vlc_stream_io_callback( p_demux->s );
  325.     p_sys->es = new EbmlStream( *p_sys->in );
  326.     p_sys->f_duration   = -1;
  327.     p_sys->i_timescale     = MKVD_TIMECODESCALE;
  328.     p_sys->i_track      = 0;
  329.     p_sys->track        = (mkv_track_t*)malloc( sizeof( mkv_track_t ) );
  330.     p_sys->i_pts   = 0;
  331.     p_sys->i_cues_position = -1;
  332.     p_sys->i_chapters_position = -1;
  333.     p_sys->i_tags_position = -1;
  334.     p_sys->b_cues       = VLC_FALSE;
  335.     p_sys->i_index      = 0;
  336.     p_sys->i_index_max  = 1024;
  337.     p_sys->index        = (mkv_index_t*)malloc( sizeof( mkv_index_t ) *
  338.                                                 p_sys->i_index_max );
  339.     p_sys->psz_muxing_application = NULL;
  340.     p_sys->psz_writing_application = NULL;
  341.     p_sys->psz_segment_filename = NULL;
  342.     p_sys->psz_title = NULL;
  343.     p_sys->psz_date_utc = NULL;;
  344.     p_sys->meta = NULL;
  345.     p_sys->title = NULL;
  346.     if( p_sys->es == NULL )
  347.     {
  348.         msg_Err( p_demux, "failed to create EbmlStream" );
  349.         delete p_sys->in;
  350.         free( p_sys );
  351.         return VLC_EGENERIC;
  352.     }
  353.     /* Find the EbmlHead element */
  354.     el = p_sys->es->FindNextID(EbmlHead::ClassInfos, 0xFFFFFFFFL);
  355.     if( el == NULL )
  356.     {
  357.         msg_Err( p_demux, "cannot find EbmlHead" );
  358.         goto error;
  359.     }
  360.     msg_Dbg( p_demux, "EbmlHead" );
  361.     /* skip it */
  362.     el->SkipData( *p_sys->es, el->Generic().Context );
  363.     delete el;
  364.     /* Find a segment */
  365.     el = p_sys->es->FindNextID( KaxSegment::ClassInfos, 0xFFFFFFFFL);
  366.     if( el == NULL )
  367.     {
  368.         msg_Err( p_demux, "cannot find KaxSegment" );
  369.         goto error;
  370.     }
  371.     MkvTree( p_demux, 0, "Segment" );
  372.     p_sys->segment = (KaxSegment*)el;
  373.     p_sys->cluster = NULL;
  374.     p_sys->ep = new EbmlParser( p_sys->es, el );
  375.     while( ( el1 = p_sys->ep->Get() ) != NULL )
  376.     {
  377.         if( MKV_IS_ID( el1, KaxInfo ) )
  378.         {
  379.             ParseInfo( p_demux, el1 );
  380.         }
  381.         else if( MKV_IS_ID( el1, KaxTracks ) )
  382.         {
  383.             ParseTracks( p_demux, el1 );
  384.         }
  385.         else if( MKV_IS_ID( el1, KaxSeekHead ) )
  386.         {
  387.             ParseSeekHead( p_demux, el1 );
  388.         }
  389.         else if( MKV_IS_ID( el1, KaxCues ) )
  390.         {
  391.             msg_Dbg( p_demux, "|   + Cues" );
  392.         }
  393.         else if( MKV_IS_ID( el1, KaxCluster ) )
  394.         {
  395.             msg_Dbg( p_demux, "|   + Cluster" );
  396.             p_sys->cluster = (KaxCluster*)el1;
  397.             p_sys->ep->Down();
  398.             /* stop parsing the stream */
  399.             break;
  400.         }
  401.         else if( MKV_IS_ID( el1, KaxAttachments ) )
  402.         {
  403.             msg_Dbg( p_demux, "|   + Attachments FIXME TODO (but probably never supported)" );
  404.         }
  405.         else if( MKV_IS_ID( el1, KaxChapters ) )
  406.         {
  407.             msg_Dbg( p_demux, "|   + Chapters" );
  408.             ParseChapters( p_demux, el1 );
  409.         }
  410.         else if( MKV_IS_ID( el1, KaxTag ) )
  411.         {
  412.             msg_Dbg( p_demux, "|   + Tags FIXME TODO" );
  413.         }
  414.         else
  415.         {
  416.             msg_Dbg( p_demux, "|   + Unknown (%s)", typeid(*el1).name() );
  417.         }
  418.     }
  419.     if( p_sys->cluster == NULL )
  420.     {
  421.         msg_Err( p_demux, "cannot find any cluster, damaged file ?" );
  422.         goto error;
  423.     }
  424.     /* *** Load the cue if found *** */
  425.     if( p_sys->i_cues_position >= 0 )
  426.     {
  427.         vlc_bool_t b_seekable;
  428.         stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b_seekable );
  429.         if( b_seekable )
  430.         {
  431.             LoadCues( p_demux );
  432.         }
  433.     }
  434.     if( !p_sys->b_cues || p_sys->i_index <= 0 )
  435.     {
  436.         msg_Warn( p_demux, "no cues/empty cues found->seek won't be precise" );
  437.         IndexAppendCluster( p_demux, p_sys->cluster );
  438.         p_sys->b_cues = VLC_FALSE;
  439.     }
  440.     /* add all es */
  441.     msg_Dbg( p_demux, "found %d es", p_sys->i_track );
  442.     for( i_track = 0; i_track < p_sys->i_track; i_track++ )
  443.     {
  444. #define tk  p_sys->track[i_track]
  445.         if( tk.fmt.i_cat == UNKNOWN_ES )
  446.         {
  447.             msg_Warn( p_demux, "invalid track[%d, n=%d]", i_track, tk.i_number );
  448.             tk.p_es = NULL;
  449.             continue;
  450.         }
  451.         if( !strcmp( tk.psz_codec, "V_MS/VFW/FOURCC" ) )
  452.         {
  453.             if( tk.i_extra_data < (int)sizeof( BITMAPINFOHEADER ) )
  454.             {
  455.                 msg_Err( p_demux, "missing/invalid BITMAPINFOHEADER" );
  456.                 tk.fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
  457.             }
  458.             else
  459.             {
  460.                 BITMAPINFOHEADER *p_bih = (BITMAPINFOHEADER*)tk.p_extra_data;
  461.                 tk.fmt.video.i_width = GetDWLE( &p_bih->biWidth );
  462.                 tk.fmt.video.i_height= GetDWLE( &p_bih->biHeight );
  463.                 tk.fmt.i_codec       = GetFOURCC( &p_bih->biCompression );
  464.                 tk.fmt.i_extra       = GetDWLE( &p_bih->biSize ) - sizeof( BITMAPINFOHEADER );
  465.                 if( tk.fmt.i_extra > 0 )
  466.                 {
  467.                     tk.fmt.p_extra = malloc( tk.fmt.i_extra );
  468.                     memcpy( tk.fmt.p_extra, &p_bih[1], tk.fmt.i_extra );
  469.                 }
  470.             }
  471.         }
  472.         else if( !strcmp( tk.psz_codec, "V_MPEG1" ) ||
  473.                  !strcmp( tk.psz_codec, "V_MPEG2" ) )
  474.         {
  475.             tk.fmt.i_codec = VLC_FOURCC( 'm', 'p', 'g', 'v' );
  476.         }
  477.         else if( !strncmp( tk.psz_codec, "V_MPEG4", 7 ) )
  478.         {
  479.             if( !strcmp( tk.psz_codec, "V_MPEG4/MS/V3" ) )
  480.             {
  481.                 tk.fmt.i_codec = VLC_FOURCC( 'D', 'I', 'V', '3' );
  482.             }
  483.             else
  484.             {
  485.                 tk.fmt.i_codec = VLC_FOURCC( 'm', 'p', '4', 'v' );
  486.             }
  487.         }
  488.         else if( !strcmp( tk.psz_codec, "V_QUICKTIME" ) )
  489.         {
  490.             MP4_Box_t *p_box = (MP4_Box_t*)malloc( sizeof( MP4_Box_t ) );
  491.             MP4_Stream_t *p_mp4_stream = MP4_MemoryStream( p_demux->s,
  492.                                                            tk.i_extra_data,
  493.                                                            tk.p_extra_data );
  494.             MP4_ReadBoxCommon( p_mp4_stream, p_box );
  495.             MP4_ReadBox_sample_vide( p_mp4_stream, p_box );
  496.             tk.fmt.i_codec = p_box->i_type;
  497.             tk.fmt.video.i_width = p_box->data.p_sample_vide->i_width;
  498.             tk.fmt.video.i_height = p_box->data.p_sample_vide->i_height;
  499.             tk.fmt.i_extra = p_box->data.p_sample_vide->i_qt_image_description;
  500.             tk.fmt.p_extra = malloc( tk.fmt.i_extra );
  501.             memcpy( tk.fmt.p_extra, p_box->data.p_sample_vide->p_qt_image_description, tk.fmt.i_extra );
  502.             MP4_FreeBox_sample_vide( p_box );
  503.             free( p_box );
  504.             free( p_mp4_stream );
  505.         }
  506.         else if( !strcmp( tk.psz_codec, "A_MS/ACM" ) )
  507.         {
  508.             if( tk.i_extra_data < (int)sizeof( WAVEFORMATEX ) )
  509.             {
  510.                 msg_Err( p_demux, "missing/invalid WAVEFORMATEX" );
  511.                 tk.fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
  512.             }
  513.             else
  514.             {
  515.                 WAVEFORMATEX *p_wf = (WAVEFORMATEX*)tk.p_extra_data;
  516.                 wf_tag_to_fourcc( GetWLE( &p_wf->wFormatTag ), &tk.fmt.i_codec, NULL );
  517.                 tk.fmt.audio.i_channels   = GetWLE( &p_wf->nChannels );
  518.                 tk.fmt.audio.i_rate = GetDWLE( &p_wf->nSamplesPerSec );
  519.                 tk.fmt.i_bitrate    = GetDWLE( &p_wf->nAvgBytesPerSec ) * 8;
  520.                 tk.fmt.audio.i_blockalign = GetWLE( &p_wf->nBlockAlign );;
  521.                 tk.fmt.audio.i_bitspersample = GetWLE( &p_wf->wBitsPerSample );
  522.                 tk.fmt.i_extra            = GetWLE( &p_wf->cbSize );
  523.                 if( tk.fmt.i_extra > 0 )
  524.                 {
  525.                     tk.fmt.p_extra = malloc( tk.fmt.i_extra );
  526.                     memcpy( tk.fmt.p_extra, &p_wf[1], tk.fmt.i_extra );
  527.                 }
  528.             }
  529.         }
  530.         else if( !strcmp( tk.psz_codec, "A_MPEG/L3" ) ||
  531.                  !strcmp( tk.psz_codec, "A_MPEG/L2" ) ||
  532.                  !strcmp( tk.psz_codec, "A_MPEG/L1" ) )
  533.         {
  534.             tk.fmt.i_codec = VLC_FOURCC( 'm', 'p', 'g', 'a' );
  535.         }
  536.         else if( !strcmp( tk.psz_codec, "A_AC3" ) )
  537.         {
  538.             tk.fmt.i_codec = VLC_FOURCC( 'a', '5', '2', ' ' );
  539.         }
  540.         else if( !strcmp( tk.psz_codec, "A_DTS" ) )
  541.         {
  542.             tk.fmt.i_codec = VLC_FOURCC( 'd', 't', 's', ' ' );
  543.         }
  544.         else if( !strcmp( tk.psz_codec, "A_FLAC" ) )
  545.         {
  546.             tk.fmt.i_codec = VLC_FOURCC( 'f', 'l', 'a', 'c' );
  547.             tk.fmt.i_extra = tk.i_extra_data;
  548.             tk.fmt.p_extra = malloc( tk.i_extra_data );
  549.             memcpy( tk.fmt.p_extra,tk.p_extra_data, tk.i_extra_data );
  550.         }
  551.         else if( !strcmp( tk.psz_codec, "A_VORBIS" ) )
  552.         {
  553.             int i, i_offset = 1, i_size[3], i_extra;
  554.             uint8_t *p_extra;
  555.             tk.fmt.i_codec = VLC_FOURCC( 'v', 'o', 'r', 'b' );
  556.             /* Split the 3 headers */
  557.             if( tk.p_extra_data[0] != 0x02 )
  558.                 msg_Err( p_demux, "invalid vorbis header" );
  559.             for( i = 0; i < 2; i++ )
  560.             {
  561.                 i_size[i] = 0;
  562.                 while( i_offset < tk.i_extra_data )
  563.                 {
  564.                     i_size[i] += tk.p_extra_data[i_offset];
  565.                     if( tk.p_extra_data[i_offset++] != 0xff ) break;
  566.                 }
  567.             }
  568.             i_size[0] = __MIN(i_size[0], tk.i_extra_data - i_offset);
  569.             i_size[1] = __MIN(i_size[1], tk.i_extra_data -i_offset -i_size[0]);
  570.             i_size[2] = tk.i_extra_data - i_offset - i_size[0] - i_size[1];
  571.             tk.fmt.i_extra = 3 * 2 + i_size[0] + i_size[1] + i_size[2];
  572.             tk.fmt.p_extra = malloc( tk.fmt.i_extra );
  573.             p_extra = (uint8_t *)tk.fmt.p_extra; i_extra = 0;
  574.             for( i = 0; i < 3; i++ )
  575.             {
  576.                 *(p_extra++) = i_size[i] >> 8;
  577.                 *(p_extra++) = i_size[i] & 0xFF;
  578.                 memcpy( p_extra, tk.p_extra_data + i_offset + i_extra,
  579.                         i_size[i] );
  580.                 p_extra += i_size[i];
  581.                 i_extra += i_size[i];
  582.             }
  583.         }
  584.         else if( !strncmp( tk.psz_codec, "A_AAC/MPEG2/", strlen( "A_AAC/MPEG2/" ) ) ||
  585.                  !strncmp( tk.psz_codec, "A_AAC/MPEG4/", strlen( "A_AAC/MPEG4/" ) ) )
  586.         {
  587.             int i_profile, i_srate;
  588.             static unsigned int i_sample_rates[] =
  589.             {
  590.                     96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
  591.                         16000, 12000, 11025, 8000,  7350,  0,     0,     0
  592.             };
  593.             tk.fmt.i_codec = VLC_FOURCC( 'm', 'p', '4', 'a' );
  594.             /* create data for faad (MP4DecSpecificDescrTag)*/
  595.             if( !strcmp( &tk.psz_codec[12], "MAIN" ) )
  596.             {
  597.                 i_profile = 0;
  598.             }
  599.             else if( !strcmp( &tk.psz_codec[12], "LC" ) )
  600.             {
  601.                 i_profile = 1;
  602.             }
  603.             else if( !strcmp( &tk.psz_codec[12], "SSR" ) )
  604.             {
  605.                 i_profile = 2;
  606.             }
  607.             else
  608.             {
  609.                 i_profile = 3;
  610.             }
  611.             for( i_srate = 0; i_srate < 13; i_srate++ )
  612.             {
  613.                 if( i_sample_rates[i_srate] == tk.fmt.audio.i_rate )
  614.                 {
  615.                     break;
  616.                 }
  617.             }
  618.             msg_Dbg( p_demux, "profile=%d srate=%d", i_profile, i_srate );
  619.             tk.fmt.i_extra = 2;
  620.             tk.fmt.p_extra = malloc( tk.fmt.i_extra );
  621.             ((uint8_t*)tk.fmt.p_extra)[0] = ((i_profile + 1) << 3) | ((i_srate&0xe) >> 1);
  622.             ((uint8_t*)tk.fmt.p_extra)[1] = ((i_srate & 0x1) << 7) | (tk.fmt.audio.i_channels << 3);
  623.         }
  624.         else if( !strcmp( tk.psz_codec, "A_PCM/INT/BIG" ) ||
  625.                  !strcmp( tk.psz_codec, "A_PCM/INT/LIT" ) ||
  626.                  !strcmp( tk.psz_codec, "A_PCM/FLOAT/IEEE" ) )
  627.         {
  628.             if( !strcmp( tk.psz_codec, "A_PCM/INT/BIG" ) )
  629.             {
  630.                 tk.fmt.i_codec = VLC_FOURCC( 't', 'w', 'o', 's' );
  631.             }
  632.             else
  633.             {
  634.                 tk.fmt.i_codec = VLC_FOURCC( 'a', 'r', 'a', 'w' );
  635.             }
  636.             tk.fmt.audio.i_blockalign = ( tk.fmt.audio.i_bitspersample + 7 ) / 8 * tk.fmt.audio.i_channels;
  637.         }
  638.         else if( !strcmp( tk.psz_codec, "S_TEXT/UTF8" ) )
  639.         {
  640.             tk.fmt.i_codec = VLC_FOURCC( 's', 'u', 'b', 't' );
  641.             tk.fmt.subs.psz_encoding = strdup( "UTF-8" );
  642.         }
  643.         else if( !strcmp( tk.psz_codec, "S_TEXT/SSA" ) ||
  644.                  !strcmp( tk.psz_codec, "S_TEXT/ASS" ) ||
  645.                  !strcmp( tk.psz_codec, "S_SSA" ) ||
  646.                  !strcmp( tk.psz_codec, "S_ASS" ))
  647.         {
  648.             tk.fmt.i_codec = VLC_FOURCC( 's', 's', 'a', ' ' );
  649.             tk.fmt.subs.psz_encoding = strdup( "UTF-8" );
  650.         }
  651.         else if( !strcmp( tk.psz_codec, "S_VOBSUB" ) )
  652.         {
  653.             tk.fmt.i_codec = VLC_FOURCC( 's','p','u',' ' );
  654.             if( tk.i_extra_data )
  655.             {
  656.                 char *p_start;
  657.                 char *p_buf = (char *)malloc( tk.i_extra_data + 1);
  658.                 memcpy( p_buf, tk.p_extra_data , tk.i_extra_data );
  659.                 p_buf[tk.i_extra_data] = '';
  660.                 
  661.                 p_start = strstr( p_buf, "size:" );
  662.                 if( sscanf( p_start, "size: %dx%d",
  663.                         &tk.fmt.subs.spu.i_original_frame_width, &tk.fmt.subs.spu.i_original_frame_height ) == 2 )
  664.                 {
  665.                     msg_Dbg( p_demux, "original frame size vobsubs: %dx%d", tk.fmt.subs.spu.i_original_frame_width, tk.fmt.subs.spu.i_original_frame_height );
  666.                 }
  667.                 else
  668.                 {
  669.                     msg_Warn( p_demux, "reading original frame size for vobsub failed" );
  670.                 }
  671.                 free( p_buf );
  672.             }
  673.         }
  674.         else
  675.         {
  676.             msg_Err( p_demux, "unknow codec id=`%s'", tk.psz_codec );
  677.             tk.fmt.i_codec = VLC_FOURCC( 'u', 'n', 'd', 'f' );
  678.         }
  679.         if( tk.b_default )
  680.         {
  681.             tk.fmt.i_priority = 1000;
  682.         }
  683.         tk.p_es = es_out_Add( p_demux->out, &tk.fmt );
  684. #undef tk
  685.     }
  686.     /* add information */
  687.     InformationCreate( p_demux );
  688.     return VLC_SUCCESS;
  689. error:
  690.     delete p_sys->es;
  691.     delete p_sys->in;
  692.     free( p_sys );
  693.     return VLC_EGENERIC;
  694. }
  695. /*****************************************************************************
  696.  * Close: frees unused data
  697.  *****************************************************************************/
  698. static void Close( vlc_object_t *p_this )
  699. {
  700.     demux_t     *p_demux = (demux_t*)p_this;
  701.     demux_sys_t *p_sys   = p_demux->p_sys;
  702.     int         i_track;
  703.     for( i_track = 0; i_track < p_sys->i_track; i_track++ )
  704.     {
  705. #define tk  p_sys->track[i_track]
  706.         if( tk.fmt.psz_description )
  707.         {
  708.             free( tk.fmt.psz_description );
  709.         }
  710.         if( tk.psz_codec )
  711.         {
  712.             free( tk.psz_codec );
  713.         }
  714.         if( tk.fmt.psz_language )
  715.         {
  716.             free( tk.fmt.psz_language );
  717.         }
  718. #undef tk
  719.     }
  720.     free( p_sys->track );
  721.     if( p_sys->psz_writing_application  )
  722.     {
  723.         free( p_sys->psz_writing_application );
  724.     }
  725.     if( p_sys->psz_muxing_application  )
  726.     {
  727.         free( p_sys->psz_muxing_application );
  728.     }
  729.     delete p_sys->segment;
  730.     delete p_sys->ep;
  731.     delete p_sys->es;
  732.     delete p_sys->in;
  733.     free( p_sys );
  734. }
  735. /*****************************************************************************
  736.  * Control:
  737.  *****************************************************************************/
  738. static int Control( demux_t *p_demux, int i_query, va_list args )
  739. {
  740.     demux_sys_t *p_sys = p_demux->p_sys;
  741.     int64_t     *pi64;
  742.     double      *pf, f;
  743.     vlc_meta_t **pp_meta;
  744.     switch( i_query )
  745.     {
  746.         case DEMUX_GET_META:
  747.             pp_meta = (vlc_meta_t**)va_arg( args, vlc_meta_t** );
  748.             *pp_meta = vlc_meta_Duplicate( p_sys->meta );
  749.             return VLC_SUCCESS;
  750.         case DEMUX_GET_LENGTH:
  751.             pi64 = (int64_t*)va_arg( args, int64_t * );
  752.             if( p_sys->f_duration > 0.0 )
  753.             {
  754.                 *pi64 = (int64_t)(p_sys->f_duration * 1000);
  755.                 return VLC_SUCCESS;
  756.             }
  757.             return VLC_EGENERIC;
  758.         case DEMUX_GET_POSITION:
  759.             pf = (double*)va_arg( args, double * );
  760.             *pf = (double)p_sys->in->getFilePointer() / (double)stream_Size( p_demux->s );
  761.             return VLC_SUCCESS;
  762.         case DEMUX_SET_POSITION:
  763.             f = (double)va_arg( args, double );
  764.             Seek( p_demux, -1, (int)(100.0 * f) );
  765.             return VLC_SUCCESS;
  766.         case DEMUX_GET_TIME:
  767.             pi64 = (int64_t*)va_arg( args, int64_t * );
  768.             if( p_sys->f_duration > 0.0 )
  769.             {
  770.                 mtime_t i_duration = (mtime_t)( p_sys->f_duration / 1000 );
  771.                 /* FIXME */
  772.                 *pi64 = (mtime_t)1000000 *
  773.                         (mtime_t)i_duration*
  774.                         (mtime_t)p_sys->in->getFilePointer() /
  775.                         (mtime_t)stream_Size( p_demux->s );
  776.                 return VLC_SUCCESS;
  777.             }
  778.             return VLC_EGENERIC;
  779.         case DEMUX_GET_TITLE_INFO:
  780.             if( p_sys->title && p_sys->title->i_seekpoint > 0 )
  781.             {
  782.                 input_title_t ***ppp_title = (input_title_t***)va_arg( args, input_title_t*** );
  783.                 int *pi_int    = (int*)va_arg( args, int* );
  784.                 *pi_int = 1;
  785.                 *ppp_title = (input_title_t**)malloc( sizeof( input_title_t**) );
  786.                 (*ppp_title)[0] = vlc_input_title_Duplicate( p_sys->title );
  787.                 return VLC_SUCCESS;
  788.             }
  789.             return VLC_EGENERIC;
  790.         case DEMUX_SET_TITLE:
  791.             if( p_sys->title && p_sys->title->i_seekpoint > 0 )
  792.             {
  793.                 return VLC_SUCCESS;
  794.             }
  795.             return VLC_EGENERIC;
  796.         case DEMUX_SET_SEEKPOINT:
  797.             /* FIXME do a better implementation */
  798.             if( p_sys->title && p_sys->title->i_seekpoint > 0 )
  799.             {
  800.                 int i_skp = (int)va_arg( args, int );
  801.                 Seek( p_demux, (int64_t)p_sys->title->seekpoint[i_skp]->i_time_offset, -1);
  802.                 return VLC_SUCCESS;
  803.             }
  804.             return VLC_EGENERIC;
  805.         case DEMUX_SET_TIME:
  806.         case DEMUX_GET_FPS:
  807.         default:
  808.             return VLC_EGENERIC;
  809.     }
  810. }
  811. static int BlockGet( demux_t *p_demux, KaxBlock **pp_block, int64_t *pi_ref1, int64_t *pi_ref2, int64_t *pi_duration )
  812. {
  813.     demux_sys_t *p_sys = p_demux->p_sys;
  814.     *pp_block = NULL;
  815.     *pi_ref1  = -1;
  816.     *pi_ref2  = -1;
  817.     for( ;; )
  818.     {
  819.         EbmlElement *el;
  820.         int         i_level;
  821.         if( p_demux->b_die )
  822.         {
  823.             return VLC_EGENERIC;
  824.         }
  825.         el = p_sys->ep->Get();
  826.         i_level = p_sys->ep->GetLevel();
  827.         if( el == NULL && *pp_block != NULL )
  828.         {
  829.             /* update the index */
  830. #define idx p_sys->index[p_sys->i_index - 1]
  831.             if( p_sys->i_index > 0 && idx.i_time == -1 )
  832.             {
  833.                 idx.i_time        = (*pp_block)->GlobalTimecode() / (mtime_t)1000;
  834.                 idx.b_key         = *pi_ref1 == -1 ? VLC_TRUE : VLC_FALSE;
  835.             }
  836. #undef idx
  837.             return VLC_SUCCESS;
  838.         }
  839.         if( el == NULL )
  840.         {
  841.             if( p_sys->ep->GetLevel() > 1 )
  842.             {
  843.                 p_sys->ep->Up();
  844.                 continue;
  845.             }
  846.             msg_Warn( p_demux, "EOF" );
  847.             return VLC_EGENERIC;
  848.         }
  849.         /* do parsing */
  850.         if( i_level == 1 )
  851.         {
  852.             if( MKV_IS_ID( el, KaxCluster ) )
  853.             {
  854.                 p_sys->cluster = (KaxCluster*)el;
  855.                 /* add it to the index */
  856.                 if( p_sys->i_index == 0 ||
  857.                     ( p_sys->i_index > 0 && p_sys->index[p_sys->i_index - 1].i_position < (int64_t)p_sys->cluster->GetElementPosition() ) )
  858.                 {
  859.                     IndexAppendCluster( p_demux, p_sys->cluster );
  860.                 }
  861.                 p_sys->ep->Down();
  862.             }
  863.             else if( MKV_IS_ID( el, KaxCues ) )
  864.             {
  865.                 msg_Warn( p_demux, "find KaxCues FIXME" );
  866.                 return VLC_EGENERIC;
  867.             }
  868.             else
  869.             {
  870.                 msg_Dbg( p_demux, "unknown (%s)", typeid( el ).name() );
  871.             }
  872.         }
  873.         else if( i_level == 2 )
  874.         {
  875.             if( MKV_IS_ID( el, KaxClusterTimecode ) )
  876.             {
  877.                 KaxClusterTimecode &ctc = *(KaxClusterTimecode*)el;
  878.                 ctc.ReadData( p_sys->es->I_O(), SCOPE_ALL_DATA );
  879.                 p_sys->cluster->InitTimecode( uint64( ctc ), p_sys->i_timescale );
  880.             }
  881.             else if( MKV_IS_ID( el, KaxBlockGroup ) )
  882.             {
  883.                 p_sys->ep->Down();
  884.             }
  885.         }
  886.         else if( i_level == 3 )
  887.         {
  888.             if( MKV_IS_ID( el, KaxBlock ) )
  889.             {
  890.                 *pp_block = (KaxBlock*)el;
  891.                 (*pp_block)->ReadData( p_sys->es->I_O() );
  892.                 (*pp_block)->SetParent( *p_sys->cluster );
  893.                 p_sys->ep->Keep();
  894.             }
  895.             else if( MKV_IS_ID( el, KaxBlockDuration ) )
  896.             {
  897.                 KaxBlockDuration &dur = *(KaxBlockDuration*)el;
  898.                 dur.ReadData( p_sys->es->I_O() );
  899.                 *pi_duration = uint64( dur );
  900.             }
  901.             else if( MKV_IS_ID( el, KaxReferenceBlock ) )
  902.             {
  903.                 KaxReferenceBlock &ref = *(KaxReferenceBlock*)el;
  904.                 ref.ReadData( p_sys->es->I_O() );
  905.                 if( *pi_ref1 == -1 )
  906.                 {
  907.                     *pi_ref1 = int64( ref );
  908.                 }
  909.                 else
  910.                 {
  911.                     *pi_ref2 = int64( ref );
  912.                 }
  913.             }
  914.         }
  915.         else
  916.         {
  917.             msg_Err( p_demux, "invalid level = %d", i_level );
  918.             return VLC_EGENERIC;
  919.         }
  920.     }
  921. }
  922. static block_t *MemToBlock( demux_t *p_demux, uint8_t *p_mem, int i_mem)
  923. {
  924.     block_t *p_block;
  925.     if( !(p_block = block_New( p_demux, i_mem ) ) ) return NULL;
  926.     memcpy( p_block->p_buffer, p_mem, i_mem );
  927.     //p_block->i_rate = p_input->stream.control.i_rate;
  928.     return p_block;
  929. }
  930. static void BlockDecode( demux_t *p_demux, KaxBlock *block, mtime_t i_pts,
  931.                          mtime_t i_duration )
  932. {
  933.     demux_sys_t *p_sys = p_demux->p_sys;
  934.     int             i_track;
  935.     unsigned int    i;
  936.     vlc_bool_t      b;
  937. #define tk  p_sys->track[i_track]
  938.     for( i_track = 0; i_track < p_sys->i_track; i_track++ )
  939.     {
  940.         if( tk.i_number == block->TrackNum() )
  941.         {
  942.             break;
  943.         }
  944.     }
  945.     if( i_track >= p_sys->i_track )
  946.     {
  947.         msg_Err( p_demux, "invalid track number=%d", block->TrackNum() );
  948.         return;
  949.     }
  950.     es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE, tk.p_es, &b );
  951.     if( !b )
  952.     {
  953.         tk.b_inited = VLC_FALSE;
  954.         return;
  955.     }
  956.     /* First send init data */
  957.     if( !tk.b_inited && tk.i_data_init > 0 )
  958.     {
  959.         block_t *p_init;
  960.         msg_Dbg( p_demux, "sending header (%d bytes)", tk.i_data_init );
  961.         p_init = MemToBlock( p_demux, tk.p_data_init, tk.i_data_init );
  962.         if( p_init ) es_out_Send( p_demux->out, tk.p_es, p_init );
  963.     }
  964.     tk.b_inited = VLC_TRUE;
  965.     for( i = 0; i < block->NumberFrames(); i++ )
  966.     {
  967.         block_t *p_block;
  968.         DataBuffer &data = block->GetBuffer(i);
  969.         p_block = MemToBlock( p_demux, data.Buffer(), data.Size() );
  970.         if( p_block == NULL )
  971.         {
  972.             break;
  973.         }
  974. #if defined(HAVE_ZLIB_H)
  975.         if( tk.i_compression_type )
  976.         {
  977.             p_block = block_zlib_decompress( VLC_OBJECT(p_demux), p_block );
  978.         }
  979. #endif
  980.         if( tk.fmt.i_cat != VIDEO_ES )
  981.             p_block->i_dts = p_block->i_pts = i_pts;
  982.         else
  983.         {
  984.             p_block->i_dts = i_pts;
  985.             p_block->i_pts = 0;
  986.         }
  987.         if( tk.fmt.i_cat == SPU_ES && strcmp( tk.psz_codec, "S_VOBSUB" ) )
  988.         {
  989.             p_block->i_length = i_duration * 1000;
  990.         }
  991.         es_out_Send( p_demux->out, tk.p_es, p_block );
  992.         /* use time stamp only for first block */
  993.         i_pts = 0;
  994.     }
  995. #undef tk
  996. }
  997. static void Seek( demux_t *p_demux, mtime_t i_date, int i_percent)
  998. {
  999.     demux_sys_t *p_sys = p_demux->p_sys;
  1000.     KaxBlock    *block;
  1001.     int64_t     i_block_duration;
  1002.     int64_t     i_block_ref1;
  1003.     int64_t     i_block_ref2;
  1004.     int         i_index;
  1005.     int         i_track_skipping;
  1006.     int         i_track;
  1007.     msg_Dbg( p_demux, "seek request to "I64Fd" (%d%%)", i_date, i_percent );
  1008.     if( i_date < 0 && i_percent < 0 )
  1009.     {
  1010.         return;
  1011.     }
  1012.     if( i_percent > 100 ) i_percent = 100;
  1013.     delete p_sys->ep;
  1014.     p_sys->ep = new EbmlParser( p_sys->es, p_sys->segment );
  1015.     p_sys->cluster = NULL;
  1016.     /* seek without index or without date */
  1017.     if( config_GetInt( p_demux, "mkv-seek-percent" ) || !p_sys->b_cues || i_date < 0 )
  1018.     {
  1019.         int64_t i_pos = i_percent * stream_Size( p_demux->s ) / 100;
  1020.         msg_Dbg( p_demux, "inacurate way of seeking" );
  1021.         for( i_index = 0; i_index < p_sys->i_index; i_index++ )
  1022.         {
  1023.             if( p_sys->index[i_index].i_position >= i_pos)
  1024.             {
  1025.                 break;
  1026.             }
  1027.         }
  1028.         if( i_index == p_sys->i_index )
  1029.         {
  1030.             i_index--;
  1031.         }
  1032.         p_sys->in->setFilePointer( p_sys->index[i_index].i_position,
  1033.                                    seek_beginning );
  1034.         if( p_sys->index[i_index].i_position < i_pos )
  1035.         {
  1036.             EbmlElement *el;
  1037.             msg_Warn( p_demux, "searching for cluster, could take some time" );
  1038.             /* search a cluster */
  1039.             while( ( el = p_sys->ep->Get() ) != NULL )
  1040.             {
  1041.                 if( MKV_IS_ID( el, KaxCluster ) )
  1042.                 {
  1043.                     KaxCluster *cluster = (KaxCluster*)el;
  1044.                     /* add it to the index */
  1045.                     IndexAppendCluster( p_demux, cluster );
  1046.                     if( (int64_t)cluster->GetElementPosition() >= i_pos )
  1047.                     {
  1048.                         p_sys->cluster = cluster;
  1049.                         p_sys->ep->Down();
  1050.                         break;
  1051.                     }
  1052.                 }
  1053.             }
  1054.         }
  1055.     }
  1056.     else
  1057.     {
  1058.         for( i_index = 0; i_index < p_sys->i_index; i_index++ )
  1059.         {
  1060.             if( p_sys->index[i_index].i_time >= i_date )
  1061.             {
  1062.                 break;
  1063.             }
  1064.         }
  1065.         if( i_index > 0 )
  1066.         {
  1067.             i_index--;
  1068.         }
  1069.         msg_Dbg( p_demux, "seek got "I64Fd" (%d%%)",
  1070.                  p_sys->index[i_index].i_time,
  1071.                  (int)( 100 * p_sys->index[i_index].i_position /
  1072.                         stream_Size( p_demux->s ) ) );
  1073.         p_sys->in->setFilePointer( p_sys->index[i_index].i_position,
  1074.                                    seek_beginning );
  1075.     }
  1076.     /* now parse until key frame */
  1077. #define tk  p_sys->track[i_track]
  1078.     i_track_skipping = 0;
  1079.     for( i_track = 0; i_track < p_sys->i_track; i_track++ )
  1080.     {
  1081.         if( tk.fmt.i_cat == VIDEO_ES )
  1082.         {
  1083.             tk.b_search_keyframe = VLC_TRUE;
  1084.             i_track_skipping++;
  1085.         }
  1086.     }
  1087.     while( i_track_skipping > 0 )
  1088.     {
  1089.         if( BlockGet( p_demux, &block, &i_block_ref1, &i_block_ref2, &i_block_duration ) )
  1090.         {
  1091.             msg_Warn( p_demux, "cannot get block EOF?" );
  1092.             return;
  1093.         }
  1094.         p_sys->i_pts = block->GlobalTimecode() / (mtime_t) 1000 + 1;
  1095.         for( i_track = 0; i_track < p_sys->i_track; i_track++ )
  1096.         {
  1097.             if( tk.i_number == block->TrackNum() )
  1098.             {
  1099.                 break;
  1100.             }
  1101.         }
  1102.         if( i_track < p_sys->i_track )
  1103.         {
  1104.             if( tk.fmt.i_cat == VIDEO_ES && i_block_ref1 == -1 && tk.b_search_keyframe )
  1105.             {
  1106.                 tk.b_search_keyframe = VLC_FALSE;
  1107.                 i_track_skipping--;
  1108.             }
  1109.             if( tk.fmt.i_cat == VIDEO_ES && !tk.b_search_keyframe )
  1110.             {
  1111.                 BlockDecode( p_demux, block, 0, 0 );
  1112.             }
  1113.         }
  1114.         delete block;
  1115.     }
  1116. #undef tk
  1117. }
  1118. /*****************************************************************************
  1119.  * Demux: reads and demuxes data packets
  1120.  *****************************************************************************
  1121.  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
  1122.  *****************************************************************************/
  1123. static int Demux( demux_t *p_demux)
  1124. {
  1125.     demux_sys_t *p_sys = p_demux->p_sys;
  1126.     mtime_t        i_start_pts;
  1127.     int            i_block_count = 0;
  1128.     KaxBlock *block;
  1129.     int64_t i_block_duration;
  1130.     int64_t i_block_ref1;
  1131.     int64_t i_block_ref2;
  1132.     i_start_pts = -1;
  1133.     for( ;; )
  1134.     {
  1135.         if( BlockGet( p_demux, &block, &i_block_ref1, &i_block_ref2, &i_block_duration ) )
  1136.         {
  1137.             msg_Warn( p_demux, "cannot get block EOF?" );
  1138.             return 0;
  1139.         }
  1140.         p_sys->i_pts = block->GlobalTimecode() / (mtime_t) 1000 + 1;
  1141.         if( p_sys->i_pts > 0 )
  1142.         {
  1143.             es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_pts );
  1144.         }
  1145.         BlockDecode( p_demux, block, p_sys->i_pts, i_block_duration );
  1146.         delete block;
  1147.         i_block_count++;
  1148.         if( i_start_pts == -1 )
  1149.         {
  1150.             i_start_pts = p_sys->i_pts;
  1151.         }
  1152.         else if( p_sys->i_pts > i_start_pts + (mtime_t)100000 || i_block_count > 5 )
  1153.         {
  1154.             return 1;
  1155.         }
  1156.     }
  1157. }
  1158. /*****************************************************************************
  1159.  * Stream managment
  1160.  *****************************************************************************/
  1161. vlc_stream_io_callback::vlc_stream_io_callback( stream_t *s_ )
  1162. {
  1163.     s = s_;
  1164.     mb_eof = VLC_FALSE;
  1165. }
  1166. uint32 vlc_stream_io_callback::read( void *p_buffer, size_t i_size )
  1167. {
  1168.     if( i_size <= 0 || mb_eof )
  1169.     {
  1170.         return 0;
  1171.     }
  1172.     return stream_Read( s, p_buffer, i_size );
  1173. }
  1174. void vlc_stream_io_callback::setFilePointer(int64_t i_offset, seek_mode mode )
  1175. {
  1176.     int64_t i_pos;
  1177.     switch( mode )
  1178.     {
  1179.         case seek_beginning:
  1180.             i_pos = i_offset;
  1181.             break;
  1182.         case seek_end:
  1183.             i_pos = stream_Size( s ) - i_offset;
  1184.             break;
  1185.         default:
  1186.             i_pos= stream_Tell( s ) + i_offset;
  1187.             break;
  1188.     }
  1189.     if( i_pos < 0 || i_pos >= stream_Size( s ) )
  1190.     {
  1191.         mb_eof = VLC_TRUE;
  1192.         return;
  1193.     }
  1194.     mb_eof = VLC_FALSE;
  1195.     if( stream_Seek( s, i_pos ) )
  1196.     {
  1197.         mb_eof = VLC_TRUE;
  1198.     }
  1199.     return;
  1200. }
  1201. size_t vlc_stream_io_callback::write( const void *p_buffer, size_t i_size )
  1202. {
  1203.     return 0;
  1204. }
  1205. uint64 vlc_stream_io_callback::getFilePointer( void )
  1206. {
  1207.     return stream_Tell( s );
  1208. }
  1209. void vlc_stream_io_callback::close( void )
  1210. {
  1211.     return;
  1212. }
  1213. /*****************************************************************************
  1214.  * Ebml Stream parser
  1215.  *****************************************************************************/
  1216. EbmlParser::EbmlParser( EbmlStream *es, EbmlElement *el_start )
  1217. {
  1218.     int i;
  1219.     m_es = es;
  1220.     m_got = NULL;
  1221.     m_el[0] = el_start;
  1222.     for( i = 1; i < 6; i++ )
  1223.     {
  1224.         m_el[i] = NULL;
  1225.     }
  1226.     mi_level = 1;
  1227.     mi_user_level = 1;
  1228.     mb_keep = VLC_FALSE;
  1229. }
  1230. EbmlParser::~EbmlParser( void )
  1231. {
  1232.     int i;
  1233.     for( i = 1; i < mi_level; i++ )
  1234.     {
  1235.         if( !mb_keep )
  1236.         {
  1237.             delete m_el[i];
  1238.         }
  1239.         mb_keep = VLC_FALSE;
  1240.     }
  1241. }
  1242. void EbmlParser::Up( void )
  1243. {
  1244.     if( mi_user_level == mi_level )
  1245.     {
  1246.         fprintf( stderr," arrrrrrrrrrrrrg Up cannot escape itselfn" );
  1247.     }
  1248.     mi_user_level--;
  1249. }
  1250. void EbmlParser::Down( void )
  1251. {
  1252.     mi_user_level++;
  1253.     mi_level++;
  1254. }
  1255. void EbmlParser::Keep( void )
  1256. {
  1257.     mb_keep = VLC_TRUE;
  1258. }
  1259. int EbmlParser::GetLevel( void )
  1260. {
  1261.     return mi_user_level;
  1262. }
  1263. EbmlElement *EbmlParser::Get( void )
  1264. {
  1265.     int i_ulev = 0;
  1266.     if( mi_user_level != mi_level )
  1267.     {
  1268.         return NULL;
  1269.     }
  1270.     if( m_got )
  1271.     {
  1272.         EbmlElement *ret = m_got;
  1273.         m_got = NULL;
  1274.         return ret;
  1275.     }
  1276.     if( m_el[mi_level] )
  1277.     {
  1278.         m_el[mi_level]->SkipData( *m_es, m_el[mi_level]->Generic().Context );
  1279.         if( !mb_keep )
  1280.         {
  1281.             delete m_el[mi_level];
  1282.         }
  1283.         mb_keep = VLC_FALSE;
  1284.     }
  1285.     m_el[mi_level] = m_es->FindNextElement( m_el[mi_level - 1]->Generic().Context, i_ulev, 0xFFFFFFFFL, true, 1 );
  1286.     if( i_ulev > 0 )
  1287.     {
  1288.         while( i_ulev > 0 )
  1289.         {
  1290.             if( mi_level == 1 )
  1291.             {
  1292.                 mi_level = 0;
  1293.                 return NULL;
  1294.             }
  1295.             delete m_el[mi_level - 1];
  1296.             m_got = m_el[mi_level -1] = m_el[mi_level];
  1297.             m_el[mi_level] = NULL;
  1298.             mi_level--;
  1299.             i_ulev--;
  1300.         }
  1301.         return NULL;
  1302.     }
  1303.     else if( m_el[mi_level] == NULL )
  1304.     {
  1305.         fprintf( stderr," m_el[mi_level] == NULLn" );
  1306.     }
  1307.     return m_el[mi_level];
  1308. }
  1309. /*****************************************************************************
  1310.  * Tools
  1311.  *  * LoadCues : load the cues element and update index
  1312.  *
  1313.  *  * LoadTags : load ... the tags element
  1314.  *
  1315.  *  * InformationCreate : create all information, load tags if present
  1316.  *
  1317.  *****************************************************************************/
  1318. static void LoadCues( demux_t *p_demux )
  1319. {
  1320.     demux_sys_t *p_sys = p_demux->p_sys;
  1321.     int64_t     i_sav_position = p_sys->in->getFilePointer();
  1322.     EbmlParser  *ep;
  1323.     EbmlElement *el, *cues;
  1324.     msg_Dbg( p_demux, "loading cues" );
  1325.     p_sys->in->setFilePointer( p_sys->i_cues_position, seek_beginning );
  1326.     cues = p_sys->es->FindNextID( KaxCues::ClassInfos, 0xFFFFFFFFL);
  1327.     if( cues == NULL )
  1328.     {
  1329.         msg_Err( p_demux, "cannot load cues (broken seekhead or file)" );
  1330.         p_sys->in->setFilePointer( i_sav_position, seek_beginning );
  1331.         return;
  1332.     }
  1333.     ep = new EbmlParser( p_sys->es, cues );
  1334.     while( ( el = ep->Get() ) != NULL )
  1335.     {
  1336.         if( MKV_IS_ID( el, KaxCuePoint ) )
  1337.         {
  1338. #define idx p_sys->index[p_sys->i_index]
  1339.             idx.i_track       = -1;
  1340.             idx.i_block_number= -1;
  1341.             idx.i_position    = -1;
  1342.             idx.i_time        = 0;
  1343.             idx.b_key         = VLC_TRUE;
  1344.             ep->Down();
  1345.             while( ( el = ep->Get() ) != NULL )
  1346.             {
  1347.                 if( MKV_IS_ID( el, KaxCueTime ) )
  1348.                 {
  1349.                     KaxCueTime &ctime = *(KaxCueTime*)el;
  1350.                     ctime.ReadData( p_sys->es->I_O() );
  1351.                     idx.i_time = uint64( ctime ) * p_sys->i_timescale / (mtime_t)1000;
  1352.                 }
  1353.                 else if( MKV_IS_ID( el, KaxCueTrackPositions ) )
  1354.                 {
  1355.                     ep->Down();
  1356.                     while( ( el = ep->Get() ) != NULL )
  1357.                     {
  1358.                         if( MKV_IS_ID( el, KaxCueTrack ) )
  1359.                         {
  1360.                             KaxCueTrack &ctrack = *(KaxCueTrack*)el;
  1361.                             ctrack.ReadData( p_sys->es->I_O() );
  1362.                             idx.i_track = uint16( ctrack );
  1363.                         }
  1364.                         else if( MKV_IS_ID( el, KaxCueClusterPosition ) )
  1365.                         {
  1366.                             KaxCueClusterPosition &ccpos = *(KaxCueClusterPosition*)el;
  1367.                             ccpos.ReadData( p_sys->es->I_O() );
  1368.                             idx.i_position = p_sys->segment->GetGlobalPosition( uint64( ccpos ) );
  1369.                         }
  1370.                         else if( MKV_IS_ID( el, KaxCueBlockNumber ) )
  1371.                         {
  1372.                             KaxCueBlockNumber &cbnum = *(KaxCueBlockNumber*)el;
  1373.                             cbnum.ReadData( p_sys->es->I_O() );
  1374.                             idx.i_block_number = uint32( cbnum );
  1375.                         }
  1376.                         else
  1377.                         {
  1378.                             msg_Dbg( p_demux, "         * Unknown (%s)", typeid(*el).name() );
  1379.                         }
  1380.                     }
  1381.                     ep->Up();
  1382.                 }
  1383.                 else
  1384.                 {
  1385.                     msg_Dbg( p_demux, "     * Unknown (%s)", typeid(*el).name() );
  1386.                 }
  1387.             }
  1388.             ep->Up();
  1389. #if 0
  1390.             msg_Dbg( p_demux, " * added time="I64Fd" pos="I64Fd
  1391.                      " track=%d bnum=%d", idx.i_time, idx.i_position,
  1392.                      idx.i_track, idx.i_block_number );
  1393. #endif
  1394.             p_sys->i_index++;
  1395.             if( p_sys->i_index >= p_sys->i_index_max )
  1396.             {
  1397.                 p_sys->i_index_max += 1024;
  1398.                 p_sys->index = (mkv_index_t*)realloc( p_sys->index, sizeof( mkv_index_t ) * p_sys->i_index_max );
  1399.             }
  1400. #undef idx
  1401.         }
  1402.         else
  1403.         {
  1404.             msg_Dbg( p_demux, " * Unknown (%s)", typeid(*el).name() );
  1405.         }
  1406.     }
  1407.     delete ep;
  1408.     delete cues;
  1409.     p_sys->b_cues = VLC_TRUE;
  1410.     msg_Dbg( p_demux, "loading cues done." );
  1411.     p_sys->in->setFilePointer( i_sav_position, seek_beginning );
  1412. }
  1413. static void LoadTags( demux_t *p_demux )
  1414. {
  1415.     demux_sys_t *p_sys = p_demux->p_sys;
  1416.     int64_t     i_sav_position = p_sys->in->getFilePointer();
  1417.     EbmlParser  *ep;
  1418.     EbmlElement *el, *tags;
  1419.     msg_Dbg( p_demux, "loading tags" );
  1420.     p_sys->in->setFilePointer( p_sys->i_tags_position, seek_beginning );
  1421.     tags = p_sys->es->FindNextID( KaxTags::ClassInfos, 0xFFFFFFFFL);
  1422.     if( tags == NULL )
  1423.     {
  1424.         msg_Err( p_demux, "cannot load tags (broken seekhead or file)" );
  1425.         p_sys->in->setFilePointer( i_sav_position, seek_beginning );
  1426.         return;
  1427.     }
  1428.     msg_Dbg( p_demux, "Tags" );
  1429.     ep = new EbmlParser( p_sys->es, tags );
  1430.     while( ( el = ep->Get() ) != NULL )
  1431.     {
  1432.         if( MKV_IS_ID( el, KaxTag ) )
  1433.         {
  1434.             msg_Dbg( p_demux, "+ Tag" );
  1435.             ep->Down();
  1436.             while( ( el = ep->Get() ) != NULL )
  1437.             {
  1438.                 if( MKV_IS_ID( el, KaxTagTargets ) )
  1439.                 {
  1440.                     msg_Dbg( p_demux, "|   + Targets" );
  1441.                     ep->Down();
  1442.                     while( ( el = ep->Get() ) != NULL )
  1443.                     {
  1444.                         msg_Dbg( p_demux, "|   |   + Unknown (%s)", typeid( *el ).name() );
  1445.                     }
  1446.                     ep->Up();
  1447.                 }
  1448.                 else if( MKV_IS_ID( el, KaxTagGeneral ) )
  1449.                 {
  1450.                     msg_Dbg( p_demux, "|   + General" );
  1451.                     ep->Down();
  1452.                     while( ( el = ep->Get() ) != NULL )
  1453.                     {
  1454.                         msg_Dbg( p_demux, "|   |   + Unknown (%s)", typeid( *el ).name() );
  1455.                     }
  1456.                     ep->Up();
  1457.                 }
  1458.                 else if( MKV_IS_ID( el, KaxTagGenres ) )
  1459.                 {
  1460.                     msg_Dbg( p_demux, "|   + Genres" );
  1461.                     ep->Down();
  1462.                     while( ( el = ep->Get() ) != NULL )
  1463.                     {
  1464.                         msg_Dbg( p_demux, "|   |   + Unknown (%s)", typeid( *el ).name() );
  1465.                     }
  1466.                     ep->Up();
  1467.                 }
  1468.                 else if( MKV_IS_ID( el, KaxTagAudioSpecific ) )
  1469.                 {
  1470.                     msg_Dbg( p_demux, "|   + Audio Specific" );
  1471.                     ep->Down();
  1472.                     while( ( el = ep->Get() ) != NULL )
  1473.                     {
  1474.                         msg_Dbg( p_demux, "|   |   + Unknown (%s)", typeid( *el ).name() );
  1475.                     }
  1476.                     ep->Up();
  1477.                 }
  1478.                 else if( MKV_IS_ID( el, KaxTagImageSpecific ) )
  1479.                 {
  1480.                     msg_Dbg( p_demux, "|   + Images Specific" );
  1481.                     ep->Down();
  1482.                     while( ( el = ep->Get() ) != NULL )
  1483.                     {
  1484.                         msg_Dbg( p_demux, "|   |   + Unknown (%s)", typeid( *el ).name() );
  1485.                     }
  1486.                     ep->Up();
  1487.                 }
  1488.                 else if( MKV_IS_ID( el, KaxTagMultiComment ) )
  1489.                 {
  1490.                     msg_Dbg( p_demux, "|   + Multi Comment" );
  1491.                 }
  1492.                 else if( MKV_IS_ID( el, KaxTagMultiCommercial ) )
  1493.                 {
  1494.                     msg_Dbg( p_demux, "|   + Multi Commercial" );
  1495.                 }
  1496.                 else if( MKV_IS_ID( el, KaxTagMultiDate ) )
  1497.                 {
  1498.                     msg_Dbg( p_demux, "|   + Multi Date" );
  1499.                 }
  1500.                 else if( MKV_IS_ID( el, KaxTagMultiEntity ) )
  1501.                 {
  1502.                     msg_Dbg( p_demux, "|   + Multi Entity" );
  1503.                 }
  1504.                 else if( MKV_IS_ID( el, KaxTagMultiIdentifier ) )
  1505.                 {
  1506.                     msg_Dbg( p_demux, "|   + Multi Identifier" );
  1507.                 }
  1508.                 else if( MKV_IS_ID( el, KaxTagMultiLegal ) )
  1509.                 {
  1510.                     msg_Dbg( p_demux, "|   + Multi Legal" );
  1511.                 }
  1512.                 else if( MKV_IS_ID( el, KaxTagMultiTitle ) )
  1513.                 {
  1514.                     msg_Dbg( p_demux, "|   + Multi Title" );
  1515.                 }
  1516.                 else
  1517.                 {
  1518.                     msg_Dbg( p_demux, "|   + Unknown (%s)", typeid( *el ).name() );
  1519.                 }
  1520.             }
  1521.             ep->Up();
  1522.         }
  1523.         else
  1524.         {
  1525.             msg_Dbg( p_demux, "+ Unknown (%s)", typeid( *el ).name() );
  1526.         }
  1527.     }
  1528.     delete ep;
  1529.     delete tags;
  1530.     msg_Dbg( p_demux, "loading tags done." );
  1531.     p_sys->in->setFilePointer( i_sav_position, seek_beginning );
  1532. }
  1533. /*****************************************************************************
  1534.  * ParseInfo:
  1535.  *****************************************************************************/
  1536. static void ParseSeekHead( demux_t *p_demux, EbmlElement *seekhead )
  1537. {
  1538.     demux_sys_t *p_sys = p_demux->p_sys;
  1539.     EbmlElement *el;
  1540.     EbmlMaster  *m;
  1541.     unsigned int i;
  1542.     int i_upper_level = 0;
  1543.     msg_Dbg( p_demux, "|   + Seek head" );
  1544.     /* Master elements */
  1545.     m = static_cast<EbmlMaster *>(seekhead);
  1546.     m->Read( *p_sys->es, seekhead->Generic().Context, i_upper_level, el, true );
  1547.     for( i = 0; i < m->ListSize(); i++ )
  1548.     {
  1549.         EbmlElement *l = (*m)[i];
  1550.         if( MKV_IS_ID( l, KaxSeek ) )
  1551.         {
  1552.             EbmlMaster *sk = static_cast<EbmlMaster *>(l);
  1553.             EbmlId id = EbmlVoid::ClassInfos.GlobalId;
  1554.             int64_t i_pos = -1;
  1555.             unsigned int j;
  1556.             for( j = 0; j < sk->ListSize(); j++ )
  1557.             {
  1558.                 EbmlElement *l = (*sk)[j];
  1559.                 if( MKV_IS_ID( l, KaxSeekID ) )
  1560.                 {
  1561.                     KaxSeekID &sid = *(KaxSeekID*)l;
  1562.                     id = EbmlId( sid.GetBuffer(), sid.GetSize() );
  1563.                 }
  1564.                 else if( MKV_IS_ID( l, KaxSeekPosition ) )
  1565.                 {
  1566.                     KaxSeekPosition &spos = *(KaxSeekPosition*)l;
  1567.                     i_pos = uint64( spos );
  1568.                 }
  1569.                 else
  1570.                 {
  1571.                     msg_Dbg( p_demux, "|   |   |   + Unknown (%s)", typeid(*l).name() );
  1572.                 }
  1573.             }
  1574.             if( i_pos >= 0 )
  1575.             {
  1576.                 if( id == KaxCues::ClassInfos.GlobalId )
  1577.                 {
  1578.                     msg_Dbg( p_demux, "|   |   |   = cues at "I64Fd, i_pos );
  1579.                     p_sys->i_cues_position = p_sys->segment->GetGlobalPosition( i_pos );
  1580.                 }
  1581.                 else if( id == KaxChapters::ClassInfos.GlobalId )
  1582.                 {
  1583.                     msg_Dbg( p_demux, "|   |   |   = chapters at "I64Fd, i_pos );
  1584.                     p_sys->i_chapters_position = p_sys->segment->GetGlobalPosition( i_pos );
  1585.                 }
  1586.                 else if( id == KaxTags::ClassInfos.GlobalId )
  1587.                 {
  1588.                     msg_Dbg( p_demux, "|   |   |   = tags at "I64Fd, i_pos );
  1589.                     p_sys->i_tags_position = p_sys->segment->GetGlobalPosition( i_pos );
  1590.                 }
  1591.             }
  1592.         }
  1593.         else
  1594.         {
  1595.             msg_Dbg( p_demux, "|   |   + Unknown (%s)", typeid(*l).name() );
  1596.         }
  1597.     }
  1598. }
  1599. /*****************************************************************************
  1600.  * ParseTracks:
  1601.  *****************************************************************************/
  1602. static void ParseTrackEntry( demux_t *p_demux, EbmlMaster *m )
  1603. {
  1604.     demux_sys_t *p_sys = p_demux->p_sys;
  1605.     unsigned int i;
  1606.     mkv_track_t *tk;
  1607.     msg_Dbg( p_demux, "|   |   + Track Entry" );
  1608.     p_sys->i_track++;
  1609.     p_sys->track = (mkv_track_t*)realloc( p_sys->track, sizeof( mkv_track_t ) * (p_sys->i_track + 1 ) );
  1610.     /* Init the track */
  1611.     tk = &p_sys->track[p_sys->i_track - 1];
  1612.     memset( tk, 0, sizeof( mkv_track_t ) );
  1613.     es_format_Init( &tk->fmt, UNKNOWN_ES, 0 );
  1614.     tk->fmt.psz_language = strdup("English");
  1615.     tk->fmt.psz_description = NULL;
  1616.     tk->b_default = VLC_TRUE;
  1617.     tk->b_enabled = VLC_TRUE;
  1618.     tk->i_number = p_sys->i_track - 1;
  1619.     tk->i_extra_data = 0;
  1620.     tk->p_extra_data = NULL;
  1621.     tk->psz_codec = NULL;
  1622.     tk->i_default_duration = 0;
  1623.     tk->f_timecodescale = 1.0;
  1624.     tk->b_inited = VLC_FALSE;
  1625.     tk->i_data_init = 0;
  1626.     tk->p_data_init = NULL;
  1627.     tk->psz_codec_name = NULL;
  1628.     tk->psz_codec_settings = NULL;
  1629.     tk->psz_codec_info_url = NULL;
  1630.     tk->psz_codec_download_url = NULL;
  1631.     
  1632.     tk->i_compression_type = MATROSKA_COMPRESSION_NONE;
  1633.     for( i = 0; i < m->ListSize(); i++ )
  1634.     {
  1635.         EbmlElement *l = (*m)[i];
  1636.         if( MKV_IS_ID( l, KaxTrackNumber ) )
  1637.         {
  1638.             KaxTrackNumber &tnum = *(KaxTrackNumber*)l;
  1639.             tk->i_number = uint32( tnum );
  1640.             msg_Dbg( p_demux, "|   |   |   + Track Number=%u", uint32( tnum ) );
  1641.         }
  1642.         else  if( MKV_IS_ID( l, KaxTrackUID ) )
  1643.         {
  1644.             KaxTrackUID &tuid = *(KaxTrackUID*)l;
  1645.             msg_Dbg( p_demux, "|   |   |   + Track UID=%u",  uint32( tuid ) );
  1646.         }
  1647.         else  if( MKV_IS_ID( l, KaxTrackType ) )
  1648.         {
  1649.             char *psz_type;
  1650.             KaxTrackType &ttype = *(KaxTrackType*)l;
  1651.             switch( uint8(ttype) )
  1652.             {
  1653.                 case track_audio:
  1654.                     psz_type = "audio";
  1655.                     tk->fmt.i_cat = AUDIO_ES;
  1656.                     break;
  1657.                 case track_video:
  1658.                     psz_type = "video";
  1659.                     tk->fmt.i_cat = VIDEO_ES;
  1660.                     break;
  1661.                 case track_subtitle:
  1662.                     psz_type = "subtitle";
  1663.                     tk->fmt.i_cat = SPU_ES;
  1664.                     break;
  1665.                 default:
  1666.                     psz_type = "unknown";
  1667.                     tk->fmt.i_cat = UNKNOWN_ES;
  1668.                     break;
  1669.             }
  1670.             msg_Dbg( p_demux, "|   |   |   + Track Type=%s", psz_type );
  1671.         }
  1672. //        else  if( EbmlId( *l ) == KaxTrackFlagEnabled::ClassInfos.GlobalId )
  1673. //        {
  1674. //            KaxTrackFlagEnabled &fenb = *(KaxTrackFlagEnabled*)l;
  1675. //            tk->b_enabled = uint32( fenb );
  1676. //            msg_Dbg( p_demux, "|   |   |   + Track Enabled=%u",
  1677. //                     uint32( fenb )  );
  1678. //        }
  1679.         else  if( MKV_IS_ID( l, KaxTrackFlagDefault ) )
  1680.         {
  1681.             KaxTrackFlagDefault &fdef = *(KaxTrackFlagDefault*)l;
  1682.             tk->b_default = uint32( fdef );
  1683.             msg_Dbg( p_demux, "|   |   |   + Track Default=%u", uint32( fdef )  );
  1684.         }
  1685.         else  if( MKV_IS_ID( l, KaxTrackFlagLacing ) )
  1686.         {
  1687.             KaxTrackFlagLacing &lac = *(KaxTrackFlagLacing*)l;
  1688.             msg_Dbg( p_demux, "|   |   |   + Track Lacing=%d", uint32( lac ) );
  1689.         }
  1690.         else  if( MKV_IS_ID( l, KaxTrackMinCache ) )
  1691.         {
  1692.             KaxTrackMinCache &cmin = *(KaxTrackMinCache*)l;
  1693.             msg_Dbg( p_demux, "|   |   |   + Track MinCache=%d", uint32( cmin ) );
  1694.         }
  1695.         else  if( MKV_IS_ID( l, KaxTrackMaxCache ) )
  1696.         {
  1697.             KaxTrackMaxCache &cmax = *(KaxTrackMaxCache*)l;
  1698.             msg_Dbg( p_demux, "|   |   |   + Track MaxCache=%d", uint32( cmax ) );
  1699.         }
  1700.         else  if( MKV_IS_ID( l, KaxTrackDefaultDuration ) )
  1701.         {
  1702.             KaxTrackDefaultDuration &defd = *(KaxTrackDefaultDuration*)l;
  1703.             tk->i_default_duration = uint64(defd);
  1704.             msg_Dbg( p_demux, "|   |   |   + Track Default Duration="I64Fd, uint64(defd) );
  1705.         }
  1706.         else  if( MKV_IS_ID( l, KaxTrackTimecodeScale ) )
  1707.         {
  1708.             KaxTrackTimecodeScale &ttcs = *(KaxTrackTimecodeScale*)l;
  1709.             tk->f_timecodescale = float( ttcs );
  1710.             msg_Dbg( p_demux, "|   |   |   + Track TimeCodeScale=%f", tk->f_timecodescale );
  1711.         }
  1712.         else if( MKV_IS_ID( l, KaxTrackName ) )
  1713.         {
  1714.             KaxTrackName &tname = *(KaxTrackName*)l;
  1715.             tk->fmt.psz_description = UTF8ToStr( UTFstring( tname ) );
  1716.             msg_Dbg( p_demux, "|   |   |   + Track Name=%s", tk->fmt.psz_description );
  1717.         }
  1718.         else  if( MKV_IS_ID( l, KaxTrackLanguage ) )
  1719.         {
  1720.             KaxTrackLanguage &lang = *(KaxTrackLanguage*)l;
  1721.             tk->fmt.psz_language = strdup( string( lang ).c_str() );
  1722.             msg_Dbg( p_demux,
  1723.                      "|   |   |   + Track Language=`%s'", tk->fmt.psz_language );
  1724.         }
  1725.         else  if( MKV_IS_ID( l, KaxCodecID ) )
  1726.         {
  1727.             KaxCodecID &codecid = *(KaxCodecID*)l;
  1728.             tk->psz_codec = strdup( string( codecid ).c_str() );
  1729.             msg_Dbg( p_demux, "|   |   |   + Track CodecId=%s", string( codecid ).c_str() );
  1730.         }
  1731.         else  if( MKV_IS_ID( l, KaxCodecPrivate ) )
  1732.         {
  1733.             KaxCodecPrivate &cpriv = *(KaxCodecPrivate*)l;
  1734.             tk->i_extra_data = cpriv.GetSize();
  1735.             if( tk->i_extra_data > 0 )
  1736.             {
  1737.                 tk->p_extra_data = (uint8_t*)malloc( tk->i_extra_data );
  1738.                 memcpy( tk->p_extra_data, cpriv.GetBuffer(), tk->i_extra_data );
  1739.             }
  1740.             msg_Dbg( p_demux, "|   |   |   + Track CodecPrivate size="I64Fd, cpriv.GetSize() );
  1741.         }
  1742.         else if( MKV_IS_ID( l, KaxCodecName ) )
  1743.         {
  1744.             KaxCodecName &cname = *(KaxCodecName*)l;
  1745.             tk->psz_codec_name = UTF8ToStr( UTFstring( cname ) );
  1746.             msg_Dbg( p_demux, "|   |   |   + Track Codec Name=%s", tk->psz_codec_name );
  1747.         }
  1748.         else if( MKV_IS_ID( l, KaxContentEncodings ) )
  1749.         {
  1750.             EbmlMaster *cencs = static_cast<EbmlMaster*>(l);
  1751.             MkvTree( p_demux, 3, "Content Encodings" );
  1752.             for( unsigned int i = 0; i < cencs->ListSize(); i++ )
  1753.             {
  1754.                 EbmlElement *l2 = (*cencs)[i];
  1755.                 if( MKV_IS_ID( l2, KaxContentEncoding ) )
  1756.                 {
  1757.                     MkvTree( p_demux, 4, "Content Encoding" );
  1758.                     EbmlMaster *cenc = static_cast<EbmlMaster*>(l2);
  1759.                     for( unsigned int i = 0; i < cenc->ListSize(); i++ )
  1760.                     {
  1761.                         EbmlElement *l3 = (*cenc)[i];
  1762.                         if( MKV_IS_ID( l3, KaxContentEncodingOrder ) )
  1763.                         {
  1764.                             KaxContentEncodingOrder &encord = *(KaxContentEncodingOrder*)l3;
  1765.                             MkvTree( p_demux, 5, "Order: %i", uint32( encord ) );
  1766.                         }
  1767.                         else if( MKV_IS_ID( l3, KaxContentEncodingScope ) )
  1768.                         {
  1769.                             KaxContentEncodingScope &encscope = *(KaxContentEncodingScope*)l3;
  1770.                             MkvTree( p_demux, 5, "Scope: %i", uint32( encscope ) );
  1771.                         }
  1772.                         else if( MKV_IS_ID( l3, KaxContentEncodingType ) )
  1773.                         {
  1774.                             KaxContentEncodingType &enctype = *(KaxContentEncodingType*)l3;
  1775.                             MkvTree( p_demux, 5, "Type: %i", uint32( enctype ) );
  1776.                         }
  1777.                         else if( MKV_IS_ID( l3, KaxContentCompression ) )
  1778.                         {
  1779.                             EbmlMaster *compr = static_cast<EbmlMaster*>(l3);
  1780.                             MkvTree( p_demux, 5, "Content Compression" );
  1781.                             for( unsigned int i = 0; i < compr->ListSize(); i++ )
  1782.                             {
  1783.                                 EbmlElement *l4 = (*compr)[i];
  1784.                                 if( MKV_IS_ID( l4, KaxContentCompAlgo ) )
  1785.                                 {
  1786.                                     KaxContentCompAlgo &compalg = *(KaxContentCompAlgo*)l4;
  1787.                                     MkvTree( p_demux, 6, "Compression Algorithm: %i", uint32(compalg) );
  1788.                                     if( uint32( compalg ) == 0 )
  1789.                                     {
  1790.                                         tk->i_compression_type = MATROSKA_COMPRESSION_ZLIB;
  1791.                                     }
  1792.                                 }
  1793.                                 else
  1794.                                 {
  1795.                                     MkvTree( p_demux, 6, "Unknown (%s)", typeid(*l4).name() );
  1796.                                 }
  1797.                             }
  1798.                         }
  1799.                         else
  1800.                         {
  1801.                             MkvTree( p_demux, 5, "Unknown (%s)", typeid(*l3).name() );
  1802.                         }
  1803.                     }
  1804.                     
  1805.                 }
  1806.                 else
  1807.                 {
  1808.                     MkvTree( p_demux, 4, "Unknown (%s)", typeid(*l2).name() );
  1809.                 }
  1810.             }
  1811.                 
  1812.         }
  1813. //        else if( EbmlId( *l ) == KaxCodecSettings::ClassInfos.GlobalId )
  1814. //        {
  1815. //            KaxCodecSettings &cset = *(KaxCodecSettings*)l;
  1816. //            tk->psz_codec_settings = UTF8ToStr( UTFstring( cset ) );
  1817. //            msg_Dbg( p_demux, "|   |   |   + Track Codec Settings=%s", tk->psz_codec_settings );
  1818. //        }
  1819. //        else if( EbmlId( *l ) == KaxCodecInfoURL::ClassInfos.GlobalId )
  1820. //        {
  1821. //            KaxCodecInfoURL &ciurl = *(KaxCodecInfoURL*)l;
  1822. //            tk->psz_codec_info_url = strdup( string( ciurl ).c_str() );
  1823. //            msg_Dbg( p_demux, "|   |   |   + Track Codec Info URL=%s", tk->psz_codec_info_url );
  1824. //        }
  1825. //        else if( EbmlId( *l ) == KaxCodecDownloadURL::ClassInfos.GlobalId )
  1826. //        {
  1827. //            KaxCodecDownloadURL &cdurl = *(KaxCodecDownloadURL*)l;
  1828. //            tk->psz_codec_download_url = strdup( string( cdurl ).c_str() );
  1829. //            msg_Dbg( p_demux, "|   |   |   + Track Codec Info URL=%s", tk->psz_codec_download_url );
  1830. //        }
  1831. //        else if( EbmlId( *l ) == KaxCodecDecodeAll::ClassInfos.GlobalId )
  1832. //        {
  1833. //            KaxCodecDecodeAll &cdall = *(KaxCodecDecodeAll*)l;
  1834. //            msg_Dbg( p_demux, "|   |   |   + Track Codec Decode All=%u <== UNUSED", uint8( cdall ) );
  1835. //        }
  1836. //        else if( EbmlId( *l ) == KaxTrackOverlay::ClassInfos.GlobalId )
  1837. //        {
  1838. //            KaxTrackOverlay &tovr = *(KaxTrackOverlay*)l;
  1839. //            msg_Dbg( p_demux, "|   |   |   + Track Overlay=%u <== UNUSED", uint32( tovr ) );
  1840. //        }
  1841.         else  if( MKV_IS_ID( l, KaxTrackVideo ) )
  1842.         {
  1843.             EbmlMaster *tkv = static_cast<EbmlMaster*>(l);
  1844.             unsigned int j;
  1845.             msg_Dbg( p_demux, "|   |   |   + Track Video" );
  1846.             tk->f_fps = 0.0;
  1847.             for( j = 0; j < tkv->ListSize(); j++ )
  1848.             {
  1849.                 EbmlElement *l = (*tkv)[j];
  1850. //                if( EbmlId( *el4 ) == KaxVideoFlagInterlaced::ClassInfos.GlobalId )
  1851. //                {
  1852. //                    KaxVideoFlagInterlaced &fint = *(KaxVideoFlagInterlaced*)el4;
  1853. //                    msg_Dbg( p_demux, "|   |   |   |   + Track Video Interlaced=%u", uint8( fint ) );
  1854. //                }
  1855. //                else if( EbmlId( *el4 ) == KaxVideoStereoMode::ClassInfos.GlobalId )
  1856. //                {
  1857. //                    KaxVideoStereoMode &stereo = *(KaxVideoStereoMode*)el4;
  1858. //                    msg_Dbg( p_demux, "|   |   |   |   + Track Video Stereo Mode=%u", uint8( stereo ) );
  1859. //                }
  1860. //                else
  1861.                 if( MKV_IS_ID( l, KaxVideoPixelWidth ) )
  1862.                 {
  1863.                     KaxVideoPixelWidth &vwidth = *(KaxVideoPixelWidth*)l;
  1864.                     tk->fmt.video.i_width = uint16( vwidth );
  1865.                     msg_Dbg( p_demux, "|   |   |   |   + width=%d", uint16( vwidth ) );
  1866.                 }
  1867.                 else if( MKV_IS_ID( l, KaxVideoPixelHeight ) )
  1868.                 {
  1869.                     KaxVideoPixelWidth &vheight = *(KaxVideoPixelWidth*)l;
  1870.                     tk->fmt.video.i_height = uint16( vheight );
  1871.                     msg_Dbg( p_demux, "|   |   |   |   + height=%d", uint16( vheight ) );
  1872.                 }
  1873.                 else if( MKV_IS_ID( l, KaxVideoDisplayWidth ) )
  1874.                 {
  1875.                     KaxVideoDisplayWidth &vwidth = *(KaxVideoDisplayWidth*)l;
  1876.                     tk->fmt.video.i_visible_width = uint16( vwidth );
  1877.                     msg_Dbg( p_demux, "|   |   |   |   + display width=%d", uint16( vwidth ) );
  1878.                 }
  1879.                 else if( MKV_IS_ID( l, KaxVideoDisplayHeight ) )
  1880.                 {
  1881.                     KaxVideoDisplayWidth &vheight = *(KaxVideoDisplayWidth*)l;
  1882.                     tk->fmt.video.i_visible_height = uint16( vheight );
  1883.                     msg_Dbg( p_demux, "|   |   |   |   + display height=%d", uint16( vheight ) );
  1884.                 }
  1885.                 else if( MKV_IS_ID( l, KaxVideoFrameRate ) )
  1886.                 {
  1887.                     KaxVideoFrameRate &vfps = *(KaxVideoFrameRate*)l;
  1888.                     tk->f_fps = float( vfps );
  1889.                     msg_Dbg( p_demux, "   |   |   |   + fps=%f", float( vfps ) );
  1890.                 }
  1891. //                else if( EbmlId( *l ) == KaxVideoDisplayUnit::ClassInfos.GlobalId )
  1892. //                {
  1893. //                     KaxVideoDisplayUnit &vdmode = *(KaxVideoDisplayUnit*)l;
  1894. //                    msg_Dbg( p_demux, "|   |   |   |   + Track Video Display Unit=%s",
  1895. //                             uint8( vdmode ) == 0 ? "pixels" : ( uint8( vdmode ) == 1 ? "centimeters": "inches" ) );
  1896. //                }
  1897. //                else if( EbmlId( *l ) == KaxVideoAspectRatio::ClassInfos.GlobalId )
  1898. //                {
  1899. //                    KaxVideoAspectRatio &ratio = *(KaxVideoAspectRatio*)l;
  1900. //                    msg_Dbg( p_demux, "   |   |   |   + Track Video Aspect Ratio Type=%u", uint8( ratio ) );
  1901. //                }
  1902. //                else if( EbmlId( *l ) == KaxVideoGamma::ClassInfos.GlobalId )
  1903. //                {
  1904. //                    KaxVideoGamma &gamma = *(KaxVideoGamma*)l;
  1905. //                    msg_Dbg( p_demux, "   |   |   |   + fps=%f", float( gamma ) );
  1906. //                }
  1907.                 else
  1908.                 {
  1909.                     msg_Dbg( p_demux, "|   |   |   |   + Unknown (%s)", typeid(*l).name() );
  1910.                 }
  1911.             }
  1912.         }
  1913.         else  if( MKV_IS_ID( l, KaxTrackAudio ) )
  1914.         {
  1915.             EbmlMaster *tka = static_cast<EbmlMaster*>(l);
  1916.             unsigned int j;
  1917.             msg_Dbg( p_demux, "|   |   |   + Track Audio" );
  1918.             for( j = 0; j < tka->ListSize(); j++ )
  1919.             {
  1920.                 EbmlElement *l = (*tka)[j];
  1921.                 if( MKV_IS_ID( l, KaxAudioSamplingFreq ) )
  1922.                 {
  1923.                     KaxAudioSamplingFreq &afreq = *(KaxAudioSamplingFreq*)l;
  1924.                     tk->fmt.audio.i_rate = (int)float( afreq );
  1925.                     msg_Dbg( p_demux, "|   |   |   |   + afreq=%d", tk->fmt.audio.i_rate );
  1926.                 }
  1927.                 else if( MKV_IS_ID( l, KaxAudioChannels ) )
  1928.                 {
  1929.                     KaxAudioChannels &achan = *(KaxAudioChannels*)l;
  1930.                     tk->fmt.audio.i_channels = uint8( achan );
  1931.                     msg_Dbg( p_demux, "|   |   |   |   + achan=%u", uint8( achan ) );
  1932.                 }
  1933.                 else if( MKV_IS_ID( l, KaxAudioBitDepth ) )
  1934.                 {
  1935.                     KaxAudioBitDepth &abits = *(KaxAudioBitDepth*)l;
  1936.                     tk->fmt.audio.i_bitspersample = uint8( abits );
  1937.                     msg_Dbg( p_demux, "|   |   |   |   + abits=%u", uint8( abits ) );
  1938.                 }
  1939.                 else
  1940.                 {
  1941.                     msg_Dbg( p_demux, "|   |   |   |   + Unknown (%s)", typeid(*l).name() );
  1942.                 }
  1943.             }
  1944.         }
  1945.         else
  1946.         {
  1947.             msg_Dbg( p_demux, "|   |   |   + Unknown (%s)",
  1948.                      typeid(*l).name() );
  1949.         }
  1950.     }
  1951. }
  1952. static void ParseTracks( demux_t *p_demux, EbmlElement *tracks )
  1953. {
  1954.     demux_sys_t *p_sys = p_demux->p_sys;
  1955.     EbmlElement *el;
  1956.     EbmlMaster  *m;
  1957.     unsigned int i;
  1958.     int i_upper_level = 0;
  1959.     msg_Dbg( p_demux, "|   + Tracks" );
  1960.     /* Master elements */
  1961.     m = static_cast<EbmlMaster *>(tracks);
  1962.     m->Read( *p_sys->es, tracks->Generic().Context, i_upper_level, el, true );
  1963.     for( i = 0; i < m->ListSize(); i++ )
  1964.     {
  1965.         EbmlElement *l = (*m)[i];
  1966.         if( MKV_IS_ID( l, KaxTrackEntry ) )
  1967.         {
  1968.             ParseTrackEntry( p_demux, static_cast<EbmlMaster *>(l) );
  1969.         }
  1970.         else
  1971.         {
  1972.             msg_Dbg( p_demux, "|   |   + Unknown (%s)", typeid(*l).name() );
  1973.         }
  1974.     }
  1975. }
  1976. /*****************************************************************************
  1977.  * ParseInfo:
  1978.  *****************************************************************************/
  1979. static void ParseInfo( demux_t *p_demux, EbmlElement *info )
  1980. {
  1981.     demux_sys_t *p_sys = p_demux->p_sys;
  1982.     EbmlElement *el;
  1983.     EbmlMaster  *m;
  1984.     unsigned int i;
  1985.     int i_upper_level = 0;
  1986.     msg_Dbg( p_demux, "|   + Information" );
  1987.     /* Master elements */
  1988.     m = static_cast<EbmlMaster *>(info);
  1989.     m->Read( *p_sys->es, info->Generic().Context, i_upper_level, el, true );
  1990.     for( i = 0; i < m->ListSize(); i++ )
  1991.     {
  1992.         EbmlElement *l = (*m)[i];
  1993.         if( MKV_IS_ID( l, KaxSegmentUID ) )
  1994.         {
  1995.             KaxSegmentUID &uid = *(KaxSegmentUID*)l;
  1996.             msg_Dbg( p_demux, "|   |   + UID=%d", uint32(uid) );
  1997.         }
  1998.         else if( MKV_IS_ID( l, KaxTimecodeScale ) )
  1999.         {
  2000.             KaxTimecodeScale &tcs = *(KaxTimecodeScale*)l;
  2001.             p_sys->i_timescale = uint64(tcs);
  2002.             msg_Dbg( p_demux, "|   |   + TimecodeScale="I64Fd,
  2003.                      p_sys->i_timescale );
  2004.         }
  2005.         else if( MKV_IS_ID( l, KaxDuration ) )
  2006.         {
  2007.             KaxDuration &dur = *(KaxDuration*)l;
  2008.             p_sys->f_duration = float(dur);
  2009.             msg_Dbg( p_demux, "|   |   + Duration=%f",
  2010.                      p_sys->f_duration );
  2011.         }
  2012.         else if( MKV_IS_ID( l, KaxMuxingApp ) )
  2013.         {
  2014.             KaxMuxingApp &mapp = *(KaxMuxingApp*)l;
  2015.             p_sys->psz_muxing_application = UTF8ToStr( UTFstring( mapp ) );
  2016.             msg_Dbg( p_demux, "|   |   + Muxing Application=%s",
  2017.                      p_sys->psz_muxing_application );
  2018.         }
  2019.         else if( MKV_IS_ID( l, KaxWritingApp ) )
  2020.         {
  2021.             KaxWritingApp &wapp = *(KaxWritingApp*)l;
  2022.             p_sys->psz_writing_application = UTF8ToStr( UTFstring( wapp ) );
  2023.             msg_Dbg( p_demux, "|   |   + Writing Application=%s",
  2024.                      p_sys->psz_writing_application );
  2025.         }
  2026.         else if( MKV_IS_ID( l, KaxSegmentFilename ) )
  2027.         {
  2028.             KaxSegmentFilename &sfn = *(KaxSegmentFilename*)l;
  2029.             p_sys->psz_segment_filename = UTF8ToStr( UTFstring( sfn ) );
  2030.             msg_Dbg( p_demux, "|   |   + Segment Filename=%s",
  2031.                      p_sys->psz_segment_filename );
  2032.         }
  2033.         else if( MKV_IS_ID( l, KaxTitle ) )
  2034.         {
  2035.             KaxTitle &title = *(KaxTitle*)l;
  2036.             p_sys->psz_title = UTF8ToStr( UTFstring( title ) );
  2037.             msg_Dbg( p_demux, "|   |   + Title=%s", p_sys->psz_title );
  2038.         }
  2039. #if defined( HAVE_GMTIME_R ) && !defined( SYS_DARWIN )
  2040.         else if( MKV_IS_ID( l, KaxDateUTC ) )
  2041.         {
  2042.             KaxDateUTC &date = *(KaxDateUTC*)l;
  2043.             time_t i_date;
  2044.             struct tm tmres;
  2045.             char   buffer[256];
  2046.             i_date = date.GetEpochDate();
  2047.             memset( buffer, 0, 256 );
  2048.             if( gmtime_r( &i_date, &tmres ) &&
  2049.                 asctime_r( &tmres, buffer ) )
  2050.             {
  2051.                 buffer[strlen( buffer)-1]= '';
  2052.                 p_sys->psz_date_utc = strdup( buffer );
  2053.                 msg_Dbg( p_demux, "|   |   + Date=%s", p_sys->psz_date_utc );
  2054.             }
  2055.         }
  2056. #endif
  2057.         else
  2058.         {
  2059.             msg_Dbg( p_demux, "|   |   + Unknown (%s)", typeid(*l).name() );
  2060.         }
  2061.     }
  2062.     p_sys->f_duration = p_sys->f_duration * p_sys->i_timescale / 1000000.0;
  2063. }
  2064. /*****************************************************************************
  2065.  * ParseChapterAtom
  2066.  *****************************************************************************/
  2067. static void ParseChapterAtom( demux_t *p_demux, int i_level, EbmlMaster *ca )
  2068. {
  2069.     demux_sys_t *p_sys = p_demux->p_sys;
  2070.     unsigned int i;
  2071.     seekpoint_t *sk;
  2072.     if( p_sys->title == NULL )
  2073.     {
  2074.         p_sys->title = vlc_input_title_New();
  2075.     }
  2076.     sk = vlc_seekpoint_New();
  2077.     msg_Dbg( p_demux, "|   |   |   + ChapterAtom (level=%d)", i_level );
  2078.     for( i = 0; i < ca->ListSize(); i++ )
  2079.     {
  2080.         EbmlElement *l = (*ca)[i];
  2081.         if( MKV_IS_ID( l, KaxChapterUID ) )
  2082.         {
  2083.             KaxChapterUID &uid = *(KaxChapterUID*)l;
  2084.             uint32_t i_uid = uint32( uid );
  2085.             msg_Dbg( p_demux, "|   |   |   |   + ChapterUID: 0x%x", i_uid );
  2086.         }
  2087.         else if( MKV_IS_ID( l, KaxChapterTimeStart ) )
  2088.         {
  2089.             KaxChapterTimeStart &start =*(KaxChapterTimeStart*)l;
  2090.             sk->i_time_offset = uint64( start ) / I64C(1000);
  2091.             msg_Dbg( p_demux, "|   |   |   |   + ChapterTimeStart: %lld", sk->i_time_offset );
  2092.         }
  2093.         else if( MKV_IS_ID( l, KaxChapterTimeEnd ) )
  2094.         {
  2095.             KaxChapterTimeEnd &end =*(KaxChapterTimeEnd*)l;
  2096.             int64_t i_end = uint64( end );
  2097.             msg_Dbg( p_demux, "|   |   |   |   + ChapterTimeEnd: %lld", i_end );
  2098.         }
  2099.         else if( MKV_IS_ID( l, KaxChapterDisplay ) )
  2100.         {
  2101.             EbmlMaster *cd = static_cast<EbmlMaster *>(l);
  2102.             unsigned int j;
  2103.             msg_Dbg( p_demux, "|   |   |   |   + ChapterDisplay" );
  2104.             for( j = 0; j < cd->ListSize(); j++ )
  2105.             {
  2106.                 EbmlElement *l= (*cd)[j];
  2107.                 if( MKV_IS_ID( l, KaxChapterString ) )
  2108.                 {
  2109.                     KaxChapterString &name =*(KaxChapterString*)l;
  2110.                     char *psz = UTF8ToStr( UTFstring( name ) );
  2111.                     sk->psz_name = strdup( psz );
  2112.                     msg_Dbg( p_demux, "|   |   |   |   |    + ChapterString '%s'", psz );
  2113.                 }
  2114.                 else if( MKV_IS_ID( l, KaxChapterLanguage ) )
  2115.                 {
  2116.                     KaxChapterLanguage &lang =*(KaxChapterLanguage*)l;
  2117.                     const char *psz = string( lang ).c_str();
  2118.                     msg_Dbg( p_demux, "|   |   |   |   |    + ChapterLanguage '%s'", psz );
  2119.                 }
  2120.                 else if( MKV_IS_ID( l, KaxChapterCountry ) )
  2121.                 {
  2122.                     KaxChapterCountry &ct =*(KaxChapterCountry*)l;
  2123.                     const char *psz = string( ct ).c_str();
  2124.                     msg_Dbg( p_demux, "|   |   |   |   |    + ChapterCountry '%s'", psz );
  2125.                 }
  2126.             }
  2127.         }
  2128.         else if( MKV_IS_ID( l, KaxChapterAtom ) )
  2129.         {
  2130.             ParseChapterAtom( p_demux, i_level+1, static_cast<EbmlMaster *>(l) );
  2131.         }
  2132.     }
  2133.     // A start time of '0' is ok. A missing ChapterTime element is ok, too, because '0' is its default value.
  2134.     p_sys->title->i_seekpoint++;
  2135.     p_sys->title->seekpoint = (seekpoint_t**)realloc( p_sys->title->seekpoint, p_sys->title->i_seekpoint * sizeof( seekpoint_t* ) );
  2136.     p_sys->title->seekpoint[p_sys->title->i_seekpoint-1] = sk;
  2137. }
  2138. /*****************************************************************************
  2139.  * ParseChapters:
  2140.  *****************************************************************************/
  2141. static void ParseChapters( demux_t *p_demux, EbmlElement *chapters )
  2142. {
  2143.     demux_sys_t *p_sys = p_demux->p_sys;
  2144.     EbmlElement *el;
  2145.     EbmlMaster  *m;
  2146.     unsigned int i;
  2147.     int i_upper_level = 0;
  2148.     /* Master elements */
  2149.     m = static_cast<EbmlMaster *>(chapters);
  2150.     m->Read( *p_sys->es, chapters->Generic().Context, i_upper_level, el, true );
  2151.     for( i = 0; i < m->ListSize(); i++ )
  2152.     {
  2153.         EbmlElement *l = (*m)[i];
  2154.         if( MKV_IS_ID( l, KaxEditionEntry ) )
  2155.         {
  2156.             EbmlMaster *E = static_cast<EbmlMaster *>(l );
  2157.             unsigned int j;
  2158.             msg_Dbg( p_demux, "|   |   + EditionEntry" );
  2159.             for( j = 0; j < E->ListSize(); j++ )
  2160.             {
  2161.                 EbmlElement *l = (*E)[j];
  2162.                 if( MKV_IS_ID( l, KaxChapterAtom ) )
  2163.                 {
  2164.                     ParseChapterAtom( p_demux, 0, static_cast<EbmlMaster *>(l) );
  2165.                 }
  2166.                 else
  2167.                 {
  2168.                     msg_Dbg( p_demux, "|   |   |   + Unknown (%s)", typeid(*l).name() );
  2169.                 }
  2170.             }
  2171.         }
  2172.         else
  2173.         {
  2174.             msg_Dbg( p_demux, "|   |   + Unknown (%s)", typeid(*l).name() );
  2175.         }
  2176.     }
  2177. }
  2178. /*****************************************************************************
  2179.  * InformationCreate:
  2180.  *****************************************************************************/
  2181. static void InformationCreate( demux_t *p_demux )
  2182. {
  2183.     demux_sys_t *p_sys = p_demux->p_sys;
  2184.     int         i_track;
  2185.     p_sys->meta = vlc_meta_New();
  2186.     if( p_sys->psz_title )
  2187.     {
  2188.         vlc_meta_Add( p_sys->meta, VLC_META_TITLE, p_sys->psz_title );
  2189.     }
  2190.     if( p_sys->psz_date_utc )
  2191.     {
  2192.         vlc_meta_Add( p_sys->meta, VLC_META_DATE, p_sys->psz_date_utc );
  2193.     }
  2194.     if( p_sys->psz_segment_filename )
  2195.     {
  2196.         vlc_meta_Add( p_sys->meta, _("Segment filename"), p_sys->psz_segment_filename );
  2197.     }
  2198.     if( p_sys->psz_muxing_application )
  2199.     {
  2200.         vlc_meta_Add( p_sys->meta, _("Muxing application"), p_sys->psz_muxing_application );
  2201.     }
  2202.     if( p_sys->psz_writing_application )
  2203.     {
  2204.         vlc_meta_Add( p_sys->meta, _("Writing application"), p_sys->psz_writing_application );
  2205.     }
  2206.     for( i_track = 0; i_track < p_sys->i_track; i_track++ )
  2207.     {
  2208.         mkv_track_t *tk = &p_sys->track[i_track];
  2209.         vlc_meta_t *mtk = vlc_meta_New();
  2210.         p_sys->meta->track = (vlc_meta_t**)realloc( p_sys->meta->track,
  2211.                                                     sizeof( vlc_meta_t * ) * ( p_sys->meta->i_track + 1 ) );
  2212.         p_sys->meta->track[p_sys->meta->i_track++] = mtk;
  2213.         if( tk->fmt.psz_description )
  2214.         {
  2215.             vlc_meta_Add( p_sys->meta, VLC_META_DESCRIPTION, tk->fmt.psz_description );
  2216.         }
  2217.         if( tk->psz_codec_name )
  2218.         {
  2219.             vlc_meta_Add( p_sys->meta, VLC_META_CODEC_NAME, tk->psz_codec_name );
  2220.         }
  2221.         if( tk->psz_codec_settings )
  2222.         {
  2223.             vlc_meta_Add( p_sys->meta, VLC_META_SETTING, tk->psz_codec_settings );
  2224.         }
  2225.         if( tk->psz_codec_info_url )
  2226.         {
  2227.             vlc_meta_Add( p_sys->meta, VLC_META_CODEC_DESCRIPTION, tk->psz_codec_info_url );
  2228.         }
  2229.         if( tk->psz_codec_download_url )
  2230.         {
  2231.             vlc_meta_Add( p_sys->meta, VLC_META_URL, tk->psz_codec_download_url );
  2232.         }
  2233.     }
  2234.     if( p_sys->i_tags_position >= 0 )
  2235.     {
  2236.         vlc_bool_t b_seekable;
  2237.         stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b_seekable );
  2238.         if( b_seekable )
  2239.         {
  2240.             LoadTags( p_demux );
  2241.         }
  2242.     }
  2243. }
  2244. /*****************************************************************************
  2245.  * Divers
  2246.  *****************************************************************************/
  2247. static void IndexAppendCluster( demux_t *p_demux, KaxCluster *cluster )
  2248. {
  2249.     demux_sys_t *p_sys = p_demux->p_sys;
  2250. #define idx p_sys->index[p_sys->i_index]
  2251.     idx.i_track       = -1;
  2252.     idx.i_block_number= -1;
  2253.     idx.i_position    = cluster->GetElementPosition();
  2254.     idx.i_time        = -1;
  2255.     idx.b_key         = VLC_TRUE;
  2256.     p_sys->i_index++;
  2257.     if( p_sys->i_index >= p_sys->i_index_max )
  2258.     {
  2259.         p_sys->i_index_max += 1024;
  2260.         p_sys->index = (mkv_index_t*)realloc( p_sys->index, sizeof( mkv_index_t ) * p_sys->i_index_max );
  2261.     }
  2262. #undef idx
  2263. }
  2264. static char * UTF8ToStr( const UTFstring &u )
  2265. {
  2266.     int     i_src;
  2267.     const wchar_t *src;
  2268.     char *dst, *p;
  2269.     i_src = u.length();
  2270.     src   = u.c_str();
  2271.     p = dst = (char*)malloc( i_src + 1);
  2272.     while( i_src > 0 )
  2273.     {
  2274.         if( *src < 255 )
  2275.         {
  2276.             *p++ = (char)*src;
  2277.         }
  2278.         else
  2279.         {
  2280.             *p++ = '?';
  2281.         }
  2282.         src++;
  2283.         i_src--;
  2284.     }
  2285.     *p++= '';
  2286.     return dst;
  2287. }