1 /* FrameReconstructor.c */
6 #include "FrameReconstructor.h"
10 static void Block_Extract8x8(
18 for (i = 0; i < 8; i++) {
19 for (j = 0; j < 8; j++) {
25 } else if (xx >= plane->CX) {
31 } else if (yy >= plane->CY) {
35 block[i * 8 + j] = plane->Plane[yy * plane->Pitch + xx];
42 static void Block_CopyIntra8x8(
48 const INT16* s = block;
50 UINT8* d = p->Plane + y * p->Pitch + x;
51 UINT8* e = d + 8 * p->Pitch;
53 UINT8 v0[2] = { 0, 0 };
54 UINT8 v1[2] = { 0, 255 };
58 for (; d < e; d += p->Pitch) {
59 for (i = 0; i < 8; i++, s++) {
63 d [i] = v1[pix > 255];
68 static void Block_ReviseInter8x8(
74 const INT16* s = block;
76 UINT8* d = p->Plane + y * p->Pitch + x;
77 UINT8* e = d + 8 * p->Pitch;
79 UINT8 v0[2] = { 0, 0 };
80 UINT8 v1[2] = { 0, 255 };
84 for (; d < e; d += p->Pitch) {
85 for (i = 0; i < 8; i++, s++) {
86 INT32 pix = d[i] + *s;
89 d [i] = v1[pix > 255];
96 static void Block_CopyPlane16x16(
102 UINT8* d0 = p->Plane + y * p->Pitch + x;
103 UINT8* e0 = d0 + 16 * p->Pitch;
105 const UINT8* s0 = s->Plane + y * s->Pitch + x;
107 for (; d0 < e0; d0 += p->Pitch, s0 += s->Pitch) {
130 static void Block_CopyPlane8x8(
136 UINT8* d0 = p->Plane + y * p->Pitch + x;
137 UINT8* e0 = d0 + 8 * p->Pitch;
139 const UINT8* s0 = s->Plane + y * s->Pitch + x;
141 for (; d0 < e0; d0 += p->Pitch, s0 += s->Pitch) {
156 static void MotionComp_Compensate8x8(
163 static void MotionComp_Compensate8x8H(
174 static void MotionComp_Compensate16x16(
181 if (x >= 0 && x + 16 < r->CX &&
182 y >= 0 && y + 16 < r->CY) {
183 const UINT8* s = r->Plane + y * r->Pitch + x;
186 UINT8* e = p + 16 * pitch;
213 MotionComp_Compensate8x8(p, pitch, r, x, y );
214 MotionComp_Compensate8x8(p + 8, pitch, r, x + 8, y );
215 MotionComp_Compensate8x8(p + 8 * pitch, pitch, r, x, y + 8);
216 MotionComp_Compensate8x8(p + 8 + 8 * pitch, pitch, r, x + 8, y + 8);
220 static void MotionComp_Compensate8x8(
229 const UINT8* s0 = r->Plane + y * r->Pitch + x;
233 UINT8* e = p + 8 * pitch;
235 if (x < 0 || x + 8 >= r->CX ||
236 y < 0 || y + 8 >= r->CY) {
239 Block_Extract8x8(r, x, y, b);
258 static void MotionComp_Compensate16x16H(
267 if (x0 >= 0 && x0 + 16 < r->CX &&
268 y0 >= 0 && y0 + 16 < r->CY &&
269 x1 >= 0 && x1 + 16 < r->CX &&
270 y1 >= 0 && y1 + 16 < r->CY) {
271 const UINT8* s0 = r->Plane + y0 * r->Pitch + x0;
272 const UINT8* s1 = r->Plane + y1 * r->Pitch + x1;
275 UINT8* e = p + 16 * pitch;
277 d[ 0] = (s0[ 0] + s1[ 0]) >> 1;
278 d[ 1] = (s0[ 1] + s1[ 1]) >> 1;
279 d[ 2] = (s0[ 2] + s1[ 2]) >> 1;
280 d[ 3] = (s0[ 3] + s1[ 3]) >> 1;
282 d[ 4] = (s0[ 4] + s1[ 4]) >> 1;
283 d[ 5] = (s0[ 5] + s1[ 5]) >> 1;
284 d[ 6] = (s0[ 6] + s1[ 6]) >> 1;
285 d[ 7] = (s0[ 7] + s1[ 7]) >> 1;
287 d[ 8] = (s0[ 8] + s1[ 8]) >> 1;
288 d[ 9] = (s0[ 9] + s1[ 9]) >> 1;
289 d[10] = (s0[10] + s1[10]) >> 1;
290 d[11] = (s0[11] + s1[11]) >> 1;
292 d[12] = (s0[12] + s1[12]) >> 1;
293 d[13] = (s0[13] + s1[13]) >> 1;
294 d[14] = (s0[14] + s1[14]) >> 1;
295 d[15] = (s0[15] + s1[15]) >> 1;
303 MotionComp_Compensate8x8H(p, pitch, r, x0, y0 , x1, y1 );
304 MotionComp_Compensate8x8H(p + 8, pitch, r, x0 + 8, y0 , x1 + 8, y1 );
305 MotionComp_Compensate8x8H(p + 8 * pitch, pitch, r, x0, y0 + 8, x1, y1 + 8);
306 MotionComp_Compensate8x8H(p + 8 + 8 * pitch, pitch, r, x0 + 8, y0 + 8, x1 + 8, y1 + 8);
310 static void MotionComp_Compensate8x8H(
319 UINT8 b0[64], b1[64];
321 const UINT8* s0 = r->Plane + y0 * r->Pitch + x0;
324 const UINT8* s1 = r->Plane + y1 * r->Pitch + x1;
328 UINT8* e = p + 8 * pitch;
330 if (x0 < 0 || x0 + 8 >= r->CX ||
331 y0 < 0 || y0 + 8 >= r->CY ||
332 x1 < 0 || x1 + 8 >= r->CX ||
333 y1 < 0 || y1 + 8 >= r->CY) {
340 Block_Extract8x8(r, x0, y0, b0);
341 Block_Extract8x8(r, x1, y1, b1);
345 d[0] = (s0[0] + s1[0]) >> 1;
346 d[1] = (s0[1] + s1[1]) >> 1;
347 d[2] = (s0[2] + s1[2]) >> 1;
348 d[3] = (s0[3] + s1[3]) >> 1;
350 d[4] = (s0[4] + s1[4]) >> 1;
351 d[5] = (s0[5] + s1[5]) >> 1;
352 d[6] = (s0[6] + s1[6]) >> 1;
353 d[7] = (s0[7] + s1[7]) >> 1;
363 static void MotionComp_Block16x16(
368 const MotionVector_t* mv)
370 INT32 dx = ((mv->X & 1) != 0);
371 INT32 dy = ((mv->Y & 1) != 0);
373 INT32 vx[2] = { mv->X >> 1 };
374 INT32 vy[2] = { mv->Y >> 1 };
376 UINT8* d = p->Plane + y * p->Pitch + x;
378 if (dx == 0 && dy == 0) {
379 MotionComp_Compensate16x16(
390 vx[mv->X >= 0] += dx;
391 vy[mv->Y >= 0] += dy;
393 MotionComp_Compensate16x16H(
404 static void MotionComp_Block8x8Y(
409 const MotionVector_t* mv)
411 INT32 dx = ((mv->X & 1) != 0);
412 INT32 dy = ((mv->Y & 1) != 0);
414 INT32 vx[2] = { mv->X >> 1 };
415 INT32 vy[2] = { mv->Y >> 1 };
417 UINT8* d = p->Plane + y * p->Pitch + x;
419 if (dx == 0 && dy == 0) {
420 MotionComp_Compensate8x8(
431 vx[mv->X >= 0] += dx;
432 vy[mv->Y >= 0] += dy;
434 MotionComp_Compensate8x8H(
445 static void MotionComp_Block8x8C(
450 const MotionVector_t* mv0)
452 MotionVector_t mv = {
453 (mv0->X >> 1) | (mv0->X & 1),
454 (mv0->Y >> 1) | (mv0->Y & 1)
457 INT32 dx = ((mv.X & 1) != 0);
458 INT32 dy = ((mv.Y & 1) != 0);
460 INT32 vx[2] = { mv.X >> 1 };
461 INT32 vy[2] = { mv.Y >> 1 };
463 UINT8* d = p->Plane + y * p->Pitch + x;
465 if (dx == 0 && dy == 0) {
466 MotionComp_Compensate8x8(
480 MotionComp_Compensate8x8H(
493 static const INT32 COS[8] = {
504 #define MUL(T,X) ((COS[T] * (X)) >> 16)
522 t[2] = MUL(6, x[2]) - MUL(2, x[6]);
523 t[3] = MUL(2, x[2]) + MUL(6, x[6]);
525 t[4] = MUL(7, x[1]) - MUL(1, x[7]);
526 t[5] = MUL(3, x[5]) - MUL(5, x[3]);
527 t[6] = MUL(5, x[5]) + MUL(3, x[3]);
528 t[7] = MUL(1, x[1]) + MUL(7, x[7]);
553 y[0*8] = t[0] + t[7];
554 y[1*8] = t[1] + t[6];
559 y[6*8] = t[1] - t[6];
560 y[7*8] = t[0] - t[7];
565 static void IDCT_8x8(
574 for (xx = x, yy = w, end = yy + 8; yy < end; xx += 4*8, yy += 4) {
575 IDCT_8(xx + 0*8, yy + 0);
576 IDCT_8(xx + 1*8, yy + 1);
577 IDCT_8(xx + 2*8, yy + 2);
578 IDCT_8(xx + 3*8, yy + 3);
581 for (xx = w, yy = y, end = yy + 8; yy < end; xx += 4*8, yy += 4) {
582 IDCT_8(xx + 0*8, yy + 0);
583 IDCT_8(xx + 1*8, yy + 1);
584 IDCT_8(xx + 2*8, yy + 2);
585 IDCT_8(xx + 3*8, yy + 3);
588 for (yy = y, end = yy + 64; yy < end; yy += 4) {
589 yy[0] = (yy[0] + 8) >> 4;
590 yy[1] = (yy[1] + 8) >> 4;
591 yy[2] = (yy[2] + 8) >> 4;
592 yy[3] = (yy[3] + 8) >> 4;
598 struct DecodeCoefficientsContext {
605 }; /* DecodeCoefficientsContext */
607 typedef struct DecodeCoefficientsContext DecodeCoefficientsContext_t;
609 static INT32 DecodeCoefficients(
611 DecodeCoefficientsContext_t* ctx,
620 if (ctx->EOB_Run[i] > 0) {
621 ctx->EOB_Run[i] -= 1;
625 INT32 run = *((ctx->Run [i])++);
626 INT16 coeff = *((ctx->Coeff[i])++);
629 ctx->EOB_Run[i] = coeff;
657 static const UINT8 ZIGZAG[64] = {
658 0, 1, 5, 6,14,15,27,28,
659 2, 4, 7,13,16,26,29,42,
660 3, 8,12,17,25,30,41,43,
661 9,11,18,24,31,40,44,53,
662 10,19,23,32,39,45,52,54,
663 20,22,33,38,46,51,55,60,
664 21,34,37,47,50,56,59,61,
665 35,36,48,49,57,58,62,63
668 static void Dequantize_DoDequantize(
669 const DequantizeMatrix_t* m,
673 const INT16* fragment)
675 const INT16* mat = m->Matrix[intra][plane];
678 for (i = 0; i < 64; i++) {
679 block[i] = fragment[ZIGZAG[i]] * mat[i];
685 static void Reconstruct_IntraBlock(
693 DecodeCoefficientsContext_t* ctx)
698 if (dc == NOT_CODED) {
699 Block_CopyPlane8x8(p, x, y, r);
703 DecodeCoefficients(t, ctx, block);
711 for (i = 0; i < 64; i++) {
715 printf("%d", block[i]);
723 Dequantize_DoDequantize(
730 IDCT_8x8(coeff, coeff);
732 Block_CopyIntra8x8(p, x, y, coeff);
737 static void Reconstruct_InterBlock(
745 DecodeCoefficientsContext_t* ctx)
750 if (dc == NOT_CODED) {
752 Block_CopyPlane8x8(p, x, y, r);
757 DecodeCoefficients(t, ctx, block);
761 Dequantize_DoDequantize(
768 IDCT_8x8(coeff, coeff);
770 Block_ReviseInter8x8(p, x, y, coeff);
775 static const INT8 S_PX[16] = {
782 static const INT8 S_PY[16] = {
789 static const INT8 M_PX[4] = {
794 static const INT8 M_PY[4] = {
801 static void Reconstruct_YPlane(
806 INT32 sx = t->Index->SX[0] * 32;
807 INT32 sy = t->Index->SY[0] * 32;
809 INT32 mx = t->Index->MX * 16;
810 INT32 my = t->Index->MY * 16;
812 INT32 bx = t->Index->BX[0];
814 const UINT16* bi = t->Index->BIndex[0];
816 Plane_t* g = t->Frame[0];
817 Plane_t* p = t->Frame[1];
818 Plane_t* r = t->Frame[2];
820 const UINT8* mm = t->MBMode;
821 const MotionVector_t* mv = t->MV;
823 DecodeCoefficientsContext_t ctx = { 0 };
826 for (i = 0; i < 64; i++) {
827 ctx.Run [i] = t->BRun [0][i];
828 ctx.Coeff[i] = t->BCoeff[0][i];
831 for (y = 0; y < sy; y += 32) {
832 for (x = 0; x < sx; x += 32) {
836 for (m = 0; m < 4; m++, i += 4) {
837 INT32 x0 = x + M_PX[m];
838 INT32 y0 = y + M_PY[m];
839 if (x0 < mx && y0 < my) {
841 case 0: /* INTER_NOMV */
842 Block_CopyPlane16x16(p, x0, y0, r);
844 Reconstruct_InterBlock(t, p, x + S_PX[i + 0], y + S_PY[i + 0], t->DC[bi[0]], 0, NULL, &ctx);
845 Reconstruct_InterBlock(t, p, x + S_PX[i + 1], y + S_PY[i + 1], t->DC[bi[1]], 0, NULL, &ctx);
846 Reconstruct_InterBlock(t, p, x + S_PX[i + 2], y + S_PY[i + 2], t->DC[bi[2]], 0, NULL, &ctx);
847 Reconstruct_InterBlock(t, p, x + S_PX[i + 3], y + S_PY[i + 3], t->DC[bi[3]], 0, NULL, &ctx);
851 Reconstruct_IntraBlock(t, p, x + S_PX[i + 0], y + S_PY[i + 0], t->DC[bi[0]], 0, r, &ctx);
852 Reconstruct_IntraBlock(t, p, x + S_PX[i + 1], y + S_PY[i + 1], t->DC[bi[1]], 0, r, &ctx);
853 Reconstruct_IntraBlock(t, p, x + S_PX[i + 2], y + S_PY[i + 2], t->DC[bi[2]], 0, r, &ctx);
854 Reconstruct_IntraBlock(t, p, x + S_PX[i + 3], y + S_PY[i + 3], t->DC[bi[3]], 0, r, &ctx);
857 case 2: /* INTER_MV */
858 case 3: /* INTER_MV_LAST */
859 case 4: /* INTER_MV_LAST2 */
860 MotionComp_Block16x16(p, x0, y0, r, mv);
862 Reconstruct_InterBlock(t, p, x + S_PX[i + 0], y + S_PY[i + 0], t->DC[bi[0]], 0, r, &ctx);
863 Reconstruct_InterBlock(t, p, x + S_PX[i + 1], y + S_PY[i + 1], t->DC[bi[1]], 0, r, &ctx);
864 Reconstruct_InterBlock(t, p, x + S_PX[i + 2], y + S_PY[i + 2], t->DC[bi[2]], 0, r, &ctx);
865 Reconstruct_InterBlock(t, p, x + S_PX[i + 3], y + S_PY[i + 3], t->DC[bi[3]], 0, r, &ctx);
868 case 5: /* INTER_GOLDEN_NOMV */
869 Block_CopyPlane16x16(p, x0, y0, g);
871 Reconstruct_InterBlock(t, p, x + S_PX[i + 0], y + S_PY[i + 0], t->DC[bi[0]], 0, r, &ctx);
872 Reconstruct_InterBlock(t, p, x + S_PX[i + 1], y + S_PY[i + 1], t->DC[bi[1]], 0, r, &ctx);
873 Reconstruct_InterBlock(t, p, x + S_PX[i + 2], y + S_PY[i + 2], t->DC[bi[2]], 0, r, &ctx);
874 Reconstruct_InterBlock(t, p, x + S_PX[i + 3], y + S_PY[i + 3], t->DC[bi[3]], 0, r, &ctx);
877 case 6: /* INTER_GOLDEN_MV */
878 MotionComp_Block16x16(p, x0, y0, g, mv);
880 Reconstruct_InterBlock(t, p, x + S_PX[i + 0], y + S_PY[i + 0], t->DC[bi[0]], 0, r, &ctx);
881 Reconstruct_InterBlock(t, p, x + S_PX[i + 1], y + S_PY[i + 1], t->DC[bi[1]], 0, r, &ctx);
882 Reconstruct_InterBlock(t, p, x + S_PX[i + 2], y + S_PY[i + 2], t->DC[bi[2]], 0, r, &ctx);
883 Reconstruct_InterBlock(t, p, x + S_PX[i + 3], y + S_PY[i + 3], t->DC[bi[3]], 0, r, &ctx);
886 case 7: /* INTER_MV_FOUR */
888 const MotionVector_t* v = mv;
890 const INT16* dc = t->DC + (x0 >> 3) + (y0 >> 3) * bx;
892 if (dc[0] != NOT_CODED) {
893 MotionComp_Block8x8Y(p, x0 + 0, y0 + 0, r, v++);
896 if (dc[1] != NOT_CODED) {
897 MotionComp_Block8x8Y(p, x0 + 8, y0 + 0, r, v++);
900 if (dc[0 + bx] != NOT_CODED) {
901 MotionComp_Block8x8Y(p, x0 + 0, y0 + 8, r, v++);
904 if (dc[1 + bx] != NOT_CODED) {
905 MotionComp_Block8x8Y(p, x0 + 8, y0 + 8, r, v++);
908 Reconstruct_InterBlock(t, p, x + S_PX[i + 0], y + S_PY[i + 0], t->DC[bi[0]], 0, r, &ctx);
909 Reconstruct_InterBlock(t, p, x + S_PX[i + 1], y + S_PY[i + 1], t->DC[bi[1]], 0, r, &ctx);
910 Reconstruct_InterBlock(t, p, x + S_PX[i + 2], y + S_PY[i + 2], t->DC[bi[2]], 0, r, &ctx);
911 Reconstruct_InterBlock(t, p, x + S_PX[i + 3], y + S_PY[i + 3], t->DC[bi[3]], 0, r, &ctx);
928 static void Reconstruct_CPlane(
933 INT32 sx = t->Index->SX[1] * 32;
934 INT32 sy = t->Index->SY[1] * 32;
936 INT32 mx = t->Index->MX * 8;
937 INT32 my = t->Index->MY * 8;
939 INT32 bx = t->Index->BX[1];
941 const UINT16* bi = t->Index->BIndex[1];
943 Plane_t* g = t->Frame[0];
944 Plane_t* p = t->Frame[1];
945 Plane_t* r = t->Frame[2];
947 const INT16* DC0 = t->DC + t->Index->BC[0];
948 const INT16* DC1 = DC0 + t->Index->BC[1];
950 const UINT8* m = t->BMode + t->Index->BC[0];
952 DecodeCoefficientsContext_t ctx[2] = { 0 };
955 for (i = 0; i < 64; i++) {
956 ctx[0].Run [i] = t->BRun [1][i];
957 ctx[0].Coeff[i] = t->BCoeff[1][i];
959 ctx[1].Run [i] = t->BRun [2][i];
960 ctx[1].Coeff[i] = t->BCoeff[2][i];
963 for (y = 0; y < sy; y += 32) {
964 for (x = 0; x < sx; x += 32) {
966 for (i = 0; i < 16; i++) {
967 INT32 xx = x + S_PX[i];
968 INT32 yy = y + S_PY[i];
970 if (xx < mx && yy < my) {
971 INT32 idx = (xx >> 3) + (yy >> 3) * bx;
974 case 0: /* INTER_NOMV */
975 Block_CopyPlane8x8(p + 1, xx, yy, r + 1);
976 Block_CopyPlane8x8(p + 2, xx, yy, r + 2);
978 Reconstruct_InterBlock(t, p + 1, xx, yy, DC0[idx], 1, NULL, ctx + 0);
979 Reconstruct_InterBlock(t, p + 2, xx, yy, DC1[idx], 2, NULL, ctx + 1);
983 Reconstruct_IntraBlock(t, p + 1, xx, yy, DC0[idx], 1, r + 1, ctx + 0);
984 Reconstruct_IntraBlock(t, p + 2, xx, yy, DC1[idx], 2, r + 2, ctx + 1);
987 case 2: /* INTER_MV */
988 case 3: /* INTER_MV_LAST */
989 case 4: /* INTER_MV_LAST2 */
990 MotionComp_Block8x8C(p + 1, xx, yy, r + 1, t->MVC + idx);
991 MotionComp_Block8x8C(p + 2, xx, yy, r + 2, t->MVC + idx);
993 Reconstruct_InterBlock(t, p + 1, xx, yy, DC0[idx], 1, r + 1, ctx + 0);
994 Reconstruct_InterBlock(t, p + 2, xx, yy, DC1[idx], 2, r + 2, ctx + 1);
997 case 5: /* INTER_GOLDEN_NOMV */
998 Block_CopyPlane8x8(p + 1, xx, yy, g + 1);
999 Block_CopyPlane8x8(p + 2, xx, yy, g + 2);
1001 Reconstruct_InterBlock(t, p + 1, xx, yy, DC0[idx], 1, r + 1, ctx + 0);
1002 Reconstruct_InterBlock(t, p + 2, xx, yy, DC1[idx], 2, r + 2, ctx + 1);
1005 case 6: /* INTER_GOLDEN_MV */
1006 MotionComp_Block8x8C(p + 1, xx, yy, g + 1, t->MVC + idx);
1007 MotionComp_Block8x8C(p + 2, xx, yy, g + 2, t->MVC + idx);
1009 Reconstruct_InterBlock(t, p + 1, xx, yy, DC0[idx], 1, r + 1, ctx + 0);
1010 Reconstruct_InterBlock(t, p + 2, xx, yy, DC1[idx], 2, r + 2, ctx + 1);
1013 case 7: /* INTER_MV_FOUR */
1014 MotionComp_Block8x8C(p + 1, xx, yy, r + 1, t->MVC + idx);
1015 MotionComp_Block8x8C(p + 2, xx, yy, r + 2, t->MVC + idx);
1017 Reconstruct_InterBlock(t, p + 1, xx, yy, DC0[idx], 1, r + 1, ctx + 0);
1018 Reconstruct_InterBlock(t, p + 2, xx, yy, DC1[idx], 2, r + 2, ctx + 1);
1030 void QT_ReconstructFrame(
1033 Reconstruct_YPlane(t);
1035 Reconstruct_CPlane(t);