+ if(chroma444){
+ if(deblock_topleft){
+ XCHG(top_border_m1 + (24 << pixel_shift), src_cb - (7 << pixel_shift), 1);
+ XCHG(top_border_m1 + (40 << pixel_shift), src_cr - (7 << pixel_shift), 1);
+ }
+ XCHG(top_border + (16 << pixel_shift), src_cb + (1 << pixel_shift), xchg);
+ XCHG(top_border + (24 << pixel_shift), src_cb + (9 << pixel_shift), 1);
+ XCHG(top_border + (32 << pixel_shift), src_cr + (1 << pixel_shift), xchg);
+ XCHG(top_border + (40 << pixel_shift), src_cr + (9 << pixel_shift), 1);
+ if(s->mb_x+1 < s->mb_width){
+ XCHG(h->top_borders[top_idx][s->mb_x+1] + (16 << pixel_shift), src_cb + (17 << pixel_shift), 1);
+ XCHG(h->top_borders[top_idx][s->mb_x+1] + (32 << pixel_shift), src_cr + (17 << pixel_shift), 1);
+ }
+ } else {
+ if(deblock_top){
+ if(deblock_topleft){
+ XCHG(top_border_m1 + (16 << pixel_shift), src_cb - (7 << pixel_shift), 1);
+ XCHG(top_border_m1 + (24 << pixel_shift), src_cr - (7 << pixel_shift), 1);
+ }
+ XCHG(top_border + (16 << pixel_shift), src_cb+1+pixel_shift, 1);
+ XCHG(top_border + (24 << pixel_shift), src_cr+1+pixel_shift, 1);
+ }
+ }
+ }
+}
+
+static av_always_inline int dctcoef_get(DCTELEM *mb, int high_bit_depth, int index) {
+ if (high_bit_depth) {
+ return AV_RN32A(((int32_t*)mb) + index);
+ } else
+ return AV_RN16A(mb + index);
+}
+
+static av_always_inline void dctcoef_set(DCTELEM *mb, int high_bit_depth, int index, int value) {
+ if (high_bit_depth) {
+ AV_WN32A(((int32_t*)mb) + index, value);
+ } else
+ AV_WN16A(mb + index, value);
+}
+
+static av_always_inline void hl_decode_mb_predict_luma(H264Context *h, int mb_type, int is_h264, int simple, int transform_bypass,
+ int pixel_shift, int *block_offset, int linesize, uint8_t *dest_y, int p)
+{
+ MpegEncContext * const s = &h->s;
+ void (*idct_add)(uint8_t *dst, DCTELEM *block, int stride);
+ void (*idct_dc_add)(uint8_t *dst, DCTELEM *block, int stride);
+ int i;
+ int qscale = p == 0 ? s->qscale : h->chroma_qp[p-1];
+ block_offset += 16*p;
+ if(IS_INTRA4x4(mb_type)){
+ if(simple || !s->encoding){
+ if(IS_8x8DCT(mb_type)){
+ if(transform_bypass){
+ idct_dc_add =
+ idct_add = s->dsp.add_pixels8;
+ }else{
+ idct_dc_add = h->h264dsp.h264_idct8_dc_add;
+ idct_add = h->h264dsp.h264_idct8_add;
+ }
+ for(i=0; i<16; i+=4){
+ 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);
+ }else{
+ const int nnz = h->non_zero_count_cache[ scan8[i+p*16] ];
+ h->hpc.pred8x8l[ dir ](ptr, (h->topleft_samples_available<<i)&0x8000,
+ (h->topright_samples_available<<i)&0x4000, linesize);
+ if(nnz){
+ if(nnz == 1 && dctcoef_get(h->mb, pixel_shift, i*16+p*256))
+ idct_dc_add(ptr, h->mb + (i*16+p*256 << pixel_shift), linesize);
+ else
+ idct_add (ptr, h->mb + (i*16+p*256 << pixel_shift), linesize);
+ }
+ }
+ }
+ }else{
+ if(transform_bypass){
+ idct_dc_add =
+ idct_add = s->dsp.add_pixels4;
+ }else{
+ idct_dc_add = h->h264dsp.h264_idct_dc_add;
+ idct_add = h->h264dsp.h264_idct_add;
+ }
+ for(i=0; i<16; i++){
+ 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.pred4x4_add[dir](ptr, h->mb + (i*16+p*256 << pixel_shift), linesize);
+ }else{
+ uint8_t *topright;
+ int nnz, tr;
+ uint64_t tr_high;
+ if(dir == DIAG_DOWN_LEFT_PRED || dir == VERT_LEFT_PRED){
+ const int topright_avail= (h->topright_samples_available<<i)&0x8000;
+ assert(s->mb_y || linesize <= block_offset[i]);
+ if(!topright_avail){
+ if (pixel_shift) {
+ tr_high= ((uint16_t*)ptr)[3 - linesize/2]*0x0001000100010001ULL;
+ topright= (uint8_t*) &tr_high;
+ } else {
+ tr= ptr[3 - linesize]*0x01010101;
+ topright= (uint8_t*) &tr;
+ }
+ }else
+ topright= ptr + (4 << pixel_shift) - linesize;
+ }else
+ topright= NULL;
+
+ h->hpc.pred4x4[ dir ](ptr, topright, linesize);
+ nnz = h->non_zero_count_cache[ scan8[i+p*16] ];
+ if(nnz){
+ if(is_h264){
+ if(nnz == 1 && dctcoef_get(h->mb, pixel_shift, i*16+p*256))
+ idct_dc_add(ptr, h->mb + (i*16+p*256 << pixel_shift), linesize);
+ else
+ idct_add (ptr, h->mb + (i*16+p*256 << pixel_shift), linesize);
+ }else
+ ff_svq3_add_idct_c(ptr, h->mb + i*16+p*256, linesize, qscale, 0);
+ }
+ }
+ }
+ }
+ }
+ }else{
+ h->hpc.pred16x16[ h->intra16x16_pred_mode ](dest_y , linesize);
+ if(is_h264){
+ if(h->non_zero_count_cache[ scan8[LUMA_DC_BLOCK_INDEX+p] ]){
+ if(!transform_bypass)
+ h->h264dsp.h264_luma_dc_dequant_idct(h->mb+(p*256 << pixel_shift), h->mb_luma_dc[p], h->dequant4_coeff[p][qscale][0]);
+ else{
+ static const uint8_t dc_mapping[16] = { 0*16, 1*16, 4*16, 5*16, 2*16, 3*16, 6*16, 7*16,
+ 8*16, 9*16,12*16,13*16,10*16,11*16,14*16,15*16};
+ for(i = 0; i < 16; i++)
+ dctcoef_set(h->mb+p*256, pixel_shift, dc_mapping[i], dctcoef_get(h->mb_luma_dc[p], pixel_shift, i));
+ }
+ }
+ }else
+ ff_svq3_luma_dc_dequant_idct_c(h->mb+p*256, h->mb_luma_dc[p], qscale);
+ }
+}
+
+static av_always_inline void hl_decode_mb_idct_luma(H264Context *h, int mb_type, int is_h264, int simple, int transform_bypass,
+ int pixel_shift, int *block_offset, int linesize, uint8_t *dest_y, int p)
+{
+ MpegEncContext * const s = &h->s;
+ void (*idct_add)(uint8_t *dst, DCTELEM *block, int stride);
+ int i;
+ block_offset += 16*p;
+ if(!IS_INTRA4x4(mb_type)){
+ if(is_h264){
+ if(IS_INTRA16x16(mb_type)){
+ if(transform_bypass){
+ if(h->sps.profile_idc==244 && (h->intra16x16_pred_mode==VERT_PRED8x8 || h->intra16x16_pred_mode==HOR_PRED8x8)){
+ h->hpc.pred16x16_add[h->intra16x16_pred_mode](dest_y, block_offset, h->mb + (p*256 << pixel_shift), linesize);
+ }else{
+ for(i=0; i<16; i++){
+ if(h->non_zero_count_cache[ scan8[i+p*16] ] || dctcoef_get(h->mb, pixel_shift, i*16+p*256))
+ s->dsp.add_pixels4(dest_y + block_offset[i], h->mb + (i*16+p*256 << pixel_shift), linesize);
+ }
+ }
+ }else{
+ h->h264dsp.h264_idct_add16intra(dest_y, block_offset, h->mb + (p*256 << pixel_shift), linesize, h->non_zero_count_cache+p*5*8);
+ }
+ }else if(h->cbp&15){
+ if(transform_bypass){
+ const int di = IS_8x8DCT(mb_type) ? 4 : 1;
+ idct_add= IS_8x8DCT(mb_type) ? s->dsp.add_pixels8 : s->dsp.add_pixels4;
+ for(i=0; i<16; i+=di){
+ if(h->non_zero_count_cache[ scan8[i+p*16] ]){
+ idct_add(dest_y + block_offset[i], h->mb + (i*16+p*256 << pixel_shift), linesize);
+ }
+ }
+ }else{
+ if(IS_8x8DCT(mb_type)){
+ h->h264dsp.h264_idct8_add4(dest_y, block_offset, h->mb + (p*256 << pixel_shift), linesize, h->non_zero_count_cache+p*5*8);
+ }else{
+ h->h264dsp.h264_idct_add16(dest_y, block_offset, h->mb + (p*256 << pixel_shift), linesize, h->non_zero_count_cache+p*5*8);
+ }
+ }
+ }
+ }else{
+ for(i=0; i<16; i++){
+ if(h->non_zero_count_cache[ scan8[i+p*16] ] || h->mb[i*16+p*256]){ //FIXME benchmark weird rule, & below
+ uint8_t * const ptr= dest_y + block_offset[i];
+ ff_svq3_add_idct_c(ptr, h->mb + i*16 + p*256, linesize, s->qscale, IS_INTRA(mb_type) ? 1 : 0);
+ }