stagefright.cpp revision 16afe2fb439cab6125bb46a07a8078d4ce1c1ea5
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" 34ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber#include "include/LiveSource.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 5820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberusing namespace android; 5920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 602d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huberstatic long gNumRepetitions; 6138b610fe53bb27946826d3f175f6fbe613f270daAndreas Huberstatic long gMaxNumFrames; // 0 means decode all available. 6280011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huberstatic long gReproduceBug; // if not -1. 635c1e3581978164d169050686c73810ce59304471Andreas Huberstatic bool gPreferSoftwareCodec; 64a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huberstatic bool gPlaybackAudio; 6519c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huberstatic bool gWriteMP4; 66fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huberstatic bool gDisplayHistogram; 6719c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huberstatic String8 gWriteMP4Filename; 6820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic int64_t getNowUs() { 7020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber struct timeval tv; 7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber gettimeofday(&tv, NULL); 7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 73d2858f047b2c52d719719532f24899c0e03c2099Andreas Huber return (int64_t)tv.tv_usec + tv.tv_sec * 1000000ll; 7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 7520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 76fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huberstatic int CompareIncreasing(const int64_t *a, const int64_t *b) { 77fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber return (*a) < (*b) ? -1 : (*a) > (*b) ? 1 : 0; 78fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber} 79fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 80fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huberstatic void displayDecodeHistogram(Vector<int64_t> *decodeTimesUs) { 81fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber printf("decode times:\n"); 82fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 83fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber decodeTimesUs->sort(CompareIncreasing); 84fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 85fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber size_t n = decodeTimesUs->size(); 86fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber int64_t minUs = decodeTimesUs->itemAt(0); 87fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber int64_t maxUs = decodeTimesUs->itemAt(n - 1); 88fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 89fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber printf("min decode time %lld us (%.2f secs)\n", minUs, minUs / 1E6); 90fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber printf("max decode time %lld us (%.2f secs)\n", maxUs, maxUs / 1E6); 91fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 92fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber size_t counts[100]; 93fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber for (size_t i = 0; i < 100; ++i) { 94fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber counts[i] = 0; 95fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber } 96fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 97fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber for (size_t i = 0; i < n; ++i) { 98fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber int64_t x = decodeTimesUs->itemAt(i); 99fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 100fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber size_t slot = ((x - minUs) * 100) / (maxUs - minUs); 101fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber if (slot == 100) { slot = 99; } 102fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 103fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber ++counts[slot]; 104fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber } 105fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 106fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber for (size_t i = 0; i < 100; ++i) { 107fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber int64_t slotUs = minUs + (i * (maxUs - minUs) / 100); 108fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 109fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber double fps = 1E6 / slotUs; 110fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber printf("[%.2f fps]: %d\n", fps, counts[i]); 111fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber } 112fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber} 113fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 1148a674dcc94936e2306121016ab258b4c00cc9d98James Dongstatic void displayAVCProfileLevelIfPossible(const sp<MetaData>& meta) { 1158a674dcc94936e2306121016ab258b4c00cc9d98James Dong uint32_t type; 1168a674dcc94936e2306121016ab258b4c00cc9d98James Dong const void *data; 1178a674dcc94936e2306121016ab258b4c00cc9d98James Dong size_t size; 1188a674dcc94936e2306121016ab258b4c00cc9d98James Dong if (meta->findData(kKeyAVCC, &type, &data, &size)) { 1198a674dcc94936e2306121016ab258b4c00cc9d98James Dong const uint8_t *ptr = (const uint8_t *)data; 1208a674dcc94936e2306121016ab258b4c00cc9d98James Dong CHECK(size >= 7); 1218a674dcc94936e2306121016ab258b4c00cc9d98James Dong CHECK(ptr[0] == 1); // configurationVersion == 1 1228a674dcc94936e2306121016ab258b4c00cc9d98James Dong uint8_t profile = ptr[1]; 1238a674dcc94936e2306121016ab258b4c00cc9d98James Dong uint8_t level = ptr[3]; 1248a674dcc94936e2306121016ab258b4c00cc9d98James Dong fprintf(stderr, "AVC video profile %d and level %d\n", profile, level); 1258a674dcc94936e2306121016ab258b4c00cc9d98James Dong } 1268a674dcc94936e2306121016ab258b4c00cc9d98James Dong} 1278a674dcc94936e2306121016ab258b4c00cc9d98James Dong 128c225da975515892952602cd3b1e24efc0cceaa4dAndreas Huberstatic void playSource(OMXClient *client, sp<MediaSource> &source) { 129693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<MetaData> meta = source->getFormat(); 130693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 131125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber const char *mime; 132125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 133125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber 134125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber sp<MediaSource> rawSource; 135125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_RAW, mime)) { 136125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber rawSource = source; 137125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber } else { 138125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber rawSource = OMXCodec::Create( 1395c1e3581978164d169050686c73810ce59304471Andreas Huber client->interface(), meta, false /* createEncoder */, source, 1405c1e3581978164d169050686c73810ce59304471Andreas Huber NULL /* matchComponentName */, 1415c1e3581978164d169050686c73810ce59304471Andreas Huber gPreferSoftwareCodec ? OMXCodec::kPreferSoftwareCodecs : 0); 142693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 143125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber if (rawSource == NULL) { 144125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber fprintf(stderr, "Failed to instantiate decoder for '%s'.\n", mime); 145125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber return; 146125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber } 1478a674dcc94936e2306121016ab258b4c00cc9d98James Dong displayAVCProfileLevelIfPossible(meta); 148693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber } 149693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 150c225da975515892952602cd3b1e24efc0cceaa4dAndreas Huber source.clear(); 151c225da975515892952602cd3b1e24efc0cceaa4dAndreas Huber 152139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber status_t err = rawSource->start(); 153139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber 154139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber if (err != OK) { 155139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber fprintf(stderr, "rawSource returned error %d (0x%08x)\n", err, err); 156139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber return; 157139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber } 158693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 159a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber if (gPlaybackAudio) { 160a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber AudioPlayer *player = new AudioPlayer(NULL); 161a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber player->setSource(rawSource); 16264105f956f15969dbe1ec7319f6caa2a984e588bAndreas Huber rawSource.clear(); 163a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 164a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber player->start(true /* sourceAlreadyStarted */); 165a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 166a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber status_t finalStatus; 167a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber while (!player->reachedEOS(&finalStatus)) { 168a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber usleep(100000ll); 169a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber } 170a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 171a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber delete player; 172a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber player = NULL; 17364105f956f15969dbe1ec7319f6caa2a984e588bAndreas Huber 17464105f956f15969dbe1ec7319f6caa2a984e588bAndreas Huber return; 175a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber } else if (gReproduceBug >= 3 && gReproduceBug <= 5) { 176bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber int64_t durationUs; 177bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber CHECK(meta->findInt64(kKeyDuration, &durationUs)); 178bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 1795228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber status_t err; 1805228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber MediaBuffer *buffer; 1815228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber MediaSource::ReadOptions options; 1825228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber int64_t seekTimeUs = -1; 1835228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber for (;;) { 184125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber err = rawSource->read(&buffer, &options); 1855228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber options.clearSeekTo(); 1865228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 1875228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber bool shouldSeek = false; 1887f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber if (err == INFO_FORMAT_CHANGED) { 189bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber CHECK(buffer == NULL); 1907f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber 1917f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber printf("format changed.\n"); 1927f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber continue; 1937f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber } else if (err != OK) { 1945228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber printf("reached EOF.\n"); 1955228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 1965228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber shouldSeek = true; 1975228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } else { 19848c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int64_t timestampUs; 19948c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber CHECK(buffer->meta_data()->findInt64(kKeyTime, ×tampUs)); 2005228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2015228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber bool failed = false; 202af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber 2035228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber if (seekTimeUs >= 0) { 20448c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int64_t diff = timestampUs - seekTimeUs; 2055228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 206af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber if (diff < 0) { 207af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber diff = -diff; 208af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber } 209af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber 210af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber if ((gReproduceBug == 4 && diff > 500000) 211af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber || (gReproduceBug == 5 && timestampUs < 0)) { 212af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber printf("wanted: %.2f secs, got: %.2f secs\n", 213af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber seekTimeUs / 1E6, timestampUs / 1E6); 2145228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2155228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber printf("ERROR: "); 2165228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber failed = true; 2175228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 2185228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 2195228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2205228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber printf("buffer has timestamp %lld us (%.2f secs)\n", 22148c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber timestampUs, timestampUs / 1E6); 2225228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2235228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber buffer->release(); 2245228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber buffer = NULL; 2255228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2265228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber if (failed) { 2275228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber break; 2285228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 2295228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2305228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber shouldSeek = ((double)rand() / RAND_MAX) < 0.1; 231af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber 232af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber if (gReproduceBug == 3) { 233af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber shouldSeek = false; 234af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber } 2355228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 2365228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2375228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber seekTimeUs = -1; 2385228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2395228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber if (shouldSeek) { 240af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber seekTimeUs = (rand() * (float)durationUs) / RAND_MAX; 2415228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber options.setSeekTo(seekTimeUs); 2425228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2435228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber printf("seeking to %lld us (%.2f secs)\n", 2445228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber seekTimeUs, seekTimeUs / 1E6); 2455228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 2465228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 2475228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 248125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber rawSource->stop(); 2495228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2505228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber return; 2515228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 2525228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2532d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber int n = 0; 254693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber int64_t startTime = getNowUs(); 255693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 2562d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber long numIterationsLeft = gNumRepetitions; 2572d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber MediaSource::ReadOptions options; 258dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 25936e3ee0094e845ed9d2a1c755addecfde9db3a68Andreas Huber int64_t sumDecodeUs = 0; 2607f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber int64_t totalBytes = 0; 26136e3ee0094e845ed9d2a1c755addecfde9db3a68Andreas Huber 262fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber Vector<int64_t> decodeTimesUs; 263fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 2642d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber while (numIterationsLeft-- > 0) { 26538b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber long numFrames = 0; 26638b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber 2672d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber MediaBuffer *buffer; 2682d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 2692d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber for (;;) { 27036e3ee0094e845ed9d2a1c755addecfde9db3a68Andreas Huber int64_t startDecodeUs = getNowUs(); 271125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber status_t err = rawSource->read(&buffer, &options); 27236e3ee0094e845ed9d2a1c755addecfde9db3a68Andreas Huber int64_t delayDecodeUs = getNowUs() - startDecodeUs; 27336e3ee0094e845ed9d2a1c755addecfde9db3a68Andreas Huber 2742d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber options.clearSeekTo(); 2752d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 2762d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber if (err != OK) { 277bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber CHECK(buffer == NULL); 2787f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber 2797f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber if (err == INFO_FORMAT_CHANGED) { 2807f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber printf("format changed.\n"); 2817f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber continue; 2827f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber } 2837f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber 2842d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber break; 2852d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 2862d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 287fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber if (buffer->range_length() > 0) { 288fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber if (gDisplayHistogram && n > 0) { 289fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber // Ignore the first time since it includes some setup 290fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber // cost. 291fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber decodeTimesUs.push(delayDecodeUs); 292fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber } 293fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 294fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber if ((n++ % 16) == 0) { 295fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber printf("."); 296fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber fflush(stdout); 297fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber } 2982d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 2992d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 30036e3ee0094e845ed9d2a1c755addecfde9db3a68Andreas Huber sumDecodeUs += delayDecodeUs; 3017f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber totalBytes += buffer->range_length(); 30236e3ee0094e845ed9d2a1c755addecfde9db3a68Andreas Huber 3032d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber buffer->release(); 3042d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber buffer = NULL; 30538b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber 30638b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber ++numFrames; 30738b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber if (gMaxNumFrames > 0 && numFrames == gMaxNumFrames) { 30838b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber break; 30938b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber } 31080011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber 31180011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber if (gReproduceBug == 1 && numFrames == 40) { 31280011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber printf("seeking past the end now."); 313a8a371c8a0d88d144d095404673d00cae6464fdeAndreas Huber options.setSeekTo(0x7fffffffL); 314e07db23c4935e47ecedfec7537ba95163e5836e5Andreas Huber } else if (gReproduceBug == 2 && numFrames == 40) { 315e07db23c4935e47ecedfec7537ba95163e5836e5Andreas Huber printf("seeking to 5 secs."); 316e07db23c4935e47ecedfec7537ba95163e5836e5Andreas Huber options.setSeekTo(5000000); 31780011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber } 318693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber } 319693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 3202d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber printf("$"); 3212d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber fflush(stdout); 3222d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 3232d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber options.setSeekTo(0); 324693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber } 3252d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 326125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber rawSource->stop(); 327693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber printf("\n"); 328693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 329693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber int64_t delay = getNowUs() - startTime; 3307f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber if (!strncasecmp("video/", mime, 6)) { 3317f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber printf("avg. %.2f fps\n", n * 1E6 / delay); 332693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 3337f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber printf("avg. time to decode one buffer %.2f usecs\n", 3347f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber (double)sumDecodeUs / n); 3357f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber 3367f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber printf("decoded a total of %d frame(s).\n", n); 337fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 338fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber if (gDisplayHistogram) { 339fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber displayDecodeHistogram(&decodeTimesUs); 340fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber } 3417f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber } else if (!strncasecmp("audio/", mime, 6)) { 3427f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber // Frame count makes less sense for audio, as the output buffer 3437f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber // sizes may be different across decoders. 3447f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber printf("avg. %.2f KB/sec\n", totalBytes / 1024 * 1E6 / delay); 3457f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber 3467f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber printf("decoded a total of %lld bytes\n", totalBytes); 3477f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber } 348693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber} 349693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 350bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber//////////////////////////////////////////////////////////////////////////////// 351bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 352bbc38312e4521cfd4299203591ef366b7624f043Andreas Huberstruct DetectSyncSource : public MediaSource { 353bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber DetectSyncSource(const sp<MediaSource> &source); 354bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 355bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber virtual status_t start(MetaData *params = NULL); 356bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber virtual status_t stop(); 357bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber virtual sp<MetaData> getFormat(); 358bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 359bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber virtual status_t read( 360bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber MediaBuffer **buffer, const ReadOptions *options); 361bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 362bbc38312e4521cfd4299203591ef366b7624f043Andreas Huberprivate: 363ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber enum StreamType { 364ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber AVC, 365ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber MPEG4, 366ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber H263, 367ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber OTHER, 368ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber }; 369ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 370bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber sp<MediaSource> mSource; 371ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber StreamType mStreamType; 372bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 373bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(DetectSyncSource); 374bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber}; 375bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 376bbc38312e4521cfd4299203591ef366b7624f043Andreas HuberDetectSyncSource::DetectSyncSource(const sp<MediaSource> &source) 377bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber : mSource(source), 378ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber mStreamType(OTHER) { 379bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber const char *mime; 380bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber CHECK(mSource->getFormat()->findCString(kKeyMIMEType, &mime)); 381bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 382ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 383ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber mStreamType = AVC; 384ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)) { 385ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber mStreamType = MPEG4; 386ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber CHECK(!"sync frame detection not implemented yet for MPEG4"); 387ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_H263)) { 388ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber mStreamType = H263; 389ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber CHECK(!"sync frame detection not implemented yet for H.263"); 390ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 391bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber} 392bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 393bbc38312e4521cfd4299203591ef366b7624f043Andreas Huberstatus_t DetectSyncSource::start(MetaData *params) { 394bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber return mSource->start(params); 395bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber} 396bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 397bbc38312e4521cfd4299203591ef366b7624f043Andreas Huberstatus_t DetectSyncSource::stop() { 398bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber return mSource->stop(); 399bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber} 400bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 401bbc38312e4521cfd4299203591ef366b7624f043Andreas Hubersp<MetaData> DetectSyncSource::getFormat() { 402bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber return mSource->getFormat(); 403bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber} 404bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 405bbc38312e4521cfd4299203591ef366b7624f043Andreas Huberstatic bool isIDRFrame(MediaBuffer *buffer) { 406bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber const uint8_t *data = 407bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber (const uint8_t *)buffer->data() + buffer->range_offset(); 408bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber size_t size = buffer->range_length(); 409bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber for (size_t i = 0; i + 3 < size; ++i) { 410bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber if (!memcmp("\x00\x00\x01", &data[i], 3)) { 411bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber uint8_t nalType = data[i + 3] & 0x1f; 412bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber if (nalType == 5) { 413bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber return true; 414bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber } 415bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber } 416bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber } 417bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 418bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber return false; 419bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber} 420bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 421bbc38312e4521cfd4299203591ef366b7624f043Andreas Huberstatus_t DetectSyncSource::read( 422bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber MediaBuffer **buffer, const ReadOptions *options) { 423bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber status_t err = mSource->read(buffer, options); 424bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 425bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber if (err != OK) { 426bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber return err; 427bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber } 428bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 429ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (mStreamType == AVC && isIDRFrame(*buffer)) { 430bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber (*buffer)->meta_data()->setInt32(kKeyIsSyncFrame, true); 431bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber } else { 432ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber (*buffer)->meta_data()->setInt32(kKeyIsSyncFrame, true); 433bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber } 434bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 435bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber return OK; 436bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber} 437bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 438bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber//////////////////////////////////////////////////////////////////////////////// 439bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 440ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huberstatic void writeSourcesToMP4( 441ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber Vector<sp<MediaSource> > &sources, bool syncInfoPresent) { 4420da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber#if 0 44319c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber sp<MPEG4Writer> writer = 44419c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber new MPEG4Writer(gWriteMP4Filename.string()); 4450da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber#else 4460da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber sp<MPEG2TSWriter> writer = 4470da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber new MPEG2TSWriter(gWriteMP4Filename.string()); 4480da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber#endif 44919c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber 450bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber // at most one minute. 451bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber writer->setMaxFileDuration(60000000ll); 452bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 453ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber for (size_t i = 0; i < sources.size(); ++i) { 454ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber sp<MediaSource> source = sources.editItemAt(i); 455ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 456ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber CHECK_EQ(writer->addSource( 457ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber syncInfoPresent ? source : new DetectSyncSource(source)), 458ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber (status_t)OK); 459ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 46019c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber 46119c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber sp<MetaData> params = new MetaData; 462bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber params->setInt32(kKeyNotRealTime, true); 463bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber CHECK_EQ(writer->start(params.get()), (status_t)OK); 46419c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber 46519c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber while (!writer->reachedEOS()) { 46619c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber usleep(100000); 46719c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber } 46819c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber writer->stop(); 46919c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber} 47019c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber 47166d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huberstatic void performSeekTest(const sp<MediaSource> &source) { 472bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber CHECK_EQ((status_t)OK, source->start()); 47366d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 47466d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber int64_t durationUs; 47566d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber CHECK(source->getFormat()->findInt64(kKeyDuration, &durationUs)); 47666d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 47766d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber for (int64_t seekTimeUs = 0; seekTimeUs <= durationUs; 47866d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber seekTimeUs += 60000ll) { 47966d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber MediaSource::ReadOptions options; 48066d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber options.setSeekTo( 48166d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber seekTimeUs, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC); 48266d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 48366d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber MediaBuffer *buffer; 48466d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber status_t err; 48566d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber for (;;) { 48666d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber err = source->read(&buffer, &options); 48766d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 48866d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber options.clearSeekTo(); 48966d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 49066d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber if (err == INFO_FORMAT_CHANGED) { 49166d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber CHECK(buffer == NULL); 49266d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber continue; 49366d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } 49466d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 49566d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber if (err != OK) { 49666d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber CHECK(buffer == NULL); 49766d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber break; 49866d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } 49966d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 50066d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber if (buffer->range_length() > 0) { 50166d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber break; 50266d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } 50366d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 50466d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber CHECK(buffer != NULL); 50566d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 50666d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber buffer->release(); 50766d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber buffer = NULL; 50866d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } 50966d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 51066d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber if (err == OK) { 51166d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber int64_t timeUs; 51266d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs)); 51366d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 51466d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber printf("%lld\t%lld\t%lld\n", seekTimeUs, timeUs, seekTimeUs - timeUs); 51566d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 51666d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber buffer->release(); 51766d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber buffer = NULL; 51866d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } else { 51966d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber printf("ERROR\n"); 52066d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber break; 52166d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } 52266d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } 52366d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 524bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber CHECK_EQ((status_t)OK, source->stop()); 52566d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber} 52666d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 5272d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huberstatic void usage(const char *me) { 5282d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber fprintf(stderr, "usage: %s\n", me); 5292d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber fprintf(stderr, " -h(elp)\n"); 5302d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber fprintf(stderr, " -a(udio)\n"); 5312d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber fprintf(stderr, " -n repetitions\n"); 5322d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber fprintf(stderr, " -l(ist) components\n"); 53338b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber fprintf(stderr, " -m max-number-of-frames-to-decode in each pass\n"); 53480011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber fprintf(stderr, " -b bug to reproduce\n"); 53518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber fprintf(stderr, " -p(rofiles) dump decoder profiles supported\n"); 5361b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber fprintf(stderr, " -t(humbnail) extract video thumbnail or album art\n"); 5375c1e3581978164d169050686c73810ce59304471Andreas Huber fprintf(stderr, " -s(oftware) prefer software codec\n"); 538a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber fprintf(stderr, " -o playback audio\n"); 53919c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber fprintf(stderr, " -w(rite) filename (write to .mp4 file)\n"); 54066d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber fprintf(stderr, " -k seek test\n"); 541fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber fprintf(stderr, " -x display a histogram of decoding times/fps " 542fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber "(video only)\n"); 5432d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber} 5442d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 54520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberint main(int argc, char **argv) { 54620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber android::ProcessState::self()->startThreadPool(); 54720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5480024245e134467d120b40099da16c467dc365e76Andreas Huber bool audioOnly = false; 5492d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber bool listComponents = false; 55018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber bool dumpProfiles = false; 5515c1e3581978164d169050686c73810ce59304471Andreas Huber bool extractThumbnail = false; 55266d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber bool seekTest = false; 5532d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber gNumRepetitions = 1; 55438b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber gMaxNumFrames = 0; 55580011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber gReproduceBug = -1; 5565c1e3581978164d169050686c73810ce59304471Andreas Huber gPreferSoftwareCodec = false; 557a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber gPlaybackAudio = false; 55819c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber gWriteMP4 = false; 559fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber gDisplayHistogram = false; 5602d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 561348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber sp<ALooper> looper; 562348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber sp<ARTSPController> rtspController; 563348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber 5642d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber int res; 565fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber while ((res = getopt(argc, argv, "han:lm:b:ptsow:kx")) >= 0) { 5662d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber switch (res) { 5672d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber case 'a': 5682d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber { 5692d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber audioOnly = true; 5702d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber break; 5712d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 5722d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 5732d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber case 'l': 5742d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber { 5752d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber listComponents = true; 5762d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber break; 5772d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 5782d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 57938b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber case 'm': 5802d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber case 'n': 58180011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber case 'b': 5822d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber { 5832d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber char *end; 5842d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber long x = strtol(optarg, &end, 10); 5852d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 5862d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber if (*end != '\0' || end == optarg || x <= 0) { 5872d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber x = 1; 5882d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 5892d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 59038b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber if (res == 'n') { 59138b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber gNumRepetitions = x; 59280011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber } else if (res == 'm') { 59338b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber gMaxNumFrames = x; 59480011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber } else { 59580011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber CHECK_EQ(res, 'b'); 59680011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber gReproduceBug = x; 59738b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber } 5982d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber break; 5992d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 6002d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 60119c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber case 'w': 60219c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber { 60319c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber gWriteMP4 = true; 60419c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber gWriteMP4Filename.setTo(optarg); 60519c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber break; 60619c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber } 60719c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber 60818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber case 'p': 60918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber { 61018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber dumpProfiles = true; 61118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber break; 61218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber } 61318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 6145c1e3581978164d169050686c73810ce59304471Andreas Huber case 't': 6155c1e3581978164d169050686c73810ce59304471Andreas Huber { 6165c1e3581978164d169050686c73810ce59304471Andreas Huber extractThumbnail = true; 6175c1e3581978164d169050686c73810ce59304471Andreas Huber break; 6185c1e3581978164d169050686c73810ce59304471Andreas Huber } 6195c1e3581978164d169050686c73810ce59304471Andreas Huber 6205c1e3581978164d169050686c73810ce59304471Andreas Huber case 's': 6215c1e3581978164d169050686c73810ce59304471Andreas Huber { 6225c1e3581978164d169050686c73810ce59304471Andreas Huber gPreferSoftwareCodec = true; 6235c1e3581978164d169050686c73810ce59304471Andreas Huber break; 6245c1e3581978164d169050686c73810ce59304471Andreas Huber } 6255c1e3581978164d169050686c73810ce59304471Andreas Huber 626a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber case 'o': 627a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber { 628a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber gPlaybackAudio = true; 629a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber break; 630a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber } 631a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 63266d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber case 'k': 63366d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber { 63466d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber seekTest = true; 63566d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber break; 63666d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } 63766d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 638fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber case 'x': 639fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber { 640fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber gDisplayHistogram = true; 641fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber break; 642fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber } 643fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 6442d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber case '?': 6452d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber case 'h': 6462d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber default: 6472d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber { 6482d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber usage(argv[0]); 6492d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber exit(1); 6502d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber break; 6512d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 6522d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 6532d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 6542d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 655a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber if (gPlaybackAudio && !audioOnly) { 656a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber // This doesn't make any sense if we're decoding the video track. 657a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber gPlaybackAudio = false; 658a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber } 659a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 6602d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber argc -= optind; 6612d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber argv += optind; 6622d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 6635c1e3581978164d169050686c73810ce59304471Andreas Huber if (extractThumbnail) { 6645c1e3581978164d169050686c73810ce59304471Andreas Huber sp<IServiceManager> sm = defaultServiceManager(); 6655c1e3581978164d169050686c73810ce59304471Andreas Huber sp<IBinder> binder = sm->getService(String16("media.player")); 6665c1e3581978164d169050686c73810ce59304471Andreas Huber sp<IMediaPlayerService> service = 6675c1e3581978164d169050686c73810ce59304471Andreas Huber interface_cast<IMediaPlayerService>(binder); 6685c1e3581978164d169050686c73810ce59304471Andreas Huber 6695c1e3581978164d169050686c73810ce59304471Andreas Huber CHECK(service.get() != NULL); 6705c1e3581978164d169050686c73810ce59304471Andreas Huber 6715c1e3581978164d169050686c73810ce59304471Andreas Huber sp<IMediaMetadataRetriever> retriever = 6725c1e3581978164d169050686c73810ce59304471Andreas Huber service->createMetadataRetriever(getpid()); 6735c1e3581978164d169050686c73810ce59304471Andreas Huber 6745c1e3581978164d169050686c73810ce59304471Andreas Huber CHECK(retriever != NULL); 6755c1e3581978164d169050686c73810ce59304471Andreas Huber 6765c1e3581978164d169050686c73810ce59304471Andreas Huber for (int k = 0; k < argc; ++k) { 6775c1e3581978164d169050686c73810ce59304471Andreas Huber const char *filename = argv[k]; 6785c1e3581978164d169050686c73810ce59304471Andreas Huber 679bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber CHECK_EQ(retriever->setDataSource(filename), (status_t)OK); 6801b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber CHECK_EQ(retriever->setMode( 6811b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber METADATA_MODE_FRAME_CAPTURE_AND_METADATA_RETRIEVAL), 682bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber (status_t)OK); 6835c1e3581978164d169050686c73810ce59304471Andreas Huber 68416afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong sp<IMemory> mem = 68516afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong retriever->getFrameAtTime(-1, 68616afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC); 6875c1e3581978164d169050686c73810ce59304471Andreas Huber 6881b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber if (mem != NULL) { 68916afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong printf("getFrameAtTime(%s) => OK\n", filename); 690f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber 691f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber VideoFrame *frame = (VideoFrame *)mem->pointer(); 692f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber 693f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber SkBitmap bitmap; 694f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber bitmap.setConfig( 695f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber SkBitmap::kRGB_565_Config, frame->mWidth, frame->mHeight); 696f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber 697f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber bitmap.setPixels((uint8_t *)frame + sizeof(VideoFrame)); 698f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber 699f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber CHECK(SkImageEncoder::EncodeFile( 700f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber "/sdcard/out.jpg", bitmap, 701f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber SkImageEncoder::kJPEG_Type, 702f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber SkImageEncoder::kDefaultQuality)); 7031b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber } else { 7041b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber mem = retriever->extractAlbumArt(); 7051b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber 7061b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber if (mem != NULL) { 7071b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber printf("extractAlbumArt(%s) => OK\n", filename); 7081b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber } else { 70916afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong printf("both getFrameAtTime and extractAlbumArt " 7101b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber "failed on file '%s'.\n", filename); 7111b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber } 7121b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber } 7135c1e3581978164d169050686c73810ce59304471Andreas Huber } 7145c1e3581978164d169050686c73810ce59304471Andreas Huber 7155c1e3581978164d169050686c73810ce59304471Andreas Huber return 0; 7165c1e3581978164d169050686c73810ce59304471Andreas Huber } 7175c1e3581978164d169050686c73810ce59304471Andreas Huber 71818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber if (dumpProfiles) { 71918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber sp<IServiceManager> sm = defaultServiceManager(); 72018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber sp<IBinder> binder = sm->getService(String16("media.player")); 72118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber sp<IMediaPlayerService> service = 72218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber interface_cast<IMediaPlayerService>(binder); 72318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 72418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber CHECK(service.get() != NULL); 72518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 726318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber sp<IOMX> omx = service->getOMX(); 72718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber CHECK(omx.get() != NULL); 72818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 72918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber const char *kMimeTypes[] = { 73018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber MEDIA_MIMETYPE_VIDEO_AVC, MEDIA_MIMETYPE_VIDEO_MPEG4, 73108a88e195d2b3697f2f967e9216491e8c5bd3c9eAndreas Huber MEDIA_MIMETYPE_VIDEO_H263, MEDIA_MIMETYPE_AUDIO_AAC, 73208a88e195d2b3697f2f967e9216491e8c5bd3c9eAndreas Huber MEDIA_MIMETYPE_AUDIO_AMR_NB, MEDIA_MIMETYPE_AUDIO_AMR_WB, 73308a88e195d2b3697f2f967e9216491e8c5bd3c9eAndreas Huber MEDIA_MIMETYPE_AUDIO_MPEG 73418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber }; 73518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 73618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber for (size_t k = 0; k < sizeof(kMimeTypes) / sizeof(kMimeTypes[0]); 73718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber ++k) { 73818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber printf("type '%s':\n", kMimeTypes[k]); 73918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 74018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber Vector<CodecCapabilities> results; 74118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber CHECK_EQ(QueryCodecs(omx, kMimeTypes[k], 74218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber true, // queryDecoders 743bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber &results), (status_t)OK); 74418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 74518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber for (size_t i = 0; i < results.size(); ++i) { 74618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber printf(" decoder '%s' supports ", 74718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber results[i].mComponentName.string()); 74818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 74918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber if (results[i].mProfileLevels.size() == 0) { 75018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber printf("NOTHING.\n"); 75118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber continue; 75218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber } 75318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 75418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber for (size_t j = 0; j < results[i].mProfileLevels.size(); ++j) { 75518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber const CodecProfileLevel &profileLevel = 75618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber results[i].mProfileLevels[j]; 75718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 75818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber printf("%s%ld/%ld", j > 0 ? ", " : "", 75918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber profileLevel.mProfile, profileLevel.mLevel); 76018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber } 76118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 76218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber printf("\n"); 76318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber } 76418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber } 76518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber } 76618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 7672d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber if (listComponents) { 76820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<IServiceManager> sm = defaultServiceManager(); 76920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<IBinder> binder = sm->getService(String16("media.player")); 77020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder); 77120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 772693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber CHECK(service.get() != NULL); 77320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 774318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber sp<IOMX> omx = service->getOMX(); 775693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber CHECK(omx.get() != NULL); 77620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 777134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber List<IOMX::ComponentInfo> list; 778318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber omx->listNodes(&list); 77920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 780134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber for (List<IOMX::ComponentInfo>::iterator it = list.begin(); 78120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber it != list.end(); ++it) { 782134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber printf("%s\n", (*it).mName.string()); 78320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 78420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 78520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber DataSource::RegisterDefaultSniffers(); 78720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber OMXClient client; 78920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = client.connect(); 79020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7912d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber for (int k = 0; k < argc; ++k) { 792bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber bool syncInfoPresent = true; 793bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 7942d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber const char *filename = argv[k]; 79520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7961c70247536457f7b7fa84daa3482bd3d3b44e225Andreas Huber sp<DataSource> dataSource = DataSource::CreateFromURI(filename); 7970024245e134467d120b40099da16c467dc365e76Andreas Huber 798ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (strncasecmp(filename, "sine:", 5) 799ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber && strncasecmp(filename, "rtsp://", 7) 800ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber && strncasecmp(filename, "httplive://", 11) 801ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber && dataSource == NULL) { 802a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber fprintf(stderr, "Unable to create data source.\n"); 803a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber return 1; 804a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber } 805a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 8062d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber bool isJPEG = false; 80720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8082d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber size_t len = strlen(filename); 8092d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber if (len >= 4 && !strcasecmp(filename + len - 4, ".jpg")) { 8102d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber isJPEG = true; 8112d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 81220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 813ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber Vector<sp<MediaSource> > mediaSources; 8142d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber sp<MediaSource> mediaSource; 81520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8162d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber if (isJPEG) { 8172d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber mediaSource = new JPEGSource(dataSource); 818ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (gWriteMP4) { 819ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber mediaSources.push(mediaSource); 820ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 821a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber } else if (!strncasecmp("sine:", filename, 5)) { 822a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber char *end; 823a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber long sampleRate = strtol(filename + 5, &end, 10); 824a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 825a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber if (end == filename + 5) { 826a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber sampleRate = 44100; 827a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber } 828a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber mediaSource = new SineSource(sampleRate, 1); 829ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (gWriteMP4) { 830ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber mediaSources.push(mediaSource); 831ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 8322d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } else { 833348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber sp<MediaExtractor> extractor; 834348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber 835348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber if (!strncasecmp("rtsp://", filename, 7)) { 836348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber if (looper == NULL) { 837348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber looper = new ALooper; 838348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber looper->start(); 839348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber } 840348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber 841348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber rtspController = new ARTSPController(looper); 842348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber status_t err = rtspController->connect(filename); 843348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber if (err != OK) { 844348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber fprintf(stderr, "could not connect to rtsp server.\n"); 845348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber return -1; 846348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber } 847348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber 848348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber extractor = rtspController.get(); 849bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 850bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber syncInfoPresent = false; 851ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } else if (!strncasecmp("httplive://", filename, 11)) { 852ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber String8 uri("http://"); 853ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber uri.append(filename + 11); 854ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 855ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber dataSource = new LiveSource(uri.string()); 856ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber dataSource = new NuCachedSource2(dataSource); 857ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 858ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber extractor = 859ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber MediaExtractor::Create( 860ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber dataSource, MEDIA_MIMETYPE_CONTAINER_MPEG2TS); 861ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 862ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber syncInfoPresent = false; 863348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber } else { 864348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber extractor = MediaExtractor::Create(dataSource); 865348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber if (extractor == NULL) { 866348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber fprintf(stderr, "could not create extractor.\n"); 867348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber return -1; 868348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber } 869b93ad64a423975748c7f5e1a5ea94ab8681bc899James Dong } 87020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8712d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber size_t numTracks = extractor->countTracks(); 87220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 873ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (gWriteMP4) { 874ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber bool haveAudio = false; 875ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber bool haveVideo = false; 876ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber for (size_t i = 0; i < numTracks; ++i) { 877ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber sp<MediaSource> source = extractor->getTrack(i); 878ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 879ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber const char *mime; 880ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber CHECK(source->getFormat()->findCString( 881ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber kKeyMIMEType, &mime)); 882ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 883ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber bool useTrack = false; 884ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (!haveAudio && !strncasecmp("audio/", mime, 6)) { 885ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber haveAudio = true; 886ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber useTrack = true; 887ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } else if (!haveVideo && !strncasecmp("video/", mime, 6)) { 888ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber haveVideo = true; 889ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber useTrack = true; 890ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 89120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 892ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (useTrack) { 893ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber mediaSources.push(source); 89420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 895ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (haveAudio && haveVideo) { 896ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber break; 897ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 898ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 8992d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 900ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } else { 901ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber sp<MetaData> meta; 902ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber size_t i; 903ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber for (i = 0; i < numTracks; ++i) { 904ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber meta = extractor->getTrackMetaData( 905ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber i, MediaExtractor::kIncludeExtensiveMetaData); 9062d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 907ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber const char *mime; 908ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber meta->findCString(kKeyMIMEType, &mime); 909ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 910ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (audioOnly && !strncasecmp(mime, "audio/", 6)) { 911ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber break; 912ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 913ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 914ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (!audioOnly && !strncasecmp(mime, "video/", 6)) { 915ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber break; 916ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 917ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 918ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber meta = NULL; 9192d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 920a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 921ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (meta == NULL) { 922ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber fprintf(stderr, 923ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber "No suitable %s track found. The '-a' option will " 924ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber "target audio tracks only, the default is to target " 925ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber "video tracks only.\n", 926ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber audioOnly ? "audio" : "video"); 927ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber return -1; 928ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 929a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 930ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber int64_t thumbTimeUs; 931ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (meta->findInt64(kKeyThumbnailTime, &thumbTimeUs)) { 932ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber printf("thumbnailTime: %lld us (%.2f secs)\n", 933ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber thumbTimeUs, thumbTimeUs / 1E6); 934ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 9352d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 936ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber mediaSource = extractor->getTrack(i); 9375c1e3581978164d169050686c73810ce59304471Andreas Huber } 93820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 93920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 94019c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber if (gWriteMP4) { 941ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber writeSourcesToMP4(mediaSources, syncInfoPresent); 94266d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } else if (seekTest) { 94366d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber performSeekTest(mediaSource); 94419c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber } else { 94519c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber playSource(&client, mediaSource); 94619c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber } 947348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber 948348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber if (rtspController != NULL) { 949348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber rtspController->disconnect(); 950348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber rtspController.clear(); 951348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber 952348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber sleep(3); 953348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber } 95420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 95520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 95620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber client.disconnect(); 95720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 95820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return 0; 95920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 960