From 6f7ca1f55be1270e0d7c33409de4473e4dd00add Mon Sep 17 00:00:00 2001 From: Yogender Kumar Gupta Date: Tue, 18 Mar 2014 16:01:15 +0530 Subject: [PATCH] avcodec/h264: fix Lossless Decoding (Profile 244) for 8x8 Intra Prediction This is limited to the case where x264_build = -1, to not break x264 decoding Signed-off-by: Michael Niedermayer --- libavcodec/h264.c | 7 +++- libavcodec/h264pred.c | 2 + libavcodec/h264pred.h | 2 + libavcodec/h264pred_template.c | 77 ++++++++++++++++++++++++++++++++++ 4 files changed, 87 insertions(+), 1 deletion(-) diff --git a/libavcodec/h264.c b/libavcodec/h264.c index d919363c66..eeb867332c 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -2486,7 +2486,12 @@ 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); + if (h->x264_build != -1) { + h->hpc.pred8x8l_add[dir](ptr, h->mb + (i * 16 + p * 256 << pixel_shift), linesize); + } else + h->hpc.pred8x8l_filter_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.c b/libavcodec/h264pred.c index 3fc3bc76e3..49a19da4d4 100644 --- a/libavcodec/h264pred.c +++ b/libavcodec/h264pred.c @@ -558,6 +558,8 @@ av_cold void ff_h264_pred_init(H264PredContext *h, int codec_id, h->pred4x4_add [ HOR_PRED ]= FUNCC(pred4x4_horizontal_add , depth);\ h->pred8x8l_add [VERT_PRED ]= FUNCC(pred8x8l_vertical_add , depth);\ h->pred8x8l_add [ HOR_PRED ]= FUNCC(pred8x8l_horizontal_add , depth);\ + h->pred8x8l_filter_add [VERT_PRED ]= FUNCC(pred8x8l_vertical_filter_add , depth);\ + h->pred8x8l_filter_add [ HOR_PRED ]= FUNCC(pred8x8l_horizontal_filter_add , depth);\ if (chroma_format_idc <= 1) {\ h->pred8x8_add [VERT_PRED8x8]= FUNCC(pred8x8_vertical_add , depth);\ h->pred8x8_add [ HOR_PRED8x8]= FUNCC(pred8x8_horizontal_add , depth);\ diff --git a/libavcodec/h264pred.h b/libavcodec/h264pred.h index 00af03a568..6708292048 100644 --- a/libavcodec/h264pred.h +++ b/libavcodec/h264pred.h @@ -101,6 +101,8 @@ typedef struct H264PredContext { 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); + void(*pred8x8l_filter_add[2])(uint8_t *pix /*align 8*/, + 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 fd1515b36d..3d67dd40ae 100644 --- a/libavcodec/h264pred_template.c +++ b/libavcodec/h264pred_template.c @@ -1124,6 +1124,83 @@ 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; } + +static void FUNCC(pred8x8l_vertical_filter_add)(uint8_t *_src, int16_t *_block, int has_topleft, + int has_topright, ptrdiff_t stride) +{ + int i; + pixel *src = (pixel*)_src; + const dctcoef *block = (const dctcoef*)_block; + pixel pix[8]; + + stride >>= sizeof(pixel)-1; + + 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[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_filter_add)(uint8_t *_src, int16_t *_block, int has_topleft, + int has_topright, ptrdiff_t stride) +{ + int i; + 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[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