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