summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/on2/h264dec/source/h264bsd_conceal.c
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/codecs/on2/h264dec/source/h264bsd_conceal.c')
-rwxr-xr-xmedia/libstagefright/codecs/on2/h264dec/source/h264bsd_conceal.c626
1 files changed, 0 insertions, 626 deletions
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_conceal.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_conceal.c
deleted file mode 100755
index 493fb9e..0000000
--- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_conceal.c
+++ /dev/null
@@ -1,626 +0,0 @@
-/*
- * 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
- h264bsdConceal
- ConcealMb
- Transform
-
-------------------------------------------------------------------------------*/
-
-/*------------------------------------------------------------------------------
- 1. Include headers
-------------------------------------------------------------------------------*/
-
-#include "h264bsd_conceal.h"
-#include "h264bsd_util.h"
-#include "h264bsd_reconstruct.h"
-#include "h264bsd_dpb.h"
-
-/*------------------------------------------------------------------------------
- 2. External compiler flags
---------------------------------------------------------------------------------
-
---------------------------------------------------------------------------------
- 3. Module defines
-------------------------------------------------------------------------------*/
-
-/*lint -e702 disable lint warning on right shift of signed quantity */
-
-/*------------------------------------------------------------------------------
- 4. Local function prototypes
-------------------------------------------------------------------------------*/
-
-static u32 ConcealMb(mbStorage_t *pMb, image_t *currImage, u32 row, u32 col,
- u32 sliceType, u8 *data);
-
-static void Transform(i32 *data);
-
-/*------------------------------------------------------------------------------
-
- Function name: h264bsdConceal
-
- Functional description:
- Perform error concealment for a picture. Two types of concealment
- is performed based on sliceType:
- 1) copy from previous picture for P-slices.
- 2) concealment from neighbour pixels for I-slices
-
- I-type concealment is based on ideas presented by Jarno Tulkki.
- The concealment algorithm determines frequency domain coefficients
- from the neighbour pixels, applies integer transform (the same
- transform used in the residual processing) and uses the results as
- pixel values for concealed macroblocks. Transform produces 4x4
- array and one pixel value has to be used for 4x4 luma blocks and
- 2x2 chroma blocks.
-
- Similar concealment is performed for whole picture (the choise
- of the type is based on last successfully decoded slice header of
- the picture but it is handled by the calling function). It is
- acknowledged that this may result in wrong type of concealment
- when a picture contains both types of slices. However,
- determination of slice type macroblock-by-macroblock cannot
- be done due to the fact that it is impossible to know to which
- slice each corrupted (not successfully decoded) macroblock
- belongs.
-
- The error concealment is started by searching the first propoerly
- decoded macroblock and concealing the row containing the macroblock
- in question. After that all macroblocks above the row in question
- are concealed. Finally concealment of rows below is performed.
- The order of concealment for 4x4 picture where macroblock 9 is the
- first properly decoded one is as follows (properly decoded
- macroblocks marked with 'x', numbers indicating the order of
- concealment):
-
- 4 6 8 10
- 3 5 7 9
- 1 x x 2
- 11 12 13 14
-
- If all macroblocks of the picture are lost, the concealment is
- copy of previous picture for P-type and setting the image to
- constant gray (pixel value 128) for I-type.
-
- Concealment sets quantization parameter of the concealed
- macroblocks to value 40 and macroblock type to intra to enable
- deblocking filter to smooth the edges of the concealed areas.
-
- Inputs:
- pStorage pointer to storage structure
- currImage pointer to current image structure
- sliceType type of the slice
-
- Outputs:
- currImage concealed macroblocks will be written here
-
- Returns:
- HANTRO_OK
-
-------------------------------------------------------------------------------*/
-
-u32 h264bsdConceal(storage_t *pStorage, image_t *currImage, u32 sliceType)
-{
-
-/* Variables */
-
- u32 i, j;
- u32 row, col;
- u32 width, height;
- u8 *refData;
- mbStorage_t *mb;
-
-/* Code */
-
- ASSERT(pStorage);
- ASSERT(currImage);
-
- DEBUG(("Concealing %s slice\n", IS_I_SLICE(sliceType) ?
- "intra" : "inter"));
-
- width = currImage->width;
- height = currImage->height;
- refData = NULL;
- /* use reference picture with smallest available index */
- if (IS_P_SLICE(sliceType) || (pStorage->intraConcealmentFlag != 0))
- {
- i = 0;
- do
- {
- refData = h264bsdGetRefPicData(pStorage->dpb, i);
- i++;
- if (i >= 16)
- break;
- } while (refData == NULL);
- }
-
- i = row = col = 0;
- /* find first properly decoded macroblock -> start point for concealment */
- while (i < pStorage->picSizeInMbs && !pStorage->mb[i].decoded)
- {
- i++;
- col++;
- if (col == width)
- {
- row++;
- col = 0;
- }
- }
-
- /* whole picture lost -> copy previous or set grey */
- if (i == pStorage->picSizeInMbs)
- {
- if ( (IS_I_SLICE(sliceType) && (pStorage->intraConcealmentFlag == 0)) ||
- refData == NULL)
- H264SwDecMemset(currImage->data, 128, width*height*384);
- else
- H264SwDecMemcpy(currImage->data, refData, width*height*384);
-
- pStorage->numConcealedMbs = pStorage->picSizeInMbs;
-
- /* no filtering if whole picture concealed */
- for (i = 0; i < pStorage->picSizeInMbs; i++)
- pStorage->mb[i].disableDeblockingFilterIdc = 1;
-
- return(HANTRO_OK);
- }
-
- /* start from the row containing the first correct macroblock, conceal the
- * row in question, all rows above that row and then continue downwards */
- mb = pStorage->mb + row * width;
- for (j = col; j--;)
- {
- ConcealMb(mb+j, currImage, row, j, sliceType, refData);
- mb[j].decoded = 1;
- pStorage->numConcealedMbs++;
- }
- for (j = col + 1; j < width; j++)
- {
- if (!mb[j].decoded)
- {
- ConcealMb(mb+j, currImage, row, j, sliceType, refData);
- mb[j].decoded = 1;
- pStorage->numConcealedMbs++;
- }
- }
- /* if previous row(s) could not be concealed -> conceal them now */
- if (row)
- {
- for (j = 0; j < width; j++)
- {
- i = row - 1;
- mb = pStorage->mb + i*width + j;
- do
- {
- ConcealMb(mb, currImage, i, j, sliceType, refData);
- mb->decoded = 1;
- pStorage->numConcealedMbs++;
- mb -= width;
- } while(i--);
- }
- }
-
- /* process rows below the one containing the first correct macroblock */
- for (i = row + 1; i < height; i++)
- {
- mb = pStorage->mb + i * width;
-
- for (j = 0; j < width; j++)
- {
- if (!mb[j].decoded)
- {
- ConcealMb(mb+j, currImage, i, j, sliceType, refData);
- mb[j].decoded = 1;
- pStorage->numConcealedMbs++;
- }
- }
- }
-
- return(HANTRO_OK);
-}
-
-/*------------------------------------------------------------------------------
-
- Function name: ConcealMb
-
- Functional description:
- Perform error concealment for one macroblock, location of the
- macroblock in the picture indicated by row and col
-
-------------------------------------------------------------------------------*/
-
-u32 ConcealMb(mbStorage_t *pMb, image_t *currImage, u32 row, u32 col,
- u32 sliceType, u8 *refData)
-{
-
-/* Variables */
-
- u32 i, j, comp;
- u32 hor, ver;
- u32 mbNum;
- u32 width, height;
- u8 *mbPos;
- u8 data[384];
- u8 *pData;
- i32 tmp;
- i32 firstPhase[16];
- i32 *pTmp;
- /* neighbours above, below, left and right */
- i32 a[4], b[4], l[4], r[4];
- u32 A, B, L, R;
-#ifdef H264DEC_OMXDL
- u8 fillBuff[32*21 + 15 + 32];
- u8 *pFill;
-#endif
-/* Code */
-
- ASSERT(pMb);
- ASSERT(!pMb->decoded);
- ASSERT(currImage);
- ASSERT(col < currImage->width);
- ASSERT(row < currImage->height);
-
-#ifdef H264DEC_OMXDL
- pFill = ALIGN(fillBuff, 16);
-#endif
- width = currImage->width;
- height = currImage->height;
- mbNum = row * width + col;
-
- h264bsdSetCurrImageMbPointers(currImage, mbNum);
-
- mbPos = currImage->data + row * 16 * width * 16 + col * 16;
- A = B = L = R = HANTRO_FALSE;
-
- /* set qpY to 40 to enable some filtering in deblocking (stetson value) */
- pMb->qpY = 40;
- pMb->disableDeblockingFilterIdc = 0;
- /* mbType set to intra to perform filtering despite the values of other
- * boundary strength determination fields */
- pMb->mbType = I_4x4;
- pMb->filterOffsetA = 0;
- pMb->filterOffsetB = 0;
- pMb->chromaQpIndexOffset = 0;
-
- if (IS_I_SLICE(sliceType))
- H264SwDecMemset(data, 0, sizeof(data));
- else
- {
- mv_t mv = {0,0};
- image_t refImage;
- refImage.width = width;
- refImage.height = height;
- refImage.data = refData;
- if (refImage.data)
- {
-#ifndef H264DEC_OMXDL
- h264bsdPredictSamples(data, &mv, &refImage, col*16, row*16,
- 0, 0, 16, 16);
-#else
- h264bsdPredictSamples(data, &mv, &refImage,
- ((row*16) + ((col*16)<<16)),
- 0x00001010, pFill);
-#endif
- h264bsdWriteMacroblock(currImage, data);
-
- return(HANTRO_OK);
- }
- else
- H264SwDecMemset(data, 0, sizeof(data));
- }
-
- H264SwDecMemset(firstPhase, 0, sizeof(firstPhase));
-
- /* counter for number of neighbours used */
- j = 0;
- hor = ver = 0;
- if (row && (pMb-width)->decoded)
- {
- A = HANTRO_TRUE;
- pData = mbPos - width*16;
- a[0] = *pData++; a[0] += *pData++; a[0] += *pData++; a[0] += *pData++;
- a[1] = *pData++; a[1] += *pData++; a[1] += *pData++; a[1] += *pData++;
- a[2] = *pData++; a[2] += *pData++; a[2] += *pData++; a[2] += *pData++;
- a[3] = *pData++; a[3] += *pData++; a[3] += *pData++; a[3] += *pData++;
- j++;
- hor++;
- firstPhase[0] += a[0] + a[1] + a[2] + a[3];
- firstPhase[1] += a[0] + a[1] - a[2] - a[3];
- }
- if ((row != height - 1) && (pMb+width)->decoded)
- {
- B = HANTRO_TRUE;
- pData = mbPos + 16*width*16;
- b[0] = *pData++; b[0] += *pData++; b[0] += *pData++; b[0] += *pData++;
- b[1] = *pData++; b[1] += *pData++; b[1] += *pData++; b[1] += *pData++;
- b[2] = *pData++; b[2] += *pData++; b[2] += *pData++; b[2] += *pData++;
- b[3] = *pData++; b[3] += *pData++; b[3] += *pData++; b[3] += *pData++;
- j++;
- hor++;
- firstPhase[0] += b[0] + b[1] + b[2] + b[3];
- firstPhase[1] += b[0] + b[1] - b[2] - b[3];
- }
- if (col && (pMb-1)->decoded)
- {
- L = HANTRO_TRUE;
- pData = mbPos - 1;
- l[0] = pData[0]; l[0] += pData[16*width];
- l[0] += pData[32*width]; l[0] += pData[48*width];
- pData += 64*width;
- l[1] = pData[0]; l[1] += pData[16*width];
- l[1] += pData[32*width]; l[1] += pData[48*width];
- pData += 64*width;
- l[2] = pData[0]; l[2] += pData[16*width];
- l[2] += pData[32*width]; l[2] += pData[48*width];
- pData += 64*width;
- l[3] = pData[0]; l[3] += pData[16*width];
- l[3] += pData[32*width]; l[3] += pData[48*width];
- j++;
- ver++;
- firstPhase[0] += l[0] + l[1] + l[2] + l[3];
- firstPhase[4] += l[0] + l[1] - l[2] - l[3];
- }
- if ((col != width - 1) && (pMb+1)->decoded)
- {
- R = HANTRO_TRUE;
- pData = mbPos + 16;
- r[0] = pData[0]; r[0] += pData[16*width];
- r[0] += pData[32*width]; r[0] += pData[48*width];
- pData += 64*width;
- r[1] = pData[0]; r[1] += pData[16*width];
- r[1] += pData[32*width]; r[1] += pData[48*width];
- pData += 64*width;
- r[2] = pData[0]; r[2] += pData[16*width];
- r[2] += pData[32*width]; r[2] += pData[48*width];
- pData += 64*width;
- r[3] = pData[0]; r[3] += pData[16*width];
- r[3] += pData[32*width]; r[3] += pData[48*width];
- j++;
- ver++;
- firstPhase[0] += r[0] + r[1] + r[2] + r[3];
- firstPhase[4] += r[0] + r[1] - r[2] - r[3];
- }
-
- /* at least one properly decoded neighbour available */
- ASSERT(j);
-
- /*lint -esym(644,l,r,a,b) variable initialized above */
- if (!hor && L && R)
- firstPhase[1] = (l[0]+l[1]+l[2]+l[3]-r[0]-r[1]-r[2]-r[3]) >> 5;
- else if (hor)
- firstPhase[1] >>= (3+hor);
-
- if (!ver && A && B)
- firstPhase[4] = (a[0]+a[1]+a[2]+a[3]-b[0]-b[1]-b[2]-b[3]) >> 5;
- else if (ver)
- firstPhase[4] >>= (3+ver);
-
- switch (j)
- {
- case 1:
- firstPhase[0] >>= 4;
- break;
-
- case 2:
- firstPhase[0] >>= 5;
- break;
-
- case 3:
- /* approximate (firstPhase[0]*4/3)>>6 */
- firstPhase[0] = (21 * firstPhase[0]) >> 10;
- break;
-
- default: /* 4 */
- firstPhase[0] >>= 6;
- break;
-
- }
-
-
- Transform(firstPhase);
-
- for (i = 0, pData = data, pTmp = firstPhase; i < 256;)
- {
- tmp = pTmp[(i & 0xF)>>2];
- /*lint -e734 CLIP1 macro results in value that fits into 8 bits */
- *pData++ = CLIP1(tmp);
- /*lint +e734 */
-
- i++;
- if (!(i & 0x3F))
- pTmp += 4;
- }
-
- /* chroma components */
- mbPos = currImage->data + width * height * 256 +
- row * 8 * width * 8 + col * 8;
- for (comp = 0; comp < 2; comp++)
- {
-
- H264SwDecMemset(firstPhase, 0, sizeof(firstPhase));
-
- /* counter for number of neighbours used */
- j = 0;
- hor = ver = 0;
- if (A)
- {
- pData = mbPos - width*8;
- a[0] = *pData++; a[0] += *pData++;
- a[1] = *pData++; a[1] += *pData++;
- a[2] = *pData++; a[2] += *pData++;
- a[3] = *pData++; a[3] += *pData++;
- j++;
- hor++;
- firstPhase[0] += a[0] + a[1] + a[2] + a[3];
- firstPhase[1] += a[0] + a[1] - a[2] - a[3];
- }
- if (B)
- {
- pData = mbPos + 8*width*8;
- b[0] = *pData++; b[0] += *pData++;
- b[1] = *pData++; b[1] += *pData++;
- b[2] = *pData++; b[2] += *pData++;
- b[3] = *pData++; b[3] += *pData++;
- j++;
- hor++;
- firstPhase[0] += b[0] + b[1] + b[2] + b[3];
- firstPhase[1] += b[0] + b[1] - b[2] - b[3];
- }
- if (L)
- {
- pData = mbPos - 1;
- l[0] = pData[0]; l[0] += pData[8*width];
- pData += 16*width;
- l[1] = pData[0]; l[1] += pData[8*width];
- pData += 16*width;
- l[2] = pData[0]; l[2] += pData[8*width];
- pData += 16*width;
- l[3] = pData[0]; l[3] += pData[8*width];
- j++;
- ver++;
- firstPhase[0] += l[0] + l[1] + l[2] + l[3];
- firstPhase[4] += l[0] + l[1] - l[2] - l[3];
- }
- if (R)
- {
- pData = mbPos + 8;
- r[0] = pData[0]; r[0] += pData[8*width];
- pData += 16*width;
- r[1] = pData[0]; r[1] += pData[8*width];
- pData += 16*width;
- r[2] = pData[0]; r[2] += pData[8*width];
- pData += 16*width;
- r[3] = pData[0]; r[3] += pData[8*width];
- j++;
- ver++;
- firstPhase[0] += r[0] + r[1] + r[2] + r[3];
- firstPhase[4] += r[0] + r[1] - r[2] - r[3];
- }
- if (!hor && L && R)
- firstPhase[1] = (l[0]+l[1]+l[2]+l[3]-r[0]-r[1]-r[2]-r[3]) >> 4;
- else if (hor)
- firstPhase[1] >>= (2+hor);
-
- if (!ver && A && B)
- firstPhase[4] = (a[0]+a[1]+a[2]+a[3]-b[0]-b[1]-b[2]-b[3]) >> 4;
- else if (ver)
- firstPhase[4] >>= (2+ver);
-
- switch (j)
- {
- case 1:
- firstPhase[0] >>= 3;
- break;
-
- case 2:
- firstPhase[0] >>= 4;
- break;
-
- case 3:
- /* approximate (firstPhase[0]*4/3)>>5 */
- firstPhase[0] = (21 * firstPhase[0]) >> 9;
- break;
-
- default: /* 4 */
- firstPhase[0] >>= 5;
- break;
-
- }
-
- Transform(firstPhase);
-
- pData = data + 256 + comp*64;
- for (i = 0, pTmp = firstPhase; i < 64;)
- {
- tmp = pTmp[(i & 0x7)>>1];
- /*lint -e734 CLIP1 macro results in value that fits into 8 bits */
- *pData++ = CLIP1(tmp);
- /*lint +e734 */
-
- i++;
- if (!(i & 0xF))
- pTmp += 4;
- }
-
- /* increment pointers for cr */
- mbPos += width * height * 64;
- }
-
- h264bsdWriteMacroblock(currImage, data);
-
- return(HANTRO_OK);
-
-}
-
-
-/*------------------------------------------------------------------------------
-
- Function name: Transform
-
- Functional description:
- Simplified transform, assuming that only dc component and lowest
- horizontal and lowest vertical component may be non-zero
-
-------------------------------------------------------------------------------*/
-
-void Transform(i32 *data)
-{
-
- u32 col;
- i32 tmp0, tmp1;
-
- if (!data[1] && !data[4])
- {
- data[1] = data[2] = data[3] = data[4] = data[5] =
- data[6] = data[7] = data[8] = data[9] = data[10] =
- data[11] = data[12] = data[13] = data[14] = data[15] = data[0];
- return;
- }
- /* first horizontal transform for rows 0 and 1 */
- tmp0 = data[0];
- tmp1 = data[1];
- data[0] = tmp0 + tmp1;
- data[1] = tmp0 + (tmp1>>1);
- data[2] = tmp0 - (tmp1>>1);
- data[3] = tmp0 - tmp1;
-
- tmp0 = data[4];
- data[5] = tmp0;
- data[6] = tmp0;
- data[7] = tmp0;
-
- /* then vertical transform */
- for (col = 4; col--; data++)
- {
- tmp0 = data[0];
- tmp1 = data[4];
- data[0] = tmp0 + tmp1;
- data[4] = tmp0 + (tmp1>>1);
- data[8] = tmp0 - (tmp1>>1);
- data[12] = tmp0 - tmp1;
- }
-
-}
-/*lint +e702 */
-