TSPacketizer.cpp revision c6920dfdca378a168a2168f4a64d21af4d37d539
1/* 2 * Copyright 2012, The Android Open Source Project 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 express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17//#define LOG_NDEBUG 0 18#define LOG_TAG "TSPacketizer" 19#include <utils/Log.h> 20 21#include "TSPacketizer.h" 22#include "include/avc_utils.h" 23 24#include <media/stagefright/foundation/ABuffer.h> 25#include <media/stagefright/foundation/ADebug.h> 26#include <media/stagefright/foundation/AMessage.h> 27#include <media/stagefright/foundation/hexdump.h> 28#include <media/stagefright/MediaDefs.h> 29#include <media/stagefright/MediaErrors.h> 30 31#include <arpa/inet.h> 32 33namespace android { 34 35struct TSPacketizer::Track : public RefBase { 36 Track(const sp<AMessage> &format, 37 unsigned PID, unsigned streamType, unsigned streamID); 38 39 unsigned PID() const; 40 unsigned streamType() const; 41 unsigned streamID() const; 42 43 // Returns the previous value. 44 unsigned incrementContinuityCounter(); 45 46 bool isAudio() const; 47 bool isVideo() const; 48 49 bool isH264() const; 50 bool lacksADTSHeader() const; 51 52 sp<ABuffer> prependCSD(const sp<ABuffer> &accessUnit) const; 53 sp<ABuffer> prependADTSHeader(const sp<ABuffer> &accessUnit) const; 54 55protected: 56 virtual ~Track(); 57 58private: 59 sp<AMessage> mFormat; 60 61 unsigned mPID; 62 unsigned mStreamType; 63 unsigned mStreamID; 64 unsigned mContinuityCounter; 65 66 AString mMIME; 67 Vector<sp<ABuffer> > mCSD; 68 69 bool mAudioLacksATDSHeaders; 70 71 DISALLOW_EVIL_CONSTRUCTORS(Track); 72}; 73 74TSPacketizer::Track::Track( 75 const sp<AMessage> &format, 76 unsigned PID, unsigned streamType, unsigned streamID) 77 : mFormat(format), 78 mPID(PID), 79 mStreamType(streamType), 80 mStreamID(streamID), 81 mContinuityCounter(0), 82 mAudioLacksATDSHeaders(false) { 83 CHECK(format->findString("mime", &mMIME)); 84 85 if (!strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_VIDEO_AVC) 86 || !strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) { 87 for (size_t i = 0;; ++i) { 88 sp<ABuffer> csd; 89 if (!format->findBuffer(StringPrintf("csd-%d", i).c_str(), &csd)) { 90 break; 91 } 92 93 mCSD.push(csd); 94 } 95 96 if (!strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) { 97 int32_t isADTS; 98 if (!mFormat->findInt32("is-adts", &isADTS) || isADTS == 0) { 99 mAudioLacksATDSHeaders = true; 100 } 101 } 102 } 103} 104 105TSPacketizer::Track::~Track() { 106} 107 108unsigned TSPacketizer::Track::PID() const { 109 return mPID; 110} 111 112unsigned TSPacketizer::Track::streamType() const { 113 return mStreamType; 114} 115 116unsigned TSPacketizer::Track::streamID() const { 117 return mStreamID; 118} 119 120unsigned TSPacketizer::Track::incrementContinuityCounter() { 121 unsigned prevCounter = mContinuityCounter; 122 123 if (++mContinuityCounter == 16) { 124 mContinuityCounter = 0; 125 } 126 127 return prevCounter; 128} 129 130bool TSPacketizer::Track::isAudio() const { 131 return !strncasecmp("audio/", mMIME.c_str(), 6); 132} 133 134bool TSPacketizer::Track::isVideo() const { 135 return !strncasecmp("video/", mMIME.c_str(), 6); 136} 137 138bool TSPacketizer::Track::isH264() const { 139 return !strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_VIDEO_AVC); 140} 141 142bool TSPacketizer::Track::lacksADTSHeader() const { 143 return mAudioLacksATDSHeaders; 144} 145 146sp<ABuffer> TSPacketizer::Track::prependCSD( 147 const sp<ABuffer> &accessUnit) const { 148 size_t size = 0; 149 for (size_t i = 0; i < mCSD.size(); ++i) { 150 size += mCSD.itemAt(i)->size(); 151 } 152 153 sp<ABuffer> dup = new ABuffer(accessUnit->size() + size); 154 size_t offset = 0; 155 for (size_t i = 0; i < mCSD.size(); ++i) { 156 const sp<ABuffer> &csd = mCSD.itemAt(i); 157 158 memcpy(dup->data() + offset, csd->data(), csd->size()); 159 offset += csd->size(); 160 } 161 162 memcpy(dup->data() + offset, accessUnit->data(), accessUnit->size()); 163 164 return dup; 165} 166 167sp<ABuffer> TSPacketizer::Track::prependADTSHeader( 168 const sp<ABuffer> &accessUnit) const { 169 CHECK_EQ(mCSD.size(), 1u); 170 171 const uint8_t *codec_specific_data = mCSD.itemAt(0)->data(); 172 173 const uint32_t aac_frame_length = accessUnit->size() + 7; 174 175 sp<ABuffer> dup = new ABuffer(aac_frame_length); 176 177 unsigned profile = (codec_specific_data[0] >> 3) - 1; 178 179 unsigned sampling_freq_index = 180 ((codec_specific_data[0] & 7) << 1) 181 | (codec_specific_data[1] >> 7); 182 183 unsigned channel_configuration = 184 (codec_specific_data[1] >> 3) & 0x0f; 185 186 uint8_t *ptr = dup->data(); 187 188 *ptr++ = 0xff; 189 *ptr++ = 0xf1; // b11110001, ID=0, layer=0, protection_absent=1 190 191 *ptr++ = 192 profile << 6 193 | sampling_freq_index << 2 194 | ((channel_configuration >> 2) & 1); // private_bit=0 195 196 // original_copy=0, home=0, copyright_id_bit=0, copyright_id_start=0 197 *ptr++ = 198 (channel_configuration & 3) << 6 199 | aac_frame_length >> 11; 200 *ptr++ = (aac_frame_length >> 3) & 0xff; 201 *ptr++ = (aac_frame_length & 7) << 5; 202 203 // adts_buffer_fullness=0, number_of_raw_data_blocks_in_frame=0 204 *ptr++ = 0; 205 206 memcpy(ptr, accessUnit->data(), accessUnit->size()); 207 208 return dup; 209} 210 211//////////////////////////////////////////////////////////////////////////////// 212 213TSPacketizer::TSPacketizer() 214 : mPATContinuityCounter(0), 215 mPMTContinuityCounter(0) { 216 initCrcTable(); 217} 218 219TSPacketizer::~TSPacketizer() { 220} 221 222ssize_t TSPacketizer::addTrack(const sp<AMessage> &format) { 223 AString mime; 224 CHECK(format->findString("mime", &mime)); 225 226 unsigned PIDStart; 227 bool isVideo = !strncasecmp("video/", mime.c_str(), 6); 228 bool isAudio = !strncasecmp("audio/", mime.c_str(), 6); 229 230 if (isVideo) { 231 PIDStart = 0x1011; 232 } else if (isAudio) { 233 PIDStart = 0x1100; 234 } else { 235 return ERROR_UNSUPPORTED; 236 } 237 238 unsigned streamType; 239 unsigned streamIDStart; 240 unsigned streamIDStop; 241 242 if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) { 243 streamType = 0x1b; 244 streamIDStart = 0xe0; 245 streamIDStop = 0xef; 246 } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) { 247 streamType = 0x0f; 248 streamIDStart = 0xc0; 249 streamIDStop = 0xdf; 250 } else { 251 return ERROR_UNSUPPORTED; 252 } 253 254 size_t numTracksOfThisType = 0; 255 unsigned PID = PIDStart; 256 257 for (size_t i = 0; i < mTracks.size(); ++i) { 258 const sp<Track> &track = mTracks.itemAt(i); 259 260 if (track->streamType() == streamType) { 261 ++numTracksOfThisType; 262 } 263 264 if ((isAudio && track->isAudio()) || (isVideo && track->isVideo())) { 265 ++PID; 266 } 267 } 268 269 unsigned streamID = streamIDStart + numTracksOfThisType; 270 if (streamID > streamIDStop) { 271 return -ERANGE; 272 } 273 274 sp<Track> track = new Track(format, PID, streamType, streamID); 275 return mTracks.add(track); 276} 277 278status_t TSPacketizer::packetize( 279 size_t trackIndex, 280 const sp<ABuffer> &_accessUnit, 281 sp<ABuffer> *packets, 282 uint32_t flags, 283 const uint8_t *PES_private_data, size_t PES_private_data_len) { 284 sp<ABuffer> accessUnit = _accessUnit; 285 286 int64_t timeUs; 287 CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs)); 288 289 packets->clear(); 290 291 if (trackIndex >= mTracks.size()) { 292 return -ERANGE; 293 } 294 295 const sp<Track> &track = mTracks.itemAt(trackIndex); 296 297 if (track->isH264() && (flags & PREPEND_SPS_PPS_TO_IDR_FRAMES) 298 && IsIDR(accessUnit)) { 299 // prepend codec specific data, i.e. SPS and PPS. 300 accessUnit = track->prependCSD(accessUnit); 301 } else if (track->isAudio() && track->lacksADTSHeader()) { 302 CHECK(!(flags & IS_ENCRYPTED)); 303 accessUnit = track->prependADTSHeader(accessUnit); 304 } 305 306 // 0x47 307 // transport_error_indicator = b0 308 // payload_unit_start_indicator = b1 309 // transport_priority = b0 310 // PID 311 // transport_scrambling_control = b00 312 // adaptation_field_control = b?? 313 // continuity_counter = b???? 314 // -- payload follows 315 // packet_startcode_prefix = 0x000001 316 // stream_id 317 // PES_packet_length = 0x???? 318 // reserved = b10 319 // PES_scrambling_control = b00 320 // PES_priority = b0 321 // data_alignment_indicator = b1 322 // copyright = b0 323 // original_or_copy = b0 324 // PTS_DTS_flags = b10 (PTS only) 325 // ESCR_flag = b0 326 // ES_rate_flag = b0 327 // DSM_trick_mode_flag = b0 328 // additional_copy_info_flag = b0 329 // PES_CRC_flag = b0 330 // PES_extension_flag = b0 331 // PES_header_data_length = 0x05 332 // reserved = b0010 (PTS) 333 // PTS[32..30] = b??? 334 // reserved = b1 335 // PTS[29..15] = b??? ???? ???? ???? (15 bits) 336 // reserved = b1 337 // PTS[14..0] = b??? ???? ???? ???? (15 bits) 338 // reserved = b1 339 // the first fragment of "buffer" follows 340 341 size_t PES_packet_length = accessUnit->size() + 8; 342 if (PES_private_data_len > 0) { 343 PES_packet_length += PES_private_data_len + 1; 344 } 345 346 size_t numTSPackets; 347 if (PES_packet_length <= 178) { 348 numTSPackets = 1; 349 } else { 350 numTSPackets = 1 + ((PES_packet_length - 178) + 183) / 184; 351 } 352 353 if (flags & EMIT_PAT_AND_PMT) { 354 numTSPackets += 2; 355 } 356 357 if (flags & EMIT_PCR) { 358 ++numTSPackets; 359 } 360 361 sp<ABuffer> buffer = new ABuffer(numTSPackets * 188); 362 uint8_t *packetDataStart = buffer->data(); 363 364 if (flags & EMIT_PAT_AND_PMT) { 365 // Program Association Table (PAT): 366 // 0x47 367 // transport_error_indicator = b0 368 // payload_unit_start_indicator = b1 369 // transport_priority = b0 370 // PID = b0000000000000 (13 bits) 371 // transport_scrambling_control = b00 372 // adaptation_field_control = b01 (no adaptation field, payload only) 373 // continuity_counter = b???? 374 // skip = 0x00 375 // --- payload follows 376 // table_id = 0x00 377 // section_syntax_indicator = b1 378 // must_be_zero = b0 379 // reserved = b11 380 // section_length = 0x00d 381 // transport_stream_id = 0x0000 382 // reserved = b11 383 // version_number = b00001 384 // current_next_indicator = b1 385 // section_number = 0x00 386 // last_section_number = 0x00 387 // one program follows: 388 // program_number = 0x0001 389 // reserved = b111 390 // program_map_PID = kPID_PMT (13 bits!) 391 // CRC = 0x???????? 392 393 if (++mPATContinuityCounter == 16) { 394 mPATContinuityCounter = 0; 395 } 396 397 uint8_t *ptr = packetDataStart; 398 *ptr++ = 0x47; 399 *ptr++ = 0x40; 400 *ptr++ = 0x00; 401 *ptr++ = 0x10 | mPATContinuityCounter; 402 *ptr++ = 0x00; 403 404 const uint8_t *crcDataStart = ptr; 405 *ptr++ = 0x00; 406 *ptr++ = 0xb0; 407 *ptr++ = 0x0d; 408 *ptr++ = 0x00; 409 *ptr++ = 0x00; 410 *ptr++ = 0xc3; 411 *ptr++ = 0x00; 412 *ptr++ = 0x00; 413 *ptr++ = 0x00; 414 *ptr++ = 0x01; 415 *ptr++ = 0xe0 | (kPID_PMT >> 8); 416 *ptr++ = kPID_PMT & 0xff; 417 418 CHECK_EQ(ptr - crcDataStart, 12); 419 uint32_t crc = htonl(crc32(crcDataStart, ptr - crcDataStart)); 420 memcpy(ptr, &crc, 4); 421 ptr += 4; 422 423 size_t sizeLeft = packetDataStart + 188 - ptr; 424 memset(ptr, 0xff, sizeLeft); 425 426 packetDataStart += 188; 427 428 // Program Map (PMT): 429 // 0x47 430 // transport_error_indicator = b0 431 // payload_unit_start_indicator = b1 432 // transport_priority = b0 433 // PID = kPID_PMT (13 bits) 434 // transport_scrambling_control = b00 435 // adaptation_field_control = b01 (no adaptation field, payload only) 436 // continuity_counter = b???? 437 // skip = 0x00 438 // -- payload follows 439 // table_id = 0x02 440 // section_syntax_indicator = b1 441 // must_be_zero = b0 442 // reserved = b11 443 // section_length = 0x??? 444 // program_number = 0x0001 445 // reserved = b11 446 // version_number = b00001 447 // current_next_indicator = b1 448 // section_number = 0x00 449 // last_section_number = 0x00 450 // reserved = b111 451 // PCR_PID = kPCR_PID (13 bits) 452 // reserved = b1111 453 // program_info_length = 0x000 454 // one or more elementary stream descriptions follow: 455 // stream_type = 0x?? 456 // reserved = b111 457 // elementary_PID = b? ???? ???? ???? (13 bits) 458 // reserved = b1111 459 // ES_info_length = 0x000 460 // CRC = 0x???????? 461 462 if (++mPMTContinuityCounter == 16) { 463 mPMTContinuityCounter = 0; 464 } 465 466 size_t section_length = 5 * mTracks.size() + 4 + 9; 467 468 ptr = packetDataStart; 469 *ptr++ = 0x47; 470 *ptr++ = 0x40 | (kPID_PMT >> 8); 471 *ptr++ = kPID_PMT & 0xff; 472 *ptr++ = 0x10 | mPMTContinuityCounter; 473 *ptr++ = 0x00; 474 475 crcDataStart = ptr; 476 *ptr++ = 0x02; 477 *ptr++ = 0xb0 | (section_length >> 8); 478 *ptr++ = section_length & 0xff; 479 *ptr++ = 0x00; 480 *ptr++ = 0x01; 481 *ptr++ = 0xc3; 482 *ptr++ = 0x00; 483 *ptr++ = 0x00; 484 *ptr++ = 0xe0 | (kPID_PCR >> 8); 485 *ptr++ = kPID_PCR & 0xff; 486 *ptr++ = 0xf0; 487 *ptr++ = 0x00; 488 489 for (size_t i = 0; i < mTracks.size(); ++i) { 490 const sp<Track> &track = mTracks.itemAt(i); 491 492 *ptr++ = track->streamType(); 493 *ptr++ = 0xe0 | (track->PID() >> 8); 494 *ptr++ = track->PID() & 0xff; 495 *ptr++ = 0xf0; 496 *ptr++ = 0x00; 497 } 498 499 CHECK_EQ(ptr - crcDataStart, 12 + mTracks.size() * 5); 500 crc = htonl(crc32(crcDataStart, ptr - crcDataStart)); 501 memcpy(ptr, &crc, 4); 502 ptr += 4; 503 504 sizeLeft = packetDataStart + 188 - ptr; 505 memset(ptr, 0xff, sizeLeft); 506 507 packetDataStart += 188; 508 } 509 510 if (flags & EMIT_PCR) { 511 // PCR stream 512 // 0x47 513 // transport_error_indicator = b0 514 // payload_unit_start_indicator = b1 515 // transport_priority = b0 516 // PID = kPCR_PID (13 bits) 517 // transport_scrambling_control = b00 518 // adaptation_field_control = b10 (adaptation field only, no payload) 519 // continuity_counter = b0000 (does not increment) 520 // adaptation_field_length = 183 521 // discontinuity_indicator = b0 522 // random_access_indicator = b0 523 // elementary_stream_priority_indicator = b0 524 // PCR_flag = b1 525 // OPCR_flag = b0 526 // splicing_point_flag = b0 527 // transport_private_data_flag = b0 528 // adaptation_field_extension_flag = b0 529 // program_clock_reference_base = b????????????????????????????????? 530 // reserved = b111111 531 // program_clock_reference_extension = b????????? 532 533 int64_t nowUs = ALooper::GetNowUs(); 534 535 uint64_t PCR = nowUs * 27; // PCR based on a 27MHz clock 536 uint64_t PCR_base = PCR / 300; 537 uint32_t PCR_ext = PCR % 300; 538 539 uint8_t *ptr = packetDataStart; 540 *ptr++ = 0x47; 541 *ptr++ = 0x40 | (kPID_PCR >> 8); 542 *ptr++ = kPID_PCR & 0xff; 543 *ptr++ = 0x20; 544 *ptr++ = 0xb7; // adaptation_field_length 545 *ptr++ = 0x10; 546 *ptr++ = (PCR_base >> 25) & 0xff; 547 *ptr++ = (PCR_base >> 17) & 0xff; 548 *ptr++ = (PCR_base >> 9) & 0xff; 549 *ptr++ = ((PCR_base & 1) << 7) | 0x7e | ((PCR_ext >> 8) & 1); 550 *ptr++ = (PCR_ext & 0xff); 551 552 size_t sizeLeft = packetDataStart + 188 - ptr; 553 memset(ptr, 0xff, sizeLeft); 554 555 packetDataStart += 188; 556 } 557 558 uint64_t PTS = (timeUs * 9ll) / 100ll; 559 560 bool padding = (PES_packet_length < (188 - 10)); 561 562 if (PES_packet_length >= 65536) { 563 // This really should only happen for video. 564 CHECK(track->isVideo()); 565 566 // It's valid to set this to 0 for video according to the specs. 567 PES_packet_length = 0; 568 } 569 570 uint8_t *ptr = packetDataStart; 571 *ptr++ = 0x47; 572 *ptr++ = 0x40 | (track->PID() >> 8); 573 *ptr++ = track->PID() & 0xff; 574 *ptr++ = (padding ? 0x30 : 0x10) | track->incrementContinuityCounter(); 575 576 if (padding) { 577 size_t paddingSize = 188 - 10 - PES_packet_length; 578 *ptr++ = paddingSize - 1; 579 if (paddingSize >= 2) { 580 *ptr++ = 0x00; 581 memset(ptr, 0xff, paddingSize - 2); 582 ptr += paddingSize - 2; 583 } 584 } 585 586 *ptr++ = 0x00; 587 *ptr++ = 0x00; 588 *ptr++ = 0x01; 589 *ptr++ = track->streamID(); 590 *ptr++ = PES_packet_length >> 8; 591 *ptr++ = PES_packet_length & 0xff; 592 *ptr++ = 0x84; 593 *ptr++ = (PES_private_data_len > 0) ? 0x81 : 0x80; 594 595 *ptr++ = (PES_private_data_len > 0) 596 ? (1 + PES_private_data_len + 0x05) : 0x05; 597 598 *ptr++ = 0x20 | (((PTS >> 30) & 7) << 1) | 1; 599 *ptr++ = (PTS >> 22) & 0xff; 600 *ptr++ = (((PTS >> 15) & 0x7f) << 1) | 1; 601 *ptr++ = (PTS >> 7) & 0xff; 602 *ptr++ = ((PTS & 0x7f) << 1) | 1; 603 604 if (PES_private_data_len > 0) { 605 *ptr++ = 0x8e; // PES_private_data_flag, reserved. 606 memcpy(ptr, PES_private_data, PES_private_data_len); 607 ptr += PES_private_data_len; 608 } 609 610 // 18 bytes of TS/PES header leave 188 - 18 = 170 bytes for the payload 611 612 size_t sizeLeft = packetDataStart + 188 - ptr; 613 size_t copy = accessUnit->size(); 614 if (copy > sizeLeft) { 615 copy = sizeLeft; 616 } 617 618 memcpy(ptr, accessUnit->data(), copy); 619 ptr += copy; 620 CHECK_EQ(sizeLeft, copy); 621 memset(ptr, 0xff, sizeLeft - copy); 622 623 packetDataStart += 188; 624 625 size_t offset = copy; 626 while (offset < accessUnit->size()) { 627 bool padding = (accessUnit->size() - offset) < (188 - 4); 628 629 // for subsequent fragments of "buffer": 630 // 0x47 631 // transport_error_indicator = b0 632 // payload_unit_start_indicator = b0 633 // transport_priority = b0 634 // PID = b0 0001 1110 ???? (13 bits) [0x1e0 + 1 + sourceIndex] 635 // transport_scrambling_control = b00 636 // adaptation_field_control = b?? 637 // continuity_counter = b???? 638 // the fragment of "buffer" follows. 639 640 uint8_t *ptr = packetDataStart; 641 *ptr++ = 0x47; 642 *ptr++ = 0x00 | (track->PID() >> 8); 643 *ptr++ = track->PID() & 0xff; 644 645 *ptr++ = (padding ? 0x30 : 0x10) | track->incrementContinuityCounter(); 646 647 if (padding) { 648 size_t paddingSize = 188 - 4 - (accessUnit->size() - offset); 649 *ptr++ = paddingSize - 1; 650 if (paddingSize >= 2) { 651 *ptr++ = 0x00; 652 memset(ptr, 0xff, paddingSize - 2); 653 ptr += paddingSize - 2; 654 } 655 } 656 657 // 4 bytes of TS header leave 188 - 4 = 184 bytes for the payload 658 659 size_t sizeLeft = packetDataStart + 188 - ptr; 660 size_t copy = accessUnit->size() - offset; 661 if (copy > sizeLeft) { 662 copy = sizeLeft; 663 } 664 665 memcpy(ptr, accessUnit->data() + offset, copy); 666 ptr += copy; 667 CHECK_EQ(sizeLeft, copy); 668 memset(ptr, 0xff, sizeLeft - copy); 669 670 offset += copy; 671 packetDataStart += 188; 672 } 673 674 CHECK(packetDataStart == buffer->data() + buffer->capacity()); 675 676 *packets = buffer; 677 678 return OK; 679} 680 681void TSPacketizer::initCrcTable() { 682 uint32_t poly = 0x04C11DB7; 683 684 for (int i = 0; i < 256; i++) { 685 uint32_t crc = i << 24; 686 for (int j = 0; j < 8; j++) { 687 crc = (crc << 1) ^ ((crc & 0x80000000) ? (poly) : 0); 688 } 689 mCrcTable[i] = crc; 690 } 691} 692 693uint32_t TSPacketizer::crc32(const uint8_t *start, size_t size) const { 694 uint32_t crc = 0xFFFFFFFF; 695 const uint8_t *p; 696 697 for (p = start; p < start + size; ++p) { 698 crc = (crc << 8) ^ mCrcTable[((crc >> 24) ^ *p) & 0xFF]; 699 } 700 701 return crc; 702} 703 704sp<ABuffer> TSPacketizer::prependCSD( 705 size_t trackIndex, const sp<ABuffer> &accessUnit) const { 706 CHECK_LT(trackIndex, mTracks.size()); 707 708 const sp<Track> &track = mTracks.itemAt(trackIndex); 709 CHECK(track->isH264() && IsIDR(accessUnit)); 710 711 int64_t timeUs; 712 CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs)); 713 714 sp<ABuffer> accessUnit2 = track->prependCSD(accessUnit); 715 716 accessUnit2->meta()->setInt64("timeUs", timeUs); 717 718 return accessUnit2; 719} 720 721} // namespace android 722 723