1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
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
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18
19 #include "ti_m4v_config_parser.h"
20 #include "oscl_mem.h"
21 #include "oscl_dll.h"
22 OSCL_DLL_ENTRY_POINT_DEFAULT()
23
24 #define PV_CLZ(A,B) while (((B) & 0x8000) == 0) {(B) <<=1; A++;}
25
26 static const uint32 mask[33] =
27 {
28 0x00000000, 0x00000001, 0x00000003, 0x00000007,
29 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
30 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
31 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
32 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
33 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
34 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
35 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
36 0xffffffff
37 };
38
LocateFrameHeader(uint8 * ptr,int32 size)39 int32 LocateFrameHeader(uint8 *ptr, int32 size)
40 {
41 int32 count = 0;
42 int32 i = size;
43
44 if (size < 1)
45 {
46 return 0;
47 }
48 while (i--)
49 {
50 if ((count > 1) && (*ptr == 0x01))
51 {
52 i += 2;
53 break;
54 }
55
56 if (*ptr++)
57 count = 0;
58 else
59 count++;
60 }
61 return (size - (i + 1));
62 }
63
movePointerTo(mp4StreamType * psBits,int32 pos)64 void movePointerTo(mp4StreamType *psBits, int32 pos)
65 {
66 uint32 byte_pos;
67 if (pos < 0)
68 {
69 pos = 0;
70 }
71
72 byte_pos = pos >> 3;
73
74 if (byte_pos > (psBits->numBytes - psBits->bytePos))
75 {
76 byte_pos = (psBits->numBytes - psBits->bytePos);
77 }
78
79 psBits->bytePos = byte_pos & -4;
80 psBits->dataBitPos = psBits->bytePos << 3;
81 FlushBits(psBits, ((pos & 0x7) + ((byte_pos & 0x3) << 3)));
82 }
83
SearchNextM4VFrame(mp4StreamType * psBits)84 int16 SearchNextM4VFrame(mp4StreamType *psBits)
85 {
86 int16 status = 0;
87 uint8 *ptr;
88 int32 i;
89 uint32 initial_byte_aligned_position = (psBits->dataBitPos + 7) >> 3;
90
91 ptr = psBits->data + initial_byte_aligned_position;
92
93 i = LocateFrameHeader(ptr, psBits->numBytes - initial_byte_aligned_position);
94 if (psBits->numBytes <= initial_byte_aligned_position + i)
95 {
96 status = -1;
97 }
98 (void)movePointerTo(psBits, ((i + initial_byte_aligned_position) << 3)); /* ptr + i */
99 return status;
100 }
101
iGetM4VConfigInfo(uint8 * buffer,int32 length,int32 * width,int32 * height,int32 * display_width,int32 * display_height)102 OSCL_EXPORT_REF int16 iGetM4VConfigInfo(uint8 *buffer, int32 length, int32 *width, int32 *height, int32 *display_width, int32 *display_height)
103 {
104 int16 status;
105 mp4StreamType psBits;
106 psBits.data = buffer;
107 psBits.numBytes = length;
108 psBits.bitBuf = 0;
109 psBits.bitPos = 32;
110 psBits.bytePos = 0;
111 psBits.dataBitPos = 0;
112 *width = *height = *display_height = *display_width = 0;
113
114 if (length == 0)
115 {
116 return MP4_INVALID_VOL_PARAM;
117 }
118 int32 profilelevel = 0; // dummy value discarded here
119 status = iDecodeVOLHeader(&psBits, width, height, display_width, display_height, &profilelevel);
120 return status;
121 }
122
123 // name: iDecodeVOLHeader
124 // Purpose: decode VOL header
125 // return: error code
iDecodeVOLHeader(mp4StreamType * psBits,int32 * width,int32 * height,int32 * display_width,int32 * display_height,int32 * profilelevel)126 OSCL_EXPORT_REF int16 iDecodeVOLHeader(mp4StreamType *psBits, int32 *width, int32 *height, int32 *display_width, int32 *display_height, int32 *profilelevel)
127 {
128 int16 iErrorStat;
129 uint32 codeword;
130 int32 time_increment_resolution, nbits_time_increment;
131 int32 i, j;
132
133 *profilelevel = 0x0000FFFF; // init to some invalid value. When this value is returned, then no profilelevel info is available
134
135 ShowBits(psBits, 32, &codeword);
136
137 if (codeword == VISUAL_OBJECT_SEQUENCE_START_CODE)
138 {
139 //DV: this is the wrong way to skip bits, use FLush or Read psBits->dataBitPos += 32;
140 ReadBits(psBits, 32, &codeword); // skip 32 bits of the Start code
141
142 ReadBits(psBits, 8, &codeword);
143
144 // record profile and level
145 *profilelevel = (int) codeword;
146
147 ShowBits(psBits, 32, &codeword);
148 if (codeword == USER_DATA_START_CODE)
149 {
150 iErrorStat = DecodeUserData(psBits);
151 if (iErrorStat) return MP4_INVALID_VOL_PARAM;
152 }
153
154
155 ReadBits(psBits, 32, &codeword);
156 if (codeword != VISUAL_OBJECT_START_CODE) return MP4_INVALID_VOL_PARAM;
157
158 /* is_visual_object_identifier */
159 ReadBits(psBits, 1, &codeword);
160
161 if (codeword)
162 {
163 /* visual_object_verid */
164 ReadBits(psBits, 4, &codeword);
165 /* visual_object_priority */
166 ReadBits(psBits, 3, &codeword);
167 }
168 /* visual_object_type */
169 ReadBits(psBits, 4, &codeword);
170
171 if (codeword == 1)
172 { /* video_signal_type */
173 ReadBits(psBits, 1, &codeword);
174 if (codeword == 1)
175 {
176 /* video_format */
177 ReadBits(psBits, 3, &codeword);
178 /* video_range */
179 ReadBits(psBits, 1, &codeword);
180 /* color_description */
181 ReadBits(psBits, 1, &codeword);
182 if (codeword == 1)
183 {
184 /* color_primaries */
185 ReadBits(psBits, 8, &codeword);;
186 /* transfer_characteristics */
187 ReadBits(psBits, 8, &codeword);
188 /* matrix_coefficients */
189 ReadBits(psBits, 8, &codeword);
190 }
191 }
192 }
193 else
194 {
195 int16 status = 0;
196 do
197 {
198 /* Search for VOL_HEADER */
199 status = SearchNextM4VFrame(psBits); /* search 0x00 0x00 0x01 */
200 if (status != 0)
201 return MP4_INVALID_VOL_PARAM;
202
203 status = ReadBits(psBits, VOL_START_CODE_LENGTH, &codeword);
204 }
205 while ((codeword != VOL_START_CODE) && (status == 0));
206 goto decode_vol;
207 }
208 /* next_start_code() */
209 ByteAlign(psBits);
210
211 ShowBits(psBits, 32, &codeword);
212 if (codeword == USER_DATA_START_CODE)
213 {
214 iErrorStat = DecodeUserData(psBits);
215 if (iErrorStat) return MP4_INVALID_VOL_PARAM;
216 }
217 ShowBits(psBits, 27, &codeword);
218 }
219 else
220 {
221 ShowBits(psBits, 27, &codeword);
222 }
223
224 if (codeword == VO_START_CODE)
225 {
226
227 ReadBits(psBits, 32, &codeword);
228
229 /* video_object_layer_start_code */
230 ReadBits(psBits, 28, &codeword);
231 if (codeword != VOL_START_CODE)
232 {
233 if (psBits->dataBitPos >= (psBits->numBytes << 3))
234 {
235 return SHORT_HEADER_MODE; /* SH */
236 }
237 else
238 {
239 int16 status = 0;
240 do
241 {
242 /* Search for VOL_HEADER */
243 status = SearchNextM4VFrame(psBits); /* search 0x00 0x00 0x01 */
244 if (status != 0)
245 return MP4_INVALID_VOL_PARAM;
246
247 status = ReadBits(psBits, VOL_START_CODE_LENGTH, &codeword);
248 }
249 while ((codeword != VOL_START_CODE) && (status == 0));
250 goto decode_vol;
251 }
252 }
253 decode_vol:
254
255 uint32 vol_id;
256
257 /* vol_id (4 bits) */
258 ReadBits(psBits, 4, & vol_id);
259
260 // RandomAccessibleVOLFlag
261 ReadBits(psBits, 1, &codeword);
262
263 //Video Object Type Indication
264 ReadBits(psBits, 8, &codeword);
265 if (codeword != 1)
266 {
267 //return MP4_INVALID_VOL_PARAM; //TI supports this feature
268 }
269
270 // is_object_layer_identifier
271 ReadBits(psBits, 1, &codeword);
272
273 if (codeword)
274 {
275 ReadBits(psBits, 4, &codeword);
276 ReadBits(psBits, 3, &codeword);
277 }
278
279 // aspect ratio
280 ReadBits(psBits, 4, &codeword);
281
282 if (codeword == 0xF)
283 {
284 // Extended Parameter
285 /* width */
286 ReadBits(psBits, 8, &codeword);
287 /* height */
288 ReadBits(psBits, 8, &codeword);
289 }
290
291 ReadBits(psBits, 1, &codeword);
292
293 if (codeword)
294 {
295 ReadBits(psBits, 2, &codeword);
296 if (codeword != 1)
297 {
298 return MP4_INVALID_VOL_PARAM;
299 }
300
301 ReadBits(psBits, 1, &codeword);
302
303 if (!codeword)
304 {
305 //return MP4_INVALID_VOL_PARAM; //TI supports this feature
306 }
307
308 ReadBits(psBits, 1, &codeword);
309 if (codeword) /* if (vbv_parameters) {}, page 36 */
310 {
311 ReadBits(psBits, 15, &codeword);
312 ReadBits(psBits, 1, &codeword);
313 if (codeword != 1)
314 {
315 return MP4_INVALID_VOL_PARAM;
316 }
317
318 ReadBits(psBits, 15, &codeword);
319 ReadBits(psBits, 1, &codeword);
320 if (codeword != 1)
321 {
322 return MP4_INVALID_VOL_PARAM;
323 }
324
325
326 ReadBits(psBits, 19, &codeword);
327 if (!(codeword & 0x8))
328 {
329 return MP4_INVALID_VOL_PARAM;
330 }
331
332 ReadBits(psBits, 11, &codeword);
333 ReadBits(psBits, 1, &codeword);
334 if (codeword != 1)
335 {
336 return MP4_INVALID_VOL_PARAM;
337 }
338
339 ReadBits(psBits, 15, &codeword);
340 ReadBits(psBits, 1, &codeword);
341 if (codeword != 1)
342 {
343 return MP4_INVALID_VOL_PARAM;
344 }
345 }
346
347 }
348
349 ReadBits(psBits, 2, &codeword);
350
351 if (codeword != 0)
352 {
353 return MP4_INVALID_VOL_PARAM;
354 }
355
356 ReadBits(psBits, 1, &codeword);
357 if (codeword != 1)
358 {
359 return MP4_INVALID_VOL_PARAM;
360 }
361
362 ReadBits(psBits, 16, &codeword);
363 time_increment_resolution = codeword;
364
365
366 ReadBits(psBits, 1, &codeword);
367 if (codeword != 1)
368 {
369 return MP4_INVALID_VOL_PARAM;
370 }
371
372
373
374 ReadBits(psBits, 1, &codeword);
375
376 if (codeword && time_increment_resolution > 2)
377 {
378 i = time_increment_resolution - 1;
379 j = 1;
380 while (i >>= 1)
381 {
382 j++;
383 }
384 nbits_time_increment = j;
385
386 ReadBits(psBits, nbits_time_increment, &codeword);
387 }
388
389 ReadBits(psBits, 1, &codeword);
390 if (codeword != 1)
391 {
392 return MP4_INVALID_VOL_PARAM;
393 }
394
395 /* this should be 176 for QCIF */
396 ReadBits(psBits, 13, &codeword);
397 *display_width = (int32)codeword;
398 ReadBits(psBits, 1, &codeword);
399 if (codeword != 1)
400 {
401 return MP4_INVALID_VOL_PARAM;
402 }
403
404 /* this should be 144 for QCIF */
405 ReadBits(psBits, 13, &codeword);
406 *display_height = (int32)codeword;
407
408 *width = (*display_width + 15) & -16;
409 *height = (*display_height + 15) & -16;
410 }
411 else
412 {
413 /* SHORT_HEADER */
414 ShowBits(psBits, SHORT_VIDEO_START_MARKER_LENGTH, &codeword);
415 if (codeword == SHORT_VIDEO_START_MARKER)
416 {
417 iDecodeShortHeader(psBits, width, height, display_width, display_height);
418 }
419 else
420 {
421 int16 status = 0;
422 do
423 {
424 /* Search for VOL_HEADER */
425 status = SearchNextM4VFrame(psBits); /* search 0x00 0x00 0x01 */
426 if (status != 0)
427 {
428 return MP4_INVALID_VOL_PARAM;
429 }
430
431 status = ReadBits(psBits, VOL_START_CODE_LENGTH, &codeword);
432 }
433 while ((codeword != VOL_START_CODE) && (status == 0));
434 goto decode_vol;
435 }
436 }
437 return 0;
438 }
439
440
441
442 OSCL_EXPORT_REF
iDecodeShortHeader(mp4StreamType * psBits,int32 * width,int32 * height,int32 * display_width,int32 * display_height)443 int16 iDecodeShortHeader(mp4StreamType *psBits,
444 int32 *width,
445 int32 *height,
446 int32 *display_width,
447 int32 *display_height)
448 {
449 uint32 codeword;
450 int32 extended_PTYPE = 0;
451 int32 UFEP = 0;
452 int32 custom_PFMT = 0;
453
454 ShowBits(psBits, 22, &codeword);
455
456 if (codeword != 0x20)
457 {
458 return MP4_INVALID_VOL_PARAM;
459 }
460 FlushBits(psBits, 22);
461 ReadBits(psBits, 8, &codeword);
462
463 ReadBits(psBits, 1, &codeword);
464 if (codeword == 0) return MP4_INVALID_VOL_PARAM;
465
466 ReadBits(psBits, 1, &codeword);
467 if (codeword == 1) return MP4_INVALID_VOL_PARAM;
468
469 ReadBits(psBits, 1, &codeword);
470 if (codeword == 1) return MP4_INVALID_VOL_PARAM;
471
472 ReadBits(psBits, 1, &codeword);
473 if (codeword == 1) return MP4_INVALID_VOL_PARAM;
474
475 ReadBits(psBits, 1, &codeword);
476 if (codeword == 1) return MP4_INVALID_VOL_PARAM;
477
478 /* source format */
479 ReadBits(psBits, 3, &codeword);
480 switch (codeword)
481 {
482 case 1:
483 *width = 128;
484 *height = 96;
485 break;
486
487 case 2:
488 *width = 176;
489 *height = 144;
490 break;
491
492 case 3:
493 *width = 352;
494 *height = 288;
495 break;
496
497 case 4:
498 *width = 704;
499 *height = 576;
500 break;
501
502 case 5:
503 *width = 1408;
504 *height = 1152;
505 break;
506
507 case 7:
508 extended_PTYPE = 1;
509 break;
510 default:
511 /* Msg("H.263 source format not legal\n"); */
512 return MP4_INVALID_VOL_PARAM;
513 }
514
515 if (extended_PTYPE == 0)
516 {
517 *display_width = *width;
518 *display_height = *height;
519 return 0;
520 }
521 /* source format */
522 ReadBits(psBits, 3, &codeword);
523 UFEP = codeword;
524 if (UFEP == 1)
525 {
526 ReadBits(psBits, 3, &codeword);
527 switch (codeword)
528 {
529 case 1:
530 *width = 128;
531 *height = 96;
532 break;
533
534 case 2:
535 *width = 176;
536 *height = 144;
537 break;
538
539 case 3:
540 *width = 352;
541 *height = 288;
542 break;
543
544 case 4:
545 *width = 704;
546 *height = 576;
547 break;
548
549 case 5:
550 *width = 1408;
551 *height = 1152;
552 break;
553
554 case 6:
555 custom_PFMT = 1;
556 break;
557 default:
558 /* Msg("H.263 source format not legal\n"); */
559 return MP4_INVALID_VOL_PARAM;
560 }
561 if (custom_PFMT == 0)
562 {
563 *display_width = *width;
564 *display_height = *height;
565 return 0;
566 }
567 ReadBits(psBits, 1, &codeword);
568 ReadBits(psBits, 1, &codeword);
569 if (codeword) return MP4_INVALID_VOL_PARAM;
570 ReadBits(psBits, 1, &codeword);
571 if (codeword) return MP4_INVALID_VOL_PARAM;
572 ReadBits(psBits, 1, &codeword);
573 if (codeword) return MP4_INVALID_VOL_PARAM;
574 ReadBits(psBits, 3, &codeword);
575 ReadBits(psBits, 3, &codeword);
576 if (codeword) return MP4_INVALID_VOL_PARAM; /* RPS, ISD, AIV */
577 ReadBits(psBits, 1, &codeword);
578 ReadBits(psBits, 4, &codeword);
579 if (codeword != 8) return MP4_INVALID_VOL_PARAM;
580 }
581 if (UFEP == 0 || UFEP == 1)
582 {
583 ReadBits(psBits, 3, &codeword);
584 if (codeword > 1) return MP4_INVALID_VOL_PARAM;
585 ReadBits(psBits, 1, &codeword);
586 if (codeword) return MP4_INVALID_VOL_PARAM;
587 ReadBits(psBits, 1, &codeword);
588 if (codeword) return MP4_INVALID_VOL_PARAM;
589 ReadBits(psBits, 1, &codeword);
590 ReadBits(psBits, 3, &codeword);
591 if (codeword != 1) return MP4_INVALID_VOL_PARAM;
592 }
593 else
594 {
595 return MP4_INVALID_VOL_PARAM;
596 }
597 ReadBits(psBits, 1, &codeword);
598 if (codeword) return MP4_INVALID_VOL_PARAM; /* CPM */
599 if (custom_PFMT == 1 && UFEP == 1)
600 {
601 ReadBits(psBits, 4, &codeword);
602 if (codeword == 0) return MP4_INVALID_VOL_PARAM;
603 if (codeword == 0xf)
604 {
605 ReadBits(psBits, 8, &codeword);
606 ReadBits(psBits, 8, &codeword);
607 }
608 ReadBits(psBits, 9, &codeword);
609 *display_width = (codeword + 1) << 2;
610 *width = (*display_width + 15) & -16;
611 ReadBits(psBits, 1, &codeword);
612 if (codeword != 1) return MP4_INVALID_VOL_PARAM;
613 ReadBits(psBits, 9, &codeword);
614 if (codeword == 0) return MP4_INVALID_VOL_PARAM;
615 *display_height = codeword << 2;
616 *height = (*display_height + 15) & -16;
617 }
618
619 return 0;
620 }
621
622
ShowBits(mp4StreamType * pStream,uint8 ucNBits,uint32 * pulOutData)623 int16 ShowBits(
624 mp4StreamType *pStream, /* Input Stream */
625 uint8 ucNBits, /* nr of bits to read */
626 uint32 *pulOutData /* output target */
627 )
628 {
629 uint8 *bits;
630 uint32 dataBitPos = pStream->dataBitPos;
631 uint32 bitPos = pStream->bitPos;
632 uint32 dataBytePos;
633
634 uint i;
635
636 if (ucNBits > (32 - bitPos)) /* not enough bits */
637 {
638 dataBytePos = dataBitPos >> 3; /* Byte Aligned Position */
639 bitPos = dataBitPos & 7; /* update bit position */
640 if (dataBytePos > pStream->numBytes - 4)
641 {
642 pStream->bitBuf = 0;
643 for (i = 0;i < pStream->numBytes - dataBytePos;i++)
644 {
645 pStream->bitBuf |= pStream->data[dataBytePos+i];
646 pStream->bitBuf <<= 8;
647 }
648 pStream->bitBuf <<= 8 * (3 - i);
649 }
650 else
651 {
652 bits = &pStream->data[dataBytePos];
653 pStream->bitBuf = (bits[0] << 24) | (bits[1] << 16) | (bits[2] << 8) | bits[3];
654 }
655 pStream->bitPos = bitPos;
656 }
657
658 bitPos += ucNBits;
659
660 *pulOutData = (pStream->bitBuf >> (32 - bitPos)) & mask[(uint16)ucNBits];
661
662
663 return 0;
664 }
665
FlushBits(mp4StreamType * pStream,uint8 ucNBits)666 int16 FlushBits(
667 mp4StreamType *pStream, /* Input Stream */
668 uint8 ucNBits /* number of bits to flush */
669 )
670 {
671 uint8 *bits;
672 uint32 dataBitPos = pStream->dataBitPos;
673 uint32 bitPos = pStream->bitPos;
674 uint32 dataBytePos;
675
676
677 if ((dataBitPos + ucNBits) > (uint32)(pStream->numBytes << 3))
678 return (-2); // Buffer over run
679
680 dataBitPos += ucNBits;
681 bitPos += ucNBits;
682
683 if (bitPos > 32)
684 {
685 dataBytePos = dataBitPos >> 3; /* Byte Aligned Position */
686 bitPos = dataBitPos & 7; /* update bit position */
687 bits = &pStream->data[dataBytePos];
688 pStream->bitBuf = (bits[0] << 24) | (bits[1] << 16) | (bits[2] << 8) | bits[3];
689 }
690
691 pStream->dataBitPos = dataBitPos;
692 pStream->bitPos = bitPos;
693
694 return 0;
695 }
696
ReadBits(mp4StreamType * pStream,uint8 ucNBits,uint32 * pulOutData)697 int16 ReadBits(
698 mp4StreamType *pStream, /* Input Stream */
699 uint8 ucNBits, /* nr of bits to read */
700 uint32 *pulOutData /* output target */
701 )
702 {
703 uint8 *bits;
704 uint32 dataBitPos = pStream->dataBitPos;
705 uint32 bitPos = pStream->bitPos;
706 uint32 dataBytePos;
707
708
709 if ((dataBitPos + ucNBits) > (pStream->numBytes << 3))
710 {
711 *pulOutData = 0;
712 return (-2); // Buffer over run
713 }
714
715 // dataBitPos += ucNBits;
716
717 if (ucNBits > (32 - bitPos)) /* not enough bits */
718 {
719 dataBytePos = dataBitPos >> 3; /* Byte Aligned Position */
720 bitPos = dataBitPos & 7; /* update bit position */
721 bits = &pStream->data[dataBytePos];
722 pStream->bitBuf = (bits[0] << 24) | (bits[1] << 16) | (bits[2] << 8) | bits[3];
723 }
724
725 pStream->dataBitPos += ucNBits;
726 pStream->bitPos = (unsigned char)(bitPos + ucNBits);
727
728 *pulOutData = (pStream->bitBuf >> (32 - pStream->bitPos)) & mask[(uint16)ucNBits];
729
730 return 0;
731 }
732
733
734
ByteAlign(mp4StreamType * pStream)735 int16 ByteAlign(
736 mp4StreamType *pStream /* Input Stream */
737 )
738 {
739 uint8 *bits;
740 uint32 dataBitPos = pStream->dataBitPos;
741 uint32 bitPos = pStream->bitPos;
742 uint32 dataBytePos;
743 uint32 leftBits;
744
745 leftBits = 8 - (dataBitPos & 0x7);
746 if (leftBits == 8)
747 {
748 if ((dataBitPos + 8) > (uint32)(pStream->numBytes << 3))
749 return (-2); // Buffer over run
750 dataBitPos += 8;
751 bitPos += 8;
752 }
753 else
754 {
755 dataBytePos = dataBitPos >> 3;
756 dataBitPos += leftBits;
757 bitPos += leftBits;
758 }
759
760
761 if (bitPos > 32)
762 {
763 dataBytePos = dataBitPos >> 3; /* Byte Aligned Position */
764 bits = &pStream->data[dataBytePos];
765 pStream->bitBuf = (bits[0] << 24) | (bits[1] << 16) | (bits[2] << 8) | bits[3];
766 }
767
768 pStream->dataBitPos = dataBitPos;
769 pStream->bitPos = bitPos;
770
771 return 0;
772 }
773
DecodeUserData(mp4StreamType * pStream)774 int16 DecodeUserData(mp4StreamType *pStream)
775 {
776
777 uint32 codeword;
778 int16 iErrorStat;
779
780 iErrorStat = ReadBits(pStream, 32, &codeword);
781 if (iErrorStat) return iErrorStat;
782 iErrorStat = ShowBits(pStream, 24, &codeword);
783 if (iErrorStat) return iErrorStat;
784
785 while (codeword != 1)
786 {
787 /* Discard user data for now. */
788 iErrorStat = ReadBits(pStream, 8, &codeword);
789 if (iErrorStat) return iErrorStat;
790 iErrorStat = ShowBits(pStream, 24, &codeword);
791 if (iErrorStat) return iErrorStat;
792 }
793 return 0;
794 }
795
796
iGetAVCConfigInfo(uint8 * buffer,int32 length,int32 * width,int32 * height,int32 * display_width,int32 * display_height,int32 * profile_idc,int32 * level_idc,uint32 * entropy_coding_mode_flag)797 OSCL_EXPORT_REF int16 iGetAVCConfigInfo(uint8 *buffer, int32 length, int32 *width, int32 *height, int32 *display_width, int32 *display_height, int32 *profile_idc, int32 *level_idc, uint32 *entropy_coding_mode_flag)
798 {
799 int16 status;
800 mp4StreamType psBits;
801 uint16 sps_length, pps_length;
802 int32 size;
803 int32 i = 0;
804 uint8* sps = NULL;
805 uint8* temp = (uint8 *)OSCL_MALLOC(sizeof(uint8) * length);
806 uint8* pps = NULL;
807
808
809 if (temp)
810 {
811 sps = temp; // Make a copy of the original pointer to be freed later
812 // Successfull allocation... copy input buffer
813 oscl_memcpy(sps, buffer, length);
814 }
815 else
816 {
817 // Allocation failed
818 return MP4_INVALID_VOL_PARAM;
819 }
820
821 if (length < 3)
822 {
823 OSCL_FREE(temp);
824 return MP4_INVALID_VOL_PARAM;
825 }
826
827 *width = *height = *display_height = *display_width = 0;
828
829 if (sps[0] == 0 && sps[1] == 0)
830 {
831 /* find SC at the beginning of the NAL */
832 while (sps[i++] == 0 && i < length)
833 {
834 }
835
836 if (sps[i-1] == 1)
837 {
838 sps += i;
839
840 sps_length = 0;
841 // search for the next start code
842 while (!(sps[sps_length] == 0 && sps[sps_length+1] == 0 && sps[sps_length+2] == 1) &&
843 sps_length < length - i - 2)
844 {
845 sps_length++;
846 }
847
848 if (sps_length >= length - i - 2)
849 {
850 OSCL_FREE(temp);
851 return MP4_INVALID_VOL_PARAM;
852 }
853
854 pps_length = length - i - sps_length - 3;
855 pps = sps + sps_length + 3;
856 }
857 else
858 {
859 OSCL_FREE(temp);
860 return MP4_INVALID_VOL_PARAM;
861 }
862 }
863 else
864 {
865 sps_length = (uint16)(sps[1] << 8) | sps[0];
866 sps += 2;
867 pps = sps + sps_length;
868 pps_length = (uint16)(pps[1] << 8) | pps[0];
869 pps += 2;
870 }
871
872 if (sps_length + pps_length > length)
873 {
874 OSCL_FREE(temp);
875 return MP4_INVALID_VOL_PARAM;
876 }
877
878 size = sps_length;
879
880 Parser_EBSPtoRBSP(sps, &size);
881
882 psBits.data = sps;
883 psBits.numBytes = size;
884 psBits.bitBuf = 0;
885 psBits.bitPos = 32;
886 psBits.bytePos = 0;
887 psBits.dataBitPos = 0;
888
889 if (DecodeSPS(&psBits, width, height, display_width, display_height, profile_idc, level_idc))
890 {
891 OSCL_FREE(temp);
892 return MP4_INVALID_VOL_PARAM;
893 }
894
895 // now do PPS
896 size = pps_length;
897
898 Parser_EBSPtoRBSP(pps, &size);
899 psBits.data = pps;
900 psBits.numBytes = size;
901 psBits.bitBuf = 0;
902 psBits.bitPos = 32;
903 psBits.bytePos = 0;
904 psBits.dataBitPos = 0;
905
906 status = DecodePPS(&psBits, entropy_coding_mode_flag);
907
908 OSCL_FREE(temp);
909
910 return status;
911 }
912
scaling_list_h264(int32 i4_list_size,mp4StreamType * psBits)913 void scaling_list_h264(int32 i4_list_size, mp4StreamType *psBits)
914 {
915 int32 i4_j, i4_delta_scale, i4_lastScale = 8, i4_nextScale =8;
916
917
918 for(i4_j = 0; i4_j < i4_list_size; i4_j++)
919 {
920 if(i4_nextScale !=0)
921 {
922 se_v(psBits, &i4_delta_scale);
923 i4_nextScale = ((i4_lastScale + i4_delta_scale + 256) & 0xff);
924
925 }
926 i4_lastScale = (i4_nextScale == 0)? (i4_lastScale) : (i4_nextScale);
927 }
928 }
929
DecodeSPS(mp4StreamType * psBits,int32 * width,int32 * height,int32 * display_width,int32 * display_height,int32 * profile_idc,int32 * level_idc)930 int16 DecodeSPS(mp4StreamType *psBits, int32 *width, int32 *height, int32 *display_width, int32 *display_height, int32 *profile_idc, int32 *level_idc)
931 {
932 uint32 temp;
933 int32 temp0;
934 uint left_offset, right_offset, top_offset, bottom_offset;
935 uint i;
936 c_bool highProfileDetected = false;
937
938 ReadBits(psBits, 8, &temp);
939
940 if ((temp & 0x1F) != 7) return MP4_INVALID_VOL_PARAM;
941
942 ReadBits(psBits, 8, &temp);
943
944 *profile_idc = temp;
945
946 ReadBits(psBits, 1, &temp);
947 ReadBits(psBits, 1, &temp);
948 ReadBits(psBits, 1, &temp);
949 ReadBits(psBits, 5, &temp);
950 ReadBits(psBits, 8, &temp);
951
952 *level_idc = temp;
953
954 if (temp > 51)
955 return MP4_INVALID_VOL_PARAM;
956
957 ue_v(psBits, &temp);
958
959 if(*profile_idc == H264_PROFILE_IDC_HIGH)
960 {
961 /* High Profile detected; additional parameters to be parsed */
962 uint32 i4_chroma_format_idc, i4_bit_depth_luma_minus8, i4_bit_depth_chroma_minus8;
963 uint32 i4_seq_scaling_matrix_present_flag, i4_qpprime_y_zero_transform_bypass_flag;
964
965 highProfileDetected = true;
966
967 /* reading chroma_format_idc */
968 ue_v(psBits, &i4_chroma_format_idc);
969
970 if(i4_chroma_format_idc != 1 )
971 {
972 /* chroma_format_idc 1 represents 420. Other possibility is monochrome, not supported currently */
973 return (-1);
974 }
975
976 /* reading bit_depth_luma_minus8 */
977 ue_v(psBits, &i4_bit_depth_luma_minus8);
978
979 if(i4_bit_depth_luma_minus8 != 0)
980 {
981 /* only 8 bit supported, higher bit depth not supported */
982 return (-1);
983 }
984
985 /* reading bit_depth_chroma_minus8 */
986 ue_v(psBits, &i4_bit_depth_chroma_minus8);
987
988 if(i4_bit_depth_chroma_minus8 != 0)
989 {
990 /* only 8 bit supported, higher bit depth not supported */
991 return (-1);
992 }
993
994 /* reading qpprime_y_zero_transform_bypass_flag */
995 ReadBits(psBits, 1, &i4_qpprime_y_zero_transform_bypass_flag);
996 if(i4_qpprime_y_zero_transform_bypass_flag != 0)
997 {
998 return (-1);
999 }
1000
1001 /* reading seq_scaling_matrix_present_flag */
1002 ReadBits(psBits, 1, &i4_seq_scaling_matrix_present_flag);
1003
1004 if(i4_seq_scaling_matrix_present_flag)
1005 {
1006 int32 i4_i;
1007 for(i4_i =0; i4_i < 8; i4_i++)
1008 {
1009 uint32 i4_scaling_list_present;
1010 ReadBits(psBits, 1, &i4_scaling_list_present);
1011
1012 if(i4_scaling_list_present)
1013 {
1014 if(i4_i < 6)
1015 {
1016 scaling_list_h264(16, psBits);
1017 }
1018 else
1019 {
1020 scaling_list_h264(64, psBits);
1021 }
1022 }
1023 }
1024 }
1025 }
1026
1027 ue_v(psBits, &temp);
1028 ue_v(psBits, &temp);
1029
1030 if (temp == 0)
1031 {
1032 ue_v(psBits, &temp);
1033 }
1034 else if (temp == 1)
1035 {
1036 ReadBits(psBits, 1, &temp);
1037 se_v(psBits, &temp0);
1038 se_v(psBits, &temp0);
1039 ue_v(psBits, &temp);
1040
1041 for (i = 0; i < temp; i++)
1042 {
1043 se_v(psBits, &temp0);
1044 }
1045 }
1046 ue_v(psBits, &temp);
1047
1048
1049 ReadBits(psBits, 1, &temp);
1050 ue_v(psBits, &temp);
1051 *display_width = *width = (temp + 1) << 4;
1052 ue_v(psBits, &temp);
1053 *display_height = *height = (temp + 1) << 4;
1054
1055 ReadBits(psBits, 1, &temp);
1056 if (!temp)
1057 {
1058 // we do not support if frame_mb_only_flag is off
1059 return MP4_INVALID_VOL_PARAM;
1060 //ReadBits(psBits,1, &temp);
1061 }
1062
1063 ReadBits(psBits, 1, &temp);
1064
1065 ReadBits(psBits, 1, &temp);
1066
1067 if (temp)
1068 {
1069 ue_v(psBits, (uint32*)&left_offset);
1070 ue_v(psBits, (uint32*)&right_offset);
1071 ue_v(psBits, (uint32*)&top_offset);
1072 ue_v(psBits, (uint32*)&bottom_offset);
1073
1074 *display_width = *width - 2 * (right_offset + left_offset);
1075 *display_height = *height - 2 * (top_offset + bottom_offset);
1076 }
1077
1078 /* no need to check further */
1079 #if USE_LATER
1080 ReadBits(psBits, 1, &temp);
1081 if (temp)
1082 {
1083 if (!DecodeVUI(psBits))
1084 {
1085 return MP4_INVALID_VOL_PARAM;
1086 }
1087 }
1088 #endif
1089 return 0; // return 0 for success
1090 }
1091
1092 #if USE_LATER
1093 /* unused for now */
DecodeVUI(mp4StreamType * psBits)1094 int32 DecodeVUI(mp4StreamType *psBits)
1095 {
1096 uint temp;
1097 uint32 temp32;
1098 uint aspect_ratio_idc, overscan_appopriate_flag, video_format, video_full_range_flag;
1099 int32 status;
1100
1101 ReadBits(psBits, 1, &temp); /* aspect_ratio_info_present_flag */
1102 if (temp)
1103 {
1104 ReadBits(psBits, 8, &aspect_ratio_idc);
1105 if (aspect_ratio_idc == 255)
1106 {
1107 ReadBits(psBits, 16, &temp); /* sar_width */
1108 ReadBits(psBits, 16, &temp); /* sar_height */
1109 }
1110 }
1111 ReadBits(psBits, 1, &temp); /* overscan_info_present */
1112 if (temp)
1113 {
1114 ReadBits(psBits, 1, &overscan_appopriate_flag);
1115 }
1116 ReadBits(psBits, 1, &temp); /* video_signal_type_present_flag */
1117 if (temp)
1118 {
1119 ReadBits(psBits, 3, &video_format);
1120 ReadBits(psBits, 1, &video_full_range_flag);
1121 ReadBits(psBits, 1, &temp); /* colour_description_present_flag */
1122 if (temp)
1123 {
1124 ReadBits(psBits, 8, &temp); /* colour_primaries */
1125 ReadBits(psBits, 8, &temp); /* transfer_characteristics */
1126 ReadBits(psBits, 8, &temp); /* matrix coefficients */
1127 }
1128 }
1129 ReadBits(psBits, 1, &temp);/* chroma_loc_info_present_flag */
1130 if (temp)
1131 {
1132 ue_v(psBits, &temp); /* chroma_sample_loc_type_top_field */
1133 ue_v(psBits, &temp); /* chroma_sample_loc_type_bottom_field */
1134 }
1135
1136 ReadBits(psBits, 1, &temp); /* timing_info_present_flag*/
1137 if (temp)
1138 {
1139 ReadBits(psBits, 32, &temp32); /* num_unit_in_tick*/
1140 ReadBits(psBits, 32, &temp32); /* time_scale */
1141 ReadBits(psBits, 1, &temp); /* fixed_frame_rate_flag */
1142 }
1143
1144 ReadBits(psBits, 1, &temp); /* nal_hrd_parameters_present_flag */
1145 if (temp)
1146 {
1147 if (!DecodeHRD(psBits))
1148 {
1149 return 1;
1150 }
1151 }
1152 ReadBits(psBits, 1, &temp32); /* vcl_hrd_parameters_present_flag*/
1153 if (temp32)
1154 {
1155 if (!DecodeHRD(psBits))
1156 {
1157 return 1;
1158 }
1159 }
1160 if (temp || temp32)
1161 {
1162 ReadBits(psBits, 1, &temp); /* low_delay_hrd_flag */
1163 }
1164 ReadBits(psBits, 1, &temp); /* pic_struct_present_flag */
1165 status = ReadBits(psBits, 1, &temp); /* _restriction_flag */
1166 if (status != 0) // buffer overrun
1167 {
1168 return 1;
1169 }
1170
1171 if (temp)
1172 {
1173 ReadBits(psBits, 1, &temp); /* motion_vectors_over_pic_boundaries_flag */
1174 ue_v(psBits, &temp); /* max_bytes_per_pic_denom */
1175 ue_v(psBits, &temp); /* max_bits_per_mb_denom */
1176 ue_v(psBits, &temp); /* log2_max_mv_length_horizontal */
1177 ue_v(psBits, &temp); /* log2_max_mv_length_vertical */
1178 ue_v(psBits, &temp); /* num_reorder_frames */
1179 ue_v(psBits, &temp); /* max_dec_frame_buffering */
1180 }
1181
1182 return 0; // 0 for success
1183 }
1184
1185 /* unused for now */
DecodeHRD(mp4StreamType * psBits)1186 int32 DecodeHRD(mp4StreamType *psBits)
1187 {
1188 uint temp;
1189 uint cpb_cnt_minus1;
1190 uint i;
1191 int32 status;
1192
1193 ue_v(psBits, &cpb_cnt_minus1);
1194 ReadBits(psBits, 4, &temp); /* bit_rate_scale */
1195 ReadBits(psBits, 4, &temp); /* cpb_size_scale */
1196 for (i = 0; i <= cpb_cnt_minus1; i++)
1197 {
1198 ue_v(psBits, &temp); /* bit_rate_value_minus1[i] */
1199 ue_v(psBits, &temp); /* cpb_size_value_minus1[i] */
1200 ue_v(psBits, &temp); /* cbr_flag[i] */
1201 }
1202 ReadBits(psBits, 5, &temp); /* initial_cpb_removal_delay_length_minus1 */
1203 ReadBits(psBits, 5, &temp); /* cpb_removal_delay_length_minus1 */
1204 ReadBits(psBits, 5, &temp); /* dpb_output_delay_length_minus1 */
1205 status = ReadBits(psBits, 5, &temp); /* time_offset_length */
1206
1207 if (status != 0) // buffer overrun
1208 {
1209 return 1;
1210 }
1211
1212 return 0; // 0 for success
1213 }
1214 #endif
1215
1216 // only check for entropy coding mode
DecodePPS(mp4StreamType * psBits,uint32 * entropy_coding_mode_flag)1217 int32 DecodePPS(mp4StreamType *psBits, uint32 *entropy_coding_mode_flag)
1218 {
1219 uint32 temp, pic_parameter_set_id, seq_parameter_set_id;
1220
1221 ReadBits(psBits, 8, &temp);
1222
1223 if ((temp & 0x1F) != 8) return MP4_INVALID_VOL_PARAM;
1224
1225 ue_v(psBits, &pic_parameter_set_id);
1226 ue_v(psBits, &seq_parameter_set_id);
1227
1228 ReadBits(psBits, 1, entropy_coding_mode_flag);
1229
1230 return 0;
1231 }
1232
ue_v(mp4StreamType * psBits,uint32 * codeNum)1233 void ue_v(mp4StreamType *psBits, uint32 *codeNum)
1234 {
1235 uint32 temp;
1236 uint tmp_cnt;
1237 int32 leading_zeros = 0;
1238 ShowBits(psBits, 16, &temp);
1239 tmp_cnt = temp | 0x1;
1240
1241 PV_CLZ(leading_zeros, tmp_cnt)
1242
1243 if (leading_zeros < 8)
1244 {
1245 *codeNum = (temp >> (15 - (leading_zeros << 1))) - 1;
1246 FlushBits(psBits, (leading_zeros << 1) + 1);
1247 }
1248 else
1249 {
1250 ReadBits(psBits, (leading_zeros << 1) + 1, &temp);
1251 *codeNum = temp - 1;
1252 }
1253
1254 }
1255
1256
se_v(mp4StreamType * psBits,int32 * value)1257 void se_v(mp4StreamType *psBits, int32 *value)
1258 {
1259 int32 leadingZeros = 0;
1260 uint32 temp;
1261
1262 OSCL_UNUSED_ARG(value);
1263
1264 ReadBits(psBits, 1, &temp);
1265 while (!temp)
1266 {
1267 leadingZeros++;
1268 if (ReadBits(psBits, 1, &temp))
1269 {
1270 break;
1271 }
1272 }
1273 ReadBits(psBits, leadingZeros, &temp);
1274 }
1275
Parser_EBSPtoRBSP(uint8 * nal_unit,int32 * size)1276 void Parser_EBSPtoRBSP(uint8 *nal_unit, int32 *size)
1277 {
1278 int32 i, j;
1279 int32 count = 0;
1280
1281
1282 for (i = 0; i < *size; i++)
1283 {
1284 if (count == 2 && nal_unit[i] == 0x03)
1285 {
1286 break;
1287 }
1288
1289 if (nal_unit[i])
1290 count = 0;
1291 else
1292 count++;
1293 }
1294
1295 count = 0;
1296 j = i++;
1297 for (;i < *size; i++)
1298 {
1299 if (count == 2 && nal_unit[i] == 0x03)
1300 {
1301 i++;
1302 count = 0;
1303 }
1304 nal_unit[j] = nal_unit[i];
1305 if (nal_unit[i])
1306 count = 0;
1307 else
1308 count++;
1309 j++;
1310 }
1311
1312 *size = j;
1313 }
1314
1315
1316
1317