Home | History | Annotate | Download | only in source
      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           h264bsdDecodeSliceData
     27           SetMbParams
     28           h264bsdMarkSliceCorrupted
     29 
     30 ------------------------------------------------------------------------------*/
     31 
     32 /*------------------------------------------------------------------------------
     33     1. Include headers
     34 ------------------------------------------------------------------------------*/
     35 
     36 #include "h264bsd_slice_data.h"
     37 #include "h264bsd_util.h"
     38 #include "h264bsd_vlc.h"
     39 
     40 /*------------------------------------------------------------------------------
     41     2. External compiler flags
     42 --------------------------------------------------------------------------------
     43 
     44 --------------------------------------------------------------------------------
     45     3. Module defines
     46 ------------------------------------------------------------------------------*/
     47 
     48 /*------------------------------------------------------------------------------
     49     4. Local function prototypes
     50 ------------------------------------------------------------------------------*/
     51 
     52 static void SetMbParams(mbStorage_t *pMb, sliceHeader_t *pSlice, u32 sliceId,
     53     i32 chromaQpIndexOffset);
     54 
     55 /*------------------------------------------------------------------------------
     56 
     57    5.1  Function name: h264bsdDecodeSliceData
     58 
     59         Functional description:
     60             Decode one slice. Function decodes stream data, i.e. macroblocks
     61             and possible skip_run fields. h264bsdDecodeMacroblock function is
     62             called to handle all other macroblock related processing.
     63             Macroblock to slice group mapping is considered when next
     64             macroblock to process is determined (h264bsdNextMbAddress function)
     65             map
     66 
     67         Inputs:
     68             pStrmData       pointer to stream data structure
     69             pStorage        pointer to storage structure
     70             currImage       pointer to current processed picture, needed for
     71                             intra prediction of the macroblocks
     72             pSliceHeader    pointer to slice header of the current slice
     73 
     74         Outputs:
     75             currImage       processed macroblocks are written to current image
     76             pStorage        mbStorage structure of each processed macroblock
     77                             is updated here
     78 
     79         Returns:
     80             HANTRO_OK       success
     81             HANTRO_NOK      invalid stream data
     82 
     83 ------------------------------------------------------------------------------*/
     84 
     85 u32 h264bsdDecodeSliceData(strmData_t *pStrmData, storage_t *pStorage,
     86     image_t *currImage, sliceHeader_t *pSliceHeader)
     87 {
     88 
     89 /* Variables */
     90 
     91     u8 mbData[384 + 15 + 32];
     92     u8 *data;
     93     u32 tmp;
     94     u32 skipRun;
     95     u32 prevSkipped;
     96     u32 currMbAddr;
     97     u32 moreMbs;
     98     u32 mbCount;
     99     i32 qpY;
    100     macroblockLayer_t *mbLayer;
    101 
    102 /* Code */
    103 
    104     ASSERT(pStrmData);
    105     ASSERT(pSliceHeader);
    106     ASSERT(pStorage);
    107     ASSERT(pSliceHeader->firstMbInSlice < pStorage->picSizeInMbs);
    108 
    109     /* ensure 16-byte alignment */
    110     data = (u8*)ALIGN(mbData, 16);
    111 
    112     mbLayer = pStorage->mbLayer;
    113 
    114     currMbAddr = pSliceHeader->firstMbInSlice;
    115     skipRun = 0;
    116     prevSkipped = HANTRO_FALSE;
    117 
    118     /* increment slice index, will be one for decoding of the first slice of
    119      * the picture */
    120     pStorage->slice->sliceId++;
    121 
    122     /* lastMbAddr stores address of the macroblock that was last successfully
    123      * decoded, needed for error handling */
    124     pStorage->slice->lastMbAddr = 0;
    125 
    126     mbCount = 0;
    127     /* initial quantization parameter for the slice is obtained as the sum of
    128      * initial QP for the picture and sliceQpDelta for the current slice */
    129     qpY = (i32)pStorage->activePps->picInitQp + pSliceHeader->sliceQpDelta;
    130     do
    131     {
    132         /* primary picture and already decoded macroblock -> error */
    133         if (!pSliceHeader->redundantPicCnt && pStorage->mb[currMbAddr].decoded)
    134         {
    135             EPRINT("Primary and already decoded");
    136             return(HANTRO_NOK);
    137         }
    138 
    139         SetMbParams(pStorage->mb + currMbAddr, pSliceHeader,
    140             pStorage->slice->sliceId, pStorage->activePps->chromaQpIndexOffset);
    141 
    142         if (!IS_I_SLICE(pSliceHeader->sliceType))
    143         {
    144             if (!prevSkipped)
    145             {
    146                 tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &skipRun);
    147                 if (tmp != HANTRO_OK)
    148                     return(tmp);
    149                 /* skip_run shall be less than or equal to number of
    150                  * macroblocks left */
    151                 if (skipRun > (pStorage->picSizeInMbs - currMbAddr))
    152                 {
    153                     EPRINT("skip_run");
    154                     return(HANTRO_NOK);
    155                 }
    156                 if (skipRun)
    157                 {
    158                     prevSkipped = HANTRO_TRUE;
    159                     H264SwDecMemset(&mbLayer->mbPred, 0, sizeof(mbPred_t));
    160                     /* mark current macroblock skipped */
    161                     mbLayer->mbType = P_Skip;
    162                 }
    163             }
    164         }
    165 
    166         if (skipRun)
    167         {
    168             DEBUG(("Skipping macroblock %d\n", currMbAddr));
    169             skipRun--;
    170         }
    171         else
    172         {
    173             prevSkipped = HANTRO_FALSE;
    174             tmp = h264bsdDecodeMacroblockLayer(pStrmData, mbLayer,
    175                 pStorage->mb + currMbAddr, pSliceHeader->sliceType,
    176                 pSliceHeader->numRefIdxL0Active);
    177             if (tmp != HANTRO_OK)
    178             {
    179                 EPRINT("macroblock_layer");
    180                 return(tmp);
    181             }
    182         }
    183 
    184         tmp = h264bsdDecodeMacroblock(pStorage->mb + currMbAddr, mbLayer,
    185             currImage, pStorage->dpb, &qpY, currMbAddr,
    186             pStorage->activePps->constrainedIntraPredFlag, data);
    187         if (tmp != HANTRO_OK)
    188         {
    189             EPRINT("MACRO_BLOCK");
    190             return(tmp);
    191         }
    192 
    193         /* increment macroblock count only for macroblocks that were decoded
    194          * for the first time (redundant slices) */
    195         if (pStorage->mb[currMbAddr].decoded == 1)
    196             mbCount++;
    197 
    198         /* keep on processing as long as there is stream data left or
    199          * processing of macroblocks to be skipped based on the last skipRun is
    200          * not finished */
    201         moreMbs = (h264bsdMoreRbspData(pStrmData) || skipRun) ?
    202                                         HANTRO_TRUE : HANTRO_FALSE;
    203 
    204         /* lastMbAddr is only updated for intra slices (all macroblocks of
    205          * inter slices will be lost in case of an error) */
    206         if (IS_I_SLICE(pSliceHeader->sliceType))
    207             pStorage->slice->lastMbAddr = currMbAddr;
    208 
    209         currMbAddr = h264bsdNextMbAddress(pStorage->sliceGroupMap,
    210             pStorage->picSizeInMbs, currMbAddr);
    211         /* data left in the buffer but no more macroblocks for current slice
    212          * group -> error */
    213         if (moreMbs && !currMbAddr)
    214         {
    215             EPRINT("Next mb address");
    216             return(HANTRO_NOK);
    217         }
    218 
    219     } while (moreMbs);
    220 
    221     if ((pStorage->slice->numDecodedMbs + mbCount) > pStorage->picSizeInMbs)
    222     {
    223         EPRINT("Num decoded mbs");
    224         return(HANTRO_NOK);
    225     }
    226 
    227     pStorage->slice->numDecodedMbs += mbCount;
    228 
    229     return(HANTRO_OK);
    230 
    231 }
    232 
    233 /*------------------------------------------------------------------------------
    234 
    235    5.2  Function: SetMbParams
    236 
    237         Functional description:
    238             Set macroblock parameters that remain constant for this slice
    239 
    240         Inputs:
    241             pSlice      pointer to current slice header
    242             sliceId     id of the current slice
    243             chromaQpIndexOffset
    244 
    245         Outputs:
    246             pMb         pointer to macroblock structure which is updated
    247 
    248         Returns:
    249             none
    250 
    251 ------------------------------------------------------------------------------*/
    252 
    253 void SetMbParams(mbStorage_t *pMb, sliceHeader_t *pSlice, u32 sliceId,
    254     i32 chromaQpIndexOffset)
    255 {
    256 
    257 /* Variables */
    258     u32 tmp1;
    259     i32 tmp2, tmp3;
    260 
    261 /* Code */
    262 
    263     tmp1 = pSlice->disableDeblockingFilterIdc;
    264     tmp2 = pSlice->sliceAlphaC0Offset;
    265     tmp3 = pSlice->sliceBetaOffset;
    266     pMb->sliceId = sliceId;
    267     pMb->disableDeblockingFilterIdc = tmp1;
    268     pMb->filterOffsetA = tmp2;
    269     pMb->filterOffsetB = tmp3;
    270     pMb->chromaQpIndexOffset = chromaQpIndexOffset;
    271 
    272 }
    273 
    274 /*------------------------------------------------------------------------------
    275 
    276    5.3  Function name: h264bsdMarkSliceCorrupted
    277 
    278         Functional description:
    279             Mark macroblocks of the slice corrupted. If lastMbAddr in the slice
    280             storage is set -> picWidhtInMbs (or at least 10) macroblocks back
    281             from  the lastMbAddr are marked corrupted. However, if lastMbAddr
    282             is not set -> all macroblocks of the slice are marked.
    283 
    284         Inputs:
    285             pStorage        pointer to storage structure
    286             firstMbInSlice  address of the first macroblock in the slice, this
    287                             identifies the slice to be marked corrupted
    288 
    289         Outputs:
    290             pStorage        mbStorage for the corrupted macroblocks updated
    291 
    292         Returns:
    293             none
    294 
    295 ------------------------------------------------------------------------------*/
    296 
    297 void h264bsdMarkSliceCorrupted(storage_t *pStorage, u32 firstMbInSlice)
    298 {
    299 
    300 /* Variables */
    301 
    302     u32 tmp, i;
    303     u32 sliceId;
    304     u32 currMbAddr;
    305 
    306 /* Code */
    307 
    308     ASSERT(pStorage);
    309     ASSERT(firstMbInSlice < pStorage->picSizeInMbs);
    310 
    311     currMbAddr = firstMbInSlice;
    312 
    313     sliceId = pStorage->slice->sliceId;
    314 
    315     /* DecodeSliceData sets lastMbAddr for I slices -> if it was set, go back
    316      * MAX(picWidthInMbs, 10) macroblocks and start marking from there */
    317     if (pStorage->slice->lastMbAddr)
    318     {
    319         ASSERT(pStorage->mb[pStorage->slice->lastMbAddr].sliceId == sliceId);
    320         i = pStorage->slice->lastMbAddr - 1;
    321         tmp = 0;
    322         while (i > currMbAddr)
    323         {
    324             if (pStorage->mb[i].sliceId == sliceId)
    325             {
    326                 tmp++;
    327                 if (tmp >= MAX(pStorage->activeSps->picWidthInMbs, 10))
    328                     break;
    329             }
    330             i--;
    331         }
    332         currMbAddr = i;
    333     }
    334 
    335     do
    336     {
    337 
    338         if ( (pStorage->mb[currMbAddr].sliceId == sliceId) &&
    339              (pStorage->mb[currMbAddr].decoded) )
    340         {
    341             pStorage->mb[currMbAddr].decoded--;
    342         }
    343         else
    344         {
    345             break;
    346         }
    347 
    348         currMbAddr = h264bsdNextMbAddress(pStorage->sliceGroupMap,
    349             pStorage->picSizeInMbs, currMbAddr);
    350 
    351     } while (currMbAddr);
    352 
    353 }
    354 
    355