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
61H264DEC_TRACE           Trace H264 Decoder API function calls.
62H264DEC_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
80void H264SwDecTrace(char *string) {
81    UNUSED(string);
82}
83
84void* 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
93void H264SwDecFree(void *ptr) {
94    free(ptr);
95}
96
97void H264SwDecMemcpy(void *dest, void *src, u32 count) {
98    memcpy(dest, src, count);
99}
100
101void 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
131H264SwDecRet 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
211H264SwDecRet 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
286void 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
345H264SwDecRet 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
500H264SwDecApiVersion 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
531H264SwDecRet 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