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