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