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 <pthread.h> 24 #include <sys/prctl.h> 25 #include <sys/resource.h> 26 27 #include <media/stagefright/MPEG4Writer.h> 28 #include <media/stagefright/MediaBuffer.h> 29 #include <media/stagefright/MetaData.h> 30 #include <media/stagefright/MediaDebug.h> 31 #include <media/stagefright/MediaDefs.h> 32 #include <media/stagefright/MediaErrors.h> 33 #include <media/stagefright/MediaSource.h> 34 #include <media/stagefright/Utils.h> 35 #include <media/mediarecorder.h> 36 37 #include "include/ESDS.h" 38 39 namespace android { 40 41 static const int64_t kMax32BitFileSize = 0x007fffffffLL; 42 static const uint8_t kNalUnitTypeSeqParamSet = 0x07; 43 static const uint8_t kNalUnitTypePicParamSet = 0x08; 44 45 // Using longer adjustment period to suppress fluctuations in 46 // the audio encoding paths 47 static const int64_t kVideoMediaTimeAdjustPeriodTimeUs = 600000000LL; // 10 minutes 48 49 class MPEG4Writer::Track { 50 public: 51 Track(MPEG4Writer *owner, const sp<MediaSource> &source); 52 53 ~Track(); 54 55 status_t start(MetaData *params); 56 status_t stop(); 57 status_t pause(); 58 bool reachedEOS(); 59 60 int64_t getDurationUs() const; 61 int64_t getEstimatedTrackSizeBytes() const; 62 void writeTrackHeader(int32_t trackID, bool use32BitOffset = true); 63 void bufferChunk(int64_t timestampUs); 64 bool isAvc() const { return mIsAvc; } 65 bool isAudio() const { return mIsAudio; } 66 bool isMPEG4() const { return mIsMPEG4; } 67 void addChunkOffset(off_t offset); 68 status_t dump(int fd, const Vector<String16>& args) const; 69 70 private: 71 MPEG4Writer *mOwner; 72 sp<MetaData> mMeta; 73 sp<MediaSource> mSource; 74 volatile bool mDone; 75 volatile bool mPaused; 76 volatile bool mResumed; 77 bool mIsAvc; 78 bool mIsAudio; 79 bool mIsMPEG4; 80 int64_t mTrackDurationUs; 81 82 // For realtime applications, we need to adjust the media clock 83 // for video track based on the audio media clock 84 bool mIsRealTimeRecording; 85 int64_t mMaxTimeStampUs; 86 int64_t mEstimatedTrackSizeBytes; 87 int64_t mMdatSizeBytes; 88 int32_t mTimeScale; 89 90 pthread_t mThread; 91 92 // mNumSamples is used to track how many samples in mSampleSizes List. 93 // This is to reduce the cost associated with mSampleSizes.size() call, 94 // since it is O(n). Ideally, the fix should be in List class. 95 size_t mNumSamples; 96 List<size_t> mSampleSizes; 97 bool mSamplesHaveSameSize; 98 99 List<MediaBuffer *> mChunkSamples; 100 101 size_t mNumStcoTableEntries; 102 List<off_t> mChunkOffsets; 103 104 size_t mNumStscTableEntries; 105 struct StscTableEntry { 106 107 StscTableEntry(uint32_t chunk, uint32_t samples, uint32_t id) 108 : firstChunk(chunk), 109 samplesPerChunk(samples), 110 sampleDescriptionId(id) {} 111 112 uint32_t firstChunk; 113 uint32_t samplesPerChunk; 114 uint32_t sampleDescriptionId; 115 }; 116 List<StscTableEntry> mStscTableEntries; 117 118 size_t mNumStssTableEntries; 119 List<int32_t> mStssTableEntries; 120 121 size_t mNumSttsTableEntries; 122 struct SttsTableEntry { 123 124 SttsTableEntry(uint32_t count, uint32_t durationUs) 125 : sampleCount(count), sampleDurationUs(durationUs) {} 126 127 uint32_t sampleCount; 128 uint32_t sampleDurationUs; 129 }; 130 List<SttsTableEntry> mSttsTableEntries; 131 132 // Sequence parameter set or picture parameter set 133 struct AVCParamSet { 134 AVCParamSet(uint16_t length, const uint8_t *data) 135 : mLength(length), mData(data) {} 136 137 uint16_t mLength; 138 const uint8_t *mData; 139 }; 140 List<AVCParamSet> mSeqParamSets; 141 List<AVCParamSet> mPicParamSets; 142 uint8_t mProfileIdc; 143 uint8_t mProfileCompatible; 144 uint8_t mLevelIdc; 145 146 void *mCodecSpecificData; 147 size_t mCodecSpecificDataSize; 148 bool mGotAllCodecSpecificData; 149 bool mTrackingProgressStatus; 150 151 bool mReachedEOS; 152 int64_t mStartTimestampUs; 153 int64_t mPreviousTrackTimeUs; 154 int64_t mTrackEveryTimeDurationUs; 155 156 // Has the media time adjustment for video started? 157 bool mIsMediaTimeAdjustmentOn; 158 // The time stamp when previous media time adjustment period starts 159 int64_t mPrevMediaTimeAdjustTimestampUs; 160 // Number of vidoe frames whose time stamp may be adjusted 161 int64_t mMediaTimeAdjustNumFrames; 162 // The sample number when previous meida time adjustmnet period starts 163 int64_t mPrevMediaTimeAdjustSample; 164 // The total accumulated drift time within a period of 165 // kVideoMediaTimeAdjustPeriodTimeUs. 166 int64_t mTotalDriftTimeToAdjustUs; 167 // The total accumalated drift time since the start of the recording 168 // excluding the current time adjustment period 169 int64_t mPrevTotalAccumDriftTimeUs; 170 171 // Update the audio track's drift information. 172 void updateDriftTime(const sp<MetaData>& meta); 173 174 // Adjust the time stamp of the video track according to 175 // the drift time information from the audio track. 176 void adjustMediaTime(int64_t *timestampUs); 177 178 static void *ThreadWrapper(void *me); 179 status_t threadEntry(); 180 181 const uint8_t *parseParamSet( 182 const uint8_t *data, size_t length, int type, size_t *paramSetLen); 183 184 status_t makeAVCCodecSpecificData( 185 const uint8_t *data, size_t size); 186 status_t copyAVCCodecSpecificData( 187 const uint8_t *data, size_t size); 188 status_t parseAVCCodecSpecificData( 189 const uint8_t *data, size_t size); 190 191 // Track authoring progress status 192 void trackProgressStatus(int64_t timeUs, status_t err = OK); 193 void initTrackingProgressStatus(MetaData *params); 194 195 void getCodecSpecificDataFromInputFormatIfPossible(); 196 197 // Determine the track time scale 198 // If it is an audio track, try to use the sampling rate as 199 // the time scale; however, if user chooses the overwrite 200 // value, the user-supplied time scale will be used. 201 void setTimeScale(); 202 203 // Simple validation on the codec specific data 204 status_t checkCodecSpecificData() const; 205 int32_t mRotation; 206 207 void updateTrackSizeEstimate(); 208 void addOneStscTableEntry(size_t chunkId, size_t sampleId); 209 void addOneStssTableEntry(size_t sampleId); 210 void addOneSttsTableEntry(size_t sampleCount, int64_t durationUs); 211 212 Track(const Track &); 213 Track &operator=(const Track &); 214 }; 215 216 MPEG4Writer::MPEG4Writer(const char *filename) 217 : mFile(fopen(filename, "wb")), 218 mUse4ByteNalLength(true), 219 mUse32BitOffset(true), 220 mIsFileSizeLimitExplicitlyRequested(false), 221 mPaused(false), 222 mStarted(false), 223 mOffset(0), 224 mMdatOffset(0), 225 mEstimatedMoovBoxSize(0), 226 mInterleaveDurationUs(1000000) { 227 CHECK(mFile != NULL); 228 } 229 230 MPEG4Writer::MPEG4Writer(int fd) 231 : mFile(fdopen(fd, "wb")), 232 mUse4ByteNalLength(true), 233 mUse32BitOffset(true), 234 mIsFileSizeLimitExplicitlyRequested(false), 235 mPaused(false), 236 mStarted(false), 237 mOffset(0), 238 mMdatOffset(0), 239 mEstimatedMoovBoxSize(0), 240 mInterleaveDurationUs(1000000) { 241 CHECK(mFile != NULL); 242 } 243 244 MPEG4Writer::~MPEG4Writer() { 245 stop(); 246 247 while (!mTracks.empty()) { 248 List<Track *>::iterator it = mTracks.begin(); 249 delete *it; 250 (*it) = NULL; 251 mTracks.erase(it); 252 } 253 mTracks.clear(); 254 } 255 256 status_t MPEG4Writer::dump( 257 int fd, const Vector<String16>& args) { 258 const size_t SIZE = 256; 259 char buffer[SIZE]; 260 String8 result; 261 snprintf(buffer, SIZE, " MPEG4Writer %p\n", this); 262 result.append(buffer); 263 snprintf(buffer, SIZE, " mStarted: %s\n", mStarted? "true": "false"); 264 result.append(buffer); 265 ::write(fd, result.string(), result.size()); 266 for (List<Track *>::iterator it = mTracks.begin(); 267 it != mTracks.end(); ++it) { 268 (*it)->dump(fd, args); 269 } 270 return OK; 271 } 272 273 status_t MPEG4Writer::Track::dump( 274 int fd, const Vector<String16>& args) const { 275 const size_t SIZE = 256; 276 char buffer[SIZE]; 277 String8 result; 278 snprintf(buffer, SIZE, " %s track\n", mIsAudio? "Audio": "Video"); 279 result.append(buffer); 280 snprintf(buffer, SIZE, " reached EOS: %s\n", 281 mReachedEOS? "true": "false"); 282 result.append(buffer); 283 ::write(fd, result.string(), result.size()); 284 return OK; 285 } 286 287 status_t MPEG4Writer::addSource(const sp<MediaSource> &source) { 288 Track *track = new Track(this, source); 289 mTracks.push_back(track); 290 291 return OK; 292 } 293 294 status_t MPEG4Writer::startTracks(MetaData *params) { 295 for (List<Track *>::iterator it = mTracks.begin(); 296 it != mTracks.end(); ++it) { 297 status_t err = (*it)->start(params); 298 299 if (err != OK) { 300 for (List<Track *>::iterator it2 = mTracks.begin(); 301 it2 != it; ++it2) { 302 (*it2)->stop(); 303 } 304 305 return err; 306 } 307 } 308 return OK; 309 } 310 311 int64_t MPEG4Writer::estimateMoovBoxSize(int32_t bitRate) { 312 // This implementation is highly experimental/heurisitic. 313 // 314 // Statistical analysis shows that metadata usually accounts 315 // for a small portion of the total file size, usually < 0.6%. 316 317 // The default MIN_MOOV_BOX_SIZE is set to 0.6% x 1MB / 2, 318 // where 1MB is the common file size limit for MMS application. 319 // The default MAX _MOOV_BOX_SIZE value is based on about 3 320 // minute video recording with a bit rate about 3 Mbps, because 321 // statistics also show that most of the video captured are going 322 // to be less than 3 minutes. 323 324 // If the estimation is wrong, we will pay the price of wasting 325 // some reserved space. This should not happen so often statistically. 326 static const int32_t factor = mUse32BitOffset? 1: 2; 327 static const int64_t MIN_MOOV_BOX_SIZE = 3 * 1024; // 3 KB 328 static const int64_t MAX_MOOV_BOX_SIZE = (180 * 3000000 * 6LL / 8000); 329 int64_t size = MIN_MOOV_BOX_SIZE; 330 331 // Max file size limit is set 332 if (mMaxFileSizeLimitBytes != 0 && mIsFileSizeLimitExplicitlyRequested) { 333 size = mMaxFileSizeLimitBytes * 6 / 1000; 334 } 335 336 // Max file duration limit is set 337 if (mMaxFileDurationLimitUs != 0) { 338 if (bitRate > 0) { 339 int64_t size2 = 340 ((mMaxFileDurationLimitUs * bitRate * 6) / 1000 / 8000000); 341 if (mMaxFileSizeLimitBytes != 0 && mIsFileSizeLimitExplicitlyRequested) { 342 // When both file size and duration limits are set, 343 // we use the smaller limit of the two. 344 if (size > size2) { 345 size = size2; 346 } 347 } else { 348 // Only max file duration limit is set 349 size = size2; 350 } 351 } 352 } 353 354 if (size < MIN_MOOV_BOX_SIZE) { 355 size = MIN_MOOV_BOX_SIZE; 356 } 357 358 // Any long duration recording will be probably end up with 359 // non-streamable mp4 file. 360 if (size > MAX_MOOV_BOX_SIZE) { 361 size = MAX_MOOV_BOX_SIZE; 362 } 363 364 LOGI("limits: %lld/%lld bytes/us, bit rate: %d bps and the estimated" 365 " moov size %lld bytes", 366 mMaxFileSizeLimitBytes, mMaxFileDurationLimitUs, bitRate, size); 367 return factor * size; 368 } 369 370 status_t MPEG4Writer::start(MetaData *param) { 371 if (mFile == NULL) { 372 return UNKNOWN_ERROR; 373 } 374 375 /* 376 * Check mMaxFileSizeLimitBytes at the beginning 377 * since mMaxFileSizeLimitBytes may be implicitly 378 * changed later for 32-bit file offset even if 379 * user does not ask to set it explicitly. 380 */ 381 if (mMaxFileSizeLimitBytes != 0) { 382 mIsFileSizeLimitExplicitlyRequested = true; 383 } 384 385 int32_t use64BitOffset; 386 if (param && 387 param->findInt32(kKey64BitFileOffset, &use64BitOffset) && 388 use64BitOffset) { 389 mUse32BitOffset = false; 390 } 391 392 if (mUse32BitOffset) { 393 // Implicit 32 bit file size limit 394 if (mMaxFileSizeLimitBytes == 0) { 395 mMaxFileSizeLimitBytes = kMax32BitFileSize; 396 } 397 398 // If file size is set to be larger than the 32 bit file 399 // size limit, treat it as an error. 400 if (mMaxFileSizeLimitBytes > kMax32BitFileSize) { 401 LOGW("32-bit file size limit (%lld bytes) too big. " 402 "It is changed to %lld bytes", 403 mMaxFileSizeLimitBytes, kMax32BitFileSize); 404 mMaxFileSizeLimitBytes = kMax32BitFileSize; 405 } 406 } 407 408 int32_t use2ByteNalLength; 409 if (param && 410 param->findInt32(kKey2ByteNalLength, &use2ByteNalLength) && 411 use2ByteNalLength) { 412 mUse4ByteNalLength = false; 413 } 414 415 mStartTimestampUs = -1; 416 417 if (mStarted) { 418 if (mPaused) { 419 mPaused = false; 420 return startTracks(param); 421 } 422 return OK; 423 } 424 425 if (!param || 426 !param->findInt32(kKeyTimeScale, &mTimeScale)) { 427 mTimeScale = 1000; 428 } 429 CHECK(mTimeScale > 0); 430 LOGV("movie time scale: %d", mTimeScale); 431 432 mStreamableFile = true; 433 mWriteMoovBoxToMemory = false; 434 mMoovBoxBuffer = NULL; 435 mMoovBoxBufferOffset = 0; 436 437 beginBox("ftyp"); 438 { 439 int32_t fileType; 440 if (param && param->findInt32(kKeyFileType, &fileType) && 441 fileType != OUTPUT_FORMAT_MPEG_4) { 442 writeFourcc("3gp4"); 443 } else { 444 writeFourcc("isom"); 445 } 446 } 447 writeInt32(0); 448 writeFourcc("isom"); 449 writeFourcc("3gp4"); 450 endBox(); 451 452 mFreeBoxOffset = mOffset; 453 454 if (mEstimatedMoovBoxSize == 0) { 455 int32_t bitRate = -1; 456 if (param) { 457 param->findInt32(kKeyBitRate, &bitRate); 458 } 459 mEstimatedMoovBoxSize = estimateMoovBoxSize(bitRate); 460 } 461 CHECK(mEstimatedMoovBoxSize >= 8); 462 fseeko(mFile, mFreeBoxOffset, SEEK_SET); 463 writeInt32(mEstimatedMoovBoxSize); 464 write("free", 4); 465 466 mMdatOffset = mFreeBoxOffset + mEstimatedMoovBoxSize; 467 mOffset = mMdatOffset; 468 fseeko(mFile, mMdatOffset, SEEK_SET); 469 if (mUse32BitOffset) { 470 write("????mdat", 8); 471 } else { 472 write("\x00\x00\x00\x01mdat????????", 16); 473 } 474 475 status_t err = startWriterThread(); 476 if (err != OK) { 477 return err; 478 } 479 480 err = startTracks(param); 481 if (err != OK) { 482 return err; 483 } 484 485 mStarted = true; 486 return OK; 487 } 488 489 bool MPEG4Writer::use32BitFileOffset() const { 490 return mUse32BitOffset; 491 } 492 493 status_t MPEG4Writer::pause() { 494 if (mFile == NULL) { 495 return OK; 496 } 497 mPaused = true; 498 status_t err = OK; 499 for (List<Track *>::iterator it = mTracks.begin(); 500 it != mTracks.end(); ++it) { 501 status_t status = (*it)->pause(); 502 if (status != OK) { 503 err = status; 504 } 505 } 506 return err; 507 } 508 509 void MPEG4Writer::stopWriterThread() { 510 LOGV("stopWriterThread"); 511 512 { 513 Mutex::Autolock autolock(mLock); 514 515 mDone = true; 516 mChunkReadyCondition.signal(); 517 } 518 519 void *dummy; 520 pthread_join(mThread, &dummy); 521 } 522 523 /* 524 * MP4 file standard defines a composition matrix: 525 * | a b u | 526 * | c d v | 527 * | x y w | 528 * 529 * the element in the matrix is stored in the following 530 * order: {a, b, u, c, d, v, x, y, w}, 531 * where a, b, c, d, x, and y is in 16.16 format, while 532 * u, v and w is in 2.30 format. 533 */ 534 void MPEG4Writer::writeCompositionMatrix(int degrees) { 535 LOGV("writeCompositionMatrix"); 536 uint32_t a = 0x00010000; 537 uint32_t b = 0; 538 uint32_t c = 0; 539 uint32_t d = 0x00010000; 540 switch (degrees) { 541 case 0: 542 break; 543 case 90: 544 a = 0; 545 b = 0x00010000; 546 c = 0xFFFF0000; 547 d = 0; 548 break; 549 case 180: 550 a = 0xFFFF0000; 551 d = 0xFFFF0000; 552 break; 553 case 270: 554 a = 0; 555 b = 0xFFFF0000; 556 c = 0x00010000; 557 d = 0; 558 break; 559 default: 560 CHECK(!"Should never reach this unknown rotation"); 561 break; 562 } 563 564 writeInt32(a); // a 565 writeInt32(b); // b 566 writeInt32(0); // u 567 writeInt32(c); // c 568 writeInt32(d); // d 569 writeInt32(0); // v 570 writeInt32(0); // x 571 writeInt32(0); // y 572 writeInt32(0x40000000); // w 573 } 574 575 status_t MPEG4Writer::stop() { 576 if (mFile == NULL) { 577 return OK; 578 } 579 580 status_t err = OK; 581 int64_t maxDurationUs = 0; 582 for (List<Track *>::iterator it = mTracks.begin(); 583 it != mTracks.end(); ++it) { 584 status_t status = (*it)->stop(); 585 if (err == OK && status != OK) { 586 err = status; 587 } 588 589 int64_t durationUs = (*it)->getDurationUs(); 590 if (durationUs > maxDurationUs) { 591 maxDurationUs = durationUs; 592 } 593 } 594 595 stopWriterThread(); 596 597 // Do not write out movie header on error. 598 if (err != OK) { 599 fflush(mFile); 600 fclose(mFile); 601 mFile = NULL; 602 mStarted = false; 603 return err; 604 } 605 606 // Fix up the size of the 'mdat' chunk. 607 if (mUse32BitOffset) { 608 fseeko(mFile, mMdatOffset, SEEK_SET); 609 int32_t size = htonl(static_cast<int32_t>(mOffset - mMdatOffset)); 610 fwrite(&size, 1, 4, mFile); 611 } else { 612 fseeko(mFile, mMdatOffset + 8, SEEK_SET); 613 int64_t size = mOffset - mMdatOffset; 614 size = hton64(size); 615 fwrite(&size, 1, 8, mFile); 616 } 617 fseeko(mFile, mOffset, SEEK_SET); 618 619 time_t now = time(NULL); 620 const off_t moovOffset = mOffset; 621 mWriteMoovBoxToMemory = true; 622 mMoovBoxBuffer = (uint8_t *) malloc(mEstimatedMoovBoxSize); 623 mMoovBoxBufferOffset = 0; 624 CHECK(mMoovBoxBuffer != NULL); 625 int32_t duration = (maxDurationUs * mTimeScale + 5E5) / 1E6; 626 627 beginBox("moov"); 628 629 beginBox("mvhd"); 630 writeInt32(0); // version=0, flags=0 631 writeInt32(now); // creation time 632 writeInt32(now); // modification time 633 writeInt32(mTimeScale); // mvhd timescale 634 writeInt32(duration); 635 writeInt32(0x10000); // rate: 1.0 636 writeInt16(0x100); // volume 637 writeInt16(0); // reserved 638 writeInt32(0); // reserved 639 writeInt32(0); // reserved 640 writeCompositionMatrix(0); 641 writeInt32(0); // predefined 642 writeInt32(0); // predefined 643 writeInt32(0); // predefined 644 writeInt32(0); // predefined 645 writeInt32(0); // predefined 646 writeInt32(0); // predefined 647 writeInt32(mTracks.size() + 1); // nextTrackID 648 endBox(); // mvhd 649 650 int32_t id = 1; 651 for (List<Track *>::iterator it = mTracks.begin(); 652 it != mTracks.end(); ++it, ++id) { 653 (*it)->writeTrackHeader(id, mUse32BitOffset); 654 } 655 endBox(); // moov 656 657 mWriteMoovBoxToMemory = false; 658 if (mStreamableFile) { 659 CHECK(mMoovBoxBufferOffset + 8 <= mEstimatedMoovBoxSize); 660 661 // Moov box 662 fseeko(mFile, mFreeBoxOffset, SEEK_SET); 663 mOffset = mFreeBoxOffset; 664 write(mMoovBoxBuffer, 1, mMoovBoxBufferOffset, mFile); 665 666 // Free box 667 fseeko(mFile, mOffset, SEEK_SET); 668 writeInt32(mEstimatedMoovBoxSize - mMoovBoxBufferOffset); 669 write("free", 4); 670 671 // Free temp memory 672 free(mMoovBoxBuffer); 673 mMoovBoxBuffer = NULL; 674 mMoovBoxBufferOffset = 0; 675 } else { 676 LOGI("The mp4 file will not be streamable."); 677 } 678 679 CHECK(mBoxes.empty()); 680 681 fflush(mFile); 682 fclose(mFile); 683 mFile = NULL; 684 mStarted = false; 685 return err; 686 } 687 688 status_t MPEG4Writer::setInterleaveDuration(uint32_t durationUs) { 689 mInterleaveDurationUs = durationUs; 690 return OK; 691 } 692 693 void MPEG4Writer::lock() { 694 mLock.lock(); 695 } 696 697 void MPEG4Writer::unlock() { 698 mLock.unlock(); 699 } 700 701 off_t MPEG4Writer::addSample_l(MediaBuffer *buffer) { 702 off_t old_offset = mOffset; 703 704 fwrite((const uint8_t *)buffer->data() + buffer->range_offset(), 705 1, buffer->range_length(), mFile); 706 707 mOffset += buffer->range_length(); 708 709 return old_offset; 710 } 711 712 static void StripStartcode(MediaBuffer *buffer) { 713 if (buffer->range_length() < 4) { 714 return; 715 } 716 717 const uint8_t *ptr = 718 (const uint8_t *)buffer->data() + buffer->range_offset(); 719 720 if (!memcmp(ptr, "\x00\x00\x00\x01", 4)) { 721 buffer->set_range( 722 buffer->range_offset() + 4, buffer->range_length() - 4); 723 } 724 } 725 726 off_t MPEG4Writer::addLengthPrefixedSample_l(MediaBuffer *buffer) { 727 off_t old_offset = mOffset; 728 729 size_t length = buffer->range_length(); 730 731 if (mUse4ByteNalLength) { 732 uint8_t x = length >> 24; 733 fwrite(&x, 1, 1, mFile); 734 x = (length >> 16) & 0xff; 735 fwrite(&x, 1, 1, mFile); 736 x = (length >> 8) & 0xff; 737 fwrite(&x, 1, 1, mFile); 738 x = length & 0xff; 739 fwrite(&x, 1, 1, mFile); 740 741 fwrite((const uint8_t *)buffer->data() + buffer->range_offset(), 742 1, length, mFile); 743 mOffset += length + 4; 744 } else { 745 CHECK(length < 65536); 746 747 uint8_t x = length >> 8; 748 fwrite(&x, 1, 1, mFile); 749 x = length & 0xff; 750 fwrite(&x, 1, 1, mFile); 751 fwrite((const uint8_t *)buffer->data() + buffer->range_offset(), 752 1, length, mFile); 753 mOffset += length + 2; 754 } 755 756 return old_offset; 757 } 758 759 size_t MPEG4Writer::write( 760 const void *ptr, size_t size, size_t nmemb, FILE *stream) { 761 762 const size_t bytes = size * nmemb; 763 if (mWriteMoovBoxToMemory) { 764 off_t moovBoxSize = 8 + mMoovBoxBufferOffset + bytes; 765 if (moovBoxSize > mEstimatedMoovBoxSize) { 766 for (List<off_t>::iterator it = mBoxes.begin(); 767 it != mBoxes.end(); ++it) { 768 (*it) += mOffset; 769 } 770 fseeko(mFile, mOffset, SEEK_SET); 771 fwrite(mMoovBoxBuffer, 1, mMoovBoxBufferOffset, stream); 772 fwrite(ptr, size, nmemb, stream); 773 mOffset += (bytes + mMoovBoxBufferOffset); 774 free(mMoovBoxBuffer); 775 mMoovBoxBuffer = NULL; 776 mMoovBoxBufferOffset = 0; 777 mWriteMoovBoxToMemory = false; 778 mStreamableFile = false; 779 } else { 780 memcpy(mMoovBoxBuffer + mMoovBoxBufferOffset, ptr, bytes); 781 mMoovBoxBufferOffset += bytes; 782 } 783 } else { 784 fwrite(ptr, size, nmemb, stream); 785 mOffset += bytes; 786 } 787 return bytes; 788 } 789 790 void MPEG4Writer::beginBox(const char *fourcc) { 791 CHECK_EQ(strlen(fourcc), 4); 792 793 mBoxes.push_back(mWriteMoovBoxToMemory? 794 mMoovBoxBufferOffset: mOffset); 795 796 writeInt32(0); 797 writeFourcc(fourcc); 798 } 799 800 void MPEG4Writer::endBox() { 801 CHECK(!mBoxes.empty()); 802 803 off_t offset = *--mBoxes.end(); 804 mBoxes.erase(--mBoxes.end()); 805 806 if (mWriteMoovBoxToMemory) { 807 int32_t x = htonl(mMoovBoxBufferOffset - offset); 808 memcpy(mMoovBoxBuffer + offset, &x, 4); 809 } else { 810 fseeko(mFile, offset, SEEK_SET); 811 writeInt32(mOffset - offset); 812 mOffset -= 4; 813 fseeko(mFile, mOffset, SEEK_SET); 814 } 815 } 816 817 void MPEG4Writer::writeInt8(int8_t x) { 818 write(&x, 1, 1, mFile); 819 } 820 821 void MPEG4Writer::writeInt16(int16_t x) { 822 x = htons(x); 823 write(&x, 1, 2, mFile); 824 } 825 826 void MPEG4Writer::writeInt32(int32_t x) { 827 x = htonl(x); 828 write(&x, 1, 4, mFile); 829 } 830 831 void MPEG4Writer::writeInt64(int64_t x) { 832 x = hton64(x); 833 write(&x, 1, 8, mFile); 834 } 835 836 void MPEG4Writer::writeCString(const char *s) { 837 size_t n = strlen(s); 838 write(s, 1, n + 1, mFile); 839 } 840 841 void MPEG4Writer::writeFourcc(const char *s) { 842 CHECK_EQ(strlen(s), 4); 843 write(s, 1, 4, mFile); 844 } 845 846 void MPEG4Writer::write(const void *data, size_t size) { 847 write(data, 1, size, mFile); 848 } 849 850 bool MPEG4Writer::isFileStreamable() const { 851 return mStreamableFile; 852 } 853 854 bool MPEG4Writer::exceedsFileSizeLimit() { 855 // No limit 856 if (mMaxFileSizeLimitBytes == 0) { 857 return false; 858 } 859 860 int64_t nTotalBytesEstimate = static_cast<int64_t>(mEstimatedMoovBoxSize); 861 for (List<Track *>::iterator it = mTracks.begin(); 862 it != mTracks.end(); ++it) { 863 nTotalBytesEstimate += (*it)->getEstimatedTrackSizeBytes(); 864 } 865 866 return (nTotalBytesEstimate >= mMaxFileSizeLimitBytes); 867 } 868 869 bool MPEG4Writer::exceedsFileDurationLimit() { 870 // No limit 871 if (mMaxFileDurationLimitUs == 0) { 872 return false; 873 } 874 875 for (List<Track *>::iterator it = mTracks.begin(); 876 it != mTracks.end(); ++it) { 877 if ((*it)->getDurationUs() >= mMaxFileDurationLimitUs) { 878 return true; 879 } 880 } 881 return false; 882 } 883 884 bool MPEG4Writer::reachedEOS() { 885 bool allDone = true; 886 for (List<Track *>::iterator it = mTracks.begin(); 887 it != mTracks.end(); ++it) { 888 if (!(*it)->reachedEOS()) { 889 allDone = false; 890 break; 891 } 892 } 893 894 return allDone; 895 } 896 897 void MPEG4Writer::setStartTimestampUs(int64_t timeUs) { 898 LOGI("setStartTimestampUs: %lld", timeUs); 899 CHECK(timeUs >= 0); 900 Mutex::Autolock autoLock(mLock); 901 if (mStartTimestampUs < 0 || mStartTimestampUs > timeUs) { 902 mStartTimestampUs = timeUs; 903 LOGI("Earliest track starting time: %lld", mStartTimestampUs); 904 } 905 } 906 907 int64_t MPEG4Writer::getStartTimestampUs() { 908 Mutex::Autolock autoLock(mLock); 909 return mStartTimestampUs; 910 } 911 912 size_t MPEG4Writer::numTracks() { 913 Mutex::Autolock autolock(mLock); 914 return mTracks.size(); 915 } 916 917 //////////////////////////////////////////////////////////////////////////////// 918 919 MPEG4Writer::Track::Track( 920 MPEG4Writer *owner, const sp<MediaSource> &source) 921 : mOwner(owner), 922 mMeta(source->getFormat()), 923 mSource(source), 924 mDone(false), 925 mPaused(false), 926 mResumed(false), 927 mTrackDurationUs(0), 928 mEstimatedTrackSizeBytes(0), 929 mSamplesHaveSameSize(true), 930 mCodecSpecificData(NULL), 931 mCodecSpecificDataSize(0), 932 mGotAllCodecSpecificData(false), 933 mReachedEOS(false), 934 mRotation(0) { 935 getCodecSpecificDataFromInputFormatIfPossible(); 936 937 const char *mime; 938 mMeta->findCString(kKeyMIMEType, &mime); 939 mIsAvc = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 940 mIsAudio = !strncasecmp(mime, "audio/", 6); 941 mIsMPEG4 = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) || 942 !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC); 943 944 setTimeScale(); 945 } 946 947 void MPEG4Writer::Track::updateTrackSizeEstimate() { 948 949 int64_t stcoBoxSizeBytes = mOwner->use32BitFileOffset() 950 ? mNumStcoTableEntries * 4 951 : mNumStcoTableEntries * 8; 952 953 int64_t stszBoxSizeBytes = mSamplesHaveSameSize? 4: (mNumSamples * 4); 954 955 mEstimatedTrackSizeBytes = mMdatSizeBytes; // media data size 956 if (!mOwner->isFileStreamable()) { 957 // Reserved free space is not large enough to hold 958 // all meta data and thus wasted. 959 mEstimatedTrackSizeBytes += mNumStscTableEntries * 12 + // stsc box size 960 mNumStssTableEntries * 4 + // stss box size 961 mNumSttsTableEntries * 8 + // stts box size 962 stcoBoxSizeBytes + // stco box size 963 stszBoxSizeBytes; // stsz box size 964 } 965 } 966 967 void MPEG4Writer::Track::addOneStscTableEntry( 968 size_t chunkId, size_t sampleId) { 969 970 StscTableEntry stscEntry(chunkId, sampleId, 1); 971 mStscTableEntries.push_back(stscEntry); 972 ++mNumStscTableEntries; 973 } 974 975 void MPEG4Writer::Track::addOneStssTableEntry(size_t sampleId) { 976 mStssTableEntries.push_back(sampleId); 977 ++mNumStssTableEntries; 978 } 979 980 void MPEG4Writer::Track::addOneSttsTableEntry( 981 size_t sampleCount, int64_t durationUs) { 982 983 SttsTableEntry sttsEntry(sampleCount, durationUs); 984 mSttsTableEntries.push_back(sttsEntry); 985 ++mNumSttsTableEntries; 986 } 987 988 void MPEG4Writer::Track::addChunkOffset(off_t offset) { 989 ++mNumStcoTableEntries; 990 mChunkOffsets.push_back(offset); 991 } 992 993 void MPEG4Writer::Track::setTimeScale() { 994 LOGV("setTimeScale"); 995 // Default time scale 996 mTimeScale = 90000; 997 998 if (mIsAudio) { 999 // Use the sampling rate as the default time scale for audio track. 1000 int32_t sampleRate; 1001 bool success = mMeta->findInt32(kKeySampleRate, &sampleRate); 1002 CHECK(success); 1003 mTimeScale = sampleRate; 1004 } 1005 1006 // If someone would like to overwrite the timescale, use user-supplied value. 1007 int32_t timeScale; 1008 if (mMeta->findInt32(kKeyTimeScale, &timeScale)) { 1009 mTimeScale = timeScale; 1010 } 1011 1012 CHECK(mTimeScale > 0); 1013 } 1014 1015 void MPEG4Writer::Track::getCodecSpecificDataFromInputFormatIfPossible() { 1016 const char *mime; 1017 CHECK(mMeta->findCString(kKeyMIMEType, &mime)); 1018 1019 if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 1020 uint32_t type; 1021 const void *data; 1022 size_t size; 1023 if (mMeta->findData(kKeyAVCC, &type, &data, &size)) { 1024 mCodecSpecificData = malloc(size); 1025 mCodecSpecificDataSize = size; 1026 memcpy(mCodecSpecificData, data, size); 1027 mGotAllCodecSpecificData = true; 1028 } 1029 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) 1030 || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 1031 uint32_t type; 1032 const void *data; 1033 size_t size; 1034 if (mMeta->findData(kKeyESDS, &type, &data, &size)) { 1035 ESDS esds(data, size); 1036 if (esds.getCodecSpecificInfo(&data, &size) == OK) { 1037 mCodecSpecificData = malloc(size); 1038 mCodecSpecificDataSize = size; 1039 memcpy(mCodecSpecificData, data, size); 1040 mGotAllCodecSpecificData = true; 1041 } 1042 } 1043 } 1044 } 1045 1046 MPEG4Writer::Track::~Track() { 1047 stop(); 1048 1049 if (mCodecSpecificData != NULL) { 1050 free(mCodecSpecificData); 1051 mCodecSpecificData = NULL; 1052 } 1053 } 1054 1055 void MPEG4Writer::Track::initTrackingProgressStatus(MetaData *params) { 1056 LOGV("initTrackingProgressStatus"); 1057 mPreviousTrackTimeUs = -1; 1058 mTrackingProgressStatus = false; 1059 mTrackEveryTimeDurationUs = 0; 1060 { 1061 int64_t timeUs; 1062 if (params && params->findInt64(kKeyTrackTimeStatus, &timeUs)) { 1063 LOGV("Receive request to track progress status for every %lld us", timeUs); 1064 mTrackEveryTimeDurationUs = timeUs; 1065 mTrackingProgressStatus = true; 1066 } 1067 } 1068 } 1069 1070 // static 1071 void *MPEG4Writer::ThreadWrapper(void *me) { 1072 LOGV("ThreadWrapper: %p", me); 1073 MPEG4Writer *writer = static_cast<MPEG4Writer *>(me); 1074 writer->threadFunc(); 1075 return NULL; 1076 } 1077 1078 void MPEG4Writer::bufferChunk(const Chunk& chunk) { 1079 LOGV("bufferChunk: %p", chunk.mTrack); 1080 Mutex::Autolock autolock(mLock); 1081 CHECK_EQ(mDone, false); 1082 1083 for (List<ChunkInfo>::iterator it = mChunkInfos.begin(); 1084 it != mChunkInfos.end(); ++it) { 1085 1086 if (chunk.mTrack == it->mTrack) { // Found owner 1087 it->mChunks.push_back(chunk); 1088 mChunkReadyCondition.signal(); 1089 return; 1090 } 1091 } 1092 1093 CHECK("Received a chunk for a unknown track" == 0); 1094 } 1095 1096 void MPEG4Writer::writeFirstChunk(ChunkInfo* info) { 1097 LOGV("writeFirstChunk: %p", info->mTrack); 1098 1099 List<Chunk>::iterator chunkIt = info->mChunks.begin(); 1100 for (List<MediaBuffer *>::iterator it = chunkIt->mSamples.begin(); 1101 it != chunkIt->mSamples.end(); ++it) { 1102 1103 off_t offset = info->mTrack->isAvc() 1104 ? addLengthPrefixedSample_l(*it) 1105 : addSample_l(*it); 1106 if (it == chunkIt->mSamples.begin()) { 1107 info->mTrack->addChunkOffset(offset); 1108 } 1109 } 1110 1111 // Done with the current chunk. 1112 // Release all the samples in this chunk. 1113 while (!chunkIt->mSamples.empty()) { 1114 List<MediaBuffer *>::iterator it = chunkIt->mSamples.begin(); 1115 (*it)->release(); 1116 (*it) = NULL; 1117 chunkIt->mSamples.erase(it); 1118 } 1119 chunkIt->mSamples.clear(); 1120 info->mChunks.erase(chunkIt); 1121 } 1122 1123 void MPEG4Writer::writeChunks() { 1124 LOGV("writeChunks"); 1125 size_t outstandingChunks = 0; 1126 while (!mChunkInfos.empty()) { 1127 List<ChunkInfo>::iterator it = mChunkInfos.begin(); 1128 while (!it->mChunks.empty()) { 1129 CHECK_EQ(OK, writeOneChunk()); 1130 ++outstandingChunks; 1131 } 1132 it->mTrack = NULL; 1133 mChunkInfos.erase(it); 1134 } 1135 mChunkInfos.clear(); 1136 LOGD("%d chunks are written in the last batch", outstandingChunks); 1137 } 1138 1139 status_t MPEG4Writer::writeOneChunk() { 1140 LOGV("writeOneChunk"); 1141 1142 // Find the smallest timestamp, and write that chunk out 1143 // XXX: What if some track is just too slow? 1144 int64_t minTimestampUs = 0x7FFFFFFFFFFFFFFFLL; 1145 Track *track = NULL; 1146 for (List<ChunkInfo>::iterator it = mChunkInfos.begin(); 1147 it != mChunkInfos.end(); ++it) { 1148 if (!it->mChunks.empty()) { 1149 List<Chunk>::iterator chunkIt = it->mChunks.begin(); 1150 if (chunkIt->mTimeStampUs < minTimestampUs) { 1151 minTimestampUs = chunkIt->mTimeStampUs; 1152 track = it->mTrack; 1153 } 1154 } 1155 } 1156 1157 if (track == NULL) { 1158 LOGV("Nothing to be written after all"); 1159 return OK; 1160 } 1161 1162 if (mIsFirstChunk) { 1163 mIsFirstChunk = false; 1164 } 1165 for (List<ChunkInfo>::iterator it = mChunkInfos.begin(); 1166 it != mChunkInfos.end(); ++it) { 1167 if (it->mTrack == track) { 1168 writeFirstChunk(&(*it)); 1169 } 1170 } 1171 return OK; 1172 } 1173 1174 void MPEG4Writer::threadFunc() { 1175 LOGV("threadFunc"); 1176 1177 prctl(PR_SET_NAME, (unsigned long)"MPEG4Writer", 0, 0, 0); 1178 while (!mDone) { 1179 { 1180 Mutex::Autolock autolock(mLock); 1181 mChunkReadyCondition.wait(mLock); 1182 CHECK_EQ(writeOneChunk(), OK); 1183 } 1184 } 1185 1186 { 1187 // Write ALL samples 1188 Mutex::Autolock autolock(mLock); 1189 writeChunks(); 1190 } 1191 } 1192 1193 status_t MPEG4Writer::startWriterThread() { 1194 LOGV("startWriterThread"); 1195 1196 mDone = false; 1197 mIsFirstChunk = true; 1198 mDriftTimeUs = 0; 1199 for (List<Track *>::iterator it = mTracks.begin(); 1200 it != mTracks.end(); ++it) { 1201 ChunkInfo info; 1202 info.mTrack = *it; 1203 mChunkInfos.push_back(info); 1204 } 1205 1206 pthread_attr_t attr; 1207 pthread_attr_init(&attr); 1208 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 1209 pthread_create(&mThread, &attr, ThreadWrapper, this); 1210 pthread_attr_destroy(&attr); 1211 return OK; 1212 } 1213 1214 1215 status_t MPEG4Writer::Track::start(MetaData *params) { 1216 if (!mDone && mPaused) { 1217 mPaused = false; 1218 mResumed = true; 1219 return OK; 1220 } 1221 1222 int64_t startTimeUs; 1223 if (params == NULL || !params->findInt64(kKeyTime, &startTimeUs)) { 1224 startTimeUs = 0; 1225 } 1226 1227 int32_t rotationDegrees; 1228 if (!mIsAudio && params && params->findInt32(kKeyRotationDegree, &rotationDegrees)) { 1229 mRotation = rotationDegrees; 1230 } 1231 1232 mIsRealTimeRecording = true; 1233 { 1234 int32_t isNotRealTime; 1235 if (params && params->findInt32(kKeyNotRealTime, &isNotRealTime)) { 1236 mIsRealTimeRecording = (isNotRealTime == 0); 1237 } 1238 } 1239 1240 initTrackingProgressStatus(params); 1241 1242 sp<MetaData> meta = new MetaData; 1243 meta->setInt64(kKeyTime, startTimeUs); 1244 status_t err = mSource->start(meta.get()); 1245 if (err != OK) { 1246 mDone = mReachedEOS = true; 1247 return err; 1248 } 1249 1250 pthread_attr_t attr; 1251 pthread_attr_init(&attr); 1252 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 1253 1254 mDone = false; 1255 mTrackDurationUs = 0; 1256 mReachedEOS = false; 1257 mEstimatedTrackSizeBytes = 0; 1258 mNumStcoTableEntries = 0; 1259 mNumStssTableEntries = 0; 1260 mNumStscTableEntries = 0; 1261 mNumSttsTableEntries = 0; 1262 mMdatSizeBytes = 0; 1263 mIsMediaTimeAdjustmentOn = false; 1264 mPrevMediaTimeAdjustTimestampUs = 0; 1265 mMediaTimeAdjustNumFrames = 0; 1266 mPrevMediaTimeAdjustSample = 0; 1267 mTotalDriftTimeToAdjustUs = 0; 1268 mPrevTotalAccumDriftTimeUs = 0; 1269 1270 pthread_create(&mThread, &attr, ThreadWrapper, this); 1271 pthread_attr_destroy(&attr); 1272 1273 return OK; 1274 } 1275 1276 status_t MPEG4Writer::Track::pause() { 1277 mPaused = true; 1278 return OK; 1279 } 1280 1281 status_t MPEG4Writer::Track::stop() { 1282 if (mDone) { 1283 return OK; 1284 } 1285 1286 mDone = true; 1287 1288 void *dummy; 1289 pthread_join(mThread, &dummy); 1290 1291 status_t err = (status_t) dummy; 1292 1293 { 1294 status_t status = mSource->stop(); 1295 if (err == OK && status != OK && status != ERROR_END_OF_STREAM) { 1296 err = status; 1297 } 1298 } 1299 1300 return err; 1301 } 1302 1303 bool MPEG4Writer::Track::reachedEOS() { 1304 return mReachedEOS; 1305 } 1306 1307 // static 1308 void *MPEG4Writer::Track::ThreadWrapper(void *me) { 1309 Track *track = static_cast<Track *>(me); 1310 1311 status_t err = track->threadEntry(); 1312 return (void *) err; 1313 } 1314 1315 static void getNalUnitType(uint8_t byte, uint8_t* type) { 1316 LOGV("getNalUnitType: %d", byte); 1317 1318 // nal_unit_type: 5-bit unsigned integer 1319 *type = (byte & 0x1F); 1320 } 1321 1322 static const uint8_t *findNextStartCode( 1323 const uint8_t *data, size_t length) { 1324 1325 LOGV("findNextStartCode: %p %d", data, length); 1326 1327 size_t bytesLeft = length; 1328 while (bytesLeft > 4 && 1329 memcmp("\x00\x00\x00\x01", &data[length - bytesLeft], 4)) { 1330 --bytesLeft; 1331 } 1332 if (bytesLeft <= 4) { 1333 bytesLeft = 0; // Last parameter set 1334 } 1335 return &data[length - bytesLeft]; 1336 } 1337 1338 const uint8_t *MPEG4Writer::Track::parseParamSet( 1339 const uint8_t *data, size_t length, int type, size_t *paramSetLen) { 1340 1341 LOGV("parseParamSet"); 1342 CHECK(type == kNalUnitTypeSeqParamSet || 1343 type == kNalUnitTypePicParamSet); 1344 1345 const uint8_t *nextStartCode = findNextStartCode(data, length); 1346 *paramSetLen = nextStartCode - data; 1347 if (*paramSetLen == 0) { 1348 LOGE("Param set is malformed, since its length is 0"); 1349 return NULL; 1350 } 1351 1352 AVCParamSet paramSet(*paramSetLen, data); 1353 if (type == kNalUnitTypeSeqParamSet) { 1354 if (*paramSetLen < 4) { 1355 LOGE("Seq parameter set malformed"); 1356 return NULL; 1357 } 1358 if (mSeqParamSets.empty()) { 1359 mProfileIdc = data[1]; 1360 mProfileCompatible = data[2]; 1361 mLevelIdc = data[3]; 1362 } else { 1363 if (mProfileIdc != data[1] || 1364 mProfileCompatible != data[2] || 1365 mLevelIdc != data[3]) { 1366 LOGE("Inconsistent profile/level found in seq parameter sets"); 1367 return NULL; 1368 } 1369 } 1370 mSeqParamSets.push_back(paramSet); 1371 } else { 1372 mPicParamSets.push_back(paramSet); 1373 } 1374 return nextStartCode; 1375 } 1376 1377 status_t MPEG4Writer::Track::copyAVCCodecSpecificData( 1378 const uint8_t *data, size_t size) { 1379 LOGV("copyAVCCodecSpecificData"); 1380 1381 // 2 bytes for each of the parameter set length field 1382 // plus the 7 bytes for the header 1383 if (size < 4 + 7) { 1384 LOGE("Codec specific data length too short: %d", size); 1385 return ERROR_MALFORMED; 1386 } 1387 1388 mCodecSpecificDataSize = size; 1389 mCodecSpecificData = malloc(size); 1390 memcpy(mCodecSpecificData, data, size); 1391 return OK; 1392 } 1393 1394 status_t MPEG4Writer::Track::parseAVCCodecSpecificData( 1395 const uint8_t *data, size_t size) { 1396 1397 LOGV("parseAVCCodecSpecificData"); 1398 // Data starts with a start code. 1399 // SPS and PPS are separated with start codes. 1400 // Also, SPS must come before PPS 1401 uint8_t type = kNalUnitTypeSeqParamSet; 1402 bool gotSps = false; 1403 bool gotPps = false; 1404 const uint8_t *tmp = data; 1405 const uint8_t *nextStartCode = data; 1406 size_t bytesLeft = size; 1407 size_t paramSetLen = 0; 1408 mCodecSpecificDataSize = 0; 1409 while (bytesLeft > 4 && !memcmp("\x00\x00\x00\x01", tmp, 4)) { 1410 getNalUnitType(*(tmp + 4), &type); 1411 if (type == kNalUnitTypeSeqParamSet) { 1412 if (gotPps) { 1413 LOGE("SPS must come before PPS"); 1414 return ERROR_MALFORMED; 1415 } 1416 if (!gotSps) { 1417 gotSps = true; 1418 } 1419 nextStartCode = parseParamSet(tmp + 4, bytesLeft - 4, type, ¶mSetLen); 1420 } else if (type == kNalUnitTypePicParamSet) { 1421 if (!gotSps) { 1422 LOGE("SPS must come before PPS"); 1423 return ERROR_MALFORMED; 1424 } 1425 if (!gotPps) { 1426 gotPps = true; 1427 } 1428 nextStartCode = parseParamSet(tmp + 4, bytesLeft - 4, type, ¶mSetLen); 1429 } else { 1430 LOGE("Only SPS and PPS Nal units are expected"); 1431 return ERROR_MALFORMED; 1432 } 1433 1434 if (nextStartCode == NULL) { 1435 return ERROR_MALFORMED; 1436 } 1437 1438 // Move on to find the next parameter set 1439 bytesLeft -= nextStartCode - tmp; 1440 tmp = nextStartCode; 1441 mCodecSpecificDataSize += (2 + paramSetLen); 1442 } 1443 1444 { 1445 // Check on the number of seq parameter sets 1446 size_t nSeqParamSets = mSeqParamSets.size(); 1447 if (nSeqParamSets == 0) { 1448 LOGE("Cound not find sequence parameter set"); 1449 return ERROR_MALFORMED; 1450 } 1451 1452 if (nSeqParamSets > 0x1F) { 1453 LOGE("Too many seq parameter sets (%d) found", nSeqParamSets); 1454 return ERROR_MALFORMED; 1455 } 1456 } 1457 1458 { 1459 // Check on the number of pic parameter sets 1460 size_t nPicParamSets = mPicParamSets.size(); 1461 if (nPicParamSets == 0) { 1462 LOGE("Cound not find picture parameter set"); 1463 return ERROR_MALFORMED; 1464 } 1465 if (nPicParamSets > 0xFF) { 1466 LOGE("Too many pic parameter sets (%d) found", nPicParamSets); 1467 return ERROR_MALFORMED; 1468 } 1469 } 1470 1471 { 1472 // Check on the profiles 1473 // These profiles requires additional parameter set extensions 1474 if (mProfileIdc == 100 || mProfileIdc == 110 || 1475 mProfileIdc == 122 || mProfileIdc == 144) { 1476 LOGE("Sorry, no support for profile_idc: %d!", mProfileIdc); 1477 return BAD_VALUE; 1478 } 1479 } 1480 1481 return OK; 1482 } 1483 1484 status_t MPEG4Writer::Track::makeAVCCodecSpecificData( 1485 const uint8_t *data, size_t size) { 1486 1487 if (mCodecSpecificData != NULL) { 1488 LOGE("Already have codec specific data"); 1489 return ERROR_MALFORMED; 1490 } 1491 1492 if (size < 4) { 1493 LOGE("Codec specific data length too short: %d", size); 1494 return ERROR_MALFORMED; 1495 } 1496 1497 // Data is in the form of AVCCodecSpecificData 1498 if (memcmp("\x00\x00\x00\x01", data, 4)) { 1499 return copyAVCCodecSpecificData(data, size); 1500 } 1501 1502 if (parseAVCCodecSpecificData(data, size) != OK) { 1503 return ERROR_MALFORMED; 1504 } 1505 1506 // ISO 14496-15: AVC file format 1507 mCodecSpecificDataSize += 7; // 7 more bytes in the header 1508 mCodecSpecificData = malloc(mCodecSpecificDataSize); 1509 uint8_t *header = (uint8_t *)mCodecSpecificData; 1510 header[0] = 1; // version 1511 header[1] = mProfileIdc; // profile indication 1512 header[2] = mProfileCompatible; // profile compatibility 1513 header[3] = mLevelIdc; 1514 1515 // 6-bit '111111' followed by 2-bit to lengthSizeMinuusOne 1516 if (mOwner->useNalLengthFour()) { 1517 header[4] = 0xfc | 3; // length size == 4 bytes 1518 } else { 1519 header[4] = 0xfc | 1; // length size == 2 bytes 1520 } 1521 1522 // 3-bit '111' followed by 5-bit numSequenceParameterSets 1523 int nSequenceParamSets = mSeqParamSets.size(); 1524 header[5] = 0xe0 | nSequenceParamSets; 1525 header += 6; 1526 for (List<AVCParamSet>::iterator it = mSeqParamSets.begin(); 1527 it != mSeqParamSets.end(); ++it) { 1528 // 16-bit sequence parameter set length 1529 uint16_t seqParamSetLength = it->mLength; 1530 header[0] = seqParamSetLength >> 8; 1531 header[1] = seqParamSetLength & 0xff; 1532 1533 // SPS NAL unit (sequence parameter length bytes) 1534 memcpy(&header[2], it->mData, seqParamSetLength); 1535 header += (2 + seqParamSetLength); 1536 } 1537 1538 // 8-bit nPictureParameterSets 1539 int nPictureParamSets = mPicParamSets.size(); 1540 header[0] = nPictureParamSets; 1541 header += 1; 1542 for (List<AVCParamSet>::iterator it = mPicParamSets.begin(); 1543 it != mPicParamSets.end(); ++it) { 1544 // 16-bit picture parameter set length 1545 uint16_t picParamSetLength = it->mLength; 1546 header[0] = picParamSetLength >> 8; 1547 header[1] = picParamSetLength & 0xff; 1548 1549 // PPS Nal unit (picture parameter set length bytes) 1550 memcpy(&header[2], it->mData, picParamSetLength); 1551 header += (2 + picParamSetLength); 1552 } 1553 1554 return OK; 1555 } 1556 1557 /* 1558 * The video track's media time adjustment for real-time applications 1559 * is described as follows: 1560 * 1561 * First, the media time adjustment is done for every period of 1562 * kVideoMediaTimeAdjustPeriodTimeUs. kVideoMediaTimeAdjustPeriodTimeUs 1563 * is currently a fixed value chosen heuristically. The value of 1564 * kVideoMediaTimeAdjustPeriodTimeUs should not be very large or very small 1565 * for two considerations: on one hand, a relatively large value 1566 * helps reduce large fluctuation of drift time in the audio encoding 1567 * path; while on the other hand, a relatively small value helps keep 1568 * restoring synchronization in audio/video more frequently. Note for the 1569 * very first period of kVideoMediaTimeAdjustPeriodTimeUs, there is 1570 * no media time adjustment for the video track. 1571 * 1572 * Second, the total accumulated audio track time drift found 1573 * in a period of kVideoMediaTimeAdjustPeriodTimeUs is distributed 1574 * over a stream of incoming video frames. The number of video frames 1575 * affected is determined based on the number of recorded video frames 1576 * within the past kVideoMediaTimeAdjustPeriodTimeUs period. 1577 * We choose to distribute the drift time over only a portion 1578 * (rather than all) of the total number of recorded video frames 1579 * in order to make sure that the video track media time adjustment is 1580 * completed for the current period before the next video track media 1581 * time adjustment period starts. Currently, the portion chosen is a 1582 * half (0.5). 1583 * 1584 * Last, various additional checks are performed to ensure that 1585 * the actual audio encoding path does not have too much drift. 1586 * In particular, 1) we want to limit the average incremental time 1587 * adjustment for each video frame to be less than a threshold 1588 * for a single period of kVideoMediaTimeAdjustPeriodTimeUs. 1589 * Currently, the threshold is set to 5 ms. If the average incremental 1590 * media time adjustment for a video frame is larger than the 1591 * threshold, the audio encoding path has too much time drift. 1592 * 2) We also want to limit the total time drift in the audio 1593 * encoding path to be less than a threshold for a period of 1594 * kVideoMediaTimeAdjustPeriodTimeUs. Currently, the threshold 1595 * is 0.5% of kVideoMediaTimeAdjustPeriodTimeUs. If the time drift of 1596 * the audio encoding path is larger than the threshold, the audio 1597 * encoding path has too much time drift. We treat the large time 1598 * drift of the audio encoding path as errors, since there is no 1599 * way to keep audio/video in synchronization for real-time 1600 * applications if the time drift is too large unless we drop some 1601 * video frames, which has its own problems that we don't want 1602 * to get into for the time being. 1603 */ 1604 void MPEG4Writer::Track::adjustMediaTime(int64_t *timestampUs) { 1605 if (*timestampUs - mPrevMediaTimeAdjustTimestampUs >= 1606 kVideoMediaTimeAdjustPeriodTimeUs) { 1607 1608 LOGV("New media time adjustment period at %lld us", *timestampUs); 1609 mIsMediaTimeAdjustmentOn = true; 1610 mMediaTimeAdjustNumFrames = 1611 (mNumSamples - mPrevMediaTimeAdjustSample) >> 1; 1612 1613 mPrevMediaTimeAdjustTimestampUs = *timestampUs; 1614 mPrevMediaTimeAdjustSample = mNumSamples; 1615 int64_t totalAccumDriftTimeUs = mOwner->getDriftTimeUs(); 1616 mTotalDriftTimeToAdjustUs = 1617 totalAccumDriftTimeUs - mPrevTotalAccumDriftTimeUs; 1618 1619 mPrevTotalAccumDriftTimeUs = totalAccumDriftTimeUs; 1620 1621 // Check on incremental adjusted time per frame 1622 int64_t adjustTimePerFrameUs = 1623 mTotalDriftTimeToAdjustUs / mMediaTimeAdjustNumFrames; 1624 1625 if (adjustTimePerFrameUs < 0) { 1626 adjustTimePerFrameUs = -adjustTimePerFrameUs; 1627 } 1628 if (adjustTimePerFrameUs >= 5000) { 1629 LOGE("Adjusted time per video frame is %lld us", 1630 adjustTimePerFrameUs); 1631 CHECK(!"Video frame time adjustment is too large!"); 1632 } 1633 1634 // Check on total accumulated time drift within a period of 1635 // kVideoMediaTimeAdjustPeriodTimeUs. 1636 int64_t driftPercentage = (mTotalDriftTimeToAdjustUs * 1000) 1637 / kVideoMediaTimeAdjustPeriodTimeUs; 1638 1639 if (driftPercentage < 0) { 1640 driftPercentage = -driftPercentage; 1641 } 1642 if (driftPercentage > 5) { 1643 LOGE("Audio track has time drift %lld us over %lld us", 1644 mTotalDriftTimeToAdjustUs, 1645 kVideoMediaTimeAdjustPeriodTimeUs); 1646 1647 CHECK(!"The audio track media time drifts too much!"); 1648 } 1649 1650 } 1651 1652 if (mIsMediaTimeAdjustmentOn) { 1653 if (mNumSamples - mPrevMediaTimeAdjustSample <= 1654 mMediaTimeAdjustNumFrames) { 1655 1656 // Do media time incremental adjustment 1657 int64_t incrementalAdjustTimeUs = 1658 (mTotalDriftTimeToAdjustUs * 1659 (mNumSamples - mPrevMediaTimeAdjustSample)) 1660 / mMediaTimeAdjustNumFrames; 1661 1662 *timestampUs += 1663 (incrementalAdjustTimeUs + mPrevTotalAccumDriftTimeUs); 1664 1665 LOGV("Incremental video frame media time adjustment: %lld us", 1666 (incrementalAdjustTimeUs + mPrevTotalAccumDriftTimeUs)); 1667 } else { 1668 // Within the remaining adjustment period, 1669 // no incremental adjustment is needed. 1670 *timestampUs += 1671 (mTotalDriftTimeToAdjustUs + mPrevTotalAccumDriftTimeUs); 1672 1673 LOGV("Fixed video frame media time adjustment: %lld us", 1674 (mTotalDriftTimeToAdjustUs + mPrevTotalAccumDriftTimeUs)); 1675 } 1676 } 1677 } 1678 1679 /* 1680 * Updates the drift time from the audio track so that 1681 * the video track can get the updated drift time information 1682 * from the file writer. The fluctuation of the drift time of the audio 1683 * encoding path is smoothed out with a simple filter by giving a larger 1684 * weight to more recently drift time. The filter coefficients, 0.5 and 0.5, 1685 * are heuristically determined. 1686 */ 1687 void MPEG4Writer::Track::updateDriftTime(const sp<MetaData>& meta) { 1688 int64_t driftTimeUs = 0; 1689 if (meta->findInt64(kKeyDriftTime, &driftTimeUs)) { 1690 int64_t prevDriftTimeUs = mOwner->getDriftTimeUs(); 1691 int64_t timeUs = (driftTimeUs + prevDriftTimeUs) >> 1; 1692 mOwner->setDriftTimeUs(timeUs); 1693 } 1694 } 1695 1696 status_t MPEG4Writer::Track::threadEntry() { 1697 int32_t count = 0; 1698 const int64_t interleaveDurationUs = mOwner->interleaveDuration(); 1699 int64_t chunkTimestampUs = 0; 1700 int32_t nChunks = 0; 1701 int32_t nZeroLengthFrames = 0; 1702 int64_t lastTimestampUs = 0; // Previous sample time stamp in ms 1703 int64_t lastDurationUs = 0; // Between the previous two samples in ms 1704 int64_t currDurationTicks = 0; // Timescale based ticks 1705 int64_t lastDurationTicks = 0; // Timescale based ticks 1706 int32_t sampleCount = 1; // Sample count in the current stts table entry 1707 uint32_t previousSampleSize = 0; // Size of the previous sample 1708 int64_t previousPausedDurationUs = 0; 1709 int64_t timestampUs; 1710 1711 if (mIsAudio) { 1712 prctl(PR_SET_NAME, (unsigned long)"AudioTrackEncoding", 0, 0, 0); 1713 } else { 1714 prctl(PR_SET_NAME, (unsigned long)"VideoTrackEncoding", 0, 0, 0); 1715 } 1716 sp<MetaData> meta_data; 1717 1718 mNumSamples = 0; 1719 status_t err = OK; 1720 MediaBuffer *buffer; 1721 while (!mDone && (err = mSource->read(&buffer)) == OK) { 1722 if (buffer->range_length() == 0) { 1723 buffer->release(); 1724 buffer = NULL; 1725 ++nZeroLengthFrames; 1726 continue; 1727 } 1728 1729 // If the codec specific data has not been received yet, delay pause. 1730 // After the codec specific data is received, discard what we received 1731 // when the track is to be paused. 1732 if (mPaused && !mResumed) { 1733 buffer->release(); 1734 buffer = NULL; 1735 continue; 1736 } 1737 1738 ++count; 1739 1740 int32_t isCodecConfig; 1741 if (buffer->meta_data()->findInt32(kKeyIsCodecConfig, &isCodecConfig) 1742 && isCodecConfig) { 1743 CHECK(!mGotAllCodecSpecificData); 1744 1745 if (mIsAvc) { 1746 status_t err = makeAVCCodecSpecificData( 1747 (const uint8_t *)buffer->data() 1748 + buffer->range_offset(), 1749 buffer->range_length()); 1750 CHECK_EQ(OK, err); 1751 } else if (mIsMPEG4) { 1752 mCodecSpecificDataSize = buffer->range_length(); 1753 mCodecSpecificData = malloc(mCodecSpecificDataSize); 1754 memcpy(mCodecSpecificData, 1755 (const uint8_t *)buffer->data() 1756 + buffer->range_offset(), 1757 buffer->range_length()); 1758 } 1759 1760 buffer->release(); 1761 buffer = NULL; 1762 1763 mGotAllCodecSpecificData = true; 1764 continue; 1765 } 1766 1767 // Make a deep copy of the MediaBuffer and Metadata and release 1768 // the original as soon as we can 1769 MediaBuffer *copy = new MediaBuffer(buffer->range_length()); 1770 memcpy(copy->data(), (uint8_t *)buffer->data() + buffer->range_offset(), 1771 buffer->range_length()); 1772 copy->set_range(0, buffer->range_length()); 1773 meta_data = new MetaData(*buffer->meta_data().get()); 1774 buffer->release(); 1775 buffer = NULL; 1776 1777 if (mIsAvc) StripStartcode(copy); 1778 1779 size_t sampleSize = copy->range_length(); 1780 if (mIsAvc) { 1781 if (mOwner->useNalLengthFour()) { 1782 sampleSize += 4; 1783 } else { 1784 sampleSize += 2; 1785 } 1786 } 1787 1788 // Max file size or duration handling 1789 mMdatSizeBytes += sampleSize; 1790 updateTrackSizeEstimate(); 1791 1792 if (mOwner->exceedsFileSizeLimit()) { 1793 mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED, 0); 1794 break; 1795 } 1796 if (mOwner->exceedsFileDurationLimit()) { 1797 mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_DURATION_REACHED, 0); 1798 break; 1799 } 1800 1801 1802 int32_t isSync = false; 1803 meta_data->findInt32(kKeyIsSyncFrame, &isSync); 1804 1805 /* 1806 * The original timestamp found in the data buffer will be modified as below: 1807 * 1808 * There is a playback offset into this track if the track's start time 1809 * is not the same as the movie start time, which will be recorded in edst 1810 * box of the output file. The playback offset is to make sure that the 1811 * starting time of the audio/video tracks are synchronized. Although the 1812 * track's media timestamp may be subject to various modifications 1813 * as outlined below, the track's playback offset time remains unchanged 1814 * once the first data buffer of the track is received. 1815 * 1816 * The media time stamp will be calculated by subtracting the playback offset 1817 * (and potential pause durations) from the original timestamp in the buffer. 1818 * 1819 * If this track is a video track for a real-time recording application with 1820 * both audio and video tracks, its media timestamp will subject to further 1821 * modification based on the media clock of the audio track. This modification 1822 * is needed for the purpose of maintaining good audio/video synchronization. 1823 * 1824 * If the recording session is paused and resumed multiple times, the track 1825 * media timestamp will be modified as if the recording session had never been 1826 * paused at all during playback of the recorded output file. In other words, 1827 * the output file will have no memory of pause/resume durations. 1828 * 1829 */ 1830 CHECK(meta_data->findInt64(kKeyTime, ×tampUs)); 1831 LOGV("%s timestampUs: %lld", mIsAudio? "Audio": "Video", timestampUs); 1832 1833 //////////////////////////////////////////////////////////////////////////////// 1834 if (mSampleSizes.empty()) { 1835 mStartTimestampUs = timestampUs; 1836 mOwner->setStartTimestampUs(mStartTimestampUs); 1837 previousPausedDurationUs = mStartTimestampUs; 1838 } 1839 1840 if (mResumed) { 1841 int64_t durExcludingEarlierPausesUs = timestampUs - previousPausedDurationUs; 1842 CHECK(durExcludingEarlierPausesUs >= 0); 1843 int64_t pausedDurationUs = durExcludingEarlierPausesUs - mTrackDurationUs; 1844 CHECK(pausedDurationUs >= lastDurationUs); 1845 previousPausedDurationUs += pausedDurationUs - lastDurationUs; 1846 mResumed = false; 1847 } 1848 1849 timestampUs -= previousPausedDurationUs; 1850 CHECK(timestampUs >= 0); 1851 1852 // Media time adjustment for real-time applications 1853 if (mIsRealTimeRecording) { 1854 if (mIsAudio) { 1855 updateDriftTime(meta_data); 1856 } else { 1857 adjustMediaTime(×tampUs); 1858 } 1859 } 1860 1861 CHECK(timestampUs >= 0); 1862 if (mNumSamples > 1) { 1863 if (timestampUs <= lastTimestampUs) { 1864 LOGW("Frame arrives too late!"); 1865 // Don't drop the late frame, since dropping a frame may cause 1866 // problems later during playback 1867 1868 // The idea here is to avoid having two or more samples with the 1869 // same timestamp in the output file. 1870 if (mTimeScale >= 1000000LL) { 1871 timestampUs = lastTimestampUs + 1; 1872 } else { 1873 timestampUs = lastTimestampUs + (1000000LL + (mTimeScale >> 1)) / mTimeScale; 1874 } 1875 } 1876 } 1877 1878 LOGV("%s media time stamp: %lld and previous paused duration %lld", 1879 mIsAudio? "Audio": "Video", timestampUs, previousPausedDurationUs); 1880 if (timestampUs > mTrackDurationUs) { 1881 mTrackDurationUs = timestampUs; 1882 } 1883 1884 mSampleSizes.push_back(sampleSize); 1885 ++mNumSamples; 1886 if (mNumSamples > 2) { 1887 // We need to use the time scale based ticks, rather than the 1888 // timestamp itself to determine whether we have to use a new 1889 // stts entry, since we may have rounding errors. 1890 // The calculation is intended to reduce the accumulated 1891 // rounding errors. 1892 currDurationTicks = 1893 ((timestampUs * mTimeScale + 500000LL) / 1000000LL - 1894 (lastTimestampUs * mTimeScale + 500000LL) / 1000000LL); 1895 1896 if (currDurationTicks != lastDurationTicks) { 1897 addOneSttsTableEntry(sampleCount, lastDurationUs); 1898 sampleCount = 1; 1899 } else { 1900 ++sampleCount; 1901 } 1902 } 1903 if (mSamplesHaveSameSize) { 1904 if (mNumSamples >= 2 && previousSampleSize != sampleSize) { 1905 mSamplesHaveSameSize = false; 1906 } 1907 previousSampleSize = sampleSize; 1908 } 1909 lastDurationUs = timestampUs - lastTimestampUs; 1910 lastDurationTicks = currDurationTicks; 1911 lastTimestampUs = timestampUs; 1912 1913 if (isSync != 0) { 1914 addOneStssTableEntry(mNumSamples); 1915 } 1916 1917 if (mTrackingProgressStatus) { 1918 if (mPreviousTrackTimeUs <= 0) { 1919 mPreviousTrackTimeUs = mStartTimestampUs; 1920 } 1921 trackProgressStatus(timestampUs); 1922 } 1923 if (mOwner->numTracks() == 1) { 1924 off_t offset = mIsAvc? mOwner->addLengthPrefixedSample_l(copy) 1925 : mOwner->addSample_l(copy); 1926 if (mChunkOffsets.empty()) { 1927 addChunkOffset(offset); 1928 } 1929 copy->release(); 1930 copy = NULL; 1931 continue; 1932 } 1933 1934 mChunkSamples.push_back(copy); 1935 if (interleaveDurationUs == 0) { 1936 addOneStscTableEntry(++nChunks, 1); 1937 bufferChunk(timestampUs); 1938 } else { 1939 if (chunkTimestampUs == 0) { 1940 chunkTimestampUs = timestampUs; 1941 } else { 1942 if (timestampUs - chunkTimestampUs > interleaveDurationUs) { 1943 ++nChunks; 1944 if (nChunks == 1 || // First chunk 1945 (--(mStscTableEntries.end()))->samplesPerChunk != 1946 mChunkSamples.size()) { 1947 addOneStscTableEntry(nChunks, mChunkSamples.size()); 1948 } 1949 bufferChunk(timestampUs); 1950 chunkTimestampUs = timestampUs; 1951 } 1952 } 1953 } 1954 1955 } 1956 1957 if (mSampleSizes.empty() || // no samples written 1958 (!mIsAudio && mNumStssTableEntries == 0) || // no sync frames for video 1959 (OK != checkCodecSpecificData())) { // no codec specific data 1960 err = ERROR_MALFORMED; 1961 } 1962 mOwner->trackProgressStatus(this, -1, err); 1963 1964 // Last chunk 1965 if (mOwner->numTracks() == 1) { 1966 addOneStscTableEntry(1, mNumSamples); 1967 } else if (!mChunkSamples.empty()) { 1968 addOneStscTableEntry(++nChunks, mChunkSamples.size()); 1969 bufferChunk(timestampUs); 1970 } 1971 1972 // We don't really know how long the last frame lasts, since 1973 // there is no frame time after it, just repeat the previous 1974 // frame's duration. 1975 if (mNumSamples == 1) { 1976 lastDurationUs = 0; // A single sample's duration 1977 } else { 1978 ++sampleCount; // Count for the last sample 1979 } 1980 addOneSttsTableEntry(sampleCount, lastDurationUs); 1981 mTrackDurationUs += lastDurationUs; 1982 mReachedEOS = true; 1983 LOGI("Received total/0-length (%d/%d) buffers and encoded %d frames. - %s", 1984 count, nZeroLengthFrames, mNumSamples, mIsAudio? "audio": "video"); 1985 if (mIsAudio) { 1986 LOGI("Audio track drift time: %lld us", mOwner->getDriftTimeUs()); 1987 } 1988 1989 if (err == ERROR_END_OF_STREAM) { 1990 return OK; 1991 } 1992 return err; 1993 } 1994 1995 void MPEG4Writer::Track::trackProgressStatus(int64_t timeUs, status_t err) { 1996 LOGV("trackProgressStatus: %lld us", timeUs); 1997 if (mTrackEveryTimeDurationUs > 0 && 1998 timeUs - mPreviousTrackTimeUs >= mTrackEveryTimeDurationUs) { 1999 LOGV("Fire time tracking progress status at %lld us", timeUs); 2000 mOwner->trackProgressStatus(this, timeUs - mPreviousTrackTimeUs, err); 2001 mPreviousTrackTimeUs = timeUs; 2002 } 2003 } 2004 2005 void MPEG4Writer::trackProgressStatus( 2006 const MPEG4Writer::Track* track, int64_t timeUs, status_t err) { 2007 Mutex::Autolock lock(mLock); 2008 int32_t nTracks = mTracks.size(); 2009 CHECK(nTracks >= 1); 2010 CHECK(nTracks < 64); // Arbitrary number 2011 2012 int32_t trackNum = 0; 2013 CHECK(trackNum < nTracks); 2014 trackNum <<= 16; 2015 2016 // Error notification 2017 // Do not consider ERROR_END_OF_STREAM an error 2018 if (err != OK && err != ERROR_END_OF_STREAM) { 2019 notify(MEDIA_RECORDER_EVENT_ERROR, 2020 trackNum | MEDIA_RECORDER_ERROR_UNKNOWN, 2021 err); 2022 return; 2023 } 2024 2025 if (timeUs == -1) { 2026 // Send completion notification 2027 notify(MEDIA_RECORDER_EVENT_INFO, 2028 trackNum | MEDIA_RECORDER_INFO_COMPLETION_STATUS, 2029 err); 2030 return; 2031 } else { 2032 // Send progress status 2033 notify(MEDIA_RECORDER_EVENT_INFO, 2034 trackNum | MEDIA_RECORDER_INFO_PROGRESS_TIME_STATUS, 2035 timeUs / 1000); 2036 } 2037 } 2038 2039 void MPEG4Writer::setDriftTimeUs(int64_t driftTimeUs) { 2040 LOGV("setDriftTimeUs: %lld us", driftTimeUs); 2041 Mutex::Autolock autolock(mLock); 2042 mDriftTimeUs = driftTimeUs; 2043 } 2044 2045 int64_t MPEG4Writer::getDriftTimeUs() { 2046 LOGV("getDriftTimeUs: %lld us", mDriftTimeUs); 2047 Mutex::Autolock autolock(mLock); 2048 return mDriftTimeUs; 2049 } 2050 2051 bool MPEG4Writer::useNalLengthFour() { 2052 return mUse4ByteNalLength; 2053 } 2054 2055 void MPEG4Writer::Track::bufferChunk(int64_t timestampUs) { 2056 LOGV("bufferChunk"); 2057 2058 Chunk chunk(this, timestampUs, mChunkSamples); 2059 mOwner->bufferChunk(chunk); 2060 mChunkSamples.clear(); 2061 } 2062 2063 int64_t MPEG4Writer::Track::getDurationUs() const { 2064 return mTrackDurationUs; 2065 } 2066 2067 int64_t MPEG4Writer::Track::getEstimatedTrackSizeBytes() const { 2068 return mEstimatedTrackSizeBytes; 2069 } 2070 2071 status_t MPEG4Writer::Track::checkCodecSpecificData() const { 2072 const char *mime; 2073 CHECK(mMeta->findCString(kKeyMIMEType, &mime)); 2074 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime) || 2075 !strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime) || 2076 !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) { 2077 if (!mCodecSpecificData || 2078 mCodecSpecificDataSize <= 0) { 2079 LOGE("Missing codec specific data"); 2080 return ERROR_MALFORMED; 2081 } 2082 } else { 2083 if (mCodecSpecificData || 2084 mCodecSpecificDataSize > 0) { 2085 LOGE("Unexepected codec specific data found"); 2086 return ERROR_MALFORMED; 2087 } 2088 } 2089 return OK; 2090 } 2091 2092 void MPEG4Writer::Track::writeTrackHeader( 2093 int32_t trackID, bool use32BitOffset) { 2094 const char *mime; 2095 bool success = mMeta->findCString(kKeyMIMEType, &mime); 2096 CHECK(success); 2097 2098 LOGV("%s track time scale: %d", 2099 mIsAudio? "Audio": "Video", mTimeScale); 2100 2101 time_t now = time(NULL); 2102 int32_t mvhdTimeScale = mOwner->getTimeScale(); 2103 int64_t trakDurationUs = getDurationUs(); 2104 2105 mOwner->beginBox("trak"); 2106 2107 mOwner->beginBox("tkhd"); 2108 // Flags = 7 to indicate that the track is enabled, and 2109 // part of the presentation 2110 mOwner->writeInt32(0x07); // version=0, flags=7 2111 mOwner->writeInt32(now); // creation time 2112 mOwner->writeInt32(now); // modification time 2113 mOwner->writeInt32(trackID); 2114 mOwner->writeInt32(0); // reserved 2115 int32_t tkhdDuration = 2116 (trakDurationUs * mvhdTimeScale + 5E5) / 1E6; 2117 mOwner->writeInt32(tkhdDuration); // in mvhd timescale 2118 mOwner->writeInt32(0); // reserved 2119 mOwner->writeInt32(0); // reserved 2120 mOwner->writeInt16(0); // layer 2121 mOwner->writeInt16(0); // alternate group 2122 mOwner->writeInt16(mIsAudio ? 0x100 : 0); // volume 2123 mOwner->writeInt16(0); // reserved 2124 2125 mOwner->writeCompositionMatrix(mRotation); 2126 2127 if (mIsAudio) { 2128 mOwner->writeInt32(0); 2129 mOwner->writeInt32(0); 2130 } else { 2131 int32_t width, height; 2132 bool success = mMeta->findInt32(kKeyWidth, &width); 2133 success = success && mMeta->findInt32(kKeyHeight, &height); 2134 CHECK(success); 2135 2136 mOwner->writeInt32(width << 16); // 32-bit fixed-point value 2137 mOwner->writeInt32(height << 16); // 32-bit fixed-point value 2138 } 2139 mOwner->endBox(); // tkhd 2140 2141 int64_t moovStartTimeUs = mOwner->getStartTimestampUs(); 2142 if (mStartTimestampUs != moovStartTimeUs) { 2143 mOwner->beginBox("edts"); 2144 mOwner->beginBox("elst"); 2145 mOwner->writeInt32(0); // version=0, flags=0: 32-bit time 2146 mOwner->writeInt32(2); // never ends with an empty list 2147 2148 // First elst entry: specify the starting time offset 2149 int64_t offsetUs = mStartTimestampUs - moovStartTimeUs; 2150 LOGV("OffsetUs: %lld", offsetUs); 2151 int32_t seg = (offsetUs * mvhdTimeScale + 5E5) / 1E6; 2152 mOwner->writeInt32(seg); // in mvhd timecale 2153 mOwner->writeInt32(-1); // starting time offset 2154 mOwner->writeInt32(1 << 16); // rate = 1.0 2155 2156 // Second elst entry: specify the track duration 2157 seg = (trakDurationUs * mvhdTimeScale + 5E5) / 1E6; 2158 mOwner->writeInt32(seg); // in mvhd timescale 2159 mOwner->writeInt32(0); 2160 mOwner->writeInt32(1 << 16); 2161 mOwner->endBox(); 2162 mOwner->endBox(); 2163 } 2164 2165 mOwner->beginBox("mdia"); 2166 2167 mOwner->beginBox("mdhd"); 2168 mOwner->writeInt32(0); // version=0, flags=0 2169 mOwner->writeInt32(now); // creation time 2170 mOwner->writeInt32(now); // modification time 2171 mOwner->writeInt32(mTimeScale); // media timescale 2172 int32_t mdhdDuration = (trakDurationUs * mTimeScale + 5E5) / 1E6; 2173 mOwner->writeInt32(mdhdDuration); // use media timescale 2174 // Language follows the three letter standard ISO-639-2/T 2175 // 'e', 'n', 'g' for "English", for instance. 2176 // Each character is packed as the difference between its ASCII value and 0x60. 2177 // For "English", these are 00101, 01110, 00111. 2178 // XXX: Where is the padding bit located: 0x15C7? 2179 mOwner->writeInt16(0); // language code 2180 mOwner->writeInt16(0); // predefined 2181 mOwner->endBox(); 2182 2183 mOwner->beginBox("hdlr"); 2184 mOwner->writeInt32(0); // version=0, flags=0 2185 mOwner->writeInt32(0); // component type: should be mhlr 2186 mOwner->writeFourcc(mIsAudio ? "soun" : "vide"); // component subtype 2187 mOwner->writeInt32(0); // reserved 2188 mOwner->writeInt32(0); // reserved 2189 mOwner->writeInt32(0); // reserved 2190 // Removing "r" for the name string just makes the string 4 byte aligned 2191 mOwner->writeCString(mIsAudio ? "SoundHandle": "VideoHandle"); // name 2192 mOwner->endBox(); 2193 2194 mOwner->beginBox("minf"); 2195 if (mIsAudio) { 2196 mOwner->beginBox("smhd"); 2197 mOwner->writeInt32(0); // version=0, flags=0 2198 mOwner->writeInt16(0); // balance 2199 mOwner->writeInt16(0); // reserved 2200 mOwner->endBox(); 2201 } else { 2202 mOwner->beginBox("vmhd"); 2203 mOwner->writeInt32(0x01); // version=0, flags=1 2204 mOwner->writeInt16(0); // graphics mode 2205 mOwner->writeInt16(0); // opcolor 2206 mOwner->writeInt16(0); 2207 mOwner->writeInt16(0); 2208 mOwner->endBox(); 2209 } 2210 2211 mOwner->beginBox("dinf"); 2212 mOwner->beginBox("dref"); 2213 mOwner->writeInt32(0); // version=0, flags=0 2214 mOwner->writeInt32(1); // entry count (either url or urn) 2215 // The table index here refers to the sample description index 2216 // in the sample table entries. 2217 mOwner->beginBox("url "); 2218 mOwner->writeInt32(1); // version=0, flags=1 (self-contained) 2219 mOwner->endBox(); // url 2220 mOwner->endBox(); // dref 2221 mOwner->endBox(); // dinf 2222 2223 mOwner->beginBox("stbl"); 2224 2225 mOwner->beginBox("stsd"); 2226 mOwner->writeInt32(0); // version=0, flags=0 2227 mOwner->writeInt32(1); // entry count 2228 if (mIsAudio) { 2229 const char *fourcc = NULL; 2230 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime)) { 2231 fourcc = "samr"; 2232 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) { 2233 fourcc = "sawb"; 2234 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) { 2235 fourcc = "mp4a"; 2236 } else { 2237 LOGE("Unknown mime type '%s'.", mime); 2238 CHECK(!"should not be here, unknown mime type."); 2239 } 2240 2241 mOwner->beginBox(fourcc); // audio format 2242 mOwner->writeInt32(0); // reserved 2243 mOwner->writeInt16(0); // reserved 2244 mOwner->writeInt16(0x1); // data ref index 2245 mOwner->writeInt32(0); // reserved 2246 mOwner->writeInt32(0); // reserved 2247 int32_t nChannels; 2248 CHECK_EQ(true, mMeta->findInt32(kKeyChannelCount, &nChannels)); 2249 mOwner->writeInt16(nChannels); // channel count 2250 mOwner->writeInt16(16); // sample size 2251 mOwner->writeInt16(0); // predefined 2252 mOwner->writeInt16(0); // reserved 2253 2254 int32_t samplerate; 2255 bool success = mMeta->findInt32(kKeySampleRate, &samplerate); 2256 CHECK(success); 2257 mOwner->writeInt32(samplerate << 16); 2258 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) { 2259 mOwner->beginBox("esds"); 2260 CHECK(mCodecSpecificData); 2261 CHECK(mCodecSpecificDataSize > 0); 2262 2263 mOwner->writeInt32(0); // version=0, flags=0 2264 mOwner->writeInt8(0x03); // ES_DescrTag 2265 mOwner->writeInt8(23 + mCodecSpecificDataSize); 2266 mOwner->writeInt16(0x0000);// ES_ID 2267 mOwner->writeInt8(0x00); 2268 2269 mOwner->writeInt8(0x04); // DecoderConfigDescrTag 2270 mOwner->writeInt8(15 + mCodecSpecificDataSize); 2271 mOwner->writeInt8(0x40); // objectTypeIndication ISO/IEC 14492-2 2272 mOwner->writeInt8(0x15); // streamType AudioStream 2273 2274 mOwner->writeInt16(0x03); // XXX 2275 mOwner->writeInt8(0x00); // buffer size 24-bit 2276 mOwner->writeInt32(96000); // max bit rate 2277 mOwner->writeInt32(96000); // avg bit rate 2278 2279 mOwner->writeInt8(0x05); // DecoderSpecificInfoTag 2280 mOwner->writeInt8(mCodecSpecificDataSize); 2281 mOwner->write(mCodecSpecificData, mCodecSpecificDataSize); 2282 2283 static const uint8_t kData2[] = { 2284 0x06, // SLConfigDescriptorTag 2285 0x01, 2286 0x02 2287 }; 2288 mOwner->write(kData2, sizeof(kData2)); 2289 2290 mOwner->endBox(); // esds 2291 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime) || 2292 !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) { 2293 // 3gpp2 Spec AMRSampleEntry fields 2294 mOwner->beginBox("damr"); 2295 mOwner->writeCString(" "); // vendor: 4 bytes 2296 mOwner->writeInt8(0); // decoder version 2297 mOwner->writeInt16(0x83FF); // mode set: all enabled 2298 mOwner->writeInt8(0); // mode change period 2299 mOwner->writeInt8(1); // frames per sample 2300 mOwner->endBox(); 2301 } 2302 mOwner->endBox(); 2303 } else { 2304 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { 2305 mOwner->beginBox("mp4v"); 2306 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { 2307 mOwner->beginBox("s263"); 2308 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) { 2309 mOwner->beginBox("avc1"); 2310 } else { 2311 LOGE("Unknown mime type '%s'.", mime); 2312 CHECK(!"should not be here, unknown mime type."); 2313 } 2314 2315 mOwner->writeInt32(0); // reserved 2316 mOwner->writeInt16(0); // reserved 2317 mOwner->writeInt16(1); // data ref index 2318 mOwner->writeInt16(0); // predefined 2319 mOwner->writeInt16(0); // reserved 2320 mOwner->writeInt32(0); // predefined 2321 mOwner->writeInt32(0); // predefined 2322 mOwner->writeInt32(0); // predefined 2323 2324 int32_t width, height; 2325 bool success = mMeta->findInt32(kKeyWidth, &width); 2326 success = success && mMeta->findInt32(kKeyHeight, &height); 2327 CHECK(success); 2328 2329 mOwner->writeInt16(width); 2330 mOwner->writeInt16(height); 2331 mOwner->writeInt32(0x480000); // horiz resolution 2332 mOwner->writeInt32(0x480000); // vert resolution 2333 mOwner->writeInt32(0); // reserved 2334 mOwner->writeInt16(1); // frame count 2335 mOwner->write(" ", 32); 2336 mOwner->writeInt16(0x18); // depth 2337 mOwner->writeInt16(-1); // predefined 2338 2339 CHECK(23 + mCodecSpecificDataSize < 128); 2340 2341 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { 2342 CHECK(mCodecSpecificData); 2343 CHECK(mCodecSpecificDataSize > 0); 2344 mOwner->beginBox("esds"); 2345 2346 mOwner->writeInt32(0); // version=0, flags=0 2347 2348 mOwner->writeInt8(0x03); // ES_DescrTag 2349 mOwner->writeInt8(23 + mCodecSpecificDataSize); 2350 mOwner->writeInt16(0x0000); // ES_ID 2351 mOwner->writeInt8(0x1f); 2352 2353 mOwner->writeInt8(0x04); // DecoderConfigDescrTag 2354 mOwner->writeInt8(15 + mCodecSpecificDataSize); 2355 mOwner->writeInt8(0x20); // objectTypeIndication ISO/IEC 14492-2 2356 mOwner->writeInt8(0x11); // streamType VisualStream 2357 2358 static const uint8_t kData[] = { 2359 0x01, 0x77, 0x00, 2360 0x00, 0x03, 0xe8, 0x00, 2361 0x00, 0x03, 0xe8, 0x00 2362 }; 2363 mOwner->write(kData, sizeof(kData)); 2364 2365 mOwner->writeInt8(0x05); // DecoderSpecificInfoTag 2366 2367 mOwner->writeInt8(mCodecSpecificDataSize); 2368 mOwner->write(mCodecSpecificData, mCodecSpecificDataSize); 2369 2370 static const uint8_t kData2[] = { 2371 0x06, // SLConfigDescriptorTag 2372 0x01, 2373 0x02 2374 }; 2375 mOwner->write(kData2, sizeof(kData2)); 2376 2377 mOwner->endBox(); // esds 2378 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { 2379 mOwner->beginBox("d263"); 2380 2381 mOwner->writeInt32(0); // vendor 2382 mOwner->writeInt8(0); // decoder version 2383 mOwner->writeInt8(10); // level: 10 2384 mOwner->writeInt8(0); // profile: 0 2385 2386 mOwner->endBox(); // d263 2387 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) { 2388 CHECK(mCodecSpecificData); 2389 CHECK(mCodecSpecificDataSize >= 5); 2390 2391 // Patch avcc's lengthSize field to match the number 2392 // of bytes we use to indicate the size of a nal unit. 2393 uint8_t *ptr = (uint8_t *)mCodecSpecificData; 2394 ptr[4] = 2395 (ptr[4] & 0xfc) 2396 | (mOwner->useNalLengthFour() ? 3 : 1); 2397 2398 mOwner->beginBox("avcC"); 2399 mOwner->write(mCodecSpecificData, mCodecSpecificDataSize); 2400 mOwner->endBox(); // avcC 2401 } 2402 2403 mOwner->beginBox("pasp"); 2404 // This is useful if the pixel is not square 2405 mOwner->writeInt32(1 << 16); // hspacing 2406 mOwner->writeInt32(1 << 16); // vspacing 2407 mOwner->endBox(); // pasp 2408 mOwner->endBox(); // mp4v, s263 or avc1 2409 } 2410 mOwner->endBox(); // stsd 2411 2412 mOwner->beginBox("stts"); 2413 mOwner->writeInt32(0); // version=0, flags=0 2414 mOwner->writeInt32(mNumSttsTableEntries); 2415 int64_t prevTimestampUs = 0; 2416 for (List<SttsTableEntry>::iterator it = mSttsTableEntries.begin(); 2417 it != mSttsTableEntries.end(); ++it) { 2418 mOwner->writeInt32(it->sampleCount); 2419 2420 // Make sure that we are calculating the sample duration the exactly 2421 // same way as we made decision on how to create stts entries. 2422 int64_t currTimestampUs = prevTimestampUs + it->sampleDurationUs; 2423 int32_t dur = ((currTimestampUs * mTimeScale + 500000LL) / 1000000LL - 2424 (prevTimestampUs * mTimeScale + 500000LL) / 1000000LL); 2425 prevTimestampUs += (it->sampleCount * it->sampleDurationUs); 2426 2427 mOwner->writeInt32(dur); 2428 } 2429 mOwner->endBox(); // stts 2430 2431 if (!mIsAudio) { 2432 mOwner->beginBox("stss"); 2433 mOwner->writeInt32(0); // version=0, flags=0 2434 mOwner->writeInt32(mNumStssTableEntries); // number of sync frames 2435 for (List<int32_t>::iterator it = mStssTableEntries.begin(); 2436 it != mStssTableEntries.end(); ++it) { 2437 mOwner->writeInt32(*it); 2438 } 2439 mOwner->endBox(); // stss 2440 } 2441 2442 mOwner->beginBox("stsz"); 2443 mOwner->writeInt32(0); // version=0, flags=0 2444 if (mSamplesHaveSameSize) { 2445 List<size_t>::iterator it = mSampleSizes.begin(); 2446 mOwner->writeInt32(*it); // default sample size 2447 } else { 2448 mOwner->writeInt32(0); 2449 } 2450 mOwner->writeInt32(mNumSamples); 2451 if (!mSamplesHaveSameSize) { 2452 for (List<size_t>::iterator it = mSampleSizes.begin(); 2453 it != mSampleSizes.end(); ++it) { 2454 mOwner->writeInt32(*it); 2455 } 2456 } 2457 mOwner->endBox(); // stsz 2458 2459 mOwner->beginBox("stsc"); 2460 mOwner->writeInt32(0); // version=0, flags=0 2461 mOwner->writeInt32(mNumStscTableEntries); 2462 for (List<StscTableEntry>::iterator it = mStscTableEntries.begin(); 2463 it != mStscTableEntries.end(); ++it) { 2464 mOwner->writeInt32(it->firstChunk); 2465 mOwner->writeInt32(it->samplesPerChunk); 2466 mOwner->writeInt32(it->sampleDescriptionId); 2467 } 2468 mOwner->endBox(); // stsc 2469 mOwner->beginBox(use32BitOffset? "stco": "co64"); 2470 mOwner->writeInt32(0); // version=0, flags=0 2471 mOwner->writeInt32(mNumStcoTableEntries); 2472 for (List<off_t>::iterator it = mChunkOffsets.begin(); 2473 it != mChunkOffsets.end(); ++it) { 2474 if (use32BitOffset) { 2475 mOwner->writeInt32(static_cast<int32_t>(*it)); 2476 } else { 2477 mOwner->writeInt64((*it)); 2478 } 2479 } 2480 mOwner->endBox(); // stco or co64 2481 2482 mOwner->endBox(); // stbl 2483 mOwner->endBox(); // minf 2484 mOwner->endBox(); // mdia 2485 mOwner->endBox(); // trak 2486 } 2487 2488 } // namespace android 2489