changeset 4204:672724df5c9a libavcodec

making decoding more error robust
author michael
date Tue, 14 Nov 2006 22:06:28 +0000
parents 14250f6ff483
children 8c28f03cfdd5
files mpegaudiodec.c
diffstat 1 files changed, 19 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/mpegaudiodec.c	Tue Nov 14 20:39:20 2006 +0000
+++ b/mpegaudiodec.c	Tue Nov 14 22:06:28 2006 +0000
@@ -1748,8 +1748,7 @@
     bits_left = end_pos - get_bits_count(&s->gb);
 //av_log(NULL, AV_LOG_ERROR, "left:%d buf:%p\n", bits_left, s->in_gb.buffer);
     if (bits_left < 0) {
-        dprintf("bits_left=%d\n", bits_left);
-        return -1;
+        av_log(NULL, AV_LOG_ERROR, "bits_left=%d\n", bits_left);
     }
     skip_bits_long(&s->gb, bits_left);
 
@@ -2274,20 +2273,28 @@
     /* now we get bits from the main_data_begin offset */
     dprintf("seekback: %d\n", main_data_begin);
 //av_log(NULL, AV_LOG_ERROR, "backstep:%d, lastbuf:%d\n", main_data_begin, s->last_buf_size);
-    if(main_data_begin > s->last_buf_size){
-        av_log(NULL, AV_LOG_ERROR, "backstep:%d, lastbuf:%d\n", main_data_begin, s->last_buf_size);
-//        s->last_buf_size= main_data_begin;
-        return -1;
-      }
 
     memcpy(s->last_buf + s->last_buf_size, ptr, EXTRABYTES);
     s->in_gb= s->gb;
-    init_get_bits(&s->gb, s->last_buf + s->last_buf_size - main_data_begin, main_data_begin*8);
+        init_get_bits(&s->gb, s->last_buf, s->last_buf_size*8);
+        skip_bits_long(&s->gb, 8*(s->last_buf_size - main_data_begin));
   }
 
     for(gr=0;gr<nb_granules;gr++) {
         for(ch=0;ch<s->nb_channels;ch++) {
             g = &granules[ch][gr];
+            if(get_bits_count(&s->gb)<0){
+                av_log(NULL, AV_LOG_ERROR, "mdb:%d, lastbuf:%d skiping granule %d\n",
+                                            main_data_begin, s->last_buf_size, gr);
+                skip_bits_long(&s->gb, g->part2_3_length);
+                memset(g->sb_hybrid, 0, sizeof(g->sb_hybrid));
+                if(get_bits_count(&s->gb) >= s->gb.size_in_bits && s->in_gb.buffer){
+                    skip_bits_long(&s->in_gb, get_bits_count(&s->gb) - s->gb.size_in_bits);
+                    s->gb= s->in_gb;
+                    s->in_gb.buffer=NULL;
+                }
+                continue;
+            }
 
             bits_pos = get_bits_count(&s->gb);
 
@@ -2418,9 +2425,7 @@
             exponents_from_scale_factors(s, g, exponents);
 
             /* read Huffman coded residue */
-            if (huffman_decode(s, g, exponents,
-                               bits_pos + g->part2_3_length) < 0)
-                return -1;
+            huffman_decode(s, g, exponents, bits_pos + g->part2_3_length);
 #if defined(DEBUG)
             sample_dump(0, g->sb_hybrid, 576);
 #endif
@@ -2446,6 +2451,8 @@
 #endif
         }
     } /* gr */
+    if(get_bits_count(&s->gb)<0)
+        skip_bits_long(&s->gb, -get_bits_count(&s->gb));
     return nb_granules * 18;
 }
 
@@ -2483,6 +2490,7 @@
             }else
                 av_log(NULL, AV_LOG_ERROR, "invalid old backstep %d\n", i);
             s->gb= s->in_gb;
+            s->in_gb.buffer= NULL;
         }
 
         align_get_bits(&s->gb);