diff options
author | Chong Zhang <chz@google.com> | 2015-02-18 16:06:29 -0800 |
---|---|---|
committer | Chong Zhang <chz@google.com> | 2015-02-23 13:59:09 -0800 |
commit | e76dba7af9589d9ed7b116eec3a74168a8352925 (patch) | |
tree | 72e7b80fdae4639095997418c83d7f53701b203f /media | |
parent | 07aed75a681793474487e7e5e100d21c2f31de9c (diff) | |
download | frameworks_av-e76dba7af9589d9ed7b116eec3a74168a8352925.zip frameworks_av-e76dba7af9589d9ed7b116eec3a74168a8352925.tar.gz frameworks_av-e76dba7af9589d9ed7b116eec3a74168a8352925.tar.bz2 |
MPEG4Writer: add capture fps in meta data
bug: 19460202
Change-Id: I3a6ea3a5149d124ca9a2487a300dcc2db4405d0f
Diffstat (limited to 'media')
-rw-r--r-- | media/libmediaplayerservice/StagefrightRecorder.cpp | 14 | ||||
-rw-r--r-- | media/libstagefright/MPEG4Writer.cpp | 110 |
2 files changed, 119 insertions, 5 deletions
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp index 2551040..887d4ec 100644 --- a/media/libmediaplayerservice/StagefrightRecorder.cpp +++ b/media/libmediaplayerservice/StagefrightRecorder.cpp @@ -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) { diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp index beb6f20..774ac08 100644 --- a/media/libstagefright/MPEG4Writer.cpp +++ b/media/libstagefright/MPEG4Writer.cpp @@ -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. */ |