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, &timestampUs));
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