H264SwDecApi.c revision 3e255fa2dbe9d7b05818964ddc9f6ea6bf24ec14
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
59H264DEC_TRACE           Trace H264 Decoder API function calls.
60H264DEC_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
78void H264SwDecTrace(char *string) {
79    UNUSED(string);
80}
81
82void* H264SwDecMalloc(u32 size) {
83    return malloc(size);
84}
85
86void H264SwDecFree(void *ptr) {
87    free(ptr);
88}
89
90void H264SwDecMemcpy(void *dest, void *src, u32 count) {
91    memcpy(dest, src, count);
92}
93
94void 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
124H264SwDecRet 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
204H264SwDecRet 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
279void 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
338H264SwDecRet 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
493H264SwDecApiVersion 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
524H264SwDecRet 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