/H264Dec/source/h264bsd_image.c
http://github.com/mbebenita/Broadway · C · 345 lines · 192 code · 53 blank · 100 comment · 10 complexity · 2e851e43ca23ddba84f5b3d7b13b7dd8 MD5 · raw file
- /*
- * 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
- h264bsdWriteMacroblock
- h264bsdWriteOutputBlocks
- ------------------------------------------------------------------------------*/
- /*------------------------------------------------------------------------------
- 1. Include headers
- ------------------------------------------------------------------------------*/
- #include "h264bsd_image.h"
- #include "h264bsd_util.h"
- #include "h264bsd_neighbour.h"
- /*------------------------------------------------------------------------------
- 2. External compiler flags
- --------------------------------------------------------------------------------
- --------------------------------------------------------------------------------
- 3. Module defines
- ------------------------------------------------------------------------------*/
- /* x- and y-coordinates for each block, defined in h264bsd_intra_prediction.c */
- extern const u32 h264bsdBlockX[];
- extern const u32 h264bsdBlockY[];
- /* clipping table, defined in h264bsd_intra_prediction.c */
- extern const u8 h264bsdClip[];
- /*------------------------------------------------------------------------------
- 4. Local function prototypes
- ------------------------------------------------------------------------------*/
- /*------------------------------------------------------------------------------
- Function: h264bsdWriteMacroblock
- Functional description:
- Write one macroblock into the image. Both luma and chroma
- components will be written at the same time.
- Inputs:
- data pointer to macroblock data to be written, 256 values for
- luma followed by 64 values for both chroma components
- Outputs:
- image pointer to the image where the macroblock will be written
- Returns:
- none
- ------------------------------------------------------------------------------*/
- #ifndef H264DEC_NEON
- void h264bsdWriteMacroblock(image_t *image, u8 *data)
- {
- /* Variables */
- u32 i;
- u32 width;
- u32 *lum, *cb, *cr;
- u32 *ptr;
- u32 tmp1, tmp2;
- /* Code */
- ASSERT(image);
- ASSERT(data);
- ASSERT(!((u32)data&0x3));
- width = image->width;
- /*lint -save -e826 lum, cb and cr used to copy 4 bytes at the time, disable
- * "area too small" info message */
- lum = (u32*)image->luma;
- cb = (u32*)image->cb;
- cr = (u32*)image->cr;
- ASSERT(!((u32)lum&0x3));
- ASSERT(!((u32)cb&0x3));
- ASSERT(!((u32)cr&0x3));
- ptr = (u32*)data;
- width *= 4;
- for (i = 16; i ; i--)
- {
- tmp1 = *ptr++;
- tmp2 = *ptr++;
- *lum++ = tmp1;
- *lum++ = tmp2;
- tmp1 = *ptr++;
- tmp2 = *ptr++;
- *lum++ = tmp1;
- *lum++ = tmp2;
- lum += width-4;
- }
- width >>= 1;
- for (i = 8; i ; i--)
- {
- tmp1 = *ptr++;
- tmp2 = *ptr++;
- *cb++ = tmp1;
- *cb++ = tmp2;
- cb += width-2;
- }
- for (i = 8; i ; i--)
- {
- tmp1 = *ptr++;
- tmp2 = *ptr++;
- *cr++ = tmp1;
- *cr++ = tmp2;
- cr += width-2;
- }
- }
- #endif
- #ifndef H264DEC_OMXDL
- /*------------------------------------------------------------------------------
- Function: h264bsdWriteOutputBlocks
- Functional description:
- Write one macroblock into the image. Prediction for the macroblock
- and the residual are given separately and will be combined while
- writing the data to the image
- Inputs:
- data pointer to macroblock prediction data, 256 values for
- luma followed by 64 values for both chroma components
- mbNum number of the macroblock
- residual pointer to residual data, 16 16-element arrays for luma
- followed by 4 16-element arrays for both chroma
- components
- Outputs:
- image pointer to the image where the data will be written
- Returns:
- none
- ------------------------------------------------------------------------------*/
- void h264bsdWriteOutputBlocks(image_t *image, u32 mbNum, u8 *data,
- i32 residual[][16])
- {
- /* Variables */
- u32 i;
- u32 picWidth, picSize;
- u8 *lum, *cb, *cr;
- u8 *imageBlock;
- u8 *tmp;
- u32 row, col;
- u32 block;
- u32 x, y;
- i32 *pRes;
- i32 tmp1, tmp2, tmp3, tmp4;
- const u8 *clp = h264bsdClip + 512;
- /* Code */
- ASSERT(image);
- ASSERT(data);
- ASSERT(mbNum < image->width * image->height);
- ASSERT(!((u32)data&0x3));
- /* Image size in macroblocks */
- picWidth = image->width;
- picSize = picWidth * image->height;
- row = mbNum / picWidth;
- col = mbNum % picWidth;
- /* Output macroblock position in output picture */
- lum = (image->data + row * picWidth * 256 + col * 16);
- cb = (image->data + picSize * 256 + row * picWidth * 64 + col * 8);
- cr = (cb + picSize * 64);
- picWidth *= 16;
- for (block = 0; block < 16; block++)
- {
- x = h264bsdBlockX[block];
- y = h264bsdBlockY[block];
- pRes = residual[block];
- ASSERT(pRes);
- tmp = data + y*16 + x;
- imageBlock = lum + y*picWidth + x;
- ASSERT(!((u32)tmp&0x3));
- ASSERT(!((u32)imageBlock&0x3));
- if (IS_RESIDUAL_EMPTY(pRes))
- {
- /*lint -e826 */
- i32 *in32 = (i32*)tmp;
- i32 *out32 = (i32*)imageBlock;
- /* Residual is zero => copy prediction block to output */
- tmp1 = *in32; in32 += 4;
- tmp2 = *in32; in32 += 4;
- *out32 = tmp1; out32 += picWidth/4;
- *out32 = tmp2; out32 += picWidth/4;
- tmp1 = *in32; in32 += 4;
- tmp2 = *in32;
- *out32 = tmp1; out32 += picWidth/4;
- *out32 = tmp2;
- }
- else
- {
- RANGE_CHECK_ARRAY(pRes, -512, 511, 16);
- /* Calculate image = prediction + residual
- * Process four pixels in a loop */
- for (i = 4; i; i--)
- {
- tmp1 = tmp[0];
- tmp2 = *pRes++;
- tmp3 = tmp[1];
- tmp1 = clp[tmp1 + tmp2];
- tmp4 = *pRes++;
- imageBlock[0] = (u8)tmp1;
- tmp3 = clp[tmp3 + tmp4];
- tmp1 = tmp[2];
- tmp2 = *pRes++;
- imageBlock[1] = (u8)tmp3;
- tmp1 = clp[tmp1 + tmp2];
- tmp3 = tmp[3];
- tmp4 = *pRes++;
- imageBlock[2] = (u8)tmp1;
- tmp3 = clp[tmp3 + tmp4];
- tmp += 16;
- imageBlock[3] = (u8)tmp3;
- imageBlock += picWidth;
- }
- }
- }
- picWidth /= 2;
- for (block = 16; block <= 23; block++)
- {
- x = h264bsdBlockX[block & 0x3];
- y = h264bsdBlockY[block & 0x3];
- pRes = residual[block];
- ASSERT(pRes);
- tmp = data + 256;
- imageBlock = cb;
- if (block >= 20)
- {
- imageBlock = cr;
- tmp += 64;
- }
- tmp += y*8 + x;
- imageBlock += y*picWidth + x;
- ASSERT(!((u32)tmp&0x3));
- ASSERT(!((u32)imageBlock&0x3));
- if (IS_RESIDUAL_EMPTY(pRes))
- {
- /*lint -e826 */
- i32 *in32 = (i32*)tmp;
- i32 *out32 = (i32*)imageBlock;
- /* Residual is zero => copy prediction block to output */
- tmp1 = *in32; in32 += 2;
- tmp2 = *in32; in32 += 2;
- *out32 = tmp1; out32 += picWidth/4;
- *out32 = tmp2; out32 += picWidth/4;
- tmp1 = *in32; in32 += 2;
- tmp2 = *in32;
- *out32 = tmp1; out32 += picWidth/4;
- *out32 = tmp2;
- }
- else
- {
- RANGE_CHECK_ARRAY(pRes, -512, 511, 16);
- for (i = 4; i; i--)
- {
- tmp1 = tmp[0];
- tmp2 = *pRes++;
- tmp3 = tmp[1];
- tmp1 = clp[tmp1 + tmp2];
- tmp4 = *pRes++;
- imageBlock[0] = (u8)tmp1;
- tmp3 = clp[tmp3 + tmp4];
- tmp1 = tmp[2];
- tmp2 = *pRes++;
- imageBlock[1] = (u8)tmp3;
- tmp1 = clp[tmp1 + tmp2];
- tmp3 = tmp[3];
- tmp4 = *pRes++;
- imageBlock[2] = (u8)tmp1;
- tmp3 = clp[tmp3 + tmp4];
- tmp += 8;
- imageBlock[3] = (u8)tmp3;
- imageBlock += picWidth;
- }
- }
- }
- }
- #endif /* H264DEC_OMXDL */