Merge remote-tracking branch 'qatar/master'
[ffmpeg.git] / libavcodec / mpeg4videodec.c
index cb5231a..5387064 100644 (file)
@@ -130,10 +130,11 @@ static inline int mpeg4_is_resync(MpegEncContext *s){
         v|= 0x7F >> (7-(bits_count&7));
 
         if(v==0x7F)
-            return 1;
+            return s->mb_num;
     }else{
         if(v == ff_mpeg4_resync_prefix[bits_count&7]){
-            int len;
+            int len, mb_num;
+            int mb_num_bits= av_log2(s->mb_num - 1) + 1;
             GetBitContext gb= s->gb;
 
             skip_bits(&s->gb, 1);
@@ -143,10 +144,14 @@ static inline int mpeg4_is_resync(MpegEncContext *s){
                 if(get_bits1(&s->gb)) break;
             }
 
+            mb_num= get_bits(&s->gb, mb_num_bits);
+            if(!mb_num || mb_num > s->mb_num || get_bits_count(&s->gb)+6 > s->gb.size_in_bits)
+                mb_num= -1;
+
             s->gb= gb;
 
             if(len>=ff_mpeg4_get_video_packet_prefix_length(s))
-                return 1;
+                return mb_num;
         }
     }
     return 0;
@@ -373,16 +378,6 @@ int mpeg4_decode_video_packet_header(MpegEncContext *s)
         av_log(s->avctx, AV_LOG_ERROR, "illegal mb_num in video packet (%d %d) \n", mb_num, s->mb_num);
         return -1;
     }
-    if(s->pict_type == AV_PICTURE_TYPE_B){
-        int mb_x = 0, mb_y = 0;
-
-        while (s->next_picture.f.mbskip_table[s->mb_index2xy[mb_num]]) {
-            if (!mb_x) ff_thread_await_progress((AVFrame*)s->next_picture_ptr, mb_y++, 0);
-            mb_num++;
-            if (++mb_x == s->mb_width) mb_x = 0;
-        }
-        if(mb_num >= s->mb_num) return -1; // slice contains just skipped MBs which where already decoded
-    }
 
     s->mb_x= mb_num % s->mb_width;
     s->mb_y= mb_num / s->mb_width;
@@ -1488,16 +1483,21 @@ end:
 
         /* per-MB end of slice check */
     if(s->codec_id==CODEC_ID_MPEG4){
-        if(mpeg4_is_resync(s)){
-            const int delta= s->mb_x + 1 == s->mb_width ? 2 : 1;
+        int next= mpeg4_is_resync(s);
+        if(next) {
+            if        (s->mb_x + s->mb_y*s->mb_width + 1 >  next && s->avctx->error_recognition >= FF_ER_AGGRESSIVE) {
+                return -1;
+            } else if (s->mb_x + s->mb_y*s->mb_width + 1 >= next)
+                return SLICE_END;
 
             if(s->pict_type==AV_PICTURE_TYPE_B){
+                const int delta= s->mb_x + 1 == s->mb_width ? 2 : 1;
                 ff_thread_await_progress((AVFrame*)s->next_picture_ptr,
                                         (s->mb_x + delta >= s->mb_width) ? FFMIN(s->mb_y+1, s->mb_height-1) : s->mb_y, 0);
+                if (s->next_picture.f.mbskip_table[xy + delta])
+                    return SLICE_OK;
             }
 
-            if (s->pict_type == AV_PICTURE_TYPE_B && s->next_picture.f.mbskip_table[xy + delta])
-                return SLICE_OK;
             return SLICE_END;
         }
     }
@@ -2124,7 +2124,7 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){
  */
 int ff_mpeg4_decode_picture_header(MpegEncContext * s, GetBitContext *gb)
 {
-    int startcode, v;
+    unsigned startcode, v;
 
     /* search next start code */
     align_get_bits(gb);