stagefright.cpp revision db43b34c3428e480f8c4c66e7e88f4001f37f91e
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 17db43b34c3428e480f8c4c66e7e88f4001f37f91eMark Salyzyn#include <inttypes.h> 18db43b34c3428e480f8c4c66e7e88f4001f37f91eMark Salyzyn#include <fcntl.h> 19db43b34c3428e480f8c4c66e7e88f4001f37f91eMark Salyzyn#include <stdlib.h> 20db43b34c3428e480f8c4c66e7e88f4001f37f91eMark Salyzyn#include <string.h> 21db43b34c3428e480f8c4c66e7e88f4001f37f91eMark Salyzyn#include <sys/time.h> 22db43b34c3428e480f8c4c66e7e88f4001f37f91eMark Salyzyn 23bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber//#define LOG_NDEBUG 0 24bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber#define LOG_TAG "stagefright" 25bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber#include <media/stagefright/foundation/ADebug.h> 26bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 2726a417f68526fee861bb527f1a4e3ed548979f93Colin Cross#include "jpeg.h" 28a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber#include "SineSource.h" 29a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <binder/IServiceManager.h> 3120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <binder/ProcessState.h> 3220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/IMediaPlayerService.h> 33348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber#include <media/stagefright/foundation/ALooper.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 53c85a986af84962515c10499faab3dc8f9a0948d4Ying Wang#include <gui/GLConsumer.h> 541a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian#include <gui/Surface.h> 55df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopian#include <gui/SurfaceComposerClient.h> 56c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber 5720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberusing namespace android; 5820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 592d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huberstatic long gNumRepetitions; 6038b610fe53bb27946826d3f175f6fbe613f270daAndreas Huberstatic long gMaxNumFrames; // 0 means decode all available. 6180011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huberstatic long gReproduceBug; // if not -1. 625c1e3581978164d169050686c73810ce59304471Andreas Huberstatic bool gPreferSoftwareCodec; 63cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dongstatic bool gForceToUseHardwareCodec; 64a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huberstatic bool gPlaybackAudio; 6519c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huberstatic bool gWriteMP4; 66fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huberstatic bool gDisplayHistogram; 6719c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huberstatic String8 gWriteMP4Filename; 6820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 69c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huberstatic sp<ANativeWindow> gSurface; 70c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber 7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic int64_t getNowUs() { 7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber struct timeval tv; 7320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber gettimeofday(&tv, NULL); 7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 75d2858f047b2c52d719719532f24899c0e03c2099Andreas Huber return (int64_t)tv.tv_usec + tv.tv_sec * 1000000ll; 7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huberstatic int CompareIncreasing(const int64_t *a, const int64_t *b) { 79fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber return (*a) < (*b) ? -1 : (*a) > (*b) ? 1 : 0; 80fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber} 81fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 82fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huberstatic void displayDecodeHistogram(Vector<int64_t> *decodeTimesUs) { 83fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber printf("decode times:\n"); 84fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 85fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber decodeTimesUs->sort(CompareIncreasing); 86fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 87fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber size_t n = decodeTimesUs->size(); 88fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber int64_t minUs = decodeTimesUs->itemAt(0); 89fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber int64_t maxUs = decodeTimesUs->itemAt(n - 1); 90fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 91377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT printf("min decode time %" PRId64 " us (%.2f secs)\n", minUs, minUs / 1E6); 92377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT printf("max decode time %" PRId64 " us (%.2f secs)\n", maxUs, maxUs / 1E6); 93fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 94fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber size_t counts[100]; 95fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber for (size_t i = 0; i < 100; ++i) { 96fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber counts[i] = 0; 97fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber } 98fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 99fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber for (size_t i = 0; i < n; ++i) { 100fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber int64_t x = decodeTimesUs->itemAt(i); 101fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 102fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber size_t slot = ((x - minUs) * 100) / (maxUs - minUs); 103fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber if (slot == 100) { slot = 99; } 104fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 105fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber ++counts[slot]; 106fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber } 107fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 108fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber for (size_t i = 0; i < 100; ++i) { 109fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber int64_t slotUs = minUs + (i * (maxUs - minUs) / 100); 110fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 111fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber double fps = 1E6 / slotUs; 112377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT printf("[%.2f fps]: %zu\n", fps, counts[i]); 113fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber } 114fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber} 115fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 1168a674dcc94936e2306121016ab258b4c00cc9d98James Dongstatic void displayAVCProfileLevelIfPossible(const sp<MetaData>& meta) { 1178a674dcc94936e2306121016ab258b4c00cc9d98James Dong uint32_t type; 1188a674dcc94936e2306121016ab258b4c00cc9d98James Dong const void *data; 1198a674dcc94936e2306121016ab258b4c00cc9d98James Dong size_t size; 1208a674dcc94936e2306121016ab258b4c00cc9d98James Dong if (meta->findData(kKeyAVCC, &type, &data, &size)) { 1218a674dcc94936e2306121016ab258b4c00cc9d98James Dong const uint8_t *ptr = (const uint8_t *)data; 1228a674dcc94936e2306121016ab258b4c00cc9d98James Dong CHECK(size >= 7); 1238a674dcc94936e2306121016ab258b4c00cc9d98James Dong CHECK(ptr[0] == 1); // configurationVersion == 1 1248a674dcc94936e2306121016ab258b4c00cc9d98James Dong uint8_t profile = ptr[1]; 1258a674dcc94936e2306121016ab258b4c00cc9d98James Dong uint8_t level = ptr[3]; 1268a674dcc94936e2306121016ab258b4c00cc9d98James Dong fprintf(stderr, "AVC video profile %d and level %d\n", profile, level); 1278a674dcc94936e2306121016ab258b4c00cc9d98James Dong } 1288a674dcc94936e2306121016ab258b4c00cc9d98James Dong} 1298a674dcc94936e2306121016ab258b4c00cc9d98James Dong 130d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huberstatic void dumpSource(const sp<MediaSource> &source, const String8 &filename) { 131d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber FILE *out = fopen(filename.string(), "wb"); 132d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber 133d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber CHECK_EQ((status_t)OK, source->start()); 134d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber 135d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber status_t err; 136d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber for (;;) { 137d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber MediaBuffer *mbuf; 138d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber err = source->read(&mbuf); 139d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber 140d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber if (err == INFO_FORMAT_CHANGED) { 141d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber continue; 142d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber } else if (err != OK) { 143d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber break; 144d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber } 145d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber 146d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber CHECK_EQ( 147d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber fwrite((const uint8_t *)mbuf->data() + mbuf->range_offset(), 148d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber 1, 149d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber mbuf->range_length(), 150d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber out), 151d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber (ssize_t)mbuf->range_length()); 152d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber 153d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber mbuf->release(); 154d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber mbuf = NULL; 155d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber } 156d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber 157d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber CHECK_EQ((status_t)OK, source->stop()); 158d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber 159d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber fclose(out); 160d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber out = NULL; 161d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber} 162d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber 163c225da975515892952602cd3b1e24efc0cceaa4dAndreas Huberstatic void playSource(OMXClient *client, sp<MediaSource> &source) { 164693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<MetaData> meta = source->getFormat(); 165693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 166125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber const char *mime; 167125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 168125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber 169125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber sp<MediaSource> rawSource; 170125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_RAW, mime)) { 171125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber rawSource = source; 172125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber } else { 173cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong int flags = 0; 174cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong if (gPreferSoftwareCodec) { 175cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong flags |= OMXCodec::kPreferSoftwareCodecs; 176cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong } 177cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong if (gForceToUseHardwareCodec) { 178cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong CHECK(!gPreferSoftwareCodec); 179cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong flags |= OMXCodec::kHardwareCodecsOnly; 180cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong } 181125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber rawSource = OMXCodec::Create( 1825c1e3581978164d169050686c73810ce59304471Andreas Huber client->interface(), meta, false /* createEncoder */, source, 1835c1e3581978164d169050686c73810ce59304471Andreas Huber NULL /* matchComponentName */, 184cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong flags, 185c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber gSurface); 186693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 187125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber if (rawSource == NULL) { 188125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber fprintf(stderr, "Failed to instantiate decoder for '%s'.\n", mime); 189125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber return; 190125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber } 1918a674dcc94936e2306121016ab258b4c00cc9d98James Dong displayAVCProfileLevelIfPossible(meta); 192693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber } 193693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 194c225da975515892952602cd3b1e24efc0cceaa4dAndreas Huber source.clear(); 195c225da975515892952602cd3b1e24efc0cceaa4dAndreas Huber 196139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber status_t err = rawSource->start(); 197139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber 198139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber if (err != OK) { 199139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber fprintf(stderr, "rawSource returned error %d (0x%08x)\n", err, err); 200139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber return; 201139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber } 202693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 203a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber if (gPlaybackAudio) { 204a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber AudioPlayer *player = new AudioPlayer(NULL); 205a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber player->setSource(rawSource); 20664105f956f15969dbe1ec7319f6caa2a984e588bAndreas Huber rawSource.clear(); 207a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 208a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber player->start(true /* sourceAlreadyStarted */); 209a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 210a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber status_t finalStatus; 211a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber while (!player->reachedEOS(&finalStatus)) { 212a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber usleep(100000ll); 213a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber } 214a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 215a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber delete player; 216a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber player = NULL; 21764105f956f15969dbe1ec7319f6caa2a984e588bAndreas Huber 21864105f956f15969dbe1ec7319f6caa2a984e588bAndreas Huber return; 219a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber } else if (gReproduceBug >= 3 && gReproduceBug <= 5) { 220bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber int64_t durationUs; 221bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber CHECK(meta->findInt64(kKeyDuration, &durationUs)); 222bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 2235228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber status_t err; 2245228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber MediaBuffer *buffer; 2255228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber MediaSource::ReadOptions options; 2265228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber int64_t seekTimeUs = -1; 2275228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber for (;;) { 228125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber err = rawSource->read(&buffer, &options); 2295228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber options.clearSeekTo(); 2305228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2315228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber bool shouldSeek = false; 2327f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber if (err == INFO_FORMAT_CHANGED) { 233bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber CHECK(buffer == NULL); 2347f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber 2357f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber printf("format changed.\n"); 2367f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber continue; 2377f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber } else if (err != OK) { 2385228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber printf("reached EOF.\n"); 2395228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2405228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber shouldSeek = true; 2415228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } else { 24248c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int64_t timestampUs; 24348c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber CHECK(buffer->meta_data()->findInt64(kKeyTime, ×tampUs)); 2445228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2455228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber bool failed = false; 246af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber 2475228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber if (seekTimeUs >= 0) { 24848c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int64_t diff = timestampUs - seekTimeUs; 2495228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 250af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber if (diff < 0) { 251af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber diff = -diff; 252af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber } 253af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber 254af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber if ((gReproduceBug == 4 && diff > 500000) 255af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber || (gReproduceBug == 5 && timestampUs < 0)) { 256af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber printf("wanted: %.2f secs, got: %.2f secs\n", 257af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber seekTimeUs / 1E6, timestampUs / 1E6); 2585228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2595228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber printf("ERROR: "); 2605228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber failed = true; 2615228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 2625228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 2635228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 264377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT printf("buffer has timestamp %" PRId64 " us (%.2f secs)\n", 26548c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber timestampUs, timestampUs / 1E6); 2665228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2675228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber buffer->release(); 2685228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber buffer = NULL; 2695228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2705228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber if (failed) { 2715228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber break; 2725228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 2735228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2745228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber shouldSeek = ((double)rand() / RAND_MAX) < 0.1; 275af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber 276af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber if (gReproduceBug == 3) { 277af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber shouldSeek = false; 278af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber } 2795228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 2805228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2815228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber seekTimeUs = -1; 2825228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2835228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber if (shouldSeek) { 284af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber seekTimeUs = (rand() * (float)durationUs) / RAND_MAX; 2855228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber options.setSeekTo(seekTimeUs); 2865228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 287377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT printf("seeking to %" PRId64 " us (%.2f secs)\n", 2885228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber seekTimeUs, seekTimeUs / 1E6); 2895228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 2905228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 2915228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 292125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber rawSource->stop(); 2935228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2945228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber return; 2955228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 2965228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 2972d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber int n = 0; 298693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber int64_t startTime = getNowUs(); 299693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 3002d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber long numIterationsLeft = gNumRepetitions; 3012d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber MediaSource::ReadOptions options; 302dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 30336e3ee0094e845ed9d2a1c755addecfde9db3a68Andreas Huber int64_t sumDecodeUs = 0; 3047f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber int64_t totalBytes = 0; 30536e3ee0094e845ed9d2a1c755addecfde9db3a68Andreas Huber 306fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber Vector<int64_t> decodeTimesUs; 307fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 3082d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber while (numIterationsLeft-- > 0) { 30938b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber long numFrames = 0; 31038b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber 3112d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber MediaBuffer *buffer; 3122d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 3132d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber for (;;) { 31436e3ee0094e845ed9d2a1c755addecfde9db3a68Andreas Huber int64_t startDecodeUs = getNowUs(); 315125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber status_t err = rawSource->read(&buffer, &options); 31636e3ee0094e845ed9d2a1c755addecfde9db3a68Andreas Huber int64_t delayDecodeUs = getNowUs() - startDecodeUs; 31736e3ee0094e845ed9d2a1c755addecfde9db3a68Andreas Huber 3182d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber options.clearSeekTo(); 3192d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 3202d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber if (err != OK) { 321bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber CHECK(buffer == NULL); 3227f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber 3237f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber if (err == INFO_FORMAT_CHANGED) { 3247f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber printf("format changed.\n"); 3257f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber continue; 3267f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber } 3277f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber 3282d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber break; 3292d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 3302d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 331fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber if (buffer->range_length() > 0) { 332fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber if (gDisplayHistogram && n > 0) { 333fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber // Ignore the first time since it includes some setup 334fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber // cost. 335fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber decodeTimesUs.push(delayDecodeUs); 336fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber } 337fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 338fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber if ((n++ % 16) == 0) { 339fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber printf("."); 340fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber fflush(stdout); 341fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber } 3422d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 3432d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 34436e3ee0094e845ed9d2a1c755addecfde9db3a68Andreas Huber sumDecodeUs += delayDecodeUs; 3457f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber totalBytes += buffer->range_length(); 34636e3ee0094e845ed9d2a1c755addecfde9db3a68Andreas Huber 3472d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber buffer->release(); 3482d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber buffer = NULL; 34938b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber 35038b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber ++numFrames; 35138b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber if (gMaxNumFrames > 0 && numFrames == gMaxNumFrames) { 35238b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber break; 35338b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber } 35480011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber 35580011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber if (gReproduceBug == 1 && numFrames == 40) { 35680011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber printf("seeking past the end now."); 357a8a371c8a0d88d144d095404673d00cae6464fdeAndreas Huber options.setSeekTo(0x7fffffffL); 358e07db23c4935e47ecedfec7537ba95163e5836e5Andreas Huber } else if (gReproduceBug == 2 && numFrames == 40) { 359e07db23c4935e47ecedfec7537ba95163e5836e5Andreas Huber printf("seeking to 5 secs."); 360e07db23c4935e47ecedfec7537ba95163e5836e5Andreas Huber options.setSeekTo(5000000); 36180011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber } 362693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber } 363693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 3642d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber printf("$"); 3652d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber fflush(stdout); 3662d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 3672d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber options.setSeekTo(0); 368693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber } 3692d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 370125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber rawSource->stop(); 371693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber printf("\n"); 372693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 373693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber int64_t delay = getNowUs() - startTime; 3747f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber if (!strncasecmp("video/", mime, 6)) { 3757f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber printf("avg. %.2f fps\n", n * 1E6 / delay); 376693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 3777f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber printf("avg. time to decode one buffer %.2f usecs\n", 3787f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber (double)sumDecodeUs / n); 3797f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber 3807f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber printf("decoded a total of %d frame(s).\n", n); 381fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 382fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber if (gDisplayHistogram) { 383fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber displayDecodeHistogram(&decodeTimesUs); 384fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber } 3857f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber } else if (!strncasecmp("audio/", mime, 6)) { 3867f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber // Frame count makes less sense for audio, as the output buffer 3877f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber // sizes may be different across decoders. 3887f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber printf("avg. %.2f KB/sec\n", totalBytes / 1024 * 1E6 / delay); 3897f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber 390377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT printf("decoded a total of %" PRId64 " bytes\n", totalBytes); 3917f498b90a4300ef9badf14d202b0a67c26e20931Andreas Huber } 392693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber} 393693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 394bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber//////////////////////////////////////////////////////////////////////////////// 395bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 396bbc38312e4521cfd4299203591ef366b7624f043Andreas Huberstruct DetectSyncSource : public MediaSource { 397bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber DetectSyncSource(const sp<MediaSource> &source); 398bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 399bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber virtual status_t start(MetaData *params = NULL); 400bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber virtual status_t stop(); 401bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber virtual sp<MetaData> getFormat(); 402bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 403bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber virtual status_t read( 404bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber MediaBuffer **buffer, const ReadOptions *options); 405bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 406bbc38312e4521cfd4299203591ef366b7624f043Andreas Huberprivate: 407ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber enum StreamType { 408ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber AVC, 409ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber MPEG4, 410ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber H263, 411ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber OTHER, 412ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber }; 413ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 414bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber sp<MediaSource> mSource; 415ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber StreamType mStreamType; 416fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber bool mSawFirstIDRFrame; 417bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 418bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(DetectSyncSource); 419bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber}; 420bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 421bbc38312e4521cfd4299203591ef366b7624f043Andreas HuberDetectSyncSource::DetectSyncSource(const sp<MediaSource> &source) 422bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber : mSource(source), 423fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber mStreamType(OTHER), 424fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber mSawFirstIDRFrame(false) { 425bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber const char *mime; 426bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber CHECK(mSource->getFormat()->findCString(kKeyMIMEType, &mime)); 427bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 428ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 429ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber mStreamType = AVC; 430ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)) { 431ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber mStreamType = MPEG4; 432ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber CHECK(!"sync frame detection not implemented yet for MPEG4"); 433ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_H263)) { 434ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber mStreamType = H263; 435ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber CHECK(!"sync frame detection not implemented yet for H.263"); 436ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 437bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber} 438bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 439bbc38312e4521cfd4299203591ef366b7624f043Andreas Huberstatus_t DetectSyncSource::start(MetaData *params) { 440fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber mSawFirstIDRFrame = false; 441fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber 442bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber return mSource->start(params); 443bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber} 444bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 445bbc38312e4521cfd4299203591ef366b7624f043Andreas Huberstatus_t DetectSyncSource::stop() { 446bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber return mSource->stop(); 447bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber} 448bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 449bbc38312e4521cfd4299203591ef366b7624f043Andreas Hubersp<MetaData> DetectSyncSource::getFormat() { 450bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber return mSource->getFormat(); 451bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber} 452bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 453bbc38312e4521cfd4299203591ef366b7624f043Andreas Huberstatic bool isIDRFrame(MediaBuffer *buffer) { 454bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber const uint8_t *data = 455bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber (const uint8_t *)buffer->data() + buffer->range_offset(); 456bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber size_t size = buffer->range_length(); 457bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber for (size_t i = 0; i + 3 < size; ++i) { 458bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber if (!memcmp("\x00\x00\x01", &data[i], 3)) { 459bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber uint8_t nalType = data[i + 3] & 0x1f; 460bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber if (nalType == 5) { 461bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber return true; 462bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber } 463bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber } 464bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber } 465bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 466bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber return false; 467bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber} 468bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 469bbc38312e4521cfd4299203591ef366b7624f043Andreas Huberstatus_t DetectSyncSource::read( 470bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber MediaBuffer **buffer, const ReadOptions *options) { 471fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber for (;;) { 472fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber status_t err = mSource->read(buffer, options); 473bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 474fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber if (err != OK) { 475fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber return err; 476fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber } 477bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 478fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber if (mStreamType == AVC) { 479fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber bool isIDR = isIDRFrame(*buffer); 480fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber (*buffer)->meta_data()->setInt32(kKeyIsSyncFrame, isIDR); 481fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber if (isIDR) { 482fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber mSawFirstIDRFrame = true; 483fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber } 484fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber } else { 485fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber (*buffer)->meta_data()->setInt32(kKeyIsSyncFrame, true); 486fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber } 487fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber 488fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber if (mStreamType != AVC || mSawFirstIDRFrame) { 489fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber break; 490fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber } 491fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber 492fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber // Ignore everything up to the first IDR frame. 493fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber (*buffer)->release(); 494fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber *buffer = NULL; 495bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber } 496bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 497bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber return OK; 498bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber} 499bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 500bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber//////////////////////////////////////////////////////////////////////////////// 501bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 502ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huberstatic void writeSourcesToMP4( 503ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber Vector<sp<MediaSource> > &sources, bool syncInfoPresent) { 5040da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber#if 0 50519c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber sp<MPEG4Writer> writer = 50619c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber new MPEG4Writer(gWriteMP4Filename.string()); 5070da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber#else 5080da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber sp<MPEG2TSWriter> writer = 5090da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber new MPEG2TSWriter(gWriteMP4Filename.string()); 5100da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber#endif 51119c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber 512bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber // at most one minute. 513bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber writer->setMaxFileDuration(60000000ll); 514bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 515ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber for (size_t i = 0; i < sources.size(); ++i) { 516ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber sp<MediaSource> source = sources.editItemAt(i); 517ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 518ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber CHECK_EQ(writer->addSource( 519ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber syncInfoPresent ? source : new DetectSyncSource(source)), 520ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber (status_t)OK); 521ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 52219c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber 52319c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber sp<MetaData> params = new MetaData; 524de05c8eab188e98798f2b9c3dfac53dbc18ef584ztenghui params->setInt32(kKeyRealTimeRecording, false); 525bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber CHECK_EQ(writer->start(params.get()), (status_t)OK); 52619c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber 52719c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber while (!writer->reachedEOS()) { 52819c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber usleep(100000); 52919c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber } 53019c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber writer->stop(); 53119c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber} 53219c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber 53366d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huberstatic void performSeekTest(const sp<MediaSource> &source) { 534bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber CHECK_EQ((status_t)OK, source->start()); 53566d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 53666d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber int64_t durationUs; 53766d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber CHECK(source->getFormat()->findInt64(kKeyDuration, &durationUs)); 53866d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 53966d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber for (int64_t seekTimeUs = 0; seekTimeUs <= durationUs; 54066d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber seekTimeUs += 60000ll) { 54166d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber MediaSource::ReadOptions options; 54266d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber options.setSeekTo( 54366d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber seekTimeUs, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC); 54466d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 54566d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber MediaBuffer *buffer; 54666d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber status_t err; 54766d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber for (;;) { 54866d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber err = source->read(&buffer, &options); 54966d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 55066d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber options.clearSeekTo(); 55166d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 55266d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber if (err == INFO_FORMAT_CHANGED) { 55366d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber CHECK(buffer == NULL); 55466d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber continue; 55566d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } 55666d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 55766d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber if (err != OK) { 55866d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber CHECK(buffer == NULL); 55966d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber break; 56066d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } 56166d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 56266d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber if (buffer->range_length() > 0) { 56366d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber break; 56466d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } 56566d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 56666d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber CHECK(buffer != NULL); 56766d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 56866d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber buffer->release(); 56966d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber buffer = NULL; 57066d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } 57166d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 57266d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber if (err == OK) { 57366d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber int64_t timeUs; 57466d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs)); 57566d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 576377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT printf("%" PRId64 "\t%" PRId64 "\t%" PRId64 "\n", 577377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT seekTimeUs, timeUs, seekTimeUs - timeUs); 57866d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 57966d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber buffer->release(); 58066d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber buffer = NULL; 58166d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } else { 58266d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber printf("ERROR\n"); 58366d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber break; 58466d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } 58566d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } 58666d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 587bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber CHECK_EQ((status_t)OK, source->stop()); 58866d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber} 58966d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 5902d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huberstatic void usage(const char *me) { 59171bd6f8faf362659d3a9052549607039585f4922Jean-Michel Trivi fprintf(stderr, "usage: %s [options] [input_filename]\n", me); 5922d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber fprintf(stderr, " -h(elp)\n"); 5932d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber fprintf(stderr, " -a(udio)\n"); 5942d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber fprintf(stderr, " -n repetitions\n"); 5952d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber fprintf(stderr, " -l(ist) components\n"); 59638b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber fprintf(stderr, " -m max-number-of-frames-to-decode in each pass\n"); 59780011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber fprintf(stderr, " -b bug to reproduce\n"); 59818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber fprintf(stderr, " -p(rofiles) dump decoder profiles supported\n"); 5991b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber fprintf(stderr, " -t(humbnail) extract video thumbnail or album art\n"); 6005c1e3581978164d169050686c73810ce59304471Andreas Huber fprintf(stderr, " -s(oftware) prefer software codec\n"); 601cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong fprintf(stderr, " -r(hardware) force to use hardware codec\n"); 602a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber fprintf(stderr, " -o playback audio\n"); 60319c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber fprintf(stderr, " -w(rite) filename (write to .mp4 file)\n"); 60466d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber fprintf(stderr, " -k seek test\n"); 605fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber fprintf(stderr, " -x display a histogram of decoding times/fps " 606fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber "(video only)\n"); 607c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber fprintf(stderr, " -S allocate buffers from a surface\n"); 60816f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber fprintf(stderr, " -T allocate buffers from a surface texture\n"); 60971bd6f8faf362659d3a9052549607039585f4922Jean-Michel Trivi fprintf(stderr, " -d(ump) output_filename (raw stream data to a file)\n"); 61071bd6f8faf362659d3a9052549607039585f4922Jean-Michel Trivi fprintf(stderr, " -D(ump) output_filename (decoded PCM data to a file)\n"); 6112d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber} 6122d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 6131ab12519ec3d4922d1980f975fc884908879e0f0James Dongstatic void dumpCodecProfiles(const sp<IOMX>& omx, bool queryDecoders) { 6141ab12519ec3d4922d1980f975fc884908879e0f0James Dong const char *kMimeTypes[] = { 6151ab12519ec3d4922d1980f975fc884908879e0f0James Dong MEDIA_MIMETYPE_VIDEO_AVC, MEDIA_MIMETYPE_VIDEO_MPEG4, 6161ab12519ec3d4922d1980f975fc884908879e0f0James Dong MEDIA_MIMETYPE_VIDEO_H263, MEDIA_MIMETYPE_AUDIO_AAC, 6171ab12519ec3d4922d1980f975fc884908879e0f0James Dong MEDIA_MIMETYPE_AUDIO_AMR_NB, MEDIA_MIMETYPE_AUDIO_AMR_WB, 6181ab12519ec3d4922d1980f975fc884908879e0f0James Dong MEDIA_MIMETYPE_AUDIO_MPEG, MEDIA_MIMETYPE_AUDIO_G711_MLAW, 6191ab12519ec3d4922d1980f975fc884908879e0f0James Dong MEDIA_MIMETYPE_AUDIO_G711_ALAW, MEDIA_MIMETYPE_AUDIO_VORBIS, 62094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang MEDIA_MIMETYPE_VIDEO_VP8, MEDIA_MIMETYPE_VIDEO_VP9 6211ab12519ec3d4922d1980f975fc884908879e0f0James Dong }; 6221ab12519ec3d4922d1980f975fc884908879e0f0James Dong 623209ec37b27a4fb6c92005c91ecf993ec19a3d430James Dong const char *codecType = queryDecoders? "decoder" : "encoder"; 624209ec37b27a4fb6c92005c91ecf993ec19a3d430James Dong printf("%s profiles:\n", codecType); 6251ab12519ec3d4922d1980f975fc884908879e0f0James Dong 6261ab12519ec3d4922d1980f975fc884908879e0f0James Dong for (size_t k = 0; k < sizeof(kMimeTypes) / sizeof(kMimeTypes[0]); ++k) { 6271ab12519ec3d4922d1980f975fc884908879e0f0James Dong printf("type '%s':\n", kMimeTypes[k]); 6281ab12519ec3d4922d1980f975fc884908879e0f0James Dong 6291ab12519ec3d4922d1980f975fc884908879e0f0James Dong Vector<CodecCapabilities> results; 6301ab12519ec3d4922d1980f975fc884908879e0f0James Dong // will retrieve hardware and software codecs 6311ab12519ec3d4922d1980f975fc884908879e0f0James Dong CHECK_EQ(QueryCodecs(omx, kMimeTypes[k], 6321ab12519ec3d4922d1980f975fc884908879e0f0James Dong queryDecoders, 6331ab12519ec3d4922d1980f975fc884908879e0f0James Dong &results), (status_t)OK); 6341ab12519ec3d4922d1980f975fc884908879e0f0James Dong 6351ab12519ec3d4922d1980f975fc884908879e0f0James Dong for (size_t i = 0; i < results.size(); ++i) { 636209ec37b27a4fb6c92005c91ecf993ec19a3d430James Dong printf(" %s '%s' supports ", 637209ec37b27a4fb6c92005c91ecf993ec19a3d430James Dong codecType, results[i].mComponentName.string()); 6381ab12519ec3d4922d1980f975fc884908879e0f0James Dong 6391ab12519ec3d4922d1980f975fc884908879e0f0James Dong if (results[i].mProfileLevels.size() == 0) { 6401ab12519ec3d4922d1980f975fc884908879e0f0James Dong printf("NOTHING.\n"); 6411ab12519ec3d4922d1980f975fc884908879e0f0James Dong continue; 6421ab12519ec3d4922d1980f975fc884908879e0f0James Dong } 6431ab12519ec3d4922d1980f975fc884908879e0f0James Dong 6441ab12519ec3d4922d1980f975fc884908879e0f0James Dong for (size_t j = 0; j < results[i].mProfileLevels.size(); ++j) { 6451ab12519ec3d4922d1980f975fc884908879e0f0James Dong const CodecProfileLevel &profileLevel = 6461ab12519ec3d4922d1980f975fc884908879e0f0James Dong results[i].mProfileLevels[j]; 6471ab12519ec3d4922d1980f975fc884908879e0f0James Dong 648db43b34c3428e480f8c4c66e7e88f4001f37f91eMark Salyzyn printf("%s%" PRIu32 "/%" PRIu32, j > 0 ? ", " : "", 6491ab12519ec3d4922d1980f975fc884908879e0f0James Dong profileLevel.mProfile, profileLevel.mLevel); 6501ab12519ec3d4922d1980f975fc884908879e0f0James Dong } 6511ab12519ec3d4922d1980f975fc884908879e0f0James Dong 6521ab12519ec3d4922d1980f975fc884908879e0f0James Dong printf("\n"); 6531ab12519ec3d4922d1980f975fc884908879e0f0James Dong } 6541ab12519ec3d4922d1980f975fc884908879e0f0James Dong } 6551ab12519ec3d4922d1980f975fc884908879e0f0James Dong} 6561ab12519ec3d4922d1980f975fc884908879e0f0James Dong 65720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberint main(int argc, char **argv) { 65820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber android::ProcessState::self()->startThreadPool(); 65920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6600024245e134467d120b40099da16c467dc365e76Andreas Huber bool audioOnly = false; 6612d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber bool listComponents = false; 66218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber bool dumpProfiles = false; 6635c1e3581978164d169050686c73810ce59304471Andreas Huber bool extractThumbnail = false; 66466d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber bool seekTest = false; 665c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber bool useSurfaceAlloc = false; 66616f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber bool useSurfaceTexAlloc = false; 667d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber bool dumpStream = false; 668c434ac82b57108bd08f58612f6ac8cbc92dbd975Marco Nelissen bool dumpPCMStream = false; 669d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber String8 dumpStreamFilename; 6702d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber gNumRepetitions = 1; 67138b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber gMaxNumFrames = 0; 67280011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber gReproduceBug = -1; 6735c1e3581978164d169050686c73810ce59304471Andreas Huber gPreferSoftwareCodec = false; 674cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong gForceToUseHardwareCodec = false; 675a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber gPlaybackAudio = false; 67619c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber gWriteMP4 = false; 677fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber gDisplayHistogram = false; 6782d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 679348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber sp<ALooper> looper; 680348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber 6812d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber int res; 682c434ac82b57108bd08f58612f6ac8cbc92dbd975Marco Nelissen while ((res = getopt(argc, argv, "han:lm:b:ptsrow:kxSTd:D:")) >= 0) { 6832d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber switch (res) { 6842d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber case 'a': 6852d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber { 6862d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber audioOnly = true; 6872d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber break; 6882d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 6892d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 690d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber case 'd': 691d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber { 692d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber dumpStream = true; 693d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber dumpStreamFilename.setTo(optarg); 694d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber break; 695d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber } 696d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber 697c434ac82b57108bd08f58612f6ac8cbc92dbd975Marco Nelissen case 'D': 698c434ac82b57108bd08f58612f6ac8cbc92dbd975Marco Nelissen { 699c434ac82b57108bd08f58612f6ac8cbc92dbd975Marco Nelissen dumpPCMStream = true; 700c434ac82b57108bd08f58612f6ac8cbc92dbd975Marco Nelissen audioOnly = true; 701c434ac82b57108bd08f58612f6ac8cbc92dbd975Marco Nelissen dumpStreamFilename.setTo(optarg); 702c434ac82b57108bd08f58612f6ac8cbc92dbd975Marco Nelissen break; 703c434ac82b57108bd08f58612f6ac8cbc92dbd975Marco Nelissen } 704c434ac82b57108bd08f58612f6ac8cbc92dbd975Marco Nelissen 7052d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber case 'l': 7062d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber { 7072d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber listComponents = true; 7082d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber break; 7092d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 7102d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 71138b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber case 'm': 7122d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber case 'n': 71380011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber case 'b': 7142d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber { 7152d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber char *end; 7162d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber long x = strtol(optarg, &end, 10); 7172d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 7182d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber if (*end != '\0' || end == optarg || x <= 0) { 7192d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber x = 1; 7202d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 7212d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 72238b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber if (res == 'n') { 72338b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber gNumRepetitions = x; 72480011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber } else if (res == 'm') { 72538b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber gMaxNumFrames = x; 72680011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber } else { 72780011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber CHECK_EQ(res, 'b'); 72880011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber gReproduceBug = x; 72938b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber } 7302d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber break; 7312d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 7322d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 73319c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber case 'w': 73419c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber { 73519c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber gWriteMP4 = true; 73619c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber gWriteMP4Filename.setTo(optarg); 73719c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber break; 73819c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber } 73919c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber 74018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber case 'p': 74118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber { 74218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber dumpProfiles = true; 74318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber break; 74418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber } 74518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 7465c1e3581978164d169050686c73810ce59304471Andreas Huber case 't': 7475c1e3581978164d169050686c73810ce59304471Andreas Huber { 7485c1e3581978164d169050686c73810ce59304471Andreas Huber extractThumbnail = true; 7495c1e3581978164d169050686c73810ce59304471Andreas Huber break; 7505c1e3581978164d169050686c73810ce59304471Andreas Huber } 7515c1e3581978164d169050686c73810ce59304471Andreas Huber 7525c1e3581978164d169050686c73810ce59304471Andreas Huber case 's': 7535c1e3581978164d169050686c73810ce59304471Andreas Huber { 7545c1e3581978164d169050686c73810ce59304471Andreas Huber gPreferSoftwareCodec = true; 7555c1e3581978164d169050686c73810ce59304471Andreas Huber break; 7565c1e3581978164d169050686c73810ce59304471Andreas Huber } 7575c1e3581978164d169050686c73810ce59304471Andreas Huber 758cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong case 'r': 759cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong { 760cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong gForceToUseHardwareCodec = true; 761cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong break; 762cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong } 763cfc7a7feb81b946341bc01ade68291bf8b6e1037James Dong 764a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber case 'o': 765a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber { 766a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber gPlaybackAudio = true; 767a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber break; 768a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber } 769a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 77066d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber case 'k': 77166d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber { 77266d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber seekTest = true; 77366d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber break; 77466d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } 77566d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber 776fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber case 'x': 777fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber { 778fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber gDisplayHistogram = true; 779fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber break; 780fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber } 781fed975bb3775ebdac136b21e01a9d49aec5b4d23Andreas Huber 782c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber case 'S': 783c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber { 784c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber useSurfaceAlloc = true; 785c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber break; 786c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber } 787c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber 78816f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber case 'T': 78916f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber { 79016f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber useSurfaceTexAlloc = true; 79116f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber break; 79216f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber } 79316f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber 7942d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber case '?': 7952d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber case 'h': 7962d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber default: 7972d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber { 7982d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber usage(argv[0]); 7992d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber exit(1); 8002d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber break; 8012d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 8022d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 8032d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 8042d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 805a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber if (gPlaybackAudio && !audioOnly) { 806a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber // This doesn't make any sense if we're decoding the video track. 807a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber gPlaybackAudio = false; 808a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber } 809a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 8102d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber argc -= optind; 8112d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber argv += optind; 8122d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 8135c1e3581978164d169050686c73810ce59304471Andreas Huber if (extractThumbnail) { 8145c1e3581978164d169050686c73810ce59304471Andreas Huber sp<IServiceManager> sm = defaultServiceManager(); 8155c1e3581978164d169050686c73810ce59304471Andreas Huber sp<IBinder> binder = sm->getService(String16("media.player")); 8165c1e3581978164d169050686c73810ce59304471Andreas Huber sp<IMediaPlayerService> service = 8175c1e3581978164d169050686c73810ce59304471Andreas Huber interface_cast<IMediaPlayerService>(binder); 8185c1e3581978164d169050686c73810ce59304471Andreas Huber 8195c1e3581978164d169050686c73810ce59304471Andreas Huber CHECK(service.get() != NULL); 8205c1e3581978164d169050686c73810ce59304471Andreas Huber 8215c1e3581978164d169050686c73810ce59304471Andreas Huber sp<IMediaMetadataRetriever> retriever = 8228d6cc842e8d525405c68e57fdf3bc5da0b4d7e87Glenn Kasten service->createMetadataRetriever(); 8235c1e3581978164d169050686c73810ce59304471Andreas Huber 8245c1e3581978164d169050686c73810ce59304471Andreas Huber CHECK(retriever != NULL); 8255c1e3581978164d169050686c73810ce59304471Andreas Huber 8265c1e3581978164d169050686c73810ce59304471Andreas Huber for (int k = 0; k < argc; ++k) { 8275c1e3581978164d169050686c73810ce59304471Andreas Huber const char *filename = argv[k]; 8285c1e3581978164d169050686c73810ce59304471Andreas Huber 829515e855eae78aa495da58356486aaa666cb57fd1James Dong bool failed = true; 830f4b7d94062c896dca565d849c6188cd3489be257Andreas Huber 831f4b7d94062c896dca565d849c6188cd3489be257Andreas Huber int fd = open(filename, O_RDONLY | O_LARGEFILE); 832f4b7d94062c896dca565d849c6188cd3489be257Andreas Huber CHECK_GE(fd, 0); 833f4b7d94062c896dca565d849c6188cd3489be257Andreas Huber 834f4b7d94062c896dca565d849c6188cd3489be257Andreas Huber off64_t fileSize = lseek64(fd, 0, SEEK_END); 835f4b7d94062c896dca565d849c6188cd3489be257Andreas Huber CHECK_GE(fileSize, 0ll); 836f4b7d94062c896dca565d849c6188cd3489be257Andreas Huber 837f4b7d94062c896dca565d849c6188cd3489be257Andreas Huber CHECK_EQ(retriever->setDataSource(fd, 0, fileSize), (status_t)OK); 838f4b7d94062c896dca565d849c6188cd3489be257Andreas Huber 839f4b7d94062c896dca565d849c6188cd3489be257Andreas Huber close(fd); 840f4b7d94062c896dca565d849c6188cd3489be257Andreas Huber fd = -1; 841f4b7d94062c896dca565d849c6188cd3489be257Andreas Huber 84216afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong sp<IMemory> mem = 84316afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong retriever->getFrameAtTime(-1, 84416afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC); 8455c1e3581978164d169050686c73810ce59304471Andreas Huber 8461b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber if (mem != NULL) { 847515e855eae78aa495da58356486aaa666cb57fd1James Dong failed = false; 84816afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong printf("getFrameAtTime(%s) => OK\n", filename); 849f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber 850f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber VideoFrame *frame = (VideoFrame *)mem->pointer(); 851f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber 85226a417f68526fee861bb527f1a4e3ed548979f93Colin Cross CHECK_EQ(writeJpegFile("/sdcard/out.jpg", 85326a417f68526fee861bb527f1a4e3ed548979f93Colin Cross (uint8_t *)frame + sizeof(VideoFrame), 85426a417f68526fee861bb527f1a4e3ed548979f93Colin Cross frame->mWidth, frame->mHeight), 0); 855515e855eae78aa495da58356486aaa666cb57fd1James Dong } 856515e855eae78aa495da58356486aaa666cb57fd1James Dong 857515e855eae78aa495da58356486aaa666cb57fd1James Dong { 8581b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber mem = retriever->extractAlbumArt(); 8591b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber 8601b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber if (mem != NULL) { 861515e855eae78aa495da58356486aaa666cb57fd1James Dong failed = false; 8621b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber printf("extractAlbumArt(%s) => OK\n", filename); 8631b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber } 8641b950bcd3c11a17186cf971e23f5ec829d092ed5Andreas Huber } 865515e855eae78aa495da58356486aaa666cb57fd1James Dong 866515e855eae78aa495da58356486aaa666cb57fd1James Dong if (failed) { 867515e855eae78aa495da58356486aaa666cb57fd1James Dong printf("both getFrameAtTime and extractAlbumArt " 868515e855eae78aa495da58356486aaa666cb57fd1James Dong "failed on file '%s'.\n", filename); 869515e855eae78aa495da58356486aaa666cb57fd1James Dong } 8705c1e3581978164d169050686c73810ce59304471Andreas Huber } 8715c1e3581978164d169050686c73810ce59304471Andreas Huber 8725c1e3581978164d169050686c73810ce59304471Andreas Huber return 0; 8735c1e3581978164d169050686c73810ce59304471Andreas Huber } 8745c1e3581978164d169050686c73810ce59304471Andreas Huber 87518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber if (dumpProfiles) { 87618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber sp<IServiceManager> sm = defaultServiceManager(); 87718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber sp<IBinder> binder = sm->getService(String16("media.player")); 87818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber sp<IMediaPlayerService> service = 87918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber interface_cast<IMediaPlayerService>(binder); 88018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 88118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber CHECK(service.get() != NULL); 88218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 883318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber sp<IOMX> omx = service->getOMX(); 88418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber CHECK(omx.get() != NULL); 8851ab12519ec3d4922d1980f975fc884908879e0f0James Dong dumpCodecProfiles(omx, true /* queryDecoders */); 8861ab12519ec3d4922d1980f975fc884908879e0f0James Dong dumpCodecProfiles(omx, false /* queryDecoders */); 88718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber } 88818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 8892d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber if (listComponents) { 89020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<IServiceManager> sm = defaultServiceManager(); 89120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<IBinder> binder = sm->getService(String16("media.player")); 89220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder); 89320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 894693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber CHECK(service.get() != NULL); 89520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 896318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber sp<IOMX> omx = service->getOMX(); 897693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber CHECK(omx.get() != NULL); 89820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 899134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber List<IOMX::ComponentInfo> list; 900318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber omx->listNodes(&list); 90120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 902134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber for (List<IOMX::ComponentInfo>::iterator it = list.begin(); 90320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber it != list.end(); ++it) { 904df57a0d6d3b0609e69ff79afa63fe44dfa91f6f5Jean-Michel Trivi printf("%s\t Roles: ", (*it).mName.string()); 905df57a0d6d3b0609e69ff79afa63fe44dfa91f6f5Jean-Michel Trivi for (List<String8>::iterator itRoles = (*it).mRoles.begin() ; 906df57a0d6d3b0609e69ff79afa63fe44dfa91f6f5Jean-Michel Trivi itRoles != (*it).mRoles.end() ; ++itRoles) { 907df57a0d6d3b0609e69ff79afa63fe44dfa91f6f5Jean-Michel Trivi printf("%s\t", (*itRoles).string()); 908df57a0d6d3b0609e69ff79afa63fe44dfa91f6f5Jean-Michel Trivi } 909df57a0d6d3b0609e69ff79afa63fe44dfa91f6f5Jean-Michel Trivi printf("\n"); 91020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 91120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 91220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 913c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber sp<SurfaceComposerClient> composerClient; 914c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber sp<SurfaceControl> control; 915c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber 91616f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber if ((useSurfaceAlloc || useSurfaceTexAlloc) && !audioOnly) { 91716f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber if (useSurfaceAlloc) { 91816f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber composerClient = new SurfaceComposerClient; 91916f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber CHECK_EQ(composerClient->initCheck(), (status_t)OK); 92016f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber 92116f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber control = composerClient->createSurface( 92216f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber String8("A Surface"), 92316f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber 1280, 92416f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber 800, 92516f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber PIXEL_FORMAT_RGB_565, 92616f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber 0); 92716f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber 92816f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber CHECK(control != NULL); 92916f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber CHECK(control->isValid()); 93016f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber 9312df788fb0c402938f827bf9c9ce2ca3ab1dcd464Mathias Agopian SurfaceComposerClient::openGlobalTransaction(); 93293d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber CHECK_EQ(control->setLayer(INT_MAX), (status_t)OK); 93316f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber CHECK_EQ(control->show(), (status_t)OK); 9342df788fb0c402938f827bf9c9ce2ca3ab1dcd464Mathias Agopian SurfaceComposerClient::closeGlobalTransaction(); 93516f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber 93616f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber gSurface = control->getSurface(); 93716f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber CHECK(gSurface != NULL); 93816f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber } else { 93916f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber CHECK(useSurfaceTexAlloc); 94016f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber 9418d764bfc74c40641f018a0aa87d6f484aec92eaeMathias Agopian sp<BufferQueue> bq = new BufferQueue(); 9428d764bfc74c40641f018a0aa87d6f484aec92eaeMathias Agopian sp<GLConsumer> texture = new GLConsumer(bq, 0 /* tex */); 9439e65879ebc633334bb061e8164c46602ad983c50Ying Wang gSurface = new Surface(bq); 94416f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber } 94593d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber 94693d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber CHECK_EQ((status_t)OK, 94793d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber native_window_api_connect( 94893d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber gSurface.get(), NATIVE_WINDOW_API_MEDIA)); 949c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber } 950c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber 95120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber DataSource::RegisterDefaultSniffers(); 95220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 95320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber OMXClient client; 95420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = client.connect(); 95520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9562d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber for (int k = 0; k < argc; ++k) { 957bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber bool syncInfoPresent = true; 958bbc38312e4521cfd4299203591ef366b7624f043Andreas Huber 9592d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber const char *filename = argv[k]; 96020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9611c70247536457f7b7fa84daa3482bd3d3b44e225Andreas Huber sp<DataSource> dataSource = DataSource::CreateFromURI(filename); 9620024245e134467d120b40099da16c467dc365e76Andreas Huber 96314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (strncasecmp(filename, "sine:", 5) && dataSource == NULL) { 964a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber fprintf(stderr, "Unable to create data source.\n"); 965a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber return 1; 966a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber } 967a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 9682d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber bool isJPEG = false; 96920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9702d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber size_t len = strlen(filename); 9712d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber if (len >= 4 && !strcasecmp(filename + len - 4, ".jpg")) { 9722d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber isJPEG = true; 9732d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 97420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 975ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber Vector<sp<MediaSource> > mediaSources; 9762d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber sp<MediaSource> mediaSource; 97720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9782d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber if (isJPEG) { 9792d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber mediaSource = new JPEGSource(dataSource); 980ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (gWriteMP4) { 981ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber mediaSources.push(mediaSource); 982ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 983a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber } else if (!strncasecmp("sine:", filename, 5)) { 984a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber char *end; 985a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber long sampleRate = strtol(filename + 5, &end, 10); 986a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 987a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber if (end == filename + 5) { 988a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber sampleRate = 44100; 989a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber } 990a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber mediaSource = new SineSource(sampleRate, 1); 991ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (gWriteMP4) { 992ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber mediaSources.push(mediaSource); 993ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 9942d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } else { 99514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource); 996348a8eab84f4bba76c04ca83b2f5418467aa1a48Andreas Huber 99714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (extractor == NULL) { 99814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber fprintf(stderr, "could not create extractor.\n"); 99914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return -1; 100014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 10012944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber 100214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<MetaData> meta = extractor->getMetaData(); 1003fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber 100414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (meta != NULL) { 100514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber const char *mime; 100614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 1007fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber 100814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) { 100914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber syncInfoPresent = false; 1010fed045821d5eae63b34549cb44b7d26602f5c543Andreas Huber } 1011b93ad64a423975748c7f5e1a5ea94ab8681bc899James Dong } 101220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10132d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber size_t numTracks = extractor->countTracks(); 101420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1015ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (gWriteMP4) { 1016ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber bool haveAudio = false; 1017ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber bool haveVideo = false; 1018ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber for (size_t i = 0; i < numTracks; ++i) { 1019ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber sp<MediaSource> source = extractor->getTrack(i); 1020ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 1021ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber const char *mime; 1022ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber CHECK(source->getFormat()->findCString( 1023ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber kKeyMIMEType, &mime)); 1024ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 1025ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber bool useTrack = false; 1026ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (!haveAudio && !strncasecmp("audio/", mime, 6)) { 1027ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber haveAudio = true; 1028ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber useTrack = true; 1029ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } else if (!haveVideo && !strncasecmp("video/", mime, 6)) { 1030ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber haveVideo = true; 1031ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber useTrack = true; 1032ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 103320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1034ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (useTrack) { 1035ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber mediaSources.push(source); 103620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1037ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (haveAudio && haveVideo) { 1038ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber break; 1039ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 1040ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 10412d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 1042ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } else { 1043ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber sp<MetaData> meta; 1044ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber size_t i; 1045ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber for (i = 0; i < numTracks; ++i) { 1046ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber meta = extractor->getTrackMetaData( 1047ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber i, MediaExtractor::kIncludeExtensiveMetaData); 10482d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 1049ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber const char *mime; 1050ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber meta->findCString(kKeyMIMEType, &mime); 1051ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 1052ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (audioOnly && !strncasecmp(mime, "audio/", 6)) { 1053ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber break; 1054ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 1055ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 1056ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (!audioOnly && !strncasecmp(mime, "video/", 6)) { 1057ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber break; 1058ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 1059ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber 1060ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber meta = NULL; 10612d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 1062a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 1063ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (meta == NULL) { 1064ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber fprintf(stderr, 1065ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber "No suitable %s track found. The '-a' option will " 1066ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber "target audio tracks only, the default is to target " 1067ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber "video tracks only.\n", 1068ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber audioOnly ? "audio" : "video"); 1069ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber return -1; 1070ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 1071a98420e863c374d1f15309467f2a1fc58d979d3bAndreas Huber 1072ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber int64_t thumbTimeUs; 1073ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber if (meta->findInt64(kKeyThumbnailTime, &thumbTimeUs)) { 1074377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT printf("thumbnailTime: %" PRId64 " us (%.2f secs)\n", 1075ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber thumbTimeUs, thumbTimeUs / 1E6); 1076ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber } 10772d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 1078ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber mediaSource = extractor->getTrack(i); 10795c1e3581978164d169050686c73810ce59304471Andreas Huber } 108020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 108120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 108219c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber if (gWriteMP4) { 1083ea314ac049884b31c5a2a4fecc42e8a50f928a33Andreas Huber writeSourcesToMP4(mediaSources, syncInfoPresent); 1084d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber } else if (dumpStream) { 1085d10c07603a28429beb7471c0fb23a5f9ec90bf26Andreas Huber dumpSource(mediaSource, dumpStreamFilename); 1086c434ac82b57108bd08f58612f6ac8cbc92dbd975Marco Nelissen } else if (dumpPCMStream) { 1087c434ac82b57108bd08f58612f6ac8cbc92dbd975Marco Nelissen OMXClient client; 1088c434ac82b57108bd08f58612f6ac8cbc92dbd975Marco Nelissen CHECK_EQ(client.connect(), (status_t)OK); 1089c434ac82b57108bd08f58612f6ac8cbc92dbd975Marco Nelissen 1090c434ac82b57108bd08f58612f6ac8cbc92dbd975Marco Nelissen sp<MediaSource> decSource = 1091c434ac82b57108bd08f58612f6ac8cbc92dbd975Marco Nelissen OMXCodec::Create( 1092c434ac82b57108bd08f58612f6ac8cbc92dbd975Marco Nelissen client.interface(), 1093c434ac82b57108bd08f58612f6ac8cbc92dbd975Marco Nelissen mediaSource->getFormat(), 1094c434ac82b57108bd08f58612f6ac8cbc92dbd975Marco Nelissen false, 1095c434ac82b57108bd08f58612f6ac8cbc92dbd975Marco Nelissen mediaSource, 1096c434ac82b57108bd08f58612f6ac8cbc92dbd975Marco Nelissen 0, 1097c434ac82b57108bd08f58612f6ac8cbc92dbd975Marco Nelissen 0); 1098c434ac82b57108bd08f58612f6ac8cbc92dbd975Marco Nelissen 1099c434ac82b57108bd08f58612f6ac8cbc92dbd975Marco Nelissen dumpSource(decSource, dumpStreamFilename); 110066d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber } else if (seekTest) { 110166d6f1fcd9cb80a603b833e93779eb0dfb5e67eeAndreas Huber performSeekTest(mediaSource); 110219c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber } else { 110319c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber playSource(&client, mediaSource); 110419c9a1e2bb6ead5e1e895aea8be573fe0f8cc7bbAndreas Huber } 110520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 110620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 110716f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber if ((useSurfaceAlloc || useSurfaceTexAlloc) && !audioOnly) { 110893d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber CHECK_EQ((status_t)OK, 110993d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber native_window_api_disconnect( 111093d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber gSurface.get(), NATIVE_WINDOW_API_MEDIA)); 111193d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber 1112c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber gSurface.clear(); 1113c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber 111416f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber if (useSurfaceAlloc) { 111516f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber composerClient->dispose(); 111616f7863149b400ca52e2e3cb83e50534fee6b58bAndreas Huber } 1117c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber } 1118c83d4f56f9dd45f71c0f4673737f0ad1cce60abbAndreas Huber 111920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber client.disconnect(); 112020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 112120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return 0; 112220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 1123