[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