stagefright.cpp revision df712ea86e6350f7005a02ab0e1c60c28a343ed0
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> 33a44153c1a57202fb538659eb50706e60454d6273Andreas Huber#include "include/LiveSession.h" 34ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber#include "include/NuCachedSource2.h" 35a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber#include <media/stagefright/AudioPlayer.h> 361c70247536457f7b7fa84daa3482bd3d3b44e225Andreas Huber#include <media/stagefright/DataSource.h> 37777893a928680f09e306b4b9efc1d5cf4479a9daAndreas Huber#include <media/stagefright/JPEGSource.h> 3818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h> 391c70247536457f7b7fa84daa3482bd3d3b44e225Andreas Huber#include <media/stagefright/MediaErrors.h> 4020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaExtractor.h> 4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaSource.h> 4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h> 4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/OMXClient.h> 44693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/OMXCodec.h> 455c1e3581978164d169050686c73810ce59304471Andreas Huber#include <media/mediametadataretriever.h> 4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4719c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber#include <media/stagefright/foundation/hexdump.h> 480da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber#include <media/stagefright/MPEG2TSWriter.h> 4919c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber#include <media/stagefright/MPEG4Writer.h> 5019c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber 51f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber#include <private/media/VideoFrame.h> 52f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber#include <SkBitmap.h> 53f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber#include <SkImageEncoder.h> 54f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber 55bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber#include <fcntl.h> 56bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 57c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber#include <gui/SurfaceTextureClient.h> 58df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopian#include <gui/SurfaceComposerClient.h> 59c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber 6020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberusing namespace android; 6120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 622d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huberstatic long gNumRepetitions; 6338b610fe53bb27946826d3f175f6fbe613f270daAndreas Huberstatic long gMaxNumFrames; // 0 means decode all available. 6480011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huberstatic long gReproduceBug; // if not -1. 655c1e3581978164d169050686c73810ce59304471Andreas Huberstatic bool gPreferSoftwareCodec; 66cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dongstatic bool gForceToUseHardwareCodec; 67a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huberstatic bool gPlaybackAudio; 6819c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huberstatic bool gWriteMP4; 69fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huberstatic bool gDisplayHistogram; 7019c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huberstatic String8 gWriteMP4Filename; 7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 72c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huberstatic sp<ANativeWindow> gSurface; 73c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber 7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic int64_t getNowUs() { 7520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber struct timeval tv; 7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber gettimeofday(&tv, NULL); 7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78d2858f047b2c52d719719532f24899c0e03c2099Andreas Huber return (int64_t)tv.tv_usec + tv.tv_sec * 1000000ll; 7920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 8020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huberstatic int CompareIncreasing(const int64_t *a, const int64_t *b) { 82fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber return (*a) < (*b) ? -1 : (*a) > (*b) ? 1 : 0; 83fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber} 84fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 85fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huberstatic void displayDecodeHistogram(Vector<int64_t> *decodeTimesUs) { 86fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber printf("decode times:\n"); 87fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 88fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber decodeTimesUs->sort(CompareIncreasing); 89fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 90fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber size_t n = decodeTimesUs->size(); 91fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber int64_t minUs = decodeTimesUs->itemAt(0); 92fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber int64_t maxUs = decodeTimesUs->itemAt(n - 1); 93fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 94fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber printf("min decode time %lld us (%.2f secs)\n", minUs, minUs / 1E6); 95fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber printf("max decode time %lld us (%.2f secs)\n", maxUs, maxUs / 1E6); 96fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 97fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber size_t counts[100]; 98fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber for (size_t i = 0; i < 100; ++i) { 99fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber counts[i] = 0; 100fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber } 101fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 102fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber for (size_t i = 0; i < n; ++i) { 103fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber int64_t x = decodeTimesUs->itemAt(i); 104fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 105fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber size_t slot = ((x - minUs) * 100) / (maxUs - minUs); 106fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber if (slot == 100) { slot = 99; } 107fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 108fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber ++counts[slot]; 109fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber } 110fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 111fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber for (size_t i = 0; i < 100; ++i) { 112fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber int64_t slotUs = minUs + (i * (maxUs - minUs) / 100); 113fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 114fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber double fps = 1E6 / slotUs; 115fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber printf("[%.2f fps]: %d\n", fps, counts[i]); 116fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber } 117fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber} 118fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 1198a674dcc94936e2306121016ab258b4c00cc9d98James Dongstatic void displayAVCProfileLevelIfPossible(const sp<MetaData>& meta) { 1208a674dcc94936e2306121016ab258b4c00cc9d98James Dong uint32_t type; 1218a674dcc94936e2306121016ab258b4c00cc9d98James Dong const void *data; 1228a674dcc94936e2306121016ab258b4c00cc9d98James Dong size_t size; 1238a674dcc94936e2306121016ab258b4c00cc9d98James Dong if (meta->findData(kKeyAVCC, &type, &data, &size)) { 1248a674dcc94936e2306121016ab258b4c00cc9d98James Dong const uint8_t *ptr = (const uint8_t *)data; 1258a674dcc94936e2306121016ab258b4c00cc9d98James Dong CHECK(size >= 7); 1268a674dcc94936e2306121016ab258b4c00cc9d98James Dong CHECK(ptr[0] == 1); // configurationVersion == 1 1278a674dcc94936e2306121016ab258b4c00cc9d98James Dong uint8_t profile = ptr[1]; 1288a674dcc94936e2306121016ab258b4c00cc9d98James Dong uint8_t level = ptr[3]; 1298a674dcc94936e2306121016ab258b4c00cc9d98James Dong fprintf(stderr, "AVC video profile %d and level %d\n", profile, level); 1308a674dcc94936e2306121016ab258b4c00cc9d98James Dong } 1318a674dcc94936e2306121016ab258b4c00cc9d98James Dong} 1328a674dcc94936e2306121016ab258b4c00cc9d98James Dong 133d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huberstatic void dumpSource(const sp<MediaSource> &source, const String8 &filename) { 134d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber FILE *out = fopen(filename.string(), "wb"); 135d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber 136d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber CHECK_EQ((status_t)OK, source->start()); 137d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber 138d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber status_t err; 139d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber for (;;) { 140d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber MediaBuffer *mbuf; 141d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber err = source->read(&mbuf); 142d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber 143d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber if (err == INFO_FORMAT_CHANGED) { 144d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber continue; 145d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber } else if (err != OK) { 146d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber break; 147d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber } 148d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber 149d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber CHECK_EQ( 150d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber fwrite((const uint8_t *)mbuf->data() + mbuf->range_offset(), 151d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber 1, 152d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber mbuf->range_length(), 153d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber out), 154d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber (ssize_t)mbuf->range_length()); 155d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber 156d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber mbuf->release(); 157d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber mbuf = NULL; 158d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber } 159d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber 160d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber CHECK_EQ((status_t)OK, source->stop()); 161d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber 162d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber fclose(out); 163d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber out = NULL; 164d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber} 165d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber 166c225da975515892952602cd3b1e24efc0cceaa4dAndreas Huberstatic void playSource(OMXClient *client, sp<MediaSource> &source) { 167693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<MetaData> meta = source->getFormat(); 168693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 169125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber const char *mime; 170125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 171125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber 172125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber sp<MediaSource> rawSource; 173125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_RAW, mime)) { 174125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber rawSource = source; 175125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber } else { 176cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong int flags = 0; 177cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong if (gPreferSoftwareCodec) { 178cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong flags |= OMXCodec::kPreferSoftwareCodecs; 179cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong } 180cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong if (gForceToUseHardwareCodec) { 181cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong CHECK(!gPreferSoftwareCodec); 182cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong flags |= OMXCodec::kHardwareCodecsOnly; 183cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong } 184125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber rawSource = OMXCodec::Create( 1855c1e3581978164d169050686c73810ce59304471Andreas Huber client->interface(), meta, false /* createEncoder */, source, 1865c1e3581978164d169050686c73810ce59304471Andreas Huber NULL /* matchComponentName */, 187cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong flags, 188c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber gSurface); 189693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 190125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber if (rawSource == NULL) { 191125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber fprintf(stderr, "Failed to instantiate decoder for '%s'.\n", mime); 192125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber return; 193125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber } 1948a674dcc94936e2306121016ab258b4c00cc9d98James Dong displayAVCProfileLevelIfPossible(meta); 195693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber } 196693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 197c225da975515892952602cd3b1e24efc0cceaa4dAndreas Huber source.clear(); 198c225da975515892952602cd3b1e24efc0cceaa4dAndreas Huber 199139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber status_t err = rawSource->start(); 200139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber 201139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber if (err != OK) { 202139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber fprintf(stderr, "rawSource returned error %d (0x%08x)\n", err, err); 203139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber return; 204139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber } 205693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 206a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber if (gPlaybackAudio) { 207a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber AudioPlayer *player = new AudioPlayer(NULL); 208a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber player->setSource(rawSource); 20964105f956f15969dbe1ec7319f6caa2a984e588bAndreas Huber rawSource.clear(); 210a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 211a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber player->start(true /* sourceAlreadyStarted */); 212a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 213a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber status_t finalStatus; 214a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber while (!player->reachedEOS(&finalStatus)) { 215a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber usleep(100000ll); 216a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber } 217a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 218a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber delete player; 219a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber player = NULL; 22064105f956f15969dbe1ec7319f6caa2a984e588bAndreas Huber 22164105f956f15969dbe1ec7319f6caa2a984e588bAndreas Huber return; 222a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber } else if (gReproduceBug >= 3 && gReproduceBug <= 5) { 223bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber int64_t durationUs; 224bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber CHECK(meta->findInt64(kKeyDuration, &durationUs)); 225bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 2265228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber status_t err; 2275228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber MediaBuffer *buffer; 2285228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber MediaSource::ReadOptions options; 2295228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber int64_t seekTimeUs = -1; 2305228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber for (;;) { 231125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber err = rawSource->read(&buffer, &options); 2325228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber options.clearSeekTo(); 2335228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2345228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber bool shouldSeek = false; 2357f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber if (err == INFO_FORMAT_CHANGED) { 236bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber CHECK(buffer == NULL); 2377f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber 2387f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber printf("format changed.\n"); 2397f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber continue; 2407f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber } else if (err != OK) { 2415228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber printf("reached EOF.\n"); 2425228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2435228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber shouldSeek = true; 2445228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } else { 24548c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int64_t timestampUs; 24648c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber CHECK(buffer->meta_data()->findInt64(kKeyTime, ×tampUs)); 2475228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2485228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber bool failed = false; 249af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber 2505228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber if (seekTimeUs >= 0) { 25148c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int64_t diff = timestampUs - seekTimeUs; 2525228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 253af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber if (diff < 0) { 254af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber diff = -diff; 255af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber } 256af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber 257af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber if ((gReproduceBug == 4 && diff > 500000) 258af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber || (gReproduceBug == 5 && timestampUs < 0)) { 259af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber printf("wanted: %.2f secs, got: %.2f secs\n", 260af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber seekTimeUs / 1E6, timestampUs / 1E6); 2615228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2625228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber printf("ERROR: "); 2635228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber failed = true; 2645228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 2655228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 2665228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2675228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber printf("buffer has timestamp %lld us (%.2f secs)\n", 26848c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber timestampUs, timestampUs / 1E6); 2695228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2705228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber buffer->release(); 2715228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber buffer = NULL; 2725228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2735228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber if (failed) { 2745228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber break; 2755228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 2765228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2775228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber shouldSeek = ((double)rand() / RAND_MAX) < 0.1; 278af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber 279af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber if (gReproduceBug == 3) { 280af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber shouldSeek = false; 281af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber } 2825228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 2835228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2845228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber seekTimeUs = -1; 2855228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2865228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber if (shouldSeek) { 287af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber seekTimeUs = (rand() * (float)durationUs) / RAND_MAX; 2885228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber options.setSeekTo(seekTimeUs); 2895228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2905228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber printf("seeking to %lld us (%.2f secs)\n", 2915228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber seekTimeUs, seekTimeUs / 1E6); 2925228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 2935228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 2945228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 295125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber rawSource->stop(); 2965228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2975228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber return; 2985228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 2995228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 3002d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber int n = 0; 301693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber int64_t startTime = getNowUs(); 302693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 3032d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber long numIterationsLeft = gNumRepetitions; 3042d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber MediaSource::ReadOptions options; 305dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 30636e3ee0094e845ed9d2a1c755addecfde9db3a68Andreas Huber int64_t sumDecodeUs = 0; 3077f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber int64_t totalBytes = 0; 30836e3ee0094e845ed9d2a1c755addecfde9db3a68Andreas Huber 309fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber Vector<int64_t> decodeTimesUs; 310fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 3112d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber while (numIterationsLeft-- > 0) { 31238b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber long numFrames = 0; 31338b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber 3142d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber MediaBuffer *buffer; 3152d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 3162d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber for (;;) { 31736e3ee0094e845ed9d2a1c755addecfde9db3a68Andreas Huber int64_t startDecodeUs = getNowUs(); 318125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber status_t err = rawSource->read(&buffer, &options); 31936e3ee0094e845ed9d2a1c755addecfde9db3a68Andreas Huber int64_t delayDecodeUs = getNowUs() - startDecodeUs; 32036e3ee0094e845ed9d2a1c755addecfde9db3a68Andreas Huber 3212d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber options.clearSeekTo(); 3222d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 3232d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber if (err != OK) { 324bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber CHECK(buffer == NULL); 3257f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber 3267f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber if (err == INFO_FORMAT_CHANGED) { 3277f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber printf("format changed.\n"); 3287f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber continue; 3297f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber } 3307f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber 3312d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber break; 3322d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 3332d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 334fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber if (buffer->range_length() > 0) { 335fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber if (gDisplayHistogram && n > 0) { 336fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber // Ignore the first time since it includes some setup 337fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber // cost. 338fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber decodeTimesUs.push(delayDecodeUs); 339fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber } 340fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 341fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber if ((n++ % 16) == 0) { 342fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber printf("."); 343fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber fflush(stdout); 344fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber } 3452d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 3462d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 34736e3ee0094e845ed9d2a1c755addecfde9db3a68Andreas Huber sumDecodeUs += delayDecodeUs; 3487f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber totalBytes += buffer->range_length(); 34936e3ee0094e845ed9d2a1c755addecfde9db3a68Andreas Huber 3502d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber buffer->release(); 3512d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber buffer = NULL; 35238b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber 35338b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber ++numFrames; 35438b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber if (gMaxNumFrames > 0 && numFrames == gMaxNumFrames) { 35538b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber break; 35638b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber } 35780011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber 35880011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber if (gReproduceBug == 1 && numFrames == 40) { 35980011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber printf("seeking past the end now."); 360a8a371c8a0d88d144d095404673d00cae6464fdeAndreas Huber options.setSeekTo(0x7fffffffL); 361e07db23c4935e47ecedfec7537ba95163e5836e5Andreas Huber } else if (gReproduceBug == 2 && numFrames == 40) { 362e07db23c4935e47ecedfec7537ba95163e5836e5Andreas Huber printf("seeking to 5 secs."); 363e07db23c4935e47ecedfec7537ba95163e5836e5Andreas Huber options.setSeekTo(5000000); 36480011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber } 365693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber } 366693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 3672d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber printf("$"); 3682d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber fflush(stdout); 3692d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 3702d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber options.setSeekTo(0); 371693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber } 3722d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 373125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber rawSource->stop(); 374693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber printf("\n"); 375693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 376693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber int64_t delay = getNowUs() - startTime; 3777f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber if (!strncasecmp("video/", mime, 6)) { 3787f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber printf("avg. %.2f fps\n", n * 1E6 / delay); 379693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 3807f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber printf("avg. time to decode one buffer %.2f usecs\n", 3817f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber (double)sumDecodeUs / n); 3827f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber 3837f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber printf("decoded a total of %d frame(s).\n", n); 384fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 385fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber if (gDisplayHistogram) { 386fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber displayDecodeHistogram(&decodeTimesUs); 387fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber } 3887f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber } else if (!strncasecmp("audio/", mime, 6)) { 3897f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber // Frame count makes less sense for audio, as the output buffer 3907f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber // sizes may be different across decoders. 3917f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber printf("avg. %.2f KB/sec\n", totalBytes / 1024 * 1E6 / delay); 3927f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber 3937f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber printf("decoded a total of %lld bytes\n", totalBytes); 3947f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber } 395693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber} 396693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 397bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber//////////////////////////////////////////////////////////////////////////////// 398bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 399bbc38312e4521cfd4299203591ef366b7624f043Andreas Huberstruct DetectSyncSource : public MediaSource { 400bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber DetectSyncSource(const sp<MediaSource> &source); 401bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 402bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber virtual status_t start(MetaData *params = NULL); 403bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber virtual status_t stop(); 404bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber virtual sp<MetaData> getFormat(); 405bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 406bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber virtual status_t read( 407bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber MediaBuffer **buffer, const ReadOptions *options); 408bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 409bbc38312e4521cfd4299203591ef366b7624f043Andreas Huberprivate: 410ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber enum StreamType { 411ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber AVC, 412ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber MPEG4, 413ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber H263, 414ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber OTHER, 415ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber }; 416ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 417bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber sp<MediaSource> mSource; 418ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber StreamType mStreamType; 419fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber bool mSawFirstIDRFrame; 420bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 421bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(DetectSyncSource); 422bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber}; 423bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 424bbc38312e4521cfd4299203591ef366b7624f043Andreas HuberDetectSyncSource::DetectSyncSource(const sp<MediaSource> &source) 425bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber : mSource(source), 426fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber mStreamType(OTHER), 427fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber mSawFirstIDRFrame(false) { 428bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber const char *mime; 429bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber CHECK(mSource->getFormat()->findCString(kKeyMIMEType, &mime)); 430bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 431ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 432ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber mStreamType = AVC; 433ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)) { 434ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber mStreamType = MPEG4; 435ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber CHECK(!"sync frame detection not implemented yet for MPEG4"); 436ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_H263)) { 437ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber mStreamType = H263; 438ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber CHECK(!"sync frame detection not implemented yet for H.263"); 439ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 440bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber} 441bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 442bbc38312e4521cfd4299203591ef366b7624f043Andreas Huberstatus_t DetectSyncSource::start(MetaData *params) { 443fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber mSawFirstIDRFrame = false; 444fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber 445bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber return mSource->start(params); 446bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber} 447bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 448bbc38312e4521cfd4299203591ef366b7624f043Andreas Huberstatus_t DetectSyncSource::stop() { 449bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber return mSource->stop(); 450bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber} 451bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 452bbc38312e4521cfd4299203591ef366b7624f043Andreas Hubersp<MetaData> DetectSyncSource::getFormat() { 453bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber return mSource->getFormat(); 454bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber} 455bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 456bbc38312e4521cfd4299203591ef366b7624f043Andreas Huberstatic bool isIDRFrame(MediaBuffer *buffer) { 457bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber const uint8_t *data = 458bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber (const uint8_t *)buffer->data() + buffer->range_offset(); 459bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber size_t size = buffer->range_length(); 460bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber for (size_t i = 0; i + 3 < size; ++i) { 461bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber if (!memcmp("\x00\x00\x01", &data[i], 3)) { 462bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber uint8_t nalType = data[i + 3] & 0x1f; 463bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber if (nalType == 5) { 464bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber return true; 465bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber } 466bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber } 467bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber } 468bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 469bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber return false; 470bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber} 471bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 472bbc38312e4521cfd4299203591ef366b7624f043Andreas Huberstatus_t DetectSyncSource::read( 473bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber MediaBuffer **buffer, const ReadOptions *options) { 474fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber for (;;) { 475fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber status_t err = mSource->read(buffer, options); 476bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 477fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber if (err != OK) { 478fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber return err; 479fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber } 480bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 481fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber if (mStreamType == AVC) { 482fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber bool isIDR = isIDRFrame(*buffer); 483fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber (*buffer)->meta_data()->setInt32(kKeyIsSyncFrame, isIDR); 484fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber if (isIDR) { 485fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber mSawFirstIDRFrame = true; 486fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber } 487fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber } else { 488fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber (*buffer)->meta_data()->setInt32(kKeyIsSyncFrame, true); 489fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber } 490fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber 491fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber if (mStreamType != AVC || mSawFirstIDRFrame) { 492fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber break; 493fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber } 494fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber 495fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber // Ignore everything up to the first IDR frame. 496fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber (*buffer)->release(); 497fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber *buffer = NULL; 498bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber } 499bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 500bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber return OK; 501bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber} 502bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 503bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber//////////////////////////////////////////////////////////////////////////////// 504bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 505ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huberstatic void writeSourcesToMP4( 506ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber Vector<sp<MediaSource> > &sources, bool syncInfoPresent) { 5070da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber#if 0 50819c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber sp<MPEG4Writer> writer = 50919c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber new MPEG4Writer(gWriteMP4Filename.string()); 5100da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber#else 5110da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber sp<MPEG2TSWriter> writer = 5120da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber new MPEG2TSWriter(gWriteMP4Filename.string()); 5130da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber#endif 51419c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber 515bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber // at most one minute. 516bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber writer->setMaxFileDuration(60000000ll); 517bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 518ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber for (size_t i = 0; i < sources.size(); ++i) { 519ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber sp<MediaSource> source = sources.editItemAt(i); 520ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 521ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber CHECK_EQ(writer->addSource( 522ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber syncInfoPresent ? source : new DetectSyncSource(source)), 523ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber (status_t)OK); 524ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 52519c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber 52619c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber sp<MetaData> params = new MetaData; 527bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber params->setInt32(kKeyNotRealTime, true); 528bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber CHECK_EQ(writer->start(params.get()), (status_t)OK); 52919c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber 53019c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber while (!writer->reachedEOS()) { 53119c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber usleep(100000); 53219c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber } 53319c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber writer->stop(); 53419c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber} 53519c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber 53666d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huberstatic void performSeekTest(const sp<MediaSource> &source) { 537bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber CHECK_EQ((status_t)OK, source->start()); 53866d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 53966d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber int64_t durationUs; 54066d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber CHECK(source->getFormat()->findInt64(kKeyDuration, &durationUs)); 54166d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 54266d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber for (int64_t seekTimeUs = 0; seekTimeUs <= durationUs; 54366d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber seekTimeUs += 60000ll) { 54466d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber MediaSource::ReadOptions options; 54566d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber options.setSeekTo( 54666d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber seekTimeUs, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC); 54766d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 54866d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber MediaBuffer *buffer; 54966d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber status_t err; 55066d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber for (;;) { 55166d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber err = source->read(&buffer, &options); 55266d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 55366d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber options.clearSeekTo(); 55466d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 55566d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber if (err == INFO_FORMAT_CHANGED) { 55666d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber CHECK(buffer == NULL); 55766d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber continue; 55866d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } 55966d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 56066d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber if (err != OK) { 56166d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber CHECK(buffer == NULL); 56266d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber break; 56366d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } 56466d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 56566d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber if (buffer->range_length() > 0) { 56666d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber break; 56766d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } 56866d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 56966d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber CHECK(buffer != NULL); 57066d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 57166d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber buffer->release(); 57266d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber buffer = NULL; 57366d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } 57466d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 57566d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber if (err == OK) { 57666d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber int64_t timeUs; 57766d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs)); 57866d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 57966d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber printf("%lld\t%lld\t%lld\n", seekTimeUs, timeUs, seekTimeUs - timeUs); 58066d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 58166d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber buffer->release(); 58266d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber buffer = NULL; 58366d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } else { 58466d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber printf("ERROR\n"); 58566d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber break; 58666d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } 58766d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } 58866d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 589bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber CHECK_EQ((status_t)OK, source->stop()); 59066d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber} 59166d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 5922d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huberstatic void usage(const char *me) { 5932d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber fprintf(stderr, "usage: %s\n", me); 5942d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber fprintf(stderr, " -h(elp)\n"); 5952d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber fprintf(stderr, " -a(udio)\n"); 5962d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber fprintf(stderr, " -n repetitions\n"); 5972d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber fprintf(stderr, " -l(ist) components\n"); 59838b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber fprintf(stderr, " -m max-number-of-frames-to-decode in each pass\n"); 59980011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber fprintf(stderr, " -b bug to reproduce\n"); 60018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber fprintf(stderr, " -p(rofiles) dump decoder profiles supported\n"); 6011b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber fprintf(stderr, " -t(humbnail) extract video thumbnail or album art\n"); 6025c1e3581978164d169050686c73810ce59304471Andreas Huber fprintf(stderr, " -s(oftware) prefer software codec\n"); 603cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong fprintf(stderr, " -r(hardware) force to use hardware codec\n"); 604a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber fprintf(stderr, " -o playback audio\n"); 60519c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber fprintf(stderr, " -w(rite) filename (write to .mp4 file)\n"); 60666d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber fprintf(stderr, " -k seek test\n"); 607fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber fprintf(stderr, " -x display a histogram of decoding times/fps " 608fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber "(video only)\n"); 609c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber fprintf(stderr, " -S allocate buffers from a surface\n"); 61016f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber fprintf(stderr, " -T allocate buffers from a surface texture\n"); 611d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber fprintf(stderr, " -d(ump) filename (raw stream data to a file)\n"); 6122d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber} 6132d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 61420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberint main(int argc, char **argv) { 61520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber android::ProcessState::self()->startThreadPool(); 61620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6170024245e134467d120b40099da16c467dc365e76Andreas Huber bool audioOnly = false; 6182d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber bool listComponents = false; 61918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber bool dumpProfiles = false; 6205c1e3581978164d169050686c73810ce59304471Andreas Huber bool extractThumbnail = false; 62166d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber bool seekTest = false; 622c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber bool useSurfaceAlloc = false; 62316f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber bool useSurfaceTexAlloc = false; 624d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber bool dumpStream = false; 625d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber String8 dumpStreamFilename; 6262d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber gNumRepetitions = 1; 62738b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber gMaxNumFrames = 0; 62880011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber gReproduceBug = -1; 6295c1e3581978164d169050686c73810ce59304471Andreas Huber gPreferSoftwareCodec = false; 630cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong gForceToUseHardwareCodec = false; 631a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber gPlaybackAudio = false; 63219c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber gWriteMP4 = false; 633fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber gDisplayHistogram = false; 6342d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 635348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber sp<ALooper> looper; 636a44153c1a57202fb538659eb50706e60454d6273Andreas Huber sp<LiveSession> liveSession; 637348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber 6382d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber int res; 639d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber while ((res = getopt(argc, argv, "han:lm:b:ptsrow:kxSTd:")) >= 0) { 6402d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber switch (res) { 6412d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber case 'a': 6422d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber { 6432d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber audioOnly = true; 6442d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber break; 6452d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 6462d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 647d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber case 'd': 648d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber { 649d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber dumpStream = true; 650d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber dumpStreamFilename.setTo(optarg); 651d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber break; 652d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber } 653d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber 6542d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber case 'l': 6552d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber { 6562d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber listComponents = true; 6572d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber break; 6582d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 6592d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 66038b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber case 'm': 6612d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber case 'n': 66280011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber case 'b': 6632d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber { 6642d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber char *end; 6652d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber long x = strtol(optarg, &end, 10); 6662d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 6672d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber if (*end != '\0' || end == optarg || x <= 0) { 6682d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber x = 1; 6692d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 6702d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 67138b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber if (res == 'n') { 67238b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber gNumRepetitions = x; 67380011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber } else if (res == 'm') { 67438b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber gMaxNumFrames = x; 67580011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber } else { 67680011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber CHECK_EQ(res, 'b'); 67780011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber gReproduceBug = x; 67838b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber } 6792d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber break; 6802d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 6812d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 68219c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber case 'w': 68319c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber { 68419c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber gWriteMP4 = true; 68519c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber gWriteMP4Filename.setTo(optarg); 68619c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber break; 68719c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber } 68819c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber 68918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber case 'p': 69018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber { 69118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber dumpProfiles = true; 69218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber break; 69318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber } 69418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 6955c1e3581978164d169050686c73810ce59304471Andreas Huber case 't': 6965c1e3581978164d169050686c73810ce59304471Andreas Huber { 6975c1e3581978164d169050686c73810ce59304471Andreas Huber extractThumbnail = true; 6985c1e3581978164d169050686c73810ce59304471Andreas Huber break; 6995c1e3581978164d169050686c73810ce59304471Andreas Huber } 7005c1e3581978164d169050686c73810ce59304471Andreas Huber 7015c1e3581978164d169050686c73810ce59304471Andreas Huber case 's': 7025c1e3581978164d169050686c73810ce59304471Andreas Huber { 7035c1e3581978164d169050686c73810ce59304471Andreas Huber gPreferSoftwareCodec = true; 7045c1e3581978164d169050686c73810ce59304471Andreas Huber break; 7055c1e3581978164d169050686c73810ce59304471Andreas Huber } 7065c1e3581978164d169050686c73810ce59304471Andreas Huber 707cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong case 'r': 708cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong { 709cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong gForceToUseHardwareCodec = true; 710cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong break; 711cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong } 712cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong 713a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber case 'o': 714a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber { 715a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber gPlaybackAudio = true; 716a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber break; 717a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber } 718a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 71966d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber case 'k': 72066d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber { 72166d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber seekTest = true; 72266d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber break; 72366d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } 72466d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 725fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber case 'x': 726fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber { 727fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber gDisplayHistogram = true; 728fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber break; 729fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber } 730fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 731c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber case 'S': 732c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber { 733c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber useSurfaceAlloc = true; 734c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber break; 735c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber } 736c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber 73716f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber case 'T': 73816f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber { 73916f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber useSurfaceTexAlloc = true; 74016f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber break; 74116f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber } 74216f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber 7432d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber case '?': 7442d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber case 'h': 7452d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber default: 7462d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber { 7472d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber usage(argv[0]); 7482d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber exit(1); 7492d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber break; 7502d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 7512d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 7522d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 7532d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 754a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber if (gPlaybackAudio && !audioOnly) { 755a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber // This doesn't make any sense if we're decoding the video track. 756a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber gPlaybackAudio = false; 757a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber } 758a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 7592d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber argc -= optind; 7602d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber argv += optind; 7612d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 7625c1e3581978164d169050686c73810ce59304471Andreas Huber if (extractThumbnail) { 7635c1e3581978164d169050686c73810ce59304471Andreas Huber sp<IServiceManager> sm = defaultServiceManager(); 7645c1e3581978164d169050686c73810ce59304471Andreas Huber sp<IBinder> binder = sm->getService(String16("media.player")); 7655c1e3581978164d169050686c73810ce59304471Andreas Huber sp<IMediaPlayerService> service = 7665c1e3581978164d169050686c73810ce59304471Andreas Huber interface_cast<IMediaPlayerService>(binder); 7675c1e3581978164d169050686c73810ce59304471Andreas Huber 7685c1e3581978164d169050686c73810ce59304471Andreas Huber CHECK(service.get() != NULL); 7695c1e3581978164d169050686c73810ce59304471Andreas Huber 7705c1e3581978164d169050686c73810ce59304471Andreas Huber sp<IMediaMetadataRetriever> retriever = 7715c1e3581978164d169050686c73810ce59304471Andreas Huber service->createMetadataRetriever(getpid()); 7725c1e3581978164d169050686c73810ce59304471Andreas Huber 7735c1e3581978164d169050686c73810ce59304471Andreas Huber CHECK(retriever != NULL); 7745c1e3581978164d169050686c73810ce59304471Andreas Huber 7755c1e3581978164d169050686c73810ce59304471Andreas Huber for (int k = 0; k < argc; ++k) { 7765c1e3581978164d169050686c73810ce59304471Andreas Huber const char *filename = argv[k]; 7775c1e3581978164d169050686c73810ce59304471Andreas Huber 778515e855eae78aa495da58356486aaa666cb57fd1James Dong bool failed = true; 779bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber CHECK_EQ(retriever->setDataSource(filename), (status_t)OK); 78016afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong sp<IMemory> mem = 78116afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong retriever->getFrameAtTime(-1, 78216afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC); 7835c1e3581978164d169050686c73810ce59304471Andreas Huber 7841b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber if (mem != NULL) { 785515e855eae78aa495da58356486aaa666cb57fd1James Dong failed = false; 78616afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong printf("getFrameAtTime(%s) => OK\n", filename); 787f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber 788f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber VideoFrame *frame = (VideoFrame *)mem->pointer(); 789f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber 790f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber SkBitmap bitmap; 791f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber bitmap.setConfig( 792f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber SkBitmap::kRGB_565_Config, frame->mWidth, frame->mHeight); 793f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber 794f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber bitmap.setPixels((uint8_t *)frame + sizeof(VideoFrame)); 795f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber 796f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber CHECK(SkImageEncoder::EncodeFile( 797f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber "/sdcard/out.jpg", bitmap, 798f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber SkImageEncoder::kJPEG_Type, 799f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber SkImageEncoder::kDefaultQuality)); 800515e855eae78aa495da58356486aaa666cb57fd1James Dong } 801515e855eae78aa495da58356486aaa666cb57fd1James Dong 802515e855eae78aa495da58356486aaa666cb57fd1James Dong { 8031b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber mem = retriever->extractAlbumArt(); 8041b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber 8051b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber if (mem != NULL) { 806515e855eae78aa495da58356486aaa666cb57fd1James Dong failed = false; 8071b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber printf("extractAlbumArt(%s) => OK\n", filename); 8081b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber } 8091b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber } 810515e855eae78aa495da58356486aaa666cb57fd1James Dong 811515e855eae78aa495da58356486aaa666cb57fd1James Dong if (failed) { 812515e855eae78aa495da58356486aaa666cb57fd1James Dong printf("both getFrameAtTime and extractAlbumArt " 813515e855eae78aa495da58356486aaa666cb57fd1James Dong "failed on file '%s'.\n", filename); 814515e855eae78aa495da58356486aaa666cb57fd1James Dong } 8155c1e3581978164d169050686c73810ce59304471Andreas Huber } 8165c1e3581978164d169050686c73810ce59304471Andreas Huber 8175c1e3581978164d169050686c73810ce59304471Andreas Huber return 0; 8185c1e3581978164d169050686c73810ce59304471Andreas Huber } 8195c1e3581978164d169050686c73810ce59304471Andreas Huber 82018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber if (dumpProfiles) { 82118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber sp<IServiceManager> sm = defaultServiceManager(); 82218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber sp<IBinder> binder = sm->getService(String16("media.player")); 82318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber sp<IMediaPlayerService> service = 82418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber interface_cast<IMediaPlayerService>(binder); 82518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 82618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber CHECK(service.get() != NULL); 82718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 828318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber sp<IOMX> omx = service->getOMX(); 82918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber CHECK(omx.get() != NULL); 83018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 83118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber const char *kMimeTypes[] = { 83218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber MEDIA_MIMETYPE_VIDEO_AVC, MEDIA_MIMETYPE_VIDEO_MPEG4, 83308a88e195d2b3697f2f967e9216491e8c5bd3c9eAndreas Huber MEDIA_MIMETYPE_VIDEO_H263, MEDIA_MIMETYPE_AUDIO_AAC, 83408a88e195d2b3697f2f967e9216491e8c5bd3c9eAndreas Huber MEDIA_MIMETYPE_AUDIO_AMR_NB, MEDIA_MIMETYPE_AUDIO_AMR_WB, 835a4b77bc0dbefc58b337c35b03ef21147a2cbdd4eAndreas Huber MEDIA_MIMETYPE_AUDIO_MPEG, MEDIA_MIMETYPE_AUDIO_G711_MLAW, 836a4b77bc0dbefc58b337c35b03ef21147a2cbdd4eAndreas Huber MEDIA_MIMETYPE_AUDIO_G711_ALAW, MEDIA_MIMETYPE_AUDIO_VORBIS, 837a4b77bc0dbefc58b337c35b03ef21147a2cbdd4eAndreas Huber MEDIA_MIMETYPE_VIDEO_VPX 83818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber }; 83918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 84018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber for (size_t k = 0; k < sizeof(kMimeTypes) / sizeof(kMimeTypes[0]); 84118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber ++k) { 84218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber printf("type '%s':\n", kMimeTypes[k]); 84318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 84418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber Vector<CodecCapabilities> results; 845d35924d9928f29dcee6f5666b5bbd084640c7b34Jean-Michel Trivi // will retrieve hardware and software codecs 84618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber CHECK_EQ(QueryCodecs(omx, kMimeTypes[k], 84718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber true, // queryDecoders 848bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber &results), (status_t)OK); 84918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 85018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber for (size_t i = 0; i < results.size(); ++i) { 85118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber printf(" decoder '%s' supports ", 85218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber results[i].mComponentName.string()); 85318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 85418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber if (results[i].mProfileLevels.size() == 0) { 85518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber printf("NOTHING.\n"); 85618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber continue; 85718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber } 85818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 85918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber for (size_t j = 0; j < results[i].mProfileLevels.size(); ++j) { 86018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber const CodecProfileLevel &profileLevel = 86118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber results[i].mProfileLevels[j]; 86218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 86318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber printf("%s%ld/%ld", j > 0 ? ", " : "", 86418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber profileLevel.mProfile, profileLevel.mLevel); 86518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber } 86618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 86718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber printf("\n"); 86818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber } 86918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber } 87018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber } 87118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 8722d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber if (listComponents) { 87320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<IServiceManager> sm = defaultServiceManager(); 87420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<IBinder> binder = sm->getService(String16("media.player")); 87520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder); 87620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 877693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber CHECK(service.get() != NULL); 87820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 879318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber sp<IOMX> omx = service->getOMX(); 880693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber CHECK(omx.get() != NULL); 88120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 882134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber List<IOMX::ComponentInfo> list; 883318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber omx->listNodes(&list); 88420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 885134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber for (List<IOMX::ComponentInfo>::iterator it = list.begin(); 88620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber it != list.end(); ++it) { 887df57a0d6d3b0609e69ff79afa63fe44dfa91f6f5Jean-Michel Trivi printf("%s\t Roles: ", (*it).mName.string()); 888df57a0d6d3b0609e69ff79afa63fe44dfa91f6f5Jean-Michel Trivi for (List<String8>::iterator itRoles = (*it).mRoles.begin() ; 889df57a0d6d3b0609e69ff79afa63fe44dfa91f6f5Jean-Michel Trivi itRoles != (*it).mRoles.end() ; ++itRoles) { 890df57a0d6d3b0609e69ff79afa63fe44dfa91f6f5Jean-Michel Trivi printf("%s\t", (*itRoles).string()); 891df57a0d6d3b0609e69ff79afa63fe44dfa91f6f5Jean-Michel Trivi } 892df57a0d6d3b0609e69ff79afa63fe44dfa91f6f5Jean-Michel Trivi printf("\n"); 89320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 89420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 89520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 896c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber sp<SurfaceComposerClient> composerClient; 897c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber sp<SurfaceControl> control; 898c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber 89916f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber if ((useSurfaceAlloc || useSurfaceTexAlloc) && !audioOnly) { 90016f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber if (useSurfaceAlloc) { 90116f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber composerClient = new SurfaceComposerClient; 90216f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber CHECK_EQ(composerClient->initCheck(), (status_t)OK); 90316f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber 90416f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber control = composerClient->createSurface( 90516f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber String8("A Surface"), 90616f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber 0, 90716f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber 1280, 90816f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber 800, 90916f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber PIXEL_FORMAT_RGB_565, 91016f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber 0); 91116f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber 91216f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber CHECK(control != NULL); 91316f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber CHECK(control->isValid()); 91416f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber 9152df788fb0c402938f827bf9c9ce2ca3ab1dcd464Mathias Agopian SurfaceComposerClient::openGlobalTransaction(); 91693d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber CHECK_EQ(control->setLayer(INT_MAX), (status_t)OK); 91716f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber CHECK_EQ(control->show(), (status_t)OK); 9182df788fb0c402938f827bf9c9ce2ca3ab1dcd464Mathias Agopian SurfaceComposerClient::closeGlobalTransaction(); 91916f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber 92016f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber gSurface = control->getSurface(); 92116f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber CHECK(gSurface != NULL); 92216f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber } else { 92316f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber CHECK(useSurfaceTexAlloc); 92416f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber 92516f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber sp<SurfaceTexture> texture = new SurfaceTexture(0 /* tex */); 92616f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber gSurface = new SurfaceTextureClient(texture); 92716f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber } 92893d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber 92993d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber CHECK_EQ((status_t)OK, 93093d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber native_window_api_connect( 93193d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber gSurface.get(), NATIVE_WINDOW_API_MEDIA)); 932c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber } 933c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber 93420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber DataSource::RegisterDefaultSniffers(); 93520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 93620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber OMXClient client; 93720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = client.connect(); 93820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9392d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber for (int k = 0; k < argc; ++k) { 940bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber bool syncInfoPresent = true; 941bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 9422d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber const char *filename = argv[k]; 94320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9441c70247536457f7b7fa84daa3482bd3d3b44e225Andreas Huber sp<DataSource> dataSource = DataSource::CreateFromURI(filename); 9450024245e134467d120b40099da16c467dc365e76Andreas Huber 946ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (strncasecmp(filename, "sine:", 5) 947ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber && strncasecmp(filename, "httplive://", 11) 948ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber && dataSource == NULL) { 949a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber fprintf(stderr, "Unable to create data source.\n"); 950a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber return 1; 951a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber } 952a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 9532d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber bool isJPEG = false; 95420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9552d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber size_t len = strlen(filename); 9562d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber if (len >= 4 && !strcasecmp(filename + len - 4, ".jpg")) { 9572d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber isJPEG = true; 9582d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 95920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 960ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber Vector<sp<MediaSource> > mediaSources; 9612d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber sp<MediaSource> mediaSource; 96220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9632d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber if (isJPEG) { 9642d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber mediaSource = new JPEGSource(dataSource); 965ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (gWriteMP4) { 966ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber mediaSources.push(mediaSource); 967ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 968a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber } else if (!strncasecmp("sine:", filename, 5)) { 969a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber char *end; 970a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber long sampleRate = strtol(filename + 5, &end, 10); 971a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 972a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber if (end == filename + 5) { 973a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber sampleRate = 44100; 974a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber } 975a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber mediaSource = new SineSource(sampleRate, 1); 976ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (gWriteMP4) { 977ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber mediaSources.push(mediaSource); 978ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 9792d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } else { 980348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber sp<MediaExtractor> extractor; 981348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber 9822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber if (!strncasecmp("httplive://", filename, 11)) { 983ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber String8 uri("http://"); 984ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber uri.append(filename + 11); 985ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 986a44153c1a57202fb538659eb50706e60454d6273Andreas Huber if (looper == NULL) { 987a44153c1a57202fb538659eb50706e60454d6273Andreas Huber looper = new ALooper; 988a44153c1a57202fb538659eb50706e60454d6273Andreas Huber looper->start(); 989a44153c1a57202fb538659eb50706e60454d6273Andreas Huber } 990a44153c1a57202fb538659eb50706e60454d6273Andreas Huber liveSession = new LiveSession; 991a44153c1a57202fb538659eb50706e60454d6273Andreas Huber looper->registerHandler(liveSession); 992a44153c1a57202fb538659eb50706e60454d6273Andreas Huber 993a44153c1a57202fb538659eb50706e60454d6273Andreas Huber liveSession->connect(uri.string()); 994a44153c1a57202fb538659eb50706e60454d6273Andreas Huber dataSource = liveSession->getDataSource(); 995ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 996ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber extractor = 997ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber MediaExtractor::Create( 998ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber dataSource, MEDIA_MIMETYPE_CONTAINER_MPEG2TS); 999ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 1000ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber syncInfoPresent = false; 1001348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber } else { 1002348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber extractor = MediaExtractor::Create(dataSource); 10032944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber 1004348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber if (extractor == NULL) { 1005348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber fprintf(stderr, "could not create extractor.\n"); 1006348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber return -1; 1007348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber } 1008fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber 1009fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber sp<MetaData> meta = extractor->getMetaData(); 1010fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber 1011fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber if (meta != NULL) { 1012fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber const char *mime; 1013fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 1014fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber 1015fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) { 1016fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber syncInfoPresent = false; 1017fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber } 1018fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber } 1019b93ad64a423975748c7f5e1a5ea94ab8681bc899James Dong } 102020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10212d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber size_t numTracks = extractor->countTracks(); 102220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1023ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (gWriteMP4) { 1024ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber bool haveAudio = false; 1025ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber bool haveVideo = false; 1026ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber for (size_t i = 0; i < numTracks; ++i) { 1027ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber sp<MediaSource> source = extractor->getTrack(i); 1028ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 1029ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber const char *mime; 1030ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber CHECK(source->getFormat()->findCString( 1031ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber kKeyMIMEType, &mime)); 1032ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 1033ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber bool useTrack = false; 1034ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (!haveAudio && !strncasecmp("audio/", mime, 6)) { 1035ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber haveAudio = true; 1036ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber useTrack = true; 1037ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } else if (!haveVideo && !strncasecmp("video/", mime, 6)) { 1038ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber haveVideo = true; 1039ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber useTrack = true; 1040ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 104120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1042ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (useTrack) { 1043ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber mediaSources.push(source); 104420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1045ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (haveAudio && haveVideo) { 1046ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber break; 1047ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 1048ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 10492d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 1050ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } else { 1051ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber sp<MetaData> meta; 1052ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber size_t i; 1053ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber for (i = 0; i < numTracks; ++i) { 1054ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber meta = extractor->getTrackMetaData( 1055ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber i, MediaExtractor::kIncludeExtensiveMetaData); 10562d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 1057ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber const char *mime; 1058ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber meta->findCString(kKeyMIMEType, &mime); 1059ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 1060ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (audioOnly && !strncasecmp(mime, "audio/", 6)) { 1061ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber break; 1062ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 1063ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 1064ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (!audioOnly && !strncasecmp(mime, "video/", 6)) { 1065ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber break; 1066ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 1067ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 1068ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber meta = NULL; 10692d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 1070a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 1071ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (meta == NULL) { 1072ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber fprintf(stderr, 1073ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber "No suitable %s track found. The '-a' option will " 1074ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber "target audio tracks only, the default is to target " 1075ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber "video tracks only.\n", 1076ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber audioOnly ? "audio" : "video"); 1077ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber return -1; 1078ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 1079a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 1080ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber int64_t thumbTimeUs; 1081ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (meta->findInt64(kKeyThumbnailTime, &thumbTimeUs)) { 1082ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber printf("thumbnailTime: %lld us (%.2f secs)\n", 1083ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber thumbTimeUs, thumbTimeUs / 1E6); 1084ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 10852d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 1086ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber mediaSource = extractor->getTrack(i); 10875c1e3581978164d169050686c73810ce59304471Andreas Huber } 108820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 108920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 109019c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber if (gWriteMP4) { 1091ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber writeSourcesToMP4(mediaSources, syncInfoPresent); 1092d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber } else if (dumpStream) { 1093d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber dumpSource(mediaSource, dumpStreamFilename); 109466d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } else if (seekTest) { 109566d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber performSeekTest(mediaSource); 109619c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber } else { 109719c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber playSource(&client, mediaSource); 109819c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber } 109920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 110020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 110116f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber if ((useSurfaceAlloc || useSurfaceTexAlloc) && !audioOnly) { 110293d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber CHECK_EQ((status_t)OK, 110393d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber native_window_api_disconnect( 110493d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber gSurface.get(), NATIVE_WINDOW_API_MEDIA)); 110593d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber 1106c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber gSurface.clear(); 1107c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber 110816f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber if (useSurfaceAlloc) { 110916f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber composerClient->dispose(); 111016f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber } 1111c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber } 1112c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber 111320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber client.disconnect(); 111420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 111520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return 0; 111620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 1117