PageRenderTime 338ms CodeModel.GetById 131ms app.highlight 110ms RepoModel.GetById 91ms app.codeStats 0ms

/H264Dec/source/H264SwDecApi.c

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