|
|
@ -119,6 +119,23 @@ static uint64_t truehd_layout(int chanmap) |
|
|
|
return layout; |
|
|
|
return layout; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int ff_mlp_get_major_sync_size(const uint8_t * buf, int bufsize) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
int has_extension, extensions = 0; |
|
|
|
|
|
|
|
int size = 28; |
|
|
|
|
|
|
|
if (bufsize < 28) |
|
|
|
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (AV_RB32(buf) == 0xf8726fba) { |
|
|
|
|
|
|
|
has_extension = buf[25] & 1; |
|
|
|
|
|
|
|
if (has_extension) { |
|
|
|
|
|
|
|
extensions = buf[26] >> 4; |
|
|
|
|
|
|
|
size += 2 + extensions * 2; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return size; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** Read a major sync info header - contains high level information about
|
|
|
|
/** Read a major sync info header - contains high level information about
|
|
|
|
* the stream - sample rate, channel arrangement etc. Most of this |
|
|
|
* the stream - sample rate, channel arrangement etc. Most of this |
|
|
|
* information is not actually necessary for decoding, only for playback. |
|
|
|
* information is not actually necessary for decoding, only for playback. |
|
|
@ -127,18 +144,19 @@ static uint64_t truehd_layout(int chanmap) |
|
|
|
|
|
|
|
|
|
|
|
int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb) |
|
|
|
int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb) |
|
|
|
{ |
|
|
|
{ |
|
|
|
int ratebits, channel_arrangement; |
|
|
|
int ratebits, channel_arrangement, header_size; |
|
|
|
uint16_t checksum; |
|
|
|
uint16_t checksum; |
|
|
|
|
|
|
|
|
|
|
|
assert(get_bits_count(gb) == 0); |
|
|
|
assert(get_bits_count(gb) == 0); |
|
|
|
|
|
|
|
|
|
|
|
if (gb->size_in_bits < 28 << 3) { |
|
|
|
header_size = ff_mlp_get_major_sync_size(gb->buffer, gb->size_in_bits >> 3); |
|
|
|
|
|
|
|
if (header_size < 0 || gb->size_in_bits < header_size << 3) { |
|
|
|
av_log(log, AV_LOG_ERROR, "packet too short, unable to read major sync\n"); |
|
|
|
av_log(log, AV_LOG_ERROR, "packet too short, unable to read major sync\n"); |
|
|
|
return -1; |
|
|
|
return -1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
checksum = ff_mlp_checksum16(gb->buffer, 26); |
|
|
|
checksum = ff_mlp_checksum16(gb->buffer, header_size - 2); |
|
|
|
if (checksum != AV_RL16(gb->buffer+26)) { |
|
|
|
if (checksum != AV_RL16(gb->buffer+header_size-2)) { |
|
|
|
av_log(log, AV_LOG_ERROR, "major sync info header checksum error\n"); |
|
|
|
av_log(log, AV_LOG_ERROR, "major sync info header checksum error\n"); |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
} |
|
|
|
} |
|
|
@ -147,6 +165,7 @@ int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb) |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
|
|
|
|
|
|
|
mh->stream_type = get_bits(gb, 8); |
|
|
|
mh->stream_type = get_bits(gb, 8); |
|
|
|
|
|
|
|
mh->header_size = header_size; |
|
|
|
|
|
|
|
|
|
|
|
if (mh->stream_type == 0xbb) { |
|
|
|
if (mh->stream_type == 0xbb) { |
|
|
|
mh->group1_bits = mlp_quants[get_bits(gb, 4)]; |
|
|
|
mh->group1_bits = mlp_quants[get_bits(gb, 4)]; |
|
|
@ -197,7 +216,7 @@ int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb) |
|
|
|
|
|
|
|
|
|
|
|
mh->num_substreams = get_bits(gb, 4); |
|
|
|
mh->num_substreams = get_bits(gb, 4); |
|
|
|
|
|
|
|
|
|
|
|
skip_bits_long(gb, 4 + 11 * 8); |
|
|
|
skip_bits_long(gb, 4 + (header_size - 17) * 8); |
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|