vlc | branch: master | Denis Charmet <[email protected]> | Mon Sep 2 15:02:34 2013 +0200| [8d0ea8a0adb6f2c65432610c0a3afdca79445ddb] | committer: Denis Charmet
Correctly repacketize wavpack frames from Matroska Since libavcodec decoder doesn't expect matroska formatted wavpack anymore. > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=8d0ea8a0adb6f2c65432610c0a3afdca79445ddb --- 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 997df5b..eb26199 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); _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
