| /* ------------------------------------------------------------------ |
| * 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 |
| |