summaryrefslogtreecommitdiffstats
path: root/cmds/stagefright/stagefright.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cmds/stagefright/stagefright.cpp')
-rw-r--r--cmds/stagefright/stagefright.cpp164
1 files changed, 143 insertions, 21 deletions
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index b838f32..4a1d27b 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -25,13 +25,14 @@
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
#include <media/IMediaPlayerService.h>
+#include <media/stagefright/foundation/ALooper.h>
+#include "include/ARTSPController.h"
#include <media/stagefright/AudioPlayer.h>
-#include <media/stagefright/CachingDataSource.h>
-#include <media/stagefright/FileSource.h>
-#include <media/stagefright/HTTPDataSource.h>
+#include <media/stagefright/DataSource.h>
#include <media/stagefright/JPEGSource.h>
#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MediaExtractor.h>
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/MetaData.h>
@@ -39,6 +40,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;
@@ -46,6 +50,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;
@@ -85,6 +91,7 @@ static void playSource(OMXClient *client, const sp<MediaSource> &source) {
if (gPlaybackAudio) {
AudioPlayer *player = new AudioPlayer(NULL);
player->setSource(rawSource);
+ rawSource.clear();
player->start(true /* sourceAlreadyStarted */);
@@ -95,6 +102,8 @@ static void playSource(OMXClient *client, const sp<MediaSource> &source) {
delete player;
player = NULL;
+
+ return;
} else if (gReproduceBug >= 3 && gReproduceBug <= 5) {
int64_t durationUs;
CHECK(meta->findInt64(kKeyDuration, &durationUs));
@@ -256,6 +265,77 @@ 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 performSeekTest(const sp<MediaSource> &source) {
+ CHECK_EQ(OK, source->start());
+
+ int64_t durationUs;
+ CHECK(source->getFormat()->findInt64(kKeyDuration, &durationUs));
+
+ for (int64_t seekTimeUs = 0; seekTimeUs <= durationUs;
+ seekTimeUs += 60000ll) {
+ MediaSource::ReadOptions options;
+ options.setSeekTo(
+ seekTimeUs, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
+
+ MediaBuffer *buffer;
+ status_t err;
+ for (;;) {
+ err = source->read(&buffer, &options);
+
+ options.clearSeekTo();
+
+ if (err == INFO_FORMAT_CHANGED) {
+ CHECK(buffer == NULL);
+ continue;
+ }
+
+ if (err != OK) {
+ CHECK(buffer == NULL);
+ break;
+ }
+
+ if (buffer->range_length() > 0) {
+ break;
+ }
+
+ CHECK(buffer != NULL);
+
+ buffer->release();
+ buffer = NULL;
+ }
+
+ if (err == OK) {
+ int64_t timeUs;
+ CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
+
+ printf("%lld\t%lld\t%lld\n", seekTimeUs, timeUs, seekTimeUs - timeUs);
+
+ buffer->release();
+ buffer = NULL;
+ } else {
+ printf("ERROR\n");
+ break;
+ }
+ }
+
+ CHECK_EQ(OK, source->stop());
+}
+
static void usage(const char *me) {
fprintf(stderr, "usage: %s\n", me);
fprintf(stderr, " -h(elp)\n");
@@ -268,6 +348,8 @@ 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");
+ fprintf(stderr, " -k seek test\n");
}
int main(int argc, char **argv) {
@@ -277,14 +359,19 @@ int main(int argc, char **argv) {
bool listComponents = false;
bool dumpProfiles = false;
bool extractThumbnail = false;
+ bool seekTest = false;
gNumRepetitions = 1;
gMaxNumFrames = 0;
gReproduceBug = -1;
gPreferSoftwareCodec = false;
gPlaybackAudio = false;
+ gWriteMP4 = false;
+
+ sp<ALooper> looper;
+ sp<ARTSPController> rtspController;
int res;
- while ((res = getopt(argc, argv, "han:lm:b:ptso")) >= 0) {
+ while ((res = getopt(argc, argv, "han:lm:b:ptsow:k")) >= 0) {
switch (res) {
case 'a':
{
@@ -320,6 +407,13 @@ int main(int argc, char **argv) {
break;
}
+ case 'w':
+ {
+ gWriteMP4 = true;
+ gWriteMP4Filename.setTo(optarg);
+ break;
+ }
+
case 'p':
{
dumpProfiles = true;
@@ -344,6 +438,12 @@ int main(int argc, char **argv) {
break;
}
+ case 'k':
+ {
+ seekTest = true;
+ break;
+ }
+
case '?':
case 'h':
default:
@@ -479,19 +579,10 @@ int main(int argc, char **argv) {
for (int k = 0; k < argc; ++k) {
const char *filename = argv[k];
- sp<DataSource> dataSource;
- if (!strncasecmp("http://", filename, 7)) {
- dataSource = new HTTPDataSource(filename);
- if (((HTTPDataSource *)dataSource.get())->connect() != OK) {
- fprintf(stderr, "failed to connect to HTTP server.\n");
- return -1;
- }
- dataSource = new CachingDataSource(dataSource, 32 * 1024, 20);
- } else {
- dataSource = new FileSource(filename);
- }
+ sp<DataSource> dataSource = DataSource::CreateFromURI(filename);
- if (dataSource == NULL) {
+ if ((strncasecmp(filename, "sine:", 5)
+ && strncasecmp(filename, "rtsp://", 7)) && dataSource == NULL) {
fprintf(stderr, "Unable to create data source.\n");
return 1;
}
@@ -516,10 +607,28 @@ int main(int argc, char **argv) {
}
mediaSource = new SineSource(sampleRate, 1);
} else {
- sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
- if (extractor == NULL) {
- fprintf(stderr, "could not create extractor.\n");
- return -1;
+ sp<MediaExtractor> extractor;
+
+ if (!strncasecmp("rtsp://", filename, 7)) {
+ if (looper == NULL) {
+ looper = new ALooper;
+ looper->start();
+ }
+
+ rtspController = new ARTSPController(looper);
+ status_t err = rtspController->connect(filename);
+ if (err != OK) {
+ fprintf(stderr, "could not connect to rtsp server.\n");
+ return -1;
+ }
+
+ extractor = rtspController.get();
+ } else {
+ extractor = MediaExtractor::Create(dataSource);
+ if (extractor == NULL) {
+ fprintf(stderr, "could not create extractor.\n");
+ return -1;
+ }
}
size_t numTracks = extractor->countTracks();
@@ -562,7 +671,20 @@ int main(int argc, char **argv) {
mediaSource = extractor->getTrack(i);
}
- playSource(&client, mediaSource);
+ if (gWriteMP4) {
+ writeSourceToMP4(mediaSource);
+ } else if (seekTest) {
+ performSeekTest(mediaSource);
+ } else {
+ playSource(&client, mediaSource);
+ }
+
+ if (rtspController != NULL) {
+ rtspController->disconnect();
+ rtspController.clear();
+
+ sleep(3);
+ }
}
client.disconnect();