Browse Source

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 <michaelni@gmx.at>
tags/n2.3
Yogender Kumar Gupta Michael Niedermayer 12 years ago
parent
commit
6f7ca1f55b
4 changed files with 87 additions and 1 deletions
  1. +6
    -1
      libavcodec/h264.c
  2. +2
    -0
      libavcodec/h264pred.c
  3. +2
    -0
      libavcodec/h264pred.h
  4. +77
    -0
      libavcodec/h264pred_template.c

+ 6
- 1
libavcodec/h264.c View File

@@ -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,


+ 2
- 0
libavcodec/h264pred.c View File

@@ -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);\


+ 2
- 0
libavcodec/h264pred.h View File

@@ -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);


+ 77
- 0
libavcodec/h264pred_template.c View File

@@ -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


Loading…
Cancel
Save