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