summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/m4v_h263/dec/src/post_filter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/codecs/m4v_h263/dec/src/post_filter.cpp')
-rw-r--r--media/libstagefright/codecs/m4v_h263/dec/src/post_filter.cpp585
1 files changed, 585 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/post_filter.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/post_filter.cpp
new file mode 100644
index 0000000..b36050c
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/post_filter.cpp
@@ -0,0 +1,585 @@
+/* ------------------------------------------------------------------
+ * Copyright (C) 1998-2009 PacketVideo
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ * -------------------------------------------------------------------
+ */
+
+#include "mp4dec_lib.h"
+
+#ifdef PV_ANNEX_IJKT_SUPPORT
+#include "motion_comp.h"
+#include "mbtype_mode.h"
+const static int STRENGTH_tab[] = {0, 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};
+#endif
+
+#ifdef PV_POSTPROC_ON
+/*----------------------------------------------------------------------------
+; FUNCTION CODE
+----------------------------------------------------------------------------*/
+void PostFilter(
+ VideoDecData *video,
+ int filter_type,
+ uint8 *output)
+{
+ /*----------------------------------------------------------------------------
+ ; Define all local variables
+ ----------------------------------------------------------------------------*/
+ uint8 *pp_mod;
+ int16 *QP_store;
+ int combined_with_deblock_filter;
+ int nTotalMB = video->nTotalMB;
+ int width, height;
+ int32 size;
+ int softDeblocking;
+ uint8 *decodedFrame = video->videoDecControls->outputFrame;
+ /*----------------------------------------------------------------------------
+ ; Function body here
+ ----------------------------------------------------------------------------*/
+ width = video->width;
+ height = video->height;
+ size = (int32)width * height;
+
+ oscl_memcpy(output, decodedFrame, size);
+ oscl_memcpy(output + size, decodedFrame + size, (size >> 2));
+ oscl_memcpy(output + size + (size >> 2), decodedFrame + size + (size >> 2), (size >> 2));
+
+ if (filter_type == 0)
+ return;
+
+ /* The softDecoding cutoff corresponds to ~93000 bps for QCIF 15fps clip */
+ if (PVGetDecBitrate(video->videoDecControls) > (100*video->frameRate*(size >> 12))) // MC_sofDeblock
+ softDeblocking = FALSE;
+ else
+ softDeblocking = TRUE;
+
+ combined_with_deblock_filter = filter_type & PV_DEBLOCK;
+ QP_store = video->QPMB;
+
+ /* Luma */
+ pp_mod = video->pstprcTypCur;
+
+ if ((filter_type & PV_DEBLOCK) && (filter_type & PV_DERING))
+ {
+ CombinedHorzVertRingFilter(output, width, height, QP_store, 0, pp_mod);
+ }
+ else
+ {
+ if (filter_type & PV_DEBLOCK)
+ {
+ if (softDeblocking)
+ {
+ CombinedHorzVertFilter(output, width, height,
+ QP_store, 0, pp_mod);
+ }
+ else
+ {
+ CombinedHorzVertFilter_NoSoftDeblocking(output, width, height,
+ QP_store, 0, pp_mod);
+ }
+ }
+ if (filter_type & PV_DERING)
+ {
+ Deringing_Luma(output, width, height, QP_store,
+ combined_with_deblock_filter, pp_mod);
+
+ }
+ }
+
+ /* Chroma */
+
+ pp_mod += (nTotalMB << 2);
+ output += size;
+
+ if ((filter_type & PV_DEBLOCK) && (filter_type & PV_DERING))
+ {
+ CombinedHorzVertRingFilter(output, (int)(width >> 1), (int)(height >> 1), QP_store, (int) 1, pp_mod);
+ }
+ else
+ {
+ if (filter_type & PV_DEBLOCK)
+ {
+ if (softDeblocking)
+ {
+ CombinedHorzVertFilter(output, (int)(width >> 1),
+ (int)(height >> 1), QP_store, (int) 1, pp_mod);
+ }
+ else
+ {
+ CombinedHorzVertFilter_NoSoftDeblocking(output, (int)(width >> 1),
+ (int)(height >> 1), QP_store, (int) 1, pp_mod);
+ }
+ }
+ if (filter_type & PV_DERING)
+ {
+ Deringing_Chroma(output, (int)(width >> 1),
+ (int)(height >> 1), QP_store,
+ combined_with_deblock_filter, pp_mod);
+ }
+ }
+
+ pp_mod += nTotalMB;
+ output += (size >> 2);
+
+ if ((filter_type & PV_DEBLOCK) && (filter_type & PV_DERING))
+ {
+ CombinedHorzVertRingFilter(output, (int)(width >> 1), (int)(height >> 1), QP_store, (int) 1, pp_mod);
+ }
+ else
+ {
+ if (filter_type & PV_DEBLOCK)
+ {
+ if (softDeblocking)
+ {
+ CombinedHorzVertFilter(output, (int)(width >> 1),
+ (int)(height >> 1), QP_store, (int) 1, pp_mod);
+ }
+ else
+ {
+ CombinedHorzVertFilter_NoSoftDeblocking(output, (int)(width >> 1),
+ (int)(height >> 1), QP_store, (int) 1, pp_mod);
+ }
+ }
+ if (filter_type & PV_DERING)
+ {
+ Deringing_Chroma(output, (int)(width >> 1),
+ (int)(height >> 1), QP_store,
+ combined_with_deblock_filter, pp_mod);
+ }
+ }
+
+ /* swap current pp_mod to prev_frame pp_mod */
+ pp_mod = video->pstprcTypCur;
+ video->pstprcTypCur = video->pstprcTypPrv;
+ video->pstprcTypPrv = pp_mod;
+
+ /*----------------------------------------------------------------------------
+ ; Return nothing or data or data pointer
+ ----------------------------------------------------------------------------*/
+ return;
+}
+#endif
+
+
+#ifdef PV_ANNEX_IJKT_SUPPORT
+void H263_Deblock(uint8 *rec,
+ int width,
+ int height,
+ int16 *QP_store,
+ uint8 *mode,
+ int chr, int annex_T)
+{
+ /*----------------------------------------------------------------------------
+ ; Define all local variables
+ ----------------------------------------------------------------------------*/
+ int i, j, k;
+ uint8 *rec_y;
+ int tmpvar;
+ int mbnum, strength, A_D, d1_2, d1, d2, A, B, C, D, b_size;
+ int d, offset, nMBPerRow, nMBPerCol, width2 = (width << 1);
+ /* MAKE SURE I-VOP INTRA MACROBLOCKS ARE SET TO NON-SKIPPED MODE*/
+ mbnum = 0;
+
+ if (chr)
+ {
+ nMBPerRow = width >> 3;
+ nMBPerCol = height >> 3;
+ b_size = 8;
+ }
+ else
+ {
+ nMBPerRow = width >> 4;
+ nMBPerCol = height >> 4;
+ b_size = 16;
+ }
+
+
+ /********************************* VERTICAL FILTERING ****************************/
+ /* vertical filtering of mid sections no need to check neighboring QP's etc */
+ if (!chr)
+ {
+ rec_y = rec + (width << 3);
+ for (i = 0; i < (height >> 4); i++)
+ {
+ for (j = 0; j < (width >> 4); j++)
+ {
+ if (mode[mbnum] != MODE_SKIPPED)
+ {
+ k = 16;
+ strength = STRENGTH_tab[QP_store[mbnum]];
+ while (k--)
+ {
+ A = *(rec_y - width2);
+ D = *(rec_y + width);
+ A_D = A - D;
+ C = *rec_y;
+ B = *(rec_y - width);
+ d = (((C - B) << 2) + A_D);
+
+ if (d < 0)
+ {
+ d1 = -(-d >> 3);
+ if (d1 < -(strength << 1))
+ {
+ d1 = 0;
+ }
+ else if (d1 < -strength)
+ {
+ d1 = -d1 - (strength << 1);
+ }
+ d1_2 = -d1 >> 1;
+ }
+ else
+ {
+ d1 = d >> 3;
+ if (d1 > (strength << 1))
+ {
+ d1 = 0;
+ }
+ else if (d1 > strength)
+ {
+ d1 = (strength << 1) - d1;
+ }
+ d1_2 = d1 >> 1;
+ }
+
+ if (A_D < 0)
+ {
+ d2 = -(-A_D >> 2);
+ if (d2 < -d1_2)
+ {
+ d2 = -d1_2;
+ }
+ }
+ else
+ {
+ d2 = A_D >> 2;
+ if (d2 > d1_2)
+ {
+ d2 = d1_2;
+ }
+ }
+
+ *(rec_y - width2) = A - d2;
+ tmpvar = B + d1;
+ CLIP_RESULT(tmpvar)
+ *(rec_y - width) = tmpvar;
+ tmpvar = C - d1;
+ CLIP_RESULT(tmpvar)
+ *rec_y = tmpvar;
+ *(rec_y + width) = D + d2;
+ rec_y++;
+ }
+ }
+ else
+ {
+ rec_y += b_size;
+ }
+ mbnum++;
+ }
+ rec_y += (15 * width);
+
+ }
+ }
+
+ /* VERTICAL boundary blocks */
+
+
+ rec_y = rec + width * b_size;
+
+ mbnum = nMBPerRow;
+ for (i = 0; i < nMBPerCol - 1; i++)
+ {
+ for (j = 0; j < nMBPerRow; j++)
+ {
+ if (mode[mbnum] != MODE_SKIPPED || mode[mbnum - nMBPerRow] != MODE_SKIPPED)
+ {
+ k = b_size;
+ if (mode[mbnum] != MODE_SKIPPED)
+ {
+ strength = STRENGTH_tab[(annex_T ? MQ_chroma_QP_table[QP_store[mbnum]] : QP_store[mbnum])];
+ }
+ else
+ {
+ strength = STRENGTH_tab[(annex_T ? MQ_chroma_QP_table[QP_store[mbnum - nMBPerRow]] : QP_store[mbnum - nMBPerRow])];
+ }
+
+ while (k--)
+ {
+ A = *(rec_y - width2);
+ D = *(rec_y + width);
+ A_D = A - D;
+ C = *rec_y;
+ B = *(rec_y - width);
+ d = (((C - B) << 2) + A_D);
+
+ if (d < 0)
+ {
+ d1 = -(-d >> 3);
+ if (d1 < -(strength << 1))
+ {
+ d1 = 0;
+ }
+ else if (d1 < -strength)
+ {
+ d1 = -d1 - (strength << 1);
+ }
+ d1_2 = -d1 >> 1;
+ }
+ else
+ {
+ d1 = d >> 3;
+ if (d1 > (strength << 1))
+ {
+ d1 = 0;
+ }
+ else if (d1 > strength)
+ {
+ d1 = (strength << 1) - d1;
+ }
+ d1_2 = d1 >> 1;
+ }
+
+ if (A_D < 0)
+ {
+ d2 = -(-A_D >> 2);
+ if (d2 < -d1_2)
+ {
+ d2 = -d1_2;
+ }
+ }
+ else
+ {
+ d2 = A_D >> 2;
+ if (d2 > d1_2)
+ {
+ d2 = d1_2;
+ }
+ }
+
+ *(rec_y - width2) = A - d2;
+ tmpvar = B + d1;
+ CLIP_RESULT(tmpvar)
+ *(rec_y - width) = tmpvar;
+ tmpvar = C - d1;
+ CLIP_RESULT(tmpvar)
+ *rec_y = tmpvar;
+ *(rec_y + width) = D + d2;
+ rec_y++;
+ }
+ }
+ else
+ {
+ rec_y += b_size;
+ }
+ mbnum++;
+ }
+ rec_y += ((b_size - 1) * width);
+
+ }
+
+
+ /***************************HORIZONTAL FILTERING ********************************************/
+ mbnum = 0;
+ /* HORIZONTAL INNER */
+ if (!chr)
+ {
+ rec_y = rec + 8;
+ offset = width * b_size - b_size;
+
+ for (i = 0; i < nMBPerCol; i++)
+ {
+ for (j = 0; j < nMBPerRow; j++)
+ {
+ if (mode[mbnum] != MODE_SKIPPED)
+ {
+ k = 16;
+ strength = STRENGTH_tab[QP_store[mbnum]];
+ while (k--)
+ {
+ A = *(rec_y - 2);
+ D = *(rec_y + 1);
+ A_D = A - D;
+ C = *rec_y;
+ B = *(rec_y - 1);
+ d = (((C - B) << 2) + A_D);
+
+ if (d < 0)
+ {
+ d1 = -(-d >> 3);
+ if (d1 < -(strength << 1))
+ {
+ d1 = 0;
+ }
+ else if (d1 < -strength)
+ {
+ d1 = -d1 - (strength << 1);
+ }
+ d1_2 = -d1 >> 1;
+ }
+ else
+ {
+ d1 = d >> 3;
+ if (d1 > (strength << 1))
+ {
+ d1 = 0;
+ }
+ else if (d1 > strength)
+ {
+ d1 = (strength << 1) - d1;
+ }
+ d1_2 = d1 >> 1;
+ }
+
+ if (A_D < 0)
+ {
+ d2 = -(-A_D >> 2);
+ if (d2 < -d1_2)
+ {
+ d2 = -d1_2;
+ }
+ }
+ else
+ {
+ d2 = A_D >> 2;
+ if (d2 > d1_2)
+ {
+ d2 = d1_2;
+ }
+ }
+
+ *(rec_y - 2) = A - d2;
+ tmpvar = B + d1;
+ CLIP_RESULT(tmpvar)
+ *(rec_y - 1) = tmpvar;
+ tmpvar = C - d1;
+ CLIP_RESULT(tmpvar)
+ *rec_y = tmpvar;
+ *(rec_y + 1) = D + d2;
+ rec_y += width;
+ }
+ rec_y -= offset;
+ }
+ else
+ {
+ rec_y += b_size;
+ }
+ mbnum++;
+ }
+ rec_y += (15 * width);
+
+ }
+ }
+
+
+
+ /* HORIZONTAL EDGE */
+ rec_y = rec + b_size;
+ offset = width * b_size - b_size;
+ mbnum = 1;
+ for (i = 0; i < nMBPerCol; i++)
+ {
+ for (j = 0; j < nMBPerRow - 1; j++)
+ {
+ if (mode[mbnum] != MODE_SKIPPED || mode[mbnum-1] != MODE_SKIPPED)
+ {
+ k = b_size;
+ if (mode[mbnum] != MODE_SKIPPED)
+ {
+ strength = STRENGTH_tab[(annex_T ? MQ_chroma_QP_table[QP_store[mbnum]] : QP_store[mbnum])];
+ }
+ else
+ {
+ strength = STRENGTH_tab[(annex_T ? MQ_chroma_QP_table[QP_store[mbnum - 1]] : QP_store[mbnum - 1])];
+ }
+
+ while (k--)
+ {
+ A = *(rec_y - 2);
+ D = *(rec_y + 1);
+ A_D = A - D;
+ C = *rec_y;
+ B = *(rec_y - 1);
+ d = (((C - B) << 2) + A_D);
+
+ if (d < 0)
+ {
+ d1 = -(-d >> 3);
+ if (d1 < -(strength << 1))
+ {
+ d1 = 0;
+ }
+ else if (d1 < -strength)
+ {
+ d1 = -d1 - (strength << 1);
+ }
+ d1_2 = -d1 >> 1;
+ }
+ else
+ {
+ d1 = d >> 3;
+ if (d1 > (strength << 1))
+ {
+ d1 = 0;
+ }
+ else if (d1 > strength)
+ {
+ d1 = (strength << 1) - d1;
+ }
+ d1_2 = d1 >> 1;
+ }
+
+ if (A_D < 0)
+ {
+ d2 = -(-A_D >> 2);
+ if (d2 < -d1_2)
+ {
+ d2 = -d1_2;
+ }
+ }
+ else
+ {
+ d2 = A_D >> 2;
+ if (d2 > d1_2)
+ {
+ d2 = d1_2;
+ }
+ }
+
+ *(rec_y - 2) = A - d2;
+ tmpvar = B + d1;
+ CLIP_RESULT(tmpvar)
+ *(rec_y - 1) = tmpvar;
+ tmpvar = C - d1;
+ CLIP_RESULT(tmpvar)
+ *rec_y = tmpvar;
+ *(rec_y + 1) = D + d2;
+ rec_y += width;
+ }
+ rec_y -= offset;
+ }
+ else
+ {
+ rec_y += b_size;
+ }
+ mbnum++;
+ }
+ rec_y += ((width * (b_size - 1)) + b_size);
+ mbnum++;
+ }
+
+ return;
+}
+#endif
+