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