am 45bac57a: Support for writing the extracted data to an .mp4 file in the stagefright commandline tool.

Merge commit '45bac57aa00281e6b45756c691c588bdaf762521' into gingerbread-plus-aosp

* commit '45bac57aa00281e6b45756c691c588bdaf762521':
  Support for writing the extracted data to an .mp4 file in the stagefright commandline tool.
This commit is contained in:
Andreas Huber
2010-07-01 10:07:17 -07:00
committed by Android Git Automerger
4 changed files with 80 additions and 5 deletions

View File

@@ -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) \

View File

@@ -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();

View File

@@ -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;

View File

@@ -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;