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