stagefright.cpp revision 2df788fb0c402938f827bf9c9ce2ca3ab1dcd464
120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/* 220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project 320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License. 620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at 720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software 1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and 1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License. 1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */ 1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber//#define LOG_NDEBUG 0 18bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber#define LOG_TAG "stagefright" 19bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber#include <media/stagefright/foundation/ADebug.h> 20bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 2120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <sys/time.h> 2220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdlib.h> 242d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber#include <string.h> 252d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber#include <unistd.h> 2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber#include "SineSource.h" 28a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <binder/IServiceManager.h> 3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <binder/ProcessState.h> 3120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/IMediaPlayerService.h> 32348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber#include <media/stagefright/foundation/ALooper.h> 33348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber#include "include/ARTSPController.h" 34a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include "include/LiveSession.h" 35ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber#include "include/NuCachedSource2.h" 36a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber#include <media/stagefright/AudioPlayer.h> 371c70247536457f7b7fa84daa3482bd3d3b44e225Andreas Huber#include <media/stagefright/DataSource.h> 38777893a928680f09e306b4b9efc1d5cf4479a9daAndreas Huber#include <media/stagefright/JPEGSource.h> 3918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h> 401c70247536457f7b7fa84daa3482bd3d3b44e225Andreas Huber#include <media/stagefright/MediaErrors.h> 4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaExtractor.h> 4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaSource.h> 4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h> 4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/OMXClient.h> 45693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/OMXCodec.h> 465c1e3581978164d169050686c73810ce59304471Andreas Huber#include <media/mediametadataretriever.h> 4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4819c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber#include <media/stagefright/foundation/hexdump.h> 490da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber#include <media/stagefright/MPEG2TSWriter.h> 5019c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber#include <media/stagefright/MPEG4Writer.h> 5119c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber 52f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber#include <private/media/VideoFrame.h> 53f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber#include <SkBitmap.h> 54f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber#include <SkImageEncoder.h> 55f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber 56bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber#include <fcntl.h> 57bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 58c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber#include <gui/SurfaceTextureClient.h> 59c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber 60c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber#include <surfaceflinger/ISurfaceComposer.h> 61c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber#include <surfaceflinger/SurfaceComposerClient.h> 62c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber 6320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberusing namespace android; 6420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 652d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huberstatic long gNumRepetitions; 6638b610fe53bb27946826d3f175f6fbe613f270daAndreas Huberstatic long gMaxNumFrames; // 0 means decode all available. 6780011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huberstatic long gReproduceBug; // if not -1. 685c1e3581978164d169050686c73810ce59304471Andreas Huberstatic bool gPreferSoftwareCodec; 69cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dongstatic bool gForceToUseHardwareCodec; 70a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huberstatic bool gPlaybackAudio; 7119c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huberstatic bool gWriteMP4; 72fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huberstatic bool gDisplayHistogram; 7319c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huberstatic String8 gWriteMP4Filename; 7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 75c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huberstatic sp<ANativeWindow> gSurface; 76c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber 7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic int64_t getNowUs() { 7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber struct timeval tv; 7920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber gettimeofday(&tv, NULL); 8020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81d2858f047b2c52d719719532f24899c0e03c2099Andreas Huber return (int64_t)tv.tv_usec + tv.tv_sec * 1000000ll; 8220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 8320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 84fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huberstatic int CompareIncreasing(const int64_t *a, const int64_t *b) { 85fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber return (*a) < (*b) ? -1 : (*a) > (*b) ? 1 : 0; 86fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber} 87fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 88fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huberstatic void displayDecodeHistogram(Vector<int64_t> *decodeTimesUs) { 89fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber printf("decode times:\n"); 90fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 91fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber decodeTimesUs->sort(CompareIncreasing); 92fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 93fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber size_t n = decodeTimesUs->size(); 94fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber int64_t minUs = decodeTimesUs->itemAt(0); 95fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber int64_t maxUs = decodeTimesUs->itemAt(n - 1); 96fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 97fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber printf("min decode time %lld us (%.2f secs)\n", minUs, minUs / 1E6); 98fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber printf("max decode time %lld us (%.2f secs)\n", maxUs, maxUs / 1E6); 99fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 100fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber size_t counts[100]; 101fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber for (size_t i = 0; i < 100; ++i) { 102fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber counts[i] = 0; 103fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber } 104fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 105fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber for (size_t i = 0; i < n; ++i) { 106fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber int64_t x = decodeTimesUs->itemAt(i); 107fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 108fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber size_t slot = ((x - minUs) * 100) / (maxUs - minUs); 109fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber if (slot == 100) { slot = 99; } 110fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 111fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber ++counts[slot]; 112fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber } 113fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 114fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber for (size_t i = 0; i < 100; ++i) { 115fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber int64_t slotUs = minUs + (i * (maxUs - minUs) / 100); 116fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 117fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber double fps = 1E6 / slotUs; 118fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber printf("[%.2f fps]: %d\n", fps, counts[i]); 119fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber } 120fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber} 121fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 1228a674dcc94936e2306121016ab258b4c00cc9d98James Dongstatic void displayAVCProfileLevelIfPossible(const sp<MetaData>& meta) { 1238a674dcc94936e2306121016ab258b4c00cc9d98James Dong uint32_t type; 1248a674dcc94936e2306121016ab258b4c00cc9d98James Dong const void *data; 1258a674dcc94936e2306121016ab258b4c00cc9d98James Dong size_t size; 1268a674dcc94936e2306121016ab258b4c00cc9d98James Dong if (meta->findData(kKeyAVCC, &type, &data, &size)) { 1278a674dcc94936e2306121016ab258b4c00cc9d98James Dong const uint8_t *ptr = (const uint8_t *)data; 1288a674dcc94936e2306121016ab258b4c00cc9d98James Dong CHECK(size >= 7); 1298a674dcc94936e2306121016ab258b4c00cc9d98James Dong CHECK(ptr[0] == 1); // configurationVersion == 1 1308a674dcc94936e2306121016ab258b4c00cc9d98James Dong uint8_t profile = ptr[1]; 1318a674dcc94936e2306121016ab258b4c00cc9d98James Dong uint8_t level = ptr[3]; 1328a674dcc94936e2306121016ab258b4c00cc9d98James Dong fprintf(stderr, "AVC video profile %d and level %d\n", profile, level); 1338a674dcc94936e2306121016ab258b4c00cc9d98James Dong } 1348a674dcc94936e2306121016ab258b4c00cc9d98James Dong} 1358a674dcc94936e2306121016ab258b4c00cc9d98James Dong 136c225da975515892952602cd3b1e24efc0cceaa4dAndreas Huberstatic void playSource(OMXClient *client, sp<MediaSource> &source) { 137693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<MetaData> meta = source->getFormat(); 138693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 139125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber const char *mime; 140125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 141125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber 142125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber sp<MediaSource> rawSource; 143125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_RAW, mime)) { 144125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber rawSource = source; 145125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber } else { 146cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong int flags = 0; 147cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong if (gPreferSoftwareCodec) { 148cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong flags |= OMXCodec::kPreferSoftwareCodecs; 149cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong } 150cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong if (gForceToUseHardwareCodec) { 151cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong CHECK(!gPreferSoftwareCodec); 152cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong flags |= OMXCodec::kHardwareCodecsOnly; 153cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong } 154125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber rawSource = OMXCodec::Create( 1555c1e3581978164d169050686c73810ce59304471Andreas Huber client->interface(), meta, false /* createEncoder */, source, 1565c1e3581978164d169050686c73810ce59304471Andreas Huber NULL /* matchComponentName */, 157cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong flags, 158c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber gSurface); 159693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 160125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber if (rawSource == NULL) { 161125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber fprintf(stderr, "Failed to instantiate decoder for '%s'.\n", mime); 162125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber return; 163125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber } 1648a674dcc94936e2306121016ab258b4c00cc9d98James Dong displayAVCProfileLevelIfPossible(meta); 165693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber } 166693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 167c225da975515892952602cd3b1e24efc0cceaa4dAndreas Huber source.clear(); 168c225da975515892952602cd3b1e24efc0cceaa4dAndreas Huber 169139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber status_t err = rawSource->start(); 170139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber 171139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber if (err != OK) { 172139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber fprintf(stderr, "rawSource returned error %d (0x%08x)\n", err, err); 173139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber return; 174139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber } 175693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 176a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber if (gPlaybackAudio) { 177a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber AudioPlayer *player = new AudioPlayer(NULL); 178a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber player->setSource(rawSource); 17964105f956f15969dbe1ec7319f6caa2a984e588bAndreas Huber rawSource.clear(); 180a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 181a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber player->start(true /* sourceAlreadyStarted */); 182a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 183a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber status_t finalStatus; 184a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber while (!player->reachedEOS(&finalStatus)) { 185a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber usleep(100000ll); 186a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber } 187a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 188a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber delete player; 189a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber player = NULL; 19064105f956f15969dbe1ec7319f6caa2a984e588bAndreas Huber 19164105f956f15969dbe1ec7319f6caa2a984e588bAndreas Huber return; 192a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber } else if (gReproduceBug >= 3 && gReproduceBug <= 5) { 193bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber int64_t durationUs; 194bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber CHECK(meta->findInt64(kKeyDuration, &durationUs)); 195bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 1965228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber status_t err; 1975228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber MediaBuffer *buffer; 1985228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber MediaSource::ReadOptions options; 1995228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber int64_t seekTimeUs = -1; 2005228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber for (;;) { 201125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber err = rawSource->read(&buffer, &options); 2025228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber options.clearSeekTo(); 2035228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2045228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber bool shouldSeek = false; 2057f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber if (err == INFO_FORMAT_CHANGED) { 206bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber CHECK(buffer == NULL); 2077f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber 2087f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber printf("format changed.\n"); 2097f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber continue; 2107f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber } else if (err != OK) { 2115228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber printf("reached EOF.\n"); 2125228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2135228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber shouldSeek = true; 2145228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } else { 21548c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int64_t timestampUs; 21648c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber CHECK(buffer->meta_data()->findInt64(kKeyTime, ×tampUs)); 2175228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2185228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber bool failed = false; 219af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber 2205228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber if (seekTimeUs >= 0) { 22148c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int64_t diff = timestampUs - seekTimeUs; 2225228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 223af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber if (diff < 0) { 224af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber diff = -diff; 225af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber } 226af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber 227af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber if ((gReproduceBug == 4 && diff > 500000) 228af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber || (gReproduceBug == 5 && timestampUs < 0)) { 229af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber printf("wanted: %.2f secs, got: %.2f secs\n", 230af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber seekTimeUs / 1E6, timestampUs / 1E6); 2315228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2325228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber printf("ERROR: "); 2335228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber failed = true; 2345228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 2355228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 2365228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2375228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber printf("buffer has timestamp %lld us (%.2f secs)\n", 23848c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber timestampUs, timestampUs / 1E6); 2395228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2405228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber buffer->release(); 2415228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber buffer = NULL; 2425228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2435228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber if (failed) { 2445228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber break; 2455228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 2465228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2475228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber shouldSeek = ((double)rand() / RAND_MAX) < 0.1; 248af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber 249af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber if (gReproduceBug == 3) { 250af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber shouldSeek = false; 251af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber } 2525228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 2535228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2545228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber seekTimeUs = -1; 2555228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2565228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber if (shouldSeek) { 257af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber seekTimeUs = (rand() * (float)durationUs) / RAND_MAX; 2585228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber options.setSeekTo(seekTimeUs); 2595228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2605228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber printf("seeking to %lld us (%.2f secs)\n", 2615228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber seekTimeUs, seekTimeUs / 1E6); 2625228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 2635228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 2645228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 265125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber rawSource->stop(); 2665228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2675228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber return; 2685228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 2695228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2702d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber int n = 0; 271693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber int64_t startTime = getNowUs(); 272693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 2732d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber long numIterationsLeft = gNumRepetitions; 2742d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber MediaSource::ReadOptions options; 275dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 27636e3ee0094e845ed9d2a1c755addecfde9db3a68Andreas Huber int64_t sumDecodeUs = 0; 2777f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber int64_t totalBytes = 0; 27836e3ee0094e845ed9d2a1c755addecfde9db3a68Andreas Huber 279fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber Vector<int64_t> decodeTimesUs; 280fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 2812d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber while (numIterationsLeft-- > 0) { 28238b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber long numFrames = 0; 28338b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber 2842d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber MediaBuffer *buffer; 2852d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 2862d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber for (;;) { 28736e3ee0094e845ed9d2a1c755addecfde9db3a68Andreas Huber int64_t startDecodeUs = getNowUs(); 288125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber status_t err = rawSource->read(&buffer, &options); 28936e3ee0094e845ed9d2a1c755addecfde9db3a68Andreas Huber int64_t delayDecodeUs = getNowUs() - startDecodeUs; 29036e3ee0094e845ed9d2a1c755addecfde9db3a68Andreas Huber 2912d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber options.clearSeekTo(); 2922d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 2932d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber if (err != OK) { 294bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber CHECK(buffer == NULL); 2957f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber 2967f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber if (err == INFO_FORMAT_CHANGED) { 2977f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber printf("format changed.\n"); 2987f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber continue; 2997f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber } 3007f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber 3012d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber break; 3022d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 3032d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 304fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber if (buffer->range_length() > 0) { 305fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber if (gDisplayHistogram && n > 0) { 306fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber // Ignore the first time since it includes some setup 307fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber // cost. 308fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber decodeTimesUs.push(delayDecodeUs); 309fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber } 310fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 311fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber if ((n++ % 16) == 0) { 312fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber printf("."); 313fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber fflush(stdout); 314fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber } 3152d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 3162d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 31736e3ee0094e845ed9d2a1c755addecfde9db3a68Andreas Huber sumDecodeUs += delayDecodeUs; 3187f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber totalBytes += buffer->range_length(); 31936e3ee0094e845ed9d2a1c755addecfde9db3a68Andreas Huber 3202d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber buffer->release(); 3212d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber buffer = NULL; 32238b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber 32338b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber ++numFrames; 32438b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber if (gMaxNumFrames > 0 && numFrames == gMaxNumFrames) { 32538b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber break; 32638b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber } 32780011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber 32880011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber if (gReproduceBug == 1 && numFrames == 40) { 32980011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber printf("seeking past the end now."); 330a8a371c8a0d88d144d095404673d00cae6464fdeAndreas Huber options.setSeekTo(0x7fffffffL); 331e07db23c4935e47ecedfec7537ba95163e5836e5Andreas Huber } else if (gReproduceBug == 2 && numFrames == 40) { 332e07db23c4935e47ecedfec7537ba95163e5836e5Andreas Huber printf("seeking to 5 secs."); 333e07db23c4935e47ecedfec7537ba95163e5836e5Andreas Huber options.setSeekTo(5000000); 33480011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber } 335693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber } 336693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 3372d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber printf("$"); 3382d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber fflush(stdout); 3392d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 3402d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber options.setSeekTo(0); 341693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber } 3422d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 343125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber rawSource->stop(); 344693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber printf("\n"); 345693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 346693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber int64_t delay = getNowUs() - startTime; 3477f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber if (!strncasecmp("video/", mime, 6)) { 3487f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber printf("avg. %.2f fps\n", n * 1E6 / delay); 349693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 3507f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber printf("avg. time to decode one buffer %.2f usecs\n", 3517f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber (double)sumDecodeUs / n); 3527f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber 3537f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber printf("decoded a total of %d frame(s).\n", n); 354fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 355fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber if (gDisplayHistogram) { 356fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber displayDecodeHistogram(&decodeTimesUs); 357fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber } 3587f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber } else if (!strncasecmp("audio/", mime, 6)) { 3597f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber // Frame count makes less sense for audio, as the output buffer 3607f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber // sizes may be different across decoders. 3617f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber printf("avg. %.2f KB/sec\n", totalBytes / 1024 * 1E6 / delay); 3627f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber 3637f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber printf("decoded a total of %lld bytes\n", totalBytes); 3647f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber } 365693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber} 366693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 367bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber//////////////////////////////////////////////////////////////////////////////// 368bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 369bbc38312e4521cfd4299203591ef366b7624f043Andreas Huberstruct DetectSyncSource : public MediaSource { 370bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber DetectSyncSource(const sp<MediaSource> &source); 371bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 372bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber virtual status_t start(MetaData *params = NULL); 373bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber virtual status_t stop(); 374bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber virtual sp<MetaData> getFormat(); 375bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 376bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber virtual status_t read( 377bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber MediaBuffer **buffer, const ReadOptions *options); 378bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 379bbc38312e4521cfd4299203591ef366b7624f043Andreas Huberprivate: 380ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber enum StreamType { 381ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber AVC, 382ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber MPEG4, 383ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber H263, 384ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber OTHER, 385ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber }; 386ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 387bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber sp<MediaSource> mSource; 388ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber StreamType mStreamType; 389fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber bool mSawFirstIDRFrame; 390bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 391bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(DetectSyncSource); 392bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber}; 393bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 394bbc38312e4521cfd4299203591ef366b7624f043Andreas HuberDetectSyncSource::DetectSyncSource(const sp<MediaSource> &source) 395bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber : mSource(source), 396fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber mStreamType(OTHER), 397fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber mSawFirstIDRFrame(false) { 398bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber const char *mime; 399bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber CHECK(mSource->getFormat()->findCString(kKeyMIMEType, &mime)); 400bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 401ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 402ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber mStreamType = AVC; 403ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)) { 404ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber mStreamType = MPEG4; 405ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber CHECK(!"sync frame detection not implemented yet for MPEG4"); 406ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_H263)) { 407ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber mStreamType = H263; 408ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber CHECK(!"sync frame detection not implemented yet for H.263"); 409ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 410bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber} 411bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 412bbc38312e4521cfd4299203591ef366b7624f043Andreas Huberstatus_t DetectSyncSource::start(MetaData *params) { 413fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber mSawFirstIDRFrame = false; 414fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber 415bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber return mSource->start(params); 416bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber} 417bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 418bbc38312e4521cfd4299203591ef366b7624f043Andreas Huberstatus_t DetectSyncSource::stop() { 419bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber return mSource->stop(); 420bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber} 421bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 422bbc38312e4521cfd4299203591ef366b7624f043Andreas Hubersp<MetaData> DetectSyncSource::getFormat() { 423bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber return mSource->getFormat(); 424bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber} 425bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 426bbc38312e4521cfd4299203591ef366b7624f043Andreas Huberstatic bool isIDRFrame(MediaBuffer *buffer) { 427bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber const uint8_t *data = 428bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber (const uint8_t *)buffer->data() + buffer->range_offset(); 429bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber size_t size = buffer->range_length(); 430bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber for (size_t i = 0; i + 3 < size; ++i) { 431bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber if (!memcmp("\x00\x00\x01", &data[i], 3)) { 432bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber uint8_t nalType = data[i + 3] & 0x1f; 433bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber if (nalType == 5) { 434bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber return true; 435bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber } 436bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber } 437bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber } 438bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 439bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber return false; 440bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber} 441bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 442bbc38312e4521cfd4299203591ef366b7624f043Andreas Huberstatus_t DetectSyncSource::read( 443bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber MediaBuffer **buffer, const ReadOptions *options) { 444fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber for (;;) { 445fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber status_t err = mSource->read(buffer, options); 446bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 447fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber if (err != OK) { 448fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber return err; 449fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber } 450bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 451fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber if (mStreamType == AVC) { 452fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber bool isIDR = isIDRFrame(*buffer); 453fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber (*buffer)->meta_data()->setInt32(kKeyIsSyncFrame, isIDR); 454fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber if (isIDR) { 455fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber mSawFirstIDRFrame = true; 456fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber } 457fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber } else { 458fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber (*buffer)->meta_data()->setInt32(kKeyIsSyncFrame, true); 459fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber } 460fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber 461fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber if (mStreamType != AVC || mSawFirstIDRFrame) { 462fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber break; 463fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber } 464fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber 465fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber // Ignore everything up to the first IDR frame. 466fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber (*buffer)->release(); 467fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber *buffer = NULL; 468bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber } 469bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 470bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber return OK; 471bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber} 472bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 473bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber//////////////////////////////////////////////////////////////////////////////// 474bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 475ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huberstatic void writeSourcesToMP4( 476ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber Vector<sp<MediaSource> > &sources, bool syncInfoPresent) { 4770da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber#if 0 47819c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber sp<MPEG4Writer> writer = 47919c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber new MPEG4Writer(gWriteMP4Filename.string()); 4800da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber#else 4810da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber sp<MPEG2TSWriter> writer = 4820da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber new MPEG2TSWriter(gWriteMP4Filename.string()); 4830da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber#endif 48419c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber 485bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber // at most one minute. 486bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber writer->setMaxFileDuration(60000000ll); 487bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 488ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber for (size_t i = 0; i < sources.size(); ++i) { 489ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber sp<MediaSource> source = sources.editItemAt(i); 490ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 491ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber CHECK_EQ(writer->addSource( 492ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber syncInfoPresent ? source : new DetectSyncSource(source)), 493ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber (status_t)OK); 494ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 49519c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber 49619c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber sp<MetaData> params = new MetaData; 497bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber params->setInt32(kKeyNotRealTime, true); 498bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber CHECK_EQ(writer->start(params.get()), (status_t)OK); 49919c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber 50019c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber while (!writer->reachedEOS()) { 50119c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber usleep(100000); 50219c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber } 50319c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber writer->stop(); 50419c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber} 50519c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber 50666d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huberstatic void performSeekTest(const sp<MediaSource> &source) { 507bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber CHECK_EQ((status_t)OK, source->start()); 50866d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 50966d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber int64_t durationUs; 51066d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber CHECK(source->getFormat()->findInt64(kKeyDuration, &durationUs)); 51166d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 51266d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber for (int64_t seekTimeUs = 0; seekTimeUs <= durationUs; 51366d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber seekTimeUs += 60000ll) { 51466d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber MediaSource::ReadOptions options; 51566d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber options.setSeekTo( 51666d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber seekTimeUs, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC); 51766d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 51866d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber MediaBuffer *buffer; 51966d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber status_t err; 52066d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber for (;;) { 52166d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber err = source->read(&buffer, &options); 52266d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 52366d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber options.clearSeekTo(); 52466d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 52566d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber if (err == INFO_FORMAT_CHANGED) { 52666d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber CHECK(buffer == NULL); 52766d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber continue; 52866d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } 52966d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 53066d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber if (err != OK) { 53166d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber CHECK(buffer == NULL); 53266d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber break; 53366d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } 53466d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 53566d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber if (buffer->range_length() > 0) { 53666d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber break; 53766d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } 53866d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 53966d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber CHECK(buffer != NULL); 54066d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 54166d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber buffer->release(); 54266d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber buffer = NULL; 54366d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } 54466d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 54566d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber if (err == OK) { 54666d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber int64_t timeUs; 54766d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs)); 54866d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 54966d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber printf("%lld\t%lld\t%lld\n", seekTimeUs, timeUs, seekTimeUs - timeUs); 55066d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 55166d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber buffer->release(); 55266d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber buffer = NULL; 55366d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } else { 55466d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber printf("ERROR\n"); 55566d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber break; 55666d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } 55766d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } 55866d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 559bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber CHECK_EQ((status_t)OK, source->stop()); 56066d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber} 56166d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 5622d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huberstatic void usage(const char *me) { 5632d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber fprintf(stderr, "usage: %s\n", me); 5642d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber fprintf(stderr, " -h(elp)\n"); 5652d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber fprintf(stderr, " -a(udio)\n"); 5662d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber fprintf(stderr, " -n repetitions\n"); 5672d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber fprintf(stderr, " -l(ist) components\n"); 56838b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber fprintf(stderr, " -m max-number-of-frames-to-decode in each pass\n"); 56980011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber fprintf(stderr, " -b bug to reproduce\n"); 57018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber fprintf(stderr, " -p(rofiles) dump decoder profiles supported\n"); 5711b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber fprintf(stderr, " -t(humbnail) extract video thumbnail or album art\n"); 5725c1e3581978164d169050686c73810ce59304471Andreas Huber fprintf(stderr, " -s(oftware) prefer software codec\n"); 573cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong fprintf(stderr, " -r(hardware) force to use hardware codec\n"); 574a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber fprintf(stderr, " -o playback audio\n"); 57519c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber fprintf(stderr, " -w(rite) filename (write to .mp4 file)\n"); 57666d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber fprintf(stderr, " -k seek test\n"); 577fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber fprintf(stderr, " -x display a histogram of decoding times/fps " 578fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber "(video only)\n"); 579c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber fprintf(stderr, " -S allocate buffers from a surface\n"); 58016f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber fprintf(stderr, " -T allocate buffers from a surface texture\n"); 5812d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber} 5822d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 58320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberint main(int argc, char **argv) { 58420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber android::ProcessState::self()->startThreadPool(); 58520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5860024245e134467d120b40099da16c467dc365e76Andreas Huber bool audioOnly = false; 5872d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber bool listComponents = false; 58818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber bool dumpProfiles = false; 5895c1e3581978164d169050686c73810ce59304471Andreas Huber bool extractThumbnail = false; 59066d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber bool seekTest = false; 591c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber bool useSurfaceAlloc = false; 59216f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber bool useSurfaceTexAlloc = false; 5932d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber gNumRepetitions = 1; 59438b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber gMaxNumFrames = 0; 59580011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber gReproduceBug = -1; 5965c1e3581978164d169050686c73810ce59304471Andreas Huber gPreferSoftwareCodec = false; 597cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong gForceToUseHardwareCodec = false; 598a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber gPlaybackAudio = false; 59919c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber gWriteMP4 = false; 600fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber gDisplayHistogram = false; 6012d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 602348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber sp<ALooper> looper; 603348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber sp<ARTSPController> rtspController; 604a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<LiveSession> liveSession; 605348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber 6062d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber int res; 60716f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber while ((res = getopt(argc, argv, "han:lm:b:ptsrow:kxST")) >= 0) { 6082d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber switch (res) { 6092d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber case 'a': 6102d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber { 6112d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber audioOnly = true; 6122d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber break; 6132d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 6142d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 6152d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber case 'l': 6162d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber { 6172d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber listComponents = true; 6182d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber break; 6192d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 6202d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 62138b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber case 'm': 6222d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber case 'n': 62380011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber case 'b': 6242d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber { 6252d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber char *end; 6262d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber long x = strtol(optarg, &end, 10); 6272d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 6282d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber if (*end != '\0' || end == optarg || x <= 0) { 6292d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber x = 1; 6302d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 6312d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 63238b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber if (res == 'n') { 63338b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber gNumRepetitions = x; 63480011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber } else if (res == 'm') { 63538b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber gMaxNumFrames = x; 63680011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber } else { 63780011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber CHECK_EQ(res, 'b'); 63880011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber gReproduceBug = x; 63938b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber } 6402d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber break; 6412d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 6422d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 64319c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber case 'w': 64419c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber { 64519c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber gWriteMP4 = true; 64619c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber gWriteMP4Filename.setTo(optarg); 64719c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber break; 64819c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber } 64919c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber 65018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber case 'p': 65118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber { 65218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber dumpProfiles = true; 65318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber break; 65418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber } 65518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 6565c1e3581978164d169050686c73810ce59304471Andreas Huber case 't': 6575c1e3581978164d169050686c73810ce59304471Andreas Huber { 6585c1e3581978164d169050686c73810ce59304471Andreas Huber extractThumbnail = true; 6595c1e3581978164d169050686c73810ce59304471Andreas Huber break; 6605c1e3581978164d169050686c73810ce59304471Andreas Huber } 6615c1e3581978164d169050686c73810ce59304471Andreas Huber 6625c1e3581978164d169050686c73810ce59304471Andreas Huber case 's': 6635c1e3581978164d169050686c73810ce59304471Andreas Huber { 6645c1e3581978164d169050686c73810ce59304471Andreas Huber gPreferSoftwareCodec = true; 6655c1e3581978164d169050686c73810ce59304471Andreas Huber break; 6665c1e3581978164d169050686c73810ce59304471Andreas Huber } 6675c1e3581978164d169050686c73810ce59304471Andreas Huber 668cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong case 'r': 669cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong { 670cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong gForceToUseHardwareCodec = true; 671cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong break; 672cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong } 673cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong 674a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber case 'o': 675a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber { 676a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber gPlaybackAudio = true; 677a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber break; 678a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber } 679a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 68066d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber case 'k': 68166d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber { 68266d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber seekTest = true; 68366d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber break; 68466d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } 68566d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 686fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber case 'x': 687fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber { 688fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber gDisplayHistogram = true; 689fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber break; 690fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber } 691fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 692c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber case 'S': 693c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber { 694c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber useSurfaceAlloc = true; 695c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber break; 696c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber } 697c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber 69816f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber case 'T': 69916f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber { 70016f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber useSurfaceTexAlloc = true; 70116f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber break; 70216f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber } 70316f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber 7042d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber case '?': 7052d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber case 'h': 7062d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber default: 7072d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber { 7082d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber usage(argv[0]); 7092d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber exit(1); 7102d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber break; 7112d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 7122d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 7132d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 7142d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 715a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber if (gPlaybackAudio && !audioOnly) { 716a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber // This doesn't make any sense if we're decoding the video track. 717a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber gPlaybackAudio = false; 718a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber } 719a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 7202d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber argc -= optind; 7212d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber argv += optind; 7222d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 7235c1e3581978164d169050686c73810ce59304471Andreas Huber if (extractThumbnail) { 7245c1e3581978164d169050686c73810ce59304471Andreas Huber sp<IServiceManager> sm = defaultServiceManager(); 7255c1e3581978164d169050686c73810ce59304471Andreas Huber sp<IBinder> binder = sm->getService(String16("media.player")); 7265c1e3581978164d169050686c73810ce59304471Andreas Huber sp<IMediaPlayerService> service = 7275c1e3581978164d169050686c73810ce59304471Andreas Huber interface_cast<IMediaPlayerService>(binder); 7285c1e3581978164d169050686c73810ce59304471Andreas Huber 7295c1e3581978164d169050686c73810ce59304471Andreas Huber CHECK(service.get() != NULL); 7305c1e3581978164d169050686c73810ce59304471Andreas Huber 7315c1e3581978164d169050686c73810ce59304471Andreas Huber sp<IMediaMetadataRetriever> retriever = 7325c1e3581978164d169050686c73810ce59304471Andreas Huber service->createMetadataRetriever(getpid()); 7335c1e3581978164d169050686c73810ce59304471Andreas Huber 7345c1e3581978164d169050686c73810ce59304471Andreas Huber CHECK(retriever != NULL); 7355c1e3581978164d169050686c73810ce59304471Andreas Huber 7365c1e3581978164d169050686c73810ce59304471Andreas Huber for (int k = 0; k < argc; ++k) { 7375c1e3581978164d169050686c73810ce59304471Andreas Huber const char *filename = argv[k]; 7385c1e3581978164d169050686c73810ce59304471Andreas Huber 739515e855eae78aa495da58356486aaa666cb57fd1James Dong bool failed = true; 740bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber CHECK_EQ(retriever->setDataSource(filename), (status_t)OK); 74116afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong sp<IMemory> mem = 74216afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong retriever->getFrameAtTime(-1, 74316afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC); 7445c1e3581978164d169050686c73810ce59304471Andreas Huber 7451b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber if (mem != NULL) { 746515e855eae78aa495da58356486aaa666cb57fd1James Dong failed = false; 74716afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong printf("getFrameAtTime(%s) => OK\n", filename); 748f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber 749f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber VideoFrame *frame = (VideoFrame *)mem->pointer(); 750f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber 751f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber SkBitmap bitmap; 752f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber bitmap.setConfig( 753f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber SkBitmap::kRGB_565_Config, frame->mWidth, frame->mHeight); 754f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber 755f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber bitmap.setPixels((uint8_t *)frame + sizeof(VideoFrame)); 756f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber 757f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber CHECK(SkImageEncoder::EncodeFile( 758f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber "/sdcard/out.jpg", bitmap, 759f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber SkImageEncoder::kJPEG_Type, 760f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber SkImageEncoder::kDefaultQuality)); 761515e855eae78aa495da58356486aaa666cb57fd1James Dong } 762515e855eae78aa495da58356486aaa666cb57fd1James Dong 763515e855eae78aa495da58356486aaa666cb57fd1James Dong { 7641b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber mem = retriever->extractAlbumArt(); 7651b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber 7661b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber if (mem != NULL) { 767515e855eae78aa495da58356486aaa666cb57fd1James Dong failed = false; 7681b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber printf("extractAlbumArt(%s) => OK\n", filename); 7691b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber } 7701b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber } 771515e855eae78aa495da58356486aaa666cb57fd1James Dong 772515e855eae78aa495da58356486aaa666cb57fd1James Dong if (failed) { 773515e855eae78aa495da58356486aaa666cb57fd1James Dong printf("both getFrameAtTime and extractAlbumArt " 774515e855eae78aa495da58356486aaa666cb57fd1James Dong "failed on file '%s'.\n", filename); 775515e855eae78aa495da58356486aaa666cb57fd1James Dong } 7765c1e3581978164d169050686c73810ce59304471Andreas Huber } 7775c1e3581978164d169050686c73810ce59304471Andreas Huber 7785c1e3581978164d169050686c73810ce59304471Andreas Huber return 0; 7795c1e3581978164d169050686c73810ce59304471Andreas Huber } 7805c1e3581978164d169050686c73810ce59304471Andreas Huber 78118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber if (dumpProfiles) { 78218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber sp<IServiceManager> sm = defaultServiceManager(); 78318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber sp<IBinder> binder = sm->getService(String16("media.player")); 78418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber sp<IMediaPlayerService> service = 78518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber interface_cast<IMediaPlayerService>(binder); 78618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 78718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber CHECK(service.get() != NULL); 78818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 789318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber sp<IOMX> omx = service->getOMX(); 79018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber CHECK(omx.get() != NULL); 79118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 79218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber const char *kMimeTypes[] = { 79318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber MEDIA_MIMETYPE_VIDEO_AVC, MEDIA_MIMETYPE_VIDEO_MPEG4, 79408a88e195d2b3697f2f967e9216491e8c5bd3c9eAndreas Huber MEDIA_MIMETYPE_VIDEO_H263, MEDIA_MIMETYPE_AUDIO_AAC, 79508a88e195d2b3697f2f967e9216491e8c5bd3c9eAndreas Huber MEDIA_MIMETYPE_AUDIO_AMR_NB, MEDIA_MIMETYPE_AUDIO_AMR_WB, 79608a88e195d2b3697f2f967e9216491e8c5bd3c9eAndreas Huber MEDIA_MIMETYPE_AUDIO_MPEG 79718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber }; 79818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 79918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber for (size_t k = 0; k < sizeof(kMimeTypes) / sizeof(kMimeTypes[0]); 80018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber ++k) { 80118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber printf("type '%s':\n", kMimeTypes[k]); 80218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 80318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber Vector<CodecCapabilities> results; 80418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber CHECK_EQ(QueryCodecs(omx, kMimeTypes[k], 80518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber true, // queryDecoders 806bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber &results), (status_t)OK); 80718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 80818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber for (size_t i = 0; i < results.size(); ++i) { 80918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber printf(" decoder '%s' supports ", 81018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber results[i].mComponentName.string()); 81118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 81218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber if (results[i].mProfileLevels.size() == 0) { 81318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber printf("NOTHING.\n"); 81418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber continue; 81518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber } 81618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 81718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber for (size_t j = 0; j < results[i].mProfileLevels.size(); ++j) { 81818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber const CodecProfileLevel &profileLevel = 81918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber results[i].mProfileLevels[j]; 82018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 82118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber printf("%s%ld/%ld", j > 0 ? ", " : "", 82218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber profileLevel.mProfile, profileLevel.mLevel); 82318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber } 82418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 82518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber printf("\n"); 82618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber } 82718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber } 82818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber } 82918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 8302d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber if (listComponents) { 83120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<IServiceManager> sm = defaultServiceManager(); 83220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<IBinder> binder = sm->getService(String16("media.player")); 83320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder); 83420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 835693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber CHECK(service.get() != NULL); 83620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 837318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber sp<IOMX> omx = service->getOMX(); 838693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber CHECK(omx.get() != NULL); 83920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 840134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber List<IOMX::ComponentInfo> list; 841318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber omx->listNodes(&list); 84220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 843134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber for (List<IOMX::ComponentInfo>::iterator it = list.begin(); 84420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber it != list.end(); ++it) { 845134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber printf("%s\n", (*it).mName.string()); 84620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 84720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 84820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 849c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber sp<SurfaceComposerClient> composerClient; 850c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber sp<SurfaceControl> control; 851c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber 85216f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber if ((useSurfaceAlloc || useSurfaceTexAlloc) && !audioOnly) { 85316f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber if (useSurfaceAlloc) { 85416f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber composerClient = new SurfaceComposerClient; 85516f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber CHECK_EQ(composerClient->initCheck(), (status_t)OK); 85616f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber 85716f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber control = composerClient->createSurface( 85816f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber String8("A Surface"), 85916f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber 0, 86016f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber 1280, 86116f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber 800, 86216f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber PIXEL_FORMAT_RGB_565, 86316f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber 0); 86416f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber 86516f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber CHECK(control != NULL); 86616f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber CHECK(control->isValid()); 86716f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber 8682df788fb0c402938f827bf9c9ce2ca3ab1dcd464Mathias Agopian SurfaceComposerClient::openGlobalTransaction(); 86916f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber CHECK_EQ(control->setLayer(30000), (status_t)OK); 87016f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber CHECK_EQ(control->show(), (status_t)OK); 8712df788fb0c402938f827bf9c9ce2ca3ab1dcd464Mathias Agopian SurfaceComposerClient::closeGlobalTransaction(); 87216f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber 87316f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber gSurface = control->getSurface(); 87416f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber CHECK(gSurface != NULL); 87516f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber } else { 87616f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber CHECK(useSurfaceTexAlloc); 87716f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber 87816f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber sp<SurfaceTexture> texture = new SurfaceTexture(0 /* tex */); 87916f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber gSurface = new SurfaceTextureClient(texture); 88016f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber } 881c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber } 882c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber 88320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber DataSource::RegisterDefaultSniffers(); 88420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 88520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber OMXClient client; 88620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = client.connect(); 88720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8882d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber for (int k = 0; k < argc; ++k) { 889bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber bool syncInfoPresent = true; 890bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 8912d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber const char *filename = argv[k]; 89220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8931c70247536457f7b7fa84daa3482bd3d3b44e225Andreas Huber sp<DataSource> dataSource = DataSource::CreateFromURI(filename); 8940024245e134467d120b40099da16c467dc365e76Andreas Huber 895ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (strncasecmp(filename, "sine:", 5) 896ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber && strncasecmp(filename, "rtsp://", 7) 897ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber && strncasecmp(filename, "httplive://", 11) 898ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber && dataSource == NULL) { 899a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber fprintf(stderr, "Unable to create data source.\n"); 900a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber return 1; 901a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber } 902a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 9032d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber bool isJPEG = false; 90420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9052d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber size_t len = strlen(filename); 9062d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber if (len >= 4 && !strcasecmp(filename + len - 4, ".jpg")) { 9072d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber isJPEG = true; 9082d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 90920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 910ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber Vector<sp<MediaSource> > mediaSources; 9112d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber sp<MediaSource> mediaSource; 91220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9132d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber if (isJPEG) { 9142d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber mediaSource = new JPEGSource(dataSource); 915ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (gWriteMP4) { 916ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber mediaSources.push(mediaSource); 917ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 918a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber } else if (!strncasecmp("sine:", filename, 5)) { 919a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber char *end; 920a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber long sampleRate = strtol(filename + 5, &end, 10); 921a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 922a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber if (end == filename + 5) { 923a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber sampleRate = 44100; 924a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber } 925a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber mediaSource = new SineSource(sampleRate, 1); 926ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (gWriteMP4) { 927ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber mediaSources.push(mediaSource); 928ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 9292d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } else { 930348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber sp<MediaExtractor> extractor; 931348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber 932348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber if (!strncasecmp("rtsp://", filename, 7)) { 933348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber if (looper == NULL) { 934348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber looper = new ALooper; 935348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber looper->start(); 936348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber } 937348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber 938348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber rtspController = new ARTSPController(looper); 939348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber status_t err = rtspController->connect(filename); 940348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber if (err != OK) { 941348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber fprintf(stderr, "could not connect to rtsp server.\n"); 942348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber return -1; 943348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber } 944348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber 945348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber extractor = rtspController.get(); 946bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 947bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber syncInfoPresent = false; 948ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } else if (!strncasecmp("httplive://", filename, 11)) { 949ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber String8 uri("http://"); 950ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber uri.append(filename + 11); 951ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 952a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (looper == NULL) { 953a44153c1a57202fb538659eb50706e60454d6273Andreas Huber looper = new ALooper; 954a44153c1a57202fb538659eb50706e60454d6273Andreas Huber looper->start(); 955a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 956a44153c1a57202fb538659eb50706e60454d6273Andreas Huber liveSession = new LiveSession; 957a44153c1a57202fb538659eb50706e60454d6273Andreas Huber looper->registerHandler(liveSession); 958a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 959a44153c1a57202fb538659eb50706e60454d6273Andreas Huber liveSession->connect(uri.string()); 960a44153c1a57202fb538659eb50706e60454d6273Andreas Huber dataSource = liveSession->getDataSource(); 961ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 962ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber extractor = 963ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber MediaExtractor::Create( 964ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber dataSource, MEDIA_MIMETYPE_CONTAINER_MPEG2TS); 965ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 966ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber syncInfoPresent = false; 967348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber } else { 968348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber extractor = MediaExtractor::Create(dataSource); 969348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber if (extractor == NULL) { 970348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber fprintf(stderr, "could not create extractor.\n"); 971348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber return -1; 972348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber } 973fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber 974fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber sp<MetaData> meta = extractor->getMetaData(); 975fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber 976fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber if (meta != NULL) { 977fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber const char *mime; 978fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 979fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber 980fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) { 981fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber syncInfoPresent = false; 982fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber } 983fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber } 984b93ad64a423975748c7f5e1a5ea94ab8681bc899James Dong } 98520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9862d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber size_t numTracks = extractor->countTracks(); 98720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 988ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (gWriteMP4) { 989ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber bool haveAudio = false; 990ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber bool haveVideo = false; 991ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber for (size_t i = 0; i < numTracks; ++i) { 992ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber sp<MediaSource> source = extractor->getTrack(i); 993ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 994ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber const char *mime; 995ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber CHECK(source->getFormat()->findCString( 996ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber kKeyMIMEType, &mime)); 997ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 998ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber bool useTrack = false; 999ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (!haveAudio && !strncasecmp("audio/", mime, 6)) { 1000ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber haveAudio = true; 1001ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber useTrack = true; 1002ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } else if (!haveVideo && !strncasecmp("video/", mime, 6)) { 1003ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber haveVideo = true; 1004ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber useTrack = true; 1005ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 100620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1007ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (useTrack) { 1008ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber mediaSources.push(source); 100920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1010ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (haveAudio && haveVideo) { 1011ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber break; 1012ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 1013ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 10142d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 1015ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } else { 1016ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber sp<MetaData> meta; 1017ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber size_t i; 1018ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber for (i = 0; i < numTracks; ++i) { 1019ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber meta = extractor->getTrackMetaData( 1020ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber i, MediaExtractor::kIncludeExtensiveMetaData); 10212d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 1022ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber const char *mime; 1023ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber meta->findCString(kKeyMIMEType, &mime); 1024ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 1025ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (audioOnly && !strncasecmp(mime, "audio/", 6)) { 1026ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber break; 1027ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 1028ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 1029ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (!audioOnly && !strncasecmp(mime, "video/", 6)) { 1030ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber break; 1031ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 1032ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 1033ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber meta = NULL; 10342d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 1035a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 1036ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (meta == NULL) { 1037ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber fprintf(stderr, 1038ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber "No suitable %s track found. The '-a' option will " 1039ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber "target audio tracks only, the default is to target " 1040ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber "video tracks only.\n", 1041ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber audioOnly ? "audio" : "video"); 1042ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber return -1; 1043ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 1044a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 1045ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber int64_t thumbTimeUs; 1046ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (meta->findInt64(kKeyThumbnailTime, &thumbTimeUs)) { 1047ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber printf("thumbnailTime: %lld us (%.2f secs)\n", 1048ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber thumbTimeUs, thumbTimeUs / 1E6); 1049ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 10502d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 1051ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber mediaSource = extractor->getTrack(i); 10525c1e3581978164d169050686c73810ce59304471Andreas Huber } 105320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 105420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 105519c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber if (gWriteMP4) { 1056ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber writeSourcesToMP4(mediaSources, syncInfoPresent); 105766d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } else if (seekTest) { 105866d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber performSeekTest(mediaSource); 105919c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber } else { 106019c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber playSource(&client, mediaSource); 106119c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber } 1062348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber 1063348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber if (rtspController != NULL) { 1064348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber rtspController->disconnect(); 1065348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber rtspController.clear(); 1066348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber 1067348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber sleep(3); 1068348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber } 106920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 107020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 107116f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber if ((useSurfaceAlloc || useSurfaceTexAlloc) && !audioOnly) { 1072c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber gSurface.clear(); 1073c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber 107416f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber if (useSurfaceAlloc) { 107516f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber composerClient->dispose(); 107616f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber } 1077c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber } 1078c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber 107920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber client.disconnect(); 108020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 108120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return 0; 108220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 1083