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