Commit b42bf247 authored by Denis Charmet's avatar Denis Charmet Committed by Jean-Baptiste Kempf

Use encoding scope to correctly decode data

Fix #5196
Signed-off-by: default avatarJean-Baptiste Kempf <jb@videolan.org>
parent 59253baf
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
#include "Ebml_parser.hpp" #include "Ebml_parser.hpp"
#include "util.hpp"
/***************************************************************************** /*****************************************************************************
* Some functions to manipulate memory * Some functions to manipulate memory
*****************************************************************************/ *****************************************************************************/
...@@ -199,6 +201,7 @@ void matroska_segment_c::ParseTrackEntry( KaxTrackEntry *m ) ...@@ -199,6 +201,7 @@ void matroska_segment_c::ParseTrackEntry( KaxTrackEntry *m )
tk->psz_codec_download_url = NULL; tk->psz_codec_download_url = NULL;
tk->i_compression_type = MATROSKA_COMPRESSION_NONE; tk->i_compression_type = MATROSKA_COMPRESSION_NONE;
tk->i_encoding_scope = MATROSKA_ENCODING_SCOPE_ALL_FRAMES;
tk->p_compression_data = NULL; tk->p_compression_data = NULL;
msg_Dbg( &sys.demuxer, "| | + Track Entry" ); msg_Dbg( &sys.demuxer, "| | + Track Entry" );
...@@ -392,6 +395,7 @@ void matroska_segment_c::ParseTrackEntry( KaxTrackEntry *m ) ...@@ -392,6 +395,7 @@ void matroska_segment_c::ParseTrackEntry( KaxTrackEntry *m )
else if( MKV_IS_ID( l3, KaxContentEncodingScope ) ) else if( MKV_IS_ID( l3, KaxContentEncodingScope ) )
{ {
KaxContentEncodingScope &encscope = *(KaxContentEncodingScope*)l3; KaxContentEncodingScope &encscope = *(KaxContentEncodingScope*)l3;
tk->i_encoding_scope = uint32( encscope );
MkvTree( sys.demuxer, 5, "Scope: %i", uint32( encscope ) ); MkvTree( sys.demuxer, 5, "Scope: %i", uint32( encscope ) );
} }
else if( MKV_IS_ID( l3, KaxContentEncodingType ) ) else if( MKV_IS_ID( l3, KaxContentEncodingType ) )
...@@ -654,11 +658,20 @@ void matroska_segment_c::ParseTrackEntry( KaxTrackEntry *m ) ...@@ -654,11 +658,20 @@ void matroska_segment_c::ParseTrackEntry( KaxTrackEntry *m )
if ( bSupported ) if ( bSupported )
{ {
#ifdef HAVE_ZLIB_H
if( tk->i_compression_type == MATROSKA_COMPRESSION_ZLIB &&
tk->i_encoding_scope & MATROSKA_ENCODING_SCOPE_PRIVATE &&
tk->i_extra_data && tk->p_extra_data &&
zlib_decompress_extra( &sys.demuxer, tk) )
return;
#endif
tracks.push_back( tk ); tracks.push_back( tk );
} }
else else
{ {
msg_Err( &sys.demuxer, "Track Entry %d not supported", tk->i_number ); msg_Err( &sys.demuxer, "Track Entry %d not supported", tk->i_number );
free(tk->p_extra_data);
delete tk; delete tk;
} }
} }
......
...@@ -561,7 +561,9 @@ void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock ...@@ -561,7 +561,9 @@ void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock
break; break;
} }
if( tk->i_compression_type == MATROSKA_COMPRESSION_HEADER && tk->p_compression_data != NULL ) if( tk->i_compression_type == MATROSKA_COMPRESSION_HEADER &&
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() ); p_block = MemToBlock( data->Buffer(), data->Size(), tk->p_compression_data->GetSize() );
else else
p_block = MemToBlock( data->Buffer(), data->Size(), 0 ); p_block = MemToBlock( data->Buffer(), data->Size(), 0 );
...@@ -572,7 +574,8 @@ void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock ...@@ -572,7 +574,8 @@ void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock
} }
#if defined(HAVE_ZLIB_H) #if defined(HAVE_ZLIB_H)
if( tk->i_compression_type == MATROSKA_COMPRESSION_ZLIB ) if( tk->i_compression_type == MATROSKA_COMPRESSION_ZLIB &&
tk->i_encoding_scope & MATROSKA_ENCODING_SCOPE_ALL_FRAMES )
{ {
p_block = block_zlib_decompress( VLC_OBJECT(p_demux), p_block ); p_block = block_zlib_decompress( VLC_OBJECT(p_demux), p_block );
if( p_block == NULL ) if( p_block == NULL )
...@@ -580,7 +583,8 @@ void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock ...@@ -580,7 +583,8 @@ void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock
} }
else else
#endif #endif
if( tk->i_compression_type == MATROSKA_COMPRESSION_HEADER ) if( tk->i_compression_type == MATROSKA_COMPRESSION_HEADER &&
tk->i_encoding_scope & MATROSKA_ENCODING_SCOPE_ALL_FRAMES )
{ {
memcpy( p_block->p_buffer, tk->p_compression_data->GetBuffer(), tk->p_compression_data->GetSize() ); memcpy( p_block->p_buffer, tk->p_compression_data->GetBuffer(), tk->p_compression_data->GetSize() );
} }
......
...@@ -113,6 +113,13 @@ extern "C" { ...@@ -113,6 +113,13 @@ extern "C" {
#define MATROSKA_COMPRESSION_LZOX 2 #define MATROSKA_COMPRESSION_LZOX 2
#define MATROSKA_COMPRESSION_HEADER 3 #define MATROSKA_COMPRESSION_HEADER 3
enum
{
MATROSKA_ENCODING_SCOPE_ALL_FRAMES = 1,
MATROSKA_ENCODING_SCOPE_PRIVATE = 2,
MATROSKA_ENCODING_SCOPE_NEXT = 4 /* unsupported */
};
#define MKVD_TIMECODESCALE 1000000 #define MKVD_TIMECODESCALE 1000000
#define MKV_IS_ID( el, C ) ( el != NULL && typeid( *el ) == typeid( C ) ) #define MKV_IS_ID( el, C ) ( el != NULL && typeid( *el ) == typeid( C ) )
...@@ -229,6 +236,7 @@ struct mkv_track_t ...@@ -229,6 +236,7 @@ struct mkv_track_t
/* encryption/compression */ /* encryption/compression */
int i_compression_type; int i_compression_type;
uint32_t i_encoding_scope;
KaxContentCompSettings *p_compression_data; KaxContentCompSettings *p_compression_data;
}; };
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
* along with this program; if not, write to the Free Software Foundation, * along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/ *****************************************************************************/
#include "mkv.hpp"
#include "util.hpp" #include "util.hpp"
#include "demux.hpp" #include "demux.hpp"
...@@ -30,6 +31,77 @@ ...@@ -30,6 +31,77 @@
*****************************************************************************/ *****************************************************************************/
#ifdef HAVE_ZLIB_H #ifdef HAVE_ZLIB_H
int32_t zlib_decompress_extra( demux_t * p_demux, mkv_track_t * tk )
{
int result;
z_stream d_stream;
size_t n = 0;
uint8_t * p_new_extra = NULL;
msg_Dbg(p_demux,"Inflating private data");
d_stream.zalloc = Z_NULL;
d_stream.zfree = Z_NULL;
d_stream.opaque = Z_NULL;
if( inflateInit( &d_stream ) != Z_OK )
{
msg_Err( p_demux, "Couldn't initiate inflation ignore track %d",
tk->i_number );
free(tk->p_extra_data);
delete tk;
return 1;
}
d_stream.next_in = tk->p_extra_data;
d_stream.avail_in = tk->i_extra_data;
do
{
n++;
p_new_extra = (uint8_t *) realloc(p_new_extra, n*1024);
if( !p_new_extra )
{
msg_Err( p_demux, "Couldn't allocate buffer to inflate data, ignore track %d",
tk->i_number );
inflateEnd( &d_stream );
free(tk->p_extra_data);
delete tk;
return 1;
}
d_stream.next_out = &p_new_extra[(n - 1) * 1024];
d_stream.avail_out = 1024;
result = inflate(&d_stream, Z_NO_FLUSH);
if( result != Z_OK && result != Z_STREAM_END )
{
msg_Err( p_demux, "Zlib decompression failed. Result: %d", result );
inflateEnd( &d_stream );
free(p_new_extra);
free(tk->p_extra_data);
delete tk;
return 1;
}
}
while ( d_stream.avail_out == 0 && d_stream.avail_in != 0 &&
result != Z_STREAM_END );
free( tk->p_extra_data );
tk->i_extra_data = d_stream.total_out;
p_new_extra = (uint8_t *) realloc(p_new_extra, tk->i_extra_data);
if( !p_new_extra )
{
msg_Err( p_demux, "Couldn't allocate buffer to inflate data, ignore track %d",
tk->i_number );
inflateEnd( &d_stream );
free(p_new_extra);
delete tk;
return 1;
}
tk->p_extra_data = p_new_extra;
inflateEnd( &d_stream );
return 0;
}
block_t *block_zlib_decompress( vlc_object_t *p_this, block_t *p_in_block ) { block_t *block_zlib_decompress( vlc_object_t *p_this, block_t *p_in_block ) {
int result, dstsize, n; int result, dstsize, n;
unsigned char *dst; unsigned char *dst;
...@@ -61,8 +133,10 @@ block_t *block_zlib_decompress( vlc_object_t *p_this, block_t *p_in_block ) { ...@@ -61,8 +133,10 @@ block_t *block_zlib_decompress( vlc_object_t *p_this, block_t *p_in_block ) {
result = inflate(&d_stream, Z_NO_FLUSH); result = inflate(&d_stream, Z_NO_FLUSH);
if( ( result != Z_OK ) && ( result != Z_STREAM_END ) ) if( ( result != Z_OK ) && ( result != Z_STREAM_END ) )
{ {
msg_Dbg( p_this, "Zlib decompression failed. Result: %d", result ); msg_Err( p_this, "Zlib decompression failed. Result: %d", result );
return NULL; inflateEnd( &d_stream );
block_Release( p_block );
return p_in_block;
} }
} }
while( ( d_stream.avail_out == 0 ) && ( d_stream.avail_in != 0 ) && while( ( d_stream.avail_out == 0 ) && ( d_stream.avail_in != 0 ) &&
......
...@@ -25,7 +25,10 @@ ...@@ -25,7 +25,10 @@
#include "mkv.hpp" #include "mkv.hpp"
#ifdef HAVE_ZLIB_H
int32_t zlib_decompress_extra( demux_t * p_demux, mkv_track_t * tk );
block_t *block_zlib_decompress( vlc_object_t *p_this, block_t *p_in_block ); block_t *block_zlib_decompress( vlc_object_t *p_this, block_t *p_in_block );
#endif
block_t *MemToBlock( uint8_t *p_mem, size_t i_mem, size_t offset); block_t *MemToBlock( uint8_t *p_mem, size_t i_mem, size_t offset);
void handle_real_audio(demux_t * p_demux, mkv_track_t * p_tk, block_t * p_blk, mtime_t i_pts); void handle_real_audio(demux_t * p_demux, mkv_track_t * p_tk, block_t * p_blk, mtime_t i_pts);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment