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