MPEG4Writer.cpp revision ad4e408b8ea397caadbfee85e1e39515e7e08104
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 26#include <media/stagefright/foundation/ADebug.h> 27#include <media/stagefright/MPEG4Writer.h> 28#include <media/stagefright/MediaBuffer.h> 29#include <media/stagefright/MetaData.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#include <cutils/properties.h> 36#include <sys/types.h> 37#include <sys/stat.h> 38#include <fcntl.h> 39#include <unistd.h> 40 41#include "include/ESDS.h" 42 43namespace android { 44 45static const int64_t kMinStreamableFileSizeInBytes = 5 * 1024 * 1024; 46static const int64_t kMax32BitFileSize = 0x007fffffffLL; 47static const uint8_t kNalUnitTypeSeqParamSet = 0x07; 48static const uint8_t kNalUnitTypePicParamSet = 0x08; 49static const int64_t kInitialDelayTimeUs = 700000LL; 50 51class MPEG4Writer::Track { 52public: 53 Track(MPEG4Writer *owner, const sp<MediaSource> &source, size_t trackId); 54 55 ~Track(); 56 57 status_t start(MetaData *params); 58 status_t stop(); 59 status_t pause(); 60 bool reachedEOS(); 61 62 int64_t getDurationUs() const; 63 int64_t getEstimatedTrackSizeBytes() const; 64 void writeTrackHeader(bool use32BitOffset = true); 65 void bufferChunk(int64_t timestampUs); 66 bool isAvc() const { return mIsAvc; } 67 bool isAudio() const { return mIsAudio; } 68 bool isMPEG4() const { return mIsMPEG4; } 69 void addChunkOffset(off64_t offset); 70 int32_t getTrackId() const { return mTrackId; } 71 status_t dump(int fd, const Vector<String16>& args) const; 72 73private: 74 enum { 75 kMaxCttsOffsetTimeUs = 1000000LL, // 1 second 76 kSampleArraySize = 1000, 77 }; 78 79 // A helper class to handle faster write box with table entries 80 template<class TYPE> 81 struct ListTableEntries { 82 ListTableEntries(uint32_t elementCapacity, uint32_t entryCapacity) 83 : mElementCapacity(elementCapacity), 84 mEntryCapacity(entryCapacity), 85 mTotalNumTableEntries(0), 86 mNumValuesInCurrEntry(0), 87 mCurrTableEntriesElement(NULL) { 88 CHECK_GT(mElementCapacity, 0); 89 CHECK_GT(mEntryCapacity, 0); 90 } 91 92 // Free the allocated memory. 93 ~ListTableEntries() { 94 while (!mTableEntryList.empty()) { 95 typename List<TYPE *>::iterator it = mTableEntryList.begin(); 96 delete[] (*it); 97 mTableEntryList.erase(it); 98 } 99 } 100 101 // Replace the value at the given position by the given value. 102 // There must be an existing value at the given position. 103 // @arg value must be in network byte order 104 // @arg pos location the value must be in. 105 void set(const TYPE& value, uint32_t pos) { 106 CHECK_LT(pos, mTotalNumTableEntries * mEntryCapacity); 107 108 typename List<TYPE *>::iterator it = mTableEntryList.begin(); 109 uint32_t iterations = (pos / (mElementCapacity * mEntryCapacity)); 110 while (it != mTableEntryList.end() && iterations > 0) { 111 ++it; 112 --iterations; 113 } 114 CHECK(it != mTableEntryList.end()); 115 CHECK_EQ(iterations, 0); 116 117 (*it)[(pos % (mElementCapacity * mEntryCapacity))] = value; 118 } 119 120 // Get the value at the given position by the given value. 121 // @arg value the retrieved value at the position in network byte order. 122 // @arg pos location the value must be in. 123 // @return true if a value is found. 124 bool get(TYPE& value, uint32_t pos) const { 125 if (pos >= mTotalNumTableEntries * mEntryCapacity) { 126 return false; 127 } 128 129 typename List<TYPE *>::iterator it = mTableEntryList.begin(); 130 uint32_t iterations = (pos / (mElementCapacity * mEntryCapacity)); 131 while (it != mTableEntryList.end() && iterations > 0) { 132 ++it; 133 --iterations; 134 } 135 CHECK(it != mTableEntryList.end()); 136 CHECK_EQ(iterations, 0); 137 138 value = (*it)[(pos % (mElementCapacity * mEntryCapacity))]; 139 return true; 140 } 141 142 // Store a single value. 143 // @arg value must be in network byte order. 144 void add(const TYPE& value) { 145 CHECK_LT(mNumValuesInCurrEntry, mElementCapacity); 146 uint32_t nEntries = mTotalNumTableEntries % mElementCapacity; 147 uint32_t nValues = mNumValuesInCurrEntry % mEntryCapacity; 148 if (nEntries == 0 && nValues == 0) { 149 mCurrTableEntriesElement = new TYPE[mEntryCapacity * mElementCapacity]; 150 CHECK(mCurrTableEntriesElement != NULL); 151 mTableEntryList.push_back(mCurrTableEntriesElement); 152 } 153 154 uint32_t pos = nEntries * mEntryCapacity + nValues; 155 mCurrTableEntriesElement[pos] = value; 156 157 ++mNumValuesInCurrEntry; 158 if ((mNumValuesInCurrEntry % mEntryCapacity) == 0) { 159 ++mTotalNumTableEntries; 160 mNumValuesInCurrEntry = 0; 161 } 162 } 163 164 // Write out the table entries: 165 // 1. the number of entries goes first 166 // 2. followed by the values in the table enties in order 167 // @arg writer the writer to actual write to the storage 168 void write(MPEG4Writer *writer) const { 169 CHECK_EQ(mNumValuesInCurrEntry % mEntryCapacity, 0); 170 uint32_t nEntries = mTotalNumTableEntries; 171 writer->writeInt32(nEntries); 172 for (typename List<TYPE *>::iterator it = mTableEntryList.begin(); 173 it != mTableEntryList.end(); ++it) { 174 CHECK_GT(nEntries, 0); 175 if (nEntries >= mElementCapacity) { 176 writer->write(*it, sizeof(TYPE) * mEntryCapacity, mElementCapacity); 177 nEntries -= mElementCapacity; 178 } else { 179 writer->write(*it, sizeof(TYPE) * mEntryCapacity, nEntries); 180 break; 181 } 182 } 183 } 184 185 // Return the number of entries in the table. 186 uint32_t count() const { return mTotalNumTableEntries; } 187 188 private: 189 uint32_t mElementCapacity; // # entries in an element 190 uint32_t mEntryCapacity; // # of values in each entry 191 uint32_t mTotalNumTableEntries; 192 uint32_t mNumValuesInCurrEntry; // up to mEntryCapacity 193 TYPE *mCurrTableEntriesElement; 194 mutable List<TYPE *> mTableEntryList; 195 196 DISALLOW_EVIL_CONSTRUCTORS(ListTableEntries); 197 }; 198 199 200 201 MPEG4Writer *mOwner; 202 sp<MetaData> mMeta; 203 sp<MediaSource> mSource; 204 volatile bool mDone; 205 volatile bool mPaused; 206 volatile bool mResumed; 207 volatile bool mStarted; 208 bool mIsAvc; 209 bool mIsAudio; 210 bool mIsMPEG4; 211 int32_t mTrackId; 212 int64_t mTrackDurationUs; 213 int64_t mMaxChunkDurationUs; 214 215 bool mIsRealTimeRecording; 216 int64_t mEstimatedTrackSizeBytes; 217 int64_t mMdatSizeBytes; 218 int32_t mTimeScale; 219 220 pthread_t mThread; 221 222 223 List<MediaBuffer *> mChunkSamples; 224 225 bool mSamplesHaveSameSize; 226 ListTableEntries<uint32_t> *mStszTableEntries; 227 228 ListTableEntries<uint32_t> *mStcoTableEntries; 229 ListTableEntries<off64_t> *mCo64TableEntries; 230 ListTableEntries<uint32_t> *mStscTableEntries; 231 ListTableEntries<uint32_t> *mStssTableEntries; 232 ListTableEntries<uint32_t> *mSttsTableEntries; 233 ListTableEntries<uint32_t> *mCttsTableEntries; 234 235 int64_t mMinCttsOffsetTimeUs; 236 int64_t mMaxCttsOffsetTimeUs; 237 238 // Sequence parameter set or picture parameter set 239 struct AVCParamSet { 240 AVCParamSet(uint16_t length, const uint8_t *data) 241 : mLength(length), mData(data) {} 242 243 uint16_t mLength; 244 const uint8_t *mData; 245 }; 246 List<AVCParamSet> mSeqParamSets; 247 List<AVCParamSet> mPicParamSets; 248 uint8_t mProfileIdc; 249 uint8_t mProfileCompatible; 250 uint8_t mLevelIdc; 251 252 void *mCodecSpecificData; 253 size_t mCodecSpecificDataSize; 254 bool mGotAllCodecSpecificData; 255 bool mTrackingProgressStatus; 256 257 bool mReachedEOS; 258 int64_t mStartTimestampUs; 259 int64_t mStartTimeRealUs; 260 int64_t mFirstSampleTimeRealUs; 261 int64_t mPreviousTrackTimeUs; 262 int64_t mTrackEveryTimeDurationUs; 263 264 // Update the audio track's drift information. 265 void updateDriftTime(const sp<MetaData>& meta); 266 267 int32_t getStartTimeOffsetScaledTime() const; 268 269 static void *ThreadWrapper(void *me); 270 status_t threadEntry(); 271 272 const uint8_t *parseParamSet( 273 const uint8_t *data, size_t length, int type, size_t *paramSetLen); 274 275 status_t makeAVCCodecSpecificData(const uint8_t *data, size_t size); 276 status_t copyAVCCodecSpecificData(const uint8_t *data, size_t size); 277 status_t parseAVCCodecSpecificData(const uint8_t *data, size_t size); 278 279 // Track authoring progress status 280 void trackProgressStatus(int64_t timeUs, status_t err = OK); 281 void initTrackingProgressStatus(MetaData *params); 282 283 void getCodecSpecificDataFromInputFormatIfPossible(); 284 285 // Determine the track time scale 286 // If it is an audio track, try to use the sampling rate as 287 // the time scale; however, if user chooses the overwrite 288 // value, the user-supplied time scale will be used. 289 void setTimeScale(); 290 291 // Simple validation on the codec specific data 292 status_t checkCodecSpecificData() const; 293 int32_t mRotation; 294 295 void updateTrackSizeEstimate(); 296 void addOneStscTableEntry(size_t chunkId, size_t sampleId); 297 void addOneStssTableEntry(size_t sampleId); 298 299 // Duration is time scale based 300 void addOneSttsTableEntry(size_t sampleCount, int32_t timescaledDur); 301 void addOneCttsTableEntry(size_t sampleCount, int32_t timescaledDur); 302 303 bool isTrackMalFormed() const; 304 void sendTrackSummary(bool hasMultipleTracks); 305 306 // Write the boxes 307 void writeStcoBox(bool use32BitOffset); 308 void writeStscBox(); 309 void writeStszBox(); 310 void writeStssBox(); 311 void writeSttsBox(); 312 void writeCttsBox(); 313 void writeD263Box(); 314 void writePaspBox(); 315 void writeAvccBox(); 316 void writeUrlBox(); 317 void writeDrefBox(); 318 void writeDinfBox(); 319 void writeDamrBox(); 320 void writeMdhdBox(uint32_t now); 321 void writeSmhdBox(); 322 void writeVmhdBox(); 323 void writeHdlrBox(); 324 void writeTkhdBox(uint32_t now); 325 void writeMp4aEsdsBox(); 326 void writeMp4vEsdsBox(); 327 void writeAudioFourCCBox(); 328 void writeVideoFourCCBox(); 329 void writeStblBox(bool use32BitOffset); 330 331 Track(const Track &); 332 Track &operator=(const Track &); 333}; 334 335MPEG4Writer::MPEG4Writer(const char *filename) 336 : mFd(-1), 337 mInitCheck(NO_INIT), 338 mUse4ByteNalLength(true), 339 mUse32BitOffset(true), 340 mIsFileSizeLimitExplicitlyRequested(false), 341 mPaused(false), 342 mStarted(false), 343 mWriterThreadStarted(false), 344 mOffset(0), 345 mMdatOffset(0), 346 mEstimatedMoovBoxSize(0), 347 mInterleaveDurationUs(1000000), 348 mLatitudex10000(0), 349 mLongitudex10000(0), 350 mAreGeoTagsAvailable(false), 351 mStartTimeOffsetMs(-1) { 352 353 mFd = open(filename, O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR); 354 if (mFd >= 0) { 355 mInitCheck = OK; 356 } 357} 358 359MPEG4Writer::MPEG4Writer(int fd) 360 : mFd(dup(fd)), 361 mInitCheck(mFd < 0? NO_INIT: OK), 362 mUse4ByteNalLength(true), 363 mUse32BitOffset(true), 364 mIsFileSizeLimitExplicitlyRequested(false), 365 mPaused(false), 366 mStarted(false), 367 mWriterThreadStarted(false), 368 mOffset(0), 369 mMdatOffset(0), 370 mEstimatedMoovBoxSize(0), 371 mInterleaveDurationUs(1000000), 372 mLatitudex10000(0), 373 mLongitudex10000(0), 374 mAreGeoTagsAvailable(false), 375 mStartTimeOffsetMs(-1) { 376} 377 378MPEG4Writer::~MPEG4Writer() { 379 reset(); 380 381 while (!mTracks.empty()) { 382 List<Track *>::iterator it = mTracks.begin(); 383 delete *it; 384 (*it) = NULL; 385 mTracks.erase(it); 386 } 387 mTracks.clear(); 388} 389 390status_t MPEG4Writer::dump( 391 int fd, const Vector<String16>& args) { 392 const size_t SIZE = 256; 393 char buffer[SIZE]; 394 String8 result; 395 snprintf(buffer, SIZE, " MPEG4Writer %p\n", this); 396 result.append(buffer); 397 snprintf(buffer, SIZE, " mStarted: %s\n", mStarted? "true": "false"); 398 result.append(buffer); 399 ::write(fd, result.string(), result.size()); 400 for (List<Track *>::iterator it = mTracks.begin(); 401 it != mTracks.end(); ++it) { 402 (*it)->dump(fd, args); 403 } 404 return OK; 405} 406 407status_t MPEG4Writer::Track::dump( 408 int fd, const Vector<String16>& args) const { 409 const size_t SIZE = 256; 410 char buffer[SIZE]; 411 String8 result; 412 snprintf(buffer, SIZE, " %s track\n", mIsAudio? "Audio": "Video"); 413 result.append(buffer); 414 snprintf(buffer, SIZE, " reached EOS: %s\n", 415 mReachedEOS? "true": "false"); 416 result.append(buffer); 417 snprintf(buffer, SIZE, " frames encoded : %d\n", mStszTableEntries->count()); 418 result.append(buffer); 419 snprintf(buffer, SIZE, " duration encoded : %lld us\n", mTrackDurationUs); 420 result.append(buffer); 421 ::write(fd, result.string(), result.size()); 422 return OK; 423} 424 425status_t MPEG4Writer::addSource(const sp<MediaSource> &source) { 426 Mutex::Autolock l(mLock); 427 if (mStarted) { 428 ALOGE("Attempt to add source AFTER recording is started"); 429 return UNKNOWN_ERROR; 430 } 431 Track *track = new Track(this, source, 1 + mTracks.size()); 432 mTracks.push_back(track); 433 434 return OK; 435} 436 437status_t MPEG4Writer::startTracks(MetaData *params) { 438 for (List<Track *>::iterator it = mTracks.begin(); 439 it != mTracks.end(); ++it) { 440 status_t err = (*it)->start(params); 441 442 if (err != OK) { 443 for (List<Track *>::iterator it2 = mTracks.begin(); 444 it2 != it; ++it2) { 445 (*it2)->stop(); 446 } 447 448 return err; 449 } 450 } 451 return OK; 452} 453 454int64_t MPEG4Writer::estimateMoovBoxSize(int32_t bitRate) { 455 // This implementation is highly experimental/heurisitic. 456 // 457 // Statistical analysis shows that metadata usually accounts 458 // for a small portion of the total file size, usually < 0.6%. 459 460 // The default MIN_MOOV_BOX_SIZE is set to 0.6% x 1MB / 2, 461 // where 1MB is the common file size limit for MMS application. 462 // The default MAX _MOOV_BOX_SIZE value is based on about 3 463 // minute video recording with a bit rate about 3 Mbps, because 464 // statistics also show that most of the video captured are going 465 // to be less than 3 minutes. 466 467 // If the estimation is wrong, we will pay the price of wasting 468 // some reserved space. This should not happen so often statistically. 469 static const int32_t factor = mUse32BitOffset? 1: 2; 470 static const int64_t MIN_MOOV_BOX_SIZE = 3 * 1024; // 3 KB 471 static const int64_t MAX_MOOV_BOX_SIZE = (180 * 3000000 * 6LL / 8000); 472 int64_t size = MIN_MOOV_BOX_SIZE; 473 474 // Max file size limit is set 475 if (mMaxFileSizeLimitBytes != 0 && mIsFileSizeLimitExplicitlyRequested) { 476 size = mMaxFileSizeLimitBytes * 6 / 1000; 477 } 478 479 // Max file duration limit is set 480 if (mMaxFileDurationLimitUs != 0) { 481 if (bitRate > 0) { 482 int64_t size2 = 483 ((mMaxFileDurationLimitUs * bitRate * 6) / 1000 / 8000000); 484 if (mMaxFileSizeLimitBytes != 0 && mIsFileSizeLimitExplicitlyRequested) { 485 // When both file size and duration limits are set, 486 // we use the smaller limit of the two. 487 if (size > size2) { 488 size = size2; 489 } 490 } else { 491 // Only max file duration limit is set 492 size = size2; 493 } 494 } 495 } 496 497 if (size < MIN_MOOV_BOX_SIZE) { 498 size = MIN_MOOV_BOX_SIZE; 499 } 500 501 // Any long duration recording will be probably end up with 502 // non-streamable mp4 file. 503 if (size > MAX_MOOV_BOX_SIZE) { 504 size = MAX_MOOV_BOX_SIZE; 505 } 506 507 ALOGI("limits: %lld/%lld bytes/us, bit rate: %d bps and the estimated" 508 " moov size %lld bytes", 509 mMaxFileSizeLimitBytes, mMaxFileDurationLimitUs, bitRate, size); 510 return factor * size; 511} 512 513status_t MPEG4Writer::start(MetaData *param) { 514 if (mInitCheck != OK) { 515 return UNKNOWN_ERROR; 516 } 517 518 /* 519 * Check mMaxFileSizeLimitBytes at the beginning 520 * since mMaxFileSizeLimitBytes may be implicitly 521 * changed later for 32-bit file offset even if 522 * user does not ask to set it explicitly. 523 */ 524 if (mMaxFileSizeLimitBytes != 0) { 525 mIsFileSizeLimitExplicitlyRequested = true; 526 } 527 528 int32_t use64BitOffset; 529 if (param && 530 param->findInt32(kKey64BitFileOffset, &use64BitOffset) && 531 use64BitOffset) { 532 mUse32BitOffset = false; 533 } 534 535 if (mUse32BitOffset) { 536 // Implicit 32 bit file size limit 537 if (mMaxFileSizeLimitBytes == 0) { 538 mMaxFileSizeLimitBytes = kMax32BitFileSize; 539 } 540 541 // If file size is set to be larger than the 32 bit file 542 // size limit, treat it as an error. 543 if (mMaxFileSizeLimitBytes > kMax32BitFileSize) { 544 ALOGW("32-bit file size limit (%lld bytes) too big. " 545 "It is changed to %lld bytes", 546 mMaxFileSizeLimitBytes, kMax32BitFileSize); 547 mMaxFileSizeLimitBytes = kMax32BitFileSize; 548 } 549 } 550 551 int32_t use2ByteNalLength; 552 if (param && 553 param->findInt32(kKey2ByteNalLength, &use2ByteNalLength) && 554 use2ByteNalLength) { 555 mUse4ByteNalLength = false; 556 } 557 558 mStartTimestampUs = -1; 559 560 if (mStarted) { 561 if (mPaused) { 562 mPaused = false; 563 return startTracks(param); 564 } 565 return OK; 566 } 567 568 if (!param || 569 !param->findInt32(kKeyTimeScale, &mTimeScale)) { 570 mTimeScale = 1000; 571 } 572 CHECK_GT(mTimeScale, 0); 573 ALOGV("movie time scale: %d", mTimeScale); 574 575 /* 576 * When the requested file size limit is small, the priority 577 * is to meet the file size limit requirement, rather than 578 * to make the file streamable. 579 */ 580 mStreamableFile = 581 (mMaxFileSizeLimitBytes != 0 && 582 mMaxFileSizeLimitBytes >= kMinStreamableFileSizeInBytes); 583 584 mWriteMoovBoxToMemory = mStreamableFile; 585 mMoovBoxBuffer = NULL; 586 mMoovBoxBufferOffset = 0; 587 588 writeFtypBox(param); 589 590 mFreeBoxOffset = mOffset; 591 592 if (mEstimatedMoovBoxSize == 0) { 593 int32_t bitRate = -1; 594 if (param) { 595 param->findInt32(kKeyBitRate, &bitRate); 596 } 597 mEstimatedMoovBoxSize = estimateMoovBoxSize(bitRate); 598 } 599 CHECK_GE(mEstimatedMoovBoxSize, 8); 600 if (mStreamableFile) { 601 // Reserve a 'free' box only for streamable file 602 lseek64(mFd, mFreeBoxOffset, SEEK_SET); 603 writeInt32(mEstimatedMoovBoxSize); 604 write("free", 4); 605 mMdatOffset = mFreeBoxOffset + mEstimatedMoovBoxSize; 606 } else { 607 mMdatOffset = mOffset; 608 } 609 610 mOffset = mMdatOffset; 611 lseek64(mFd, mMdatOffset, SEEK_SET); 612 if (mUse32BitOffset) { 613 write("????mdat", 8); 614 } else { 615 write("\x00\x00\x00\x01mdat????????", 16); 616 } 617 618 status_t err = startWriterThread(); 619 if (err != OK) { 620 return err; 621 } 622 623 err = startTracks(param); 624 if (err != OK) { 625 return err; 626 } 627 628 mStarted = true; 629 return OK; 630} 631 632bool MPEG4Writer::use32BitFileOffset() const { 633 return mUse32BitOffset; 634} 635 636status_t MPEG4Writer::pause() { 637 if (mInitCheck != OK) { 638 return OK; 639 } 640 mPaused = true; 641 status_t err = OK; 642 for (List<Track *>::iterator it = mTracks.begin(); 643 it != mTracks.end(); ++it) { 644 status_t status = (*it)->pause(); 645 if (status != OK) { 646 err = status; 647 } 648 } 649 return err; 650} 651 652void MPEG4Writer::stopWriterThread() { 653 ALOGD("Stopping writer thread"); 654 if (!mWriterThreadStarted) { 655 return; 656 } 657 658 { 659 Mutex::Autolock autolock(mLock); 660 661 mDone = true; 662 mChunkReadyCondition.signal(); 663 } 664 665 void *dummy; 666 pthread_join(mThread, &dummy); 667 mWriterThreadStarted = false; 668 ALOGD("Writer thread stopped"); 669} 670 671/* 672 * MP4 file standard defines a composition matrix: 673 * | a b u | 674 * | c d v | 675 * | x y w | 676 * 677 * the element in the matrix is stored in the following 678 * order: {a, b, u, c, d, v, x, y, w}, 679 * where a, b, c, d, x, and y is in 16.16 format, while 680 * u, v and w is in 2.30 format. 681 */ 682void MPEG4Writer::writeCompositionMatrix(int degrees) { 683 ALOGV("writeCompositionMatrix"); 684 uint32_t a = 0x00010000; 685 uint32_t b = 0; 686 uint32_t c = 0; 687 uint32_t d = 0x00010000; 688 switch (degrees) { 689 case 0: 690 break; 691 case 90: 692 a = 0; 693 b = 0x00010000; 694 c = 0xFFFF0000; 695 d = 0; 696 break; 697 case 180: 698 a = 0xFFFF0000; 699 d = 0xFFFF0000; 700 break; 701 case 270: 702 a = 0; 703 b = 0xFFFF0000; 704 c = 0x00010000; 705 d = 0; 706 break; 707 default: 708 CHECK(!"Should never reach this unknown rotation"); 709 break; 710 } 711 712 writeInt32(a); // a 713 writeInt32(b); // b 714 writeInt32(0); // u 715 writeInt32(c); // c 716 writeInt32(d); // d 717 writeInt32(0); // v 718 writeInt32(0); // x 719 writeInt32(0); // y 720 writeInt32(0x40000000); // w 721} 722 723void MPEG4Writer::release() { 724 close(mFd); 725 mFd = -1; 726 mInitCheck = NO_INIT; 727 mStarted = false; 728} 729 730status_t MPEG4Writer::reset() { 731 if (mInitCheck != OK) { 732 return OK; 733 } else { 734 if (!mWriterThreadStarted || 735 !mStarted) { 736 if (mWriterThreadStarted) { 737 stopWriterThread(); 738 } 739 release(); 740 return OK; 741 } 742 } 743 744 status_t err = OK; 745 int64_t maxDurationUs = 0; 746 int64_t minDurationUs = 0x7fffffffffffffffLL; 747 for (List<Track *>::iterator it = mTracks.begin(); 748 it != mTracks.end(); ++it) { 749 status_t status = (*it)->stop(); 750 if (err == OK && status != OK) { 751 err = status; 752 } 753 754 int64_t durationUs = (*it)->getDurationUs(); 755 if (durationUs > maxDurationUs) { 756 maxDurationUs = durationUs; 757 } 758 if (durationUs < minDurationUs) { 759 minDurationUs = durationUs; 760 } 761 } 762 763 if (mTracks.size() > 1) { 764 ALOGD("Duration from tracks range is [%lld, %lld] us", 765 minDurationUs, maxDurationUs); 766 } 767 768 stopWriterThread(); 769 770 // Do not write out movie header on error. 771 if (err != OK) { 772 release(); 773 return err; 774 } 775 776 // Fix up the size of the 'mdat' chunk. 777 if (mUse32BitOffset) { 778 lseek64(mFd, mMdatOffset, SEEK_SET); 779 int32_t size = htonl(static_cast<int32_t>(mOffset - mMdatOffset)); 780 ::write(mFd, &size, 4); 781 } else { 782 lseek64(mFd, mMdatOffset + 8, SEEK_SET); 783 int64_t size = mOffset - mMdatOffset; 784 size = hton64(size); 785 ::write(mFd, &size, 8); 786 } 787 lseek64(mFd, mOffset, SEEK_SET); 788 789 const off64_t moovOffset = mOffset; 790 mWriteMoovBoxToMemory = mStreamableFile; 791 mMoovBoxBuffer = (uint8_t *) malloc(mEstimatedMoovBoxSize); 792 mMoovBoxBufferOffset = 0; 793 CHECK(mMoovBoxBuffer != NULL); 794 writeMoovBox(maxDurationUs); 795 796 mWriteMoovBoxToMemory = false; 797 if (mStreamableFile) { 798 CHECK_LE(mMoovBoxBufferOffset + 8, mEstimatedMoovBoxSize); 799 800 // Moov box 801 lseek64(mFd, mFreeBoxOffset, SEEK_SET); 802 mOffset = mFreeBoxOffset; 803 write(mMoovBoxBuffer, 1, mMoovBoxBufferOffset); 804 805 // Free box 806 lseek64(mFd, mOffset, SEEK_SET); 807 writeInt32(mEstimatedMoovBoxSize - mMoovBoxBufferOffset); 808 write("free", 4); 809 810 // Free temp memory 811 free(mMoovBoxBuffer); 812 mMoovBoxBuffer = NULL; 813 mMoovBoxBufferOffset = 0; 814 } else { 815 ALOGI("The mp4 file will not be streamable."); 816 } 817 818 CHECK(mBoxes.empty()); 819 820 release(); 821 return err; 822} 823 824uint32_t MPEG4Writer::getMpeg4Time() { 825 time_t now = time(NULL); 826 // MP4 file uses time counting seconds since midnight, Jan. 1, 1904 827 // while time function returns Unix epoch values which starts 828 // at 1970-01-01. Lets add the number of seconds between them 829 uint32_t mpeg4Time = now + (66 * 365 + 17) * (24 * 60 * 60); 830 return mpeg4Time; 831} 832 833void MPEG4Writer::writeMvhdBox(int64_t durationUs) { 834 uint32_t now = getMpeg4Time(); 835 beginBox("mvhd"); 836 writeInt32(0); // version=0, flags=0 837 writeInt32(now); // creation time 838 writeInt32(now); // modification time 839 writeInt32(mTimeScale); // mvhd timescale 840 int32_t duration = (durationUs * mTimeScale + 5E5) / 1E6; 841 writeInt32(duration); 842 writeInt32(0x10000); // rate: 1.0 843 writeInt16(0x100); // volume 844 writeInt16(0); // reserved 845 writeInt32(0); // reserved 846 writeInt32(0); // reserved 847 writeCompositionMatrix(0); // matrix 848 writeInt32(0); // predefined 849 writeInt32(0); // predefined 850 writeInt32(0); // predefined 851 writeInt32(0); // predefined 852 writeInt32(0); // predefined 853 writeInt32(0); // predefined 854 writeInt32(mTracks.size() + 1); // nextTrackID 855 endBox(); // mvhd 856} 857 858void MPEG4Writer::writeMoovBox(int64_t durationUs) { 859 beginBox("moov"); 860 writeMvhdBox(durationUs); 861 if (mAreGeoTagsAvailable) { 862 writeUdtaBox(); 863 } 864 int32_t id = 1; 865 for (List<Track *>::iterator it = mTracks.begin(); 866 it != mTracks.end(); ++it, ++id) { 867 (*it)->writeTrackHeader(mUse32BitOffset); 868 } 869 endBox(); // moov 870} 871 872void MPEG4Writer::writeFtypBox(MetaData *param) { 873 beginBox("ftyp"); 874 875 int32_t fileType; 876 if (param && param->findInt32(kKeyFileType, &fileType) && 877 fileType != OUTPUT_FORMAT_MPEG_4) { 878 writeFourcc("3gp4"); 879 } else { 880 writeFourcc("isom"); 881 } 882 883 writeInt32(0); 884 writeFourcc("isom"); 885 writeFourcc("3gp4"); 886 endBox(); 887} 888 889static bool isTestModeEnabled() { 890#if (PROPERTY_VALUE_MAX < 5) 891#error "PROPERTY_VALUE_MAX must be at least 5" 892#endif 893 894 // Test mode is enabled only if rw.media.record.test system 895 // property is enabled. 896 char value[PROPERTY_VALUE_MAX]; 897 if (property_get("rw.media.record.test", value, NULL) && 898 (!strcasecmp(value, "true") || !strcasecmp(value, "1"))) { 899 return true; 900 } 901 return false; 902} 903 904void MPEG4Writer::sendSessionSummary() { 905 // Send session summary only if test mode is enabled 906 if (!isTestModeEnabled()) { 907 return; 908 } 909 910 for (List<ChunkInfo>::iterator it = mChunkInfos.begin(); 911 it != mChunkInfos.end(); ++it) { 912 int trackNum = it->mTrack->getTrackId() << 28; 913 notify(MEDIA_RECORDER_TRACK_EVENT_INFO, 914 trackNum | MEDIA_RECORDER_TRACK_INTER_CHUNK_TIME_MS, 915 it->mMaxInterChunkDurUs); 916 } 917} 918 919status_t MPEG4Writer::setInterleaveDuration(uint32_t durationUs) { 920 mInterleaveDurationUs = durationUs; 921 return OK; 922} 923 924void MPEG4Writer::lock() { 925 mLock.lock(); 926} 927 928void MPEG4Writer::unlock() { 929 mLock.unlock(); 930} 931 932off64_t MPEG4Writer::addSample_l(MediaBuffer *buffer) { 933 off64_t old_offset = mOffset; 934 935 ::write(mFd, 936 (const uint8_t *)buffer->data() + buffer->range_offset(), 937 buffer->range_length()); 938 939 mOffset += buffer->range_length(); 940 941 return old_offset; 942} 943 944static void StripStartcode(MediaBuffer *buffer) { 945 if (buffer->range_length() < 4) { 946 return; 947 } 948 949 const uint8_t *ptr = 950 (const uint8_t *)buffer->data() + buffer->range_offset(); 951 952 if (!memcmp(ptr, "\x00\x00\x00\x01", 4)) { 953 buffer->set_range( 954 buffer->range_offset() + 4, buffer->range_length() - 4); 955 } 956} 957 958off64_t MPEG4Writer::addLengthPrefixedSample_l(MediaBuffer *buffer) { 959 off64_t old_offset = mOffset; 960 961 size_t length = buffer->range_length(); 962 963 if (mUse4ByteNalLength) { 964 uint8_t x = length >> 24; 965 ::write(mFd, &x, 1); 966 x = (length >> 16) & 0xff; 967 ::write(mFd, &x, 1); 968 x = (length >> 8) & 0xff; 969 ::write(mFd, &x, 1); 970 x = length & 0xff; 971 ::write(mFd, &x, 1); 972 973 ::write(mFd, 974 (const uint8_t *)buffer->data() + buffer->range_offset(), 975 length); 976 977 mOffset += length + 4; 978 } else { 979 CHECK_LT(length, 65536); 980 981 uint8_t x = length >> 8; 982 ::write(mFd, &x, 1); 983 x = length & 0xff; 984 ::write(mFd, &x, 1); 985 ::write(mFd, (const uint8_t *)buffer->data() + buffer->range_offset(), length); 986 mOffset += length + 2; 987 } 988 989 return old_offset; 990} 991 992size_t MPEG4Writer::write( 993 const void *ptr, size_t size, size_t nmemb) { 994 995 const size_t bytes = size * nmemb; 996 if (mWriteMoovBoxToMemory) { 997 // This happens only when we write the moov box at the end of 998 // recording, not for each output video/audio frame we receive. 999 off64_t moovBoxSize = 8 + mMoovBoxBufferOffset + bytes; 1000 if (moovBoxSize > mEstimatedMoovBoxSize) { 1001 for (List<off64_t>::iterator it = mBoxes.begin(); 1002 it != mBoxes.end(); ++it) { 1003 (*it) += mOffset; 1004 } 1005 lseek64(mFd, mOffset, SEEK_SET); 1006 ::write(mFd, mMoovBoxBuffer, mMoovBoxBufferOffset); 1007 ::write(mFd, ptr, size * nmemb); 1008 mOffset += (bytes + mMoovBoxBufferOffset); 1009 free(mMoovBoxBuffer); 1010 mMoovBoxBuffer = NULL; 1011 mMoovBoxBufferOffset = 0; 1012 mWriteMoovBoxToMemory = false; 1013 mStreamableFile = false; 1014 } else { 1015 memcpy(mMoovBoxBuffer + mMoovBoxBufferOffset, ptr, bytes); 1016 mMoovBoxBufferOffset += bytes; 1017 } 1018 } else { 1019 ::write(mFd, ptr, size * nmemb); 1020 mOffset += bytes; 1021 } 1022 return bytes; 1023} 1024 1025void MPEG4Writer::beginBox(const char *fourcc) { 1026 CHECK_EQ(strlen(fourcc), 4); 1027 1028 mBoxes.push_back(mWriteMoovBoxToMemory? 1029 mMoovBoxBufferOffset: mOffset); 1030 1031 writeInt32(0); 1032 writeFourcc(fourcc); 1033} 1034 1035void MPEG4Writer::endBox() { 1036 CHECK(!mBoxes.empty()); 1037 1038 off64_t offset = *--mBoxes.end(); 1039 mBoxes.erase(--mBoxes.end()); 1040 1041 if (mWriteMoovBoxToMemory) { 1042 int32_t x = htonl(mMoovBoxBufferOffset - offset); 1043 memcpy(mMoovBoxBuffer + offset, &x, 4); 1044 } else { 1045 lseek64(mFd, offset, SEEK_SET); 1046 writeInt32(mOffset - offset); 1047 mOffset -= 4; 1048 lseek64(mFd, mOffset, SEEK_SET); 1049 } 1050} 1051 1052void MPEG4Writer::writeInt8(int8_t x) { 1053 write(&x, 1, 1); 1054} 1055 1056void MPEG4Writer::writeInt16(int16_t x) { 1057 x = htons(x); 1058 write(&x, 1, 2); 1059} 1060 1061void MPEG4Writer::writeInt32(int32_t x) { 1062 x = htonl(x); 1063 write(&x, 1, 4); 1064} 1065 1066void MPEG4Writer::writeInt64(int64_t x) { 1067 x = hton64(x); 1068 write(&x, 1, 8); 1069} 1070 1071void MPEG4Writer::writeCString(const char *s) { 1072 size_t n = strlen(s); 1073 write(s, 1, n + 1); 1074} 1075 1076void MPEG4Writer::writeFourcc(const char *s) { 1077 CHECK_EQ(strlen(s), 4); 1078 write(s, 1, 4); 1079} 1080 1081 1082// Written in +/-DD.DDDD format 1083void MPEG4Writer::writeLatitude(int degreex10000) { 1084 bool isNegative = (degreex10000 < 0); 1085 char sign = isNegative? '-': '+'; 1086 1087 // Handle the whole part 1088 char str[9]; 1089 int wholePart = degreex10000 / 10000; 1090 if (wholePart == 0) { 1091 snprintf(str, 5, "%c%.2d.", sign, wholePart); 1092 } else { 1093 snprintf(str, 5, "%+.2d.", wholePart); 1094 } 1095 1096 // Handle the fractional part 1097 int fractionalPart = degreex10000 - (wholePart * 10000); 1098 if (fractionalPart < 0) { 1099 fractionalPart = -fractionalPart; 1100 } 1101 snprintf(&str[4], 5, "%.4d", fractionalPart); 1102 1103 // Do not write the null terminator 1104 write(str, 1, 8); 1105} 1106 1107// Written in +/- DDD.DDDD format 1108void MPEG4Writer::writeLongitude(int degreex10000) { 1109 bool isNegative = (degreex10000 < 0); 1110 char sign = isNegative? '-': '+'; 1111 1112 // Handle the whole part 1113 char str[10]; 1114 int wholePart = degreex10000 / 10000; 1115 if (wholePart == 0) { 1116 snprintf(str, 6, "%c%.3d.", sign, wholePart); 1117 } else { 1118 snprintf(str, 6, "%+.3d.", wholePart); 1119 } 1120 1121 // Handle the fractional part 1122 int fractionalPart = degreex10000 - (wholePart * 10000); 1123 if (fractionalPart < 0) { 1124 fractionalPart = -fractionalPart; 1125 } 1126 snprintf(&str[5], 5, "%.4d", fractionalPart); 1127 1128 // Do not write the null terminator 1129 write(str, 1, 9); 1130} 1131 1132/* 1133 * Geodata is stored according to ISO-6709 standard. 1134 * latitudex10000 is latitude in degrees times 10000, and 1135 * longitudex10000 is longitude in degrees times 10000. 1136 * The range for the latitude is in [-90, +90], and 1137 * The range for the longitude is in [-180, +180] 1138 */ 1139status_t MPEG4Writer::setGeoData(int latitudex10000, int longitudex10000) { 1140 // Is latitude or longitude out of range? 1141 if (latitudex10000 < -900000 || latitudex10000 > 900000 || 1142 longitudex10000 < -1800000 || longitudex10000 > 1800000) { 1143 return BAD_VALUE; 1144 } 1145 1146 mLatitudex10000 = latitudex10000; 1147 mLongitudex10000 = longitudex10000; 1148 mAreGeoTagsAvailable = true; 1149 return OK; 1150} 1151 1152void MPEG4Writer::write(const void *data, size_t size) { 1153 write(data, 1, size); 1154} 1155 1156bool MPEG4Writer::isFileStreamable() const { 1157 return mStreamableFile; 1158} 1159 1160bool MPEG4Writer::exceedsFileSizeLimit() { 1161 // No limit 1162 if (mMaxFileSizeLimitBytes == 0) { 1163 return false; 1164 } 1165 1166 int64_t nTotalBytesEstimate = static_cast<int64_t>(mEstimatedMoovBoxSize); 1167 for (List<Track *>::iterator it = mTracks.begin(); 1168 it != mTracks.end(); ++it) { 1169 nTotalBytesEstimate += (*it)->getEstimatedTrackSizeBytes(); 1170 } 1171 1172 if (!mStreamableFile) { 1173 // Add 1024 bytes as error tolerance 1174 return nTotalBytesEstimate + 1024 >= mMaxFileSizeLimitBytes; 1175 } 1176 // Be conservative in the estimate: do not exceed 95% of 1177 // the target file limit. For small target file size limit, though, 1178 // this will not help. 1179 return (nTotalBytesEstimate >= (95 * mMaxFileSizeLimitBytes) / 100); 1180} 1181 1182bool MPEG4Writer::exceedsFileDurationLimit() { 1183 // No limit 1184 if (mMaxFileDurationLimitUs == 0) { 1185 return false; 1186 } 1187 1188 for (List<Track *>::iterator it = mTracks.begin(); 1189 it != mTracks.end(); ++it) { 1190 if ((*it)->getDurationUs() >= mMaxFileDurationLimitUs) { 1191 return true; 1192 } 1193 } 1194 return false; 1195} 1196 1197bool MPEG4Writer::reachedEOS() { 1198 bool allDone = true; 1199 for (List<Track *>::iterator it = mTracks.begin(); 1200 it != mTracks.end(); ++it) { 1201 if (!(*it)->reachedEOS()) { 1202 allDone = false; 1203 break; 1204 } 1205 } 1206 1207 return allDone; 1208} 1209 1210void MPEG4Writer::setStartTimestampUs(int64_t timeUs) { 1211 ALOGI("setStartTimestampUs: %lld", timeUs); 1212 CHECK_GE(timeUs, 0ll); 1213 Mutex::Autolock autoLock(mLock); 1214 if (mStartTimestampUs < 0 || mStartTimestampUs > timeUs) { 1215 mStartTimestampUs = timeUs; 1216 ALOGI("Earliest track starting time: %lld", mStartTimestampUs); 1217 } 1218} 1219 1220int64_t MPEG4Writer::getStartTimestampUs() { 1221 Mutex::Autolock autoLock(mLock); 1222 return mStartTimestampUs; 1223} 1224 1225size_t MPEG4Writer::numTracks() { 1226 Mutex::Autolock autolock(mLock); 1227 return mTracks.size(); 1228} 1229 1230//////////////////////////////////////////////////////////////////////////////// 1231 1232MPEG4Writer::Track::Track( 1233 MPEG4Writer *owner, const sp<MediaSource> &source, size_t trackId) 1234 : mOwner(owner), 1235 mMeta(source->getFormat()), 1236 mSource(source), 1237 mDone(false), 1238 mPaused(false), 1239 mResumed(false), 1240 mStarted(false), 1241 mTrackId(trackId), 1242 mTrackDurationUs(0), 1243 mEstimatedTrackSizeBytes(0), 1244 mSamplesHaveSameSize(true), 1245 mStszTableEntries(new ListTableEntries<uint32_t>(1000, 1)), 1246 mStcoTableEntries(new ListTableEntries<uint32_t>(1000, 1)), 1247 mCo64TableEntries(new ListTableEntries<off64_t>(1000, 1)), 1248 mStscTableEntries(new ListTableEntries<uint32_t>(1000, 3)), 1249 mStssTableEntries(new ListTableEntries<uint32_t>(1000, 1)), 1250 mSttsTableEntries(new ListTableEntries<uint32_t>(1000, 2)), 1251 mCttsTableEntries(new ListTableEntries<uint32_t>(1000, 2)), 1252 mCodecSpecificData(NULL), 1253 mCodecSpecificDataSize(0), 1254 mGotAllCodecSpecificData(false), 1255 mReachedEOS(false), 1256 mRotation(0) { 1257 getCodecSpecificDataFromInputFormatIfPossible(); 1258 1259 const char *mime; 1260 mMeta->findCString(kKeyMIMEType, &mime); 1261 mIsAvc = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 1262 mIsAudio = !strncasecmp(mime, "audio/", 6); 1263 mIsMPEG4 = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) || 1264 !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC); 1265 1266 setTimeScale(); 1267} 1268 1269void MPEG4Writer::Track::updateTrackSizeEstimate() { 1270 1271 uint32_t stcoBoxCount = (mOwner->use32BitFileOffset() 1272 ? mStcoTableEntries->count() 1273 : mCo64TableEntries->count()); 1274 int64_t stcoBoxSizeBytes = stcoBoxCount * 4; 1275 int64_t stszBoxSizeBytes = mSamplesHaveSameSize? 4: (mStszTableEntries->count() * 4); 1276 1277 mEstimatedTrackSizeBytes = mMdatSizeBytes; // media data size 1278 if (!mOwner->isFileStreamable()) { 1279 // Reserved free space is not large enough to hold 1280 // all meta data and thus wasted. 1281 mEstimatedTrackSizeBytes += mStscTableEntries->count() * 12 + // stsc box size 1282 mStssTableEntries->count() * 4 + // stss box size 1283 mSttsTableEntries->count() * 8 + // stts box size 1284 mCttsTableEntries->count() * 8 + // ctts box size 1285 stcoBoxSizeBytes + // stco box size 1286 stszBoxSizeBytes; // stsz box size 1287 } 1288} 1289 1290void MPEG4Writer::Track::addOneStscTableEntry( 1291 size_t chunkId, size_t sampleId) { 1292 1293 mStscTableEntries->add(htonl(chunkId)); 1294 mStscTableEntries->add(htonl(sampleId)); 1295 mStscTableEntries->add(htonl(1)); 1296} 1297 1298void MPEG4Writer::Track::addOneStssTableEntry(size_t sampleId) { 1299 mStssTableEntries->add(htonl(sampleId)); 1300} 1301 1302void MPEG4Writer::Track::addOneSttsTableEntry( 1303 size_t sampleCount, int32_t duration) { 1304 1305 if (duration == 0) { 1306 ALOGW("0-duration samples found: %d", sampleCount); 1307 } 1308 mSttsTableEntries->add(htonl(sampleCount)); 1309 mSttsTableEntries->add(htonl(duration)); 1310} 1311 1312void MPEG4Writer::Track::addOneCttsTableEntry( 1313 size_t sampleCount, int32_t duration) { 1314 1315 if (mIsAudio) { 1316 return; 1317 } 1318 mCttsTableEntries->add(htonl(sampleCount)); 1319 mCttsTableEntries->add(htonl(duration)); 1320} 1321 1322void MPEG4Writer::Track::addChunkOffset(off64_t offset) { 1323 if (mOwner->use32BitFileOffset()) { 1324 uint32_t value = offset; 1325 mStcoTableEntries->add(htonl(value)); 1326 } else { 1327 mCo64TableEntries->add(hton64(offset)); 1328 } 1329} 1330 1331void MPEG4Writer::Track::setTimeScale() { 1332 ALOGV("setTimeScale"); 1333 // Default time scale 1334 mTimeScale = 90000; 1335 1336 if (mIsAudio) { 1337 // Use the sampling rate as the default time scale for audio track. 1338 int32_t sampleRate; 1339 bool success = mMeta->findInt32(kKeySampleRate, &sampleRate); 1340 CHECK(success); 1341 mTimeScale = sampleRate; 1342 } 1343 1344 // If someone would like to overwrite the timescale, use user-supplied value. 1345 int32_t timeScale; 1346 if (mMeta->findInt32(kKeyTimeScale, &timeScale)) { 1347 mTimeScale = timeScale; 1348 } 1349 1350 CHECK_GT(mTimeScale, 0); 1351} 1352 1353void MPEG4Writer::Track::getCodecSpecificDataFromInputFormatIfPossible() { 1354 const char *mime; 1355 CHECK(mMeta->findCString(kKeyMIMEType, &mime)); 1356 1357 if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 1358 uint32_t type; 1359 const void *data; 1360 size_t size; 1361 if (mMeta->findData(kKeyAVCC, &type, &data, &size)) { 1362 mCodecSpecificData = malloc(size); 1363 mCodecSpecificDataSize = size; 1364 memcpy(mCodecSpecificData, data, size); 1365 mGotAllCodecSpecificData = true; 1366 } 1367 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) 1368 || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 1369 uint32_t type; 1370 const void *data; 1371 size_t size; 1372 if (mMeta->findData(kKeyESDS, &type, &data, &size)) { 1373 ESDS esds(data, size); 1374 if (esds.getCodecSpecificInfo(&data, &size) == OK) { 1375 mCodecSpecificData = malloc(size); 1376 mCodecSpecificDataSize = size; 1377 memcpy(mCodecSpecificData, data, size); 1378 mGotAllCodecSpecificData = true; 1379 } 1380 } 1381 } 1382} 1383 1384MPEG4Writer::Track::~Track() { 1385 stop(); 1386 1387 delete mStszTableEntries; 1388 delete mStcoTableEntries; 1389 delete mCo64TableEntries; 1390 delete mStscTableEntries; 1391 delete mSttsTableEntries; 1392 delete mStssTableEntries; 1393 delete mCttsTableEntries; 1394 1395 mStszTableEntries = NULL; 1396 mStcoTableEntries = NULL; 1397 mCo64TableEntries = NULL; 1398 mStscTableEntries = NULL; 1399 mSttsTableEntries = NULL; 1400 mStssTableEntries = NULL; 1401 mCttsTableEntries = NULL; 1402 1403 if (mCodecSpecificData != NULL) { 1404 free(mCodecSpecificData); 1405 mCodecSpecificData = NULL; 1406 } 1407} 1408 1409void MPEG4Writer::Track::initTrackingProgressStatus(MetaData *params) { 1410 ALOGV("initTrackingProgressStatus"); 1411 mPreviousTrackTimeUs = -1; 1412 mTrackingProgressStatus = false; 1413 mTrackEveryTimeDurationUs = 0; 1414 { 1415 int64_t timeUs; 1416 if (params && params->findInt64(kKeyTrackTimeStatus, &timeUs)) { 1417 ALOGV("Receive request to track progress status for every %lld us", timeUs); 1418 mTrackEveryTimeDurationUs = timeUs; 1419 mTrackingProgressStatus = true; 1420 } 1421 } 1422} 1423 1424// static 1425void *MPEG4Writer::ThreadWrapper(void *me) { 1426 ALOGV("ThreadWrapper: %p", me); 1427 MPEG4Writer *writer = static_cast<MPEG4Writer *>(me); 1428 writer->threadFunc(); 1429 return NULL; 1430} 1431 1432void MPEG4Writer::bufferChunk(const Chunk& chunk) { 1433 ALOGV("bufferChunk: %p", chunk.mTrack); 1434 Mutex::Autolock autolock(mLock); 1435 CHECK_EQ(mDone, false); 1436 1437 for (List<ChunkInfo>::iterator it = mChunkInfos.begin(); 1438 it != mChunkInfos.end(); ++it) { 1439 1440 if (chunk.mTrack == it->mTrack) { // Found owner 1441 it->mChunks.push_back(chunk); 1442 mChunkReadyCondition.signal(); 1443 return; 1444 } 1445 } 1446 1447 CHECK(!"Received a chunk for a unknown track"); 1448} 1449 1450void MPEG4Writer::writeChunkToFile(Chunk* chunk) { 1451 ALOGV("writeChunkToFile: %lld from %s track", 1452 chunk->mTimeStampUs, chunk->mTrack->isAudio()? "audio": "video"); 1453 1454 int32_t isFirstSample = true; 1455 while (!chunk->mSamples.empty()) { 1456 List<MediaBuffer *>::iterator it = chunk->mSamples.begin(); 1457 1458 off64_t offset = chunk->mTrack->isAvc() 1459 ? addLengthPrefixedSample_l(*it) 1460 : addSample_l(*it); 1461 1462 if (isFirstSample) { 1463 chunk->mTrack->addChunkOffset(offset); 1464 isFirstSample = false; 1465 } 1466 1467 (*it)->release(); 1468 (*it) = NULL; 1469 chunk->mSamples.erase(it); 1470 } 1471 chunk->mSamples.clear(); 1472} 1473 1474void MPEG4Writer::writeAllChunks() { 1475 ALOGV("writeAllChunks"); 1476 size_t outstandingChunks = 0; 1477 Chunk chunk; 1478 while (findChunkToWrite(&chunk)) { 1479 writeChunkToFile(&chunk); 1480 ++outstandingChunks; 1481 } 1482 1483 sendSessionSummary(); 1484 1485 mChunkInfos.clear(); 1486 ALOGD("%d chunks are written in the last batch", outstandingChunks); 1487} 1488 1489bool MPEG4Writer::findChunkToWrite(Chunk *chunk) { 1490 ALOGV("findChunkToWrite"); 1491 1492 int64_t minTimestampUs = 0x7FFFFFFFFFFFFFFFLL; 1493 Track *track = NULL; 1494 for (List<ChunkInfo>::iterator it = mChunkInfos.begin(); 1495 it != mChunkInfos.end(); ++it) { 1496 if (!it->mChunks.empty()) { 1497 List<Chunk>::iterator chunkIt = it->mChunks.begin(); 1498 if (chunkIt->mTimeStampUs < minTimestampUs) { 1499 minTimestampUs = chunkIt->mTimeStampUs; 1500 track = it->mTrack; 1501 } 1502 } 1503 } 1504 1505 if (track == NULL) { 1506 ALOGV("Nothing to be written after all"); 1507 return false; 1508 } 1509 1510 if (mIsFirstChunk) { 1511 mIsFirstChunk = false; 1512 } 1513 1514 for (List<ChunkInfo>::iterator it = mChunkInfos.begin(); 1515 it != mChunkInfos.end(); ++it) { 1516 if (it->mTrack == track) { 1517 *chunk = *(it->mChunks.begin()); 1518 it->mChunks.erase(it->mChunks.begin()); 1519 CHECK_EQ(chunk->mTrack, track); 1520 1521 int64_t interChunkTimeUs = 1522 chunk->mTimeStampUs - it->mPrevChunkTimestampUs; 1523 if (interChunkTimeUs > it->mPrevChunkTimestampUs) { 1524 it->mMaxInterChunkDurUs = interChunkTimeUs; 1525 } 1526 1527 return true; 1528 } 1529 } 1530 1531 return false; 1532} 1533 1534void MPEG4Writer::threadFunc() { 1535 ALOGV("threadFunc"); 1536 1537 prctl(PR_SET_NAME, (unsigned long)"MPEG4Writer", 0, 0, 0); 1538 1539 Mutex::Autolock autoLock(mLock); 1540 while (!mDone) { 1541 Chunk chunk; 1542 bool chunkFound = false; 1543 1544 while (!mDone && !(chunkFound = findChunkToWrite(&chunk))) { 1545 mChunkReadyCondition.wait(mLock); 1546 } 1547 1548 // Actual write without holding the lock in order to 1549 // reduce the blocking time for media track threads. 1550 if (chunkFound) { 1551 mLock.unlock(); 1552 writeChunkToFile(&chunk); 1553 mLock.lock(); 1554 } 1555 } 1556 1557 writeAllChunks(); 1558} 1559 1560status_t MPEG4Writer::startWriterThread() { 1561 ALOGV("startWriterThread"); 1562 1563 mDone = false; 1564 mIsFirstChunk = true; 1565 mDriftTimeUs = 0; 1566 for (List<Track *>::iterator it = mTracks.begin(); 1567 it != mTracks.end(); ++it) { 1568 ChunkInfo info; 1569 info.mTrack = *it; 1570 info.mPrevChunkTimestampUs = 0; 1571 info.mMaxInterChunkDurUs = 0; 1572 mChunkInfos.push_back(info); 1573 } 1574 1575 pthread_attr_t attr; 1576 pthread_attr_init(&attr); 1577 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 1578 pthread_create(&mThread, &attr, ThreadWrapper, this); 1579 pthread_attr_destroy(&attr); 1580 mWriterThreadStarted = true; 1581 return OK; 1582} 1583 1584 1585status_t MPEG4Writer::Track::start(MetaData *params) { 1586 if (!mDone && mPaused) { 1587 mPaused = false; 1588 mResumed = true; 1589 return OK; 1590 } 1591 1592 int64_t startTimeUs; 1593 if (params == NULL || !params->findInt64(kKeyTime, &startTimeUs)) { 1594 startTimeUs = 0; 1595 } 1596 mStartTimeRealUs = startTimeUs; 1597 1598 int32_t rotationDegrees; 1599 if (!mIsAudio && params && params->findInt32(kKeyRotation, &rotationDegrees)) { 1600 mRotation = rotationDegrees; 1601 } 1602 1603 mIsRealTimeRecording = true; 1604 { 1605 int32_t isNotRealTime; 1606 if (params && params->findInt32(kKeyNotRealTime, &isNotRealTime)) { 1607 mIsRealTimeRecording = (isNotRealTime == 0); 1608 } 1609 } 1610 1611 initTrackingProgressStatus(params); 1612 1613 sp<MetaData> meta = new MetaData; 1614 if (mIsRealTimeRecording && mOwner->numTracks() > 1) { 1615 /* 1616 * This extra delay of accepting incoming audio/video signals 1617 * helps to align a/v start time at the beginning of a recording 1618 * session, and it also helps eliminate the "recording" sound for 1619 * camcorder applications. 1620 * 1621 * If client does not set the start time offset, we fall back to 1622 * use the default initial delay value. 1623 */ 1624 int64_t startTimeOffsetUs = mOwner->getStartTimeOffsetMs() * 1000LL; 1625 if (startTimeOffsetUs < 0) { // Start time offset was not set 1626 startTimeOffsetUs = kInitialDelayTimeUs; 1627 } 1628 startTimeUs += startTimeOffsetUs; 1629 ALOGI("Start time offset: %lld us", startTimeOffsetUs); 1630 } 1631 1632 meta->setInt64(kKeyTime, startTimeUs); 1633 1634 status_t err = mSource->start(meta.get()); 1635 if (err != OK) { 1636 mDone = mReachedEOS = true; 1637 return err; 1638 } 1639 1640 pthread_attr_t attr; 1641 pthread_attr_init(&attr); 1642 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 1643 1644 mDone = false; 1645 mStarted = true; 1646 mTrackDurationUs = 0; 1647 mReachedEOS = false; 1648 mEstimatedTrackSizeBytes = 0; 1649 mMdatSizeBytes = 0; 1650 mMaxChunkDurationUs = 0; 1651 1652 pthread_create(&mThread, &attr, ThreadWrapper, this); 1653 pthread_attr_destroy(&attr); 1654 1655 return OK; 1656} 1657 1658status_t MPEG4Writer::Track::pause() { 1659 mPaused = true; 1660 return OK; 1661} 1662 1663status_t MPEG4Writer::Track::stop() { 1664 ALOGD("Stopping %s track", mIsAudio? "Audio": "Video"); 1665 if (!mStarted) { 1666 ALOGE("Stop() called but track is not started"); 1667 return ERROR_END_OF_STREAM; 1668 } 1669 1670 if (mDone) { 1671 return OK; 1672 } 1673 mDone = true; 1674 1675 void *dummy; 1676 pthread_join(mThread, &dummy); 1677 1678 status_t err = (status_t) dummy; 1679 1680 ALOGD("Stopping %s track source", mIsAudio? "Audio": "Video"); 1681 { 1682 status_t status = mSource->stop(); 1683 if (err == OK && status != OK && status != ERROR_END_OF_STREAM) { 1684 err = status; 1685 } 1686 } 1687 1688 ALOGD("%s track stopped", mIsAudio? "Audio": "Video"); 1689 return err; 1690} 1691 1692bool MPEG4Writer::Track::reachedEOS() { 1693 return mReachedEOS; 1694} 1695 1696// static 1697void *MPEG4Writer::Track::ThreadWrapper(void *me) { 1698 Track *track = static_cast<Track *>(me); 1699 1700 status_t err = track->threadEntry(); 1701 return (void *) err; 1702} 1703 1704static void getNalUnitType(uint8_t byte, uint8_t* type) { 1705 ALOGV("getNalUnitType: %d", byte); 1706 1707 // nal_unit_type: 5-bit unsigned integer 1708 *type = (byte & 0x1F); 1709} 1710 1711static const uint8_t *findNextStartCode( 1712 const uint8_t *data, size_t length) { 1713 1714 ALOGV("findNextStartCode: %p %d", data, length); 1715 1716 size_t bytesLeft = length; 1717 while (bytesLeft > 4 && 1718 memcmp("\x00\x00\x00\x01", &data[length - bytesLeft], 4)) { 1719 --bytesLeft; 1720 } 1721 if (bytesLeft <= 4) { 1722 bytesLeft = 0; // Last parameter set 1723 } 1724 return &data[length - bytesLeft]; 1725} 1726 1727const uint8_t *MPEG4Writer::Track::parseParamSet( 1728 const uint8_t *data, size_t length, int type, size_t *paramSetLen) { 1729 1730 ALOGV("parseParamSet"); 1731 CHECK(type == kNalUnitTypeSeqParamSet || 1732 type == kNalUnitTypePicParamSet); 1733 1734 const uint8_t *nextStartCode = findNextStartCode(data, length); 1735 *paramSetLen = nextStartCode - data; 1736 if (*paramSetLen == 0) { 1737 ALOGE("Param set is malformed, since its length is 0"); 1738 return NULL; 1739 } 1740 1741 AVCParamSet paramSet(*paramSetLen, data); 1742 if (type == kNalUnitTypeSeqParamSet) { 1743 if (*paramSetLen < 4) { 1744 ALOGE("Seq parameter set malformed"); 1745 return NULL; 1746 } 1747 if (mSeqParamSets.empty()) { 1748 mProfileIdc = data[1]; 1749 mProfileCompatible = data[2]; 1750 mLevelIdc = data[3]; 1751 } else { 1752 if (mProfileIdc != data[1] || 1753 mProfileCompatible != data[2] || 1754 mLevelIdc != data[3]) { 1755 ALOGE("Inconsistent profile/level found in seq parameter sets"); 1756 return NULL; 1757 } 1758 } 1759 mSeqParamSets.push_back(paramSet); 1760 } else { 1761 mPicParamSets.push_back(paramSet); 1762 } 1763 return nextStartCode; 1764} 1765 1766status_t MPEG4Writer::Track::copyAVCCodecSpecificData( 1767 const uint8_t *data, size_t size) { 1768 ALOGV("copyAVCCodecSpecificData"); 1769 1770 // 2 bytes for each of the parameter set length field 1771 // plus the 7 bytes for the header 1772 if (size < 4 + 7) { 1773 ALOGE("Codec specific data length too short: %d", size); 1774 return ERROR_MALFORMED; 1775 } 1776 1777 mCodecSpecificDataSize = size; 1778 mCodecSpecificData = malloc(size); 1779 memcpy(mCodecSpecificData, data, size); 1780 return OK; 1781} 1782 1783status_t MPEG4Writer::Track::parseAVCCodecSpecificData( 1784 const uint8_t *data, size_t size) { 1785 1786 ALOGV("parseAVCCodecSpecificData"); 1787 // Data starts with a start code. 1788 // SPS and PPS are separated with start codes. 1789 // Also, SPS must come before PPS 1790 uint8_t type = kNalUnitTypeSeqParamSet; 1791 bool gotSps = false; 1792 bool gotPps = false; 1793 const uint8_t *tmp = data; 1794 const uint8_t *nextStartCode = data; 1795 size_t bytesLeft = size; 1796 size_t paramSetLen = 0; 1797 mCodecSpecificDataSize = 0; 1798 while (bytesLeft > 4 && !memcmp("\x00\x00\x00\x01", tmp, 4)) { 1799 getNalUnitType(*(tmp + 4), &type); 1800 if (type == kNalUnitTypeSeqParamSet) { 1801 if (gotPps) { 1802 ALOGE("SPS must come before PPS"); 1803 return ERROR_MALFORMED; 1804 } 1805 if (!gotSps) { 1806 gotSps = true; 1807 } 1808 nextStartCode = parseParamSet(tmp + 4, bytesLeft - 4, type, ¶mSetLen); 1809 } else if (type == kNalUnitTypePicParamSet) { 1810 if (!gotSps) { 1811 ALOGE("SPS must come before PPS"); 1812 return ERROR_MALFORMED; 1813 } 1814 if (!gotPps) { 1815 gotPps = true; 1816 } 1817 nextStartCode = parseParamSet(tmp + 4, bytesLeft - 4, type, ¶mSetLen); 1818 } else { 1819 ALOGE("Only SPS and PPS Nal units are expected"); 1820 return ERROR_MALFORMED; 1821 } 1822 1823 if (nextStartCode == NULL) { 1824 return ERROR_MALFORMED; 1825 } 1826 1827 // Move on to find the next parameter set 1828 bytesLeft -= nextStartCode - tmp; 1829 tmp = nextStartCode; 1830 mCodecSpecificDataSize += (2 + paramSetLen); 1831 } 1832 1833 { 1834 // Check on the number of seq parameter sets 1835 size_t nSeqParamSets = mSeqParamSets.size(); 1836 if (nSeqParamSets == 0) { 1837 ALOGE("Cound not find sequence parameter set"); 1838 return ERROR_MALFORMED; 1839 } 1840 1841 if (nSeqParamSets > 0x1F) { 1842 ALOGE("Too many seq parameter sets (%d) found", nSeqParamSets); 1843 return ERROR_MALFORMED; 1844 } 1845 } 1846 1847 { 1848 // Check on the number of pic parameter sets 1849 size_t nPicParamSets = mPicParamSets.size(); 1850 if (nPicParamSets == 0) { 1851 ALOGE("Cound not find picture parameter set"); 1852 return ERROR_MALFORMED; 1853 } 1854 if (nPicParamSets > 0xFF) { 1855 ALOGE("Too many pic parameter sets (%d) found", nPicParamSets); 1856 return ERROR_MALFORMED; 1857 } 1858 } 1859// FIXME: 1860// Add chromat_format_idc, bit depth values, etc for AVC/h264 high profile and above 1861// and remove #if 0 1862#if 0 1863 { 1864 // Check on the profiles 1865 // These profiles requires additional parameter set extensions 1866 if (mProfileIdc == 100 || mProfileIdc == 110 || 1867 mProfileIdc == 122 || mProfileIdc == 144) { 1868 ALOGE("Sorry, no support for profile_idc: %d!", mProfileIdc); 1869 return BAD_VALUE; 1870 } 1871 } 1872#endif 1873 return OK; 1874} 1875 1876status_t MPEG4Writer::Track::makeAVCCodecSpecificData( 1877 const uint8_t *data, size_t size) { 1878 1879 if (mCodecSpecificData != NULL) { 1880 ALOGE("Already have codec specific data"); 1881 return ERROR_MALFORMED; 1882 } 1883 1884 if (size < 4) { 1885 ALOGE("Codec specific data length too short: %d", size); 1886 return ERROR_MALFORMED; 1887 } 1888 1889 // Data is in the form of AVCCodecSpecificData 1890 if (memcmp("\x00\x00\x00\x01", data, 4)) { 1891 return copyAVCCodecSpecificData(data, size); 1892 } 1893 1894 if (parseAVCCodecSpecificData(data, size) != OK) { 1895 return ERROR_MALFORMED; 1896 } 1897 1898 // ISO 14496-15: AVC file format 1899 mCodecSpecificDataSize += 7; // 7 more bytes in the header 1900 mCodecSpecificData = malloc(mCodecSpecificDataSize); 1901 uint8_t *header = (uint8_t *)mCodecSpecificData; 1902 header[0] = 1; // version 1903 header[1] = mProfileIdc; // profile indication 1904 header[2] = mProfileCompatible; // profile compatibility 1905 header[3] = mLevelIdc; 1906 1907 // 6-bit '111111' followed by 2-bit to lengthSizeMinuusOne 1908 if (mOwner->useNalLengthFour()) { 1909 header[4] = 0xfc | 3; // length size == 4 bytes 1910 } else { 1911 header[4] = 0xfc | 1; // length size == 2 bytes 1912 } 1913 1914 // 3-bit '111' followed by 5-bit numSequenceParameterSets 1915 int nSequenceParamSets = mSeqParamSets.size(); 1916 header[5] = 0xe0 | nSequenceParamSets; 1917 header += 6; 1918 for (List<AVCParamSet>::iterator it = mSeqParamSets.begin(); 1919 it != mSeqParamSets.end(); ++it) { 1920 // 16-bit sequence parameter set length 1921 uint16_t seqParamSetLength = it->mLength; 1922 header[0] = seqParamSetLength >> 8; 1923 header[1] = seqParamSetLength & 0xff; 1924 1925 // SPS NAL unit (sequence parameter length bytes) 1926 memcpy(&header[2], it->mData, seqParamSetLength); 1927 header += (2 + seqParamSetLength); 1928 } 1929 1930 // 8-bit nPictureParameterSets 1931 int nPictureParamSets = mPicParamSets.size(); 1932 header[0] = nPictureParamSets; 1933 header += 1; 1934 for (List<AVCParamSet>::iterator it = mPicParamSets.begin(); 1935 it != mPicParamSets.end(); ++it) { 1936 // 16-bit picture parameter set length 1937 uint16_t picParamSetLength = it->mLength; 1938 header[0] = picParamSetLength >> 8; 1939 header[1] = picParamSetLength & 0xff; 1940 1941 // PPS Nal unit (picture parameter set length bytes) 1942 memcpy(&header[2], it->mData, picParamSetLength); 1943 header += (2 + picParamSetLength); 1944 } 1945 1946 return OK; 1947} 1948 1949/* 1950 * Updates the drift time from the audio track so that 1951 * the video track can get the updated drift time information 1952 * from the file writer. The fluctuation of the drift time of the audio 1953 * encoding path is smoothed out with a simple filter by giving a larger 1954 * weight to more recently drift time. The filter coefficients, 0.5 and 0.5, 1955 * are heuristically determined. 1956 */ 1957void MPEG4Writer::Track::updateDriftTime(const sp<MetaData>& meta) { 1958 int64_t driftTimeUs = 0; 1959 if (meta->findInt64(kKeyDriftTime, &driftTimeUs)) { 1960 int64_t prevDriftTimeUs = mOwner->getDriftTimeUs(); 1961 int64_t timeUs = (driftTimeUs + prevDriftTimeUs) >> 1; 1962 mOwner->setDriftTimeUs(timeUs); 1963 } 1964} 1965 1966status_t MPEG4Writer::Track::threadEntry() { 1967 int32_t count = 0; 1968 const int64_t interleaveDurationUs = mOwner->interleaveDuration(); 1969 const bool hasMultipleTracks = (mOwner->numTracks() > 1); 1970 int64_t chunkTimestampUs = 0; 1971 int32_t nChunks = 0; 1972 int32_t nZeroLengthFrames = 0; 1973 int64_t lastTimestampUs = 0; // Previous sample time stamp 1974 int64_t lastDurationUs = 0; // Between the previous two samples 1975 int64_t currDurationTicks = 0; // Timescale based ticks 1976 int64_t lastDurationTicks = 0; // Timescale based ticks 1977 int32_t sampleCount = 1; // Sample count in the current stts table entry 1978 uint32_t previousSampleSize = 0; // Size of the previous sample 1979 int64_t previousPausedDurationUs = 0; 1980 int64_t timestampUs = 0; 1981 int64_t cttsOffsetTimeUs = 0; 1982 int64_t currCttsOffsetTimeTicks = 0; // Timescale based ticks 1983 int64_t lastCttsOffsetTimeTicks = -1; // Timescale based ticks 1984 int32_t cttsSampleCount = 0; // Sample count in the current ctts table entry 1985 uint32_t lastSamplesPerChunk = 0; 1986 1987 if (mIsAudio) { 1988 prctl(PR_SET_NAME, (unsigned long)"AudioTrackEncoding", 0, 0, 0); 1989 } else { 1990 prctl(PR_SET_NAME, (unsigned long)"VideoTrackEncoding", 0, 0, 0); 1991 } 1992 androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO); 1993 1994 sp<MetaData> meta_data; 1995 1996 status_t err = OK; 1997 MediaBuffer *buffer; 1998 while (!mDone && (err = mSource->read(&buffer)) == OK) { 1999 if (buffer->range_length() == 0) { 2000 buffer->release(); 2001 buffer = NULL; 2002 ++nZeroLengthFrames; 2003 continue; 2004 } 2005 2006 // If the codec specific data has not been received yet, delay pause. 2007 // After the codec specific data is received, discard what we received 2008 // when the track is to be paused. 2009 if (mPaused && !mResumed) { 2010 buffer->release(); 2011 buffer = NULL; 2012 continue; 2013 } 2014 2015 ++count; 2016 2017 int32_t isCodecConfig; 2018 if (buffer->meta_data()->findInt32(kKeyIsCodecConfig, &isCodecConfig) 2019 && isCodecConfig) { 2020 CHECK(!mGotAllCodecSpecificData); 2021 2022 if (mIsAvc) { 2023 status_t err = makeAVCCodecSpecificData( 2024 (const uint8_t *)buffer->data() 2025 + buffer->range_offset(), 2026 buffer->range_length()); 2027 CHECK_EQ((status_t)OK, err); 2028 } else if (mIsMPEG4) { 2029 mCodecSpecificDataSize = buffer->range_length(); 2030 mCodecSpecificData = malloc(mCodecSpecificDataSize); 2031 memcpy(mCodecSpecificData, 2032 (const uint8_t *)buffer->data() 2033 + buffer->range_offset(), 2034 buffer->range_length()); 2035 } 2036 2037 buffer->release(); 2038 buffer = NULL; 2039 2040 mGotAllCodecSpecificData = true; 2041 continue; 2042 } 2043 2044 // Make a deep copy of the MediaBuffer and Metadata and release 2045 // the original as soon as we can 2046 MediaBuffer *copy = new MediaBuffer(buffer->range_length()); 2047 memcpy(copy->data(), (uint8_t *)buffer->data() + buffer->range_offset(), 2048 buffer->range_length()); 2049 copy->set_range(0, buffer->range_length()); 2050 meta_data = new MetaData(*buffer->meta_data().get()); 2051 buffer->release(); 2052 buffer = NULL; 2053 2054 if (mIsAvc) StripStartcode(copy); 2055 2056 size_t sampleSize = copy->range_length(); 2057 if (mIsAvc) { 2058 if (mOwner->useNalLengthFour()) { 2059 sampleSize += 4; 2060 } else { 2061 sampleSize += 2; 2062 } 2063 } 2064 2065 // Max file size or duration handling 2066 mMdatSizeBytes += sampleSize; 2067 updateTrackSizeEstimate(); 2068 2069 if (mOwner->exceedsFileSizeLimit()) { 2070 mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED, 0); 2071 break; 2072 } 2073 if (mOwner->exceedsFileDurationLimit()) { 2074 mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_DURATION_REACHED, 0); 2075 break; 2076 } 2077 2078 2079 int32_t isSync = false; 2080 meta_data->findInt32(kKeyIsSyncFrame, &isSync); 2081 CHECK(meta_data->findInt64(kKeyTime, ×tampUs)); 2082 2083//////////////////////////////////////////////////////////////////////////////// 2084 if (mStszTableEntries->count() == 0) { 2085 mFirstSampleTimeRealUs = systemTime() / 1000; 2086 mStartTimestampUs = timestampUs; 2087 mOwner->setStartTimestampUs(mStartTimestampUs); 2088 previousPausedDurationUs = mStartTimestampUs; 2089 } 2090 2091 if (mResumed) { 2092 int64_t durExcludingEarlierPausesUs = timestampUs - previousPausedDurationUs; 2093 CHECK_GE(durExcludingEarlierPausesUs, 0ll); 2094 int64_t pausedDurationUs = durExcludingEarlierPausesUs - mTrackDurationUs; 2095 CHECK_GE(pausedDurationUs, lastDurationUs); 2096 previousPausedDurationUs += pausedDurationUs - lastDurationUs; 2097 mResumed = false; 2098 } 2099 2100 timestampUs -= previousPausedDurationUs; 2101 CHECK_GE(timestampUs, 0ll); 2102 if (!mIsAudio) { 2103 /* 2104 * Composition time: timestampUs 2105 * Decoding time: decodingTimeUs 2106 * Composition time offset = composition time - decoding time 2107 */ 2108 int64_t decodingTimeUs; 2109 CHECK(meta_data->findInt64(kKeyDecodingTime, &decodingTimeUs)); 2110 decodingTimeUs -= previousPausedDurationUs; 2111 cttsOffsetTimeUs = 2112 timestampUs + kMaxCttsOffsetTimeUs - decodingTimeUs; 2113 CHECK_GE(cttsOffsetTimeUs, 0ll); 2114 timestampUs = decodingTimeUs; 2115 ALOGV("decoding time: %lld and ctts offset time: %lld", 2116 timestampUs, cttsOffsetTimeUs); 2117 2118 // Update ctts box table if necessary 2119 currCttsOffsetTimeTicks = 2120 (cttsOffsetTimeUs * mTimeScale + 500000LL) / 1000000LL; 2121 CHECK_LE(currCttsOffsetTimeTicks, 0x0FFFFFFFFLL); 2122 if (mStszTableEntries->count() == 0) { 2123 // Force the first ctts table entry to have one single entry 2124 // so that we can do adjustment for the initial track start 2125 // time offset easily in writeCttsBox(). 2126 lastCttsOffsetTimeTicks = currCttsOffsetTimeTicks; 2127 addOneCttsTableEntry(1, currCttsOffsetTimeTicks); 2128 cttsSampleCount = 0; // No sample in ctts box is pending 2129 } else { 2130 if (currCttsOffsetTimeTicks != lastCttsOffsetTimeTicks) { 2131 addOneCttsTableEntry(cttsSampleCount, lastCttsOffsetTimeTicks); 2132 lastCttsOffsetTimeTicks = currCttsOffsetTimeTicks; 2133 cttsSampleCount = 1; // One sample in ctts box is pending 2134 } else { 2135 ++cttsSampleCount; 2136 } 2137 } 2138 2139 // Update ctts time offset range 2140 if (mStszTableEntries->count() == 0) { 2141 mMinCttsOffsetTimeUs = currCttsOffsetTimeTicks; 2142 mMaxCttsOffsetTimeUs = currCttsOffsetTimeTicks; 2143 } else { 2144 if (currCttsOffsetTimeTicks > mMaxCttsOffsetTimeUs) { 2145 mMaxCttsOffsetTimeUs = currCttsOffsetTimeTicks; 2146 } else if (currCttsOffsetTimeTicks < mMinCttsOffsetTimeUs) { 2147 mMinCttsOffsetTimeUs = currCttsOffsetTimeTicks; 2148 } 2149 } 2150 2151 } 2152 2153 if (mIsRealTimeRecording) { 2154 if (mIsAudio) { 2155 updateDriftTime(meta_data); 2156 } 2157 } 2158 2159 CHECK_GE(timestampUs, 0ll); 2160 ALOGV("%s media time stamp: %lld and previous paused duration %lld", 2161 mIsAudio? "Audio": "Video", timestampUs, previousPausedDurationUs); 2162 if (timestampUs > mTrackDurationUs) { 2163 mTrackDurationUs = timestampUs; 2164 } 2165 2166 // We need to use the time scale based ticks, rather than the 2167 // timestamp itself to determine whether we have to use a new 2168 // stts entry, since we may have rounding errors. 2169 // The calculation is intended to reduce the accumulated 2170 // rounding errors. 2171 currDurationTicks = 2172 ((timestampUs * mTimeScale + 500000LL) / 1000000LL - 2173 (lastTimestampUs * mTimeScale + 500000LL) / 1000000LL); 2174 if (currDurationTicks < 0ll) { 2175 ALOGE("timestampUs %lld < lastTimestampUs %lld for %s track", 2176 timestampUs, lastTimestampUs, mIsAudio? "Audio": "Video"); 2177 return UNKNOWN_ERROR; 2178 } 2179 2180 mStszTableEntries->add(htonl(sampleSize)); 2181 if (mStszTableEntries->count() > 2) { 2182 2183 // Force the first sample to have its own stts entry so that 2184 // we can adjust its value later to maintain the A/V sync. 2185 if (mStszTableEntries->count() == 3 || currDurationTicks != lastDurationTicks) { 2186 addOneSttsTableEntry(sampleCount, lastDurationTicks); 2187 sampleCount = 1; 2188 } else { 2189 ++sampleCount; 2190 } 2191 2192 } 2193 if (mSamplesHaveSameSize) { 2194 if (mStszTableEntries->count() >= 2 && previousSampleSize != sampleSize) { 2195 mSamplesHaveSameSize = false; 2196 } 2197 previousSampleSize = sampleSize; 2198 } 2199 ALOGV("%s timestampUs/lastTimestampUs: %lld/%lld", 2200 mIsAudio? "Audio": "Video", timestampUs, lastTimestampUs); 2201 lastDurationUs = timestampUs - lastTimestampUs; 2202 lastDurationTicks = currDurationTicks; 2203 lastTimestampUs = timestampUs; 2204 2205 if (isSync != 0) { 2206 addOneStssTableEntry(mStszTableEntries->count()); 2207 } 2208 2209 if (mTrackingProgressStatus) { 2210 if (mPreviousTrackTimeUs <= 0) { 2211 mPreviousTrackTimeUs = mStartTimestampUs; 2212 } 2213 trackProgressStatus(timestampUs); 2214 } 2215 if (!hasMultipleTracks) { 2216 off64_t offset = mIsAvc? mOwner->addLengthPrefixedSample_l(copy) 2217 : mOwner->addSample_l(copy); 2218 2219 uint32_t count = (mOwner->use32BitFileOffset() 2220 ? mStcoTableEntries->count() 2221 : mCo64TableEntries->count()); 2222 2223 if (count == 0) { 2224 addChunkOffset(offset); 2225 } 2226 copy->release(); 2227 copy = NULL; 2228 continue; 2229 } 2230 2231 mChunkSamples.push_back(copy); 2232 if (interleaveDurationUs == 0) { 2233 addOneStscTableEntry(++nChunks, 1); 2234 bufferChunk(timestampUs); 2235 } else { 2236 if (chunkTimestampUs == 0) { 2237 chunkTimestampUs = timestampUs; 2238 } else { 2239 int64_t chunkDurationUs = timestampUs - chunkTimestampUs; 2240 if (chunkDurationUs > interleaveDurationUs) { 2241 if (chunkDurationUs > mMaxChunkDurationUs) { 2242 mMaxChunkDurationUs = chunkDurationUs; 2243 } 2244 ++nChunks; 2245 if (nChunks == 1 || // First chunk 2246 lastSamplesPerChunk != mChunkSamples.size()) { 2247 lastSamplesPerChunk = mChunkSamples.size(); 2248 addOneStscTableEntry(nChunks, lastSamplesPerChunk); 2249 } 2250 bufferChunk(timestampUs); 2251 chunkTimestampUs = timestampUs; 2252 } 2253 } 2254 } 2255 2256 } 2257 2258 if (isTrackMalFormed()) { 2259 err = ERROR_MALFORMED; 2260 } 2261 2262 mOwner->trackProgressStatus(mTrackId, -1, err); 2263 2264 // Last chunk 2265 if (!hasMultipleTracks) { 2266 addOneStscTableEntry(1, mStszTableEntries->count()); 2267 } else if (!mChunkSamples.empty()) { 2268 addOneStscTableEntry(++nChunks, mChunkSamples.size()); 2269 bufferChunk(timestampUs); 2270 } 2271 2272 // We don't really know how long the last frame lasts, since 2273 // there is no frame time after it, just repeat the previous 2274 // frame's duration. 2275 if (mStszTableEntries->count() == 1) { 2276 lastDurationUs = 0; // A single sample's duration 2277 lastDurationTicks = 0; 2278 } else { 2279 ++sampleCount; // Count for the last sample 2280 } 2281 2282 if (mStszTableEntries->count() <= 2) { 2283 addOneSttsTableEntry(1, lastDurationTicks); 2284 if (sampleCount - 1 > 0) { 2285 addOneSttsTableEntry(sampleCount - 1, lastDurationTicks); 2286 } 2287 } else { 2288 addOneSttsTableEntry(sampleCount, lastDurationTicks); 2289 } 2290 2291 // The last ctts box may not have been written yet, and this 2292 // is to make sure that we write out the last ctts box. 2293 if (currCttsOffsetTimeTicks == lastCttsOffsetTimeTicks) { 2294 if (cttsSampleCount > 0) { 2295 addOneCttsTableEntry(cttsSampleCount, lastCttsOffsetTimeTicks); 2296 } 2297 } 2298 2299 mTrackDurationUs += lastDurationUs; 2300 mReachedEOS = true; 2301 2302 sendTrackSummary(hasMultipleTracks); 2303 2304 ALOGI("Received total/0-length (%d/%d) buffers and encoded %d frames. - %s", 2305 count, nZeroLengthFrames, mStszTableEntries->count(), mIsAudio? "audio": "video"); 2306 if (mIsAudio) { 2307 ALOGI("Audio track drift time: %lld us", mOwner->getDriftTimeUs()); 2308 } 2309 2310 if (err == ERROR_END_OF_STREAM) { 2311 return OK; 2312 } 2313 return err; 2314} 2315 2316bool MPEG4Writer::Track::isTrackMalFormed() const { 2317 if (mStszTableEntries->count() == 0) { // no samples written 2318 ALOGE("The number of recorded samples is 0"); 2319 return true; 2320 } 2321 2322 if (!mIsAudio && mStssTableEntries->count() == 0) { // no sync frames for video 2323 ALOGE("There are no sync frames for video track"); 2324 return true; 2325 } 2326 2327 if (OK != checkCodecSpecificData()) { // no codec specific data 2328 return true; 2329 } 2330 2331 return false; 2332} 2333 2334void MPEG4Writer::Track::sendTrackSummary(bool hasMultipleTracks) { 2335 2336 // Send track summary only if test mode is enabled. 2337 if (!isTestModeEnabled()) { 2338 return; 2339 } 2340 2341 int trackNum = (mTrackId << 28); 2342 2343 mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO, 2344 trackNum | MEDIA_RECORDER_TRACK_INFO_TYPE, 2345 mIsAudio? 0: 1); 2346 2347 mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO, 2348 trackNum | MEDIA_RECORDER_TRACK_INFO_DURATION_MS, 2349 mTrackDurationUs / 1000); 2350 2351 mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO, 2352 trackNum | MEDIA_RECORDER_TRACK_INFO_ENCODED_FRAMES, 2353 mStszTableEntries->count()); 2354 2355 { 2356 // The system delay time excluding the requested initial delay that 2357 // is used to eliminate the recording sound. 2358 int64_t startTimeOffsetUs = mOwner->getStartTimeOffsetMs() * 1000LL; 2359 if (startTimeOffsetUs < 0) { // Start time offset was not set 2360 startTimeOffsetUs = kInitialDelayTimeUs; 2361 } 2362 int64_t initialDelayUs = 2363 mFirstSampleTimeRealUs - mStartTimeRealUs - startTimeOffsetUs; 2364 2365 mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO, 2366 trackNum | MEDIA_RECORDER_TRACK_INFO_INITIAL_DELAY_MS, 2367 (initialDelayUs) / 1000); 2368 } 2369 2370 mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO, 2371 trackNum | MEDIA_RECORDER_TRACK_INFO_DATA_KBYTES, 2372 mMdatSizeBytes / 1024); 2373 2374 if (hasMultipleTracks) { 2375 mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO, 2376 trackNum | MEDIA_RECORDER_TRACK_INFO_MAX_CHUNK_DUR_MS, 2377 mMaxChunkDurationUs / 1000); 2378 2379 int64_t moovStartTimeUs = mOwner->getStartTimestampUs(); 2380 if (mStartTimestampUs != moovStartTimeUs) { 2381 int64_t startTimeOffsetUs = mStartTimestampUs - moovStartTimeUs; 2382 mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO, 2383 trackNum | MEDIA_RECORDER_TRACK_INFO_START_OFFSET_MS, 2384 startTimeOffsetUs / 1000); 2385 } 2386 } 2387} 2388 2389void MPEG4Writer::Track::trackProgressStatus(int64_t timeUs, status_t err) { 2390 ALOGV("trackProgressStatus: %lld us", timeUs); 2391 2392 if (mTrackEveryTimeDurationUs > 0 && 2393 timeUs - mPreviousTrackTimeUs >= mTrackEveryTimeDurationUs) { 2394 ALOGV("Fire time tracking progress status at %lld us", timeUs); 2395 mOwner->trackProgressStatus(mTrackId, timeUs - mPreviousTrackTimeUs, err); 2396 mPreviousTrackTimeUs = timeUs; 2397 } 2398} 2399 2400void MPEG4Writer::trackProgressStatus( 2401 size_t trackId, int64_t timeUs, status_t err) { 2402 Mutex::Autolock lock(mLock); 2403 int32_t trackNum = (trackId << 28); 2404 2405 // Error notification 2406 // Do not consider ERROR_END_OF_STREAM an error 2407 if (err != OK && err != ERROR_END_OF_STREAM) { 2408 notify(MEDIA_RECORDER_TRACK_EVENT_ERROR, 2409 trackNum | MEDIA_RECORDER_TRACK_ERROR_GENERAL, 2410 err); 2411 return; 2412 } 2413 2414 if (timeUs == -1) { 2415 // Send completion notification 2416 notify(MEDIA_RECORDER_TRACK_EVENT_INFO, 2417 trackNum | MEDIA_RECORDER_TRACK_INFO_COMPLETION_STATUS, 2418 err); 2419 } else { 2420 // Send progress status 2421 notify(MEDIA_RECORDER_TRACK_EVENT_INFO, 2422 trackNum | MEDIA_RECORDER_TRACK_INFO_PROGRESS_IN_TIME, 2423 timeUs / 1000); 2424 } 2425} 2426 2427void MPEG4Writer::setDriftTimeUs(int64_t driftTimeUs) { 2428 ALOGV("setDriftTimeUs: %lld us", driftTimeUs); 2429 Mutex::Autolock autolock(mLock); 2430 mDriftTimeUs = driftTimeUs; 2431} 2432 2433int64_t MPEG4Writer::getDriftTimeUs() { 2434 ALOGV("getDriftTimeUs: %lld us", mDriftTimeUs); 2435 Mutex::Autolock autolock(mLock); 2436 return mDriftTimeUs; 2437} 2438 2439bool MPEG4Writer::useNalLengthFour() { 2440 return mUse4ByteNalLength; 2441} 2442 2443void MPEG4Writer::Track::bufferChunk(int64_t timestampUs) { 2444 ALOGV("bufferChunk"); 2445 2446 Chunk chunk(this, timestampUs, mChunkSamples); 2447 mOwner->bufferChunk(chunk); 2448 mChunkSamples.clear(); 2449} 2450 2451int64_t MPEG4Writer::Track::getDurationUs() const { 2452 return mTrackDurationUs; 2453} 2454 2455int64_t MPEG4Writer::Track::getEstimatedTrackSizeBytes() const { 2456 return mEstimatedTrackSizeBytes; 2457} 2458 2459status_t MPEG4Writer::Track::checkCodecSpecificData() const { 2460 const char *mime; 2461 CHECK(mMeta->findCString(kKeyMIMEType, &mime)); 2462 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime) || 2463 !strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime) || 2464 !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) { 2465 if (!mCodecSpecificData || 2466 mCodecSpecificDataSize <= 0) { 2467 ALOGE("Missing codec specific data"); 2468 return ERROR_MALFORMED; 2469 } 2470 } else { 2471 if (mCodecSpecificData || 2472 mCodecSpecificDataSize > 0) { 2473 ALOGE("Unexepected codec specific data found"); 2474 return ERROR_MALFORMED; 2475 } 2476 } 2477 return OK; 2478} 2479 2480void MPEG4Writer::Track::writeTrackHeader(bool use32BitOffset) { 2481 2482 ALOGV("%s track time scale: %d", 2483 mIsAudio? "Audio": "Video", mTimeScale); 2484 2485 uint32_t now = getMpeg4Time(); 2486 mOwner->beginBox("trak"); 2487 writeTkhdBox(now); 2488 mOwner->beginBox("mdia"); 2489 writeMdhdBox(now); 2490 writeHdlrBox(); 2491 mOwner->beginBox("minf"); 2492 if (mIsAudio) { 2493 writeSmhdBox(); 2494 } else { 2495 writeVmhdBox(); 2496 } 2497 writeDinfBox(); 2498 writeStblBox(use32BitOffset); 2499 mOwner->endBox(); // minf 2500 mOwner->endBox(); // mdia 2501 mOwner->endBox(); // trak 2502} 2503 2504void MPEG4Writer::Track::writeStblBox(bool use32BitOffset) { 2505 mOwner->beginBox("stbl"); 2506 mOwner->beginBox("stsd"); 2507 mOwner->writeInt32(0); // version=0, flags=0 2508 mOwner->writeInt32(1); // entry count 2509 if (mIsAudio) { 2510 writeAudioFourCCBox(); 2511 } else { 2512 writeVideoFourCCBox(); 2513 } 2514 mOwner->endBox(); // stsd 2515 writeSttsBox(); 2516 writeCttsBox(); 2517 if (!mIsAudio) { 2518 writeStssBox(); 2519 } 2520 writeStszBox(); 2521 writeStscBox(); 2522 writeStcoBox(use32BitOffset); 2523 mOwner->endBox(); // stbl 2524} 2525 2526void MPEG4Writer::Track::writeVideoFourCCBox() { 2527 const char *mime; 2528 bool success = mMeta->findCString(kKeyMIMEType, &mime); 2529 CHECK(success); 2530 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { 2531 mOwner->beginBox("mp4v"); 2532 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { 2533 mOwner->beginBox("s263"); 2534 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) { 2535 mOwner->beginBox("avc1"); 2536 } else { 2537 ALOGE("Unknown mime type '%s'.", mime); 2538 CHECK(!"should not be here, unknown mime type."); 2539 } 2540 2541 mOwner->writeInt32(0); // reserved 2542 mOwner->writeInt16(0); // reserved 2543 mOwner->writeInt16(1); // data ref index 2544 mOwner->writeInt16(0); // predefined 2545 mOwner->writeInt16(0); // reserved 2546 mOwner->writeInt32(0); // predefined 2547 mOwner->writeInt32(0); // predefined 2548 mOwner->writeInt32(0); // predefined 2549 2550 int32_t width, height; 2551 success = mMeta->findInt32(kKeyWidth, &width); 2552 success = success && mMeta->findInt32(kKeyHeight, &height); 2553 CHECK(success); 2554 2555 mOwner->writeInt16(width); 2556 mOwner->writeInt16(height); 2557 mOwner->writeInt32(0x480000); // horiz resolution 2558 mOwner->writeInt32(0x480000); // vert resolution 2559 mOwner->writeInt32(0); // reserved 2560 mOwner->writeInt16(1); // frame count 2561 mOwner->write(" ", 32); 2562 mOwner->writeInt16(0x18); // depth 2563 mOwner->writeInt16(-1); // predefined 2564 2565 CHECK_LT(23 + mCodecSpecificDataSize, 128); 2566 2567 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { 2568 writeMp4vEsdsBox(); 2569 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { 2570 writeD263Box(); 2571 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) { 2572 writeAvccBox(); 2573 } 2574 2575 writePaspBox(); 2576 mOwner->endBox(); // mp4v, s263 or avc1 2577} 2578 2579void MPEG4Writer::Track::writeAudioFourCCBox() { 2580 const char *mime; 2581 bool success = mMeta->findCString(kKeyMIMEType, &mime); 2582 CHECK(success); 2583 const char *fourcc = NULL; 2584 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime)) { 2585 fourcc = "samr"; 2586 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) { 2587 fourcc = "sawb"; 2588 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) { 2589 fourcc = "mp4a"; 2590 } else { 2591 ALOGE("Unknown mime type '%s'.", mime); 2592 CHECK(!"should not be here, unknown mime type."); 2593 } 2594 2595 mOwner->beginBox(fourcc); // audio format 2596 mOwner->writeInt32(0); // reserved 2597 mOwner->writeInt16(0); // reserved 2598 mOwner->writeInt16(0x1); // data ref index 2599 mOwner->writeInt32(0); // reserved 2600 mOwner->writeInt32(0); // reserved 2601 int32_t nChannels; 2602 CHECK_EQ(true, mMeta->findInt32(kKeyChannelCount, &nChannels)); 2603 mOwner->writeInt16(nChannels); // channel count 2604 mOwner->writeInt16(16); // sample size 2605 mOwner->writeInt16(0); // predefined 2606 mOwner->writeInt16(0); // reserved 2607 2608 int32_t samplerate; 2609 success = mMeta->findInt32(kKeySampleRate, &samplerate); 2610 CHECK(success); 2611 mOwner->writeInt32(samplerate << 16); 2612 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) { 2613 writeMp4aEsdsBox(); 2614 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime) || 2615 !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) { 2616 writeDamrBox(); 2617 } 2618 mOwner->endBox(); 2619} 2620 2621void MPEG4Writer::Track::writeMp4aEsdsBox() { 2622 mOwner->beginBox("esds"); 2623 CHECK(mCodecSpecificData); 2624 CHECK_GT(mCodecSpecificDataSize, 0); 2625 2626 // Make sure all sizes encode to a single byte. 2627 CHECK_LT(mCodecSpecificDataSize + 23, 128); 2628 2629 mOwner->writeInt32(0); // version=0, flags=0 2630 mOwner->writeInt8(0x03); // ES_DescrTag 2631 mOwner->writeInt8(23 + mCodecSpecificDataSize); 2632 mOwner->writeInt16(0x0000);// ES_ID 2633 mOwner->writeInt8(0x00); 2634 2635 mOwner->writeInt8(0x04); // DecoderConfigDescrTag 2636 mOwner->writeInt8(15 + mCodecSpecificDataSize); 2637 mOwner->writeInt8(0x40); // objectTypeIndication ISO/IEC 14492-2 2638 mOwner->writeInt8(0x15); // streamType AudioStream 2639 2640 mOwner->writeInt16(0x03); // XXX 2641 mOwner->writeInt8(0x00); // buffer size 24-bit 2642 mOwner->writeInt32(96000); // max bit rate 2643 mOwner->writeInt32(96000); // avg bit rate 2644 2645 mOwner->writeInt8(0x05); // DecoderSpecificInfoTag 2646 mOwner->writeInt8(mCodecSpecificDataSize); 2647 mOwner->write(mCodecSpecificData, mCodecSpecificDataSize); 2648 2649 static const uint8_t kData2[] = { 2650 0x06, // SLConfigDescriptorTag 2651 0x01, 2652 0x02 2653 }; 2654 mOwner->write(kData2, sizeof(kData2)); 2655 2656 mOwner->endBox(); // esds 2657} 2658 2659void MPEG4Writer::Track::writeMp4vEsdsBox() { 2660 CHECK(mCodecSpecificData); 2661 CHECK_GT(mCodecSpecificDataSize, 0); 2662 mOwner->beginBox("esds"); 2663 2664 mOwner->writeInt32(0); // version=0, flags=0 2665 2666 mOwner->writeInt8(0x03); // ES_DescrTag 2667 mOwner->writeInt8(23 + mCodecSpecificDataSize); 2668 mOwner->writeInt16(0x0000); // ES_ID 2669 mOwner->writeInt8(0x1f); 2670 2671 mOwner->writeInt8(0x04); // DecoderConfigDescrTag 2672 mOwner->writeInt8(15 + mCodecSpecificDataSize); 2673 mOwner->writeInt8(0x20); // objectTypeIndication ISO/IEC 14492-2 2674 mOwner->writeInt8(0x11); // streamType VisualStream 2675 2676 static const uint8_t kData[] = { 2677 0x01, 0x77, 0x00, 2678 0x00, 0x03, 0xe8, 0x00, 2679 0x00, 0x03, 0xe8, 0x00 2680 }; 2681 mOwner->write(kData, sizeof(kData)); 2682 2683 mOwner->writeInt8(0x05); // DecoderSpecificInfoTag 2684 2685 mOwner->writeInt8(mCodecSpecificDataSize); 2686 mOwner->write(mCodecSpecificData, mCodecSpecificDataSize); 2687 2688 static const uint8_t kData2[] = { 2689 0x06, // SLConfigDescriptorTag 2690 0x01, 2691 0x02 2692 }; 2693 mOwner->write(kData2, sizeof(kData2)); 2694 2695 mOwner->endBox(); // esds 2696} 2697 2698void MPEG4Writer::Track::writeTkhdBox(uint32_t now) { 2699 mOwner->beginBox("tkhd"); 2700 // Flags = 7 to indicate that the track is enabled, and 2701 // part of the presentation 2702 mOwner->writeInt32(0x07); // version=0, flags=7 2703 mOwner->writeInt32(now); // creation time 2704 mOwner->writeInt32(now); // modification time 2705 mOwner->writeInt32(mTrackId); // track id starts with 1 2706 mOwner->writeInt32(0); // reserved 2707 int64_t trakDurationUs = getDurationUs(); 2708 int32_t mvhdTimeScale = mOwner->getTimeScale(); 2709 int32_t tkhdDuration = 2710 (trakDurationUs * mvhdTimeScale + 5E5) / 1E6; 2711 mOwner->writeInt32(tkhdDuration); // in mvhd timescale 2712 mOwner->writeInt32(0); // reserved 2713 mOwner->writeInt32(0); // reserved 2714 mOwner->writeInt16(0); // layer 2715 mOwner->writeInt16(0); // alternate group 2716 mOwner->writeInt16(mIsAudio ? 0x100 : 0); // volume 2717 mOwner->writeInt16(0); // reserved 2718 2719 mOwner->writeCompositionMatrix(mRotation); // matrix 2720 2721 if (mIsAudio) { 2722 mOwner->writeInt32(0); 2723 mOwner->writeInt32(0); 2724 } else { 2725 int32_t width, height; 2726 bool success = mMeta->findInt32(kKeyWidth, &width); 2727 success = success && mMeta->findInt32(kKeyHeight, &height); 2728 CHECK(success); 2729 2730 mOwner->writeInt32(width << 16); // 32-bit fixed-point value 2731 mOwner->writeInt32(height << 16); // 32-bit fixed-point value 2732 } 2733 mOwner->endBox(); // tkhd 2734} 2735 2736void MPEG4Writer::Track::writeVmhdBox() { 2737 mOwner->beginBox("vmhd"); 2738 mOwner->writeInt32(0x01); // version=0, flags=1 2739 mOwner->writeInt16(0); // graphics mode 2740 mOwner->writeInt16(0); // opcolor 2741 mOwner->writeInt16(0); 2742 mOwner->writeInt16(0); 2743 mOwner->endBox(); 2744} 2745 2746void MPEG4Writer::Track::writeSmhdBox() { 2747 mOwner->beginBox("smhd"); 2748 mOwner->writeInt32(0); // version=0, flags=0 2749 mOwner->writeInt16(0); // balance 2750 mOwner->writeInt16(0); // reserved 2751 mOwner->endBox(); 2752} 2753 2754void MPEG4Writer::Track::writeHdlrBox() { 2755 mOwner->beginBox("hdlr"); 2756 mOwner->writeInt32(0); // version=0, flags=0 2757 mOwner->writeInt32(0); // component type: should be mhlr 2758 mOwner->writeFourcc(mIsAudio ? "soun" : "vide"); // component subtype 2759 mOwner->writeInt32(0); // reserved 2760 mOwner->writeInt32(0); // reserved 2761 mOwner->writeInt32(0); // reserved 2762 // Removing "r" for the name string just makes the string 4 byte aligned 2763 mOwner->writeCString(mIsAudio ? "SoundHandle": "VideoHandle"); // name 2764 mOwner->endBox(); 2765} 2766 2767void MPEG4Writer::Track::writeMdhdBox(uint32_t now) { 2768 int64_t trakDurationUs = getDurationUs(); 2769 mOwner->beginBox("mdhd"); 2770 mOwner->writeInt32(0); // version=0, flags=0 2771 mOwner->writeInt32(now); // creation time 2772 mOwner->writeInt32(now); // modification time 2773 mOwner->writeInt32(mTimeScale); // media timescale 2774 int32_t mdhdDuration = (trakDurationUs * mTimeScale + 5E5) / 1E6; 2775 mOwner->writeInt32(mdhdDuration); // use media timescale 2776 // Language follows the three letter standard ISO-639-2/T 2777 // 'e', 'n', 'g' for "English", for instance. 2778 // Each character is packed as the difference between its ASCII value and 0x60. 2779 // For "English", these are 00101, 01110, 00111. 2780 // XXX: Where is the padding bit located: 0x15C7? 2781 mOwner->writeInt16(0); // language code 2782 mOwner->writeInt16(0); // predefined 2783 mOwner->endBox(); 2784} 2785 2786void MPEG4Writer::Track::writeDamrBox() { 2787 // 3gpp2 Spec AMRSampleEntry fields 2788 mOwner->beginBox("damr"); 2789 mOwner->writeCString(" "); // vendor: 4 bytes 2790 mOwner->writeInt8(0); // decoder version 2791 mOwner->writeInt16(0x83FF); // mode set: all enabled 2792 mOwner->writeInt8(0); // mode change period 2793 mOwner->writeInt8(1); // frames per sample 2794 mOwner->endBox(); 2795} 2796 2797void MPEG4Writer::Track::writeUrlBox() { 2798 // The table index here refers to the sample description index 2799 // in the sample table entries. 2800 mOwner->beginBox("url "); 2801 mOwner->writeInt32(1); // version=0, flags=1 (self-contained) 2802 mOwner->endBox(); // url 2803} 2804 2805void MPEG4Writer::Track::writeDrefBox() { 2806 mOwner->beginBox("dref"); 2807 mOwner->writeInt32(0); // version=0, flags=0 2808 mOwner->writeInt32(1); // entry count (either url or urn) 2809 writeUrlBox(); 2810 mOwner->endBox(); // dref 2811} 2812 2813void MPEG4Writer::Track::writeDinfBox() { 2814 mOwner->beginBox("dinf"); 2815 writeDrefBox(); 2816 mOwner->endBox(); // dinf 2817} 2818 2819void MPEG4Writer::Track::writeAvccBox() { 2820 CHECK(mCodecSpecificData); 2821 CHECK_GE(mCodecSpecificDataSize, 5); 2822 2823 // Patch avcc's lengthSize field to match the number 2824 // of bytes we use to indicate the size of a nal unit. 2825 uint8_t *ptr = (uint8_t *)mCodecSpecificData; 2826 ptr[4] = (ptr[4] & 0xfc) | (mOwner->useNalLengthFour() ? 3 : 1); 2827 mOwner->beginBox("avcC"); 2828 mOwner->write(mCodecSpecificData, mCodecSpecificDataSize); 2829 mOwner->endBox(); // avcC 2830} 2831 2832void MPEG4Writer::Track::writeD263Box() { 2833 mOwner->beginBox("d263"); 2834 mOwner->writeInt32(0); // vendor 2835 mOwner->writeInt8(0); // decoder version 2836 mOwner->writeInt8(10); // level: 10 2837 mOwner->writeInt8(0); // profile: 0 2838 mOwner->endBox(); // d263 2839} 2840 2841// This is useful if the pixel is not square 2842void MPEG4Writer::Track::writePaspBox() { 2843 mOwner->beginBox("pasp"); 2844 mOwner->writeInt32(1 << 16); // hspacing 2845 mOwner->writeInt32(1 << 16); // vspacing 2846 mOwner->endBox(); // pasp 2847} 2848 2849int32_t MPEG4Writer::Track::getStartTimeOffsetScaledTime() const { 2850 int64_t trackStartTimeOffsetUs = 0; 2851 int64_t moovStartTimeUs = mOwner->getStartTimestampUs(); 2852 if (mStartTimestampUs != moovStartTimeUs) { 2853 CHECK_GT(mStartTimestampUs, moovStartTimeUs); 2854 trackStartTimeOffsetUs = mStartTimestampUs - moovStartTimeUs; 2855 } 2856 return (trackStartTimeOffsetUs * mTimeScale + 500000LL) / 1000000LL; 2857} 2858 2859void MPEG4Writer::Track::writeSttsBox() { 2860 mOwner->beginBox("stts"); 2861 mOwner->writeInt32(0); // version=0, flags=0 2862 uint32_t duration; 2863 CHECK(mSttsTableEntries->get(duration, 1)); 2864 duration = htonl(duration); // Back to host byte order 2865 mSttsTableEntries->set(htonl(duration + getStartTimeOffsetScaledTime()), 1); 2866 mSttsTableEntries->write(mOwner); 2867 mOwner->endBox(); // stts 2868} 2869 2870void MPEG4Writer::Track::writeCttsBox() { 2871 if (mIsAudio) { // ctts is not for audio 2872 return; 2873 } 2874 2875 // There is no B frame at all 2876 if (mMinCttsOffsetTimeUs == mMaxCttsOffsetTimeUs) { 2877 return; 2878 } 2879 2880 // Do not write ctts box when there is no need to have it. 2881 if (mCttsTableEntries->count() == 0) { 2882 return; 2883 } 2884 2885 ALOGV("ctts box has %d entries with range [%lld, %lld]", 2886 mCttsTableEntries->count(), mMinCttsOffsetTimeUs, mMaxCttsOffsetTimeUs); 2887 2888 mOwner->beginBox("ctts"); 2889 mOwner->writeInt32(0); // version=0, flags=0 2890 uint32_t duration; 2891 CHECK(mCttsTableEntries->get(duration, 1)); 2892 duration = htonl(duration); // Back host byte order 2893 mCttsTableEntries->set(htonl(duration + getStartTimeOffsetScaledTime() - mMinCttsOffsetTimeUs), 1); 2894 mCttsTableEntries->write(mOwner); 2895 mOwner->endBox(); // ctts 2896} 2897 2898void MPEG4Writer::Track::writeStssBox() { 2899 mOwner->beginBox("stss"); 2900 mOwner->writeInt32(0); // version=0, flags=0 2901 mStssTableEntries->write(mOwner); 2902 mOwner->endBox(); // stss 2903} 2904 2905void MPEG4Writer::Track::writeStszBox() { 2906 mOwner->beginBox("stsz"); 2907 mOwner->writeInt32(0); // version=0, flags=0 2908 mOwner->writeInt32(0); 2909 mStszTableEntries->write(mOwner); 2910 mOwner->endBox(); // stsz 2911} 2912 2913void MPEG4Writer::Track::writeStscBox() { 2914 mOwner->beginBox("stsc"); 2915 mOwner->writeInt32(0); // version=0, flags=0 2916 mStscTableEntries->write(mOwner); 2917 mOwner->endBox(); // stsc 2918} 2919 2920void MPEG4Writer::Track::writeStcoBox(bool use32BitOffset) { 2921 mOwner->beginBox(use32BitOffset? "stco": "co64"); 2922 mOwner->writeInt32(0); // version=0, flags=0 2923 if (use32BitOffset) { 2924 mStcoTableEntries->write(mOwner); 2925 } else { 2926 mCo64TableEntries->write(mOwner); 2927 } 2928 mOwner->endBox(); // stco or co64 2929} 2930 2931void MPEG4Writer::writeUdtaBox() { 2932 beginBox("udta"); 2933 writeGeoDataBox(); 2934 endBox(); 2935} 2936 2937/* 2938 * Geodata is stored according to ISO-6709 standard. 2939 */ 2940void MPEG4Writer::writeGeoDataBox() { 2941 beginBox("\xA9xyz"); 2942 /* 2943 * For historical reasons, any user data start 2944 * with "\0xA9", must be followed by its assoicated 2945 * language code. 2946 * 0x0012: text string length 2947 * 0x15c7: lang (locale) code: en 2948 */ 2949 writeInt32(0x001215c7); 2950 writeLatitude(mLatitudex10000); 2951 writeLongitude(mLongitudex10000); 2952 writeInt8(0x2F); 2953 endBox(); 2954} 2955 2956} // namespace android 2957