diff options
| -rw-r--r-- | cmds/stagefright/Android.mk | 2 | ||||
| -rw-r--r-- | cmds/stagefright/stagefright.cpp | 37 | ||||
| -rw-r--r-- | include/media/stagefright/MediaWriter.h | 5 | ||||
| -rw-r--r-- | media/libstagefright/MPEG4Writer.cpp | 41 |
4 files changed, 80 insertions, 5 deletions
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk index 33696f4eae5c..9a972841460a 100644 --- a/cmds/stagefright/Android.mk +++ b/cmds/stagefright/Android.mk @@ -7,7 +7,7 @@ LOCAL_SRC_FILES:= \ SineSource.cpp LOCAL_SHARED_LIBRARIES := \ - libstagefright libmedia libutils libbinder + libstagefright libmedia libutils libbinder libstagefright_foundation LOCAL_C_INCLUDES:= \ $(JNI_H_INCLUDE) \ diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp index 877b90878d68..b7a3f99fd833 100644 --- a/cmds/stagefright/stagefright.cpp +++ b/cmds/stagefright/stagefright.cpp @@ -38,6 +38,9 @@ #include <media/stagefright/OMXCodec.h> #include <media/mediametadataretriever.h> +#include <media/stagefright/foundation/hexdump.h> +#include <media/stagefright/MPEG4Writer.h> + using namespace android; static long gNumRepetitions; @@ -45,6 +48,8 @@ static long gMaxNumFrames; // 0 means decode all available. static long gReproduceBug; // if not -1. static bool gPreferSoftwareCodec; static bool gPlaybackAudio; +static bool gWriteMP4; +static String8 gWriteMP4Filename; static int64_t getNowUs() { struct timeval tv; @@ -258,6 +263,21 @@ static void playSource(OMXClient *client, const sp<MediaSource> &source) { } } +static void writeSourceToMP4(const sp<MediaSource> &source) { + sp<MPEG4Writer> writer = + new MPEG4Writer(gWriteMP4Filename.string()); + + CHECK_EQ(writer->addSource(source), OK); + + sp<MetaData> params = new MetaData; + CHECK_EQ(writer->start(), OK); + + while (!writer->reachedEOS()) { + usleep(100000); + } + writer->stop(); +} + static void usage(const char *me) { fprintf(stderr, "usage: %s\n", me); fprintf(stderr, " -h(elp)\n"); @@ -270,6 +290,7 @@ static void usage(const char *me) { fprintf(stderr, " -t(humbnail) extract video thumbnail or album art\n"); fprintf(stderr, " -s(oftware) prefer software codec\n"); fprintf(stderr, " -o playback audio\n"); + fprintf(stderr, " -w(rite) filename (write to .mp4 file)\n"); } int main(int argc, char **argv) { @@ -284,9 +305,10 @@ int main(int argc, char **argv) { gReproduceBug = -1; gPreferSoftwareCodec = false; gPlaybackAudio = false; + gWriteMP4 = false; int res; - while ((res = getopt(argc, argv, "han:lm:b:ptso")) >= 0) { + while ((res = getopt(argc, argv, "han:lm:b:ptsow:")) >= 0) { switch (res) { case 'a': { @@ -322,6 +344,13 @@ int main(int argc, char **argv) { break; } + case 'w': + { + gWriteMP4 = true; + gWriteMP4Filename.setTo(optarg); + break; + } + case 'p': { dumpProfiles = true; @@ -554,7 +583,11 @@ int main(int argc, char **argv) { mediaSource = extractor->getTrack(i); } - playSource(&client, mediaSource); + if (gWriteMP4) { + writeSourceToMP4(mediaSource); + } else { + playSource(&client, mediaSource); + } } client.disconnect(); diff --git a/include/media/stagefright/MediaWriter.h b/include/media/stagefright/MediaWriter.h index e91d066c04f6..8d3a9df39302 100644 --- a/include/media/stagefright/MediaWriter.h +++ b/include/media/stagefright/MediaWriter.h @@ -27,7 +27,10 @@ struct MediaSource; struct MetaData; struct MediaWriter : public RefBase { - MediaWriter() {} + MediaWriter() + : mMaxFileSizeLimitBytes(0), + mMaxFileDurationLimitUs(0) { + } virtual status_t addSource(const sp<MediaSource> &source) = 0; virtual bool reachedEOS() = 0; diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp index a52c88850320..6a4a13118bc2 100644 --- a/media/libstagefright/MPEG4Writer.cpp +++ b/media/libstagefright/MPEG4Writer.cpp @@ -34,6 +34,8 @@ #include <media/mediarecorder.h> #include <cutils/properties.h> +#include "include/ESDS.h" + namespace android { class MPEG4Writer::Track { @@ -126,6 +128,8 @@ private: int32_t *min, int32_t *avg, int32_t *max); void findMinMaxChunkDurations(int64_t *min, int64_t *max); + void getCodecSpecificDataFromInputFormatIfPossible(); + Track(const Track &); Track &operator=(const Track &); }; @@ -678,6 +682,38 @@ MPEG4Writer::Track::Track( mCodecSpecificDataSize(0), mGotAllCodecSpecificData(false), mReachedEOS(false) { + getCodecSpecificDataFromInputFormatIfPossible(); +} + +void MPEG4Writer::Track::getCodecSpecificDataFromInputFormatIfPossible() { + const char *mime; + CHECK(mMeta->findCString(kKeyMIMEType, &mime)); + + if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { + uint32_t type; + const void *data; + size_t size; + if (mMeta->findData(kKeyAVCC, &type, &data, &size)) { + mCodecSpecificData = malloc(size); + mCodecSpecificDataSize = size; + memcpy(mCodecSpecificData, data, size); + mGotAllCodecSpecificData = true; + } + } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) + || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { + uint32_t type; + const void *data; + size_t size; + if (mMeta->findData(kKeyESDS, &type, &data, &size)) { + ESDS esds(data, size); + if (esds.getCodecSpecificInfo(&data, &size) == OK) { + mCodecSpecificData = malloc(size); + mCodecSpecificDataSize = size; + memcpy(mCodecSpecificData, data, size); + mGotAllCodecSpecificData = true; + } + } + } } MPEG4Writer::Track::~Track() { @@ -721,7 +757,10 @@ status_t MPEG4Writer::Track::start(MetaData *params) { } int64_t startTimeUs; - CHECK(params && params->findInt64(kKeyTime, &startTimeUs)); + if (params == NULL || !params->findInt64(kKeyTime, &startTimeUs)) { + startTimeUs = 0; + } + initTrackingProgressStatus(params); sp<MetaData> meta = new MetaData; |