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