MediaPlayerService.cpp revision 3856b090cd04ba5dd4a59a12430ed724d5995909
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#include <media/stagefright/MediaErrors.h> 56 57#include <system/audio.h> 58 59#include <private/android_filesystem_config.h> 60 61#include "MediaRecorderClient.h" 62#include "MediaPlayerService.h" 63#include "MetadataRetrieverClient.h" 64 65#include "MidiFile.h" 66#include "TestPlayerStub.h" 67#include "StagefrightPlayer.h" 68#include "nuplayer/NuPlayerDriver.h" 69 70#include <OMX.h> 71 72namespace { 73using android::media::Metadata; 74using android::status_t; 75using android::OK; 76using android::BAD_VALUE; 77using android::NOT_ENOUGH_DATA; 78using android::Parcel; 79 80// Max number of entries in the filter. 81const int kMaxFilterSize = 64; // I pulled that out of thin air. 82 83// FIXME: Move all the metadata related function in the Metadata.cpp 84 85 86// Unmarshall a filter from a Parcel. 87// Filter format in a parcel: 88// 89// 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 90// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 91// | number of entries (n) | 92// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 93// | metadata type 1 | 94// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 95// | metadata type 2 | 96// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 97// .... 98// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 99// | metadata type n | 100// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 101// 102// @param p Parcel that should start with a filter. 103// @param[out] filter On exit contains the list of metadata type to be 104// filtered. 105// @param[out] status On exit contains the status code to be returned. 106// @return true if the parcel starts with a valid filter. 107bool unmarshallFilter(const Parcel& p, 108 Metadata::Filter *filter, 109 status_t *status) 110{ 111 int32_t val; 112 if (p.readInt32(&val) != OK) 113 { 114 LOGE("Failed to read filter's length"); 115 *status = NOT_ENOUGH_DATA; 116 return false; 117 } 118 119 if( val > kMaxFilterSize || val < 0) 120 { 121 LOGE("Invalid filter len %d", val); 122 *status = BAD_VALUE; 123 return false; 124 } 125 126 const size_t num = val; 127 128 filter->clear(); 129 filter->setCapacity(num); 130 131 size_t size = num * sizeof(Metadata::Type); 132 133 134 if (p.dataAvail() < size) 135 { 136 LOGE("Filter too short expected %d but got %d", size, p.dataAvail()); 137 *status = NOT_ENOUGH_DATA; 138 return false; 139 } 140 141 const Metadata::Type *data = 142 static_cast<const Metadata::Type*>(p.readInplace(size)); 143 144 if (NULL == data) 145 { 146 LOGE("Filter had no data"); 147 *status = BAD_VALUE; 148 return false; 149 } 150 151 // TODO: The stl impl of vector would be more efficient here 152 // because it degenerates into a memcpy on pod types. Try to 153 // replace later or use stl::set. 154 for (size_t i = 0; i < num; ++i) 155 { 156 filter->add(*data); 157 ++data; 158 } 159 *status = OK; 160 return true; 161} 162 163// @param filter Of metadata type. 164// @param val To be searched. 165// @return true if a match was found. 166bool findMetadata(const Metadata::Filter& filter, const int32_t val) 167{ 168 // Deal with empty and ANY right away 169 if (filter.isEmpty()) return false; 170 if (filter[0] == Metadata::kAny) return true; 171 172 return filter.indexOf(val) >= 0; 173} 174 175} // anonymous namespace 176 177 178namespace android { 179 180static bool checkPermission(const char* permissionString) { 181#ifndef HAVE_ANDROID_OS 182 return true; 183#endif 184 if (getpid() == IPCThreadState::self()->getCallingPid()) return true; 185 bool ok = checkCallingPermission(String16(permissionString)); 186 if (!ok) LOGE("Request requires %s", permissionString); 187 return ok; 188} 189 190// TODO: Temp hack until we can register players 191typedef struct { 192 const char *extension; 193 const player_type playertype; 194} extmap; 195extmap FILE_EXTS [] = { 196 {".mid", SONIVOX_PLAYER}, 197 {".midi", SONIVOX_PLAYER}, 198 {".smf", SONIVOX_PLAYER}, 199 {".xmf", SONIVOX_PLAYER}, 200 {".imy", SONIVOX_PLAYER}, 201 {".rtttl", SONIVOX_PLAYER}, 202 {".rtx", SONIVOX_PLAYER}, 203 {".ota", SONIVOX_PLAYER}, 204}; 205 206// TODO: Find real cause of Audio/Video delay in PV framework and remove this workaround 207/* static */ int MediaPlayerService::AudioOutput::mMinBufferCount = 4; 208/* static */ bool MediaPlayerService::AudioOutput::mIsOnEmulator = false; 209 210void MediaPlayerService::instantiate() { 211 defaultServiceManager()->addService( 212 String16("media.player"), new MediaPlayerService()); 213} 214 215MediaPlayerService::MediaPlayerService() 216{ 217 ALOGV("MediaPlayerService created"); 218 mNextConnId = 1; 219 220 mBatteryAudio.refCount = 0; 221 for (int i = 0; i < NUM_AUDIO_DEVICES; i++) { 222 mBatteryAudio.deviceOn[i] = 0; 223 mBatteryAudio.lastTime[i] = 0; 224 mBatteryAudio.totalTime[i] = 0; 225 } 226 // speaker is on by default 227 mBatteryAudio.deviceOn[SPEAKER] = 1; 228} 229 230MediaPlayerService::~MediaPlayerService() 231{ 232 ALOGV("MediaPlayerService destroyed"); 233} 234 235sp<IMediaRecorder> MediaPlayerService::createMediaRecorder(pid_t pid) 236{ 237 sp<MediaRecorderClient> recorder = new MediaRecorderClient(this, pid); 238 wp<MediaRecorderClient> w = recorder; 239 Mutex::Autolock lock(mLock); 240 mMediaRecorderClients.add(w); 241 ALOGV("Create new media recorder client from pid %d", pid); 242 return recorder; 243} 244 245void MediaPlayerService::removeMediaRecorderClient(wp<MediaRecorderClient> client) 246{ 247 Mutex::Autolock lock(mLock); 248 mMediaRecorderClients.remove(client); 249 ALOGV("Delete media recorder client"); 250} 251 252sp<IMediaMetadataRetriever> MediaPlayerService::createMetadataRetriever(pid_t pid) 253{ 254 sp<MetadataRetrieverClient> retriever = new MetadataRetrieverClient(pid); 255 ALOGV("Create new media retriever from pid %d", pid); 256 return retriever; 257} 258 259sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClient>& client, 260 int audioSessionId) 261{ 262 int32_t connId = android_atomic_inc(&mNextConnId); 263 264 sp<Client> c = new Client( 265 this, pid, connId, client, audioSessionId, 266 IPCThreadState::self()->getCallingUid()); 267 268 ALOGV("Create new client(%d) from pid %d, uid %d, ", connId, pid, 269 IPCThreadState::self()->getCallingUid()); 270 271 wp<Client> w = c; 272 { 273 Mutex::Autolock lock(mLock); 274 mClients.add(w); 275 } 276 return c; 277} 278 279sp<IOMX> MediaPlayerService::getOMX() { 280 Mutex::Autolock autoLock(mLock); 281 282 if (mOMX.get() == NULL) { 283 mOMX = new OMX; 284 } 285 286 return mOMX; 287} 288 289status_t MediaPlayerService::AudioCache::dump(int fd, const Vector<String16>& args) const 290{ 291 const size_t SIZE = 256; 292 char buffer[SIZE]; 293 String8 result; 294 295 result.append(" AudioCache\n"); 296 if (mHeap != 0) { 297 snprintf(buffer, 255, " heap base(%p), size(%d), flags(%d), device(%s)\n", 298 mHeap->getBase(), mHeap->getSize(), mHeap->getFlags(), mHeap->getDevice()); 299 result.append(buffer); 300 } 301 snprintf(buffer, 255, " msec per frame(%f), channel count(%d), format(%d), frame count(%ld)\n", 302 mMsecsPerFrame, mChannelCount, mFormat, mFrameCount); 303 result.append(buffer); 304 snprintf(buffer, 255, " sample rate(%d), size(%d), error(%d), command complete(%s)\n", 305 mSampleRate, mSize, mError, mCommandComplete?"true":"false"); 306 result.append(buffer); 307 ::write(fd, result.string(), result.size()); 308 return NO_ERROR; 309} 310 311status_t MediaPlayerService::AudioOutput::dump(int fd, const Vector<String16>& args) const 312{ 313 const size_t SIZE = 256; 314 char buffer[SIZE]; 315 String8 result; 316 317 result.append(" AudioOutput\n"); 318 snprintf(buffer, 255, " stream type(%d), left - right volume(%f, %f)\n", 319 mStreamType, mLeftVolume, mRightVolume); 320 result.append(buffer); 321 snprintf(buffer, 255, " msec per frame(%f), latency (%d)\n", 322 mMsecsPerFrame, mLatency); 323 result.append(buffer); 324 snprintf(buffer, 255, " aux effect id(%d), send level (%f)\n", 325 mAuxEffectId, mSendLevel); 326 result.append(buffer); 327 328 ::write(fd, result.string(), result.size()); 329 if (mTrack != 0) { 330 mTrack->dump(fd, args); 331 } 332 return NO_ERROR; 333} 334 335status_t MediaPlayerService::Client::dump(int fd, const Vector<String16>& args) const 336{ 337 const size_t SIZE = 256; 338 char buffer[SIZE]; 339 String8 result; 340 result.append(" Client\n"); 341 snprintf(buffer, 255, " pid(%d), connId(%d), status(%d), looping(%s)\n", 342 mPid, mConnId, mStatus, mLoop?"true": "false"); 343 result.append(buffer); 344 write(fd, result.string(), result.size()); 345 if (mPlayer != NULL) { 346 mPlayer->dump(fd, args); 347 } 348 if (mAudioOutput != 0) { 349 mAudioOutput->dump(fd, args); 350 } 351 write(fd, "\n", 1); 352 return NO_ERROR; 353} 354 355status_t MediaPlayerService::dump(int fd, const Vector<String16>& args) 356{ 357 const size_t SIZE = 256; 358 char buffer[SIZE]; 359 String8 result; 360 if (checkCallingPermission(String16("android.permission.DUMP")) == false) { 361 snprintf(buffer, SIZE, "Permission Denial: " 362 "can't dump MediaPlayerService from pid=%d, uid=%d\n", 363 IPCThreadState::self()->getCallingPid(), 364 IPCThreadState::self()->getCallingUid()); 365 result.append(buffer); 366 } else { 367 Mutex::Autolock lock(mLock); 368 for (int i = 0, n = mClients.size(); i < n; ++i) { 369 sp<Client> c = mClients[i].promote(); 370 if (c != 0) c->dump(fd, args); 371 } 372 if (mMediaRecorderClients.size() == 0) { 373 result.append(" No media recorder client\n\n"); 374 } else { 375 for (int i = 0, n = mMediaRecorderClients.size(); i < n; ++i) { 376 sp<MediaRecorderClient> c = mMediaRecorderClients[i].promote(); 377 if (c != 0) { 378 snprintf(buffer, 255, " MediaRecorderClient pid(%d)\n", c->mPid); 379 result.append(buffer); 380 write(fd, result.string(), result.size()); 381 result = "\n"; 382 c->dump(fd, args); 383 } 384 } 385 } 386 387 result.append(" Files opened and/or mapped:\n"); 388 snprintf(buffer, SIZE, "/proc/%d/maps", gettid()); 389 FILE *f = fopen(buffer, "r"); 390 if (f) { 391 while (!feof(f)) { 392 fgets(buffer, SIZE, f); 393 if (strstr(buffer, " /mnt/sdcard/") || 394 strstr(buffer, " /system/sounds/") || 395 strstr(buffer, " /data/") || 396 strstr(buffer, " /system/media/")) { 397 result.append(" "); 398 result.append(buffer); 399 } 400 } 401 fclose(f); 402 } else { 403 result.append("couldn't open "); 404 result.append(buffer); 405 result.append("\n"); 406 } 407 408 snprintf(buffer, SIZE, "/proc/%d/fd", gettid()); 409 DIR *d = opendir(buffer); 410 if (d) { 411 struct dirent *ent; 412 while((ent = readdir(d)) != NULL) { 413 if (strcmp(ent->d_name,".") && strcmp(ent->d_name,"..")) { 414 snprintf(buffer, SIZE, "/proc/%d/fd/%s", gettid(), ent->d_name); 415 struct stat s; 416 if (lstat(buffer, &s) == 0) { 417 if ((s.st_mode & S_IFMT) == S_IFLNK) { 418 char linkto[256]; 419 int len = readlink(buffer, linkto, sizeof(linkto)); 420 if(len > 0) { 421 if(len > 255) { 422 linkto[252] = '.'; 423 linkto[253] = '.'; 424 linkto[254] = '.'; 425 linkto[255] = 0; 426 } else { 427 linkto[len] = 0; 428 } 429 if (strstr(linkto, "/mnt/sdcard/") == linkto || 430 strstr(linkto, "/system/sounds/") == linkto || 431 strstr(linkto, "/data/") == linkto || 432 strstr(linkto, "/system/media/") == linkto) { 433 result.append(" "); 434 result.append(buffer); 435 result.append(" -> "); 436 result.append(linkto); 437 result.append("\n"); 438 } 439 } 440 } else { 441 result.append(" unexpected type for "); 442 result.append(buffer); 443 result.append("\n"); 444 } 445 } 446 } 447 } 448 closedir(d); 449 } else { 450 result.append("couldn't open "); 451 result.append(buffer); 452 result.append("\n"); 453 } 454 455 bool dumpMem = false; 456 for (size_t i = 0; i < args.size(); i++) { 457 if (args[i] == String16("-m")) { 458 dumpMem = true; 459 } 460 } 461 if (dumpMem) { 462 dumpMemoryAddresses(fd); 463 } 464 } 465 write(fd, result.string(), result.size()); 466 return NO_ERROR; 467} 468 469void MediaPlayerService::removeClient(wp<Client> client) 470{ 471 Mutex::Autolock lock(mLock); 472 mClients.remove(client); 473} 474 475MediaPlayerService::Client::Client( 476 const sp<MediaPlayerService>& service, pid_t pid, 477 int32_t connId, const sp<IMediaPlayerClient>& client, 478 int audioSessionId, uid_t uid) 479{ 480 ALOGV("Client(%d) constructor", connId); 481 mPid = pid; 482 mConnId = connId; 483 mService = service; 484 mClient = client; 485 mLoop = false; 486 mStatus = NO_INIT; 487 mAudioSessionId = audioSessionId; 488 mUID = uid; 489 490#if CALLBACK_ANTAGONIZER 491 LOGD("create Antagonizer"); 492 mAntagonizer = new Antagonizer(notify, this); 493#endif 494} 495 496MediaPlayerService::Client::~Client() 497{ 498 ALOGV("Client(%d) destructor pid = %d", mConnId, mPid); 499 mAudioOutput.clear(); 500 wp<Client> client(this); 501 disconnect(); 502 mService->removeClient(client); 503} 504 505void MediaPlayerService::Client::disconnect() 506{ 507 ALOGV("disconnect(%d) from pid %d", mConnId, mPid); 508 // grab local reference and clear main reference to prevent future 509 // access to object 510 sp<MediaPlayerBase> p; 511 { 512 Mutex::Autolock l(mLock); 513 p = mPlayer; 514 } 515 mClient.clear(); 516 517 mPlayer.clear(); 518 519 // clear the notification to prevent callbacks to dead client 520 // and reset the player. We assume the player will serialize 521 // access to itself if necessary. 522 if (p != 0) { 523 p->setNotifyCallback(0, 0); 524#if CALLBACK_ANTAGONIZER 525 LOGD("kill Antagonizer"); 526 mAntagonizer->kill(); 527#endif 528 p->reset(); 529 } 530 531 IPCThreadState::self()->flushCommands(); 532} 533 534static player_type getDefaultPlayerType() { 535 return STAGEFRIGHT_PLAYER; 536} 537 538player_type getPlayerType(int fd, int64_t offset, int64_t length) 539{ 540 char buf[20]; 541 lseek(fd, offset, SEEK_SET); 542 read(fd, buf, sizeof(buf)); 543 lseek(fd, offset, SEEK_SET); 544 545 long ident = *((long*)buf); 546 547 // Ogg vorbis? 548 if (ident == 0x5367674f) // 'OggS' 549 return STAGEFRIGHT_PLAYER; 550 551 // Some kind of MIDI? 552 EAS_DATA_HANDLE easdata; 553 if (EAS_Init(&easdata) == EAS_SUCCESS) { 554 EAS_FILE locator; 555 locator.path = NULL; 556 locator.fd = fd; 557 locator.offset = offset; 558 locator.length = length; 559 EAS_HANDLE eashandle; 560 if (EAS_OpenFile(easdata, &locator, &eashandle) == EAS_SUCCESS) { 561 EAS_CloseFile(easdata, eashandle); 562 EAS_Shutdown(easdata); 563 return SONIVOX_PLAYER; 564 } 565 EAS_Shutdown(easdata); 566 } 567 568 return getDefaultPlayerType(); 569} 570 571player_type getPlayerType(const char* url) 572{ 573 if (TestPlayerStub::canBeUsed(url)) { 574 return TEST_PLAYER; 575 } 576 577 if (!strncasecmp("http://", url, 7) 578 || !strncasecmp("https://", url, 8)) { 579 size_t len = strlen(url); 580 if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) { 581 return NU_PLAYER; 582 } 583 584 if (strstr(url,"m3u8")) { 585 return NU_PLAYER; 586 } 587 } 588 589 if (!strncasecmp("rtsp://", url, 7)) { 590 return NU_PLAYER; 591 } 592 593 // use MidiFile for MIDI extensions 594 int lenURL = strlen(url); 595 for (int i = 0; i < NELEM(FILE_EXTS); ++i) { 596 int len = strlen(FILE_EXTS[i].extension); 597 int start = lenURL - len; 598 if (start > 0) { 599 if (!strncasecmp(url + start, FILE_EXTS[i].extension, len)) { 600 return FILE_EXTS[i].playertype; 601 } 602 } 603 } 604 605 return getDefaultPlayerType(); 606} 607 608static sp<MediaPlayerBase> createPlayer(player_type playerType, void* cookie, 609 notify_callback_f notifyFunc) 610{ 611 sp<MediaPlayerBase> p; 612 switch (playerType) { 613 case SONIVOX_PLAYER: 614 ALOGV(" create MidiFile"); 615 p = new MidiFile(); 616 break; 617 case STAGEFRIGHT_PLAYER: 618 ALOGV(" create StagefrightPlayer"); 619 p = new StagefrightPlayer; 620 break; 621 case NU_PLAYER: 622 ALOGV(" create NuPlayer"); 623 p = new NuPlayerDriver; 624 break; 625 case TEST_PLAYER: 626 ALOGV("Create Test Player stub"); 627 p = new TestPlayerStub(); 628 break; 629 default: 630 LOGE("Unknown player type: %d", playerType); 631 return NULL; 632 } 633 if (p != NULL) { 634 if (p->initCheck() == NO_ERROR) { 635 p->setNotifyCallback(cookie, notifyFunc); 636 } else { 637 p.clear(); 638 } 639 } 640 if (p == NULL) { 641 LOGE("Failed to create player object"); 642 } 643 return p; 644} 645 646sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerType) 647{ 648 // determine if we have the right player type 649 sp<MediaPlayerBase> p = mPlayer; 650 if ((p != NULL) && (p->playerType() != playerType)) { 651 ALOGV("delete player"); 652 p.clear(); 653 } 654 if (p == NULL) { 655 p = android::createPlayer(playerType, this, notify); 656 } 657 658 if (p != NULL) { 659 p->setUID(mUID); 660 } 661 662 return p; 663} 664 665status_t MediaPlayerService::Client::setDataSource( 666 const char *url, const KeyedVector<String8, String8> *headers) 667{ 668 ALOGV("setDataSource(%s)", url); 669 if (url == NULL) 670 return UNKNOWN_ERROR; 671 672 if ((strncmp(url, "http://", 7) == 0) || 673 (strncmp(url, "https://", 8) == 0) || 674 (strncmp(url, "rtsp://", 7) == 0)) { 675 if (!checkPermission("android.permission.INTERNET")) { 676 return PERMISSION_DENIED; 677 } 678 } 679 680 if (strncmp(url, "content://", 10) == 0) { 681 // get a filedescriptor for the content Uri and 682 // pass it to the setDataSource(fd) method 683 684 String16 url16(url); 685 int fd = android::openContentProviderFile(url16); 686 if (fd < 0) 687 { 688 LOGE("Couldn't open fd for %s", url); 689 return UNKNOWN_ERROR; 690 } 691 setDataSource(fd, 0, 0x7fffffffffLL); // this sets mStatus 692 close(fd); 693 return mStatus; 694 } else { 695 player_type playerType = getPlayerType(url); 696 ALOGV("player type = %d", playerType); 697 698 // create the right type of player 699 sp<MediaPlayerBase> p = createPlayer(playerType); 700 if (p == NULL) return NO_INIT; 701 702 if (!p->hardwareOutput()) { 703 mAudioOutput = new AudioOutput(mAudioSessionId); 704 static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput); 705 } 706 707 // now set data source 708 ALOGV(" setDataSource"); 709 mStatus = p->setDataSource(url, headers); 710 if (mStatus == NO_ERROR) { 711 mPlayer = p; 712 } else { 713 LOGE(" error: %d", mStatus); 714 } 715 return mStatus; 716 } 717} 718 719status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64_t length) 720{ 721 ALOGV("setDataSource fd=%d, offset=%lld, length=%lld", fd, offset, length); 722 struct stat sb; 723 int ret = fstat(fd, &sb); 724 if (ret != 0) { 725 LOGE("fstat(%d) failed: %d, %s", fd, ret, strerror(errno)); 726 return UNKNOWN_ERROR; 727 } 728 729 ALOGV("st_dev = %llu", sb.st_dev); 730 ALOGV("st_mode = %u", sb.st_mode); 731 ALOGV("st_uid = %lu", sb.st_uid); 732 ALOGV("st_gid = %lu", sb.st_gid); 733 ALOGV("st_size = %llu", sb.st_size); 734 735 if (offset >= sb.st_size) { 736 LOGE("offset error"); 737 ::close(fd); 738 return UNKNOWN_ERROR; 739 } 740 if (offset + length > sb.st_size) { 741 length = sb.st_size - offset; 742 ALOGV("calculated length = %lld", length); 743 } 744 745 player_type playerType = getPlayerType(fd, offset, length); 746 ALOGV("player type = %d", playerType); 747 748 // create the right type of player 749 sp<MediaPlayerBase> p = createPlayer(playerType); 750 if (p == NULL) return NO_INIT; 751 752 if (!p->hardwareOutput()) { 753 mAudioOutput = new AudioOutput(mAudioSessionId); 754 static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput); 755 } 756 757 // now set data source 758 mStatus = p->setDataSource(fd, offset, length); 759 if (mStatus == NO_ERROR) mPlayer = p; 760 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 ALOGV("[%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 ALOGV("[%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 ALOGV("[%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 ALOGV("[%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 ALOGV("[%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 ALOGV("[%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 ALOGV("[%d] isPlaying: %d", mConnId, *state); 917 return NO_ERROR; 918} 919 920status_t MediaPlayerService::Client::getCurrentPosition(int *msec) 921{ 922 ALOGV("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 ALOGV("[%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 ALOGV("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 ALOGV("[%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 ALOGV("[%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 ALOGV("[%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 ALOGV("[%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 ALOGV("[%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 ALOGV("[%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 ALOGV("[%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 ALOGV("[%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 ALOGV("[%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 ALOGV("[%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 ALOGV("[%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 ALOGV("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 ALOGV("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 ALOGV("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 ALOGV("prepare"); 1133 player->prepareAsync(); 1134 1135 ALOGV("wait for prepare"); 1136 if (cache->wait() != NO_ERROR) goto Exit; 1137 1138 ALOGV("start"); 1139 player->start(); 1140 1141 ALOGV("wait for playback complete"); 1142 cache->wait(); 1143 // in case of error, return what was successfully decoded. 1144 if (cache->size() == 0) { 1145 goto Exit; 1146 } 1147 1148 mem = new MemoryBase(cache->getHeap(), 0, cache->size()); 1149 *pSampleRate = cache->sampleRate(); 1150 *pNumChannels = cache->channelCount(); 1151 *pFormat = (int)cache->format(); 1152 ALOGV("return memory @ %p, sampleRate=%u, channelCount = %d, format = %d", mem->pointer(), *pSampleRate, *pNumChannels, *pFormat); 1153 1154Exit: 1155 if (player != 0) player->reset(); 1156 return mem; 1157} 1158 1159sp<IMemory> MediaPlayerService::decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) 1160{ 1161 ALOGV("decode(%d, %lld, %lld)", fd, offset, length); 1162 sp<MemoryBase> mem; 1163 sp<MediaPlayerBase> player; 1164 1165 player_type playerType = getPlayerType(fd, offset, length); 1166 ALOGV("player type = %d", playerType); 1167 1168 // create the right type of player 1169 sp<AudioCache> cache = new AudioCache("decode_fd"); 1170 player = android::createPlayer(playerType, cache.get(), cache->notify); 1171 if (player == NULL) goto Exit; 1172 if (player->hardwareOutput()) goto Exit; 1173 1174 static_cast<MediaPlayerInterface*>(player.get())->setAudioSink(cache); 1175 1176 // set data source 1177 if (player->setDataSource(fd, offset, length) != NO_ERROR) goto Exit; 1178 1179 ALOGV("prepare"); 1180 player->prepareAsync(); 1181 1182 ALOGV("wait for prepare"); 1183 if (cache->wait() != NO_ERROR) goto Exit; 1184 1185 ALOGV("start"); 1186 player->start(); 1187 1188 ALOGV("wait for playback complete"); 1189 cache->wait(); 1190 // in case of error, return what was successfully decoded. 1191 if (cache->size() == 0) { 1192 goto Exit; 1193 } 1194 1195 mem = new MemoryBase(cache->getHeap(), 0, cache->size()); 1196 *pSampleRate = cache->sampleRate(); 1197 *pNumChannels = cache->channelCount(); 1198 *pFormat = cache->format(); 1199 ALOGV("return memory @ %p, sampleRate=%u, channelCount = %d, format = %d", mem->pointer(), *pSampleRate, *pNumChannels, *pFormat); 1200 1201Exit: 1202 if (player != 0) player->reset(); 1203 ::close(fd); 1204 return mem; 1205} 1206 1207 1208#undef LOG_TAG 1209#define LOG_TAG "AudioSink" 1210MediaPlayerService::AudioOutput::AudioOutput(int sessionId) 1211 : mCallback(NULL), 1212 mCallbackCookie(NULL), 1213 mSessionId(sessionId) { 1214 ALOGV("AudioOutput(%d)", sessionId); 1215 mTrack = 0; 1216 mStreamType = AUDIO_STREAM_MUSIC; 1217 mLeftVolume = 1.0; 1218 mRightVolume = 1.0; 1219 mLatency = 0; 1220 mMsecsPerFrame = 0; 1221 mAuxEffectId = 0; 1222 mSendLevel = 0.0; 1223 setMinBufferCount(); 1224} 1225 1226MediaPlayerService::AudioOutput::~AudioOutput() 1227{ 1228 close(); 1229} 1230 1231void MediaPlayerService::AudioOutput::setMinBufferCount() 1232{ 1233 char value[PROPERTY_VALUE_MAX]; 1234 if (property_get("ro.kernel.qemu", value, 0)) { 1235 mIsOnEmulator = true; 1236 mMinBufferCount = 12; // to prevent systematic buffer underrun for emulator 1237 } 1238} 1239 1240bool MediaPlayerService::AudioOutput::isOnEmulator() 1241{ 1242 setMinBufferCount(); 1243 return mIsOnEmulator; 1244} 1245 1246int MediaPlayerService::AudioOutput::getMinBufferCount() 1247{ 1248 setMinBufferCount(); 1249 return mMinBufferCount; 1250} 1251 1252ssize_t MediaPlayerService::AudioOutput::bufferSize() const 1253{ 1254 if (mTrack == 0) return NO_INIT; 1255 return mTrack->frameCount() * frameSize(); 1256} 1257 1258ssize_t MediaPlayerService::AudioOutput::frameCount() const 1259{ 1260 if (mTrack == 0) return NO_INIT; 1261 return mTrack->frameCount(); 1262} 1263 1264ssize_t MediaPlayerService::AudioOutput::channelCount() const 1265{ 1266 if (mTrack == 0) return NO_INIT; 1267 return mTrack->channelCount(); 1268} 1269 1270ssize_t MediaPlayerService::AudioOutput::frameSize() const 1271{ 1272 if (mTrack == 0) return NO_INIT; 1273 return mTrack->frameSize(); 1274} 1275 1276uint32_t MediaPlayerService::AudioOutput::latency () const 1277{ 1278 return mLatency; 1279} 1280 1281float MediaPlayerService::AudioOutput::msecsPerFrame() const 1282{ 1283 return mMsecsPerFrame; 1284} 1285 1286status_t MediaPlayerService::AudioOutput::getPosition(uint32_t *position) 1287{ 1288 if (mTrack == 0) return NO_INIT; 1289 return mTrack->getPosition(position); 1290} 1291 1292status_t MediaPlayerService::AudioOutput::open( 1293 uint32_t sampleRate, int channelCount, int format, int bufferCount, 1294 AudioCallback cb, void *cookie) 1295{ 1296 mCallback = cb; 1297 mCallbackCookie = cookie; 1298 1299 // Check argument "bufferCount" against the mininum buffer count 1300 if (bufferCount < mMinBufferCount) { 1301 LOGD("bufferCount (%d) is too small and increased to %d", bufferCount, mMinBufferCount); 1302 bufferCount = mMinBufferCount; 1303 1304 } 1305 ALOGV("open(%u, %d, %d, %d, %d)", sampleRate, channelCount, format, bufferCount,mSessionId); 1306 if (mTrack) close(); 1307 int afSampleRate; 1308 int afFrameCount; 1309 int frameCount; 1310 1311 if (AudioSystem::getOutputFrameCount(&afFrameCount, mStreamType) != NO_ERROR) { 1312 return NO_INIT; 1313 } 1314 if (AudioSystem::getOutputSamplingRate(&afSampleRate, mStreamType) != NO_ERROR) { 1315 return NO_INIT; 1316 } 1317 1318 frameCount = (sampleRate*afFrameCount*bufferCount)/afSampleRate; 1319 1320 AudioTrack *t; 1321 if (mCallback != NULL) { 1322 t = new AudioTrack( 1323 mStreamType, 1324 sampleRate, 1325 format, 1326 (channelCount == 2) ? AUDIO_CHANNEL_OUT_STEREO : AUDIO_CHANNEL_OUT_MONO, 1327 frameCount, 1328 0 /* flags */, 1329 CallbackWrapper, 1330 this, 1331 0, 1332 mSessionId); 1333 } else { 1334 t = new AudioTrack( 1335 mStreamType, 1336 sampleRate, 1337 format, 1338 (channelCount == 2) ? AUDIO_CHANNEL_OUT_STEREO : AUDIO_CHANNEL_OUT_MONO, 1339 frameCount, 1340 0, 1341 NULL, 1342 NULL, 1343 0, 1344 mSessionId); 1345 } 1346 1347 if ((t == 0) || (t->initCheck() != NO_ERROR)) { 1348 LOGE("Unable to create audio track"); 1349 delete t; 1350 return NO_INIT; 1351 } 1352 1353 ALOGV("setVolume"); 1354 t->setVolume(mLeftVolume, mRightVolume); 1355 1356 mMsecsPerFrame = 1.e3 / (float) sampleRate; 1357 mLatency = t->latency(); 1358 mTrack = t; 1359 1360 t->setAuxEffectSendLevel(mSendLevel); 1361 return t->attachAuxEffect(mAuxEffectId);; 1362} 1363 1364void MediaPlayerService::AudioOutput::start() 1365{ 1366 ALOGV("start"); 1367 if (mTrack) { 1368 mTrack->setVolume(mLeftVolume, mRightVolume); 1369 mTrack->setAuxEffectSendLevel(mSendLevel); 1370 mTrack->start(); 1371 } 1372} 1373 1374 1375 1376ssize_t MediaPlayerService::AudioOutput::write(const void* buffer, size_t size) 1377{ 1378 LOG_FATAL_IF(mCallback != NULL, "Don't call write if supplying a callback."); 1379 1380 //ALOGV("write(%p, %u)", buffer, size); 1381 if (mTrack) { 1382 ssize_t ret = mTrack->write(buffer, size); 1383 return ret; 1384 } 1385 return NO_INIT; 1386} 1387 1388void MediaPlayerService::AudioOutput::stop() 1389{ 1390 ALOGV("stop"); 1391 if (mTrack) mTrack->stop(); 1392} 1393 1394void MediaPlayerService::AudioOutput::flush() 1395{ 1396 ALOGV("flush"); 1397 if (mTrack) mTrack->flush(); 1398} 1399 1400void MediaPlayerService::AudioOutput::pause() 1401{ 1402 ALOGV("pause"); 1403 if (mTrack) mTrack->pause(); 1404} 1405 1406void MediaPlayerService::AudioOutput::close() 1407{ 1408 ALOGV("close"); 1409 delete mTrack; 1410 mTrack = 0; 1411} 1412 1413void MediaPlayerService::AudioOutput::setVolume(float left, float right) 1414{ 1415 ALOGV("setVolume(%f, %f)", left, right); 1416 mLeftVolume = left; 1417 mRightVolume = right; 1418 if (mTrack) { 1419 mTrack->setVolume(left, right); 1420 } 1421} 1422 1423status_t MediaPlayerService::AudioOutput::setAuxEffectSendLevel(float level) 1424{ 1425 ALOGV("setAuxEffectSendLevel(%f)", level); 1426 mSendLevel = level; 1427 if (mTrack) { 1428 return mTrack->setAuxEffectSendLevel(level); 1429 } 1430 return NO_ERROR; 1431} 1432 1433status_t MediaPlayerService::AudioOutput::attachAuxEffect(int effectId) 1434{ 1435 ALOGV("attachAuxEffect(%d)", effectId); 1436 mAuxEffectId = effectId; 1437 if (mTrack) { 1438 return mTrack->attachAuxEffect(effectId); 1439 } 1440 return NO_ERROR; 1441} 1442 1443// static 1444void MediaPlayerService::AudioOutput::CallbackWrapper( 1445 int event, void *cookie, void *info) { 1446 //ALOGV("callbackwrapper"); 1447 if (event != AudioTrack::EVENT_MORE_DATA) { 1448 return; 1449 } 1450 1451 AudioOutput *me = (AudioOutput *)cookie; 1452 AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info; 1453 1454 size_t actualSize = (*me->mCallback)( 1455 me, buffer->raw, buffer->size, me->mCallbackCookie); 1456 1457 if (actualSize == 0 && buffer->size > 0) { 1458 // We've reached EOS but the audio track is not stopped yet, 1459 // keep playing silence. 1460 1461 memset(buffer->raw, 0, buffer->size); 1462 actualSize = buffer->size; 1463 } 1464 1465 buffer->size = actualSize; 1466} 1467 1468int MediaPlayerService::AudioOutput::getSessionId() 1469{ 1470 return mSessionId; 1471} 1472 1473#undef LOG_TAG 1474#define LOG_TAG "AudioCache" 1475MediaPlayerService::AudioCache::AudioCache(const char* name) : 1476 mChannelCount(0), mFrameCount(1024), mSampleRate(0), mSize(0), 1477 mError(NO_ERROR), mCommandComplete(false) 1478{ 1479 // create ashmem heap 1480 mHeap = new MemoryHeapBase(kDefaultHeapSize, 0, name); 1481} 1482 1483uint32_t MediaPlayerService::AudioCache::latency () const 1484{ 1485 return 0; 1486} 1487 1488float MediaPlayerService::AudioCache::msecsPerFrame() const 1489{ 1490 return mMsecsPerFrame; 1491} 1492 1493status_t MediaPlayerService::AudioCache::getPosition(uint32_t *position) 1494{ 1495 if (position == 0) return BAD_VALUE; 1496 *position = mSize; 1497 return NO_ERROR; 1498} 1499 1500//////////////////////////////////////////////////////////////////////////////// 1501 1502struct CallbackThread : public Thread { 1503 CallbackThread(const wp<MediaPlayerBase::AudioSink> &sink, 1504 MediaPlayerBase::AudioSink::AudioCallback cb, 1505 void *cookie); 1506 1507protected: 1508 virtual ~CallbackThread(); 1509 1510 virtual bool threadLoop(); 1511 1512private: 1513 wp<MediaPlayerBase::AudioSink> mSink; 1514 MediaPlayerBase::AudioSink::AudioCallback mCallback; 1515 void *mCookie; 1516 void *mBuffer; 1517 size_t mBufferSize; 1518 1519 CallbackThread(const CallbackThread &); 1520 CallbackThread &operator=(const CallbackThread &); 1521}; 1522 1523CallbackThread::CallbackThread( 1524 const wp<MediaPlayerBase::AudioSink> &sink, 1525 MediaPlayerBase::AudioSink::AudioCallback cb, 1526 void *cookie) 1527 : mSink(sink), 1528 mCallback(cb), 1529 mCookie(cookie), 1530 mBuffer(NULL), 1531 mBufferSize(0) { 1532} 1533 1534CallbackThread::~CallbackThread() { 1535 if (mBuffer) { 1536 free(mBuffer); 1537 mBuffer = NULL; 1538 } 1539} 1540 1541bool CallbackThread::threadLoop() { 1542 sp<MediaPlayerBase::AudioSink> sink = mSink.promote(); 1543 if (sink == NULL) { 1544 return false; 1545 } 1546 1547 if (mBuffer == NULL) { 1548 mBufferSize = sink->bufferSize(); 1549 mBuffer = malloc(mBufferSize); 1550 } 1551 1552 size_t actualSize = 1553 (*mCallback)(sink.get(), mBuffer, mBufferSize, mCookie); 1554 1555 if (actualSize > 0) { 1556 sink->write(mBuffer, actualSize); 1557 } 1558 1559 return true; 1560} 1561 1562//////////////////////////////////////////////////////////////////////////////// 1563 1564status_t MediaPlayerService::AudioCache::open( 1565 uint32_t sampleRate, int channelCount, int format, int bufferCount, 1566 AudioCallback cb, void *cookie) 1567{ 1568 ALOGV("open(%u, %d, %d, %d)", sampleRate, channelCount, format, bufferCount); 1569 if (mHeap->getHeapID() < 0) { 1570 return NO_INIT; 1571 } 1572 1573 mSampleRate = sampleRate; 1574 mChannelCount = (uint16_t)channelCount; 1575 mFormat = (uint16_t)format; 1576 mMsecsPerFrame = 1.e3 / (float) sampleRate; 1577 1578 if (cb != NULL) { 1579 mCallbackThread = new CallbackThread(this, cb, cookie); 1580 } 1581 return NO_ERROR; 1582} 1583 1584void MediaPlayerService::AudioCache::start() { 1585 if (mCallbackThread != NULL) { 1586 mCallbackThread->run("AudioCache callback"); 1587 } 1588} 1589 1590void MediaPlayerService::AudioCache::stop() { 1591 if (mCallbackThread != NULL) { 1592 mCallbackThread->requestExitAndWait(); 1593 } 1594} 1595 1596ssize_t MediaPlayerService::AudioCache::write(const void* buffer, size_t size) 1597{ 1598 ALOGV("write(%p, %u)", buffer, size); 1599 if ((buffer == 0) || (size == 0)) return size; 1600 1601 uint8_t* p = static_cast<uint8_t*>(mHeap->getBase()); 1602 if (p == NULL) return NO_INIT; 1603 p += mSize; 1604 ALOGV("memcpy(%p, %p, %u)", p, buffer, size); 1605 if (mSize + size > mHeap->getSize()) { 1606 LOGE("Heap size overflow! req size: %d, max size: %d", (mSize + size), mHeap->getSize()); 1607 size = mHeap->getSize() - mSize; 1608 } 1609 memcpy(p, buffer, size); 1610 mSize += size; 1611 return size; 1612} 1613 1614// call with lock held 1615status_t MediaPlayerService::AudioCache::wait() 1616{ 1617 Mutex::Autolock lock(mLock); 1618 while (!mCommandComplete) { 1619 mSignal.wait(mLock); 1620 } 1621 mCommandComplete = false; 1622 1623 if (mError == NO_ERROR) { 1624 ALOGV("wait - success"); 1625 } else { 1626 ALOGV("wait - error"); 1627 } 1628 return mError; 1629} 1630 1631void MediaPlayerService::AudioCache::notify( 1632 void* cookie, int msg, int ext1, int ext2, const Parcel *obj) 1633{ 1634 ALOGV("notify(%p, %d, %d, %d)", cookie, msg, ext1, ext2); 1635 AudioCache* p = static_cast<AudioCache*>(cookie); 1636 1637 // ignore buffering messages 1638 switch (msg) 1639 { 1640 case MEDIA_ERROR: 1641 LOGE("Error %d, %d occurred", ext1, ext2); 1642 p->mError = ext1; 1643 break; 1644 case MEDIA_PREPARED: 1645 ALOGV("prepared"); 1646 break; 1647 case MEDIA_PLAYBACK_COMPLETE: 1648 ALOGV("playback complete"); 1649 break; 1650 default: 1651 ALOGV("ignored"); 1652 return; 1653 } 1654 1655 // wake up thread 1656 Mutex::Autolock lock(p->mLock); 1657 p->mCommandComplete = true; 1658 p->mSignal.signal(); 1659} 1660 1661int MediaPlayerService::AudioCache::getSessionId() 1662{ 1663 return 0; 1664} 1665 1666void MediaPlayerService::addBatteryData(uint32_t params) 1667{ 1668 Mutex::Autolock lock(mLock); 1669 1670 int32_t time = systemTime() / 1000000L; 1671 1672 // change audio output devices. This notification comes from AudioFlinger 1673 if ((params & kBatteryDataSpeakerOn) 1674 || (params & kBatteryDataOtherAudioDeviceOn)) { 1675 1676 int deviceOn[NUM_AUDIO_DEVICES]; 1677 for (int i = 0; i < NUM_AUDIO_DEVICES; i++) { 1678 deviceOn[i] = 0; 1679 } 1680 1681 if ((params & kBatteryDataSpeakerOn) 1682 && (params & kBatteryDataOtherAudioDeviceOn)) { 1683 deviceOn[SPEAKER_AND_OTHER] = 1; 1684 } else if (params & kBatteryDataSpeakerOn) { 1685 deviceOn[SPEAKER] = 1; 1686 } else { 1687 deviceOn[OTHER_AUDIO_DEVICE] = 1; 1688 } 1689 1690 for (int i = 0; i < NUM_AUDIO_DEVICES; i++) { 1691 if (mBatteryAudio.deviceOn[i] != deviceOn[i]){ 1692 1693 if (mBatteryAudio.refCount > 0) { // if playing audio 1694 if (!deviceOn[i]) { 1695 mBatteryAudio.lastTime[i] += time; 1696 mBatteryAudio.totalTime[i] += mBatteryAudio.lastTime[i]; 1697 mBatteryAudio.lastTime[i] = 0; 1698 } else { 1699 mBatteryAudio.lastTime[i] = 0 - time; 1700 } 1701 } 1702 1703 mBatteryAudio.deviceOn[i] = deviceOn[i]; 1704 } 1705 } 1706 return; 1707 } 1708 1709 // an sudio stream is started 1710 if (params & kBatteryDataAudioFlingerStart) { 1711 // record the start time only if currently no other audio 1712 // is being played 1713 if (mBatteryAudio.refCount == 0) { 1714 for (int i = 0; i < NUM_AUDIO_DEVICES; i++) { 1715 if (mBatteryAudio.deviceOn[i]) { 1716 mBatteryAudio.lastTime[i] -= time; 1717 } 1718 } 1719 } 1720 1721 mBatteryAudio.refCount ++; 1722 return; 1723 1724 } else if (params & kBatteryDataAudioFlingerStop) { 1725 if (mBatteryAudio.refCount <= 0) { 1726 LOGW("Battery track warning: refCount is <= 0"); 1727 return; 1728 } 1729 1730 // record the stop time only if currently this is the only 1731 // audio being played 1732 if (mBatteryAudio.refCount == 1) { 1733 for (int i = 0; i < NUM_AUDIO_DEVICES; i++) { 1734 if (mBatteryAudio.deviceOn[i]) { 1735 mBatteryAudio.lastTime[i] += time; 1736 mBatteryAudio.totalTime[i] += mBatteryAudio.lastTime[i]; 1737 mBatteryAudio.lastTime[i] = 0; 1738 } 1739 } 1740 } 1741 1742 mBatteryAudio.refCount --; 1743 return; 1744 } 1745 1746 int uid = IPCThreadState::self()->getCallingUid(); 1747 if (uid == AID_MEDIA) { 1748 return; 1749 } 1750 int index = mBatteryData.indexOfKey(uid); 1751 1752 if (index < 0) { // create a new entry for this UID 1753 BatteryUsageInfo info; 1754 info.audioTotalTime = 0; 1755 info.videoTotalTime = 0; 1756 info.audioLastTime = 0; 1757 info.videoLastTime = 0; 1758 info.refCount = 0; 1759 1760 if (mBatteryData.add(uid, info) == NO_MEMORY) { 1761 LOGE("Battery track error: no memory for new app"); 1762 return; 1763 } 1764 } 1765 1766 BatteryUsageInfo &info = mBatteryData.editValueFor(uid); 1767 1768 if (params & kBatteryDataCodecStarted) { 1769 if (params & kBatteryDataTrackAudio) { 1770 info.audioLastTime -= time; 1771 info.refCount ++; 1772 } 1773 if (params & kBatteryDataTrackVideo) { 1774 info.videoLastTime -= time; 1775 info.refCount ++; 1776 } 1777 } else { 1778 if (info.refCount == 0) { 1779 LOGW("Battery track warning: refCount is already 0"); 1780 return; 1781 } else if (info.refCount < 0) { 1782 LOGE("Battery track error: refCount < 0"); 1783 mBatteryData.removeItem(uid); 1784 return; 1785 } 1786 1787 if (params & kBatteryDataTrackAudio) { 1788 info.audioLastTime += time; 1789 info.refCount --; 1790 } 1791 if (params & kBatteryDataTrackVideo) { 1792 info.videoLastTime += time; 1793 info.refCount --; 1794 } 1795 1796 // no stream is being played by this UID 1797 if (info.refCount == 0) { 1798 info.audioTotalTime += info.audioLastTime; 1799 info.audioLastTime = 0; 1800 info.videoTotalTime += info.videoLastTime; 1801 info.videoLastTime = 0; 1802 } 1803 } 1804} 1805 1806status_t MediaPlayerService::pullBatteryData(Parcel* reply) { 1807 Mutex::Autolock lock(mLock); 1808 1809 // audio output devices usage 1810 int32_t time = systemTime() / 1000000L; //in ms 1811 int32_t totalTime; 1812 1813 for (int i = 0; i < NUM_AUDIO_DEVICES; i++) { 1814 totalTime = mBatteryAudio.totalTime[i]; 1815 1816 if (mBatteryAudio.deviceOn[i] 1817 && (mBatteryAudio.lastTime[i] != 0)) { 1818 int32_t tmpTime = mBatteryAudio.lastTime[i] + time; 1819 totalTime += tmpTime; 1820 } 1821 1822 reply->writeInt32(totalTime); 1823 // reset the total time 1824 mBatteryAudio.totalTime[i] = 0; 1825 } 1826 1827 // codec usage 1828 BatteryUsageInfo info; 1829 int size = mBatteryData.size(); 1830 1831 reply->writeInt32(size); 1832 int i = 0; 1833 1834 while (i < size) { 1835 info = mBatteryData.valueAt(i); 1836 1837 reply->writeInt32(mBatteryData.keyAt(i)); //UID 1838 reply->writeInt32(info.audioTotalTime); 1839 reply->writeInt32(info.videoTotalTime); 1840 1841 info.audioTotalTime = 0; 1842 info.videoTotalTime = 0; 1843 1844 // remove the UID entry where no stream is being played 1845 if (info.refCount <= 0) { 1846 mBatteryData.removeItemsAt(i); 1847 size --; 1848 i --; 1849 } 1850 i++; 1851 } 1852 return NO_ERROR; 1853} 1854} // namespace android 1855