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