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 #include "bitstream.h"
     19 #include "mp4dec_lib.h"
     20 
     21 
     22 #define OSCL_DISABLE_WARNING_CONDITIONAL_IS_CONSTANT
     23 /* to mask the n least significant bits of an integer */
     24 static const uint32 msk[33] =
     25 {
     26     0x00000000, 0x00000001, 0x00000003, 0x00000007,
     27     0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
     28     0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
     29     0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
     30     0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
     31     0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
     32     0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
     33     0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
     34     0xffffffff
     35 };
     36 
     37 
     38 /* ======================================================================== */
     39 /*  Function : BitstreamFillCache()                                         */
     40 /*  Date     : 08/29/2000                                                   */
     41 /*  Purpose  : Read more bitstream data into buffer & the 24-byte cache.    */
     42 /*              This function is different from BitstreamFillBuffer in      */
     43 /*              that the buffer is the frame-based buffer provided by       */
     44 /*              the application.                                            */
     45 /*  In/out   :                                                              */
     46 /*  Return   : PV_SUCCESS if successed, PV_FAIL if failed.                  */
     47 /*  Modified : 4/16/01  : removed return of PV_END_OF_BUFFER                */
     48 /* ======================================================================== */
     49 PV_STATUS BitstreamFillCache(BitstreamDecVideo *stream)
     50 {
     51     uint8 *bitstreamBuffer = stream->bitstreamBuffer;
     52     uint8 *v;
     53     int num_bits, i;
     54 
     55     stream->curr_word |= (stream->next_word >> stream->incnt);   // stream->incnt cannot be 32
     56     stream->next_word <<= (31 - stream->incnt);
     57     stream->next_word <<= 1;
     58     num_bits = stream->incnt_next + stream->incnt;
     59     if (num_bits >= 32)
     60     {
     61         stream->incnt_next -= (32 - stream->incnt);
     62         stream->incnt = 32;
     63         return PV_SUCCESS;
     64     }
     65     /* this check can be removed if there is additional extra 4 bytes at the end of the bitstream */
     66     v = bitstreamBuffer + stream->read_point;
     67 
     68     if (stream->read_point > stream->data_end_pos - 4)
     69     {
     70         if (stream->data_end_pos <= stream->read_point)
     71         {
     72             stream->incnt = num_bits;
     73             stream->incnt_next = 0;
     74             return PV_SUCCESS;
     75         }
     76 
     77         stream->next_word = 0;
     78 
     79         for (i = 0; i < stream->data_end_pos - stream->read_point; i++)
     80         {
     81             stream->next_word |= (v[i] << ((3 - i) << 3));
     82         }
     83 
     84         stream->read_point = stream->data_end_pos;
     85         stream->curr_word |= (stream->next_word >> num_bits); // this is safe
     86 
     87         stream->next_word <<= (31 - num_bits);
     88         stream->next_word <<= 1;
     89         num_bits = i << 3;
     90         stream->incnt += stream->incnt_next;
     91         stream->incnt_next = num_bits - (32 - stream->incnt);
     92         if (stream->incnt_next < 0)
     93         {
     94             stream->incnt +=  num_bits;
     95             stream->incnt_next = 0;
     96         }
     97         else
     98         {
     99             stream->incnt = 32;
    100         }
    101         return PV_SUCCESS;
    102     }
    103 
    104     stream->next_word = ((uint32)v[0] << 24) | (v[1] << 16) | (v[2] << 8) | v[3];
    105     stream->read_point += 4;
    106 
    107     stream->curr_word |= (stream->next_word >> num_bits); // this is safe
    108     stream->next_word <<= (31 - num_bits);
    109     stream->next_word <<= 1;
    110     stream->incnt_next += stream->incnt;
    111     stream->incnt = 32;
    112     return PV_SUCCESS;
    113 }
    114 
    115 
    116 /* ======================================================================== */
    117 /*  Function : BitstreamReset()                                             */
    118 /*  Date     : 08/29/2000                                                   */
    119 /*  Purpose  : Initialize the bitstream buffer for frame-based decoding.    */
    120 /*  In/out   :                                                              */
    121 /*  Return   :                                                              */
    122 /*  Modified :                                                              */
    123 /* ======================================================================== */
    124 void BitstreamReset(BitstreamDecVideo *stream, uint8 *buffer, int32 buffer_size)
    125 {
    126     /* set up frame-based bitstream buffer */
    127     oscl_memset(stream, 0, sizeof(BitstreamDecVideo));
    128     stream->data_end_pos = buffer_size;
    129     stream->bitstreamBuffer = buffer;
    130 }
    131 
    132 
    133 /* ======================================================================== */
    134 /*  Function : BitstreamOpen()                                              */
    135 /*  Purpose  : Initialize the bitstream data structure.                     */
    136 /*  In/out   :                                                              */
    137 /*  Return   :                                                              */
    138 /*  Modified :                                                              */
    139 /* ======================================================================== */
    140 int BitstreamOpen(BitstreamDecVideo *stream, int)
    141 {
    142     int buffer_size = 0;
    143     /* set up linear bitstream buffer */
    144 //  stream->currentBytePos = 0;
    145     stream->data_end_pos = 0;
    146 
    147     stream->incnt = 0;
    148     stream->incnt_next = 0;
    149     stream->bitcnt = 0;
    150     stream->curr_word = stream->next_word = 0;
    151     stream->read_point = stream->data_end_pos;
    152     return buffer_size;
    153 }
    154 
    155 
    156 /* ======================================================================== */
    157 /*  Function : BitstreamClose()                                             */
    158 /*  Purpose  : Cleanup the bitstream data structure.                        */
    159 /*  In/out   :                                                              */
    160 /*  Return   :                                                              */
    161 /*  Modified :                                                              */
    162 /* ======================================================================== */
    163 void BitstreamClose(BitstreamDecVideo *)
    164 {
    165     return;
    166 }
    167 
    168 
    169 /***********************************************************CommentBegin******
    170 *
    171 * -- BitstreamShowBits32HC
    172 * Shows 32 bits
    173 ***********************************************************CommentEnd********/
    174 
    175 PV_STATUS BitstreamShowBits32HC(BitstreamDecVideo *stream, uint32 *code)
    176 {
    177     PV_STATUS status = PV_SUCCESS;
    178 
    179     if (stream->incnt < 32)
    180     {
    181         /* frame-based decoding */
    182         status = BitstreamFillCache(stream);
    183     }
    184     *code = stream->curr_word;
    185     return status;
    186 }
    187 
    188 /***********************************************************CommentBegin******
    189 *
    190 * -- BitstreamShowBits32
    191 * Shows upto and including 31 bits
    192 ***********************************************************CommentEnd********/
    193 PV_STATUS BitstreamShowBits32(BitstreamDecVideo *stream, int nbits, uint32 *code)
    194 {
    195     PV_STATUS status = PV_SUCCESS;
    196 
    197     if (stream->incnt < nbits)
    198     {
    199         /* frame-based decoding */
    200         status = BitstreamFillCache(stream);
    201     }
    202     *code = stream->curr_word >> (32 - nbits);
    203     return status;
    204 }
    205 
    206 
    207 #ifndef PV_BS_INLINE
    208 /*========================================================================= */
    209 /*  Function:   BitstreamShowBits16()                                       */
    210 /*  Date:       12/18/2000                                                  */
    211 /*  Purpose:    To see the next "nbits"(nbits<=16) bitstream bits           */
    212 /*              without advancing the read pointer                          */
    213 /*                                                                          */
    214 /* =========================================================================*/
    215 PV_STATUS BitstreamShowBits16(BitstreamDecVideo *stream, int nbits, uint *code)
    216 {
    217     PV_STATUS status = PV_SUCCESS;
    218 
    219 
    220     if (stream->incnt < nbits)
    221     {
    222         /* frame-based decoding */
    223         status = BitstreamFillCache(stream);
    224     }
    225 
    226     *code = stream->curr_word >> (32 - nbits);
    227     return status;
    228 }
    229 
    230 
    231 /*========================================================================= */
    232 /*  Function:   BitstreamShow15Bits()                                       */
    233 /*  Date:       01/23/2001                                                  */
    234 /*  Purpose:    To see the next 15 bitstream bits                           */
    235 /*              without advancing the read pointer                          */
    236 /*                                                                          */
    237 /* =========================================================================*/
    238 PV_STATUS BitstreamShow15Bits(BitstreamDecVideo *stream, uint *code)
    239 {
    240     PV_STATUS status = PV_SUCCESS;
    241 
    242     if (stream->incnt < 15)
    243     {
    244         /* frame-based decoding */
    245         status = BitstreamFillCache(stream);
    246     }
    247     *code = stream->curr_word >> 17;
    248     return status;
    249 }
    250 /*========================================================================= */
    251 /*  Function: BitstreamShow13Bits                                           */
    252 /*  Date:       050923                                              */
    253 /*  Purpose:    Faciliate and speed up showing 13 bit from bitstream        */
    254 /*              used in VlcTCOEFF decoding                                  */
    255 /*  Modified:                            */
    256 /* =========================================================================*/
    257 PV_STATUS BitstreamShow13Bits(BitstreamDecVideo *stream, uint *code)
    258 {
    259     PV_STATUS status = PV_SUCCESS;
    260 
    261     if (stream->incnt < 13)
    262     {
    263         /* frame-based decoding */
    264         status = BitstreamFillCache(stream);
    265     }
    266     *code = stream->curr_word >> 19;
    267     return status;
    268 }
    269 
    270 uint BitstreamReadBits16_INLINE(BitstreamDecVideo *stream, int nbits)
    271 {
    272     uint code;
    273     PV_STATUS status;
    274 
    275     if (stream->incnt < nbits)
    276     {
    277         /* frame-based decoding */
    278         status = BitstreamFillCache(stream);
    279     }
    280     code = stream->curr_word >> (32 - nbits);
    281     PV_BitstreamFlushBits(stream, nbits);
    282     return code;
    283 }
    284 
    285 
    286 uint BitstreamRead1Bits_INLINE(BitstreamDecVideo *stream)
    287 {
    288     PV_STATUS status = PV_SUCCESS;
    289     uint    code;
    290 
    291 
    292     if (stream->incnt < 1)
    293     {
    294         /* frame-based decoding */
    295         status = BitstreamFillCache(stream);
    296     }
    297     code = stream->curr_word >> 31;
    298     PV_BitstreamFlushBits(stream, 1);
    299 
    300     return code;
    301 }
    302 
    303 #endif
    304 
    305 /* ======================================================================== */
    306 /*  Function : BitstreamReadBits16()                                        */
    307 /*  Purpose  : Read bits (nbits <=16) from bitstream buffer.                */
    308 /*  In/out   :                                                              */
    309 /*  Return   :                                                              */
    310 /* ======================================================================== */
    311 uint BitstreamReadBits16(BitstreamDecVideo *stream, int nbits)
    312 {
    313     uint code;
    314 
    315     if (stream->incnt < nbits)
    316     {
    317         /* frame-based decoding */
    318         BitstreamFillCache(stream);
    319     }
    320     code = stream->curr_word >> (32 - nbits);
    321     PV_BitstreamFlushBits(stream, nbits);
    322     return code;
    323 }
    324 
    325 /* ======================================================================== */
    326 /*  Function : BitstreamRead1Bits()                                         */
    327 /*  Date     : 10/23/2000                                                   */
    328 /*  Purpose  : Faciliate and speed up reading 1 bit from bitstream.         */
    329 /*  In/out   :                                                              */
    330 /*  Return   :                                                              */
    331 /* ======================================================================== */
    332 
    333 uint BitstreamRead1Bits(BitstreamDecVideo *stream)
    334 {
    335     uint    code;
    336 
    337     if (stream->incnt < 1)
    338     {
    339         /* frame-based decoding */
    340         BitstreamFillCache(stream);
    341     }
    342     code = stream->curr_word >> 31;
    343     PV_BitstreamFlushBits(stream, 1);
    344 
    345     return code;
    346 }
    347 
    348 /* ======================================================================== */
    349 /*  Function : PV_BitstreamFlushBitsCheck()                                 */
    350 /*  Purpose  : Flush nbits bits from bitstream buffer. Check for cache      */
    351 /*  In/out   :                                                              */
    352 /*  Return   :                                                              */
    353 /*  Modified :                                                              */
    354 /* ======================================================================== */
    355 PV_STATUS PV_BitstreamFlushBitsCheck(BitstreamDecVideo *stream, int nbits)
    356 {
    357     PV_STATUS status = PV_SUCCESS;
    358 
    359     stream->bitcnt += nbits;
    360     stream->incnt -= nbits;
    361     if (stream->incnt < 0)
    362     {
    363         /* frame-based decoding */
    364         status = BitstreamFillCache(stream);
    365 
    366         if (stream->incnt < 0)
    367         {
    368             stream->bitcnt += stream->incnt;
    369             stream->incnt = 0;
    370         }
    371     }
    372     stream->curr_word <<= nbits;
    373     return status;
    374 }
    375 
    376 /* ======================================================================== */
    377 /*  Function : BitstreamReadBits32()                                        */
    378 /*  Purpose  : Read bits from bitstream buffer.                             */
    379 /*  In/out   :                                                              */
    380 /*  Return   :                                                              */
    381 /* ======================================================================== */
    382 uint32 BitstreamReadBits32(BitstreamDecVideo *stream, int nbits)
    383 {
    384     uint32 code;
    385 
    386     if (stream->incnt < nbits)
    387     {
    388         /* frame-based decoding */
    389         BitstreamFillCache(stream);
    390     }
    391     code = stream->curr_word >> (32 - nbits);
    392     PV_BitstreamFlushBits(stream, nbits);
    393     return code;
    394 }
    395 
    396 uint32 BitstreamReadBits32HC(BitstreamDecVideo *stream)
    397 {
    398     uint32 code;
    399 
    400     BitstreamShowBits32HC(stream, &code);
    401     stream->bitcnt += 32;
    402     stream->incnt = 0;
    403     stream->curr_word = 0;
    404     return code;
    405 }
    406 
    407 /* ======================================================================== */
    408 /*  Function : BitstreamCheckEndBuffer()                                    */
    409 /*  Date     : 03/30/2001                                                   */
    410 /*  Purpose  : Check to see if we are at the end of buffer                  */
    411 /*  In/out   :                                                              */
    412 /*  Return   :                                                              */
    413 /*  Modified :                                                              */
    414 /* ======================================================================== */
    415 PV_STATUS BitstreamCheckEndBuffer(BitstreamDecVideo *stream)
    416 {
    417     if (stream->read_point >= stream->data_end_pos && stream->incnt <= 0) return PV_END_OF_VOP;
    418     return PV_SUCCESS;
    419 }
    420 
    421 
    422 PV_STATUS PV_BitstreamShowBitsByteAlign(BitstreamDecVideo *stream, int nbits, uint32 *code)
    423 {
    424     PV_STATUS status = PV_SUCCESS;
    425 
    426     int n_stuffed;
    427 
    428     n_stuffed = 8 - (stream->bitcnt & 0x7); /*  07/05/01 */
    429 
    430     if (stream->incnt < (nbits + n_stuffed))
    431     {
    432         /* frame-based decoding */
    433         status = BitstreamFillCache(stream);
    434     }
    435 
    436     *code = (stream->curr_word << n_stuffed) >> (32 - nbits);
    437     return status;
    438 }
    439 
    440 #ifdef PV_ANNEX_IJKT_SUPPORT
    441 PV_STATUS PV_BitstreamShowBitsByteAlignNoForceStuffing(BitstreamDecVideo *stream, int nbits, uint32 *code)
    442 {
    443     PV_STATUS status = PV_SUCCESS;
    444 
    445     int n_stuffed;
    446 
    447     n_stuffed = (8 - (stream->bitcnt & 0x7)) & 7;
    448 
    449     if (stream->incnt < (nbits + n_stuffed))
    450     {
    451         /* frame-based decoding */
    452         status = BitstreamFillCache(stream);
    453     }
    454 
    455     *code = (stream->curr_word << n_stuffed) >> (32 - nbits);
    456     return status;
    457 }
    458 #endif
    459 
    460 PV_STATUS PV_BitstreamByteAlign(BitstreamDecVideo *stream)
    461 {
    462     PV_STATUS status = PV_SUCCESS;
    463     int n_stuffed;
    464 
    465     n_stuffed = 8 - (stream->bitcnt & 0x7); /*  07/05/01 */
    466 
    467     /* We have to make sure we have enough bits in the cache.   08/15/2000 */
    468     if (stream->incnt < n_stuffed)
    469     {
    470         /* frame-based decoding */
    471         status = BitstreamFillCache(stream);
    472     }
    473 
    474 
    475     stream->bitcnt += n_stuffed;
    476     stream->incnt -= n_stuffed;
    477     stream->curr_word <<= n_stuffed;
    478     if (stream->incnt < 0)
    479     {
    480         stream->bitcnt += stream->incnt;
    481         stream->incnt = 0;
    482     }
    483     return status;
    484 }
    485 
    486 
    487 PV_STATUS BitstreamByteAlignNoForceStuffing(BitstreamDecVideo *stream)
    488 {
    489     uint n_stuffed;
    490 
    491     n_stuffed = (8 - (stream->bitcnt & 0x7)) & 0x7; /*  07/05/01 */
    492 
    493     stream->bitcnt += n_stuffed;
    494     stream->incnt -= n_stuffed;
    495 
    496     if (stream->incnt < 0)
    497     {
    498         stream->bitcnt += stream->incnt;
    499         stream->incnt = 0;
    500     }
    501     stream->curr_word <<= n_stuffed;
    502     return PV_SUCCESS;
    503 }
    504 
    505 
    506 /* ==================================================================== */
    507 /*  Function : getPointer()                                             */
    508 /*  Date     : 10/98                                                    */
    509 /*  Purpose  : get current position of file pointer                     */
    510 /*  In/out   :                                                          */
    511 /*  Return   :                                                          */
    512 /* ==================================================================== */
    513 int32 getPointer(BitstreamDecVideo *stream)
    514 {
    515     return stream->bitcnt;
    516 }
    517 
    518 
    519 
    520 
    521 /* ====================================================================== /
    522 Function : movePointerTo()
    523 Date     : 05/14/2004
    524 Purpose  : move bitstream pointer to a desired position
    525 In/out   :
    526 Return   :
    527 Modified :
    528 / ====================================================================== */
    529 PV_STATUS movePointerTo(BitstreamDecVideo *stream, int32 pos)
    530 {
    531     int32 byte_pos;
    532     if (pos < 0)
    533     {
    534         pos = 0;
    535     }
    536 
    537     byte_pos = pos >> 3;
    538 
    539     if (byte_pos > stream->data_end_pos)
    540     {
    541         byte_pos = stream->data_end_pos;
    542     }
    543 
    544     stream->read_point = byte_pos & -4;
    545     stream->bitcnt = stream->read_point << 3;;
    546     stream->curr_word = 0;
    547     stream->next_word = 0;
    548     stream->incnt = 0;
    549     stream->incnt_next = 0;
    550     BitstreamFillCache(stream);
    551     PV_BitstreamFlushBits(stream, ((pos & 0x7) + ((byte_pos & 0x3) << 3)));
    552     return PV_SUCCESS;
    553 }
    554 
    555 
    556 /* ======================================================================== */
    557 /*  Function : validStuffing()                                              */
    558 /*  Date     : 04/11/2000                                                   */
    559 /*  Purpose  : Check whether we have valid stuffing at current position.    */
    560 /*  In/out   :                                                              */
    561 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.                    */
    562 /*  Modified : 12/18/2000 : changed the pattern type to uint    */
    563 /*             04/01/2001 : removed PV_END_OF_BUFFER                        */
    564 /* ======================================================================== */
    565 Bool validStuffing(BitstreamDecVideo *stream)
    566 {
    567     uint n_stuffed;
    568     uint pattern;
    569 
    570 
    571     n_stuffed = 8 - (stream->bitcnt & 0x7);
    572     BitstreamShowBits16(stream, n_stuffed, &pattern);
    573     if (pattern == msk[n_stuffed-1]) return PV_TRUE;
    574     return PV_FALSE;
    575 }
    576 #ifdef PV_ANNEX_IJKT_SUPPORT
    577 Bool validStuffing_h263(BitstreamDecVideo *stream)
    578 {
    579     uint n_stuffed;
    580     uint pattern;
    581 
    582 
    583     n_stuffed = (8 - (stream->bitcnt & 0x7)) & 7;  //  stream->incnt % 8
    584     if (n_stuffed == 0)
    585     {
    586         return PV_TRUE;
    587     }
    588     BitstreamShowBits16(stream, n_stuffed, &pattern);
    589     if (pattern == 0) return PV_TRUE;
    590     return PV_FALSE;
    591 }
    592 #endif
    593 
    594 
    595 /* ======================================================================== */
    596 /*  Function : PVSearchNextH263Frame()                                      */
    597 /*  Date     : 04/08/2005                                                   */
    598 /*  Purpose  : search for 0x00 0x00 0x80                                    */
    599 /*  In/out   :                                                              */
    600 /*  Return   : PV_SUCCESS if succeeded  or PV_END_OF_VOP if failed          */
    601 /*  Modified :                                                              */
    602 /* ======================================================================== */
    603 PV_STATUS PVSearchNextH263Frame(BitstreamDecVideo *stream)
    604 {
    605     PV_STATUS status = PV_SUCCESS;
    606     uint8 *ptr;
    607     int32 i;
    608     int32 initial_byte_aligned_position = (stream->bitcnt + 7) >> 3;
    609 
    610     ptr = stream->bitstreamBuffer + initial_byte_aligned_position;
    611 
    612     i = PVLocateH263FrameHeader(ptr, stream->data_end_pos - initial_byte_aligned_position);
    613     if (stream->data_end_pos <= initial_byte_aligned_position + i)
    614     {
    615         status = PV_END_OF_VOP;
    616     }
    617     (void)movePointerTo(stream, ((i + initial_byte_aligned_position) << 3)); /* ptr + i */
    618     return status;
    619 }
    620 
    621 
    622 /* ======================================================================== */
    623 /*  Function : PVSearchNextM4VFrame()                                       */
    624 /*  Date     : 04/08/2005                                                   */
    625 /*  Purpose  : search for 0x00 0x00 0x01 and move the pointer to the        */
    626 /*  beginning of the start code                                             */
    627 /*  In/out   :                                                              */
    628 /*  Return   : PV_SUCCESS if succeeded  or PV_END_OF_VOP if failed          */
    629 /*  Modified :                                                              */
    630 /* ======================================================================== */
    631 
    632 PV_STATUS PVSearchNextM4VFrame(BitstreamDecVideo *stream)
    633 {
    634     PV_STATUS status = PV_SUCCESS;
    635     uint8 *ptr;
    636     int32 i;
    637     int32 initial_byte_aligned_position = (stream->bitcnt + 7) >> 3;
    638 
    639     ptr = stream->bitstreamBuffer + initial_byte_aligned_position;
    640 
    641     i = PVLocateFrameHeader(ptr, stream->data_end_pos - initial_byte_aligned_position);
    642     if (stream->data_end_pos <= initial_byte_aligned_position + i)
    643     {
    644         status = PV_END_OF_VOP;
    645     }
    646     (void)movePointerTo(stream, ((i + initial_byte_aligned_position) << 3)); /* ptr + i */
    647     return status;
    648 }
    649 
    650 
    651 
    652 void PVLocateM4VFrameBoundary(BitstreamDecVideo *stream)
    653 {
    654     uint8 *ptr;
    655     int32 byte_pos = (stream->bitcnt >> 3);
    656 
    657     stream->searched_frame_boundary = 1;
    658     ptr = stream->bitstreamBuffer + byte_pos;
    659 
    660     stream->data_end_pos = PVLocateFrameHeader(ptr, (int32)stream->data_end_pos - byte_pos) + byte_pos;
    661 }
    662 
    663 void PVLocateH263FrameBoundary(BitstreamDecVideo *stream)
    664 {
    665     uint8 *ptr;
    666     int32 byte_pos = (stream->bitcnt >> 3);
    667 
    668     stream->searched_frame_boundary = 1;
    669     ptr = stream->bitstreamBuffer + byte_pos;
    670 
    671     stream->data_end_pos = PVLocateH263FrameHeader(ptr, (int32)stream->data_end_pos - byte_pos) + byte_pos;
    672 }
    673 
    674 /* ======================================================================== */
    675 /*  Function : quickSearchVideoPacketHeader()               */
    676 /*  Date     : 05/08/2000                           */
    677 /*  Purpose  : Quick search for the next video packet header        */
    678 /*  In/out   :                              */
    679 /*  Return   : PV_TRUE if successed, PV_FALSE if failed.            */
    680 /*  Modified :                              */
    681 /* ======================================================================== */
    682 PV_STATUS quickSearchVideoPacketHeader(BitstreamDecVideo *stream, int marker_length)
    683 {
    684     PV_STATUS status = PV_SUCCESS;
    685     uint32 tmpvar;
    686 
    687 
    688     if (stream->searched_frame_boundary == 0)
    689     {
    690         PVLocateM4VFrameBoundary(stream);
    691     }
    692 
    693     do
    694     {
    695         status = BitstreamCheckEndBuffer(stream);
    696         if (status == PV_END_OF_VOP) break;
    697         PV_BitstreamShowBitsByteAlign(stream, marker_length, &tmpvar);
    698         if (tmpvar == RESYNC_MARKER) break;
    699         PV_BitstreamFlushBits(stream, 8);
    700     }
    701     while (status == PV_SUCCESS);
    702 
    703     return status;
    704 }
    705 #ifdef PV_ANNEX_IJKT_SUPPORT
    706 PV_STATUS quickSearchH263SliceHeader(BitstreamDecVideo *stream)
    707 {
    708     PV_STATUS status = PV_SUCCESS;
    709     uint32 tmpvar;
    710 
    711 
    712     if (stream->searched_frame_boundary == 0)
    713     {
    714         PVLocateH263FrameBoundary(stream);
    715     }
    716 
    717     do
    718     {
    719         status = BitstreamCheckEndBuffer(stream);
    720         if (status == PV_END_OF_VOP) break;
    721         PV_BitstreamShowBitsByteAlignNoForceStuffing(stream, 17, &tmpvar);
    722         if (tmpvar == RESYNC_MARKER) break;
    723         PV_BitstreamFlushBits(stream, 8);
    724     }
    725     while (status == PV_SUCCESS);
    726 
    727     return status;
    728 }
    729 #endif
    730 /* ======================================================================== */
    731 /*          The following functions are for Error Concealment.              */
    732 /* ======================================================================== */
    733 
    734 /****************************************************/
    735 //  01/22/99 Quick search of Resync Marker
    736 // (actually the first part of it, i.e. 16 0's and a 1.
    737 
    738 /* We are not using the fastest algorithm possible. What this function does is
    739 to locate 11 consecutive 0's and then check if the 5 bits before them and
    740 the 1 bit after them are all 1's.
    741 */
    742 
    743 //  Table used for quick search of markers. Gives the last `1' in
    744 // 4 bits. The MSB is bit #1, the LSB is bit #4.
    745 const int lastOne[] =
    746 {
    747     0,  4,  3,  4,  2,  4,  3,  4,
    748     1,  4,  3,  4,  2,  4,  3,  4
    749 };
    750 
    751 //  Table used for quick search of markers. Gives the last `0' in
    752 // 4 bits. The MSB is bit #1, the LSB is bit #4.
    753 /*const int lastZero[]=
    754 {
    755     4,  3,  4,  2,  4,  3,  4,  1,
    756         4,  3,  4,  2,  4,  3,  4,  0
    757 };
    758 */
    759 //  Table used for quick search of markers. Gives the first `0' in
    760 // 4 bits. The MSB is bit #1, the LSB is bit #4.
    761 const int firstZero[] =
    762 {
    763     1, 1, 1, 1, 1, 1, 1, 1,
    764     2, 2, 2, 2, 3, 3, 4, 0
    765 };
    766 
    767 //  Table used for quick search of markers. Gives the first `1' in
    768 // 4 bits. The MSB is bit #1, the LSB is bit #4.
    769 const int firstOne[] =
    770 {
    771     0, 4, 3, 3, 2, 2, 2, 2,
    772     1, 1, 1, 1, 1, 1, 1, 1
    773 };
    774 
    775 
    776 /* ======================================================================== */
    777 /*  Function : quickSearchMarkers()                                         */
    778 /*  Date     : 01/25/99                                                     */
    779 /*  Purpose  : Quick search for Motion marker                               */
    780 /*  In/out   :                                                              */
    781 /*  Return   : Boolean true of false                                        */
    782 /*  Modified : 12/18/2000 : 32-bit version                    */
    783 /* ======================================================================== */
    784 PV_STATUS quickSearchMotionMarker(BitstreamDecVideo *stream)
    785 // MM: (11111000000000001)
    786 {
    787     PV_STATUS status;
    788     uint32 tmpvar, tmpvar2;
    789 
    790     if (stream->searched_frame_boundary == 0)
    791     {
    792         PVLocateM4VFrameBoundary(stream);
    793     }
    794 
    795     while (TRUE)
    796     {
    797         status = BitstreamCheckEndBuffer(stream);
    798         if (status == PV_END_OF_VOP) return PV_END_OF_VOP;
    799 
    800         BitstreamShowBits32(stream, 17, &tmpvar);
    801         if (!tmpvar) return PV_FAIL;
    802 
    803         if (tmpvar & 1) //  Check if the 17th bit from the curr bit pos is a '1'
    804         {
    805             if (tmpvar == MOTION_MARKER_COMB)
    806             {
    807                 return PV_SUCCESS; //  Found
    808             }
    809             else
    810             {
    811                 tmpvar >>= 1;
    812                 tmpvar &= 0xF;
    813                 PV_BitstreamFlushBits(stream, (int)(12 + firstZero[tmpvar]));
    814             }
    815         }
    816         else
    817         {
    818             //  01/25/99 Get the first 16 bits
    819             tmpvar >>= 1;
    820             tmpvar2 = tmpvar & 0xF;
    821 
    822             //  01/26/99 Check bits #13 ~ #16
    823             if (tmpvar2)
    824             {
    825                 PV_BitstreamFlushBits(stream, (int)(7 + lastOne[tmpvar2]));
    826             }
    827             else
    828             {
    829                 tmpvar >>= 4;
    830                 tmpvar2 = tmpvar & 0xF;
    831 
    832                 //  01/26/99 Check bits #9 ~ #12
    833                 if (tmpvar2)
    834                 {
    835                     PV_BitstreamFlushBits(stream, (int)(3 + lastOne[tmpvar2]));
    836                 }
    837                 else
    838                 {
    839                     tmpvar >>= 4;
    840                     tmpvar2 = tmpvar & 0xF;
    841 
    842                     //  01/26/99 Check bits #5 ~ #8
    843                     // We don't need to check further
    844                     // for the first 5 bits should be all 1's
    845                     if (lastOne[tmpvar2] < 2)
    846                     {
    847                         /* we already have too many consecutive 0's. */
    848                         /* Go directly pass the last of the 17 bits. */
    849                         PV_BitstreamFlushBits(stream, 17);
    850                     }
    851                     else
    852                     {
    853                         PV_BitstreamFlushBits(stream, (int)(lastOne[tmpvar2] - 1));
    854                     }
    855                 }
    856             }
    857         }
    858 
    859     }
    860 }
    861 
    862 /* ======================================================================== */
    863 /*  Function : quickSearchDCM()                                             */
    864 /*  Date     : 01/22/99                                                     */
    865 /*  Purpose  : Quick search for DC Marker                                   */
    866 /*              We are not using the fastest algorithm possible.  What this */
    867 /*              function does is to locate 11 consecutive 0's and then      */
    868 /*              check if the 7 bits before them and the 1 bit after them    */
    869 /*              are correct.  (actually the first part of it, i.e. 16 0's   */
    870 /*              and a 1.                                                    */
    871 /*  In/out   :                                                              */
    872 /*  Return   : Boolean true of false                                        */
    873 /*  Modified : 12/18/2000 : 32-bit version                    */
    874 /* ======================================================================== */
    875 PV_STATUS quickSearchDCM(BitstreamDecVideo *stream)
    876 // DCM: (110 1011 0000 0000 0001)
    877 {
    878     PV_STATUS status;
    879     uint32 tmpvar, tmpvar2;
    880 
    881     if (stream->searched_frame_boundary == 0)
    882     {
    883         PVLocateM4VFrameBoundary(stream);
    884     }
    885 
    886     while (TRUE)
    887     {
    888         status = BitstreamCheckEndBuffer(stream);
    889         if (status == PV_END_OF_VOP) return PV_END_OF_VOP;
    890         BitstreamShowBits32(stream, 19, &tmpvar);
    891 
    892         if (tmpvar & 1) //  Check if the 17th bit from the curr bit pos is a '1'
    893         {
    894             if (tmpvar == DC_MARKER)
    895             {
    896                 return PV_SUCCESS; //  Found
    897             }
    898             else
    899             {
    900                 //  01/25/99 We treat the last of the 19 bits as its 7th bit (which is
    901                 // also a `1'
    902                 PV_BitstreamFlushBits(stream, 12);
    903             }
    904         }
    905         else
    906         {
    907             tmpvar >>= 1;
    908             tmpvar2 = tmpvar & 0xF;
    909 
    910             if (tmpvar2)
    911             {
    912                 PV_BitstreamFlushBits(stream, (int)(7 + lastOne[tmpvar2]));
    913             }
    914             else
    915             {
    916                 tmpvar >>= 4;
    917                 tmpvar2 = tmpvar & 0xF;
    918                 if (tmpvar2)
    919                 {
    920                     PV_BitstreamFlushBits(stream, (int)(3 + lastOne[tmpvar2]));
    921                 }
    922                 else
    923                 {
    924                     tmpvar >>= 4;
    925                     tmpvar2 = tmpvar & 0xF;
    926                     if (lastOne[tmpvar2] < 2)
    927                     {
    928                         /* we already have too many consecutive 0's. */
    929                         /* Go directly pass the last of the 17 bits. */
    930                         PV_BitstreamFlushBits(stream, 19);
    931                     }
    932                     else
    933                     {
    934                         PV_BitstreamFlushBits(stream, (int)(lastOne[tmpvar2] - 1));
    935                     }
    936                 }
    937             }
    938         }
    939     }
    940 }
    941 
    942 /* ======================================================================== */
    943 /*  Function : quickSearchGOBHeader()   0000 0000 0000 0000 1               */
    944 /*  Date     : 07/06/01                                                     */
    945 /*  Purpose  : Quick search of GOBHeader (not byte aligned)                 */
    946 /*  In/out   :                                                              */
    947 /*  Return   : Integer value indicates type of marker found                 */
    948 /*  Modified :                                                              */
    949 /* ======================================================================== */
    950 PV_STATUS quickSearchGOBHeader(BitstreamDecVideo *stream)
    951 {
    952     PV_STATUS status;
    953     int byte0, byte1, byte2, shift, tmpvar;
    954 
    955     BitstreamByteAlignNoForceStuffing(stream);
    956 
    957     if (stream->searched_frame_boundary == 0)
    958     {
    959         PVLocateH263FrameBoundary(stream);
    960     }
    961 
    962     while (TRUE)
    963     {
    964         status = BitstreamCheckEndBuffer(stream);
    965         if (status == PV_END_OF_VOP) return PV_END_OF_VOP;
    966 
    967         if (stream->incnt < 24)
    968         {
    969             status = BitstreamFillCache(stream);
    970         }
    971 
    972 
    973         byte1 = (stream->curr_word << 8) >> 24;
    974         if (byte1 == 0)
    975         {
    976             byte2 = (stream->curr_word << 16) >> 24;
    977             if (byte2)
    978             {
    979                 tmpvar = byte2 >> 4;
    980 
    981                 if (tmpvar)
    982                 {
    983                     shift = 9 - firstOne[tmpvar];
    984                 }
    985                 else
    986                 {
    987                     shift = 5 - firstOne[byte2];
    988                 }
    989                 byte0 = stream->curr_word >> 24;
    990                 if ((byte0 & msk[shift]) == 0)
    991                 {
    992                     PV_BitstreamFlushBits(stream, 8 - shift);
    993                     return PV_SUCCESS;
    994                 }
    995                 PV_BitstreamFlushBits(stream, 8);    /* third_byte is not zero */
    996             }
    997         }
    998 
    999         PV_BitstreamFlushBits(stream, 8);
   1000     }
   1001 }
   1002