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