summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmds/stagefright/muxer.cpp15
-rw-r--r--include/media/stagefright/MediaMuxer.h14
-rw-r--r--media/libstagefright/MediaMuxer.cpp48
3 files changed, 58 insertions, 19 deletions
diff --git a/cmds/stagefright/muxer.cpp b/cmds/stagefright/muxer.cpp
index fac2acc..cca33e0 100644
--- a/cmds/stagefright/muxer.cpp
+++ b/cmds/stagefright/muxer.cpp
@@ -55,7 +55,8 @@ static int muxing(
const char *outputFileName,
bool enableTrim,
int trimStartTimeMs,
- int trimEndTimeMs) {
+ int trimEndTimeMs,
+ int rotationDegrees) {
sp<NuMediaExtractor> extractor = new NuMediaExtractor;
if (extractor->setDataSource(path) != OK) {
fprintf(stderr, "unable to instantiate extractor. %s\n", path);
@@ -141,6 +142,7 @@ static int muxing(
size_t trackIndex = -1;
sp<ABuffer> newBuffer = new ABuffer(bufferSize);
+ muxer->setOrientationHint(rotationDegrees);
muxer->start();
while (!sawInputEOS) {
@@ -210,12 +212,13 @@ int main(int argc, char **argv) {
char *outputFileName = NULL;
int trimStartTimeMs = -1;
int trimEndTimeMs = -1;
+ int rotationDegrees = 0;
// When trimStartTimeMs and trimEndTimeMs seems valid, we turn this switch
// to true.
bool enableTrim = false;
int res;
- while ((res = getopt(argc, argv, "h?avo:s:e:")) >= 0) {
+ while ((res = getopt(argc, argv, "h?avo:s:e:r:")) >= 0) {
switch (res) {
case 'a':
{
@@ -247,6 +250,12 @@ int main(int argc, char **argv) {
break;
}
+ case 'r':
+ {
+ rotationDegrees = atoi(optarg);
+ break;
+ }
+
case '?':
case 'h':
default:
@@ -288,7 +297,7 @@ int main(int argc, char **argv) {
looper->start();
int result = muxing(looper, argv[0], useAudio, useVideo, outputFileName,
- enableTrim, trimStartTimeMs, trimEndTimeMs);
+ enableTrim, trimStartTimeMs, trimEndTimeMs, rotationDegrees);
looper->stop();
diff --git a/include/media/stagefright/MediaMuxer.h b/include/media/stagefright/MediaMuxer.h
index 167d0d9..fad319f 100644
--- a/include/media/stagefright/MediaMuxer.h
+++ b/include/media/stagefright/MediaMuxer.h
@@ -77,11 +77,20 @@ public:
status_t start();
/**
+ * Set the orientation hint.
+ * @param degrees The rotation degrees. It has to be either 0,
+ * 90, 180 or 270.
+ * @return OK if no error.
+ */
+ status_t setOrientationHint(int degrees);
+
+ /**
* Stop muxing.
* This method is a blocking call. Depending on how
* much data is bufferred internally, the time needed for stopping
* the muxer may be time consuming. UI thread is
* not recommended for launching this call.
+ * @return OK if no error.
*/
status_t stop();
@@ -104,12 +113,13 @@ public:
private:
sp<MPEG4Writer> mWriter;
Vector< sp<MediaAdapter> > mTrackList; // Each track has its MediaAdapter.
+ sp<MetaData> mFileMeta; // Metadata for the whole file.
Mutex mMuxerLock;
enum State {
- UNINITED,
- INITED,
+ UNINITIALIZED,
+ INITIALIZED,
STARTED,
STOPPED
};
diff --git a/media/libstagefright/MediaMuxer.cpp b/media/libstagefright/MediaMuxer.cpp
index 21841b3..b948fe2 100644
--- a/media/libstagefright/MediaMuxer.cpp
+++ b/media/libstagefright/MediaMuxer.cpp
@@ -36,18 +36,21 @@
namespace android {
MediaMuxer::MediaMuxer(const char *path, OutputFormat format)
- : mState(UNINITED) {
+ : mState(UNINITIALIZED) {
if (format == OUTPUT_FORMAT_MPEG_4) {
mWriter = new MPEG4Writer(path);
- mState = INITED;
+ mFileMeta = new MetaData;
+ mState = INITIALIZED;
}
+
}
MediaMuxer::MediaMuxer(int fd, OutputFormat format)
- : mState(UNINITED) {
+ : mState(UNINITIALIZED) {
if (format == OUTPUT_FORMAT_MPEG_4) {
mWriter = new MPEG4Writer(fd);
- mState = INITED;
+ mFileMeta = new MetaData;
+ mState = INITIALIZED;
}
}
@@ -55,6 +58,7 @@ MediaMuxer::~MediaMuxer() {
Mutex::Autolock autoLock(mMuxerLock);
// Clean up all the internal resources.
+ mFileMeta.clear();
mWriter.clear();
mTrackList.clear();
}
@@ -67,15 +71,15 @@ ssize_t MediaMuxer::addTrack(const sp<AMessage> &format) {
return -EINVAL;
}
- if (mState != INITED) {
+ if (mState != INITIALIZED) {
ALOGE("addTrack() must be called after constructor and before start().");
return INVALID_OPERATION;
}
- sp<MetaData> meta = new MetaData;
- convertMessageToMetaData(format, meta);
+ sp<MetaData> trackMeta = new MetaData;
+ convertMessageToMetaData(format, trackMeta);
- sp<MediaAdapter> newTrack = new MediaAdapter(meta);
+ sp<MediaAdapter> newTrack = new MediaAdapter(trackMeta);
status_t result = mWriter->addSource(newTrack);
if (result == OK) {
return mTrackList.add(newTrack);
@@ -83,11 +87,27 @@ ssize_t MediaMuxer::addTrack(const sp<AMessage> &format) {
return -1;
}
+status_t MediaMuxer::setOrientationHint(int degrees) {
+ Mutex::Autolock autoLock(mMuxerLock);
+ if (mState != INITIALIZED) {
+ ALOGE("setOrientationHint() must be called before start().");
+ return INVALID_OPERATION;
+ }
+
+ if (degrees != 0 && degrees != 90 && degrees != 180 && degrees != 270) {
+ ALOGE("setOrientationHint() get invalid degrees");
+ return -EINVAL;
+ }
+
+ mFileMeta->setInt32(kKeyRotation, degrees);
+ return OK;
+}
+
status_t MediaMuxer::start() {
Mutex::Autolock autoLock(mMuxerLock);
- if (mState == INITED) {
+ if (mState == INITIALIZED) {
mState = STARTED;
- return mWriter->start();
+ return mWriter->start(mFileMeta.get());
} else {
ALOGE("start() is called in invalid state %d", mState);
return INVALID_OPERATION;
@@ -135,13 +155,13 @@ status_t MediaMuxer::writeSampleData(const sp<ABuffer> &buffer, size_t trackInde
mediaBuffer->add_ref(); // Released in MediaAdapter::signalBufferReturned().
mediaBuffer->set_range(buffer->offset(), buffer->size());
- sp<MetaData> metaData = mediaBuffer->meta_data();
- metaData->setInt64(kKeyTime, timeUs);
+ sp<MetaData> sampleMetaData = mediaBuffer->meta_data();
+ sampleMetaData->setInt64(kKeyTime, timeUs);
// Just set the kKeyDecodingTime as the presentation time for now.
- metaData->setInt64(kKeyDecodingTime, timeUs);
+ sampleMetaData->setInt64(kKeyDecodingTime, timeUs);
if (flags & SAMPLE_FLAG_SYNC) {
- metaData->setInt32(kKeyIsSyncFrame, true);
+ sampleMetaData->setInt32(kKeyIsSyncFrame, true);
}
sp<MediaAdapter> currentTrack = mTrackList[trackIndex];