[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