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