• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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