Loading include/media/stagefright/MPEG4Writer.h +9 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ namespace android { class AMessage; class MediaBuffer; class MediaSource; class MetaData; Loading @@ -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); Loading @@ -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; } Loading Loading @@ -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); Loading Loading @@ -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(); Loading media/libmediaplayerservice/StagefrightRecorder.cpp +9 −5 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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) { Loading media/libstagefright/MPEG4Writer.cpp +110 −0 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -362,6 +363,7 @@ MPEG4Writer::MPEG4Writer(int fd) mLatitudex10000(0), mLongitudex10000(0), mAreGeoTagsAvailable(false), mMetaKeys(new AMessage()), mStartTimeOffsetMs(-1) { } Loading Loading @@ -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) { Loading Loading @@ -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); Loading Loading @@ -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); } Loading Loading @@ -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. */ Loading Loading
include/media/stagefright/MPEG4Writer.h +9 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ namespace android { class AMessage; class MediaBuffer; class MediaSource; class MetaData; Loading @@ -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); Loading @@ -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; } Loading Loading @@ -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); Loading Loading @@ -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(); Loading
media/libmediaplayerservice/StagefrightRecorder.cpp +9 −5 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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) { Loading
media/libstagefright/MPEG4Writer.cpp +110 −0 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -362,6 +363,7 @@ MPEG4Writer::MPEG4Writer(int fd) mLatitudex10000(0), mLongitudex10000(0), mAreGeoTagsAvailable(false), mMetaKeys(new AMessage()), mStartTimeOffsetMs(-1) { } Loading Loading @@ -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) { Loading Loading @@ -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); Loading Loading @@ -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); } Loading Loading @@ -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. */ Loading