/H264Dec/source/h264bsd_deblocking.c
C | 2417 lines | 1698 code | 295 blank | 424 comment | 323 complexity | 7c34d152f359d1bdba24d54c513ce489 MD5 | raw file
Possible License(s): BSD-3-Clause
- /*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * 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.
- */
- /*------------------------------------------------------------------------------
- Table of contents
- 1. Include headers
- 2. External compiler flags
- 3. Module defines
- 4. Local function prototypes
- 5. Functions
- h264bsdFilterPicture
- FilterVerLumaEdge
- FilterHorLumaEdge
- FilterHorLuma
- FilterVerChromaEdge
- FilterHorChromaEdge
- FilterHorChroma
- InnerBoundaryStrength
- EdgeBoundaryStrength
- GetBoundaryStrengths
- IsSliceBoundaryOnLeft
- IsSliceBoundaryOnTop
- GetMbFilteringFlags
- GetLumaEdgeThresholds
- GetChromaEdgeThresholds
- FilterLuma
- FilterChroma
- ------------------------------------------------------------------------------*/
- /*------------------------------------------------------------------------------
- 1. Include headers
- ------------------------------------------------------------------------------*/
- #include "basetype.h"
- #include "h264bsd_util.h"
- #include "h264bsd_macroblock_layer.h"
- #include "h264bsd_deblocking.h"
- #include "h264bsd_dpb.h"
- #ifdef H264DEC_OMXDL
- #include "omxtypes.h"
- #include "omxVC.h"
- #include "armVC.h"
- #endif /* H264DEC_OMXDL */
- /*------------------------------------------------------------------------------
- 2. External compiler flags
- --------------------------------------------------------------------------------
- --------------------------------------------------------------------------------
- 3. Module defines
- ------------------------------------------------------------------------------*/
- /* Switch off the following Lint messages for this file:
- * Info 701: Shift left of signed quantity (int)
- * Info 702: Shift right of signed quantity (int)
- */
- /*lint -e701 -e702 */
- /* array of alpha values, from the standard */
- static const u8 alphas[52] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,5,6,7,8,9,10,
- 12,13,15,17,20,22,25,28,32,36,40,45,50,56,63,71,80,90,101,113,127,144,162,
- 182,203,226,255,255};
- /* array of beta values, from the standard */
- static const u8 betas[52] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,3,3,3,3,4,4,
- 4,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18};
- #ifndef H264DEC_OMXDL
- /* array of tc0 values, from the standard, each triplet corresponds to a
- * column in the table. Indexing goes as tc0[indexA][bS-1] */
- static const u8 tc0[52][3] = {
- {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
- {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
- {0,0,0},{0,0,1},{0,0,1},{0,0,1},{0,0,1},{0,1,1},{0,1,1},{1,1,1},
- {1,1,1},{1,1,1},{1,1,1},{1,1,2},{1,1,2},{1,1,2},{1,1,2},{1,2,3},
- {1,2,3},{2,2,3},{2,2,4},{2,3,4},{2,3,4},{3,3,5},{3,4,6},{3,4,6},
- {4,5,7},{4,5,8},{4,6,9},{5,7,10},{6,8,11},{6,8,13},{7,10,14},{8,11,16},
- {9,12,18},{10,13,20},{11,15,23},{13,17,25}
- };
- #else
- /* array of tc0 values, from the standard, each triplet corresponds to a
- * column in the table. Indexing goes as tc0[indexA][bS] */
- static const u8 tc0[52][5] = {
- {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0}, {0, 0, 0, 1, 0}, {0, 0, 0, 1, 0}, {0, 0, 0, 1, 0},
- {0, 0, 0, 1, 0}, {0, 0, 1, 1, 0}, {0, 0, 1, 1, 0}, {0, 1, 1, 1, 0},
- {0, 1, 1, 1, 0}, {0, 1, 1, 1, 0}, {0, 1, 1, 1, 0}, {0, 1, 1, 2, 0},
- {0, 1, 1, 2, 0}, {0, 1, 1, 2, 0}, {0, 1, 1, 2, 0}, {0, 1, 2, 3, 0},
- {0, 1, 2, 3, 0}, {0, 2, 2, 3, 0}, {0, 2, 2, 4, 0}, {0, 2, 3, 4, 0},
- {0, 2, 3, 4, 0}, {0, 3, 3, 5, 0}, {0, 3, 4, 6, 0}, {0, 3, 4, 6, 0},
- {0, 4, 5, 7, 0}, {0, 4, 5, 8, 0}, {0, 4, 6, 9, 0}, {0, 5, 7, 10, 0},
- {0, 6, 8, 11, 0}, {0, 6, 8, 13, 0}, {0, 7, 10, 14, 0},
- {0, 8, 11, 16, 0}, {0, 9, 12, 18, 0}, {0, 10, 13, 20, 0},
- {0, 11, 15, 23, 0}, {0, 13, 17, 25, 0}
- };
- #endif
- #ifndef H264DEC_OMXDL
- /* mapping of raster scan block index to 4x4 block index */
- static const u32 mb4x4Index[16] =
- {0, 1, 4, 5, 2, 3, 6, 7, 8, 9, 12, 13, 10, 11, 14, 15};
- typedef struct {
- const u8 *tc0;
- u32 alpha;
- u32 beta;
- } edgeThreshold_t;
- typedef struct {
- u32 top;
- u32 left;
- } bS_t;
- enum { TOP = 0, LEFT = 1, INNER = 2 };
- #endif /* H264DEC_OMXDL */
- #define FILTER_LEFT_EDGE 0x04
- #define FILTER_TOP_EDGE 0x02
- #define FILTER_INNER_EDGE 0x01
- /* clipping table defined in intra_prediction.c */
- extern const u8 h264bsdClip[];
- /*------------------------------------------------------------------------------
- 4. Local function prototypes
- ------------------------------------------------------------------------------*/
- static u32 InnerBoundaryStrength(mbStorage_t *mb1, u32 i1, u32 i2);
- #ifndef H264DEC_OMXDL
- static u32 EdgeBoundaryStrength(mbStorage_t *mb1, mbStorage_t *mb2,
- u32 i1, u32 i2);
- #else
- static u32 InnerBoundaryStrength2(mbStorage_t *mb1, u32 i1, u32 i2);
- static u32 EdgeBoundaryStrengthLeft(mbStorage_t *mb1, mbStorage_t *mb2);
- static u32 EdgeBoundaryStrengthTop(mbStorage_t *mb1, mbStorage_t *mb2);
- #endif
- static u32 IsSliceBoundaryOnLeft(mbStorage_t *mb);
- static u32 IsSliceBoundaryOnTop(mbStorage_t *mb);
- static u32 GetMbFilteringFlags(mbStorage_t *mb);
- #ifndef H264DEC_OMXDL
- static u32 GetBoundaryStrengths(mbStorage_t *mb, bS_t *bs, u32 flags);
- static void FilterLuma(u8 *data, bS_t *bS, edgeThreshold_t *thresholds,
- u32 imageWidth);
- static void FilterChroma(u8 *cb, u8 *cr, bS_t *bS, edgeThreshold_t *thresholds,
- u32 imageWidth);
- static void FilterVerLumaEdge( u8 *data, u32 bS, edgeThreshold_t *thresholds,
- u32 imageWidth);
- static void FilterHorLumaEdge( u8 *data, u32 bS, edgeThreshold_t *thresholds,
- i32 imageWidth);
- static void FilterHorLuma( u8 *data, u32 bS, edgeThreshold_t *thresholds,
- i32 imageWidth);
- static void FilterVerChromaEdge( u8 *data, u32 bS, edgeThreshold_t *thresholds,
- u32 imageWidth);
- static void FilterHorChromaEdge( u8 *data, u32 bS, edgeThreshold_t *thresholds,
- i32 imageWidth);
- static void FilterHorChroma( u8 *data, u32 bS, edgeThreshold_t *thresholds,
- i32 imageWidth);
- static void GetLumaEdgeThresholds(
- edgeThreshold_t *thresholds,
- mbStorage_t *mb,
- u32 filteringFlags);
- static void GetChromaEdgeThresholds(
- edgeThreshold_t *thresholds,
- mbStorage_t *mb,
- u32 filteringFlags,
- i32 chromaQpIndexOffset);
- #else /* H264DEC_OMXDL */
- static u32 GetBoundaryStrengths(mbStorage_t *mb, u8 (*bs)[16], u32 flags);
- static void GetLumaEdgeThresholds(
- mbStorage_t *mb,
- u8 (*alpha)[2],
- u8 (*beta)[2],
- u8 (*threshold)[16],
- u8 (*bs)[16],
- u32 filteringFlags );
- static void GetChromaEdgeThresholds(
- mbStorage_t *mb,
- u8 (*alpha)[2],
- u8 (*beta)[2],
- u8 (*threshold)[8],
- u8 (*bs)[16],
- u32 filteringFlags,
- i32 chromaQpIndexOffset);
- #endif /* H264DEC_OMXDL */
- /*------------------------------------------------------------------------------
- Function: IsSliceBoundaryOnLeft
- Functional description:
- Function to determine if there is a slice boundary on the left side
- of a macroblock.
- ------------------------------------------------------------------------------*/
- u32 IsSliceBoundaryOnLeft(mbStorage_t *mb)
- {
- /* Variables */
- /* Code */
- ASSERT(mb && mb->mbA);
- if (mb->sliceId != mb->mbA->sliceId)
- return(HANTRO_TRUE);
- else
- return(HANTRO_FALSE);
- }
- /*------------------------------------------------------------------------------
- Function: IsSliceBoundaryOnTop
- Functional description:
- Function to determine if there is a slice boundary above the
- current macroblock.
- ------------------------------------------------------------------------------*/
- u32 IsSliceBoundaryOnTop(mbStorage_t *mb)
- {
- /* Variables */
- /* Code */
- ASSERT(mb && mb->mbB);
- if (mb->sliceId != mb->mbB->sliceId)
- return(HANTRO_TRUE);
- else
- return(HANTRO_FALSE);
- }
- /*------------------------------------------------------------------------------
- Function: GetMbFilteringFlags
- Functional description:
- Function to determine which edges of a macroblock has to be
- filtered. Output is a bit-wise OR of FILTER_LEFT_EDGE,
- FILTER_TOP_EDGE and FILTER_INNER_EDGE, depending on which edges
- shall be filtered.
- ------------------------------------------------------------------------------*/
- u32 GetMbFilteringFlags(mbStorage_t *mb)
- {
- /* Variables */
- u32 flags = 0;
- /* Code */
- ASSERT(mb);
- /* nothing will be filtered if disableDeblockingFilterIdc == 1 */
- if (mb->disableDeblockingFilterIdc != 1)
- {
- flags |= FILTER_INNER_EDGE;
- /* filterLeftMbEdgeFlag, left mb is MB_A */
- if (mb->mbA &&
- ((mb->disableDeblockingFilterIdc != 2) ||
- !IsSliceBoundaryOnLeft(mb)))
- flags |= FILTER_LEFT_EDGE;
- /* filterTopMbEdgeFlag */
- if (mb->mbB &&
- ((mb->disableDeblockingFilterIdc != 2) ||
- !IsSliceBoundaryOnTop(mb)))
- flags |= FILTER_TOP_EDGE;
- }
- return(flags);
- }
- /*------------------------------------------------------------------------------
- Function: InnerBoundaryStrength
- Functional description:
- Function to calculate boundary strength value bs for an inner
- edge of a macroblock. Macroblock type is checked before this is
- called -> no intra mb condition here.
- ------------------------------------------------------------------------------*/
- u32 InnerBoundaryStrength(mbStorage_t *mb1, u32 ind1, u32 ind2)
- {
- i32 tmp1, tmp2;
- i32 mv1, mv2, mv3, mv4;
- tmp1 = mb1->totalCoeff[ind1];
- tmp2 = mb1->totalCoeff[ind2];
- mv1 = mb1->mv[ind1].hor;
- mv2 = mb1->mv[ind2].hor;
- mv3 = mb1->mv[ind1].ver;
- mv4 = mb1->mv[ind2].ver;
- if (tmp1 || tmp2)
- {
- return 2;
- }
- else if ( (ABS(mv1 - mv2) >= 4) || (ABS(mv3 - mv4) >= 4) ||
- (mb1->refAddr[ind1 >> 2] != mb1->refAddr[ind2 >> 2]) )
- {
- return 1;
- }
- else
- return 0;
- }
- /*------------------------------------------------------------------------------
- Function: InnerBoundaryStrength2
- Functional description:
- Function to calculate boundary strength value bs for an inner
- edge of a macroblock. The function is the same as
- InnerBoundaryStrength but without checking totalCoeff.
- ------------------------------------------------------------------------------*/
- u32 InnerBoundaryStrength2(mbStorage_t *mb1, u32 ind1, u32 ind2)
- {
- i32 tmp1, tmp2, tmp3, tmp4;
- tmp1 = mb1->mv[ind1].hor;
- tmp2 = mb1->mv[ind2].hor;
- tmp3 = mb1->mv[ind1].ver;
- tmp4 = mb1->mv[ind2].ver;
- if ( (ABS(tmp1 - tmp2) >= 4) || (ABS(tmp3 - tmp4) >= 4) ||
- (mb1->refAddr[ind1 >> 2] != mb1->refAddr[ind2 >> 2]))
- {
- return 1;
- }
- else
- return 0;
- }
- #ifndef H264DEC_OMXDL
- /*------------------------------------------------------------------------------
- Function: EdgeBoundaryStrength
- Functional description:
- Function to calculate boundary strength value bs for left- or
- top-most edge of a macroblock. Macroblock types are checked
- before this is called -> no intra mb conditions here.
- ------------------------------------------------------------------------------*/
- u32 EdgeBoundaryStrength(mbStorage_t *mb1, mbStorage_t *mb2,
- u32 ind1, u32 ind2)
- {
- if (mb1->totalCoeff[ind1] || mb2->totalCoeff[ind2])
- {
- return 2;
- }
- else if ((mb1->refAddr[ind1 >> 2] != mb2->refAddr[ind2 >> 2]) ||
- (ABS(mb1->mv[ind1].hor - mb2->mv[ind2].hor) >= 4) ||
- (ABS(mb1->mv[ind1].ver - mb2->mv[ind2].ver) >= 4))
- {
- return 1;
- }
- else
- return 0;
- }
- #else /* H264DEC_OMXDL */
- /*------------------------------------------------------------------------------
- Function: EdgeBoundaryStrengthTop
- Functional description:
- Function to calculate boundary strength value bs for
- top-most edge of a macroblock. Macroblock types are checked
- before this is called -> no intra mb conditions here.
- ------------------------------------------------------------------------------*/
- u32 EdgeBoundaryStrengthTop(mbStorage_t *mb1, mbStorage_t *mb2)
- {
- u32 topBs = 0;
- u32 tmp1, tmp2, tmp3, tmp4;
- tmp1 = mb1->totalCoeff[0];
- tmp2 = mb2->totalCoeff[10];
- tmp3 = mb1->totalCoeff[1];
- tmp4 = mb2->totalCoeff[11];
- if (tmp1 || tmp2)
- {
- topBs = 2<<0;
- }
- else if ((ABS(mb1->mv[0].hor - mb2->mv[10].hor) >= 4) ||
- (ABS(mb1->mv[0].ver - mb2->mv[10].ver) >= 4) ||
- (mb1->refAddr[0] != mb2->refAddr[10 >> 2]))
- {
- topBs = 1<<0;
- }
- tmp1 = mb1->totalCoeff[4];
- tmp2 = mb2->totalCoeff[14];
- if (tmp3 || tmp4)
- {
- topBs += 2<<8;
- }
- else if ((ABS(mb1->mv[1].hor - mb2->mv[11].hor) >= 4) ||
- (ABS(mb1->mv[1].ver - mb2->mv[11].ver) >= 4) ||
- (mb1->refAddr[0] != mb2->refAddr[11 >> 2]))
- {
- topBs += 1<<8;
- }
- tmp3 = mb1->totalCoeff[5];
- tmp4 = mb2->totalCoeff[15];
- if (tmp1 || tmp2)
- {
- topBs += 2<<16;
- }
- else if ((ABS(mb1->mv[4].hor - mb2->mv[14].hor) >= 4) ||
- (ABS(mb1->mv[4].ver - mb2->mv[14].ver) >= 4) ||
- (mb1->refAddr[4 >> 2] != mb2->refAddr[14 >> 2]))
- {
- topBs += 1<<16;
- }
- if (tmp3 || tmp4)
- {
- topBs += 2<<24;
- }
- else if ((ABS(mb1->mv[5].hor - mb2->mv[15].hor) >= 4) ||
- (ABS(mb1->mv[5].ver - mb2->mv[15].ver) >= 4) ||
- (mb1->refAddr[5 >> 2] != mb2->refAddr[15 >> 2]))
- {
- topBs += 1<<24;
- }
- return topBs;
- }
- /*------------------------------------------------------------------------------
- Function: EdgeBoundaryStrengthLeft
- Functional description:
- Function to calculate boundary strength value bs for left-
- edge of a macroblock. Macroblock types are checked
- before this is called -> no intra mb conditions here.
- ------------------------------------------------------------------------------*/
- u32 EdgeBoundaryStrengthLeft(mbStorage_t *mb1, mbStorage_t *mb2)
- {
- u32 leftBs = 0;
- u32 tmp1, tmp2, tmp3, tmp4;
- tmp1 = mb1->totalCoeff[0];
- tmp2 = mb2->totalCoeff[5];
- tmp3 = mb1->totalCoeff[2];
- tmp4 = mb2->totalCoeff[7];
- if (tmp1 || tmp2)
- {
- leftBs = 2<<0;
- }
- else if ((ABS(mb1->mv[0].hor - mb2->mv[5].hor) >= 4) ||
- (ABS(mb1->mv[0].ver - mb2->mv[5].ver) >= 4) ||
- (mb1->refAddr[0] != mb2->refAddr[5 >> 2]))
- {
- leftBs = 1<<0;
- }
- tmp1 = mb1->totalCoeff[8];
- tmp2 = mb2->totalCoeff[13];
- if (tmp3 || tmp4)
- {
- leftBs += 2<<8;
- }
- else if ((ABS(mb1->mv[2].hor - mb2->mv[7].hor) >= 4) ||
- (ABS(mb1->mv[2].ver - mb2->mv[7].ver) >= 4) ||
- (mb1->refAddr[0] != mb2->refAddr[7 >> 2]))
- {
- leftBs += 1<<8;
- }
- tmp3 = mb1->totalCoeff[10];
- tmp4 = mb2->totalCoeff[15];
- if (tmp1 || tmp2)
- {
- leftBs += 2<<16;
- }
- else if ((ABS(mb1->mv[8].hor - mb2->mv[13].hor) >= 4) ||
- (ABS(mb1->mv[8].ver - mb2->mv[13].ver) >= 4) ||
- (mb1->refAddr[8 >> 2] != mb2->refAddr[13 >> 2]))
- {
- leftBs += 1<<16;
- }
- if (tmp3 || tmp4)
- {
- leftBs += 2<<24;
- }
- else if ((ABS(mb1->mv[10].hor - mb2->mv[15].hor) >= 4) ||
- (ABS(mb1->mv[10].ver - mb2->mv[15].ver) >= 4) ||
- (mb1->refAddr[10 >> 2] != mb2->refAddr[15 >> 2]))
- {
- leftBs += 1<<24;
- }
- return leftBs;
- }
- #endif /* H264DEC_OMXDL */
- /*------------------------------------------------------------------------------
- Function: h264bsdFilterPicture
- Functional description:
- Perform deblocking filtering for a picture. Filter does not copy
- the original picture anywhere but filtering is performed directly
- on the original image. Parameters controlling the filtering process
- are computed based on information in macroblock structures of the
- filtered macroblock, macroblock above and macroblock on the left of
- the filtered one.
- Inputs:
- image pointer to image to be filtered
- mb pointer to macroblock data structure of the top-left
- macroblock of the picture
- Outputs:
- image filtered image stored here
- Returns:
- none
- ------------------------------------------------------------------------------*/
- #ifndef H264DEC_OMXDL
- void h264bsdFilterPicture(
- image_t *image,
- mbStorage_t *mb)
- {
- /* Variables */
- u32 flags;
- u32 picSizeInMbs, mbRow, mbCol;
- u32 picWidthInMbs;
- u8 *data;
- mbStorage_t *pMb;
- bS_t bS[16];
- edgeThreshold_t thresholds[3];
- /* Code */
- ASSERT(image);
- ASSERT(mb);
- ASSERT(image->data);
- ASSERT(image->width);
- ASSERT(image->height);
- picWidthInMbs = image->width;
- data = image->data;
- picSizeInMbs = picWidthInMbs * image->height;
- pMb = mb;
- for (mbRow = 0, mbCol = 0; mbRow < image->height; pMb++)
- {
- flags = GetMbFilteringFlags(pMb);
- if (flags)
- {
- /* GetBoundaryStrengths function returns non-zero value if any of
- * the bS values for the macroblock being processed was non-zero */
- if (GetBoundaryStrengths(pMb, bS, flags))
- {
- /* luma */
- GetLumaEdgeThresholds(thresholds, pMb, flags);
- data = image->data + mbRow * picWidthInMbs * 256 + mbCol * 16;
- FilterLuma((u8*)data, bS, thresholds, picWidthInMbs*16);
- /* chroma */
- GetChromaEdgeThresholds(thresholds, pMb, flags,
- pMb->chromaQpIndexOffset);
- data = image->data + picSizeInMbs * 256 +
- mbRow * picWidthInMbs * 64 + mbCol * 8;
- FilterChroma((u8*)data, data + 64*picSizeInMbs, bS,
- thresholds, picWidthInMbs*8);
- }
- }
- mbCol++;
- if (mbCol == picWidthInMbs)
- {
- mbCol = 0;
- mbRow++;
- }
- }
- }
- /*------------------------------------------------------------------------------
- Function: FilterVerLumaEdge
- Functional description:
- Filter one vertical 4-pixel luma edge.
- ------------------------------------------------------------------------------*/
- void FilterVerLumaEdge(
- u8 *data,
- u32 bS,
- edgeThreshold_t *thresholds,
- u32 imageWidth)
- {
- /* Variables */
- i32 delta, tc, tmp;
- u32 i;
- u8 p0, q0, p1, q1, p2, q2;
- u32 tmpFlag;
- const u8 *clp = h264bsdClip + 512;
- /* Code */
- ASSERT(data);
- ASSERT(bS && bS <= 4);
- ASSERT(thresholds);
- if (bS < 4)
- {
- tc = thresholds->tc0[bS-1];
- tmp = tc;
- for (i = 4; i; i--, data += imageWidth)
- {
- p1 = data[-2]; p0 = data[-1];
- q0 = data[0]; q1 = data[1];
- if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
- ((unsigned)ABS(p1-p0) < thresholds->beta) &&
- ((unsigned)ABS(q1-q0) < thresholds->beta) )
- {
- p2 = data[-3];
- q2 = data[2];
- if ((unsigned)ABS(p2-p0) < thresholds->beta)
- {
- data[-2] = (u8)(p1 + CLIP3(-tc,tc,
- (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1));
- tmp++;
- }
- if ((unsigned)ABS(q2-q0) < thresholds->beta)
- {
- data[1] = (u8)(q1 + CLIP3(-tc,tc,
- (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1));
- tmp++;
- }
- delta = CLIP3(-tmp, tmp, ((((q0 - p0) << 2) +
- (p1 - q1) + 4) >> 3));
- p0 = clp[p0 + delta];
- q0 = clp[q0 - delta];
- tmp = tc;
- data[-1] = p0;
- data[ 0] = q0;
- }
- }
- }
- else
- {
- for (i = 4; i; i--, data += imageWidth)
- {
- p1 = data[-2]; p0 = data[-1];
- q0 = data[0]; q1 = data[1];
- if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
- ((unsigned)ABS(p1-p0) < thresholds->beta) &&
- ((unsigned)ABS(q1-q0) < thresholds->beta) )
- {
- tmpFlag =
- ((unsigned)ABS(p0-q0) < ((thresholds->alpha >> 2) +2)) ?
- HANTRO_TRUE : HANTRO_FALSE;
- p2 = data[-3];
- q2 = data[2];
- if (tmpFlag && (unsigned)ABS(p2-p0) < thresholds->beta)
- {
- tmp = p1 + p0 + q0;
- data[-1] = (u8)((p2 + 2 * tmp + q1 + 4) >> 3);
- data[-2] = (u8)((p2 + tmp + 2) >> 2);
- data[-3] = (u8)((2 * data[-4] + 3 * p2 + tmp + 4) >> 3);
- }
- else
- data[-1] = (2 * p1 + p0 + q1 + 2) >> 2;
- if (tmpFlag && (unsigned)ABS(q2-q0) < thresholds->beta)
- {
- tmp = p0 + q0 + q1;
- data[0] = (u8)((p1 + 2 * tmp + q2 + 4) >> 3);
- data[1] = (u8)((tmp + q2 + 2) >> 2);
- data[2] = (u8)((2 * data[3] + 3 * q2 + tmp + 4) >> 3);
- }
- else
- data[0] = (u8)((2 * q1 + q0 + p1 + 2) >> 2);
- }
- }
- }
- }
- /*------------------------------------------------------------------------------
- Function: FilterHorLumaEdge
- Functional description:
- Filter one horizontal 4-pixel luma edge
- ------------------------------------------------------------------------------*/
- void FilterHorLumaEdge(
- u8 *data,
- u32 bS,
- edgeThreshold_t *thresholds,
- i32 imageWidth)
- {
- /* Variables */
- i32 delta, tc, tmp;
- u32 i;
- u8 p0, q0, p1, q1, p2, q2;
- const u8 *clp = h264bsdClip + 512;
- /* Code */
- ASSERT(data);
- ASSERT(bS < 4);
- ASSERT(thresholds);
- tc = thresholds->tc0[bS-1];
- tmp = tc;
- for (i = 4; i; i--, data++)
- {
- p1 = data[-imageWidth*2]; p0 = data[-imageWidth];
- q0 = data[0]; q1 = data[imageWidth];
- if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
- ((unsigned)ABS(p1-p0) < thresholds->beta) &&
- ((unsigned)ABS(q1-q0) < thresholds->beta) )
- {
- p2 = data[-imageWidth*3];
- if ((unsigned)ABS(p2-p0) < thresholds->beta)
- {
- data[-imageWidth*2] = (u8)(p1 + CLIP3(-tc,tc,
- (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1));
- tmp++;
- }
- q2 = data[imageWidth*2];
- if ((unsigned)ABS(q2-q0) < thresholds->beta)
- {
- data[imageWidth] = (u8)(q1 + CLIP3(-tc,tc,
- (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1));
- tmp++;
- }
- delta = CLIP3(-tmp, tmp, ((((q0 - p0) << 2) +
- (p1 - q1) + 4) >> 3));
- p0 = clp[p0 + delta];
- q0 = clp[q0 - delta];
- tmp = tc;
- data[-imageWidth] = p0;
- data[ 0] = q0;
- }
- }
- }
- /*------------------------------------------------------------------------------
- Function: FilterHorLuma
- Functional description:
- Filter all four successive horizontal 4-pixel luma edges. This can
- be done when bS is equal to all four edges.
- ------------------------------------------------------------------------------*/
- void FilterHorLuma(
- u8 *data,
- u32 bS,
- edgeThreshold_t *thresholds,
- i32 imageWidth)
- {
- /* Variables */
- i32 delta, tc, tmp;
- u32 i;
- u8 p0, q0, p1, q1, p2, q2;
- u32 tmpFlag;
- const u8 *clp = h264bsdClip + 512;
- /* Code */
- ASSERT(data);
- ASSERT(bS <= 4);
- ASSERT(thresholds);
- if (bS < 4)
- {
- tc = thresholds->tc0[bS-1];
- tmp = tc;
- for (i = 16; i; i--, data++)
- {
- p1 = data[-imageWidth*2]; p0 = data[-imageWidth];
- q0 = data[0]; q1 = data[imageWidth];
- if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
- ((unsigned)ABS(p1-p0) < thresholds->beta) &&
- ((unsigned)ABS(q1-q0) < thresholds->beta) )
- {
- p2 = data[-imageWidth*3];
- if ((unsigned)ABS(p2-p0) < thresholds->beta)
- {
- data[-imageWidth*2] = (u8)(p1 + CLIP3(-tc,tc,
- (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1));
- tmp++;
- }
- q2 = data[imageWidth*2];
- if ((unsigned)ABS(q2-q0) < thresholds->beta)
- {
- data[imageWidth] = (u8)(q1 + CLIP3(-tc,tc,
- (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1));
- tmp++;
- }
- delta = CLIP3(-tmp, tmp, ((((q0 - p0) << 2) +
- (p1 - q1) + 4) >> 3));
- p0 = clp[p0 + delta];
- q0 = clp[q0 - delta];
- tmp = tc;
- data[-imageWidth] = p0;
- data[ 0] = q0;
- }
- }
- }
- else
- {
- for (i = 16; i; i--, data++)
- {
- p1 = data[-imageWidth*2]; p0 = data[-imageWidth];
- q0 = data[0]; q1 = data[imageWidth];
- if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
- ((unsigned)ABS(p1-p0) < thresholds->beta) &&
- ((unsigned)ABS(q1-q0) < thresholds->beta) )
- {
- tmpFlag = ((unsigned)ABS(p0-q0) < ((thresholds->alpha >> 2) +2))
- ? HANTRO_TRUE : HANTRO_FALSE;
- p2 = data[-imageWidth*3];
- q2 = data[imageWidth*2];
- if (tmpFlag && (unsigned)ABS(p2-p0) < thresholds->beta)
- {
- tmp = p1 + p0 + q0;
- data[-imageWidth] = (u8)((p2 + 2 * tmp + q1 + 4) >> 3);
- data[-imageWidth*2] = (u8)((p2 + tmp + 2) >> 2);
- data[-imageWidth*3] = (u8)((2 * data[-imageWidth*4] +
- 3 * p2 + tmp + 4) >> 3);
- }
- else
- data[-imageWidth] = (u8)((2 * p1 + p0 + q1 + 2) >> 2);
- if (tmpFlag && (unsigned)ABS(q2-q0) < thresholds->beta)
- {
- tmp = p0 + q0 + q1;
- data[ 0] = (u8)((p1 + 2 * tmp + q2 + 4) >> 3);
- data[imageWidth] = (u8)((tmp + q2 + 2) >> 2);
- data[imageWidth*2] = (u8)((2 * data[imageWidth*3] +
- 3 * q2 + tmp + 4) >> 3);
- }
- else
- data[0] = (2 * q1 + q0 + p1 + 2) >> 2;
- }
- }
- }
- }
- /*------------------------------------------------------------------------------
- Function: FilterVerChromaEdge
- Functional description:
- Filter one vertical 2-pixel chroma edge
- ------------------------------------------------------------------------------*/
- void FilterVerChromaEdge(
- u8 *data,
- u32 bS,
- edgeThreshold_t *thresholds,
- u32 width)
- {
- /* Variables */
- i32 delta, tc;
- u8 p0, q0, p1, q1;
- const u8 *clp = h264bsdClip + 512;
- /* Code */
- ASSERT(data);
- ASSERT(bS <= 4);
- ASSERT(thresholds);
- p1 = data[-2]; p0 = data[-1];
- q0 = data[0]; q1 = data[1];
- if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
- ((unsigned)ABS(p1-p0) < thresholds->beta) &&
- ((unsigned)ABS(q1-q0) < thresholds->beta) )
- {
- if (bS < 4)
- {
- tc = thresholds->tc0[bS-1] + 1;
- delta = CLIP3(-tc, tc, ((((q0 - p0) << 2) +
- (p1 - q1) + 4) >> 3));
- p0 = clp[p0 + delta];
- q0 = clp[q0 - delta];
- data[-1] = p0;
- data[ 0] = q0;
- }
- else
- {
- data[-1] = (2 * p1 + p0 + q1 + 2) >> 2;
- data[ 0] = (2 * q1 + q0 + p1 + 2) >> 2;
- }
- }
- data += width;
- p1 = data[-2]; p0 = data[-1];
- q0 = data[0]; q1 = data[1];
- if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
- ((unsigned)ABS(p1-p0) < thresholds->beta) &&
- ((unsigned)ABS(q1-q0) < thresholds->beta) )
- {
- if (bS < 4)
- {
- tc = thresholds->tc0[bS-1] + 1;
- delta = CLIP3(-tc, tc, ((((q0 - p0) << 2) +
- (p1 - q1) + 4) >> 3));
- p0 = clp[p0 + delta];
- q0 = clp[q0 - delta];
- data[-1] = p0;
- data[ 0] = q0;
- }
- else
- {
- data[-1] = (2 * p1 + p0 + q1 + 2) >> 2;
- data[ 0] = (2 * q1 + q0 + p1 + 2) >> 2;
- }
- }
- }
- /*------------------------------------------------------------------------------
- Function: FilterHorChromaEdge
- Functional description:
- Filter one horizontal 2-pixel chroma edge
- ------------------------------------------------------------------------------*/
- void FilterHorChromaEdge(
- u8 *data,
- u32 bS,
- edgeThreshold_t *thresholds,
- i32 width)
- {
- /* Variables */
- i32 delta, tc;
- u32 i;
- u8 p0, q0, p1, q1;
- const u8 *clp = h264bsdClip + 512;
- /* Code */
- ASSERT(data);
- ASSERT(bS < 4);
- ASSERT(thresholds);
- tc = thresholds->tc0[bS-1] + 1;
- for (i = 2; i; i--, data++)
- {
- p1 = data[-width*2]; p0 = data[-width];
- q0 = data[0]; q1 = data[width];
- if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
- ((unsigned)ABS(p1-p0) < thresholds->beta) &&
- ((unsigned)ABS(q1-q0) < thresholds->beta) )
- {
- delta = CLIP3(-tc, tc, ((((q0 - p0) << 2) +
- (p1 - q1) + 4) >> 3));
- p0 = clp[p0 + delta];
- q0 = clp[q0 - delta];
- data[-width] = p0;
- data[ 0] = q0;
- }
- }
- }
- /*------------------------------------------------------------------------------
- Function: FilterHorChroma
- Functional description:
- Filter all four successive horizontal 2-pixel chroma edges. This
- can be done if bS is equal for all four edges.
- ------------------------------------------------------------------------------*/
- void FilterHorChroma(
- u8 *data,
- u32 bS,
- edgeThreshold_t *thresholds,
- i32 width)
- {
- /* Variables */
- i32 delta, tc;
- u32 i;
- u8 p0, q0, p1, q1;
- const u8 *clp = h264bsdClip + 512;
- /* Code */
- ASSERT(data);
- ASSERT(bS <= 4);
- ASSERT(thresholds);
- if (bS < 4)
- {
- tc = thresholds->tc0[bS-1] + 1;
- for (i = 8; i; i--, data++)
- {
- p1 = data[-width*2]; p0 = data[-width];
- q0 = data[0]; q1 = data[width];
- if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
- ((unsigned)ABS(p1-p0) < thresholds->beta) &&
- ((unsigned)ABS(q1-q0) < thresholds->beta) )
- {
- delta = CLIP3(-tc, tc, ((((q0 - p0) << 2) +
- (p1 - q1) + 4) >> 3));
- p0 = clp[p0 + delta];
- q0 = clp[q0 - delta];
- data[-width] = p0;
- data[ 0] = q0;
- }
- }
- }
- else
- {
- for (i = 8; i; i--, data++)
- {
- p1 = data[-width*2]; p0 = data[-width];
- q0 = data[0]; q1 = data[width];
- if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
- ((unsigned)ABS(p1-p0) < thresholds->beta) &&
- ((unsigned)ABS(q1-q0) < thresholds->beta) )
- {
- data[-width] = (2 * p1 + p0 + q1 + 2) >> 2;
- data[ 0] = (2 * q1 + q0 + p1 + 2) >> 2;
- }
- }
- }
- }
- /*------------------------------------------------------------------------------
- Function: GetBoundaryStrengths
- Functional description:
- Function to calculate boundary strengths for all edges of a
- macroblock. Function returns HANTRO_TRUE if any of the bS values for
- the macroblock had non-zero value, HANTRO_FALSE otherwise.
- ------------------------------------------------------------------------------*/
- u32 GetBoundaryStrengths(mbStorage_t *mb, bS_t *bS, u32 flags)
- {
- /* Variables */
- /* this flag is set HANTRO_TRUE as soon as any boundary strength value is
- * non-zero */
- u32 nonZeroBs = HANTRO_FALSE;
- /* Code */
- ASSERT(mb);
- ASSERT(bS);
- ASSERT(flags);
- /* top edges */
- if (flags & FILTER_TOP_EDGE)
- {
- if (IS_INTRA_MB(*mb) || IS_INTRA_MB(*mb->mbB))
- {
- bS[0].top = bS[1].top = bS[2].top = bS[3].top = 4;
- nonZeroBs = HANTRO_TRUE;
- }
- else
- {
- bS[0].top = EdgeBoundaryStrength(mb, mb->mbB, 0, 10);
- bS[1].top = EdgeBoundaryStrength(mb, mb->mbB, 1, 11);
- bS[2].top = EdgeBoundaryStrength(mb, mb->mbB, 4, 14);
- bS[3].top = EdgeBoundaryStrength(mb, mb->mbB, 5, 15);
- if (bS[0].top || bS[1].top || bS[2].top || bS[3].top)
- nonZeroBs = HANTRO_TRUE;
- }
- }
- else
- {
- bS[0].top = bS[1].top = bS[2].top = bS[3].top = 0;
- }
- /* left edges */
- if (flags & FILTER_LEFT_EDGE)
- {
- if (IS_INTRA_MB(*mb) || IS_INTRA_MB(*mb->mbA))
- {
- bS[0].left = bS[4].left = bS[8].left = bS[12].left = 4;
- nonZeroBs = HANTRO_TRUE;
- }
- else
- {
- bS[0].left = EdgeBoundaryStrength(mb, mb->mbA, 0, 5);
- bS[4].left = EdgeBoundaryStrength(mb, mb->mbA, 2, 7);
- bS[8].left = EdgeBoundaryStrength(mb, mb->mbA, 8, 13);
- bS[12].left = EdgeBoundaryStrength(mb, mb->mbA, 10, 15);
- if (!nonZeroBs &&
- (bS[0].left || bS[4].left || bS[8].left || bS[12].left))
- nonZeroBs = HANTRO_TRUE;
- }
- }
- else
- {
- bS[0].left = bS[4].left = bS[8].left = bS[12].left = 0;
- }
- /* inner edges */
- if (IS_INTRA_MB(*mb))
- {
- bS[4].top = bS[5].top = bS[6].top = bS[7].top =
- bS[8].top = bS[9].top = bS[10].top = bS[11].top =
- bS[12].top = bS[13].top = bS[14].top = bS[15].top = 3;
- bS[1].left = bS[2].left = bS[3].left =
- bS[5].left = bS[6].left = bS[7].left =
- bS[9].left = bS[10].left = bS[11].left =
- bS[13].left = bS[14].left = bS[15].left = 3;
- nonZeroBs = HANTRO_TRUE;
- }
- else
- {
- /* 16x16 inter mb -> ref addresses or motion vectors cannot differ,
- * only check if either of the blocks contain coefficients */
- if (h264bsdNumMbPart(mb->mbType) == 1)
- {
- bS[4].top = mb->totalCoeff[2] || mb->totalCoeff[0] ? 2 : 0;
- bS[5].top = mb->totalCoeff[3] || mb->totalCoeff[1] ? 2 : 0;
- bS[6].top = mb->totalCoeff[6] || mb->totalCoeff[4] ? 2 : 0;
- bS[7].top = mb->totalCoeff[7] || mb->totalCoeff[5] ? 2 : 0;
- bS[8].top = mb->totalCoeff[8] || mb->totalCoeff[2] ? 2 : 0;
- bS[9].top = mb->totalCoeff[9] || mb->totalCoeff[3] ? 2 : 0;
- bS[10].top = mb->totalCoeff[12] || mb->totalCoeff[6] ? 2 : 0;
- bS[11].top = mb->totalCoeff[13] || mb->totalCoeff[7] ? 2 : 0;
- bS[12].top = mb->totalCoeff[10] || mb->totalCoeff[8] ? 2 : 0;
- bS[13].top = mb->totalCoeff[11] || mb->totalCoeff[9] ? 2 : 0;
- bS[14].top = mb->totalCoeff[14] || mb->totalCoeff[12] ? 2 : 0;
- bS[15].top = mb->totalCoeff[15] || mb->totalCoeff[13] ? 2 : 0;
- bS[1].left = mb->totalCoeff[1] || mb->totalCoeff[0] ? 2 : 0;
- bS[2].left = mb->totalCoeff[4] || mb->totalCoeff[1] ? 2 : 0;
- bS[3].left = mb->totalCoeff[5] || mb->totalCoeff[4] ? 2 : 0;
- bS[5].left = mb->totalCoeff[3] || mb->totalCoeff[2] ? 2 : 0;
- bS[6].left = mb->totalCoeff[6] || mb->totalCoeff[3] ? 2 : 0;
- bS[7].left = mb->totalCoeff[7] || mb->totalCoeff[6] ? 2 : 0;
- bS[9].left = mb->totalCoeff[9] || mb->totalCoeff[8] ? 2 : 0;
- bS[10].left = mb->totalCoeff[12] || mb->totalCoeff[9] ? 2 : 0;
- bS[11].left = mb->totalCoeff[13] || mb->totalCoeff[12] ? 2 : 0;
- bS[13].left = mb->totalCoeff[11] || mb->totalCoeff[10] ? 2 : 0;
- bS[14].left = mb->totalCoeff[14] || mb->totalCoeff[11] ? 2 : 0;
- bS[15].left = mb->totalCoeff[15] || mb->totalCoeff[14] ? 2 : 0;
- }
- /* 16x8 inter mb -> ref addresses and motion vectors can be different
- * only for the middle horizontal edge, for the other top edges it is
- * enough to check whether the blocks contain coefficients or not. The
- * same applies to all internal left edges. */
- else if (mb->mbType == P_L0_L0_16x8)
- {
- bS[4].top = mb->totalCoeff[2] || mb->totalCoeff[0] ? 2 : 0;
- bS[5].top = mb->totalCoeff[3] || mb->totalCoeff[1] ? 2 : 0;
- bS[6].top = mb->totalCoeff[6] || mb->totalCoeff[4] ? 2 : 0;
- bS[7].top = mb->totalCoeff[7] || mb->totalCoeff[5] ? 2 : 0;
- bS[12].top = mb->totalCoeff[10] || mb->totalCoeff[8] ? 2 : 0;
- bS[13].top = mb->totalCoeff[11] || mb->totalCoeff[9] ? 2 : 0;
- bS[14].top = mb->totalCoeff[14] || mb->totalCoeff[12] ? 2 : 0;
- bS[15].top = mb->totalCoeff[15] || mb->totalCoeff[13] ? 2 : 0;
- bS[8].top = InnerBoundaryStrength(mb, 8, 2);
- bS[9].top = InnerBoundaryStrength(mb, 9, 3);
- bS[10].top = InnerBoundaryStrength(mb, 12, 6);
- bS[11].top = InnerBoundaryStrength(mb, 13, 7);
- bS[1].left = mb->totalCoeff[1] || mb->totalCoeff[0] ? 2 : 0;
- bS[2].left = mb->totalCoeff[4] || mb->totalCoeff[1] ? 2 : 0;
- bS[3].left = mb->totalCoeff[5] || mb->totalCoeff[4] ? 2 : 0;
- bS[5].left = mb->totalCoeff[3] || mb->totalCoeff[2] ? 2 : 0;
- bS[6].left = mb->totalCoeff[6] || mb->totalCoeff[3] ? 2 : 0;
- bS[7].left = mb->totalCoeff[7] || mb->totalCoeff[6] ? 2 : 0;
- bS[9].left = mb->totalCoeff[9] || mb->totalCoeff[8] ? 2 : 0;
- bS[10].left = mb->totalCoeff[12] || mb->totalCoeff[9] ? 2 : 0;
- bS[11].left = mb->totalCoeff[13] || mb->totalCoeff[12] ? 2 : 0;
- bS[13].left = mb->totalCoeff[11] || mb->totalCoeff[10] ? 2 : 0;
- bS[14].left = mb->totalCoeff[14] || mb->totalCoeff[11] ? 2 : 0;
- bS[15].left = mb->totalCoeff[15] || mb->totalCoeff[14] ? 2 : 0;
- }
- /* 8x16 inter mb -> ref addresses and motion vectors can be different
- * only for the middle vertical edge, for the other left edges it is
- * enough to check whether the blocks contain coefficients or not. The
- * same applies to all internal top edges. */
- else if (mb->mbType == P_L0_L0_8x16)
- {
- bS[4].top = mb->totalCoeff[2] || mb->totalCoeff[0] ? 2 : 0;
- bS[5].top = mb->totalCoeff[3] || mb->totalCoeff[1] ? 2 : 0;
- bS[6].top = mb->totalCoeff[6] || mb->totalCoeff[4] ? 2 : 0;
- bS[7].top = mb->totalCoeff[7] || mb->totalCoeff[5] ? 2 : 0;
- bS[8].top = mb->totalCoeff[8] || mb->totalCoeff[2] ? 2 : 0;
- bS[9].top = mb->totalCoeff[9] || mb->totalCoeff[3] ? 2 : 0;
- bS[10].top = mb->totalCoeff[12] || mb->totalCoeff[6] ? 2 : 0;
- bS[11].top = mb->totalCoeff[13] || mb->totalCoeff[7] ? 2 : 0;
- bS[12].top = mb->totalCoeff[10] || mb->totalCoeff[8] ? 2 : 0;
- bS[13].top = mb->totalCoeff[11] || mb->totalCoeff[9] ? 2 : 0;
- bS[14].top = mb->totalCoeff[14] || mb->totalCoeff[12] ? 2 : 0;
- bS[15].top = mb->totalCoeff[15] || mb->totalCoeff[13] ? 2 : 0;
- bS[1].left = mb->totalCoeff[1] || mb->totalCoeff[0] ? 2 : 0;
- bS[3].left = mb->totalCoeff[5] || mb->totalCoeff[4] ? 2 : 0;
- bS[5].left = mb->totalCoeff[3] || mb->totalCoeff[2] ? 2 : 0;
- bS[7].left = mb->totalCoeff[7] || mb->totalCoeff[6] ? 2 : 0;
- bS[9].left = mb->totalCoeff[9] || mb->totalCoeff[8] ? 2 : 0;
- bS[11].left = mb->totalCoeff[13] || mb->totalCoeff[12] ? 2 : 0;
- bS[13].left = mb->totalCoeff[11] || mb->totalCoeff[10] ? 2 : 0;
- bS[15].left = mb->totalCoeff[15] || mb->totalCoeff[14] ? 2 : 0;
- bS[2].left = InnerBoundaryStrength(mb, 4, 1);
- bS[6].left = InnerBoundaryStrength(mb, 6, 3);
- bS[10].left = InnerBoundaryStrength(mb, 12, 9);
- bS[14].left = InnerBoundaryStrength(mb, 14, 11);
- }
- else
- {
- bS[4].top =
- InnerBoundaryStrength(mb, mb4x4Index[4], mb4x4Index[0]);
- bS[5].top =
- InnerBoundaryStrength(mb, mb4x4Index[5], mb4x4Index[1]);
- bS[6].top =
- InnerBoundaryStrength(mb, mb4x4Index[6], mb4x4Index[2]);
- bS[7].top =
- InnerBoundaryStrength(mb, mb4x4Index[7], mb4x4Index[3]);
- bS[8].top =
- InnerBoundaryStrength(mb, mb4x4Index[8], mb4x4Index[4]);
- bS[9].top =
- InnerBoundaryStrength(mb, mb4x4Index[9], mb4x4Index[5]);
- bS[10].top =
- InnerBoundaryStrength(mb, mb4x4Index[10], mb4x4Index[6]);
- bS[11].top =
- InnerBoundaryStrength(mb, mb4x4Index[11], mb4x4Index[7]);
- bS[12].top =
- InnerBoundaryStrength(mb, mb4x4Index[12], mb4x4Index[8]);
- bS[13].top =
- InnerBoundaryStrength(mb, mb4x4Index[13], mb4x4Index[9]);
- bS[14].top =
- InnerBoundaryStrength(mb, mb4x4Index[14], mb4x4Index[10]);
- bS[15].top =
- InnerBoundaryStrength(mb, mb4x4Index[15], mb4x4Index[11]);
- bS[1].left =
- InnerBoundaryStrength(mb, mb4x4Index[1], mb4x4Index[0]);
- bS[2].left =
- InnerBoundaryStrength(mb, mb4x4Index[2], mb4x4Index[1]);
- bS[3].left =
- InnerBoundaryStrength(mb, mb4x4Index[3], mb4x4Index[2]);
- bS[5].left =
- InnerBoundaryStrength(mb, mb4x4Index[5], mb4x4Index[4]);
- bS[6].left =
- InnerBoundaryStrength(mb, mb4x4Index[6], mb4x4Index[5]);
- bS[7].left =
- InnerBoundaryStrength(mb, mb4x4Index[7], mb4x4Index[6]);
- bS[9].left =
- InnerBoundaryStrength(mb, mb4x4Index[9], mb4x4Index[8]);
- bS[10].left =
- InnerBoundaryStrength(mb, mb4x4Index[10], mb4x4Index[9]);
- bS[11].left =
- InnerBoundaryStrength(mb, mb4x4Index[11], mb4x4Index[10]);
- bS[13].left =
- InnerBoundaryStrength(mb, mb4x4Index[13], mb4x4Index[12]);
- bS[14].left =
- InnerBoundaryStrength(mb, mb4x4Index[14], mb4x4Index[13]);
- bS[15].left =
- InnerBoundaryStrength(mb, mb4x4Index[15], mb4x4Index[14]);
- }
- if (!nonZeroBs &&
- (bS[4].top || bS[5].top || bS[6].top || bS[7].top ||
- bS[8].top || bS[9].top || bS[10].top || bS[11].top ||
- bS[12].top || bS[13].top || bS[14].top || bS[15].top ||
- bS[1].left || bS[2].left || bS[3].left ||
- bS[5].left || bS[6].left || bS[7].left ||
- bS[9].left || bS[10].left || bS[11].left ||
- bS[13].left || bS[14].left || bS[15].left))
- nonZeroBs = HANTRO_TRUE;
- }
- return(nonZeroBs);
- }
- /*------------------------------------------------------------------------------
- Function: GetLumaEdgeThresholds
- Functional description:
- Compute alpha, beta and tc0 thresholds for inner, left and top
- luma edges of a macroblock.
- ------------------------------------------------------------------------------*/
- void GetLumaEdgeThresholds(
- edgeThreshold_t *thresholds,
- mbStorage_t *mb,
- u32 filteringFlags)
- {
- /* Variables */
- u32 indexA, indexB;
- u32 qpAv, qp, qpTmp;
- /* Code */
- ASSERT(thresholds);
- ASSERT(mb);
- qp = mb->qpY;
- indexA = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetA);
- indexB = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetB);
- thresholds[INNER].alpha = alphas[indexA];
- thresholds[INNER].beta = betas[indexB];
- thresholds[INNER].tc0 = tc0[indexA];
- if (filteringFlags & FILTER_TOP_EDGE)
- {
- qpTmp = mb->mbB->qpY;
- if (qpTmp != qp)
- {
- qpAv = (qp + qpTmp + 1) >> 1;
- indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
- indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
- thresholds[TOP].alpha = alphas[indexA];
- thresholds[TOP].beta = betas[indexB];
- thresholds[TOP].tc0 = tc0[indexA];
- }
- else
- {
- thresholds[TOP].alpha = thresholds[INNER].alpha;
- thresholds[TOP].beta = thresholds[INNER].beta;
- thresholds[TOP].tc0 = thresholds[INNER].tc0;
- }
- }
- if (filteringFlags & FILTER_LEFT_EDGE)
- {
- qpTmp = mb->mbA->qpY;
- if (qpTmp != qp)
- {
- qpAv = (qp + qpTmp + 1) >> 1;
- indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
- indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
- thresholds[LEFT].alpha = alphas[indexA];
- thresholds[LEFT].beta = betas[indexB];
- thresholds[LEFT].tc0 = tc0[indexA];
- }
- else
- {
- thresholds[LEFT].alpha = thresholds[INNER].alpha;
- thresholds[LEFT].beta = thresholds[INNER].beta;
- thresholds[LEFT].tc0 = thresholds[INNER].tc0;
- }
- }
- }
- /*------------------------------------------------------------------------------
- Function: GetChromaEdgeThresholds
- Functional description:
- Compute alpha, beta and tc0 thresholds for inner, left and top
- chroma edges of a macroblock.
- ------------------------------------------------------------------------------*/
- void GetChromaEdgeThresholds(
- edgeThreshold_t *thresholds,
- mbStorage_t *mb,
- u32 filteringFlags,
- i32 chromaQpIndexOffset)
- {
- /* Variables */
- u32 indexA, indexB;
- u32 qpAv, qp, qpTmp;
- /* Code */
- ASSERT(thresholds);
- ASSERT(mb);
- qp = mb->qpY;
- qp = h264bsdQpC[CLIP3(0, 51, (i32)qp + chromaQpIndexOffset)];
- indexA = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetA);
- indexB = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetB);
- thresholds[INNER].alpha = alphas[indexA];
- thresholds[INNER].beta = betas[indexB];
- thresholds[INNER].tc0 = tc0[indexA];
- if (filteringFlags & FILTER_TOP_EDGE)
- {
- qpTmp = mb->mbB->qpY;
- if (qpTmp != mb->qpY)
- {
- qpTmp = h264bsdQpC[CLIP3(0, 51, (i32)qpTmp + chromaQpIndexOffset)];
- qpAv = (qp + qpTmp + 1) >> 1;
- indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
- indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
- thresholds[TOP].alpha = alphas[indexA];
- thresholds[TOP].beta = betas[indexB];
- thresholds[TOP].tc0 = tc0[indexA];
- }
- else
- {
- thresholds[TOP].alpha = thresholds[INNER].alpha;
- thresholds[TOP].beta = thresholds[INNER].beta;
- thresholds[TOP].tc0 = thresholds[INNER].tc0;
- }
- }
- if (filteringFlags & FILTER_LEFT_EDGE)
- {
- qpTmp = mb->mbA->qpY;
- if (qpTmp != mb->qpY)
- {
- qpTmp = h264bsdQpC[CLIP3(0, 51, (i32)qpTmp + chromaQpIndexOffset)];
- qpAv = (qp + qpTmp + 1) >> 1;
- indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
- indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
- thresholds[LEFT].alpha = alphas[indexA];
- thresholds[LEFT].beta = betas[indexB];
- thresholds[LEFT].tc0 = tc0[indexA];
- }
- else
- {
- thresholds[LEFT].alpha = thresholds[INNER].alpha;
- thresholds[LEFT].beta = thresholds[INNER].beta;
- thresholds[LEFT].tc0 = thresholds[INNER].tc0;
- }
- }
- }
- /*------------------------------------------------------------------------------
- Function: FilterLuma
- Functional description:
- Function to filter all luma edges of a macroblock
- ------------------------------------------------------------------------------*/
- void FilterLuma(
- u8 *data,
- bS_t *bS,
- edgeThreshold_t *thresholds,
- u32 width)
- {
- /* Variables */
- u32 vblock;
- bS_t *tmp;
- u8 *ptr;
- u32 offset;
- /* Code */
- ASSERT(data);
- ASSERT(bS);
- ASSERT(thresholds);
- ptr = data;
- tmp = bS;
- offset = TOP;
- /* loop block rows, perform filtering for all vertical edges of the block
- * row first, then filter each horizontal edge of the row */
- for (vblock = 4; vblock--;)
- {
- /* only perform filtering if bS is non-zero, first of the four
- * FilterVerLumaEdge handles the left edge of the macroblock, others
- * filter inner edges */
- if (tmp[0].left)
- FilterVerLumaEdge(ptr, tmp[0].left, thresholds + LEFT, width);
- if (tmp[1].left)
- FilterVerLumaEdge(ptr+4, tmp[1].left, thresholds + INNER, width);
- if (tmp[2].left)
- FilterVerLumaEdge(ptr+8, tmp[2].left, thresholds + INNER, width);
- if (tmp[3].left)
- FilterVerLumaEdge(ptr+12, tmp[3].left, thresholds + INNER, width);
- /* if bS is equal for all horizontal edges of the row -> perform
- * filtering with FilterHorLuma, otherwise use FilterHorLumaEdge for
- * each edge separately. offset variable indicates top macroblock edge
- * on the first loop round, inner edge for the other rounds */
- if (tmp[0].top == tmp[1].top && tmp[1].top == tmp[2].top &&
- tmp[2].top == tmp[3].top)
- {
- if(tmp[0].top)
- FilterHorLuma(ptr, tmp[0].top, thresholds + offset, (i32)width);
- }
- else
- {
- if(tmp[0].top)
- FilterHorLumaEdge(ptr, tmp[0].top, thresholds+offset,
- (i32)width);
- if(tmp[1].top)
- FilterHorLumaEdge(ptr+4, tmp[1].top, thresholds+offset,
- (i32)width);
- if(tmp[2].top)
- FilterHorLumaEdge(ptr+8, tmp[2].top, thresholds+offset,
- (i32)width);
- if(tmp[3].top)
- FilterHorLumaEdge(ptr+12, tmp[3].top, thresholds+offset,
- (i32)width);
- }
- /* four pixel rows ahead, i.e. next row of 4x4-blocks */
- ptr += width*4;
- tmp += 4;
- offset = INNER;
- }
- }
- /*------------------------------------------------------------------------------
- Function: FilterChroma
- Functional description:
- Function to filter all chroma edges of a macroblock
- ------------------------------------------------------------------------------*/
- void FilterChroma(
- u8 *dataCb,
- u8 *dataCr,
- bS_t *bS,
- edgeThreshold_t *thresholds,
- u32 width)
- {
- /* Variables */
- u32 vblock;
- bS_t *tmp;
- u32 offset;
- /* Code */
- ASSERT(dataCb);
- ASSERT(dataCr);
- ASSERT(bS);
- ASSERT(thresholds);
- tmp = bS;
- offset = TOP;
- /* loop block rows, perform filtering for all vertical edges of the block
- * row first, then filter each horizontal edge of the row */
- for (vblock = 0; vblock < 2; vblock++)
- {
- /* only perform filtering if bS is non-zero, first two of the four
- * FilterVerChromaEdge calls handle the left edge of the macroblock,
- * others filter the inner edge. Note that as chroma uses bS values
- * determined for luma edges, each bS is used only for 2 pixels of
- * a 4-pixel edge */
- if (tmp[0].left)
- {
- FilterVerChromaEdge(dataCb, tmp[0].left, thresholds + LEFT, width);
- FilterVerChromaEdge(dataCr, tmp[0].left, thresholds + LEFT, width);
- }
- if (tmp[4].left)
- {
- FilterVerChromaEdge(dataCb+2*width, tmp[4].left, thresholds + LEFT,
- width);
- FilterVerChromaEdge(dataCr+2*width, tmp[4].left, thresholds + LEFT,
- width);
- }
- if (tmp[2].left)
- {
- FilterVerChromaEdge(dataCb+4, tmp[2].left, thresholds + INNER,
- width);
- FilterVerChromaEdge(dataCr+4, tmp[2].left, thresholds + INNER,
- width);
- }
- if (tmp[6].left)
- {
- FilterVerChromaEdge(dataCb+2*width+4, tmp[6].left,
- thresholds + INNER, width);
- FilterVerChromaEdge(dataCr+2*width+4, tmp[6].left,
- thresholds + INNER, width);
- }
- /* if bS is equal for all horizontal edges of the row -> perform
- * filtering with FilterHorChroma, otherwise use FilterHorChromaEdge
- * for each edge separately. offset variable indicates top macroblock
- * edge on the first loop round, inner edge for the second */
- if (tmp[0].top == tmp[1].top && tmp[1].top == tmp[2].top &&
- tmp[2].top == tmp[3].top)
- {
- if(tmp[0].top)
- {
- FilterHorChroma(dataCb, tmp[0].top, thresholds+offset,
- (i32)width);
- FilterHorChroma(dataCr, tmp[0].top, thresholds+offset,
- (i32)width);
- }
- }
- else
- {
- if (tmp[0].top)
- {
- FilterHorChromaEdge(dataCb, tmp[0].top, thresholds+offset,
- (i32)width);
- FilterHorChromaEdge(dataCr, tmp[0].top, thresholds+offset,
- (i32)width);
- }
- if (tmp[1].top)
- {
- FilterHorChromaEdge(dataCb+2, tmp[1].top, thresholds+offset,
- (i32)width);
- FilterHorChromaEdge(dataCr+2, tmp[1].top, thresholds+offset,
- (i32)width);
- }
- if (tmp[2].top)
- {
- FilterHorChromaEdge(dataCb+4, tmp[2].top, thresholds+offset,
- (i32)width);
- FilterHorChromaEdge(dataCr+4, tmp[2].top, thresholds+offset,
- (i32)width);
- }
- if (tmp[3].top)
- {
- FilterHorChromaEdge(dataCb+6, tmp[3].top, thresholds+offset,
- (i32)width);
- FilterHorChromaEdge(dataCr+6, tmp[3].top, thresholds+offset,
- (i32)width);
- }
- }
- tmp += 8;
- dataCb += width*4;
- dataCr += width*4;
- offset = INNER;
- }
- }
- #else /* H264DEC_OMXDL */
- /*------------------------------------------------------------------------------
- Function: h264bsdFilterPicture
- Functional description:
- Perform deblocking filtering for a picture. Filter does not copy
- the original picture anywhere but filtering is performed directly
- on the original image. Parameters controlling the filtering process
- are computed based on information in macroblock structures of the
- filtered macroblock, macroblock above and macroblock on the left of
- the filtered one.
- Inputs:
- image pointer to image to be filtered
- mb pointer to macroblock data structure of the top-left
- macroblock of the picture
- Outputs:
- image filtered image stored here
- Returns:
- none
- ------------------------------------------------------------------------------*/
- /*lint --e{550} Symbol not accessed */
- void h264bsdFilterPicture(
- image_t *image,
- mbStorage_t *mb)
- {
- /* Variables */
- u32 flags;
- u32 picSizeInMbs, mbRow, mbCol;
- u32 picWidthInMbs;
- u8 *data;
- mbStorage_t *pMb;
- u8 bS[2][16];
- u8 thresholdLuma[2][16];
- u8 thresholdChroma[2][8];
- u8 alpha[2][2];
- u8 beta[2][2];
- OMXResult res;
- /* Code */
- ASSERT(image);
- ASSERT(mb);
- ASSERT(image->data);
- ASSERT(image->width);
- ASSERT(image->height);
- picWidthInMbs = image->width;
- data = image->data;
- picSizeInMbs = picWidthInMbs * image->height;
- pMb = mb;
- for (mbRow = 0, mbCol = 0; mbRow < image->height; pMb++)
- {
- flags = GetMbFilteringFlags(pMb);
- if (flags)
- {
- /* GetBoundaryStrengths function returns non-zero value if any of
- * the bS values for the macroblock being processed was non-zero */
- if (GetBoundaryStrengths(pMb, bS, flags))
- {
- /* Luma */
- GetLumaEdgeThresholds(pMb,alpha,beta,thresholdLuma,bS,flags);
- data = image->data + mbRow * picWidthInMbs * 256 + mbCol * 16;
- res = omxVCM4P10_FilterDeblockingLuma_VerEdge_I( data,
- (OMX_S32)(picWidthInMbs*16),
- (const OMX_U8*)alpha,
- (const OMX_U8*)beta,
- (const OMX_U8*)thresholdLuma,
- (const OMX_U8*)bS );
- res = omxVCM4P10_FilterDeblockingLuma_HorEdge_I( data,
- (OMX_S32)(picWidthInMbs*16),
- (const OMX_U8*)alpha+2,
- (const OMX_U8*)beta+2,
- (const OMX_U8*)thresholdLuma+16,
- (const OMX_U8*)bS+16 );
- /* Cb */
- GetChromaEdgeThresholds(pMb, alpha, beta, thresholdChroma,
- bS, flags, pMb->chromaQpIndexOffset);
- data = image->data + picSizeInMbs * 256 +
- mbRow * picWidthInMbs * 64 + mbCol * 8;
- res = omxVCM4P10_FilterDeblockingChroma_VerEdge_I( data,
- (OMX_S32)(picWidthInMbs*8),
- (const OMX_U8*)alpha,
- (const OMX_U8*)beta,
- (const OMX_U8*)thresholdChroma,
- (const OMX_U8*)bS );
- res = omxVCM4P10_FilterDeblockingChroma_HorEdge_I( data,
- (OMX_S32)(picWidthInMbs*8),
- (const OMX_U8*)alpha+2,
- (const OMX_U8*)beta+2,
- (const OMX_U8*)thresholdChroma+8,
- (const OMX_U8*)bS+16 );
- /* Cr */
- data += (picSizeInMbs * 64);
- res = omxVCM4P10_FilterDeblockingChroma_VerEdge_I( data,
- (OMX_S32)(picWidthInMbs*8),
- (const OMX_U8*)alpha,
- (const OMX_U8*)beta,
- (const OMX_U8*)thresholdChroma,
- (const OMX_U8*)bS );
- res = omxVCM4P10_FilterDeblockingChroma_HorEdge_I( data,
- (OMX_S32)(picWidthInMbs*8),
- (const OMX_U8*)alpha+2,
- (const OMX_U8*)beta+2,
- (const OMX_U8*)thresholdChroma+8,
- (const OMX_U8*)bS+16 );
- }
- }
- mbCol++;
- if (mbCol == picWidthInMbs)
- {
- mbCol = 0;
- mbRow++;
- }
- }
- }
- /*------------------------------------------------------------------------------
- Function: GetBoundaryStrengths
- Functional description:
- Function to calculate boundary strengths for all edges of a
- macroblock. Function returns HANTRO_TRUE if any of the bS values for
- the macroblock had non-zero value, HANTRO_FALSE otherwise.
- ------------------------------------------------------------------------------*/
- u32 GetBoundaryStrengths(mbStorage_t *mb, u8 (*bS)[16], u32 flags)
- {
- /* Variables */
- /* this flag is set HANTRO_TRUE as soon as any boundary strength value is
- * non-zero */
- u32 nonZeroBs = HANTRO_FALSE;
- u32 *pTmp;
- u32 tmp1, tmp2, isIntraMb;
- /* Code */
- ASSERT(mb);
- ASSERT(bS);
- ASSERT(flags);
- isIntraMb = IS_INTRA_MB(*mb);
- /* top edges */
- pTmp = (u32*)&bS[1][0];
- if (flags & FILTER_TOP_EDGE)
- {
- if (isIntraMb || IS_INTRA_MB(*mb->mbB))
- {
- *pTmp = 0x04040404;
- nonZeroBs = HANTRO_TRUE;
- }
- else
- {
- *pTmp = EdgeBoundaryStrengthTop(mb, mb->mbB);
- if (*pTmp)
- nonZeroBs = HANTRO_TRUE;
- }
- }
- else
- {
- *pTmp = 0;
- }
- /* left edges */
- pTmp = (u32*)&bS[0][0];
- if (flags & FILTER_LEFT_EDGE)
- {
- if (isIntraMb || IS_INTRA_MB(*mb->mbA))
- {
- /*bS[0][0] = bS[0][1] = bS[0][2] = bS[0][3] = 4;*/
- *pTmp = 0x04040404;
- nonZeroBs = HANTRO_TRUE;
- }
- else
- {
- *pTmp = EdgeBoundaryStrengthLeft(mb, mb->mbA);
- if (!nonZeroBs && *pTmp)
- nonZeroBs = HANTRO_TRUE;
- }
- }
- else
- {
- *pTmp = 0;
- }
- /* inner edges */
- if (isIntraMb)
- {
- pTmp++;
- *pTmp++ = 0x03030303;
- *pTmp++ = 0x03030303;
- *pTmp++ = 0x03030303;
- pTmp++;
- *pTmp++ = 0x03030303;
- *pTmp++ = 0x03030303;
- *pTmp = 0x03030303;
- nonZeroBs = HANTRO_TRUE;
- }
- else
- {
- pTmp = (u32*)mb->totalCoeff;
- /* 16x16 inter mb -> ref addresses or motion vectors cannot differ,
- * only check if either of the blocks contain coefficients */
- if (h264bsdNumMbPart(mb->mbType) == 1)
- {
- tmp1 = *pTmp++;
- tmp2 = *pTmp++;
- bS[1][4] = (tmp1 & 0x00FF00FF) ? 2 : 0; /* [2] || [0] */
- bS[1][5] = (tmp1 & 0xFF00FF00) ? 2 : 0; /* [3] || [1] */
- bS[0][4] = (tmp1 & 0x0000FFFF) ? 2 : 0; /* [1] || [0] */
- bS[0][5] = (tmp1 & 0xFFFF0000) ? 2 : 0; /* [3] || [2] */
- tmp1 = *pTmp++;
- bS[1][6] = (tmp2 & 0x00FF00FF) ? 2 : 0; /* [6] || [4] */
- bS[1][7] = (tmp2 & 0xFF00FF00) ? 2 : 0; /* [7] || [5] */
- bS[0][12] = (tmp2 & 0x0000FFFF) ? 2 : 0; /* [5] || [4] */
- bS[0][13] = (tmp2 & 0xFFFF0000) ? 2 : 0; /* [7] || [6] */
- tmp2 = *pTmp;
- bS[1][12] = (tmp1 & 0x00FF00FF) ? 2 : 0; /* [10] || [8] */
- bS[1][13] = (tmp1 & 0xFF00FF00) ? 2 : 0; /* [11] || [9] */
- bS[0][6] = (tmp1 & 0x0000FFFF) ? 2 : 0; /* [9] || [8] */
- bS[0][7] = (tmp1 & 0xFFFF0000) ? 2 : 0; /* [11] || [10] */
- bS[1][14] = (tmp2 & 0x00FF00FF) ? 2 : 0; /* [14] || [12] */
- bS[1][15] = (tmp2 & 0xFF00FF00) ? 2 : 0; /* [15] || [13] */
- bS[0][14] = (tmp2 & 0x0000FFFF) ? 2 : 0; /* [13] || [12] */
- bS[0][15] = (tmp2 & 0xFFFF0000) ? 2 : 0; /* [15] || [14] */
- {
- u32 tmp3, tmp4;
- tmp1 = mb->totalCoeff[8];
- tmp2 = mb->totalCoeff[2];
- tmp3 = mb->totalCoeff[9];
- tmp4 = mb->totalCoeff[3];
- bS[1][8] = tmp1 || tmp2 ? 2 : 0;
- tmp1 = mb->totalCoeff[12];
- tmp2 = mb->totalCoeff[6];
- bS[1][9] = tmp3 || tmp4 ? 2 : 0;
- tmp3 = mb->totalCoeff[13];
- tmp4 = mb->totalCoeff[7];
- bS[1][10] = tmp1 || tmp2 ? 2 : 0;
- tmp1 = mb->totalCoeff[4];
- tmp2 = mb->totalCoeff[1];
- bS[1][11] = tmp3 || tmp4 ? 2 : 0;
- tmp3 = mb->totalCoeff[6];
- tmp4 = mb->totalCoeff[3];
- bS[0][8] = tmp1 || tmp2 ? 2 : 0;
- tmp1 = mb->totalCoeff[12];
- tmp2 = mb->totalCoeff[9];
- bS[0][9] = tmp3 || tmp4 ? 2 : 0;
- tmp3 = mb->totalCoeff[14];
- tmp4 = mb->totalCoeff[11];
- bS[0][10] = tmp1 || tmp2 ? 2 : 0;
- bS[0][11] = tmp3 || tmp4 ? 2 : 0;
- }
- }
- /* 16x8 inter mb -> ref addresses and motion vectors can be different
- * only for the middle horizontal edge, for the other top edges it is
- * enough to check whether the blocks contain coefficients or not. The
- * same applies to all internal left edges. */
- else if (mb->mbType == P_L0_L0_16x8)
- {
- tmp1 = *pTmp++;
- tmp2 = *pTmp++;
- bS[1][4] = (tmp1 & 0x00FF00FF) ? 2 : 0; /* [2] || [0] */
- bS[1][5] = (tmp1 & 0xFF00FF00) ? 2 : 0; /* [3] || [1] */
- bS[0][4] = (tmp1 & 0x0000FFFF) ? 2 : 0; /* [1] || [0] */
- bS[0][5] = (tmp1 & 0xFFFF0000) ? 2 : 0; /* [3] || [2] */
- tmp1 = *pTmp++;
- bS[1][6] = (tmp2 & 0x00FF00FF) ? 2 : 0; /* [6] || [4] */
- bS[1][7] = (tmp2 & 0xFF00FF00) ? 2 : 0; /* [7] || [5] */
- bS[0][12] = (tmp2 & 0x0000FFFF) ? 2 : 0; /* [5] || [4] */
- bS[0][13] = (tmp2 & 0xFFFF0000) ? 2 : 0; /* [7] || [6] */
- tmp2 = *pTmp;
- bS[1][12] = (tmp1 & 0x00FF00FF) ? 2 : 0; /* [10] || [8] */
- bS[1][13] = (tmp1 & 0xFF00FF00) ? 2 : 0; /* [11] || [9] */
- bS[0][6] = (tmp1 & 0x0000FFFF) ? 2 : 0; /* [9] || [8] */
- bS[0][7] = (tmp1 & 0xFFFF0000) ? 2 : 0; /* [11] || [10] */
- bS[1][14] = (tmp2 & 0x00FF00FF) ? 2 : 0; /* [14] || [12] */
- bS[1][15] = (tmp2 & 0xFF00FF00) ? 2 : 0; /* [15] || [13] */
- bS[0][14] = (tmp2 & 0x0000FFFF) ? 2 : 0; /* [13] || [12] */
- bS[0][15] = (tmp2 & 0xFFFF0000) ? 2 : 0; /* [15] || [14] */
- bS[1][8] = (u8)InnerBoundaryStrength(mb, 8, 2);
- bS[1][9] = (u8)InnerBoundaryStrength(mb, 9, 3);
- bS[1][10] = (u8)InnerBoundaryStrength(mb, 12, 6);
- bS[1][11] = (u8)InnerBoundaryStrength(mb, 13, 7);
- {
- u32 tmp3, tmp4;
- tmp1 = mb->totalCoeff[4];
- tmp2 = mb->totalCoeff[1];
- tmp3 = mb->totalCoeff[6];
- tmp4 = mb->totalCoeff[3];
- bS[0][8] = tmp1 || tmp2 ? 2 : 0;
- tmp1 = mb->totalCoeff[12];
- tmp2 = mb->totalCoeff[9];
- bS[0][9] = tmp3 || tmp4 ? 2 : 0;
- tmp3 = mb->totalCoeff[14];
- tmp4 = mb->totalCoeff[11];
- bS[0][10] = tmp1 || tmp2 ? 2 : 0;
- bS[0][11] = tmp3 || tmp4 ? 2 : 0;
- }
- }
- /* 8x16 inter mb -> ref addresses and motion vectors can be different
- * only for the middle vertical edge, for the other left edges it is
- * enough to check whether the blocks contain coefficients or not. The
- * same applies to all internal top edges. */
- else if (mb->mbType == P_L0_L0_8x16)
- {
- tmp1 = *pTmp++;
- tmp2 = *pTmp++;
- bS[1][4] = (tmp1 & 0x00FF00FF) ? 2 : 0; /* [2] || [0] */
- bS[1][5] = (tmp1 & 0xFF00FF00) ? 2 : 0; /* [3] || [1] */
- bS[0][4] = (tmp1 & 0x0000FFFF) ? 2 : 0; /* [1] || [0] */
- bS[0][5] = (tmp1 & 0xFFFF0000) ? 2 : 0; /* [3] || [2] */
- tmp1 = *pTmp++;
- bS[1][6] = (tmp2 & 0x00FF00FF) ? 2 : 0; /* [6] || [4] */
- bS[1][7] = (tmp2 & 0xFF00FF00) ? 2 : 0; /* [7] || [5] */
- bS[0][12] = (tmp2 & 0x0000FFFF) ? 2 : 0; /* [5] || [4] */
- bS[0][13] = (tmp2 & 0xFFFF0000) ? 2 : 0; /* [7] || [6] */
- tmp2 = *pTmp;
- bS[1][12] = (tmp1 & 0x00FF00FF) ? 2 : 0; /* [10] || [8] */
- bS[1][13] = (tmp1 & 0xFF00FF00) ? 2 : 0; /* [11] || [9] */
- bS[0][6] = (tmp1 & 0x0000FFFF) ? 2 : 0; /* [9] || [8] */
- bS[0][7] = (tmp1 & 0xFFFF0000) ? 2 : 0; /* [11] || [10] */
- bS[1][14] = (tmp2 & 0x00FF00FF) ? 2 : 0; /* [14] || [12] */
- bS[1][15] = (tmp2 & 0xFF00FF00) ? 2 : 0; /* [15] || [13] */
- bS[0][14] = (tmp2 & 0x0000FFFF) ? 2 : 0; /* [13] || [12] */
- bS[0][15] = (tmp2 & 0xFFFF0000) ? 2 : 0; /* [15] || [14] */
- bS[0][8] = (u8)InnerBoundaryStrength(mb, 4, 1);
- bS[0][9] = (u8)InnerBoundaryStrength(mb, 6, 3);
- bS[0][10] = (u8)InnerBoundaryStrength(mb, 12, 9);
- bS[0][11] = (u8)InnerBoundaryStrength(mb, 14, 11);
- {
- u32 tmp3, tmp4;
- tmp1 = mb->totalCoeff[8];
- tmp2 = mb->totalCoeff[2];
- tmp3 = mb->totalCoeff[9];
- tmp4 = mb->totalCoeff[3];
- bS[1][8] = tmp1 || tmp2 ? 2 : 0;
- tmp1 = mb->totalCoeff[12];
- tmp2 = mb->totalCoeff[6];
- bS[1][9] = tmp3 || tmp4 ? 2 : 0;
- tmp3 = mb->totalCoeff[13];
- tmp4 = mb->totalCoeff[7];
- bS[1][10] = tmp1 || tmp2 ? 2 : 0;
- bS[1][11] = tmp3 || tmp4 ? 2 : 0;
- }
- }
- else
- {
- tmp1 = *pTmp++;
- bS[1][4] = (tmp1 & 0x00FF00FF) ? 2 : (u8)InnerBoundaryStrength2(mb, 2, 0);
- bS[1][5] = (tmp1 & 0xFF00FF00) ? 2 : (u8)InnerBoundaryStrength2(mb, 3, 1);
- bS[0][4] = (tmp1 & 0x0000FFFF) ? 2 : (u8)InnerBoundaryStrength2(mb, 1, 0);
- bS[0][5] = (tmp1 & 0xFFFF0000) ? 2 : (u8)InnerBoundaryStrength2(mb, 3, 2);
- tmp1 = *pTmp++;
- bS[1][6] = (tmp1 & 0x00FF00FF) ? 2 : (u8)InnerBoundaryStrength2(mb, 6, 4);
- bS[1][7] = (tmp1 & 0xFF00FF00) ? 2 : (u8)InnerBoundaryStrength2(mb, 7, 5);
- bS[0][12] = (tmp1 & 0x0000FFFF) ? 2 : (u8)InnerBoundaryStrength2(mb, 5, 4);
- bS[0][13] = (tmp1 & 0xFFFF0000) ? 2 : (u8)InnerBoundaryStrength2(mb, 7, 6);
- tmp1 = *pTmp++;
- bS[1][12] = (tmp1 & 0x00FF00FF) ? 2 : (u8)InnerBoundaryStrength2(mb, 10, 8);
- bS[1][13] = (tmp1 & 0xFF00FF00) ? 2 : (u8)InnerBoundaryStrength2(mb, 11, 9);
- bS[0][6] = (tmp1 & 0x0000FFFF) ? 2 : (u8)InnerBoundaryStrength2(mb, 9, 8);
- bS[0][7] = (tmp1 & 0xFFFF0000) ? 2 : (u8)InnerBoundaryStrength2(mb, 11, 10);
- tmp1 = *pTmp;
- bS[1][14] = (tmp1 & 0x00FF00FF) ? 2 : (u8)InnerBoundaryStrength2(mb, 14, 12);
- bS[1][15] = (tmp1 & 0xFF00FF00) ? 2 : (u8)InnerBoundaryStrength2(mb, 15, 13);
- bS[0][14] = (tmp1 & 0x0000FFFF) ? 2 : (u8)InnerBoundaryStrength2(mb, 13, 12);
- bS[0][15] = (tmp1 & 0xFFFF0000) ? 2 : (u8)InnerBoundaryStrength2(mb, 15, 14);
- bS[1][8] = (u8)InnerBoundaryStrength(mb, 8, 2);
- bS[1][9] = (u8)InnerBoundaryStrength(mb, 9, 3);
- bS[1][10] = (u8)InnerBoundaryStrength(mb, 12, 6);
- bS[1][11] = (u8)InnerBoundaryStrength(mb, 13, 7);
- bS[0][8] = (u8)InnerBoundaryStrength(mb, 4, 1);
- bS[0][9] = (u8)InnerBoundaryStrength(mb, 6, 3);
- bS[0][10] = (u8)InnerBoundaryStrength(mb, 12, 9);
- bS[0][11] = (u8)InnerBoundaryStrength(mb, 14, 11);
- }
- pTmp = (u32*)&bS[0][0];
- if (!nonZeroBs && (pTmp[1] || pTmp[2] || pTmp[3] ||
- pTmp[5] || pTmp[6] || pTmp[7]) )
- {
- nonZeroBs = HANTRO_TRUE;
- }
- }
- return(nonZeroBs);
- }
- /*------------------------------------------------------------------------------
- Function: GetLumaEdgeThresholds
- Functional description:
- Compute alpha, beta and tc0 thresholds for inner, left and top
- luma edges of a macroblock.
- ------------------------------------------------------------------------------*/
- void GetLumaEdgeThresholds(
- mbStorage_t *mb,
- u8 (*alpha)[2],
- u8 (*beta)[2],
- u8 (*threshold)[16],
- u8 (*bs)[16],
- u32 filteringFlags )
- {
- /* Variables */
- u32 indexA, indexB;
- u32 qpAv, qp, qpTmp;
- u32 i;
- /* Code */
- ASSERT(threshold);
- ASSERT(bs);
- ASSERT(beta);
- ASSERT(alpha);
- ASSERT(mb);
- qp = mb->qpY;
- indexA = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetA);
- indexB = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetB);
- /* Internal edge values */
- alpha[0][1] = alphas[indexA];
- alpha[1][1] = alphas[indexA];
- alpha[1][0] = alphas[indexA];
- alpha[0][0] = alphas[indexA];
- beta[0][1] = betas[indexB];
- beta[1][1] = betas[indexB];
- beta[1][0] = betas[indexB];
- beta[0][0] = betas[indexB];
- /* vertical scan order */
- for (i = 0; i < 2; i++)
- {
- u32 t1, t2;
- t1 = bs[i][0];
- t2 = bs[i][1];
- threshold[i][0] = (t1) ? tc0[indexA][t1] : 0;
- t1 = bs[i][2];
- threshold[i][1] = (t2) ? tc0[indexA][t2] : 0;
- t2 = bs[i][3];
- threshold[i][2] = (t1) ? tc0[indexA][t1] : 0;
- t1 = bs[i][4];
- threshold[i][3] = (t2) ? tc0[indexA][t2] : 0;
- t2 = bs[i][5];
- threshold[i][4] = (t1) ? tc0[indexA][t1] : 0;
- t1 = bs[i][6];
- threshold[i][5] = (t2) ? tc0[indexA][t2] : 0;
- t2 = bs[i][7];
- threshold[i][6] = (t1) ? tc0[indexA][t1] : 0;
- t1 = bs[i][8];
- threshold[i][7] = (t2) ? tc0[indexA][t2] : 0;
- t2 = bs[i][9];
- threshold[i][8] = (t1) ? tc0[indexA][t1] : 0;
- t1 = bs[i][10];
- threshold[i][9] = (t2) ? tc0[indexA][t2] : 0;
- t2 = bs[i][11];
- threshold[i][10] = (t1) ? tc0[indexA][t1] : 0;
- t1 = bs[i][12];
- threshold[i][11] = (t2) ? tc0[indexA][t2] : 0;
- t2 = bs[i][13];
- threshold[i][12] = (t1) ? tc0[indexA][t1] : 0;
- t1 = bs[i][14];
- threshold[i][13] = (t2) ? tc0[indexA][t2] : 0;
- t2 = bs[i][15];
- threshold[i][14] = (t1) ? tc0[indexA][t1] : 0;
- threshold[i][15] = (t2) ? tc0[indexA][t2] : 0;
- }
- if (filteringFlags & FILTER_TOP_EDGE)
- {
- qpTmp = mb->mbB->qpY;
- if (qpTmp != qp)
- {
- u32 t1, t2, t3, t4;
- qpAv = (qp + qpTmp + 1) >> 1;
- indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
- indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
- alpha[1][0] = alphas[indexA];
- beta[1][0] = betas[indexB];
- t1 = bs[1][0];
- t2 = bs[1][1];
- t3 = bs[1][2];
- t4 = bs[1][3];
- threshold[1][0] = (t1 && (t1 < 4)) ? tc0[indexA][t1] : 0;
- threshold[1][1] = (t2 && (t2 < 4)) ? tc0[indexA][t2] : 0;
- threshold[1][2] = (t3 && (t3 < 4)) ? tc0[indexA][t3] : 0;
- threshold[1][3] = (t4 && (t4 < 4)) ? tc0[indexA][t4] : 0;
- }
- }
- if (filteringFlags & FILTER_LEFT_EDGE)
- {
- qpTmp = mb->mbA->qpY;
- if (qpTmp != qp)
- {
- qpAv = (qp + qpTmp + 1) >> 1;
- indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
- indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
- alpha[0][0] = alphas[indexA];
- beta[0][0] = betas[indexB];
- threshold[0][0] = (bs[0][0] && (bs[0][0] < 4)) ? tc0[indexA][bs[0][0]] : 0;
- threshold[0][1] = (bs[0][1] && (bs[0][1] < 4)) ? tc0[indexA][bs[0][1]] : 0;
- threshold[0][2] = (bs[0][2] && (bs[0][2] < 4)) ? tc0[indexA][bs[0][2]] : 0;
- threshold[0][3] = (bs[0][3] && (bs[0][3] < 4)) ? tc0[indexA][bs[0][3]] : 0;
- }
- }
- }
- /*------------------------------------------------------------------------------
- Function: GetChromaEdgeThresholds
- Functional description:
- Compute alpha, beta and tc0 thresholds for inner, left and top
- chroma edges of a macroblock.
- ------------------------------------------------------------------------------*/
- void GetChromaEdgeThresholds(
- mbStorage_t *mb,
- u8 (*alpha)[2],
- u8 (*beta)[2],
- u8 (*threshold)[8],
- u8 (*bs)[16],
- u32 filteringFlags,
- i32 chromaQpIndexOffset)
- {
- /* Variables */
- u32 indexA, indexB;
- u32 qpAv, qp, qpTmp;
- u32 i;
- /* Code */
- ASSERT(threshold);
- ASSERT(bs);
- ASSERT(beta);
- ASSERT(alpha);
- ASSERT(mb);
- ASSERT(mb);
- qp = mb->qpY;
- qp = h264bsdQpC[CLIP3(0, 51, (i32)qp + chromaQpIndexOffset)];
- indexA = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetA);
- indexB = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetB);
- alpha[0][1] = alphas[indexA];
- alpha[1][1] = alphas[indexA];
- alpha[1][0] = alphas[indexA];
- alpha[0][0] = alphas[indexA];
- beta[0][1] = betas[indexB];
- beta[1][1] = betas[indexB];
- beta[1][0] = betas[indexB];
- beta[0][0] = betas[indexB];
- for (i = 0; i < 2; i++)
- {
- u32 t1, t2;
- t1 = bs[i][0];
- t2 = bs[i][1];
- threshold[i][0] = (t1) ? tc0[indexA][t1] : 0;
- t1 = bs[i][2];
- threshold[i][1] = (t2) ? tc0[indexA][t2] : 0;
- t2 = bs[i][3];
- threshold[i][2] = (t1) ? tc0[indexA][t1] : 0;
- t1 = bs[i][8];
- threshold[i][3] = (t2) ? tc0[indexA][t2] : 0;
- t2 = bs[i][9];
- threshold[i][4] = (t1) ? tc0[indexA][t1] : 0;
- t1 = bs[i][10];
- threshold[i][5] = (t2) ? tc0[indexA][t2] : 0;
- t2 = bs[i][11];
- threshold[i][6] = (t1) ? tc0[indexA][t1] : 0;
- threshold[i][7] = (t2) ? tc0[indexA][t2] : 0;
- }
- if (filteringFlags & FILTER_TOP_EDGE)
- {
- qpTmp = mb->mbB->qpY;
- if (qpTmp != mb->qpY)
- {
- u32 t1, t2, t3, t4;
- qpTmp = h264bsdQpC[CLIP3(0, 51, (i32)qpTmp + chromaQpIndexOffset)];
- qpAv = (qp + qpTmp + 1) >> 1;
- indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
- indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
- alpha[1][0] = alphas[indexA];
- beta[1][0] = betas[indexB];
- t1 = bs[1][0];
- t2 = bs[1][1];
- t3 = bs[1][2];
- t4 = bs[1][3];
- threshold[1][0] = (t1) ? tc0[indexA][t1] : 0;
- threshold[1][1] = (t2) ? tc0[indexA][t2] : 0;
- threshold[1][2] = (t3) ? tc0[indexA][t3] : 0;
- threshold[1][3] = (t4) ? tc0[indexA][t4] : 0;
- }
- }
- if (filteringFlags & FILTER_LEFT_EDGE)
- {
- qpTmp = mb->mbA->qpY;
- if (qpTmp != mb->qpY)
- {
- qpTmp = h264bsdQpC[CLIP3(0, 51, (i32)qpTmp + chromaQpIndexOffset)];
- qpAv = (qp + qpTmp + 1) >> 1;
- indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
- indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
- alpha[0][0] = alphas[indexA];
- beta[0][0] = betas[indexB];
- threshold[0][0] = (bs[0][0]) ? tc0[indexA][bs[0][0]] : 0;
- threshold[0][1] = (bs[0][1]) ? tc0[indexA][bs[0][1]] : 0;
- threshold[0][2] = (bs[0][2]) ? tc0[indexA][bs[0][2]] : 0;
- threshold[0][3] = (bs[0][3]) ? tc0[indexA][bs[0][3]] : 0;
- }
- }
- }
- #endif /* H264DEC_OMXDL */
- /*lint +e701 +e702 */