diff options
Diffstat (limited to 'media/libmediaplayerservice')
-rw-r--r-- | media/libmediaplayerservice/Android.mk | 15 | ||||
-rw-r--r-- | media/libmediaplayerservice/MediaPlayerService.cpp | 88 | ||||
-rw-r--r-- | media/libmediaplayerservice/MediaPlayerService.h | 20 | ||||
-rw-r--r-- | media/libmediaplayerservice/StagefrightPlayer.cpp | 208 | ||||
-rw-r--r-- | media/libmediaplayerservice/StagefrightPlayer.h | 60 |
5 files changed, 383 insertions, 8 deletions
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk index 0877142..6978b3d 100644 --- a/media/libmediaplayerservice/Android.mk +++ b/media/libmediaplayerservice/Android.mk @@ -29,9 +29,22 @@ LOCAL_SHARED_LIBRARIES := \ libandroid_runtime LOCAL_C_INCLUDES := external/tremor/Tremor \ - $(call include-path-for, graphics corecg) + $(call include-path-for, graphics corecg) \ + $(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include LOCAL_MODULE:= libmediaplayerservice +ifeq ($(BUILD_WITH_STAGEFRIGHT),true) + LOCAL_SRC_FILES += StagefrightPlayer.cpp + + LOCAL_SHARED_LIBRARIES += \ + libstagefright \ + libstagefright_omx + + LOCAL_C_INCLUDES += $(TOP)/frameworks/base/media/libstagefright/omx + + LOCAL_CFLAGS += -DBUILD_WITH_STAGEFRIGHT -DUSE_STAGEFRIGHT +endif + include $(BUILD_SHARED_LIBRARY) diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index 493dc13..c575f6c 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -58,6 +58,15 @@ #include "MidiFile.h" #include "VorbisPlayer.h" #include <media/PVPlayer.h> +#if USE_STAGEFRIGHT +#include "StagefrightPlayer.h" +#endif + +#ifdef BUILD_WITH_STAGEFRIGHT +#include <OMX.h> +#else +#include <media/IOMX.h> +#endif /* desktop Linux needs a little help with gettid() */ #if defined(HAVE_GETTID) && !defined(HAVE_ANDROID_OS) @@ -186,6 +195,10 @@ typedef struct { const player_type playertype; } extmap; extmap FILE_EXTS [] = { +#if USE_STAGEFRIGHT + {".mp4", STAGEFRIGHT_PLAYER}, + {".3gp", STAGEFRIGHT_PLAYER}, +#endif {".mid", SONIVOX_PLAYER}, {".midi", SONIVOX_PLAYER}, {".smf", SONIVOX_PLAYER}, @@ -271,6 +284,14 @@ sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClie return c; } +sp<IOMX> MediaPlayerService::createOMX() { +#ifdef BUILD_WITH_STAGEFRIGHT + return new OMX; +#else + return NULL; +#endif +} + status_t MediaPlayerService::AudioCache::dump(int fd, const Vector<String16>& args) const { const size_t SIZE = 256; @@ -577,6 +598,7 @@ void MediaPlayerService::Client::disconnect() p = mPlayer; } mClient.clear(); + mPlayer.clear(); // clear the notification to prevent callbacks to dead client @@ -624,13 +646,16 @@ static player_type getPlayerType(int fd, int64_t offset, int64_t length) EAS_Shutdown(easdata); } +#if USE_STAGEFRIGHT + return STAGEFRIGHT_PLAYER; +#endif + // Fall through to PV return PV_PLAYER; } static player_type getPlayerType(const char* url) { - // use MidiFile for MIDI extensions int lenURL = strlen(url); for (int i = 0; i < NELEM(FILE_EXTS); ++i) { @@ -643,6 +668,10 @@ static player_type getPlayerType(const char* url) } } +#if USE_STAGEFRIGHT + return STAGEFRIGHT_PLAYER; +#endif + // Fall through to PV return PV_PLAYER; } @@ -666,6 +695,17 @@ static sp<MediaPlayerBase> createPlayer(player_type playerType, void* cookie, LOGV(" create VorbisPlayer"); p = new VorbisPlayer(); break; +#if USE_STAGEFRIGHT + case STAGEFRIGHT_PLAYER: + LOGV(" create StagefrightPlayer"); + p = new StagefrightPlayer; + break; +#else + case STAGEFRIGHT_PLAYER: + LOG_ALWAYS_FATAL( + "Should not be here, stagefright player not enabled."); + break; +#endif } if (p != NULL) { if (p->initCheck() == NO_ERROR) { @@ -1136,7 +1176,8 @@ Exit: #undef LOG_TAG #define LOG_TAG "AudioSink" MediaPlayerService::AudioOutput::AudioOutput() -{ + : mCallback(NULL), + mCallbackCookie(NULL) { mTrack = 0; mStreamType = AudioSystem::MUSIC; mLeftVolume = 1.0; @@ -1206,8 +1247,13 @@ float MediaPlayerService::AudioOutput::msecsPerFrame() const return mMsecsPerFrame; } -status_t MediaPlayerService::AudioOutput::open(uint32_t sampleRate, int channelCount, int format, int bufferCount) +status_t MediaPlayerService::AudioOutput::open( + uint32_t sampleRate, int channelCount, int format, int bufferCount, + AudioCallback cb, void *cookie) { + mCallback = cb; + mCallbackCookie = cookie; + // Check argument "bufferCount" against the mininum buffer count if (bufferCount < mMinBufferCount) { LOGD("bufferCount (%d) is too small and increased to %d", bufferCount, mMinBufferCount); @@ -1228,7 +1274,17 @@ status_t MediaPlayerService::AudioOutput::open(uint32_t sampleRate, int channelC } frameCount = (sampleRate*afFrameCount*bufferCount)/afSampleRate; - AudioTrack *t = new AudioTrack(mStreamType, sampleRate, format, channelCount, frameCount); + + AudioTrack *t; + if (mCallback != NULL) { + t = new AudioTrack( + mStreamType, sampleRate, format, channelCount, frameCount, + 0 /* flags */, CallbackWrapper, this); + } else { + t = new AudioTrack( + mStreamType, sampleRate, format, channelCount, frameCount); + } + if ((t == 0) || (t->initCheck() != NO_ERROR)) { LOGE("Unable to create audio track"); delete t; @@ -1254,6 +1310,8 @@ void MediaPlayerService::AudioOutput::start() ssize_t MediaPlayerService::AudioOutput::write(const void* buffer, size_t size) { + LOG_FATAL_IF(mCallback != NULL, "Don't call write if supplying a callback."); + //LOGV("write(%p, %u)", buffer, size); if (mTrack) return mTrack->write(buffer, size); return NO_INIT; @@ -1294,6 +1352,20 @@ void MediaPlayerService::AudioOutput::setVolume(float left, float right) } } +// static +void MediaPlayerService::AudioOutput::CallbackWrapper( + int event, void *cookie, void *info) { + if (event != AudioTrack::EVENT_MORE_DATA) { + return; + } + + AudioOutput *me = (AudioOutput *)cookie; + AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info; + + (*me->mCallback)( + me, buffer->raw, buffer->size, me->mCallbackCookie); +} + #undef LOG_TAG #define LOG_TAG "AudioCache" MediaPlayerService::AudioCache::AudioCache(const char* name) : @@ -1314,8 +1386,14 @@ float MediaPlayerService::AudioCache::msecsPerFrame() const return mMsecsPerFrame; } -status_t MediaPlayerService::AudioCache::open(uint32_t sampleRate, int channelCount, int format, int bufferCount) +status_t MediaPlayerService::AudioCache::open( + uint32_t sampleRate, int channelCount, int format, int bufferCount, + AudioCallback cb, void *cookie) { + if (cb != NULL) { + return UNKNOWN_ERROR; // TODO: implement this. + } + LOGV("open(%u, %d, %d, %d)", sampleRate, channelCount, format, bufferCount); if (mHeap->getHeapID() < 0) return NO_INIT; mSampleRate = sampleRate; diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h index db3d5d7..94cb917 100644 --- a/media/libmediaplayerservice/MediaPlayerService.h +++ b/media/libmediaplayerservice/MediaPlayerService.h @@ -35,6 +35,7 @@ typedef int32_t MetadataType; class IMediaRecorder; class IMediaMetadataRetriever; +class IOMX; #define CALLBACK_ANTAGONIZER 0 #if CALLBACK_ANTAGONIZER @@ -75,7 +76,12 @@ class MediaPlayerService : public BnMediaPlayerService virtual ssize_t frameSize() const; virtual uint32_t latency() const; virtual float msecsPerFrame() const; - virtual status_t open(uint32_t sampleRate, int channelCount, int format, int bufferCount=4); + + virtual status_t open( + uint32_t sampleRate, int channelCount, + int format, int bufferCount, + AudioCallback cb, void *cookie); + virtual void start(); virtual ssize_t write(const void* buffer, size_t size); virtual void stop(); @@ -90,8 +96,12 @@ class MediaPlayerService : public BnMediaPlayerService static int getMinBufferCount(); private: static void setMinBufferCount(); + static void CallbackWrapper( + int event, void *me, void *info); AudioTrack* mTrack; + AudioCallback mCallback; + void * mCallbackCookie; int mStreamType; float mLeftVolume; float mRightVolume; @@ -119,7 +129,12 @@ class MediaPlayerService : public BnMediaPlayerService virtual ssize_t frameSize() const { return ssize_t(mChannelCount * ((mFormat == AudioSystem::PCM_16_BIT)?sizeof(int16_t):sizeof(u_int8_t))); } virtual uint32_t latency() const; virtual float msecsPerFrame() const; - virtual status_t open(uint32_t sampleRate, int channelCount, int format, int bufferCount=1); + + virtual status_t open( + uint32_t sampleRate, int channelCount, int format, + int bufferCount = 1, + AudioCallback cb = NULL, void *cookie = NULL); + virtual void start() {} virtual ssize_t write(const void* buffer, size_t size); virtual void stop() {} @@ -166,6 +181,7 @@ public: virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd, int64_t offset, int64_t length); virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat); virtual sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat); + virtual sp<IOMX> createOMX(); virtual status_t dump(int fd, const Vector<String16>& args); diff --git a/media/libmediaplayerservice/StagefrightPlayer.cpp b/media/libmediaplayerservice/StagefrightPlayer.cpp new file mode 100644 index 0000000..ad1afbb --- /dev/null +++ b/media/libmediaplayerservice/StagefrightPlayer.cpp @@ -0,0 +1,208 @@ +//#define LOG_NDEBUG 0 +#define LOG_TAG "StagefrightPlayer" +#include <utils/Log.h> + +#include "StagefrightPlayer.h" +#include <media/stagefright/MediaPlayerImpl.h> + +namespace android { + +StagefrightPlayer::StagefrightPlayer() + : mPlayer(NULL) { + LOGV("StagefrightPlayer"); +} + +StagefrightPlayer::~StagefrightPlayer() { + LOGV("~StagefrightPlayer"); + reset(); + LOGV("~StagefrightPlayer done."); +} + +status_t StagefrightPlayer::initCheck() { + LOGV("initCheck"); + return OK; +} + +status_t StagefrightPlayer::setDataSource(const char *url) { + LOGV("setDataSource('%s')", url); + + reset(); + mPlayer = new MediaPlayerImpl(url); + + status_t err = mPlayer->initCheck(); + if (err != OK) { + delete mPlayer; + mPlayer = NULL; + } else { + mPlayer->setAudioSink(mAudioSink); + } + + return err; +} + +status_t StagefrightPlayer::setDataSource(int fd, int64_t offset, int64_t length) { + LOGV("setDataSource(%d, %lld, %lld)", fd, offset, length); + + reset(); + mPlayer = new MediaPlayerImpl(fd, offset, length); + + status_t err = mPlayer->initCheck(); + if (err != OK) { + delete mPlayer; + mPlayer = NULL; + } else { + mPlayer->setAudioSink(mAudioSink); + } + + return err; +} + +status_t StagefrightPlayer::setVideoSurface(const sp<ISurface> &surface) { + LOGV("setVideoSurface"); + + if (mPlayer == NULL) { + return NO_INIT; + } + + mPlayer->setISurface(surface); + + return OK; +} + +status_t StagefrightPlayer::prepare() { + LOGV("prepare"); + + if (mPlayer == NULL) { + return NO_INIT; + } + + sendEvent( + MEDIA_SET_VIDEO_SIZE, + mPlayer->getWidth(), mPlayer->getHeight()); + + return OK; +} + +status_t StagefrightPlayer::prepareAsync() { + LOGV("prepareAsync"); + + status_t err = prepare(); + + if (err != OK) { + return err; + } + + sendEvent(MEDIA_PREPARED); + + return OK; +} + +status_t StagefrightPlayer::start() { + LOGV("start"); + + if (mPlayer == NULL) { + return NO_INIT; + } + + mPlayer->play(); + + return OK; +} + +status_t StagefrightPlayer::stop() { + LOGV("stop"); + + if (mPlayer == NULL) { + return NO_INIT; + } + + reset(); + + return OK; +} + +status_t StagefrightPlayer::pause() { + LOGV("pause"); + + if (mPlayer == NULL) { + return NO_INIT; + } + + mPlayer->pause(); + + return OK; +} + +bool StagefrightPlayer::isPlaying() { + LOGV("isPlaying"); + return mPlayer != NULL && mPlayer->isPlaying(); +} + +status_t StagefrightPlayer::seekTo(int msec) { + LOGV("seekTo"); + + if (mPlayer == NULL) { + return NO_INIT; + } + + status_t err = mPlayer->seekTo((int64_t)msec * 1000); + + sendEvent(MEDIA_SEEK_COMPLETE); + + return err; +} + +status_t StagefrightPlayer::getCurrentPosition(int *msec) { + LOGV("getCurrentPosition"); + + if (mPlayer == NULL) { + return NO_INIT; + } + + *msec = mPlayer->getPosition() / 1000; + return OK; +} + +status_t StagefrightPlayer::getDuration(int *msec) { + LOGV("getDuration"); + + if (mPlayer == NULL) { + return NO_INIT; + } + + *msec = mPlayer->getDuration() / 1000; + return OK; +} + +status_t StagefrightPlayer::reset() { + LOGV("reset"); + + delete mPlayer; + mPlayer = NULL; + + return OK; +} + +status_t StagefrightPlayer::setLooping(int loop) { + LOGV("setLooping"); + return UNKNOWN_ERROR; +} + +player_type StagefrightPlayer::playerType() { + LOGV("playerType"); + return STAGEFRIGHT_PLAYER; +} + +status_t StagefrightPlayer::invoke(const Parcel &request, Parcel *reply) { + return INVALID_OPERATION; +} + +void StagefrightPlayer::setAudioSink(const sp<AudioSink> &audioSink) { + MediaPlayerInterface::setAudioSink(audioSink); + + if (mPlayer != NULL) { + mPlayer->setAudioSink(audioSink); + } +} + +} // namespace android diff --git a/media/libmediaplayerservice/StagefrightPlayer.h b/media/libmediaplayerservice/StagefrightPlayer.h new file mode 100644 index 0000000..f214872 --- /dev/null +++ b/media/libmediaplayerservice/StagefrightPlayer.h @@ -0,0 +1,60 @@ +/* +** +** Copyright 2009, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +#ifndef ANDROID_STAGEFRIGHTPLAYER_H +#define ANDROID_STAGEFRIGHTPLAYER_H + +#include <media/MediaPlayerInterface.h> + +namespace android { + +class MediaPlayerImpl; + +class StagefrightPlayer : public MediaPlayerInterface { +public: + StagefrightPlayer(); + virtual ~StagefrightPlayer(); + + virtual status_t initCheck(); + virtual status_t setDataSource(const char *url); + virtual status_t setDataSource(int fd, int64_t offset, int64_t length); + virtual status_t setVideoSurface(const sp<ISurface> &surface); + virtual status_t prepare(); + virtual status_t prepareAsync(); + virtual status_t start(); + virtual status_t stop(); + virtual status_t pause(); + virtual bool isPlaying(); + virtual status_t seekTo(int msec); + virtual status_t getCurrentPosition(int *msec); + virtual status_t getDuration(int *msec); + virtual status_t reset(); + virtual status_t setLooping(int loop); + virtual player_type playerType(); + virtual status_t invoke(const Parcel &request, Parcel *reply); + virtual void setAudioSink(const sp<AudioSink> &audioSink); + +private: + MediaPlayerImpl *mPlayer; + + StagefrightPlayer(const StagefrightPlayer &); + StagefrightPlayer &operator=(const StagefrightPlayer &); +}; + +} // namespace android + +#endif // ANDROID_STAGEFRIGHTPLAYER_H |