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