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 "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 
     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 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
    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
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 */
   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 */
   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
   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 
   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 
   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 
   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