• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
61 H264DEC_TRACE           Trace H264 Decoder API function calls.
62 H264DEC_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 
H264SwDecTrace(char * string)80 void H264SwDecTrace(char *string) {
81     UNUSED(string);
82 }
83 
H264SwDecMalloc(u32 size,u32 num)84 void* 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 
H264SwDecFree(void * ptr)93 void H264SwDecFree(void *ptr) {
94     free(ptr);
95 }
96 
H264SwDecMemcpy(void * dest,void * src,u32 count)97 void H264SwDecMemcpy(void *dest, void *src, u32 count) {
98     memcpy(dest, src, count);
99 }
100 
H264SwDecMemset(void * ptr,i32 value,u32 count)101 void 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 
H264SwDecInit(H264SwDecInst * decInst,u32 noOutputReordering)131 H264SwDecRet 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 
H264SwDecGetInfo(H264SwDecInst decInst,H264SwDecInfo * pDecInfo)211 H264SwDecRet 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 
H264SwDecRelease(H264SwDecInst decInst)286 void 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 
H264SwDecDecode(H264SwDecInst decInst,H264SwDecInput * pInput,H264SwDecOutput * pOutput)345 H264SwDecRet 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 
H264SwDecGetAPIVersion()500 H264SwDecApiVersion 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 
H264SwDecNextPicture(H264SwDecInst decInst,H264SwDecPicture * pOutput,u32 flushBuffer)531 H264SwDecRet 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