diff options
Diffstat (limited to 'media/libstagefright/codecs/m4v_h263/dec/src/get_pred_outside.cpp')
-rw-r--r-- | media/libstagefright/codecs/m4v_h263/dec/src/get_pred_outside.cpp | 514 |
1 files changed, 514 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/get_pred_outside.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/get_pred_outside.cpp new file mode 100644 index 0000000..9cd9022 --- /dev/null +++ b/media/libstagefright/codecs/m4v_h263/dec/src/get_pred_outside.cpp @@ -0,0 +1,514 @@ +/* ------------------------------------------------------------------ + * 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. + * ------------------------------------------------------------------- + */ +/* +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + xpos = x half-pixel of (x,y) coordinates within a VOP; motion + compensated coordinates; native data type + ypos = y half-pixel of (x,y) coordinates within a VOP; motion + compensated coordinates; native data type + comp = pointer to 8-bit compensated prediction values within a VOP; + computed by this module (i/o); full-pel resolution; 8-bit data + c_prev = pointer to previous 8-bit prediction values within a VOP; + values range from (0-255); full-pel resolution; 8-bit data + sh_d = pointer to residual values used to compensate the predicted + value; values range from (-512 to 511); full-pel resolution; + native data type + width = width of the VOP in pixels (x axis); full-pel resolution; + native data type + height = height of the VOP in pixels (y axis); full-pel resolution; + native data type + rnd1 = rounding value for case when one dimension uses half-pel + resolution; native data type + rnd2 = rounding value for case when two dimensions uses half-pel + resolution; native data type + + Outputs: + returns 1 + + Local Stores/Buffers/Pointers Needed: + None + + Global Stores/Buffers/Pointers Needed: + None + + Pointers and Buffers Modified: + comp = buffer contains newly computed compensated prediction values + + Local Stores Modified: + None + + Global Stores Modified: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Summary: + + This function performs motion compensated prediction for the case where + the motion vector points to a block outside the VOP. The function interpolates + the pixels that are outside the VOP using the boundary pixels for the block. + Once the values are interpolated, the pixel values are computed for a block + in the current VOP. The prediction values are generated by averaging pixel + values in the previous VOP; the block position in the previous frame is + computed from the current block's motion vector. The computed pixel values + are calculated by adding the prediction values to the block residual values. + + Details: + + First, this functions determines which VOP boundary(ies) the motion vector + is outside, i.e., left, right, top, bottom. xpos is compared to the left and + right boundaries; ypos is compared to the top and bottom boundaries. The number + of block pixels inside the the boundary in the x and y directions are stored + in endx and endy, respectively. If the entire block is inside the x or y + boundary, the respectively end is set to 0. + + After the boundaries are tested, any pixels lying outside a boundary are + interpolated from the boundary pixels. For example, if the block is outside the + bottom boundary, boundary pixels alone the bottom of the VOP as used to + interpolated those pixels lying outside the bottom boundary. The interpolation + used is a simple column-wise or row-wise copy of the boundary pixels (inside the + block) depending on which boundary the block is outside. In our example, each + boundary pixel would be copied column-wise to the pixel beneath it. If the + block was outside right boundary, the boundary pixels would be copied row-wise + to the pixel to the right of it. If the block was outside both an x and y + boundary, the boundary pixels would be copied row-wise for the portion of the + block outside the x boundary, and column-wise for the portion of the block + outside the y boundary. And so on. + + Once the pixel interpolation is complete, the motion compensated output values + (comp[]) are calculed from the motion compensated prediction (pred[])values and + the residual values (sh_d[]) of the current frame. The prediction values are + generated by averaging pixel values in the previous VOP; the block position in + the previous frame is computed from the current block's motion vector. The + computed pixel values are calculated by adding the prediction values to the + block residual values. + +*/ + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "mp4dec_lib.h" +#include "motion_comp.h" + +#define PAD_CORNER { temp = *prev; \ + temp |= (temp<<8); \ + temp |= (temp<<16); \ + *((uint32*)ptr) = temp; \ + *((uint32*)(ptr+4)) = temp; \ + *((uint32*)(ptr+=16)) = temp; \ + *((uint32*)(ptr+4)) = temp; \ + *((uint32*)(ptr+=16)) = temp; \ + *((uint32*)(ptr+4)) = temp; \ + *((uint32*)(ptr+=16)) = temp; \ + *((uint32*)(ptr+4)) = temp; \ + *((uint32*)(ptr+=16)) = temp; \ + *((uint32*)(ptr+4)) = temp; \ + *((uint32*)(ptr+=16)) = temp; \ + *((uint32*)(ptr+4)) = temp; \ + *((uint32*)(ptr+=16)) = temp; \ + *((uint32*)(ptr+4)) = temp; \ + *((uint32*)(ptr+=16)) = temp; \ + *((uint32*)(ptr+4)) = temp; } + +#define PAD_ROW { temp = *((uint32*)prev); \ + temp2 = *((uint32*)(prev+4)); \ + *((uint32*)ptr) = temp;\ + *((uint32*)(ptr+4)) = temp2; \ + *((uint32*)(ptr+=16)) = temp; \ + *((uint32*)(ptr+4)) = temp2;\ + *((uint32*)(ptr+=16)) = temp; \ + *((uint32*)(ptr+4)) = temp2;\ + *((uint32*)(ptr+=16)) = temp; \ + *((uint32*)(ptr+4)) = temp2;\ + *((uint32*)(ptr+=16)) = temp; \ + *((uint32*)(ptr+4)) = temp2;\ + *((uint32*)(ptr+=16)) = temp; \ + *((uint32*)(ptr+4)) = temp2;\ + *((uint32*)(ptr+=16)) = temp; \ + *((uint32*)(ptr+4)) = temp2;\ + *((uint32*)(ptr+=16)) = temp; \ + *((uint32*)(ptr+4)) = temp2;} + +#define PAD_EXTRA_4x8 { temp = *((uint32*)(prev+8)); \ + *((uint32*)ptr) = temp; \ + *((uint32*)(ptr+=16)) = temp; \ + *((uint32*)(ptr+=16)) = temp; \ + *((uint32*)(ptr+=16)) = temp; \ + *((uint32*)(ptr+=16)) = temp; \ + *((uint32*)(ptr+=16)) = temp; \ + *((uint32*)(ptr+=16)) = temp; \ + *((uint32*)(ptr+=16)) = temp; } + +#define PAD_COL { temp = *prev; \ + temp|=(temp<<8); temp|=(temp<<16); \ + *((uint32*)ptr) = temp; \ + *((uint32*)(ptr+4)) = temp; \ + temp = *(prev+=16); \ + temp|=(temp<<8); temp|=(temp<<16); \ + *((uint32*)(ptr+=16)) = temp; \ + *((uint32*)(ptr+4)) = temp; \ + temp = *(prev+=16); \ + temp|=(temp<<8); temp|=(temp<<16); \ + *((uint32*)(ptr+=16)) = temp; \ + *((uint32*)(ptr+4)) = temp; \ + temp = *(prev+=16); \ + temp|=(temp<<8); temp|=(temp<<16); \ + *((uint32*)(ptr+=16)) = temp; \ + *((uint32*)(ptr+4)) = temp; \ + temp = *(prev+=16); \ + temp|=(temp<<8); temp|=(temp<<16); \ + *((uint32*)(ptr+=16)) = temp; \ + *((uint32*)(ptr+4)) = temp; \ + temp = *(prev+=16); \ + temp|=(temp<<8); temp|=(temp<<16); \ + *((uint32*)(ptr+=16)) = temp; \ + *((uint32*)(ptr+4)) = temp; \ + temp = *(prev+=16); \ + temp|=(temp<<8); temp|=(temp<<16); \ + *((uint32*)(ptr+=16)) = temp; \ + *((uint32*)(ptr+4)) = temp; \ + temp = *(prev+=16); \ + temp|=(temp<<8); temp|=(temp<<16); \ + *((uint32*)(ptr+=16)) = temp; \ + *((uint32*)(ptr+4)) = temp;} + +/* copy 8x8 block */ +#define COPY_BLOCK { *((uint32*)ptr) = *((uint32*)prev); \ + *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \ + *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \ + *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \ + *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \ + *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \ + *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \ + *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \ + *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \ + *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \ + *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \ + *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \ + *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \ + *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \ + *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \ + *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); } + +#define COPY_12x8 { *((uint32*)ptr) = *((uint32*)prev); \ + *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \ + *((uint32*)(ptr+8)) = *((uint32*)(prev+8)); \ + *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \ + *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \ + *((uint32*)(ptr+8)) = *((uint32*)(prev+8)); \ + *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \ + *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \ + *((uint32*)(ptr+8)) = *((uint32*)(prev+8)); \ + *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \ + *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \ + *((uint32*)(ptr+8)) = *((uint32*)(prev+8)); \ + *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \ + *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \ + *((uint32*)(ptr+8)) = *((uint32*)(prev+8)); \ + *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \ + *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \ + *((uint32*)(ptr+8)) = *((uint32*)(prev+8)); \ + *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \ + *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \ + *((uint32*)(ptr+8)) = *((uint32*)(prev+8)); \ + *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \ + *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \ + *((uint32*)(ptr+8)) = *((uint32*)(prev+8)); } + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +int GetPredOutside( + int xpos, /* i */ + int ypos, /* i */ + uint8 *c_prev, /* i */ + uint8 *pred_block, /* i */ + int width, /* i */ + int height, /* i */ + int rnd1, /* i */ + int pred_width +) +{ + /*---------------------------------------------------------------------------- + ; Define all local variables + ----------------------------------------------------------------------------*/ + uint8 *prev; /* pointers to adjacent pixels in the */ + uint8 pred[256]; /* storage for padded pixel values, 16x16 */ + uint8 *ptr; + int xoffset; + uint32 temp, temp2; + + /*---------------------------------------------------------------------------- + ; Function body here + ----------------------------------------------------------------------------*/ + /* saturate xpos and ypos */ + if (xpos < -16) xpos = -16; + if (xpos > ((width - 1) << 1)) xpos = (width - 1) << 1; + if (ypos < -16) ypos = -16; + if (ypos > ((height - 1) << 1)) ypos = (height - 1) << 1; + + if (xpos < 0) + { + if (ypos < 0) /* pad top left of frame */ + { + /* copy the block */ + ptr = pred + (8 << 4) + 8; + prev = c_prev; + COPY_BLOCK + + /* pad the corner */ + ptr = pred; + prev = pred + (8 << 4) + 8; + PAD_CORNER + + /* pad top */ + ptr = pred + 8; + prev = pred + (8 << 4) + 8; + PAD_ROW + + /* pad left */ + ptr = pred + (8 << 4); + prev = pred + (8 << 4) + 8; + PAD_COL + + + ptr = pred + (((ypos >> 1) + 8) << 4) + (xpos >> 1) + 8; + + GetPredAdvBTable[ypos&1][xpos&1](ptr, pred_block, 16, (pred_width << 1) | rnd1); + + return 1; + } + else if ((ypos >> 1) < (height - B_SIZE)) /* pad left of frame */ + { + /* copy block */ + ptr = pred + 8; + prev = c_prev + (ypos >> 1) * width; + COPY_BLOCK + /* copy extra line */ + *((uint32*)(ptr += 16)) = *((uint32*)(prev += width)); + *((uint32*)(ptr + 4)) = *((uint32*)(prev + 4)); + + /* pad left */ + ptr = pred; + prev = pred + 8; + PAD_COL + /* pad extra line */ + temp = *(prev += 16); + temp |= (temp << 8); + temp |= (temp << 16); + *((uint32*)(ptr += 16)) = temp; + *((uint32*)(ptr + 4)) = temp; + + ptr = pred + 8 + (xpos >> 1); + + GetPredAdvBTable[ypos&1][xpos&1](ptr, pred_block, 16, (pred_width << 1) | rnd1); + + return 1; + } + else /* pad bottom left of frame */ + { + /* copy the block */ + ptr = pred + 8; /* point to the center */ + prev = c_prev + width * (height - 8); + COPY_BLOCK + + /* pad the corner */ + ptr = pred + (8 << 4); + prev = ptr - 8; + PAD_CORNER + + /* pad bottom */ + ptr = pred + (8 << 4) + 8; + prev = ptr - 16; + PAD_ROW + + /* pad left */ + ptr = pred ; + prev = ptr + 8; + PAD_COL + + ptr = pred + 8 + (((ypos >> 1) - (height - 8)) << 4) + (xpos >> 1); + + GetPredAdvBTable[ypos&1][xpos&1](ptr, pred_block, 16, (pred_width << 1) | rnd1); + + return 1; + } + } + else if ((xpos >> 1) < (width - B_SIZE)) + { + if (ypos < 0) /* pad top of frame */ + { + xoffset = xpos >> 1; + xoffset = xoffset & 0x3; /* word align ptr */ + + /* copy block */ + ptr = pred + (8 << 4); + prev = c_prev + (xpos >> 1) - xoffset; + + if (xoffset || (xpos&1)) /* copy extra 4x8 */ + { + COPY_12x8 + } + else + { + COPY_BLOCK + } + + /* pad top */ + ptr = pred; + prev = pred + (8 << 4); + PAD_ROW + if (xoffset || (xpos&1)) /* pad extra 4x8 */ + { + ptr = pred + 8; + PAD_EXTRA_4x8 + } + + ptr = pred + (((ypos >> 1) + 8) << 4) + xoffset; + + GetPredAdvBTable[ypos&1][xpos&1](ptr, pred_block, 16, (pred_width << 1) | rnd1); + + return 1; + } + else /* pad bottom of frame */ + { + xoffset = xpos >> 1; + xoffset = xoffset & 0x3; /* word align ptr */ + /* copy block */ + ptr = pred ; + prev = c_prev + width * (height - 8) + (xpos >> 1) - xoffset; + if (xoffset || (xpos&1)) + { + COPY_12x8 + } + else + { + COPY_BLOCK + } + + /* pad bottom */ + ptr = pred + (8 << 4); + prev = ptr - 16; + PAD_ROW + if (xoffset || (xpos&1)) + { + ptr = pred + (8 << 4) + 8; + PAD_EXTRA_4x8 + } + + ptr = pred + (((ypos >> 1) - (height - 8)) << 4) + xoffset; + + GetPredAdvBTable[ypos&1][xpos&1](ptr, pred_block, 16, (pred_width << 1) | rnd1); + + return 1; + } + } + else + { + if (ypos < 0) /* pad top right of frame */ + { + /* copy block */ + ptr = pred + (8 << 4); + prev = c_prev + width - 8; + COPY_BLOCK + + /* pad top-right */ + ptr = pred + 8; + prev = pred + (8 << 4) + 7; + PAD_CORNER + + /* pad top */ + ptr = pred ; + prev = pred + (8 << 4); + PAD_ROW; + + /* pad right */ + ptr = pred + (8 << 4) + 8; + prev = ptr - 1; + PAD_COL; + + ptr = pred + ((8 + (ypos >> 1)) << 4) + (8 - (width - (xpos >> 1))); + + GetPredAdvBTable[ypos&1][xpos&1](ptr, pred_block, 16, (pred_width << 1) | rnd1); + + return 1; + } + else if ((ypos >> 1) < (height - B_SIZE)) /* pad right of frame */ + { + /* copy block */ + ptr = pred; + prev = c_prev + (ypos >> 1) * width + width - 8; + COPY_BLOCK + /* copy extra line */ + *((uint32*)(ptr += 16)) = *((uint32*)(prev += width)); + *((uint32*)(ptr + 4)) = *((uint32*)(prev + 4)); + + /* pad right */ + ptr = pred + 8; + prev = ptr - 1; + PAD_COL; + /* pad extra line */ + temp = *(prev += 16); + temp |= (temp << 8); + temp |= (temp << 16); + *((uint32*)(ptr += 16)) = temp; + *((uint32*)(ptr + 4)) = temp; + + + ptr = pred + 8 - (width - (xpos >> 1)); + + GetPredAdvBTable[ypos&1][xpos&1](ptr, pred_block, 16, (pred_width << 1) | rnd1); + + return 1; + + } + else /* pad bottom right of frame */ + { + /* copy block */ + ptr = pred; + prev = c_prev + width * (height - 8) + width - 8; + COPY_BLOCK + + /* pad bottom-right */ + ptr = pred + (8 << 4) + 8; + prev = ptr - 17; + PAD_CORNER + + /* pad right */ + ptr = pred + 8; + prev = ptr - 1; + PAD_COL + + /* pad bottom */ + ptr = pred + (8 << 4); + prev = ptr - 16; + PAD_ROW + + ptr = pred + 8 - (width - (xpos >> 1)) + ((8 - (height - (ypos >> 1))) << 4); + + GetPredAdvBTable[ypos&1][xpos&1](ptr, pred_block, 16, (pred_width << 1) | rnd1); + + return 1; + } + } +} |