summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/m4v_h263/dec/src/adaptive_smooth_no_mmx.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/codecs/m4v_h263/dec/src/adaptive_smooth_no_mmx.cpp')
-rw-r--r--media/libstagefright/codecs/m4v_h263/dec/src/adaptive_smooth_no_mmx.cpp421
1 files changed, 421 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/adaptive_smooth_no_mmx.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/adaptive_smooth_no_mmx.cpp
new file mode 100644
index 0000000..e2761eb
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/adaptive_smooth_no_mmx.cpp
@@ -0,0 +1,421 @@
+/* ------------------------------------------------------------------
+ * 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.
+ * -------------------------------------------------------------------
+ */
+/*
+
+ Description: Separated modules into one function per file and put into
+ new template.
+
+ Description: Optimizing C code and adding comments. Also changing variable
+ names to make them more meaningful.
+
+ Who: Date:
+ Description:
+
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+
+ Rec_Y = pointer to 0th position in buffer containing luminance values
+ of type uint8.
+ y_start = value of y coordinate of type int that specifies the first
+ row of pixels to be used in the filter algorithm.
+ x_start = value of x coordinate of type int that specifies the first
+ column of pixels to be used in the filter algorithm.
+ y_blk_start = value of the y coordinate of type int that specifies the
+ row of pixels which contains the start of a block. The row
+ specified by y_blk_start+BLK_SIZE is the last row of pixels
+ that are used in the filter algorithm.
+ x_blk_start = value of the x coordinate of type int that specifies the
+ column of pixels which contains the start of a block. The
+ column specified by x_blk_start+BLK_SIZE is the last column of
+ pixels that are used in the filter algorithm.
+ thr = value of type int that is compared to the elements in Rec_Y to
+ determine if a particular value in Rec_Y will be modified by
+ the filter or not
+ width = value of type int that specifies the width of the display
+ in pixels (or pels, equivalently).
+ max_diff = value of type int that specifies the value that may be added
+ or subtracted from the pixel in Rec_Y that is being filtered
+ if the filter algorithm decides to change that particular
+ pixel's luminance value.
+
+
+ Local Stores/Buffers/Pointers Needed:
+ None
+
+ Global Stores/Buffers/Pointers Needed:
+ None
+
+ Outputs:
+ None
+
+ Pointers and Buffers Modified:
+ Buffer pointed to by Rec_Y is modified with the filtered
+ luminance values.
+
+ Local Stores Modified:
+ None
+
+ Global Stores Modified:
+ None
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This function implements a motion compensated noise filter using adaptive
+ weighted averaging of luminance values. *Rec_Y contains the luminance values
+ that are being filtered.
+
+ The picture below depicts a 3x3 group of pixel luminance values. The "u", "c",
+ and "l" stand for "upper", "center" and "lower", respectively. The location
+ of pelc0 is specified by x_start and y_start in the 1-D array "Rec_Y" as
+ follows (assuming x_start=0):
+
+ location of pelc0 = [(y_start+1) * width] + x_start
+
+ Moving up or down 1 row (moving from pelu2 to pelc2, for example) is done by
+ incrementing or decrementing "width" elements within Rec_Y.
+
+ The coordinates of the upper left hand corner of a block (not the group of
+ 9 pixels depicted in the figure below) is specified by
+ (y_blk_start, x_blk_start). The width and height of the block is BLKSIZE.
+ (y_start,x_start) may be specified independently of (y_blk_start, x_blk_start).
+
+ (y_start,x_start)
+ -----------|--------------------------
+ | | | | |
+ | X | pelu1 | pelu2 |
+ | pelu0 | | |
+ | | | |
+ --------------------------------------
+ | | | |
+ | pelc0 | pelc1 | pelc2 |
+ | | | |
+ | | | |
+ --------------------------------------
+ | | | |
+ | pell0 | pell1 | pell2 |
+ | | | |
+ | | | |
+ --------------------------------------
+
+ The filtering of the luminance values is achieved by comparing the 9
+ luminance values to a threshold value ("thr") and then changing the
+ luminance value of pelc1 if all of the values are above or all of the values
+ are below the threshold. The amount that the luminance value is changed
+ depends on a weighted sum of the 9 luminance values. The position of Pelc1
+ is then advanced to the right by one (as well as all of the surrounding pixels)
+ and the same calculation is performed again for the luminance value of the new
+ Pelc1. This continues row-wise until pixels in the last row of the block are
+ filtered.
+
+
+------------------------------------------------------------------------------
+ REQUIREMENTS
+
+ None.
+
+------------------------------------------------------------------------------
+ REFERENCES
+
+ ..\corelibs\decoder\common\src\post_proc.c
+
+------------------------------------------------------------------------------
+ PSEUDO-CODE
+
+------------------------------------------------------------------------------
+ RESOURCES USED
+ When the code is written for a specific target processor the
+ the resources used should be documented below.
+
+ STACK USAGE: [stack count for this module] + [variable to represent
+ stack usage for each subroutine called]
+
+ where: [stack usage variable] = stack usage for [subroutine
+ name] (see [filename].ext)
+
+ DATA MEMORY USED: x words
+
+ PROGRAM MEMORY USED: x words
+
+ CLOCK CYCLES: [cycle count equation for this module] + [variable
+ used to represent cycle count for each subroutine
+ called]
+
+ where: [cycle count variable] = cycle count for [subroutine
+ name] (see [filename].ext)
+
+------------------------------------------------------------------------------
+*/
+
+
+/*----------------------------------------------------------------------------
+; INCLUDES
+----------------------------------------------------------------------------*/
+#include "mp4dec_lib.h"
+#include "post_proc.h"
+#include "mp4def.h"
+
+#define OSCL_DISABLE_WARNING_CONV_POSSIBLE_LOSS_OF_DATA
+
+/*----------------------------------------------------------------------------
+; MACROS
+; Define module specific macros here
+----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+; DEFINES
+; Include all pre-processor statements here. Include conditional
+; compile variables also.
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; LOCAL FUNCTION DEFINITIONS
+; Function Prototype declaration
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; LOCAL STORE/BUFFER/POINTER DEFINITIONS
+; Variable declaration - defined here and used outside this module
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; EXTERNAL FUNCTION REFERENCES
+; Declare functions defined elsewhere and referenced in this module
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
+; Declare variables used in this module but defined elsewhere
+----------------------------------------------------------------------------*/
+#ifdef PV_POSTPROC_ON
+/*----------------------------------------------------------------------------
+; FUNCTION CODE
+----------------------------------------------------------------------------*/
+void AdaptiveSmooth_NoMMX(
+ uint8 *Rec_Y, /* i/o */
+ int y_start, /* i */
+ int x_start, /* i */
+ int y_blk_start, /* i */
+ int x_blk_start, /* i */
+ int thr, /* i */
+ int width, /* i */
+ int max_diff /* i */
+)
+{
+
+ /*----------------------------------------------------------------------------
+ ; Define all local variables
+ ----------------------------------------------------------------------------*/
+ int sign_v[15];
+ int sum_v[15];
+ int *sum_V_ptr;
+ int *sign_V_ptr;
+ uint8 pelu;
+ uint8 pelc;
+ uint8 pell;
+ uint8 *pelp;
+ uint8 oldrow[15];
+ int sum;
+ int sum1;
+ uint8 *Rec_Y_ptr;
+ int32 addr_v;
+ int row_cntr;
+ int col_cntr;
+
+ /*----------------------------------------------------------------------------
+ ; Function body here
+ ----------------------------------------------------------------------------*/
+ /* first row
+ */
+ addr_v = (int32)(y_start + 1) * width; /* y coord of 1st element in the row /
+ /containing pelc pixel / */
+ Rec_Y_ptr = &Rec_Y[addr_v + x_start]; /* initializing pointer to
+ / pelc0 position */
+ sum_V_ptr = &sum_v[0]; /* initializing pointer to 0th element of array
+ / that will contain weighted sums of pixel
+ / luminance values */
+ sign_V_ptr = &sign_v[0]; /* initializing pointer to 0th element of
+ / array that will contain sums that indicate
+ / how many of the 9 pixels are above or below
+ / the threshold value (thr) */
+ pelp = &oldrow[0]; /* initializing pointer to the 0th element of array
+ / that will contain current values of pelc that
+ / are saved and used as values of pelu when the
+ / next row of pixels are filtered */
+
+ pelu = *(Rec_Y_ptr - width); /* assigning value of pelu0 to pelu */
+ *pelp++ = pelc = *Rec_Y_ptr; /* assigning value of pelc0 to pelc and
+ / storing this value in pelp which
+ / will be used as value of pelu0 when
+ / next row is filtered */
+ pell = *(Rec_Y_ptr + width); /* assigning value of pell0 to pell */
+ Rec_Y_ptr++; /* advancing pointer from pelc0 to pelc1 */
+ *sum_V_ptr++ = pelu + (pelc << 1) + pell; /* weighted sum of pelu0,
+ / pelc0 and pell0 */
+ /* sum of 0's and 1's (0 if pixel value is below thr, 1 if value
+ /is above thr) */
+ *sign_V_ptr++ = INDEX(pelu, thr) + INDEX(pelc, thr) + INDEX(pell, thr);
+
+
+ pelu = *(Rec_Y_ptr - width); /* assigning value of pelu1 to pelu */
+ *pelp++ = pelc = *Rec_Y_ptr; /* assigning value of pelc1 to pelc and
+ / storing this value in pelp which
+ / will be used as the value of pelu1 when
+ / next row is filtered */
+ pell = *(Rec_Y_ptr + width); /* assigning value of pell1 to pell */
+ Rec_Y_ptr++; /* advancing pointer from pelc1 to pelc2 */
+ *sum_V_ptr++ = pelu + (pelc << 1) + pell; /* weighted sum of pelu1,
+ / pelc1 and pell1 */
+ /* sum of 0's and 1's (0 if pixel value is below thr, 1 if value
+ /is above thr) */
+ *sign_V_ptr++ = INDEX(pelu, thr) + INDEX(pelc, thr) + INDEX(pell, thr);
+
+ /* The loop below performs the filtering for the first row of
+ / pixels in the region. It steps across the remaining pixels in
+ / the row and alters the luminance value of pelc1 if necessary,
+ / depending on the luminance values of the adjacent pixels*/
+
+ for (col_cntr = (x_blk_start + BLKSIZE - 1) - x_start; col_cntr > 0; col_cntr--)
+ {
+ pelu = *(Rec_Y_ptr - width); /* assigning value of pelu2 to
+ / pelu */
+ *pelp++ = pelc = *Rec_Y_ptr; /* assigning value of pelc2 to pelc
+ / and storing this value in pelp
+ / which will be used as value of pelu2
+ / when next row is filtered */
+ pell = *(Rec_Y_ptr + width); /* assigning value of pell2 to pell */
+
+ /* weighted sum of pelu1, pelc1 and pell1 */
+ *sum_V_ptr = pelu + (pelc << 1) + pell;
+ /* sum of 0's and 1's (0 if pixel value is below thr,
+ /1 if value is above thr) */
+ *sign_V_ptr = INDEX(pelu, thr) + INDEX(pelc, thr) +
+ INDEX(pell, thr);
+ /* the value of sum1 indicates how many of the 9 pixels'
+ /luminance values are above or equal to thr */
+ sum1 = *(sign_V_ptr - 2) + *(sign_V_ptr - 1) + *sign_V_ptr;
+
+ /* alter the luminance value of pelc1 if all 9 luminance values
+ /are above or equal to thr or if all 9 values are below thr */
+ if (sum1 == 0 || sum1 == 9)
+ {
+ /* sum is a weighted average of the 9 pixel luminance
+ /values */
+ sum = (*(sum_V_ptr - 2) + (*(sum_V_ptr - 1) << 1) +
+ *sum_V_ptr + 8) >> 4;
+
+ Rec_Y_ptr--; /* move pointer back to pelc1 */
+ /* If luminance value of pelc1 is larger than
+ / sum by more than max_diff, then subract max_diff
+ / from luminance value of pelc1*/
+ if ((int)(*Rec_Y_ptr - sum) > max_diff)
+ {
+ sum = *Rec_Y_ptr - max_diff;
+ }
+ /* If luminance value of pelc1 is smaller than
+ / sum by more than max_diff, then add max_diff
+ / to luminance value of pelc1*/
+ else if ((int)(*Rec_Y_ptr - sum) < -max_diff)
+ {
+ sum = *Rec_Y_ptr + max_diff;
+ }
+ *Rec_Y_ptr++ = sum; /* assign value of sum to pelc1
+ and advance pointer to pelc2 */
+ }
+ Rec_Y_ptr++; /* advance pointer to new value of pelc2
+ / old pelc2 is now treated as pelc1*/
+ sum_V_ptr++; /* pointer is advanced so next weighted sum may
+ / be saved */
+ sign_V_ptr++; /* pointer is advanced so next sum of 0's and
+ / 1's may be saved */
+ }
+
+ /* The nested loops below perform the filtering for the remaining rows */
+
+ addr_v = (y_start + 2) * width; /* advance addr_v to the next row
+ / (corresponding to pell0)*/
+ /* The outer loop steps throught the rows. */
+ for (row_cntr = (y_blk_start + BLKSIZE) - (y_start + 2); row_cntr > 0; row_cntr--)
+ {
+ Rec_Y_ptr = &Rec_Y[addr_v + x_start]; /* advance pointer to
+ /the old pell0, which has become the new pelc0 */
+ addr_v += width; /* move addr_v down 1 row */
+ sum_V_ptr = &sum_v[0]; /* re-initializing pointer */
+ sign_V_ptr = &sign_v[0]; /* re-initilaizing pointer */
+ pelp = &oldrow[0]; /* re-initializing pointer */
+
+ pelu = *pelp; /* setting pelu0 to old value of pelc0 */
+ *pelp++ = pelc = *Rec_Y_ptr;
+ pell = *(Rec_Y_ptr + width);
+ Rec_Y_ptr++;
+ *sum_V_ptr++ = pelu + (pelc << 1) + pell;
+ *sign_V_ptr++ = INDEX(pelu, thr) + INDEX(pelc, thr) +
+ INDEX(pell, thr);
+
+ pelu = *pelp; /* setting pelu1 to old value of pelc1 */
+ *pelp++ = pelc = *Rec_Y_ptr;
+ pell = *(Rec_Y_ptr + width);
+ Rec_Y_ptr++;
+ *sum_V_ptr++ = pelu + (pelc << 1) + pell;
+ *sign_V_ptr++ = INDEX(pelu, thr) + INDEX(pelc, thr) +
+ INDEX(pell, thr);
+ /* The inner loop steps through the columns */
+ for (col_cntr = (x_blk_start + BLKSIZE - 1) - x_start; col_cntr > 0; col_cntr--)
+ {
+ pelu = *pelp; /* setting pelu2 to old value of pelc2 */
+ *pelp++ = pelc = *Rec_Y_ptr;
+ pell = *(Rec_Y_ptr + width);
+
+ *sum_V_ptr = pelu + (pelc << 1) + pell;
+ *sign_V_ptr = INDEX(pelu, thr) + INDEX(pelc, thr) +
+ INDEX(pell, thr);
+
+ sum1 = *(sign_V_ptr - 2) + *(sign_V_ptr - 1) + *sign_V_ptr;
+ /* the "if" statement below is the same as the one in
+ / the first loop */
+ if (sum1 == 0 || sum1 == 9)
+ {
+ sum = (*(sum_V_ptr - 2) + (*(sum_V_ptr - 1) << 1) +
+ *sum_V_ptr + 8) >> 4;
+
+ Rec_Y_ptr--;
+ if ((int)(*Rec_Y_ptr - sum) > max_diff)
+ {
+ sum = *Rec_Y_ptr - max_diff;
+ }
+ else if ((int)(*Rec_Y_ptr - sum) < -max_diff)
+ {
+ sum = *Rec_Y_ptr + max_diff;
+ }
+ *Rec_Y_ptr++ = (uint8) sum;
+ }
+ Rec_Y_ptr++;
+ sum_V_ptr++;
+ sign_V_ptr++;
+ }
+ }
+
+ /*----------------------------------------------------------------------------
+ ; Return nothing or data or data pointer
+ ----------------------------------------------------------------------------*/
+ return;
+}
+#endif