[vlc-commits] packetizer: flac: do better fallback on invalid values (fix #15740)
Francois Cartegnie
git at videolan.org
Thu Dec 3 22:39:15 CET 2015
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Thu Dec 3 22:37:16 2015 +0100| [4fc0c1d860a999bf447937948a0c39acbc3918f7] | committer: Francois Cartegnie
packetizer: flac: do better fallback on invalid values (fix #15740)
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=4fc0c1d860a999bf447937948a0c39acbc3918f7
---
modules/packetizer/flac.c | 42 ++++++++++++++++++++++++++----------------
1 file changed, 26 insertions(+), 16 deletions(-)
diff --git a/modules/packetizer/flac.c b/modules/packetizer/flac.c
index f59a1d2..c2c9f32 100644
--- a/modules/packetizer/flac.c
+++ b/modules/packetizer/flac.c
@@ -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;
More information about the vlc-commits
mailing list