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