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