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