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