MediaPlayerService.cpp revision fc1c7b940c84793ad262a345af117c482a86acec
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 "VorbisPlayer.h" 60#include <media/PVPlayer.h> 61#include "TestPlayerStub.h" 62#include "StagefrightPlayer.h" 63 64#include <OMX.h> 65 66/* desktop Linux needs a little help with gettid() */ 67#if defined(HAVE_GETTID) && !defined(HAVE_ANDROID_OS) 68#define __KERNEL__ 69# include <linux/unistd.h> 70#ifdef _syscall0 71_syscall0(pid_t,gettid) 72#else 73pid_t gettid() { return syscall(__NR_gettid);} 74#endif 75#undef __KERNEL__ 76#endif 77 78namespace { 79using android::media::Metadata; 80using android::status_t; 81using android::OK; 82using android::BAD_VALUE; 83using android::NOT_ENOUGH_DATA; 84using android::Parcel; 85 86// Max number of entries in the filter. 87const int kMaxFilterSize = 64; // I pulled that out of thin air. 88 89// FIXME: Move all the metadata related function in the Metadata.cpp 90 91 92// Unmarshall a filter from a Parcel. 93// Filter format in a parcel: 94// 95// 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 96// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 97// | number of entries (n) | 98// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 99// | metadata type 1 | 100// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 101// | metadata type 2 | 102// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 103// .... 104// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 105// | metadata type n | 106// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 107// 108// @param p Parcel that should start with a filter. 109// @param[out] filter On exit contains the list of metadata type to be 110// filtered. 111// @param[out] status On exit contains the status code to be returned. 112// @return true if the parcel starts with a valid filter. 113bool unmarshallFilter(const Parcel& p, 114 Metadata::Filter *filter, 115 status_t *status) 116{ 117 int32_t val; 118 if (p.readInt32(&val) != OK) 119 { 120 LOGE("Failed to read filter's length"); 121 *status = NOT_ENOUGH_DATA; 122 return false; 123 } 124 125 if( val > kMaxFilterSize || val < 0) 126 { 127 LOGE("Invalid filter len %d", val); 128 *status = BAD_VALUE; 129 return false; 130 } 131 132 const size_t num = val; 133 134 filter->clear(); 135 filter->setCapacity(num); 136 137 size_t size = num * sizeof(Metadata::Type); 138 139 140 if (p.dataAvail() < size) 141 { 142 LOGE("Filter too short expected %d but got %d", size, p.dataAvail()); 143 *status = NOT_ENOUGH_DATA; 144 return false; 145 } 146 147 const Metadata::Type *data = 148 static_cast<const Metadata::Type*>(p.readInplace(size)); 149 150 if (NULL == data) 151 { 152 LOGE("Filter had no data"); 153 *status = BAD_VALUE; 154 return false; 155 } 156 157 // TODO: The stl impl of vector would be more efficient here 158 // because it degenerates into a memcpy on pod types. Try to 159 // replace later or use stl::set. 160 for (size_t i = 0; i < num; ++i) 161 { 162 filter->add(*data); 163 ++data; 164 } 165 *status = OK; 166 return true; 167} 168 169// @param filter Of metadata type. 170// @param val To be searched. 171// @return true if a match was found. 172bool findMetadata(const Metadata::Filter& filter, const int32_t val) 173{ 174 // Deal with empty and ANY right away 175 if (filter.isEmpty()) return false; 176 if (filter[0] == Metadata::kAny) return true; 177 178 return filter.indexOf(val) >= 0; 179} 180 181} // anonymous namespace 182 183 184namespace android { 185 186// TODO: Temp hack until we can register players 187typedef struct { 188 const char *extension; 189 const player_type playertype; 190} extmap; 191extmap FILE_EXTS [] = { 192 {".mid", SONIVOX_PLAYER}, 193 {".midi", SONIVOX_PLAYER}, 194 {".smf", SONIVOX_PLAYER}, 195 {".xmf", SONIVOX_PLAYER}, 196 {".imy", SONIVOX_PLAYER}, 197 {".rtttl", SONIVOX_PLAYER}, 198 {".rtx", SONIVOX_PLAYER}, 199 {".ota", SONIVOX_PLAYER}, 200 {".ogg", VORBIS_PLAYER}, 201 {".oga", VORBIS_PLAYER}, 202}; 203 204// TODO: Find real cause of Audio/Video delay in PV framework and remove this workaround 205/* static */ const uint32_t MediaPlayerService::AudioOutput::kAudioVideoDelayMs = 0; 206/* static */ int MediaPlayerService::AudioOutput::mMinBufferCount = 4; 207/* static */ bool MediaPlayerService::AudioOutput::mIsOnEmulator = false; 208 209void MediaPlayerService::instantiate() { 210 defaultServiceManager()->addService( 211 String16("media.player"), new MediaPlayerService()); 212} 213 214MediaPlayerService::MediaPlayerService() 215{ 216 LOGV("MediaPlayerService created"); 217 mNextConnId = 1; 218} 219 220MediaPlayerService::~MediaPlayerService() 221{ 222 LOGV("MediaPlayerService destroyed"); 223} 224 225sp<IMediaRecorder> MediaPlayerService::createMediaRecorder(pid_t pid) 226{ 227#ifndef NO_OPENCORE 228 sp<MediaRecorderClient> recorder = new MediaRecorderClient(this, pid); 229 wp<MediaRecorderClient> w = recorder; 230 Mutex::Autolock lock(mLock); 231 mMediaRecorderClients.add(w); 232#else 233 sp<MediaRecorderClient> recorder = NULL; 234#endif 235 LOGV("Create new media recorder client from pid %d", pid); 236 return recorder; 237} 238 239void MediaPlayerService::removeMediaRecorderClient(wp<MediaRecorderClient> client) 240{ 241 Mutex::Autolock lock(mLock); 242 mMediaRecorderClients.remove(client); 243 LOGV("Delete media recorder client"); 244} 245 246sp<IMediaMetadataRetriever> MediaPlayerService::createMetadataRetriever(pid_t pid) 247{ 248 sp<MetadataRetrieverClient> retriever = new MetadataRetrieverClient(pid); 249 LOGV("Create new media retriever from pid %d", pid); 250 return retriever; 251} 252 253sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClient>& client, const char* url) 254{ 255 int32_t connId = android_atomic_inc(&mNextConnId); 256 sp<Client> c = new Client(this, pid, connId, client); 257 LOGV("Create new client(%d) from pid %d, url=%s, connId=%d", connId, pid, url, connId); 258 if (NO_ERROR != c->setDataSource(url)) 259 { 260 c.clear(); 261 return c; 262 } 263 wp<Client> w = c; 264 Mutex::Autolock lock(mLock); 265 mClients.add(w); 266 return c; 267} 268 269sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClient>& client, 270 int fd, int64_t offset, int64_t length) 271{ 272 int32_t connId = android_atomic_inc(&mNextConnId); 273 sp<Client> c = new Client(this, pid, connId, client); 274 LOGV("Create new client(%d) from pid %d, fd=%d, offset=%lld, length=%lld", 275 connId, pid, fd, offset, length); 276 if (NO_ERROR != c->setDataSource(fd, offset, length)) { 277 c.clear(); 278 } else { 279 wp<Client> w = c; 280 Mutex::Autolock lock(mLock); 281 mClients.add(w); 282 } 283 ::close(fd); 284 return c; 285} 286 287sp<IOMX> MediaPlayerService::getOMX() { 288 Mutex::Autolock autoLock(mLock); 289 290 if (mOMX.get() == NULL) { 291 mOMX = new OMX; 292 } 293 294 return mOMX; 295} 296 297status_t MediaPlayerService::AudioCache::dump(int fd, const Vector<String16>& args) const 298{ 299 const size_t SIZE = 256; 300 char buffer[SIZE]; 301 String8 result; 302 303 result.append(" AudioCache\n"); 304 if (mHeap != 0) { 305 snprintf(buffer, 255, " heap base(%p), size(%d), flags(%d), device(%s)\n", 306 mHeap->getBase(), mHeap->getSize(), mHeap->getFlags(), mHeap->getDevice()); 307 result.append(buffer); 308 } 309 snprintf(buffer, 255, " msec per frame(%f), channel count(%d), format(%d), frame count(%ld)\n", 310 mMsecsPerFrame, mChannelCount, mFormat, mFrameCount); 311 result.append(buffer); 312 snprintf(buffer, 255, " sample rate(%d), size(%d), error(%d), command complete(%s)\n", 313 mSampleRate, mSize, mError, mCommandComplete?"true":"false"); 314 result.append(buffer); 315 ::write(fd, result.string(), result.size()); 316 return NO_ERROR; 317} 318 319status_t MediaPlayerService::AudioOutput::dump(int fd, const Vector<String16>& args) const 320{ 321 const size_t SIZE = 256; 322 char buffer[SIZE]; 323 String8 result; 324 325 result.append(" AudioOutput\n"); 326 snprintf(buffer, 255, " stream type(%d), left - right volume(%f, %f)\n", 327 mStreamType, mLeftVolume, mRightVolume); 328 result.append(buffer); 329 snprintf(buffer, 255, " msec per frame(%f), latency (%d)\n", 330 mMsecsPerFrame, mLatency); 331 result.append(buffer); 332 ::write(fd, result.string(), result.size()); 333 if (mTrack != 0) { 334 mTrack->dump(fd, args); 335 } 336 return NO_ERROR; 337} 338 339status_t MediaPlayerService::Client::dump(int fd, const Vector<String16>& args) const 340{ 341 const size_t SIZE = 256; 342 char buffer[SIZE]; 343 String8 result; 344 result.append(" Client\n"); 345 snprintf(buffer, 255, " pid(%d), connId(%d), status(%d), looping(%s)\n", 346 mPid, mConnId, mStatus, mLoop?"true": "false"); 347 result.append(buffer); 348 write(fd, result.string(), result.size()); 349 if (mAudioOutput != 0) { 350 mAudioOutput->dump(fd, args); 351 } 352 write(fd, "\n", 1); 353 return NO_ERROR; 354} 355 356static int myTid() { 357#ifdef HAVE_GETTID 358 return gettid(); 359#else 360 return getpid(); 361#endif 362} 363 364#if defined(__arm__) 365extern "C" void get_malloc_leak_info(uint8_t** info, size_t* overallSize, 366 size_t* infoSize, size_t* totalMemory, size_t* backtraceSize); 367extern "C" void free_malloc_leak_info(uint8_t* info); 368 369void memStatus(int fd, const Vector<String16>& args) 370{ 371 const size_t SIZE = 256; 372 char buffer[SIZE]; 373 String8 result; 374 375 typedef struct { 376 size_t size; 377 size_t dups; 378 intptr_t * backtrace; 379 } AllocEntry; 380 381 uint8_t *info = NULL; 382 size_t overallSize = 0; 383 size_t infoSize = 0; 384 size_t totalMemory = 0; 385 size_t backtraceSize = 0; 386 387 get_malloc_leak_info(&info, &overallSize, &infoSize, &totalMemory, &backtraceSize); 388 if (info) { 389 uint8_t *ptr = info; 390 size_t count = overallSize / infoSize; 391 392 snprintf(buffer, SIZE, " Allocation count %i\n", count); 393 result.append(buffer); 394 395 AllocEntry * entries = new AllocEntry[count]; 396 397 for (size_t i = 0; i < count; i++) { 398 // Each entry should be size_t, size_t, intptr_t[backtraceSize] 399 AllocEntry *e = &entries[i]; 400 401 e->size = *reinterpret_cast<size_t *>(ptr); 402 ptr += sizeof(size_t); 403 404 e->dups = *reinterpret_cast<size_t *>(ptr); 405 ptr += sizeof(size_t); 406 407 e->backtrace = reinterpret_cast<intptr_t *>(ptr); 408 ptr += sizeof(intptr_t) * backtraceSize; 409 } 410 411 // Now we need to sort the entries. They come sorted by size but 412 // not by stack trace which causes problems using diff. 413 bool moved; 414 do { 415 moved = false; 416 for (size_t i = 0; i < (count - 1); i++) { 417 AllocEntry *e1 = &entries[i]; 418 AllocEntry *e2 = &entries[i+1]; 419 420 bool swap = e1->size < e2->size; 421 if (e1->size == e2->size) { 422 for(size_t j = 0; j < backtraceSize; j++) { 423 if (e1->backtrace[j] == e2->backtrace[j]) { 424 continue; 425 } 426 swap = e1->backtrace[j] < e2->backtrace[j]; 427 break; 428 } 429 } 430 if (swap) { 431 AllocEntry t = entries[i]; 432 entries[i] = entries[i+1]; 433 entries[i+1] = t; 434 moved = true; 435 } 436 } 437 } while (moved); 438 439 for (size_t i = 0; i < count; i++) { 440 AllocEntry *e = &entries[i]; 441 442 snprintf(buffer, SIZE, "size %8i, dup %4i", e->size, e->dups); 443 result.append(buffer); 444 for (size_t ct = 0; (ct < backtraceSize) && e->backtrace[ct]; ct++) { 445 if (ct) { 446 result.append(", "); 447 } 448 snprintf(buffer, SIZE, "0x%08x", e->backtrace[ct]); 449 result.append(buffer); 450 } 451 result.append("\n"); 452 } 453 454 delete[] entries; 455 free_malloc_leak_info(info); 456 } 457 458 write(fd, result.string(), result.size()); 459} 460#endif 461 462status_t MediaPlayerService::dump(int fd, const Vector<String16>& args) 463{ 464 const size_t SIZE = 256; 465 char buffer[SIZE]; 466 String8 result; 467 if (checkCallingPermission(String16("android.permission.DUMP")) == false) { 468 snprintf(buffer, SIZE, "Permission Denial: " 469 "can't dump MediaPlayerService from pid=%d, uid=%d\n", 470 IPCThreadState::self()->getCallingPid(), 471 IPCThreadState::self()->getCallingUid()); 472 result.append(buffer); 473 } else { 474 Mutex::Autolock lock(mLock); 475 for (int i = 0, n = mClients.size(); i < n; ++i) { 476 sp<Client> c = mClients[i].promote(); 477 if (c != 0) c->dump(fd, args); 478 } 479 for (int i = 0, n = mMediaRecorderClients.size(); i < n; ++i) { 480 result.append(" MediaRecorderClient\n"); 481 sp<MediaRecorderClient> c = mMediaRecorderClients[i].promote(); 482 snprintf(buffer, 255, " pid(%d)\n\n", c->mPid); 483 result.append(buffer); 484 } 485 486 result.append(" Files opened and/or mapped:\n"); 487 snprintf(buffer, SIZE, "/proc/%d/maps", myTid()); 488 FILE *f = fopen(buffer, "r"); 489 if (f) { 490 while (!feof(f)) { 491 fgets(buffer, SIZE, f); 492 if (strstr(buffer, " /sdcard/") || 493 strstr(buffer, " /system/sounds/") || 494 strstr(buffer, " /system/media/")) { 495 result.append(" "); 496 result.append(buffer); 497 } 498 } 499 fclose(f); 500 } else { 501 result.append("couldn't open "); 502 result.append(buffer); 503 result.append("\n"); 504 } 505 506 snprintf(buffer, SIZE, "/proc/%d/fd", myTid()); 507 DIR *d = opendir(buffer); 508 if (d) { 509 struct dirent *ent; 510 while((ent = readdir(d)) != NULL) { 511 if (strcmp(ent->d_name,".") && strcmp(ent->d_name,"..")) { 512 snprintf(buffer, SIZE, "/proc/%d/fd/%s", myTid(), ent->d_name); 513 struct stat s; 514 if (lstat(buffer, &s) == 0) { 515 if ((s.st_mode & S_IFMT) == S_IFLNK) { 516 char linkto[256]; 517 int len = readlink(buffer, linkto, sizeof(linkto)); 518 if(len > 0) { 519 if(len > 255) { 520 linkto[252] = '.'; 521 linkto[253] = '.'; 522 linkto[254] = '.'; 523 linkto[255] = 0; 524 } else { 525 linkto[len] = 0; 526 } 527 if (strstr(linkto, "/sdcard/") == linkto || 528 strstr(linkto, "/system/sounds/") == linkto || 529 strstr(linkto, "/system/media/") == linkto) { 530 result.append(" "); 531 result.append(buffer); 532 result.append(" -> "); 533 result.append(linkto); 534 result.append("\n"); 535 } 536 } 537 } else { 538 result.append(" unexpected type for "); 539 result.append(buffer); 540 result.append("\n"); 541 } 542 } 543 } 544 } 545 closedir(d); 546 } else { 547 result.append("couldn't open "); 548 result.append(buffer); 549 result.append("\n"); 550 } 551 552#if defined(__arm__) 553 bool dumpMem = false; 554 for (size_t i = 0; i < args.size(); i++) { 555 if (args[i] == String16("-m")) { 556 dumpMem = true; 557 } 558 } 559 if (dumpMem) { 560 memStatus(fd, args); 561 } 562#endif 563 } 564 write(fd, result.string(), result.size()); 565 return NO_ERROR; 566} 567 568void MediaPlayerService::removeClient(wp<Client> client) 569{ 570 Mutex::Autolock lock(mLock); 571 mClients.remove(client); 572} 573 574MediaPlayerService::Client::Client(const sp<MediaPlayerService>& service, pid_t pid, 575 int32_t connId, const sp<IMediaPlayerClient>& client) 576{ 577 LOGV("Client(%d) constructor", connId); 578 mPid = pid; 579 mConnId = connId; 580 mService = service; 581 mClient = client; 582 mLoop = false; 583 mStatus = NO_INIT; 584#if CALLBACK_ANTAGONIZER 585 LOGD("create Antagonizer"); 586 mAntagonizer = new Antagonizer(notify, this); 587#endif 588} 589 590MediaPlayerService::Client::~Client() 591{ 592 LOGV("Client(%d) destructor pid = %d", mConnId, mPid); 593 mAudioOutput.clear(); 594 wp<Client> client(this); 595 disconnect(); 596 mService->removeClient(client); 597} 598 599void MediaPlayerService::Client::disconnect() 600{ 601 LOGV("disconnect(%d) from pid %d", mConnId, mPid); 602 // grab local reference and clear main reference to prevent future 603 // access to object 604 sp<MediaPlayerBase> p; 605 { 606 Mutex::Autolock l(mLock); 607 p = mPlayer; 608 } 609 mClient.clear(); 610 611 mPlayer.clear(); 612 613 // clear the notification to prevent callbacks to dead client 614 // and reset the player. We assume the player will serialize 615 // access to itself if necessary. 616 if (p != 0) { 617 p->setNotifyCallback(0, 0); 618#if CALLBACK_ANTAGONIZER 619 LOGD("kill Antagonizer"); 620 mAntagonizer->kill(); 621#endif 622 p->reset(); 623 } 624 625 IPCThreadState::self()->flushCommands(); 626} 627 628static player_type getDefaultPlayerType() { 629#if BUILD_WITH_FULL_STAGEFRIGHT 630 char value[PROPERTY_VALUE_MAX]; 631 if (property_get("media.stagefright.enable-player", value, NULL) 632 && (!strcmp(value, "1") || !strcasecmp(value, "true"))) { 633 return STAGEFRIGHT_PLAYER; 634 } 635#endif 636 637 return PV_PLAYER; 638} 639 640player_type getPlayerType(int fd, int64_t offset, int64_t length) 641{ 642 char buf[20]; 643 lseek(fd, offset, SEEK_SET); 644 read(fd, buf, sizeof(buf)); 645 lseek(fd, offset, SEEK_SET); 646 647 long ident = *((long*)buf); 648 649 // Ogg vorbis? 650 if (ident == 0x5367674f) // 'OggS' 651 return VORBIS_PLAYER; 652 653 // Some kind of MIDI? 654 EAS_DATA_HANDLE easdata; 655 if (EAS_Init(&easdata) == EAS_SUCCESS) { 656 EAS_FILE locator; 657 locator.path = NULL; 658 locator.fd = fd; 659 locator.offset = offset; 660 locator.length = length; 661 EAS_HANDLE eashandle; 662 if (EAS_OpenFile(easdata, &locator, &eashandle) == EAS_SUCCESS) { 663 EAS_CloseFile(easdata, eashandle); 664 EAS_Shutdown(easdata); 665 return SONIVOX_PLAYER; 666 } 667 EAS_Shutdown(easdata); 668 } 669 670 return getDefaultPlayerType(); 671} 672 673player_type getPlayerType(const char* url) 674{ 675 if (TestPlayerStub::canBeUsed(url)) { 676 return TEST_PLAYER; 677 } 678 679 // use MidiFile for MIDI extensions 680 int lenURL = strlen(url); 681 for (int i = 0; i < NELEM(FILE_EXTS); ++i) { 682 int len = strlen(FILE_EXTS[i].extension); 683 int start = lenURL - len; 684 if (start > 0) { 685 if (!strncasecmp(url + start, FILE_EXTS[i].extension, len)) { 686 return FILE_EXTS[i].playertype; 687 } 688 } 689 } 690 691 return getDefaultPlayerType(); 692} 693 694static sp<MediaPlayerBase> createPlayer(player_type playerType, void* cookie, 695 notify_callback_f notifyFunc) 696{ 697 sp<MediaPlayerBase> p; 698 switch (playerType) { 699#ifndef NO_OPENCORE 700 case PV_PLAYER: 701 LOGV(" create PVPlayer"); 702 p = new PVPlayer(); 703 break; 704#endif 705 case SONIVOX_PLAYER: 706 LOGV(" create MidiFile"); 707 p = new MidiFile(); 708 break; 709 case VORBIS_PLAYER: 710 LOGV(" create VorbisPlayer"); 711 p = new VorbisPlayer(); 712 break; 713#if BUILD_WITH_FULL_STAGEFRIGHT 714 case STAGEFRIGHT_PLAYER: 715 LOGV(" create StagefrightPlayer"); 716 p = new StagefrightPlayer; 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 media::Metadata::Filter 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> player = getPlayer(); 876 if (player == 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 media::Metadata::Filter 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 media::Metadata metadata(reply); 896 897 metadata.appendHeader(); 898 status = player->getMetadata(ids, reply); 899 900 if (status != OK) { 901 metadata.resetParcel(); 902 LOGE("getMetadata failed %d", status); 903 return status; 904 } 905 906 // FIXME: Implement filtering on the result. Not critical since 907 // filtering takes place on the update notifications already. This 908 // would be when all the metadata are fetch and a filter is set. 909 910 // Everything is fine, update the metadata length. 911 metadata.updateLength(); 912 return OK; 913} 914 915status_t MediaPlayerService::Client::prepareAsync() 916{ 917 LOGV("[%d] prepareAsync", mConnId); 918 sp<MediaPlayerBase> p = getPlayer(); 919 if (p == 0) return UNKNOWN_ERROR; 920 status_t ret = p->prepareAsync(); 921#if CALLBACK_ANTAGONIZER 922 LOGD("start Antagonizer"); 923 if (ret == NO_ERROR) mAntagonizer->start(); 924#endif 925 return ret; 926} 927 928status_t MediaPlayerService::Client::start() 929{ 930 LOGV("[%d] start", mConnId); 931 sp<MediaPlayerBase> p = getPlayer(); 932 if (p == 0) return UNKNOWN_ERROR; 933 p->setLooping(mLoop); 934 return p->start(); 935} 936 937status_t MediaPlayerService::Client::stop() 938{ 939 LOGV("[%d] stop", mConnId); 940 sp<MediaPlayerBase> p = getPlayer(); 941 if (p == 0) return UNKNOWN_ERROR; 942 return p->stop(); 943} 944 945status_t MediaPlayerService::Client::pause() 946{ 947 LOGV("[%d] pause", mConnId); 948 sp<MediaPlayerBase> p = getPlayer(); 949 if (p == 0) return UNKNOWN_ERROR; 950 return p->pause(); 951} 952 953status_t MediaPlayerService::Client::isPlaying(bool* state) 954{ 955 *state = false; 956 sp<MediaPlayerBase> p = getPlayer(); 957 if (p == 0) return UNKNOWN_ERROR; 958 *state = p->isPlaying(); 959 LOGV("[%d] isPlaying: %d", mConnId, *state); 960 return NO_ERROR; 961} 962 963status_t MediaPlayerService::Client::getCurrentPosition(int *msec) 964{ 965 LOGV("getCurrentPosition"); 966 sp<MediaPlayerBase> p = getPlayer(); 967 if (p == 0) return UNKNOWN_ERROR; 968 status_t ret = p->getCurrentPosition(msec); 969 if (ret == NO_ERROR) { 970 LOGV("[%d] getCurrentPosition = %d", mConnId, *msec); 971 } else { 972 LOGE("getCurrentPosition returned %d", ret); 973 } 974 return ret; 975} 976 977status_t MediaPlayerService::Client::getDuration(int *msec) 978{ 979 LOGV("getDuration"); 980 sp<MediaPlayerBase> p = getPlayer(); 981 if (p == 0) return UNKNOWN_ERROR; 982 status_t ret = p->getDuration(msec); 983 if (ret == NO_ERROR) { 984 LOGV("[%d] getDuration = %d", mConnId, *msec); 985 } else { 986 LOGE("getDuration returned %d", ret); 987 } 988 return ret; 989} 990 991status_t MediaPlayerService::Client::seekTo(int msec) 992{ 993 LOGV("[%d] seekTo(%d)", mConnId, msec); 994 sp<MediaPlayerBase> p = getPlayer(); 995 if (p == 0) return UNKNOWN_ERROR; 996 return p->seekTo(msec); 997} 998 999status_t MediaPlayerService::Client::reset() 1000{ 1001 LOGV("[%d] reset", mConnId); 1002 sp<MediaPlayerBase> p = getPlayer(); 1003 if (p == 0) return UNKNOWN_ERROR; 1004 return p->reset(); 1005} 1006 1007status_t MediaPlayerService::Client::setAudioStreamType(int type) 1008{ 1009 LOGV("[%d] setAudioStreamType(%d)", mConnId, type); 1010 // TODO: for hardware output, call player instead 1011 Mutex::Autolock l(mLock); 1012 if (mAudioOutput != 0) mAudioOutput->setAudioStreamType(type); 1013 return NO_ERROR; 1014} 1015 1016status_t MediaPlayerService::Client::setLooping(int loop) 1017{ 1018 LOGV("[%d] setLooping(%d)", mConnId, loop); 1019 mLoop = loop; 1020 sp<MediaPlayerBase> p = getPlayer(); 1021 if (p != 0) return p->setLooping(loop); 1022 return NO_ERROR; 1023} 1024 1025status_t MediaPlayerService::Client::setVolume(float leftVolume, float rightVolume) 1026{ 1027 LOGV("[%d] setVolume(%f, %f)", mConnId, leftVolume, rightVolume); 1028 // TODO: for hardware output, call player instead 1029 Mutex::Autolock l(mLock); 1030 if (mAudioOutput != 0) mAudioOutput->setVolume(leftVolume, rightVolume); 1031 return NO_ERROR; 1032} 1033 1034 1035void MediaPlayerService::Client::notify(void* cookie, int msg, int ext1, int ext2) 1036{ 1037 Client* client = static_cast<Client*>(cookie); 1038 1039 if (MEDIA_INFO == msg && 1040 MEDIA_INFO_METADATA_UPDATE == ext1) { 1041 const media::Metadata::Type metadata_type = ext2; 1042 1043 if(client->shouldDropMetadata(metadata_type)) { 1044 return; 1045 } 1046 1047 // Update the list of metadata that have changed. getMetadata 1048 // also access mMetadataUpdated and clears it. 1049 client->addNewMetadataUpdate(metadata_type); 1050 } 1051 LOGV("[%d] notify (%p, %d, %d, %d)", client->mConnId, cookie, msg, ext1, ext2); 1052 client->mClient->notify(msg, ext1, ext2); 1053} 1054 1055 1056bool MediaPlayerService::Client::shouldDropMetadata(media::Metadata::Type code) const 1057{ 1058 Mutex::Autolock lock(mLock); 1059 1060 if (findMetadata(mMetadataDrop, code)) { 1061 return true; 1062 } 1063 1064 if (mMetadataAllow.isEmpty() || findMetadata(mMetadataAllow, code)) { 1065 return false; 1066 } else { 1067 return true; 1068 } 1069} 1070 1071 1072void MediaPlayerService::Client::addNewMetadataUpdate(media::Metadata::Type metadata_type) { 1073 Mutex::Autolock lock(mLock); 1074 if (mMetadataUpdated.indexOf(metadata_type) < 0) { 1075 mMetadataUpdated.add(metadata_type); 1076 } 1077} 1078 1079#if CALLBACK_ANTAGONIZER 1080const int Antagonizer::interval = 10000; // 10 msecs 1081 1082Antagonizer::Antagonizer(notify_callback_f cb, void* client) : 1083 mExit(false), mActive(false), mClient(client), mCb(cb) 1084{ 1085 createThread(callbackThread, this); 1086} 1087 1088void Antagonizer::kill() 1089{ 1090 Mutex::Autolock _l(mLock); 1091 mActive = false; 1092 mExit = true; 1093 mCondition.wait(mLock); 1094} 1095 1096int Antagonizer::callbackThread(void* user) 1097{ 1098 LOGD("Antagonizer started"); 1099 Antagonizer* p = reinterpret_cast<Antagonizer*>(user); 1100 while (!p->mExit) { 1101 if (p->mActive) { 1102 LOGV("send event"); 1103 p->mCb(p->mClient, 0, 0, 0); 1104 } 1105 usleep(interval); 1106 } 1107 Mutex::Autolock _l(p->mLock); 1108 p->mCondition.signal(); 1109 LOGD("Antagonizer stopped"); 1110 return 0; 1111} 1112#endif 1113 1114static size_t kDefaultHeapSize = 1024 * 1024; // 1MB 1115 1116sp<IMemory> MediaPlayerService::decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) 1117{ 1118 LOGV("decode(%s)", url); 1119 sp<MemoryBase> mem; 1120 sp<MediaPlayerBase> player; 1121 1122 // Protect our precious, precious DRMd ringtones by only allowing 1123 // decoding of http, but not filesystem paths or content Uris. 1124 // If the application wants to decode those, it should open a 1125 // filedescriptor for them and use that. 1126 if (url != NULL && strncmp(url, "http://", 7) != 0) { 1127 LOGD("Can't decode %s by path, use filedescriptor instead", url); 1128 return mem; 1129 } 1130 1131 player_type playerType = getPlayerType(url); 1132 LOGV("player type = %d", playerType); 1133 1134 // create the right type of player 1135 sp<AudioCache> cache = new AudioCache(url); 1136 player = android::createPlayer(playerType, cache.get(), cache->notify); 1137 if (player == NULL) goto Exit; 1138 if (player->hardwareOutput()) goto Exit; 1139 1140 static_cast<MediaPlayerInterface*>(player.get())->setAudioSink(cache); 1141 1142 // set data source 1143 if (player->setDataSource(url) != NO_ERROR) goto Exit; 1144 1145 LOGV("prepare"); 1146 player->prepareAsync(); 1147 1148 LOGV("wait for prepare"); 1149 if (cache->wait() != NO_ERROR) goto Exit; 1150 1151 LOGV("start"); 1152 player->start(); 1153 1154 LOGV("wait for playback complete"); 1155 if (cache->wait() != NO_ERROR) goto Exit; 1156 1157 mem = new MemoryBase(cache->getHeap(), 0, cache->size()); 1158 *pSampleRate = cache->sampleRate(); 1159 *pNumChannels = cache->channelCount(); 1160 *pFormat = cache->format(); 1161 LOGV("return memory @ %p, sampleRate=%u, channelCount = %d, format = %d", mem->pointer(), *pSampleRate, *pNumChannels, *pFormat); 1162 1163Exit: 1164 if (player != 0) player->reset(); 1165 return mem; 1166} 1167 1168sp<IMemory> MediaPlayerService::decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) 1169{ 1170 LOGV("decode(%d, %lld, %lld)", fd, offset, length); 1171 sp<MemoryBase> mem; 1172 sp<MediaPlayerBase> player; 1173 1174 player_type playerType = getPlayerType(fd, offset, length); 1175 LOGV("player type = %d", playerType); 1176 1177 // create the right type of player 1178 sp<AudioCache> cache = new AudioCache("decode_fd"); 1179 player = android::createPlayer(playerType, cache.get(), cache->notify); 1180 if (player == NULL) goto Exit; 1181 if (player->hardwareOutput()) goto Exit; 1182 1183 static_cast<MediaPlayerInterface*>(player.get())->setAudioSink(cache); 1184 1185 // set data source 1186 if (player->setDataSource(fd, offset, length) != NO_ERROR) goto Exit; 1187 1188 LOGV("prepare"); 1189 player->prepareAsync(); 1190 1191 LOGV("wait for prepare"); 1192 if (cache->wait() != NO_ERROR) goto Exit; 1193 1194 LOGV("start"); 1195 player->start(); 1196 1197 LOGV("wait for playback complete"); 1198 if (cache->wait() != NO_ERROR) goto Exit; 1199 1200 mem = new MemoryBase(cache->getHeap(), 0, cache->size()); 1201 *pSampleRate = cache->sampleRate(); 1202 *pNumChannels = cache->channelCount(); 1203 *pFormat = cache->format(); 1204 LOGV("return memory @ %p, sampleRate=%u, channelCount = %d, format = %d", mem->pointer(), *pSampleRate, *pNumChannels, *pFormat); 1205 1206Exit: 1207 if (player != 0) player->reset(); 1208 ::close(fd); 1209 return mem; 1210} 1211 1212/* 1213 * Avert your eyes, ugly hack ahead. 1214 * The following is to support music visualizations. 1215 */ 1216 1217static const int NUMVIZBUF = 32; 1218static const int VIZBUFFRAMES = 1024; 1219static const int TOTALBUFTIMEMSEC = NUMVIZBUF * VIZBUFFRAMES * 1000 / 44100; 1220 1221static bool gotMem = false; 1222static sp<MemoryBase> mem[NUMVIZBUF]; 1223static uint64_t timeStamp[NUMVIZBUF]; 1224static uint64_t lastReadTime; 1225static uint64_t lastWriteTime; 1226static int writeIdx = 0; 1227 1228static void allocVizBufs() { 1229 if (!gotMem) { 1230 for (int i=0;i<NUMVIZBUF;i++) { 1231 sp<MemoryHeapBase> heap = new MemoryHeapBase(VIZBUFFRAMES*2, 0, "snooper"); 1232 mem[i] = new MemoryBase(heap, 0, heap->getSize()); 1233 timeStamp[i] = 0; 1234 } 1235 gotMem = true; 1236 } 1237} 1238 1239 1240/* 1241 * Get a buffer of audio data that is about to be played. 1242 * We don't synchronize this because in practice the writer 1243 * is ahead of the reader, and even if we did happen to catch 1244 * a buffer while it's being written, it's just a visualization, 1245 * so no harm done. 1246 */ 1247static sp<MemoryBase> getVizBuffer() { 1248 1249 allocVizBufs(); 1250 1251 lastReadTime = uptimeMillis() + 100; // account for renderer delay (we shouldn't be doing this here) 1252 1253 // if there is no recent buffer (yet), just return empty handed 1254 if (lastWriteTime + TOTALBUFTIMEMSEC < lastReadTime) { 1255 //LOGI("@@@@ no audio data to look at yet"); 1256 return NULL; 1257 } 1258 1259 char buf[200]; 1260 1261 int closestIdx = -1; 1262 uint32_t closestTime = 0x7ffffff; 1263 1264 for (int i = 0; i < NUMVIZBUF; i++) { 1265 uint64_t tsi = timeStamp[i]; 1266 uint64_t diff = tsi > lastReadTime ? tsi - lastReadTime : lastReadTime - tsi; 1267 if (diff < closestTime) { 1268 closestIdx = i; 1269 closestTime = diff; 1270 } 1271 } 1272 1273 1274 if (closestIdx >= 0) { 1275 //LOGI("@@@ return buffer %d, %d/%d", closestIdx, uint32_t(lastReadTime), uint32_t(timeStamp[closestIdx])); 1276 return mem[closestIdx]; 1277 } 1278 1279 // we won't get here, since we either bailed out early, or got a buffer 1280 LOGD("Didn't expect to be here"); 1281 return NULL; 1282} 1283 1284static void storeVizBuf(const void *data, int len, uint64_t time) { 1285 // Copy the data in to the visualizer buffer 1286 // Assume a 16 bit stereo source for now. 1287 short *viz = (short*)mem[writeIdx]->pointer(); 1288 short *src = (short*)data; 1289 for (int i = 0; i < VIZBUFFRAMES; i++) { 1290 // Degrade quality by mixing to mono and clearing the lowest 3 bits. 1291 // This should still be good enough for a visualization 1292 *viz++ = ((int(src[0]) + int(src[1])) >> 1) & ~0x7; 1293 src += 2; 1294 } 1295 timeStamp[writeIdx++] = time; 1296 if (writeIdx >= NUMVIZBUF) { 1297 writeIdx = 0; 1298 } 1299} 1300 1301static void makeVizBuffers(const char *data, int len, uint64_t time) { 1302 1303 allocVizBufs(); 1304 1305 uint64_t startTime = time; 1306 const int frameSize = 4; // 16 bit stereo sample is 4 bytes 1307 while (len >= VIZBUFFRAMES * frameSize) { 1308 storeVizBuf(data, len, time); 1309 data += VIZBUFFRAMES * frameSize; 1310 len -= VIZBUFFRAMES * frameSize; 1311 time += 1000 * VIZBUFFRAMES / 44100; 1312 } 1313 //LOGI("@@@ stored buffers from %d to %d", uint32_t(startTime), uint32_t(time)); 1314} 1315 1316sp<IMemory> MediaPlayerService::snoop() 1317{ 1318 sp<MemoryBase> mem = getVizBuffer(); 1319 return mem; 1320} 1321 1322 1323#undef LOG_TAG 1324#define LOG_TAG "AudioSink" 1325MediaPlayerService::AudioOutput::AudioOutput() 1326 : mCallback(NULL), 1327 mCallbackCookie(NULL) { 1328 mTrack = 0; 1329 mStreamType = AudioSystem::MUSIC; 1330 mLeftVolume = 1.0; 1331 mRightVolume = 1.0; 1332 mLatency = 0; 1333 mMsecsPerFrame = 0; 1334 mNumFramesWritten = 0; 1335 setMinBufferCount(); 1336} 1337 1338MediaPlayerService::AudioOutput::~AudioOutput() 1339{ 1340 close(); 1341} 1342 1343void MediaPlayerService::AudioOutput::setMinBufferCount() 1344{ 1345 char value[PROPERTY_VALUE_MAX]; 1346 if (property_get("ro.kernel.qemu", value, 0)) { 1347 mIsOnEmulator = true; 1348 mMinBufferCount = 12; // to prevent systematic buffer underrun for emulator 1349 } 1350} 1351 1352bool MediaPlayerService::AudioOutput::isOnEmulator() 1353{ 1354 setMinBufferCount(); 1355 return mIsOnEmulator; 1356} 1357 1358int MediaPlayerService::AudioOutput::getMinBufferCount() 1359{ 1360 setMinBufferCount(); 1361 return mMinBufferCount; 1362} 1363 1364ssize_t MediaPlayerService::AudioOutput::bufferSize() const 1365{ 1366 if (mTrack == 0) return NO_INIT; 1367 return mTrack->frameCount() * frameSize(); 1368} 1369 1370ssize_t MediaPlayerService::AudioOutput::frameCount() const 1371{ 1372 if (mTrack == 0) return NO_INIT; 1373 return mTrack->frameCount(); 1374} 1375 1376ssize_t MediaPlayerService::AudioOutput::channelCount() const 1377{ 1378 if (mTrack == 0) return NO_INIT; 1379 return mTrack->channelCount(); 1380} 1381 1382ssize_t MediaPlayerService::AudioOutput::frameSize() const 1383{ 1384 if (mTrack == 0) return NO_INIT; 1385 return mTrack->frameSize(); 1386} 1387 1388uint32_t MediaPlayerService::AudioOutput::latency () const 1389{ 1390 return mLatency; 1391} 1392 1393float MediaPlayerService::AudioOutput::msecsPerFrame() const 1394{ 1395 return mMsecsPerFrame; 1396} 1397 1398status_t MediaPlayerService::AudioOutput::open( 1399 uint32_t sampleRate, int channelCount, int format, int bufferCount, 1400 AudioCallback cb, void *cookie) 1401{ 1402 mCallback = cb; 1403 mCallbackCookie = cookie; 1404 1405 // Check argument "bufferCount" against the mininum buffer count 1406 if (bufferCount < mMinBufferCount) { 1407 LOGD("bufferCount (%d) is too small and increased to %d", bufferCount, mMinBufferCount); 1408 bufferCount = mMinBufferCount; 1409 1410 } 1411 LOGV("open(%u, %d, %d, %d)", sampleRate, channelCount, format, bufferCount); 1412 if (mTrack) close(); 1413 int afSampleRate; 1414 int afFrameCount; 1415 int frameCount; 1416 1417 if (AudioSystem::getOutputFrameCount(&afFrameCount, mStreamType) != NO_ERROR) { 1418 return NO_INIT; 1419 } 1420 if (AudioSystem::getOutputSamplingRate(&afSampleRate, mStreamType) != NO_ERROR) { 1421 return NO_INIT; 1422 } 1423 1424 frameCount = (sampleRate*afFrameCount*bufferCount)/afSampleRate; 1425 1426 AudioTrack *t; 1427 if (mCallback != NULL) { 1428 t = new AudioTrack( 1429 mStreamType, 1430 sampleRate, 1431 format, 1432 (channelCount == 2) ? AudioSystem::CHANNEL_OUT_STEREO : AudioSystem::CHANNEL_OUT_MONO, 1433 frameCount, 1434 0 /* flags */, 1435 CallbackWrapper, 1436 this); 1437 } else { 1438 t = new AudioTrack( 1439 mStreamType, 1440 sampleRate, 1441 format, 1442 (channelCount == 2) ? AudioSystem::CHANNEL_OUT_STEREO : AudioSystem::CHANNEL_OUT_MONO, 1443 frameCount); 1444 } 1445 1446 if ((t == 0) || (t->initCheck() != NO_ERROR)) { 1447 LOGE("Unable to create audio track"); 1448 delete t; 1449 return NO_INIT; 1450 } 1451 1452 LOGV("setVolume"); 1453 t->setVolume(mLeftVolume, mRightVolume); 1454 mMsecsPerFrame = 1.e3 / (float) sampleRate; 1455 mLatency = t->latency() + kAudioVideoDelayMs; 1456 mTrack = t; 1457 return NO_ERROR; 1458} 1459 1460void MediaPlayerService::AudioOutput::start() 1461{ 1462 LOGV("start"); 1463 if (mTrack) { 1464 mTrack->setVolume(mLeftVolume, mRightVolume); 1465 mTrack->start(); 1466 mTrack->getPosition(&mNumFramesWritten); 1467 } 1468} 1469 1470ssize_t MediaPlayerService::AudioOutput::write(const void* buffer, size_t size) 1471{ 1472 LOG_FATAL_IF(mCallback != NULL, "Don't call write if supplying a callback."); 1473 1474 //LOGV("write(%p, %u)", buffer, size); 1475 if (mTrack) { 1476 // Only make visualization buffers if anyone recently requested visualization data 1477 uint64_t now = uptimeMillis(); 1478 if (lastReadTime + TOTALBUFTIMEMSEC >= now) { 1479 // Based on the current play counter, the number of frames written and 1480 // the current real time we can calculate the approximate real start 1481 // time of the buffer we're about to write. 1482 uint32_t pos; 1483 mTrack->getPosition(&pos); 1484 1485 // we're writing ahead by this many frames: 1486 int ahead = mNumFramesWritten - pos; 1487 //LOGI("@@@ written: %d, playpos: %d, latency: %d", mNumFramesWritten, pos, mTrack->latency()); 1488 // which is this many milliseconds, assuming 44100 Hz: 1489 ahead /= 44; 1490 1491 makeVizBuffers((const char*)buffer, size, now + ahead + mTrack->latency()); 1492 lastWriteTime = now; 1493 } 1494 ssize_t ret = mTrack->write(buffer, size); 1495 mNumFramesWritten += ret / 4; // assume 16 bit stereo 1496 return ret; 1497 } 1498 return NO_INIT; 1499} 1500 1501void MediaPlayerService::AudioOutput::stop() 1502{ 1503 LOGV("stop"); 1504 if (mTrack) mTrack->stop(); 1505 lastWriteTime = 0; 1506} 1507 1508void MediaPlayerService::AudioOutput::flush() 1509{ 1510 LOGV("flush"); 1511 if (mTrack) mTrack->flush(); 1512} 1513 1514void MediaPlayerService::AudioOutput::pause() 1515{ 1516 LOGV("pause"); 1517 if (mTrack) mTrack->pause(); 1518 lastWriteTime = 0; 1519} 1520 1521void MediaPlayerService::AudioOutput::close() 1522{ 1523 LOGV("close"); 1524 delete mTrack; 1525 mTrack = 0; 1526} 1527 1528void MediaPlayerService::AudioOutput::setVolume(float left, float right) 1529{ 1530 LOGV("setVolume(%f, %f)", left, right); 1531 mLeftVolume = left; 1532 mRightVolume = right; 1533 if (mTrack) { 1534 mTrack->setVolume(left, right); 1535 } 1536} 1537 1538// static 1539void MediaPlayerService::AudioOutput::CallbackWrapper( 1540 int event, void *cookie, void *info) { 1541 if (event != AudioTrack::EVENT_MORE_DATA) { 1542 return; 1543 } 1544 1545 AudioOutput *me = (AudioOutput *)cookie; 1546 AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info; 1547 1548 (*me->mCallback)( 1549 me, buffer->raw, buffer->size, me->mCallbackCookie); 1550} 1551 1552#undef LOG_TAG 1553#define LOG_TAG "AudioCache" 1554MediaPlayerService::AudioCache::AudioCache(const char* name) : 1555 mChannelCount(0), mFrameCount(1024), mSampleRate(0), mSize(0), 1556 mError(NO_ERROR), mCommandComplete(false) 1557{ 1558 // create ashmem heap 1559 mHeap = new MemoryHeapBase(kDefaultHeapSize, 0, name); 1560} 1561 1562uint32_t MediaPlayerService::AudioCache::latency () const 1563{ 1564 return 0; 1565} 1566 1567float MediaPlayerService::AudioCache::msecsPerFrame() const 1568{ 1569 return mMsecsPerFrame; 1570} 1571 1572status_t MediaPlayerService::AudioCache::open( 1573 uint32_t sampleRate, int channelCount, int format, int bufferCount, 1574 AudioCallback cb, void *cookie) 1575{ 1576 LOGV("open(%u, %d, %d, %d)", sampleRate, channelCount, format, bufferCount); 1577 if (cb != NULL) { 1578 return UNKNOWN_ERROR; // TODO: implement this. 1579 } 1580 if (mHeap->getHeapID() < 0) { 1581 return NO_INIT; 1582 } 1583 1584 mSampleRate = sampleRate; 1585 mChannelCount = (uint16_t)channelCount; 1586 mFormat = (uint16_t)format; 1587 mMsecsPerFrame = 1.e3 / (float) sampleRate; 1588 return NO_ERROR; 1589} 1590 1591ssize_t MediaPlayerService::AudioCache::write(const void* buffer, size_t size) 1592{ 1593 LOGV("write(%p, %u)", buffer, size); 1594 if ((buffer == 0) || (size == 0)) return size; 1595 1596 uint8_t* p = static_cast<uint8_t*>(mHeap->getBase()); 1597 if (p == NULL) return NO_INIT; 1598 p += mSize; 1599 LOGV("memcpy(%p, %p, %u)", p, buffer, size); 1600 if (mSize + size > mHeap->getSize()) { 1601 LOGE("Heap size overflow! req size: %d, max size: %d", (mSize + size), mHeap->getSize()); 1602 size = mHeap->getSize() - mSize; 1603 } 1604 memcpy(p, buffer, size); 1605 mSize += size; 1606 return size; 1607} 1608 1609// call with lock held 1610status_t MediaPlayerService::AudioCache::wait() 1611{ 1612 Mutex::Autolock lock(mLock); 1613 if (!mCommandComplete) { 1614 mSignal.wait(mLock); 1615 } 1616 mCommandComplete = false; 1617 1618 if (mError == NO_ERROR) { 1619 LOGV("wait - success"); 1620 } else { 1621 LOGV("wait - error"); 1622 } 1623 return mError; 1624} 1625 1626void MediaPlayerService::AudioCache::notify(void* cookie, int msg, int ext1, int ext2) 1627{ 1628 LOGV("notify(%p, %d, %d, %d)", cookie, msg, ext1, ext2); 1629 AudioCache* p = static_cast<AudioCache*>(cookie); 1630 1631 // ignore buffering messages 1632 switch (msg) 1633 { 1634 case MEDIA_ERROR: 1635 LOGE("Error %d, %d occurred", ext1, ext2); 1636 p->mError = ext1; 1637 break; 1638 case MEDIA_PREPARED: 1639 LOGV("prepared"); 1640 break; 1641 case MEDIA_PLAYBACK_COMPLETE: 1642 LOGV("playback complete"); 1643 break; 1644 default: 1645 LOGV("ignored"); 1646 return; 1647 } 1648 1649 // wake up thread 1650 p->mCommandComplete = true; 1651 p->mSignal.signal(); 1652} 1653 1654} // namespace android 1655