post_proc_semaphore.cpp revision 3306cfee3bf38ab207a0504e49c2d492bb73ffbf
1/* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18/*
19------------------------------------------------------------------------------
20 INPUT AND OUTPUT DEFINITIONS
21
22 Inputs:
23    q_block = pointer to buffer of inverse quantized DCT coefficients of type
24              int for intra-VOP mode or buffer of residual data of type int
25              for inter-VOP mode
26
27 Local Stores/Buffers/Pointers Needed:
28    None
29
30 Global Stores/Buffers/Pointers Needed:
31    None
32
33 Outputs:
34    postmode = post processing semaphore with the vertical deblocking,
35               horizontal deblocking, and deringing bits set up accordingly
36
37 Pointers and Buffers Modified:
38    None
39
40 Local Stores Modified:
41    None
42
43 Global Stores Modified:
44    None
45
46------------------------------------------------------------------------------
47 FUNCTION DESCRIPTION
48
49 This function sets up the postmode semaphore based on the contents of the
50 buffer pointed to by q_block. The function starts out with the assumption
51 that all entries of q_block, except for the first entry (q_block[0]), are
52 zero. This case can induce horizontal and vertical blocking artifacts,
53 therefore, both horizontal and vertical deblocking bits are enabled.
54
55 The following conditions are tested when setting up the horizontal/vertical
56 deblocking and deringing bits:
57 1. When only the elements of the top row of the B_SIZE x B_SIZE block
58    (q_block[n], n = 0,..., B_SIZE-1) are non-zero, vertical blocking artifacts
59    may result, therefore, only the vertical deblocking bit is enabled.
60    Otherwise, the vertical deblocking bit is disabled.
61 2. When only the elements of the far left column of the B_SIZE x B_SIZE block
62    (q_block[n*B_SIZE], n = 0, ..., B_SIZE-1) are non-zero, horizontal blocking
63    artifacts may result, therefore, only the horizontal deblocking bit is
64    enabled. Otherwise, the horizontal deblocking bit is disabled.
65 3. If any non-zero elements exist in positions other than q_block[0],
66    q_block[1], or q_block[B_SIZE], the deringing bit is enabled. Otherwise,
67    it is disabled.
68
69 The 3 least significant bits of postmode defines vertical or horizontal
70 deblocking and deringing.
71
72 The valid values are shown below:
73 -------------------------------------------------------
74 |           Type                 | Enabled | Disabled |
75 -------------------------------------------------------
76 | Vertical Deblocking (Bit #0)   |    1    |     0    |
77 -------------------------------------------------------
78 | Horizontal Deblocking (Bit #1) |    1    |     0    |
79 -------------------------------------------------------
80 | Deringing (Bit #2)             |    1    |     0    |
81 -------------------------------------------------------
82
83*/
84
85
86/*----------------------------------------------------------------------------
87; INCLUDES
88----------------------------------------------------------------------------*/
89#include    "mp4dec_lib.h"
90#include    "mp4def.h"
91#include    "post_proc.h"
92
93/*----------------------------------------------------------------------------
94; MACROS
95; Define module specific macros here
96----------------------------------------------------------------------------*/
97
98
99/*----------------------------------------------------------------------------
100; DEFINES
101; Include all pre-processor statements here. Include conditional
102; compile variables also.
103----------------------------------------------------------------------------*/
104
105/*----------------------------------------------------------------------------
106; LOCAL FUNCTION DEFINITIONS
107; Function Prototype declaration
108----------------------------------------------------------------------------*/
109
110/*----------------------------------------------------------------------------
111; LOCAL STORE/BUFFER/POINTER DEFINITIONS
112; Variable declaration - defined here and used outside this module
113----------------------------------------------------------------------------*/
114
115/*----------------------------------------------------------------------------
116; EXTERNAL FUNCTION REFERENCES
117; Declare functions defined elsewhere and referenced in this module
118----------------------------------------------------------------------------*/
119
120/*----------------------------------------------------------------------------
121; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
122; Declare variables used in this module but defined elsewhere
123----------------------------------------------------------------------------*/
124#ifdef PV_POSTPROC_ON
125/*----------------------------------------------------------------------------
126; FUNCTION CODE
127----------------------------------------------------------------------------*/
128int PostProcSemaphore(
129    int16 *q_block)
130{
131    /*----------------------------------------------------------------------------
132    ; Define all local variables
133    ----------------------------------------------------------------------------*/
134    int i, j;
135
136    /* Set default value to vertical and horizontal deblocking enabled */
137    /* Initial assumption is that only q_block[0] element is non-zero, */
138    /* therefore, vertical and horizontal deblocking bits are set to 1 */
139    int postmode = 0x3;
140
141    /*----------------------------------------------------------------------------
142    ; Function body here
143    ----------------------------------------------------------------------------*/
144    /* Vertical deblocking bit is enabled when only the entire top row of   */
145    /* the B_SIZE x B_SIZE block, i.e., q_block[n], n = 0,..., B_SIZE-1,    */
146    /* are non-zero. Since initial assumption is that all elements, except  */
147    /* q_block[0], is zero, we need to check the remaining elements in the  */
148    /* top row to  determine if all or some are non-zero.                   */
149    if (q_block[1] != 0)
150    {
151        /* At this point, q_block[0] and q_block[1] are non-zero, while */
152        /* q_block[n], n = 2,..., B_SIZE-1, are zero. Therefore, we     */
153        /* need to disable vertical deblocking                          */
154        postmode &= 0xE;
155    }
156
157    for (i = 2; i < B_SIZE; i++)
158    {
159        if (q_block[i])
160        {
161            /* Check if q_block[n], n = 2,..., B_SIZE-1, are non-zero.*/
162            /* If any of them turn out to be non-zero, we need to     */
163            /* disable vertical deblocking.                           */
164            postmode &= 0xE;
165
166            /* Deringing is enabled if any nonzero elements exist in */
167            /* positions other than q_block[0], q_block[1] or        */
168            /* q_block[B_SIZE].                                      */
169            postmode |= 0x4;
170
171            break;
172        }
173    }
174
175    /* Horizontal deblocking bit is enabled when only the entire far */
176    /* left column, i.e., q_block[n*B_SIZE], n = 0, ..., B_SIZE-1,   */
177    /* are non-zero. Since initial assumption is that all elements,  */
178    /* except q_block[0], is zero, we need to check the remaining    */
179    /* elements in the far left column to determine if all or some   */
180    /* are non-zero.                                                 */
181    if (q_block[B_SIZE])
182    {
183        /* At this point, only q_block[0] and q_block[B_SIZE] are non-zero, */
184        /* while q_block[n*B_SIZE], n = 2, 3,..., B_SIZE-1, are zero.       */
185        /* Therefore, we need to disable horizontal deblocking.             */
186        postmode &= 0xD;
187    }
188
189    for (i = 16; i < NCOEFF_BLOCK; i += B_SIZE)
190    {
191        if (q_block[i])
192        {
193            /* Check if q_block[n], n = 2*B_SIZE,...,(B_SIZE-1)*B_SIZE,  */
194            /* are non-zero. If any of them turn out to be non-zero,     */
195            /* we need to disable horizontal deblocking.                 */
196            postmode &= 0xD;
197
198            /* Deringing is enabled if any nonzero elements exist in */
199            /* positions other than q_block[0], q_block[1] or        */
200            /* q_block[B_SIZE].                                      */
201            postmode |= 0x4;
202
203            break;
204        }
205    }
206
207    /* At this point, only the first row and far left column elements */
208    /* have been tested. If deringing bit is still not set at this    */
209    /* point, check the rest of q_block to determine if the elements  */
210    /* are non-zero. If all elements, besides q_block[0], q_block[1], */
211    /* or q_block[B_SIZE] are non-zero, deringing bit must be set     */
212    if ((postmode & 0x4) == 0)
213    {
214        for (i = 1; i < B_SIZE; i++)
215        {
216            for (j = 1; j < B_SIZE; j++)
217            {
218                if (q_block[(i<<3)+j])
219                {
220                    /* At this point, q_block[0] and another q_block */
221                    /* element are non-zero, therefore, we need to   */
222                    /* disable vertical and horizontal deblocking    */
223                    postmode &= 0xC;
224
225                    /* Deringing is enabled if any nonzero elements exist in */
226                    /* positions other than q_block[0], q_block[1] or        */
227                    /* q_block[B_SIZE].                                      */
228                    postmode |= 0x4;
229
230                    /* Set outer FOR loop count to B_SIZE to get out of */
231                    /* outer FOR loop                                   */
232                    i = B_SIZE;
233
234                    /* Get out of inner FOR loop */
235                    break;
236                }
237            }
238        }
239    }
240
241    /*----------------------------------------------------------------------------
242    ; Return nothing or data or data pointer
243    ----------------------------------------------------------------------------*/
244    return (postmode);
245}
246
247#endif
248