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 h264bsdDecodeSeqParamSet
27 GetDpbSize
28 h264bsdCompareSeqParamSets
29
30 ------------------------------------------------------------------------------*/
31
32 /*------------------------------------------------------------------------------
33 1. Include headers
34 ------------------------------------------------------------------------------*/
35
36 #include "h264bsd_seq_param_set.h"
37 #include "h264bsd_util.h"
38 #include "h264bsd_vlc.h"
39 #include "h264bsd_vui.h"
40 #include "h264bsd_cfg.h"
41
42 /*------------------------------------------------------------------------------
43 2. External compiler flags
44 --------------------------------------------------------------------------------
45
46 --------------------------------------------------------------------------------
47 3. Module defines
48 ------------------------------------------------------------------------------*/
49
50 /* enumeration to indicate invalid return value from the GetDpbSize function */
51 enum {INVALID_DPB_SIZE = 0x7FFFFFFF};
52
53 /*------------------------------------------------------------------------------
54 4. Local function prototypes
55 ------------------------------------------------------------------------------*/
56
57 static u32 GetDpbSize(u32 picSizeInMbs, u32 levelIdc);
58
59 /*------------------------------------------------------------------------------
60
61 Function name: h264bsdDecodeSeqParamSet
62
63 Functional description:
64 Decode sequence parameter set information from the stream.
65
66 Function allocates memory for offsetForRefFrame array if
67 picture order count type is 1 and numRefFramesInPicOrderCntCycle
68 is greater than zero.
69
70 Inputs:
71 pStrmData pointer to stream data structure
72
73 Outputs:
74 pSeqParamSet decoded information is stored here
75
76 Returns:
77 HANTRO_OK success
78 HANTRO_NOK failure, invalid information or end of stream
79 MEMORY_ALLOCATION_ERROR for memory allocation failure
80
81 ------------------------------------------------------------------------------*/
82
h264bsdDecodeSeqParamSet(strmData_t * pStrmData,seqParamSet_t * pSeqParamSet)83 u32 h264bsdDecodeSeqParamSet(strmData_t *pStrmData, seqParamSet_t *pSeqParamSet)
84 {
85
86 /* Variables */
87
88 u32 tmp, i, value;
89
90 /* Code */
91
92 ASSERT(pStrmData);
93 ASSERT(pSeqParamSet);
94
95 H264SwDecMemset(pSeqParamSet, 0, sizeof(seqParamSet_t));
96
97 /* profile_idc */
98 tmp = h264bsdGetBits(pStrmData, 8);
99 if (tmp == END_OF_STREAM)
100 return(HANTRO_NOK);
101 if (tmp != 66)
102 {
103 DEBUG(("NOT BASELINE PROFILE %d\n", tmp));
104 }
105 pSeqParamSet->profileIdc = tmp;
106
107 /* constrained_set0_flag */
108 tmp = h264bsdGetBits(pStrmData, 1);
109 /* constrained_set1_flag */
110 tmp = h264bsdGetBits(pStrmData, 1);
111 /* constrained_set2_flag */
112 tmp = h264bsdGetBits(pStrmData, 1);
113
114 if (tmp == END_OF_STREAM)
115 return(HANTRO_NOK);
116
117 /* reserved_zero_5bits, values of these bits shall be ignored */
118 tmp = h264bsdGetBits(pStrmData, 5);
119 if (tmp == END_OF_STREAM)
120 return(HANTRO_NOK);
121
122 tmp = h264bsdGetBits(pStrmData, 8);
123 if (tmp == END_OF_STREAM)
124 return(HANTRO_NOK);
125 pSeqParamSet->levelIdc = tmp;
126
127 tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
128 &pSeqParamSet->seqParameterSetId);
129 if (tmp != HANTRO_OK)
130 return(tmp);
131 if (pSeqParamSet->seqParameterSetId >= MAX_NUM_SEQ_PARAM_SETS)
132 {
133 EPRINT("seq_param_set_id");
134 return(HANTRO_NOK);
135 }
136
137 /* log2_max_frame_num_minus4 */
138 tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
139 if (tmp != HANTRO_OK)
140 return(tmp);
141 if (value > 12)
142 {
143 EPRINT("log2_max_frame_num_minus4");
144 return(HANTRO_NOK);
145 }
146 /* maxFrameNum = 2^(log2_max_frame_num_minus4 + 4) */
147 pSeqParamSet->maxFrameNum = 1 << (value+4);
148
149 /* valid POC types are 0, 1 and 2 */
150 tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
151 if (tmp != HANTRO_OK)
152 return(tmp);
153 if (value > 2)
154 {
155 EPRINT("pic_order_cnt_type");
156 return(HANTRO_NOK);
157 }
158 pSeqParamSet->picOrderCntType = value;
159
160 if (pSeqParamSet->picOrderCntType == 0)
161 {
162 /* log2_max_pic_order_cnt_lsb_minus4 */
163 tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
164 if (tmp != HANTRO_OK)
165 return(tmp);
166 if (value > 12)
167 {
168 EPRINT("log2_max_pic_order_cnt_lsb_minus4");
169 return(HANTRO_NOK);
170 }
171 /* maxPicOrderCntLsb = 2^(log2_max_pic_order_cnt_lsb_minus4 + 4) */
172 pSeqParamSet->maxPicOrderCntLsb = 1 << (value+4);
173 }
174 else if (pSeqParamSet->picOrderCntType == 1)
175 {
176 tmp = h264bsdGetBits(pStrmData, 1);
177 if (tmp == END_OF_STREAM)
178 return(HANTRO_NOK);
179 pSeqParamSet->deltaPicOrderAlwaysZeroFlag = (tmp == 1) ?
180 HANTRO_TRUE : HANTRO_FALSE;
181
182 tmp = h264bsdDecodeExpGolombSigned(pStrmData,
183 &pSeqParamSet->offsetForNonRefPic);
184 if (tmp != HANTRO_OK)
185 return(tmp);
186
187 tmp = h264bsdDecodeExpGolombSigned(pStrmData,
188 &pSeqParamSet->offsetForTopToBottomField);
189 if (tmp != HANTRO_OK)
190 return(tmp);
191
192 tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
193 &pSeqParamSet->numRefFramesInPicOrderCntCycle);
194 if (tmp != HANTRO_OK)
195 return(tmp);
196 if (pSeqParamSet->numRefFramesInPicOrderCntCycle > 255)
197 {
198 EPRINT("num_ref_frames_in_pic_order_cnt_cycle");
199 return(HANTRO_NOK);
200 }
201
202 if (pSeqParamSet->numRefFramesInPicOrderCntCycle)
203 {
204 /* NOTE: This has to be freed somewhere! */
205 ALLOCATE(pSeqParamSet->offsetForRefFrame,
206 pSeqParamSet->numRefFramesInPicOrderCntCycle, i32);
207 if (pSeqParamSet->offsetForRefFrame == NULL)
208 return(MEMORY_ALLOCATION_ERROR);
209
210 for (i = 0; i < pSeqParamSet->numRefFramesInPicOrderCntCycle; i++)
211 {
212 tmp = h264bsdDecodeExpGolombSigned(pStrmData,
213 pSeqParamSet->offsetForRefFrame + i);
214 if (tmp != HANTRO_OK)
215 return(tmp);
216 }
217 }
218 else
219 {
220 pSeqParamSet->offsetForRefFrame = NULL;
221 }
222 }
223
224 tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
225 &pSeqParamSet->numRefFrames);
226 if (tmp != HANTRO_OK)
227 return(tmp);
228 if (pSeqParamSet->numRefFrames > MAX_NUM_REF_PICS)
229 {
230 EPRINT("num_ref_frames");
231 return(HANTRO_NOK);
232 }
233
234 tmp = h264bsdGetBits(pStrmData, 1);
235 if (tmp == END_OF_STREAM)
236 return(HANTRO_NOK);
237 pSeqParamSet->gapsInFrameNumValueAllowedFlag = (tmp == 1) ?
238 HANTRO_TRUE : HANTRO_FALSE;
239
240 tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
241 if (tmp != HANTRO_OK)
242 return(tmp);
243 pSeqParamSet->picWidthInMbs = value + 1;
244
245 tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
246 if (tmp != HANTRO_OK)
247 return(tmp);
248 pSeqParamSet->picHeightInMbs = value + 1;
249
250 /* frame_mbs_only_flag, shall be 1 for baseline profile */
251 tmp = h264bsdGetBits(pStrmData, 1);
252 if (tmp == END_OF_STREAM)
253 return(HANTRO_NOK);
254 if (!tmp)
255 {
256 EPRINT("frame_mbs_only_flag");
257 return(HANTRO_NOK);
258 }
259
260 /* direct_8x8_inference_flag */
261 tmp = h264bsdGetBits(pStrmData, 1);
262 if (tmp == END_OF_STREAM)
263 return(HANTRO_NOK);
264
265 tmp = h264bsdGetBits(pStrmData, 1);
266 if (tmp == END_OF_STREAM)
267 return(HANTRO_NOK);
268 pSeqParamSet->frameCroppingFlag = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
269
270 if (pSeqParamSet->frameCroppingFlag)
271 {
272 tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
273 &pSeqParamSet->frameCropLeftOffset);
274 if (tmp != HANTRO_OK)
275 return(tmp);
276 tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
277 &pSeqParamSet->frameCropRightOffset);
278 if (tmp != HANTRO_OK)
279 return(tmp);
280 tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
281 &pSeqParamSet->frameCropTopOffset);
282 if (tmp != HANTRO_OK)
283 return(tmp);
284 tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
285 &pSeqParamSet->frameCropBottomOffset);
286 if (tmp != HANTRO_OK)
287 return(tmp);
288
289 /* check that frame cropping params are valid, parameters shall
290 * specify non-negative area within the original picture */
291 if ( ( (i32)pSeqParamSet->frameCropLeftOffset >
292 ( 8 * (i32)pSeqParamSet->picWidthInMbs -
293 ((i32)pSeqParamSet->frameCropRightOffset + 1) ) ) ||
294 ( (i32)pSeqParamSet->frameCropTopOffset >
295 ( 8 * (i32)pSeqParamSet->picHeightInMbs -
296 ((i32)pSeqParamSet->frameCropBottomOffset + 1) ) ) )
297 {
298 EPRINT("frame_cropping");
299 return(HANTRO_NOK);
300 }
301 }
302
303 /* check that image dimensions and levelIdc match */
304 tmp = pSeqParamSet->picWidthInMbs * pSeqParamSet->picHeightInMbs;
305 value = GetDpbSize(tmp, pSeqParamSet->levelIdc);
306 if (value == INVALID_DPB_SIZE || pSeqParamSet->numRefFrames > value)
307 {
308 DEBUG(("WARNING! Invalid DPB size based on SPS Level!\n"));
309 DEBUG(("WARNING! Using num_ref_frames =%d for DPB size!\n",
310 pSeqParamSet->numRefFrames));
311 value = pSeqParamSet->numRefFrames;
312 }
313 pSeqParamSet->maxDpbSize = value;
314
315 tmp = h264bsdGetBits(pStrmData, 1);
316 if (tmp == END_OF_STREAM)
317 return(HANTRO_NOK);
318 pSeqParamSet->vuiParametersPresentFlag = (tmp == 1) ?
319 HANTRO_TRUE : HANTRO_FALSE;
320
321 /* VUI */
322 if (pSeqParamSet->vuiParametersPresentFlag)
323 {
324 ALLOCATE(pSeqParamSet->vuiParameters, 1, vuiParameters_t);
325 if (pSeqParamSet->vuiParameters == NULL)
326 return(MEMORY_ALLOCATION_ERROR);
327 tmp = h264bsdDecodeVuiParameters(pStrmData,
328 pSeqParamSet->vuiParameters);
329 if (tmp != HANTRO_OK)
330 return(tmp);
331 /* check numReorderFrames and maxDecFrameBuffering */
332 if (pSeqParamSet->vuiParameters->bitstreamRestrictionFlag)
333 {
334 if (pSeqParamSet->vuiParameters->numReorderFrames >
335 pSeqParamSet->vuiParameters->maxDecFrameBuffering ||
336 pSeqParamSet->vuiParameters->maxDecFrameBuffering <
337 pSeqParamSet->numRefFrames ||
338 pSeqParamSet->vuiParameters->maxDecFrameBuffering >
339 pSeqParamSet->maxDpbSize)
340 {
341 return(HANTRO_NOK);
342 }
343
344 /* standard says that "the sequence shall not require a DPB with
345 * size of more than max(1, maxDecFrameBuffering) */
346 pSeqParamSet->maxDpbSize =
347 MAX(1, pSeqParamSet->vuiParameters->maxDecFrameBuffering);
348 }
349 }
350
351 tmp = h264bsdRbspTrailingBits(pStrmData);
352
353 /* ignore possible errors in trailing bits of parameters sets */
354 return(HANTRO_OK);
355
356 }
357
358 /*------------------------------------------------------------------------------
359
360 Function: GetDpbSize
361
362 Functional description:
363 Get size of the DPB in frames. Size is determined based on the
364 picture size and MaxDPB for the specified level. These determine
365 how many pictures may fit into to the buffer. However, the size
366 is also limited to a maximum of 16 frames and therefore function
367 returns the minimum of the determined size and 16.
368
369 Inputs:
370 picSizeInMbs number of macroblocks in the picture
371 levelIdc indicates the level
372
373 Outputs:
374 none
375
376 Returns:
377 size of the DPB in frames
378 INVALID_DPB_SIZE when invalid levelIdc specified or picSizeInMbs
379 is higher than supported by the level in question
380
381 ------------------------------------------------------------------------------*/
382
GetDpbSize(u32 picSizeInMbs,u32 levelIdc)383 u32 GetDpbSize(u32 picSizeInMbs, u32 levelIdc)
384 {
385
386 /* Variables */
387
388 u32 tmp;
389 u32 maxPicSizeInMbs;
390
391 /* Code */
392
393 ASSERT(picSizeInMbs);
394
395 /* use tmp as the size of the DPB in bytes, computes as 1024 * MaxDPB
396 * (from table A-1 in Annex A) */
397 switch (levelIdc)
398 {
399 case 10:
400 tmp = 152064;
401 maxPicSizeInMbs = 99;
402 break;
403
404 case 11:
405 tmp = 345600;
406 maxPicSizeInMbs = 396;
407 break;
408
409 case 12:
410 tmp = 912384;
411 maxPicSizeInMbs = 396;
412 break;
413
414 case 13:
415 tmp = 912384;
416 maxPicSizeInMbs = 396;
417 break;
418
419 case 20:
420 tmp = 912384;
421 maxPicSizeInMbs = 396;
422 break;
423
424 case 21:
425 tmp = 1824768;
426 maxPicSizeInMbs = 792;
427 break;
428
429 case 22:
430 tmp = 3110400;
431 maxPicSizeInMbs = 1620;
432 break;
433
434 case 30:
435 tmp = 3110400;
436 maxPicSizeInMbs = 1620;
437 break;
438
439 case 31:
440 tmp = 6912000;
441 maxPicSizeInMbs = 3600;
442 break;
443
444 case 32:
445 tmp = 7864320;
446 maxPicSizeInMbs = 5120;
447 break;
448
449 case 40:
450 tmp = 12582912;
451 maxPicSizeInMbs = 8192;
452 break;
453
454 case 41:
455 tmp = 12582912;
456 maxPicSizeInMbs = 8192;
457 break;
458
459 case 42:
460 tmp = 34816*384;
461 maxPicSizeInMbs = 8704;
462 break;
463
464 case 50:
465 /* standard says 42301440 here, but corrigendum "corrects" this to
466 * 42393600 */
467 tmp = 42393600;
468 maxPicSizeInMbs = 22080;
469 break;
470
471 case 51:
472 tmp = 70778880;
473 maxPicSizeInMbs = 36864;
474 break;
475
476 default:
477 return(INVALID_DPB_SIZE);
478 }
479
480 /* this is not "correct" return value! However, it results in error in
481 * decoding and this was easiest place to check picture size */
482 if (picSizeInMbs > maxPicSizeInMbs)
483 return(INVALID_DPB_SIZE);
484
485 tmp /= (picSizeInMbs*384);
486
487 return(MIN(tmp, 16));
488
489 }
490
491 /*------------------------------------------------------------------------------
492
493 Function name: h264bsdCompareSeqParamSets
494
495 Functional description:
496 Compare two sequence parameter sets.
497
498 Inputs:
499 pSps1 pointer to a sequence parameter set
500 pSps2 pointer to another sequence parameter set
501
502 Outputs:
503 0 sequence parameter sets are equal
504 1 otherwise
505
506 ------------------------------------------------------------------------------*/
507
h264bsdCompareSeqParamSets(seqParamSet_t * pSps1,seqParamSet_t * pSps2)508 u32 h264bsdCompareSeqParamSets(seqParamSet_t *pSps1, seqParamSet_t *pSps2)
509 {
510
511 /* Variables */
512
513 u32 i;
514
515 /* Code */
516
517 ASSERT(pSps1);
518 ASSERT(pSps2);
519
520 /* first compare parameters whose existence does not depend on other
521 * parameters and only compare the rest of the params if these are equal */
522 if (pSps1->profileIdc == pSps2->profileIdc &&
523 pSps1->levelIdc == pSps2->levelIdc &&
524 pSps1->maxFrameNum == pSps2->maxFrameNum &&
525 pSps1->picOrderCntType == pSps2->picOrderCntType &&
526 pSps1->numRefFrames == pSps2->numRefFrames &&
527 pSps1->gapsInFrameNumValueAllowedFlag ==
528 pSps2->gapsInFrameNumValueAllowedFlag &&
529 pSps1->picWidthInMbs == pSps2->picWidthInMbs &&
530 pSps1->picHeightInMbs == pSps2->picHeightInMbs &&
531 pSps1->frameCroppingFlag == pSps2->frameCroppingFlag &&
532 pSps1->vuiParametersPresentFlag == pSps2->vuiParametersPresentFlag)
533 {
534 if (pSps1->picOrderCntType == 0)
535 {
536 if (pSps1->maxPicOrderCntLsb != pSps2->maxPicOrderCntLsb)
537 return 1;
538 }
539 else if (pSps1->picOrderCntType == 1)
540 {
541 if (pSps1->deltaPicOrderAlwaysZeroFlag !=
542 pSps2->deltaPicOrderAlwaysZeroFlag ||
543 pSps1->offsetForNonRefPic != pSps2->offsetForNonRefPic ||
544 pSps1->offsetForTopToBottomField !=
545 pSps2->offsetForTopToBottomField ||
546 pSps1->numRefFramesInPicOrderCntCycle !=
547 pSps2->numRefFramesInPicOrderCntCycle)
548 {
549 return 1;
550 }
551 else
552 {
553 for (i = 0; i < pSps1->numRefFramesInPicOrderCntCycle; i++)
554 if (pSps1->offsetForRefFrame[i] !=
555 pSps2->offsetForRefFrame[i])
556 {
557 return 1;
558 }
559 }
560 }
561 if (pSps1->frameCroppingFlag)
562 {
563 if (pSps1->frameCropLeftOffset != pSps2->frameCropLeftOffset ||
564 pSps1->frameCropRightOffset != pSps2->frameCropRightOffset ||
565 pSps1->frameCropTopOffset != pSps2->frameCropTopOffset ||
566 pSps1->frameCropBottomOffset != pSps2->frameCropBottomOffset)
567 {
568 return 1;
569 }
570 }
571
572 return 0;
573 }
574
575 return 1;
576 }
577
578