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