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