Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 96faa25f authored by Chong Zhang's avatar Chong Zhang Committed by Android (Google) Code Review
Browse files

Merge "MPEG4Writer: add capture fps in meta data"

parents 17af1192 e76dba7a
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@

namespace android {

class AMessage;
class MediaBuffer;
class MediaSource;
class MetaData;
@@ -48,6 +49,7 @@ public:
    virtual status_t dump(int fd, const Vector<String16>& args);

    void beginBox(const char *fourcc);
    void beginBox(uint32_t id);
    void writeInt8(int8_t x);
    void writeInt16(int16_t x);
    void writeInt32(int32_t x);
@@ -62,6 +64,7 @@ public:
    int32_t getTimeScale() const { return mTimeScale; }

    status_t setGeoData(int latitudex10000, int longitudex10000);
    status_t setCaptureRate(float captureFps);
    virtual void setStartTimeOffsetMs(int ms) { mStartTimeOffsetMs = ms; }
    virtual int32_t getStartTimeOffsetMs() const { return mStartTimeOffsetMs; }

@@ -102,6 +105,8 @@ private:

    List<off64_t> mBoxes;

    sp<AMessage> mMetaKeys;

    void setStartTimestampUs(int64_t timeUs);
    int64_t getStartTimestampUs();  // Not const
    status_t startTracks(MetaData *params);
@@ -195,6 +200,10 @@ private:
    void writeGeoDataBox();
    void writeLatitude(int degreex10000);
    void writeLongitude(int degreex10000);
    void writeHdlr();
    void writeKeys();
    void writeIlst();
    void writeMetaBox();
    void sendSessionSummary();
    void release();
    status_t reset();
+9 −5
Original line number Diff line number Diff line
@@ -1581,10 +1581,11 @@ status_t StagefrightRecorder::setupMPEG4orWEBMRecording() {

    status_t err = OK;
    sp<MediaWriter> writer;
    sp<MPEG4Writer> mp4writer;
    if (mOutputFormat == OUTPUT_FORMAT_WEBM) {
        writer = new WebmWriter(mOutputFd);
    } else {
        writer = new MPEG4Writer(mOutputFd);
        writer = mp4writer = new MPEG4Writer(mOutputFd);
    }

    if (mVideoSource < VIDEO_SOURCE_LIST_END) {
@@ -1617,13 +1618,16 @@ status_t StagefrightRecorder::setupMPEG4orWEBMRecording() {
            mTotalBitRate += mAudioBitRate;
        }

        if (mCaptureTimeLapse) {
            // TODO(chz): pass down fps in float from MediaRecorder.java
            mp4writer->setCaptureRate(1000000.0f / mTimeBetweenTimeLapseFrameCaptureUs);
        }

        if (mInterleaveDurationUs > 0) {
            reinterpret_cast<MPEG4Writer *>(writer.get())->
                setInterleaveDuration(mInterleaveDurationUs);
            mp4writer->setInterleaveDuration(mInterleaveDurationUs);
        }
        if (mLongitudex10000 > -3600000 && mLatitudex10000 > -3600000) {
            reinterpret_cast<MPEG4Writer *>(writer.get())->
                setGeoData(mLatitudex10000, mLongitudex10000);
            mp4writer->setGeoData(mLatitudex10000, mLongitudex10000);
        }
    }
    if (mMaxFileDurationUs != 0) {
+110 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#include <utils/Log.h>

#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/MPEG4Writer.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MetaData.h>
@@ -362,6 +363,7 @@ MPEG4Writer::MPEG4Writer(int fd)
      mLatitudex10000(0),
      mLongitudex10000(0),
      mAreGeoTagsAvailable(false),
      mMetaKeys(new AMessage()),
      mStartTimeOffsetMs(-1) {
}

@@ -946,6 +948,7 @@ void MPEG4Writer::writeMoovBox(int64_t durationUs) {
    if (mAreGeoTagsAvailable) {
        writeUdtaBox();
    }
    writeMetaBox();
    int32_t id = 1;
    for (List<Track *>::iterator it = mTracks.begin();
        it != mTracks.end(); ++it, ++id) {
@@ -1115,6 +1118,14 @@ size_t MPEG4Writer::write(
    return bytes;
}

void MPEG4Writer::beginBox(uint32_t id) {
    mBoxes.push_back(mWriteMoovBoxToMemory?
            mMoovBoxBufferOffset: mOffset);

    writeInt32(0);
    writeInt32(id);
}

void MPEG4Writer::beginBox(const char *fourcc) {
    CHECK_EQ(strlen(fourcc), 4);

@@ -1242,6 +1253,15 @@ status_t MPEG4Writer::setGeoData(int latitudex10000, int longitudex10000) {
    return OK;
}

status_t MPEG4Writer::setCaptureRate(float captureFps) {
    if (captureFps <= 0.0f) {
        return BAD_VALUE;
    }

    mMetaKeys->setFloat("com.android.capture.fps", captureFps);
    return OK;
}

void MPEG4Writer::write(const void *data, size_t size) {
    write(data, 1, size);
}
@@ -3070,6 +3090,96 @@ void MPEG4Writer::writeUdtaBox() {
    endBox();
}

void MPEG4Writer::writeHdlr() {
    beginBox("hdlr");
    writeInt32(0); // Version, Flags
    writeInt32(0); // Predefined
    writeFourcc("mdta");
    writeInt32(0); // Reserved[0]
    writeInt32(0); // Reserved[1]
    writeInt32(0); // Reserved[2]
    writeInt8(0);  // Name (empty)
    endBox();
}

void MPEG4Writer::writeKeys() {
    size_t count = mMetaKeys->countEntries();

    beginBox("keys");
    writeInt32(0);     // Version, Flags
    writeInt32(count); // Entry_count
    for (size_t i = 0; i < count; i++) {
        AMessage::Type type;
        const char *key = mMetaKeys->getEntryNameAt(i, &type);
        size_t n = strlen(key);
        writeInt32(n + 8);
        writeFourcc("mdta");
        write(key, n); // write without the \0
    }
    endBox();
}

void MPEG4Writer::writeIlst() {
    size_t count = mMetaKeys->countEntries();

    // meta data key types
    static const int32_t kKeyType_BE32Float = 23;
    static const int32_t kKeyType_BE32SignedInteger = 67;
    static const int32_t kKeyType_BE32UnsignedInteger = 77;

    beginBox("ilst");
    for (size_t i = 0; i < count; i++) {
        beginBox(i + 1); // key id (1-based)
        beginBox("data");
        AMessage::Type type;
        const char *key = mMetaKeys->getEntryNameAt(i, &type);
        switch (type) {
            case AMessage::kTypeFloat:
            {
                float val;
                CHECK(mMetaKeys->findFloat(key, &val));
                writeInt32(kKeyType_BE32Float);
                writeInt32(*reinterpret_cast<int32_t *>(&val));
                break;
            }

            case AMessage::kTypeInt32:
            {
                int32_t val;
                CHECK(mMetaKeys->findInt32(key, &val));
                writeInt32(kKeyType_BE32SignedInteger);
                writeInt32(val);
                break;
            }

            default:
            {
                ALOGW("Unsupported key type, writing 0 instead");
                writeInt32(kKeyType_BE32UnsignedInteger);
                writeInt32(0);
                break;
            }
        }
        endBox(); // data
        endBox(); // key id
    }
    endBox(); // ilst
}

void MPEG4Writer::writeMetaBox() {
    size_t count = mMetaKeys->countEntries();
    if (count == 0) {
        return;
    }

    beginBox("meta");
    writeHdlr();
    writeKeys();
    writeIlst();
    endBox();
}


/*
 * Geodata is stored according to ISO-6709 standard.
 */