MPEG4Writer.cpp revision acd234bba9f048971d66890009eeff9a8db94be3
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 39namespace android { 40 41static const int64_t kMax32BitFileSize = 0x007fffffffLL; 42static const uint8_t kNalUnitTypeSeqParamSet = 0x07; 43static const uint8_t kNalUnitTypePicParamSet = 0x08; 44 45// Using longer adjustment period to suppress fluctuations in 46// the audio encoding paths 47static const int64_t kVideoMediaTimeAdjustPeriodTimeUs = 600000000LL; // 10 minutes 48 49class MPEG4Writer::Track { 50public: 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 70private: 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 216MPEG4Writer::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 230MPEG4Writer::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 244MPEG4Writer::~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 256status_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 273status_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 287status_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 294status_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 311int64_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 370status_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 489bool MPEG4Writer::use32BitFileOffset() const { 490 return mUse32BitOffset; 491} 492 493status_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 509void 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 */ 534void 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 575status_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 688status_t MPEG4Writer::setInterleaveDuration(uint32_t durationUs) { 689 mInterleaveDurationUs = durationUs; 690 return OK; 691} 692 693void MPEG4Writer::lock() { 694 mLock.lock(); 695} 696 697void MPEG4Writer::unlock() { 698 mLock.unlock(); 699} 700 701off_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 712static 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 726off_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 759size_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 790void 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 800void 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 817void MPEG4Writer::writeInt8(int8_t x) { 818 write(&x, 1, 1, mFile); 819} 820 821void MPEG4Writer::writeInt16(int16_t x) { 822 x = htons(x); 823 write(&x, 1, 2, mFile); 824} 825 826void MPEG4Writer::writeInt32(int32_t x) { 827 x = htonl(x); 828 write(&x, 1, 4, mFile); 829} 830 831void MPEG4Writer::writeInt64(int64_t x) { 832 x = hton64(x); 833 write(&x, 1, 8, mFile); 834} 835 836void MPEG4Writer::writeCString(const char *s) { 837 size_t n = strlen(s); 838 write(s, 1, n + 1, mFile); 839} 840 841void MPEG4Writer::writeFourcc(const char *s) { 842 CHECK_EQ(strlen(s), 4); 843 write(s, 1, 4, mFile); 844} 845 846void MPEG4Writer::write(const void *data, size_t size) { 847 write(data, 1, size, mFile); 848} 849 850bool MPEG4Writer::isFileStreamable() const { 851 return mStreamableFile; 852} 853 854bool 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 // Be conservative in the estimate: do not exceed 95% of 867 // the target file limit. For small target file size limit, though, 868 // this will not help. 869 return (nTotalBytesEstimate >= (95 * mMaxFileSizeLimitBytes) / 100); 870} 871 872bool MPEG4Writer::exceedsFileDurationLimit() { 873 // No limit 874 if (mMaxFileDurationLimitUs == 0) { 875 return false; 876 } 877 878 for (List<Track *>::iterator it = mTracks.begin(); 879 it != mTracks.end(); ++it) { 880 if ((*it)->getDurationUs() >= mMaxFileDurationLimitUs) { 881 return true; 882 } 883 } 884 return false; 885} 886 887bool MPEG4Writer::reachedEOS() { 888 bool allDone = true; 889 for (List<Track *>::iterator it = mTracks.begin(); 890 it != mTracks.end(); ++it) { 891 if (!(*it)->reachedEOS()) { 892 allDone = false; 893 break; 894 } 895 } 896 897 return allDone; 898} 899 900void MPEG4Writer::setStartTimestampUs(int64_t timeUs) { 901 LOGI("setStartTimestampUs: %lld", timeUs); 902 CHECK(timeUs >= 0); 903 Mutex::Autolock autoLock(mLock); 904 if (mStartTimestampUs < 0 || mStartTimestampUs > timeUs) { 905 mStartTimestampUs = timeUs; 906 LOGI("Earliest track starting time: %lld", mStartTimestampUs); 907 } 908} 909 910int64_t MPEG4Writer::getStartTimestampUs() { 911 Mutex::Autolock autoLock(mLock); 912 return mStartTimestampUs; 913} 914 915size_t MPEG4Writer::numTracks() { 916 Mutex::Autolock autolock(mLock); 917 return mTracks.size(); 918} 919 920//////////////////////////////////////////////////////////////////////////////// 921 922MPEG4Writer::Track::Track( 923 MPEG4Writer *owner, const sp<MediaSource> &source) 924 : mOwner(owner), 925 mMeta(source->getFormat()), 926 mSource(source), 927 mDone(false), 928 mPaused(false), 929 mResumed(false), 930 mTrackDurationUs(0), 931 mEstimatedTrackSizeBytes(0), 932 mSamplesHaveSameSize(true), 933 mCodecSpecificData(NULL), 934 mCodecSpecificDataSize(0), 935 mGotAllCodecSpecificData(false), 936 mReachedEOS(false), 937 mRotation(0) { 938 getCodecSpecificDataFromInputFormatIfPossible(); 939 940 const char *mime; 941 mMeta->findCString(kKeyMIMEType, &mime); 942 mIsAvc = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 943 mIsAudio = !strncasecmp(mime, "audio/", 6); 944 mIsMPEG4 = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) || 945 !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC); 946 947 setTimeScale(); 948} 949 950void MPEG4Writer::Track::updateTrackSizeEstimate() { 951 952 int64_t stcoBoxSizeBytes = mOwner->use32BitFileOffset() 953 ? mNumStcoTableEntries * 4 954 : mNumStcoTableEntries * 8; 955 956 int64_t stszBoxSizeBytes = mSamplesHaveSameSize? 4: (mNumSamples * 4); 957 958 mEstimatedTrackSizeBytes = mMdatSizeBytes; // media data size 959 if (!mOwner->isFileStreamable()) { 960 // Reserved free space is not large enough to hold 961 // all meta data and thus wasted. 962 mEstimatedTrackSizeBytes += mNumStscTableEntries * 12 + // stsc box size 963 mNumStssTableEntries * 4 + // stss box size 964 mNumSttsTableEntries * 8 + // stts box size 965 stcoBoxSizeBytes + // stco box size 966 stszBoxSizeBytes; // stsz box size 967 } 968} 969 970void MPEG4Writer::Track::addOneStscTableEntry( 971 size_t chunkId, size_t sampleId) { 972 973 StscTableEntry stscEntry(chunkId, sampleId, 1); 974 mStscTableEntries.push_back(stscEntry); 975 ++mNumStscTableEntries; 976} 977 978void MPEG4Writer::Track::addOneStssTableEntry(size_t sampleId) { 979 mStssTableEntries.push_back(sampleId); 980 ++mNumStssTableEntries; 981} 982 983void MPEG4Writer::Track::addOneSttsTableEntry( 984 size_t sampleCount, int64_t durationUs) { 985 986 SttsTableEntry sttsEntry(sampleCount, durationUs); 987 mSttsTableEntries.push_back(sttsEntry); 988 ++mNumSttsTableEntries; 989} 990 991void MPEG4Writer::Track::addChunkOffset(off_t offset) { 992 ++mNumStcoTableEntries; 993 mChunkOffsets.push_back(offset); 994} 995 996void MPEG4Writer::Track::setTimeScale() { 997 LOGV("setTimeScale"); 998 // Default time scale 999 mTimeScale = 90000; 1000 1001 if (mIsAudio) { 1002 // Use the sampling rate as the default time scale for audio track. 1003 int32_t sampleRate; 1004 bool success = mMeta->findInt32(kKeySampleRate, &sampleRate); 1005 CHECK(success); 1006 mTimeScale = sampleRate; 1007 } 1008 1009 // If someone would like to overwrite the timescale, use user-supplied value. 1010 int32_t timeScale; 1011 if (mMeta->findInt32(kKeyTimeScale, &timeScale)) { 1012 mTimeScale = timeScale; 1013 } 1014 1015 CHECK(mTimeScale > 0); 1016} 1017 1018void MPEG4Writer::Track::getCodecSpecificDataFromInputFormatIfPossible() { 1019 const char *mime; 1020 CHECK(mMeta->findCString(kKeyMIMEType, &mime)); 1021 1022 if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 1023 uint32_t type; 1024 const void *data; 1025 size_t size; 1026 if (mMeta->findData(kKeyAVCC, &type, &data, &size)) { 1027 mCodecSpecificData = malloc(size); 1028 mCodecSpecificDataSize = size; 1029 memcpy(mCodecSpecificData, data, size); 1030 mGotAllCodecSpecificData = true; 1031 } 1032 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) 1033 || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 1034 uint32_t type; 1035 const void *data; 1036 size_t size; 1037 if (mMeta->findData(kKeyESDS, &type, &data, &size)) { 1038 ESDS esds(data, size); 1039 if (esds.getCodecSpecificInfo(&data, &size) == OK) { 1040 mCodecSpecificData = malloc(size); 1041 mCodecSpecificDataSize = size; 1042 memcpy(mCodecSpecificData, data, size); 1043 mGotAllCodecSpecificData = true; 1044 } 1045 } 1046 } 1047} 1048 1049MPEG4Writer::Track::~Track() { 1050 stop(); 1051 1052 if (mCodecSpecificData != NULL) { 1053 free(mCodecSpecificData); 1054 mCodecSpecificData = NULL; 1055 } 1056} 1057 1058void MPEG4Writer::Track::initTrackingProgressStatus(MetaData *params) { 1059 LOGV("initTrackingProgressStatus"); 1060 mPreviousTrackTimeUs = -1; 1061 mTrackingProgressStatus = false; 1062 mTrackEveryTimeDurationUs = 0; 1063 { 1064 int64_t timeUs; 1065 if (params && params->findInt64(kKeyTrackTimeStatus, &timeUs)) { 1066 LOGV("Receive request to track progress status for every %lld us", timeUs); 1067 mTrackEveryTimeDurationUs = timeUs; 1068 mTrackingProgressStatus = true; 1069 } 1070 } 1071} 1072 1073// static 1074void *MPEG4Writer::ThreadWrapper(void *me) { 1075 LOGV("ThreadWrapper: %p", me); 1076 MPEG4Writer *writer = static_cast<MPEG4Writer *>(me); 1077 writer->threadFunc(); 1078 return NULL; 1079} 1080 1081void MPEG4Writer::bufferChunk(const Chunk& chunk) { 1082 LOGV("bufferChunk: %p", chunk.mTrack); 1083 Mutex::Autolock autolock(mLock); 1084 CHECK_EQ(mDone, false); 1085 1086 for (List<ChunkInfo>::iterator it = mChunkInfos.begin(); 1087 it != mChunkInfos.end(); ++it) { 1088 1089 if (chunk.mTrack == it->mTrack) { // Found owner 1090 it->mChunks.push_back(chunk); 1091 mChunkReadyCondition.signal(); 1092 return; 1093 } 1094 } 1095 1096 CHECK("Received a chunk for a unknown track" == 0); 1097} 1098 1099void MPEG4Writer::writeFirstChunk(ChunkInfo* info) { 1100 LOGV("writeFirstChunk: %p", info->mTrack); 1101 1102 List<Chunk>::iterator chunkIt = info->mChunks.begin(); 1103 for (List<MediaBuffer *>::iterator it = chunkIt->mSamples.begin(); 1104 it != chunkIt->mSamples.end(); ++it) { 1105 1106 off_t offset = info->mTrack->isAvc() 1107 ? addLengthPrefixedSample_l(*it) 1108 : addSample_l(*it); 1109 if (it == chunkIt->mSamples.begin()) { 1110 info->mTrack->addChunkOffset(offset); 1111 } 1112 } 1113 1114 // Done with the current chunk. 1115 // Release all the samples in this chunk. 1116 while (!chunkIt->mSamples.empty()) { 1117 List<MediaBuffer *>::iterator it = chunkIt->mSamples.begin(); 1118 (*it)->release(); 1119 (*it) = NULL; 1120 chunkIt->mSamples.erase(it); 1121 } 1122 chunkIt->mSamples.clear(); 1123 info->mChunks.erase(chunkIt); 1124} 1125 1126void MPEG4Writer::writeChunks() { 1127 LOGV("writeChunks"); 1128 size_t outstandingChunks = 0; 1129 while (!mChunkInfos.empty()) { 1130 List<ChunkInfo>::iterator it = mChunkInfos.begin(); 1131 while (!it->mChunks.empty()) { 1132 CHECK_EQ(OK, writeOneChunk()); 1133 ++outstandingChunks; 1134 } 1135 it->mTrack = NULL; 1136 mChunkInfos.erase(it); 1137 } 1138 mChunkInfos.clear(); 1139 LOGD("%d chunks are written in the last batch", outstandingChunks); 1140} 1141 1142status_t MPEG4Writer::writeOneChunk() { 1143 LOGV("writeOneChunk"); 1144 1145 // Find the smallest timestamp, and write that chunk out 1146 // XXX: What if some track is just too slow? 1147 int64_t minTimestampUs = 0x7FFFFFFFFFFFFFFFLL; 1148 Track *track = NULL; 1149 for (List<ChunkInfo>::iterator it = mChunkInfos.begin(); 1150 it != mChunkInfos.end(); ++it) { 1151 if (!it->mChunks.empty()) { 1152 List<Chunk>::iterator chunkIt = it->mChunks.begin(); 1153 if (chunkIt->mTimeStampUs < minTimestampUs) { 1154 minTimestampUs = chunkIt->mTimeStampUs; 1155 track = it->mTrack; 1156 } 1157 } 1158 } 1159 1160 if (track == NULL) { 1161 LOGV("Nothing to be written after all"); 1162 return OK; 1163 } 1164 1165 if (mIsFirstChunk) { 1166 mIsFirstChunk = false; 1167 } 1168 for (List<ChunkInfo>::iterator it = mChunkInfos.begin(); 1169 it != mChunkInfos.end(); ++it) { 1170 if (it->mTrack == track) { 1171 writeFirstChunk(&(*it)); 1172 } 1173 } 1174 return OK; 1175} 1176 1177void MPEG4Writer::threadFunc() { 1178 LOGV("threadFunc"); 1179 1180 prctl(PR_SET_NAME, (unsigned long)"MPEG4Writer", 0, 0, 0); 1181 while (!mDone) { 1182 { 1183 Mutex::Autolock autolock(mLock); 1184 mChunkReadyCondition.wait(mLock); 1185 CHECK_EQ(writeOneChunk(), OK); 1186 } 1187 } 1188 1189 { 1190 // Write ALL samples 1191 Mutex::Autolock autolock(mLock); 1192 writeChunks(); 1193 } 1194} 1195 1196status_t MPEG4Writer::startWriterThread() { 1197 LOGV("startWriterThread"); 1198 1199 mDone = false; 1200 mIsFirstChunk = true; 1201 mDriftTimeUs = 0; 1202 for (List<Track *>::iterator it = mTracks.begin(); 1203 it != mTracks.end(); ++it) { 1204 ChunkInfo info; 1205 info.mTrack = *it; 1206 mChunkInfos.push_back(info); 1207 } 1208 1209 pthread_attr_t attr; 1210 pthread_attr_init(&attr); 1211 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 1212 pthread_create(&mThread, &attr, ThreadWrapper, this); 1213 pthread_attr_destroy(&attr); 1214 return OK; 1215} 1216 1217 1218status_t MPEG4Writer::Track::start(MetaData *params) { 1219 if (!mDone && mPaused) { 1220 mPaused = false; 1221 mResumed = true; 1222 return OK; 1223 } 1224 1225 int64_t startTimeUs; 1226 if (params == NULL || !params->findInt64(kKeyTime, &startTimeUs)) { 1227 startTimeUs = 0; 1228 } 1229 1230 int32_t rotationDegrees; 1231 if (!mIsAudio && params && params->findInt32(kKeyRotationDegree, &rotationDegrees)) { 1232 mRotation = rotationDegrees; 1233 } 1234 1235 mIsRealTimeRecording = true; 1236 { 1237 int32_t isNotRealTime; 1238 if (params && params->findInt32(kKeyNotRealTime, &isNotRealTime)) { 1239 mIsRealTimeRecording = (isNotRealTime == 0); 1240 } 1241 } 1242 1243 initTrackingProgressStatus(params); 1244 1245 sp<MetaData> meta = new MetaData; 1246 meta->setInt64(kKeyTime, startTimeUs); 1247 status_t err = mSource->start(meta.get()); 1248 if (err != OK) { 1249 mDone = mReachedEOS = true; 1250 return err; 1251 } 1252 1253 pthread_attr_t attr; 1254 pthread_attr_init(&attr); 1255 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 1256 1257 mDone = false; 1258 mTrackDurationUs = 0; 1259 mReachedEOS = false; 1260 mEstimatedTrackSizeBytes = 0; 1261 mNumStcoTableEntries = 0; 1262 mNumStssTableEntries = 0; 1263 mNumStscTableEntries = 0; 1264 mNumSttsTableEntries = 0; 1265 mMdatSizeBytes = 0; 1266 mIsMediaTimeAdjustmentOn = false; 1267 mPrevMediaTimeAdjustTimestampUs = 0; 1268 mMediaTimeAdjustNumFrames = 0; 1269 mPrevMediaTimeAdjustSample = 0; 1270 mTotalDriftTimeToAdjustUs = 0; 1271 mPrevTotalAccumDriftTimeUs = 0; 1272 1273 pthread_create(&mThread, &attr, ThreadWrapper, this); 1274 pthread_attr_destroy(&attr); 1275 1276 return OK; 1277} 1278 1279status_t MPEG4Writer::Track::pause() { 1280 mPaused = true; 1281 return OK; 1282} 1283 1284status_t MPEG4Writer::Track::stop() { 1285 if (mDone) { 1286 return OK; 1287 } 1288 1289 mDone = true; 1290 1291 void *dummy; 1292 pthread_join(mThread, &dummy); 1293 1294 status_t err = (status_t) dummy; 1295 1296 { 1297 status_t status = mSource->stop(); 1298 if (err == OK && status != OK && status != ERROR_END_OF_STREAM) { 1299 err = status; 1300 } 1301 } 1302 1303 return err; 1304} 1305 1306bool MPEG4Writer::Track::reachedEOS() { 1307 return mReachedEOS; 1308} 1309 1310// static 1311void *MPEG4Writer::Track::ThreadWrapper(void *me) { 1312 Track *track = static_cast<Track *>(me); 1313 1314 status_t err = track->threadEntry(); 1315 return (void *) err; 1316} 1317 1318static void getNalUnitType(uint8_t byte, uint8_t* type) { 1319 LOGV("getNalUnitType: %d", byte); 1320 1321 // nal_unit_type: 5-bit unsigned integer 1322 *type = (byte & 0x1F); 1323} 1324 1325static const uint8_t *findNextStartCode( 1326 const uint8_t *data, size_t length) { 1327 1328 LOGV("findNextStartCode: %p %d", data, length); 1329 1330 size_t bytesLeft = length; 1331 while (bytesLeft > 4 && 1332 memcmp("\x00\x00\x00\x01", &data[length - bytesLeft], 4)) { 1333 --bytesLeft; 1334 } 1335 if (bytesLeft <= 4) { 1336 bytesLeft = 0; // Last parameter set 1337 } 1338 return &data[length - bytesLeft]; 1339} 1340 1341const uint8_t *MPEG4Writer::Track::parseParamSet( 1342 const uint8_t *data, size_t length, int type, size_t *paramSetLen) { 1343 1344 LOGV("parseParamSet"); 1345 CHECK(type == kNalUnitTypeSeqParamSet || 1346 type == kNalUnitTypePicParamSet); 1347 1348 const uint8_t *nextStartCode = findNextStartCode(data, length); 1349 *paramSetLen = nextStartCode - data; 1350 if (*paramSetLen == 0) { 1351 LOGE("Param set is malformed, since its length is 0"); 1352 return NULL; 1353 } 1354 1355 AVCParamSet paramSet(*paramSetLen, data); 1356 if (type == kNalUnitTypeSeqParamSet) { 1357 if (*paramSetLen < 4) { 1358 LOGE("Seq parameter set malformed"); 1359 return NULL; 1360 } 1361 if (mSeqParamSets.empty()) { 1362 mProfileIdc = data[1]; 1363 mProfileCompatible = data[2]; 1364 mLevelIdc = data[3]; 1365 } else { 1366 if (mProfileIdc != data[1] || 1367 mProfileCompatible != data[2] || 1368 mLevelIdc != data[3]) { 1369 LOGE("Inconsistent profile/level found in seq parameter sets"); 1370 return NULL; 1371 } 1372 } 1373 mSeqParamSets.push_back(paramSet); 1374 } else { 1375 mPicParamSets.push_back(paramSet); 1376 } 1377 return nextStartCode; 1378} 1379 1380status_t MPEG4Writer::Track::copyAVCCodecSpecificData( 1381 const uint8_t *data, size_t size) { 1382 LOGV("copyAVCCodecSpecificData"); 1383 1384 // 2 bytes for each of the parameter set length field 1385 // plus the 7 bytes for the header 1386 if (size < 4 + 7) { 1387 LOGE("Codec specific data length too short: %d", size); 1388 return ERROR_MALFORMED; 1389 } 1390 1391 mCodecSpecificDataSize = size; 1392 mCodecSpecificData = malloc(size); 1393 memcpy(mCodecSpecificData, data, size); 1394 return OK; 1395} 1396 1397status_t MPEG4Writer::Track::parseAVCCodecSpecificData( 1398 const uint8_t *data, size_t size) { 1399 1400 LOGV("parseAVCCodecSpecificData"); 1401 // Data starts with a start code. 1402 // SPS and PPS are separated with start codes. 1403 // Also, SPS must come before PPS 1404 uint8_t type = kNalUnitTypeSeqParamSet; 1405 bool gotSps = false; 1406 bool gotPps = false; 1407 const uint8_t *tmp = data; 1408 const uint8_t *nextStartCode = data; 1409 size_t bytesLeft = size; 1410 size_t paramSetLen = 0; 1411 mCodecSpecificDataSize = 0; 1412 while (bytesLeft > 4 && !memcmp("\x00\x00\x00\x01", tmp, 4)) { 1413 getNalUnitType(*(tmp + 4), &type); 1414 if (type == kNalUnitTypeSeqParamSet) { 1415 if (gotPps) { 1416 LOGE("SPS must come before PPS"); 1417 return ERROR_MALFORMED; 1418 } 1419 if (!gotSps) { 1420 gotSps = true; 1421 } 1422 nextStartCode = parseParamSet(tmp + 4, bytesLeft - 4, type, ¶mSetLen); 1423 } else if (type == kNalUnitTypePicParamSet) { 1424 if (!gotSps) { 1425 LOGE("SPS must come before PPS"); 1426 return ERROR_MALFORMED; 1427 } 1428 if (!gotPps) { 1429 gotPps = true; 1430 } 1431 nextStartCode = parseParamSet(tmp + 4, bytesLeft - 4, type, ¶mSetLen); 1432 } else { 1433 LOGE("Only SPS and PPS Nal units are expected"); 1434 return ERROR_MALFORMED; 1435 } 1436 1437 if (nextStartCode == NULL) { 1438 return ERROR_MALFORMED; 1439 } 1440 1441 // Move on to find the next parameter set 1442 bytesLeft -= nextStartCode - tmp; 1443 tmp = nextStartCode; 1444 mCodecSpecificDataSize += (2 + paramSetLen); 1445 } 1446 1447 { 1448 // Check on the number of seq parameter sets 1449 size_t nSeqParamSets = mSeqParamSets.size(); 1450 if (nSeqParamSets == 0) { 1451 LOGE("Cound not find sequence parameter set"); 1452 return ERROR_MALFORMED; 1453 } 1454 1455 if (nSeqParamSets > 0x1F) { 1456 LOGE("Too many seq parameter sets (%d) found", nSeqParamSets); 1457 return ERROR_MALFORMED; 1458 } 1459 } 1460 1461 { 1462 // Check on the number of pic parameter sets 1463 size_t nPicParamSets = mPicParamSets.size(); 1464 if (nPicParamSets == 0) { 1465 LOGE("Cound not find picture parameter set"); 1466 return ERROR_MALFORMED; 1467 } 1468 if (nPicParamSets > 0xFF) { 1469 LOGE("Too many pic parameter sets (%d) found", nPicParamSets); 1470 return ERROR_MALFORMED; 1471 } 1472 } 1473 1474 { 1475 // Check on the profiles 1476 // These profiles requires additional parameter set extensions 1477 if (mProfileIdc == 100 || mProfileIdc == 110 || 1478 mProfileIdc == 122 || mProfileIdc == 144) { 1479 LOGE("Sorry, no support for profile_idc: %d!", mProfileIdc); 1480 return BAD_VALUE; 1481 } 1482 } 1483 1484 return OK; 1485} 1486 1487status_t MPEG4Writer::Track::makeAVCCodecSpecificData( 1488 const uint8_t *data, size_t size) { 1489 1490 if (mCodecSpecificData != NULL) { 1491 LOGE("Already have codec specific data"); 1492 return ERROR_MALFORMED; 1493 } 1494 1495 if (size < 4) { 1496 LOGE("Codec specific data length too short: %d", size); 1497 return ERROR_MALFORMED; 1498 } 1499 1500 // Data is in the form of AVCCodecSpecificData 1501 if (memcmp("\x00\x00\x00\x01", data, 4)) { 1502 return copyAVCCodecSpecificData(data, size); 1503 } 1504 1505 if (parseAVCCodecSpecificData(data, size) != OK) { 1506 return ERROR_MALFORMED; 1507 } 1508 1509 // ISO 14496-15: AVC file format 1510 mCodecSpecificDataSize += 7; // 7 more bytes in the header 1511 mCodecSpecificData = malloc(mCodecSpecificDataSize); 1512 uint8_t *header = (uint8_t *)mCodecSpecificData; 1513 header[0] = 1; // version 1514 header[1] = mProfileIdc; // profile indication 1515 header[2] = mProfileCompatible; // profile compatibility 1516 header[3] = mLevelIdc; 1517 1518 // 6-bit '111111' followed by 2-bit to lengthSizeMinuusOne 1519 if (mOwner->useNalLengthFour()) { 1520 header[4] = 0xfc | 3; // length size == 4 bytes 1521 } else { 1522 header[4] = 0xfc | 1; // length size == 2 bytes 1523 } 1524 1525 // 3-bit '111' followed by 5-bit numSequenceParameterSets 1526 int nSequenceParamSets = mSeqParamSets.size(); 1527 header[5] = 0xe0 | nSequenceParamSets; 1528 header += 6; 1529 for (List<AVCParamSet>::iterator it = mSeqParamSets.begin(); 1530 it != mSeqParamSets.end(); ++it) { 1531 // 16-bit sequence parameter set length 1532 uint16_t seqParamSetLength = it->mLength; 1533 header[0] = seqParamSetLength >> 8; 1534 header[1] = seqParamSetLength & 0xff; 1535 1536 // SPS NAL unit (sequence parameter length bytes) 1537 memcpy(&header[2], it->mData, seqParamSetLength); 1538 header += (2 + seqParamSetLength); 1539 } 1540 1541 // 8-bit nPictureParameterSets 1542 int nPictureParamSets = mPicParamSets.size(); 1543 header[0] = nPictureParamSets; 1544 header += 1; 1545 for (List<AVCParamSet>::iterator it = mPicParamSets.begin(); 1546 it != mPicParamSets.end(); ++it) { 1547 // 16-bit picture parameter set length 1548 uint16_t picParamSetLength = it->mLength; 1549 header[0] = picParamSetLength >> 8; 1550 header[1] = picParamSetLength & 0xff; 1551 1552 // PPS Nal unit (picture parameter set length bytes) 1553 memcpy(&header[2], it->mData, picParamSetLength); 1554 header += (2 + picParamSetLength); 1555 } 1556 1557 return OK; 1558} 1559 1560/* 1561* The video track's media time adjustment for real-time applications 1562* is described as follows: 1563* 1564* First, the media time adjustment is done for every period of 1565* kVideoMediaTimeAdjustPeriodTimeUs. kVideoMediaTimeAdjustPeriodTimeUs 1566* is currently a fixed value chosen heuristically. The value of 1567* kVideoMediaTimeAdjustPeriodTimeUs should not be very large or very small 1568* for two considerations: on one hand, a relatively large value 1569* helps reduce large fluctuation of drift time in the audio encoding 1570* path; while on the other hand, a relatively small value helps keep 1571* restoring synchronization in audio/video more frequently. Note for the 1572* very first period of kVideoMediaTimeAdjustPeriodTimeUs, there is 1573* no media time adjustment for the video track. 1574* 1575* Second, the total accumulated audio track time drift found 1576* in a period of kVideoMediaTimeAdjustPeriodTimeUs is distributed 1577* over a stream of incoming video frames. The number of video frames 1578* affected is determined based on the number of recorded video frames 1579* within the past kVideoMediaTimeAdjustPeriodTimeUs period. 1580* We choose to distribute the drift time over only a portion 1581* (rather than all) of the total number of recorded video frames 1582* in order to make sure that the video track media time adjustment is 1583* completed for the current period before the next video track media 1584* time adjustment period starts. Currently, the portion chosen is a 1585* half (0.5). 1586* 1587* Last, various additional checks are performed to ensure that 1588* the actual audio encoding path does not have too much drift. 1589* In particular, 1) we want to limit the average incremental time 1590* adjustment for each video frame to be less than a threshold 1591* for a single period of kVideoMediaTimeAdjustPeriodTimeUs. 1592* Currently, the threshold is set to 5 ms. If the average incremental 1593* media time adjustment for a video frame is larger than the 1594* threshold, the audio encoding path has too much time drift. 1595* 2) We also want to limit the total time drift in the audio 1596* encoding path to be less than a threshold for a period of 1597* kVideoMediaTimeAdjustPeriodTimeUs. Currently, the threshold 1598* is 0.5% of kVideoMediaTimeAdjustPeriodTimeUs. If the time drift of 1599* the audio encoding path is larger than the threshold, the audio 1600* encoding path has too much time drift. We treat the large time 1601* drift of the audio encoding path as errors, since there is no 1602* way to keep audio/video in synchronization for real-time 1603* applications if the time drift is too large unless we drop some 1604* video frames, which has its own problems that we don't want 1605* to get into for the time being. 1606*/ 1607void MPEG4Writer::Track::adjustMediaTime(int64_t *timestampUs) { 1608 if (*timestampUs - mPrevMediaTimeAdjustTimestampUs >= 1609 kVideoMediaTimeAdjustPeriodTimeUs) { 1610 1611 LOGV("New media time adjustment period at %lld us", *timestampUs); 1612 mIsMediaTimeAdjustmentOn = true; 1613 mMediaTimeAdjustNumFrames = 1614 (mNumSamples - mPrevMediaTimeAdjustSample) >> 1; 1615 1616 mPrevMediaTimeAdjustTimestampUs = *timestampUs; 1617 mPrevMediaTimeAdjustSample = mNumSamples; 1618 int64_t totalAccumDriftTimeUs = mOwner->getDriftTimeUs(); 1619 mTotalDriftTimeToAdjustUs = 1620 totalAccumDriftTimeUs - mPrevTotalAccumDriftTimeUs; 1621 1622 mPrevTotalAccumDriftTimeUs = totalAccumDriftTimeUs; 1623 1624 // Check on incremental adjusted time per frame 1625 int64_t adjustTimePerFrameUs = 1626 mTotalDriftTimeToAdjustUs / mMediaTimeAdjustNumFrames; 1627 1628 if (adjustTimePerFrameUs < 0) { 1629 adjustTimePerFrameUs = -adjustTimePerFrameUs; 1630 } 1631 if (adjustTimePerFrameUs >= 5000) { 1632 LOGE("Adjusted time per video frame is %lld us", 1633 adjustTimePerFrameUs); 1634 CHECK(!"Video frame time adjustment is too large!"); 1635 } 1636 1637 // Check on total accumulated time drift within a period of 1638 // kVideoMediaTimeAdjustPeriodTimeUs. 1639 int64_t driftPercentage = (mTotalDriftTimeToAdjustUs * 1000) 1640 / kVideoMediaTimeAdjustPeriodTimeUs; 1641 1642 if (driftPercentage < 0) { 1643 driftPercentage = -driftPercentage; 1644 } 1645 if (driftPercentage > 5) { 1646 LOGE("Audio track has time drift %lld us over %lld us", 1647 mTotalDriftTimeToAdjustUs, 1648 kVideoMediaTimeAdjustPeriodTimeUs); 1649 1650 CHECK(!"The audio track media time drifts too much!"); 1651 } 1652 1653 } 1654 1655 if (mIsMediaTimeAdjustmentOn) { 1656 if (mNumSamples - mPrevMediaTimeAdjustSample <= 1657 mMediaTimeAdjustNumFrames) { 1658 1659 // Do media time incremental adjustment 1660 int64_t incrementalAdjustTimeUs = 1661 (mTotalDriftTimeToAdjustUs * 1662 (mNumSamples - mPrevMediaTimeAdjustSample)) 1663 / mMediaTimeAdjustNumFrames; 1664 1665 *timestampUs += 1666 (incrementalAdjustTimeUs + mPrevTotalAccumDriftTimeUs); 1667 1668 LOGV("Incremental video frame media time adjustment: %lld us", 1669 (incrementalAdjustTimeUs + mPrevTotalAccumDriftTimeUs)); 1670 } else { 1671 // Within the remaining adjustment period, 1672 // no incremental adjustment is needed. 1673 *timestampUs += 1674 (mTotalDriftTimeToAdjustUs + mPrevTotalAccumDriftTimeUs); 1675 1676 LOGV("Fixed video frame media time adjustment: %lld us", 1677 (mTotalDriftTimeToAdjustUs + mPrevTotalAccumDriftTimeUs)); 1678 } 1679 } 1680} 1681 1682/* 1683 * Updates the drift time from the audio track so that 1684 * the video track can get the updated drift time information 1685 * from the file writer. The fluctuation of the drift time of the audio 1686 * encoding path is smoothed out with a simple filter by giving a larger 1687 * weight to more recently drift time. The filter coefficients, 0.5 and 0.5, 1688 * are heuristically determined. 1689 */ 1690void MPEG4Writer::Track::updateDriftTime(const sp<MetaData>& meta) { 1691 int64_t driftTimeUs = 0; 1692 if (meta->findInt64(kKeyDriftTime, &driftTimeUs)) { 1693 int64_t prevDriftTimeUs = mOwner->getDriftTimeUs(); 1694 int64_t timeUs = (driftTimeUs + prevDriftTimeUs) >> 1; 1695 mOwner->setDriftTimeUs(timeUs); 1696 } 1697} 1698 1699status_t MPEG4Writer::Track::threadEntry() { 1700 int32_t count = 0; 1701 const int64_t interleaveDurationUs = mOwner->interleaveDuration(); 1702 int64_t chunkTimestampUs = 0; 1703 int32_t nChunks = 0; 1704 int32_t nZeroLengthFrames = 0; 1705 int64_t lastTimestampUs = 0; // Previous sample time stamp in ms 1706 int64_t lastDurationUs = 0; // Between the previous two samples in ms 1707 int64_t currDurationTicks = 0; // Timescale based ticks 1708 int64_t lastDurationTicks = 0; // Timescale based ticks 1709 int32_t sampleCount = 1; // Sample count in the current stts table entry 1710 uint32_t previousSampleSize = 0; // Size of the previous sample 1711 int64_t previousPausedDurationUs = 0; 1712 int64_t timestampUs; 1713 1714 if (mIsAudio) { 1715 prctl(PR_SET_NAME, (unsigned long)"AudioTrackEncoding", 0, 0, 0); 1716 } else { 1717 prctl(PR_SET_NAME, (unsigned long)"VideoTrackEncoding", 0, 0, 0); 1718 } 1719 sp<MetaData> meta_data; 1720 1721 mNumSamples = 0; 1722 status_t err = OK; 1723 MediaBuffer *buffer; 1724 while (!mDone && (err = mSource->read(&buffer)) == OK) { 1725 if (buffer->range_length() == 0) { 1726 buffer->release(); 1727 buffer = NULL; 1728 ++nZeroLengthFrames; 1729 continue; 1730 } 1731 1732 // If the codec specific data has not been received yet, delay pause. 1733 // After the codec specific data is received, discard what we received 1734 // when the track is to be paused. 1735 if (mPaused && !mResumed) { 1736 buffer->release(); 1737 buffer = NULL; 1738 continue; 1739 } 1740 1741 ++count; 1742 1743 int32_t isCodecConfig; 1744 if (buffer->meta_data()->findInt32(kKeyIsCodecConfig, &isCodecConfig) 1745 && isCodecConfig) { 1746 CHECK(!mGotAllCodecSpecificData); 1747 1748 if (mIsAvc) { 1749 status_t err = makeAVCCodecSpecificData( 1750 (const uint8_t *)buffer->data() 1751 + buffer->range_offset(), 1752 buffer->range_length()); 1753 CHECK_EQ(OK, err); 1754 } else if (mIsMPEG4) { 1755 mCodecSpecificDataSize = buffer->range_length(); 1756 mCodecSpecificData = malloc(mCodecSpecificDataSize); 1757 memcpy(mCodecSpecificData, 1758 (const uint8_t *)buffer->data() 1759 + buffer->range_offset(), 1760 buffer->range_length()); 1761 } 1762 1763 buffer->release(); 1764 buffer = NULL; 1765 1766 mGotAllCodecSpecificData = true; 1767 continue; 1768 } 1769 1770 // Make a deep copy of the MediaBuffer and Metadata and release 1771 // the original as soon as we can 1772 MediaBuffer *copy = new MediaBuffer(buffer->range_length()); 1773 memcpy(copy->data(), (uint8_t *)buffer->data() + buffer->range_offset(), 1774 buffer->range_length()); 1775 copy->set_range(0, buffer->range_length()); 1776 meta_data = new MetaData(*buffer->meta_data().get()); 1777 buffer->release(); 1778 buffer = NULL; 1779 1780 if (mIsAvc) StripStartcode(copy); 1781 1782 size_t sampleSize = copy->range_length(); 1783 if (mIsAvc) { 1784 if (mOwner->useNalLengthFour()) { 1785 sampleSize += 4; 1786 } else { 1787 sampleSize += 2; 1788 } 1789 } 1790 1791 // Max file size or duration handling 1792 mMdatSizeBytes += sampleSize; 1793 updateTrackSizeEstimate(); 1794 1795 if (mOwner->exceedsFileSizeLimit()) { 1796 mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED, 0); 1797 break; 1798 } 1799 if (mOwner->exceedsFileDurationLimit()) { 1800 mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_DURATION_REACHED, 0); 1801 break; 1802 } 1803 1804 1805 int32_t isSync = false; 1806 meta_data->findInt32(kKeyIsSyncFrame, &isSync); 1807 1808 /* 1809 * The original timestamp found in the data buffer will be modified as below: 1810 * 1811 * There is a playback offset into this track if the track's start time 1812 * is not the same as the movie start time, which will be recorded in edst 1813 * box of the output file. The playback offset is to make sure that the 1814 * starting time of the audio/video tracks are synchronized. Although the 1815 * track's media timestamp may be subject to various modifications 1816 * as outlined below, the track's playback offset time remains unchanged 1817 * once the first data buffer of the track is received. 1818 * 1819 * The media time stamp will be calculated by subtracting the playback offset 1820 * (and potential pause durations) from the original timestamp in the buffer. 1821 * 1822 * If this track is a video track for a real-time recording application with 1823 * both audio and video tracks, its media timestamp will subject to further 1824 * modification based on the media clock of the audio track. This modification 1825 * is needed for the purpose of maintaining good audio/video synchronization. 1826 * 1827 * If the recording session is paused and resumed multiple times, the track 1828 * media timestamp will be modified as if the recording session had never been 1829 * paused at all during playback of the recorded output file. In other words, 1830 * the output file will have no memory of pause/resume durations. 1831 * 1832 */ 1833 CHECK(meta_data->findInt64(kKeyTime, ×tampUs)); 1834 LOGV("%s timestampUs: %lld", mIsAudio? "Audio": "Video", timestampUs); 1835 1836//////////////////////////////////////////////////////////////////////////////// 1837 if (mSampleSizes.empty()) { 1838 mStartTimestampUs = timestampUs; 1839 mOwner->setStartTimestampUs(mStartTimestampUs); 1840 previousPausedDurationUs = mStartTimestampUs; 1841 } 1842 1843 if (mResumed) { 1844 int64_t durExcludingEarlierPausesUs = timestampUs - previousPausedDurationUs; 1845 CHECK(durExcludingEarlierPausesUs >= 0); 1846 int64_t pausedDurationUs = durExcludingEarlierPausesUs - mTrackDurationUs; 1847 CHECK(pausedDurationUs >= lastDurationUs); 1848 previousPausedDurationUs += pausedDurationUs - lastDurationUs; 1849 mResumed = false; 1850 } 1851 1852 timestampUs -= previousPausedDurationUs; 1853 CHECK(timestampUs >= 0); 1854 1855 // Media time adjustment for real-time applications 1856 if (mIsRealTimeRecording) { 1857 if (mIsAudio) { 1858 updateDriftTime(meta_data); 1859 } else { 1860 adjustMediaTime(×tampUs); 1861 } 1862 } 1863 1864 CHECK(timestampUs >= 0); 1865 if (mNumSamples > 1) { 1866 if (timestampUs <= lastTimestampUs) { 1867 LOGW("Frame arrives too late!"); 1868 // Don't drop the late frame, since dropping a frame may cause 1869 // problems later during playback 1870 1871 // The idea here is to avoid having two or more samples with the 1872 // same timestamp in the output file. 1873 if (mTimeScale >= 1000000LL) { 1874 timestampUs = lastTimestampUs + 1; 1875 } else { 1876 timestampUs = lastTimestampUs + (1000000LL + (mTimeScale >> 1)) / mTimeScale; 1877 } 1878 } 1879 } 1880 1881 LOGV("%s media time stamp: %lld and previous paused duration %lld", 1882 mIsAudio? "Audio": "Video", timestampUs, previousPausedDurationUs); 1883 if (timestampUs > mTrackDurationUs) { 1884 mTrackDurationUs = timestampUs; 1885 } 1886 1887 mSampleSizes.push_back(sampleSize); 1888 ++mNumSamples; 1889 if (mNumSamples > 2) { 1890 // We need to use the time scale based ticks, rather than the 1891 // timestamp itself to determine whether we have to use a new 1892 // stts entry, since we may have rounding errors. 1893 // The calculation is intended to reduce the accumulated 1894 // rounding errors. 1895 currDurationTicks = 1896 ((timestampUs * mTimeScale + 500000LL) / 1000000LL - 1897 (lastTimestampUs * mTimeScale + 500000LL) / 1000000LL); 1898 1899 if (currDurationTicks != lastDurationTicks) { 1900 addOneSttsTableEntry(sampleCount, lastDurationUs); 1901 sampleCount = 1; 1902 } else { 1903 ++sampleCount; 1904 } 1905 } 1906 if (mSamplesHaveSameSize) { 1907 if (mNumSamples >= 2 && previousSampleSize != sampleSize) { 1908 mSamplesHaveSameSize = false; 1909 } 1910 previousSampleSize = sampleSize; 1911 } 1912 lastDurationUs = timestampUs - lastTimestampUs; 1913 lastDurationTicks = currDurationTicks; 1914 lastTimestampUs = timestampUs; 1915 1916 if (isSync != 0) { 1917 addOneStssTableEntry(mNumSamples); 1918 } 1919 1920 if (mTrackingProgressStatus) { 1921 if (mPreviousTrackTimeUs <= 0) { 1922 mPreviousTrackTimeUs = mStartTimestampUs; 1923 } 1924 trackProgressStatus(timestampUs); 1925 } 1926 if (mOwner->numTracks() == 1) { 1927 off_t offset = mIsAvc? mOwner->addLengthPrefixedSample_l(copy) 1928 : mOwner->addSample_l(copy); 1929 if (mChunkOffsets.empty()) { 1930 addChunkOffset(offset); 1931 } 1932 copy->release(); 1933 copy = NULL; 1934 continue; 1935 } 1936 1937 mChunkSamples.push_back(copy); 1938 if (interleaveDurationUs == 0) { 1939 addOneStscTableEntry(++nChunks, 1); 1940 bufferChunk(timestampUs); 1941 } else { 1942 if (chunkTimestampUs == 0) { 1943 chunkTimestampUs = timestampUs; 1944 } else { 1945 if (timestampUs - chunkTimestampUs > interleaveDurationUs) { 1946 ++nChunks; 1947 if (nChunks == 1 || // First chunk 1948 (--(mStscTableEntries.end()))->samplesPerChunk != 1949 mChunkSamples.size()) { 1950 addOneStscTableEntry(nChunks, mChunkSamples.size()); 1951 } 1952 bufferChunk(timestampUs); 1953 chunkTimestampUs = timestampUs; 1954 } 1955 } 1956 } 1957 1958 } 1959 1960 if (mSampleSizes.empty() || // no samples written 1961 (!mIsAudio && mNumStssTableEntries == 0) || // no sync frames for video 1962 (OK != checkCodecSpecificData())) { // no codec specific data 1963 err = ERROR_MALFORMED; 1964 } 1965 mOwner->trackProgressStatus(this, -1, err); 1966 1967 // Last chunk 1968 if (mOwner->numTracks() == 1) { 1969 addOneStscTableEntry(1, mNumSamples); 1970 } else if (!mChunkSamples.empty()) { 1971 addOneStscTableEntry(++nChunks, mChunkSamples.size()); 1972 bufferChunk(timestampUs); 1973 } 1974 1975 // We don't really know how long the last frame lasts, since 1976 // there is no frame time after it, just repeat the previous 1977 // frame's duration. 1978 if (mNumSamples == 1) { 1979 lastDurationUs = 0; // A single sample's duration 1980 } else { 1981 ++sampleCount; // Count for the last sample 1982 } 1983 addOneSttsTableEntry(sampleCount, lastDurationUs); 1984 mTrackDurationUs += lastDurationUs; 1985 mReachedEOS = true; 1986 LOGI("Received total/0-length (%d/%d) buffers and encoded %d frames. - %s", 1987 count, nZeroLengthFrames, mNumSamples, mIsAudio? "audio": "video"); 1988 if (mIsAudio) { 1989 LOGI("Audio track drift time: %lld us", mOwner->getDriftTimeUs()); 1990 } 1991 1992 if (err == ERROR_END_OF_STREAM) { 1993 return OK; 1994 } 1995 return err; 1996} 1997 1998void MPEG4Writer::Track::trackProgressStatus(int64_t timeUs, status_t err) { 1999 LOGV("trackProgressStatus: %lld us", timeUs); 2000 if (mTrackEveryTimeDurationUs > 0 && 2001 timeUs - mPreviousTrackTimeUs >= mTrackEveryTimeDurationUs) { 2002 LOGV("Fire time tracking progress status at %lld us", timeUs); 2003 mOwner->trackProgressStatus(this, timeUs - mPreviousTrackTimeUs, err); 2004 mPreviousTrackTimeUs = timeUs; 2005 } 2006} 2007 2008void MPEG4Writer::trackProgressStatus( 2009 const MPEG4Writer::Track* track, int64_t timeUs, status_t err) { 2010 Mutex::Autolock lock(mLock); 2011 int32_t nTracks = mTracks.size(); 2012 CHECK(nTracks >= 1); 2013 CHECK(nTracks < 64); // Arbitrary number 2014 2015 int32_t trackNum = 0; 2016 CHECK(trackNum < nTracks); 2017 trackNum <<= 16; 2018 2019 // Error notification 2020 // Do not consider ERROR_END_OF_STREAM an error 2021 if (err != OK && err != ERROR_END_OF_STREAM) { 2022 notify(MEDIA_RECORDER_EVENT_ERROR, 2023 trackNum | MEDIA_RECORDER_ERROR_UNKNOWN, 2024 err); 2025 return; 2026 } 2027 2028 if (timeUs == -1) { 2029 // Send completion notification 2030 notify(MEDIA_RECORDER_EVENT_INFO, 2031 trackNum | MEDIA_RECORDER_INFO_COMPLETION_STATUS, 2032 err); 2033 return; 2034 } else { 2035 // Send progress status 2036 notify(MEDIA_RECORDER_EVENT_INFO, 2037 trackNum | MEDIA_RECORDER_INFO_PROGRESS_TIME_STATUS, 2038 timeUs / 1000); 2039 } 2040} 2041 2042void MPEG4Writer::setDriftTimeUs(int64_t driftTimeUs) { 2043 LOGV("setDriftTimeUs: %lld us", driftTimeUs); 2044 Mutex::Autolock autolock(mLock); 2045 mDriftTimeUs = driftTimeUs; 2046} 2047 2048int64_t MPEG4Writer::getDriftTimeUs() { 2049 LOGV("getDriftTimeUs: %lld us", mDriftTimeUs); 2050 Mutex::Autolock autolock(mLock); 2051 return mDriftTimeUs; 2052} 2053 2054bool MPEG4Writer::useNalLengthFour() { 2055 return mUse4ByteNalLength; 2056} 2057 2058void MPEG4Writer::Track::bufferChunk(int64_t timestampUs) { 2059 LOGV("bufferChunk"); 2060 2061 Chunk chunk(this, timestampUs, mChunkSamples); 2062 mOwner->bufferChunk(chunk); 2063 mChunkSamples.clear(); 2064} 2065 2066int64_t MPEG4Writer::Track::getDurationUs() const { 2067 return mTrackDurationUs; 2068} 2069 2070int64_t MPEG4Writer::Track::getEstimatedTrackSizeBytes() const { 2071 return mEstimatedTrackSizeBytes; 2072} 2073 2074status_t MPEG4Writer::Track::checkCodecSpecificData() const { 2075 const char *mime; 2076 CHECK(mMeta->findCString(kKeyMIMEType, &mime)); 2077 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime) || 2078 !strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime) || 2079 !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) { 2080 if (!mCodecSpecificData || 2081 mCodecSpecificDataSize <= 0) { 2082 LOGE("Missing codec specific data"); 2083 return ERROR_MALFORMED; 2084 } 2085 } else { 2086 if (mCodecSpecificData || 2087 mCodecSpecificDataSize > 0) { 2088 LOGE("Unexepected codec specific data found"); 2089 return ERROR_MALFORMED; 2090 } 2091 } 2092 return OK; 2093} 2094 2095void MPEG4Writer::Track::writeTrackHeader( 2096 int32_t trackID, bool use32BitOffset) { 2097 const char *mime; 2098 bool success = mMeta->findCString(kKeyMIMEType, &mime); 2099 CHECK(success); 2100 2101 LOGV("%s track time scale: %d", 2102 mIsAudio? "Audio": "Video", mTimeScale); 2103 2104 time_t now = time(NULL); 2105 int32_t mvhdTimeScale = mOwner->getTimeScale(); 2106 int64_t trakDurationUs = getDurationUs(); 2107 2108 mOwner->beginBox("trak"); 2109 2110 mOwner->beginBox("tkhd"); 2111 // Flags = 7 to indicate that the track is enabled, and 2112 // part of the presentation 2113 mOwner->writeInt32(0x07); // version=0, flags=7 2114 mOwner->writeInt32(now); // creation time 2115 mOwner->writeInt32(now); // modification time 2116 mOwner->writeInt32(trackID); 2117 mOwner->writeInt32(0); // reserved 2118 int32_t tkhdDuration = 2119 (trakDurationUs * mvhdTimeScale + 5E5) / 1E6; 2120 mOwner->writeInt32(tkhdDuration); // in mvhd timescale 2121 mOwner->writeInt32(0); // reserved 2122 mOwner->writeInt32(0); // reserved 2123 mOwner->writeInt16(0); // layer 2124 mOwner->writeInt16(0); // alternate group 2125 mOwner->writeInt16(mIsAudio ? 0x100 : 0); // volume 2126 mOwner->writeInt16(0); // reserved 2127 2128 mOwner->writeCompositionMatrix(mRotation); 2129 2130 if (mIsAudio) { 2131 mOwner->writeInt32(0); 2132 mOwner->writeInt32(0); 2133 } else { 2134 int32_t width, height; 2135 bool success = mMeta->findInt32(kKeyWidth, &width); 2136 success = success && mMeta->findInt32(kKeyHeight, &height); 2137 CHECK(success); 2138 2139 mOwner->writeInt32(width << 16); // 32-bit fixed-point value 2140 mOwner->writeInt32(height << 16); // 32-bit fixed-point value 2141 } 2142 mOwner->endBox(); // tkhd 2143 2144 int64_t moovStartTimeUs = mOwner->getStartTimestampUs(); 2145 if (mStartTimestampUs != moovStartTimeUs) { 2146 mOwner->beginBox("edts"); 2147 mOwner->beginBox("elst"); 2148 mOwner->writeInt32(0); // version=0, flags=0: 32-bit time 2149 mOwner->writeInt32(2); // never ends with an empty list 2150 2151 // First elst entry: specify the starting time offset 2152 int64_t offsetUs = mStartTimestampUs - moovStartTimeUs; 2153 LOGV("OffsetUs: %lld", offsetUs); 2154 int32_t seg = (offsetUs * mvhdTimeScale + 5E5) / 1E6; 2155 mOwner->writeInt32(seg); // in mvhd timecale 2156 mOwner->writeInt32(-1); // starting time offset 2157 mOwner->writeInt32(1 << 16); // rate = 1.0 2158 2159 // Second elst entry: specify the track duration 2160 seg = (trakDurationUs * mvhdTimeScale + 5E5) / 1E6; 2161 mOwner->writeInt32(seg); // in mvhd timescale 2162 mOwner->writeInt32(0); 2163 mOwner->writeInt32(1 << 16); 2164 mOwner->endBox(); 2165 mOwner->endBox(); 2166 } 2167 2168 mOwner->beginBox("mdia"); 2169 2170 mOwner->beginBox("mdhd"); 2171 mOwner->writeInt32(0); // version=0, flags=0 2172 mOwner->writeInt32(now); // creation time 2173 mOwner->writeInt32(now); // modification time 2174 mOwner->writeInt32(mTimeScale); // media timescale 2175 int32_t mdhdDuration = (trakDurationUs * mTimeScale + 5E5) / 1E6; 2176 mOwner->writeInt32(mdhdDuration); // use media timescale 2177 // Language follows the three letter standard ISO-639-2/T 2178 // 'e', 'n', 'g' for "English", for instance. 2179 // Each character is packed as the difference between its ASCII value and 0x60. 2180 // For "English", these are 00101, 01110, 00111. 2181 // XXX: Where is the padding bit located: 0x15C7? 2182 mOwner->writeInt16(0); // language code 2183 mOwner->writeInt16(0); // predefined 2184 mOwner->endBox(); 2185 2186 mOwner->beginBox("hdlr"); 2187 mOwner->writeInt32(0); // version=0, flags=0 2188 mOwner->writeInt32(0); // component type: should be mhlr 2189 mOwner->writeFourcc(mIsAudio ? "soun" : "vide"); // component subtype 2190 mOwner->writeInt32(0); // reserved 2191 mOwner->writeInt32(0); // reserved 2192 mOwner->writeInt32(0); // reserved 2193 // Removing "r" for the name string just makes the string 4 byte aligned 2194 mOwner->writeCString(mIsAudio ? "SoundHandle": "VideoHandle"); // name 2195 mOwner->endBox(); 2196 2197 mOwner->beginBox("minf"); 2198 if (mIsAudio) { 2199 mOwner->beginBox("smhd"); 2200 mOwner->writeInt32(0); // version=0, flags=0 2201 mOwner->writeInt16(0); // balance 2202 mOwner->writeInt16(0); // reserved 2203 mOwner->endBox(); 2204 } else { 2205 mOwner->beginBox("vmhd"); 2206 mOwner->writeInt32(0x01); // version=0, flags=1 2207 mOwner->writeInt16(0); // graphics mode 2208 mOwner->writeInt16(0); // opcolor 2209 mOwner->writeInt16(0); 2210 mOwner->writeInt16(0); 2211 mOwner->endBox(); 2212 } 2213 2214 mOwner->beginBox("dinf"); 2215 mOwner->beginBox("dref"); 2216 mOwner->writeInt32(0); // version=0, flags=0 2217 mOwner->writeInt32(1); // entry count (either url or urn) 2218 // The table index here refers to the sample description index 2219 // in the sample table entries. 2220 mOwner->beginBox("url "); 2221 mOwner->writeInt32(1); // version=0, flags=1 (self-contained) 2222 mOwner->endBox(); // url 2223 mOwner->endBox(); // dref 2224 mOwner->endBox(); // dinf 2225 2226 mOwner->beginBox("stbl"); 2227 2228 mOwner->beginBox("stsd"); 2229 mOwner->writeInt32(0); // version=0, flags=0 2230 mOwner->writeInt32(1); // entry count 2231 if (mIsAudio) { 2232 const char *fourcc = NULL; 2233 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime)) { 2234 fourcc = "samr"; 2235 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) { 2236 fourcc = "sawb"; 2237 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) { 2238 fourcc = "mp4a"; 2239 } else { 2240 LOGE("Unknown mime type '%s'.", mime); 2241 CHECK(!"should not be here, unknown mime type."); 2242 } 2243 2244 mOwner->beginBox(fourcc); // audio format 2245 mOwner->writeInt32(0); // reserved 2246 mOwner->writeInt16(0); // reserved 2247 mOwner->writeInt16(0x1); // data ref index 2248 mOwner->writeInt32(0); // reserved 2249 mOwner->writeInt32(0); // reserved 2250 int32_t nChannels; 2251 CHECK_EQ(true, mMeta->findInt32(kKeyChannelCount, &nChannels)); 2252 mOwner->writeInt16(nChannels); // channel count 2253 mOwner->writeInt16(16); // sample size 2254 mOwner->writeInt16(0); // predefined 2255 mOwner->writeInt16(0); // reserved 2256 2257 int32_t samplerate; 2258 bool success = mMeta->findInt32(kKeySampleRate, &samplerate); 2259 CHECK(success); 2260 mOwner->writeInt32(samplerate << 16); 2261 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) { 2262 mOwner->beginBox("esds"); 2263 CHECK(mCodecSpecificData); 2264 CHECK(mCodecSpecificDataSize > 0); 2265 2266 mOwner->writeInt32(0); // version=0, flags=0 2267 mOwner->writeInt8(0x03); // ES_DescrTag 2268 mOwner->writeInt8(23 + mCodecSpecificDataSize); 2269 mOwner->writeInt16(0x0000);// ES_ID 2270 mOwner->writeInt8(0x00); 2271 2272 mOwner->writeInt8(0x04); // DecoderConfigDescrTag 2273 mOwner->writeInt8(15 + mCodecSpecificDataSize); 2274 mOwner->writeInt8(0x40); // objectTypeIndication ISO/IEC 14492-2 2275 mOwner->writeInt8(0x15); // streamType AudioStream 2276 2277 mOwner->writeInt16(0x03); // XXX 2278 mOwner->writeInt8(0x00); // buffer size 24-bit 2279 mOwner->writeInt32(96000); // max bit rate 2280 mOwner->writeInt32(96000); // avg bit rate 2281 2282 mOwner->writeInt8(0x05); // DecoderSpecificInfoTag 2283 mOwner->writeInt8(mCodecSpecificDataSize); 2284 mOwner->write(mCodecSpecificData, mCodecSpecificDataSize); 2285 2286 static const uint8_t kData2[] = { 2287 0x06, // SLConfigDescriptorTag 2288 0x01, 2289 0x02 2290 }; 2291 mOwner->write(kData2, sizeof(kData2)); 2292 2293 mOwner->endBox(); // esds 2294 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime) || 2295 !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) { 2296 // 3gpp2 Spec AMRSampleEntry fields 2297 mOwner->beginBox("damr"); 2298 mOwner->writeCString(" "); // vendor: 4 bytes 2299 mOwner->writeInt8(0); // decoder version 2300 mOwner->writeInt16(0x83FF); // mode set: all enabled 2301 mOwner->writeInt8(0); // mode change period 2302 mOwner->writeInt8(1); // frames per sample 2303 mOwner->endBox(); 2304 } 2305 mOwner->endBox(); 2306 } else { 2307 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { 2308 mOwner->beginBox("mp4v"); 2309 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { 2310 mOwner->beginBox("s263"); 2311 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) { 2312 mOwner->beginBox("avc1"); 2313 } else { 2314 LOGE("Unknown mime type '%s'.", mime); 2315 CHECK(!"should not be here, unknown mime type."); 2316 } 2317 2318 mOwner->writeInt32(0); // reserved 2319 mOwner->writeInt16(0); // reserved 2320 mOwner->writeInt16(1); // data ref index 2321 mOwner->writeInt16(0); // predefined 2322 mOwner->writeInt16(0); // reserved 2323 mOwner->writeInt32(0); // predefined 2324 mOwner->writeInt32(0); // predefined 2325 mOwner->writeInt32(0); // predefined 2326 2327 int32_t width, height; 2328 bool success = mMeta->findInt32(kKeyWidth, &width); 2329 success = success && mMeta->findInt32(kKeyHeight, &height); 2330 CHECK(success); 2331 2332 mOwner->writeInt16(width); 2333 mOwner->writeInt16(height); 2334 mOwner->writeInt32(0x480000); // horiz resolution 2335 mOwner->writeInt32(0x480000); // vert resolution 2336 mOwner->writeInt32(0); // reserved 2337 mOwner->writeInt16(1); // frame count 2338 mOwner->write(" ", 32); 2339 mOwner->writeInt16(0x18); // depth 2340 mOwner->writeInt16(-1); // predefined 2341 2342 CHECK(23 + mCodecSpecificDataSize < 128); 2343 2344 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { 2345 CHECK(mCodecSpecificData); 2346 CHECK(mCodecSpecificDataSize > 0); 2347 mOwner->beginBox("esds"); 2348 2349 mOwner->writeInt32(0); // version=0, flags=0 2350 2351 mOwner->writeInt8(0x03); // ES_DescrTag 2352 mOwner->writeInt8(23 + mCodecSpecificDataSize); 2353 mOwner->writeInt16(0x0000); // ES_ID 2354 mOwner->writeInt8(0x1f); 2355 2356 mOwner->writeInt8(0x04); // DecoderConfigDescrTag 2357 mOwner->writeInt8(15 + mCodecSpecificDataSize); 2358 mOwner->writeInt8(0x20); // objectTypeIndication ISO/IEC 14492-2 2359 mOwner->writeInt8(0x11); // streamType VisualStream 2360 2361 static const uint8_t kData[] = { 2362 0x01, 0x77, 0x00, 2363 0x00, 0x03, 0xe8, 0x00, 2364 0x00, 0x03, 0xe8, 0x00 2365 }; 2366 mOwner->write(kData, sizeof(kData)); 2367 2368 mOwner->writeInt8(0x05); // DecoderSpecificInfoTag 2369 2370 mOwner->writeInt8(mCodecSpecificDataSize); 2371 mOwner->write(mCodecSpecificData, mCodecSpecificDataSize); 2372 2373 static const uint8_t kData2[] = { 2374 0x06, // SLConfigDescriptorTag 2375 0x01, 2376 0x02 2377 }; 2378 mOwner->write(kData2, sizeof(kData2)); 2379 2380 mOwner->endBox(); // esds 2381 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { 2382 mOwner->beginBox("d263"); 2383 2384 mOwner->writeInt32(0); // vendor 2385 mOwner->writeInt8(0); // decoder version 2386 mOwner->writeInt8(10); // level: 10 2387 mOwner->writeInt8(0); // profile: 0 2388 2389 mOwner->endBox(); // d263 2390 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) { 2391 CHECK(mCodecSpecificData); 2392 CHECK(mCodecSpecificDataSize >= 5); 2393 2394 // Patch avcc's lengthSize field to match the number 2395 // of bytes we use to indicate the size of a nal unit. 2396 uint8_t *ptr = (uint8_t *)mCodecSpecificData; 2397 ptr[4] = 2398 (ptr[4] & 0xfc) 2399 | (mOwner->useNalLengthFour() ? 3 : 1); 2400 2401 mOwner->beginBox("avcC"); 2402 mOwner->write(mCodecSpecificData, mCodecSpecificDataSize); 2403 mOwner->endBox(); // avcC 2404 } 2405 2406 mOwner->beginBox("pasp"); 2407 // This is useful if the pixel is not square 2408 mOwner->writeInt32(1 << 16); // hspacing 2409 mOwner->writeInt32(1 << 16); // vspacing 2410 mOwner->endBox(); // pasp 2411 mOwner->endBox(); // mp4v, s263 or avc1 2412 } 2413 mOwner->endBox(); // stsd 2414 2415 mOwner->beginBox("stts"); 2416 mOwner->writeInt32(0); // version=0, flags=0 2417 mOwner->writeInt32(mNumSttsTableEntries); 2418 int64_t prevTimestampUs = 0; 2419 for (List<SttsTableEntry>::iterator it = mSttsTableEntries.begin(); 2420 it != mSttsTableEntries.end(); ++it) { 2421 mOwner->writeInt32(it->sampleCount); 2422 2423 // Make sure that we are calculating the sample duration the exactly 2424 // same way as we made decision on how to create stts entries. 2425 int64_t currTimestampUs = prevTimestampUs + it->sampleDurationUs; 2426 int32_t dur = ((currTimestampUs * mTimeScale + 500000LL) / 1000000LL - 2427 (prevTimestampUs * mTimeScale + 500000LL) / 1000000LL); 2428 prevTimestampUs += (it->sampleCount * it->sampleDurationUs); 2429 2430 mOwner->writeInt32(dur); 2431 } 2432 mOwner->endBox(); // stts 2433 2434 if (!mIsAudio) { 2435 mOwner->beginBox("stss"); 2436 mOwner->writeInt32(0); // version=0, flags=0 2437 mOwner->writeInt32(mNumStssTableEntries); // number of sync frames 2438 for (List<int32_t>::iterator it = mStssTableEntries.begin(); 2439 it != mStssTableEntries.end(); ++it) { 2440 mOwner->writeInt32(*it); 2441 } 2442 mOwner->endBox(); // stss 2443 } 2444 2445 mOwner->beginBox("stsz"); 2446 mOwner->writeInt32(0); // version=0, flags=0 2447 if (mSamplesHaveSameSize) { 2448 List<size_t>::iterator it = mSampleSizes.begin(); 2449 mOwner->writeInt32(*it); // default sample size 2450 } else { 2451 mOwner->writeInt32(0); 2452 } 2453 mOwner->writeInt32(mNumSamples); 2454 if (!mSamplesHaveSameSize) { 2455 for (List<size_t>::iterator it = mSampleSizes.begin(); 2456 it != mSampleSizes.end(); ++it) { 2457 mOwner->writeInt32(*it); 2458 } 2459 } 2460 mOwner->endBox(); // stsz 2461 2462 mOwner->beginBox("stsc"); 2463 mOwner->writeInt32(0); // version=0, flags=0 2464 mOwner->writeInt32(mNumStscTableEntries); 2465 for (List<StscTableEntry>::iterator it = mStscTableEntries.begin(); 2466 it != mStscTableEntries.end(); ++it) { 2467 mOwner->writeInt32(it->firstChunk); 2468 mOwner->writeInt32(it->samplesPerChunk); 2469 mOwner->writeInt32(it->sampleDescriptionId); 2470 } 2471 mOwner->endBox(); // stsc 2472 mOwner->beginBox(use32BitOffset? "stco": "co64"); 2473 mOwner->writeInt32(0); // version=0, flags=0 2474 mOwner->writeInt32(mNumStcoTableEntries); 2475 for (List<off_t>::iterator it = mChunkOffsets.begin(); 2476 it != mChunkOffsets.end(); ++it) { 2477 if (use32BitOffset) { 2478 mOwner->writeInt32(static_cast<int32_t>(*it)); 2479 } else { 2480 mOwner->writeInt64((*it)); 2481 } 2482 } 2483 mOwner->endBox(); // stco or co64 2484 2485 mOwner->endBox(); // stbl 2486 mOwner->endBox(); // minf 2487 mOwner->endBox(); // mdia 2488 mOwner->endBox(); // trak 2489} 2490 2491} // namespace android 2492