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 /* ======================================================================== */ 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 /* ======================================================================== */ 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 /* ======================================================================== */ 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 /* ======================================================================== */ 163 void BitstreamClose(BitstreamDecVideo *) 164 { 165 return; 166 } 167 168 169 /***********************************************************CommentBegin****** 170 * 171 * -- BitstreamShowBits32HC 172 * Shows 32 bits 173 ***********************************************************CommentEnd********/ 174 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********/ 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 /* =========================================================================*/ 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 /* =========================================================================*/ 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 /* =========================================================================*/ 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 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 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 /* ======================================================================== */ 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 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 /* ======================================================================== */ 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 /* ======================================================================== */ 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 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 /* ======================================================================== */ 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 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 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 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 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 /* ==================================================================== */ 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 / ====================================================================== */ 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 /* ======================================================================== */ 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 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 /* ======================================================================== */ 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 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 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 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 /* ======================================================================== */ 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 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 /* ======================================================================== */ 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 /* ======================================================================== */ 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 /* ======================================================================== */ 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