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 /* ======================================================================== */
BitstreamFillCache(BitstreamDecVideo * stream)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 /* ======================================================================== */
BitstreamReset(BitstreamDecVideo * stream,uint8 * buffer,int32 buffer_size)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 /* ======================================================================== */
BitstreamOpen(BitstreamDecVideo * stream,int)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 /* ======================================================================== */
BitstreamClose(BitstreamDecVideo *)163 void BitstreamClose(BitstreamDecVideo *)
164 {
165     return;
166 }
167 
168 
169 /***********************************************************CommentBegin******
170 *
171 * -- BitstreamShowBits32HC
172 * Shows 32 bits
173 ***********************************************************CommentEnd********/
174 
BitstreamShowBits32HC(BitstreamDecVideo * stream,uint32 * code)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********/
BitstreamShowBits32(BitstreamDecVideo * stream,int nbits,uint32 * code)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 /* =========================================================================*/
BitstreamShowBits16(BitstreamDecVideo * stream,int nbits,uint * code)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 /* =========================================================================*/
BitstreamShow15Bits(BitstreamDecVideo * stream,uint * code)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 /* =========================================================================*/
BitstreamShow13Bits(BitstreamDecVideo * stream,uint * code)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 
BitstreamReadBits16_INLINE(BitstreamDecVideo * stream,int nbits)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 
BitstreamRead1Bits_INLINE(BitstreamDecVideo * stream)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 /* ======================================================================== */
BitstreamReadBits16(BitstreamDecVideo * stream,int nbits)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 
BitstreamRead1Bits(BitstreamDecVideo * stream)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 /* ======================================================================== */
PV_BitstreamFlushBitsCheck(BitstreamDecVideo * stream,int nbits)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 /* ======================================================================== */
BitstreamReadBits32(BitstreamDecVideo * stream,int nbits)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 
BitstreamReadBits32HC(BitstreamDecVideo * stream)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 /* ======================================================================== */
BitstreamCheckEndBuffer(BitstreamDecVideo * stream)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 
PV_BitstreamShowBitsByteAlign(BitstreamDecVideo * stream,int nbits,uint32 * code)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
PV_BitstreamShowBitsByteAlignNoForceStuffing(BitstreamDecVideo * stream,int nbits,uint32 * code)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 
PV_BitstreamByteAlign(BitstreamDecVideo * stream)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 
BitstreamByteAlignNoForceStuffing(BitstreamDecVideo * stream)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 /* ==================================================================== */
getPointer(BitstreamDecVideo * stream)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 / ====================================================================== */
movePointerTo(BitstreamDecVideo * stream,int32 pos)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 /* ======================================================================== */
validStuffing(BitstreamDecVideo * stream)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
validStuffing_h263(BitstreamDecVideo * stream)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 /* ======================================================================== */
PVSearchNextH263Frame(BitstreamDecVideo * stream)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 
PVSearchNextM4VFrame(BitstreamDecVideo * stream)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 
PVLocateM4VFrameBoundary(BitstreamDecVideo * stream)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 
PVLocateH263FrameBoundary(BitstreamDecVideo * stream)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 /* ======================================================================== */
quickSearchVideoPacketHeader(BitstreamDecVideo * stream,int marker_length)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
quickSearchH263SliceHeader(BitstreamDecVideo * stream)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 /* ======================================================================== */
quickSearchMotionMarker(BitstreamDecVideo * stream)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 /* ======================================================================== */
quickSearchDCM(BitstreamDecVideo * stream)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 /* ======================================================================== */
quickSearchGOBHeader(BitstreamDecVideo * stream)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