[FFmpeg-devel] [PATCH] fix H.264 crash (issue 706)

Reimar Döffinger Reimar.Doeffinger
Thu Apr 9 21:51:56 CEST 2009


On Thu, Apr 09, 2009 at 09:03:31PM +0200, Michael Niedermayer wrote:
> On Thu, Apr 09, 2009 at 07:46:19PM +0200, Reimar D?ffinger wrote:
> > Index: libavcodec/error_resilience.c
> > ===================================================================
> > --- libavcodec/error_resilience.c	(revision 18389)
> > +++ libavcodec/error_resilience.c	(working copy)
> > @@ -343,6 +343,7 @@
> >  
> >                  if(IS_INTRA(s->current_picture.mb_type[mb_xy]))  continue;
> >                  if(!(s->error_status_table[mb_xy]&MV_ERROR)) continue;
> > +                if(!s->last_picture.data[0]) continue;
> >  
> >                  s->mv_dir = MV_DIR_FORWARD;
> >                  s->mb_intra=0;
> 
> this should use MV_DIR_BACKWARD i suspect instead of skiping it completely

Do I need to flip the sign of the mvs or is that correct as-is (well, in
one of those cases those mvs are 0 anyway).

> > @@ -908,8 +910,11 @@
> >                  if(IS_INTRA(mb_type)) continue;
> >                  if(!(error&MV_ERROR)) continue;           //inter with undamaged MV
> >                  if(!(error&AC_ERROR)) continue;           //undamaged inter
> > +                if(!s->last_picture.data[0] && !s->next_picture.data[0]) continue;
> 
> that should not happen, i mean mb_typeshould be intra if there are no reference
> frames

Not sure, did you meant even currently mb_type will be intra if no
reference frames are available? I can't really see that, so I assumed
you want me to change this...
-------------- next part --------------
Index: libavcodec/error_resilience.c
===================================================================
--- libavcodec/error_resilience.c	(revision 18389)
+++ libavcodec/error_resilience.c	(working copy)
@@ -344,7 +344,7 @@
                 if(IS_INTRA(s->current_picture.mb_type[mb_xy]))  continue;
                 if(!(s->error_status_table[mb_xy]&MV_ERROR)) continue;
 
-                s->mv_dir = MV_DIR_FORWARD;
+                s->mv_dir = s->last_picture.data[0] ? MV_DIR_FORWARD : MV_DIR_BACKWARD;
                 s->mb_intra=0;
                 s->mv_type = MV_TYPE_16X16;
                 s->mb_skipped=0;
@@ -850,6 +850,12 @@
     /* set unknown mb-type to most likely */
     for(i=0; i<s->mb_num; i++){
         const int mb_xy= s->mb_index2xy[i];
+        // change inter with no references to intra
+        if (!IS_INTRA(s->current_picture.mb_type[mb_xy]) &&
+            !s->last_picture.data[0] && !s->next_picture.data[0]) {
+            s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA4x4;
+            continue;
+        }
         error= s->error_status_table[mb_xy];
         if(!((error&DC_ERROR) && (error&MV_ERROR)))
             continue;
@@ -871,7 +877,7 @@
             if(error&MV_ERROR) continue;              //inter with damaged MV
             if(!(error&AC_ERROR)) continue;           //undamaged inter
 
-            s->mv_dir = MV_DIR_FORWARD;
+            s->mv_dir = s->last_picture.data[0] ? MV_DIR_FORWARD : MV_DIR_BACKWARD;
             s->mb_intra=0;
             s->mb_skipped=0;
             if(IS_8X8(mb_type)){
@@ -910,6 +916,8 @@
                 if(!(error&AC_ERROR)) continue;           //undamaged inter
 
                 s->mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD;
+                if(!s->last_picture.data[0]) s->mv_dir &= ~MV_DIR_FORWARD;
+                if(!s->next_picture.data[0]) s->mv_dir &= ~MV_DIR_BACKWARD;
                 s->mb_intra=0;
                 s->mv_type = MV_TYPE_16X16;
                 s->mb_skipped=0;



More information about the ffmpeg-devel mailing list