MPEG4Writer.cpp revision e136c3bb38e88315bf8797a464ebf2c788296b22
1/* 2 * Copyright (C) 2009 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 "MPEG4Writer" 19#include <utils/Log.h> 20 21#include <arpa/inet.h> 22 23#include <ctype.h> 24#include <pthread.h> 25 26#include <media/stagefright/MPEG4Writer.h> 27#include <media/stagefright/MediaBuffer.h> 28#include <media/stagefright/MetaData.h> 29#include <media/stagefright/MediaDebug.h> 30#include <media/stagefright/MediaDefs.h> 31#include <media/stagefright/MediaErrors.h> 32#include <media/stagefright/MediaSource.h> 33#include <media/stagefright/Utils.h> 34#include <media/mediarecorder.h> 35 36namespace android { 37 38class MPEG4Writer::Track { 39public: 40 Track(MPEG4Writer *owner, const sp<MediaSource> &source); 41 ~Track(); 42 43 status_t start(); 44 void stop(); 45 bool reachedEOS(); 46 47 int64_t getDurationUs() const; 48 int64_t getEstimatedTrackSizeBytes() const; 49 void writeTrackHeader(int32_t trackID); 50 51private: 52 MPEG4Writer *mOwner; 53 sp<MetaData> mMeta; 54 sp<MediaSource> mSource; 55 volatile bool mDone; 56 int64_t mMaxTimeStampUs; 57 int64_t mEstimatedTrackSizeBytes; 58 59 pthread_t mThread; 60 61 struct SampleInfo { 62 size_t size; 63 int64_t timestamp; 64 }; 65 List<SampleInfo> mSampleInfos; 66 bool mSamplesHaveSameSize; 67 68 List<MediaBuffer *> mChunkSamples; 69 List<off_t> mChunkOffsets; 70 71 struct StscTableEntry { 72 73 StscTableEntry(uint32_t chunk, uint32_t samples, uint32_t id) 74 : firstChunk(chunk), 75 samplesPerChunk(samples), 76 sampleDescriptionId(id) {} 77 78 uint32_t firstChunk; 79 uint32_t samplesPerChunk; 80 uint32_t sampleDescriptionId; 81 }; 82 List<StscTableEntry> mStscTableEntries; 83 84 List<int32_t> mStssTableEntries; 85 86 struct SttsTableEntry { 87 88 SttsTableEntry(uint32_t count, uint32_t duration) 89 : sampleCount(count), sampleDuration(duration) {} 90 91 uint32_t sampleCount; 92 uint32_t sampleDuration; 93 }; 94 List<SttsTableEntry> mSttsTableEntries; 95 96 void *mCodecSpecificData; 97 size_t mCodecSpecificDataSize; 98 bool mGotAllCodecSpecificData; 99 100 bool mReachedEOS; 101 int64_t mStartTimestampUs; 102 103 static void *ThreadWrapper(void *me); 104 void threadEntry(); 105 106 status_t makeAVCCodecSpecificData( 107 const uint8_t *data, size_t size); 108 void writeOneChunk(bool isAvc); 109 110 Track(const Track &); 111 Track &operator=(const Track &); 112}; 113 114#define USE_NALLEN_FOUR 1 115 116MPEG4Writer::MPEG4Writer(const char *filename) 117 : mFile(fopen(filename, "wb")), 118 mOffset(0), 119 mMdatOffset(0), 120 mEstimatedMoovBoxSize(0), 121 mInterleaveDurationUs(500000) { 122 CHECK(mFile != NULL); 123} 124 125MPEG4Writer::MPEG4Writer(int fd) 126 : mFile(fdopen(fd, "wb")), 127 mOffset(0), 128 mMdatOffset(0), 129 mEstimatedMoovBoxSize(0), 130 mInterleaveDurationUs(500000) { 131 CHECK(mFile != NULL); 132} 133 134MPEG4Writer::~MPEG4Writer() { 135 stop(); 136 137 for (List<Track *>::iterator it = mTracks.begin(); 138 it != mTracks.end(); ++it) { 139 delete *it; 140 } 141 mTracks.clear(); 142} 143 144status_t MPEG4Writer::addSource(const sp<MediaSource> &source) { 145 Track *track = new Track(this, source); 146 mTracks.push_back(track); 147 148 return OK; 149} 150 151status_t MPEG4Writer::start() { 152 if (mFile == NULL) { 153 return UNKNOWN_ERROR; 154 } 155 156 mStartTimestampUs = 0; 157 mStreamableFile = true; 158 mWriteMoovBoxToMemory = false; 159 mMoovBoxBuffer = NULL; 160 mMoovBoxBufferOffset = 0; 161 162 beginBox("ftyp"); 163 writeFourcc("isom"); 164 writeInt32(0); 165 writeFourcc("isom"); 166 endBox(); 167 168 mFreeBoxOffset = mOffset; 169 170 if (mEstimatedMoovBoxSize == 0) { 171 // XXX: Estimate the moov box size 172 // based on max file size or duration limit 173 mEstimatedMoovBoxSize = 0x0F00; 174 } 175 CHECK(mEstimatedMoovBoxSize >= 8); 176 fseeko(mFile, mFreeBoxOffset, SEEK_SET); 177 writeInt32(mEstimatedMoovBoxSize); 178 write("free", 4); 179 180 mMdatOffset = mFreeBoxOffset + mEstimatedMoovBoxSize; 181 mOffset = mMdatOffset; 182 fseeko(mFile, mMdatOffset, SEEK_SET); 183 write("\x00\x00\x00\x01mdat????????", 16); 184 for (List<Track *>::iterator it = mTracks.begin(); 185 it != mTracks.end(); ++it) { 186 status_t err = (*it)->start(); 187 188 if (err != OK) { 189 for (List<Track *>::iterator it2 = mTracks.begin(); 190 it2 != it; ++it2) { 191 (*it2)->stop(); 192 } 193 194 return err; 195 } 196 } 197 198 return OK; 199} 200 201void MPEG4Writer::stop() { 202 if (mFile == NULL) { 203 return; 204 } 205 206 int64_t max_duration = 0; 207 for (List<Track *>::iterator it = mTracks.begin(); 208 it != mTracks.end(); ++it) { 209 (*it)->stop(); 210 211 int64_t duration = (*it)->getDurationUs(); 212 if (duration > max_duration) { 213 max_duration = duration; 214 } 215 } 216 217 218 // Fix up the size of the 'mdat' chunk. 219 fseeko(mFile, mMdatOffset + 8, SEEK_SET); 220 int64_t size = mOffset - mMdatOffset; 221 size = hton64(size); 222 fwrite(&size, 1, 8, mFile); 223 fseeko(mFile, mOffset, SEEK_SET); 224 225 time_t now = time(NULL); 226 const off_t moovOffset = mOffset; 227 mWriteMoovBoxToMemory = true; 228 mMoovBoxBuffer = (uint8_t *) malloc(mEstimatedMoovBoxSize); 229 mMoovBoxBufferOffset = 0; 230 CHECK(mMoovBoxBuffer != NULL); 231 232 beginBox("moov"); 233 234 beginBox("mvhd"); 235 writeInt32(0); // version=0, flags=0 236 writeInt32(now); // creation time 237 writeInt32(now); // modification time 238 writeInt32(1000); // timescale 239 writeInt32(max_duration / 1000); 240 writeInt32(0x10000); // rate 241 writeInt16(0x100); // volume 242 writeInt16(0); // reserved 243 writeInt32(0); // reserved 244 writeInt32(0); // reserved 245 writeInt32(0x10000); // matrix 246 writeInt32(0); 247 writeInt32(0); 248 writeInt32(0); 249 writeInt32(0x10000); 250 writeInt32(0); 251 writeInt32(0); 252 writeInt32(0); 253 writeInt32(0x40000000); 254 writeInt32(0); // predefined 255 writeInt32(0); // predefined 256 writeInt32(0); // predefined 257 writeInt32(0); // predefined 258 writeInt32(0); // predefined 259 writeInt32(0); // predefined 260 writeInt32(mTracks.size() + 1); // nextTrackID 261 endBox(); // mvhd 262 263 int32_t id = 1; 264 for (List<Track *>::iterator it = mTracks.begin(); 265 it != mTracks.end(); ++it, ++id) { 266 (*it)->writeTrackHeader(id); 267 } 268 endBox(); // moov 269 270 mWriteMoovBoxToMemory = false; 271 if (mStreamableFile) { 272 CHECK(mMoovBoxBufferOffset + 8 <= mEstimatedMoovBoxSize); 273 274 // Moov box 275 fseeko(mFile, mFreeBoxOffset, SEEK_SET); 276 mOffset = mFreeBoxOffset; 277 write(mMoovBoxBuffer, 1, mMoovBoxBufferOffset, mFile); 278 279 // Free box 280 mFreeBoxOffset = mStreamableFile? mOffset: mFreeBoxOffset; 281 fseeko(mFile, mFreeBoxOffset, SEEK_SET); 282 writeInt32(mEstimatedMoovBoxSize - mMoovBoxBufferOffset); 283 write("free", 4); 284 285 // Free temp memory 286 free(mMoovBoxBuffer); 287 mMoovBoxBuffer = NULL; 288 mMoovBoxBufferOffset = 0; 289 } 290 291 CHECK(mBoxes.empty()); 292 293 fflush(mFile); 294 fclose(mFile); 295 mFile = NULL; 296} 297 298status_t MPEG4Writer::setInterleaveDuration(uint32_t durationUs) { 299 mInterleaveDurationUs = durationUs; 300 return OK; 301} 302 303void MPEG4Writer::lock() { 304 mLock.lock(); 305} 306 307void MPEG4Writer::unlock() { 308 mLock.unlock(); 309} 310 311off_t MPEG4Writer::addSample_l(MediaBuffer *buffer) { 312 off_t old_offset = mOffset; 313 314 fwrite((const uint8_t *)buffer->data() + buffer->range_offset(), 315 1, buffer->range_length(), mFile); 316 317 mOffset += buffer->range_length(); 318 319 return old_offset; 320} 321 322static void StripStartcode(MediaBuffer *buffer) { 323 if (buffer->range_length() < 4) { 324 return; 325 } 326 327 const uint8_t *ptr = 328 (const uint8_t *)buffer->data() + buffer->range_offset(); 329 330 if (!memcmp(ptr, "\x00\x00\x00\x01", 4)) { 331 buffer->set_range( 332 buffer->range_offset() + 4, buffer->range_length() - 4); 333 } 334} 335 336off_t MPEG4Writer::addLengthPrefixedSample_l(MediaBuffer *buffer) { 337 off_t old_offset = mOffset; 338 339 size_t length = buffer->range_length(); 340 341#if USE_NALLEN_FOUR 342 uint8_t x = length >> 24; 343 fwrite(&x, 1, 1, mFile); 344 x = (length >> 16) & 0xff; 345 fwrite(&x, 1, 1, mFile); 346 x = (length >> 8) & 0xff; 347 fwrite(&x, 1, 1, mFile); 348 x = length & 0xff; 349 fwrite(&x, 1, 1, mFile); 350#else 351 CHECK(length < 65536); 352 353 uint8_t x = length >> 8; 354 fwrite(&x, 1, 1, mFile); 355 x = length & 0xff; 356 fwrite(&x, 1, 1, mFile); 357#endif 358 359 fwrite((const uint8_t *)buffer->data() + buffer->range_offset(), 360 1, length, mFile); 361 362#if USE_NALLEN_FOUR 363 mOffset += length + 4; 364#else 365 mOffset += length + 2; 366#endif 367 368 return old_offset; 369} 370 371size_t MPEG4Writer::write( 372 const void *ptr, size_t size, size_t nmemb, FILE *stream) { 373 374 const size_t bytes = size * nmemb; 375 if (mWriteMoovBoxToMemory) { 376 if (8 + mMoovBoxBufferOffset + bytes > mEstimatedMoovBoxSize) { 377 for (List<off_t>::iterator it = mBoxes.begin(); 378 it != mBoxes.end(); ++it) { 379 (*it) += mOffset; 380 } 381 fseeko(mFile, mOffset, SEEK_SET); 382 fwrite(mMoovBoxBuffer, 1, mMoovBoxBufferOffset, stream); 383 fwrite(ptr, size, nmemb, stream); 384 mOffset += (bytes + mMoovBoxBufferOffset); 385 free(mMoovBoxBuffer); 386 mMoovBoxBuffer = NULL; 387 mMoovBoxBufferOffset = 0; 388 mWriteMoovBoxToMemory = false; 389 mStreamableFile = false; 390 } else { 391 memcpy(mMoovBoxBuffer + mMoovBoxBufferOffset, ptr, bytes); 392 mMoovBoxBufferOffset += bytes; 393 } 394 } else { 395 fwrite(ptr, size, nmemb, stream); 396 mOffset += bytes; 397 } 398 return bytes; 399} 400 401void MPEG4Writer::beginBox(const char *fourcc) { 402 CHECK_EQ(strlen(fourcc), 4); 403 404 mBoxes.push_back(mWriteMoovBoxToMemory? 405 mMoovBoxBufferOffset: mOffset); 406 407 writeInt32(0); 408 writeFourcc(fourcc); 409} 410 411void MPEG4Writer::endBox() { 412 CHECK(!mBoxes.empty()); 413 414 off_t offset = *--mBoxes.end(); 415 mBoxes.erase(--mBoxes.end()); 416 417 if (mWriteMoovBoxToMemory) { 418 int32_t x = htonl(mMoovBoxBufferOffset - offset); 419 memcpy(mMoovBoxBuffer + offset, &x, 4); 420 } else { 421 fseeko(mFile, offset, SEEK_SET); 422 writeInt32(mOffset - offset); 423 mOffset -= 4; 424 fseeko(mFile, mOffset, SEEK_SET); 425 } 426} 427 428void MPEG4Writer::writeInt8(int8_t x) { 429 write(&x, 1, 1, mFile); 430} 431 432void MPEG4Writer::writeInt16(int16_t x) { 433 x = htons(x); 434 write(&x, 1, 2, mFile); 435} 436 437void MPEG4Writer::writeInt32(int32_t x) { 438 x = htonl(x); 439 write(&x, 1, 4, mFile); 440} 441 442void MPEG4Writer::writeInt64(int64_t x) { 443 x = hton64(x); 444 write(&x, 1, 8, mFile); 445} 446 447void MPEG4Writer::writeCString(const char *s) { 448 size_t n = strlen(s); 449 write(s, 1, n + 1, mFile); 450} 451 452void MPEG4Writer::writeFourcc(const char *s) { 453 CHECK_EQ(strlen(s), 4); 454 write(s, 1, 4, mFile); 455} 456 457void MPEG4Writer::write(const void *data, size_t size) { 458 write(data, 1, size, mFile); 459} 460 461bool MPEG4Writer::exceedsFileSizeLimit() { 462 // No limit 463 if (mMaxFileSizeLimitBytes == 0) { 464 return false; 465 } 466 467 int64_t nTotalBytesEstimate = static_cast<int64_t>(mEstimatedMoovBoxSize); 468 for (List<Track *>::iterator it = mTracks.begin(); 469 it != mTracks.end(); ++it) { 470 nTotalBytesEstimate += (*it)->getEstimatedTrackSizeBytes(); 471 } 472 return (nTotalBytesEstimate >= mMaxFileSizeLimitBytes); 473} 474 475bool MPEG4Writer::exceedsFileDurationLimit() { 476 // No limit 477 if (mMaxFileDurationLimitUs == 0) { 478 return false; 479 } 480 481 for (List<Track *>::iterator it = mTracks.begin(); 482 it != mTracks.end(); ++it) { 483 if ((*it)->getDurationUs() >= mMaxFileDurationLimitUs) { 484 return true; 485 } 486 } 487 return false; 488} 489 490bool MPEG4Writer::reachedEOS() { 491 bool allDone = true; 492 for (List<Track *>::iterator it = mTracks.begin(); 493 it != mTracks.end(); ++it) { 494 if (!(*it)->reachedEOS()) { 495 allDone = false; 496 break; 497 } 498 } 499 500 return allDone; 501} 502 503void MPEG4Writer::setStartTimestamp(int64_t timeUs) { 504 LOGI("setStartTimestamp: %lld", timeUs); 505 Mutex::Autolock autoLock(mLock); 506 if (mStartTimestampUs != 0) { 507 return; // Sorry, too late 508 } 509 mStartTimestampUs = timeUs; 510} 511 512int64_t MPEG4Writer::getStartTimestamp() { 513 LOGI("getStartTimestamp: %lld", mStartTimestampUs); 514 Mutex::Autolock autoLock(mLock); 515 return mStartTimestampUs; 516} 517 518//////////////////////////////////////////////////////////////////////////////// 519 520MPEG4Writer::Track::Track( 521 MPEG4Writer *owner, const sp<MediaSource> &source) 522 : mOwner(owner), 523 mMeta(source->getFormat()), 524 mSource(source), 525 mDone(false), 526 mMaxTimeStampUs(0), 527 mEstimatedTrackSizeBytes(0), 528 mSamplesHaveSameSize(true), 529 mCodecSpecificData(NULL), 530 mCodecSpecificDataSize(0), 531 mGotAllCodecSpecificData(false), 532 mReachedEOS(false) { 533} 534 535MPEG4Writer::Track::~Track() { 536 stop(); 537 538 if (mCodecSpecificData != NULL) { 539 free(mCodecSpecificData); 540 mCodecSpecificData = NULL; 541 } 542} 543 544status_t MPEG4Writer::Track::start() { 545 status_t err = mSource->start(); 546 547 if (err != OK) { 548 mDone = mReachedEOS = true; 549 return err; 550 } 551 552 pthread_attr_t attr; 553 pthread_attr_init(&attr); 554 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 555 556 mDone = false; 557 mMaxTimeStampUs = 0; 558 mReachedEOS = false; 559 mEstimatedTrackSizeBytes = 0; 560 561 pthread_create(&mThread, &attr, ThreadWrapper, this); 562 pthread_attr_destroy(&attr); 563 564 return OK; 565} 566 567void MPEG4Writer::Track::stop() { 568 if (mDone) { 569 return; 570 } 571 572 mDone = true; 573 574 void *dummy; 575 pthread_join(mThread, &dummy); 576 577 mSource->stop(); 578} 579 580bool MPEG4Writer::Track::reachedEOS() { 581 return mReachedEOS; 582} 583 584// static 585void *MPEG4Writer::Track::ThreadWrapper(void *me) { 586 Track *track = static_cast<Track *>(me); 587 588 track->threadEntry(); 589 590 return NULL; 591} 592 593#include <ctype.h> 594static void hexdump(const void *_data, size_t size) { 595 const uint8_t *data = (const uint8_t *)_data; 596 size_t offset = 0; 597 while (offset < size) { 598 printf("0x%04x ", offset); 599 600 size_t n = size - offset; 601 if (n > 16) { 602 n = 16; 603 } 604 605 for (size_t i = 0; i < 16; ++i) { 606 if (i == 8) { 607 printf(" "); 608 } 609 610 if (offset + i < size) { 611 printf("%02x ", data[offset + i]); 612 } else { 613 printf(" "); 614 } 615 } 616 617 printf(" "); 618 619 for (size_t i = 0; i < n; ++i) { 620 if (isprint(data[offset + i])) { 621 printf("%c", data[offset + i]); 622 } else { 623 printf("."); 624 } 625 } 626 627 printf("\n"); 628 629 offset += 16; 630 } 631} 632 633 634status_t MPEG4Writer::Track::makeAVCCodecSpecificData( 635 const uint8_t *data, size_t size) { 636 // hexdump(data, size); 637 638 if (mCodecSpecificData != NULL) { 639 LOGE("Already have codec specific data"); 640 return ERROR_MALFORMED; 641 } 642 643 if (size < 4 || memcmp("\x00\x00\x00\x01", data, 4)) { 644 LOGE("Must start with a start code"); 645 return ERROR_MALFORMED; 646 } 647 648 size_t picParamOffset = 4; 649 while (picParamOffset + 3 < size 650 && memcmp("\x00\x00\x00\x01", &data[picParamOffset], 4)) { 651 ++picParamOffset; 652 } 653 654 if (picParamOffset + 3 >= size) { 655 LOGE("Could not find start-code for pictureParameterSet"); 656 return ERROR_MALFORMED; 657 } 658 659 size_t seqParamSetLength = picParamOffset - 4; 660 size_t picParamSetLength = size - picParamOffset - 4; 661 662 mCodecSpecificDataSize = 663 6 + 1 + seqParamSetLength + 2 + picParamSetLength + 2; 664 665 mCodecSpecificData = malloc(mCodecSpecificDataSize); 666 uint8_t *header = (uint8_t *)mCodecSpecificData; 667 header[0] = 1; 668 header[1] = 0x42; // profile 669 header[2] = 0x80; 670 header[3] = 0x1e; // level 671 672#if USE_NALLEN_FOUR 673 header[4] = 0xfc | 3; // length size == 4 bytes 674#else 675 header[4] = 0xfc | 1; // length size == 2 bytes 676#endif 677 678 header[5] = 0xe0 | 1; 679 header[6] = seqParamSetLength >> 8; 680 header[7] = seqParamSetLength & 0xff; 681 memcpy(&header[8], &data[4], seqParamSetLength); 682 header += 8 + seqParamSetLength; 683 header[0] = 1; 684 header[1] = picParamSetLength >> 8; 685 header[2] = picParamSetLength & 0xff; 686 memcpy(&header[3], &data[picParamOffset + 4], picParamSetLength); 687 688 return OK; 689} 690 691void MPEG4Writer::Track::threadEntry() { 692 sp<MetaData> meta = mSource->getFormat(); 693 const char *mime; 694 meta->findCString(kKeyMIMEType, &mime); 695 bool is_mpeg4 = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) || 696 !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC); 697 bool is_avc = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 698 bool is_audio = !strncasecmp(mime, "audio/", 6); 699 int32_t count = 0; 700 const int64_t interleaveDurationUs = mOwner->interleaveDuration(); 701 int64_t chunkTimestampUs = 0; 702 int32_t nChunks = 0; 703 int32_t nZeroLengthFrames = 0; 704 int64_t lastTimestamp = 0; // Timestamp of the previous sample 705 int64_t lastDuration = 0; // Time spacing between the previous two samples 706 int32_t sampleCount = 1; // Sample count in the current stts table entry 707 uint32_t previousSampleSize = 0; // Size of the previous sample 708 709 MediaBuffer *buffer; 710 while (!mDone && mSource->read(&buffer) == OK) { 711 if (buffer->range_length() == 0) { 712 buffer->release(); 713 buffer = NULL; 714 ++nZeroLengthFrames; 715 continue; 716 } 717 718 ++count; 719 720 int32_t isCodecConfig; 721 if (buffer->meta_data()->findInt32(kKeyIsCodecConfig, &isCodecConfig) 722 && isCodecConfig) { 723 CHECK(!mGotAllCodecSpecificData); 724 725 if (is_avc) { 726 status_t err = makeAVCCodecSpecificData( 727 (const uint8_t *)buffer->data() 728 + buffer->range_offset(), 729 buffer->range_length()); 730 CHECK_EQ(OK, err); 731 } else if (is_mpeg4) { 732 mCodecSpecificDataSize = buffer->range_length(); 733 mCodecSpecificData = malloc(mCodecSpecificDataSize); 734 memcpy(mCodecSpecificData, 735 (const uint8_t *)buffer->data() 736 + buffer->range_offset(), 737 buffer->range_length()); 738 } 739 740 buffer->release(); 741 buffer = NULL; 742 743 mGotAllCodecSpecificData = true; 744 continue; 745 } else if (!mGotAllCodecSpecificData && 746 count == 1 && is_mpeg4 && mCodecSpecificData == NULL) { 747 // The TI mpeg4 encoder does not properly set the 748 // codec-specific-data flag. 749 750 const uint8_t *data = 751 (const uint8_t *)buffer->data() + buffer->range_offset(); 752 753 const size_t size = buffer->range_length(); 754 755 size_t offset = 0; 756 while (offset + 3 < size) { 757 if (data[offset] == 0x00 && data[offset + 1] == 0x00 758 && data[offset + 2] == 0x01 && data[offset + 3] == 0xb6) { 759 break; 760 } 761 762 ++offset; 763 } 764 765 // CHECK(offset + 3 < size); 766 if (offset + 3 >= size) { 767 // XXX assume the entire first chunk of data is the codec specific 768 // data. 769 offset = size; 770 } 771 772 mCodecSpecificDataSize = offset; 773 mCodecSpecificData = malloc(offset); 774 memcpy(mCodecSpecificData, data, offset); 775 776 buffer->set_range(buffer->range_offset() + offset, size - offset); 777 778 if (size == offset) { 779 buffer->release(); 780 buffer = NULL; 781 782 continue; 783 } 784 785 mGotAllCodecSpecificData = true; 786 } else if (!mGotAllCodecSpecificData && is_avc && count < 3) { 787 // The TI video encoder does not flag codec specific data 788 // as such and also splits up SPS and PPS across two buffers. 789 790 const uint8_t *data = 791 (const uint8_t *)buffer->data() + buffer->range_offset(); 792 793 size_t size = buffer->range_length(); 794 795 CHECK(count == 2 || mCodecSpecificData == NULL); 796 797 size_t offset = mCodecSpecificDataSize; 798 mCodecSpecificDataSize += size + 4; 799 mCodecSpecificData = 800 realloc(mCodecSpecificData, mCodecSpecificDataSize); 801 802 memcpy((uint8_t *)mCodecSpecificData + offset, 803 "\x00\x00\x00\x01", 4); 804 805 memcpy((uint8_t *)mCodecSpecificData + offset + 4, data, size); 806 807 buffer->release(); 808 buffer = NULL; 809 810 if (count == 2) { 811 void *tmp = mCodecSpecificData; 812 size = mCodecSpecificDataSize; 813 mCodecSpecificData = NULL; 814 mCodecSpecificDataSize = 0; 815 816 status_t err = makeAVCCodecSpecificData( 817 (const uint8_t *)tmp, size); 818 free(tmp); 819 tmp = NULL; 820 CHECK_EQ(OK, err); 821 822 mGotAllCodecSpecificData = true; 823 } 824 825 continue; 826 } 827 828 if (is_avc) StripStartcode(buffer); 829 830 SampleInfo info; 831 info.size = is_avc 832#if USE_NALLEN_FOUR 833 ? buffer->range_length() + 4 834#else 835 ? buffer->range_length() + 2 836#endif 837 : buffer->range_length(); 838 839 // Max file size or duration handling 840 mEstimatedTrackSizeBytes += info.size; 841 if (mOwner->exceedsFileSizeLimit()) { 842 buffer->release(); 843 buffer = NULL; 844 mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED, 0); 845 break; 846 } 847 if (mOwner->exceedsFileDurationLimit()) { 848 buffer->release(); 849 buffer = NULL; 850 mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_DURATION_REACHED, 0); 851 break; 852 } 853 854 855 int64_t timestampUs; 856 CHECK(buffer->meta_data()->findInt64(kKeyTime, ×tampUs)); 857 if (mSampleInfos.empty()) { 858 mOwner->setStartTimestamp(timestampUs); 859 mStartTimestampUs = (timestampUs - mOwner->getStartTimestamp()); 860 } 861 862 if (timestampUs > mMaxTimeStampUs) { 863 mMaxTimeStampUs = timestampUs; 864 } 865 866 // Our timestamp is in ms. 867 info.timestamp = (timestampUs + 500) / 1000; 868 mSampleInfos.push_back(info); 869 if (mSampleInfos.size() > 2) { 870 if (lastDuration != info.timestamp - lastTimestamp) { 871 SttsTableEntry sttsEntry(sampleCount, lastDuration); 872 mSttsTableEntries.push_back(sttsEntry); 873 sampleCount = 1; 874 } else { 875 ++sampleCount; 876 } 877 } 878 if (mSamplesHaveSameSize) { 879 if (mSampleInfos.size() >= 2 && previousSampleSize != info.size) { 880 mSamplesHaveSameSize = false; 881 } 882 previousSampleSize = info.size; 883 } 884 lastDuration = info.timestamp - lastTimestamp; 885 lastTimestamp = info.timestamp; 886 887//////////////////////////////////////////////////////////////////////////////// 888 // Make a deep copy of the MediaBuffer less Metadata 889 MediaBuffer *copy = new MediaBuffer(buffer->range_length()); 890 memcpy(copy->data(), (uint8_t *)buffer->data() + buffer->range_offset(), 891 buffer->range_length()); 892 copy->set_range(0, buffer->range_length()); 893 894 mChunkSamples.push_back(copy); 895 if (interleaveDurationUs == 0) { 896 StscTableEntry stscEntry(++nChunks, 1, 1); 897 mStscTableEntries.push_back(stscEntry); 898 writeOneChunk(is_avc); 899 } else { 900 if (chunkTimestampUs == 0) { 901 chunkTimestampUs = timestampUs; 902 } else { 903 if (timestampUs - chunkTimestampUs > interleaveDurationUs) { 904 ++nChunks; 905 if (nChunks == 1 || // First chunk 906 (--(mStscTableEntries.end()))->samplesPerChunk != 907 mChunkSamples.size()) { 908 StscTableEntry stscEntry(nChunks, 909 mChunkSamples.size(), 1); 910 mStscTableEntries.push_back(stscEntry); 911 } 912 writeOneChunk(is_avc); 913 chunkTimestampUs = timestampUs; 914 } 915 } 916 } 917 918 int32_t isSync = false; 919 if (buffer->meta_data()->findInt32(kKeyIsSyncFrame, &isSync) && 920 isSync != 0) { 921 mStssTableEntries.push_back(mSampleInfos.size()); 922 } 923 924 buffer->release(); 925 buffer = NULL; 926 } 927 928 if (mSampleInfos.empty()) { 929 mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_STOP_PREMATURELY, 0); 930 } 931 932 // Last chunk 933 if (!mChunkSamples.empty()) { 934 ++nChunks; 935 StscTableEntry stscEntry(nChunks, mChunkSamples.size(), 1); 936 mStscTableEntries.push_back(stscEntry); 937 writeOneChunk(is_avc); 938 } 939 940 // We don't really know how long the last frame lasts, since 941 // there is no frame time after it, just repeat the previous 942 // frame's duration. 943 if (mSampleInfos.size() == 1) { 944 lastDuration = 0; // A single sample's duration 945 } else { 946 ++sampleCount; // Count for the last sample 947 } 948 SttsTableEntry sttsEntry(sampleCount, lastDuration); 949 mSttsTableEntries.push_back(sttsEntry); 950 mReachedEOS = true; 951 LOGI("Received total/0-length (%d/%d) buffers and encoded %d frames - %s", 952 count, nZeroLengthFrames, mSampleInfos.size(), is_audio? "audio": "video"); 953} 954 955void MPEG4Writer::Track::writeOneChunk(bool isAvc) { 956 mOwner->lock(); 957 for (List<MediaBuffer *>::iterator it = mChunkSamples.begin(); 958 it != mChunkSamples.end(); ++it) { 959 off_t offset = isAvc? mOwner->addLengthPrefixedSample_l(*it) 960 : mOwner->addSample_l(*it); 961 if (it == mChunkSamples.begin()) { 962 mChunkOffsets.push_back(offset); 963 } 964 } 965 mOwner->unlock(); 966 while (!mChunkSamples.empty()) { 967 List<MediaBuffer *>::iterator it = mChunkSamples.begin(); 968 (*it)->release(); 969 (*it) = NULL; 970 mChunkSamples.erase(it); 971 } 972 mChunkSamples.clear(); 973} 974 975int64_t MPEG4Writer::Track::getDurationUs() const { 976 return mMaxTimeStampUs; 977} 978 979int64_t MPEG4Writer::Track::getEstimatedTrackSizeBytes() const { 980 return mEstimatedTrackSizeBytes; 981} 982 983void MPEG4Writer::Track::writeTrackHeader(int32_t trackID) { 984 const char *mime; 985 bool success = mMeta->findCString(kKeyMIMEType, &mime); 986 CHECK(success); 987 988 bool is_audio = !strncasecmp(mime, "audio/", 6); 989 990 time_t now = time(NULL); 991 992 mOwner->beginBox("trak"); 993 994 mOwner->beginBox("tkhd"); 995 mOwner->writeInt32(0); // version=0, flags=0 996 mOwner->writeInt32(now); // creation time 997 mOwner->writeInt32(now); // modification time 998 mOwner->writeInt32(trackID); 999 mOwner->writeInt32(0); // reserved 1000 mOwner->writeInt32(getDurationUs() / 1000); 1001 mOwner->writeInt32(0); // reserved 1002 mOwner->writeInt32(0); // reserved 1003 mOwner->writeInt16(0); // layer 1004 mOwner->writeInt16(0); // alternate group 1005 mOwner->writeInt16(is_audio ? 0x100 : 0); // volume 1006 mOwner->writeInt16(0); // reserved 1007 1008 mOwner->writeInt32(0x10000); // matrix 1009 mOwner->writeInt32(0); 1010 mOwner->writeInt32(0); 1011 mOwner->writeInt32(0); 1012 mOwner->writeInt32(0x10000); 1013 mOwner->writeInt32(0); 1014 mOwner->writeInt32(0); 1015 mOwner->writeInt32(0); 1016 mOwner->writeInt32(0x40000000); 1017 1018 if (is_audio) { 1019 mOwner->writeInt32(0); 1020 mOwner->writeInt32(0); 1021 } else { 1022 int32_t width, height; 1023 bool success = mMeta->findInt32(kKeyWidth, &width); 1024 success = success && mMeta->findInt32(kKeyHeight, &height); 1025 CHECK(success); 1026 1027 mOwner->writeInt32(width << 16); // 32-bit fixed-point value 1028 mOwner->writeInt32(height << 16); // 32-bit fixed-point value 1029 } 1030 mOwner->endBox(); // tkhd 1031 1032 if (mStartTimestampUs != 0) { 1033 mOwner->beginBox("edts"); 1034 mOwner->writeInt32(0); // version=0, flags=0 1035 mOwner->beginBox("elst"); 1036 mOwner->writeInt32(0); // version=0, flags=0 1037 mOwner->writeInt32(1); // a single entry 1038 mOwner->writeInt32(mStartTimestampUs / 1000); // edit duration 1039 mOwner->writeInt32(-1); // empty edit box to signal starting time offset 1040 mOwner->writeInt32(1); // x1 rate 1041 mOwner->endBox(); 1042 mOwner->endBox(); 1043 } 1044 1045 mOwner->beginBox("mdia"); 1046 1047 mOwner->beginBox("mdhd"); 1048 mOwner->writeInt32(0); // version=0, flags=0 1049 mOwner->writeInt32(now); // creation time 1050 mOwner->writeInt32(now); // modification time 1051 mOwner->writeInt32(1000); // timescale 1052 mOwner->writeInt32(getDurationUs() / 1000); 1053 mOwner->writeInt16(0); // language code XXX 1054 mOwner->writeInt16(0); // predefined 1055 mOwner->endBox(); 1056 1057 mOwner->beginBox("hdlr"); 1058 mOwner->writeInt32(0); // version=0, flags=0 1059 mOwner->writeInt32(0); // component type: should be mhlr 1060 mOwner->writeFourcc(is_audio ? "soun" : "vide"); // component subtype 1061 mOwner->writeInt32(0); // reserved 1062 mOwner->writeInt32(0); // reserved 1063 mOwner->writeInt32(0); // reserved 1064 mOwner->writeCString(is_audio ? "SoundHandler": ""); // name 1065 mOwner->endBox(); 1066 1067 mOwner->beginBox("minf"); 1068 if (is_audio) { 1069 mOwner->beginBox("smhd"); 1070 mOwner->writeInt32(0); // version=0, flags=0 1071 mOwner->writeInt16(0); // balance 1072 mOwner->writeInt16(0); // reserved 1073 mOwner->endBox(); 1074 } else { 1075 mOwner->beginBox("vmhd"); 1076 mOwner->writeInt32(0x00000001); // version=0, flags=1 1077 mOwner->writeInt16(0); // graphics mode 1078 mOwner->writeInt16(0); // opcolor 1079 mOwner->writeInt16(0); 1080 mOwner->writeInt16(0); 1081 mOwner->endBox(); 1082 } 1083 1084 mOwner->beginBox("dinf"); 1085 mOwner->beginBox("dref"); 1086 mOwner->writeInt32(0); // version=0, flags=0 1087 mOwner->writeInt32(1); 1088 mOwner->beginBox("url "); 1089 mOwner->writeInt32(1); // version=0, flags=1 1090 mOwner->endBox(); // url 1091 mOwner->endBox(); // dref 1092 mOwner->endBox(); // dinf 1093 1094 mOwner->endBox(); // minf 1095 1096 mOwner->beginBox("stbl"); 1097 1098 mOwner->beginBox("stsd"); 1099 mOwner->writeInt32(0); // version=0, flags=0 1100 mOwner->writeInt32(1); // entry count 1101 if (is_audio) { 1102 const char *fourcc = NULL; 1103 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime)) { 1104 fourcc = "samr"; 1105 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) { 1106 fourcc = "sawb"; 1107 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) { 1108 fourcc = "mp4a"; 1109 } else { 1110 LOGE("Unknown mime type '%s'.", mime); 1111 CHECK(!"should not be here, unknown mime type."); 1112 } 1113 1114 mOwner->beginBox(fourcc); // audio format 1115 mOwner->writeInt32(0); // reserved 1116 mOwner->writeInt16(0); // reserved 1117 mOwner->writeInt16(0x1); // data ref index 1118 mOwner->writeInt32(0); // reserved 1119 mOwner->writeInt32(0); // reserved 1120 int32_t nChannels; 1121 CHECK_EQ(true, mMeta->findInt32(kKeyChannelCount, &nChannels)); 1122 mOwner->writeInt16(nChannels); // channel count 1123 mOwner->writeInt16(16); // sample size 1124 mOwner->writeInt16(0); // predefined 1125 mOwner->writeInt16(0); // reserved 1126 1127 int32_t samplerate; 1128 bool success = mMeta->findInt32(kKeySampleRate, &samplerate); 1129 CHECK(success); 1130 1131 mOwner->writeInt32(samplerate << 16); 1132 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) { 1133 mOwner->beginBox("esds"); 1134 1135 mOwner->writeInt32(0); // version=0, flags=0 1136 mOwner->writeInt8(0x03); // ES_DescrTag 1137 mOwner->writeInt8(23 + mCodecSpecificDataSize); 1138 mOwner->writeInt16(0x0000);// ES_ID 1139 mOwner->writeInt8(0x00); 1140 1141 mOwner->writeInt8(0x04); // DecoderConfigDescrTag 1142 mOwner->writeInt8(15 + mCodecSpecificDataSize); 1143 mOwner->writeInt8(0x40); // objectTypeIndication ISO/IEC 14492-2 1144 mOwner->writeInt8(0x15); // streamType AudioStream 1145 1146 mOwner->writeInt16(0x03); // XXX 1147 mOwner->writeInt8(0x00); // buffer size 24-bit 1148 mOwner->writeInt32(96000); // max bit rate 1149 mOwner->writeInt32(96000); // avg bit rate 1150 1151 mOwner->writeInt8(0x05); // DecoderSpecificInfoTag 1152 mOwner->writeInt8(mCodecSpecificDataSize); 1153 mOwner->write(mCodecSpecificData, mCodecSpecificDataSize); 1154 1155 static const uint8_t kData2[] = { 1156 0x06, // SLConfigDescriptorTag 1157 0x01, 1158 0x02 1159 }; 1160 mOwner->write(kData2, sizeof(kData2)); 1161 1162 mOwner->endBox(); // esds 1163 } 1164 mOwner->endBox(); 1165 } else { 1166 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { 1167 mOwner->beginBox("mp4v"); 1168 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { 1169 mOwner->beginBox("s263"); 1170 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) { 1171 mOwner->beginBox("avc1"); 1172 } else { 1173 LOGE("Unknown mime type '%s'.", mime); 1174 CHECK(!"should not be here, unknown mime type."); 1175 } 1176 1177 mOwner->writeInt32(0); // reserved 1178 mOwner->writeInt16(0); // reserved 1179 mOwner->writeInt16(0); // data ref index 1180 mOwner->writeInt16(0); // predefined 1181 mOwner->writeInt16(0); // reserved 1182 mOwner->writeInt32(0); // predefined 1183 mOwner->writeInt32(0); // predefined 1184 mOwner->writeInt32(0); // predefined 1185 1186 int32_t width, height; 1187 bool success = mMeta->findInt32(kKeyWidth, &width); 1188 success = success && mMeta->findInt32(kKeyHeight, &height); 1189 CHECK(success); 1190 1191 mOwner->writeInt16(width); 1192 mOwner->writeInt16(height); 1193 mOwner->writeInt32(0x480000); // horiz resolution 1194 mOwner->writeInt32(0x480000); // vert resolution 1195 mOwner->writeInt32(0); // reserved 1196 mOwner->writeInt16(1); // frame count 1197 mOwner->write(" ", 32); 1198 mOwner->writeInt16(0x18); // depth 1199 mOwner->writeInt16(-1); // predefined 1200 1201 CHECK(23 + mCodecSpecificDataSize < 128); 1202 1203 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { 1204 mOwner->beginBox("esds"); 1205 1206 mOwner->writeInt32(0); // version=0, flags=0 1207 1208 mOwner->writeInt8(0x03); // ES_DescrTag 1209 mOwner->writeInt8(23 + mCodecSpecificDataSize); 1210 mOwner->writeInt16(0x0000); // ES_ID 1211 mOwner->writeInt8(0x1f); 1212 1213 mOwner->writeInt8(0x04); // DecoderConfigDescrTag 1214 mOwner->writeInt8(15 + mCodecSpecificDataSize); 1215 mOwner->writeInt8(0x20); // objectTypeIndication ISO/IEC 14492-2 1216 mOwner->writeInt8(0x11); // streamType VisualStream 1217 1218 static const uint8_t kData[] = { 1219 0x01, 0x77, 0x00, 1220 0x00, 0x03, 0xe8, 0x00, 1221 0x00, 0x03, 0xe8, 0x00 1222 }; 1223 mOwner->write(kData, sizeof(kData)); 1224 1225 mOwner->writeInt8(0x05); // DecoderSpecificInfoTag 1226 1227 mOwner->writeInt8(mCodecSpecificDataSize); 1228 mOwner->write(mCodecSpecificData, mCodecSpecificDataSize); 1229 1230 static const uint8_t kData2[] = { 1231 0x06, // SLConfigDescriptorTag 1232 0x01, 1233 0x02 1234 }; 1235 mOwner->write(kData2, sizeof(kData2)); 1236 1237 mOwner->endBox(); // esds 1238 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { 1239 mOwner->beginBox("d263"); 1240 1241 mOwner->writeInt32(0); // vendor 1242 mOwner->writeInt8(0); // decoder version 1243 mOwner->writeInt8(10); // level: 10 1244 mOwner->writeInt8(0); // profile: 0 1245 1246 mOwner->endBox(); // d263 1247 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) { 1248 mOwner->beginBox("avcC"); 1249 mOwner->write(mCodecSpecificData, mCodecSpecificDataSize); 1250 mOwner->endBox(); // avcC 1251 } 1252 1253 mOwner->endBox(); // mp4v, s263 or avc1 1254 } 1255 mOwner->endBox(); // stsd 1256 1257 mOwner->beginBox("stts"); 1258 mOwner->writeInt32(0); // version=0, flags=0 1259 mOwner->writeInt32(mSttsTableEntries.size()); 1260 for (List<SttsTableEntry>::iterator it = mSttsTableEntries.begin(); 1261 it != mSttsTableEntries.end(); ++it) { 1262 mOwner->writeInt32(it->sampleCount); 1263 mOwner->writeInt32(it->sampleDuration); 1264 } 1265 mOwner->endBox(); // stts 1266 1267 if (!is_audio) { 1268 mOwner->beginBox("stss"); 1269 mOwner->writeInt32(0); // version=0, flags=0 1270 mOwner->writeInt32(mStssTableEntries.size()); // number of sync frames 1271 for (List<int32_t>::iterator it = mStssTableEntries.begin(); 1272 it != mStssTableEntries.end(); ++it) { 1273 mOwner->writeInt32(*it); 1274 } 1275 mOwner->endBox(); // stss 1276 } 1277 1278 mOwner->beginBox("stsz"); 1279 mOwner->writeInt32(0); // version=0, flags=0 1280 if (mSamplesHaveSameSize) { 1281 List<SampleInfo>::iterator it = mSampleInfos.begin(); 1282 mOwner->writeInt32(it->size); // default sample size 1283 } else { 1284 mOwner->writeInt32(0); 1285 } 1286 mOwner->writeInt32(mSampleInfos.size()); 1287 if (!mSamplesHaveSameSize) { 1288 for (List<SampleInfo>::iterator it = mSampleInfos.begin(); 1289 it != mSampleInfos.end(); ++it) { 1290 mOwner->writeInt32((*it).size); 1291 } 1292 } 1293 mOwner->endBox(); // stsz 1294 1295 mOwner->beginBox("stsc"); 1296 mOwner->writeInt32(0); // version=0, flags=0 1297 mOwner->writeInt32(mStscTableEntries.size()); 1298 for (List<StscTableEntry>::iterator it = mStscTableEntries.begin(); 1299 it != mStscTableEntries.end(); ++it) { 1300 mOwner->writeInt32(it->firstChunk); 1301 mOwner->writeInt32(it->samplesPerChunk); 1302 mOwner->writeInt32(it->sampleDescriptionId); 1303 } 1304 mOwner->endBox(); // stsc 1305 1306 mOwner->beginBox("co64"); 1307 mOwner->writeInt32(0); // version=0, flags=0 1308 mOwner->writeInt32(mChunkOffsets.size()); 1309 for (List<off_t>::iterator it = mChunkOffsets.begin(); 1310 it != mChunkOffsets.end(); ++it) { 1311 mOwner->writeInt64((*it)); 1312 } 1313 mOwner->endBox(); // co64 1314 1315 mOwner->endBox(); // stbl 1316 mOwner->endBox(); // mdia 1317 mOwner->endBox(); // trak 1318} 1319 1320} // namespace android 1321