summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/m4v_h263/dec/src/get_pred_outside.cpp
diff options
context:
space:
mode:
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.cpp514
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;
+ }
+ }
+}