[vlc-commits] Correctly repacketize wavpack frames from Matroska

Denis Charmet git at videolan.org
Sun Sep 8 18:51:01 CEST 2013


vlc/vlc-2.1 | branch: master | Denis Charmet <typx at dinauz.org> | Mon Sep  2 15:02:34 2013 +0200| [5086b57fea23c647335ab824d86716e3c2c59892] | committer: Jean-Baptiste Kempf

Correctly repacketize wavpack frames from Matroska

Since libavcodec decoder doesn't expect matroska formatted wavpack anymore.

(cherry picked from commit 8d0ea8a0adb6f2c65432610c0a3afdca79445ddb)
Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>

> http://git.videolan.org/gitweb.cgi/vlc/vlc-2.1.git/?a=commit;h=5086b57fea23c647335ab824d86716e3c2c59892
---

 modules/demux/mkv/mkv.cpp  |    2 +
 modules/demux/mkv/util.cpp |   91 ++++++++++++++++++++++++++++++++++++++++++++
 modules/demux/mkv/util.hpp |    2 +
 3 files changed, 95 insertions(+)

diff --git a/modules/demux/mkv/mkv.cpp b/modules/demux/mkv/mkv.cpp
index 7ac1418..6398409 100644
--- a/modules/demux/mkv/mkv.cpp
+++ b/modules/demux/mkv/mkv.cpp
@@ -567,6 +567,8 @@ void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock
             tk->p_compression_data != NULL &&
             tk->i_encoding_scope & MATROSKA_ENCODING_SCOPE_ALL_FRAMES )
             p_block = MemToBlock( data->Buffer(), data->Size(), tk->p_compression_data->GetSize() );
+        else if( unlikely( tk->fmt.i_codec == VLC_CODEC_WAVPACK ) )
+            p_block = packetize_wavpack(tk, data->Buffer(), data->Size());
         else
             p_block = MemToBlock( data->Buffer(), data->Size(), 0 );
 
diff --git a/modules/demux/mkv/util.cpp b/modules/demux/mkv/util.cpp
index 7eea9a0..326f631 100644
--- a/modules/demux/mkv/util.cpp
+++ b/modules/demux/mkv/util.cpp
@@ -258,3 +258,94 @@ Cook_PrivateTrackData::~Cook_PrivateTrackData()
 
     free( p_subpackets );    
 }
+
+static inline void fill_wvpk_block(uint16_t version, uint32_t block_samples, uint32_t flags,
+                                   uint32_t crc, uint8_t * src, size_t srclen, uint8_t * dst)
+{
+    const uint8_t wvpk_header[] = {'w','v','p','k',         /* ckId */
+                                    0x0, 0x0, 0x0, 0x0,     /* ckSize */
+                                    0x0, 0x0,               /* version */
+                                    0x0,                    /* track_no */
+                                    0x0,                    /* index_no */
+                                    0xFF, 0xFF, 0xFF, 0xFF, /* total_samples */
+                                    0x0, 0x0, 0x0, 0x0 };   /* block_index */
+    memcpy( dst, wvpk_header, sizeof( wvpk_header ) );
+    SetDWLE( dst + 4, srclen + 24 );
+    SetWLE( dst + 8, version );
+    SetDWLE( dst + 20, block_samples );
+    SetDWLE( dst + 24, flags );
+    SetDWLE( dst + 28, crc );
+    memcpy( dst + 32, src, srclen ); 
+}
+
+block_t * packetize_wavpack( mkv_track_t * p_tk, uint8_t * buffer, size_t  size)
+{
+    uint16_t version = 0x403;
+    uint32_t block_samples;
+    uint32_t flags;
+    uint32_t crc;
+    block_t * p_block = NULL;
+    
+    if( p_tk->i_extra_data >= 2 )
+        version = GetWLE( p_tk->p_extra_data );
+
+    if( size < 12 )
+        return NULL;
+ 
+    block_samples = GetDWLE(buffer);
+    buffer += 4;
+    flags = GetDWLE(buffer);
+    size -= 4;
+
+    /* Check if WV_INITIAL_BLOCK and WV_FINAL_BLOCK are present */
+    if( ( flags & 0x1800 ) == 0x1800 )
+    {
+        crc = GetDWLE(buffer+4);
+        buffer += 8;
+        size -= 8;
+
+        p_block = block_Alloc( size + 32 );
+        if( !p_block )
+            return NULL;
+
+        fill_wvpk_block(version, block_samples, flags, crc, buffer, size, p_block->p_buffer);
+    }
+    else
+    {
+        /* Multiblock */
+        size_t total_size = 0; 
+
+        p_block = block_Alloc( 0 );
+        if( !p_block )
+            return NULL;
+
+        while(size >= 12)
+        {
+            flags = GetDWLE(buffer);
+            buffer += 4;
+            crc = GetDWLE(buffer);
+            buffer += 4;
+            uint32_t bsz = GetDWLE(buffer);
+            buffer+= 4;
+            size -= 12;
+
+            bsz = (bsz < size)?bsz:size;
+
+            total_size += bsz + 32;
+
+            assert(total_size >= p_block->i_buffer);
+
+            p_block = block_Realloc( p_block, 0, total_size );
+
+            if( !p_block )
+                return NULL;
+
+            fill_wvpk_block(version, block_samples, flags, crc, buffer, bsz,
+                            p_block->p_buffer + total_size - bsz - 32 );
+            buffer += bsz;
+            size -= bsz;
+        }
+    }
+
+    return p_block;
+}
diff --git a/modules/demux/mkv/util.hpp b/modules/demux/mkv/util.hpp
index 3ec5a70..c181ad2 100644
--- a/modules/demux/mkv/util.hpp
+++ b/modules/demux/mkv/util.hpp
@@ -87,3 +87,5 @@ public:
     size_t   i_subpackets;
     size_t   i_subpacket;
 };
+
+block_t * packetize_wavpack( mkv_track_t *, uint8_t *, size_t);



More information about the vlc-commits mailing list