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 */
64 static 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 */
73 static 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 */
82 static 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 */
91 static 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 
h264bsdInitMbNeighbours(mbStorage_t * pMbStorage,u32 picWidth,u32 picSizeInMbs)127 void 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 
h264bsdGetNeighbourMb(mbStorage_t * pMb,neighbourMb_e neighbour)198 mbStorage_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 
h264bsdNeighbour4x4BlockA(u32 blockIndex)241 const 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 
h264bsdNeighbour4x4BlockB(u32 blockIndex)272 const 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 
h264bsdNeighbour4x4BlockC(u32 blockIndex)303 const 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 
h264bsdNeighbour4x4BlockD(u32 blockIndex)334 const 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 
h264bsdIsNeighbourAvailable(mbStorage_t * pMb,mbStorage_t * pNeighbour)369 u32 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