blob: fd5f0ed579175a1f99e4fcbbc04db1301e6c1f76 [file] [log] [blame]
The Android Open Source Project2729ea92008-10-21 07:00:00 -07001/*
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#include <cutils/atomic.h>
31
32#include <android_runtime/ActivityManager.h>
33#include <utils/IPCThreadState.h>
34#include <utils/IServiceManager.h>
35#include <utils/MemoryHeapBase.h>
36#include <utils/MemoryBase.h>
37
38#include <media/MediaPlayerInterface.h>
39#include <media/AudioTrack.h>
40
41#include "MediaPlayerService.h"
42#include "MidiFile.h"
43#include "VorbisPlayer.h"
44#include <media/PVPlayer.h>
45
46/* desktop Linux needs a little help with gettid() */
47#if defined(HAVE_GETTID) && !defined(HAVE_ANDROID_OS)
48#define __KERNEL__
49# include <linux/unistd.h>
50#ifdef _syscall0
51_syscall0(pid_t,gettid)
52#else
53pid_t gettid() { return syscall(__NR_gettid);}
54#endif
55#undef __KERNEL__
56#endif
57
58/*
59 When USE_SIGBUS_HANDLER is set to 1, a handler for SIGBUS will be
60 installed, which allows us to recover when there is a read error
61 when accessing an mmap'ed file. However, since the kernel folks
62 don't seem to like it when non kernel folks install signal handlers
63 in their own process, this is currently disabled.
64 Without the handler, the process hosting this service will die and
65 then be restarted. This is mostly OK right now because the process is
66 not being shared with any other services, and clients of the service
67 will be notified of its death in their MediaPlayer.onErrorListener
68 callback, assuming they have installed one, and can then attempt to
69 do their own recovery.
70 It does open us up to a DOS attack against the media server, where
71 a malicious application can trivially force the media server to
72 restart continuously.
73*/
74#define USE_SIGBUS_HANDLER 0
75
76// TODO: Temp hack until we can register players
77static const char* MIDI_FILE_EXTS[] =
78{
79 ".mid",
80 ".smf",
81 ".xmf",
82 ".imy",
83 ".rtttl",
84 ".rtx",
85 ".ota"
86};
87
88namespace android {
89
90// TODO: should come from audio driver
91/* static */ const uint32_t MediaPlayerService::AudioOutput::kDriverLatencyInMsecs = 150;
92
93static struct sigaction oldact;
94static pthread_key_t sigbuskey;
95
96static void sigbushandler(int signal, siginfo_t *info, void *context)
97{
98 char *faultaddr = (char*) info->si_addr;
99 LOGE("SIGBUS at %p\n", faultaddr);
100
101 struct mediasigbushandler* h = (struct mediasigbushandler*) pthread_getspecific(sigbuskey);
102
103 if (h) {
104 if (h->len) {
105 if (faultaddr < h->base || faultaddr >= h->base + h->len) {
106 // outside specified range, call old handler
107 if (oldact.sa_flags & SA_SIGINFO) {
108 oldact.sa_sigaction(signal, info, context);
109 } else {
110 oldact.sa_handler(signal);
111 }
112 return;
113 }
114 }
115
116 // no range specified or address was in range
117
118 if (h->handlesigbus) {
119 if (h->handlesigbus(info, h)) {
120 // thread's handler didn't handle the signal
121 if (oldact.sa_flags & SA_SIGINFO) {
122 oldact.sa_sigaction(signal, info, context);
123 } else {
124 oldact.sa_handler(signal);
125 }
126 }
127 return;
128 }
129
130 if (h->sigbusvar) {
131 // map in a zeroed out page so the operation can succeed
132 long pagesize = sysconf(_SC_PAGE_SIZE);
133 long pagemask = ~(pagesize - 1);
134 void * pageaddr = (void*) (((long)(faultaddr)) & pagemask);
135
136 void * bar = mmap( pageaddr, pagesize, PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE|MAP_FIXED, -1, 0);
137 if (bar == MAP_FAILED) {
138 LOGE("couldn't map zero page at %p: %s", pageaddr, strerror(errno));
139 if (oldact.sa_flags & SA_SIGINFO) {
140 oldact.sa_sigaction(signal, info, context);
141 } else {
142 oldact.sa_handler(signal);
143 }
144 return;
145 }
146
147 LOGE("setting sigbusvar at %p", h->sigbusvar);
148 *(h->sigbusvar) = 1;
149 return;
150 }
151 }
152
153 LOGE("SIGBUS: no handler, or improperly configured handler (%p)", h);
154
155 if (oldact.sa_flags & SA_SIGINFO) {
156 oldact.sa_sigaction(signal, info, context);
157 } else {
158 oldact.sa_handler(signal);
159 }
160 return;
161}
162
163void MediaPlayerService::instantiate() {
164 defaultServiceManager()->addService(
165 String16("media.player"), new MediaPlayerService());
166}
167
168MediaPlayerService::MediaPlayerService()
169{
170 LOGV("MediaPlayerService created");
171 mNextConnId = 1;
172
173 pthread_key_create(&sigbuskey, NULL);
174
175
176#if USE_SIGBUS_HANDLER
177 struct sigaction act;
178 memset(&act,0, sizeof act);
179 act.sa_sigaction = sigbushandler;
180 act.sa_flags = SA_SIGINFO;
181 sigaction(SIGBUS, &act, &oldact);
182#endif
183}
184
185MediaPlayerService::~MediaPlayerService()
186{
187#if USE_SIGBUS_HANDLER
188 sigaction(SIGBUS, &oldact, NULL);
189#endif
190 pthread_key_delete(sigbuskey);
191 LOGV("MediaPlayerService destroyed");
192}
193
194sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClient>& client, const char* url)
195{
196 int32_t connId = android_atomic_inc(&mNextConnId);
197 sp<Client> c = new Client(this, pid, connId, client);
198 LOGV("Create new client(%d) from pid %d, url=%s, connId=%d", connId, pid, url, connId);
199 if (NO_ERROR != c->setDataSource(url))
200 {
201 c.clear();
202 return c;
203 }
204 wp<Client> w = c;
205 Mutex::Autolock lock(mLock);
206 mClients.add(w);
207 return c;
208}
209
210sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClient>& client,
211 int fd, int64_t offset, int64_t length)
212{
213 int32_t connId = android_atomic_inc(&mNextConnId);
214 sp<Client> c = new Client(this, pid, connId, client);
215 LOGV("Create new client(%d) from pid %d, fd=%d, offset=%lld, length=%lld",
216 connId, pid, fd, offset, length);
217 if (NO_ERROR != c->setDataSource(fd, offset, length)) {
218 c.clear();
219 } else {
220 wp<Client> w = c;
221 Mutex::Autolock lock(mLock);
222 mClients.add(w);
223 }
224 ::close(fd);
225 return c;
226}
227
228status_t MediaPlayerService::AudioCache::dump(int fd, const Vector<String16>& args) const
229{
230 const size_t SIZE = 256;
231 char buffer[SIZE];
232 String8 result;
233
234 result.append(" AudioCache\n");
235 if (mHeap != 0) {
236 snprintf(buffer, 255, " heap base(%p), size(%d), flags(%d), device(%s)\n",
237 mHeap->getBase(), mHeap->getSize(), mHeap->getFlags(), mHeap->getDevice());
238 result.append(buffer);
239 }
240 snprintf(buffer, 255, " msec per frame(%f), channel count(%ld), frame count(%ld)\n",
241 mMsecsPerFrame, mChannelCount, mFrameCount);
242 result.append(buffer);
243 snprintf(buffer, 255, " sample rate(%d), size(%d), error(%d), command complete(%s)\n",
244 mSampleRate, mSize, mError, mCommandComplete?"true":"false");
245 result.append(buffer);
246 ::write(fd, result.string(), result.size());
247 return NO_ERROR;
248}
249
250status_t MediaPlayerService::AudioOutput::dump(int fd, const Vector<String16>& args) const
251{
252 const size_t SIZE = 256;
253 char buffer[SIZE];
254 String8 result;
255
256 result.append(" AudioOutput\n");
257 snprintf(buffer, 255, " stream type(%d), left - right volume(%f, %f)\n",
258 mStreamType, mLeftVolume, mRightVolume);
259 result.append(buffer);
260 snprintf(buffer, 255, " msec per frame(%f), latency (%d), driver latency(%d)\n",
261 mMsecsPerFrame, mLatency, kDriverLatencyInMsecs);
262 result.append(buffer);
263 ::write(fd, result.string(), result.size());
264 if (mTrack != 0) {
265 mTrack->dump(fd, args);
266 }
267 return NO_ERROR;
268}
269
270status_t MediaPlayerService::Client::dump(int fd, const Vector<String16>& args) const
271{
272 const size_t SIZE = 256;
273 char buffer[SIZE];
274 String8 result;
275 result.append(" Client\n");
276 snprintf(buffer, 255, " pid(%d), connId(%d), status(%d), looping(%s)\n",
277 mPid, mConnId, mStatus, mLoop?"true": "false");
278 result.append(buffer);
279 write(fd, result.string(), result.size());
280 if (mAudioOutput != 0) {
281 mAudioOutput->dump(fd, args);
282 }
283 write(fd, "\n", 1);
284 return NO_ERROR;
285}
286
287static int myTid() {
288#ifdef HAVE_GETTID
289 return gettid();
290#else
291 return getpid();
292#endif
293}
294
295status_t MediaPlayerService::dump(int fd, const Vector<String16>& args)
296{
297 const size_t SIZE = 256;
298 char buffer[SIZE];
299 String8 result;
300 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
301 snprintf(buffer, SIZE, "Permission Denial: "
302 "can't dump MediaPlayerService from pid=%d, uid=%d\n",
303 IPCThreadState::self()->getCallingPid(),
304 IPCThreadState::self()->getCallingUid());
305 result.append(buffer);
306 } else {
307 Mutex::Autolock lock(mLock);
308 for (int i = 0, n = mClients.size(); i < n; ++i) {
309 sp<Client> c = mClients[i].promote();
310 if (c != 0) c->dump(fd, args);
311 }
312 result.append(" Files opened and/or mapped:\n");
313 snprintf(buffer, SIZE, "/proc/%d/maps", myTid());
314 FILE *f = fopen(buffer, "r");
315 if (f) {
316 while (!feof(f)) {
317 fgets(buffer, SIZE, f);
318 if (strstr(buffer, " /sdcard/") ||
319 strstr(buffer, " /system/sounds/") ||
320 strstr(buffer, " /system/media/")) {
321 result.append(" ");
322 result.append(buffer);
323 }
324 }
325 fclose(f);
326 } else {
327 result.append("couldn't open ");
328 result.append(buffer);
329 result.append("\n");
330 }
331
332 snprintf(buffer, SIZE, "/proc/%d/fd", myTid());
333 DIR *d = opendir(buffer);
334 if (d) {
335 struct dirent *ent;
336 while((ent = readdir(d)) != NULL) {
337 if (strcmp(ent->d_name,".") && strcmp(ent->d_name,"..")) {
338 snprintf(buffer, SIZE, "/proc/%d/fd/%s", myTid(), ent->d_name);
339 struct stat s;
340 if (lstat(buffer, &s) == 0) {
341 if ((s.st_mode & S_IFMT) == S_IFLNK) {
342 char linkto[256];
343 int len = readlink(buffer, linkto, sizeof(linkto));
344 if(len > 0) {
345 if(len > 255) {
346 linkto[252] = '.';
347 linkto[253] = '.';
348 linkto[254] = '.';
349 linkto[255] = 0;
350 } else {
351 linkto[len] = 0;
352 }
353 if (strstr(linkto, "/sdcard/") == linkto ||
354 strstr(linkto, "/system/sounds/") == linkto ||
355 strstr(linkto, "/system/media/") == linkto) {
356 result.append(" ");
357 result.append(buffer);
358 result.append(" -> ");
359 result.append(linkto);
360 result.append("\n");
361 }
362 }
363 } else {
364 result.append(" unexpected type for ");
365 result.append(buffer);
366 result.append("\n");
367 }
368 }
369 }
370 }
371 closedir(d);
372 } else {
373 result.append("couldn't open ");
374 result.append(buffer);
375 result.append("\n");
376 }
377 }
378 write(fd, result.string(), result.size());
379 return NO_ERROR;
380}
381
382void MediaPlayerService::removeClient(wp<Client> client)
383{
384 Mutex::Autolock lock(mLock);
385 mClients.remove(client);
386}
387
388MediaPlayerService::Client::Client(const sp<MediaPlayerService>& service, pid_t pid,
389 int32_t connId, const sp<IMediaPlayerClient>& client)
390{
391 LOGV("Client(%d) constructor", connId);
392 mPid = pid;
393 mConnId = connId;
394 mService = service;
395 mClient = client;
396 mLoop = false;
397 mStatus = NO_INIT;
398#if CALLBACK_ANTAGONIZER
399 LOGD("create Antagonizer");
400 mAntagonizer = new Antagonizer(notify, this);
401#endif
402}
403
404MediaPlayerService::Client::~Client()
405{
406 LOGV("Client(%d) destructor pid = %d", mConnId, mPid);
407 mAudioOutput.clear();
408 wp<Client> client(this);
409 disconnect();
410 mService->removeClient(client);
411}
412
413void MediaPlayerService::Client::disconnect()
414{
415 LOGV("disconnect(%d) from pid %d", mConnId, mPid);
416 // grab local reference and clear main reference to prevent future
417 // access to object
418 sp<MediaPlayerBase> p;
419 {
420 Mutex::Autolock l(mLock);
421 p = mPlayer;
422 }
423 mPlayer.clear();
424
425 // clear the notification to prevent callbacks to dead client
426 // and reset the player. We assume the player will serialize
427 // access to itself if necessary.
428 if (p != 0) {
429 p->setNotifyCallback(0, 0);
430#if CALLBACK_ANTAGONIZER
431 LOGD("kill Antagonizer");
432 mAntagonizer->kill();
433#endif
434 p->reset();
435 }
436
437 IPCThreadState::self()->flushCommands();
438}
439
440static player_type getPlayerType(int fd, int64_t offset, int64_t length)
441{
442 char buf[20];
443 lseek(fd, offset, SEEK_SET);
444 read(fd, buf, sizeof(buf));
445 lseek(fd, offset, SEEK_SET);
446
447 long ident = *((long*)buf);
448
449 // Ogg vorbis?
450 if (ident == 0x5367674f) // 'OggS'
451 return VORBIS_PLAYER;
452
453 // Some kind of MIDI?
454 EAS_DATA_HANDLE easdata;
455 if (EAS_Init(&easdata) == EAS_SUCCESS) {
456 EAS_FILE locator;
457 locator.path = NULL;
458 locator.fd = fd;
459 locator.offset = offset;
460 locator.length = length;
461 EAS_HANDLE eashandle;
462 if (EAS_OpenFile(easdata, &locator, &eashandle, NULL) == EAS_SUCCESS) {
463 EAS_CloseFile(easdata, eashandle);
464 EAS_Shutdown(easdata);
465 return SONIVOX_PLAYER;
466 }
467 EAS_Shutdown(easdata);
468 }
469
470 // Fall through to PV
471 return PV_PLAYER;
472}
473
474static player_type getPlayerType(const char* url)
475{
476
477 // use MidiFile for MIDI extensions
478 int lenURL = strlen(url);
479 for (int i = 0; i < NELEM(MIDI_FILE_EXTS); ++i) {
480 int len = strlen(MIDI_FILE_EXTS[i]);
481 int start = lenURL - len;
482 if (start > 0) {
483 if (!strncmp(url + start, MIDI_FILE_EXTS[i], len)) {
484 LOGV("Type is MIDI");
485 return SONIVOX_PLAYER;
486 }
487 }
488 }
489
490 if (strcmp(url + strlen(url) - 4, ".ogg") == 0) {
491 LOGV("Type is Vorbis");
492 return VORBIS_PLAYER;
493 }
494
495 // Fall through to PV
496 return PV_PLAYER;
497}
498
499static sp<MediaPlayerBase> createPlayer(player_type playerType, void* cookie,
500 notify_callback_f notifyFunc)
501{
502 sp<MediaPlayerBase> p;
503 switch (playerType) {
504 case PV_PLAYER:
505 LOGV(" create PVPlayer");
506 p = new PVPlayer();
507 break;
508 case SONIVOX_PLAYER:
509 LOGV(" create MidiFile");
510 p = new MidiFile();
511 break;
512 case VORBIS_PLAYER:
513 LOGV(" create VorbisPlayer");
514 p = new VorbisPlayer();
515 break;
516 }
517 if (p != NULL) {
518 if (p->initCheck() == NO_ERROR) {
519 p->setNotifyCallback(cookie, notifyFunc);
520 p->setSigBusHandlerStructTLSKey(sigbuskey);
521 } else {
522 p.clear();
523 }
524 }
525 if (p == NULL) {
526 LOGE("Failed to create player object");
527 }
528 return p;
529}
530
531sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerType)
532{
533 // determine if we have the right player type
534 sp<MediaPlayerBase> p = mPlayer;
535 if ((p != NULL) && (p->playerType() != playerType)) {
536 LOGV("delete player");
537 p.clear();
538 }
539 if (p == NULL) {
540 p = android::createPlayer(playerType, this, notify);
541 }
542 return p;
543}
544
545status_t MediaPlayerService::Client::setDataSource(const char *url)
546{
547 LOGV("setDataSource(%s)", url);
548 if (url == NULL)
549 return UNKNOWN_ERROR;
550
551 if (strncmp(url, "content://", 10) == 0) {
552 // get a filedescriptor for the content Uri and
553 // pass it to the setDataSource(fd) method
554
555 String16 url16(url);
556 int fd = android::openContentProviderFile(url16);
557 if (fd < 0)
558 {
559 LOGE("Couldn't open fd for %s", url);
560 return UNKNOWN_ERROR;
561 }
562 setDataSource(fd, 0, 0x7fffffffffLL); // this sets mStatus
563 close(fd);
564 return mStatus;
565 } else {
566 player_type playerType = getPlayerType(url);
567 LOGV("player type = %d", playerType);
568
569 // create the right type of player
570 sp<MediaPlayerBase> p = createPlayer(playerType);
571 if (p == NULL) return NO_INIT;
572
573 if (!p->hardwareOutput()) {
574 mAudioOutput = new AudioOutput();
575 static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);
576 }
577
578 // now set data source
579 LOGV(" setDataSource");
580 mStatus = p->setDataSource(url);
581 if (mStatus == NO_ERROR) mPlayer = p;
582 return mStatus;
583 }
584}
585
586status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64_t length)
587{
588 LOGV("setDataSource fd=%d, offset=%lld, length=%lld", fd, offset, length);
589 struct stat sb;
590 int ret = fstat(fd, &sb);
591 if (ret != 0) {
592 LOGE("fstat(%d) failed: %d, %s", fd, ret, strerror(errno));
593 return UNKNOWN_ERROR;
594 }
595
596 LOGV("st_dev = %llu", sb.st_dev);
597 LOGV("st_mode = %u", sb.st_mode);
598 LOGV("st_uid = %lu", sb.st_uid);
599 LOGV("st_gid = %lu", sb.st_gid);
600 LOGV("st_size = %llu", sb.st_size);
601
602 if (offset >= sb.st_size) {
603 LOGE("offset error");
604 ::close(fd);
605 return UNKNOWN_ERROR;
606 }
607 if (offset + length > sb.st_size) {
608 length = sb.st_size - offset;
609 LOGV("calculated length = %lld", length);
610 }
611
612 player_type playerType = getPlayerType(fd, offset, length);
613 LOGV("player type = %d", playerType);
614
615 // create the right type of player
616 sp<MediaPlayerBase> p = createPlayer(playerType);
617 if (p == NULL) return NO_INIT;
618
619 if (!p->hardwareOutput()) {
620 mAudioOutput = new AudioOutput();
621 static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);
622 }
623
624 // now set data source
625 mStatus = p->setDataSource(fd, offset, length);
626 if (mStatus == NO_ERROR) mPlayer = p;
627 return mStatus;
628}
629
630status_t MediaPlayerService::Client::setVideoSurface(const sp<ISurface>& surface)
631{
632 LOGV("[%d] setVideoSurface(%p)", mConnId, surface.get());
633 sp<MediaPlayerBase> p = getPlayer();
634 if (p == 0) return UNKNOWN_ERROR;
635 return p->setVideoSurface(surface);
636}
637
638status_t MediaPlayerService::Client::prepareAsync()
639{
640 LOGV("[%d] prepareAsync", mConnId);
641 sp<MediaPlayerBase> p = getPlayer();
642 if (p == 0) return UNKNOWN_ERROR;
643 status_t ret = p->prepareAsync();
644#if CALLBACK_ANTAGONIZER
645 LOGD("start Antagonizer");
646 if (ret == NO_ERROR) mAntagonizer->start();
647#endif
648 return ret;
649}
650
651status_t MediaPlayerService::Client::start()
652{
653 LOGV("[%d] start", mConnId);
654 sp<MediaPlayerBase> p = getPlayer();
655 if (p == 0) return UNKNOWN_ERROR;
656 p->setLooping(mLoop);
657 return p->start();
658}
659
660status_t MediaPlayerService::Client::stop()
661{
662 LOGV("[%d] stop", mConnId);
663 sp<MediaPlayerBase> p = getPlayer();
664 if (p == 0) return UNKNOWN_ERROR;
665 return p->stop();
666}
667
668status_t MediaPlayerService::Client::pause()
669{
670 LOGV("[%d] pause", mConnId);
671 sp<MediaPlayerBase> p = getPlayer();
672 if (p == 0) return UNKNOWN_ERROR;
673 return p->pause();
674}
675
676status_t MediaPlayerService::Client::isPlaying(bool* state)
677{
678 *state = false;
679 sp<MediaPlayerBase> p = getPlayer();
680 if (p == 0) return UNKNOWN_ERROR;
681 *state = p->isPlaying();
682 LOGV("[%d] isPlaying: %d", mConnId, *state);
683 return NO_ERROR;
684}
685
686status_t MediaPlayerService::Client::getVideoSize(int *w, int *h)
687{
688 sp<MediaPlayerBase> p = getPlayer();
689 if (p == 0) return UNKNOWN_ERROR;
690 status_t ret = p->getVideoWidth(w);
691 if (ret == NO_ERROR) ret = p->getVideoHeight(h);
692 if (ret == NO_ERROR) {
693 LOGV("[%d] getVideoWidth = (%d, %d)", mConnId, *w, *h);
694 } else {
695 LOGE("getVideoSize returned %d", ret);
696 }
697 return ret;
698}
699
700status_t MediaPlayerService::Client::getCurrentPosition(int *msec)
701{
702 LOGV("getCurrentPosition");
703 sp<MediaPlayerBase> p = getPlayer();
704 if (p == 0) return UNKNOWN_ERROR;
705 status_t ret = p->getCurrentPosition(msec);
706 if (ret == NO_ERROR) {
707 LOGV("[%d] getCurrentPosition = %d", mConnId, *msec);
708 } else {
709 LOGE("getCurrentPosition returned %d", ret);
710 }
711 return ret;
712}
713
714status_t MediaPlayerService::Client::getDuration(int *msec)
715{
716 LOGV("getDuration");
717 sp<MediaPlayerBase> p = getPlayer();
718 if (p == 0) return UNKNOWN_ERROR;
719 status_t ret = p->getDuration(msec);
720 if (ret == NO_ERROR) {
721 LOGV("[%d] getDuration = %d", mConnId, *msec);
722 } else {
723 LOGE("getDuration returned %d", ret);
724 }
725 return ret;
726}
727
728status_t MediaPlayerService::Client::seekTo(int msec)
729{
730 LOGV("[%d] seekTo(%d)", mConnId, msec);
731 sp<MediaPlayerBase> p = getPlayer();
732 if (p == 0) return UNKNOWN_ERROR;
733 return p->seekTo(msec);
734}
735
736status_t MediaPlayerService::Client::reset()
737{
738 LOGV("[%d] reset", mConnId);
739 sp<MediaPlayerBase> p = getPlayer();
740 if (p == 0) return UNKNOWN_ERROR;
741 return p->reset();
742}
743
744status_t MediaPlayerService::Client::setAudioStreamType(int type)
745{
746 LOGV("[%d] setAudioStreamType(%d)", mConnId, type);
747 // TODO: for hardware output, call player instead
748 Mutex::Autolock l(mLock);
749 if (mAudioOutput != 0) mAudioOutput->setAudioStreamType(type);
750 return NO_ERROR;
751}
752
753status_t MediaPlayerService::Client::setLooping(int loop)
754{
755 LOGV("[%d] setLooping(%d)", mConnId, loop);
756 mLoop = loop;
757 sp<MediaPlayerBase> p = getPlayer();
758 if (p != 0) return p->setLooping(loop);
759 return NO_ERROR;
760}
761
762status_t MediaPlayerService::Client::setVolume(float leftVolume, float rightVolume)
763{
764 LOGV("[%d] setVolume(%f, %f)", mConnId, leftVolume, rightVolume);
765 // TODO: for hardware output, call player instead
766 Mutex::Autolock l(mLock);
767 if (mAudioOutput != 0) mAudioOutput->setVolume(leftVolume, rightVolume);
768 return NO_ERROR;
769}
770
771void MediaPlayerService::Client::notify(void* cookie, int msg, int ext1, int ext2)
772{
773 Client* client = static_cast<Client*>(cookie);
774 LOGV("[%d] notify (%p, %d, %d, %d)", client->mConnId, cookie, msg, ext1, ext2);
775 client->mClient->notify(msg, ext1, ext2);
776}
777
778#if CALLBACK_ANTAGONIZER
779const int Antagonizer::interval = 10000; // 10 msecs
780
781Antagonizer::Antagonizer(notify_callback_f cb, void* client) :
782 mExit(false), mActive(false), mClient(client), mCb(cb)
783{
784 createThread(callbackThread, this);
785}
786
787void Antagonizer::kill()
788{
789 Mutex::Autolock _l(mLock);
790 mActive = false;
791 mExit = true;
792 mCondition.wait(mLock);
793}
794
795int Antagonizer::callbackThread(void* user)
796{
797 LOGD("Antagonizer started");
798 Antagonizer* p = reinterpret_cast<Antagonizer*>(user);
799 while (!p->mExit) {
800 if (p->mActive) {
801 LOGV("send event");
802 p->mCb(p->mClient, 0, 0, 0);
803 }
804 usleep(interval);
805 }
806 Mutex::Autolock _l(p->mLock);
807 p->mCondition.signal();
808 LOGD("Antagonizer stopped");
809 return 0;
810}
811#endif
812
813static size_t kDefaultHeapSize = 1024 * 1024; // 1MB
814
815sp<IMemory> MediaPlayerService::decode(const char* url, uint32_t *pSampleRate, int* pNumChannels)
816{
817 LOGV("decode(%s)", url);
818 sp<MemoryBase> mem;
819 sp<MediaPlayerBase> player;
820
821 // Protect our precious, precious DRMd ringtones by only allowing
822 // decoding of http, but not filesystem paths or content Uris.
823 // If the application wants to decode those, it should open a
824 // filedescriptor for them and use that.
825 if (url != NULL && strncmp(url, "http://", 7) != 0) {
826 LOGD("Can't decode %s by path, use filedescriptor instead", url);
827 return mem;
828 }
829
830 player_type playerType = getPlayerType(url);
831 LOGV("player type = %d", playerType);
832
833 // create the right type of player
834 sp<AudioCache> cache = new AudioCache(url);
835 player = android::createPlayer(playerType, cache.get(), cache->notify);
836 if (player == NULL) goto Exit;
837 if (player->hardwareOutput()) goto Exit;
838
839 static_cast<MediaPlayerInterface*>(player.get())->setAudioSink(cache);
840
841 // set data source
842 if (player->setDataSource(url) != NO_ERROR) goto Exit;
843
844 LOGV("prepare");
845 player->prepareAsync();
846
847 LOGV("wait for prepare");
848 if (cache->wait() != NO_ERROR) goto Exit;
849
850 LOGV("start");
851 player->start();
852
853 LOGV("wait for playback complete");
854 if (cache->wait() != NO_ERROR) goto Exit;
855
856 mem = new MemoryBase(cache->getHeap(), 0, cache->size());
857 *pSampleRate = cache->sampleRate();
858 *pNumChannels = cache->channelCount();
859 LOGV("return memory @ %p, sampleRate=%u, channelCount = %d", mem->pointer(), *pSampleRate, *pNumChannels);
860
861Exit:
862 if (player != 0) player->reset();
863 return mem;
864}
865
866sp<IMemory> MediaPlayerService::decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels)
867{
868 LOGV("decode(%d, %lld, %lld)", fd, offset, length);
869 sp<MemoryBase> mem;
870 sp<MediaPlayerBase> player;
871
872 player_type playerType = getPlayerType(fd, offset, length);
873 LOGV("player type = %d", playerType);
874
875 // create the right type of player
876 sp<AudioCache> cache = new AudioCache("decode_fd");
877 player = android::createPlayer(playerType, cache.get(), cache->notify);
878 if (player == NULL) goto Exit;
879 if (player->hardwareOutput()) goto Exit;
880
881 static_cast<MediaPlayerInterface*>(player.get())->setAudioSink(cache);
882
883 // set data source
884 if (player->setDataSource(fd, offset, length) != NO_ERROR) goto Exit;
885
886 LOGV("prepare");
887 player->prepareAsync();
888
889 LOGV("wait for prepare");
890 if (cache->wait() != NO_ERROR) goto Exit;
891
892 LOGV("start");
893 player->start();
894
895 LOGV("wait for playback complete");
896 if (cache->wait() != NO_ERROR) goto Exit;
897
898 mem = new MemoryBase(cache->getHeap(), 0, cache->size());
899 *pSampleRate = cache->sampleRate();
900 *pNumChannels = cache->channelCount();
901 LOGV("return memory @ %p, sampleRate=%u, channelCount = %d", mem->pointer(), *pSampleRate, *pNumChannels);
902
903Exit:
904 if (player != 0) player->reset();
905 ::close(fd);
906 return mem;
907}
908
909#undef LOG_TAG
910#define LOG_TAG "AudioSink"
911MediaPlayerService::AudioOutput::AudioOutput()
912{
913 mTrack = 0;
914 mStreamType = AudioTrack::MUSIC;
915 mLeftVolume = 1.0;
916 mRightVolume = 1.0;
917 mLatency = 0;
918 mMsecsPerFrame = 0;
919}
920
921MediaPlayerService::AudioOutput::~AudioOutput()
922{
923 close();
924}
925
926ssize_t MediaPlayerService::AudioOutput::bufferSize() const
927{
928 if (mTrack == 0) return NO_INIT;
929 return mTrack->frameCount() * mTrack->channelCount() * sizeof(int16_t);
930}
931
932ssize_t MediaPlayerService::AudioOutput::frameCount() const
933{
934 if (mTrack == 0) return NO_INIT;
935 return mTrack->frameCount();
936}
937
938ssize_t MediaPlayerService::AudioOutput::channelCount() const
939{
940 if (mTrack == 0) return NO_INIT;
941 return mTrack->channelCount();
942}
943
944ssize_t MediaPlayerService::AudioOutput::frameSize() const
945{
946 if (mTrack == 0) return NO_INIT;
947 return mTrack->channelCount() * sizeof(int16_t);
948}
949
950uint32_t MediaPlayerService::AudioOutput::latency () const
951{
952 return mLatency;
953}
954
955float MediaPlayerService::AudioOutput::msecsPerFrame() const
956{
957 return mMsecsPerFrame;
958}
959
960status_t MediaPlayerService::AudioOutput::open(uint32_t sampleRate, int channelCount, int bufferCount)
961{
962 LOGV("open(%u, %d, %d)", sampleRate, channelCount, bufferCount);
963 if (mTrack) close();
964
965 AudioTrack *t = new AudioTrack(mStreamType, sampleRate, AudioSystem::PCM_16_BIT, channelCount, bufferCount);
966 if ((t == 0) || (t->initCheck() != NO_ERROR)) {
967 LOGE("Unable to create audio track");
968 delete t;
969 return NO_INIT;
970 }
971
972 LOGV("setVolume");
973 t->setVolume(mLeftVolume, mRightVolume);
974 mMsecsPerFrame = 1.e3 / (float) sampleRate;
975 mLatency = (mMsecsPerFrame * bufferCount * t->frameCount()) + kDriverLatencyInMsecs;
976 mTrack = t;
977 return NO_ERROR;
978}
979
980void MediaPlayerService::AudioOutput::start()
981{
982 LOGV("start");
983 if (mTrack) {
984 mTrack->setVolume(mLeftVolume, mRightVolume);
985 mTrack->start();
986 }
987}
988
989ssize_t MediaPlayerService::AudioOutput::write(const void* buffer, size_t size)
990{
991 //LOGV("write(%p, %u)", buffer, size);
992 if (mTrack) return mTrack->write(buffer, size);
993 return NO_INIT;
994}
995
996void MediaPlayerService::AudioOutput::stop()
997{
998 LOGV("stop");
999 if (mTrack) mTrack->stop();
1000}
1001
1002void MediaPlayerService::AudioOutput::flush()
1003{
1004 LOGV("flush");
1005 if (mTrack) mTrack->flush();
1006}
1007
1008void MediaPlayerService::AudioOutput::pause()
1009{
1010 LOGV("pause");
1011 if (mTrack) mTrack->pause();
1012}
1013
1014void MediaPlayerService::AudioOutput::close()
1015{
1016 LOGV("close");
1017 delete mTrack;
1018 mTrack = 0;
1019}
1020
1021void MediaPlayerService::AudioOutput::setVolume(float left, float right)
1022{
1023 LOGV("setVolume(%f, %f)", left, right);
1024 mLeftVolume = left;
1025 mRightVolume = right;
1026 if (mTrack) {
1027 mTrack->setVolume(left, right);
1028 }
1029}
1030
1031#undef LOG_TAG
1032#define LOG_TAG "AudioCache"
1033MediaPlayerService::AudioCache::AudioCache(const char* name) :
1034 mChannelCount(0), mFrameCount(0), mSampleRate(0), mSize(0),
1035 mError(NO_ERROR), mCommandComplete(false)
1036{
1037 // create ashmem heap
1038 mHeap = new MemoryHeapBase(kDefaultHeapSize, 0, name);
1039}
1040
1041uint32_t MediaPlayerService::AudioCache::latency () const
1042{
1043 return 0;
1044}
1045
1046float MediaPlayerService::AudioCache::msecsPerFrame() const
1047{
1048 return mMsecsPerFrame;
1049}
1050
1051status_t MediaPlayerService::AudioCache::open(uint32_t sampleRate, int channelCount, int bufferCount)
1052{
1053 LOGV("open(%u, %d, %d)", sampleRate, channelCount, bufferCount);
1054 if (mHeap->getHeapID() < 0) return NO_INIT;
1055 mSampleRate = sampleRate;
1056 mChannelCount = channelCount;
1057 mMsecsPerFrame = 1.e3 / (float) sampleRate;
1058 return NO_ERROR;
1059}
1060
1061ssize_t MediaPlayerService::AudioCache::write(const void* buffer, size_t size)
1062{
1063 LOGV("write(%p, %u)", buffer, size);
1064 if ((buffer == 0) || (size == 0)) return size;
1065
1066 uint8_t* p = static_cast<uint8_t*>(mHeap->getBase());
1067 if (p == NULL) return NO_INIT;
1068 p += mSize;
1069 LOGV("memcpy(%p, %p, %u)", p, buffer, size);
1070 memcpy(p, buffer, size);
1071 mSize += size;
1072 return size;
1073}
1074
1075// call with lock held
1076status_t MediaPlayerService::AudioCache::wait()
1077{
1078 Mutex::Autolock lock(mLock);
1079 if (!mCommandComplete) {
1080 mSignal.wait(mLock);
1081 }
1082 mCommandComplete = false;
1083
1084 if (mError == NO_ERROR) {
1085 LOGV("wait - success");
1086 } else {
1087 LOGV("wait - error");
1088 }
1089 return mError;
1090}
1091
1092void MediaPlayerService::AudioCache::notify(void* cookie, int msg, int ext1, int ext2)
1093{
1094 LOGV("notify(%p, %d, %d, %d)", cookie, msg, ext1, ext2);
1095 AudioCache* p = static_cast<AudioCache*>(cookie);
1096
1097 // ignore buffering messages
1098 if (msg == MEDIA_BUFFERING_UPDATE) return;
1099
1100 // set error condition
1101 if (msg == MEDIA_ERROR) {
1102 LOGE("Error %d, %d occurred", ext1, ext2);
1103 p->mError = ext1;
1104 }
1105
1106 // wake up thread
1107 LOGV("wakeup thread");
1108 p->mCommandComplete = true;
1109 p->mSignal.signal();
1110}
1111
1112}; // namespace android