h264bsd_neighbour.c revision 0c1bc742181ded4930842b46e9507372f0b1b963
1/*
2 * Copyright (C) 2009 The Android Open Source Project
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 express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*------------------------------------------------------------------------------
18
19    Table of contents
20
21     1. Include headers
22     2. External compiler flags
23     3. Module defines
24     4. Local function prototypes
25     5. Functions
26          h264bsdInitMbNeighbours
27          h264bsdGetNeighbourMb
28          h264bsdNeighbour4x4BlockA
29          h264bsdNeighbour4x4BlockB
30          h264bsdNeighbour4x4BlockC
31          h264bsdNeighbour4x4BlockD
32
33------------------------------------------------------------------------------*/
34
35/*------------------------------------------------------------------------------
36    1. Include headers
37------------------------------------------------------------------------------*/
38
39#include "h264bsd_neighbour.h"
40#include "h264bsd_util.h"
41
42/*------------------------------------------------------------------------------
43    2. External compiler flags
44--------------------------------------------------------------------------------
45
46--------------------------------------------------------------------------------
47    3. Module defines
48------------------------------------------------------------------------------*/
49
50/* Following four tables indicate neighbours of each block of a macroblock.
51 * First 16 values are for luma blocks, next 4 values for Cb and last 4
52 * values for Cr. Elements of the table indicate to which macroblock the
53 * neighbour block belongs and the index of the neighbour block in question.
54 * Indexing of the blocks goes as follows
55 *
56 *          Y             Cb       Cr
57 *      0  1  4  5      16 17    20 21
58 *      2  3  6  7      18 19    22 23
59 *      8  9 12 13
60 *     10 11 14 15
61 */
62
63/* left neighbour for each block */
64static const neighbour_t N_A_4x4B[24] = {
65    {MB_A,5},    {MB_CURR,0}, {MB_A,7},    {MB_CURR,2},
66    {MB_CURR,1}, {MB_CURR,4}, {MB_CURR,3}, {MB_CURR,6},
67    {MB_A,13},   {MB_CURR,8}, {MB_A,15},   {MB_CURR,10},
68    {MB_CURR,9}, {MB_CURR,12},{MB_CURR,11},{MB_CURR,14},
69    {MB_A,17},   {MB_CURR,16},{MB_A,19},   {MB_CURR,18},
70    {MB_A,21},   {MB_CURR,20},{MB_A,23},   {MB_CURR,22} };
71
72/* above neighbour for each block */
73static const neighbour_t N_B_4x4B[24] = {
74    {MB_B,10},   {MB_B,11},   {MB_CURR,0}, {MB_CURR,1},
75    {MB_B,14},   {MB_B,15},   {MB_CURR,4}, {MB_CURR,5},
76    {MB_CURR,2}, {MB_CURR,3}, {MB_CURR,8}, {MB_CURR,9},
77    {MB_CURR,6}, {MB_CURR,7}, {MB_CURR,12},{MB_CURR,13},
78    {MB_B,18},   {MB_B,19},   {MB_CURR,16},{MB_CURR,17},
79    {MB_B,22},   {MB_B,23},   {MB_CURR,20},{MB_CURR,21} };
80
81/* above-right neighbour for each block */
82static const neighbour_t N_C_4x4B[24] = {
83    {MB_B,11},   {MB_B,14},   {MB_CURR,1}, {MB_NA,4},
84    {MB_B,15},   {MB_C,10},   {MB_CURR,5}, {MB_NA,0},
85    {MB_CURR,3}, {MB_CURR,6}, {MB_CURR,9}, {MB_NA,12},
86    {MB_CURR,7}, {MB_NA,2},   {MB_CURR,13},{MB_NA,8},
87    {MB_B,19},   {MB_C,18},   {MB_CURR,17},{MB_NA,16},
88    {MB_B,23},   {MB_C,22},   {MB_CURR,21},{MB_NA,20} };
89
90/* above-left neighbour for each block */
91static const neighbour_t N_D_4x4B[24] = {
92    {MB_D,15},   {MB_B,10},   {MB_A,5},    {MB_CURR,0},
93    {MB_B,11},   {MB_B,14},   {MB_CURR,1}, {MB_CURR,4},
94    {MB_A,7},    {MB_CURR,2}, {MB_A,13},   {MB_CURR,8},
95    {MB_CURR,3}, {MB_CURR,6}, {MB_CURR,9}, {MB_CURR,12},
96    {MB_D,19},   {MB_B,18},   {MB_A,17},   {MB_CURR,16},
97    {MB_D,23},   {MB_B,22},   {MB_A,21},   {MB_CURR,20} };
98
99/*------------------------------------------------------------------------------
100    4. Local function prototypes
101------------------------------------------------------------------------------*/
102
103/*------------------------------------------------------------------------------
104
105    Function: h264bsdInitMbNeighbours
106
107        Functional description:
108            Initialize macroblock neighbours. Function sets neighbour
109            macroblock pointers in macroblock structures to point to
110            macroblocks on the left, above, above-right and above-left.
111            Pointers are set NULL if the neighbour does not fit into the
112            picture.
113
114        Inputs:
115            picWidth        width of the picture in macroblocks
116            picSizeInMbs    no need to clarify
117
118        Outputs:
119            pMbStorage      neighbour pointers of each mbStorage structure
120                            stored here
121
122        Returns:
123            none
124
125------------------------------------------------------------------------------*/
126
127void h264bsdInitMbNeighbours(mbStorage_t *pMbStorage, u32 picWidth,
128    u32 picSizeInMbs)
129{
130
131/* Variables */
132
133    u32 i, row, col;
134
135/* Code */
136
137    ASSERT(pMbStorage);
138    ASSERT(picWidth);
139    ASSERT(picWidth <= picSizeInMbs);
140    ASSERT(((picSizeInMbs / picWidth) * picWidth) == picSizeInMbs);
141
142    row = col = 0;
143
144    for (i = 0; i < picSizeInMbs; i++)
145    {
146
147        if (col)
148            pMbStorage[i].mbA = pMbStorage + i - 1;
149        else
150            pMbStorage[i].mbA = NULL;
151
152        if (row)
153            pMbStorage[i].mbB = pMbStorage + i - picWidth;
154        else
155            pMbStorage[i].mbB = NULL;
156
157        if (row && (col < picWidth - 1))
158            pMbStorage[i].mbC = pMbStorage + i - (picWidth - 1);
159        else
160            pMbStorage[i].mbC = NULL;
161
162        if (row && col)
163            pMbStorage[i].mbD = pMbStorage + i - (picWidth + 1);
164        else
165            pMbStorage[i].mbD = NULL;
166
167        col++;
168        if (col == picWidth)
169        {
170            col = 0;
171            row++;
172        }
173    }
174
175}
176
177/*------------------------------------------------------------------------------
178
179    Function: h264bsdGetNeighbourMb
180
181        Functional description:
182            Get pointer to neighbour macroblock.
183
184        Inputs:
185            pMb         pointer to macroblock structure of the macroblock
186                        whose neighbour is wanted
187            neighbour   indicates which neighbour is wanted
188
189        Outputs:
190            none
191
192        Returns:
193            pointer to neighbour macroblock
194            NULL if not available
195
196------------------------------------------------------------------------------*/
197
198mbStorage_t* h264bsdGetNeighbourMb(mbStorage_t *pMb, neighbourMb_e neighbour)
199{
200
201/* Variables */
202
203
204/* Code */
205
206    ASSERT((neighbour <= MB_CURR) || (neighbour == MB_NA));
207
208    if (neighbour == MB_A)
209        return(pMb->mbA);
210    else if (neighbour == MB_B)
211        return(pMb->mbB);
212    else if (neighbour == MB_C)
213        return(pMb->mbC);
214    else if (neighbour == MB_D)
215        return(pMb->mbD);
216    else if (neighbour == MB_CURR)
217        return(pMb);
218    else
219        return(NULL);
220
221}
222
223/*------------------------------------------------------------------------------
224
225    Function: h264bsdNeighbour4x4BlockA
226
227        Functional description:
228            Get left neighbour of the block. Function returns pointer to
229            the table defined in the beginning of the file.
230
231        Inputs:
232            blockIndex  indicates the block whose neighbours are wanted
233
234        Outputs:
235
236        Returns:
237            pointer to neighbour structure
238
239------------------------------------------------------------------------------*/
240
241const neighbour_t* h264bsdNeighbour4x4BlockA(u32 blockIndex)
242{
243
244/* Variables */
245
246/* Code */
247
248    ASSERT(blockIndex < 24);
249
250    return(N_A_4x4B+blockIndex);
251
252}
253
254/*------------------------------------------------------------------------------
255
256    Function: h264bsdNeighbour4x4BlockB
257
258        Functional description:
259            Get above neighbour of the block. Function returns pointer to
260            the table defined in the beginning of the file.
261
262        Inputs:
263            blockIndex  indicates the block whose neighbours are wanted
264
265        Outputs:
266
267        Returns:
268            pointer to neighbour structure
269
270------------------------------------------------------------------------------*/
271
272const neighbour_t* h264bsdNeighbour4x4BlockB(u32 blockIndex)
273{
274
275/* Variables */
276
277/* Code */
278
279    ASSERT(blockIndex < 24);
280
281    return(N_B_4x4B+blockIndex);
282
283}
284
285/*------------------------------------------------------------------------------
286
287    Function: h264bsdNeighbour4x4BlockC
288
289        Functional description:
290            Get above-right  neighbour of the block. Function returns pointer
291            to the table defined in the beginning of the file.
292
293        Inputs:
294            blockIndex  indicates the block whose neighbours are wanted
295
296        Outputs:
297
298        Returns:
299            pointer to neighbour structure
300
301------------------------------------------------------------------------------*/
302
303const neighbour_t* h264bsdNeighbour4x4BlockC(u32 blockIndex)
304{
305
306/* Variables */
307
308/* Code */
309
310    ASSERT(blockIndex < 24);
311
312    return(N_C_4x4B+blockIndex);
313
314}
315
316/*------------------------------------------------------------------------------
317
318    Function: h264bsdNeighbour4x4BlockD
319
320        Functional description:
321            Get above-left neighbour of the block. Function returns pointer to
322            the table defined in the beginning of the file.
323
324        Inputs:
325            blockIndex  indicates the block whose neighbours are wanted
326
327        Outputs:
328
329        Returns:
330            pointer to neighbour structure
331
332------------------------------------------------------------------------------*/
333
334const neighbour_t* h264bsdNeighbour4x4BlockD(u32 blockIndex)
335{
336
337/* Variables */
338
339/* Code */
340
341    ASSERT(blockIndex < 24);
342
343    return(N_D_4x4B+blockIndex);
344
345}
346
347/*------------------------------------------------------------------------------
348
349    Function: h264bsdIsNeighbourAvailable
350
351        Functional description:
352            Check if neighbour macroblock is available. Neighbour macroblock
353            is considered available if it is within the picture and belongs
354            to the same slice as the current macroblock.
355
356        Inputs:
357            pMb         pointer to the current macroblock
358            pNeighbour  pointer to the neighbour macroblock
359
360        Outputs:
361            none
362
363        Returns:
364            TRUE    neighbour is available
365            FALSE   neighbour is not available
366
367------------------------------------------------------------------------------*/
368
369u32 h264bsdIsNeighbourAvailable(mbStorage_t *pMb, mbStorage_t *pNeighbour)
370{
371
372/* Variables */
373
374/* Code */
375
376    if ( (pNeighbour == NULL) || (pMb->sliceId != pNeighbour->sliceId) )
377        return(HANTRO_FALSE);
378    else
379        return(HANTRO_TRUE);
380
381}
382
383