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