#include "Ebml_parser.hpp"
+#include "util.hpp"
+
/*****************************************************************************
* Some functions to manipulate memory
*****************************************************************************/
tk->psz_codec_download_url = NULL;
tk->i_compression_type = MATROSKA_COMPRESSION_NONE;
+ tk->i_encoding_scope = MATROSKA_ENCODING_SCOPE_ALL_FRAMES;
tk->p_compression_data = NULL;
msg_Dbg( &sys.demuxer, "| | + Track Entry" );
else if( MKV_IS_ID( l3, KaxContentEncodingScope ) )
{
KaxContentEncodingScope &encscope = *(KaxContentEncodingScope*)l3;
+ tk->i_encoding_scope = uint32( encscope );
MkvTree( sys.demuxer, 5, "Scope: %i", uint32( encscope ) );
}
else if( MKV_IS_ID( l3, KaxContentEncodingType ) )
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 );
}
else
{
msg_Err( &sys.demuxer, "Track Entry %d not supported", tk->i_number );
+ free(tk->p_extra_data);
delete tk;
}
}
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() );
else
p_block = MemToBlock( data->Buffer(), data->Size(), 0 );
}
#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 );
if( p_block == NULL )
}
else
#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() );
}
#define MATROSKA_COMPRESSION_LZOX 2
#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 MKV_IS_ID( el, C ) ( el != NULL && typeid( *el ) == typeid( C ) )
/* encryption/compression */
int i_compression_type;
+ uint32_t i_encoding_scope;
KaxContentCompSettings *p_compression_data;
};
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
+#include "mkv.hpp"
#include "util.hpp"
#include "demux.hpp"
*****************************************************************************/
#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 ) {
int result, dstsize, n;
unsigned char *dst;
result = inflate(&d_stream, Z_NO_FLUSH);
if( ( result != Z_OK ) && ( result != Z_STREAM_END ) )
{
- msg_Dbg( p_this, "Zlib decompression failed. Result: %d", result );
- return NULL;
+ msg_Err( p_this, "Zlib decompression failed. Result: %d", result );
+ inflateEnd( &d_stream );
+ block_Release( p_block );
+ return p_in_block;
}
}
while( ( d_stream.avail_out == 0 ) && ( d_stream.avail_in != 0 ) &&
#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 );
+#endif
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);