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 19 #include "ti_m4v_config_parser.h" 20 #include "oscl_mem.h" 21 #include "oscl_dll.h" 22 OSCL_DLL_ENTRY_POINT_DEFAULT() 23 24 #define PV_CLZ(A,B) while (((B) & 0x8000) == 0) {(B) <<=1; A++;} 25 26 static const uint32 mask[33] = 27 { 28 0x00000000, 0x00000001, 0x00000003, 0x00000007, 29 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 30 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, 31 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 32 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, 33 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, 34 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, 35 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, 36 0xffffffff 37 }; 38 39 int32 LocateFrameHeader(uint8 *ptr, int32 size) 40 { 41 int32 count = 0; 42 int32 i = size; 43 44 if (size < 1) 45 { 46 return 0; 47 } 48 while (i--) 49 { 50 if ((count > 1) && (*ptr == 0x01)) 51 { 52 i += 2; 53 break; 54 } 55 56 if (*ptr++) 57 count = 0; 58 else 59 count++; 60 } 61 return (size - (i + 1)); 62 } 63 64 void movePointerTo(mp4StreamType *psBits, int32 pos) 65 { 66 uint32 byte_pos; 67 if (pos < 0) 68 { 69 pos = 0; 70 } 71 72 byte_pos = pos >> 3; 73 74 if (byte_pos > (psBits->numBytes - psBits->bytePos)) 75 { 76 byte_pos = (psBits->numBytes - psBits->bytePos); 77 } 78 79 psBits->bytePos = byte_pos & -4; 80 psBits->dataBitPos = psBits->bytePos << 3; 81 FlushBits(psBits, ((pos & 0x7) + ((byte_pos & 0x3) << 3))); 82 } 83 84 int16 SearchNextM4VFrame(mp4StreamType *psBits) 85 { 86 int16 status = 0; 87 uint8 *ptr; 88 int32 i; 89 uint32 initial_byte_aligned_position = (psBits->dataBitPos + 7) >> 3; 90 91 ptr = psBits->data + initial_byte_aligned_position; 92 93 i = LocateFrameHeader(ptr, psBits->numBytes - initial_byte_aligned_position); 94 if (psBits->numBytes <= initial_byte_aligned_position + i) 95 { 96 status = -1; 97 } 98 (void)movePointerTo(psBits, ((i + initial_byte_aligned_position) << 3)); /* ptr + i */ 99 return status; 100 } 101 102 OSCL_EXPORT_REF int16 iGetM4VConfigInfo(uint8 *buffer, int32 length, int32 *width, int32 *height, int32 *display_width, int32 *display_height) 103 { 104 int16 status; 105 mp4StreamType psBits; 106 psBits.data = buffer; 107 psBits.numBytes = length; 108 psBits.bitBuf = 0; 109 psBits.bitPos = 32; 110 psBits.bytePos = 0; 111 psBits.dataBitPos = 0; 112 *width = *height = *display_height = *display_width = 0; 113 114 if (length == 0) 115 { 116 return MP4_INVALID_VOL_PARAM; 117 } 118 int32 profilelevel = 0; // dummy value discarded here 119 status = iDecodeVOLHeader(&psBits, width, height, display_width, display_height, &profilelevel); 120 return status; 121 } 122 123 // name: iDecodeVOLHeader 124 // Purpose: decode VOL header 125 // return: error code 126 OSCL_EXPORT_REF int16 iDecodeVOLHeader(mp4StreamType *psBits, int32 *width, int32 *height, int32 *display_width, int32 *display_height, int32 *profilelevel) 127 { 128 int16 iErrorStat; 129 uint32 codeword; 130 int32 time_increment_resolution, nbits_time_increment; 131 int32 i, j; 132 133 *profilelevel = 0x0000FFFF; // init to some invalid value. When this value is returned, then no profilelevel info is available 134 135 ShowBits(psBits, 32, &codeword); 136 137 if (codeword == VISUAL_OBJECT_SEQUENCE_START_CODE) 138 { 139 //DV: this is the wrong way to skip bits, use FLush or Read psBits->dataBitPos += 32; 140 ReadBits(psBits, 32, &codeword); // skip 32 bits of the Start code 141 142 ReadBits(psBits, 8, &codeword); 143 144 // record profile and level 145 *profilelevel = (int) codeword; 146 147 ShowBits(psBits, 32, &codeword); 148 if (codeword == USER_DATA_START_CODE) 149 { 150 iErrorStat = DecodeUserData(psBits); 151 if (iErrorStat) return MP4_INVALID_VOL_PARAM; 152 } 153 154 155 ReadBits(psBits, 32, &codeword); 156 if (codeword != VISUAL_OBJECT_START_CODE) return MP4_INVALID_VOL_PARAM; 157 158 /* is_visual_object_identifier */ 159 ReadBits(psBits, 1, &codeword); 160 161 if (codeword) 162 { 163 /* visual_object_verid */ 164 ReadBits(psBits, 4, &codeword); 165 /* visual_object_priority */ 166 ReadBits(psBits, 3, &codeword); 167 } 168 /* visual_object_type */ 169 ReadBits(psBits, 4, &codeword); 170 171 if (codeword == 1) 172 { /* video_signal_type */ 173 ReadBits(psBits, 1, &codeword); 174 if (codeword == 1) 175 { 176 /* video_format */ 177 ReadBits(psBits, 3, &codeword); 178 /* video_range */ 179 ReadBits(psBits, 1, &codeword); 180 /* color_description */ 181 ReadBits(psBits, 1, &codeword); 182 if (codeword == 1) 183 { 184 /* color_primaries */ 185 ReadBits(psBits, 8, &codeword);; 186 /* transfer_characteristics */ 187 ReadBits(psBits, 8, &codeword); 188 /* matrix_coefficients */ 189 ReadBits(psBits, 8, &codeword); 190 } 191 } 192 } 193 else 194 { 195 int16 status = 0; 196 do 197 { 198 /* Search for VOL_HEADER */ 199 status = SearchNextM4VFrame(psBits); /* search 0x00 0x00 0x01 */ 200 if (status != 0) 201 return MP4_INVALID_VOL_PARAM; 202 203 status = ReadBits(psBits, VOL_START_CODE_LENGTH, &codeword); 204 } 205 while ((codeword != VOL_START_CODE) && (status == 0)); 206 goto decode_vol; 207 } 208 /* next_start_code() */ 209 ByteAlign(psBits); 210 211 ShowBits(psBits, 32, &codeword); 212 if (codeword == USER_DATA_START_CODE) 213 { 214 iErrorStat = DecodeUserData(psBits); 215 if (iErrorStat) return MP4_INVALID_VOL_PARAM; 216 } 217 ShowBits(psBits, 27, &codeword); 218 } 219 else 220 { 221 ShowBits(psBits, 27, &codeword); 222 } 223 224 if (codeword == VO_START_CODE) 225 { 226 227 ReadBits(psBits, 32, &codeword); 228 229 /* video_object_layer_start_code */ 230 ReadBits(psBits, 28, &codeword); 231 if (codeword != VOL_START_CODE) 232 { 233 if (psBits->dataBitPos >= (psBits->numBytes << 3)) 234 { 235 return SHORT_HEADER_MODE; /* SH */ 236 } 237 else 238 { 239 int16 status = 0; 240 do 241 { 242 /* Search for VOL_HEADER */ 243 status = SearchNextM4VFrame(psBits); /* search 0x00 0x00 0x01 */ 244 if (status != 0) 245 return MP4_INVALID_VOL_PARAM; 246 247 status = ReadBits(psBits, VOL_START_CODE_LENGTH, &codeword); 248 } 249 while ((codeword != VOL_START_CODE) && (status == 0)); 250 goto decode_vol; 251 } 252 } 253 decode_vol: 254 255 uint32 vol_id; 256 257 /* vol_id (4 bits) */ 258 ReadBits(psBits, 4, & vol_id); 259 260 // RandomAccessibleVOLFlag 261 ReadBits(psBits, 1, &codeword); 262 263 //Video Object Type Indication 264 ReadBits(psBits, 8, &codeword); 265 if (codeword != 1) 266 { 267 //return MP4_INVALID_VOL_PARAM; //TI supports this feature 268 } 269 270 // is_object_layer_identifier 271 ReadBits(psBits, 1, &codeword); 272 273 if (codeword) 274 { 275 ReadBits(psBits, 4, &codeword); 276 ReadBits(psBits, 3, &codeword); 277 } 278 279 // aspect ratio 280 ReadBits(psBits, 4, &codeword); 281 282 if (codeword == 0xF) 283 { 284 // Extended Parameter 285 /* width */ 286 ReadBits(psBits, 8, &codeword); 287 /* height */ 288 ReadBits(psBits, 8, &codeword); 289 } 290 291 ReadBits(psBits, 1, &codeword); 292 293 if (codeword) 294 { 295 ReadBits(psBits, 2, &codeword); 296 if (codeword != 1) 297 { 298 return MP4_INVALID_VOL_PARAM; 299 } 300 301 ReadBits(psBits, 1, &codeword); 302 303 if (!codeword) 304 { 305 //return MP4_INVALID_VOL_PARAM; //TI supports this feature 306 } 307 308 ReadBits(psBits, 1, &codeword); 309 if (codeword) /* if (vbv_parameters) {}, page 36 */ 310 { 311 ReadBits(psBits, 15, &codeword); 312 ReadBits(psBits, 1, &codeword); 313 if (codeword != 1) 314 { 315 return MP4_INVALID_VOL_PARAM; 316 } 317 318 ReadBits(psBits, 15, &codeword); 319 ReadBits(psBits, 1, &codeword); 320 if (codeword != 1) 321 { 322 return MP4_INVALID_VOL_PARAM; 323 } 324 325 326 ReadBits(psBits, 19, &codeword); 327 if (!(codeword & 0x8)) 328 { 329 return MP4_INVALID_VOL_PARAM; 330 } 331 332 ReadBits(psBits, 11, &codeword); 333 ReadBits(psBits, 1, &codeword); 334 if (codeword != 1) 335 { 336 return MP4_INVALID_VOL_PARAM; 337 } 338 339 ReadBits(psBits, 15, &codeword); 340 ReadBits(psBits, 1, &codeword); 341 if (codeword != 1) 342 { 343 return MP4_INVALID_VOL_PARAM; 344 } 345 } 346 347 } 348 349 ReadBits(psBits, 2, &codeword); 350 351 if (codeword != 0) 352 { 353 return MP4_INVALID_VOL_PARAM; 354 } 355 356 ReadBits(psBits, 1, &codeword); 357 if (codeword != 1) 358 { 359 return MP4_INVALID_VOL_PARAM; 360 } 361 362 ReadBits(psBits, 16, &codeword); 363 time_increment_resolution = codeword; 364 365 366 ReadBits(psBits, 1, &codeword); 367 if (codeword != 1) 368 { 369 return MP4_INVALID_VOL_PARAM; 370 } 371 372 373 374 ReadBits(psBits, 1, &codeword); 375 376 if (codeword && time_increment_resolution > 2) 377 { 378 i = time_increment_resolution - 1; 379 j = 1; 380 while (i >>= 1) 381 { 382 j++; 383 } 384 nbits_time_increment = j; 385 386 ReadBits(psBits, nbits_time_increment, &codeword); 387 } 388 389 ReadBits(psBits, 1, &codeword); 390 if (codeword != 1) 391 { 392 return MP4_INVALID_VOL_PARAM; 393 } 394 395 /* this should be 176 for QCIF */ 396 ReadBits(psBits, 13, &codeword); 397 *display_width = (int32)codeword; 398 ReadBits(psBits, 1, &codeword); 399 if (codeword != 1) 400 { 401 return MP4_INVALID_VOL_PARAM; 402 } 403 404 /* this should be 144 for QCIF */ 405 ReadBits(psBits, 13, &codeword); 406 *display_height = (int32)codeword; 407 408 *width = (*display_width + 15) & -16; 409 *height = (*display_height + 15) & -16; 410 } 411 else 412 { 413 /* SHORT_HEADER */ 414 ShowBits(psBits, SHORT_VIDEO_START_MARKER_LENGTH, &codeword); 415 if (codeword == SHORT_VIDEO_START_MARKER) 416 { 417 iDecodeShortHeader(psBits, width, height, display_width, display_height); 418 } 419 else 420 { 421 int16 status = 0; 422 do 423 { 424 /* Search for VOL_HEADER */ 425 status = SearchNextM4VFrame(psBits); /* search 0x00 0x00 0x01 */ 426 if (status != 0) 427 { 428 return MP4_INVALID_VOL_PARAM; 429 } 430 431 status = ReadBits(psBits, VOL_START_CODE_LENGTH, &codeword); 432 } 433 while ((codeword != VOL_START_CODE) && (status == 0)); 434 goto decode_vol; 435 } 436 } 437 return 0; 438 } 439 440 441 442 OSCL_EXPORT_REF 443 int16 iDecodeShortHeader(mp4StreamType *psBits, 444 int32 *width, 445 int32 *height, 446 int32 *display_width, 447 int32 *display_height) 448 { 449 uint32 codeword; 450 int32 extended_PTYPE = 0; 451 int32 UFEP = 0; 452 int32 custom_PFMT = 0; 453 454 ShowBits(psBits, 22, &codeword); 455 456 if (codeword != 0x20) 457 { 458 return MP4_INVALID_VOL_PARAM; 459 } 460 FlushBits(psBits, 22); 461 ReadBits(psBits, 8, &codeword); 462 463 ReadBits(psBits, 1, &codeword); 464 if (codeword == 0) return MP4_INVALID_VOL_PARAM; 465 466 ReadBits(psBits, 1, &codeword); 467 if (codeword == 1) return MP4_INVALID_VOL_PARAM; 468 469 ReadBits(psBits, 1, &codeword); 470 if (codeword == 1) return MP4_INVALID_VOL_PARAM; 471 472 ReadBits(psBits, 1, &codeword); 473 if (codeword == 1) return MP4_INVALID_VOL_PARAM; 474 475 ReadBits(psBits, 1, &codeword); 476 if (codeword == 1) return MP4_INVALID_VOL_PARAM; 477 478 /* source format */ 479 ReadBits(psBits, 3, &codeword); 480 switch (codeword) 481 { 482 case 1: 483 *width = 128; 484 *height = 96; 485 break; 486 487 case 2: 488 *width = 176; 489 *height = 144; 490 break; 491 492 case 3: 493 *width = 352; 494 *height = 288; 495 break; 496 497 case 4: 498 *width = 704; 499 *height = 576; 500 break; 501 502 case 5: 503 *width = 1408; 504 *height = 1152; 505 break; 506 507 case 7: 508 extended_PTYPE = 1; 509 break; 510 default: 511 /* Msg("H.263 source format not legal\n"); */ 512 return MP4_INVALID_VOL_PARAM; 513 } 514 515 if (extended_PTYPE == 0) 516 { 517 *display_width = *width; 518 *display_height = *height; 519 return 0; 520 } 521 /* source format */ 522 ReadBits(psBits, 3, &codeword); 523 UFEP = codeword; 524 if (UFEP == 1) 525 { 526 ReadBits(psBits, 3, &codeword); 527 switch (codeword) 528 { 529 case 1: 530 *width = 128; 531 *height = 96; 532 break; 533 534 case 2: 535 *width = 176; 536 *height = 144; 537 break; 538 539 case 3: 540 *width = 352; 541 *height = 288; 542 break; 543 544 case 4: 545 *width = 704; 546 *height = 576; 547 break; 548 549 case 5: 550 *width = 1408; 551 *height = 1152; 552 break; 553 554 case 6: 555 custom_PFMT = 1; 556 break; 557 default: 558 /* Msg("H.263 source format not legal\n"); */ 559 return MP4_INVALID_VOL_PARAM; 560 } 561 if (custom_PFMT == 0) 562 { 563 *display_width = *width; 564 *display_height = *height; 565 return 0; 566 } 567 ReadBits(psBits, 1, &codeword); 568 ReadBits(psBits, 1, &codeword); 569 if (codeword) return MP4_INVALID_VOL_PARAM; 570 ReadBits(psBits, 1, &codeword); 571 if (codeword) return MP4_INVALID_VOL_PARAM; 572 ReadBits(psBits, 1, &codeword); 573 if (codeword) return MP4_INVALID_VOL_PARAM; 574 ReadBits(psBits, 3, &codeword); 575 ReadBits(psBits, 3, &codeword); 576 if (codeword) return MP4_INVALID_VOL_PARAM; /* RPS, ISD, AIV */ 577 ReadBits(psBits, 1, &codeword); 578 ReadBits(psBits, 4, &codeword); 579 if (codeword != 8) return MP4_INVALID_VOL_PARAM; 580 } 581 if (UFEP == 0 || UFEP == 1) 582 { 583 ReadBits(psBits, 3, &codeword); 584 if (codeword > 1) return MP4_INVALID_VOL_PARAM; 585 ReadBits(psBits, 1, &codeword); 586 if (codeword) return MP4_INVALID_VOL_PARAM; 587 ReadBits(psBits, 1, &codeword); 588 if (codeword) return MP4_INVALID_VOL_PARAM; 589 ReadBits(psBits, 1, &codeword); 590 ReadBits(psBits, 3, &codeword); 591 if (codeword != 1) return MP4_INVALID_VOL_PARAM; 592 } 593 else 594 { 595 return MP4_INVALID_VOL_PARAM; 596 } 597 ReadBits(psBits, 1, &codeword); 598 if (codeword) return MP4_INVALID_VOL_PARAM; /* CPM */ 599 if (custom_PFMT == 1 && UFEP == 1) 600 { 601 ReadBits(psBits, 4, &codeword); 602 if (codeword == 0) return MP4_INVALID_VOL_PARAM; 603 if (codeword == 0xf) 604 { 605 ReadBits(psBits, 8, &codeword); 606 ReadBits(psBits, 8, &codeword); 607 } 608 ReadBits(psBits, 9, &codeword); 609 *display_width = (codeword + 1) << 2; 610 *width = (*display_width + 15) & -16; 611 ReadBits(psBits, 1, &codeword); 612 if (codeword != 1) return MP4_INVALID_VOL_PARAM; 613 ReadBits(psBits, 9, &codeword); 614 if (codeword == 0) return MP4_INVALID_VOL_PARAM; 615 *display_height = codeword << 2; 616 *height = (*display_height + 15) & -16; 617 } 618 619 return 0; 620 } 621 622 623 int16 ShowBits( 624 mp4StreamType *pStream, /* Input Stream */ 625 uint8 ucNBits, /* nr of bits to read */ 626 uint32 *pulOutData /* output target */ 627 ) 628 { 629 uint8 *bits; 630 uint32 dataBitPos = pStream->dataBitPos; 631 uint32 bitPos = pStream->bitPos; 632 uint32 dataBytePos; 633 634 uint i; 635 636 if (ucNBits > (32 - bitPos)) /* not enough bits */ 637 { 638 dataBytePos = dataBitPos >> 3; /* Byte Aligned Position */ 639 bitPos = dataBitPos & 7; /* update bit position */ 640 if (dataBytePos > pStream->numBytes - 4) 641 { 642 pStream->bitBuf = 0; 643 for (i = 0;i < pStream->numBytes - dataBytePos;i++) 644 { 645 pStream->bitBuf |= pStream->data[dataBytePos+i]; 646 pStream->bitBuf <<= 8; 647 } 648 pStream->bitBuf <<= 8 * (3 - i); 649 } 650 else 651 { 652 bits = &pStream->data[dataBytePos]; 653 pStream->bitBuf = (bits[0] << 24) | (bits[1] << 16) | (bits[2] << 8) | bits[3]; 654 } 655 pStream->bitPos = bitPos; 656 } 657 658 bitPos += ucNBits; 659 660 *pulOutData = (pStream->bitBuf >> (32 - bitPos)) & mask[(uint16)ucNBits]; 661 662 663 return 0; 664 } 665 666 int16 FlushBits( 667 mp4StreamType *pStream, /* Input Stream */ 668 uint8 ucNBits /* number of bits to flush */ 669 ) 670 { 671 uint8 *bits; 672 uint32 dataBitPos = pStream->dataBitPos; 673 uint32 bitPos = pStream->bitPos; 674 uint32 dataBytePos; 675 676 677 if ((dataBitPos + ucNBits) > (uint32)(pStream->numBytes << 3)) 678 return (-2); // Buffer over run 679 680 dataBitPos += ucNBits; 681 bitPos += ucNBits; 682 683 if (bitPos > 32) 684 { 685 dataBytePos = dataBitPos >> 3; /* Byte Aligned Position */ 686 bitPos = dataBitPos & 7; /* update bit position */ 687 bits = &pStream->data[dataBytePos]; 688 pStream->bitBuf = (bits[0] << 24) | (bits[1] << 16) | (bits[2] << 8) | bits[3]; 689 } 690 691 pStream->dataBitPos = dataBitPos; 692 pStream->bitPos = bitPos; 693 694 return 0; 695 } 696 697 int16 ReadBits( 698 mp4StreamType *pStream, /* Input Stream */ 699 uint8 ucNBits, /* nr of bits to read */ 700 uint32 *pulOutData /* output target */ 701 ) 702 { 703 uint8 *bits; 704 uint32 dataBitPos = pStream->dataBitPos; 705 uint32 bitPos = pStream->bitPos; 706 uint32 dataBytePos; 707 708 709 if ((dataBitPos + ucNBits) > (pStream->numBytes << 3)) 710 { 711 *pulOutData = 0; 712 return (-2); // Buffer over run 713 } 714 715 // dataBitPos += ucNBits; 716 717 if (ucNBits > (32 - bitPos)) /* not enough bits */ 718 { 719 dataBytePos = dataBitPos >> 3; /* Byte Aligned Position */ 720 bitPos = dataBitPos & 7; /* update bit position */ 721 bits = &pStream->data[dataBytePos]; 722 pStream->bitBuf = (bits[0] << 24) | (bits[1] << 16) | (bits[2] << 8) | bits[3]; 723 } 724 725 pStream->dataBitPos += ucNBits; 726 pStream->bitPos = (unsigned char)(bitPos + ucNBits); 727 728 *pulOutData = (pStream->bitBuf >> (32 - pStream->bitPos)) & mask[(uint16)ucNBits]; 729 730 return 0; 731 } 732 733 734 735 int16 ByteAlign( 736 mp4StreamType *pStream /* Input Stream */ 737 ) 738 { 739 uint8 *bits; 740 uint32 dataBitPos = pStream->dataBitPos; 741 uint32 bitPos = pStream->bitPos; 742 uint32 dataBytePos; 743 uint32 leftBits; 744 745 leftBits = 8 - (dataBitPos & 0x7); 746 if (leftBits == 8) 747 { 748 if ((dataBitPos + 8) > (uint32)(pStream->numBytes << 3)) 749 return (-2); // Buffer over run 750 dataBitPos += 8; 751 bitPos += 8; 752 } 753 else 754 { 755 dataBytePos = dataBitPos >> 3; 756 dataBitPos += leftBits; 757 bitPos += leftBits; 758 } 759 760 761 if (bitPos > 32) 762 { 763 dataBytePos = dataBitPos >> 3; /* Byte Aligned Position */ 764 bits = &pStream->data[dataBytePos]; 765 pStream->bitBuf = (bits[0] << 24) | (bits[1] << 16) | (bits[2] << 8) | bits[3]; 766 } 767 768 pStream->dataBitPos = dataBitPos; 769 pStream->bitPos = bitPos; 770 771 return 0; 772 } 773 774 int16 DecodeUserData(mp4StreamType *pStream) 775 { 776 777 uint32 codeword; 778 int16 iErrorStat; 779 780 iErrorStat = ReadBits(pStream, 32, &codeword); 781 if (iErrorStat) return iErrorStat; 782 iErrorStat = ShowBits(pStream, 24, &codeword); 783 if (iErrorStat) return iErrorStat; 784 785 while (codeword != 1) 786 { 787 /* Discard user data for now. */ 788 iErrorStat = ReadBits(pStream, 8, &codeword); 789 if (iErrorStat) return iErrorStat; 790 iErrorStat = ShowBits(pStream, 24, &codeword); 791 if (iErrorStat) return iErrorStat; 792 } 793 return 0; 794 } 795 796 797 OSCL_EXPORT_REF int16 iGetAVCConfigInfo(uint8 *buffer, int32 length, int32 *width, int32 *height, int32 *display_width, int32 *display_height, int32 *profile_idc, int32 *level_idc, uint32 *entropy_coding_mode_flag) 798 { 799 int16 status; 800 mp4StreamType psBits; 801 uint16 sps_length, pps_length; 802 int32 size; 803 int32 i = 0; 804 uint8* sps = NULL; 805 uint8* temp = (uint8 *)OSCL_MALLOC(sizeof(uint8) * length); 806 uint8* pps = NULL; 807 808 809 if (temp) 810 { 811 sps = temp; // Make a copy of the original pointer to be freed later 812 // Successfull allocation... copy input buffer 813 oscl_memcpy(sps, buffer, length); 814 } 815 else 816 { 817 // Allocation failed 818 return MP4_INVALID_VOL_PARAM; 819 } 820 821 if (length < 3) 822 { 823 OSCL_FREE(temp); 824 return MP4_INVALID_VOL_PARAM; 825 } 826 827 *width = *height = *display_height = *display_width = 0; 828 829 if (sps[0] == 0 && sps[1] == 0) 830 { 831 /* find SC at the beginning of the NAL */ 832 while (sps[i++] == 0 && i < length) 833 { 834 } 835 836 if (sps[i-1] == 1) 837 { 838 sps += i; 839 840 sps_length = 0; 841 // search for the next start code 842 while (!(sps[sps_length] == 0 && sps[sps_length+1] == 0 && sps[sps_length+2] == 1) && 843 sps_length < length - i - 2) 844 { 845 sps_length++; 846 } 847 848 if (sps_length >= length - i - 2) 849 { 850 OSCL_FREE(temp); 851 return MP4_INVALID_VOL_PARAM; 852 } 853 854 pps_length = length - i - sps_length - 3; 855 pps = sps + sps_length + 3; 856 } 857 else 858 { 859 OSCL_FREE(temp); 860 return MP4_INVALID_VOL_PARAM; 861 } 862 } 863 else 864 { 865 sps_length = (uint16)(sps[1] << 8) | sps[0]; 866 sps += 2; 867 pps = sps + sps_length; 868 pps_length = (uint16)(pps[1] << 8) | pps[0]; 869 pps += 2; 870 } 871 872 if (sps_length + pps_length > length) 873 { 874 OSCL_FREE(temp); 875 return MP4_INVALID_VOL_PARAM; 876 } 877 878 size = sps_length; 879 880 Parser_EBSPtoRBSP(sps, &size); 881 882 psBits.data = sps; 883 psBits.numBytes = size; 884 psBits.bitBuf = 0; 885 psBits.bitPos = 32; 886 psBits.bytePos = 0; 887 psBits.dataBitPos = 0; 888 889 if (DecodeSPS(&psBits, width, height, display_width, display_height, profile_idc, level_idc)) 890 { 891 OSCL_FREE(temp); 892 return MP4_INVALID_VOL_PARAM; 893 } 894 895 // now do PPS 896 size = pps_length; 897 898 Parser_EBSPtoRBSP(pps, &size); 899 psBits.data = pps; 900 psBits.numBytes = size; 901 psBits.bitBuf = 0; 902 psBits.bitPos = 32; 903 psBits.bytePos = 0; 904 psBits.dataBitPos = 0; 905 906 status = DecodePPS(&psBits, entropy_coding_mode_flag); 907 908 OSCL_FREE(temp); 909 910 return status; 911 } 912 913 void scaling_list_h264(int32 i4_list_size, mp4StreamType *psBits) 914 { 915 int32 i4_j, i4_delta_scale, i4_lastScale = 8, i4_nextScale =8; 916 917 918 for(i4_j = 0; i4_j < i4_list_size; i4_j++) 919 { 920 if(i4_nextScale !=0) 921 { 922 se_v(psBits, &i4_delta_scale); 923 i4_nextScale = ((i4_lastScale + i4_delta_scale + 256) & 0xff); 924 925 } 926 i4_lastScale = (i4_nextScale == 0)? (i4_lastScale) : (i4_nextScale); 927 } 928 } 929 930 int16 DecodeSPS(mp4StreamType *psBits, int32 *width, int32 *height, int32 *display_width, int32 *display_height, int32 *profile_idc, int32 *level_idc) 931 { 932 uint32 temp; 933 int32 temp0; 934 uint left_offset, right_offset, top_offset, bottom_offset; 935 uint i; 936 c_bool highProfileDetected = false; 937 938 ReadBits(psBits, 8, &temp); 939 940 if ((temp & 0x1F) != 7) return MP4_INVALID_VOL_PARAM; 941 942 ReadBits(psBits, 8, &temp); 943 944 *profile_idc = temp; 945 946 ReadBits(psBits, 1, &temp); 947 ReadBits(psBits, 1, &temp); 948 ReadBits(psBits, 1, &temp); 949 ReadBits(psBits, 5, &temp); 950 ReadBits(psBits, 8, &temp); 951 952 *level_idc = temp; 953 954 if (temp > 51) 955 return MP4_INVALID_VOL_PARAM; 956 957 ue_v(psBits, &temp); 958 959 if(*profile_idc == H264_PROFILE_IDC_HIGH) 960 { 961 /* High Profile detected; additional parameters to be parsed */ 962 uint32 i4_chroma_format_idc, i4_bit_depth_luma_minus8, i4_bit_depth_chroma_minus8; 963 uint32 i4_seq_scaling_matrix_present_flag, i4_qpprime_y_zero_transform_bypass_flag; 964 965 highProfileDetected = true; 966 967 /* reading chroma_format_idc */ 968 ue_v(psBits, &i4_chroma_format_idc); 969 970 if(i4_chroma_format_idc != 1 ) 971 { 972 /* chroma_format_idc 1 represents 420. Other possibility is monochrome, not supported currently */ 973 return (-1); 974 } 975 976 /* reading bit_depth_luma_minus8 */ 977 ue_v(psBits, &i4_bit_depth_luma_minus8); 978 979 if(i4_bit_depth_luma_minus8 != 0) 980 { 981 /* only 8 bit supported, higher bit depth not supported */ 982 return (-1); 983 } 984 985 /* reading bit_depth_chroma_minus8 */ 986 ue_v(psBits, &i4_bit_depth_chroma_minus8); 987 988 if(i4_bit_depth_chroma_minus8 != 0) 989 { 990 /* only 8 bit supported, higher bit depth not supported */ 991 return (-1); 992 } 993 994 /* reading qpprime_y_zero_transform_bypass_flag */ 995 ReadBits(psBits, 1, &i4_qpprime_y_zero_transform_bypass_flag); 996 if(i4_qpprime_y_zero_transform_bypass_flag != 0) 997 { 998 return (-1); 999 } 1000 1001 /* reading seq_scaling_matrix_present_flag */ 1002 ReadBits(psBits, 1, &i4_seq_scaling_matrix_present_flag); 1003 1004 if(i4_seq_scaling_matrix_present_flag) 1005 { 1006 int32 i4_i; 1007 for(i4_i =0; i4_i < 8; i4_i++) 1008 { 1009 uint32 i4_scaling_list_present; 1010 ReadBits(psBits, 1, &i4_scaling_list_present); 1011 1012 if(i4_scaling_list_present) 1013 { 1014 if(i4_i < 6) 1015 { 1016 scaling_list_h264(16, psBits); 1017 } 1018 else 1019 { 1020 scaling_list_h264(64, psBits); 1021 } 1022 } 1023 } 1024 } 1025 } 1026 1027 ue_v(psBits, &temp); 1028 ue_v(psBits, &temp); 1029 1030 if (temp == 0) 1031 { 1032 ue_v(psBits, &temp); 1033 } 1034 else if (temp == 1) 1035 { 1036 ReadBits(psBits, 1, &temp); 1037 se_v(psBits, &temp0); 1038 se_v(psBits, &temp0); 1039 ue_v(psBits, &temp); 1040 1041 for (i = 0; i < temp; i++) 1042 { 1043 se_v(psBits, &temp0); 1044 } 1045 } 1046 ue_v(psBits, &temp); 1047 1048 1049 ReadBits(psBits, 1, &temp); 1050 ue_v(psBits, &temp); 1051 *display_width = *width = (temp + 1) << 4; 1052 ue_v(psBits, &temp); 1053 *display_height = *height = (temp + 1) << 4; 1054 1055 ReadBits(psBits, 1, &temp); 1056 if (!temp) 1057 { 1058 // we do not support if frame_mb_only_flag is off 1059 return MP4_INVALID_VOL_PARAM; 1060 //ReadBits(psBits,1, &temp); 1061 } 1062 1063 ReadBits(psBits, 1, &temp); 1064 1065 ReadBits(psBits, 1, &temp); 1066 1067 if (temp) 1068 { 1069 ue_v(psBits, (uint32*)&left_offset); 1070 ue_v(psBits, (uint32*)&right_offset); 1071 ue_v(psBits, (uint32*)&top_offset); 1072 ue_v(psBits, (uint32*)&bottom_offset); 1073 1074 *display_width = *width - 2 * (right_offset + left_offset); 1075 *display_height = *height - 2 * (top_offset + bottom_offset); 1076 } 1077 1078 /* no need to check further */ 1079 #if USE_LATER 1080 ReadBits(psBits, 1, &temp); 1081 if (temp) 1082 { 1083 if (!DecodeVUI(psBits)) 1084 { 1085 return MP4_INVALID_VOL_PARAM; 1086 } 1087 } 1088 #endif 1089 return 0; // return 0 for success 1090 } 1091 1092 #if USE_LATER 1093 /* unused for now */ 1094 int32 DecodeVUI(mp4StreamType *psBits) 1095 { 1096 uint temp; 1097 uint32 temp32; 1098 uint aspect_ratio_idc, overscan_appopriate_flag, video_format, video_full_range_flag; 1099 int32 status; 1100 1101 ReadBits(psBits, 1, &temp); /* aspect_ratio_info_present_flag */ 1102 if (temp) 1103 { 1104 ReadBits(psBits, 8, &aspect_ratio_idc); 1105 if (aspect_ratio_idc == 255) 1106 { 1107 ReadBits(psBits, 16, &temp); /* sar_width */ 1108 ReadBits(psBits, 16, &temp); /* sar_height */ 1109 } 1110 } 1111 ReadBits(psBits, 1, &temp); /* overscan_info_present */ 1112 if (temp) 1113 { 1114 ReadBits(psBits, 1, &overscan_appopriate_flag); 1115 } 1116 ReadBits(psBits, 1, &temp); /* video_signal_type_present_flag */ 1117 if (temp) 1118 { 1119 ReadBits(psBits, 3, &video_format); 1120 ReadBits(psBits, 1, &video_full_range_flag); 1121 ReadBits(psBits, 1, &temp); /* colour_description_present_flag */ 1122 if (temp) 1123 { 1124 ReadBits(psBits, 8, &temp); /* colour_primaries */ 1125 ReadBits(psBits, 8, &temp); /* transfer_characteristics */ 1126 ReadBits(psBits, 8, &temp); /* matrix coefficients */ 1127 } 1128 } 1129 ReadBits(psBits, 1, &temp);/* chroma_loc_info_present_flag */ 1130 if (temp) 1131 { 1132 ue_v(psBits, &temp); /* chroma_sample_loc_type_top_field */ 1133 ue_v(psBits, &temp); /* chroma_sample_loc_type_bottom_field */ 1134 } 1135 1136 ReadBits(psBits, 1, &temp); /* timing_info_present_flag*/ 1137 if (temp) 1138 { 1139 ReadBits(psBits, 32, &temp32); /* num_unit_in_tick*/ 1140 ReadBits(psBits, 32, &temp32); /* time_scale */ 1141 ReadBits(psBits, 1, &temp); /* fixed_frame_rate_flag */ 1142 } 1143 1144 ReadBits(psBits, 1, &temp); /* nal_hrd_parameters_present_flag */ 1145 if (temp) 1146 { 1147 if (!DecodeHRD(psBits)) 1148 { 1149 return 1; 1150 } 1151 } 1152 ReadBits(psBits, 1, &temp32); /* vcl_hrd_parameters_present_flag*/ 1153 if (temp32) 1154 { 1155 if (!DecodeHRD(psBits)) 1156 { 1157 return 1; 1158 } 1159 } 1160 if (temp || temp32) 1161 { 1162 ReadBits(psBits, 1, &temp); /* low_delay_hrd_flag */ 1163 } 1164 ReadBits(psBits, 1, &temp); /* pic_struct_present_flag */ 1165 status = ReadBits(psBits, 1, &temp); /* _restriction_flag */ 1166 if (status != 0) // buffer overrun 1167 { 1168 return 1; 1169 } 1170 1171 if (temp) 1172 { 1173 ReadBits(psBits, 1, &temp); /* motion_vectors_over_pic_boundaries_flag */ 1174 ue_v(psBits, &temp); /* max_bytes_per_pic_denom */ 1175 ue_v(psBits, &temp); /* max_bits_per_mb_denom */ 1176 ue_v(psBits, &temp); /* log2_max_mv_length_horizontal */ 1177 ue_v(psBits, &temp); /* log2_max_mv_length_vertical */ 1178 ue_v(psBits, &temp); /* num_reorder_frames */ 1179 ue_v(psBits, &temp); /* max_dec_frame_buffering */ 1180 } 1181 1182 return 0; // 0 for success 1183 } 1184 1185 /* unused for now */ 1186 int32 DecodeHRD(mp4StreamType *psBits) 1187 { 1188 uint temp; 1189 uint cpb_cnt_minus1; 1190 uint i; 1191 int32 status; 1192 1193 ue_v(psBits, &cpb_cnt_minus1); 1194 ReadBits(psBits, 4, &temp); /* bit_rate_scale */ 1195 ReadBits(psBits, 4, &temp); /* cpb_size_scale */ 1196 for (i = 0; i <= cpb_cnt_minus1; i++) 1197 { 1198 ue_v(psBits, &temp); /* bit_rate_value_minus1[i] */ 1199 ue_v(psBits, &temp); /* cpb_size_value_minus1[i] */ 1200 ue_v(psBits, &temp); /* cbr_flag[i] */ 1201 } 1202 ReadBits(psBits, 5, &temp); /* initial_cpb_removal_delay_length_minus1 */ 1203 ReadBits(psBits, 5, &temp); /* cpb_removal_delay_length_minus1 */ 1204 ReadBits(psBits, 5, &temp); /* dpb_output_delay_length_minus1 */ 1205 status = ReadBits(psBits, 5, &temp); /* time_offset_length */ 1206 1207 if (status != 0) // buffer overrun 1208 { 1209 return 1; 1210 } 1211 1212 return 0; // 0 for success 1213 } 1214 #endif 1215 1216 // only check for entropy coding mode 1217 int32 DecodePPS(mp4StreamType *psBits, uint32 *entropy_coding_mode_flag) 1218 { 1219 uint32 temp, pic_parameter_set_id, seq_parameter_set_id; 1220 1221 ReadBits(psBits, 8, &temp); 1222 1223 if ((temp & 0x1F) != 8) return MP4_INVALID_VOL_PARAM; 1224 1225 ue_v(psBits, &pic_parameter_set_id); 1226 ue_v(psBits, &seq_parameter_set_id); 1227 1228 ReadBits(psBits, 1, entropy_coding_mode_flag); 1229 1230 return 0; 1231 } 1232 1233 void ue_v(mp4StreamType *psBits, uint32 *codeNum) 1234 { 1235 uint32 temp; 1236 uint tmp_cnt; 1237 int32 leading_zeros = 0; 1238 ShowBits(psBits, 16, &temp); 1239 tmp_cnt = temp | 0x1; 1240 1241 PV_CLZ(leading_zeros, tmp_cnt) 1242 1243 if (leading_zeros < 8) 1244 { 1245 *codeNum = (temp >> (15 - (leading_zeros << 1))) - 1; 1246 FlushBits(psBits, (leading_zeros << 1) + 1); 1247 } 1248 else 1249 { 1250 ReadBits(psBits, (leading_zeros << 1) + 1, &temp); 1251 *codeNum = temp - 1; 1252 } 1253 1254 } 1255 1256 1257 void se_v(mp4StreamType *psBits, int32 *value) 1258 { 1259 int32 leadingZeros = 0; 1260 uint32 temp; 1261 1262 OSCL_UNUSED_ARG(value); 1263 1264 ReadBits(psBits, 1, &temp); 1265 while (!temp) 1266 { 1267 leadingZeros++; 1268 if (ReadBits(psBits, 1, &temp)) 1269 { 1270 break; 1271 } 1272 } 1273 ReadBits(psBits, leadingZeros, &temp); 1274 } 1275 1276 void Parser_EBSPtoRBSP(uint8 *nal_unit, int32 *size) 1277 { 1278 int32 i, j; 1279 int32 count = 0; 1280 1281 1282 for (i = 0; i < *size; i++) 1283 { 1284 if (count == 2 && nal_unit[i] == 0x03) 1285 { 1286 break; 1287 } 1288 1289 if (nal_unit[i]) 1290 count = 0; 1291 else 1292 count++; 1293 } 1294 1295 count = 0; 1296 j = i++; 1297 for (;i < *size; i++) 1298 { 1299 if (count == 2 && nal_unit[i] == 0x03) 1300 { 1301 i++; 1302 count = 0; 1303 } 1304 nal_unit[j] = nal_unit[i]; 1305 if (nal_unit[i]) 1306 count = 0; 1307 else 1308 count++; 1309 j++; 1310 } 1311 1312 *size = j; 1313 } 1314 1315 1316 1317