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