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           H264SwDecInit
     27           H264SwDecGetInfo
     28           H264SwDecRelease
     29           H264SwDecDecode
     30           H264SwDecGetAPIVersion
     31           H264SwDecNextPicture
     32 
     33 ------------------------------------------------------------------------------*/
     34 
     35 /*------------------------------------------------------------------------------
     36     1. Include headers
     37 ------------------------------------------------------------------------------*/
     38 #include <stdlib.h>
     39 #include "basetype.h"
     40 #include "h264bsd_container.h"
     41 #include "H264SwDecApi.h"
     42 #include "h264bsd_decoder.h"
     43 #include "h264bsd_util.h"
     44 
     45 #define UNUSED(x) (void)(x)
     46 
     47 /*------------------------------------------------------------------------------
     48        Version Information
     49 ------------------------------------------------------------------------------*/
     50 
     51 #define H264SWDEC_MAJOR_VERSION 2
     52 #define H264SWDEC_MINOR_VERSION 3
     53 
     54 /*------------------------------------------------------------------------------
     55     2. External compiler flags
     56 --------------------------------------------------------------------------------
     57 
     58 H264DEC_TRACE           Trace H264 Decoder API function calls.
     59 H264DEC_EVALUATION      Compile evaluation version, restricts number of frames
     60                         that can be decoded
     61 
     62 --------------------------------------------------------------------------------
     63     3. Module defines
     64 ------------------------------------------------------------------------------*/
     65 
     66 #ifdef H264DEC_TRACE
     67 #include <stdio.h>
     68 #define DEC_API_TRC(str)    H264SwDecTrace(str)
     69 #else
     70 #define DEC_API_TRC(str)
     71 #endif
     72 
     73 #ifdef H264DEC_EVALUATION
     74 #define H264DEC_EVALUATION_LIMIT   500
     75 #endif
     76 
     77 void H264SwDecTrace(char *string) {
     78     UNUSED(string);
     79 }
     80 
     81 void* H264SwDecMalloc(u32 size) {
     82     return malloc(size);
     83 }
     84 
     85 void H264SwDecFree(void *ptr) {
     86     free(ptr);
     87 }
     88 
     89 void H264SwDecMemcpy(void *dest, void *src, u32 count) {
     90     memcpy(dest, src, count);
     91 }
     92 
     93 void H264SwDecMemset(void *ptr, i32 value, u32 count) {
     94     memset(ptr, value, count);
     95 }
     96 
     97 
     98 /*------------------------------------------------------------------------------
     99 
    100     Function: H264SwDecInit()
    101 
    102         Functional description:
    103             Initialize decoder software. Function reserves memory for the
    104             decoder instance and calls h264bsdInit to initialize the
    105             instance data.
    106 
    107         Inputs:
    108             noOutputReordering  flag to indicate decoder that it doesn't have
    109                                 to try to provide output pictures in display
    110                                 order, saves memory
    111 
    112         Outputs:
    113             decInst             pointer to initialized instance is stored here
    114 
    115         Returns:
    116             H264SWDEC_OK        successfully initialized the instance
    117             H264SWDEC_INITFAIL  initialization failed
    118             H264SWDEC_PARAM_ERR invalid parameters
    119             H264SWDEC_MEM_FAIL  memory allocation failed
    120 
    121 ------------------------------------------------------------------------------*/
    122 
    123 H264SwDecRet H264SwDecInit(H264SwDecInst *decInst, u32 noOutputReordering)
    124 {
    125     u32 rv = 0;
    126 
    127     decContainer_t *pDecCont;
    128 
    129     DEC_API_TRC("H264SwDecInit#");
    130 
    131     /* check that right shift on negative numbers is performed signed */
    132     /*lint -save -e* following check causes multiple lint messages */
    133     if ( ((-1)>>1) != (-1) )
    134     {
    135         DEC_API_TRC("H264SwDecInit# ERROR: Right shift is not signed");
    136         return(H264SWDEC_INITFAIL);
    137     }
    138     /*lint -restore */
    139 
    140     if (decInst == NULL)
    141     {
    142         DEC_API_TRC("H264SwDecInit# ERROR: decInst == NULL");
    143         return(H264SWDEC_PARAM_ERR);
    144     }
    145 
    146     pDecCont = (decContainer_t *)H264SwDecMalloc(sizeof(decContainer_t));
    147 
    148     if (pDecCont == NULL)
    149     {
    150         DEC_API_TRC("H264SwDecInit# ERROR: Memory allocation failed");
    151         return(H264SWDEC_MEMFAIL);
    152     }
    153 
    154 #ifdef H264DEC_TRACE
    155     sprintf(pDecCont->str, "H264SwDecInit# decInst %p noOutputReordering %d",
    156             (void*)decInst, noOutputReordering);
    157     DEC_API_TRC(pDecCont->str);
    158 #endif
    159 
    160     rv = h264bsdInit(&pDecCont->storage, noOutputReordering);
    161     if (rv != HANTRO_OK)
    162     {
    163         H264SwDecRelease(pDecCont);
    164         return(H264SWDEC_MEMFAIL);
    165     }
    166 
    167     pDecCont->decStat  = INITIALIZED;
    168     pDecCont->picNumber = 0;
    169 
    170 #ifdef H264DEC_TRACE
    171     sprintf(pDecCont->str, "H264SwDecInit# OK: return %p", (void*)pDecCont);
    172     DEC_API_TRC(pDecCont->str);
    173 #endif
    174 
    175     *decInst = (decContainer_t *)pDecCont;
    176 
    177     return(H264SWDEC_OK);
    178 
    179 }
    180 
    181 /*------------------------------------------------------------------------------
    182 
    183     Function: H264SwDecGetInfo()
    184 
    185         Functional description:
    186             This function provides read access to decoder information. This
    187             function should not be called before H264SwDecDecode function has
    188             indicated that headers are ready.
    189 
    190         Inputs:
    191             decInst     decoder instance
    192 
    193         Outputs:
    194             pDecInfo    pointer to info struct where data is written
    195 
    196         Returns:
    197             H264SWDEC_OK            success
    198             H264SWDEC_PARAM_ERR     invalid parameters
    199             H264SWDEC_HDRS_NOT_RDY  information not available yet
    200 
    201 ------------------------------------------------------------------------------*/
    202 
    203 H264SwDecRet H264SwDecGetInfo(H264SwDecInst decInst, H264SwDecInfo *pDecInfo)
    204 {
    205 
    206     storage_t *pStorage;
    207 
    208     DEC_API_TRC("H264SwDecGetInfo#");
    209 
    210     if (decInst == NULL || pDecInfo == NULL)
    211     {
    212         DEC_API_TRC("H264SwDecGetInfo# ERROR: decInst or pDecInfo is NULL");
    213         return(H264SWDEC_PARAM_ERR);
    214     }
    215 
    216     pStorage = &(((decContainer_t *)decInst)->storage);
    217 
    218     if (pStorage->activeSps == NULL || pStorage->activePps == NULL)
    219     {
    220         DEC_API_TRC("H264SwDecGetInfo# ERROR: Headers not decoded yet");
    221         return(H264SWDEC_HDRS_NOT_RDY);
    222     }
    223 
    224 #ifdef H264DEC_TRACE
    225     sprintf(((decContainer_t*)decInst)->str,
    226         "H264SwDecGetInfo# decInst %p  pDecInfo %p", decInst, (void*)pDecInfo);
    227     DEC_API_TRC(((decContainer_t*)decInst)->str);
    228 #endif
    229 
    230     /* h264bsdPicWidth and -Height return dimensions in macroblock units,
    231      * picWidth and -Height in pixels */
    232     pDecInfo->picWidth        = h264bsdPicWidth(pStorage) << 4;
    233     pDecInfo->picHeight       = h264bsdPicHeight(pStorage) << 4;
    234     pDecInfo->videoRange      = h264bsdVideoRange(pStorage);
    235     pDecInfo->matrixCoefficients = h264bsdMatrixCoefficients(pStorage);
    236 
    237     h264bsdCroppingParams(pStorage,
    238         &pDecInfo->croppingFlag,
    239         &pDecInfo->cropParams.cropLeftOffset,
    240         &pDecInfo->cropParams.cropOutWidth,
    241         &pDecInfo->cropParams.cropTopOffset,
    242         &pDecInfo->cropParams.cropOutHeight);
    243 
    244     /* sample aspect ratio */
    245     h264bsdSampleAspectRatio(pStorage,
    246                              &pDecInfo->parWidth,
    247                              &pDecInfo->parHeight);
    248 
    249     /* profile */
    250     pDecInfo->profile = h264bsdProfile(pStorage);
    251 
    252     DEC_API_TRC("H264SwDecGetInfo# OK");
    253 
    254     return(H264SWDEC_OK);
    255 
    256 }
    257 
    258 /*------------------------------------------------------------------------------
    259 
    260     Function: H264SwDecRelease()
    261 
    262         Functional description:
    263             Release the decoder instance. Function calls h264bsdShutDown to
    264             release instance data and frees the memory allocated for the
    265             instance.
    266 
    267         Inputs:
    268             decInst     Decoder instance
    269 
    270         Outputs:
    271             none
    272 
    273         Returns:
    274             none
    275 
    276 ------------------------------------------------------------------------------*/
    277 
    278 void H264SwDecRelease(H264SwDecInst decInst)
    279 {
    280 
    281     decContainer_t *pDecCont;
    282 
    283     DEC_API_TRC("H264SwDecRelease#");
    284 
    285     if (decInst == NULL)
    286     {
    287         DEC_API_TRC("H264SwDecRelease# ERROR: decInst == NULL");
    288         return;
    289     }
    290 
    291     pDecCont = (decContainer_t*)decInst;
    292 
    293 #ifdef H264DEC_TRACE
    294     sprintf(pDecCont->str, "H264SwDecRelease# decInst %p",decInst);
    295     DEC_API_TRC(pDecCont->str);
    296 #endif
    297 
    298     h264bsdShutdown(&pDecCont->storage);
    299 
    300     H264SwDecFree(pDecCont);
    301 
    302 }
    303 
    304 /*------------------------------------------------------------------------------
    305 
    306     Function: H264SwDecDecode
    307 
    308         Functional description:
    309             Decode stream data. Calls h264bsdDecode to do the actual decoding.
    310 
    311         Input:
    312             decInst     decoder instance
    313             pInput      pointer to input struct
    314 
    315         Outputs:
    316             pOutput     pointer to output struct
    317 
    318         Returns:
    319             H264SWDEC_NOT_INITIALIZED   decoder instance not initialized yet
    320             H264SWDEC_PARAM_ERR         invalid parameters
    321 
    322             H264SWDEC_STRM_PROCESSED    stream buffer decoded
    323             H264SWDEC_HDRS_RDY_BUFF_NOT_EMPTY   headers decoded,
    324                                                 stream buffer not finished
    325             H264SWDEC_PIC_RDY                   decoding of a picture finished
    326             H264SWDEC_PIC_RDY_BUFF_NOT_EMPTY    decoding of a picture finished,
    327                                                 stream buffer not finished
    328             H264SWDEC_STRM_ERR                  serious error in decoding, no
    329                                                 valid parameter sets available
    330                                                 to decode picture data
    331             H264SWDEC_EVALUATION_LIMIT_EXCEEDED this can only occur when
    332                                                 evaluation version is used,
    333                                                 max number of frames reached
    334 
    335 ------------------------------------------------------------------------------*/
    336 
    337 H264SwDecRet H264SwDecDecode(H264SwDecInst decInst, H264SwDecInput *pInput,
    338                   H264SwDecOutput *pOutput)
    339 {
    340 
    341     decContainer_t *pDecCont;
    342     u32 strmLen;
    343     u32 numReadBytes;
    344     u8 *tmpStream;
    345     u32 decResult = 0;
    346     H264SwDecRet returnValue = H264SWDEC_STRM_PROCESSED;
    347 
    348     DEC_API_TRC("H264SwDecDecode#");
    349 
    350     /* Check that function input parameters are valid */
    351     if (pInput == NULL || pOutput == NULL)
    352     {
    353         DEC_API_TRC("H264SwDecDecode# ERROR: pInput or pOutput is NULL");
    354         return(H264SWDEC_PARAM_ERR);
    355     }
    356 
    357     if ((pInput->pStream == NULL) || (pInput->dataLen == 0))
    358     {
    359         DEC_API_TRC("H264SwDecDecode# ERROR: Invalid input parameters");
    360         return(H264SWDEC_PARAM_ERR);
    361     }
    362 
    363     pDecCont = (decContainer_t *)decInst;
    364 
    365     /* Check if decoder is in an incorrect mode */
    366     if (decInst == NULL || pDecCont->decStat == UNINITIALIZED)
    367     {
    368         DEC_API_TRC("H264SwDecDecode# ERROR: Decoder not initialized");
    369         return(H264SWDEC_NOT_INITIALIZED);
    370     }
    371 
    372 #ifdef H264DEC_EVALUATION
    373     if (pDecCont->picNumber >= H264DEC_EVALUATION_LIMIT)
    374         return(H264SWDEC_EVALUATION_LIMIT_EXCEEDED);
    375 #endif
    376 
    377 #ifdef H264DEC_TRACE
    378     sprintf(pDecCont->str, "H264SwDecDecode# decInst %p  pInput %p  pOutput %p",
    379             decInst, (void*)pInput, (void*)pOutput);
    380     DEC_API_TRC(pDecCont->str);
    381 #endif
    382 
    383     pOutput->pStrmCurrPos   = NULL;
    384 
    385     numReadBytes = 0;
    386     strmLen = pInput->dataLen;
    387     tmpStream = pInput->pStream;
    388     pDecCont->storage.intraConcealmentFlag = pInput->intraConcealmentMethod;
    389 
    390     do
    391     {
    392         /* Return HDRS_RDY after DPB flush caused by new SPS */
    393         if (pDecCont->decStat == NEW_HEADERS)
    394         {
    395             decResult = H264BSD_HDRS_RDY;
    396             pDecCont->decStat = INITIALIZED;
    397         }
    398         else /* Continue decoding normally */
    399         {
    400             decResult = h264bsdDecode(&pDecCont->storage, tmpStream, strmLen,
    401                 pInput->picId, &numReadBytes);
    402         }
    403         tmpStream += numReadBytes;
    404         /* check if too many bytes are read from stream */
    405         if ( (i32)(strmLen - numReadBytes) >= 0 )
    406             strmLen -= numReadBytes;
    407         else
    408             strmLen = 0;
    409 
    410         pOutput->pStrmCurrPos = tmpStream;
    411 
    412         switch (decResult)
    413         {
    414             case H264BSD_HDRS_RDY:
    415 
    416                 if(pDecCont->storage.dpb->flushed &&
    417                    pDecCont->storage.dpb->numOut !=
    418                    pDecCont->storage.dpb->outIndex)
    419                 {
    420                     /* output first all DPB stored pictures
    421                      * DPB flush caused by new SPS */
    422                     pDecCont->storage.dpb->flushed = 0;
    423                     pDecCont->decStat = NEW_HEADERS;
    424                     returnValue = H264SWDEC_PIC_RDY_BUFF_NOT_EMPTY;
    425                     strmLen = 0;
    426                 }
    427                 else
    428                 {
    429                     returnValue = H264SWDEC_HDRS_RDY_BUFF_NOT_EMPTY;
    430                     strmLen = 0;
    431                 }
    432                 break;
    433 
    434             case H264BSD_PIC_RDY:
    435                 pDecCont->picNumber++;
    436 
    437                 if (strmLen == 0)
    438                     returnValue = H264SWDEC_PIC_RDY;
    439                 else
    440                     returnValue = H264SWDEC_PIC_RDY_BUFF_NOT_EMPTY;
    441 
    442                 strmLen = 0;
    443                 break;
    444 
    445             case H264BSD_PARAM_SET_ERROR:
    446                 if ( !h264bsdCheckValidParamSets(&pDecCont->storage) &&
    447                      strmLen == 0 )
    448                 {
    449                     returnValue = H264SWDEC_STRM_ERR;
    450                 }
    451                 break;
    452             case H264BSD_MEMALLOC_ERROR:
    453                 {
    454                     returnValue = H264SWDEC_MEMFAIL;
    455                     strmLen = 0;
    456                 }
    457                 break;
    458             default:
    459                 break;
    460         }
    461 
    462     } while (strmLen);
    463 
    464 #ifdef H264DEC_TRACE
    465     sprintf(pDecCont->str, "H264SwDecDecode# OK: DecResult %d",
    466             returnValue);
    467     DEC_API_TRC(pDecCont->str);
    468 #endif
    469 
    470     return(returnValue);
    471 
    472 }
    473 
    474 /*------------------------------------------------------------------------------
    475 
    476     Function: H264SwDecGetAPIVersion
    477 
    478         Functional description:
    479             Return version information of the API
    480 
    481         Inputs:
    482             none
    483 
    484         Outputs:
    485             none
    486 
    487         Returns:
    488             API version
    489 
    490 ------------------------------------------------------------------------------*/
    491 
    492 H264SwDecApiVersion H264SwDecGetAPIVersion()
    493 {
    494     H264SwDecApiVersion ver;
    495 
    496     ver.major = H264SWDEC_MAJOR_VERSION;
    497     ver.minor = H264SWDEC_MINOR_VERSION;
    498 
    499     return(ver);
    500 }
    501 
    502 /*------------------------------------------------------------------------------
    503 
    504     Function: H264SwDecNextPicture
    505 
    506         Functional description:
    507             Get next picture in display order if any available.
    508 
    509         Input:
    510             decInst     decoder instance.
    511             flushBuffer force output of all buffered pictures
    512 
    513         Output:
    514             pOutput     pointer to output structure
    515 
    516         Returns:
    517             H264SWDEC_OK            no pictures available for display
    518             H264SWDEC_PIC_RDY       picture available for display
    519             H264SWDEC_PARAM_ERR     invalid parameters
    520 
    521 ------------------------------------------------------------------------------*/
    522 
    523 H264SwDecRet H264SwDecNextPicture(H264SwDecInst decInst,
    524     H264SwDecPicture *pOutput, u32 flushBuffer)
    525 {
    526 
    527     decContainer_t *pDecCont;
    528     u32 numErrMbs, isIdrPic, picId;
    529     u32 *pOutPic;
    530 
    531     DEC_API_TRC("H264SwDecNextPicture#");
    532 
    533     if (decInst == NULL || pOutput == NULL)
    534     {
    535         DEC_API_TRC("H264SwDecNextPicture# ERROR: decInst or pOutput is NULL");
    536         return(H264SWDEC_PARAM_ERR);
    537     }
    538 
    539     pDecCont = (decContainer_t*)decInst;
    540 
    541 #ifdef H264DEC_TRACE
    542     sprintf(pDecCont->str, "H264SwDecNextPicture# decInst %p pOutput %p %s %d",
    543             decInst, (void*)pOutput, "flushBuffer", flushBuffer);
    544     DEC_API_TRC(pDecCont->str);
    545 #endif
    546 
    547     if (flushBuffer)
    548         h264bsdFlushBuffer(&pDecCont->storage);
    549 
    550     pOutPic = (u32*)h264bsdNextOutputPicture(&pDecCont->storage, &picId,
    551                                              &isIdrPic, &numErrMbs);
    552 
    553     if (pOutPic == NULL)
    554     {
    555         DEC_API_TRC("H264SwDecNextPicture# OK: return H264SWDEC_OK");
    556         return(H264SWDEC_OK);
    557     }
    558     else
    559     {
    560         pOutput->pOutputPicture = pOutPic;
    561         pOutput->picId          = picId;
    562         pOutput->isIdrPicture   = isIdrPic;
    563         pOutput->nbrOfErrMBs    = numErrMbs;
    564         DEC_API_TRC("H264SwDecNextPicture# OK: return H264SWDEC_PIC_RDY");
    565         return(H264SWDEC_PIC_RDY);
    566     }
    567 
    568 }
    569 
    570 
    571