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