dest_cb-= s->linesize*7; dest_cr-= s->linesize*7;
dest_cb-= s->uvlinesize*7; dest_cr-= s->uvlinesize*7;
static void hl_decode_mb(H264Context *h){    MpegEncContext * const s = &h->s;    const int mb_x= s->mb_x;    const int mb_y= s->mb_y;    const int mb_xy= mb_x + mb_y*s->mb_stride;    const int mb_type= s->current_picture.mb_type[mb_xy];    uint8_t  *dest_y, *dest_cb, *dest_cr;    int linesize, uvlinesize /*dct_offset*/;    int i;    if(!s->decode)        return;    if(s->mb_skiped){    }    dest_y  = s->current_picture.data[0] + (mb_y * 16* s->linesize  ) + mb_x * 16;    dest_cb = s->current_picture.data[1] + (mb_y * 8 * s->uvlinesize) + mb_x * 8;    dest_cr = s->current_picture.data[2] + (mb_y * 8 * s->uvlinesize) + mb_x * 8;    if (h->mb_field_decoding_flag) {        linesize = s->linesize * 2;        uvlinesize = s->uvlinesize * 2;        if(mb_y&1){ //FIXME move out of this func?            dest_y -= s->linesize*15;            dest_cb-= s->linesize*7;            dest_cr-= s->linesize*7;        }    } else {        linesize = s->linesize;        uvlinesize = s->uvlinesize;//        dct_offset = s->linesize * 16;    }    if (IS_INTRA_PCM(mb_type)) {        unsigned int x, y;        // The pixels are stored in h->mb array in the same order as levels,        // copy them in output in the correct order.        for(i=0; i<16; i++) {            for (y=0; y<4; y++) {                for (x=0; x<4; x++) {                    *(dest_y + h->block_offset[i] + y*linesize + x) = h->mb[i*16+y*4+x];                }            }        }        for(i=16; i<16+4; i++) {            for (y=0; y<4; y++) {                for (x=0; x<4; x++) {                    *(dest_cb + h->block_offset[i] + y*uvlinesize + x) = h->mb[i*16+y*4+x];                }            }        }        for(i=20; i<20+4; i++) {            for (y=0; y<4; y++) {                for (x=0; x<4; x++) {                    *(dest_cr + h->block_offset[i] + y*uvlinesize + x) = h->mb[i*16+y*4+x];                }            }        }    } else {        if(IS_INTRA(mb_type)){            if(h->deblocking_filter)                xchg_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, 1);            if(!(s->flags&CODEC_FLAG_GRAY)){                h->pred8x8[ h->chroma_pred_mode ](dest_cb, uvlinesize);                h->pred8x8[ h->chroma_pred_mode ](dest_cr, uvlinesize);            }            if(IS_INTRA4x4(mb_type)){                if(!s->encoding){                    for(i=0; i<16; i++){                        uint8_t * const ptr= dest_y + h->block_offset[i];                        uint8_t *topright;                        const int dir= h->intra4x4_pred_mode_cache[ scan8[i] ];                        int tr;                        if(dir == DIAG_DOWN_LEFT_PRED || dir == VERT_LEFT_PRED){                            const int topright_avail= (h->topright_samples_available<<i)&0x8000;                            assert(mb_y || linesize <= h->block_offset[i]);                            if(!topright_avail){                                tr= ptr[3 - linesize]*0x01010101;                                topright= (uint8_t*) &tr;                            }else if(i==5 && h->deblocking_filter){                                tr= *(uint32_t*)h->top_border[mb_x+1];                                topright= (uint8_t*) &tr;                            }else                                topright= ptr + 4 - linesize;                        }else                            topright= NULL;                        h->pred4x4[ dir ](ptr, topright, linesize);                        if(h->non_zero_count_cache[ scan8[i] ]){                            if(s->codec_id == CODEC_ID_H264)                                s->dsp.h264_idct_add(ptr, h->mb + i*16, linesize);                            else                                svq3_add_idct_c(ptr, h->mb + i*16, linesize, s->qscale, 0);                        }                    }                }            }else{                h->pred16x16[ h->intra16x16_pred_mode ](dest_y , linesize);                if(s->codec_id == CODEC_ID_H264)                    h264_luma_dc_dequant_idct_c(h->mb, s->qscale);                else                    svq3_luma_dc_dequant_idct_c(h->mb, s->qscale);            }            if(h->deblocking_filter)                xchg_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, 0);        }else if(s->codec_id == CODEC_ID_H264){            hl_motion(h, dest_y, dest_cb, dest_cr,                      s->dsp.put_h264_qpel_pixels_tab, s->dsp.put_h264_chroma_pixels_tab,                       s->dsp.avg_h264_qpel_pixels_tab, s->dsp.avg_h264_chroma_pixels_tab,                      s->dsp.weight_h264_pixels_tab, s->dsp.biweight_h264_pixels_tab);        }        if(!IS_INTRA4x4(mb_type)){            if(s->codec_id == CODEC_ID_H264){                for(i=0; i<16; i++){                    if(h->non_zero_count_cache[ scan8[i] ] || h->mb[i*16]){ //FIXME benchmark weird rule, & below                        uint8_t * const ptr= dest_y + h->block_offset[i];                        s->dsp.h264_idct_add(ptr, h->mb + i*16, linesize);                    }                }            }else{                for(i=0; i<16; i++){                    if(h->non_zero_count_cache[ scan8[i] ] || h->mb[i*16]){ //FIXME benchmark weird rule, & below                        uint8_t * const ptr= dest_y + h->block_offset[i];                        svq3_add_idct_c(ptr, h->mb + i*16, linesize, s->qscale, IS_INTRA(mb_type) ? 1 : 0);                    }                }            }        }        if(!(s->flags&CODEC_FLAG_GRAY)){            chroma_dc_dequant_idct_c(h->mb + 16*16, h->chroma_qp);            chroma_dc_dequant_idct_c(h->mb + 16*16+4*16, h->chroma_qp);            if(s->codec_id == CODEC_ID_H264){                for(i=16; i<16+4; i++){                    if(h->non_zero_count_cache[ scan8[i] ] || h->mb[i*16]){                        uint8_t * const ptr= dest_cb + h->block_offset[i];                        s->dsp.h264_idct_add(ptr, h->mb + i*16, uvlinesize);                    }                }                for(i=20; i<20+4; i++){                    if(h->non_zero_count_cache[ scan8[i] ] || h->mb[i*16]){                        uint8_t * const ptr= dest_cr + h->block_offset[i];                        s->dsp.h264_idct_add(ptr, h->mb + i*16, uvlinesize);                    }                }            }else{                for(i=16; i<16+4; i++){                    if(h->non_zero_count_cache[ scan8[i] ] || h->mb[i*16]){                        uint8_t * const ptr= dest_cb + h->block_offset[i];                        svq3_add_idct_c(ptr, h->mb + i*16, uvlinesize, chroma_qp[s->qscale + 12] - 12, 2);                    }                }                for(i=20; i<20+4; i++){                    if(h->non_zero_count_cache[ scan8[i] ] || h->mb[i*16]){                        uint8_t * const ptr= dest_cr + h->block_offset[i];                        svq3_add_idct_c(ptr, h->mb + i*16, uvlinesize, chroma_qp[s->qscale + 12] - 12, 2);                    }                }            }        }    }    if(h->deblocking_filter) {        backup_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize);        fill_caches(h, mb_type, 1); //FIXME dont fill stuff which isnt used by filter_mb        filter_mb(h, mb_x, mb_y, dest_y, dest_cb, dest_cr);    }}