[FFmpeg-devel] H.264 Lossless Decoding Patch (Profile 244) for 8x8 Intra Prediction

Carl Eugen Hoyos cehoyos at ag.or.at
Wed Mar 5 14:03:18 CET 2014


On Wednesday 05 March 2014 12:05:42 pm Yogender Kumar Gupta wrote:
> Please find attached the patch for fixing of 8x8 prediction for the
> lossless H.264 (profile 244) decoding. The patch adds support for the
> filtering for the 8x8 intra prediction for the lossless decoding.

I can confirm that attached patch (by Yogender) makes his sample bit-exact 
with respect to the reference decoder.

Carl Eugen
-------------- next part --------------
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index 9379b2f..8b4f0d5 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -2493,7 +2493,8 @@ static av_always_inline void hl_decode_mb_predict_luma(H264Context *h,
                 uint8_t *const ptr = dest_y + block_offset[i];
                 const int dir      = h->intra4x4_pred_mode_cache[scan8[i]];
                 if (transform_bypass && h->sps.profile_idc == 244 && dir <= 1) {
-                    h->hpc.pred8x8l_add[dir](ptr, h->mb + (i * 16 + p * 256 << pixel_shift), linesize);
+                    h->hpc.pred8x8l_add[dir](ptr, h->mb + (i * 16 + p * 256 << pixel_shift), (h->topleft_samples_available << i) & 0x8000,
+                                            (h->topright_samples_available << i) & 0x4000, linesize);
                 } else {
                     const int nnz = h->non_zero_count_cache[scan8[i + p * 16]];
                     h->hpc.pred8x8l[dir](ptr, (h->topleft_samples_available << i) & 0x8000,
diff --git a/libavcodec/h264pred.h b/libavcodec/h264pred.h
index 00af03a..a3eec6e 100644
--- a/libavcodec/h264pred.h
+++ b/libavcodec/h264pred.h
@@ -100,7 +100,7 @@ typedef struct H264PredContext {
     void(*pred4x4_add[2])(uint8_t *pix /*align  4*/,
                           int16_t *block /*align 16*/, ptrdiff_t stride);
     void(*pred8x8l_add[2])(uint8_t *pix /*align  8*/,
-                           int16_t *block /*align 16*/, ptrdiff_t stride);
+                           int16_t *block /*align 16*/, int topleft, int topright, ptrdiff_t stride);
     void(*pred8x8_add[3])(uint8_t *pix /*align  8*/,
                           const int *block_offset,
                           int16_t *block /*align 16*/, ptrdiff_t stride);
diff --git a/libavcodec/h264pred_template.c b/libavcodec/h264pred_template.c
index 8d8d62e..5454944 100644
--- a/libavcodec/h264pred_template.c
+++ b/libavcodec/h264pred_template.c
@@ -1122,15 +1122,6 @@ static void FUNCC(pred8x8l_horizontal_up)(uint8_t *_src, int has_topleft,
     SRC(5,6)=SRC(5,7)=SRC(6,4)=SRC(6,5)=SRC(6,6)=
     SRC(6,7)=SRC(7,4)=SRC(7,5)=SRC(7,6)=SRC(7,7)= l7;
 }
-#undef PREDICT_8x8_LOAD_LEFT
-#undef PREDICT_8x8_LOAD_TOP
-#undef PREDICT_8x8_LOAD_TOPLEFT
-#undef PREDICT_8x8_LOAD_TOPRIGHT
-#undef PREDICT_8x8_DC
-#undef PTR
-#undef PT
-#undef PL
-#undef SRC
 
 static void FUNCC(pred4x4_vertical_add)(uint8_t *_pix, int16_t *_block,
                                         ptrdiff_t stride)
@@ -1173,54 +1164,90 @@ static void FUNCC(pred4x4_horizontal_add)(uint8_t *_pix, int16_t *_block,
     memset(_block, 0, sizeof(dctcoef) * 16);
 }
 
-static void FUNCC(pred8x8l_vertical_add)(uint8_t *_pix, int16_t *_block,
-                                         ptrdiff_t stride)
+static void FUNCC(pred8x8l_vertical_add)(uint8_t *_src, int16_t *_block, int has_topleft,
+                                         int has_topright, ptrdiff_t stride)
 {
     int i;
-    pixel *pix = (pixel*)_pix;
+    pixel *src = (pixel*)_src;
     const dctcoef *block = (const dctcoef*)_block;
+    pixel pix[8];
+
     stride >>= sizeof(pixel)-1;
-    pix -= stride;
+
+    PREDICT_8x8_LOAD_TOP;
+
+    pix[0] = t0;
+    pix[1] = t1;
+    pix[2] = t2;
+    pix[3] = t3;
+    pix[4] = t4;
+    pix[5] = t5;
+    pix[6] = t6;
+    pix[7] = t7;
+
     for(i=0; i<8; i++){
-        pixel v = pix[0];
-        pix[1*stride]= v += block[0];
-        pix[2*stride]= v += block[8];
-        pix[3*stride]= v += block[16];
-        pix[4*stride]= v += block[24];
-        pix[5*stride]= v += block[32];
-        pix[6*stride]= v += block[40];
-        pix[7*stride]= v += block[48];
-        pix[8*stride]= v +  block[56];
-        pix++;
+        pixel v = pix[i];
+        src[0*stride]= v += block[0];
+        src[1*stride]= v += block[8];
+        src[2*stride]= v += block[16];
+        src[3*stride]= v += block[24];
+        src[4*stride]= v += block[32];
+        src[5*stride]= v += block[40];
+        src[6*stride]= v += block[48];
+        src[7*stride]= v +  block[56];
+        src++;
         block++;
     }
 
     memset(_block, 0, sizeof(dctcoef) * 64);
 }
 
-static void FUNCC(pred8x8l_horizontal_add)(uint8_t *_pix, int16_t *_block,
-                                           ptrdiff_t stride)
+static void FUNCC(pred8x8l_horizontal_add)(uint8_t *_src, int16_t *_block, int has_topleft,
+                                           int has_topright, ptrdiff_t stride)
 {
     int i;
-    pixel *pix = (pixel*)_pix;
+    pixel *src = (pixel*)_src;
     const dctcoef *block = (const dctcoef*)_block;
+    pixel pix[8];
+
     stride >>= sizeof(pixel)-1;
+
+    PREDICT_8x8_LOAD_LEFT;
+
+    pix[0] = l0;
+    pix[1] = l1;
+    pix[2] = l2;
+    pix[3] = l3;
+    pix[4] = l4;
+    pix[5] = l5;
+    pix[6] = l6;
+    pix[7] = l7;
+
     for(i=0; i<8; i++){
-        pixel v = pix[-1];
-        pix[0]= v += block[0];
-        pix[1]= v += block[1];
-        pix[2]= v += block[2];
-        pix[3]= v += block[3];
-        pix[4]= v += block[4];
-        pix[5]= v += block[5];
-        pix[6]= v += block[6];
-        pix[7]= v +  block[7];
-        pix+= stride;
+        pixel v = pix[i];
+        src[0]= v += block[0];
+        src[1]= v += block[1];
+        src[2]= v += block[2];
+        src[3]= v += block[3];
+        src[4]= v += block[4];
+        src[5]= v += block[5];
+        src[6]= v += block[6];
+        src[7]= v +  block[7];
+        src+= stride;
         block+= 8;
     }
 
     memset(_block, 0, sizeof(dctcoef) * 64);
 }
+#undef PREDICT_8x8_LOAD_LEFT
+#undef PREDICT_8x8_LOAD_TOP
+#undef PREDICT_8x8_LOAD_TOPLEFT
+#undef PREDICT_8x8_LOAD_TOPRIGHT
+#undef PREDICT_8x8_DC
+#undef PTR
+#undef PT
+#undef PL
+#undef SRC
 
 static void FUNCC(pred16x16_vertical_add)(uint8_t *pix, const int *block_offset,
                                           int16_t *block,


More information about the ffmpeg-devel mailing list