MediaPlayerService.cpp revision 0512ab559d4670c2204078470d7ef5d376811c57
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 <sys/time.h> 27#include <dirent.h> 28#include <unistd.h> 29 30#include <string.h> 31 32#include <cutils/atomic.h> 33#include <cutils/properties.h> // for property_get 34 35#include <utils/misc.h> 36 37#include <android_runtime/ActivityManager.h> 38 39#include <binder/IPCThreadState.h> 40#include <binder/IServiceManager.h> 41#include <binder/MemoryHeapBase.h> 42#include <binder/MemoryBase.h> 43#include <utils/Errors.h> // for status_t 44#include <utils/String8.h> 45#include <utils/SystemClock.h> 46#include <utils/Vector.h> 47#include <cutils/properties.h> 48 49#include <media/MediaPlayerInterface.h> 50#include <media/mediarecorder.h> 51#include <media/MediaMetadataRetrieverInterface.h> 52#include <media/Metadata.h> 53#include <media/AudioTrack.h> 54#include <media/MemoryLeakTrackUtil.h> 55 56#include <system/audio.h> 57 58#include <private/android_filesystem_config.h> 59 60#include "MediaRecorderClient.h" 61#include "MediaPlayerService.h" 62#include "MetadataRetrieverClient.h" 63 64#include "MidiFile.h" 65#include "TestPlayerStub.h" 66#include "StagefrightPlayer.h" 67#include "nuplayer/NuPlayerDriver.h" 68 69#include <OMX.h> 70 71namespace { 72using android::media::Metadata; 73using android::status_t; 74using android::OK; 75using android::BAD_VALUE; 76using android::NOT_ENOUGH_DATA; 77using android::Parcel; 78 79// Max number of entries in the filter. 80const int kMaxFilterSize = 64; // I pulled that out of thin air. 81 82// FIXME: Move all the metadata related function in the Metadata.cpp 83 84 85// Unmarshall a filter from a Parcel. 86// Filter format in a parcel: 87// 88// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 89// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 90// | number of entries (n) | 91// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 92// | metadata type 1 | 93// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 94// | metadata type 2 | 95// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 96// .... 97// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 98// | metadata type n | 99// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 100// 101// @param p Parcel that should start with a filter. 102// @param[out] filter On exit contains the list of metadata type to be 103// filtered. 104// @param[out] status On exit contains the status code to be returned. 105// @return true if the parcel starts with a valid filter. 106bool unmarshallFilter(const Parcel& p, 107 Metadata::Filter *filter, 108 status_t *status) 109{ 110 int32_t val; 111 if (p.readInt32(&val) != OK) 112 { 113 LOGE("Failed to read filter's length"); 114 *status = NOT_ENOUGH_DATA; 115 return false; 116 } 117 118 if( val > kMaxFilterSize || val < 0) 119 { 120 LOGE("Invalid filter len %d", val); 121 *status = BAD_VALUE; 122 return false; 123 } 124 125 const size_t num = val; 126 127 filter->clear(); 128 filter->setCapacity(num); 129 130 size_t size = num * sizeof(Metadata::Type); 131 132 133 if (p.dataAvail() < size) 134 { 135 LOGE("Filter too short expected %d but got %d", size, p.dataAvail()); 136 *status = NOT_ENOUGH_DATA; 137 return false; 138 } 139 140 const Metadata::Type *data = 141 static_cast<const Metadata::Type*>(p.readInplace(size)); 142 143 if (NULL == data) 144 { 145 LOGE("Filter had no data"); 146 *status = BAD_VALUE; 147 return false; 148 } 149 150 // TODO: The stl impl of vector would be more efficient here 151 // because it degenerates into a memcpy on pod types. Try to 152 // replace later or use stl::set. 153 for (size_t i = 0; i < num; ++i) 154 { 155 filter->add(*data); 156 ++data; 157 } 158 *status = OK; 159 return true; 160} 161 162// @param filter Of metadata type. 163// @param val To be searched. 164// @return true if a match was found. 165bool findMetadata(const Metadata::Filter& filter, const int32_t val) 166{ 167 // Deal with empty and ANY right away 168 if (filter.isEmpty()) return false; 169 if (filter[0] == Metadata::kAny) return true; 170 171 return filter.indexOf(val) >= 0; 172} 173 174} // anonymous namespace 175 176 177namespace android { 178 179// TODO: Temp hack until we can register players 180typedef struct { 181 const char *extension; 182 const player_type playertype; 183} extmap; 184extmap FILE_EXTS [] = { 185 {".mid", SONIVOX_PLAYER}, 186 {".midi", SONIVOX_PLAYER}, 187 {".smf", SONIVOX_PLAYER}, 188 {".xmf", SONIVOX_PLAYER}, 189 {".imy", SONIVOX_PLAYER}, 190 {".rtttl", SONIVOX_PLAYER}, 191 {".rtx", SONIVOX_PLAYER}, 192 {".ota", SONIVOX_PLAYER}, 193}; 194 195// TODO: Find real cause of Audio/Video delay in PV framework and remove this workaround 196/* static */ int MediaPlayerService::AudioOutput::mMinBufferCount = 4; 197/* static */ bool MediaPlayerService::AudioOutput::mIsOnEmulator = false; 198 199void MediaPlayerService::instantiate() { 200 defaultServiceManager()->addService( 201 String16("media.player"), new MediaPlayerService()); 202} 203 204MediaPlayerService::MediaPlayerService() 205{ 206 LOGV("MediaPlayerService created"); 207 mNextConnId = 1; 208 209 mBatteryAudio.refCount = 0; 210 for (int i = 0; i < NUM_AUDIO_DEVICES; i++) { 211 mBatteryAudio.deviceOn[i] = 0; 212 mBatteryAudio.lastTime[i] = 0; 213 mBatteryAudio.totalTime[i] = 0; 214 } 215 // speaker is on by default 216 mBatteryAudio.deviceOn[SPEAKER] = 1; 217} 218 219MediaPlayerService::~MediaPlayerService() 220{ 221 LOGV("MediaPlayerService destroyed"); 222} 223 224sp<IMediaRecorder> MediaPlayerService::createMediaRecorder(pid_t pid) 225{ 226 sp<MediaRecorderClient> recorder = new MediaRecorderClient(this, pid); 227 wp<MediaRecorderClient> w = recorder; 228 Mutex::Autolock lock(mLock); 229 mMediaRecorderClients.add(w); 230 LOGV("Create new media recorder client from pid %d", pid); 231 return recorder; 232} 233 234void MediaPlayerService::removeMediaRecorderClient(wp<MediaRecorderClient> client) 235{ 236 Mutex::Autolock lock(mLock); 237 mMediaRecorderClients.remove(client); 238 LOGV("Delete media recorder client"); 239} 240 241sp<IMediaMetadataRetriever> MediaPlayerService::createMetadataRetriever(pid_t pid) 242{ 243 sp<MetadataRetrieverClient> retriever = new MetadataRetrieverClient(pid); 244 LOGV("Create new media retriever from pid %d", pid); 245 return retriever; 246} 247 248sp<IMediaPlayer> MediaPlayerService::create( 249 pid_t pid, const sp<IMediaPlayerClient>& client, const char* url, 250 const KeyedVector<String8, String8> *headers, int audioSessionId) 251{ 252 int32_t connId = android_atomic_inc(&mNextConnId); 253 sp<Client> c = new Client(this, pid, connId, client, audioSessionId); 254 LOGV("Create new client(%d) from pid %d, url=%s, connId=%d, audioSessionId=%d", 255 connId, pid, url, connId, audioSessionId); 256 if (NO_ERROR != c->setDataSource(url, headers)) 257 { 258 c.clear(); 259 return c; 260 } 261 wp<Client> w = c; 262 Mutex::Autolock lock(mLock); 263 mClients.add(w); 264 return c; 265} 266 267sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClient>& client, 268 int fd, int64_t offset, int64_t length, int audioSessionId) 269{ 270 int32_t connId = android_atomic_inc(&mNextConnId); 271 sp<Client> c = new Client(this, pid, connId, client, audioSessionId); 272 LOGV("Create new client(%d) from pid %d, fd=%d, offset=%lld, length=%lld, audioSessionId=%d", 273 connId, pid, fd, offset, length, audioSessionId); 274 if (NO_ERROR != c->setDataSource(fd, offset, length)) { 275 c.clear(); 276 } else { 277 wp<Client> w = c; 278 Mutex::Autolock lock(mLock); 279 mClients.add(w); 280 } 281 ::close(fd); 282 return c; 283} 284 285sp<IMediaPlayer> MediaPlayerService::create( 286 pid_t pid, const sp<IMediaPlayerClient> &client, 287 const sp<IStreamSource> &source, int audioSessionId) { 288 int32_t connId = android_atomic_inc(&mNextConnId); 289 sp<Client> c = new Client(this, pid, connId, client, audioSessionId); 290 291 LOGV("Create new client(%d) from pid %d, audioSessionId=%d", 292 connId, pid, audioSessionId); 293 294 if (OK != c->setDataSource(source)) { 295 c.clear(); 296 } else { 297 wp<Client> w = c; 298 Mutex::Autolock lock(mLock); 299 mClients.add(w); 300 } 301 302 return c; 303} 304 305sp<IOMX> MediaPlayerService::getOMX() { 306 Mutex::Autolock autoLock(mLock); 307 308 if (mOMX.get() == NULL) { 309 mOMX = new OMX; 310 } 311 312 return mOMX; 313} 314 315status_t MediaPlayerService::AudioCache::dump(int fd, const Vector<String16>& args) const 316{ 317 const size_t SIZE = 256; 318 char buffer[SIZE]; 319 String8 result; 320 321 result.append(" AudioCache\n"); 322 if (mHeap != 0) { 323 snprintf(buffer, 255, " heap base(%p), size(%d), flags(%d), device(%s)\n", 324 mHeap->getBase(), mHeap->getSize(), mHeap->getFlags(), mHeap->getDevice()); 325 result.append(buffer); 326 } 327 snprintf(buffer, 255, " msec per frame(%f), channel count(%d), format(%d), frame count(%ld)\n", 328 mMsecsPerFrame, mChannelCount, mFormat, mFrameCount); 329 result.append(buffer); 330 snprintf(buffer, 255, " sample rate(%d), size(%d), error(%d), command complete(%s)\n", 331 mSampleRate, mSize, mError, mCommandComplete?"true":"false"); 332 result.append(buffer); 333 ::write(fd, result.string(), result.size()); 334 return NO_ERROR; 335} 336 337status_t MediaPlayerService::AudioOutput::dump(int fd, const Vector<String16>& args) const 338{ 339 const size_t SIZE = 256; 340 char buffer[SIZE]; 341 String8 result; 342 343 result.append(" AudioOutput\n"); 344 snprintf(buffer, 255, " stream type(%d), left - right volume(%f, %f)\n", 345 mStreamType, mLeftVolume, mRightVolume); 346 result.append(buffer); 347 snprintf(buffer, 255, " msec per frame(%f), latency (%d)\n", 348 mMsecsPerFrame, mLatency); 349 result.append(buffer); 350 snprintf(buffer, 255, " aux effect id(%d), send level (%f)\n", 351 mAuxEffectId, mSendLevel); 352 result.append(buffer); 353 354 ::write(fd, result.string(), result.size()); 355 if (mTrack != 0) { 356 mTrack->dump(fd, args); 357 } 358 return NO_ERROR; 359} 360 361status_t MediaPlayerService::Client::dump(int fd, const Vector<String16>& args) const 362{ 363 const size_t SIZE = 256; 364 char buffer[SIZE]; 365 String8 result; 366 result.append(" Client\n"); 367 snprintf(buffer, 255, " pid(%d), connId(%d), status(%d), looping(%s)\n", 368 mPid, mConnId, mStatus, mLoop?"true": "false"); 369 result.append(buffer); 370 write(fd, result.string(), result.size()); 371 if (mAudioOutput != 0) { 372 mAudioOutput->dump(fd, args); 373 } 374 write(fd, "\n", 1); 375 return NO_ERROR; 376} 377 378status_t MediaPlayerService::dump(int fd, const Vector<String16>& args) 379{ 380 const size_t SIZE = 256; 381 char buffer[SIZE]; 382 String8 result; 383 if (checkCallingPermission(String16("android.permission.DUMP")) == false) { 384 snprintf(buffer, SIZE, "Permission Denial: " 385 "can't dump MediaPlayerService from pid=%d, uid=%d\n", 386 IPCThreadState::self()->getCallingPid(), 387 IPCThreadState::self()->getCallingUid()); 388 result.append(buffer); 389 } else { 390 Mutex::Autolock lock(mLock); 391 for (int i = 0, n = mClients.size(); i < n; ++i) { 392 sp<Client> c = mClients[i].promote(); 393 if (c != 0) c->dump(fd, args); 394 } 395 if (mMediaRecorderClients.size() == 0) { 396 result.append(" No media recorder client\n\n"); 397 } else { 398 for (int i = 0, n = mMediaRecorderClients.size(); i < n; ++i) { 399 sp<MediaRecorderClient> c = mMediaRecorderClients[i].promote(); 400 snprintf(buffer, 255, " MediaRecorderClient pid(%d)\n", c->mPid); 401 result.append(buffer); 402 write(fd, result.string(), result.size()); 403 result = "\n"; 404 c->dump(fd, args); 405 } 406 } 407 408 result.append(" Files opened and/or mapped:\n"); 409 snprintf(buffer, SIZE, "/proc/%d/maps", gettid()); 410 FILE *f = fopen(buffer, "r"); 411 if (f) { 412 while (!feof(f)) { 413 fgets(buffer, SIZE, f); 414 if (strstr(buffer, " /mnt/sdcard/") || 415 strstr(buffer, " /system/sounds/") || 416 strstr(buffer, " /data/") || 417 strstr(buffer, " /system/media/")) { 418 result.append(" "); 419 result.append(buffer); 420 } 421 } 422 fclose(f); 423 } else { 424 result.append("couldn't open "); 425 result.append(buffer); 426 result.append("\n"); 427 } 428 429 snprintf(buffer, SIZE, "/proc/%d/fd", gettid()); 430 DIR *d = opendir(buffer); 431 if (d) { 432 struct dirent *ent; 433 while((ent = readdir(d)) != NULL) { 434 if (strcmp(ent->d_name,".") && strcmp(ent->d_name,"..")) { 435 snprintf(buffer, SIZE, "/proc/%d/fd/%s", gettid(), ent->d_name); 436 struct stat s; 437 if (lstat(buffer, &s) == 0) { 438 if ((s.st_mode & S_IFMT) == S_IFLNK) { 439 char linkto[256]; 440 int len = readlink(buffer, linkto, sizeof(linkto)); 441 if(len > 0) { 442 if(len > 255) { 443 linkto[252] = '.'; 444 linkto[253] = '.'; 445 linkto[254] = '.'; 446 linkto[255] = 0; 447 } else { 448 linkto[len] = 0; 449 } 450 if (strstr(linkto, "/mnt/sdcard/") == linkto || 451 strstr(linkto, "/system/sounds/") == linkto || 452 strstr(linkto, "/data/") == linkto || 453 strstr(linkto, "/system/media/") == linkto) { 454 result.append(" "); 455 result.append(buffer); 456 result.append(" -> "); 457 result.append(linkto); 458 result.append("\n"); 459 } 460 } 461 } else { 462 result.append(" unexpected type for "); 463 result.append(buffer); 464 result.append("\n"); 465 } 466 } 467 } 468 } 469 closedir(d); 470 } else { 471 result.append("couldn't open "); 472 result.append(buffer); 473 result.append("\n"); 474 } 475 476 bool dumpMem = false; 477 for (size_t i = 0; i < args.size(); i++) { 478 if (args[i] == String16("-m")) { 479 dumpMem = true; 480 } 481 } 482 if (dumpMem) { 483 dumpMemoryAddresses(fd); 484 } 485 } 486 write(fd, result.string(), result.size()); 487 return NO_ERROR; 488} 489 490void MediaPlayerService::removeClient(wp<Client> client) 491{ 492 Mutex::Autolock lock(mLock); 493 mClients.remove(client); 494} 495 496MediaPlayerService::Client::Client(const sp<MediaPlayerService>& service, pid_t pid, 497 int32_t connId, const sp<IMediaPlayerClient>& client, int audioSessionId) 498{ 499 LOGV("Client(%d) constructor", connId); 500 mPid = pid; 501 mConnId = connId; 502 mService = service; 503 mClient = client; 504 mLoop = false; 505 mStatus = NO_INIT; 506 mAudioSessionId = audioSessionId; 507 508#if CALLBACK_ANTAGONIZER 509 LOGD("create Antagonizer"); 510 mAntagonizer = new Antagonizer(notify, this); 511#endif 512} 513 514MediaPlayerService::Client::~Client() 515{ 516 LOGV("Client(%d) destructor pid = %d", mConnId, mPid); 517 mAudioOutput.clear(); 518 wp<Client> client(this); 519 disconnect(); 520 mService->removeClient(client); 521} 522 523void MediaPlayerService::Client::disconnect() 524{ 525 LOGV("disconnect(%d) from pid %d", mConnId, mPid); 526 // grab local reference and clear main reference to prevent future 527 // access to object 528 sp<MediaPlayerBase> p; 529 { 530 Mutex::Autolock l(mLock); 531 p = mPlayer; 532 } 533 mClient.clear(); 534 535 mPlayer.clear(); 536 537 // clear the notification to prevent callbacks to dead client 538 // and reset the player. We assume the player will serialize 539 // access to itself if necessary. 540 if (p != 0) { 541 p->setNotifyCallback(0, 0); 542#if CALLBACK_ANTAGONIZER 543 LOGD("kill Antagonizer"); 544 mAntagonizer->kill(); 545#endif 546 p->reset(); 547 } 548 549 IPCThreadState::self()->flushCommands(); 550} 551 552static player_type getDefaultPlayerType() { 553 return STAGEFRIGHT_PLAYER; 554} 555 556player_type getPlayerType(int fd, int64_t offset, int64_t length) 557{ 558 char buf[20]; 559 lseek(fd, offset, SEEK_SET); 560 read(fd, buf, sizeof(buf)); 561 lseek(fd, offset, SEEK_SET); 562 563 long ident = *((long*)buf); 564 565 // Ogg vorbis? 566 if (ident == 0x5367674f) // 'OggS' 567 return STAGEFRIGHT_PLAYER; 568 569 // Some kind of MIDI? 570 EAS_DATA_HANDLE easdata; 571 if (EAS_Init(&easdata) == EAS_SUCCESS) { 572 EAS_FILE locator; 573 locator.path = NULL; 574 locator.fd = fd; 575 locator.offset = offset; 576 locator.length = length; 577 EAS_HANDLE eashandle; 578 if (EAS_OpenFile(easdata, &locator, &eashandle) == EAS_SUCCESS) { 579 EAS_CloseFile(easdata, eashandle); 580 EAS_Shutdown(easdata); 581 return SONIVOX_PLAYER; 582 } 583 EAS_Shutdown(easdata); 584 } 585 586 return getDefaultPlayerType(); 587} 588 589player_type getPlayerType(const char* url) 590{ 591 if (TestPlayerStub::canBeUsed(url)) { 592 return TEST_PLAYER; 593 } 594 595 if (!strncasecmp("http://", url, 7) 596 || !strncasecmp("https://", url, 8)) { 597 size_t len = strlen(url); 598 if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) { 599 return NU_PLAYER; 600 } 601 602 if (strstr(url,"m3u8")) { 603 return NU_PLAYER; 604 } 605 } 606 607 // use MidiFile for MIDI extensions 608 int lenURL = strlen(url); 609 for (int i = 0; i < NELEM(FILE_EXTS); ++i) { 610 int len = strlen(FILE_EXTS[i].extension); 611 int start = lenURL - len; 612 if (start > 0) { 613 if (!strncasecmp(url + start, FILE_EXTS[i].extension, len)) { 614 return FILE_EXTS[i].playertype; 615 } 616 } 617 } 618 619 return getDefaultPlayerType(); 620} 621 622static sp<MediaPlayerBase> createPlayer(player_type playerType, void* cookie, 623 notify_callback_f notifyFunc) 624{ 625 sp<MediaPlayerBase> p; 626 switch (playerType) { 627 case SONIVOX_PLAYER: 628 LOGV(" create MidiFile"); 629 p = new MidiFile(); 630 break; 631 case STAGEFRIGHT_PLAYER: 632 LOGV(" create StagefrightPlayer"); 633 p = new StagefrightPlayer; 634 break; 635 case NU_PLAYER: 636 LOGV(" create NuPlayer"); 637 p = new NuPlayerDriver; 638 break; 639 case TEST_PLAYER: 640 LOGV("Create Test Player stub"); 641 p = new TestPlayerStub(); 642 break; 643 default: 644 LOGE("Unknown player type: %d", playerType); 645 return NULL; 646 } 647 if (p != NULL) { 648 if (p->initCheck() == NO_ERROR) { 649 p->setNotifyCallback(cookie, notifyFunc); 650 } else { 651 p.clear(); 652 } 653 } 654 if (p == NULL) { 655 LOGE("Failed to create player object"); 656 } 657 return p; 658} 659 660sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerType) 661{ 662 // determine if we have the right player type 663 sp<MediaPlayerBase> p = mPlayer; 664 if ((p != NULL) && (p->playerType() != playerType)) { 665 LOGV("delete player"); 666 p.clear(); 667 } 668 if (p == NULL) { 669 p = android::createPlayer(playerType, this, notify); 670 } 671 return p; 672} 673 674status_t MediaPlayerService::Client::setDataSource( 675 const char *url, const KeyedVector<String8, String8> *headers) 676{ 677 LOGV("setDataSource(%s)", url); 678 if (url == NULL) 679 return UNKNOWN_ERROR; 680 681 if (strncmp(url, "content://", 10) == 0) { 682 // get a filedescriptor for the content Uri and 683 // pass it to the setDataSource(fd) method 684 685 String16 url16(url); 686 int fd = android::openContentProviderFile(url16); 687 if (fd < 0) 688 { 689 LOGE("Couldn't open fd for %s", url); 690 return UNKNOWN_ERROR; 691 } 692 setDataSource(fd, 0, 0x7fffffffffLL); // this sets mStatus 693 close(fd); 694 return mStatus; 695 } else { 696 player_type playerType = getPlayerType(url); 697 LOGV("player type = %d", playerType); 698 699 // create the right type of player 700 sp<MediaPlayerBase> p = createPlayer(playerType); 701 if (p == NULL) return NO_INIT; 702 703 if (!p->hardwareOutput()) { 704 mAudioOutput = new AudioOutput(mAudioSessionId); 705 static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput); 706 } 707 708 // now set data source 709 LOGV(" setDataSource"); 710 mStatus = p->setDataSource(url, headers); 711 if (mStatus == NO_ERROR) { 712 mPlayer = p; 713 } else { 714 LOGE(" error: %d", mStatus); 715 } 716 return mStatus; 717 } 718} 719 720status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64_t length) 721{ 722 LOGV("setDataSource fd=%d, offset=%lld, length=%lld", fd, offset, length); 723 struct stat sb; 724 int ret = fstat(fd, &sb); 725 if (ret != 0) { 726 LOGE("fstat(%d) failed: %d, %s", fd, ret, strerror(errno)); 727 return UNKNOWN_ERROR; 728 } 729 730 LOGV("st_dev = %llu", sb.st_dev); 731 LOGV("st_mode = %u", sb.st_mode); 732 LOGV("st_uid = %lu", sb.st_uid); 733 LOGV("st_gid = %lu", sb.st_gid); 734 LOGV("st_size = %llu", sb.st_size); 735 736 if (offset >= sb.st_size) { 737 LOGE("offset error"); 738 ::close(fd); 739 return UNKNOWN_ERROR; 740 } 741 if (offset + length > sb.st_size) { 742 length = sb.st_size - offset; 743 LOGV("calculated length = %lld", length); 744 } 745 746 player_type playerType = getPlayerType(fd, offset, length); 747 LOGV("player type = %d", playerType); 748 749 // create the right type of player 750 sp<MediaPlayerBase> p = createPlayer(playerType); 751 if (p == NULL) return NO_INIT; 752 753 if (!p->hardwareOutput()) { 754 mAudioOutput = new AudioOutput(mAudioSessionId); 755 static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput); 756 } 757 758 // now set data source 759 mStatus = p->setDataSource(fd, offset, length); 760 if (mStatus == NO_ERROR) mPlayer = p; 761 return mStatus; 762} 763 764status_t MediaPlayerService::Client::setDataSource( 765 const sp<IStreamSource> &source) { 766 // create the right type of player 767 sp<MediaPlayerBase> p = createPlayer(NU_PLAYER); 768 769 if (p == NULL) { 770 return NO_INIT; 771 } 772 773 if (!p->hardwareOutput()) { 774 mAudioOutput = new AudioOutput(mAudioSessionId); 775 static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput); 776 } 777 778 // now set data source 779 mStatus = p->setDataSource(source); 780 781 if (mStatus == OK) { 782 mPlayer = p; 783 } 784 785 return mStatus; 786} 787 788status_t MediaPlayerService::Client::setVideoSurface(const sp<Surface>& surface) 789{ 790 LOGV("[%d] setVideoSurface(%p)", mConnId, surface.get()); 791 sp<MediaPlayerBase> p = getPlayer(); 792 if (p == 0) return UNKNOWN_ERROR; 793 return p->setVideoSurface(surface); 794} 795 796status_t MediaPlayerService::Client::setVideoSurfaceTexture( 797 const sp<ISurfaceTexture>& surfaceTexture) 798{ 799 LOGV("[%d] setVideoSurfaceTexture(%p)", mConnId, surfaceTexture.get()); 800 sp<MediaPlayerBase> p = getPlayer(); 801 if (p == 0) return UNKNOWN_ERROR; 802 return p->setVideoSurfaceTexture(surfaceTexture); 803} 804 805status_t MediaPlayerService::Client::invoke(const Parcel& request, 806 Parcel *reply) 807{ 808 sp<MediaPlayerBase> p = getPlayer(); 809 if (p == NULL) return UNKNOWN_ERROR; 810 return p->invoke(request, reply); 811} 812 813// This call doesn't need to access the native player. 814status_t MediaPlayerService::Client::setMetadataFilter(const Parcel& filter) 815{ 816 status_t status; 817 media::Metadata::Filter allow, drop; 818 819 if (unmarshallFilter(filter, &allow, &status) && 820 unmarshallFilter(filter, &drop, &status)) { 821 Mutex::Autolock lock(mLock); 822 823 mMetadataAllow = allow; 824 mMetadataDrop = drop; 825 } 826 return status; 827} 828 829status_t MediaPlayerService::Client::getMetadata( 830 bool update_only, bool apply_filter, Parcel *reply) 831{ 832 sp<MediaPlayerBase> player = getPlayer(); 833 if (player == 0) return UNKNOWN_ERROR; 834 835 status_t status; 836 // Placeholder for the return code, updated by the caller. 837 reply->writeInt32(-1); 838 839 media::Metadata::Filter ids; 840 841 // We don't block notifications while we fetch the data. We clear 842 // mMetadataUpdated first so we don't lose notifications happening 843 // during the rest of this call. 844 { 845 Mutex::Autolock lock(mLock); 846 if (update_only) { 847 ids = mMetadataUpdated; 848 } 849 mMetadataUpdated.clear(); 850 } 851 852 media::Metadata metadata(reply); 853 854 metadata.appendHeader(); 855 status = player->getMetadata(ids, reply); 856 857 if (status != OK) { 858 metadata.resetParcel(); 859 LOGE("getMetadata failed %d", status); 860 return status; 861 } 862 863 // FIXME: Implement filtering on the result. Not critical since 864 // filtering takes place on the update notifications already. This 865 // would be when all the metadata are fetch and a filter is set. 866 867 // Everything is fine, update the metadata length. 868 metadata.updateLength(); 869 return OK; 870} 871 872status_t MediaPlayerService::Client::prepareAsync() 873{ 874 LOGV("[%d] prepareAsync", mConnId); 875 sp<MediaPlayerBase> p = getPlayer(); 876 if (p == 0) return UNKNOWN_ERROR; 877 status_t ret = p->prepareAsync(); 878#if CALLBACK_ANTAGONIZER 879 LOGD("start Antagonizer"); 880 if (ret == NO_ERROR) mAntagonizer->start(); 881#endif 882 return ret; 883} 884 885status_t MediaPlayerService::Client::start() 886{ 887 LOGV("[%d] start", mConnId); 888 sp<MediaPlayerBase> p = getPlayer(); 889 if (p == 0) return UNKNOWN_ERROR; 890 p->setLooping(mLoop); 891 return p->start(); 892} 893 894status_t MediaPlayerService::Client::stop() 895{ 896 LOGV("[%d] stop", mConnId); 897 sp<MediaPlayerBase> p = getPlayer(); 898 if (p == 0) return UNKNOWN_ERROR; 899 return p->stop(); 900} 901 902status_t MediaPlayerService::Client::pause() 903{ 904 LOGV("[%d] pause", mConnId); 905 sp<MediaPlayerBase> p = getPlayer(); 906 if (p == 0) return UNKNOWN_ERROR; 907 return p->pause(); 908} 909 910status_t MediaPlayerService::Client::isPlaying(bool* state) 911{ 912 *state = false; 913 sp<MediaPlayerBase> p = getPlayer(); 914 if (p == 0) return UNKNOWN_ERROR; 915 *state = p->isPlaying(); 916 LOGV("[%d] isPlaying: %d", mConnId, *state); 917 return NO_ERROR; 918} 919 920status_t MediaPlayerService::Client::getCurrentPosition(int *msec) 921{ 922 LOGV("getCurrentPosition"); 923 sp<MediaPlayerBase> p = getPlayer(); 924 if (p == 0) return UNKNOWN_ERROR; 925 status_t ret = p->getCurrentPosition(msec); 926 if (ret == NO_ERROR) { 927 LOGV("[%d] getCurrentPosition = %d", mConnId, *msec); 928 } else { 929 LOGE("getCurrentPosition returned %d", ret); 930 } 931 return ret; 932} 933 934status_t MediaPlayerService::Client::getDuration(int *msec) 935{ 936 LOGV("getDuration"); 937 sp<MediaPlayerBase> p = getPlayer(); 938 if (p == 0) return UNKNOWN_ERROR; 939 status_t ret = p->getDuration(msec); 940 if (ret == NO_ERROR) { 941 LOGV("[%d] getDuration = %d", mConnId, *msec); 942 } else { 943 LOGE("getDuration returned %d", ret); 944 } 945 return ret; 946} 947 948status_t MediaPlayerService::Client::seekTo(int msec) 949{ 950 LOGV("[%d] seekTo(%d)", mConnId, msec); 951 sp<MediaPlayerBase> p = getPlayer(); 952 if (p == 0) return UNKNOWN_ERROR; 953 return p->seekTo(msec); 954} 955 956status_t MediaPlayerService::Client::reset() 957{ 958 LOGV("[%d] reset", mConnId); 959 sp<MediaPlayerBase> p = getPlayer(); 960 if (p == 0) return UNKNOWN_ERROR; 961 return p->reset(); 962} 963 964status_t MediaPlayerService::Client::setAudioStreamType(int type) 965{ 966 LOGV("[%d] setAudioStreamType(%d)", mConnId, type); 967 // TODO: for hardware output, call player instead 968 Mutex::Autolock l(mLock); 969 if (mAudioOutput != 0) mAudioOutput->setAudioStreamType(type); 970 return NO_ERROR; 971} 972 973status_t MediaPlayerService::Client::setLooping(int loop) 974{ 975 LOGV("[%d] setLooping(%d)", mConnId, loop); 976 mLoop = loop; 977 sp<MediaPlayerBase> p = getPlayer(); 978 if (p != 0) return p->setLooping(loop); 979 return NO_ERROR; 980} 981 982status_t MediaPlayerService::Client::setVolume(float leftVolume, float rightVolume) 983{ 984 LOGV("[%d] setVolume(%f, %f)", mConnId, leftVolume, rightVolume); 985 // TODO: for hardware output, call player instead 986 Mutex::Autolock l(mLock); 987 if (mAudioOutput != 0) mAudioOutput->setVolume(leftVolume, rightVolume); 988 return NO_ERROR; 989} 990 991status_t MediaPlayerService::Client::setAuxEffectSendLevel(float level) 992{ 993 LOGV("[%d] setAuxEffectSendLevel(%f)", mConnId, level); 994 Mutex::Autolock l(mLock); 995 if (mAudioOutput != 0) return mAudioOutput->setAuxEffectSendLevel(level); 996 return NO_ERROR; 997} 998 999status_t MediaPlayerService::Client::attachAuxEffect(int effectId) 1000{ 1001 LOGV("[%d] attachAuxEffect(%d)", mConnId, effectId); 1002 Mutex::Autolock l(mLock); 1003 if (mAudioOutput != 0) return mAudioOutput->attachAuxEffect(effectId); 1004 return NO_ERROR; 1005} 1006 1007status_t MediaPlayerService::Client::setParameter(int key, const Parcel &request) { 1008 LOGV("[%d] setParameter(%d)", mConnId, key); 1009 sp<MediaPlayerBase> p = getPlayer(); 1010 if (p == 0) return UNKNOWN_ERROR; 1011 return p->setParameter(key, request); 1012} 1013 1014status_t MediaPlayerService::Client::getParameter(int key, Parcel *reply) { 1015 LOGV("[%d] getParameter(%d)", mConnId, key); 1016 sp<MediaPlayerBase> p = getPlayer(); 1017 if (p == 0) return UNKNOWN_ERROR; 1018 return p->getParameter(key, reply); 1019} 1020 1021void MediaPlayerService::Client::notify( 1022 void* cookie, int msg, int ext1, int ext2, const Parcel *obj) 1023{ 1024 Client* client = static_cast<Client*>(cookie); 1025 1026 if (MEDIA_INFO == msg && 1027 MEDIA_INFO_METADATA_UPDATE == ext1) { 1028 const media::Metadata::Type metadata_type = ext2; 1029 1030 if(client->shouldDropMetadata(metadata_type)) { 1031 return; 1032 } 1033 1034 // Update the list of metadata that have changed. getMetadata 1035 // also access mMetadataUpdated and clears it. 1036 client->addNewMetadataUpdate(metadata_type); 1037 } 1038 LOGV("[%d] notify (%p, %d, %d, %d)", client->mConnId, cookie, msg, ext1, ext2); 1039 client->mClient->notify(msg, ext1, ext2, obj); 1040} 1041 1042 1043bool MediaPlayerService::Client::shouldDropMetadata(media::Metadata::Type code) const 1044{ 1045 Mutex::Autolock lock(mLock); 1046 1047 if (findMetadata(mMetadataDrop, code)) { 1048 return true; 1049 } 1050 1051 if (mMetadataAllow.isEmpty() || findMetadata(mMetadataAllow, code)) { 1052 return false; 1053 } else { 1054 return true; 1055 } 1056} 1057 1058 1059void MediaPlayerService::Client::addNewMetadataUpdate(media::Metadata::Type metadata_type) { 1060 Mutex::Autolock lock(mLock); 1061 if (mMetadataUpdated.indexOf(metadata_type) < 0) { 1062 mMetadataUpdated.add(metadata_type); 1063 } 1064} 1065 1066#if CALLBACK_ANTAGONIZER 1067const int Antagonizer::interval = 10000; // 10 msecs 1068 1069Antagonizer::Antagonizer(notify_callback_f cb, void* client) : 1070 mExit(false), mActive(false), mClient(client), mCb(cb) 1071{ 1072 createThread(callbackThread, this); 1073} 1074 1075void Antagonizer::kill() 1076{ 1077 Mutex::Autolock _l(mLock); 1078 mActive = false; 1079 mExit = true; 1080 mCondition.wait(mLock); 1081} 1082 1083int Antagonizer::callbackThread(void* user) 1084{ 1085 LOGD("Antagonizer started"); 1086 Antagonizer* p = reinterpret_cast<Antagonizer*>(user); 1087 while (!p->mExit) { 1088 if (p->mActive) { 1089 LOGV("send event"); 1090 p->mCb(p->mClient, 0, 0, 0); 1091 } 1092 usleep(interval); 1093 } 1094 Mutex::Autolock _l(p->mLock); 1095 p->mCondition.signal(); 1096 LOGD("Antagonizer stopped"); 1097 return 0; 1098} 1099#endif 1100 1101static size_t kDefaultHeapSize = 1024 * 1024; // 1MB 1102 1103sp<IMemory> MediaPlayerService::decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) 1104{ 1105 LOGV("decode(%s)", url); 1106 sp<MemoryBase> mem; 1107 sp<MediaPlayerBase> player; 1108 1109 // Protect our precious, precious DRMd ringtones by only allowing 1110 // decoding of http, but not filesystem paths or content Uris. 1111 // If the application wants to decode those, it should open a 1112 // filedescriptor for them and use that. 1113 if (url != NULL && strncmp(url, "http://", 7) != 0) { 1114 LOGD("Can't decode %s by path, use filedescriptor instead", url); 1115 return mem; 1116 } 1117 1118 player_type playerType = getPlayerType(url); 1119 LOGV("player type = %d", playerType); 1120 1121 // create the right type of player 1122 sp<AudioCache> cache = new AudioCache(url); 1123 player = android::createPlayer(playerType, cache.get(), cache->notify); 1124 if (player == NULL) goto Exit; 1125 if (player->hardwareOutput()) goto Exit; 1126 1127 static_cast<MediaPlayerInterface*>(player.get())->setAudioSink(cache); 1128 1129 // set data source 1130 if (player->setDataSource(url) != NO_ERROR) goto Exit; 1131 1132 LOGV("prepare"); 1133 player->prepareAsync(); 1134 1135 LOGV("wait for prepare"); 1136 if (cache->wait() != NO_ERROR) goto Exit; 1137 1138 LOGV("start"); 1139 player->start(); 1140 1141 LOGV("wait for playback complete"); 1142 if (cache->wait() != NO_ERROR) goto Exit; 1143 1144 mem = new MemoryBase(cache->getHeap(), 0, cache->size()); 1145 *pSampleRate = cache->sampleRate(); 1146 *pNumChannels = cache->channelCount(); 1147 *pFormat = (int)cache->format(); 1148 LOGV("return memory @ %p, sampleRate=%u, channelCount = %d, format = %d", mem->pointer(), *pSampleRate, *pNumChannels, *pFormat); 1149 1150Exit: 1151 if (player != 0) player->reset(); 1152 return mem; 1153} 1154 1155sp<IMemory> MediaPlayerService::decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) 1156{ 1157 LOGV("decode(%d, %lld, %lld)", fd, offset, length); 1158 sp<MemoryBase> mem; 1159 sp<MediaPlayerBase> player; 1160 1161 player_type playerType = getPlayerType(fd, offset, length); 1162 LOGV("player type = %d", playerType); 1163 1164 // create the right type of player 1165 sp<AudioCache> cache = new AudioCache("decode_fd"); 1166 player = android::createPlayer(playerType, cache.get(), cache->notify); 1167 if (player == NULL) goto Exit; 1168 if (player->hardwareOutput()) goto Exit; 1169 1170 static_cast<MediaPlayerInterface*>(player.get())->setAudioSink(cache); 1171 1172 // set data source 1173 if (player->setDataSource(fd, offset, length) != NO_ERROR) goto Exit; 1174 1175 LOGV("prepare"); 1176 player->prepareAsync(); 1177 1178 LOGV("wait for prepare"); 1179 if (cache->wait() != NO_ERROR) goto Exit; 1180 1181 LOGV("start"); 1182 player->start(); 1183 1184 LOGV("wait for playback complete"); 1185 if (cache->wait() != NO_ERROR) goto Exit; 1186 1187 mem = new MemoryBase(cache->getHeap(), 0, cache->size()); 1188 *pSampleRate = cache->sampleRate(); 1189 *pNumChannels = cache->channelCount(); 1190 *pFormat = cache->format(); 1191 LOGV("return memory @ %p, sampleRate=%u, channelCount = %d, format = %d", mem->pointer(), *pSampleRate, *pNumChannels, *pFormat); 1192 1193Exit: 1194 if (player != 0) player->reset(); 1195 ::close(fd); 1196 return mem; 1197} 1198 1199 1200#undef LOG_TAG 1201#define LOG_TAG "AudioSink" 1202MediaPlayerService::AudioOutput::AudioOutput(int sessionId) 1203 : mCallback(NULL), 1204 mCallbackCookie(NULL), 1205 mSessionId(sessionId) { 1206 LOGV("AudioOutput(%d)", sessionId); 1207 mTrack = 0; 1208 mStreamType = AUDIO_STREAM_MUSIC; 1209 mLeftVolume = 1.0; 1210 mRightVolume = 1.0; 1211 mLatency = 0; 1212 mMsecsPerFrame = 0; 1213 mAuxEffectId = 0; 1214 mSendLevel = 0.0; 1215 setMinBufferCount(); 1216} 1217 1218MediaPlayerService::AudioOutput::~AudioOutput() 1219{ 1220 close(); 1221} 1222 1223void MediaPlayerService::AudioOutput::setMinBufferCount() 1224{ 1225 char value[PROPERTY_VALUE_MAX]; 1226 if (property_get("ro.kernel.qemu", value, 0)) { 1227 mIsOnEmulator = true; 1228 mMinBufferCount = 12; // to prevent systematic buffer underrun for emulator 1229 } 1230} 1231 1232bool MediaPlayerService::AudioOutput::isOnEmulator() 1233{ 1234 setMinBufferCount(); 1235 return mIsOnEmulator; 1236} 1237 1238int MediaPlayerService::AudioOutput::getMinBufferCount() 1239{ 1240 setMinBufferCount(); 1241 return mMinBufferCount; 1242} 1243 1244ssize_t MediaPlayerService::AudioOutput::bufferSize() const 1245{ 1246 if (mTrack == 0) return NO_INIT; 1247 return mTrack->frameCount() * frameSize(); 1248} 1249 1250ssize_t MediaPlayerService::AudioOutput::frameCount() const 1251{ 1252 if (mTrack == 0) return NO_INIT; 1253 return mTrack->frameCount(); 1254} 1255 1256ssize_t MediaPlayerService::AudioOutput::channelCount() const 1257{ 1258 if (mTrack == 0) return NO_INIT; 1259 return mTrack->channelCount(); 1260} 1261 1262ssize_t MediaPlayerService::AudioOutput::frameSize() const 1263{ 1264 if (mTrack == 0) return NO_INIT; 1265 return mTrack->frameSize(); 1266} 1267 1268uint32_t MediaPlayerService::AudioOutput::latency () const 1269{ 1270 return mLatency; 1271} 1272 1273float MediaPlayerService::AudioOutput::msecsPerFrame() const 1274{ 1275 return mMsecsPerFrame; 1276} 1277 1278status_t MediaPlayerService::AudioOutput::getPosition(uint32_t *position) 1279{ 1280 if (mTrack == 0) return NO_INIT; 1281 return mTrack->getPosition(position); 1282} 1283 1284status_t MediaPlayerService::AudioOutput::open( 1285 uint32_t sampleRate, int channelCount, int format, int bufferCount, 1286 AudioCallback cb, void *cookie) 1287{ 1288 mCallback = cb; 1289 mCallbackCookie = cookie; 1290 1291 // Check argument "bufferCount" against the mininum buffer count 1292 if (bufferCount < mMinBufferCount) { 1293 LOGD("bufferCount (%d) is too small and increased to %d", bufferCount, mMinBufferCount); 1294 bufferCount = mMinBufferCount; 1295 1296 } 1297 LOGV("open(%u, %d, %d, %d, %d)", sampleRate, channelCount, format, bufferCount,mSessionId); 1298 if (mTrack) close(); 1299 int afSampleRate; 1300 int afFrameCount; 1301 int frameCount; 1302 1303 if (AudioSystem::getOutputFrameCount(&afFrameCount, mStreamType) != NO_ERROR) { 1304 return NO_INIT; 1305 } 1306 if (AudioSystem::getOutputSamplingRate(&afSampleRate, mStreamType) != NO_ERROR) { 1307 return NO_INIT; 1308 } 1309 1310 frameCount = (sampleRate*afFrameCount*bufferCount)/afSampleRate; 1311 1312 AudioTrack *t; 1313 if (mCallback != NULL) { 1314 t = new AudioTrack( 1315 mStreamType, 1316 sampleRate, 1317 format, 1318 (channelCount == 2) ? AUDIO_CHANNEL_OUT_STEREO : AUDIO_CHANNEL_OUT_MONO, 1319 frameCount, 1320 0 /* flags */, 1321 CallbackWrapper, 1322 this, 1323 0, 1324 mSessionId); 1325 } else { 1326 t = new AudioTrack( 1327 mStreamType, 1328 sampleRate, 1329 format, 1330 (channelCount == 2) ? AUDIO_CHANNEL_OUT_STEREO : AUDIO_CHANNEL_OUT_MONO, 1331 frameCount, 1332 0, 1333 NULL, 1334 NULL, 1335 0, 1336 mSessionId); 1337 } 1338 1339 if ((t == 0) || (t->initCheck() != NO_ERROR)) { 1340 LOGE("Unable to create audio track"); 1341 delete t; 1342 return NO_INIT; 1343 } 1344 1345 LOGV("setVolume"); 1346 t->setVolume(mLeftVolume, mRightVolume); 1347 1348 mMsecsPerFrame = 1.e3 / (float) sampleRate; 1349 mLatency = t->latency(); 1350 mTrack = t; 1351 1352 t->setAuxEffectSendLevel(mSendLevel); 1353 return t->attachAuxEffect(mAuxEffectId);; 1354} 1355 1356void MediaPlayerService::AudioOutput::start() 1357{ 1358 LOGV("start"); 1359 if (mTrack) { 1360 mTrack->setVolume(mLeftVolume, mRightVolume); 1361 mTrack->setAuxEffectSendLevel(mSendLevel); 1362 mTrack->start(); 1363 } 1364} 1365 1366 1367 1368ssize_t MediaPlayerService::AudioOutput::write(const void* buffer, size_t size) 1369{ 1370 LOG_FATAL_IF(mCallback != NULL, "Don't call write if supplying a callback."); 1371 1372 //LOGV("write(%p, %u)", buffer, size); 1373 if (mTrack) { 1374 ssize_t ret = mTrack->write(buffer, size); 1375 return ret; 1376 } 1377 return NO_INIT; 1378} 1379 1380void MediaPlayerService::AudioOutput::stop() 1381{ 1382 LOGV("stop"); 1383 if (mTrack) mTrack->stop(); 1384} 1385 1386void MediaPlayerService::AudioOutput::flush() 1387{ 1388 LOGV("flush"); 1389 if (mTrack) mTrack->flush(); 1390} 1391 1392void MediaPlayerService::AudioOutput::pause() 1393{ 1394 LOGV("pause"); 1395 if (mTrack) mTrack->pause(); 1396} 1397 1398void MediaPlayerService::AudioOutput::close() 1399{ 1400 LOGV("close"); 1401 delete mTrack; 1402 mTrack = 0; 1403} 1404 1405void MediaPlayerService::AudioOutput::setVolume(float left, float right) 1406{ 1407 LOGV("setVolume(%f, %f)", left, right); 1408 mLeftVolume = left; 1409 mRightVolume = right; 1410 if (mTrack) { 1411 mTrack->setVolume(left, right); 1412 } 1413} 1414 1415status_t MediaPlayerService::AudioOutput::setAuxEffectSendLevel(float level) 1416{ 1417 LOGV("setAuxEffectSendLevel(%f)", level); 1418 mSendLevel = level; 1419 if (mTrack) { 1420 return mTrack->setAuxEffectSendLevel(level); 1421 } 1422 return NO_ERROR; 1423} 1424 1425status_t MediaPlayerService::AudioOutput::attachAuxEffect(int effectId) 1426{ 1427 LOGV("attachAuxEffect(%d)", effectId); 1428 mAuxEffectId = effectId; 1429 if (mTrack) { 1430 return mTrack->attachAuxEffect(effectId); 1431 } 1432 return NO_ERROR; 1433} 1434 1435// static 1436void MediaPlayerService::AudioOutput::CallbackWrapper( 1437 int event, void *cookie, void *info) { 1438 //LOGV("callbackwrapper"); 1439 if (event != AudioTrack::EVENT_MORE_DATA) { 1440 return; 1441 } 1442 1443 AudioOutput *me = (AudioOutput *)cookie; 1444 AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info; 1445 1446 size_t actualSize = (*me->mCallback)( 1447 me, buffer->raw, buffer->size, me->mCallbackCookie); 1448 1449 if (actualSize == 0 && buffer->size > 0) { 1450 // We've reached EOS but the audio track is not stopped yet, 1451 // keep playing silence. 1452 1453 memset(buffer->raw, 0, buffer->size); 1454 actualSize = buffer->size; 1455 } 1456 1457 buffer->size = actualSize; 1458} 1459 1460int MediaPlayerService::AudioOutput::getSessionId() 1461{ 1462 return mSessionId; 1463} 1464 1465#undef LOG_TAG 1466#define LOG_TAG "AudioCache" 1467MediaPlayerService::AudioCache::AudioCache(const char* name) : 1468 mChannelCount(0), mFrameCount(1024), mSampleRate(0), mSize(0), 1469 mError(NO_ERROR), mCommandComplete(false) 1470{ 1471 // create ashmem heap 1472 mHeap = new MemoryHeapBase(kDefaultHeapSize, 0, name); 1473} 1474 1475uint32_t MediaPlayerService::AudioCache::latency () const 1476{ 1477 return 0; 1478} 1479 1480float MediaPlayerService::AudioCache::msecsPerFrame() const 1481{ 1482 return mMsecsPerFrame; 1483} 1484 1485status_t MediaPlayerService::AudioCache::getPosition(uint32_t *position) 1486{ 1487 if (position == 0) return BAD_VALUE; 1488 *position = mSize; 1489 return NO_ERROR; 1490} 1491 1492//////////////////////////////////////////////////////////////////////////////// 1493 1494struct CallbackThread : public Thread { 1495 CallbackThread(const wp<MediaPlayerBase::AudioSink> &sink, 1496 MediaPlayerBase::AudioSink::AudioCallback cb, 1497 void *cookie); 1498 1499protected: 1500 virtual ~CallbackThread(); 1501 1502 virtual bool threadLoop(); 1503 1504private: 1505 wp<MediaPlayerBase::AudioSink> mSink; 1506 MediaPlayerBase::AudioSink::AudioCallback mCallback; 1507 void *mCookie; 1508 void *mBuffer; 1509 size_t mBufferSize; 1510 1511 CallbackThread(const CallbackThread &); 1512 CallbackThread &operator=(const CallbackThread &); 1513}; 1514 1515CallbackThread::CallbackThread( 1516 const wp<MediaPlayerBase::AudioSink> &sink, 1517 MediaPlayerBase::AudioSink::AudioCallback cb, 1518 void *cookie) 1519 : mSink(sink), 1520 mCallback(cb), 1521 mCookie(cookie), 1522 mBuffer(NULL), 1523 mBufferSize(0) { 1524} 1525 1526CallbackThread::~CallbackThread() { 1527 if (mBuffer) { 1528 free(mBuffer); 1529 mBuffer = NULL; 1530 } 1531} 1532 1533bool CallbackThread::threadLoop() { 1534 sp<MediaPlayerBase::AudioSink> sink = mSink.promote(); 1535 if (sink == NULL) { 1536 return false; 1537 } 1538 1539 if (mBuffer == NULL) { 1540 mBufferSize = sink->bufferSize(); 1541 mBuffer = malloc(mBufferSize); 1542 } 1543 1544 size_t actualSize = 1545 (*mCallback)(sink.get(), mBuffer, mBufferSize, mCookie); 1546 1547 if (actualSize > 0) { 1548 sink->write(mBuffer, actualSize); 1549 } 1550 1551 return true; 1552} 1553 1554//////////////////////////////////////////////////////////////////////////////// 1555 1556status_t MediaPlayerService::AudioCache::open( 1557 uint32_t sampleRate, int channelCount, int format, int bufferCount, 1558 AudioCallback cb, void *cookie) 1559{ 1560 LOGV("open(%u, %d, %d, %d)", sampleRate, channelCount, format, bufferCount); 1561 if (mHeap->getHeapID() < 0) { 1562 return NO_INIT; 1563 } 1564 1565 mSampleRate = sampleRate; 1566 mChannelCount = (uint16_t)channelCount; 1567 mFormat = (uint16_t)format; 1568 mMsecsPerFrame = 1.e3 / (float) sampleRate; 1569 1570 if (cb != NULL) { 1571 mCallbackThread = new CallbackThread(this, cb, cookie); 1572 } 1573 return NO_ERROR; 1574} 1575 1576void MediaPlayerService::AudioCache::start() { 1577 if (mCallbackThread != NULL) { 1578 mCallbackThread->run("AudioCache callback"); 1579 } 1580} 1581 1582void MediaPlayerService::AudioCache::stop() { 1583 if (mCallbackThread != NULL) { 1584 mCallbackThread->requestExitAndWait(); 1585 } 1586} 1587 1588ssize_t MediaPlayerService::AudioCache::write(const void* buffer, size_t size) 1589{ 1590 LOGV("write(%p, %u)", buffer, size); 1591 if ((buffer == 0) || (size == 0)) return size; 1592 1593 uint8_t* p = static_cast<uint8_t*>(mHeap->getBase()); 1594 if (p == NULL) return NO_INIT; 1595 p += mSize; 1596 LOGV("memcpy(%p, %p, %u)", p, buffer, size); 1597 if (mSize + size > mHeap->getSize()) { 1598 LOGE("Heap size overflow! req size: %d, max size: %d", (mSize + size), mHeap->getSize()); 1599 size = mHeap->getSize() - mSize; 1600 } 1601 memcpy(p, buffer, size); 1602 mSize += size; 1603 return size; 1604} 1605 1606// call with lock held 1607status_t MediaPlayerService::AudioCache::wait() 1608{ 1609 Mutex::Autolock lock(mLock); 1610 while (!mCommandComplete) { 1611 mSignal.wait(mLock); 1612 } 1613 mCommandComplete = false; 1614 1615 if (mError == NO_ERROR) { 1616 LOGV("wait - success"); 1617 } else { 1618 LOGV("wait - error"); 1619 } 1620 return mError; 1621} 1622 1623void MediaPlayerService::AudioCache::notify( 1624 void* cookie, int msg, int ext1, int ext2, const Parcel *obj) 1625{ 1626 LOGV("notify(%p, %d, %d, %d)", cookie, msg, ext1, ext2); 1627 AudioCache* p = static_cast<AudioCache*>(cookie); 1628 1629 // ignore buffering messages 1630 switch (msg) 1631 { 1632 case MEDIA_ERROR: 1633 LOGE("Error %d, %d occurred", ext1, ext2); 1634 p->mError = ext1; 1635 break; 1636 case MEDIA_PREPARED: 1637 LOGV("prepared"); 1638 break; 1639 case MEDIA_PLAYBACK_COMPLETE: 1640 LOGV("playback complete"); 1641 break; 1642 default: 1643 LOGV("ignored"); 1644 return; 1645 } 1646 1647 // wake up thread 1648 Mutex::Autolock lock(p->mLock); 1649 p->mCommandComplete = true; 1650 p->mSignal.signal(); 1651} 1652 1653int MediaPlayerService::AudioCache::getSessionId() 1654{ 1655 return 0; 1656} 1657 1658void MediaPlayerService::addBatteryData(uint32_t params) 1659{ 1660 Mutex::Autolock lock(mLock); 1661 1662 int32_t time = systemTime() / 1000000L; 1663 1664 // change audio output devices. This notification comes from AudioFlinger 1665 if ((params & kBatteryDataSpeakerOn) 1666 || (params & kBatteryDataOtherAudioDeviceOn)) { 1667 1668 int deviceOn[NUM_AUDIO_DEVICES]; 1669 for (int i = 0; i < NUM_AUDIO_DEVICES; i++) { 1670 deviceOn[i] = 0; 1671 } 1672 1673 if ((params & kBatteryDataSpeakerOn) 1674 && (params & kBatteryDataOtherAudioDeviceOn)) { 1675 deviceOn[SPEAKER_AND_OTHER] = 1; 1676 } else if (params & kBatteryDataSpeakerOn) { 1677 deviceOn[SPEAKER] = 1; 1678 } else { 1679 deviceOn[OTHER_AUDIO_DEVICE] = 1; 1680 } 1681 1682 for (int i = 0; i < NUM_AUDIO_DEVICES; i++) { 1683 if (mBatteryAudio.deviceOn[i] != deviceOn[i]){ 1684 1685 if (mBatteryAudio.refCount > 0) { // if playing audio 1686 if (!deviceOn[i]) { 1687 mBatteryAudio.lastTime[i] += time; 1688 mBatteryAudio.totalTime[i] += mBatteryAudio.lastTime[i]; 1689 mBatteryAudio.lastTime[i] = 0; 1690 } else { 1691 mBatteryAudio.lastTime[i] = 0 - time; 1692 } 1693 } 1694 1695 mBatteryAudio.deviceOn[i] = deviceOn[i]; 1696 } 1697 } 1698 return; 1699 } 1700 1701 // an sudio stream is started 1702 if (params & kBatteryDataAudioFlingerStart) { 1703 // record the start time only if currently no other audio 1704 // is being played 1705 if (mBatteryAudio.refCount == 0) { 1706 for (int i = 0; i < NUM_AUDIO_DEVICES; i++) { 1707 if (mBatteryAudio.deviceOn[i]) { 1708 mBatteryAudio.lastTime[i] -= time; 1709 } 1710 } 1711 } 1712 1713 mBatteryAudio.refCount ++; 1714 return; 1715 1716 } else if (params & kBatteryDataAudioFlingerStop) { 1717 if (mBatteryAudio.refCount <= 0) { 1718 LOGW("Battery track warning: refCount is <= 0"); 1719 return; 1720 } 1721 1722 // record the stop time only if currently this is the only 1723 // audio being played 1724 if (mBatteryAudio.refCount == 1) { 1725 for (int i = 0; i < NUM_AUDIO_DEVICES; i++) { 1726 if (mBatteryAudio.deviceOn[i]) { 1727 mBatteryAudio.lastTime[i] += time; 1728 mBatteryAudio.totalTime[i] += mBatteryAudio.lastTime[i]; 1729 mBatteryAudio.lastTime[i] = 0; 1730 } 1731 } 1732 } 1733 1734 mBatteryAudio.refCount --; 1735 return; 1736 } 1737 1738 int uid = IPCThreadState::self()->getCallingUid(); 1739 if (uid == AID_MEDIA) { 1740 return; 1741 } 1742 int index = mBatteryData.indexOfKey(uid); 1743 1744 if (index < 0) { // create a new entry for this UID 1745 BatteryUsageInfo info; 1746 info.audioTotalTime = 0; 1747 info.videoTotalTime = 0; 1748 info.audioLastTime = 0; 1749 info.videoLastTime = 0; 1750 info.refCount = 0; 1751 1752 if (mBatteryData.add(uid, info) == NO_MEMORY) { 1753 LOGE("Battery track error: no memory for new app"); 1754 return; 1755 } 1756 } 1757 1758 BatteryUsageInfo &info = mBatteryData.editValueFor(uid); 1759 1760 if (params & kBatteryDataCodecStarted) { 1761 if (params & kBatteryDataTrackAudio) { 1762 info.audioLastTime -= time; 1763 info.refCount ++; 1764 } 1765 if (params & kBatteryDataTrackVideo) { 1766 info.videoLastTime -= time; 1767 info.refCount ++; 1768 } 1769 } else { 1770 if (info.refCount == 0) { 1771 LOGW("Battery track warning: refCount is already 0"); 1772 return; 1773 } else if (info.refCount < 0) { 1774 LOGE("Battery track error: refCount < 0"); 1775 mBatteryData.removeItem(uid); 1776 return; 1777 } 1778 1779 if (params & kBatteryDataTrackAudio) { 1780 info.audioLastTime += time; 1781 info.refCount --; 1782 } 1783 if (params & kBatteryDataTrackVideo) { 1784 info.videoLastTime += time; 1785 info.refCount --; 1786 } 1787 1788 // no stream is being played by this UID 1789 if (info.refCount == 0) { 1790 info.audioTotalTime += info.audioLastTime; 1791 info.audioLastTime = 0; 1792 info.videoTotalTime += info.videoLastTime; 1793 info.videoLastTime = 0; 1794 } 1795 } 1796} 1797 1798status_t MediaPlayerService::pullBatteryData(Parcel* reply) { 1799 Mutex::Autolock lock(mLock); 1800 1801 // audio output devices usage 1802 int32_t time = systemTime() / 1000000L; //in ms 1803 int32_t totalTime; 1804 1805 for (int i = 0; i < NUM_AUDIO_DEVICES; i++) { 1806 totalTime = mBatteryAudio.totalTime[i]; 1807 1808 if (mBatteryAudio.deviceOn[i] 1809 && (mBatteryAudio.lastTime[i] != 0)) { 1810 int32_t tmpTime = mBatteryAudio.lastTime[i] + time; 1811 totalTime += tmpTime; 1812 } 1813 1814 reply->writeInt32(totalTime); 1815 // reset the total time 1816 mBatteryAudio.totalTime[i] = 0; 1817 } 1818 1819 // codec usage 1820 BatteryUsageInfo info; 1821 int size = mBatteryData.size(); 1822 1823 reply->writeInt32(size); 1824 int i = 0; 1825 1826 while (i < size) { 1827 info = mBatteryData.valueAt(i); 1828 1829 reply->writeInt32(mBatteryData.keyAt(i)); //UID 1830 reply->writeInt32(info.audioTotalTime); 1831 reply->writeInt32(info.videoTotalTime); 1832 1833 info.audioTotalTime = 0; 1834 info.videoTotalTime = 0; 1835 1836 // remove the UID entry where no stream is being played 1837 if (info.refCount <= 0) { 1838 mBatteryData.removeItemsAt(i); 1839 size --; 1840 i --; 1841 } 1842 i++; 1843 } 1844 return NO_ERROR; 1845} 1846} // namespace android 1847