MPEG4Writer.cpp revision e136c3bb38e88315bf8797a464ebf2c788296b22
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    int64_t mStartTimestampUs;
102
103    static void *ThreadWrapper(void *me);
104    void threadEntry();
105
106    status_t makeAVCCodecSpecificData(
107            const uint8_t *data, size_t size);
108    void writeOneChunk(bool isAvc);
109
110    Track(const Track &);
111    Track &operator=(const Track &);
112};
113
114#define USE_NALLEN_FOUR         1
115
116MPEG4Writer::MPEG4Writer(const char *filename)
117    : mFile(fopen(filename, "wb")),
118      mOffset(0),
119      mMdatOffset(0),
120      mEstimatedMoovBoxSize(0),
121      mInterleaveDurationUs(500000) {
122    CHECK(mFile != NULL);
123}
124
125MPEG4Writer::MPEG4Writer(int fd)
126    : mFile(fdopen(fd, "wb")),
127      mOffset(0),
128      mMdatOffset(0),
129      mEstimatedMoovBoxSize(0),
130      mInterleaveDurationUs(500000) {
131    CHECK(mFile != NULL);
132}
133
134MPEG4Writer::~MPEG4Writer() {
135    stop();
136
137    for (List<Track *>::iterator it = mTracks.begin();
138         it != mTracks.end(); ++it) {
139        delete *it;
140    }
141    mTracks.clear();
142}
143
144status_t MPEG4Writer::addSource(const sp<MediaSource> &source) {
145    Track *track = new Track(this, source);
146    mTracks.push_back(track);
147
148    return OK;
149}
150
151status_t MPEG4Writer::start() {
152    if (mFile == NULL) {
153        return UNKNOWN_ERROR;
154    }
155
156    mStartTimestampUs = 0;
157    mStreamableFile = true;
158    mWriteMoovBoxToMemory = false;
159    mMoovBoxBuffer = NULL;
160    mMoovBoxBufferOffset = 0;
161
162    beginBox("ftyp");
163      writeFourcc("isom");
164      writeInt32(0);
165      writeFourcc("isom");
166    endBox();
167
168    mFreeBoxOffset = mOffset;
169
170    if (mEstimatedMoovBoxSize == 0) {
171        // XXX: Estimate the moov box size
172        //      based on max file size or duration limit
173        mEstimatedMoovBoxSize = 0x0F00;
174    }
175    CHECK(mEstimatedMoovBoxSize >= 8);
176    fseeko(mFile, mFreeBoxOffset, SEEK_SET);
177    writeInt32(mEstimatedMoovBoxSize);
178    write("free", 4);
179
180    mMdatOffset = mFreeBoxOffset + mEstimatedMoovBoxSize;
181    mOffset = mMdatOffset;
182    fseeko(mFile, mMdatOffset, SEEK_SET);
183    write("\x00\x00\x00\x01mdat????????", 16);
184    for (List<Track *>::iterator it = mTracks.begin();
185         it != mTracks.end(); ++it) {
186        status_t err = (*it)->start();
187
188        if (err != OK) {
189            for (List<Track *>::iterator it2 = mTracks.begin();
190                 it2 != it; ++it2) {
191                (*it2)->stop();
192            }
193
194            return err;
195        }
196    }
197
198    return OK;
199}
200
201void MPEG4Writer::stop() {
202    if (mFile == NULL) {
203        return;
204    }
205
206    int64_t max_duration = 0;
207    for (List<Track *>::iterator it = mTracks.begin();
208         it != mTracks.end(); ++it) {
209        (*it)->stop();
210
211        int64_t duration = (*it)->getDurationUs();
212        if (duration > max_duration) {
213            max_duration = duration;
214        }
215    }
216
217
218    // Fix up the size of the 'mdat' chunk.
219    fseeko(mFile, mMdatOffset + 8, SEEK_SET);
220    int64_t size = mOffset - mMdatOffset;
221    size = hton64(size);
222    fwrite(&size, 1, 8, mFile);
223    fseeko(mFile, mOffset, SEEK_SET);
224
225    time_t now = time(NULL);
226    const off_t moovOffset = mOffset;
227    mWriteMoovBoxToMemory = true;
228    mMoovBoxBuffer = (uint8_t *) malloc(mEstimatedMoovBoxSize);
229    mMoovBoxBufferOffset = 0;
230    CHECK(mMoovBoxBuffer != NULL);
231
232    beginBox("moov");
233
234      beginBox("mvhd");
235        writeInt32(0);             // version=0, flags=0
236        writeInt32(now);           // creation time
237        writeInt32(now);           // modification time
238        writeInt32(1000);          // timescale
239        writeInt32(max_duration / 1000);
240        writeInt32(0x10000);       // rate
241        writeInt16(0x100);         // volume
242        writeInt16(0);             // reserved
243        writeInt32(0);             // reserved
244        writeInt32(0);             // reserved
245        writeInt32(0x10000);       // matrix
246        writeInt32(0);
247        writeInt32(0);
248        writeInt32(0);
249        writeInt32(0x10000);
250        writeInt32(0);
251        writeInt32(0);
252        writeInt32(0);
253        writeInt32(0x40000000);
254        writeInt32(0);             // predefined
255        writeInt32(0);             // predefined
256        writeInt32(0);             // predefined
257        writeInt32(0);             // predefined
258        writeInt32(0);             // predefined
259        writeInt32(0);             // predefined
260        writeInt32(mTracks.size() + 1);  // nextTrackID
261      endBox();  // mvhd
262
263      int32_t id = 1;
264      for (List<Track *>::iterator it = mTracks.begin();
265           it != mTracks.end(); ++it, ++id) {
266          (*it)->writeTrackHeader(id);
267      }
268    endBox();  // moov
269
270    mWriteMoovBoxToMemory = false;
271    if (mStreamableFile) {
272        CHECK(mMoovBoxBufferOffset + 8 <= mEstimatedMoovBoxSize);
273
274        // Moov box
275        fseeko(mFile, mFreeBoxOffset, SEEK_SET);
276        mOffset = mFreeBoxOffset;
277        write(mMoovBoxBuffer, 1, mMoovBoxBufferOffset, mFile);
278
279        // Free box
280        mFreeBoxOffset = mStreamableFile? mOffset: mFreeBoxOffset;
281        fseeko(mFile, mFreeBoxOffset, SEEK_SET);
282        writeInt32(mEstimatedMoovBoxSize - mMoovBoxBufferOffset);
283        write("free", 4);
284
285        // Free temp memory
286        free(mMoovBoxBuffer);
287        mMoovBoxBuffer = NULL;
288        mMoovBoxBufferOffset = 0;
289    }
290
291    CHECK(mBoxes.empty());
292
293    fflush(mFile);
294    fclose(mFile);
295    mFile = NULL;
296}
297
298status_t MPEG4Writer::setInterleaveDuration(uint32_t durationUs) {
299    mInterleaveDurationUs = durationUs;
300    return OK;
301}
302
303void MPEG4Writer::lock() {
304    mLock.lock();
305}
306
307void MPEG4Writer::unlock() {
308    mLock.unlock();
309}
310
311off_t MPEG4Writer::addSample_l(MediaBuffer *buffer) {
312    off_t old_offset = mOffset;
313
314    fwrite((const uint8_t *)buffer->data() + buffer->range_offset(),
315           1, buffer->range_length(), mFile);
316
317    mOffset += buffer->range_length();
318
319    return old_offset;
320}
321
322static void StripStartcode(MediaBuffer *buffer) {
323    if (buffer->range_length() < 4) {
324        return;
325    }
326
327    const uint8_t *ptr =
328        (const uint8_t *)buffer->data() + buffer->range_offset();
329
330    if (!memcmp(ptr, "\x00\x00\x00\x01", 4)) {
331        buffer->set_range(
332                buffer->range_offset() + 4, buffer->range_length() - 4);
333    }
334}
335
336off_t MPEG4Writer::addLengthPrefixedSample_l(MediaBuffer *buffer) {
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 = static_cast<int64_t>(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
503void MPEG4Writer::setStartTimestamp(int64_t timeUs) {
504    LOGI("setStartTimestamp: %lld", timeUs);
505    Mutex::Autolock autoLock(mLock);
506    if (mStartTimestampUs != 0) {
507        return;  // Sorry, too late
508    }
509    mStartTimestampUs = timeUs;
510}
511
512int64_t MPEG4Writer::getStartTimestamp() {
513    LOGI("getStartTimestamp: %lld", mStartTimestampUs);
514    Mutex::Autolock autoLock(mLock);
515    return mStartTimestampUs;
516}
517
518////////////////////////////////////////////////////////////////////////////////
519
520MPEG4Writer::Track::Track(
521        MPEG4Writer *owner, const sp<MediaSource> &source)
522    : mOwner(owner),
523      mMeta(source->getFormat()),
524      mSource(source),
525      mDone(false),
526      mMaxTimeStampUs(0),
527      mEstimatedTrackSizeBytes(0),
528      mSamplesHaveSameSize(true),
529      mCodecSpecificData(NULL),
530      mCodecSpecificDataSize(0),
531      mGotAllCodecSpecificData(false),
532      mReachedEOS(false) {
533}
534
535MPEG4Writer::Track::~Track() {
536    stop();
537
538    if (mCodecSpecificData != NULL) {
539        free(mCodecSpecificData);
540        mCodecSpecificData = NULL;
541    }
542}
543
544status_t MPEG4Writer::Track::start() {
545    status_t err = mSource->start();
546
547    if (err != OK) {
548        mDone = mReachedEOS = true;
549        return err;
550    }
551
552    pthread_attr_t attr;
553    pthread_attr_init(&attr);
554    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
555
556    mDone = false;
557    mMaxTimeStampUs = 0;
558    mReachedEOS = false;
559    mEstimatedTrackSizeBytes = 0;
560
561    pthread_create(&mThread, &attr, ThreadWrapper, this);
562    pthread_attr_destroy(&attr);
563
564    return OK;
565}
566
567void MPEG4Writer::Track::stop() {
568    if (mDone) {
569        return;
570    }
571
572    mDone = true;
573
574    void *dummy;
575    pthread_join(mThread, &dummy);
576
577    mSource->stop();
578}
579
580bool MPEG4Writer::Track::reachedEOS() {
581    return mReachedEOS;
582}
583
584// static
585void *MPEG4Writer::Track::ThreadWrapper(void *me) {
586    Track *track = static_cast<Track *>(me);
587
588    track->threadEntry();
589
590    return NULL;
591}
592
593#include <ctype.h>
594static void hexdump(const void *_data, size_t size) {
595    const uint8_t *data = (const uint8_t *)_data;
596    size_t offset = 0;
597    while (offset < size) {
598        printf("0x%04x  ", offset);
599
600        size_t n = size - offset;
601        if (n > 16) {
602            n = 16;
603        }
604
605        for (size_t i = 0; i < 16; ++i) {
606            if (i == 8) {
607                printf(" ");
608            }
609
610            if (offset + i < size) {
611                printf("%02x ", data[offset + i]);
612            } else {
613                printf("   ");
614            }
615        }
616
617        printf(" ");
618
619        for (size_t i = 0; i < n; ++i) {
620            if (isprint(data[offset + i])) {
621                printf("%c", data[offset + i]);
622            } else {
623                printf(".");
624            }
625        }
626
627        printf("\n");
628
629        offset += 16;
630    }
631}
632
633
634status_t MPEG4Writer::Track::makeAVCCodecSpecificData(
635        const uint8_t *data, size_t size) {
636    // hexdump(data, size);
637
638    if (mCodecSpecificData != NULL) {
639        LOGE("Already have codec specific data");
640        return ERROR_MALFORMED;
641    }
642
643    if (size < 4 || memcmp("\x00\x00\x00\x01", data, 4)) {
644        LOGE("Must start with a start code");
645        return ERROR_MALFORMED;
646    }
647
648    size_t picParamOffset = 4;
649    while (picParamOffset + 3 < size
650            && memcmp("\x00\x00\x00\x01", &data[picParamOffset], 4)) {
651        ++picParamOffset;
652    }
653
654    if (picParamOffset + 3 >= size) {
655        LOGE("Could not find start-code for pictureParameterSet");
656        return ERROR_MALFORMED;
657    }
658
659    size_t seqParamSetLength = picParamOffset - 4;
660    size_t picParamSetLength = size - picParamOffset - 4;
661
662    mCodecSpecificDataSize =
663        6 + 1 + seqParamSetLength + 2 + picParamSetLength + 2;
664
665    mCodecSpecificData = malloc(mCodecSpecificDataSize);
666    uint8_t *header = (uint8_t *)mCodecSpecificData;
667    header[0] = 1;
668    header[1] = 0x42;  // profile
669    header[2] = 0x80;
670    header[3] = 0x1e;  // level
671
672#if USE_NALLEN_FOUR
673    header[4] = 0xfc | 3;  // length size == 4 bytes
674#else
675    header[4] = 0xfc | 1;  // length size == 2 bytes
676#endif
677
678    header[5] = 0xe0 | 1;
679    header[6] = seqParamSetLength >> 8;
680    header[7] = seqParamSetLength & 0xff;
681    memcpy(&header[8], &data[4], seqParamSetLength);
682    header += 8 + seqParamSetLength;
683    header[0] = 1;
684    header[1] = picParamSetLength >> 8;
685    header[2] = picParamSetLength & 0xff;
686    memcpy(&header[3], &data[picParamOffset + 4], picParamSetLength);
687
688    return OK;
689}
690
691void MPEG4Writer::Track::threadEntry() {
692    sp<MetaData> meta = mSource->getFormat();
693    const char *mime;
694    meta->findCString(kKeyMIMEType, &mime);
695    bool is_mpeg4 = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) ||
696                    !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC);
697    bool is_avc = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
698    bool is_audio = !strncasecmp(mime, "audio/", 6);
699    int32_t count = 0;
700    const int64_t interleaveDurationUs = mOwner->interleaveDuration();
701    int64_t chunkTimestampUs = 0;
702    int32_t nChunks = 0;
703    int32_t nZeroLengthFrames = 0;
704    int64_t lastTimestamp = 0;  // Timestamp of the previous sample
705    int64_t lastDuration = 0;   // Time spacing between the previous two samples
706    int32_t sampleCount = 1;    // Sample count in the current stts table entry
707    uint32_t previousSampleSize = 0;  // Size of the previous sample
708
709    MediaBuffer *buffer;
710    while (!mDone && mSource->read(&buffer) == OK) {
711        if (buffer->range_length() == 0) {
712            buffer->release();
713            buffer = NULL;
714            ++nZeroLengthFrames;
715            continue;
716        }
717
718        ++count;
719
720        int32_t isCodecConfig;
721        if (buffer->meta_data()->findInt32(kKeyIsCodecConfig, &isCodecConfig)
722                && isCodecConfig) {
723            CHECK(!mGotAllCodecSpecificData);
724
725            if (is_avc) {
726                status_t err = makeAVCCodecSpecificData(
727                        (const uint8_t *)buffer->data()
728                            + buffer->range_offset(),
729                        buffer->range_length());
730                CHECK_EQ(OK, err);
731            } else if (is_mpeg4) {
732                mCodecSpecificDataSize = buffer->range_length();
733                mCodecSpecificData = malloc(mCodecSpecificDataSize);
734                memcpy(mCodecSpecificData,
735                        (const uint8_t *)buffer->data()
736                            + buffer->range_offset(),
737                       buffer->range_length());
738            }
739
740            buffer->release();
741            buffer = NULL;
742
743            mGotAllCodecSpecificData = true;
744            continue;
745        } else if (!mGotAllCodecSpecificData &&
746                count == 1 && is_mpeg4 && mCodecSpecificData == NULL) {
747            // The TI mpeg4 encoder does not properly set the
748            // codec-specific-data flag.
749
750            const uint8_t *data =
751                (const uint8_t *)buffer->data() + buffer->range_offset();
752
753            const size_t size = buffer->range_length();
754
755            size_t offset = 0;
756            while (offset + 3 < size) {
757                if (data[offset] == 0x00 && data[offset + 1] == 0x00
758                    && data[offset + 2] == 0x01 && data[offset + 3] == 0xb6) {
759                    break;
760                }
761
762                ++offset;
763            }
764
765            // CHECK(offset + 3 < size);
766            if (offset + 3 >= size) {
767                // XXX assume the entire first chunk of data is the codec specific
768                // data.
769                offset = size;
770            }
771
772            mCodecSpecificDataSize = offset;
773            mCodecSpecificData = malloc(offset);
774            memcpy(mCodecSpecificData, data, offset);
775
776            buffer->set_range(buffer->range_offset() + offset, size - offset);
777
778            if (size == offset) {
779                buffer->release();
780                buffer = NULL;
781
782                continue;
783            }
784
785            mGotAllCodecSpecificData = true;
786        } else if (!mGotAllCodecSpecificData && is_avc && count < 3) {
787            // The TI video encoder does not flag codec specific data
788            // as such and also splits up SPS and PPS across two buffers.
789
790            const uint8_t *data =
791                (const uint8_t *)buffer->data() + buffer->range_offset();
792
793            size_t size = buffer->range_length();
794
795            CHECK(count == 2 || mCodecSpecificData == NULL);
796
797            size_t offset = mCodecSpecificDataSize;
798            mCodecSpecificDataSize += size + 4;
799            mCodecSpecificData =
800                realloc(mCodecSpecificData, mCodecSpecificDataSize);
801
802            memcpy((uint8_t *)mCodecSpecificData + offset,
803                   "\x00\x00\x00\x01", 4);
804
805            memcpy((uint8_t *)mCodecSpecificData + offset + 4, data, size);
806
807            buffer->release();
808            buffer = NULL;
809
810            if (count == 2) {
811                void *tmp = mCodecSpecificData;
812                size = mCodecSpecificDataSize;
813                mCodecSpecificData = NULL;
814                mCodecSpecificDataSize = 0;
815
816                status_t err = makeAVCCodecSpecificData(
817                        (const uint8_t *)tmp, size);
818                free(tmp);
819                tmp = NULL;
820                CHECK_EQ(OK, err);
821
822                mGotAllCodecSpecificData = true;
823            }
824
825            continue;
826        }
827
828        if (is_avc) StripStartcode(buffer);
829
830        SampleInfo info;
831        info.size = is_avc
832#if USE_NALLEN_FOUR
833                ? buffer->range_length() + 4
834#else
835                ? buffer->range_length() + 2
836#endif
837                : buffer->range_length();
838
839        // Max file size or duration handling
840        mEstimatedTrackSizeBytes += info.size;
841        if (mOwner->exceedsFileSizeLimit()) {
842            buffer->release();
843            buffer = NULL;
844            mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED, 0);
845            break;
846        }
847        if (mOwner->exceedsFileDurationLimit()) {
848            buffer->release();
849            buffer = NULL;
850            mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_DURATION_REACHED, 0);
851            break;
852        }
853
854
855        int64_t timestampUs;
856        CHECK(buffer->meta_data()->findInt64(kKeyTime, &timestampUs));
857        if (mSampleInfos.empty()) {
858            mOwner->setStartTimestamp(timestampUs);
859            mStartTimestampUs = (timestampUs - mOwner->getStartTimestamp());
860        }
861
862        if (timestampUs > mMaxTimeStampUs) {
863            mMaxTimeStampUs = timestampUs;
864        }
865
866        // Our timestamp is in ms.
867        info.timestamp = (timestampUs + 500) / 1000;
868        mSampleInfos.push_back(info);
869        if (mSampleInfos.size() > 2) {
870            if (lastDuration != info.timestamp - lastTimestamp) {
871                SttsTableEntry sttsEntry(sampleCount, lastDuration);
872                mSttsTableEntries.push_back(sttsEntry);
873                sampleCount = 1;
874            } else {
875                ++sampleCount;
876            }
877        }
878        if (mSamplesHaveSameSize) {
879            if (mSampleInfos.size() >= 2 && previousSampleSize != info.size) {
880                mSamplesHaveSameSize = false;
881            }
882            previousSampleSize = info.size;
883        }
884        lastDuration = info.timestamp - lastTimestamp;
885        lastTimestamp = info.timestamp;
886
887////////////////////////////////////////////////////////////////////////////////
888        // Make a deep copy of the MediaBuffer less Metadata
889        MediaBuffer *copy = new MediaBuffer(buffer->range_length());
890        memcpy(copy->data(), (uint8_t *)buffer->data() + buffer->range_offset(),
891                buffer->range_length());
892        copy->set_range(0, buffer->range_length());
893
894        mChunkSamples.push_back(copy);
895        if (interleaveDurationUs == 0) {
896            StscTableEntry stscEntry(++nChunks, 1, 1);
897            mStscTableEntries.push_back(stscEntry);
898            writeOneChunk(is_avc);
899        } else {
900            if (chunkTimestampUs == 0) {
901                chunkTimestampUs = timestampUs;
902            } else {
903                if (timestampUs - chunkTimestampUs > interleaveDurationUs) {
904                    ++nChunks;
905                    if (nChunks == 1 ||  // First chunk
906                        (--(mStscTableEntries.end()))->samplesPerChunk !=
907                         mChunkSamples.size()) {
908                        StscTableEntry stscEntry(nChunks,
909                                mChunkSamples.size(), 1);
910                        mStscTableEntries.push_back(stscEntry);
911                    }
912                    writeOneChunk(is_avc);
913                    chunkTimestampUs = timestampUs;
914                }
915            }
916        }
917
918        int32_t isSync = false;
919        if (buffer->meta_data()->findInt32(kKeyIsSyncFrame, &isSync) &&
920            isSync != 0) {
921            mStssTableEntries.push_back(mSampleInfos.size());
922        }
923
924        buffer->release();
925        buffer = NULL;
926    }
927
928    if (mSampleInfos.empty()) {
929        mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_STOP_PREMATURELY, 0);
930    }
931
932    // Last chunk
933    if (!mChunkSamples.empty()) {
934        ++nChunks;
935        StscTableEntry stscEntry(nChunks, mChunkSamples.size(), 1);
936        mStscTableEntries.push_back(stscEntry);
937        writeOneChunk(is_avc);
938    }
939
940    // We don't really know how long the last frame lasts, since
941    // there is no frame time after it, just repeat the previous
942    // frame's duration.
943    if (mSampleInfos.size() == 1) {
944        lastDuration = 0;  // A single sample's duration
945    } else {
946        ++sampleCount;  // Count for the last sample
947    }
948    SttsTableEntry sttsEntry(sampleCount, lastDuration);
949    mSttsTableEntries.push_back(sttsEntry);
950    mReachedEOS = true;
951    LOGI("Received total/0-length (%d/%d) buffers and encoded %d frames - %s",
952            count, nZeroLengthFrames, mSampleInfos.size(), is_audio? "audio": "video");
953}
954
955void MPEG4Writer::Track::writeOneChunk(bool isAvc) {
956    mOwner->lock();
957    for (List<MediaBuffer *>::iterator it = mChunkSamples.begin();
958         it != mChunkSamples.end(); ++it) {
959        off_t offset = isAvc? mOwner->addLengthPrefixedSample_l(*it)
960                            : mOwner->addSample_l(*it);
961        if (it == mChunkSamples.begin()) {
962            mChunkOffsets.push_back(offset);
963        }
964    }
965    mOwner->unlock();
966    while (!mChunkSamples.empty()) {
967        List<MediaBuffer *>::iterator it = mChunkSamples.begin();
968        (*it)->release();
969        (*it) = NULL;
970        mChunkSamples.erase(it);
971    }
972    mChunkSamples.clear();
973}
974
975int64_t MPEG4Writer::Track::getDurationUs() const {
976    return mMaxTimeStampUs;
977}
978
979int64_t MPEG4Writer::Track::getEstimatedTrackSizeBytes() const {
980    return mEstimatedTrackSizeBytes;
981}
982
983void MPEG4Writer::Track::writeTrackHeader(int32_t trackID) {
984    const char *mime;
985    bool success = mMeta->findCString(kKeyMIMEType, &mime);
986    CHECK(success);
987
988    bool is_audio = !strncasecmp(mime, "audio/", 6);
989
990    time_t now = time(NULL);
991
992    mOwner->beginBox("trak");
993
994      mOwner->beginBox("tkhd");
995        mOwner->writeInt32(0);             // version=0, flags=0
996        mOwner->writeInt32(now);           // creation time
997        mOwner->writeInt32(now);           // modification time
998        mOwner->writeInt32(trackID);
999        mOwner->writeInt32(0);             // reserved
1000        mOwner->writeInt32(getDurationUs() / 1000);
1001        mOwner->writeInt32(0);             // reserved
1002        mOwner->writeInt32(0);             // reserved
1003        mOwner->writeInt16(0);             // layer
1004        mOwner->writeInt16(0);             // alternate group
1005        mOwner->writeInt16(is_audio ? 0x100 : 0);  // volume
1006        mOwner->writeInt16(0);             // reserved
1007
1008        mOwner->writeInt32(0x10000);       // matrix
1009        mOwner->writeInt32(0);
1010        mOwner->writeInt32(0);
1011        mOwner->writeInt32(0);
1012        mOwner->writeInt32(0x10000);
1013        mOwner->writeInt32(0);
1014        mOwner->writeInt32(0);
1015        mOwner->writeInt32(0);
1016        mOwner->writeInt32(0x40000000);
1017
1018        if (is_audio) {
1019            mOwner->writeInt32(0);
1020            mOwner->writeInt32(0);
1021        } else {
1022            int32_t width, height;
1023            bool success = mMeta->findInt32(kKeyWidth, &width);
1024            success = success && mMeta->findInt32(kKeyHeight, &height);
1025            CHECK(success);
1026
1027            mOwner->writeInt32(width << 16);   // 32-bit fixed-point value
1028            mOwner->writeInt32(height << 16);  // 32-bit fixed-point value
1029        }
1030      mOwner->endBox();  // tkhd
1031
1032      if (mStartTimestampUs != 0) {
1033        mOwner->beginBox("edts");
1034          mOwner->writeInt32(0);             // version=0, flags=0
1035          mOwner->beginBox("elst");
1036            mOwner->writeInt32(0);           // version=0, flags=0
1037            mOwner->writeInt32(1);           // a single entry
1038            mOwner->writeInt32(mStartTimestampUs / 1000);  // edit duration
1039            mOwner->writeInt32(-1);          // empty edit box to signal starting time offset
1040            mOwner->writeInt32(1);           // x1 rate
1041          mOwner->endBox();
1042        mOwner->endBox();
1043      }
1044
1045      mOwner->beginBox("mdia");
1046
1047        mOwner->beginBox("mdhd");
1048          mOwner->writeInt32(0);             // version=0, flags=0
1049          mOwner->writeInt32(now);           // creation time
1050          mOwner->writeInt32(now);           // modification time
1051          mOwner->writeInt32(1000);          // timescale
1052          mOwner->writeInt32(getDurationUs() / 1000);
1053          mOwner->writeInt16(0);             // language code XXX
1054          mOwner->writeInt16(0);             // predefined
1055        mOwner->endBox();
1056
1057        mOwner->beginBox("hdlr");
1058          mOwner->writeInt32(0);             // version=0, flags=0
1059          mOwner->writeInt32(0);             // component type: should be mhlr
1060          mOwner->writeFourcc(is_audio ? "soun" : "vide");  // component subtype
1061          mOwner->writeInt32(0);             // reserved
1062          mOwner->writeInt32(0);             // reserved
1063          mOwner->writeInt32(0);             // reserved
1064          mOwner->writeCString(is_audio ? "SoundHandler": "");  // name
1065        mOwner->endBox();
1066
1067        mOwner->beginBox("minf");
1068          if (is_audio) {
1069              mOwner->beginBox("smhd");
1070              mOwner->writeInt32(0);           // version=0, flags=0
1071              mOwner->writeInt16(0);           // balance
1072              mOwner->writeInt16(0);           // reserved
1073              mOwner->endBox();
1074          } else {
1075              mOwner->beginBox("vmhd");
1076              mOwner->writeInt32(0x00000001);  // version=0, flags=1
1077              mOwner->writeInt16(0);           // graphics mode
1078              mOwner->writeInt16(0);           // opcolor
1079              mOwner->writeInt16(0);
1080              mOwner->writeInt16(0);
1081              mOwner->endBox();
1082          }
1083
1084          mOwner->beginBox("dinf");
1085            mOwner->beginBox("dref");
1086              mOwner->writeInt32(0);  // version=0, flags=0
1087              mOwner->writeInt32(1);
1088              mOwner->beginBox("url ");
1089                mOwner->writeInt32(1);  // version=0, flags=1
1090              mOwner->endBox();  // url
1091            mOwner->endBox();  // dref
1092          mOwner->endBox();  // dinf
1093
1094       mOwner->endBox();  // minf
1095
1096        mOwner->beginBox("stbl");
1097
1098          mOwner->beginBox("stsd");
1099            mOwner->writeInt32(0);               // version=0, flags=0
1100            mOwner->writeInt32(1);               // entry count
1101            if (is_audio) {
1102                const char *fourcc = NULL;
1103                if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime)) {
1104                    fourcc = "samr";
1105                } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) {
1106                    fourcc = "sawb";
1107                } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
1108                    fourcc = "mp4a";
1109                } else {
1110                    LOGE("Unknown mime type '%s'.", mime);
1111                    CHECK(!"should not be here, unknown mime type.");
1112                }
1113
1114                mOwner->beginBox(fourcc);          // audio format
1115                  mOwner->writeInt32(0);           // reserved
1116                  mOwner->writeInt16(0);           // reserved
1117                  mOwner->writeInt16(0x1);         // data ref index
1118                  mOwner->writeInt32(0);           // reserved
1119                  mOwner->writeInt32(0);           // reserved
1120                  int32_t nChannels;
1121                  CHECK_EQ(true, mMeta->findInt32(kKeyChannelCount, &nChannels));
1122                  mOwner->writeInt16(nChannels);   // channel count
1123                  mOwner->writeInt16(16);          // sample size
1124                  mOwner->writeInt16(0);           // predefined
1125                  mOwner->writeInt16(0);           // reserved
1126
1127                  int32_t samplerate;
1128                  bool success = mMeta->findInt32(kKeySampleRate, &samplerate);
1129                  CHECK(success);
1130
1131                  mOwner->writeInt32(samplerate << 16);
1132                  if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
1133                    mOwner->beginBox("esds");
1134
1135                        mOwner->writeInt32(0);     // version=0, flags=0
1136                        mOwner->writeInt8(0x03);   // ES_DescrTag
1137                        mOwner->writeInt8(23 + mCodecSpecificDataSize);
1138                        mOwner->writeInt16(0x0000);// ES_ID
1139                        mOwner->writeInt8(0x00);
1140
1141                        mOwner->writeInt8(0x04);   // DecoderConfigDescrTag
1142                        mOwner->writeInt8(15 + mCodecSpecificDataSize);
1143                        mOwner->writeInt8(0x40);   // objectTypeIndication ISO/IEC 14492-2
1144                        mOwner->writeInt8(0x15);   // streamType AudioStream
1145
1146                        mOwner->writeInt16(0x03);  // XXX
1147                        mOwner->writeInt8(0x00);   // buffer size 24-bit
1148                        mOwner->writeInt32(96000); // max bit rate
1149                        mOwner->writeInt32(96000); // avg bit rate
1150
1151                        mOwner->writeInt8(0x05);   // DecoderSpecificInfoTag
1152                        mOwner->writeInt8(mCodecSpecificDataSize);
1153                        mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
1154
1155                        static const uint8_t kData2[] = {
1156                            0x06,  // SLConfigDescriptorTag
1157                            0x01,
1158                            0x02
1159                        };
1160                        mOwner->write(kData2, sizeof(kData2));
1161
1162                    mOwner->endBox();  // esds
1163                  }
1164                mOwner->endBox();
1165            } else {
1166                if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
1167                    mOwner->beginBox("mp4v");
1168                } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
1169                    mOwner->beginBox("s263");
1170                } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
1171                    mOwner->beginBox("avc1");
1172                } else {
1173                    LOGE("Unknown mime type '%s'.", mime);
1174                    CHECK(!"should not be here, unknown mime type.");
1175                }
1176
1177                  mOwner->writeInt32(0);           // reserved
1178                  mOwner->writeInt16(0);           // reserved
1179                  mOwner->writeInt16(0);           // data ref index
1180                  mOwner->writeInt16(0);           // predefined
1181                  mOwner->writeInt16(0);           // reserved
1182                  mOwner->writeInt32(0);           // predefined
1183                  mOwner->writeInt32(0);           // predefined
1184                  mOwner->writeInt32(0);           // predefined
1185
1186                  int32_t width, height;
1187                  bool success = mMeta->findInt32(kKeyWidth, &width);
1188                  success = success && mMeta->findInt32(kKeyHeight, &height);
1189                  CHECK(success);
1190
1191                  mOwner->writeInt16(width);
1192                  mOwner->writeInt16(height);
1193                  mOwner->writeInt32(0x480000);    // horiz resolution
1194                  mOwner->writeInt32(0x480000);    // vert resolution
1195                  mOwner->writeInt32(0);           // reserved
1196                  mOwner->writeInt16(1);           // frame count
1197                  mOwner->write("                                ", 32);
1198                  mOwner->writeInt16(0x18);        // depth
1199                  mOwner->writeInt16(-1);          // predefined
1200
1201                  CHECK(23 + mCodecSpecificDataSize < 128);
1202
1203                  if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
1204                      mOwner->beginBox("esds");
1205
1206                        mOwner->writeInt32(0);           // version=0, flags=0
1207
1208                        mOwner->writeInt8(0x03);  // ES_DescrTag
1209                        mOwner->writeInt8(23 + mCodecSpecificDataSize);
1210                        mOwner->writeInt16(0x0000);  // ES_ID
1211                        mOwner->writeInt8(0x1f);
1212
1213                        mOwner->writeInt8(0x04);  // DecoderConfigDescrTag
1214                        mOwner->writeInt8(15 + mCodecSpecificDataSize);
1215                        mOwner->writeInt8(0x20);  // objectTypeIndication ISO/IEC 14492-2
1216                        mOwner->writeInt8(0x11);  // streamType VisualStream
1217
1218                        static const uint8_t kData[] = {
1219                            0x01, 0x77, 0x00,
1220                            0x00, 0x03, 0xe8, 0x00,
1221                            0x00, 0x03, 0xe8, 0x00
1222                        };
1223                        mOwner->write(kData, sizeof(kData));
1224
1225                        mOwner->writeInt8(0x05);  // DecoderSpecificInfoTag
1226
1227                        mOwner->writeInt8(mCodecSpecificDataSize);
1228                        mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
1229
1230                        static const uint8_t kData2[] = {
1231                            0x06,  // SLConfigDescriptorTag
1232                            0x01,
1233                            0x02
1234                        };
1235                        mOwner->write(kData2, sizeof(kData2));
1236
1237                      mOwner->endBox();  // esds
1238                  } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
1239                      mOwner->beginBox("d263");
1240
1241                          mOwner->writeInt32(0);  // vendor
1242                          mOwner->writeInt8(0);   // decoder version
1243                          mOwner->writeInt8(10);  // level: 10
1244                          mOwner->writeInt8(0);   // profile: 0
1245
1246                      mOwner->endBox();  // d263
1247                  } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
1248                      mOwner->beginBox("avcC");
1249                        mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
1250                      mOwner->endBox();  // avcC
1251                  }
1252
1253                mOwner->endBox();  // mp4v, s263 or avc1
1254            }
1255          mOwner->endBox();  // stsd
1256
1257          mOwner->beginBox("stts");
1258            mOwner->writeInt32(0);  // version=0, flags=0
1259            mOwner->writeInt32(mSttsTableEntries.size());
1260            for (List<SttsTableEntry>::iterator it = mSttsTableEntries.begin();
1261                 it != mSttsTableEntries.end(); ++it) {
1262                mOwner->writeInt32(it->sampleCount);
1263                mOwner->writeInt32(it->sampleDuration);
1264            }
1265          mOwner->endBox();  // stts
1266
1267          if (!is_audio) {
1268            mOwner->beginBox("stss");
1269              mOwner->writeInt32(0);  // version=0, flags=0
1270              mOwner->writeInt32(mStssTableEntries.size());  // number of sync frames
1271              for (List<int32_t>::iterator it = mStssTableEntries.begin();
1272                   it != mStssTableEntries.end(); ++it) {
1273                  mOwner->writeInt32(*it);
1274              }
1275            mOwner->endBox();  // stss
1276          }
1277
1278          mOwner->beginBox("stsz");
1279            mOwner->writeInt32(0);  // version=0, flags=0
1280            if (mSamplesHaveSameSize) {
1281                List<SampleInfo>::iterator it = mSampleInfos.begin();
1282                mOwner->writeInt32(it->size);  // default sample size
1283            } else {
1284                mOwner->writeInt32(0);
1285            }
1286            mOwner->writeInt32(mSampleInfos.size());
1287            if (!mSamplesHaveSameSize) {
1288                for (List<SampleInfo>::iterator it = mSampleInfos.begin();
1289                     it != mSampleInfos.end(); ++it) {
1290                    mOwner->writeInt32((*it).size);
1291                }
1292            }
1293          mOwner->endBox();  // stsz
1294
1295          mOwner->beginBox("stsc");
1296            mOwner->writeInt32(0);  // version=0, flags=0
1297            mOwner->writeInt32(mStscTableEntries.size());
1298            for (List<StscTableEntry>::iterator it = mStscTableEntries.begin();
1299                 it != mStscTableEntries.end(); ++it) {
1300                mOwner->writeInt32(it->firstChunk);
1301                mOwner->writeInt32(it->samplesPerChunk);
1302                mOwner->writeInt32(it->sampleDescriptionId);
1303            }
1304          mOwner->endBox();  // stsc
1305
1306          mOwner->beginBox("co64");
1307            mOwner->writeInt32(0);  // version=0, flags=0
1308            mOwner->writeInt32(mChunkOffsets.size());
1309            for (List<off_t>::iterator it = mChunkOffsets.begin();
1310                 it != mChunkOffsets.end(); ++it) {
1311                mOwner->writeInt64((*it));
1312            }
1313          mOwner->endBox();  // co64
1314
1315        mOwner->endBox();  // stbl
1316      mOwner->endBox();  // mdia
1317    mOwner->endBox();  // trak
1318}
1319
1320}  // namespace android
1321