h264bsd_vui.c revision 21e525fdcc234c22d843a8bf1a4ec35c4b376314
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          h264bsdDecodeVuiParameters
27          DecodeHrdParameters
28
29------------------------------------------------------------------------------*/
30
31/*------------------------------------------------------------------------------
32    1. Include headers
33------------------------------------------------------------------------------*/
34
35#include "h264bsd_vui.h"
36#include "basetype.h"
37#include "h264bsd_vlc.h"
38#include "h264bsd_stream.h"
39#include "h264bsd_util.h"
40
41/*------------------------------------------------------------------------------
42    2. External compiler flags
43--------------------------------------------------------------------------------
44
45--------------------------------------------------------------------------------
46    3. Module defines
47------------------------------------------------------------------------------*/
48
49#define MAX_DPB_SIZE 16
50#define MAX_BR       240000 /* for level 5.1 */
51#define MAX_CPB      240000 /* for level 5.1 */
52
53/*------------------------------------------------------------------------------
54    4. Local function prototypes
55------------------------------------------------------------------------------*/
56
57static u32 DecodeHrdParameters(
58  strmData_t *pStrmData,
59  hrdParameters_t *pHrdParameters);
60
61/*------------------------------------------------------------------------------
62
63    Function: h264bsdDecodeVuiParameters
64
65        Functional description:
66            Decode VUI parameters from the stream. See standard for details.
67
68        Inputs:
69            pStrmData       pointer to stream data structure
70
71        Outputs:
72            pVuiParameters  decoded information is stored here
73
74        Returns:
75            HANTRO_OK       success
76            HANTRO_NOK      invalid stream data or end of stream
77
78------------------------------------------------------------------------------*/
79
80u32 h264bsdDecodeVuiParameters(strmData_t *pStrmData,
81    vuiParameters_t *pVuiParameters)
82{
83
84/* Variables */
85
86    u32 tmp;
87
88/* Code */
89
90    ASSERT(pStrmData);
91    ASSERT(pVuiParameters);
92
93    H264SwDecMemset(pVuiParameters, 0, sizeof(vuiParameters_t));
94
95    tmp = h264bsdGetBits(pStrmData, 1);
96    if (tmp == END_OF_STREAM)
97        return(HANTRO_NOK);
98    pVuiParameters->aspectRatioPresentFlag = (tmp == 1) ?
99                                HANTRO_TRUE : HANTRO_FALSE;
100
101    if (pVuiParameters->aspectRatioPresentFlag)
102    {
103        tmp = h264bsdGetBits(pStrmData, 8);
104        if (tmp == END_OF_STREAM)
105            return(HANTRO_NOK);
106        pVuiParameters->aspectRatioIdc = tmp;
107
108        if (pVuiParameters->aspectRatioIdc == ASPECT_RATIO_EXTENDED_SAR)
109        {
110            tmp = h264bsdGetBits(pStrmData, 16);
111            if (tmp == END_OF_STREAM)
112                return(HANTRO_NOK);
113            pVuiParameters->sarWidth = tmp;
114
115            tmp = h264bsdGetBits(pStrmData, 16);
116            if (tmp == END_OF_STREAM)
117                return(HANTRO_NOK);
118            pVuiParameters->sarHeight = tmp;
119        }
120    }
121
122    tmp = h264bsdGetBits(pStrmData, 1);
123    if (tmp == END_OF_STREAM)
124        return(HANTRO_NOK);
125    pVuiParameters->overscanInfoPresentFlag = (tmp == 1) ?
126                                HANTRO_TRUE : HANTRO_FALSE;
127
128    if (pVuiParameters->overscanInfoPresentFlag)
129    {
130        tmp = h264bsdGetBits(pStrmData, 1);
131        if (tmp == END_OF_STREAM)
132            return(HANTRO_NOK);
133        pVuiParameters->overscanAppropriateFlag = (tmp == 1) ?
134                                HANTRO_TRUE : HANTRO_FALSE;
135    }
136
137    tmp = h264bsdGetBits(pStrmData, 1);
138    if (tmp == END_OF_STREAM)
139        return(HANTRO_NOK);
140    pVuiParameters->videoSignalTypePresentFlag = (tmp == 1) ?
141                                HANTRO_TRUE : HANTRO_FALSE;
142
143    if (pVuiParameters->videoSignalTypePresentFlag)
144    {
145        tmp = h264bsdGetBits(pStrmData, 3);
146        if (tmp == END_OF_STREAM)
147            return(HANTRO_NOK);
148        pVuiParameters->videoFormat = tmp;
149
150        tmp = h264bsdGetBits(pStrmData, 1);
151        if (tmp == END_OF_STREAM)
152            return(HANTRO_NOK);
153        pVuiParameters->videoFullRangeFlag = (tmp == 1) ?
154                                HANTRO_TRUE : HANTRO_FALSE;
155
156        tmp = h264bsdGetBits(pStrmData, 1);
157        if (tmp == END_OF_STREAM)
158            return(HANTRO_NOK);
159        pVuiParameters->colourDescriptionPresentFlag =
160            (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
161
162        if (pVuiParameters->colourDescriptionPresentFlag)
163        {
164            tmp = h264bsdGetBits(pStrmData, 8);
165            if (tmp == END_OF_STREAM)
166                return(HANTRO_NOK);
167            pVuiParameters->colourPrimaries = tmp;
168
169            tmp = h264bsdGetBits(pStrmData, 8);
170            if (tmp == END_OF_STREAM)
171                return(HANTRO_NOK);
172            pVuiParameters->transferCharacteristics = tmp;
173
174            tmp = h264bsdGetBits(pStrmData, 8);
175            if (tmp == END_OF_STREAM)
176                return(HANTRO_NOK);
177            pVuiParameters->matrixCoefficients = tmp;
178        }
179        else
180        {
181            pVuiParameters->colourPrimaries         = 2;
182            pVuiParameters->transferCharacteristics = 2;
183            pVuiParameters->matrixCoefficients      = 2;
184        }
185    }
186    else
187    {
188        pVuiParameters->videoFormat             = 5;
189        pVuiParameters->colourPrimaries         = 2;
190        pVuiParameters->transferCharacteristics = 2;
191        pVuiParameters->matrixCoefficients      = 2;
192    }
193
194    tmp = h264bsdGetBits(pStrmData, 1);
195    if (tmp == END_OF_STREAM)
196        return(HANTRO_NOK);
197    pVuiParameters->chromaLocInfoPresentFlag =
198        (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
199
200    if (pVuiParameters->chromaLocInfoPresentFlag)
201    {
202        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
203          &pVuiParameters->chromaSampleLocTypeTopField);
204        if (tmp != HANTRO_OK)
205            return(tmp);
206        if (pVuiParameters->chromaSampleLocTypeTopField > 5)
207            return(HANTRO_NOK);
208
209        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
210          &pVuiParameters->chromaSampleLocTypeBottomField);
211        if (tmp != HANTRO_OK)
212            return(tmp);
213        if (pVuiParameters->chromaSampleLocTypeBottomField > 5)
214            return(HANTRO_NOK);
215    }
216
217    tmp = h264bsdGetBits(pStrmData, 1);
218    if (tmp == END_OF_STREAM)
219        return(HANTRO_NOK);
220    pVuiParameters->timingInfoPresentFlag =
221        (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
222
223    if (pVuiParameters->timingInfoPresentFlag)
224    {
225        tmp = h264bsdShowBits32(pStrmData);
226        if (h264bsdFlushBits(pStrmData, 32) == END_OF_STREAM)
227            return(HANTRO_NOK);
228        if (tmp == 0)
229            return(HANTRO_NOK);
230        pVuiParameters->numUnitsInTick = tmp;
231
232        tmp = h264bsdShowBits32(pStrmData);
233        if (h264bsdFlushBits(pStrmData, 32) == END_OF_STREAM)
234            return(HANTRO_NOK);
235        if (tmp == 0)
236            return(HANTRO_NOK);
237        pVuiParameters->timeScale = tmp;
238
239        tmp = h264bsdGetBits(pStrmData, 1);
240        if (tmp == END_OF_STREAM)
241            return(HANTRO_NOK);
242        pVuiParameters->fixedFrameRateFlag =
243            (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
244    }
245
246    tmp = h264bsdGetBits(pStrmData, 1);
247    if (tmp == END_OF_STREAM)
248        return(HANTRO_NOK);
249    pVuiParameters->nalHrdParametersPresentFlag =
250        (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
251
252    if (pVuiParameters->nalHrdParametersPresentFlag)
253    {
254        tmp = DecodeHrdParameters(pStrmData, &pVuiParameters->nalHrdParameters);
255        if (tmp != HANTRO_OK)
256            return(tmp);
257    }
258    else
259    {
260        pVuiParameters->nalHrdParameters.cpbCnt          = 1;
261        /* MaxBR and MaxCPB should be the values correspondig to the levelIdc
262         * in the SPS containing these VUI parameters. However, these values
263         * are not used anywhere and maximum for any level will be used here */
264        pVuiParameters->nalHrdParameters.bitRateValue[0] = 1200 * MAX_BR + 1;
265        pVuiParameters->nalHrdParameters.cpbSizeValue[0] = 1200 * MAX_CPB + 1;
266        pVuiParameters->nalHrdParameters.initialCpbRemovalDelayLength = 24;
267        pVuiParameters->nalHrdParameters.cpbRemovalDelayLength        = 24;
268        pVuiParameters->nalHrdParameters.dpbOutputDelayLength         = 24;
269        pVuiParameters->nalHrdParameters.timeOffsetLength             = 24;
270    }
271
272    tmp = h264bsdGetBits(pStrmData, 1);
273    if (tmp == END_OF_STREAM)
274        return(HANTRO_NOK);
275    pVuiParameters->vclHrdParametersPresentFlag =
276        (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
277
278    if (pVuiParameters->vclHrdParametersPresentFlag)
279    {
280        tmp = DecodeHrdParameters(pStrmData, &pVuiParameters->vclHrdParameters);
281        if (tmp != HANTRO_OK)
282            return(tmp);
283    }
284    else
285    {
286        pVuiParameters->vclHrdParameters.cpbCnt          = 1;
287        /* MaxBR and MaxCPB should be the values correspondig to the levelIdc
288         * in the SPS containing these VUI parameters. However, these values
289         * are not used anywhere and maximum for any level will be used here */
290        pVuiParameters->vclHrdParameters.bitRateValue[0] = 1000 * MAX_BR + 1;
291        pVuiParameters->vclHrdParameters.cpbSizeValue[0] = 1000 * MAX_CPB + 1;
292        pVuiParameters->vclHrdParameters.initialCpbRemovalDelayLength = 24;
293        pVuiParameters->vclHrdParameters.cpbRemovalDelayLength        = 24;
294        pVuiParameters->vclHrdParameters.dpbOutputDelayLength         = 24;
295        pVuiParameters->vclHrdParameters.timeOffsetLength             = 24;
296    }
297
298    if (pVuiParameters->nalHrdParametersPresentFlag ||
299      pVuiParameters->vclHrdParametersPresentFlag)
300    {
301        tmp = h264bsdGetBits(pStrmData, 1);
302        if (tmp == END_OF_STREAM)
303            return(HANTRO_NOK);
304        pVuiParameters->lowDelayHrdFlag =
305            (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
306    }
307
308    tmp = h264bsdGetBits(pStrmData, 1);
309    if (tmp == END_OF_STREAM)
310        return(HANTRO_NOK);
311    pVuiParameters->picStructPresentFlag =
312        (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
313
314    tmp = h264bsdGetBits(pStrmData, 1);
315    if (tmp == END_OF_STREAM)
316        return(HANTRO_NOK);
317    pVuiParameters->bitstreamRestrictionFlag =
318        (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
319
320    if (pVuiParameters->bitstreamRestrictionFlag)
321    {
322        tmp = h264bsdGetBits(pStrmData, 1);
323        if (tmp == END_OF_STREAM)
324            return(HANTRO_NOK);
325        pVuiParameters->motionVectorsOverPicBoundariesFlag =
326            (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
327
328        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
329          &pVuiParameters->maxBytesPerPicDenom);
330        if (tmp != HANTRO_OK)
331            return(tmp);
332        if (pVuiParameters->maxBytesPerPicDenom > 16)
333            return(HANTRO_NOK);
334
335        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
336          &pVuiParameters->maxBitsPerMbDenom);
337        if (tmp != HANTRO_OK)
338            return(tmp);
339        if (pVuiParameters->maxBitsPerMbDenom > 16)
340            return(HANTRO_NOK);
341
342        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
343          &pVuiParameters->log2MaxMvLengthHorizontal);
344        if (tmp != HANTRO_OK)
345            return(tmp);
346        if (pVuiParameters->log2MaxMvLengthHorizontal > 16)
347            return(HANTRO_NOK);
348
349        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
350          &pVuiParameters->log2MaxMvLengthVertical);
351        if (tmp != HANTRO_OK)
352            return(tmp);
353        if (pVuiParameters->log2MaxMvLengthVertical > 16)
354            return(HANTRO_NOK);
355
356        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
357          &pVuiParameters->numReorderFrames);
358        if (tmp != HANTRO_OK)
359            return(tmp);
360
361        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
362          &pVuiParameters->maxDecFrameBuffering);
363        if (tmp != HANTRO_OK)
364            return(tmp);
365    }
366    else
367    {
368        pVuiParameters->motionVectorsOverPicBoundariesFlag = HANTRO_TRUE;
369        pVuiParameters->maxBytesPerPicDenom       = 2;
370        pVuiParameters->maxBitsPerMbDenom         = 1;
371        pVuiParameters->log2MaxMvLengthHorizontal = 16;
372        pVuiParameters->log2MaxMvLengthVertical   = 16;
373        pVuiParameters->numReorderFrames          = MAX_DPB_SIZE;
374        pVuiParameters->maxDecFrameBuffering      = MAX_DPB_SIZE;
375    }
376
377    return(HANTRO_OK);
378
379}
380
381/*------------------------------------------------------------------------------
382
383    Function: DecodeHrdParameters
384
385        Functional description:
386            Decode HRD parameters from the stream. See standard for details.
387
388        Inputs:
389            pStrmData       pointer to stream data structure
390
391        Outputs:
392            pHrdParameters  decoded information is stored here
393
394        Returns:
395            HANTRO_OK       success
396            HANTRO_NOK      invalid stream data
397
398------------------------------------------------------------------------------*/
399
400static u32 DecodeHrdParameters(
401  strmData_t *pStrmData,
402  hrdParameters_t *pHrdParameters)
403{
404
405/* Variables */
406
407    u32 tmp, i;
408
409/* Code */
410
411    ASSERT(pStrmData);
412    ASSERT(pHrdParameters);
413
414
415    tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &pHrdParameters->cpbCnt);
416    if (tmp != HANTRO_OK)
417        return(tmp);
418    /* cpbCount = cpb_cnt_minus1 + 1 */
419    pHrdParameters->cpbCnt++;
420    if (pHrdParameters->cpbCnt > MAX_CPB_CNT)
421        return(HANTRO_NOK);
422
423    tmp = h264bsdGetBits(pStrmData, 4);
424    if (tmp == END_OF_STREAM)
425        return(HANTRO_NOK);
426    pHrdParameters->bitRateScale = tmp;
427
428    tmp = h264bsdGetBits(pStrmData, 4);
429    if (tmp == END_OF_STREAM)
430        return(HANTRO_NOK);
431    pHrdParameters->cpbSizeScale = tmp;
432
433    for (i = 0; i < pHrdParameters->cpbCnt; i++)
434    {
435        /* bit_rate_value_minus1 in the range [0, 2^32 - 2] */
436        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
437          &pHrdParameters->bitRateValue[i]);
438        if (tmp != HANTRO_OK)
439            return(tmp);
440        if (pHrdParameters->bitRateValue[i] > 4294967294U)
441            return(HANTRO_NOK);
442        pHrdParameters->bitRateValue[i]++;
443        /* this may result in overflow, but this value is not used for
444         * anything */
445        pHrdParameters->bitRateValue[i] *=
446            1 << (6 + pHrdParameters->bitRateScale);
447
448        /* cpb_size_value_minus1 in the range [0, 2^32 - 2] */
449        tmp = h264bsdDecodeExpGolombUnsigned(pStrmData,
450          &pHrdParameters->cpbSizeValue[i]);
451        if (tmp != HANTRO_OK)
452            return(tmp);
453        if (pHrdParameters->cpbSizeValue[i] > 4294967294U)
454            return(HANTRO_NOK);
455        pHrdParameters->cpbSizeValue[i]++;
456        /* this may result in overflow, but this value is not used for
457         * anything */
458        pHrdParameters->cpbSizeValue[i] *=
459            1 << (4 + pHrdParameters->cpbSizeScale);
460
461        tmp = h264bsdGetBits(pStrmData, 1);
462        if (tmp == END_OF_STREAM)
463            return(HANTRO_NOK);
464        pHrdParameters->cbrFlag[i] = (tmp == 1) ? HANTRO_TRUE : HANTRO_FALSE;
465    }
466
467    tmp = h264bsdGetBits(pStrmData, 5);
468    if (tmp == END_OF_STREAM)
469        return(HANTRO_NOK);
470    pHrdParameters->initialCpbRemovalDelayLength = tmp + 1;
471
472    tmp = h264bsdGetBits(pStrmData, 5);
473    if (tmp == END_OF_STREAM)
474        return(HANTRO_NOK);
475    pHrdParameters->cpbRemovalDelayLength = tmp + 1;
476
477    tmp = h264bsdGetBits(pStrmData, 5);
478    if (tmp == END_OF_STREAM)
479        return(HANTRO_NOK);
480    pHrdParameters->dpbOutputDelayLength = tmp + 1;
481
482    tmp = h264bsdGetBits(pStrmData, 5);
483    if (tmp == END_OF_STREAM)
484        return(HANTRO_NOK);
485    pHrdParameters->timeOffsetLength = tmp;
486
487    return(HANTRO_OK);
488
489}
490
491