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
63H264DEC_TRACE           Trace H264 Decoder API function calls.
64H264DEC_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
82void H264SwDecTrace(char *string) {
83    UNUSED(string);
84}
85
86void* 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
95void H264SwDecFree(void *ptr) {
96    free(ptr);
97}
98
99void H264SwDecMemcpy(void *dest, void *src, u32 count) {
100    memcpy(dest, src, count);
101}
102
103void 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
133H264SwDecRet 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
213H264SwDecRet 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
288void 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
347H264SwDecRet 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
502H264SwDecApiVersion 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
533H264SwDecRet 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