MPEG4Writer.cpp revision d599cd4573b5a2d5914c5040e0565ef866749b77
1/* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17//#define LOG_NDEBUG 0 18#define LOG_TAG "MPEG4Writer" 19#include <utils/Log.h> 20 21#include <arpa/inet.h> 22 23#include <ctype.h> 24#include <pthread.h> 25 26#include <media/stagefright/MPEG4Writer.h> 27#include <media/stagefright/MediaBuffer.h> 28#include <media/stagefright/MetaData.h> 29#include <media/stagefright/MediaDebug.h> 30#include <media/stagefright/MediaDefs.h> 31#include <media/stagefright/MediaErrors.h> 32#include <media/stagefright/MediaSource.h> 33#include <media/stagefright/Utils.h> 34#include <media/mediarecorder.h> 35 36namespace android { 37 38class MPEG4Writer::Track { 39public: 40 Track(MPEG4Writer *owner, const sp<MediaSource> &source); 41 ~Track(); 42 43 status_t start(); 44 void stop(); 45 bool reachedEOS(); 46 47 int64_t getDurationUs() const; 48 int64_t getEstimatedTrackSizeBytes() const; 49 void writeTrackHeader(int32_t trackID); 50 51private: 52 MPEG4Writer *mOwner; 53 sp<MetaData> mMeta; 54 sp<MediaSource> mSource; 55 volatile bool mDone; 56 int64_t mMaxTimeStampUs; 57 int64_t mEstimatedTrackSizeBytes; 58 59 pthread_t mThread; 60 61 struct SampleInfo { 62 size_t size; 63 int64_t timestamp; 64 }; 65 List<SampleInfo> mSampleInfos; 66 bool mSamplesHaveSameSize; 67 68 List<MediaBuffer *> mChunkSamples; 69 List<off_t> mChunkOffsets; 70 71 struct StscTableEntry { 72 73 StscTableEntry(uint32_t chunk, uint32_t samples, uint32_t id) 74 : firstChunk(chunk), 75 samplesPerChunk(samples), 76 sampleDescriptionId(id) {} 77 78 uint32_t firstChunk; 79 uint32_t samplesPerChunk; 80 uint32_t sampleDescriptionId; 81 }; 82 List<StscTableEntry> mStscTableEntries; 83 84 List<int32_t> mStssTableEntries; 85 86 struct SttsTableEntry { 87 88 SttsTableEntry(uint32_t count, uint32_t duration) 89 : sampleCount(count), sampleDuration(duration) {} 90 91 uint32_t sampleCount; 92 uint32_t sampleDuration; 93 }; 94 List<SttsTableEntry> mSttsTableEntries; 95 96 void *mCodecSpecificData; 97 size_t mCodecSpecificDataSize; 98 bool mGotAllCodecSpecificData; 99 100 bool mReachedEOS; 101 102 static void *ThreadWrapper(void *me); 103 void threadEntry(); 104 105 status_t makeAVCCodecSpecificData( 106 const uint8_t *data, size_t size); 107 void writeOneChunk(bool isAvc); 108 109 Track(const Track &); 110 Track &operator=(const Track &); 111}; 112 113#define USE_NALLEN_FOUR 1 114 115MPEG4Writer::MPEG4Writer(const char *filename) 116 : mFile(fopen(filename, "wb")), 117 mOffset(0), 118 mMdatOffset(0), 119 mEstimatedMoovBoxSize(0), 120 mInterleaveDurationUs(500000) { 121 CHECK(mFile != NULL); 122} 123 124MPEG4Writer::MPEG4Writer(int fd) 125 : mFile(fdopen(fd, "wb")), 126 mOffset(0), 127 mMdatOffset(0), 128 mEstimatedMoovBoxSize(0), 129 mInterleaveDurationUs(500000) { 130 CHECK(mFile != NULL); 131} 132 133MPEG4Writer::~MPEG4Writer() { 134 stop(); 135 136 for (List<Track *>::iterator it = mTracks.begin(); 137 it != mTracks.end(); ++it) { 138 delete *it; 139 } 140 mTracks.clear(); 141} 142 143status_t MPEG4Writer::addSource(const sp<MediaSource> &source) { 144 Track *track = new Track(this, source); 145 mTracks.push_back(track); 146 147 return OK; 148} 149 150status_t MPEG4Writer::start() { 151 if (mFile == NULL) { 152 return UNKNOWN_ERROR; 153 } 154 155 mStreamableFile = true; 156 mWriteMoovBoxToMemory = false; 157 mMoovBoxBuffer = NULL; 158 mMoovBoxBufferOffset = 0; 159 160 beginBox("ftyp"); 161 writeFourcc("isom"); 162 writeInt32(0); 163 writeFourcc("isom"); 164 endBox(); 165 166 mFreeBoxOffset = mOffset; 167 168 if (mEstimatedMoovBoxSize == 0) { 169 // XXX: Estimate the moov box size 170 // based on max file size or duration limit 171 mEstimatedMoovBoxSize = 0x0F00; 172 } 173 CHECK(mEstimatedMoovBoxSize >= 8); 174 fseeko(mFile, mFreeBoxOffset, SEEK_SET); 175 writeInt32(mEstimatedMoovBoxSize); 176 write("free", 4); 177 178 mMdatOffset = mFreeBoxOffset + mEstimatedMoovBoxSize; 179 mOffset = mMdatOffset; 180 fseeko(mFile, mMdatOffset, SEEK_SET); 181 write("\x00\x00\x00\x01mdat????????", 16); 182 for (List<Track *>::iterator it = mTracks.begin(); 183 it != mTracks.end(); ++it) { 184 status_t err = (*it)->start(); 185 186 if (err != OK) { 187 for (List<Track *>::iterator it2 = mTracks.begin(); 188 it2 != it; ++it2) { 189 (*it2)->stop(); 190 } 191 192 return err; 193 } 194 } 195 196 return OK; 197} 198 199void MPEG4Writer::stop() { 200 if (mFile == NULL) { 201 return; 202 } 203 204 int64_t max_duration = 0; 205 for (List<Track *>::iterator it = mTracks.begin(); 206 it != mTracks.end(); ++it) { 207 (*it)->stop(); 208 209 int64_t duration = (*it)->getDurationUs(); 210 if (duration > max_duration) { 211 max_duration = duration; 212 } 213 } 214 215 216 // Fix up the size of the 'mdat' chunk. 217 fseeko(mFile, mMdatOffset + 8, SEEK_SET); 218 int64_t size = mOffset - mMdatOffset; 219 size = hton64(size); 220 fwrite(&size, 1, 8, mFile); 221 fseeko(mFile, mOffset, SEEK_SET); 222 223 time_t now = time(NULL); 224 const off_t moovOffset = mOffset; 225 mWriteMoovBoxToMemory = true; 226 mMoovBoxBuffer = (uint8_t *) malloc(mEstimatedMoovBoxSize); 227 mMoovBoxBufferOffset = 0; 228 CHECK(mMoovBoxBuffer != NULL); 229 230 beginBox("moov"); 231 232 beginBox("mvhd"); 233 writeInt32(0); // version=0, flags=0 234 writeInt32(now); // creation time 235 writeInt32(now); // modification time 236 writeInt32(1000); // timescale 237 writeInt32(max_duration / 1000); 238 writeInt32(0x10000); // rate 239 writeInt16(0x100); // volume 240 writeInt16(0); // reserved 241 writeInt32(0); // reserved 242 writeInt32(0); // reserved 243 writeInt32(0x10000); // matrix 244 writeInt32(0); 245 writeInt32(0); 246 writeInt32(0); 247 writeInt32(0x10000); 248 writeInt32(0); 249 writeInt32(0); 250 writeInt32(0); 251 writeInt32(0x40000000); 252 writeInt32(0); // predefined 253 writeInt32(0); // predefined 254 writeInt32(0); // predefined 255 writeInt32(0); // predefined 256 writeInt32(0); // predefined 257 writeInt32(0); // predefined 258 writeInt32(mTracks.size() + 1); // nextTrackID 259 endBox(); // mvhd 260 261 int32_t id = 1; 262 for (List<Track *>::iterator it = mTracks.begin(); 263 it != mTracks.end(); ++it, ++id) { 264 (*it)->writeTrackHeader(id); 265 } 266 endBox(); // moov 267 268 mWriteMoovBoxToMemory = false; 269 if (mStreamableFile) { 270 CHECK(mMoovBoxBufferOffset + 8 <= mEstimatedMoovBoxSize); 271 272 // Moov box 273 fseeko(mFile, mFreeBoxOffset, SEEK_SET); 274 mOffset = mFreeBoxOffset; 275 write(mMoovBoxBuffer, 1, mMoovBoxBufferOffset, mFile); 276 277 // Free box 278 mFreeBoxOffset = mStreamableFile? mOffset: mFreeBoxOffset; 279 fseeko(mFile, mFreeBoxOffset, SEEK_SET); 280 writeInt32(mEstimatedMoovBoxSize - mMoovBoxBufferOffset); 281 write("free", 4); 282 283 // Free temp memory 284 free(mMoovBoxBuffer); 285 mMoovBoxBuffer = NULL; 286 mMoovBoxBufferOffset = 0; 287 } 288 289 CHECK(mBoxes.empty()); 290 291 fflush(mFile); 292 fclose(mFile); 293 mFile = NULL; 294} 295 296status_t MPEG4Writer::setInterleaveDuration(uint32_t durationUs) { 297 mInterleaveDurationUs = durationUs; 298 return OK; 299} 300 301void MPEG4Writer::lock() { 302 mLock.lock(); 303} 304 305void MPEG4Writer::unlock() { 306 mLock.unlock(); 307} 308 309off_t MPEG4Writer::addSample_l(MediaBuffer *buffer) { 310 off_t old_offset = mOffset; 311 312 fwrite((const uint8_t *)buffer->data() + buffer->range_offset(), 313 1, buffer->range_length(), mFile); 314 315 mOffset += buffer->range_length(); 316 317 return old_offset; 318} 319 320static void StripStartcode(MediaBuffer *buffer) { 321 if (buffer->range_length() < 4) { 322 return; 323 } 324 325 const uint8_t *ptr = 326 (const uint8_t *)buffer->data() + buffer->range_offset(); 327 328 if (!memcmp(ptr, "\x00\x00\x00\x01", 4)) { 329 buffer->set_range( 330 buffer->range_offset() + 4, buffer->range_length() - 4); 331 } 332} 333 334off_t MPEG4Writer::addLengthPrefixedSample_l(MediaBuffer *buffer) { 335 StripStartcode(buffer); 336 337 off_t old_offset = mOffset; 338 339 size_t length = buffer->range_length(); 340 341#if USE_NALLEN_FOUR 342 uint8_t x = length >> 24; 343 fwrite(&x, 1, 1, mFile); 344 x = (length >> 16) & 0xff; 345 fwrite(&x, 1, 1, mFile); 346 x = (length >> 8) & 0xff; 347 fwrite(&x, 1, 1, mFile); 348 x = length & 0xff; 349 fwrite(&x, 1, 1, mFile); 350#else 351 CHECK(length < 65536); 352 353 uint8_t x = length >> 8; 354 fwrite(&x, 1, 1, mFile); 355 x = length & 0xff; 356 fwrite(&x, 1, 1, mFile); 357#endif 358 359 fwrite((const uint8_t *)buffer->data() + buffer->range_offset(), 360 1, length, mFile); 361 362#if USE_NALLEN_FOUR 363 mOffset += length + 4; 364#else 365 mOffset += length + 2; 366#endif 367 368 return old_offset; 369} 370 371size_t MPEG4Writer::write( 372 const void *ptr, size_t size, size_t nmemb, FILE *stream) { 373 374 const size_t bytes = size * nmemb; 375 if (mWriteMoovBoxToMemory) { 376 if (8 + mMoovBoxBufferOffset + bytes > mEstimatedMoovBoxSize) { 377 for (List<off_t>::iterator it = mBoxes.begin(); 378 it != mBoxes.end(); ++it) { 379 (*it) += mOffset; 380 } 381 fseeko(mFile, mOffset, SEEK_SET); 382 fwrite(mMoovBoxBuffer, 1, mMoovBoxBufferOffset, stream); 383 fwrite(ptr, size, nmemb, stream); 384 mOffset += (bytes + mMoovBoxBufferOffset); 385 free(mMoovBoxBuffer); 386 mMoovBoxBuffer = NULL; 387 mMoovBoxBufferOffset = 0; 388 mWriteMoovBoxToMemory = false; 389 mStreamableFile = false; 390 } else { 391 memcpy(mMoovBoxBuffer + mMoovBoxBufferOffset, ptr, bytes); 392 mMoovBoxBufferOffset += bytes; 393 } 394 } else { 395 fwrite(ptr, size, nmemb, stream); 396 mOffset += bytes; 397 } 398 return bytes; 399} 400 401void MPEG4Writer::beginBox(const char *fourcc) { 402 CHECK_EQ(strlen(fourcc), 4); 403 404 mBoxes.push_back(mWriteMoovBoxToMemory? 405 mMoovBoxBufferOffset: mOffset); 406 407 writeInt32(0); 408 writeFourcc(fourcc); 409} 410 411void MPEG4Writer::endBox() { 412 CHECK(!mBoxes.empty()); 413 414 off_t offset = *--mBoxes.end(); 415 mBoxes.erase(--mBoxes.end()); 416 417 if (mWriteMoovBoxToMemory) { 418 int32_t x = htonl(mMoovBoxBufferOffset - offset); 419 memcpy(mMoovBoxBuffer + offset, &x, 4); 420 } else { 421 fseeko(mFile, offset, SEEK_SET); 422 writeInt32(mOffset - offset); 423 mOffset -= 4; 424 fseeko(mFile, mOffset, SEEK_SET); 425 } 426} 427 428void MPEG4Writer::writeInt8(int8_t x) { 429 write(&x, 1, 1, mFile); 430} 431 432void MPEG4Writer::writeInt16(int16_t x) { 433 x = htons(x); 434 write(&x, 1, 2, mFile); 435} 436 437void MPEG4Writer::writeInt32(int32_t x) { 438 x = htonl(x); 439 write(&x, 1, 4, mFile); 440} 441 442void MPEG4Writer::writeInt64(int64_t x) { 443 x = hton64(x); 444 write(&x, 1, 8, mFile); 445} 446 447void MPEG4Writer::writeCString(const char *s) { 448 size_t n = strlen(s); 449 write(s, 1, n + 1, mFile); 450} 451 452void MPEG4Writer::writeFourcc(const char *s) { 453 CHECK_EQ(strlen(s), 4); 454 write(s, 1, 4, mFile); 455} 456 457void MPEG4Writer::write(const void *data, size_t size) { 458 write(data, 1, size, mFile); 459} 460 461bool MPEG4Writer::exceedsFileSizeLimit() { 462 // No limit 463 if (mMaxFileSizeLimitBytes == 0) { 464 return false; 465 } 466 467 int64_t nTotalBytesEstimate = mEstimatedMoovBoxSize; 468 for (List<Track *>::iterator it = mTracks.begin(); 469 it != mTracks.end(); ++it) { 470 nTotalBytesEstimate += (*it)->getEstimatedTrackSizeBytes(); 471 } 472 return (nTotalBytesEstimate >= mMaxFileSizeLimitBytes); 473} 474 475bool MPEG4Writer::exceedsFileDurationLimit() { 476 // No limit 477 if (mMaxFileDurationLimitUs == 0) { 478 return false; 479 } 480 481 for (List<Track *>::iterator it = mTracks.begin(); 482 it != mTracks.end(); ++it) { 483 if ((*it)->getDurationUs() >= mMaxFileDurationLimitUs) { 484 return true; 485 } 486 } 487 return false; 488} 489 490bool MPEG4Writer::reachedEOS() { 491 bool allDone = true; 492 for (List<Track *>::iterator it = mTracks.begin(); 493 it != mTracks.end(); ++it) { 494 if (!(*it)->reachedEOS()) { 495 allDone = false; 496 break; 497 } 498 } 499 500 return allDone; 501} 502 503//////////////////////////////////////////////////////////////////////////////// 504 505MPEG4Writer::Track::Track( 506 MPEG4Writer *owner, const sp<MediaSource> &source) 507 : mOwner(owner), 508 mMeta(source->getFormat()), 509 mSource(source), 510 mDone(false), 511 mMaxTimeStampUs(0), 512 mSamplesHaveSameSize(true), 513 mCodecSpecificData(NULL), 514 mCodecSpecificDataSize(0), 515 mGotAllCodecSpecificData(false), 516 mReachedEOS(false) { 517} 518 519MPEG4Writer::Track::~Track() { 520 stop(); 521 522 if (mCodecSpecificData != NULL) { 523 free(mCodecSpecificData); 524 mCodecSpecificData = NULL; 525 } 526} 527 528status_t MPEG4Writer::Track::start() { 529 status_t err = mSource->start(); 530 531 if (err != OK) { 532 mDone = mReachedEOS = true; 533 return err; 534 } 535 536 pthread_attr_t attr; 537 pthread_attr_init(&attr); 538 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 539 540 mDone = false; 541 mMaxTimeStampUs = 0; 542 mReachedEOS = false; 543 544 pthread_create(&mThread, &attr, ThreadWrapper, this); 545 pthread_attr_destroy(&attr); 546 547 return OK; 548} 549 550void MPEG4Writer::Track::stop() { 551 if (mDone) { 552 return; 553 } 554 555 mDone = true; 556 557 void *dummy; 558 pthread_join(mThread, &dummy); 559 560 mSource->stop(); 561} 562 563bool MPEG4Writer::Track::reachedEOS() { 564 return mReachedEOS; 565} 566 567// static 568void *MPEG4Writer::Track::ThreadWrapper(void *me) { 569 Track *track = static_cast<Track *>(me); 570 571 track->threadEntry(); 572 573 return NULL; 574} 575 576#include <ctype.h> 577static void hexdump(const void *_data, size_t size) { 578 const uint8_t *data = (const uint8_t *)_data; 579 size_t offset = 0; 580 while (offset < size) { 581 printf("0x%04x ", offset); 582 583 size_t n = size - offset; 584 if (n > 16) { 585 n = 16; 586 } 587 588 for (size_t i = 0; i < 16; ++i) { 589 if (i == 8) { 590 printf(" "); 591 } 592 593 if (offset + i < size) { 594 printf("%02x ", data[offset + i]); 595 } else { 596 printf(" "); 597 } 598 } 599 600 printf(" "); 601 602 for (size_t i = 0; i < n; ++i) { 603 if (isprint(data[offset + i])) { 604 printf("%c", data[offset + i]); 605 } else { 606 printf("."); 607 } 608 } 609 610 printf("\n"); 611 612 offset += 16; 613 } 614} 615 616 617status_t MPEG4Writer::Track::makeAVCCodecSpecificData( 618 const uint8_t *data, size_t size) { 619 // hexdump(data, size); 620 621 if (mCodecSpecificData != NULL) { 622 LOGE("Already have codec specific data"); 623 return ERROR_MALFORMED; 624 } 625 626 if (size < 4 || memcmp("\x00\x00\x00\x01", data, 4)) { 627 LOGE("Must start with a start code"); 628 return ERROR_MALFORMED; 629 } 630 631 size_t picParamOffset = 4; 632 while (picParamOffset + 3 < size 633 && memcmp("\x00\x00\x00\x01", &data[picParamOffset], 4)) { 634 ++picParamOffset; 635 } 636 637 if (picParamOffset + 3 >= size) { 638 LOGE("Could not find start-code for pictureParameterSet"); 639 return ERROR_MALFORMED; 640 } 641 642 size_t seqParamSetLength = picParamOffset - 4; 643 size_t picParamSetLength = size - picParamOffset - 4; 644 645 mCodecSpecificDataSize = 646 6 + 1 + seqParamSetLength + 2 + picParamSetLength + 2; 647 648 mCodecSpecificData = malloc(mCodecSpecificDataSize); 649 uint8_t *header = (uint8_t *)mCodecSpecificData; 650 header[0] = 1; 651 header[1] = 0x42; // profile 652 header[2] = 0x80; 653 header[3] = 0x1e; // level 654 655#if USE_NALLEN_FOUR 656 header[4] = 0xfc | 3; // length size == 4 bytes 657#else 658 header[4] = 0xfc | 1; // length size == 2 bytes 659#endif 660 661 header[5] = 0xe0 | 1; 662 header[6] = seqParamSetLength >> 8; 663 header[7] = seqParamSetLength & 0xff; 664 memcpy(&header[8], &data[4], seqParamSetLength); 665 header += 8 + seqParamSetLength; 666 header[0] = 1; 667 header[1] = picParamSetLength >> 8; 668 header[2] = picParamSetLength & 0xff; 669 memcpy(&header[3], &data[picParamOffset + 4], picParamSetLength); 670 671 return OK; 672} 673 674void MPEG4Writer::Track::threadEntry() { 675 sp<MetaData> meta = mSource->getFormat(); 676 const char *mime; 677 meta->findCString(kKeyMIMEType, &mime); 678 bool is_mpeg4 = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) || 679 !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC); 680 bool is_avc = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 681 int32_t count = 0; 682 const int64_t interleaveDurationUs = mOwner->interleaveDuration(); 683 int64_t chunkTimestampUs = 0; 684 int32_t nChunks = 0; 685 int32_t nZeroLengthFrames = 0; 686 int64_t lastTimestamp = 0; // Timestamp of the previous sample 687 int64_t lastDuration = 0; // Time spacing between the previous two samples 688 int32_t sampleCount = 1; // Sample count in the current stts table entry 689 uint32_t previousSampleSize = 0; // Size of the previous sample 690 691 mEstimatedTrackSizeBytes = 0; 692 MediaBuffer *buffer; 693 while (!mDone && mSource->read(&buffer) == OK) { 694 if (buffer->range_length() == 0) { 695 buffer->release(); 696 buffer = NULL; 697 ++nZeroLengthFrames; 698 continue; 699 } 700 701 ++count; 702 703 int32_t isCodecConfig; 704 if (buffer->meta_data()->findInt32(kKeyIsCodecConfig, &isCodecConfig) 705 && isCodecConfig) { 706 CHECK(!mGotAllCodecSpecificData); 707 708 if (is_avc) { 709 status_t err = makeAVCCodecSpecificData( 710 (const uint8_t *)buffer->data() 711 + buffer->range_offset(), 712 buffer->range_length()); 713 CHECK_EQ(OK, err); 714 } else if (is_mpeg4) { 715 mCodecSpecificDataSize = buffer->range_length(); 716 mCodecSpecificData = malloc(mCodecSpecificDataSize); 717 memcpy(mCodecSpecificData, 718 (const uint8_t *)buffer->data() 719 + buffer->range_offset(), 720 buffer->range_length()); 721 } 722 723 buffer->release(); 724 buffer = NULL; 725 726 mGotAllCodecSpecificData = true; 727 continue; 728 } else if (!mGotAllCodecSpecificData && 729 count == 1 && is_mpeg4 && mCodecSpecificData == NULL) { 730 // The TI mpeg4 encoder does not properly set the 731 // codec-specific-data flag. 732 733 const uint8_t *data = 734 (const uint8_t *)buffer->data() + buffer->range_offset(); 735 736 const size_t size = buffer->range_length(); 737 738 size_t offset = 0; 739 while (offset + 3 < size) { 740 if (data[offset] == 0x00 && data[offset + 1] == 0x00 741 && data[offset + 2] == 0x01 && data[offset + 3] == 0xb6) { 742 break; 743 } 744 745 ++offset; 746 } 747 748 // CHECK(offset + 3 < size); 749 if (offset + 3 >= size) { 750 // XXX assume the entire first chunk of data is the codec specific 751 // data. 752 offset = size; 753 } 754 755 mCodecSpecificDataSize = offset; 756 mCodecSpecificData = malloc(offset); 757 memcpy(mCodecSpecificData, data, offset); 758 759 buffer->set_range(buffer->range_offset() + offset, size - offset); 760 761 if (size == offset) { 762 buffer->release(); 763 buffer = NULL; 764 765 continue; 766 } 767 768 mGotAllCodecSpecificData = true; 769 } else if (!mGotAllCodecSpecificData && is_avc && count < 3) { 770 // The TI video encoder does not flag codec specific data 771 // as such and also splits up SPS and PPS across two buffers. 772 773 const uint8_t *data = 774 (const uint8_t *)buffer->data() + buffer->range_offset(); 775 776 size_t size = buffer->range_length(); 777 778 CHECK(count == 2 || mCodecSpecificData == NULL); 779 780 size_t offset = mCodecSpecificDataSize; 781 mCodecSpecificDataSize += size + 4; 782 mCodecSpecificData = 783 realloc(mCodecSpecificData, mCodecSpecificDataSize); 784 785 memcpy((uint8_t *)mCodecSpecificData + offset, 786 "\x00\x00\x00\x01", 4); 787 788 memcpy((uint8_t *)mCodecSpecificData + offset + 4, data, size); 789 790 buffer->release(); 791 buffer = NULL; 792 793 if (count == 2) { 794 void *tmp = mCodecSpecificData; 795 size = mCodecSpecificDataSize; 796 mCodecSpecificData = NULL; 797 mCodecSpecificDataSize = 0; 798 799 status_t err = makeAVCCodecSpecificData( 800 (const uint8_t *)tmp, size); 801 free(tmp); 802 tmp = NULL; 803 CHECK_EQ(OK, err); 804 805 mGotAllCodecSpecificData = true; 806 } 807 808 continue; 809 } 810 811 SampleInfo info; 812 info.size = is_avc 813#if USE_NALLEN_FOUR 814 ? buffer->range_length() + 4 815#else 816 ? buffer->range_length() + 2 817#endif 818 : buffer->range_length(); 819 820 // Max file size or duration handling 821 mEstimatedTrackSizeBytes += info.size; 822 if (mOwner->exceedsFileSizeLimit()) { 823 buffer->release(); 824 buffer = NULL; 825 mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED, 0); 826 break; 827 } 828 if (mOwner->exceedsFileDurationLimit()) { 829 buffer->release(); 830 buffer = NULL; 831 mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_DURATION_REACHED, 0); 832 break; 833 } 834 835 bool is_audio = !strncasecmp(mime, "audio/", 6); 836 837 int64_t timestampUs; 838 CHECK(buffer->meta_data()->findInt64(kKeyTime, ×tampUs)); 839 840 if (timestampUs > mMaxTimeStampUs) { 841 mMaxTimeStampUs = timestampUs; 842 } 843 844 // Our timestamp is in ms. 845 info.timestamp = (timestampUs + 500) / 1000; 846 mSampleInfos.push_back(info); 847 if (mSampleInfos.size() > 2) { 848 if (lastDuration != info.timestamp - lastTimestamp) { 849 SttsTableEntry sttsEntry(sampleCount, lastDuration); 850 mSttsTableEntries.push_back(sttsEntry); 851 sampleCount = 1; 852 } else { 853 ++sampleCount; 854 } 855 } 856 if (mSamplesHaveSameSize) { 857 if (mSampleInfos.size() >= 2 && previousSampleSize != info.size) { 858 mSamplesHaveSameSize = false; 859 } 860 previousSampleSize = info.size; 861 } 862 lastDuration = info.timestamp - lastTimestamp; 863 lastTimestamp = info.timestamp; 864 865//////////////////////////////////////////////////////////////////////////////// 866 // Make a deep copy of the MediaBuffer less Metadata 867 MediaBuffer *copy = new MediaBuffer(buffer->range_length()); 868 memcpy(copy->data(), (uint8_t *)buffer->data() + buffer->range_offset(), 869 buffer->range_length()); 870 copy->set_range(0, buffer->range_length()); 871 872 mChunkSamples.push_back(copy); 873 if (interleaveDurationUs == 0) { 874 StscTableEntry stscEntry(++nChunks, 1, 1); 875 mStscTableEntries.push_back(stscEntry); 876 writeOneChunk(is_avc); 877 } else { 878 if (chunkTimestampUs == 0) { 879 chunkTimestampUs = timestampUs; 880 } else { 881 if (timestampUs - chunkTimestampUs > interleaveDurationUs) { 882 ++nChunks; 883 if (nChunks == 1 || // First chunk 884 (--(mStscTableEntries.end()))->samplesPerChunk != 885 mChunkSamples.size()) { 886 StscTableEntry stscEntry(nChunks, 887 mChunkSamples.size(), 1); 888 mStscTableEntries.push_back(stscEntry); 889 } 890 writeOneChunk(is_avc); 891 chunkTimestampUs = timestampUs; 892 } 893 } 894 } 895 896 int32_t isSync = false; 897 if (buffer->meta_data()->findInt32(kKeyIsSyncFrame, &isSync) && 898 isSync != 0) { 899 mStssTableEntries.push_back(mSampleInfos.size()); 900 } 901 902 buffer->release(); 903 buffer = NULL; 904 } 905 906 CHECK(!mSampleInfos.empty()); 907 908 // Last chunk 909 if (!mChunkSamples.empty()) { 910 ++nChunks; 911 StscTableEntry stscEntry(nChunks, mChunkSamples.size(), 1); 912 mStscTableEntries.push_back(stscEntry); 913 writeOneChunk(is_avc); 914 } 915 916 // We don't really know how long the last frame lasts, since 917 // there is no frame time after it, just repeat the previous 918 // frame's duration. 919 if (mSampleInfos.size() == 1) { 920 lastDuration = 0; // A single sample's duration 921 } else { 922 ++sampleCount; // Count for the last sample 923 } 924 SttsTableEntry sttsEntry(sampleCount, lastDuration); 925 mSttsTableEntries.push_back(sttsEntry); 926 mReachedEOS = true; 927 LOGI("Received total/0-length (%d/%d) buffers and encoded %d frames", 928 count, nZeroLengthFrames, mSampleInfos.size()); 929} 930 931void MPEG4Writer::Track::writeOneChunk(bool isAvc) { 932 mOwner->lock(); 933 for (List<MediaBuffer *>::iterator it = mChunkSamples.begin(); 934 it != mChunkSamples.end(); ++it) { 935 off_t offset = isAvc? mOwner->addLengthPrefixedSample_l(*it) 936 : mOwner->addSample_l(*it); 937 if (it == mChunkSamples.begin()) { 938 mChunkOffsets.push_back(offset); 939 } 940 } 941 mOwner->unlock(); 942 while (!mChunkSamples.empty()) { 943 List<MediaBuffer *>::iterator it = mChunkSamples.begin(); 944 (*it)->release(); 945 (*it) = NULL; 946 mChunkSamples.erase(it); 947 } 948 mChunkSamples.clear(); 949} 950 951int64_t MPEG4Writer::Track::getDurationUs() const { 952 return mMaxTimeStampUs; 953} 954 955int64_t MPEG4Writer::Track::getEstimatedTrackSizeBytes() const { 956 return mEstimatedTrackSizeBytes; 957} 958 959void MPEG4Writer::Track::writeTrackHeader(int32_t trackID) { 960 const char *mime; 961 bool success = mMeta->findCString(kKeyMIMEType, &mime); 962 CHECK(success); 963 964 bool is_audio = !strncasecmp(mime, "audio/", 6); 965 966 time_t now = time(NULL); 967 968 mOwner->beginBox("trak"); 969 970 mOwner->beginBox("tkhd"); 971 mOwner->writeInt32(0); // version=0, flags=0 972 mOwner->writeInt32(now); // creation time 973 mOwner->writeInt32(now); // modification time 974 mOwner->writeInt32(trackID); 975 mOwner->writeInt32(0); // reserved 976 mOwner->writeInt32(getDurationUs() / 1000); 977 mOwner->writeInt32(0); // reserved 978 mOwner->writeInt32(0); // reserved 979 mOwner->writeInt16(0); // layer 980 mOwner->writeInt16(0); // alternate group 981 mOwner->writeInt16(is_audio ? 0x100 : 0); // volume 982 mOwner->writeInt16(0); // reserved 983 984 mOwner->writeInt32(0x10000); // matrix 985 mOwner->writeInt32(0); 986 mOwner->writeInt32(0); 987 mOwner->writeInt32(0); 988 mOwner->writeInt32(0x10000); 989 mOwner->writeInt32(0); 990 mOwner->writeInt32(0); 991 mOwner->writeInt32(0); 992 mOwner->writeInt32(0x40000000); 993 994 if (is_audio) { 995 mOwner->writeInt32(0); 996 mOwner->writeInt32(0); 997 } else { 998 int32_t width, height; 999 bool success = mMeta->findInt32(kKeyWidth, &width); 1000 success = success && mMeta->findInt32(kKeyHeight, &height); 1001 CHECK(success); 1002 1003 mOwner->writeInt32(width << 16); // 32-bit fixed-point value 1004 mOwner->writeInt32(height << 16); // 32-bit fixed-point value 1005 } 1006 mOwner->endBox(); // tkhd 1007 1008 mOwner->beginBox("mdia"); 1009 1010 mOwner->beginBox("mdhd"); 1011 mOwner->writeInt32(0); // version=0, flags=0 1012 mOwner->writeInt32(now); // creation time 1013 mOwner->writeInt32(now); // modification time 1014 mOwner->writeInt32(1000); // timescale 1015 mOwner->writeInt32(getDurationUs() / 1000); 1016 mOwner->writeInt16(0); // language code XXX 1017 mOwner->writeInt16(0); // predefined 1018 mOwner->endBox(); 1019 1020 mOwner->beginBox("hdlr"); 1021 mOwner->writeInt32(0); // version=0, flags=0 1022 mOwner->writeInt32(0); // component type: should be mhlr 1023 mOwner->writeFourcc(is_audio ? "soun" : "vide"); // component subtype 1024 mOwner->writeInt32(0); // reserved 1025 mOwner->writeInt32(0); // reserved 1026 mOwner->writeInt32(0); // reserved 1027 mOwner->writeCString("SoundHandler"); // name 1028 mOwner->endBox(); 1029 1030 mOwner->beginBox("minf"); 1031 if (is_audio) { 1032 mOwner->beginBox("smhd"); 1033 mOwner->writeInt32(0); // version=0, flags=0 1034 mOwner->writeInt16(0); // balance 1035 mOwner->writeInt16(0); // reserved 1036 mOwner->endBox(); 1037 } else { 1038 mOwner->beginBox("vmhd"); 1039 mOwner->writeInt32(0x00000001); // version=0, flags=1 1040 mOwner->writeInt16(0); // graphics mode 1041 mOwner->writeInt16(0); // opcolor 1042 mOwner->writeInt16(0); 1043 mOwner->writeInt16(0); 1044 mOwner->endBox(); 1045 } 1046 1047 mOwner->beginBox("dinf"); 1048 mOwner->beginBox("dref"); 1049 mOwner->writeInt32(0); // version=0, flags=0 1050 mOwner->writeInt32(1); 1051 mOwner->beginBox("url "); 1052 mOwner->writeInt32(1); // version=0, flags=1 1053 mOwner->endBox(); // url 1054 mOwner->endBox(); // dref 1055 mOwner->endBox(); // dinf 1056 1057 mOwner->endBox(); // minf 1058 1059 mOwner->beginBox("stbl"); 1060 1061 mOwner->beginBox("stsd"); 1062 mOwner->writeInt32(0); // version=0, flags=0 1063 mOwner->writeInt32(1); // entry count 1064 if (is_audio) { 1065 const char *fourcc = NULL; 1066 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime)) { 1067 fourcc = "samr"; 1068 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) { 1069 fourcc = "sawb"; 1070 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) { 1071 fourcc = "mp4a"; 1072 } else { 1073 LOGE("Unknown mime type '%s'.", mime); 1074 CHECK(!"should not be here, unknown mime type."); 1075 } 1076 1077 mOwner->beginBox(fourcc); // audio format 1078 mOwner->writeInt32(0); // reserved 1079 mOwner->writeInt16(0); // reserved 1080 mOwner->writeInt16(0x1); // data ref index 1081 mOwner->writeInt32(0); // reserved 1082 mOwner->writeInt32(0); // reserved 1083 int32_t nChannels; 1084 CHECK_EQ(true, mMeta->findInt32(kKeyChannelCount, &nChannels)); 1085 mOwner->writeInt16(nChannels); // channel count 1086 mOwner->writeInt16(16); // sample size 1087 mOwner->writeInt16(0); // predefined 1088 mOwner->writeInt16(0); // reserved 1089 1090 int32_t samplerate; 1091 bool success = mMeta->findInt32(kKeySampleRate, &samplerate); 1092 CHECK(success); 1093 1094 mOwner->writeInt32(samplerate << 16); 1095 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) { 1096 mOwner->beginBox("esds"); 1097 1098 mOwner->writeInt32(0); // version=0, flags=0 1099 mOwner->writeInt8(0x03); // ES_DescrTag 1100 mOwner->writeInt8(23 + mCodecSpecificDataSize); 1101 mOwner->writeInt16(0x0000);// ES_ID 1102 mOwner->writeInt8(0x00); 1103 1104 mOwner->writeInt8(0x04); // DecoderConfigDescrTag 1105 mOwner->writeInt8(15 + mCodecSpecificDataSize); 1106 mOwner->writeInt8(0x40); // objectTypeIndication ISO/IEC 14492-2 1107 mOwner->writeInt8(0x15); // streamType AudioStream 1108 1109 mOwner->writeInt16(0x03); // XXX 1110 mOwner->writeInt8(0x00); // buffer size 24-bit 1111 mOwner->writeInt32(96000); // max bit rate 1112 mOwner->writeInt32(96000); // avg bit rate 1113 1114 mOwner->writeInt8(0x05); // DecoderSpecificInfoTag 1115 mOwner->writeInt8(mCodecSpecificDataSize); 1116 mOwner->write(mCodecSpecificData, mCodecSpecificDataSize); 1117 1118 static const uint8_t kData2[] = { 1119 0x06, // SLConfigDescriptorTag 1120 0x01, 1121 0x02 1122 }; 1123 mOwner->write(kData2, sizeof(kData2)); 1124 1125 mOwner->endBox(); // esds 1126 } 1127 mOwner->endBox(); 1128 } else { 1129 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { 1130 mOwner->beginBox("mp4v"); 1131 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { 1132 mOwner->beginBox("s263"); 1133 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) { 1134 mOwner->beginBox("avc1"); 1135 } else { 1136 LOGE("Unknown mime type '%s'.", mime); 1137 CHECK(!"should not be here, unknown mime type."); 1138 } 1139 1140 mOwner->writeInt32(0); // reserved 1141 mOwner->writeInt16(0); // reserved 1142 mOwner->writeInt16(0); // data ref index 1143 mOwner->writeInt16(0); // predefined 1144 mOwner->writeInt16(0); // reserved 1145 mOwner->writeInt32(0); // predefined 1146 mOwner->writeInt32(0); // predefined 1147 mOwner->writeInt32(0); // predefined 1148 1149 int32_t width, height; 1150 bool success = mMeta->findInt32(kKeyWidth, &width); 1151 success = success && mMeta->findInt32(kKeyHeight, &height); 1152 CHECK(success); 1153 1154 mOwner->writeInt16(width); 1155 mOwner->writeInt16(height); 1156 mOwner->writeInt32(0x480000); // horiz resolution 1157 mOwner->writeInt32(0x480000); // vert resolution 1158 mOwner->writeInt32(0); // reserved 1159 mOwner->writeInt16(1); // frame count 1160 mOwner->write(" ", 32); 1161 mOwner->writeInt16(0x18); // depth 1162 mOwner->writeInt16(-1); // predefined 1163 1164 CHECK(23 + mCodecSpecificDataSize < 128); 1165 1166 if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { 1167 mOwner->beginBox("esds"); 1168 1169 mOwner->writeInt32(0); // version=0, flags=0 1170 1171 mOwner->writeInt8(0x03); // ES_DescrTag 1172 mOwner->writeInt8(23 + mCodecSpecificDataSize); 1173 mOwner->writeInt16(0x0000); // ES_ID 1174 mOwner->writeInt8(0x1f); 1175 1176 mOwner->writeInt8(0x04); // DecoderConfigDescrTag 1177 mOwner->writeInt8(15 + mCodecSpecificDataSize); 1178 mOwner->writeInt8(0x20); // objectTypeIndication ISO/IEC 14492-2 1179 mOwner->writeInt8(0x11); // streamType VisualStream 1180 1181 static const uint8_t kData[] = { 1182 0x01, 0x77, 0x00, 1183 0x00, 0x03, 0xe8, 0x00, 1184 0x00, 0x03, 0xe8, 0x00 1185 }; 1186 mOwner->write(kData, sizeof(kData)); 1187 1188 mOwner->writeInt8(0x05); // DecoderSpecificInfoTag 1189 1190 mOwner->writeInt8(mCodecSpecificDataSize); 1191 mOwner->write(mCodecSpecificData, mCodecSpecificDataSize); 1192 1193 static const uint8_t kData2[] = { 1194 0x06, // SLConfigDescriptorTag 1195 0x01, 1196 0x02 1197 }; 1198 mOwner->write(kData2, sizeof(kData2)); 1199 1200 mOwner->endBox(); // esds 1201 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { 1202 mOwner->beginBox("d263"); 1203 1204 mOwner->writeInt32(0); // vendor 1205 mOwner->writeInt8(0); // decoder version 1206 mOwner->writeInt8(10); // level: 10 1207 mOwner->writeInt8(0); // profile: 0 1208 1209 mOwner->endBox(); // d263 1210 } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) { 1211 mOwner->beginBox("avcC"); 1212 mOwner->write(mCodecSpecificData, mCodecSpecificDataSize); 1213 mOwner->endBox(); // avcC 1214 } 1215 1216 mOwner->endBox(); // mp4v, s263 or avc1 1217 } 1218 mOwner->endBox(); // stsd 1219 1220 mOwner->beginBox("stts"); 1221 mOwner->writeInt32(0); // version=0, flags=0 1222 mOwner->writeInt32(mSttsTableEntries.size()); 1223 for (List<SttsTableEntry>::iterator it = mSttsTableEntries.begin(); 1224 it != mSttsTableEntries.end(); ++it) { 1225 mOwner->writeInt32(it->sampleCount); 1226 mOwner->writeInt32(it->sampleDuration); 1227 } 1228 mOwner->endBox(); // stts 1229 1230 if (!is_audio) { 1231 mOwner->beginBox("stss"); 1232 mOwner->writeInt32(0); // version=0, flags=0 1233 mOwner->writeInt32(mStssTableEntries.size()); // number of sync frames 1234 for (List<int32_t>::iterator it = mStssTableEntries.begin(); 1235 it != mStssTableEntries.end(); ++it) { 1236 mOwner->writeInt32(*it); 1237 } 1238 mOwner->endBox(); // stss 1239 } 1240 1241 mOwner->beginBox("stsz"); 1242 mOwner->writeInt32(0); // version=0, flags=0 1243 if (mSamplesHaveSameSize) { 1244 List<SampleInfo>::iterator it = mSampleInfos.begin(); 1245 mOwner->writeInt32(it->size); // default sample size 1246 } else { 1247 mOwner->writeInt32(0); 1248 } 1249 mOwner->writeInt32(mSampleInfos.size()); 1250 if (!mSamplesHaveSameSize) { 1251 for (List<SampleInfo>::iterator it = mSampleInfos.begin(); 1252 it != mSampleInfos.end(); ++it) { 1253 mOwner->writeInt32((*it).size); 1254 } 1255 } 1256 mOwner->endBox(); // stsz 1257 1258 mOwner->beginBox("stsc"); 1259 mOwner->writeInt32(0); // version=0, flags=0 1260 mOwner->writeInt32(mStscTableEntries.size()); 1261 for (List<StscTableEntry>::iterator it = mStscTableEntries.begin(); 1262 it != mStscTableEntries.end(); ++it) { 1263 mOwner->writeInt32(it->firstChunk); 1264 mOwner->writeInt32(it->samplesPerChunk); 1265 mOwner->writeInt32(it->sampleDescriptionId); 1266 } 1267 mOwner->endBox(); // stsc 1268 1269 mOwner->beginBox("co64"); 1270 mOwner->writeInt32(0); // version=0, flags=0 1271 mOwner->writeInt32(mChunkOffsets.size()); 1272 for (List<off_t>::iterator it = mChunkOffsets.begin(); 1273 it != mChunkOffsets.end(); ++it) { 1274 mOwner->writeInt64((*it)); 1275 } 1276 mOwner->endBox(); // co64 1277 1278 mOwner->endBox(); // stbl 1279 mOwner->endBox(); // mdia 1280 mOwner->endBox(); // trak 1281} 1282 1283} // namespace android 1284