]> git.sesse.net Git - vlc/blobdiff - modules/demux/mkv.cpp
* fixing the OSX playlist (at least it compiles again)
[vlc] / modules / demux / mkv.cpp
index 9dcd168cc7806dc435feeb80bfb6133c3e525746..88ca9c3751d0a15fcd34fd46e33136e900629127 100644 (file)
@@ -75,6 +75,9 @@
 
 #include "ebml/StdIOCallback.h"
 
+extern "C" {
+   #include "mp4/libmp4.h"
+}
 #ifdef HAVE_ZLIB_H
 #   include <zlib.h>
 #endif
@@ -161,6 +164,29 @@ block_t *block_zlib_decompress( vlc_object_t *p_this, block_t *p_in_block ) {
 }
 #endif
 
+/**
+ * Helper function to print the mkv parse tree
+ */
+static void MkvTree( demux_t *p_this, int i_level, char *psz_format, ... )
+{
+    va_list args;
+    if( i_level > 9 )
+    {
+        msg_Err( p_this, "too deep tree" );
+        return;
+    }
+    va_start( args, psz_format );
+    static char *psz_foo = "|   |   |   |   |   |   |   |   |   |";
+    char *psz_foo2 = (char*)malloc( ( i_level * 4 + 3 + strlen( psz_format ) ) * sizeof(char) );
+    strncpy( psz_foo2, psz_foo, 4 * i_level );
+    psz_foo2[ 4 * i_level ] = '+';
+    psz_foo2[ 4 * i_level + 1 ] = ' ';
+    strcpy( &psz_foo2[ 4 * i_level + 2 ], psz_format );
+    __msg_GenericVa( VLC_OBJECT(p_this), VLC_MSG_DBG, "mkv", psz_foo2, args );
+    free( psz_foo2 );
+    va_end( args );
+}
+    
 /*****************************************************************************
  * Stream managment
  *****************************************************************************/
@@ -254,7 +280,7 @@ typedef struct
     char         *psz_codec_download_url;
     
     /* encryption/compression */
-    vlc_bool_t   b_compression_zlib;
+    int           i_compression_type;
 
 } mkv_track_t;
 
@@ -414,7 +440,7 @@ static int Open( vlc_object_t * p_this )
         msg_Err( p_demux, "cannot find KaxSegment" );
         goto error;
     }
-    msg_Dbg( p_demux, "+ Segment" );
+    MkvTree( p_demux, 0, "Segment" );
     p_sys->segment = (KaxSegment*)el;
     p_sys->cluster = NULL;
 
@@ -545,6 +571,24 @@ static int Open( vlc_object_t * p_this )
                 tk.fmt.i_codec = VLC_FOURCC( 'm', 'p', '4', 'v' );
             }
         }
+        else if( !strcmp( tk.psz_codec, "V_QUICKTIME" ) )
+        {
+            MP4_Box_t *p_box = (MP4_Box_t*)malloc( sizeof( MP4_Box_t ) );
+            MP4_Stream_t *p_mp4_stream = MP4_MemoryStream( p_demux->s,
+                                                           tk.i_extra_data,
+                                                           tk.p_extra_data );
+            MP4_ReadBoxCommon( p_mp4_stream, p_box );
+            MP4_ReadBox_sample_vide( p_mp4_stream, p_box );
+            tk.fmt.i_codec = p_box->i_type;
+            tk.fmt.video.i_width = p_box->data.p_sample_vide->i_width;
+            tk.fmt.video.i_height = p_box->data.p_sample_vide->i_height;
+            tk.fmt.i_extra = p_box->data.p_sample_vide->i_qt_image_description;
+            tk.fmt.p_extra = malloc( tk.fmt.i_extra );
+            memcpy( tk.fmt.p_extra, p_box->data.p_sample_vide->p_qt_image_description, tk.fmt.i_extra );
+            MP4_FreeBox_sample_vide( p_box );
+            free( p_box );
+            free( p_mp4_stream );
+        }
         else if( !strcmp( tk.psz_codec, "A_MS/ACM" ) )
         {
             if( tk.i_extra_data < (int)sizeof( WAVEFORMATEX ) )
@@ -1074,16 +1118,18 @@ static void BlockDecode( demux_t *p_demux, KaxBlock *block, mtime_t i_pts,
         DataBuffer &data = block->GetBuffer(i);
 
         p_block = MemToBlock( p_demux, data.Buffer(), data.Size() );
+
+        if( p_block == NULL )
+        {
+            break;
+        }
+
 #if defined(HAVE_ZLIB_H)
-        if( p_block != NULL && tk.b_compression_zlib )
+        if( tk.i_compression_type )
         {
             p_block = block_zlib_decompress( VLC_OBJECT(p_demux), p_block );
         }
 #endif
-        if( p_block == NULL )
-        {
-            break;
-        }
 
         if( tk.fmt.i_cat != VIDEO_ES )
             p_block->i_dts = p_block->i_pts = i_pts;
@@ -1840,7 +1886,7 @@ static void ParseTrackEntry( demux_t *p_demux, EbmlMaster *m )
     tk->psz_codec_info_url = NULL;
     tk->psz_codec_download_url = NULL;
     
-    tk->b_compression_zlib = VLC_FALSE;
+    tk->i_compression_type = MATROSKA_COMPRESSION_NONE;
 
     for( i = 0; i < m->ListSize(); i++ )
     {
@@ -1977,13 +2023,13 @@ static void ParseTrackEntry( demux_t *p_demux, EbmlMaster *m )
         else if( MKV_IS_ID( l, KaxContentEncodings ) )
         {
             EbmlMaster *cencs = static_cast<EbmlMaster*>(l);
-            msg_Dbg( p_demux, "|   |   |   + Content Encodings" );
+            MkvTree( p_demux, 3, "Content Encodings" );
             for( unsigned int i = 0; i < cencs->ListSize(); i++ )
             {
                 EbmlElement *l2 = (*cencs)[i];
                 if( MKV_IS_ID( l2, KaxContentEncoding ) )
                 {
-                    msg_Dbg( p_demux, "|   |   |   |   + Content Encoding" );
+                    MkvTree( p_demux, 4, "Content Encoding" );
                     EbmlMaster *cenc = static_cast<EbmlMaster*>(l2);
                     for( unsigned int i = 0; i < cenc->ListSize(); i++ )
                     {
@@ -1991,51 +2037,51 @@ static void ParseTrackEntry( demux_t *p_demux, EbmlMaster *m )
                         if( MKV_IS_ID( l3, KaxContentEncodingOrder ) )
                         {
                             KaxContentEncodingOrder &encord = *(KaxContentEncodingOrder*)l3;
-                            msg_Dbg( p_demux, "|   |   |   |   |   + Order: %i", uint32( encord ) );
+                            MkvTree( p_demux, 5, "Order: %i", uint32( encord ) );
                         }
                         else if( MKV_IS_ID( l3, KaxContentEncodingScope ) )
                         {
                             KaxContentEncodingScope &encscope = *(KaxContentEncodingScope*)l3;
-                            msg_Dbg( p_demux, "|   |   |   |   |   + Scope: %i", uint32( encscope ) );
+                            MkvTree( p_demux, 5, "Scope: %i", uint32( encscope ) );
                         }
                         else if( MKV_IS_ID( l3, KaxContentEncodingType ) )
                         {
                             KaxContentEncodingType &enctype = *(KaxContentEncodingType*)l3;
-                            msg_Dbg( p_demux, "|   |   |   |   |   + Type: %i", uint32( enctype ) );
+                            MkvTree( p_demux, 5, "Type: %i", uint32( enctype ) );
                         }
                         else if( MKV_IS_ID( l3, KaxContentCompression ) )
                         {
                             EbmlMaster *compr = static_cast<EbmlMaster*>(l3);
-                            msg_Dbg( p_demux, "|   |   |   |   |   + Content Compression" );
+                            MkvTree( p_demux, 5, "Content Compression" );
                             for( unsigned int i = 0; i < compr->ListSize(); i++ )
                             {
                                 EbmlElement *l4 = (*compr)[i];
                                 if( MKV_IS_ID( l4, KaxContentCompAlgo ) )
                                 {
                                     KaxContentCompAlgo &compalg = *(KaxContentCompAlgo*)l4;
-                                    msg_Dbg( p_demux, "|   |   |   |   |   |   + Compression Algorithm: %i", uint32(compalg) );
+                                    MkvTree( p_demux, 6, "Compression Algorithm: %i", uint32(compalg) );
                                     if( uint32( compalg ) == 0 )
                                     {
-                                        tk->b_compression_zlib = VLC_TRUE;
+                                        tk->i_compression_type = MATROSKA_COMPRESSION_ZLIB;
                                     }
                                 }
                                 else
                                 {
-                                    msg_Dbg( p_demux, "|   |   |   |   |   |   + Unknown (%s)", typeid(*l4).name() );
+                                    MkvTree( p_demux, 6, "Unknown (%s)", typeid(*l4).name() );
                                 }
                             }
                         }
 
                         else
                         {
-                            msg_Dbg( p_demux, "|   |   |   |   |   + Unknown (%s)", typeid(*l3).name() );
+                            MkvTree( p_demux, 5, "Unknown (%s)", typeid(*l3).name() );
                         }
                     }
                     
                 }
                 else
                 {
-                    msg_Dbg( p_demux, "|   |   |   |   + Unknown (%s)", typeid(*l2).name() );
+                    MkvTree( p_demux, 4, "Unknown (%s)", typeid(*l2).name() );
                 }
             }