Commit 4fc0c1d8 authored by François Cartegnie's avatar François Cartegnie 🤞

packetizer: flac: do better fallback on invalid values (fix #15740)

parent 885932e3
......@@ -88,7 +88,7 @@ struct decoder_sys_t
mtime_t i_firstframepts;
mtime_t i_duration;
int i_frame_length;
unsigned int i_frame_length;
size_t i_frame_size;
uint16_t crc;
unsigned int i_rate, i_channels, i_bits_per_sample;
......@@ -346,14 +346,17 @@ static uint16_t flac_crc16_undo(uint16_t crc, const uint8_t last_byte)
/*****************************************************************************
* SyncInfo: parse FLAC sync info
*****************************************************************************/
/* Returns: 1 on success, 0 on failure, and -1 if could be incorrect */
static int SyncInfo(decoder_t *p_dec, uint8_t *p_buf,
unsigned int * pi_channels,
unsigned int * pi_sample_rate,
unsigned int * pi_bits_per_sample,
mtime_t * pi_pts,
mtime_t * pi_duration )
mtime_t * pi_duration,
unsigned int *pi_frame_length )
{
decoder_sys_t *p_sys = p_dec->p_sys;
bool b_guessing = false;
/* Check syncword */
if (p_buf[0] != 0xFF || (p_buf[1] & 0xFE) != 0xF8)
......@@ -369,6 +372,7 @@ static int SyncInfo(decoder_t *p_dec, uint8_t *p_buf,
if (blocksize >= 8) {
blocksize = 256 << (blocksize - 8);
} else if (blocksize == 0) { /* value 0 is reserved */
b_guessing = true;
if (p_sys->b_stream_info &&
p_sys->stream_info.min_blocksize == p_sys->stream_info.max_blocksize)
blocksize = p_sys->stream_info.min_blocksize;
......@@ -513,7 +517,10 @@ static int SyncInfo(decoder_t *p_dec, uint8_t *p_buf,
*pi_sample_rate = samplerate;
*pi_channels = channels;
return blocksize;
if( pi_frame_length )
*pi_frame_length = blocksize;
return b_guessing ? -1 : 1;
}
/* */
......@@ -590,13 +597,13 @@ static block_t *Packetize(decoder_t *p_dec, block_t **pp_block)
return NULL; /* Need more data */
/* Check if frame is valid and get frame info */
p_sys->i_frame_length = SyncInfo(p_dec, p_header,
&p_sys->i_channels,
int i_ret = SyncInfo(p_dec, p_header, &p_sys->i_channels,
&p_sys->i_rate,
&p_sys->i_bits_per_sample,
&p_sys->i_pts,
&p_sys->i_duration );
if (!p_sys->i_frame_length) {
&p_sys->i_duration,
&p_sys->i_frame_length );
if (!i_ret) {
msg_Dbg(p_dec, "emulated sync word");
block_SkipByte(&p_sys->bytestream);
p_sys->i_state = STATE_NOSYNC;
......@@ -641,14 +648,13 @@ static block_t *Packetize(decoder_t *p_dec, block_t **pp_block)
p_header, MAX_FLAC_HEADER_SIZE)) {
if (p_header[0] == 0xFF && (p_header[1] & 0xFE) == 0xF8) {
/* Check if frame is valid and get frame info */
int i_frame_length =
SyncInfo(p_dec, p_header,
int i_ret = SyncInfo(p_dec, p_header,
&p_sys->i_channels,
&p_sys->i_rate,
&p_sys->i_bits_per_sample,
NULL, NULL );
NULL, NULL, NULL );
if (i_frame_length) {
if (i_ret) {
uint8_t crc_bytes[2];
block_PeekOffsetBytes(&p_sys->bytestream,
p_sys->i_frame_size - 2, crc_bytes, 2);
......@@ -657,11 +663,15 @@ static block_t *Packetize(decoder_t *p_dec, block_t **pp_block)
/* Calculate the frame CRC: remove the last 2 bytes */
uint16_t crc = flac_crc16_undo(p_sys->crc, crc_bytes[1]);
crc = flac_crc16_undo(crc, crc_bytes[0]);
if (stream_crc != crc) {
msg_Warn(p_dec, "Bad CRC for frame size %zu: 0x%x != 0x%x",
p_sys->i_frame_size, crc, stream_crc);
block_SkipByte(&p_sys->bytestream);
p_sys->i_state = STATE_NOSYNC;
if (stream_crc != crc)
{
if(i_ret > 0)
{
msg_Warn(p_dec, "Bad CRC for frame size %zu: 0x%x != 0x%x",
p_sys->i_frame_size, crc, stream_crc);
block_SkipByte(&p_sys->bytestream);
p_sys->i_state = STATE_NOSYNC;
}
} else {
p_sys->i_state = STATE_SEND_DATA;
p_sys->crc = 0;
......
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