mirror of
https://github.com/xenia-project/FFmpeg.git
synced 2024-11-24 12:09:55 +00:00
h264dec: fix Lossless Decoding (Profile 244) for 8x8 Intra Prediction
CC: libav-stable@libav.org Signed-off-by: Anton Khirnov <anton@khirnov.net>
This commit is contained in:
parent
45c4bf3df0
commit
79c6477c2a
@ -636,7 +636,12 @@ static av_always_inline void hl_decode_mb_predict_luma(const H264Context *h,
|
||||
uint8_t *const ptr = dest_y + block_offset[i];
|
||||
const int dir = sl->intra4x4_pred_mode_cache[scan8[i]];
|
||||
if (transform_bypass && h->ps.sps->profile_idc == 244 && dir <= 1) {
|
||||
if (h->x264_build < 151U) {
|
||||
h->hpc.pred8x8l_add[dir](ptr, sl->mb + (i * 16 + p * 256 << pixel_shift), linesize);
|
||||
} else
|
||||
h->hpc.pred8x8l_filter_add[dir](ptr, sl->mb + (i * 16 + p * 256 << pixel_shift),
|
||||
(sl-> topleft_samples_available << i) & 0x8000,
|
||||
(sl->topright_samples_available << i) & 0x4000, linesize);
|
||||
} else {
|
||||
const int nnz = sl->non_zero_count_cache[scan8[i + p * 16]];
|
||||
h->hpc.pred8x8l[dir](ptr, (sl->topleft_samples_available << i) & 0x8000,
|
||||
|
@ -552,6 +552,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);\
|
||||
|
@ -101,6 +101,9 @@ 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);
|
||||
|
@ -1123,6 +1123,79 @@ 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];
|
||||
int stride = _stride/sizeof(pixel);
|
||||
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];
|
||||
int stride = _stride/sizeof(pixel);
|
||||
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…
Reference in New Issue
Block a user