|
|
|
@ -972,6 +972,82 @@ matroska_parse_info (MatroskaDemuxContext *matroska) |
|
|
|
|
return res; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int |
|
|
|
|
matroska_decode_buffer(uint8_t** buf, int* buf_size, MatroskaTrack *track) |
|
|
|
|
{ |
|
|
|
|
uint8_t* data = *buf; |
|
|
|
|
int isize = *buf_size; |
|
|
|
|
uint8_t* pkt_data = NULL; |
|
|
|
|
int pkt_size = isize; |
|
|
|
|
int result = 0; |
|
|
|
|
int olen; |
|
|
|
|
|
|
|
|
|
switch (track->encoding_algo) { |
|
|
|
|
case MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP: |
|
|
|
|
return track->encoding_settings_len; |
|
|
|
|
case MATROSKA_TRACK_ENCODING_COMP_LZO: |
|
|
|
|
do { |
|
|
|
|
olen = pkt_size *= 3; |
|
|
|
|
pkt_data = av_realloc(pkt_data, |
|
|
|
|
pkt_size+LZO_OUTPUT_PADDING); |
|
|
|
|
result = lzo1x_decode(pkt_data, &olen, data, &isize); |
|
|
|
|
} while (result==LZO_OUTPUT_FULL && pkt_size<10000000); |
|
|
|
|
if (result) |
|
|
|
|
goto failed; |
|
|
|
|
pkt_size -= olen; |
|
|
|
|
break; |
|
|
|
|
#ifdef CONFIG_ZLIB |
|
|
|
|
case MATROSKA_TRACK_ENCODING_COMP_ZLIB: { |
|
|
|
|
z_stream zstream = {0}; |
|
|
|
|
if (inflateInit(&zstream) != Z_OK) |
|
|
|
|
return -1; |
|
|
|
|
zstream.next_in = data; |
|
|
|
|
zstream.avail_in = isize; |
|
|
|
|
do { |
|
|
|
|
pkt_size *= 3; |
|
|
|
|
pkt_data = av_realloc(pkt_data, pkt_size); |
|
|
|
|
zstream.avail_out = pkt_size - zstream.total_out; |
|
|
|
|
zstream.next_out = pkt_data + zstream.total_out; |
|
|
|
|
result = inflate(&zstream, Z_NO_FLUSH); |
|
|
|
|
} while (result==Z_OK && pkt_size<10000000); |
|
|
|
|
pkt_size = zstream.total_out; |
|
|
|
|
inflateEnd(&zstream); |
|
|
|
|
if (result != Z_STREAM_END) |
|
|
|
|
goto failed; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
#ifdef CONFIG_BZLIB |
|
|
|
|
case MATROSKA_TRACK_ENCODING_COMP_BZLIB: { |
|
|
|
|
bz_stream bzstream = {0}; |
|
|
|
|
if (BZ2_bzDecompressInit(&bzstream, 0, 0) != BZ_OK) |
|
|
|
|
return -1; |
|
|
|
|
bzstream.next_in = data; |
|
|
|
|
bzstream.avail_in = isize; |
|
|
|
|
do { |
|
|
|
|
pkt_size *= 3; |
|
|
|
|
pkt_data = av_realloc(pkt_data, pkt_size); |
|
|
|
|
bzstream.avail_out = pkt_size - bzstream.total_out_lo32; |
|
|
|
|
bzstream.next_out = pkt_data + bzstream.total_out_lo32; |
|
|
|
|
result = BZ2_bzDecompress(&bzstream); |
|
|
|
|
} while (result==BZ_OK && pkt_size<10000000); |
|
|
|
|
pkt_size = bzstream.total_out_lo32; |
|
|
|
|
BZ2_bzDecompressEnd(&bzstream); |
|
|
|
|
if (result != BZ_STREAM_END) |
|
|
|
|
goto failed; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
*buf = pkt_data; |
|
|
|
|
*buf_size = pkt_size; |
|
|
|
|
return 0; |
|
|
|
|
failed: |
|
|
|
|
av_free(pkt_data); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int |
|
|
|
|
matroska_add_stream (MatroskaDemuxContext *matroska) |
|
|
|
|
{ |
|
|
|
@ -2801,78 +2877,14 @@ matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, int size, |
|
|
|
|
matroska_queue_packet(matroska, pkt); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
int result, offset = 0, ilen, olen, pkt_size = lace_size[n]; |
|
|
|
|
int offset = 0, pkt_size = lace_size[n]; |
|
|
|
|
uint8_t *pkt_data = data; |
|
|
|
|
|
|
|
|
|
if (matroska->tracks[track]->encoding_scope & 1) { |
|
|
|
|
switch (matroska->tracks[track]->encoding_algo) { |
|
|
|
|
case MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP: |
|
|
|
|
offset = matroska->tracks[track]->encoding_settings_len; |
|
|
|
|
break; |
|
|
|
|
case MATROSKA_TRACK_ENCODING_COMP_LZO: |
|
|
|
|
pkt_data = NULL; |
|
|
|
|
do { |
|
|
|
|
ilen = lace_size[n]; |
|
|
|
|
olen = pkt_size *= 3; |
|
|
|
|
pkt_data = av_realloc(pkt_data, |
|
|
|
|
pkt_size+LZO_OUTPUT_PADDING); |
|
|
|
|
result = lzo1x_decode(pkt_data, &olen, data, &ilen); |
|
|
|
|
} while (result==LZO_OUTPUT_FULL && pkt_size<10000000); |
|
|
|
|
if (result) { |
|
|
|
|
av_free(pkt_data); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
pkt_size -= olen; |
|
|
|
|
break; |
|
|
|
|
#ifdef CONFIG_ZLIB |
|
|
|
|
case MATROSKA_TRACK_ENCODING_COMP_ZLIB: { |
|
|
|
|
z_stream zstream = {0}; |
|
|
|
|
pkt_data = NULL; |
|
|
|
|
if (inflateInit(&zstream) != Z_OK) |
|
|
|
|
continue; |
|
|
|
|
zstream.next_in = data; |
|
|
|
|
zstream.avail_in = lace_size[n]; |
|
|
|
|
do { |
|
|
|
|
pkt_size *= 3; |
|
|
|
|
pkt_data = av_realloc(pkt_data, pkt_size); |
|
|
|
|
zstream.avail_out = pkt_size - zstream.total_out; |
|
|
|
|
zstream.next_out = pkt_data + zstream.total_out; |
|
|
|
|
result = inflate(&zstream, Z_NO_FLUSH); |
|
|
|
|
} while (result==Z_OK && pkt_size<10000000); |
|
|
|
|
pkt_size = zstream.total_out; |
|
|
|
|
inflateEnd(&zstream); |
|
|
|
|
if (result != Z_STREAM_END) { |
|
|
|
|
av_free(pkt_data); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
#ifdef CONFIG_BZLIB |
|
|
|
|
case MATROSKA_TRACK_ENCODING_COMP_BZLIB: { |
|
|
|
|
bz_stream bzstream = {0}; |
|
|
|
|
pkt_data = NULL; |
|
|
|
|
if (BZ2_bzDecompressInit(&bzstream, 0, 0) != BZ_OK) |
|
|
|
|
offset = matroska_decode_buffer(&pkt_data, &pkt_size, |
|
|
|
|
matroska->tracks[track]); |
|
|
|
|
if (offset < 0) |
|
|
|
|
continue; |
|
|
|
|
bzstream.next_in = data; |
|
|
|
|
bzstream.avail_in = lace_size[n]; |
|
|
|
|
do { |
|
|
|
|
pkt_size *= 3; |
|
|
|
|
pkt_data = av_realloc(pkt_data, pkt_size); |
|
|
|
|
bzstream.avail_out = pkt_size - bzstream.total_out_lo32; |
|
|
|
|
bzstream.next_out = pkt_data + bzstream.total_out_lo32; |
|
|
|
|
result = BZ2_bzDecompress(&bzstream); |
|
|
|
|
} while (result==BZ_OK && pkt_size<10000000); |
|
|
|
|
pkt_size = bzstream.total_out_lo32; |
|
|
|
|
BZ2_bzDecompressEnd(&bzstream); |
|
|
|
|
if (result != BZ_STREAM_END) { |
|
|
|
|
av_free(pkt_data); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pkt = av_mallocz(sizeof(AVPacket)); |
|
|
|
|