Support MBAFF + constrained intra prediction.
authorMichael Niedermayer <michaelni@gmx.at>
Mon, 11 Aug 2008 02:21:33 +0000 (02:21 +0000)
committerMichael Niedermayer <michaelni@gmx.at>
Mon, 11 Aug 2008 02:21:33 +0000 (02:21 +0000)
(no i would not have tried to implement this had i known what mess it is)
fixes at least:
CAMACI3_Sony_C

Originally committed as revision 14687 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/h264.c
libavcodec/h264pred.c
libavcodec/h264pred.h

index 619b618..b24e491 100644 (file)
@@ -217,8 +217,27 @@ static void fill_caches(H264Context *h, int mb_type, int for_deblock){
             h->top_samples_available= 0x33FF;
             h->topright_samples_available= 0x26EA;
         }
             h->top_samples_available= 0x33FF;
             h->topright_samples_available= 0x26EA;
         }
-        for(i=0; i<2; i++){
-            if(!IS_INTRA(left_type[i]) && (left_type[i]==0 || h->pps.constrained_intra_pred)){
+        if(IS_INTERLACED(mb_type) != IS_INTERLACED(left_type[0])){
+            if(IS_INTERLACED(mb_type)){
+                if(!IS_INTRA(left_type[0]) && (left_type[0]==0 || h->pps.constrained_intra_pred)){
+                    h->topleft_samples_available&= 0xDFFF;
+                    h->left_samples_available&= 0x5FFF;
+                }
+                if(!IS_INTRA(left_type[1]) && (left_type[1]==0 || h->pps.constrained_intra_pred)){
+                    h->topleft_samples_available&= 0xFF5F;
+                    h->left_samples_available&= 0xFF5F;
+                }
+            }else{
+                int left_typei = h->slice_table[left_xy[0] + s->mb_stride ] == h->slice_num
+                                ? s->current_picture.mb_type[left_xy[0] + s->mb_stride] : 0;
+                assert(left_xy[0] == left_xy[1]);
+                if(!(IS_INTRA(left_typei) && IS_INTRA(left_type[0])) && (left_typei==0 || h->pps.constrained_intra_pred)){
+                    h->topleft_samples_available&= 0xDF5F;
+                    h->left_samples_available&= 0x5F5F;
+                }
+            }
+        }else{
+            if(!IS_INTRA(left_type[0]) && (left_type[0]==0 || h->pps.constrained_intra_pred)){
                 h->topleft_samples_available&= 0xDF5F;
                 h->left_samples_available&= 0x5F5F;
             }
                 h->topleft_samples_available&= 0xDF5F;
                 h->left_samples_available&= 0x5F5F;
             }
@@ -565,8 +584,10 @@ static inline int check_intra4x4_pred_mode(H264Context *h){
         }
     }
 
         }
     }
 
-    if(!(h->left_samples_available&0x8000)){
+    if((h->left_samples_available&0x8888)!=0x8888){
+        static const int mask[4]={0x8000,0x2000,0x80,0x20};
         for(i=0; i<4; i++){
         for(i=0; i<4; i++){
+            if(!(h->left_samples_available&mask[i])){
             int status= left[ h->intra4x4_pred_mode_cache[scan8[0] + 8*i] ];
             if(status<0){
                 av_log(h->s.avctx, AV_LOG_ERROR, "left block unavailable for requested intra4x4 mode %d at %d %d\n", status, s->mb_x, s->mb_y);
             int status= left[ h->intra4x4_pred_mode_cache[scan8[0] + 8*i] ];
             if(status<0){
                 av_log(h->s.avctx, AV_LOG_ERROR, "left block unavailable for requested intra4x4 mode %d at %d %d\n", status, s->mb_x, s->mb_y);
@@ -574,6 +595,7 @@ static inline int check_intra4x4_pred_mode(H264Context *h){
             } else if(status){
                 h->intra4x4_pred_mode_cache[scan8[0] + 8*i]= status;
             }
             } else if(status){
                 h->intra4x4_pred_mode_cache[scan8[0] + 8*i]= status;
             }
+            }
         }
     }
 
         }
     }
 
@@ -601,8 +623,11 @@ static inline int check_intra_pred_mode(H264Context *h, int mode){
         }
     }
 
         }
     }
 
-    if(!(h->left_samples_available&0x8000)){
+    if((h->left_samples_available&0x8080) != 0x8080){
         mode= left[ mode ];
         mode= left[ mode ];
+        if(h->left_samples_available&0x8080){ //mad cow disease mode, aka MBAFF + constrained_intra_pred
+            mode= ALZHEIMER_DC_L0T_PRED8x8 + (!(h->left_samples_available&0x8000)) + 2*(mode == DC_128_PRED8x8);
+        }
         if(mode<0){
             av_log(h->s.avctx, AV_LOG_ERROR, "left block unavailable for requested intra mode at %d %d\n", s->mb_x, s->mb_y);
             return -1;
         if(mode<0){
             av_log(h->s.avctx, AV_LOG_ERROR, "left block unavailable for requested intra mode at %d %d\n", s->mb_x, s->mb_y);
             return -1;
index b3e84b7..0b7394a 100644 (file)
@@ -690,6 +690,29 @@ static void pred8x8_dc_c(uint8_t *src, int stride){
     }
 }
 
     }
 }
 
+//the following 4 function should not be optimized!
+static void pred8x8_mad_cow_dc_l0t(uint8_t *src, int stride){
+    pred8x8_top_dc_c(src, stride);
+    pred4x4_dc_c(src, NULL, stride);
+}
+
+static void pred8x8_mad_cow_dc_0lt(uint8_t *src, int stride){
+    pred8x8_dc_c(src, stride);
+    pred4x4_top_dc_c(src, NULL, stride);
+}
+
+static void pred8x8_mad_cow_dc_l00(uint8_t *src, int stride){
+    pred8x8_left_dc_c(src, stride);
+    pred4x4_128_dc_c(src + 4*stride    , NULL, stride);
+    pred4x4_128_dc_c(src + 4*stride + 4, NULL, stride);
+}
+
+static void pred8x8_mad_cow_dc_0l0(uint8_t *src, int stride){
+    pred8x8_left_dc_c(src, stride);
+    pred4x4_128_dc_c(src    , NULL, stride);
+    pred4x4_128_dc_c(src + 4, NULL, stride);
+}
+
 static void pred8x8_dc_rv40_c(uint8_t *src, int stride){
     int i;
     int dc0=0;
 static void pred8x8_dc_rv40_c(uint8_t *src, int stride){
     int i;
     int dc0=0;
@@ -1046,6 +1069,10 @@ void ff_h264_pred_init(H264PredContext *h, int codec_id){
         h->pred8x8[DC_PRED8x8     ]= pred8x8_dc_c;
         h->pred8x8[LEFT_DC_PRED8x8]= pred8x8_left_dc_c;
         h->pred8x8[TOP_DC_PRED8x8 ]= pred8x8_top_dc_c;
         h->pred8x8[DC_PRED8x8     ]= pred8x8_dc_c;
         h->pred8x8[LEFT_DC_PRED8x8]= pred8x8_left_dc_c;
         h->pred8x8[TOP_DC_PRED8x8 ]= pred8x8_top_dc_c;
+        h->pred8x8[ALZHEIMER_DC_L0T_PRED8x8 ]= pred8x8_mad_cow_dc_l0t;
+        h->pred8x8[ALZHEIMER_DC_0LT_PRED8x8 ]= pred8x8_mad_cow_dc_0lt;
+        h->pred8x8[ALZHEIMER_DC_L00_PRED8x8 ]= pred8x8_mad_cow_dc_l00;
+        h->pred8x8[ALZHEIMER_DC_0L0_PRED8x8 ]= pred8x8_mad_cow_dc_0l0;
     }else{
         h->pred8x8[DC_PRED8x8     ]= pred8x8_dc_rv40_c;
         h->pred8x8[LEFT_DC_PRED8x8]= pred8x8_left_dc_rv40_c;
     }else{
         h->pred8x8[DC_PRED8x8     ]= pred8x8_dc_rv40_c;
         h->pred8x8[LEFT_DC_PRED8x8]= pred8x8_left_dc_rv40_c;
index 4e3fcdf..dae0d81 100644 (file)
 #define LEFT_DC_PRED8x8       4
 #define TOP_DC_PRED8x8        5
 #define DC_128_PRED8x8        6
 #define LEFT_DC_PRED8x8       4
 #define TOP_DC_PRED8x8        5
 #define DC_128_PRED8x8        6
+
+#define ALZHEIMER_DC_L0T_PRED8x8 7
+#define ALZHEIMER_DC_0LT_PRED8x8 8
+#define ALZHEIMER_DC_L00_PRED8x8 9
+#define ALZHEIMER_DC_0L0_PRED8x8 10
 //@}
 
 /**
 //@}
 
 /**
@@ -68,7 +73,7 @@
 typedef struct H264PredContext{
     void (*pred4x4  [9+3+3])(uint8_t *src, uint8_t *topright, int stride);//FIXME move to dsp?
     void (*pred8x8l [9+3])(uint8_t *src, int topleft, int topright, int stride);
 typedef struct H264PredContext{
     void (*pred4x4  [9+3+3])(uint8_t *src, uint8_t *topright, int stride);//FIXME move to dsp?
     void (*pred8x8l [9+3])(uint8_t *src, int topleft, int topright, int stride);
-    void (*pred8x8  [4+3])(uint8_t *src, int stride);
+    void (*pred8x8  [4+3+4])(uint8_t *src, int stride);
     void (*pred16x16[4+3])(uint8_t *src, int stride);
 }H264PredContext;
 
     void (*pred16x16[4+3])(uint8_t *src, int stride);
 }H264PredContext;