MediaPlayerService.cpp revision 99ffda877980468a9ae31e013cd10fb3645df1b0
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 mPlayer.clear(); 460 461 // clear the notification to prevent callbacks to dead client 462 // and reset the player. We assume the player will serialize 463 // access to itself if necessary. 464 if (p != 0) { 465 p->setNotifyCallback(0, 0); 466#if CALLBACK_ANTAGONIZER 467 LOGD("kill Antagonizer"); 468 mAntagonizer->kill(); 469#endif 470 p->reset(); 471 } 472 473 IPCThreadState::self()->flushCommands(); 474} 475 476static player_type getPlayerType(int fd, int64_t offset, int64_t length) 477{ 478 char buf[20]; 479 lseek(fd, offset, SEEK_SET); 480 read(fd, buf, sizeof(buf)); 481 lseek(fd, offset, SEEK_SET); 482 483 long ident = *((long*)buf); 484 485 // Ogg vorbis? 486 if (ident == 0x5367674f) // 'OggS' 487 return VORBIS_PLAYER; 488 489 // Some kind of MIDI? 490 EAS_DATA_HANDLE easdata; 491 if (EAS_Init(&easdata) == EAS_SUCCESS) { 492 EAS_FILE locator; 493 locator.path = NULL; 494 locator.fd = fd; 495 locator.offset = offset; 496 locator.length = length; 497 EAS_HANDLE eashandle; 498 if (EAS_OpenFile(easdata, &locator, &eashandle) == EAS_SUCCESS) { 499 EAS_CloseFile(easdata, eashandle); 500 EAS_Shutdown(easdata); 501 return SONIVOX_PLAYER; 502 } 503 EAS_Shutdown(easdata); 504 } 505 506 // Fall through to PV 507 return PV_PLAYER; 508} 509 510static player_type getPlayerType(const char* url) 511{ 512 513 // use MidiFile for MIDI extensions 514 int lenURL = strlen(url); 515 for (int i = 0; i < NELEM(FILE_EXTS); ++i) { 516 int len = strlen(FILE_EXTS[i].extension); 517 int start = lenURL - len; 518 if (start > 0) { 519 if (!strncmp(url + start, FILE_EXTS[i].extension, len)) { 520 return FILE_EXTS[i].playertype; 521 } 522 } 523 } 524 525 // Fall through to PV 526 return PV_PLAYER; 527} 528 529static sp<MediaPlayerBase> createPlayer(player_type playerType, void* cookie, 530 notify_callback_f notifyFunc) 531{ 532 sp<MediaPlayerBase> p; 533 switch (playerType) { 534 case PV_PLAYER: 535 LOGV(" create PVPlayer"); 536 p = new PVPlayer(); 537 break; 538 case SONIVOX_PLAYER: 539 LOGV(" create MidiFile"); 540 p = new MidiFile(); 541 break; 542 case VORBIS_PLAYER: 543 LOGV(" create VorbisPlayer"); 544 p = new VorbisPlayer(); 545 break; 546 } 547 if (p != NULL) { 548 if (p->initCheck() == NO_ERROR) { 549 p->setNotifyCallback(cookie, notifyFunc); 550 } else { 551 p.clear(); 552 } 553 } 554 if (p == NULL) { 555 LOGE("Failed to create player object"); 556 } 557 return p; 558} 559 560sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerType) 561{ 562 // determine if we have the right player type 563 sp<MediaPlayerBase> p = mPlayer; 564 if ((p != NULL) && (p->playerType() != playerType)) { 565 LOGV("delete player"); 566 p.clear(); 567 } 568 if (p == NULL) { 569 p = android::createPlayer(playerType, this, notify); 570 } 571 return p; 572} 573 574status_t MediaPlayerService::Client::setDataSource(const char *url) 575{ 576 LOGV("setDataSource(%s)", url); 577 if (url == NULL) 578 return UNKNOWN_ERROR; 579 580 if (strncmp(url, "content://", 10) == 0) { 581 // get a filedescriptor for the content Uri and 582 // pass it to the setDataSource(fd) method 583 584 String16 url16(url); 585 int fd = android::openContentProviderFile(url16); 586 if (fd < 0) 587 { 588 LOGE("Couldn't open fd for %s", url); 589 return UNKNOWN_ERROR; 590 } 591 setDataSource(fd, 0, 0x7fffffffffLL); // this sets mStatus 592 close(fd); 593 return mStatus; 594 } else { 595 player_type playerType = getPlayerType(url); 596 LOGV("player type = %d", playerType); 597 598 // create the right type of player 599 sp<MediaPlayerBase> p = createPlayer(playerType); 600 if (p == NULL) return NO_INIT; 601 602 if (!p->hardwareOutput()) { 603 mAudioOutput = new AudioOutput(); 604 static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput); 605 } 606 607 // now set data source 608 LOGV(" setDataSource"); 609 mStatus = p->setDataSource(url); 610 if (mStatus == NO_ERROR) mPlayer = p; 611 return mStatus; 612 } 613} 614 615status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64_t length) 616{ 617 LOGV("setDataSource fd=%d, offset=%lld, length=%lld", fd, offset, length); 618 struct stat sb; 619 int ret = fstat(fd, &sb); 620 if (ret != 0) { 621 LOGE("fstat(%d) failed: %d, %s", fd, ret, strerror(errno)); 622 return UNKNOWN_ERROR; 623 } 624 625 LOGV("st_dev = %llu", sb.st_dev); 626 LOGV("st_mode = %u", sb.st_mode); 627 LOGV("st_uid = %lu", sb.st_uid); 628 LOGV("st_gid = %lu", sb.st_gid); 629 LOGV("st_size = %llu", sb.st_size); 630 631 if (offset >= sb.st_size) { 632 LOGE("offset error"); 633 ::close(fd); 634 return UNKNOWN_ERROR; 635 } 636 if (offset + length > sb.st_size) { 637 length = sb.st_size - offset; 638 LOGV("calculated length = %lld", length); 639 } 640 641 player_type playerType = getPlayerType(fd, offset, length); 642 LOGV("player type = %d", playerType); 643 644 // create the right type of player 645 sp<MediaPlayerBase> p = createPlayer(playerType); 646 if (p == NULL) return NO_INIT; 647 648 if (!p->hardwareOutput()) { 649 mAudioOutput = new AudioOutput(); 650 static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput); 651 } 652 653 // now set data source 654 mStatus = p->setDataSource(fd, offset, length); 655 if (mStatus == NO_ERROR) mPlayer = p; 656 return mStatus; 657} 658 659status_t MediaPlayerService::Client::setVideoSurface(const sp<ISurface>& surface) 660{ 661 LOGV("[%d] setVideoSurface(%p)", mConnId, surface.get()); 662 sp<MediaPlayerBase> p = getPlayer(); 663 if (p == 0) return UNKNOWN_ERROR; 664 return p->setVideoSurface(surface); 665} 666 667status_t MediaPlayerService::Client::prepareAsync() 668{ 669 LOGV("[%d] prepareAsync", mConnId); 670 sp<MediaPlayerBase> p = getPlayer(); 671 if (p == 0) return UNKNOWN_ERROR; 672 status_t ret = p->prepareAsync(); 673#if CALLBACK_ANTAGONIZER 674 LOGD("start Antagonizer"); 675 if (ret == NO_ERROR) mAntagonizer->start(); 676#endif 677 return ret; 678} 679 680status_t MediaPlayerService::Client::start() 681{ 682 LOGV("[%d] start", mConnId); 683 sp<MediaPlayerBase> p = getPlayer(); 684 if (p == 0) return UNKNOWN_ERROR; 685 p->setLooping(mLoop); 686 return p->start(); 687} 688 689status_t MediaPlayerService::Client::stop() 690{ 691 LOGV("[%d] stop", mConnId); 692 sp<MediaPlayerBase> p = getPlayer(); 693 if (p == 0) return UNKNOWN_ERROR; 694 return p->stop(); 695} 696 697status_t MediaPlayerService::Client::pause() 698{ 699 LOGV("[%d] pause", mConnId); 700 sp<MediaPlayerBase> p = getPlayer(); 701 if (p == 0) return UNKNOWN_ERROR; 702 return p->pause(); 703} 704 705status_t MediaPlayerService::Client::isPlaying(bool* state) 706{ 707 *state = false; 708 sp<MediaPlayerBase> p = getPlayer(); 709 if (p == 0) return UNKNOWN_ERROR; 710 *state = p->isPlaying(); 711 LOGV("[%d] isPlaying: %d", mConnId, *state); 712 return NO_ERROR; 713} 714 715status_t MediaPlayerService::Client::getCurrentPosition(int *msec) 716{ 717 LOGV("getCurrentPosition"); 718 sp<MediaPlayerBase> p = getPlayer(); 719 if (p == 0) return UNKNOWN_ERROR; 720 status_t ret = p->getCurrentPosition(msec); 721 if (ret == NO_ERROR) { 722 LOGV("[%d] getCurrentPosition = %d", mConnId, *msec); 723 } else { 724 LOGE("getCurrentPosition returned %d", ret); 725 } 726 return ret; 727} 728 729status_t MediaPlayerService::Client::getDuration(int *msec) 730{ 731 LOGV("getDuration"); 732 sp<MediaPlayerBase> p = getPlayer(); 733 if (p == 0) return UNKNOWN_ERROR; 734 status_t ret = p->getDuration(msec); 735 if (ret == NO_ERROR) { 736 LOGV("[%d] getDuration = %d", mConnId, *msec); 737 } else { 738 LOGE("getDuration returned %d", ret); 739 } 740 return ret; 741} 742 743status_t MediaPlayerService::Client::seekTo(int msec) 744{ 745 LOGV("[%d] seekTo(%d)", mConnId, msec); 746 sp<MediaPlayerBase> p = getPlayer(); 747 if (p == 0) return UNKNOWN_ERROR; 748 return p->seekTo(msec); 749} 750 751status_t MediaPlayerService::Client::reset() 752{ 753 LOGV("[%d] reset", mConnId); 754 sp<MediaPlayerBase> p = getPlayer(); 755 if (p == 0) return UNKNOWN_ERROR; 756 return p->reset(); 757} 758 759status_t MediaPlayerService::Client::setAudioStreamType(int type) 760{ 761 LOGV("[%d] setAudioStreamType(%d)", mConnId, type); 762 // TODO: for hardware output, call player instead 763 Mutex::Autolock l(mLock); 764 if (mAudioOutput != 0) mAudioOutput->setAudioStreamType(type); 765 return NO_ERROR; 766} 767 768status_t MediaPlayerService::Client::setLooping(int loop) 769{ 770 LOGV("[%d] setLooping(%d)", mConnId, loop); 771 mLoop = loop; 772 sp<MediaPlayerBase> p = getPlayer(); 773 if (p != 0) return p->setLooping(loop); 774 return NO_ERROR; 775} 776 777status_t MediaPlayerService::Client::setVolume(float leftVolume, float rightVolume) 778{ 779 LOGV("[%d] setVolume(%f, %f)", mConnId, leftVolume, rightVolume); 780 // TODO: for hardware output, call player instead 781 Mutex::Autolock l(mLock); 782 if (mAudioOutput != 0) mAudioOutput->setVolume(leftVolume, rightVolume); 783 return NO_ERROR; 784} 785 786void MediaPlayerService::Client::notify(void* cookie, int msg, int ext1, int ext2) 787{ 788 Client* client = static_cast<Client*>(cookie); 789 LOGV("[%d] notify (%p, %d, %d, %d)", client->mConnId, cookie, msg, ext1, ext2); 790 client->mClient->notify(msg, ext1, ext2); 791} 792 793#if CALLBACK_ANTAGONIZER 794const int Antagonizer::interval = 10000; // 10 msecs 795 796Antagonizer::Antagonizer(notify_callback_f cb, void* client) : 797 mExit(false), mActive(false), mClient(client), mCb(cb) 798{ 799 createThread(callbackThread, this); 800} 801 802void Antagonizer::kill() 803{ 804 Mutex::Autolock _l(mLock); 805 mActive = false; 806 mExit = true; 807 mCondition.wait(mLock); 808} 809 810int Antagonizer::callbackThread(void* user) 811{ 812 LOGD("Antagonizer started"); 813 Antagonizer* p = reinterpret_cast<Antagonizer*>(user); 814 while (!p->mExit) { 815 if (p->mActive) { 816 LOGV("send event"); 817 p->mCb(p->mClient, 0, 0, 0); 818 } 819 usleep(interval); 820 } 821 Mutex::Autolock _l(p->mLock); 822 p->mCondition.signal(); 823 LOGD("Antagonizer stopped"); 824 return 0; 825} 826#endif 827 828static size_t kDefaultHeapSize = 1024 * 1024; // 1MB 829 830sp<IMemory> MediaPlayerService::decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) 831{ 832 LOGV("decode(%s)", url); 833 sp<MemoryBase> mem; 834 sp<MediaPlayerBase> player; 835 836 // Protect our precious, precious DRMd ringtones by only allowing 837 // decoding of http, but not filesystem paths or content Uris. 838 // If the application wants to decode those, it should open a 839 // filedescriptor for them and use that. 840 if (url != NULL && strncmp(url, "http://", 7) != 0) { 841 LOGD("Can't decode %s by path, use filedescriptor instead", url); 842 return mem; 843 } 844 845 player_type playerType = getPlayerType(url); 846 LOGV("player type = %d", playerType); 847 848 // create the right type of player 849 sp<AudioCache> cache = new AudioCache(url); 850 player = android::createPlayer(playerType, cache.get(), cache->notify); 851 if (player == NULL) goto Exit; 852 if (player->hardwareOutput()) goto Exit; 853 854 static_cast<MediaPlayerInterface*>(player.get())->setAudioSink(cache); 855 856 // set data source 857 if (player->setDataSource(url) != NO_ERROR) goto Exit; 858 859 LOGV("prepare"); 860 player->prepareAsync(); 861 862 LOGV("wait for prepare"); 863 if (cache->wait() != NO_ERROR) goto Exit; 864 865 LOGV("start"); 866 player->start(); 867 868 LOGV("wait for playback complete"); 869 if (cache->wait() != NO_ERROR) goto Exit; 870 871 mem = new MemoryBase(cache->getHeap(), 0, cache->size()); 872 *pSampleRate = cache->sampleRate(); 873 *pNumChannels = cache->channelCount(); 874 *pFormat = cache->format(); 875 LOGV("return memory @ %p, sampleRate=%u, channelCount = %d, format = %d", mem->pointer(), *pSampleRate, *pNumChannels, *pFormat); 876 877Exit: 878 if (player != 0) player->reset(); 879 return mem; 880} 881 882sp<IMemory> MediaPlayerService::decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) 883{ 884 LOGV("decode(%d, %lld, %lld)", fd, offset, length); 885 sp<MemoryBase> mem; 886 sp<MediaPlayerBase> player; 887 888 player_type playerType = getPlayerType(fd, offset, length); 889 LOGV("player type = %d", playerType); 890 891 // create the right type of player 892 sp<AudioCache> cache = new AudioCache("decode_fd"); 893 player = android::createPlayer(playerType, cache.get(), cache->notify); 894 if (player == NULL) goto Exit; 895 if (player->hardwareOutput()) goto Exit; 896 897 static_cast<MediaPlayerInterface*>(player.get())->setAudioSink(cache); 898 899 // set data source 900 if (player->setDataSource(fd, offset, length) != NO_ERROR) goto Exit; 901 902 LOGV("prepare"); 903 player->prepareAsync(); 904 905 LOGV("wait for prepare"); 906 if (cache->wait() != NO_ERROR) goto Exit; 907 908 LOGV("start"); 909 player->start(); 910 911 LOGV("wait for playback complete"); 912 if (cache->wait() != NO_ERROR) goto Exit; 913 914 mem = new MemoryBase(cache->getHeap(), 0, cache->size()); 915 *pSampleRate = cache->sampleRate(); 916 *pNumChannels = cache->channelCount(); 917 *pFormat = cache->format(); 918 LOGV("return memory @ %p, sampleRate=%u, channelCount = %d, format = %d", mem->pointer(), *pSampleRate, *pNumChannels, *pFormat); 919 920Exit: 921 if (player != 0) player->reset(); 922 ::close(fd); 923 return mem; 924} 925 926#undef LOG_TAG 927#define LOG_TAG "AudioSink" 928MediaPlayerService::AudioOutput::AudioOutput() 929{ 930 mTrack = 0; 931 mStreamType = AudioSystem::MUSIC; 932 mLeftVolume = 1.0; 933 mRightVolume = 1.0; 934 mLatency = 0; 935 mMsecsPerFrame = 0; 936 setMinBufferCount(); 937} 938 939MediaPlayerService::AudioOutput::~AudioOutput() 940{ 941 close(); 942} 943 944void MediaPlayerService::AudioOutput::setMinBufferCount() 945{ 946 char value[PROPERTY_VALUE_MAX]; 947 if (property_get("ro.kernel.qemu", value, 0)) { 948 mIsOnEmulator = true; 949 mMinBufferCount = 12; // to prevent systematic buffer underrun for emulator 950 } 951} 952 953bool MediaPlayerService::AudioOutput::isOnEmulator() 954{ 955 setMinBufferCount(); 956 return mIsOnEmulator; 957} 958 959int MediaPlayerService::AudioOutput::getMinBufferCount() 960{ 961 setMinBufferCount(); 962 return mMinBufferCount; 963} 964 965ssize_t MediaPlayerService::AudioOutput::bufferSize() const 966{ 967 if (mTrack == 0) return NO_INIT; 968 return mTrack->frameCount() * frameSize(); 969} 970 971ssize_t MediaPlayerService::AudioOutput::frameCount() const 972{ 973 if (mTrack == 0) return NO_INIT; 974 return mTrack->frameCount(); 975} 976 977ssize_t MediaPlayerService::AudioOutput::channelCount() const 978{ 979 if (mTrack == 0) return NO_INIT; 980 return mTrack->channelCount(); 981} 982 983ssize_t MediaPlayerService::AudioOutput::frameSize() const 984{ 985 if (mTrack == 0) return NO_INIT; 986 return mTrack->frameSize(); 987} 988 989uint32_t MediaPlayerService::AudioOutput::latency () const 990{ 991 return mLatency; 992} 993 994float MediaPlayerService::AudioOutput::msecsPerFrame() const 995{ 996 return mMsecsPerFrame; 997} 998 999status_t MediaPlayerService::AudioOutput::open(uint32_t sampleRate, int channelCount, int format, int bufferCount) 1000{ 1001 // Check argument "bufferCount" against the mininum buffer count 1002 if (bufferCount < mMinBufferCount) { 1003 LOGD("bufferCount (%d) is too small and increased to %d", bufferCount, mMinBufferCount); 1004 bufferCount = mMinBufferCount; 1005 1006 } 1007 LOGV("open(%u, %d, %d, %d)", sampleRate, channelCount, format, bufferCount); 1008 if (mTrack) close(); 1009 int afSampleRate; 1010 int afFrameCount; 1011 int frameCount; 1012 1013 if (AudioSystem::getOutputFrameCount(&afFrameCount, mStreamType) != NO_ERROR) { 1014 return NO_INIT; 1015 } 1016 if (AudioSystem::getOutputSamplingRate(&afSampleRate, mStreamType) != NO_ERROR) { 1017 return NO_INIT; 1018 } 1019 1020 frameCount = (sampleRate*afFrameCount*bufferCount)/afSampleRate; 1021 AudioTrack *t = new AudioTrack(mStreamType, sampleRate, format, channelCount, frameCount); 1022 if ((t == 0) || (t->initCheck() != NO_ERROR)) { 1023 LOGE("Unable to create audio track"); 1024 delete t; 1025 return NO_INIT; 1026 } 1027 1028 LOGV("setVolume"); 1029 t->setVolume(mLeftVolume, mRightVolume); 1030 mMsecsPerFrame = 1.e3 / (float) sampleRate; 1031 mLatency = t->latency() + kAudioVideoDelayMs; 1032 mTrack = t; 1033 return NO_ERROR; 1034} 1035 1036void MediaPlayerService::AudioOutput::start() 1037{ 1038 LOGV("start"); 1039 if (mTrack) { 1040 mTrack->setVolume(mLeftVolume, mRightVolume); 1041 mTrack->start(); 1042 } 1043} 1044 1045ssize_t MediaPlayerService::AudioOutput::write(const void* buffer, size_t size) 1046{ 1047 //LOGV("write(%p, %u)", buffer, size); 1048 if (mTrack) return mTrack->write(buffer, size); 1049 return NO_INIT; 1050} 1051 1052void MediaPlayerService::AudioOutput::stop() 1053{ 1054 LOGV("stop"); 1055 if (mTrack) mTrack->stop(); 1056} 1057 1058void MediaPlayerService::AudioOutput::flush() 1059{ 1060 LOGV("flush"); 1061 if (mTrack) mTrack->flush(); 1062} 1063 1064void MediaPlayerService::AudioOutput::pause() 1065{ 1066 LOGV("pause"); 1067 if (mTrack) mTrack->pause(); 1068} 1069 1070void MediaPlayerService::AudioOutput::close() 1071{ 1072 LOGV("close"); 1073 delete mTrack; 1074 mTrack = 0; 1075} 1076 1077void MediaPlayerService::AudioOutput::setVolume(float left, float right) 1078{ 1079 LOGV("setVolume(%f, %f)", left, right); 1080 mLeftVolume = left; 1081 mRightVolume = right; 1082 if (mTrack) { 1083 mTrack->setVolume(left, right); 1084 } 1085} 1086 1087#undef LOG_TAG 1088#define LOG_TAG "AudioCache" 1089MediaPlayerService::AudioCache::AudioCache(const char* name) : 1090 mChannelCount(0), mFrameCount(1024), mSampleRate(0), mSize(0), 1091 mError(NO_ERROR), mCommandComplete(false) 1092{ 1093 // create ashmem heap 1094 mHeap = new MemoryHeapBase(kDefaultHeapSize, 0, name); 1095} 1096 1097uint32_t MediaPlayerService::AudioCache::latency () const 1098{ 1099 return 0; 1100} 1101 1102float MediaPlayerService::AudioCache::msecsPerFrame() const 1103{ 1104 return mMsecsPerFrame; 1105} 1106 1107status_t MediaPlayerService::AudioCache::open(uint32_t sampleRate, int channelCount, int format, int bufferCount) 1108{ 1109 LOGV("open(%u, %d, %d, %d)", sampleRate, channelCount, format, bufferCount); 1110 if (mHeap->getHeapID() < 0) return NO_INIT; 1111 mSampleRate = sampleRate; 1112 mChannelCount = (uint16_t)channelCount; 1113 mFormat = (uint16_t)format; 1114 mMsecsPerFrame = 1.e3 / (float) sampleRate; 1115 return NO_ERROR; 1116} 1117 1118ssize_t MediaPlayerService::AudioCache::write(const void* buffer, size_t size) 1119{ 1120 LOGV("write(%p, %u)", buffer, size); 1121 if ((buffer == 0) || (size == 0)) return size; 1122 1123 uint8_t* p = static_cast<uint8_t*>(mHeap->getBase()); 1124 if (p == NULL) return NO_INIT; 1125 p += mSize; 1126 LOGV("memcpy(%p, %p, %u)", p, buffer, size); 1127 if (mSize + size > mHeap->getSize()) { 1128 LOGE("Heap size overflow! req size: %d, max size: %d", (mSize + size), mHeap->getSize()); 1129 size = mHeap->getSize() - mSize; 1130 } 1131 memcpy(p, buffer, size); 1132 mSize += size; 1133 return size; 1134} 1135 1136// call with lock held 1137status_t MediaPlayerService::AudioCache::wait() 1138{ 1139 Mutex::Autolock lock(mLock); 1140 if (!mCommandComplete) { 1141 mSignal.wait(mLock); 1142 } 1143 mCommandComplete = false; 1144 1145 if (mError == NO_ERROR) { 1146 LOGV("wait - success"); 1147 } else { 1148 LOGV("wait - error"); 1149 } 1150 return mError; 1151} 1152 1153void MediaPlayerService::AudioCache::notify(void* cookie, int msg, int ext1, int ext2) 1154{ 1155 LOGV("notify(%p, %d, %d, %d)", cookie, msg, ext1, ext2); 1156 AudioCache* p = static_cast<AudioCache*>(cookie); 1157 1158 // ignore buffering messages 1159 if (msg == MEDIA_BUFFERING_UPDATE) return; 1160 1161 // set error condition 1162 if (msg == MEDIA_ERROR) { 1163 LOGE("Error %d, %d occurred", ext1, ext2); 1164 p->mError = ext1; 1165 } 1166 1167 // wake up thread 1168 LOGV("wakeup thread"); 1169 p->mCommandComplete = true; 1170 p->mSignal.signal(); 1171} 1172 1173}; // namespace android 1174