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 PV_STATUS PVLocateM4VFrameBoundary(BitstreamDecVideo *stream)
653 {
654 PV_STATUS status = BitstreamCheckEndBuffer(stream);
655 if (status == PV_END_OF_VOP) return status;
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 return PV_SUCCESS;
665 }
666
PVLocateH263FrameBoundary(BitstreamDecVideo * stream)667 PV_STATUS PVLocateH263FrameBoundary(BitstreamDecVideo *stream)
668 {
669 PV_STATUS status = BitstreamCheckEndBuffer(stream);
670 if (status == PV_END_OF_VOP) return status;
671
672 uint8 *ptr;
673 int32 byte_pos = (stream->bitcnt >> 3);
674
675 stream->searched_frame_boundary = 1;
676 ptr = stream->bitstreamBuffer + byte_pos;
677
678 stream->data_end_pos = PVLocateH263FrameHeader(ptr, (int32)stream->data_end_pos - byte_pos) + byte_pos;
679 return PV_SUCCESS;
680 }
681
682 /* ======================================================================== */
683 /* Function : quickSearchVideoPacketHeader() */
684 /* Date : 05/08/2000 */
685 /* Purpose : Quick search for the next video packet header */
686 /* In/out : */
687 /* Return : PV_TRUE if successed, PV_FALSE if failed. */
688 /* Modified : */
689 /* ======================================================================== */
quickSearchVideoPacketHeader(BitstreamDecVideo * stream,int marker_length)690 PV_STATUS quickSearchVideoPacketHeader(BitstreamDecVideo *stream, int marker_length)
691 {
692 PV_STATUS status = PV_SUCCESS;
693 uint32 tmpvar;
694
695
696 if (stream->searched_frame_boundary == 0)
697 {
698 status = PVLocateM4VFrameBoundary(stream);
699 if (status != PV_SUCCESS) return status;
700 }
701
702 do
703 {
704 status = BitstreamCheckEndBuffer(stream);
705 if (status == PV_END_OF_VOP) break;
706 PV_BitstreamShowBitsByteAlign(stream, marker_length, &tmpvar);
707 if (tmpvar == RESYNC_MARKER) break;
708 PV_BitstreamFlushBits(stream, 8);
709 }
710 while (status == PV_SUCCESS);
711
712 return status;
713 }
714 #ifdef PV_ANNEX_IJKT_SUPPORT
quickSearchH263SliceHeader(BitstreamDecVideo * stream)715 PV_STATUS quickSearchH263SliceHeader(BitstreamDecVideo *stream)
716 {
717 PV_STATUS status = PV_SUCCESS;
718 uint32 tmpvar;
719
720
721 if (stream->searched_frame_boundary == 0)
722 {
723 status = PVLocateH263FrameBoundary(stream);
724 if (status != PV_SUCCESS) return status;
725 }
726
727 do
728 {
729 status = BitstreamCheckEndBuffer(stream);
730 if (status == PV_END_OF_VOP) break;
731 PV_BitstreamShowBitsByteAlignNoForceStuffing(stream, 17, &tmpvar);
732 if (tmpvar == RESYNC_MARKER) break;
733 PV_BitstreamFlushBits(stream, 8);
734 }
735 while (status == PV_SUCCESS);
736
737 return status;
738 }
739 #endif
740 /* ======================================================================== */
741 /* The following functions are for Error Concealment. */
742 /* ======================================================================== */
743
744 /****************************************************/
745 // 01/22/99 Quick search of Resync Marker
746 // (actually the first part of it, i.e. 16 0's and a 1.
747
748 /* We are not using the fastest algorithm possible. What this function does is
749 to locate 11 consecutive 0's and then check if the 5 bits before them and
750 the 1 bit after them are all 1's.
751 */
752
753 // Table used for quick search of markers. Gives the last `1' in
754 // 4 bits. The MSB is bit #1, the LSB is bit #4.
755 const int lastOne[] =
756 {
757 0, 4, 3, 4, 2, 4, 3, 4,
758 1, 4, 3, 4, 2, 4, 3, 4
759 };
760
761 // Table used for quick search of markers. Gives the last `0' in
762 // 4 bits. The MSB is bit #1, the LSB is bit #4.
763 /*const int lastZero[]=
764 {
765 4, 3, 4, 2, 4, 3, 4, 1,
766 4, 3, 4, 2, 4, 3, 4, 0
767 };
768 */
769 // Table used for quick search of markers. Gives the first `0' in
770 // 4 bits. The MSB is bit #1, the LSB is bit #4.
771 const int firstZero[] =
772 {
773 1, 1, 1, 1, 1, 1, 1, 1,
774 2, 2, 2, 2, 3, 3, 4, 0
775 };
776
777 // Table used for quick search of markers. Gives the first `1' in
778 // 4 bits. The MSB is bit #1, the LSB is bit #4.
779 const int firstOne[] =
780 {
781 0, 4, 3, 3, 2, 2, 2, 2,
782 1, 1, 1, 1, 1, 1, 1, 1
783 };
784
785
786 /* ======================================================================== */
787 /* Function : quickSearchMarkers() */
788 /* Date : 01/25/99 */
789 /* Purpose : Quick search for Motion marker */
790 /* In/out : */
791 /* Return : Boolean true of false */
792 /* Modified : 12/18/2000 : 32-bit version */
793 /* ======================================================================== */
quickSearchMotionMarker(BitstreamDecVideo * stream)794 PV_STATUS quickSearchMotionMarker(BitstreamDecVideo *stream)
795 // MM: (11111000000000001)
796 {
797 PV_STATUS status;
798 uint32 tmpvar, tmpvar2;
799
800 if (stream->searched_frame_boundary == 0)
801 {
802 status = PVLocateM4VFrameBoundary(stream);
803 if (status != PV_SUCCESS) return status;
804 }
805
806 while (TRUE)
807 {
808 status = BitstreamCheckEndBuffer(stream);
809 if (status == PV_END_OF_VOP) return PV_END_OF_VOP;
810
811 BitstreamShowBits32(stream, 17, &tmpvar);
812 if (!tmpvar) return PV_FAIL;
813
814 if (tmpvar & 1) // Check if the 17th bit from the curr bit pos is a '1'
815 {
816 if (tmpvar == MOTION_MARKER_COMB)
817 {
818 return PV_SUCCESS; // Found
819 }
820 else
821 {
822 tmpvar >>= 1;
823 tmpvar &= 0xF;
824 PV_BitstreamFlushBits(stream, (int)(12 + firstZero[tmpvar]));
825 }
826 }
827 else
828 {
829 // 01/25/99 Get the first 16 bits
830 tmpvar >>= 1;
831 tmpvar2 = tmpvar & 0xF;
832
833 // 01/26/99 Check bits #13 ~ #16
834 if (tmpvar2)
835 {
836 PV_BitstreamFlushBits(stream, (int)(7 + lastOne[tmpvar2]));
837 }
838 else
839 {
840 tmpvar >>= 4;
841 tmpvar2 = tmpvar & 0xF;
842
843 // 01/26/99 Check bits #9 ~ #12
844 if (tmpvar2)
845 {
846 PV_BitstreamFlushBits(stream, (int)(3 + lastOne[tmpvar2]));
847 }
848 else
849 {
850 tmpvar >>= 4;
851 tmpvar2 = tmpvar & 0xF;
852
853 // 01/26/99 Check bits #5 ~ #8
854 // We don't need to check further
855 // for the first 5 bits should be all 1's
856 if (lastOne[tmpvar2] < 2)
857 {
858 /* we already have too many consecutive 0's. */
859 /* Go directly pass the last of the 17 bits. */
860 PV_BitstreamFlushBits(stream, 17);
861 }
862 else
863 {
864 PV_BitstreamFlushBits(stream, (int)(lastOne[tmpvar2] - 1));
865 }
866 }
867 }
868 }
869
870 }
871 }
872
873 /* ======================================================================== */
874 /* Function : quickSearchDCM() */
875 /* Date : 01/22/99 */
876 /* Purpose : Quick search for DC Marker */
877 /* We are not using the fastest algorithm possible. What this */
878 /* function does is to locate 11 consecutive 0's and then */
879 /* check if the 7 bits before them and the 1 bit after them */
880 /* are correct. (actually the first part of it, i.e. 16 0's */
881 /* and a 1. */
882 /* In/out : */
883 /* Return : Boolean true of false */
884 /* Modified : 12/18/2000 : 32-bit version */
885 /* ======================================================================== */
quickSearchDCM(BitstreamDecVideo * stream)886 PV_STATUS quickSearchDCM(BitstreamDecVideo *stream)
887 // DCM: (110 1011 0000 0000 0001)
888 {
889 PV_STATUS status;
890 uint32 tmpvar, tmpvar2;
891
892 if (stream->searched_frame_boundary == 0)
893 {
894 status = PVLocateM4VFrameBoundary(stream);
895 if (status != PV_SUCCESS) return status;
896 }
897
898 while (TRUE)
899 {
900 status = BitstreamCheckEndBuffer(stream);
901 if (status == PV_END_OF_VOP) return PV_END_OF_VOP;
902 BitstreamShowBits32(stream, 19, &tmpvar);
903
904 if (tmpvar & 1) // Check if the 17th bit from the curr bit pos is a '1'
905 {
906 if (tmpvar == DC_MARKER)
907 {
908 return PV_SUCCESS; // Found
909 }
910 else
911 {
912 // 01/25/99 We treat the last of the 19 bits as its 7th bit (which is
913 // also a `1'
914 PV_BitstreamFlushBits(stream, 12);
915 }
916 }
917 else
918 {
919 tmpvar >>= 1;
920 tmpvar2 = tmpvar & 0xF;
921
922 if (tmpvar2)
923 {
924 PV_BitstreamFlushBits(stream, (int)(7 + lastOne[tmpvar2]));
925 }
926 else
927 {
928 tmpvar >>= 4;
929 tmpvar2 = tmpvar & 0xF;
930 if (tmpvar2)
931 {
932 PV_BitstreamFlushBits(stream, (int)(3 + lastOne[tmpvar2]));
933 }
934 else
935 {
936 tmpvar >>= 4;
937 tmpvar2 = tmpvar & 0xF;
938 if (lastOne[tmpvar2] < 2)
939 {
940 /* we already have too many consecutive 0's. */
941 /* Go directly pass the last of the 17 bits. */
942 PV_BitstreamFlushBits(stream, 19);
943 }
944 else
945 {
946 PV_BitstreamFlushBits(stream, (int)(lastOne[tmpvar2] - 1));
947 }
948 }
949 }
950 }
951 }
952 }
953
954 /* ======================================================================== */
955 /* Function : quickSearchGOBHeader() 0000 0000 0000 0000 1 */
956 /* Date : 07/06/01 */
957 /* Purpose : Quick search of GOBHeader (not byte aligned) */
958 /* In/out : */
959 /* Return : Integer value indicates type of marker found */
960 /* Modified : */
961 /* ======================================================================== */
quickSearchGOBHeader(BitstreamDecVideo * stream)962 PV_STATUS quickSearchGOBHeader(BitstreamDecVideo *stream)
963 {
964 PV_STATUS status;
965 int byte0, byte1, byte2, shift, tmpvar;
966
967 BitstreamByteAlignNoForceStuffing(stream);
968
969 if (stream->searched_frame_boundary == 0)
970 {
971 status = PVLocateH263FrameBoundary(stream);
972 if (status != PV_SUCCESS) return status;
973 }
974
975 while (TRUE)
976 {
977 status = BitstreamCheckEndBuffer(stream);
978 if (status == PV_END_OF_VOP) return PV_END_OF_VOP;
979
980 if (stream->incnt < 24)
981 {
982 status = BitstreamFillCache(stream);
983 }
984
985
986 byte1 = (stream->curr_word << 8) >> 24;
987 if (byte1 == 0)
988 {
989 byte2 = (stream->curr_word << 16) >> 24;
990 if (byte2)
991 {
992 tmpvar = byte2 >> 4;
993
994 if (tmpvar)
995 {
996 shift = 9 - firstOne[tmpvar];
997 }
998 else
999 {
1000 shift = 5 - firstOne[byte2];
1001 }
1002 byte0 = stream->curr_word >> 24;
1003 if ((byte0 & msk[shift]) == 0)
1004 {
1005 PV_BitstreamFlushBits(stream, 8 - shift);
1006 return PV_SUCCESS;
1007 }
1008 PV_BitstreamFlushBits(stream, 8); /* third_byte is not zero */
1009 }
1010 }
1011
1012 PV_BitstreamFlushBits(stream, 8);
1013 }
1014 }
1015