diff options
Diffstat (limited to 'cmds/stagefright/stagefright.cpp')
-rw-r--r-- | cmds/stagefright/stagefright.cpp | 164 |
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(); |