MediaPlayerService.cpp revision 3c4b3e3f8927dd149df87bb98646497c7043d0ae
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 221#if defined(__arm__) 222extern "C" void get_malloc_leak_info(uint8_t** info, size_t* overallSize, 223 size_t* infoSize, size_t* totalMemory, size_t* backtraceSize); 224extern "C" void free_malloc_leak_info(uint8_t* info); 225 226void memStatus(int fd, const Vector<String16>& args) 227{ 228 const size_t SIZE = 256; 229 char buffer[SIZE]; 230 String8 result; 231 232 typedef struct { 233 size_t size; 234 size_t dups; 235 intptr_t * backtrace; 236 } AllocEntry; 237 238 uint8_t *info = NULL; 239 size_t overallSize = 0; 240 size_t infoSize = 0; 241 size_t totalMemory = 0; 242 size_t backtraceSize = 0; 243 244 get_malloc_leak_info(&info, &overallSize, &infoSize, &totalMemory, &backtraceSize); 245 if (info) { 246 uint8_t *ptr = info; 247 size_t count = overallSize / infoSize; 248 249 snprintf(buffer, SIZE, " Allocation count %i\n", count); 250 result.append(buffer); 251 252 AllocEntry * entries = new AllocEntry[count]; 253 254 for (size_t i = 0; i < count; i++) { 255 // Each entry should be size_t, size_t, intptr_t[backtraceSize] 256 AllocEntry *e = &entries[i]; 257 258 e->size = *reinterpret_cast<size_t *>(ptr); 259 ptr += sizeof(size_t); 260 261 e->dups = *reinterpret_cast<size_t *>(ptr); 262 ptr += sizeof(size_t); 263 264 e->backtrace = reinterpret_cast<intptr_t *>(ptr); 265 ptr += sizeof(intptr_t) * backtraceSize; 266 } 267 268 // Now we need to sort the entries. They come sorted by size but 269 // not by stack trace which causes problems using diff. 270 bool moved; 271 do { 272 moved = false; 273 for (size_t i = 0; i < (count - 1); i++) { 274 AllocEntry *e1 = &entries[i]; 275 AllocEntry *e2 = &entries[i+1]; 276 277 bool swap = e1->size < e2->size; 278 if (e1->size == e2->size) { 279 for(size_t j = 0; j < backtraceSize; j++) { 280 if (e1->backtrace[j] == e2->backtrace[j]) { 281 continue; 282 } 283 swap = e1->backtrace[j] < e2->backtrace[j]; 284 break; 285 } 286 } 287 if (swap) { 288 AllocEntry t = entries[i]; 289 entries[i] = entries[i+1]; 290 entries[i+1] = t; 291 moved = true; 292 } 293 } 294 } while (moved); 295 296 for (size_t i = 0; i < count; i++) { 297 AllocEntry *e = &entries[i]; 298 299 snprintf(buffer, SIZE, "size %8i, dup %4i", e->size, e->dups); 300 result.append(buffer); 301 for (size_t ct = 0; (ct < backtraceSize) && e->backtrace[ct]; ct++) { 302 if (ct) { 303 result.append(", "); 304 } 305 snprintf(buffer, SIZE, "0x%08x", e->backtrace[ct]); 306 result.append(buffer); 307 } 308 result.append("\n"); 309 } 310 311 delete[] entries; 312 free_malloc_leak_info(info); 313 } 314 315 write(fd, result.string(), result.size()); 316} 317#endif 318 319status_t MediaPlayerService::dump(int fd, const Vector<String16>& args) 320{ 321 const size_t SIZE = 256; 322 char buffer[SIZE]; 323 String8 result; 324 if (checkCallingPermission(String16("android.permission.DUMP")) == false) { 325 snprintf(buffer, SIZE, "Permission Denial: " 326 "can't dump MediaPlayerService from pid=%d, uid=%d\n", 327 IPCThreadState::self()->getCallingPid(), 328 IPCThreadState::self()->getCallingUid()); 329 result.append(buffer); 330 } else { 331 Mutex::Autolock lock(mLock); 332 for (int i = 0, n = mClients.size(); i < n; ++i) { 333 sp<Client> c = mClients[i].promote(); 334 if (c != 0) c->dump(fd, args); 335 } 336 result.append(" Files opened and/or mapped:\n"); 337 snprintf(buffer, SIZE, "/proc/%d/maps", myTid()); 338 FILE *f = fopen(buffer, "r"); 339 if (f) { 340 while (!feof(f)) { 341 fgets(buffer, SIZE, f); 342 if (strstr(buffer, " /sdcard/") || 343 strstr(buffer, " /system/sounds/") || 344 strstr(buffer, " /system/media/")) { 345 result.append(" "); 346 result.append(buffer); 347 } 348 } 349 fclose(f); 350 } else { 351 result.append("couldn't open "); 352 result.append(buffer); 353 result.append("\n"); 354 } 355 356 snprintf(buffer, SIZE, "/proc/%d/fd", myTid()); 357 DIR *d = opendir(buffer); 358 if (d) { 359 struct dirent *ent; 360 while((ent = readdir(d)) != NULL) { 361 if (strcmp(ent->d_name,".") && strcmp(ent->d_name,"..")) { 362 snprintf(buffer, SIZE, "/proc/%d/fd/%s", myTid(), ent->d_name); 363 struct stat s; 364 if (lstat(buffer, &s) == 0) { 365 if ((s.st_mode & S_IFMT) == S_IFLNK) { 366 char linkto[256]; 367 int len = readlink(buffer, linkto, sizeof(linkto)); 368 if(len > 0) { 369 if(len > 255) { 370 linkto[252] = '.'; 371 linkto[253] = '.'; 372 linkto[254] = '.'; 373 linkto[255] = 0; 374 } else { 375 linkto[len] = 0; 376 } 377 if (strstr(linkto, "/sdcard/") == linkto || 378 strstr(linkto, "/system/sounds/") == linkto || 379 strstr(linkto, "/system/media/") == linkto) { 380 result.append(" "); 381 result.append(buffer); 382 result.append(" -> "); 383 result.append(linkto); 384 result.append("\n"); 385 } 386 } 387 } else { 388 result.append(" unexpected type for "); 389 result.append(buffer); 390 result.append("\n"); 391 } 392 } 393 } 394 } 395 closedir(d); 396 } else { 397 result.append("couldn't open "); 398 result.append(buffer); 399 result.append("\n"); 400 } 401 402#if defined(__arm__) 403 bool dumpMem = false; 404 for (size_t i = 0; i < args.size(); i++) { 405 if (args[i] == String16("-m")) { 406 dumpMem = true; 407 } 408 } 409 if (dumpMem) { 410 memStatus(fd, args); 411 } 412#endif 413 } 414 write(fd, result.string(), result.size()); 415 return NO_ERROR; 416} 417 418void MediaPlayerService::removeClient(wp<Client> client) 419{ 420 Mutex::Autolock lock(mLock); 421 mClients.remove(client); 422} 423 424MediaPlayerService::Client::Client(const sp<MediaPlayerService>& service, pid_t pid, 425 int32_t connId, const sp<IMediaPlayerClient>& client) 426{ 427 LOGV("Client(%d) constructor", connId); 428 mPid = pid; 429 mConnId = connId; 430 mService = service; 431 mClient = client; 432 mLoop = false; 433 mStatus = NO_INIT; 434#if CALLBACK_ANTAGONIZER 435 LOGD("create Antagonizer"); 436 mAntagonizer = new Antagonizer(notify, this); 437#endif 438} 439 440MediaPlayerService::Client::~Client() 441{ 442 LOGV("Client(%d) destructor pid = %d", mConnId, mPid); 443 mAudioOutput.clear(); 444 wp<Client> client(this); 445 disconnect(); 446 mService->removeClient(client); 447} 448 449void MediaPlayerService::Client::disconnect() 450{ 451 LOGV("disconnect(%d) from pid %d", mConnId, mPid); 452 // grab local reference and clear main reference to prevent future 453 // access to object 454 sp<MediaPlayerBase> p; 455 { 456 Mutex::Autolock l(mLock); 457 p = mPlayer; 458 } 459 mClient.clear(); 460 mPlayer.clear(); 461 462 // clear the notification to prevent callbacks to dead client 463 // and reset the player. We assume the player will serialize 464 // access to itself if necessary. 465 if (p != 0) { 466 p->setNotifyCallback(0, 0); 467#if CALLBACK_ANTAGONIZER 468 LOGD("kill Antagonizer"); 469 mAntagonizer->kill(); 470#endif 471 p->reset(); 472 } 473 474 IPCThreadState::self()->flushCommands(); 475} 476 477static player_type getPlayerType(int fd, int64_t offset, int64_t length) 478{ 479 char buf[20]; 480 lseek(fd, offset, SEEK_SET); 481 read(fd, buf, sizeof(buf)); 482 lseek(fd, offset, SEEK_SET); 483 484 long ident = *((long*)buf); 485 486 // Ogg vorbis? 487 if (ident == 0x5367674f) // 'OggS' 488 return VORBIS_PLAYER; 489 490 // Some kind of MIDI? 491 EAS_DATA_HANDLE easdata; 492 if (EAS_Init(&easdata) == EAS_SUCCESS) { 493 EAS_FILE locator; 494 locator.path = NULL; 495 locator.fd = fd; 496 locator.offset = offset; 497 locator.length = length; 498 EAS_HANDLE eashandle; 499 if (EAS_OpenFile(easdata, &locator, &eashandle) == EAS_SUCCESS) { 500 EAS_CloseFile(easdata, eashandle); 501 EAS_Shutdown(easdata); 502 return SONIVOX_PLAYER; 503 } 504 EAS_Shutdown(easdata); 505 } 506 507 // Fall through to PV 508 return PV_PLAYER; 509} 510 511static player_type getPlayerType(const char* url) 512{ 513 514 // use MidiFile for MIDI extensions 515 int lenURL = strlen(url); 516 for (int i = 0; i < NELEM(FILE_EXTS); ++i) { 517 int len = strlen(FILE_EXTS[i].extension); 518 int start = lenURL - len; 519 if (start > 0) { 520 if (!strncmp(url + start, FILE_EXTS[i].extension, len)) { 521 return FILE_EXTS[i].playertype; 522 } 523 } 524 } 525 526 // Fall through to PV 527 return PV_PLAYER; 528} 529 530static sp<MediaPlayerBase> createPlayer(player_type playerType, void* cookie, 531 notify_callback_f notifyFunc) 532{ 533 sp<MediaPlayerBase> p; 534 switch (playerType) { 535 case PV_PLAYER: 536 LOGV(" create PVPlayer"); 537 p = new PVPlayer(); 538 break; 539 case SONIVOX_PLAYER: 540 LOGV(" create MidiFile"); 541 p = new MidiFile(); 542 break; 543 case VORBIS_PLAYER: 544 LOGV(" create VorbisPlayer"); 545 p = new VorbisPlayer(); 546 break; 547 } 548 if (p != NULL) { 549 if (p->initCheck() == NO_ERROR) { 550 p->setNotifyCallback(cookie, notifyFunc); 551 } else { 552 p.clear(); 553 } 554 } 555 if (p == NULL) { 556 LOGE("Failed to create player object"); 557 } 558 return p; 559} 560 561sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerType) 562{ 563 // determine if we have the right player type 564 sp<MediaPlayerBase> p = mPlayer; 565 if ((p != NULL) && (p->playerType() != playerType)) { 566 LOGV("delete player"); 567 p.clear(); 568 } 569 if (p == NULL) { 570 p = android::createPlayer(playerType, this, notify); 571 } 572 return p; 573} 574 575status_t MediaPlayerService::Client::setDataSource(const char *url) 576{ 577 LOGV("setDataSource(%s)", url); 578 if (url == NULL) 579 return UNKNOWN_ERROR; 580 581 if (strncmp(url, "content://", 10) == 0) { 582 // get a filedescriptor for the content Uri and 583 // pass it to the setDataSource(fd) method 584 585 String16 url16(url); 586 int fd = android::openContentProviderFile(url16); 587 if (fd < 0) 588 { 589 LOGE("Couldn't open fd for %s", url); 590 return UNKNOWN_ERROR; 591 } 592 setDataSource(fd, 0, 0x7fffffffffLL); // this sets mStatus 593 close(fd); 594 return mStatus; 595 } else { 596 player_type playerType = getPlayerType(url); 597 LOGV("player type = %d", playerType); 598 599 // create the right type of player 600 sp<MediaPlayerBase> p = createPlayer(playerType); 601 if (p == NULL) return NO_INIT; 602 603 if (!p->hardwareOutput()) { 604 mAudioOutput = new AudioOutput(); 605 static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput); 606 } 607 608 // now set data source 609 LOGV(" setDataSource"); 610 mStatus = p->setDataSource(url); 611 if (mStatus == NO_ERROR) mPlayer = p; 612 return mStatus; 613 } 614} 615 616status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64_t length) 617{ 618 LOGV("setDataSource fd=%d, offset=%lld, length=%lld", fd, offset, length); 619 struct stat sb; 620 int ret = fstat(fd, &sb); 621 if (ret != 0) { 622 LOGE("fstat(%d) failed: %d, %s", fd, ret, strerror(errno)); 623 return UNKNOWN_ERROR; 624 } 625 626 LOGV("st_dev = %llu", sb.st_dev); 627 LOGV("st_mode = %u", sb.st_mode); 628 LOGV("st_uid = %lu", sb.st_uid); 629 LOGV("st_gid = %lu", sb.st_gid); 630 LOGV("st_size = %llu", sb.st_size); 631 632 if (offset >= sb.st_size) { 633 LOGE("offset error"); 634 ::close(fd); 635 return UNKNOWN_ERROR; 636 } 637 if (offset + length > sb.st_size) { 638 length = sb.st_size - offset; 639 LOGV("calculated length = %lld", length); 640 } 641 642 player_type playerType = getPlayerType(fd, offset, length); 643 LOGV("player type = %d", playerType); 644 645 // create the right type of player 646 sp<MediaPlayerBase> p = createPlayer(playerType); 647 if (p == NULL) return NO_INIT; 648 649 if (!p->hardwareOutput()) { 650 mAudioOutput = new AudioOutput(); 651 static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput); 652 } 653 654 // now set data source 655 mStatus = p->setDataSource(fd, offset, length); 656 if (mStatus == NO_ERROR) mPlayer = p; 657 return mStatus; 658} 659 660status_t MediaPlayerService::Client::setVideoSurface(const sp<ISurface>& surface) 661{ 662 LOGV("[%d] setVideoSurface(%p)", mConnId, surface.get()); 663 sp<MediaPlayerBase> p = getPlayer(); 664 if (p == 0) return UNKNOWN_ERROR; 665 return p->setVideoSurface(surface); 666} 667 668status_t MediaPlayerService::Client::prepareAsync() 669{ 670 LOGV("[%d] prepareAsync", mConnId); 671 sp<MediaPlayerBase> p = getPlayer(); 672 if (p == 0) return UNKNOWN_ERROR; 673 status_t ret = p->prepareAsync(); 674#if CALLBACK_ANTAGONIZER 675 LOGD("start Antagonizer"); 676 if (ret == NO_ERROR) mAntagonizer->start(); 677#endif 678 return ret; 679} 680 681status_t MediaPlayerService::Client::start() 682{ 683 LOGV("[%d] start", mConnId); 684 sp<MediaPlayerBase> p = getPlayer(); 685 if (p == 0) return UNKNOWN_ERROR; 686 p->setLooping(mLoop); 687 return p->start(); 688} 689 690status_t MediaPlayerService::Client::stop() 691{ 692 LOGV("[%d] stop", mConnId); 693 sp<MediaPlayerBase> p = getPlayer(); 694 if (p == 0) return UNKNOWN_ERROR; 695 return p->stop(); 696} 697 698status_t MediaPlayerService::Client::pause() 699{ 700 LOGV("[%d] pause", mConnId); 701 sp<MediaPlayerBase> p = getPlayer(); 702 if (p == 0) return UNKNOWN_ERROR; 703 return p->pause(); 704} 705 706status_t MediaPlayerService::Client::isPlaying(bool* state) 707{ 708 *state = false; 709 sp<MediaPlayerBase> p = getPlayer(); 710 if (p == 0) return UNKNOWN_ERROR; 711 *state = p->isPlaying(); 712 LOGV("[%d] isPlaying: %d", mConnId, *state); 713 return NO_ERROR; 714} 715 716status_t MediaPlayerService::Client::getCurrentPosition(int *msec) 717{ 718 LOGV("getCurrentPosition"); 719 sp<MediaPlayerBase> p = getPlayer(); 720 if (p == 0) return UNKNOWN_ERROR; 721 status_t ret = p->getCurrentPosition(msec); 722 if (ret == NO_ERROR) { 723 LOGV("[%d] getCurrentPosition = %d", mConnId, *msec); 724 } else { 725 LOGE("getCurrentPosition returned %d", ret); 726 } 727 return ret; 728} 729 730status_t MediaPlayerService::Client::getDuration(int *msec) 731{ 732 LOGV("getDuration"); 733 sp<MediaPlayerBase> p = getPlayer(); 734 if (p == 0) return UNKNOWN_ERROR; 735 status_t ret = p->getDuration(msec); 736 if (ret == NO_ERROR) { 737 LOGV("[%d] getDuration = %d", mConnId, *msec); 738 } else { 739 LOGE("getDuration returned %d", ret); 740 } 741 return ret; 742} 743 744status_t MediaPlayerService::Client::seekTo(int msec) 745{ 746 LOGV("[%d] seekTo(%d)", mConnId, msec); 747 sp<MediaPlayerBase> p = getPlayer(); 748 if (p == 0) return UNKNOWN_ERROR; 749 return p->seekTo(msec); 750} 751 752status_t MediaPlayerService::Client::reset() 753{ 754 LOGV("[%d] reset", mConnId); 755 sp<MediaPlayerBase> p = getPlayer(); 756 if (p == 0) return UNKNOWN_ERROR; 757 return p->reset(); 758} 759 760status_t MediaPlayerService::Client::setAudioStreamType(int type) 761{ 762 LOGV("[%d] setAudioStreamType(%d)", mConnId, type); 763 // TODO: for hardware output, call player instead 764 Mutex::Autolock l(mLock); 765 if (mAudioOutput != 0) mAudioOutput->setAudioStreamType(type); 766 return NO_ERROR; 767} 768 769status_t MediaPlayerService::Client::setLooping(int loop) 770{ 771 LOGV("[%d] setLooping(%d)", mConnId, loop); 772 mLoop = loop; 773 sp<MediaPlayerBase> p = getPlayer(); 774 if (p != 0) return p->setLooping(loop); 775 return NO_ERROR; 776} 777 778status_t MediaPlayerService::Client::setVolume(float leftVolume, float rightVolume) 779{ 780 LOGV("[%d] setVolume(%f, %f)", mConnId, leftVolume, rightVolume); 781 // TODO: for hardware output, call player instead 782 Mutex::Autolock l(mLock); 783 if (mAudioOutput != 0) mAudioOutput->setVolume(leftVolume, rightVolume); 784 return NO_ERROR; 785} 786 787void MediaPlayerService::Client::notify(void* cookie, int msg, int ext1, int ext2) 788{ 789 Client* client = static_cast<Client*>(cookie); 790 LOGV("[%d] notify (%p, %d, %d, %d)", client->mConnId, cookie, msg, ext1, ext2); 791 client->mClient->notify(msg, ext1, ext2); 792} 793 794#if CALLBACK_ANTAGONIZER 795const int Antagonizer::interval = 10000; // 10 msecs 796 797Antagonizer::Antagonizer(notify_callback_f cb, void* client) : 798 mExit(false), mActive(false), mClient(client), mCb(cb) 799{ 800 createThread(callbackThread, this); 801} 802 803void Antagonizer::kill() 804{ 805 Mutex::Autolock _l(mLock); 806 mActive = false; 807 mExit = true; 808 mCondition.wait(mLock); 809} 810 811int Antagonizer::callbackThread(void* user) 812{ 813 LOGD("Antagonizer started"); 814 Antagonizer* p = reinterpret_cast<Antagonizer*>(user); 815 while (!p->mExit) { 816 if (p->mActive) { 817 LOGV("send event"); 818 p->mCb(p->mClient, 0, 0, 0); 819 } 820 usleep(interval); 821 } 822 Mutex::Autolock _l(p->mLock); 823 p->mCondition.signal(); 824 LOGD("Antagonizer stopped"); 825 return 0; 826} 827#endif 828 829static size_t kDefaultHeapSize = 1024 * 1024; // 1MB 830 831sp<IMemory> MediaPlayerService::decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) 832{ 833 LOGV("decode(%s)", url); 834 sp<MemoryBase> mem; 835 sp<MediaPlayerBase> player; 836 837 // Protect our precious, precious DRMd ringtones by only allowing 838 // decoding of http, but not filesystem paths or content Uris. 839 // If the application wants to decode those, it should open a 840 // filedescriptor for them and use that. 841 if (url != NULL && strncmp(url, "http://", 7) != 0) { 842 LOGD("Can't decode %s by path, use filedescriptor instead", url); 843 return mem; 844 } 845 846 player_type playerType = getPlayerType(url); 847 LOGV("player type = %d", playerType); 848 849 // create the right type of player 850 sp<AudioCache> cache = new AudioCache(url); 851 player = android::createPlayer(playerType, cache.get(), cache->notify); 852 if (player == NULL) goto Exit; 853 if (player->hardwareOutput()) goto Exit; 854 855 static_cast<MediaPlayerInterface*>(player.get())->setAudioSink(cache); 856 857 // set data source 858 if (player->setDataSource(url) != NO_ERROR) goto Exit; 859 860 LOGV("prepare"); 861 player->prepareAsync(); 862 863 LOGV("wait for prepare"); 864 if (cache->wait() != NO_ERROR) goto Exit; 865 866 LOGV("start"); 867 player->start(); 868 869 LOGV("wait for playback complete"); 870 if (cache->wait() != NO_ERROR) goto Exit; 871 872 mem = new MemoryBase(cache->getHeap(), 0, cache->size()); 873 *pSampleRate = cache->sampleRate(); 874 *pNumChannels = cache->channelCount(); 875 *pFormat = cache->format(); 876 LOGV("return memory @ %p, sampleRate=%u, channelCount = %d, format = %d", mem->pointer(), *pSampleRate, *pNumChannels, *pFormat); 877 878Exit: 879 if (player != 0) player->reset(); 880 return mem; 881} 882 883sp<IMemory> MediaPlayerService::decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) 884{ 885 LOGV("decode(%d, %lld, %lld)", fd, offset, length); 886 sp<MemoryBase> mem; 887 sp<MediaPlayerBase> player; 888 889 player_type playerType = getPlayerType(fd, offset, length); 890 LOGV("player type = %d", playerType); 891 892 // create the right type of player 893 sp<AudioCache> cache = new AudioCache("decode_fd"); 894 player = android::createPlayer(playerType, cache.get(), cache->notify); 895 if (player == NULL) goto Exit; 896 if (player->hardwareOutput()) goto Exit; 897 898 static_cast<MediaPlayerInterface*>(player.get())->setAudioSink(cache); 899 900 // set data source 901 if (player->setDataSource(fd, offset, length) != NO_ERROR) goto Exit; 902 903 LOGV("prepare"); 904 player->prepareAsync(); 905 906 LOGV("wait for prepare"); 907 if (cache->wait() != NO_ERROR) goto Exit; 908 909 LOGV("start"); 910 player->start(); 911 912 LOGV("wait for playback complete"); 913 if (cache->wait() != NO_ERROR) goto Exit; 914 915 mem = new MemoryBase(cache->getHeap(), 0, cache->size()); 916 *pSampleRate = cache->sampleRate(); 917 *pNumChannels = cache->channelCount(); 918 *pFormat = cache->format(); 919 LOGV("return memory @ %p, sampleRate=%u, channelCount = %d, format = %d", mem->pointer(), *pSampleRate, *pNumChannels, *pFormat); 920 921Exit: 922 if (player != 0) player->reset(); 923 ::close(fd); 924 return mem; 925} 926 927#undef LOG_TAG 928#define LOG_TAG "AudioSink" 929MediaPlayerService::AudioOutput::AudioOutput() 930{ 931 mTrack = 0; 932 mStreamType = AudioSystem::MUSIC; 933 mLeftVolume = 1.0; 934 mRightVolume = 1.0; 935 mLatency = 0; 936 mMsecsPerFrame = 0; 937 setMinBufferCount(); 938} 939 940MediaPlayerService::AudioOutput::~AudioOutput() 941{ 942 close(); 943} 944 945void MediaPlayerService::AudioOutput::setMinBufferCount() 946{ 947 char value[PROPERTY_VALUE_MAX]; 948 if (property_get("ro.kernel.qemu", value, 0)) { 949 mIsOnEmulator = true; 950 mMinBufferCount = 12; // to prevent systematic buffer underrun for emulator 951 } 952} 953 954bool MediaPlayerService::AudioOutput::isOnEmulator() 955{ 956 setMinBufferCount(); 957 return mIsOnEmulator; 958} 959 960int MediaPlayerService::AudioOutput::getMinBufferCount() 961{ 962 setMinBufferCount(); 963 return mMinBufferCount; 964} 965 966ssize_t MediaPlayerService::AudioOutput::bufferSize() const 967{ 968 if (mTrack == 0) return NO_INIT; 969 return mTrack->frameCount() * frameSize(); 970} 971 972ssize_t MediaPlayerService::AudioOutput::frameCount() const 973{ 974 if (mTrack == 0) return NO_INIT; 975 return mTrack->frameCount(); 976} 977 978ssize_t MediaPlayerService::AudioOutput::channelCount() const 979{ 980 if (mTrack == 0) return NO_INIT; 981 return mTrack->channelCount(); 982} 983 984ssize_t MediaPlayerService::AudioOutput::frameSize() const 985{ 986 if (mTrack == 0) return NO_INIT; 987 return mTrack->frameSize(); 988} 989 990uint32_t MediaPlayerService::AudioOutput::latency () const 991{ 992 return mLatency; 993} 994 995float MediaPlayerService::AudioOutput::msecsPerFrame() const 996{ 997 return mMsecsPerFrame; 998} 999 1000status_t MediaPlayerService::AudioOutput::open(uint32_t sampleRate, int channelCount, int format, int bufferCount) 1001{ 1002 // Check argument "bufferCount" against the mininum buffer count 1003 if (bufferCount < mMinBufferCount) { 1004 LOGD("bufferCount (%d) is too small and increased to %d", bufferCount, mMinBufferCount); 1005 bufferCount = mMinBufferCount; 1006 1007 } 1008 LOGV("open(%u, %d, %d, %d)", sampleRate, channelCount, format, bufferCount); 1009 if (mTrack) close(); 1010 int afSampleRate; 1011 int afFrameCount; 1012 int frameCount; 1013 1014 if (AudioSystem::getOutputFrameCount(&afFrameCount, mStreamType) != NO_ERROR) { 1015 return NO_INIT; 1016 } 1017 if (AudioSystem::getOutputSamplingRate(&afSampleRate, mStreamType) != NO_ERROR) { 1018 return NO_INIT; 1019 } 1020 1021 frameCount = (sampleRate*afFrameCount*bufferCount)/afSampleRate; 1022 AudioTrack *t = new AudioTrack(mStreamType, sampleRate, format, channelCount, frameCount); 1023 if ((t == 0) || (t->initCheck() != NO_ERROR)) { 1024 LOGE("Unable to create audio track"); 1025 delete t; 1026 return NO_INIT; 1027 } 1028 1029 LOGV("setVolume"); 1030 t->setVolume(mLeftVolume, mRightVolume); 1031 mMsecsPerFrame = 1.e3 / (float) sampleRate; 1032 mLatency = t->latency() + kAudioVideoDelayMs; 1033 mTrack = t; 1034 return NO_ERROR; 1035} 1036 1037void MediaPlayerService::AudioOutput::start() 1038{ 1039 LOGV("start"); 1040 if (mTrack) { 1041 mTrack->setVolume(mLeftVolume, mRightVolume); 1042 mTrack->start(); 1043 } 1044} 1045 1046ssize_t MediaPlayerService::AudioOutput::write(const void* buffer, size_t size) 1047{ 1048 //LOGV("write(%p, %u)", buffer, size); 1049 if (mTrack) return mTrack->write(buffer, size); 1050 return NO_INIT; 1051} 1052 1053void MediaPlayerService::AudioOutput::stop() 1054{ 1055 LOGV("stop"); 1056 if (mTrack) mTrack->stop(); 1057} 1058 1059void MediaPlayerService::AudioOutput::flush() 1060{ 1061 LOGV("flush"); 1062 if (mTrack) mTrack->flush(); 1063} 1064 1065void MediaPlayerService::AudioOutput::pause() 1066{ 1067 LOGV("pause"); 1068 if (mTrack) mTrack->pause(); 1069} 1070 1071void MediaPlayerService::AudioOutput::close() 1072{ 1073 LOGV("close"); 1074 delete mTrack; 1075 mTrack = 0; 1076} 1077 1078void MediaPlayerService::AudioOutput::setVolume(float left, float right) 1079{ 1080 LOGV("setVolume(%f, %f)", left, right); 1081 mLeftVolume = left; 1082 mRightVolume = right; 1083 if (mTrack) { 1084 mTrack->setVolume(left, right); 1085 } 1086} 1087 1088#undef LOG_TAG 1089#define LOG_TAG "AudioCache" 1090MediaPlayerService::AudioCache::AudioCache(const char* name) : 1091 mChannelCount(0), mFrameCount(1024), mSampleRate(0), mSize(0), 1092 mError(NO_ERROR), mCommandComplete(false) 1093{ 1094 // create ashmem heap 1095 mHeap = new MemoryHeapBase(kDefaultHeapSize, 0, name); 1096} 1097 1098uint32_t MediaPlayerService::AudioCache::latency () const 1099{ 1100 return 0; 1101} 1102 1103float MediaPlayerService::AudioCache::msecsPerFrame() const 1104{ 1105 return mMsecsPerFrame; 1106} 1107 1108status_t MediaPlayerService::AudioCache::open(uint32_t sampleRate, int channelCount, int format, int bufferCount) 1109{ 1110 LOGV("open(%u, %d, %d, %d)", sampleRate, channelCount, format, bufferCount); 1111 if (mHeap->getHeapID() < 0) return NO_INIT; 1112 mSampleRate = sampleRate; 1113 mChannelCount = (uint16_t)channelCount; 1114 mFormat = (uint16_t)format; 1115 mMsecsPerFrame = 1.e3 / (float) sampleRate; 1116 return NO_ERROR; 1117} 1118 1119ssize_t MediaPlayerService::AudioCache::write(const void* buffer, size_t size) 1120{ 1121 LOGV("write(%p, %u)", buffer, size); 1122 if ((buffer == 0) || (size == 0)) return size; 1123 1124 uint8_t* p = static_cast<uint8_t*>(mHeap->getBase()); 1125 if (p == NULL) return NO_INIT; 1126 p += mSize; 1127 LOGV("memcpy(%p, %p, %u)", p, buffer, size); 1128 if (mSize + size > mHeap->getSize()) { 1129 LOGE("Heap size overflow! req size: %d, max size: %d", (mSize + size), mHeap->getSize()); 1130 size = mHeap->getSize() - mSize; 1131 } 1132 memcpy(p, buffer, size); 1133 mSize += size; 1134 return size; 1135} 1136 1137// call with lock held 1138status_t MediaPlayerService::AudioCache::wait() 1139{ 1140 Mutex::Autolock lock(mLock); 1141 if (!mCommandComplete) { 1142 mSignal.wait(mLock); 1143 } 1144 mCommandComplete = false; 1145 1146 if (mError == NO_ERROR) { 1147 LOGV("wait - success"); 1148 } else { 1149 LOGV("wait - error"); 1150 } 1151 return mError; 1152} 1153 1154void MediaPlayerService::AudioCache::notify(void* cookie, int msg, int ext1, int ext2) 1155{ 1156 LOGV("notify(%p, %d, %d, %d)", cookie, msg, ext1, ext2); 1157 AudioCache* p = static_cast<AudioCache*>(cookie); 1158 1159 // ignore buffering messages 1160 if (msg == MEDIA_BUFFERING_UPDATE) return; 1161 1162 // set error condition 1163 if (msg == MEDIA_ERROR) { 1164 LOGE("Error %d, %d occurred", ext1, ext2); 1165 p->mError = ext1; 1166 } 1167 1168 // wake up thread 1169 LOGV("wakeup thread"); 1170 p->mCommandComplete = true; 1171 p->mSignal.signal(); 1172} 1173 1174}; // namespace android 1175