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 */ 24static 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/* ======================================================================== */ 49PV_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/* ======================================================================== */ 124void 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/* ======================================================================== */ 140int 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/* ======================================================================== */ 163void BitstreamClose(BitstreamDecVideo *) 164{ 165 return; 166} 167 168 169/***********************************************************CommentBegin****** 170* 171* -- BitstreamShowBits32HC 172* Shows 32 bits 173***********************************************************CommentEnd********/ 174 175PV_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********/ 193PV_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/* =========================================================================*/ 215PV_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/* =========================================================================*/ 238PV_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/* =========================================================================*/ 257PV_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 270uint 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 286uint 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/* ======================================================================== */ 311uint 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 333uint 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/* ======================================================================== */ 355PV_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/* ======================================================================== */ 382uint32 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 396uint32 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/* ======================================================================== */ 415PV_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 422PV_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 441PV_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 460PV_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 487PV_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/* ==================================================================== */ 513int32 getPointer(BitstreamDecVideo *stream) 514{ 515 return stream->bitcnt; 516} 517 518 519 520 521/* ====================================================================== / 522Function : movePointerTo() 523Date : 05/14/2004 524Purpose : move bitstream pointer to a desired position 525In/out : 526Return : 527Modified : 528/ ====================================================================== */ 529PV_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/* ======================================================================== */ 565Bool 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 577Bool 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/* ======================================================================== */ 603PV_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 632PV_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 652void 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 663void 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/* ======================================================================== */ 682PV_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 706PV_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 739to locate 11 consecutive 0's and then check if the 5 bits before them and 740the 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. 745const 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. 761const 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. 769const 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/* ======================================================================== */ 784PV_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/* ======================================================================== */ 875PV_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/* ======================================================================== */ 950PV_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