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 */
51enum {INVALID_DPB_SIZE = 0x7FFFFFFF};
52
53/*------------------------------------------------------------------------------
54    4. Local function prototypes
55------------------------------------------------------------------------------*/
56
57static 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
83u32 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
383u32 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
508u32 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