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 "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;
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;
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 return MP4_INVALID_VOL_PARAM;
315
316 ReadBits(psBits, 15, &codeword);
317 ReadBits(psBits, 1, &codeword);
318 if (codeword != 1)
319 return MP4_INVALID_VOL_PARAM;
320
321
322 ReadBits(psBits, 19, &codeword);
323 if (!(codeword & 0x8))
324 return MP4_INVALID_VOL_PARAM;
325
326 ReadBits(psBits, 11, &codeword);
327 ReadBits(psBits, 1, &codeword);
328 if (codeword != 1)
329 return MP4_INVALID_VOL_PARAM;
330
331 ReadBits(psBits, 15, &codeword);
332 ReadBits(psBits, 1, &codeword);
333 if (codeword != 1)
334 return MP4_INVALID_VOL_PARAM;
335 }
336
337 }
338
339 ReadBits(psBits, 2, &codeword);
340
341 if (codeword != 0)
342 {
343 return MP4_INVALID_VOL_PARAM;
344 }
345
346 ReadBits(psBits, 1, &codeword);
347 if (codeword != 1)
348 return MP4_INVALID_VOL_PARAM;
349
350 ReadBits(psBits, 16, &codeword);
351 time_increment_resolution = codeword;
352
353
354 ReadBits(psBits, 1, &codeword);
355 if (codeword != 1)
356 return MP4_INVALID_VOL_PARAM;
357
358
359
360 ReadBits(psBits, 1, &codeword);
361
362 if (codeword && time_increment_resolution > 2)
363 {
364 i = time_increment_resolution - 1;
365 j = 1;
366 while (i >>= 1)
367 {
368 j++;
369 }
370 nbits_time_increment = j;
371
372 ReadBits(psBits, nbits_time_increment, &codeword);
373 }
374
375 ReadBits(psBits, 1, &codeword);
376 if (codeword != 1)
377 return MP4_INVALID_VOL_PARAM;
378
379 /* this should be 176 for QCIF */
380 ReadBits(psBits, 13, &codeword);
381 *display_width = (int32)codeword;
382 ReadBits(psBits, 1, &codeword);
383 if (codeword != 1)
384 return MP4_INVALID_VOL_PARAM;
385
386 /* this should be 144 for QCIF */
387 ReadBits(psBits, 13, &codeword);
388 *display_height = (int32)codeword;
389
390 *width = (*display_width + 15) & -16;
391 *height = (*display_height + 15) & -16;
392 }
393 else
394 {
395 /* SHORT_HEADER */
396 ShowBits(psBits, SHORT_VIDEO_START_MARKER_LENGTH, &codeword);
397 if (codeword == SHORT_VIDEO_START_MARKER)
398 {
399 iDecodeShortHeader(psBits, width, height, display_width, display_height);
400 }
401 else
402 {
403 int16 status = 0;
404 do
405 {
406 /* Search for VOL_HEADER */
407 status = SearchNextM4VFrame(psBits); /* search 0x00 0x00 0x01 */
408 if (status != 0)
409 return MP4_INVALID_VOL_PARAM;
410
411 status = ReadBits(psBits, VOL_START_CODE_LENGTH, &codeword);
412 }
413 while ((codeword != VOL_START_CODE) && (status == 0));
414 goto decode_vol;
415 }
416 }
417 return 0;
418 }
419
420
421
422 OSCL_EXPORT_REF
iDecodeShortHeader(mp4StreamType * psBits,int32 * width,int32 * height,int32 * display_width,int32 * display_height)423 int16 iDecodeShortHeader(mp4StreamType *psBits,
424 int32 *width,
425 int32 *height,
426 int32 *display_width,
427 int32 *display_height)
428 {
429 uint32 codeword;
430 int32 extended_PTYPE = 0;
431 int32 UFEP = 0;
432 int32 custom_PFMT = 0;
433
434 ShowBits(psBits, 22, &codeword);
435
436 if (codeword != 0x20)
437 {
438 return MP4_INVALID_VOL_PARAM;
439 }
440 FlushBits(psBits, 22);
441 ReadBits(psBits, 8, &codeword);
442
443 ReadBits(psBits, 1, &codeword);
444 if (codeword == 0) return MP4_INVALID_VOL_PARAM;
445
446 ReadBits(psBits, 1, &codeword);
447 if (codeword == 1) return MP4_INVALID_VOL_PARAM;
448
449 ReadBits(psBits, 1, &codeword);
450 if (codeword == 1) return MP4_INVALID_VOL_PARAM;
451
452 ReadBits(psBits, 1, &codeword);
453 if (codeword == 1) return MP4_INVALID_VOL_PARAM;
454
455 ReadBits(psBits, 1, &codeword);
456 if (codeword == 1) return MP4_INVALID_VOL_PARAM;
457
458 /* source format */
459 ReadBits(psBits, 3, &codeword);
460 switch (codeword)
461 {
462 case 1:
463 *width = 128;
464 *height = 96;
465 break;
466
467 case 2:
468 *width = 176;
469 *height = 144;
470 break;
471
472 case 3:
473 *width = 352;
474 *height = 288;
475 break;
476
477 case 4:
478 *width = 704;
479 *height = 576;
480 break;
481
482 case 5:
483 *width = 1408;
484 *height = 1152;
485 break;
486
487 case 7:
488 extended_PTYPE = 1;
489 break;
490 default:
491 /* Msg("H.263 source format not legal\n"); */
492 return MP4_INVALID_VOL_PARAM;
493 }
494
495 if (extended_PTYPE == 0)
496 {
497 *display_width = *width;
498 *display_height = *height;
499 return 0;
500 }
501 /* source format */
502 ReadBits(psBits, 3, &codeword);
503 UFEP = codeword;
504 if (UFEP == 1)
505 {
506 ReadBits(psBits, 3, &codeword);
507 switch (codeword)
508 {
509 case 1:
510 *width = 128;
511 *height = 96;
512 break;
513
514 case 2:
515 *width = 176;
516 *height = 144;
517 break;
518
519 case 3:
520 *width = 352;
521 *height = 288;
522 break;
523
524 case 4:
525 *width = 704;
526 *height = 576;
527 break;
528
529 case 5:
530 *width = 1408;
531 *height = 1152;
532 break;
533
534 case 6:
535 custom_PFMT = 1;
536 break;
537 default:
538 /* Msg("H.263 source format not legal\n"); */
539 return MP4_INVALID_VOL_PARAM;
540 }
541 if (custom_PFMT == 0)
542 {
543 *display_width = *width;
544 *display_height = *height;
545 return 0;
546 }
547 ReadBits(psBits, 1, &codeword);
548 ReadBits(psBits, 1, &codeword);
549 if (codeword) return MP4_INVALID_VOL_PARAM;
550 ReadBits(psBits, 1, &codeword);
551 if (codeword) return MP4_INVALID_VOL_PARAM;
552 ReadBits(psBits, 1, &codeword);
553 if (codeword) return MP4_INVALID_VOL_PARAM;
554 ReadBits(psBits, 3, &codeword);
555 ReadBits(psBits, 3, &codeword);
556 if (codeword) return MP4_INVALID_VOL_PARAM; /* RPS, ISD, AIV */
557 ReadBits(psBits, 1, &codeword);
558 ReadBits(psBits, 4, &codeword);
559 if (codeword != 8) return MP4_INVALID_VOL_PARAM;
560 }
561 if (UFEP == 0 || UFEP == 1)
562 {
563 ReadBits(psBits, 3, &codeword);
564 if (codeword > 1) return MP4_INVALID_VOL_PARAM;
565 ReadBits(psBits, 1, &codeword);
566 if (codeword) return MP4_INVALID_VOL_PARAM;
567 ReadBits(psBits, 1, &codeword);
568 if (codeword) return MP4_INVALID_VOL_PARAM;
569 ReadBits(psBits, 1, &codeword);
570 ReadBits(psBits, 3, &codeword);
571 if (codeword != 1) return MP4_INVALID_VOL_PARAM;
572 }
573 else
574 {
575 return MP4_INVALID_VOL_PARAM;
576 }
577 ReadBits(psBits, 1, &codeword);
578 if (codeword) return MP4_INVALID_VOL_PARAM; /* CPM */
579 if (custom_PFMT == 1 && UFEP == 1)
580 {
581 ReadBits(psBits, 4, &codeword);
582 if (codeword == 0) return MP4_INVALID_VOL_PARAM;
583 if (codeword == 0xf)
584 {
585 ReadBits(psBits, 8, &codeword);
586 ReadBits(psBits, 8, &codeword);
587 }
588 ReadBits(psBits, 9, &codeword);
589 *display_width = (codeword + 1) << 2;
590 *width = (*display_width + 15) & -16;
591 ReadBits(psBits, 1, &codeword);
592 if (codeword != 1) return MP4_INVALID_VOL_PARAM;
593 ReadBits(psBits, 9, &codeword);
594 if (codeword == 0) return MP4_INVALID_VOL_PARAM;
595 *display_height = codeword << 2;
596 *height = (*display_height + 15) & -16;
597 }
598
599 return 0;
600 }
601
602
ShowBits(mp4StreamType * pStream,uint8 ucNBits,uint32 * pulOutData)603 int16 ShowBits(
604 mp4StreamType *pStream, /* Input Stream */
605 uint8 ucNBits, /* nr of bits to read */
606 uint32 *pulOutData /* output target */
607 )
608 {
609 uint8 *bits;
610 uint32 dataBitPos = pStream->dataBitPos;
611 uint32 bitPos = pStream->bitPos;
612 uint32 dataBytePos;
613
614 uint i;
615
616 if (ucNBits > (32 - bitPos)) /* not enough bits */
617 {
618 dataBytePos = dataBitPos >> 3; /* Byte Aligned Position */
619 bitPos = dataBitPos & 7; /* update bit position */
620 if (dataBytePos > pStream->numBytes - 4)
621 {
622 pStream->bitBuf = 0;
623 for (i = 0; i < pStream->numBytes - dataBytePos; i++)
624 {
625 pStream->bitBuf |= pStream->data[dataBytePos+i];
626 pStream->bitBuf <<= 8;
627 }
628 pStream->bitBuf <<= 8 * (3 - i);
629 }
630 else
631 {
632 bits = &pStream->data[dataBytePos];
633 pStream->bitBuf = (bits[0] << 24) | (bits[1] << 16) | (bits[2] << 8) | bits[3];
634 }
635 pStream->bitPos = bitPos;
636 }
637
638 bitPos += ucNBits;
639
640 *pulOutData = (pStream->bitBuf >> (32 - bitPos)) & mask[(uint16)ucNBits];
641
642
643 return 0;
644 }
645
FlushBits(mp4StreamType * pStream,uint8 ucNBits)646 int16 FlushBits(
647 mp4StreamType *pStream, /* Input Stream */
648 uint8 ucNBits /* number of bits to flush */
649 )
650 {
651 uint8 *bits;
652 uint32 dataBitPos = pStream->dataBitPos;
653 uint32 bitPos = pStream->bitPos;
654 uint32 dataBytePos;
655
656
657 if ((dataBitPos + ucNBits) > (uint32)(pStream->numBytes << 3))
658 return (-2); // Buffer over run
659
660 dataBitPos += ucNBits;
661 bitPos += ucNBits;
662
663 if (bitPos > 32)
664 {
665 dataBytePos = dataBitPos >> 3; /* Byte Aligned Position */
666 bitPos = dataBitPos & 7; /* update bit position */
667 bits = &pStream->data[dataBytePos];
668 pStream->bitBuf = (bits[0] << 24) | (bits[1] << 16) | (bits[2] << 8) | bits[3];
669 }
670
671 pStream->dataBitPos = dataBitPos;
672 pStream->bitPos = bitPos;
673
674 return 0;
675 }
676
ReadBits(mp4StreamType * pStream,uint8 ucNBits,uint32 * pulOutData)677 int16 ReadBits(
678 mp4StreamType *pStream, /* Input Stream */
679 uint8 ucNBits, /* nr of bits to read */
680 uint32 *pulOutData /* output target */
681 )
682 {
683 uint8 *bits;
684 uint32 dataBitPos = pStream->dataBitPos;
685 uint32 bitPos = pStream->bitPos;
686 uint32 dataBytePos;
687
688
689 if ((dataBitPos + ucNBits) > (pStream->numBytes << 3))
690 {
691 *pulOutData = 0;
692 return (-2); // Buffer over run
693 }
694
695 // dataBitPos += ucNBits;
696
697 if (ucNBits > (32 - bitPos)) /* not enough bits */
698 {
699 dataBytePos = dataBitPos >> 3; /* Byte Aligned Position */
700 bitPos = dataBitPos & 7; /* update bit position */
701 bits = &pStream->data[dataBytePos];
702 pStream->bitBuf = (bits[0] << 24) | (bits[1] << 16) | (bits[2] << 8) | bits[3];
703 }
704
705 pStream->dataBitPos += ucNBits;
706 pStream->bitPos = (unsigned char)(bitPos + ucNBits);
707
708 *pulOutData = (pStream->bitBuf >> (32 - pStream->bitPos)) & mask[(uint16)ucNBits];
709
710 return 0;
711 }
712
713
714
ByteAlign(mp4StreamType * pStream)715 int16 ByteAlign(
716 mp4StreamType *pStream /* Input Stream */
717 )
718 {
719 uint8 *bits;
720 uint32 dataBitPos = pStream->dataBitPos;
721 uint32 bitPos = pStream->bitPos;
722 uint32 dataBytePos;
723 uint32 leftBits;
724
725 leftBits = 8 - (dataBitPos & 0x7);
726 if (leftBits == 8)
727 {
728 if ((dataBitPos + 8) > (uint32)(pStream->numBytes << 3))
729 return (-2); // Buffer over run
730 dataBitPos += 8;
731 bitPos += 8;
732 }
733 else
734 {
735 dataBytePos = dataBitPos >> 3;
736 dataBitPos += leftBits;
737 bitPos += leftBits;
738 }
739
740
741 if (bitPos > 32)
742 {
743 dataBytePos = dataBitPos >> 3; /* Byte Aligned Position */
744 bits = &pStream->data[dataBytePos];
745 pStream->bitBuf = (bits[0] << 24) | (bits[1] << 16) | (bits[2] << 8) | bits[3];
746 }
747
748 pStream->dataBitPos = dataBitPos;
749 pStream->bitPos = bitPos;
750
751 return 0;
752 }
753
DecodeUserData(mp4StreamType * pStream)754 int16 DecodeUserData(mp4StreamType *pStream)
755 {
756
757 uint32 codeword;
758 int16 iErrorStat;
759
760 iErrorStat = ReadBits(pStream, 32, &codeword);
761 if (iErrorStat) return iErrorStat;
762 iErrorStat = ShowBits(pStream, 24, &codeword);
763 if (iErrorStat) return iErrorStat;
764
765 while (codeword != 1)
766 {
767 /* Discard user data for now. */
768 iErrorStat = ReadBits(pStream, 8, &codeword);
769 if (iErrorStat) return iErrorStat;
770 iErrorStat = ShowBits(pStream, 24, &codeword);
771 if (iErrorStat) return iErrorStat;
772 }
773 return 0;
774 }
775
776
iGetAVCConfigInfo(uint8 * buffer,int32 length,int32 * width,int32 * height,int32 * display_width,int32 * display_height,int32 * profile_idc,int32 * level_idc)777 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)
778 {
779 int16 status;
780 mp4StreamType psBits;
781 uint16 sps_length, pps_length;
782 int32 size;
783 int32 i = 0;
784 uint8* sps = NULL;
785 uint8* temp = (uint8 *)OSCL_MALLOC(sizeof(uint8) * length);
786 uint8* pps = NULL;
787
788
789 if (temp)
790 {
791 sps = temp; // Make a copy of the original pointer to be freed later
792 // Successfull allocation... copy input buffer
793 oscl_memcpy(sps, buffer, length);
794 }
795 else
796 {
797 // Allocation failed
798 return MP4_INVALID_VOL_PARAM;
799 }
800
801 if (length < 3)
802 {
803 OSCL_FREE(temp);
804 return MP4_INVALID_VOL_PARAM;
805 }
806
807 *width = *height = *display_height = *display_width = 0;
808
809 if (sps[0] == 0 && sps[1] == 0)
810 {
811 /* find SC at the beginning of the NAL */
812 while (sps[i++] == 0 && i < length)
813 {
814 }
815
816 if (sps[i-1] == 1)
817 {
818 sps += i;
819
820 sps_length = 0;
821 // search for the next start code
822 while (!(sps[sps_length] == 0 && sps[sps_length+1] == 0 && sps[sps_length+2] == 1) &&
823 sps_length < length - i - 2)
824 {
825 sps_length++;
826 }
827
828 if (sps_length >= length - i - 2)
829 {
830 OSCL_FREE(temp);
831 return MP4_INVALID_VOL_PARAM;
832 }
833
834 pps_length = length - i - sps_length - 3;
835 pps = sps + sps_length + 3;
836 }
837 else
838 {
839 OSCL_FREE(temp);
840 return MP4_INVALID_VOL_PARAM;
841 }
842 }
843 else
844 {
845 sps_length = (uint16)(sps[1] << 8) | sps[0];
846 sps += 2;
847 pps = sps + sps_length;
848 pps_length = (uint16)(pps[1] << 8) | pps[0];
849 pps += 2;
850 }
851
852 if (sps_length + pps_length > length)
853 {
854 OSCL_FREE(temp);
855 return MP4_INVALID_VOL_PARAM;
856 }
857
858 size = sps_length;
859
860 Parser_EBSPtoRBSP(sps, &size);
861
862 psBits.data = sps;
863 psBits.numBytes = size;
864 psBits.bitBuf = 0;
865 psBits.bitPos = 32;
866 psBits.bytePos = 0;
867 psBits.dataBitPos = 0;
868
869 if (DecodeSPS(&psBits, width, height, display_width, display_height, profile_idc, level_idc))
870 {
871 OSCL_FREE(temp);
872 return MP4_INVALID_VOL_PARAM;
873 }
874
875 // now do PPS
876 size = pps_length;
877
878 Parser_EBSPtoRBSP(pps, &size);
879 psBits.data = pps;
880 psBits.numBytes = size;
881 psBits.bitBuf = 0;
882 psBits.bitPos = 32;
883 psBits.bytePos = 0;
884 psBits.dataBitPos = 0;
885
886 status = DecodePPS(&psBits);
887
888 OSCL_FREE(temp);
889
890 return status;
891 }
892
893
DecodeSPS(mp4StreamType * psBits,int32 * width,int32 * height,int32 * display_width,int32 * display_height,int32 * profile_idc,int32 * level_idc)894 int16 DecodeSPS(mp4StreamType *psBits, int32 *width, int32 *height, int32 *display_width, int32 *display_height, int32 *profile_idc, int32 *level_idc)
895 {
896 uint32 temp;
897 int32 temp0;
898 uint left_offset, right_offset, top_offset, bottom_offset;
899 uint i;
900
901 ReadBits(psBits, 8, &temp);
902
903
904
905 if ((temp & 0x1F) != 7) return MP4_INVALID_VOL_PARAM;
906
907 ReadBits(psBits, 8, &temp);
908
909 *profile_idc = temp;
910
911 ReadBits(psBits, 1, &temp);
912 ReadBits(psBits, 1, &temp);
913 ReadBits(psBits, 1, &temp);
914 ReadBits(psBits, 5, &temp);
915 ReadBits(psBits, 8, &temp);
916
917 *level_idc = temp;
918
919 if (temp > 51)
920 return MP4_INVALID_VOL_PARAM;
921
922 ue_v(psBits, &temp);
923 ue_v(psBits, &temp);
924 ue_v(psBits, &temp);
925
926 if (temp == 0)
927 {
928 ue_v(psBits, &temp);
929 }
930 else if (temp == 1)
931 {
932 ReadBits(psBits, 1, &temp);
933 se_v(psBits, &temp0);
934 se_v(psBits, &temp0);
935 ue_v(psBits, &temp);
936
937 for (i = 0; i < temp; i++)
938 {
939 se_v(psBits, &temp0);
940 }
941 }
942 ue_v(psBits, &temp);
943
944
945 ReadBits(psBits, 1, &temp);
946 ue_v(psBits, &temp);
947 *display_width = *width = (temp + 1) << 4;
948 ue_v(psBits, &temp);
949 *display_height = *height = (temp + 1) << 4;
950
951
952 ReadBits(psBits, 1, &temp);
953 if (!temp)
954 {
955 // we do not support if frame_mb_only_flag is off
956 return MP4_INVALID_VOL_PARAM;
957 //ReadBits(psBits,1, &temp);
958 }
959
960 ReadBits(psBits, 1, &temp);
961
962 ReadBits(psBits, 1, &temp);
963
964 if (temp)
965 {
966 ue_v(psBits, (uint32*)&left_offset);
967 ue_v(psBits, (uint32*)&right_offset);
968 ue_v(psBits, (uint32*)&top_offset);
969 ue_v(psBits, (uint32*)&bottom_offset);
970
971 *display_width = *width - 2 * (right_offset + left_offset);
972 *display_height = *height - 2 * (top_offset + bottom_offset);
973 }
974
975 /* no need to check further */
976 #if USE_LATER
977 ReadBits(psBits, 1, &temp);
978 if (temp)
979 {
980 if (!DecodeVUI(psBits))
981 {
982 return MP4_INVALID_VOL_PARAM;
983 }
984 }
985 #endif
986 return 0; // return 0 for success
987 }
988
989 #if USE_LATER
990 /* unused for now */
DecodeVUI(mp4StreamType * psBits)991 int32 DecodeVUI(mp4StreamType *psBits)
992 {
993 uint temp;
994 uint32 temp32;
995 uint aspect_ratio_idc, overscan_appopriate_flag, video_format, video_full_range_flag;
996 int32 status;
997
998 ReadBits(psBits, 1, &temp); /* aspect_ratio_info_present_flag */
999 if (temp)
1000 {
1001 ReadBits(psBits, 8, &aspect_ratio_idc);
1002 if (aspect_ratio_idc == 255)
1003 {
1004 ReadBits(psBits, 16, &temp); /* sar_width */
1005 ReadBits(psBits, 16, &temp); /* sar_height */
1006 }
1007 }
1008 ReadBits(psBits, 1, &temp); /* overscan_info_present */
1009 if (temp)
1010 {
1011 ReadBits(psBits, 1, &overscan_appopriate_flag);
1012 }
1013 ReadBits(psBits, 1, &temp); /* video_signal_type_present_flag */
1014 if (temp)
1015 {
1016 ReadBits(psBits, 3, &video_format);
1017 ReadBits(psBits, 1, &video_full_range_flag);
1018 ReadBits(psBits, 1, &temp); /* colour_description_present_flag */
1019 if (temp)
1020 {
1021 ReadBits(psBits, 8, &temp); /* colour_primaries */
1022 ReadBits(psBits, 8, &temp); /* transfer_characteristics */
1023 ReadBits(psBits, 8, &temp); /* matrix coefficients */
1024 }
1025 }
1026 ReadBits(psBits, 1, &temp);/* chroma_loc_info_present_flag */
1027 if (temp)
1028 {
1029 ue_v(psBits, &temp); /* chroma_sample_loc_type_top_field */
1030 ue_v(psBits, &temp); /* chroma_sample_loc_type_bottom_field */
1031 }
1032
1033 ReadBits(psBits, 1, &temp); /* timing_info_present_flag*/
1034 if (temp)
1035 {
1036 ReadBits(psBits, 32, &temp32); /* num_unit_in_tick*/
1037 ReadBits(psBits, 32, &temp32); /* time_scale */
1038 ReadBits(psBits, 1, &temp); /* fixed_frame_rate_flag */
1039 }
1040
1041 ReadBits(psBits, 1, &temp); /* nal_hrd_parameters_present_flag */
1042 if (temp)
1043 {
1044 if (!DecodeHRD(psBits))
1045 {
1046 return 1;
1047 }
1048 }
1049 ReadBits(psBits, 1, &temp32); /* vcl_hrd_parameters_present_flag*/
1050 if (temp32)
1051 {
1052 if (!DecodeHRD(psBits))
1053 {
1054 return 1;
1055 }
1056 }
1057 if (temp || temp32)
1058 {
1059 ReadBits(psBits, 1, &temp); /* low_delay_hrd_flag */
1060 }
1061 ReadBits(psBits, 1, &temp); /* pic_struct_present_flag */
1062 status = ReadBits(psBits, 1, &temp); /* _restriction_flag */
1063 if (status != 0) // buffer overrun
1064 {
1065 return 1;
1066 }
1067
1068 if (temp)
1069 {
1070 ReadBits(psBits, 1, &temp); /* motion_vectors_over_pic_boundaries_flag */
1071 ue_v(psBits, &temp); /* max_bytes_per_pic_denom */
1072 ue_v(psBits, &temp); /* max_bits_per_mb_denom */
1073 ue_v(psBits, &temp); /* log2_max_mv_length_horizontal */
1074 ue_v(psBits, &temp); /* log2_max_mv_length_vertical */
1075 ue_v(psBits, &temp); /* num_reorder_frames */
1076 ue_v(psBits, &temp); /* max_dec_frame_buffering */
1077 }
1078
1079 return 0; // 0 for success
1080 }
1081
1082 /* unused for now */
DecodeHRD(mp4StreamType * psBits)1083 int32 DecodeHRD(mp4StreamType *psBits)
1084 {
1085 uint temp;
1086 uint cpb_cnt_minus1;
1087 uint i;
1088 int32 status;
1089
1090 ue_v(psBits, &cpb_cnt_minus1);
1091 ReadBits(psBits, 4, &temp); /* bit_rate_scale */
1092 ReadBits(psBits, 4, &temp); /* cpb_size_scale */
1093 for (i = 0; i <= cpb_cnt_minus1; i++)
1094 {
1095 ue_v(psBits, &temp); /* bit_rate_value_minus1[i] */
1096 ue_v(psBits, &temp); /* cpb_size_value_minus1[i] */
1097 ue_v(psBits, &temp); /* cbr_flag[i] */
1098 }
1099 ReadBits(psBits, 5, &temp); /* initial_cpb_removal_delay_length_minus1 */
1100 ReadBits(psBits, 5, &temp); /* cpb_removal_delay_length_minus1 */
1101 ReadBits(psBits, 5, &temp); /* dpb_output_delay_length_minus1 */
1102 status = ReadBits(psBits, 5, &temp); /* time_offset_length */
1103
1104 if (status != 0) // buffer overrun
1105 {
1106 return 1;
1107 }
1108
1109 return 0; // 0 for success
1110 }
1111 #endif
1112
1113 // only check for entropy coding mode
DecodePPS(mp4StreamType * psBits)1114 int32 DecodePPS(mp4StreamType *psBits)
1115 {
1116 uint32 temp, pic_parameter_set_id, seq_parameter_set_id, entropy_coding_mode_flag;
1117
1118 ReadBits(psBits, 8, &temp);
1119
1120 if ((temp & 0x1F) != 8) return MP4_INVALID_VOL_PARAM;
1121
1122 ue_v(psBits, &pic_parameter_set_id);
1123 ue_v(psBits, &seq_parameter_set_id);
1124
1125 ReadBits(psBits, 1, &entropy_coding_mode_flag);
1126 if (entropy_coding_mode_flag)
1127 {
1128 return 1;
1129 }
1130
1131 return 0;
1132 }
1133
ue_v(mp4StreamType * psBits,uint32 * codeNum)1134 void ue_v(mp4StreamType *psBits, uint32 *codeNum)
1135 {
1136 uint32 temp;
1137 uint tmp_cnt;
1138 int32 leading_zeros = 0;
1139 ShowBits(psBits, 16, &temp);
1140 tmp_cnt = temp | 0x1;
1141
1142 PV_CLZ(leading_zeros, tmp_cnt)
1143
1144 if (leading_zeros < 8)
1145 {
1146 *codeNum = (temp >> (15 - (leading_zeros << 1))) - 1;
1147 FlushBits(psBits, (leading_zeros << 1) + 1);
1148 }
1149 else
1150 {
1151 ReadBits(psBits, (leading_zeros << 1) + 1, &temp);
1152 *codeNum = temp - 1;
1153 }
1154
1155 }
1156
1157
se_v(mp4StreamType * psBits,int32 * value)1158 void se_v(mp4StreamType *psBits, int32 *value)
1159 {
1160 int32 leadingZeros = 0;
1161 uint32 temp;
1162
1163 OSCL_UNUSED_ARG(value);
1164
1165 ReadBits(psBits, 1, &temp);
1166 while (!temp)
1167 {
1168 leadingZeros++;
1169 if (ReadBits(psBits, 1, &temp))
1170 {
1171 break;
1172 }
1173 }
1174 ReadBits(psBits, leadingZeros, &temp);
1175 }
1176
Parser_EBSPtoRBSP(uint8 * nal_unit,int32 * size)1177 void Parser_EBSPtoRBSP(uint8 *nal_unit, int32 *size)
1178 {
1179 int32 i, j;
1180 int32 count = 0;
1181
1182
1183 for (i = 0; i < *size; i++)
1184 {
1185 if (count == 2 && nal_unit[i] == 0x03)
1186 {
1187 break;
1188 }
1189
1190 if (nal_unit[i])
1191 count = 0;
1192 else
1193 count++;
1194 }
1195
1196 count = 0;
1197 j = i++;
1198 for (; i < *size; i++)
1199 {
1200 if (count == 2 && nal_unit[i] == 0x03)
1201 {
1202 i++;
1203 count = 0;
1204 }
1205 nal_unit[j] = nal_unit[i];
1206 if (nal_unit[i])
1207 count = 0;
1208 else
1209 count++;
1210 j++;
1211 }
1212
1213 *size = j;
1214 }
1215
1216
1217
1218