diff options
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.cpp | 585 |
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 + |