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          h264bsdInit
27          h264bsdDecode
28          h264bsdShutdown
29          h264bsdCurrentImage
30          h264bsdNextOutputPicture
31          h264bsdPicWidth
32          h264bsdPicHeight
33          h264bsdFlushBuffer
34          h264bsdCheckValidParamSets
35          h264bsdVideoRange
36          h264bsdMatrixCoefficients
37          h264bsdCroppingParams
38
39------------------------------------------------------------------------------*/
40
41/*------------------------------------------------------------------------------
42    1. Include headers
43------------------------------------------------------------------------------*/
44
45#include "h264bsd_decoder.h"
46#include "h264bsd_nal_unit.h"
47#include "h264bsd_byte_stream.h"
48#include "h264bsd_seq_param_set.h"
49#include "h264bsd_pic_param_set.h"
50#include "h264bsd_slice_header.h"
51#include "h264bsd_slice_data.h"
52#include "h264bsd_neighbour.h"
53#include "h264bsd_util.h"
54#include "h264bsd_dpb.h"
55#include "h264bsd_deblocking.h"
56#include "h264bsd_conceal.h"
57
58/*------------------------------------------------------------------------------
59    2. External compiler flags
60--------------------------------------------------------------------------------
61
62--------------------------------------------------------------------------------
63    3. Module defines
64------------------------------------------------------------------------------*/
65
66/*------------------------------------------------------------------------------
67    4. Local function prototypes
68------------------------------------------------------------------------------*/
69
70/*------------------------------------------------------------------------------
71
72    Function name: h264bsdInit
73
74        Functional description:
75            Initialize the decoder.
76
77        Inputs:
78            noOutputReordering  flag to indicate the decoder that it does not
79                                have to perform reordering of display images.
80
81        Outputs:
82            pStorage            pointer to initialized storage structure
83
84        Returns:
85            none
86
87------------------------------------------------------------------------------*/
88
89u32 h264bsdInit(storage_t *pStorage, u32 noOutputReordering)
90{
91
92/* Variables */
93    u32 size;
94/* Code */
95
96    ASSERT(pStorage);
97
98    h264bsdInitStorage(pStorage);
99
100    /* allocate mbLayer to be next multiple of 64 to enable use of
101     * specific NEON optimized "memset" for clearing the structure */
102    size = (sizeof(macroblockLayer_t) + 63) & ~0x3F;
103
104    pStorage->mbLayer = (macroblockLayer_t*)H264SwDecMalloc(size, 1);
105    if (!pStorage->mbLayer)
106        return HANTRO_NOK;
107
108    if (noOutputReordering)
109        pStorage->noReordering = HANTRO_TRUE;
110
111    return HANTRO_OK;
112}
113
114/*------------------------------------------------------------------------------
115
116    Function: h264bsdDecode
117
118        Functional description:
119            Decode a NAL unit. This function calls other modules to perform
120            tasks like
121                * extract and decode NAL unit from the byte stream
122                * decode parameter sets
123                * decode slice header and slice data
124                * conceal errors in the picture
125                * perform deblocking filtering
126
127            This function contains top level control logic of the decoder.
128
129        Inputs:
130            pStorage        pointer to storage data structure
131            byteStrm        pointer to stream buffer given by application
132            len             length of the buffer in bytes
133            picId           identifier for a picture, assigned by the
134                            application
135
136        Outputs:
137            readBytes       number of bytes read from the stream is stored
138                            here
139
140        Returns:
141            H264BSD_RDY             decoding finished, nothing special
142            H264BSD_PIC_RDY         decoding of a picture finished
143            H264BSD_HDRS_RDY        param sets activated, information like
144                                    picture dimensions etc can be read
145            H264BSD_ERROR           error in decoding
146            H264BSD_PARAM_SET_ERROR serius error in decoding, failed to
147                                    activate param sets
148
149------------------------------------------------------------------------------*/
150
151u32 h264bsdDecode(storage_t *pStorage, u8 *byteStrm, u32 len, u32 picId,
152    u32 *readBytes)
153{
154
155/* Variables */
156
157    u32 tmp, ppsId, spsId;
158    i32 picOrderCnt;
159    nalUnit_t nalUnit;
160    seqParamSet_t seqParamSet;
161    picParamSet_t picParamSet;
162    strmData_t strm;
163    u32 accessUnitBoundaryFlag = HANTRO_FALSE;
164    u32 picReady = HANTRO_FALSE;
165
166/* Code */
167
168    ASSERT(pStorage);
169    ASSERT(byteStrm);
170    ASSERT(len);
171    ASSERT(readBytes);
172
173    /* if previous buffer was not finished and same pointer given -> skip NAL
174     * unit extraction */
175    if (pStorage->prevBufNotFinished && byteStrm == pStorage->prevBufPointer)
176    {
177        strm = pStorage->strm[0];
178        strm.pStrmCurrPos = strm.pStrmBuffStart;
179        strm.strmBuffReadBits = strm.bitPosInWord = 0;
180        *readBytes = pStorage->prevBytesConsumed;
181    }
182    else
183    {
184        tmp = h264bsdExtractNalUnit(byteStrm, len, &strm, readBytes);
185        if (tmp != HANTRO_OK)
186        {
187            EPRINT("BYTE_STREAM");
188            return(H264BSD_ERROR);
189        }
190        /* store stream */
191        pStorage->strm[0] = strm;
192        pStorage->prevBytesConsumed = *readBytes;
193        pStorage->prevBufPointer = byteStrm;
194    }
195    pStorage->prevBufNotFinished = HANTRO_FALSE;
196
197    tmp = h264bsdDecodeNalUnit(&strm, &nalUnit);
198    if (tmp != HANTRO_OK)
199    {
200        EPRINT("NAL_UNIT");
201        return(H264BSD_ERROR);
202    }
203
204    /* Discard unspecified, reserved, SPS extension and auxiliary picture slices */
205    if(nalUnit.nalUnitType == 0 || nalUnit.nalUnitType >= 13)
206    {
207        DEBUG(("DISCARDED NAL (UNSPECIFIED, REGISTERED, SPS ext or AUX slice)\n"));
208        return(H264BSD_RDY);
209    }
210
211    tmp = h264bsdCheckAccessUnitBoundary(
212      &strm,
213      &nalUnit,
214      pStorage,
215      &accessUnitBoundaryFlag);
216    if (tmp != HANTRO_OK)
217    {
218        EPRINT("ACCESS UNIT BOUNDARY CHECK");
219        if (tmp == PARAM_SET_ERROR)
220            return(H264BSD_PARAM_SET_ERROR);
221        else
222            return(H264BSD_ERROR);
223    }
224
225    if ( accessUnitBoundaryFlag )
226    {
227        DEBUG(("Access unit boundary\n"));
228        /* conceal if picture started and param sets activated */
229        if (pStorage->picStarted && pStorage->activeSps != NULL)
230        {
231            DEBUG(("CONCEALING..."));
232
233            /* return error if second phase of
234             * initialization is not completed */
235            if (pStorage->pendingActivation)
236            {
237                EPRINT("Pending activation not completed");
238                return (H264BSD_ERROR);
239            }
240
241            if (!pStorage->validSliceInAccessUnit)
242            {
243                pStorage->currImage->data =
244                    h264bsdAllocateDpbImage(pStorage->dpb);
245                h264bsdInitRefPicList(pStorage->dpb);
246                tmp = h264bsdConceal(pStorage, pStorage->currImage, P_SLICE);
247            }
248            else
249                tmp = h264bsdConceal(pStorage, pStorage->currImage,
250                    pStorage->sliceHeader->sliceType);
251
252            picReady = HANTRO_TRUE;
253
254            /* current NAL unit should be decoded on next activation -> set
255             * readBytes to 0 */
256            *readBytes = 0;
257            pStorage->prevBufNotFinished = HANTRO_TRUE;
258            DEBUG(("...DONE\n"));
259        }
260        else
261        {
262            pStorage->validSliceInAccessUnit = HANTRO_FALSE;
263        }
264        pStorage->skipRedundantSlices = HANTRO_FALSE;
265    }
266
267    if (!picReady)
268    {
269        switch (nalUnit.nalUnitType)
270        {
271            case NAL_SEQ_PARAM_SET:
272                DEBUG(("SEQ PARAM SET\n"));
273                tmp = h264bsdDecodeSeqParamSet(&strm, &seqParamSet);
274                if (tmp != HANTRO_OK)
275                {
276                    EPRINT("SEQ_PARAM_SET");
277                    FREE(seqParamSet.offsetForRefFrame);
278                    FREE(seqParamSet.vuiParameters);
279                    return(H264BSD_ERROR);
280                }
281                tmp = h264bsdStoreSeqParamSet(pStorage, &seqParamSet);
282                break;
283
284            case NAL_PIC_PARAM_SET:
285                DEBUG(("PIC PARAM SET\n"));
286                tmp = h264bsdDecodePicParamSet(&strm, &picParamSet);
287                if (tmp != HANTRO_OK)
288                {
289                    EPRINT("PIC_PARAM_SET");
290                    FREE(picParamSet.runLength);
291                    FREE(picParamSet.topLeft);
292                    FREE(picParamSet.bottomRight);
293                    FREE(picParamSet.sliceGroupId);
294                    return(H264BSD_ERROR);
295                }
296                tmp = h264bsdStorePicParamSet(pStorage, &picParamSet);
297                break;
298
299            case NAL_CODED_SLICE_IDR:
300                DEBUG(("IDR "));
301                /* fall through */
302            case NAL_CODED_SLICE:
303                DEBUG(("SLICE HEADER\n"));
304
305                /* picture successfully finished and still decoding same old
306                 * access unit -> no need to decode redundant slices */
307                if (pStorage->skipRedundantSlices)
308                    return(H264BSD_RDY);
309
310                pStorage->picStarted = HANTRO_TRUE;
311
312                if (h264bsdIsStartOfPicture(pStorage))
313                {
314                    pStorage->numConcealedMbs = 0;
315                    pStorage->currentPicId    = picId;
316
317                    tmp = h264bsdCheckPpsId(&strm, &ppsId);
318                    ASSERT(tmp == HANTRO_OK);
319                    /* store old activeSpsId and return headers ready
320                     * indication if activeSps changes */
321                    spsId = pStorage->activeSpsId;
322                    tmp = h264bsdActivateParamSets(pStorage, ppsId,
323                            IS_IDR_NAL_UNIT(&nalUnit) ?
324                            HANTRO_TRUE : HANTRO_FALSE);
325                    if (tmp != HANTRO_OK)
326                    {
327                        EPRINT("Param set activation");
328                        pStorage->activePpsId = MAX_NUM_PIC_PARAM_SETS;
329                        pStorage->activePps = NULL;
330                        pStorage->activeSpsId = MAX_NUM_SEQ_PARAM_SETS;
331                        pStorage->activeSps = NULL;
332                        pStorage->pendingActivation = HANTRO_FALSE;
333
334                        if(tmp == MEMORY_ALLOCATION_ERROR)
335                        {
336                            return H264BSD_MEMALLOC_ERROR;
337                        }
338                        else
339                            return(H264BSD_PARAM_SET_ERROR);
340                    }
341
342                    if (spsId != pStorage->activeSpsId)
343                    {
344                        seqParamSet_t *oldSPS = NULL;
345                        seqParamSet_t *newSPS = pStorage->activeSps;
346                        u32 noOutputOfPriorPicsFlag = 1;
347
348                        if(pStorage->oldSpsId < MAX_NUM_SEQ_PARAM_SETS)
349                        {
350                            oldSPS = pStorage->sps[pStorage->oldSpsId];
351                        }
352
353                        *readBytes = 0;
354                        pStorage->prevBufNotFinished = HANTRO_TRUE;
355
356
357                        if(nalUnit.nalUnitType == NAL_CODED_SLICE_IDR)
358                        {
359                            tmp =
360                            h264bsdCheckPriorPicsFlag(&noOutputOfPriorPicsFlag,
361                                                          &strm, newSPS,
362                                                          pStorage->activePps,
363                                                          nalUnit.nalUnitType);
364                        }
365                        else
366                        {
367                            tmp = HANTRO_NOK;
368                        }
369
370                        if((tmp != HANTRO_OK) ||
371                           (noOutputOfPriorPicsFlag != 0) ||
372                           (pStorage->dpb->noReordering) ||
373                           (oldSPS == NULL) ||
374                           (oldSPS->picWidthInMbs != newSPS->picWidthInMbs) ||
375                           (oldSPS->picHeightInMbs != newSPS->picHeightInMbs) ||
376                           (oldSPS->maxDpbSize != newSPS->maxDpbSize))
377                        {
378                            pStorage->dpb->flushed = 0;
379                        }
380                        else
381                        {
382                            h264bsdFlushDpb(pStorage->dpb);
383                        }
384
385                        pStorage->oldSpsId = pStorage->activeSpsId;
386
387                        return(H264BSD_HDRS_RDY);
388                    }
389                }
390
391                /* return error if second phase of
392                 * initialization is not completed */
393                if (pStorage->pendingActivation)
394                {
395                    EPRINT("Pending activation not completed");
396                    return (H264BSD_ERROR);
397                }
398                tmp = h264bsdDecodeSliceHeader(&strm, pStorage->sliceHeader + 1,
399                    pStorage->activeSps, pStorage->activePps, &nalUnit);
400                if (tmp != HANTRO_OK)
401                {
402                    EPRINT("SLICE_HEADER");
403                    return(H264BSD_ERROR);
404                }
405                if (h264bsdIsStartOfPicture(pStorage))
406                {
407                    if (!IS_IDR_NAL_UNIT(&nalUnit))
408                    {
409                        tmp = h264bsdCheckGapsInFrameNum(pStorage->dpb,
410                            pStorage->sliceHeader[1].frameNum,
411                            nalUnit.nalRefIdc != 0 ?
412                            HANTRO_TRUE : HANTRO_FALSE,
413                            pStorage->activeSps->
414                            gapsInFrameNumValueAllowedFlag);
415                        if (tmp != HANTRO_OK)
416                        {
417                            EPRINT("Gaps in frame num");
418                            return(H264BSD_ERROR);
419                        }
420                    }
421                    pStorage->currImage->data =
422                        h264bsdAllocateDpbImage(pStorage->dpb);
423                }
424
425                /* store slice header to storage if successfully decoded */
426                pStorage->sliceHeader[0] = pStorage->sliceHeader[1];
427                pStorage->validSliceInAccessUnit = HANTRO_TRUE;
428                pStorage->prevNalUnit[0] = nalUnit;
429
430                h264bsdComputeSliceGroupMap(pStorage,
431                    pStorage->sliceHeader->sliceGroupChangeCycle);
432
433                h264bsdInitRefPicList(pStorage->dpb);
434                tmp = h264bsdReorderRefPicList(pStorage->dpb,
435                    &pStorage->sliceHeader->refPicListReordering,
436                    pStorage->sliceHeader->frameNum,
437                    pStorage->sliceHeader->numRefIdxL0Active);
438                if (tmp != HANTRO_OK)
439                {
440                    EPRINT("Reordering");
441                    return(H264BSD_ERROR);
442                }
443
444                DEBUG(("SLICE DATA, FIRST %d\n",
445                        pStorage->sliceHeader->firstMbInSlice));
446                tmp = h264bsdDecodeSliceData(&strm, pStorage,
447                    pStorage->currImage, pStorage->sliceHeader);
448                if (tmp != HANTRO_OK)
449                {
450                    EPRINT("SLICE_DATA");
451                    h264bsdMarkSliceCorrupted(pStorage,
452                        pStorage->sliceHeader->firstMbInSlice);
453                    return(H264BSD_ERROR);
454                }
455
456                if (h264bsdIsEndOfPicture(pStorage))
457                {
458                    picReady = HANTRO_TRUE;
459                    pStorage->skipRedundantSlices = HANTRO_TRUE;
460                }
461                break;
462
463            case NAL_SEI:
464                DEBUG(("SEI MESSAGE, NOT DECODED"));
465                break;
466
467            default:
468                DEBUG(("NOT IMPLEMENTED YET %d\n",nalUnit.nalUnitType));
469        }
470    }
471
472    if (picReady)
473    {
474        h264bsdFilterPicture(pStorage->currImage, pStorage->mb);
475
476        h264bsdResetStorage(pStorage);
477
478        picOrderCnt = h264bsdDecodePicOrderCnt(pStorage->poc,
479            pStorage->activeSps, pStorage->sliceHeader, pStorage->prevNalUnit);
480
481        if (pStorage->validSliceInAccessUnit)
482        {
483            if (pStorage->prevNalUnit->nalRefIdc)
484            {
485                tmp = h264bsdMarkDecRefPic(pStorage->dpb,
486                    &pStorage->sliceHeader->decRefPicMarking,
487                    pStorage->currImage, pStorage->sliceHeader->frameNum,
488                    picOrderCnt,
489                    IS_IDR_NAL_UNIT(pStorage->prevNalUnit) ?
490                    HANTRO_TRUE : HANTRO_FALSE,
491                    pStorage->currentPicId, pStorage->numConcealedMbs);
492            }
493            /* non-reference picture, just store for possible display
494             * reordering */
495            else
496            {
497                tmp = h264bsdMarkDecRefPic(pStorage->dpb, NULL,
498                    pStorage->currImage, pStorage->sliceHeader->frameNum,
499                    picOrderCnt,
500                    IS_IDR_NAL_UNIT(pStorage->prevNalUnit) ?
501                    HANTRO_TRUE : HANTRO_FALSE,
502                    pStorage->currentPicId, pStorage->numConcealedMbs);
503            }
504        }
505
506        pStorage->picStarted = HANTRO_FALSE;
507        pStorage->validSliceInAccessUnit = HANTRO_FALSE;
508
509        return(H264BSD_PIC_RDY);
510    }
511    else
512        return(H264BSD_RDY);
513
514}
515
516/*------------------------------------------------------------------------------
517
518    Function: h264bsdShutdown
519
520        Functional description:
521            Shutdown a decoder instance. Function frees all the memories
522            allocated for the decoder instance.
523
524        Inputs:
525            pStorage    pointer to storage data structure
526
527        Returns:
528            none
529
530
531------------------------------------------------------------------------------*/
532
533void h264bsdShutdown(storage_t *pStorage)
534{
535
536/* Variables */
537
538    u32 i;
539
540/* Code */
541
542    ASSERT(pStorage);
543
544    for (i = 0; i < MAX_NUM_SEQ_PARAM_SETS; i++)
545    {
546        if (pStorage->sps[i])
547        {
548            FREE(pStorage->sps[i]->offsetForRefFrame);
549            FREE(pStorage->sps[i]->vuiParameters);
550            FREE(pStorage->sps[i]);
551        }
552    }
553
554    for (i = 0; i < MAX_NUM_PIC_PARAM_SETS; i++)
555    {
556        if (pStorage->pps[i])
557        {
558            FREE(pStorage->pps[i]->runLength);
559            FREE(pStorage->pps[i]->topLeft);
560            FREE(pStorage->pps[i]->bottomRight);
561            FREE(pStorage->pps[i]->sliceGroupId);
562            FREE(pStorage->pps[i]);
563        }
564    }
565
566    FREE(pStorage->mbLayer);
567    FREE(pStorage->mb);
568    FREE(pStorage->sliceGroupMap);
569
570    h264bsdFreeDpb(pStorage->dpb);
571
572}
573
574/*------------------------------------------------------------------------------
575
576    Function: h264bsdNextOutputPicture
577
578        Functional description:
579            Get next output picture in display order.
580
581        Inputs:
582            pStorage    pointer to storage data structure
583
584        Outputs:
585            picId       identifier of the picture will be stored here
586            isIdrPic    IDR flag of the picture will be stored here
587            numErrMbs   number of concealed macroblocks in the picture
588                        will be stored here
589
590        Returns:
591            pointer to the picture data
592            NULL if no pictures available for display
593
594------------------------------------------------------------------------------*/
595
596u8* h264bsdNextOutputPicture(storage_t *pStorage, u32 *picId, u32 *isIdrPic,
597    u32 *numErrMbs)
598{
599
600/* Variables */
601
602    dpbOutPicture_t *pOut;
603
604/* Code */
605
606    ASSERT(pStorage);
607
608    pOut = h264bsdDpbOutputPicture(pStorage->dpb);
609
610    if (pOut != NULL)
611    {
612        *picId = pOut->picId;
613        *isIdrPic = pOut->isIdr;
614        *numErrMbs = pOut->numErrMbs;
615        return (pOut->data);
616    }
617    else
618        return(NULL);
619
620}
621
622/*------------------------------------------------------------------------------
623
624    Function: h264bsdPicWidth
625
626        Functional description:
627            Get width of the picture in macroblocks
628
629        Inputs:
630            pStorage    pointer to storage data structure
631
632        Outputs:
633            none
634
635        Returns:
636            picture width
637            0 if parameters sets not yet activated
638
639------------------------------------------------------------------------------*/
640
641u32 h264bsdPicWidth(storage_t *pStorage)
642{
643
644/* Variables */
645
646/* Code */
647
648    ASSERT(pStorage);
649
650    if (pStorage->activeSps)
651        return(pStorage->activeSps->picWidthInMbs);
652    else
653        return(0);
654
655}
656
657/*------------------------------------------------------------------------------
658
659    Function: h264bsdPicHeight
660
661        Functional description:
662            Get height of the picture in macroblocks
663
664        Inputs:
665            pStorage    pointer to storage data structure
666
667        Outputs:
668            none
669
670        Returns:
671            picture width
672            0 if parameters sets not yet activated
673
674------------------------------------------------------------------------------*/
675
676u32 h264bsdPicHeight(storage_t *pStorage)
677{
678
679/* Variables */
680
681/* Code */
682
683    ASSERT(pStorage);
684
685    if (pStorage->activeSps)
686        return(pStorage->activeSps->picHeightInMbs);
687    else
688        return(0);
689
690}
691
692/*------------------------------------------------------------------------------
693
694    Function: h264bsdFlushBuffer
695
696        Functional description:
697            Flush the decoded picture buffer, see dpb.c for details
698
699        Inputs:
700            pStorage    pointer to storage data structure
701
702------------------------------------------------------------------------------*/
703
704void h264bsdFlushBuffer(storage_t *pStorage)
705{
706
707/* Variables */
708
709/* Code */
710
711    ASSERT(pStorage);
712
713    h264bsdFlushDpb(pStorage->dpb);
714
715}
716
717/*------------------------------------------------------------------------------
718
719    Function: h264bsdCheckValidParamSets
720
721        Functional description:
722            Check if any valid parameter set combinations (SPS/PPS) exists.
723
724        Inputs:
725            pStorage    pointer to storage structure
726
727        Returns:
728            1       at least one valid SPS/PPS combination found
729            0       no valid param set combinations found
730
731
732------------------------------------------------------------------------------*/
733
734u32 h264bsdCheckValidParamSets(storage_t *pStorage)
735{
736
737/* Variables */
738
739/* Code */
740
741    ASSERT(pStorage);
742
743    return(h264bsdValidParamSets(pStorage) == HANTRO_OK ? 1 : 0);
744
745}
746
747/*------------------------------------------------------------------------------
748
749    Function: h264bsdVideoRange
750
751        Functional description:
752            Get value of video_full_range_flag received in the VUI data.
753
754        Inputs:
755            pStorage    pointer to storage structure
756
757        Returns:
758            1   video_full_range_flag received and value is 1
759            0   otherwise
760
761------------------------------------------------------------------------------*/
762
763u32 h264bsdVideoRange(storage_t *pStorage)
764{
765
766/* Variables */
767
768/* Code */
769
770    ASSERT(pStorage);
771
772    if (pStorage->activeSps && pStorage->activeSps->vuiParametersPresentFlag &&
773        pStorage->activeSps->vuiParameters &&
774        pStorage->activeSps->vuiParameters->videoSignalTypePresentFlag &&
775        pStorage->activeSps->vuiParameters->videoFullRangeFlag)
776        return(1);
777    else /* default value of video_full_range_flag is 0 */
778        return(0);
779
780}
781
782/*------------------------------------------------------------------------------
783
784    Function: h264bsdMatrixCoefficients
785
786        Functional description:
787            Get value of matrix_coefficients received in the VUI data
788
789        Inputs:
790            pStorage    pointer to storage structure
791
792        Outputs:
793            value of matrix_coefficients if received
794            2   otherwise (this is the default value)
795
796------------------------------------------------------------------------------*/
797
798u32 h264bsdMatrixCoefficients(storage_t *pStorage)
799{
800
801/* Variables */
802
803/* Code */
804
805    ASSERT(pStorage);
806
807    if (pStorage->activeSps && pStorage->activeSps->vuiParametersPresentFlag &&
808        pStorage->activeSps->vuiParameters &&
809        pStorage->activeSps->vuiParameters->videoSignalTypePresentFlag &&
810        pStorage->activeSps->vuiParameters->colourDescriptionPresentFlag)
811        return(pStorage->activeSps->vuiParameters->matrixCoefficients);
812    else /* default unspecified */
813        return(2);
814
815}
816
817/*------------------------------------------------------------------------------
818
819    Function: hh264bsdCroppingParams
820
821        Functional description:
822            Get cropping parameters of the active SPS
823
824        Inputs:
825            pStorage    pointer to storage structure
826
827        Outputs:
828            croppingFlag    flag indicating if cropping params present is
829                            stored here
830            leftOffset      cropping left offset in pixels is stored here
831            width           width of the image after cropping is stored here
832            topOffset       cropping top offset in pixels is stored here
833            height          height of the image after cropping is stored here
834
835        Returns:
836            none
837
838------------------------------------------------------------------------------*/
839
840void h264bsdCroppingParams(storage_t *pStorage, u32 *croppingFlag,
841    u32 *leftOffset, u32 *width, u32 *topOffset, u32 *height)
842{
843
844/* Variables */
845
846/* Code */
847
848    ASSERT(pStorage);
849
850    if (pStorage->activeSps && pStorage->activeSps->frameCroppingFlag)
851    {
852        *croppingFlag = 1;
853        *leftOffset = 2 * pStorage->activeSps->frameCropLeftOffset;
854        *width = 16 * pStorage->activeSps->picWidthInMbs -
855                 2 * (pStorage->activeSps->frameCropLeftOffset +
856                      pStorage->activeSps->frameCropRightOffset);
857        *topOffset = 2 * pStorage->activeSps->frameCropTopOffset;
858        *height = 16 * pStorage->activeSps->picHeightInMbs -
859                  2 * (pStorage->activeSps->frameCropTopOffset +
860                       pStorage->activeSps->frameCropBottomOffset);
861    }
862    else
863    {
864        *croppingFlag = 0;
865        *leftOffset = 0;
866        *width = 0;
867        *topOffset = 0;
868        *height = 0;
869    }
870
871}
872
873/*------------------------------------------------------------------------------
874
875    Function: h264bsdSampleAspectRatio
876
877        Functional description:
878            Get aspect ratio received in the VUI data
879
880        Inputs:
881            pStorage    pointer to storage structure
882
883        Outputs:
884            sarWidth    sample aspect ratio height
885            sarHeight   sample aspect ratio width
886
887------------------------------------------------------------------------------*/
888
889void h264bsdSampleAspectRatio(storage_t *pStorage, u32 *sarWidth, u32 *sarHeight)
890{
891
892/* Variables */
893    u32 w = 1;
894    u32 h = 1;
895/* Code */
896
897    ASSERT(pStorage);
898
899
900    if (pStorage->activeSps &&
901        pStorage->activeSps->vuiParametersPresentFlag &&
902        pStorage->activeSps->vuiParameters &&
903        pStorage->activeSps->vuiParameters->aspectRatioPresentFlag )
904    {
905        switch (pStorage->activeSps->vuiParameters->aspectRatioIdc)
906        {
907            case ASPECT_RATIO_UNSPECIFIED:  w =   0; h =  0; break;
908            case ASPECT_RATIO_1_1:          w =   1; h =  1; break;
909            case ASPECT_RATIO_12_11:        w =  12; h = 11; break;
910            case ASPECT_RATIO_10_11:        w =  10; h = 11; break;
911            case ASPECT_RATIO_16_11:        w =  16; h = 11; break;
912            case ASPECT_RATIO_40_33:        w =  40; h = 33; break;
913            case ASPECT_RATIO_24_11:        w =  24; h = 11; break;
914            case ASPECT_RATIO_20_11:        w =  20; h = 11; break;
915            case ASPECT_RATIO_32_11:        w =  32; h = 11; break;
916            case ASPECT_RATIO_80_33:        w =  80; h = 33; break;
917            case ASPECT_RATIO_18_11:        w =  18; h = 11; break;
918            case ASPECT_RATIO_15_11:        w =  15; h = 11; break;
919            case ASPECT_RATIO_64_33:        w =  64; h = 33; break;
920            case ASPECT_RATIO_160_99:       w = 160; h = 99; break;
921            case ASPECT_RATIO_EXTENDED_SAR:
922                w = pStorage->activeSps->vuiParameters->sarWidth;
923                h = pStorage->activeSps->vuiParameters->sarHeight;
924                if ((w == 0) || (h == 0))
925                    w = h = 0;
926                break;
927            default:
928                w = 0;
929                h = 0;
930                break;
931        }
932    }
933
934    /* set aspect ratio*/
935    *sarWidth = w;
936    *sarHeight = h;
937
938}
939
940/*------------------------------------------------------------------------------
941
942    Function: h264bsdProfile
943
944        Functional description:
945            Get profile information from active SPS
946
947        Inputs:
948            pStorage    pointer to storage structure
949
950        Outputs:
951            profile   current profile
952
953------------------------------------------------------------------------------*/
954u32 h264bsdProfile(storage_t *pStorage)
955{
956    if (pStorage->activeSps)
957        return pStorage->activeSps->profileIdc;
958    else
959        return 0;
960}
961
962