]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/h264_cavlc.c
x86: disable SSE functions using stack when stack is not aligned
[ffmpeg] / libavcodec / h264_cavlc.c
index d83a306a5e3a17dd01c0a270c23be2c93eae7612..6f3bcad782bf660c58c62de5ebbb31d6f0a8799f 100644 (file)
@@ -20,7 +20,7 @@
  */
 
 /**
- * @file libavcodec/h264_cavlc.c
+ * @file
  * H.264 / AVC / MPEG4 part10 cavlc bitstream decoding.
  * @author Michael Niedermayer <michaelni@gmx.at>
  */
@@ -367,7 +367,7 @@ static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, in
     MpegEncContext * const s = &h->s;
     static const int coeff_token_table_index[17]= {0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3};
     int level[16];
-    int zeros_left, coeff_num, coeff_token, total_coeff, i, j, trailing_ones, run_before;
+    int zeros_left, coeff_token, total_coeff, i, trailing_ones, run_before;
 
     //FIXME put trailing_onex into the context
 
@@ -431,8 +431,13 @@ static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, in
                     level_code= prefix + get_bits(gb, 4); //part
             }else{
                 level_code= 30 + get_bits(gb, prefix-3); //part
-                if(prefix>=16)
+                if(prefix>=16){
+                    if(prefix > 25+3){
+                        av_log(h->s.avctx, AV_LOG_ERROR, "Invalid level prefix\n");
+                        return -1;
+                    }
                     level_code += (1<<(prefix-3))-4096;
+                }
             }
 
             if(trailing_ones < 3) level_code += 2;
@@ -483,39 +488,36 @@ static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, in
             zeros_left= get_vlc2(gb, (total_zeros_vlc-1)[ total_coeff ].table, TOTAL_ZEROS_VLC_BITS, 1);
     }
 
-    coeff_num = zeros_left + total_coeff - 1;
-    j = scantable[coeff_num];
+    scantable += zeros_left + total_coeff - 1;
     if(n > 24){
-        block[j] = level[0];
-        for(i=1;i<total_coeff;i++) {
-            if(zeros_left <= 0)
-                run_before = 0;
-            else if(zeros_left < 7){
+        block[*scantable] = level[0];
+        for(i=1;i<total_coeff && zeros_left > 0;i++) {
+            if(zeros_left < 7)
                 run_before= get_vlc2(gb, (run_vlc-1)[zeros_left].table, RUN_VLC_BITS, 1);
-            }else{
+            else
                 run_before= get_vlc2(gb, run7_vlc.table, RUN7_VLC_BITS, 2);
-            }
             zeros_left -= run_before;
-            coeff_num -= 1 + run_before;
-            j= scantable[ coeff_num ];
-
-            block[j]= level[i];
+            scantable -= 1 + run_before;
+            block[*scantable]= level[i];
+        }
+        for(;i<total_coeff;i++) {
+            scantable--;
+            block[*scantable]= level[i];
         }
     }else{
-        block[j] = (level[0] * qmul[j] + 32)>>6;
-        for(i=1;i<total_coeff;i++) {
-            if(zeros_left <= 0)
-                run_before = 0;
-            else if(zeros_left < 7){
+        block[*scantable] = (level[0] * qmul[*scantable] + 32)>>6;
+        for(i=1;i<total_coeff && zeros_left > 0;i++) {
+            if(zeros_left < 7)
                 run_before= get_vlc2(gb, (run_vlc-1)[zeros_left].table, RUN_VLC_BITS, 1);
-            }else{
+            else
                 run_before= get_vlc2(gb, run7_vlc.table, RUN7_VLC_BITS, 2);
-            }
             zeros_left -= run_before;
-            coeff_num -= 1 + run_before;
-            j= scantable[ coeff_num ];
-
-            block[j]= (level[i] * qmul[j] + 32)>>6;
+            scantable -= 1 + run_before;
+            block[*scantable]= (level[i] * qmul[*scantable] + 32)>>6;
+        }
+        for(;i<total_coeff;i++) {
+            scantable--;
+            block[*scantable]= (level[i] * qmul[*scantable] + 32)>>6;
         }
     }
 
@@ -789,22 +791,18 @@ decode_intra_mb:
                                 return -1;
                             }
                         }
-                    }else
-                        val= LIST_NOT_USED&0xFF;
                     fill_rectangle(&h->ref_cache[list][ scan8[0] ], 4, 4, 8, val, 1);
+                    }
             }
             for(list=0; list<h->list_count; list++){
-                unsigned int val;
                 if(IS_DIR(mb_type, 0, list)){
                     pred_motion(h, 0, 4, list, h->ref_cache[list][ scan8[0] ], &mx, &my);
                     mx += get_se_golomb(&s->gb);
                     my += get_se_golomb(&s->gb);
                     tprintf(s->avctx, "final mv:%d %d\n", mx, my);
 
-                    val= pack16to32(mx,my);
-                }else
-                    val=0;
-                fill_rectangle(h->mv_cache[list][ scan8[0] ], 4, 4, 8, val, 4);
+                    fill_rectangle(h->mv_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx,my), 4);
+                }
             }
         }
         else if(IS_16X8(mb_type)){