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