stagefright.cpp revision 5c1e3581978164d169050686c73810ce59304471
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 1720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <sys/time.h> 1820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdlib.h> 202d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber#include <string.h> 212d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber#include <unistd.h> 2220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <binder/IServiceManager.h> 2420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <binder/ProcessState.h> 2520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/IMediaPlayerService.h> 262ea76ead54982376e32ab196093babded80e05e4Andreas Huber#include <media/stagefright/CachingDataSource.h> 27bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber#include <media/stagefright/FileSource.h> 282ea76ead54982376e32ab196093babded80e05e4Andreas Huber#include <media/stagefright/HTTPDataSource.h> 29777893a928680f09e306b4b9efc1d5cf4479a9daAndreas Huber#include <media/stagefright/JPEGSource.h> 30693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/MediaDebug.h> 3118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h> 3220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaExtractor.h> 3320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaSource.h> 3420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h> 3520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/OMXClient.h> 36693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber#include <media/stagefright/OMXCodec.h> 375c1e3581978164d169050686c73810ce59304471Andreas Huber#include <media/mediametadataretriever.h> 3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberusing namespace android; 4020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 412d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huberstatic long gNumRepetitions; 4238b610fe53bb27946826d3f175f6fbe613f270daAndreas Huberstatic long gMaxNumFrames; // 0 means decode all available. 4380011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huberstatic long gReproduceBug; // if not -1. 445c1e3581978164d169050686c73810ce59304471Andreas Huberstatic bool gPreferSoftwareCodec; 4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic int64_t getNowUs() { 4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber struct timeval tv; 4820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber gettimeofday(&tv, NULL); 4920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return (int64_t)tv.tv_usec + tv.tv_sec * 1000000; 5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 53693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberstatic void playSource(OMXClient *client, const sp<MediaSource> &source) { 54693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<MetaData> meta = source->getFormat(); 55693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 56125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber const char *mime; 57125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 58125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber 59125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber sp<MediaSource> rawSource; 60125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_RAW, mime)) { 61125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber rawSource = source; 62125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber } else { 63125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber rawSource = OMXCodec::Create( 645c1e3581978164d169050686c73810ce59304471Andreas Huber client->interface(), meta, false /* createEncoder */, source, 655c1e3581978164d169050686c73810ce59304471Andreas Huber NULL /* matchComponentName */, 665c1e3581978164d169050686c73810ce59304471Andreas Huber gPreferSoftwareCodec ? OMXCodec::kPreferSoftwareCodecs : 0); 67693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 68125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber if (rawSource == NULL) { 69125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber fprintf(stderr, "Failed to instantiate decoder for '%s'.\n", mime); 70125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber return; 71125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber } 72693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber } 73693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 74125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber rawSource->start(); 75693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 76af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber if (gReproduceBug >= 3 && gReproduceBug <= 5) { 77bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber int64_t durationUs; 78bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber CHECK(meta->findInt64(kKeyDuration, &durationUs)); 79bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 805228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber status_t err; 815228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber MediaBuffer *buffer; 825228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber MediaSource::ReadOptions options; 835228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber int64_t seekTimeUs = -1; 845228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber for (;;) { 85125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber err = rawSource->read(&buffer, &options); 865228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber options.clearSeekTo(); 875228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 885228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber bool shouldSeek = false; 897f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber if (err == INFO_FORMAT_CHANGED) { 907f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber CHECK_EQ(buffer, NULL); 917f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber 927f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber printf("format changed.\n"); 937f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber continue; 947f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber } else if (err != OK) { 955228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber printf("reached EOF.\n"); 965228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 975228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber shouldSeek = true; 985228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } else { 9948c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int64_t timestampUs; 10048c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber CHECK(buffer->meta_data()->findInt64(kKeyTime, ×tampUs)); 1015228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 1025228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber bool failed = false; 103af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber 1045228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber if (seekTimeUs >= 0) { 10548c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int64_t diff = timestampUs - seekTimeUs; 1065228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 107af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber if (diff < 0) { 108af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber diff = -diff; 109af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber } 110af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber 111af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber if ((gReproduceBug == 4 && diff > 500000) 112af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber || (gReproduceBug == 5 && timestampUs < 0)) { 113af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber printf("wanted: %.2f secs, got: %.2f secs\n", 114af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber seekTimeUs / 1E6, timestampUs / 1E6); 1155228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 1165228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber printf("ERROR: "); 1175228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber failed = true; 1185228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 1195228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 1205228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 1215228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber printf("buffer has timestamp %lld us (%.2f secs)\n", 12248c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber timestampUs, timestampUs / 1E6); 1235228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 1245228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber buffer->release(); 1255228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber buffer = NULL; 1265228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 1275228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber if (failed) { 1285228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber break; 1295228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 1305228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 1315228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber shouldSeek = ((double)rand() / RAND_MAX) < 0.1; 132af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber 133af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber if (gReproduceBug == 3) { 134af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber shouldSeek = false; 135af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber } 1365228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 1375228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 1385228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber seekTimeUs = -1; 1395228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 1405228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber if (shouldSeek) { 141af6757c1de099b5352a52b8ed4a67af40f49fc78Andreas Huber seekTimeUs = (rand() * (float)durationUs) / RAND_MAX; 1425228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber options.setSeekTo(seekTimeUs); 1435228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 1445228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber printf("seeking to %lld us (%.2f secs)\n", 1455228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber seekTimeUs, seekTimeUs / 1E6); 1465228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 1475228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 1485228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 149125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber rawSource->stop(); 1505228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 1515228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber return; 1525228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber } 1535228dd1b7468bfc86a807a299f515d33048f96acAndreas Huber 1542d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber int n = 0; 155693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber int64_t startTime = getNowUs(); 156693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 1572d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber long numIterationsLeft = gNumRepetitions; 1582d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber MediaSource::ReadOptions options; 159dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1602d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber while (numIterationsLeft-- > 0) { 16138b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber long numFrames = 0; 16238b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber 1632d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber MediaBuffer *buffer; 1642d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 1652d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber for (;;) { 166125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber status_t err = rawSource->read(&buffer, &options); 1672d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber options.clearSeekTo(); 1682d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 1692d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber if (err != OK) { 1702d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber CHECK_EQ(buffer, NULL); 1717f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber 1727f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber if (err == INFO_FORMAT_CHANGED) { 1737f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber printf("format changed.\n"); 1747f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber continue; 1757f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber } 1767f281f87670c63775ea1ae8b24af31822d5ad416Andreas Huber 1772d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber break; 1782d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 1792d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 180ab0f94d68bcb74547c8191bd4c47a9ad1b7c7c48Andreas Huber if (buffer->range_length() > 0 && (n++ % 16) == 0) { 1812d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber printf("."); 1822d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber fflush(stdout); 1832d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 1842d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 1852d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber buffer->release(); 1862d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber buffer = NULL; 18738b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber 18838b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber ++numFrames; 18938b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber if (gMaxNumFrames > 0 && numFrames == gMaxNumFrames) { 19038b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber break; 19138b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber } 19280011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber 19380011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber if (gReproduceBug == 1 && numFrames == 40) { 19480011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber printf("seeking past the end now."); 195a8a371c8a0d88d144d095404673d00cae6464fdeAndreas Huber options.setSeekTo(0x7fffffffL); 196e07db23c4935e47ecedfec7537ba95163e5836e5Andreas Huber } else if (gReproduceBug == 2 && numFrames == 40) { 197e07db23c4935e47ecedfec7537ba95163e5836e5Andreas Huber printf("seeking to 5 secs."); 198e07db23c4935e47ecedfec7537ba95163e5836e5Andreas Huber options.setSeekTo(5000000); 19980011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber } 200693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber } 201693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 2022d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber printf("$"); 2032d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber fflush(stdout); 2042d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 2052d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber options.setSeekTo(0); 206693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber } 2072d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 208125ef261deb4efbb50cc41c60902dea48d8d4187Andreas Huber rawSource->stop(); 209693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber printf("\n"); 210693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 211693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber int64_t delay = getNowUs() - startTime; 212693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber printf("avg. %.2f fps\n", n * 1E6 / delay); 213693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 214693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber printf("decoded a total of %d frame(s).\n", n); 215693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber} 216693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 2172d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huberstatic void usage(const char *me) { 2182d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber fprintf(stderr, "usage: %s\n", me); 2192d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber fprintf(stderr, " -h(elp)\n"); 2202d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber fprintf(stderr, " -a(udio)\n"); 2212d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber fprintf(stderr, " -n repetitions\n"); 2222d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber fprintf(stderr, " -l(ist) components\n"); 22338b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber fprintf(stderr, " -m max-number-of-frames-to-decode in each pass\n"); 22480011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber fprintf(stderr, " -b bug to reproduce\n"); 22518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber fprintf(stderr, " -p(rofiles) dump decoder profiles supported\n"); 2265c1e3581978164d169050686c73810ce59304471Andreas Huber fprintf(stderr, " -t(humbnail) extract video thumbnail\n"); 2275c1e3581978164d169050686c73810ce59304471Andreas Huber fprintf(stderr, " -s(oftware) prefer software codec\n"); 2282d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber} 2292d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 23020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberint main(int argc, char **argv) { 23120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber android::ProcessState::self()->startThreadPool(); 23220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2330024245e134467d120b40099da16c467dc365e76Andreas Huber bool audioOnly = false; 2342d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber bool listComponents = false; 23518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber bool dumpProfiles = false; 2365c1e3581978164d169050686c73810ce59304471Andreas Huber bool extractThumbnail = false; 2372d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber gNumRepetitions = 1; 23838b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber gMaxNumFrames = 0; 23980011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber gReproduceBug = -1; 2405c1e3581978164d169050686c73810ce59304471Andreas Huber gPreferSoftwareCodec = false; 2412d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 2422d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber int res; 2435c1e3581978164d169050686c73810ce59304471Andreas Huber while ((res = getopt(argc, argv, "han:lm:b:pts")) >= 0) { 2442d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber switch (res) { 2452d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber case 'a': 2462d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber { 2472d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber audioOnly = true; 2482d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber break; 2492d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 2502d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 2512d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber case 'l': 2522d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber { 2532d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber listComponents = true; 2542d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber break; 2552d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 2562d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 25738b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber case 'm': 2582d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber case 'n': 25980011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber case 'b': 2602d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber { 2612d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber char *end; 2622d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber long x = strtol(optarg, &end, 10); 2632d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 2642d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber if (*end != '\0' || end == optarg || x <= 0) { 2652d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber x = 1; 2662d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 2672d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 26838b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber if (res == 'n') { 26938b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber gNumRepetitions = x; 27080011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber } else if (res == 'm') { 27138b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber gMaxNumFrames = x; 27280011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber } else { 27380011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber CHECK_EQ(res, 'b'); 27480011fe130bc966aa357ed2b3dcc80cde2d0bb82Andreas Huber gReproduceBug = x; 27538b610fe53bb27946826d3f175f6fbe613f270daAndreas Huber } 2762d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber break; 2772d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 2782d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 27918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber case 'p': 28018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber { 28118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber dumpProfiles = true; 28218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber break; 28318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber } 28418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 2855c1e3581978164d169050686c73810ce59304471Andreas Huber case 't': 2865c1e3581978164d169050686c73810ce59304471Andreas Huber { 2875c1e3581978164d169050686c73810ce59304471Andreas Huber extractThumbnail = true; 2885c1e3581978164d169050686c73810ce59304471Andreas Huber break; 2895c1e3581978164d169050686c73810ce59304471Andreas Huber } 2905c1e3581978164d169050686c73810ce59304471Andreas Huber 2915c1e3581978164d169050686c73810ce59304471Andreas Huber case 's': 2925c1e3581978164d169050686c73810ce59304471Andreas Huber { 2935c1e3581978164d169050686c73810ce59304471Andreas Huber gPreferSoftwareCodec = true; 2945c1e3581978164d169050686c73810ce59304471Andreas Huber break; 2955c1e3581978164d169050686c73810ce59304471Andreas Huber } 2965c1e3581978164d169050686c73810ce59304471Andreas Huber 2972d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber case '?': 2982d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber case 'h': 2992d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber default: 3002d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber { 3012d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber usage(argv[0]); 3022d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber exit(1); 3032d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber break; 3042d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 3052d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 3062d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 3072d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 3082d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber argc -= optind; 3092d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber argv += optind; 3102d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 3115c1e3581978164d169050686c73810ce59304471Andreas Huber if (extractThumbnail) { 3125c1e3581978164d169050686c73810ce59304471Andreas Huber sp<IServiceManager> sm = defaultServiceManager(); 3135c1e3581978164d169050686c73810ce59304471Andreas Huber sp<IBinder> binder = sm->getService(String16("media.player")); 3145c1e3581978164d169050686c73810ce59304471Andreas Huber sp<IMediaPlayerService> service = 3155c1e3581978164d169050686c73810ce59304471Andreas Huber interface_cast<IMediaPlayerService>(binder); 3165c1e3581978164d169050686c73810ce59304471Andreas Huber 3175c1e3581978164d169050686c73810ce59304471Andreas Huber CHECK(service.get() != NULL); 3185c1e3581978164d169050686c73810ce59304471Andreas Huber 3195c1e3581978164d169050686c73810ce59304471Andreas Huber sp<IMediaMetadataRetriever> retriever = 3205c1e3581978164d169050686c73810ce59304471Andreas Huber service->createMetadataRetriever(getpid()); 3215c1e3581978164d169050686c73810ce59304471Andreas Huber 3225c1e3581978164d169050686c73810ce59304471Andreas Huber CHECK(retriever != NULL); 3235c1e3581978164d169050686c73810ce59304471Andreas Huber 3245c1e3581978164d169050686c73810ce59304471Andreas Huber for (int k = 0; k < argc; ++k) { 3255c1e3581978164d169050686c73810ce59304471Andreas Huber const char *filename = argv[k]; 3265c1e3581978164d169050686c73810ce59304471Andreas Huber 3275c1e3581978164d169050686c73810ce59304471Andreas Huber CHECK_EQ(retriever->setDataSource(filename), OK); 3285c1e3581978164d169050686c73810ce59304471Andreas Huber CHECK_EQ(retriever->setMode(METADATA_MODE_FRAME_CAPTURE_ONLY), OK); 3295c1e3581978164d169050686c73810ce59304471Andreas Huber 3305c1e3581978164d169050686c73810ce59304471Andreas Huber sp<IMemory> mem = retriever->captureFrame(); 3315c1e3581978164d169050686c73810ce59304471Andreas Huber 3325c1e3581978164d169050686c73810ce59304471Andreas Huber printf("captureFrame(%s) => %s\n", 3335c1e3581978164d169050686c73810ce59304471Andreas Huber filename, mem != NULL ? "OK" : "FAILED"); 3345c1e3581978164d169050686c73810ce59304471Andreas Huber } 3355c1e3581978164d169050686c73810ce59304471Andreas Huber 3365c1e3581978164d169050686c73810ce59304471Andreas Huber return 0; 3375c1e3581978164d169050686c73810ce59304471Andreas Huber } 3385c1e3581978164d169050686c73810ce59304471Andreas Huber 33918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber if (dumpProfiles) { 34018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber sp<IServiceManager> sm = defaultServiceManager(); 34118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber sp<IBinder> binder = sm->getService(String16("media.player")); 34218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber sp<IMediaPlayerService> service = 34318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber interface_cast<IMediaPlayerService>(binder); 34418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 34518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber CHECK(service.get() != NULL); 34618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 347318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber sp<IOMX> omx = service->getOMX(); 34818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber CHECK(omx.get() != NULL); 34918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 35018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber const char *kMimeTypes[] = { 35118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber MEDIA_MIMETYPE_VIDEO_AVC, MEDIA_MIMETYPE_VIDEO_MPEG4, 35218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber MEDIA_MIMETYPE_VIDEO_H263 35318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber }; 35418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 35518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber for (size_t k = 0; k < sizeof(kMimeTypes) / sizeof(kMimeTypes[0]); 35618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber ++k) { 35718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber printf("type '%s':\n", kMimeTypes[k]); 35818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 35918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber Vector<CodecCapabilities> results; 36018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber CHECK_EQ(QueryCodecs(omx, kMimeTypes[k], 36118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber true, // queryDecoders 36218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber &results), OK); 36318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 36418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber for (size_t i = 0; i < results.size(); ++i) { 36518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber printf(" decoder '%s' supports ", 36618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber results[i].mComponentName.string()); 36718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 36818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber if (results[i].mProfileLevels.size() == 0) { 36918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber printf("NOTHING.\n"); 37018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber continue; 37118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber } 37218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 37318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber for (size_t j = 0; j < results[i].mProfileLevels.size(); ++j) { 37418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber const CodecProfileLevel &profileLevel = 37518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber results[i].mProfileLevels[j]; 37618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 37718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber printf("%s%ld/%ld", j > 0 ? ", " : "", 37818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber profileLevel.mProfile, profileLevel.mLevel); 37918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber } 38018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 38118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber printf("\n"); 38218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber } 38318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber } 38418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber } 38518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber 3862d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber if (listComponents) { 38720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<IServiceManager> sm = defaultServiceManager(); 38820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<IBinder> binder = sm->getService(String16("media.player")); 38920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder); 39020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 391693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber CHECK(service.get() != NULL); 39220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 393318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber sp<IOMX> omx = service->getOMX(); 394693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber CHECK(omx.get() != NULL); 39520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 396134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber List<IOMX::ComponentInfo> list; 397318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber omx->listNodes(&list); 39820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 399134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber for (List<IOMX::ComponentInfo>::iterator it = list.begin(); 40020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber it != list.end(); ++it) { 401134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber printf("%s\n", (*it).mName.string()); 40220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 40320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 40420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 40520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber DataSource::RegisterDefaultSniffers(); 40620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 40720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber OMXClient client; 40820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = client.connect(); 40920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4102d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber for (int k = 0; k < argc; ++k) { 4112d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber const char *filename = argv[k]; 41220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4132ea76ead54982376e32ab196093babded80e05e4Andreas Huber sp<DataSource> dataSource; 4142ea76ead54982376e32ab196093babded80e05e4Andreas Huber if (!strncasecmp("http://", filename, 7)) { 4152ea76ead54982376e32ab196093babded80e05e4Andreas Huber dataSource = new HTTPDataSource(filename); 4162ea76ead54982376e32ab196093babded80e05e4Andreas Huber dataSource = new CachingDataSource(dataSource, 64 * 1024, 10); 4172ea76ead54982376e32ab196093babded80e05e4Andreas Huber } else { 418bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber dataSource = new FileSource(filename); 4192ea76ead54982376e32ab196093babded80e05e4Andreas Huber } 4200024245e134467d120b40099da16c467dc365e76Andreas Huber 4212d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber bool isJPEG = false; 42220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4232d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber size_t len = strlen(filename); 4242d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber if (len >= 4 && !strcasecmp(filename + len - 4, ".jpg")) { 4252d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber isJPEG = true; 4262d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 42720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4282d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber sp<MediaSource> mediaSource; 42920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4302d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber if (isJPEG) { 4312d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber mediaSource = new JPEGSource(dataSource); 4322d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } else { 4332d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource); 43420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4352d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber size_t numTracks = extractor->countTracks(); 43620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4372d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber sp<MetaData> meta; 4382d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber size_t i; 4392d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber for (i = 0; i < numTracks; ++i) { 4405c1e3581978164d169050686c73810ce59304471Andreas Huber meta = extractor->getTrackMetaData( 4415c1e3581978164d169050686c73810ce59304471Andreas Huber i, MediaExtractor::kIncludeExtensiveMetaData); 44220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4432d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber const char *mime; 4442d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber meta->findCString(kKeyMIMEType, &mime); 44520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4462d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber if (audioOnly && !strncasecmp(mime, "audio/", 6)) { 4472d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber break; 4482d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 4492d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 4502d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber if (!audioOnly && !strncasecmp(mime, "video/", 6)) { 4512d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber break; 4522d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber } 453693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber } 4542d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber 4555c1e3581978164d169050686c73810ce59304471Andreas Huber int64_t thumbTimeUs; 4565c1e3581978164d169050686c73810ce59304471Andreas Huber if (meta->findInt64(kKeyThumbnailTime, &thumbTimeUs)) { 4575c1e3581978164d169050686c73810ce59304471Andreas Huber printf("thumbnailTime: %lld us (%.2f secs)\n", 4585c1e3581978164d169050686c73810ce59304471Andreas Huber thumbTimeUs, thumbTimeUs / 1E6); 4595c1e3581978164d169050686c73810ce59304471Andreas Huber } 4605c1e3581978164d169050686c73810ce59304471Andreas Huber 4612d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber mediaSource = extractor->getTrack(i); 46220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 46320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4642d7d46fb2d7f5f80afbf060f25ed049079fb0fc9Andreas Huber playSource(&client, mediaSource); 46520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 46620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 46720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber client.disconnect(); 46820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 46920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return 0; 47020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 471