]> git.sesse.net Git - vlc/commitdiff
Correctly repacketize wavpack frames from Matroska
authorDenis Charmet <typx@dinauz.org>
Mon, 2 Sep 2013 13:02:34 +0000 (15:02 +0200)
committerDenis Charmet <typx@dinauz.org>
Mon, 2 Sep 2013 13:07:09 +0000 (15:07 +0200)
Since libavcodec decoder doesn't expect matroska formatted wavpack anymore.

modules/demux/mkv/mkv.cpp
modules/demux/mkv/util.cpp
modules/demux/mkv/util.hpp

index 997df5ba99f76d9d4e17fa8885c3c895e7ca40ab..eb26199be1f0e1e250b74f5e01e57990fdaf427e 100644 (file)
@@ -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 );
 
index 7eea9a049b81df3b019f462a6d95bee0920b9a13..326f631fb87faaf5a49808d0c7dbb65ca1bd0277 100644 (file)
@@ -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;
+}
index 3ec5a702001ef896d472edc249381e72095521cd..c181ad23be316f15470605833baf722f9fe6b83f 100644 (file)
@@ -87,3 +87,5 @@ public:
     size_t   i_subpackets;
     size_t   i_subpacket;
 };
+
+block_t * packetize_wavpack( mkv_track_t *, uint8_t *, size_t);