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