diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/f263/Picture.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/f263/Picture.cpp')
-rw-r--r-- | Src/f263/Picture.cpp | 870 |
1 files changed, 870 insertions, 0 deletions
diff --git a/Src/f263/Picture.cpp b/Src/f263/Picture.cpp new file mode 100644 index 00000000..b9ed185e --- /dev/null +++ b/Src/f263/Picture.cpp @@ -0,0 +1,870 @@ +#include "Decoder.h" +#define sign(a) ((a) < 0 ? -1 : 1) +/* private prototypes*/ +static int motion_decode(int vec,int pmv); +static void make_edge_image(const unsigned char *src, unsigned char *dst, int width, int height, int edge); + +/* decode one frame or field picture */ + +void Decoder::getpicture(Frame decodedFrame) +{ + int i; + unsigned char *tmp; + + for (i=0; i<3; i++) + { + tmp = oldrefframe[i]; + oldrefframe[i] = refframe[i]; + refframe[i] = tmp; + newframe[i] = refframe[i]; + } + + if (!firstFrame) + { + make_edge_image(oldrefframe[0],edgeframe[0],coded_picture_width, + coded_picture_height,32); + make_edge_image(oldrefframe[1],edgeframe[1],chrom_width, chrom_height,16); + make_edge_image(oldrefframe[2],edgeframe[2],chrom_width, chrom_height,16); + } + + //getMBs(); + get_I_P_MBs(); + + if (deblock) + edge_filter(newframe[0], newframe[1], newframe[2], + coded_picture_width, coded_picture_height); + + /* + PostFilter(newframe[0], newframe[1], newframe[2], + coded_picture_width, coded_picture_height); + */ + + decodedFrame[0] = newframe[0]; + decodedFrame[1] = newframe[1]; + decodedFrame[2] = newframe[2]; + + firstFrame=false; +} + + +/* decode all macroblocks of the current picture */ + + +void Decoder::clearblock(int comp) +{ + int *bp; + int i; + + bp = (int *)block[comp]; + + for (i=0; i<8; i++) + { + bp[0] = bp[1] = bp[2] = bp[3] = 0; + bp += 4; + } +} + + +/* move/add 8x8-Block from block[comp] to refframe or bframe */ + +void Decoder::addblock(int comp, int bx, int by, int addflag) +{ + int cc,i, iincr; + unsigned char *rfp; + short *bp; + + bp = block[comp]; + + /* TODO: benski> +ippiCopy8x8_8u_C1R (addflag = 0) +ippiAdd8x8_16s8u_C1IRS (addflag = 1) + */ + cc = (comp<4) ? 0 : (comp&1)+1; /* color component index */ + + if (cc==0) + { + /* luminance */ + + /* frame DCT coding */ + rfp = newframe[0] + + coded_picture_width*(by+((comp&2)<<2)) + bx + ((comp&1)<<3); + + iincr = coded_picture_width; + } + else + { + /* chrominance */ + + /* scale coordinates */ + bx >>= 1; + by >>= 1; + /* frame DCT coding */ + rfp = newframe[cc] + chrom_width*by + bx; + iincr = chrom_width; + } + + + if (addflag) + { + for (i=0; i<8; i++) + { + rfp[0] = clp[bp[0]+rfp[0]]; + rfp[1] = clp[bp[1]+rfp[1]]; + rfp[2] = clp[bp[2]+rfp[2]]; + rfp[3] = clp[bp[3]+rfp[3]]; + rfp[4] = clp[bp[4]+rfp[4]]; + rfp[5] = clp[bp[5]+rfp[5]]; + rfp[6] = clp[bp[6]+rfp[6]]; + rfp[7] = clp[bp[7]+rfp[7]]; + bp += 8; + rfp+= iincr; + } + } + else + { + for (i=0; i<8; i++) + { + rfp[0] = clp[bp[0]]; + rfp[1] = clp[bp[1]]; + rfp[2] = clp[bp[2]]; + rfp[3] = clp[bp[3]]; + rfp[4] = clp[bp[4]]; + rfp[5] = clp[bp[5]]; + rfp[6] = clp[bp[6]]; + rfp[7] = clp[bp[7]]; + bp += 8; + rfp += iincr; + } + } +} + + +int motion_decode(int vec, int pmv) +{ + if (vec > 31) vec -= 64; + vec += pmv; + + if (vec > 31) + vec -= 64; + if (vec < -32) + vec += 64; + + return vec; +} + + +int Decoder::find_pmv(int x, int y, int block, int comp) + +{ + int p1,p2,p3; + int xin1,xin2,xin3; + int yin1,yin2,yin3; + int vec1,vec2,vec3; + int l8,o8,or8; + + x++;y++; + + l8 = (modemap[y][x-1] == MODE_INTER4V ? 1 : 0); + o8 = (modemap[y-1][x] == MODE_INTER4V ? 1 : 0); + or8 = (modemap[y-1][x+1] == MODE_INTER4V ? 1 : 0); + + switch (block) + { + case 0: + vec1 = (l8 ? 2 : 0) ; yin1 = y ; xin1 = x-1; + vec2 = (o8 ? 3 : 0) ; yin2 = y-1; xin2 = x; + vec3 = (or8? 3 : 0) ; yin3 = y-1; xin3 = x+1; + break; + case 1: + vec1 = (l8 ? 2 : 0) ; yin1 = y ; xin1 = x-1; + vec2 = (o8 ? 3 : 0) ; yin2 = y-1; xin2 = x; + vec3 = (or8? 3 : 0) ; yin3 = y-1; xin3 = x+1; + break; + case 2: + vec1 = 1 ; yin1 = y ; xin1 = x; + vec2 = (o8 ? 4 : 0) ; yin2 = y-1; xin2 = x; + vec3 = (or8? 3 : 0) ; yin3 = y-1; xin3 = x+1; + break; + case 3: + vec1 = (l8 ? 4 : 0) ; yin1 = y ; xin1 = x-1; + vec2 = 1 ; yin2 = y ; xin2 = x; + vec3 = 2 ; yin3 = y ; xin3 = x; + break; + case 4: + vec1 = 3 ; yin1 = y ; xin1 = x; + vec2 = 1 ; yin2 = y ; xin2 = x; + vec3 = 2 ; yin3 = y ; xin3 = x; + break; + default: + exit(1); + break; + } + p1 = MV[comp][vec1][yin1][xin1]; + p2 = MV[comp][vec2][yin2][xin2]; + p3 = MV[comp][vec3][yin3][xin3]; + + if (p2 == NO_VEC) + { + p2 = p3 = p1; + } + + return p1+p2+p3 - max(p1,max(p2,p3)) - min(p1,min(p2,p3)); +} + + +void make_edge_image(const unsigned char *src,unsigned char *dst,int width,int height,int edge) +{ + int i,j; + unsigned char *p1,*p2,*p3,*p4; + const unsigned char *o1,*o2,*o3,*o4; + + /* center image */ + p1 = dst; + o1 = src; + for (j = 0; j < height;j++) + { + for (i = 0; i < width; i++) + { + *(p1 + i) = *(o1 + i); + } + p1 += width + (edge<<1); + o1 += width; + } + + /* left and right edges */ + p1 = dst-1; + o1 = src; + for (j = 0; j < height;j++) + { + for (i = 0; i < edge; i++) + { + *(p1 - i) = *o1; + *(p1 + width + i + 1) = *(o1 + width - 1); + } + p1 += width + (edge<<1); + o1 += width; + } + + /* top and bottom edges */ + p1 = dst; + p2 = dst + (width + (edge<<1))*(height-1); + o1 = src; + o2 = src + width*(height-1); + for (j = 0; j < edge;j++) + { + p1 = p1 - (width + (edge<<1)); + p2 = p2 + (width + (edge<<1)); + for (i = 0; i < width; i++) + { + *(p1 + i) = *(o1 + i); + *(p2 + i) = *(o2 + i); + } + } + + /* corners */ + p1 = dst - (width+(edge<<1)) - 1; + p2 = p1 + width + 1; + p3 = dst + (width+(edge<<1))*(height)-1; + p4 = p3 + width + 1; + + o1 = src; + o2 = o1 + width - 1; + o3 = src + width*(height-1); + o4 = o3 + width - 1; + for (j = 0; j < edge; j++) + { + for (i = 0; i < edge; i++) + { + *(p1 - i) = *o1; + *(p2 + i) = *o2; + *(p3 - i) = *o3; + *(p4 + i) = *o4; + } + p1 = p1 - (width + (edge<<1)); + p2 = p2 - (width + (edge<<1)); + p3 = p3 + width + (edge<<1); + p4 = p4 + width + (edge<<1); + } + +} + +static bool Mode_IsInter(int Mode) +{ +return (Mode == MODE_INTER || Mode == MODE_INTER_Q || + Mode == MODE_INTER4V || Mode == MODE_INTER4V_Q); +} + + +static bool Mode_IsIntra(int Mode) +{ + return (Mode == MODE_INTRA || Mode == MODE_INTRA_Q); +} + +void Decoder::get_I_P_MBs() +{ + int comp; + int MBA, MBAmax; + + int COD = 0, MCBPC, CBPY, CBP = 0, CBPB = 0, MODB = 0, Mode = 0, DQUANT; + int mvx = 0, mvy = 0, pmv0, pmv1, xpos, ypos, k; + int startmv, stopmv, last_done = 0, pCBP = 0, pCBPB = 0, pCOD = 0, pMODB = 0; + int DQ_tab[4] = {-1, -2, 1, 2}; + unsigned int i; + short *bp; + + /* number of macroblocks per picture */ + MBAmax = mb_width * mb_height; + + MBA = 0; /* macroblock address */ + xpos = ypos = 0; + + /* mark MV's above the picture */ + for (i = 1; i < mb_width + 1; i++) + { + for (k = 0; k < 5; k++) + { + MV[0][k][0][i] = NO_VEC; + MV[1][k][0][i] = NO_VEC; + } + modemap[0][i] = MODE_INTRA; + } + /* zero MV's on the sides of the picture */ + for (i = 0; i < mb_height + 1; i++) + { + for (k = 0; k < 5; k++) + { + MV[0][k][i][0] = 0; + MV[1][k][i][0] = 0; + MV[0][k][i][mb_width + 1] = 0; + MV[1][k][i][mb_width + 1] = 0; + } + modemap[i][0] = MODE_INTRA; + modemap[i][mb_width + 1] = MODE_INTRA; + } + /* initialize the qcoeff used in advanced intra coding */ + + fault = 0; + + for (;;) + { + + +resync: + /* This version of the decoder does not resync on every possible + * error, and it does not do all possible error checks. It is not + * difficult to make it much more error robust, but I do not think it + * is necessary to include this in the freely available version. */ + + if (fault) + { + startcode(); /* sync on new startcode */ + fault = 0; + } + + + xpos = MBA % mb_width; + ypos = MBA / mb_width; + + if (MBA >= MBAmax) + { + /* all macroblocks decoded */ + return; + } +read_cod: + + + if (PCT_INTER == pict_type || PCT_DISPOSABLE_INTER == pict_type) + { + COD = buffer.showbits(1); + } + else + { + COD = 0; /* Intra picture -> not skipped */ + coded_map[ypos + 1][xpos + 1] = 1; + } + + + if (!COD) + { + /* COD == 0 --> not skipped */ + + if (PCT_INTER == pict_type || PCT_DISPOSABLE_INTER == pict_type) + { + /* flush COD bit */ + buffer.flushbits(1); + } + if (PCT_INTRA == pict_type) + { + MCBPC = getMCBPCintra(); + } + else + { + MCBPC = getMCBPC(); + } + + + if (fault) + goto resync; + + if (MCBPC == 255) + { + /* stuffing - read next COD without advancing MB count. */ + goto read_cod; + } + else + { + /* normal MB data */ + Mode = MCBPC & 7; + + + /* MODB and CBPB */ + + + CBPY = getCBPY(); + + } + + /* Decode Mode and CBP */ + if ((Mode == MODE_INTRA || Mode == MODE_INTRA_Q)) + { + /* Intra */ + coded_map[ypos + 1][xpos + 1] = 1; + + CBPY = CBPY ^ 15; /* needed in huffman coding only */ + } + + CBP = (CBPY << 2) | (MCBPC >> 4); + + if (Mode == MODE_INTER_Q || Mode == MODE_INTRA_Q || Mode == MODE_INTER4V_Q) + { + /* Read DQUANT if necessary */ + + DQUANT = buffer.getbits(2); + quant += DQ_tab[DQUANT]; + + + if (quant > 31 || quant < 1) + { + quant = max(1, (31, quant)); + /* could set fault-flag and resync here */ + fault = 1; + } + } + + /* motion vectors */ + if (Mode == MODE_INTER || Mode == MODE_INTER_Q || + Mode == MODE_INTER4V || Mode == MODE_INTER4V_Q) + { + if (Mode == MODE_INTER4V || Mode == MODE_INTER4V_Q) + { + startmv = 1; + stopmv = 4; + } + else + { + startmv = 0; + stopmv = 0; + } + + for (k = startmv; k <= stopmv; k++) + { + mvx = getTMNMV(); + mvy = getTMNMV(); + + pmv0 = find_pmv(xpos, ypos, k, 0); + pmv1 = find_pmv(xpos, ypos, k, 1); + + mvx = motion_decode(mvx, pmv0); + mvy = motion_decode(mvy, pmv1); + + /* store coded or not-coded */ + coded_map[ypos + 1][xpos + 1] = 1; + MV[0][k][ypos+1][xpos+1] = mvx; + MV[1][k][ypos+1][xpos+1] = mvy; + } + + } + /* Intra. */ + else + { + } + if (fault) + goto resync; + } + else + { + /* COD == 1 --> skipped MB */ + if (MBA >= MBAmax) + { + /* all macroblocks decoded */ + return; + } + + if (PCT_INTER == pict_type || PCT_DISPOSABLE_INTER == pict_type) + buffer.flushbits(1); + + Mode = MODE_INTER; + /* Reset CBP */ + CBP = CBPB = 0; + coded_map[ypos + 1][xpos + 1] = 0; + + /* reset motion vectors */ + MV[0][0][ypos + 1][xpos + 1] = 0; + MV[1][0][ypos + 1][xpos + 1] = 0; + } + + /* Store mode and prediction type */ + modemap[ypos + 1][xpos + 1] = Mode; + + /* store defaults for advanced intra coding mode */ + + if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) + { + MV[0][0][ypos + 1][xpos + 1] = MV[1][0][ypos + 1][xpos + 1] = 0; + } + + + + + if (!COD) + { + Mode = modemap[ypos + 1][xpos + 1]; + + /* decode blocks */ + for (comp = 0; comp < 6; comp++) + { + clearblock(comp); + if ((Mode == MODE_INTRA || Mode == MODE_INTRA_Q)) + { + /* Intra (except in advanced intra coding mode) */ + bp = block[comp]; + + + bp[0] = buffer.getbits(8); + + if (bp[0] == 255) /* Spec. in H.26P, not in TMN4 */ + bp[0] = 128; + bp[0] *= 8; /* Iquant */ + if ((CBP & (1 << (6 - 1 - comp)))) + { + getblock(comp, 0); + } + } + else + { + /* Inter (or Intra in advanced intra coding mode) */ + if ((CBP & (1 << (6 - 1 - comp)))) + { + getblock(comp, 1); + } + } + + if (fault) + goto resync; + } + + } + + /* decode the last MB if data is missing */ + + /* advance to next macroblock */ + MBA++; + pCBP = CBP; + pCBPB = CBPB; + pCOD = COD; + pMODB = MODB; + quant_map[ypos + 1][xpos + 1] = quant; + + int bx = 16 * xpos; + int by = 16 * ypos; + + Mode = modemap[by / 16 + 1][bx / 16 + 1]; + + /* motion compensation for P-frame */ + if (Mode == MODE_INTER || Mode == MODE_INTER_Q || + Mode == MODE_INTER4V || Mode == MODE_INTER4V_Q) + { + reconstruct(bx, by, Mode); + } + + /* copy or add block data into P-picture */ + for (comp = 0; comp < 6; comp++) + { + /* inverse DCT */ + if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) + { + idct.idct(block[comp]); + addblock(comp, bx, by, 0); + } + else if ((pCBP & (1 << (6 - 1 - comp)))) + { + /* No need to to do this for blocks with no coeffs */ + idct.idct(block[comp]); + addblock(comp, bx, by, 1); + } + } + } +} + +static int STRENGTH[] = {1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12}; +void Decoder::horiz_edge_filter(unsigned char *rec, int width, int height, int chr) +{ + int i, j; + int delta, d1, d2; + int mbc, mbr, do_filter; + int QP; + int mbr_above; + + + /* horizontal edges */ + for (j = 8; j < height; j += 8) + { + if (!chr) + { + mbr = j >> 4; + mbr_above = (j - 8) >> 4; + } + else + { + mbr = j >> 3; + mbr_above = mbr - 1; + } + const int * const cur_coded_map = coded_map[mbr + 1]; + for (i = 0; i < width; i++) + { + // TODO: replace all below with FilterDeblocking8x8HorEdge_H263(rec+i+(j+1)*width, width, QP) and i+=8 ? + if (!chr) + { + mbc = i >> 4; + } + else + { + mbc = i >> 3; + } + + do_filter = cur_coded_map[mbc + 1] || coded_map[mbr_above + 1][mbc + 1]; + if (do_filter) + { + QP = cur_coded_map[mbc + 1] ? quant_map[mbr + 1][mbc + 1] : quant_map[mbr_above + 1][mbc + 1]; + + + delta = (int)(((int)(*(rec + i + (j - 2) * width)) + + (int)(*(rec + i + (j - 1) * width) * (-4)) + + (int)(*(rec + i + (j) * width) * (4)) + + (int)(*(rec + i + (j + 1) * width) * (-1))) / 8.0); + + d1 = sign(delta) * max(0, abs(delta) - max(0, 2 * (abs(delta) - STRENGTH[QP - 1]))); + + d2 = min(abs(d1 / 2), max(-abs(d1 / 2), (int)(((*(rec + i + (j - 2) * width) - + *(rec + i + (j + 1) * width))) / 4))); + + *(rec + i + (j + 1) * width) += d2; /* D */ + *(rec + i + (j) * width) = min(255, max(0, (int)(*(rec + i + (j) * width)) - d1)); /* C */ + *(rec + i + (j - 1) * width) = min(255, max(0, (int)(*(rec + i + (j - 1) * width)) + d1)); /* B */ + *(rec + i + (j - 2) * width) -= d2; /* A */ + } + } + } + return; +} + +void Decoder::vert_edge_filter(unsigned char *rec, int width, int height, int chr) +{ + int i, j; + int delta, d1, d2; + int mbc, mbr; + int do_filter; + int QP; + int mbc_left; + + + /* vertical edges */ + for (i = 8; i < width; i += 8) + { + if (!chr) + { + mbc = i >> 4; + mbc_left = (i - 8) >> 4; + } + else + { + mbc = i >> 3; + mbc_left = mbc - 1; + } + // TODO: replace all below with FilterDeblocking8x8VerEdge_H263(rec+i +j*width, width, QP) and i+=8 ? + for (j = 0; j < height; j++) + { + if (!chr) + { + mbr = j >> 4; + } + else + { + mbr = j >> 3; + + } + do_filter = coded_map[mbr + 1][mbc + 1] || coded_map[mbr + 1][mbc_left + 1]; + + if (do_filter) + { + + QP = coded_map[mbr + 1][mbc + 1] ? + quant_map[mbr + 1][mbc + 1] : quant_map[mbr + 1][mbc_left + 1]; + + delta = (int)(((int)(*(rec + i - 2 + j * width)) + + (int)(*(rec + i - 1 + j * width) * (-4)) + + (int)(*(rec + i + j * width) * (4)) + + (int)(*(rec + i + 1 + j * width) * (-1))) / 8.0); + + d1 = sign(delta) * max(0, abs(delta) - + max(0, 2 * (abs(delta) - STRENGTH[QP - 1]))); + + d2 = min(abs(d1 / 2), max(-abs(d1 / 2), + (int)((*(rec + i - 2 + j * width) - + *(rec + i + 1 + j * width)) / 4))); + + *(rec + i + 1 + j * width) += d2; /* D */ + *(rec + i + j * width) = min(255, max(0, (int)(*(rec + i + j * width)) - d1)); /* C */ + *(rec + i - 1 + j * width) = min(255, max(0, (int)(*(rec + i - 1 + j * width)) + d1)); /* B */ + *(rec + i - 2 + j * width) -= d2; /* A */ + } + } + } + return; +} + +void Decoder::edge_filter(unsigned char *lum, unsigned char *Cb, unsigned char *Cr, int width, int height) +{ + + /* Luma */ + horiz_edge_filter(lum, width, height, 0); + vert_edge_filter(lum, width, height, 0); + + /* Chroma */ + horiz_edge_filter(Cb, width / 2, height / 2, 1); + vert_edge_filter(Cb, width / 2, height / 2, 1); + horiz_edge_filter(Cr, width / 2, height / 2, 1); + vert_edge_filter(Cr, width / 2, height / 2, 1); + + /* that's it */ + return; +} + + + +void Decoder::PostFilter(unsigned char *lum, unsigned char *Cb, unsigned char *Cr, + int width, int height) +{ + + /* Luma */ + horiz_post_filter(lum, width, height, 0); + vert_post_filter(lum, width, height, 0); + + /* Chroma */ + horiz_post_filter(Cb, width / 2, height / 2, 1); + vert_post_filter(Cb, width / 2, height / 2, 1); + horiz_post_filter(Cr, width / 2, height / 2, 1); + vert_post_filter(Cr, width / 2, height / 2, 1); + + /* that's it */ + return; +} + + +/***********************************************************************/ + +static int STRENGTH1[] = {1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4}; +void Decoder::horiz_post_filter(unsigned char *rec, int width, int height, int chr) +{ + int i, j; + int delta, d1; + int mbc, mbr; + int QP; + int mbr_above; + + + /* horizontal edges */ + for (j = 8; j < height; j += 8) + { + for (i = 0; i < width; i++) + { + if (!chr) + { + mbr = j >> 4; + mbc = i >> 4; + mbr_above = (j - 8) >> 4; + } + else + { + mbr = j >> 3; + mbc = i >> 3; + mbr_above = mbr - 1; + } + + QP = coded_map[mbr + 1][mbc + 1] ? + quant_map[mbr + 1][mbc + 1] : quant_map[mbr_above + 1][mbc + 1]; + + delta = (int)(((int)(*(rec + i + (j - 3) * width)) + + (int)(*(rec + i + (j - 2) * width)) + + (int)(*(rec + i + (j - 1) * width)) + + (int)(*(rec + i + (j) * width) * (-6)) + + (int)(*(rec + i + (j + 1) * width)) + + (int)(*(rec + i + (j + 2) * width)) + + (int)(*(rec + i + (j + 3) * width))) / 8.0); + + d1 = sign(delta) * max(0, abs(delta) - max(0, 2 * (abs(delta) - STRENGTH1[QP - 1]))); + + /* Filter D */ + *(rec + i + (j) * width) += d1; + } + } + return; +} + +static int STRENGTH2[] = {1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}; +void Decoder::vert_post_filter(unsigned char *rec, int width, int height, int chr) +{ + int i, j; + int delta, d1; + int mbc, mbr; + int QP; + int mbc_left; + + + /* vertical edges */ + for (i = 8; i < width; i += 8) + { + for (j = 0; j < height; j++) + { + if (!chr) + { + mbr = j >> 4; + mbc = i >> 4; + mbc_left = (i - 8) >> 4; + } + else + { + mbr = j >> 3; + mbc = i >> 3; + mbc_left = mbc - 1; + } + + QP = coded_map[mbr + 1][mbc + 1] ? + quant_map[mbr + 1][mbc + 1] : quant_map[mbr + 1][mbc_left + 1]; + + delta = (int)(((int)(*(rec + i - 3 + j * width)) + + (int)(*(rec + i - 2 + j * width)) + + (int)(*(rec + i - 1 + j * width)) + + (int)(*(rec + i + j * width) * (-6)) + + (int)(*(rec + i + 1 + j * width)) + + (int)(*(rec + i + 2 + j * width)) + + (int)(*(rec + i + 3 + j * width))) / 8.0); + + d1 = sign(delta) * max(0, abs(delta) - max(0, 2 * (abs(delta) - STRENGTH2[QP - 1]))); + + /* Post Filter D */ + *(rec + i + j * width) += d1; + } + } + return; +} |