Loading include/media/MediaPlayerInterface.h +3 −3 Original line number Diff line number Diff line Loading @@ -62,7 +62,8 @@ public: // AudioSink: abstraction layer for audio output class AudioSink : public RefBase { public: typedef void (*AudioCallback)( // Callback returns the number of bytes actually written to the buffer. typedef size_t (*AudioCallback)( AudioSink *audioSink, void *buffer, size_t size, void *cookie); virtual ~AudioSink() {} Loading @@ -77,8 +78,7 @@ public: virtual status_t getPosition(uint32_t *position) = 0; // If no callback is specified, use the "write" API below to submit // audio data. Otherwise return a full buffer of audio data on each // callback. // audio data. virtual status_t open( uint32_t sampleRate, int channelCount, int format=AudioSystem::PCM_16_BIT, Loading include/media/stagefright/AudioPlayer.h +2 −2 Original line number Diff line number Diff line Loading @@ -90,11 +90,11 @@ private: static void AudioCallback(int event, void *user, void *info); void AudioCallback(int event, void *info); static void AudioSinkCallback( static size_t AudioSinkCallback( MediaPlayerBase::AudioSink *audioSink, void *data, size_t size, void *me); void fillBuffer(void *data, size_t size); size_t fillBuffer(void *data, size_t size); int64_t getRealTimeUsLocked() const; Loading media/libmediaplayerservice/MediaPlayerService.cpp +85 −5 Original line number Diff line number Diff line Loading @@ -1597,9 +1597,12 @@ void MediaPlayerService::AudioOutput::CallbackWrapper( AudioOutput *me = (AudioOutput *)cookie; AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info; (*me->mCallback)( size_t actualSize = (*me->mCallback)( me, buffer->raw, buffer->size, me->mCallbackCookie); me->snoopWrite(buffer->raw, buffer->size); if (actualSize > 0) { me->snoopWrite(buffer->raw, actualSize); } } #undef LOG_TAG Loading Loading @@ -1629,14 +1632,75 @@ status_t MediaPlayerService::AudioCache::getPosition(uint32_t *position) return NO_ERROR; } //////////////////////////////////////////////////////////////////////////////// struct CallbackThread : public Thread { CallbackThread(const wp<MediaPlayerBase::AudioSink> &sink, MediaPlayerBase::AudioSink::AudioCallback cb, void *cookie); protected: virtual ~CallbackThread(); virtual bool threadLoop(); private: wp<MediaPlayerBase::AudioSink> mSink; MediaPlayerBase::AudioSink::AudioCallback mCallback; void *mCookie; void *mBuffer; size_t mBufferSize; CallbackThread(const CallbackThread &); CallbackThread &operator=(const CallbackThread &); }; CallbackThread::CallbackThread( const wp<MediaPlayerBase::AudioSink> &sink, MediaPlayerBase::AudioSink::AudioCallback cb, void *cookie) : mSink(sink), mCallback(cb), mCookie(cookie), mBuffer(NULL), mBufferSize(0) { } CallbackThread::~CallbackThread() { if (mBuffer) { free(mBuffer); mBuffer = NULL; } } bool CallbackThread::threadLoop() { sp<MediaPlayerBase::AudioSink> sink = mSink.promote(); if (sink == NULL) { return false; } if (mBuffer == NULL) { mBufferSize = sink->bufferSize(); mBuffer = malloc(mBufferSize); } size_t actualSize = (*mCallback)(sink.get(), mBuffer, mBufferSize, mCookie); if (actualSize > 0) { sink->write(mBuffer, actualSize); } return true; } //////////////////////////////////////////////////////////////////////////////// status_t MediaPlayerService::AudioCache::open( uint32_t sampleRate, int channelCount, int format, int bufferCount, AudioCallback cb, void *cookie) { LOGV("open(%u, %d, %d, %d)", sampleRate, channelCount, format, bufferCount); if (cb != NULL) { return UNKNOWN_ERROR; // TODO: implement this. } if (mHeap->getHeapID() < 0) { return NO_INIT; } Loading @@ -1645,9 +1709,25 @@ status_t MediaPlayerService::AudioCache::open( mChannelCount = (uint16_t)channelCount; mFormat = (uint16_t)format; mMsecsPerFrame = 1.e3 / (float) sampleRate; if (cb != NULL) { mCallbackThread = new CallbackThread(this, cb, cookie); } return NO_ERROR; } void MediaPlayerService::AudioCache::start() { if (mCallbackThread != NULL) { mCallbackThread->run("AudioCache callback"); } } void MediaPlayerService::AudioCache::stop() { if (mCallbackThread != NULL) { mCallbackThread->requestExitAndWait(); } } ssize_t MediaPlayerService::AudioCache::write(const void* buffer, size_t size) { LOGV("write(%p, %u)", buffer, size); Loading media/libmediaplayerservice/MediaPlayerService.h +4 −2 Original line number Diff line number Diff line Loading @@ -139,9 +139,9 @@ class MediaPlayerService : public BnMediaPlayerService int bufferCount = 1, AudioCallback cb = NULL, void *cookie = NULL); virtual void start() {} virtual void start(); virtual ssize_t write(const void* buffer, size_t size); virtual void stop() {} virtual void stop(); virtual void flush() {} virtual void pause() {} virtual void close() {} Loading Loading @@ -171,6 +171,8 @@ class MediaPlayerService : public BnMediaPlayerService uint32_t mSize; int mError; bool mCommandComplete; sp<Thread> mCallbackThread; }; public: Loading media/libstagefright/AudioPlayer.cpp +10 −8 Original line number Diff line number Diff line Loading @@ -187,12 +187,12 @@ bool AudioPlayer::reachedEOS() { } // static void AudioPlayer::AudioSinkCallback( size_t AudioPlayer::AudioSinkCallback( MediaPlayerBase::AudioSink *audioSink, void *buffer, size_t size, void *cookie) { AudioPlayer *me = (AudioPlayer *)cookie; me->fillBuffer(buffer, size); return me->fillBuffer(buffer, size); } void AudioPlayer::AudioCallback(int event, void *info) { Loading @@ -201,17 +201,18 @@ void AudioPlayer::AudioCallback(int event, void *info) { } AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info; fillBuffer(buffer->raw, buffer->size); size_t numBytesWritten = fillBuffer(buffer->raw, buffer->size); buffer->size = numBytesWritten; } void AudioPlayer::fillBuffer(void *data, size_t size) { size_t AudioPlayer::fillBuffer(void *data, size_t size) { if (mNumFramesPlayed == 0) { LOGV("AudioCallback"); } if (mReachedEOS) { memset(data, 0, size); return; return 0; } size_t size_done = 0; Loading Loading @@ -244,7 +245,6 @@ void AudioPlayer::fillBuffer(void *data, size_t size) { if (err != OK) { mReachedEOS = true; memset((char *)data + size_done, 0, size_remaining); break; } Loading Loading @@ -285,7 +285,9 @@ void AudioPlayer::fillBuffer(void *data, size_t size) { } Mutex::Autolock autoLock(mLock); mNumFramesPlayed += size / mFrameSize; mNumFramesPlayed += size_done / mFrameSize; return size_done; } int64_t AudioPlayer::getRealTimeUs() { Loading Loading
include/media/MediaPlayerInterface.h +3 −3 Original line number Diff line number Diff line Loading @@ -62,7 +62,8 @@ public: // AudioSink: abstraction layer for audio output class AudioSink : public RefBase { public: typedef void (*AudioCallback)( // Callback returns the number of bytes actually written to the buffer. typedef size_t (*AudioCallback)( AudioSink *audioSink, void *buffer, size_t size, void *cookie); virtual ~AudioSink() {} Loading @@ -77,8 +78,7 @@ public: virtual status_t getPosition(uint32_t *position) = 0; // If no callback is specified, use the "write" API below to submit // audio data. Otherwise return a full buffer of audio data on each // callback. // audio data. virtual status_t open( uint32_t sampleRate, int channelCount, int format=AudioSystem::PCM_16_BIT, Loading
include/media/stagefright/AudioPlayer.h +2 −2 Original line number Diff line number Diff line Loading @@ -90,11 +90,11 @@ private: static void AudioCallback(int event, void *user, void *info); void AudioCallback(int event, void *info); static void AudioSinkCallback( static size_t AudioSinkCallback( MediaPlayerBase::AudioSink *audioSink, void *data, size_t size, void *me); void fillBuffer(void *data, size_t size); size_t fillBuffer(void *data, size_t size); int64_t getRealTimeUsLocked() const; Loading
media/libmediaplayerservice/MediaPlayerService.cpp +85 −5 Original line number Diff line number Diff line Loading @@ -1597,9 +1597,12 @@ void MediaPlayerService::AudioOutput::CallbackWrapper( AudioOutput *me = (AudioOutput *)cookie; AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info; (*me->mCallback)( size_t actualSize = (*me->mCallback)( me, buffer->raw, buffer->size, me->mCallbackCookie); me->snoopWrite(buffer->raw, buffer->size); if (actualSize > 0) { me->snoopWrite(buffer->raw, actualSize); } } #undef LOG_TAG Loading Loading @@ -1629,14 +1632,75 @@ status_t MediaPlayerService::AudioCache::getPosition(uint32_t *position) return NO_ERROR; } //////////////////////////////////////////////////////////////////////////////// struct CallbackThread : public Thread { CallbackThread(const wp<MediaPlayerBase::AudioSink> &sink, MediaPlayerBase::AudioSink::AudioCallback cb, void *cookie); protected: virtual ~CallbackThread(); virtual bool threadLoop(); private: wp<MediaPlayerBase::AudioSink> mSink; MediaPlayerBase::AudioSink::AudioCallback mCallback; void *mCookie; void *mBuffer; size_t mBufferSize; CallbackThread(const CallbackThread &); CallbackThread &operator=(const CallbackThread &); }; CallbackThread::CallbackThread( const wp<MediaPlayerBase::AudioSink> &sink, MediaPlayerBase::AudioSink::AudioCallback cb, void *cookie) : mSink(sink), mCallback(cb), mCookie(cookie), mBuffer(NULL), mBufferSize(0) { } CallbackThread::~CallbackThread() { if (mBuffer) { free(mBuffer); mBuffer = NULL; } } bool CallbackThread::threadLoop() { sp<MediaPlayerBase::AudioSink> sink = mSink.promote(); if (sink == NULL) { return false; } if (mBuffer == NULL) { mBufferSize = sink->bufferSize(); mBuffer = malloc(mBufferSize); } size_t actualSize = (*mCallback)(sink.get(), mBuffer, mBufferSize, mCookie); if (actualSize > 0) { sink->write(mBuffer, actualSize); } return true; } //////////////////////////////////////////////////////////////////////////////// status_t MediaPlayerService::AudioCache::open( uint32_t sampleRate, int channelCount, int format, int bufferCount, AudioCallback cb, void *cookie) { LOGV("open(%u, %d, %d, %d)", sampleRate, channelCount, format, bufferCount); if (cb != NULL) { return UNKNOWN_ERROR; // TODO: implement this. } if (mHeap->getHeapID() < 0) { return NO_INIT; } Loading @@ -1645,9 +1709,25 @@ status_t MediaPlayerService::AudioCache::open( mChannelCount = (uint16_t)channelCount; mFormat = (uint16_t)format; mMsecsPerFrame = 1.e3 / (float) sampleRate; if (cb != NULL) { mCallbackThread = new CallbackThread(this, cb, cookie); } return NO_ERROR; } void MediaPlayerService::AudioCache::start() { if (mCallbackThread != NULL) { mCallbackThread->run("AudioCache callback"); } } void MediaPlayerService::AudioCache::stop() { if (mCallbackThread != NULL) { mCallbackThread->requestExitAndWait(); } } ssize_t MediaPlayerService::AudioCache::write(const void* buffer, size_t size) { LOGV("write(%p, %u)", buffer, size); Loading
media/libmediaplayerservice/MediaPlayerService.h +4 −2 Original line number Diff line number Diff line Loading @@ -139,9 +139,9 @@ class MediaPlayerService : public BnMediaPlayerService int bufferCount = 1, AudioCallback cb = NULL, void *cookie = NULL); virtual void start() {} virtual void start(); virtual ssize_t write(const void* buffer, size_t size); virtual void stop() {} virtual void stop(); virtual void flush() {} virtual void pause() {} virtual void close() {} Loading Loading @@ -171,6 +171,8 @@ class MediaPlayerService : public BnMediaPlayerService uint32_t mSize; int mError; bool mCommandComplete; sp<Thread> mCallbackThread; }; public: Loading
media/libstagefright/AudioPlayer.cpp +10 −8 Original line number Diff line number Diff line Loading @@ -187,12 +187,12 @@ bool AudioPlayer::reachedEOS() { } // static void AudioPlayer::AudioSinkCallback( size_t AudioPlayer::AudioSinkCallback( MediaPlayerBase::AudioSink *audioSink, void *buffer, size_t size, void *cookie) { AudioPlayer *me = (AudioPlayer *)cookie; me->fillBuffer(buffer, size); return me->fillBuffer(buffer, size); } void AudioPlayer::AudioCallback(int event, void *info) { Loading @@ -201,17 +201,18 @@ void AudioPlayer::AudioCallback(int event, void *info) { } AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info; fillBuffer(buffer->raw, buffer->size); size_t numBytesWritten = fillBuffer(buffer->raw, buffer->size); buffer->size = numBytesWritten; } void AudioPlayer::fillBuffer(void *data, size_t size) { size_t AudioPlayer::fillBuffer(void *data, size_t size) { if (mNumFramesPlayed == 0) { LOGV("AudioCallback"); } if (mReachedEOS) { memset(data, 0, size); return; return 0; } size_t size_done = 0; Loading Loading @@ -244,7 +245,6 @@ void AudioPlayer::fillBuffer(void *data, size_t size) { if (err != OK) { mReachedEOS = true; memset((char *)data + size_done, 0, size_remaining); break; } Loading Loading @@ -285,7 +285,9 @@ void AudioPlayer::fillBuffer(void *data, size_t size) { } Mutex::Autolock autoLock(mLock); mNumFramesPlayed += size / mFrameSize; mNumFramesPlayed += size_done / mFrameSize; return size_done; } int64_t AudioPlayer::getRealTimeUs() { Loading