MediaPlayerService.cpp revision 5e07b5774c8b376776caa4f5b0a193767697e97e
1/* 2** 3** Copyright 2008, The Android Open Source Project 4** 5** Licensed under the Apache License, Version 2.0 (the "License"); 6** you may not use this file except in compliance with the License. 7** You may obtain a copy of the License at 8** 9** http://www.apache.org/licenses/LICENSE-2.0 10** 11** Unless required by applicable law or agreed to in writing, software 12** distributed under the License is distributed on an "AS IS" BASIS, 13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14** See the License for the specific language governing permissions and 15** limitations under the License. 16*/ 17 18// Proxy for media player implementations 19 20//#define LOG_NDEBUG 0 21#define LOG_TAG "MediaPlayerService" 22#include <utils/Log.h> 23 24#include <sys/types.h> 25#include <sys/stat.h> 26#include <dirent.h> 27#include <unistd.h> 28 29#include <string.h> 30#include <cutils/atomic.h> 31 32#include <android_runtime/ActivityManager.h> 33#include <utils/IPCThreadState.h> 34#include <utils/IServiceManager.h> 35#include <utils/MemoryHeapBase.h> 36#include <utils/MemoryBase.h> 37#include <cutils/properties.h> 38 39#include <media/MediaPlayerInterface.h> 40#include <media/mediarecorder.h> 41#include <media/MediaMetadataRetrieverInterface.h> 42#include <media/AudioTrack.h> 43 44#include "MediaRecorderClient.h" 45#include "MediaPlayerService.h" 46#include "MetadataRetrieverClient.h" 47 48#include "MidiFile.h" 49#include "VorbisPlayer.h" 50#include <media/PVPlayer.h> 51 52/* desktop Linux needs a little help with gettid() */ 53#if defined(HAVE_GETTID) && !defined(HAVE_ANDROID_OS) 54#define __KERNEL__ 55# include <linux/unistd.h> 56#ifdef _syscall0 57_syscall0(pid_t,gettid) 58#else 59pid_t gettid() { return syscall(__NR_gettid);} 60#endif 61#undef __KERNEL__ 62#endif 63 64 65namespace android { 66 67// TODO: Temp hack until we can register players 68typedef struct { 69 const char *extension; 70 const player_type playertype; 71} extmap; 72extmap FILE_EXTS [] = { 73 {".mid", SONIVOX_PLAYER}, 74 {".midi", SONIVOX_PLAYER}, 75 {".smf", SONIVOX_PLAYER}, 76 {".xmf", SONIVOX_PLAYER}, 77 {".imy", SONIVOX_PLAYER}, 78 {".rtttl", SONIVOX_PLAYER}, 79 {".rtx", SONIVOX_PLAYER}, 80 {".ota", SONIVOX_PLAYER}, 81 {".ogg", VORBIS_PLAYER}, 82 {".oga", VORBIS_PLAYER}, 83}; 84 85// TODO: Find real cause of Audio/Video delay in PV framework and remove this workaround 86/* static */ const uint32_t MediaPlayerService::AudioOutput::kAudioVideoDelayMs = 96; 87/* static */ int MediaPlayerService::AudioOutput::mMinBufferCount = 4; 88/* static */ bool MediaPlayerService::AudioOutput::mIsOnEmulator = false; 89 90void MediaPlayerService::instantiate() { 91 defaultServiceManager()->addService( 92 String16("media.player"), new MediaPlayerService()); 93} 94 95MediaPlayerService::MediaPlayerService() 96{ 97 LOGV("MediaPlayerService created"); 98 mNextConnId = 1; 99} 100 101MediaPlayerService::~MediaPlayerService() 102{ 103 LOGV("MediaPlayerService destroyed"); 104} 105 106sp<IMediaRecorder> MediaPlayerService::createMediaRecorder(pid_t pid) 107{ 108 sp<MediaRecorderClient> recorder = new MediaRecorderClient(pid); 109 LOGV("Create new media recorder client from pid %d", pid); 110 return recorder; 111} 112 113sp<IMediaMetadataRetriever> MediaPlayerService::createMetadataRetriever(pid_t pid) 114{ 115 sp<MetadataRetrieverClient> retriever = new MetadataRetrieverClient(pid); 116 LOGV("Create new media retriever from pid %d", pid); 117 return retriever; 118} 119 120sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClient>& client, const char* url) 121{ 122 int32_t connId = android_atomic_inc(&mNextConnId); 123 sp<Client> c = new Client(this, pid, connId, client); 124 LOGV("Create new client(%d) from pid %d, url=%s, connId=%d", connId, pid, url, connId); 125 if (NO_ERROR != c->setDataSource(url)) 126 { 127 c.clear(); 128 return c; 129 } 130 wp<Client> w = c; 131 Mutex::Autolock lock(mLock); 132 mClients.add(w); 133 return c; 134} 135 136sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClient>& client, 137 int fd, int64_t offset, int64_t length) 138{ 139 int32_t connId = android_atomic_inc(&mNextConnId); 140 sp<Client> c = new Client(this, pid, connId, client); 141 LOGV("Create new client(%d) from pid %d, fd=%d, offset=%lld, length=%lld", 142 connId, pid, fd, offset, length); 143 if (NO_ERROR != c->setDataSource(fd, offset, length)) { 144 c.clear(); 145 } else { 146 wp<Client> w = c; 147 Mutex::Autolock lock(mLock); 148 mClients.add(w); 149 } 150 ::close(fd); 151 return c; 152} 153 154status_t MediaPlayerService::AudioCache::dump(int fd, const Vector<String16>& args) const 155{ 156 const size_t SIZE = 256; 157 char buffer[SIZE]; 158 String8 result; 159 160 result.append(" AudioCache\n"); 161 if (mHeap != 0) { 162 snprintf(buffer, 255, " heap base(%p), size(%d), flags(%d), device(%s)\n", 163 mHeap->getBase(), mHeap->getSize(), mHeap->getFlags(), mHeap->getDevice()); 164 result.append(buffer); 165 } 166 snprintf(buffer, 255, " msec per frame(%f), channel count(%d), format(%d), frame count(%ld)\n", 167 mMsecsPerFrame, mChannelCount, mFormat, mFrameCount); 168 result.append(buffer); 169 snprintf(buffer, 255, " sample rate(%d), size(%d), error(%d), command complete(%s)\n", 170 mSampleRate, mSize, mError, mCommandComplete?"true":"false"); 171 result.append(buffer); 172 ::write(fd, result.string(), result.size()); 173 return NO_ERROR; 174} 175 176status_t MediaPlayerService::AudioOutput::dump(int fd, const Vector<String16>& args) const 177{ 178 const size_t SIZE = 256; 179 char buffer[SIZE]; 180 String8 result; 181 182 result.append(" AudioOutput\n"); 183 snprintf(buffer, 255, " stream type(%d), left - right volume(%f, %f)\n", 184 mStreamType, mLeftVolume, mRightVolume); 185 result.append(buffer); 186 snprintf(buffer, 255, " msec per frame(%f), latency (%d)\n", 187 mMsecsPerFrame, mLatency); 188 result.append(buffer); 189 ::write(fd, result.string(), result.size()); 190 if (mTrack != 0) { 191 mTrack->dump(fd, args); 192 } 193 return NO_ERROR; 194} 195 196status_t MediaPlayerService::Client::dump(int fd, const Vector<String16>& args) const 197{ 198 const size_t SIZE = 256; 199 char buffer[SIZE]; 200 String8 result; 201 result.append(" Client\n"); 202 snprintf(buffer, 255, " pid(%d), connId(%d), status(%d), looping(%s)\n", 203 mPid, mConnId, mStatus, mLoop?"true": "false"); 204 result.append(buffer); 205 write(fd, result.string(), result.size()); 206 if (mAudioOutput != 0) { 207 mAudioOutput->dump(fd, args); 208 } 209 write(fd, "\n", 1); 210 return NO_ERROR; 211} 212 213static int myTid() { 214#ifdef HAVE_GETTID 215 return gettid(); 216#else 217 return getpid(); 218#endif 219} 220 221status_t MediaPlayerService::dump(int fd, const Vector<String16>& args) 222{ 223 const size_t SIZE = 256; 224 char buffer[SIZE]; 225 String8 result; 226 if (checkCallingPermission(String16("android.permission.DUMP")) == false) { 227 snprintf(buffer, SIZE, "Permission Denial: " 228 "can't dump MediaPlayerService from pid=%d, uid=%d\n", 229 IPCThreadState::self()->getCallingPid(), 230 IPCThreadState::self()->getCallingUid()); 231 result.append(buffer); 232 } else { 233 Mutex::Autolock lock(mLock); 234 for (int i = 0, n = mClients.size(); i < n; ++i) { 235 sp<Client> c = mClients[i].promote(); 236 if (c != 0) c->dump(fd, args); 237 } 238 result.append(" Files opened and/or mapped:\n"); 239 snprintf(buffer, SIZE, "/proc/%d/maps", myTid()); 240 FILE *f = fopen(buffer, "r"); 241 if (f) { 242 while (!feof(f)) { 243 fgets(buffer, SIZE, f); 244 if (strstr(buffer, " /sdcard/") || 245 strstr(buffer, " /system/sounds/") || 246 strstr(buffer, " /system/media/")) { 247 result.append(" "); 248 result.append(buffer); 249 } 250 } 251 fclose(f); 252 } else { 253 result.append("couldn't open "); 254 result.append(buffer); 255 result.append("\n"); 256 } 257 258 snprintf(buffer, SIZE, "/proc/%d/fd", myTid()); 259 DIR *d = opendir(buffer); 260 if (d) { 261 struct dirent *ent; 262 while((ent = readdir(d)) != NULL) { 263 if (strcmp(ent->d_name,".") && strcmp(ent->d_name,"..")) { 264 snprintf(buffer, SIZE, "/proc/%d/fd/%s", myTid(), ent->d_name); 265 struct stat s; 266 if (lstat(buffer, &s) == 0) { 267 if ((s.st_mode & S_IFMT) == S_IFLNK) { 268 char linkto[256]; 269 int len = readlink(buffer, linkto, sizeof(linkto)); 270 if(len > 0) { 271 if(len > 255) { 272 linkto[252] = '.'; 273 linkto[253] = '.'; 274 linkto[254] = '.'; 275 linkto[255] = 0; 276 } else { 277 linkto[len] = 0; 278 } 279 if (strstr(linkto, "/sdcard/") == linkto || 280 strstr(linkto, "/system/sounds/") == linkto || 281 strstr(linkto, "/system/media/") == linkto) { 282 result.append(" "); 283 result.append(buffer); 284 result.append(" -> "); 285 result.append(linkto); 286 result.append("\n"); 287 } 288 } 289 } else { 290 result.append(" unexpected type for "); 291 result.append(buffer); 292 result.append("\n"); 293 } 294 } 295 } 296 } 297 closedir(d); 298 } else { 299 result.append("couldn't open "); 300 result.append(buffer); 301 result.append("\n"); 302 } 303 } 304 write(fd, result.string(), result.size()); 305 return NO_ERROR; 306} 307 308void MediaPlayerService::removeClient(wp<Client> client) 309{ 310 Mutex::Autolock lock(mLock); 311 mClients.remove(client); 312} 313 314MediaPlayerService::Client::Client(const sp<MediaPlayerService>& service, pid_t pid, 315 int32_t connId, const sp<IMediaPlayerClient>& client) 316{ 317 LOGV("Client(%d) constructor", connId); 318 mPid = pid; 319 mConnId = connId; 320 mService = service; 321 mClient = client; 322 mLoop = false; 323 mStatus = NO_INIT; 324#if CALLBACK_ANTAGONIZER 325 LOGD("create Antagonizer"); 326 mAntagonizer = new Antagonizer(notify, this); 327#endif 328} 329 330MediaPlayerService::Client::~Client() 331{ 332 LOGV("Client(%d) destructor pid = %d", mConnId, mPid); 333 mAudioOutput.clear(); 334 wp<Client> client(this); 335 disconnect(); 336 mService->removeClient(client); 337} 338 339void MediaPlayerService::Client::disconnect() 340{ 341 LOGV("disconnect(%d) from pid %d", mConnId, mPid); 342 // grab local reference and clear main reference to prevent future 343 // access to object 344 sp<MediaPlayerBase> p; 345 { 346 Mutex::Autolock l(mLock); 347 p = mPlayer; 348 } 349 mPlayer.clear(); 350 351 // clear the notification to prevent callbacks to dead client 352 // and reset the player. We assume the player will serialize 353 // access to itself if necessary. 354 if (p != 0) { 355 p->setNotifyCallback(0, 0); 356#if CALLBACK_ANTAGONIZER 357 LOGD("kill Antagonizer"); 358 mAntagonizer->kill(); 359#endif 360 p->reset(); 361 } 362 363 IPCThreadState::self()->flushCommands(); 364} 365 366static player_type getPlayerType(int fd, int64_t offset, int64_t length) 367{ 368 char buf[20]; 369 lseek(fd, offset, SEEK_SET); 370 read(fd, buf, sizeof(buf)); 371 lseek(fd, offset, SEEK_SET); 372 373 long ident = *((long*)buf); 374 375 // Ogg vorbis? 376 if (ident == 0x5367674f) // 'OggS' 377 return VORBIS_PLAYER; 378 379 // Some kind of MIDI? 380 EAS_DATA_HANDLE easdata; 381 if (EAS_Init(&easdata) == EAS_SUCCESS) { 382 EAS_FILE locator; 383 locator.path = NULL; 384 locator.fd = fd; 385 locator.offset = offset; 386 locator.length = length; 387 EAS_HANDLE eashandle; 388 if (EAS_OpenFile(easdata, &locator, &eashandle) == EAS_SUCCESS) { 389 EAS_CloseFile(easdata, eashandle); 390 EAS_Shutdown(easdata); 391 return SONIVOX_PLAYER; 392 } 393 EAS_Shutdown(easdata); 394 } 395 396 // Fall through to PV 397 return PV_PLAYER; 398} 399 400static player_type getPlayerType(const char* url) 401{ 402 403 // use MidiFile for MIDI extensions 404 int lenURL = strlen(url); 405 for (int i = 0; i < NELEM(FILE_EXTS); ++i) { 406 int len = strlen(FILE_EXTS[i].extension); 407 int start = lenURL - len; 408 if (start > 0) { 409 if (!strncmp(url + start, FILE_EXTS[i].extension, len)) { 410 return FILE_EXTS[i].playertype; 411 } 412 } 413 } 414 415 // Fall through to PV 416 return PV_PLAYER; 417} 418 419static sp<MediaPlayerBase> createPlayer(player_type playerType, void* cookie, 420 notify_callback_f notifyFunc) 421{ 422 sp<MediaPlayerBase> p; 423 switch (playerType) { 424 case PV_PLAYER: 425 LOGV(" create PVPlayer"); 426 p = new PVPlayer(); 427 break; 428 case SONIVOX_PLAYER: 429 LOGV(" create MidiFile"); 430 p = new MidiFile(); 431 break; 432 case VORBIS_PLAYER: 433 LOGV(" create VorbisPlayer"); 434 p = new VorbisPlayer(); 435 break; 436 } 437 if (p != NULL) { 438 if (p->initCheck() == NO_ERROR) { 439 p->setNotifyCallback(cookie, notifyFunc); 440 } else { 441 p.clear(); 442 } 443 } 444 if (p == NULL) { 445 LOGE("Failed to create player object"); 446 } 447 return p; 448} 449 450sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerType) 451{ 452 // determine if we have the right player type 453 sp<MediaPlayerBase> p = mPlayer; 454 if ((p != NULL) && (p->playerType() != playerType)) { 455 LOGV("delete player"); 456 p.clear(); 457 } 458 if (p == NULL) { 459 p = android::createPlayer(playerType, this, notify); 460 } 461 return p; 462} 463 464status_t MediaPlayerService::Client::setDataSource(const char *url) 465{ 466 LOGV("setDataSource(%s)", url); 467 if (url == NULL) 468 return UNKNOWN_ERROR; 469 470 if (strncmp(url, "content://", 10) == 0) { 471 // get a filedescriptor for the content Uri and 472 // pass it to the setDataSource(fd) method 473 474 String16 url16(url); 475 int fd = android::openContentProviderFile(url16); 476 if (fd < 0) 477 { 478 LOGE("Couldn't open fd for %s", url); 479 return UNKNOWN_ERROR; 480 } 481 setDataSource(fd, 0, 0x7fffffffffLL); // this sets mStatus 482 close(fd); 483 return mStatus; 484 } else { 485 player_type playerType = getPlayerType(url); 486 LOGV("player type = %d", playerType); 487 488 // create the right type of player 489 sp<MediaPlayerBase> p = createPlayer(playerType); 490 if (p == NULL) return NO_INIT; 491 492 if (!p->hardwareOutput()) { 493 mAudioOutput = new AudioOutput(); 494 static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput); 495 } 496 497 // now set data source 498 LOGV(" setDataSource"); 499 mStatus = p->setDataSource(url); 500 if (mStatus == NO_ERROR) mPlayer = p; 501 return mStatus; 502 } 503} 504 505status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64_t length) 506{ 507 LOGV("setDataSource fd=%d, offset=%lld, length=%lld", fd, offset, length); 508 struct stat sb; 509 int ret = fstat(fd, &sb); 510 if (ret != 0) { 511 LOGE("fstat(%d) failed: %d, %s", fd, ret, strerror(errno)); 512 return UNKNOWN_ERROR; 513 } 514 515 LOGV("st_dev = %llu", sb.st_dev); 516 LOGV("st_mode = %u", sb.st_mode); 517 LOGV("st_uid = %lu", sb.st_uid); 518 LOGV("st_gid = %lu", sb.st_gid); 519 LOGV("st_size = %llu", sb.st_size); 520 521 if (offset >= sb.st_size) { 522 LOGE("offset error"); 523 ::close(fd); 524 return UNKNOWN_ERROR; 525 } 526 if (offset + length > sb.st_size) { 527 length = sb.st_size - offset; 528 LOGV("calculated length = %lld", length); 529 } 530 531 player_type playerType = getPlayerType(fd, offset, length); 532 LOGV("player type = %d", playerType); 533 534 // create the right type of player 535 sp<MediaPlayerBase> p = createPlayer(playerType); 536 if (p == NULL) return NO_INIT; 537 538 if (!p->hardwareOutput()) { 539 mAudioOutput = new AudioOutput(); 540 static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput); 541 } 542 543 // now set data source 544 mStatus = p->setDataSource(fd, offset, length); 545 if (mStatus == NO_ERROR) mPlayer = p; 546 return mStatus; 547} 548 549status_t MediaPlayerService::Client::setVideoSurface(const sp<ISurface>& surface) 550{ 551 LOGV("[%d] setVideoSurface(%p)", mConnId, surface.get()); 552 sp<MediaPlayerBase> p = getPlayer(); 553 if (p == 0) return UNKNOWN_ERROR; 554 return p->setVideoSurface(surface); 555} 556 557status_t MediaPlayerService::Client::prepareAsync() 558{ 559 LOGV("[%d] prepareAsync", mConnId); 560 sp<MediaPlayerBase> p = getPlayer(); 561 if (p == 0) return UNKNOWN_ERROR; 562 status_t ret = p->prepareAsync(); 563#if CALLBACK_ANTAGONIZER 564 LOGD("start Antagonizer"); 565 if (ret == NO_ERROR) mAntagonizer->start(); 566#endif 567 return ret; 568} 569 570status_t MediaPlayerService::Client::start() 571{ 572 LOGV("[%d] start", mConnId); 573 sp<MediaPlayerBase> p = getPlayer(); 574 if (p == 0) return UNKNOWN_ERROR; 575 p->setLooping(mLoop); 576 return p->start(); 577} 578 579status_t MediaPlayerService::Client::stop() 580{ 581 LOGV("[%d] stop", mConnId); 582 sp<MediaPlayerBase> p = getPlayer(); 583 if (p == 0) return UNKNOWN_ERROR; 584 return p->stop(); 585} 586 587status_t MediaPlayerService::Client::pause() 588{ 589 LOGV("[%d] pause", mConnId); 590 sp<MediaPlayerBase> p = getPlayer(); 591 if (p == 0) return UNKNOWN_ERROR; 592 return p->pause(); 593} 594 595status_t MediaPlayerService::Client::isPlaying(bool* state) 596{ 597 *state = false; 598 sp<MediaPlayerBase> p = getPlayer(); 599 if (p == 0) return UNKNOWN_ERROR; 600 *state = p->isPlaying(); 601 LOGV("[%d] isPlaying: %d", mConnId, *state); 602 return NO_ERROR; 603} 604 605status_t MediaPlayerService::Client::getCurrentPosition(int *msec) 606{ 607 LOGV("getCurrentPosition"); 608 sp<MediaPlayerBase> p = getPlayer(); 609 if (p == 0) return UNKNOWN_ERROR; 610 status_t ret = p->getCurrentPosition(msec); 611 if (ret == NO_ERROR) { 612 LOGV("[%d] getCurrentPosition = %d", mConnId, *msec); 613 } else { 614 LOGE("getCurrentPosition returned %d", ret); 615 } 616 return ret; 617} 618 619status_t MediaPlayerService::Client::getDuration(int *msec) 620{ 621 LOGV("getDuration"); 622 sp<MediaPlayerBase> p = getPlayer(); 623 if (p == 0) return UNKNOWN_ERROR; 624 status_t ret = p->getDuration(msec); 625 if (ret == NO_ERROR) { 626 LOGV("[%d] getDuration = %d", mConnId, *msec); 627 } else { 628 LOGE("getDuration returned %d", ret); 629 } 630 return ret; 631} 632 633status_t MediaPlayerService::Client::seekTo(int msec) 634{ 635 LOGV("[%d] seekTo(%d)", mConnId, msec); 636 sp<MediaPlayerBase> p = getPlayer(); 637 if (p == 0) return UNKNOWN_ERROR; 638 return p->seekTo(msec); 639} 640 641status_t MediaPlayerService::Client::reset() 642{ 643 LOGV("[%d] reset", mConnId); 644 sp<MediaPlayerBase> p = getPlayer(); 645 if (p == 0) return UNKNOWN_ERROR; 646 return p->reset(); 647} 648 649status_t MediaPlayerService::Client::setAudioStreamType(int type) 650{ 651 LOGV("[%d] setAudioStreamType(%d)", mConnId, type); 652 // TODO: for hardware output, call player instead 653 Mutex::Autolock l(mLock); 654 if (mAudioOutput != 0) mAudioOutput->setAudioStreamType(type); 655 return NO_ERROR; 656} 657 658status_t MediaPlayerService::Client::setLooping(int loop) 659{ 660 LOGV("[%d] setLooping(%d)", mConnId, loop); 661 mLoop = loop; 662 sp<MediaPlayerBase> p = getPlayer(); 663 if (p != 0) return p->setLooping(loop); 664 return NO_ERROR; 665} 666 667status_t MediaPlayerService::Client::setVolume(float leftVolume, float rightVolume) 668{ 669 LOGV("[%d] setVolume(%f, %f)", mConnId, leftVolume, rightVolume); 670 // TODO: for hardware output, call player instead 671 Mutex::Autolock l(mLock); 672 if (mAudioOutput != 0) mAudioOutput->setVolume(leftVolume, rightVolume); 673 return NO_ERROR; 674} 675 676void MediaPlayerService::Client::notify(void* cookie, int msg, int ext1, int ext2) 677{ 678 Client* client = static_cast<Client*>(cookie); 679 LOGV("[%d] notify (%p, %d, %d, %d)", client->mConnId, cookie, msg, ext1, ext2); 680 client->mClient->notify(msg, ext1, ext2); 681} 682 683#if CALLBACK_ANTAGONIZER 684const int Antagonizer::interval = 10000; // 10 msecs 685 686Antagonizer::Antagonizer(notify_callback_f cb, void* client) : 687 mExit(false), mActive(false), mClient(client), mCb(cb) 688{ 689 createThread(callbackThread, this); 690} 691 692void Antagonizer::kill() 693{ 694 Mutex::Autolock _l(mLock); 695 mActive = false; 696 mExit = true; 697 mCondition.wait(mLock); 698} 699 700int Antagonizer::callbackThread(void* user) 701{ 702 LOGD("Antagonizer started"); 703 Antagonizer* p = reinterpret_cast<Antagonizer*>(user); 704 while (!p->mExit) { 705 if (p->mActive) { 706 LOGV("send event"); 707 p->mCb(p->mClient, 0, 0, 0); 708 } 709 usleep(interval); 710 } 711 Mutex::Autolock _l(p->mLock); 712 p->mCondition.signal(); 713 LOGD("Antagonizer stopped"); 714 return 0; 715} 716#endif 717 718static size_t kDefaultHeapSize = 1024 * 1024; // 1MB 719 720sp<IMemory> MediaPlayerService::decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) 721{ 722 LOGV("decode(%s)", url); 723 sp<MemoryBase> mem; 724 sp<MediaPlayerBase> player; 725 726 // Protect our precious, precious DRMd ringtones by only allowing 727 // decoding of http, but not filesystem paths or content Uris. 728 // If the application wants to decode those, it should open a 729 // filedescriptor for them and use that. 730 if (url != NULL && strncmp(url, "http://", 7) != 0) { 731 LOGD("Can't decode %s by path, use filedescriptor instead", url); 732 return mem; 733 } 734 735 player_type playerType = getPlayerType(url); 736 LOGV("player type = %d", playerType); 737 738 // create the right type of player 739 sp<AudioCache> cache = new AudioCache(url); 740 player = android::createPlayer(playerType, cache.get(), cache->notify); 741 if (player == NULL) goto Exit; 742 if (player->hardwareOutput()) goto Exit; 743 744 static_cast<MediaPlayerInterface*>(player.get())->setAudioSink(cache); 745 746 // set data source 747 if (player->setDataSource(url) != NO_ERROR) goto Exit; 748 749 LOGV("prepare"); 750 player->prepareAsync(); 751 752 LOGV("wait for prepare"); 753 if (cache->wait() != NO_ERROR) goto Exit; 754 755 LOGV("start"); 756 player->start(); 757 758 LOGV("wait for playback complete"); 759 if (cache->wait() != NO_ERROR) goto Exit; 760 761 mem = new MemoryBase(cache->getHeap(), 0, cache->size()); 762 *pSampleRate = cache->sampleRate(); 763 *pNumChannels = cache->channelCount(); 764 *pFormat = cache->format(); 765 LOGV("return memory @ %p, sampleRate=%u, channelCount = %d, format = %d", mem->pointer(), *pSampleRate, *pNumChannels, *pFormat); 766 767Exit: 768 if (player != 0) player->reset(); 769 return mem; 770} 771 772sp<IMemory> MediaPlayerService::decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) 773{ 774 LOGV("decode(%d, %lld, %lld)", fd, offset, length); 775 sp<MemoryBase> mem; 776 sp<MediaPlayerBase> player; 777 778 player_type playerType = getPlayerType(fd, offset, length); 779 LOGV("player type = %d", playerType); 780 781 // create the right type of player 782 sp<AudioCache> cache = new AudioCache("decode_fd"); 783 player = android::createPlayer(playerType, cache.get(), cache->notify); 784 if (player == NULL) goto Exit; 785 if (player->hardwareOutput()) goto Exit; 786 787 static_cast<MediaPlayerInterface*>(player.get())->setAudioSink(cache); 788 789 // set data source 790 if (player->setDataSource(fd, offset, length) != NO_ERROR) goto Exit; 791 792 LOGV("prepare"); 793 player->prepareAsync(); 794 795 LOGV("wait for prepare"); 796 if (cache->wait() != NO_ERROR) goto Exit; 797 798 LOGV("start"); 799 player->start(); 800 801 LOGV("wait for playback complete"); 802 if (cache->wait() != NO_ERROR) goto Exit; 803 804 mem = new MemoryBase(cache->getHeap(), 0, cache->size()); 805 *pSampleRate = cache->sampleRate(); 806 *pNumChannels = cache->channelCount(); 807 *pFormat = cache->format(); 808 LOGV("return memory @ %p, sampleRate=%u, channelCount = %d, format = %d", mem->pointer(), *pSampleRate, *pNumChannels, *pFormat); 809 810Exit: 811 if (player != 0) player->reset(); 812 ::close(fd); 813 return mem; 814} 815 816#undef LOG_TAG 817#define LOG_TAG "AudioSink" 818MediaPlayerService::AudioOutput::AudioOutput() 819{ 820 mTrack = 0; 821 mStreamType = AudioTrack::MUSIC; 822 mLeftVolume = 1.0; 823 mRightVolume = 1.0; 824 mLatency = 0; 825 mMsecsPerFrame = 0; 826 setMinBufferCount(); 827} 828 829MediaPlayerService::AudioOutput::~AudioOutput() 830{ 831 close(); 832} 833 834void MediaPlayerService::AudioOutput::setMinBufferCount() 835{ 836 char value[PROPERTY_VALUE_MAX]; 837 if (property_get("ro.kernel.qemu", value, 0)) { 838 mIsOnEmulator = true; 839 mMinBufferCount = 12; // to prevent systematic buffer underrun for emulator 840 } 841} 842 843bool MediaPlayerService::AudioOutput::isOnEmulator() 844{ 845 setMinBufferCount(); 846 return mIsOnEmulator; 847} 848 849int MediaPlayerService::AudioOutput::getMinBufferCount() 850{ 851 setMinBufferCount(); 852 return mMinBufferCount; 853} 854 855ssize_t MediaPlayerService::AudioOutput::bufferSize() const 856{ 857 if (mTrack == 0) return NO_INIT; 858 return mTrack->frameCount() * frameSize(); 859} 860 861ssize_t MediaPlayerService::AudioOutput::frameCount() const 862{ 863 if (mTrack == 0) return NO_INIT; 864 return mTrack->frameCount(); 865} 866 867ssize_t MediaPlayerService::AudioOutput::channelCount() const 868{ 869 if (mTrack == 0) return NO_INIT; 870 return mTrack->channelCount(); 871} 872 873ssize_t MediaPlayerService::AudioOutput::frameSize() const 874{ 875 if (mTrack == 0) return NO_INIT; 876 return mTrack->frameSize(); 877} 878 879uint32_t MediaPlayerService::AudioOutput::latency () const 880{ 881 return mLatency; 882} 883 884float MediaPlayerService::AudioOutput::msecsPerFrame() const 885{ 886 return mMsecsPerFrame; 887} 888 889status_t MediaPlayerService::AudioOutput::open(uint32_t sampleRate, int channelCount, int format, int bufferCount) 890{ 891 // Check argument "bufferCount" against the mininum buffer count 892 if (bufferCount < mMinBufferCount) { 893 LOGD("bufferCount (%d) is too small and increased to %d", bufferCount, mMinBufferCount); 894 bufferCount = mMinBufferCount; 895 896 } 897 LOGV("open(%u, %d, %d, %d)", sampleRate, channelCount, format, bufferCount); 898 if (mTrack) close(); 899 int afSampleRate; 900 int afFrameCount; 901 int frameCount; 902 903 if (AudioSystem::getOutputFrameCount(&afFrameCount) != NO_ERROR) { 904 return NO_INIT; 905 } 906 if (AudioSystem::getOutputSamplingRate(&afSampleRate) != NO_ERROR) { 907 return NO_INIT; 908 } 909 910 frameCount = (sampleRate*afFrameCount)/afSampleRate; 911 AudioTrack *t = new AudioTrack(mStreamType, sampleRate, format, channelCount, frameCount*bufferCount); 912 if ((t == 0) || (t->initCheck() != NO_ERROR)) { 913 LOGE("Unable to create audio track"); 914 delete t; 915 return NO_INIT; 916 } 917 918 LOGV("setVolume"); 919 t->setVolume(mLeftVolume, mRightVolume); 920 mMsecsPerFrame = 1.e3 / (float) sampleRate; 921 mLatency = t->latency() + kAudioVideoDelayMs; 922 mTrack = t; 923 return NO_ERROR; 924} 925 926void MediaPlayerService::AudioOutput::start() 927{ 928 LOGV("start"); 929 if (mTrack) { 930 mTrack->setVolume(mLeftVolume, mRightVolume); 931 mTrack->start(); 932 } 933} 934 935ssize_t MediaPlayerService::AudioOutput::write(const void* buffer, size_t size) 936{ 937 //LOGV("write(%p, %u)", buffer, size); 938 if (mTrack) return mTrack->write(buffer, size); 939 return NO_INIT; 940} 941 942void MediaPlayerService::AudioOutput::stop() 943{ 944 LOGV("stop"); 945 if (mTrack) mTrack->stop(); 946} 947 948void MediaPlayerService::AudioOutput::flush() 949{ 950 LOGV("flush"); 951 if (mTrack) mTrack->flush(); 952} 953 954void MediaPlayerService::AudioOutput::pause() 955{ 956 LOGV("pause"); 957 if (mTrack) mTrack->pause(); 958} 959 960void MediaPlayerService::AudioOutput::close() 961{ 962 LOGV("close"); 963 delete mTrack; 964 mTrack = 0; 965} 966 967void MediaPlayerService::AudioOutput::setVolume(float left, float right) 968{ 969 LOGV("setVolume(%f, %f)", left, right); 970 mLeftVolume = left; 971 mRightVolume = right; 972 if (mTrack) { 973 mTrack->setVolume(left, right); 974 } 975} 976 977#undef LOG_TAG 978#define LOG_TAG "AudioCache" 979MediaPlayerService::AudioCache::AudioCache(const char* name) : 980 mChannelCount(0), mFrameCount(1024), mSampleRate(0), mSize(0), 981 mError(NO_ERROR), mCommandComplete(false) 982{ 983 // create ashmem heap 984 mHeap = new MemoryHeapBase(kDefaultHeapSize, 0, name); 985} 986 987uint32_t MediaPlayerService::AudioCache::latency () const 988{ 989 return 0; 990} 991 992float MediaPlayerService::AudioCache::msecsPerFrame() const 993{ 994 return mMsecsPerFrame; 995} 996 997status_t MediaPlayerService::AudioCache::open(uint32_t sampleRate, int channelCount, int format, int bufferCount) 998{ 999 LOGV("open(%u, %d, %d, %d)", sampleRate, channelCount, format, bufferCount); 1000 if (mHeap->getHeapID() < 0) return NO_INIT; 1001 mSampleRate = sampleRate; 1002 mChannelCount = (uint16_t)channelCount; 1003 mFormat = (uint16_t)format; 1004 mMsecsPerFrame = 1.e3 / (float) sampleRate; 1005 return NO_ERROR; 1006} 1007 1008ssize_t MediaPlayerService::AudioCache::write(const void* buffer, size_t size) 1009{ 1010 LOGV("write(%p, %u)", buffer, size); 1011 if ((buffer == 0) || (size == 0)) return size; 1012 1013 uint8_t* p = static_cast<uint8_t*>(mHeap->getBase()); 1014 if (p == NULL) return NO_INIT; 1015 p += mSize; 1016 LOGV("memcpy(%p, %p, %u)", p, buffer, size); 1017 if (mSize + size > mHeap->getSize()) { 1018 LOGE("Heap size overflow! req size: %d, max size: %d", (mSize + size), mHeap->getSize()); 1019 size = mHeap->getSize() - mSize; 1020 } 1021 memcpy(p, buffer, size); 1022 mSize += size; 1023 return size; 1024} 1025 1026// call with lock held 1027status_t MediaPlayerService::AudioCache::wait() 1028{ 1029 Mutex::Autolock lock(mLock); 1030 if (!mCommandComplete) { 1031 mSignal.wait(mLock); 1032 } 1033 mCommandComplete = false; 1034 1035 if (mError == NO_ERROR) { 1036 LOGV("wait - success"); 1037 } else { 1038 LOGV("wait - error"); 1039 } 1040 return mError; 1041} 1042 1043void MediaPlayerService::AudioCache::notify(void* cookie, int msg, int ext1, int ext2) 1044{ 1045 LOGV("notify(%p, %d, %d, %d)", cookie, msg, ext1, ext2); 1046 AudioCache* p = static_cast<AudioCache*>(cookie); 1047 1048 // ignore buffering messages 1049 if (msg == MEDIA_BUFFERING_UPDATE) return; 1050 1051 // set error condition 1052 if (msg == MEDIA_ERROR) { 1053 LOGE("Error %d, %d occurred", ext1, ext2); 1054 p->mError = ext1; 1055 } 1056 1057 // wake up thread 1058 LOGV("wakeup thread"); 1059 p->mCommandComplete = true; 1060 p->mSignal.signal(); 1061} 1062 1063}; // namespace android 1064