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