summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorSteve Kondik <shade@chemlab.org>2012-05-25 08:02:21 +0400
committerGerrit Code Review <gerrit@review.cyanogenmod.com>2012-05-25 08:02:21 +0400
commit9788e7f5e2cf5077e25bcb2115745bd79d5008d7 (patch)
treecd8960f8c78b709ae28eaa6b8deae4b99c759e16 /include
parent44a85a17befc0d42693e2957b62a9ddf068c69d1 (diff)
parentef930d1572d5baab13e6a25ea842d83a861a96e2 (diff)
downloadframeworks_base-9788e7f5e2cf5077e25bcb2115745bd79d5008d7.zip
frameworks_base-9788e7f5e2cf5077e25bcb2115745bd79d5008d7.tar.gz
frameworks_base-9788e7f5e2cf5077e25bcb2115745bd79d5008d7.tar.bz2
Merge "audio: Squashed commit of LPA support from CAF" into ics
Diffstat (limited to 'include')
-rw-r--r--include/media/AudioSystem.h13
-rw-r--r--include/media/AudioTrack.h34
-rw-r--r--include/media/IAudioFlinger.h32
-rw-r--r--include/media/IAudioPolicyService.h9
-rw-r--r--include/media/MediaPlayerInterface.h13
-rw-r--r--include/media/stagefright/AudioPlayer.h18
-rw-r--r--include/media/stagefright/LPAPlayer.h342
7 files changed, 451 insertions, 10 deletions
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 6a15f6e..f80a8d6 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -120,6 +120,10 @@ public:
INPUT_CLOSED,
INPUT_CONFIG_CHANGED,
STREAM_CONFIG_CHANGED,
+#ifdef WITH_QCOM_LPA
+ A2DP_OUTPUT_STATE,
+ EFFECT_CONFIG_CHANGED,
+#endif
NUM_CONFIG_EVENTS
};
@@ -151,6 +155,15 @@ public:
uint32_t format = AUDIO_FORMAT_DEFAULT,
uint32_t channels = AUDIO_CHANNEL_OUT_STEREO,
audio_policy_output_flags_t flags = AUDIO_POLICY_OUTPUT_FLAG_INDIRECT);
+#ifdef WITH_QCOM_LPA
+ static audio_io_handle_t getSession(audio_stream_type_t stream,
+ uint32_t format = AUDIO_FORMAT_DEFAULT,
+ audio_policy_output_flags_t flags = AUDIO_POLICY_OUTPUT_FLAG_DIRECT,
+ int32_t sessionId = -1);
+ static void closeSession(audio_io_handle_t output);
+ static status_t pauseSession(audio_io_handle_t output, audio_stream_type_t stream);
+ static status_t resumeSession(audio_io_handle_t output, audio_stream_type_t stream);
+#endif
static status_t startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
int session = 0);
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index 1c401e2..f518198 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -172,6 +172,20 @@ public:
void* user = 0,
int notificationFrames = 0,
int sessionId = 0);
+#ifdef WITH_QCOM_LPA
+ /* Creates an audio track and registers it with AudioFlinger. With this constructor,
+ * session ID of compressed stream can be registered AudioFlinger and AudioHardware,
+ * for routing purpose.
+ */
+
+ AudioTrack( int streamType,
+ uint32_t sampleRate = 0,
+ int format = 0,
+ int channels = 0,
+ uint32_t flags = 0,
+ int sessionId = 0,
+ int lpaSessionId =-1);
+#endif
/* Terminates the AudioTrack and unregisters it from AudioFlinger.
* Also destroys all resources assotiated with the AudioTrack.
@@ -198,7 +212,22 @@ public:
const sp<IMemory>& sharedBuffer = 0,
bool threadCanCallJava = false,
int sessionId = 0);
-
+#ifdef WITH_QCOM_LPA
+ /* Initialize an AudioTrack and registers session Id for Tunneled audio decoding.
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR: successful intialization
+ * - INVALID_OPERATION: AudioTrack is already intitialized
+ * - BAD_VALUE: invalid parameter (channels, format, sampleRate...)
+ * - NO_INIT: audio server or audio hardware not initialized
+ * */
+ status_t set(int streamType =-1,
+ uint32_t sampleRate = 0,
+ int format = 0,
+ int channels = 0,
+ uint32_t flags = 0,
+ int sessionId = 0,
+ int lpaSessionId =-1);
+#endif
/* Result of constructing the AudioTrack. This must be checked
* before using any AudioTrack API (except for set()), using
@@ -485,6 +514,9 @@ private:
uint32_t mUpdatePeriod;
bool mFlushed; // FIXME will be made obsolete by making flush() synchronous
uint32_t mFlags;
+#ifdef WITH_QCOM_LPA
+ audio_io_handle_t mAudioSession;
+#endif
int mSessionId;
int mAuxEffectId;
Mutex mLock;
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index 9e3cb7f..6a9d4b0 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -57,6 +57,22 @@ public:
int *sessionId,
status_t *status) = 0;
+#ifdef WITH_QCOM_LPA
+ virtual void createSession(
+ pid_t pid,
+ uint32_t sampleRate,
+ int channelCount,
+ int *sessionId,
+ status_t *status) = 0;
+
+ virtual void deleteSession() = 0;
+
+ virtual void applyEffectsOn(
+ int16_t *buffer1,
+ int16_t *buffer2,
+ int size) = 0;
+#endif
+
virtual sp<IAudioRecord> openRecord(
pid_t pid,
int input,
@@ -86,6 +102,9 @@ public:
virtual float masterVolume() const = 0;
virtual bool masterMute() const = 0;
+#ifdef WITH_QCOM_LPA
+ virtual status_t setSessionVolume(int stream, float value, float right) = 0;
+#endif
/* set/get stream type state. This will probably be used by
* the preference panel, mostly.
*/
@@ -117,6 +136,16 @@ public:
uint32_t *pChannels,
uint32_t *pLatencyMs,
uint32_t flags) = 0;
+#ifdef WITH_QCOM_LPA
+ virtual int openSession(uint32_t *pDevices,
+ uint32_t *pFormat,
+ uint32_t flags,
+ int32_t stream,
+ int32_t sessionId){return 0;};
+ virtual status_t pauseSession(int output, int32_t stream) = 0;
+ virtual status_t resumeSession(int output, int32_t stream) = 0;
+ virtual status_t closeSession(int output) = 0;
+#endif
virtual int openDuplicateOutput(int output1, int output2) = 0;
virtual status_t closeOutput(int output) = 0;
virtual status_t suspendOutput(int output) = 0;
@@ -159,6 +188,9 @@ public:
int *enabled) = 0;
virtual status_t moveEffects(int session, int srcOutput, int dstOutput) = 0;
+#ifdef WITH_QCOM_LPA
+ virtual status_t deregisterClient(const sp<IAudioFlingerClient>& client) { return false; };
+#endif
};
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index 9807cbe..b8a4621 100644
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -54,6 +54,15 @@ public:
uint32_t format = AUDIO_FORMAT_DEFAULT,
uint32_t channels = 0,
audio_policy_output_flags_t flags = AUDIO_POLICY_OUTPUT_FLAG_INDIRECT) = 0;
+#ifdef WITH_QCOM_LPA
+ virtual audio_io_handle_t getSession(audio_stream_type_t stream,
+ uint32_t format = AUDIO_FORMAT_DEFAULT,
+ audio_policy_output_flags_t flags = AUDIO_POLICY_OUTPUT_FLAG_DIRECT,
+ int32_t sessionId=-1) { return 0; }
+ virtual status_t pauseSession(audio_io_handle_t output, audio_stream_type_t stream) { return 0; }
+ virtual status_t resumeSession(audio_io_handle_t output, audio_stream_type_t stream) { return 0; }
+ virtual status_t closeSession(audio_io_handle_t output) = 0;
+#endif
virtual status_t startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
int session = 0) = 0;
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index 80f43a3..e05e5c5 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -90,12 +90,25 @@ public:
AudioCallback cb = NULL,
void *cookie = NULL) = 0;
+#ifdef WITH_QCOM_LPA
+ // API to open a routing session for tunneled audio playback
+ virtual status_t openSession(
+ int format, int sessionId, uint32_t sampleRate = 44100, int channels = 2) {return 0;};
+#endif
+
virtual void start() = 0;
virtual ssize_t write(const void* buffer, size_t size) = 0;
virtual void stop() = 0;
virtual void flush() = 0;
virtual void pause() = 0;
+#ifdef WITH_QCOM_LPA
+ virtual void pauseSession() {return;};
+ virtual void resumeSession() {return;};
+#endif
virtual void close() = 0;
+#ifdef WITH_QCOM_LPA
+ virtual void closeSession() {return;};
+#endif
};
MediaPlayerBase() : mCookie(0), mNotify(0) {}
diff --git a/include/media/stagefright/AudioPlayer.h b/include/media/stagefright/AudioPlayer.h
index 7adefaa..bb05ba3 100644
--- a/include/media/stagefright/AudioPlayer.h
+++ b/include/media/stagefright/AudioPlayer.h
@@ -42,27 +42,27 @@ public:
virtual ~AudioPlayer();
// Caller retains ownership of "source".
- void setSource(const sp<MediaSource> &source);
+ virtual void setSource(const sp<MediaSource> &source);
// Return time in us.
virtual int64_t getRealTimeUs();
- status_t start(bool sourceAlreadyStarted = false);
+ virtual status_t start(bool sourceAlreadyStarted = false);
- void pause(bool playPendingSamples = false);
- void resume();
+ virtual void pause(bool playPendingSamples = false);
+ virtual void resume();
// Returns the timestamp of the last buffer played (in us).
- int64_t getMediaTimeUs();
+ virtual int64_t getMediaTimeUs();
// Returns true iff a mapping is established, i.e. the AudioPlayer
// has played at least one frame of audio.
- bool getMediaTimeMapping(int64_t *realtime_us, int64_t *mediatime_us);
+ virtual bool getMediaTimeMapping(int64_t *realtime_us, int64_t *mediatime_us);
- status_t seekTo(int64_t time_us);
+ virtual status_t seekTo(int64_t time_us);
- bool isSeeking();
- bool reachedEOS(status_t *finalStatus);
+ virtual bool isSeeking();
+ virtual bool reachedEOS(status_t *finalStatus);
private:
friend class VideoEditorAudioPlayer;
diff --git a/include/media/stagefright/LPAPlayer.h b/include/media/stagefright/LPAPlayer.h
new file mode 100644
index 0000000..0326d97
--- /dev/null
+++ b/include/media/stagefright/LPAPlayer.h
@@ -0,0 +1,342 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ *
+ * 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 LPA_PLAYER_H_
+
+#define LPA_PLAYER_H_
+
+#include "AudioPlayer.h"
+#include <media/IAudioFlinger.h>
+#include <utils/threads.h>
+#include <utils/List.h>
+#include <utils/Vector.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <binder/IServiceManager.h>
+#include <linux/unistd.h>
+#include <linux/msm_audio.h>
+#include <linux/ion.h>
+#include <include/TimedEventQueue.h>
+#include <binder/BinderService.h>
+#include <binder/MemoryDealer.h>
+#include <powermanager/IPowerManager.h>
+
+// Pause timeout = 3sec
+#define LPA_PAUSE_TIMEOUT_USEC 3000000
+
+namespace android {
+
+class LPAPlayer : public AudioPlayer {
+public:
+ enum {
+ REACHED_EOS,
+ SEEK_COMPLETE
+ };
+
+ LPAPlayer(const sp<MediaPlayerBase::AudioSink> &audioSink, bool &initCheck,
+ AwesomePlayer *audioObserver = NULL);
+
+ virtual ~LPAPlayer();
+
+ // Caller retains ownership of "source".
+ virtual void setSource(const sp<MediaSource> &source);
+
+ // Return time in us.
+ virtual int64_t getRealTimeUs();
+
+ virtual status_t start(bool sourceAlreadyStarted = false);
+
+ virtual void pause(bool playPendingSamples = false);
+ virtual void resume();
+
+ // Returns the timestamp of the last buffer played (in us).
+ virtual int64_t getMediaTimeUs();
+
+ // Returns true iff a mapping is established, i.e. the LPAPlayer
+ // has played at least one frame of audio.
+ virtual bool getMediaTimeMapping(int64_t *realtime_us, int64_t *mediatime_us);
+
+ virtual status_t seekTo(int64_t time_us);
+
+ virtual bool isSeeking();
+ virtual bool reachedEOS(status_t *finalStatus);
+
+
+ void* handle;
+ static int objectsAlive;
+private:
+
+ int afd;
+ int efd;
+ int ionfd;
+ int sessionId;
+ uint32_t bytesToWrite;
+ bool isPaused;
+ bool mSeeked;
+ bool a2dpDisconnectPause;
+ bool a2dpThreadStarted;
+ volatile bool asyncReset;
+ bool eventThreadCreated;
+ int mBuffSize;
+ int mBuffNumber;
+
+ void clearPowerManager();
+
+ class PMDeathRecipient : public IBinder::DeathRecipient {
+ public:
+ PMDeathRecipient(void *obj){parentClass = (LPAPlayer *)obj;}
+ virtual ~PMDeathRecipient() {}
+
+ // IBinder::DeathRecipient
+ virtual void binderDied(const wp<IBinder>& who);
+
+ private:
+ LPAPlayer *parentClass;
+ PMDeathRecipient(const PMDeathRecipient&);
+ PMDeathRecipient& operator = (const PMDeathRecipient&);
+
+ friend class LPAPlayer;
+ };
+
+ friend class PMDeathRecipient;
+
+ void acquireWakeLock();
+ void releaseWakeLock();
+
+ sp<IPowerManager> mPowerManager;
+ sp<IBinder> mWakeLockToken;
+ sp<PMDeathRecipient> mDeathRecipient;
+
+ //Structure to hold ion buffer information
+ class BuffersAllocated {
+ /* overload BuffersAllocated constructor to support both ion and pmem memory allocation */
+ public:
+ BuffersAllocated(void *buf1, void *buf2, int32_t nSize, int32_t fd) :
+ localBuf(buf1), memBuf(buf2), memBufsize(nSize), memFd(fd)
+ {}
+ BuffersAllocated(void *buf1, void *buf2, int32_t nSize, int32_t share_fd, struct ion_handle *handle) :
+ ion_handle(handle), localBuf(buf1), memBuf(buf2), memBufsize(nSize), memFd(share_fd)
+ {}
+ struct ion_handle *ion_handle;
+ void* localBuf;
+ void* memBuf;
+ int32_t memBufsize;
+ int32_t memFd;
+ uint32_t bytesToWrite;
+ };
+ void audio_register_memory();
+ void memBufferDeAlloc();
+ void *memBufferAlloc(int32_t nSize, int32_t *mem_fd);
+
+ List<BuffersAllocated> memBuffersRequestQueue;
+ List<BuffersAllocated> memBuffersResponseQueue;
+ List<BuffersAllocated> bufPool;
+ List<BuffersAllocated> effectsQueue;
+
+
+ //Declare all the threads
+ pthread_t eventThread;
+ pthread_t decoderThread;
+ pthread_t A2DPThread;
+ pthread_t EffectsThread;
+ pthread_t A2DPNotificationThread;
+
+ //Kill Thread boolean
+ bool killDecoderThread;
+ bool killEventThread;
+ bool killA2DPThread;
+ bool killEffectsThread;
+ bool killA2DPNotificationThread;
+
+ //Thread alive boolean
+ bool decoderThreadAlive;
+ bool eventThreadAlive;
+ bool a2dpThreadAlive;
+ bool effectsThreadAlive;
+ bool a2dpNotificationThreadAlive;
+
+ //Declare the condition Variables and Mutex
+ pthread_mutex_t mem_request_mutex;
+ pthread_mutex_t mem_response_mutex;
+ pthread_mutex_t decoder_mutex;
+ pthread_mutex_t event_mutex;
+ pthread_mutex_t a2dp_mutex;
+ pthread_mutex_t effect_mutex;
+ pthread_mutex_t apply_effect_mutex;
+ pthread_mutex_t a2dp_notification_mutex;
+ pthread_mutex_t pause_mutex;
+
+ pthread_cond_t event_cv;
+ pthread_cond_t decoder_cv;
+ pthread_cond_t a2dp_cv;
+ pthread_cond_t effect_cv;
+ pthread_cond_t event_thread_cv;
+ pthread_cond_t a2dp_notification_cv;
+ pthread_cond_t pause_cv;
+
+ // make sure Decoder thread has exited
+ void requestAndWaitForDecoderThreadExit();
+
+ // make sure the event thread also exited
+ void requestAndWaitForEventThreadExit();
+
+ // make sure the A2dp thread also exited
+ void requestAndWaitForA2DPThreadExit();
+
+ // make sure the Effects thread also exited
+ void requestAndWaitForEffectsThreadExit();
+
+ // make sure the Effects thread also exited
+ void requestAndWaitForA2DPNotificationThreadExit();
+
+ static void *eventThreadWrapper(void *me);
+ void eventThreadEntry();
+ static void *decoderThreadWrapper(void *me);
+ void decoderThreadEntry();
+ static void *A2DPThreadWrapper(void *me);
+ void A2DPThreadEntry();
+ static void *EffectsThreadWrapper(void *me);
+ void EffectsThreadEntry();
+ static void *A2DPNotificationThreadWrapper(void *me);
+ void A2DPNotificationThreadEntry();
+
+ void createThreads();
+
+ volatile bool bIsA2DPEnabled, bIsAudioRouted, bEffectConfigChanged;
+
+ //Structure to recieve the BT notification from the flinger.
+ class AudioFlingerLPAdecodeClient: public IBinder::DeathRecipient, public BnAudioFlingerClient {
+ public:
+ AudioFlingerLPAdecodeClient(void *obj);
+
+ LPAPlayer *pBaseClass;
+ // DeathRecipient
+ virtual void binderDied(const wp<IBinder>& who);
+
+ // IAudioFlingerClient
+
+ // indicate a change in the configuration of an output or input: keeps the cached
+ // values for output/input parameters upto date in client process
+ virtual void ioConfigChanged(int event, int ioHandle, void *param2);
+
+ friend class LPAPlayer;
+ };
+
+ sp<IAudioFlinger> mAudioFlinger;
+
+ // helper function to obtain AudioFlinger service handle
+ void getAudioFlinger();
+
+ void handleA2DPSwitch();
+
+ sp<AudioFlingerLPAdecodeClient> AudioFlingerClient;
+ friend class AudioFlingerLPAdecodeClient;
+ Mutex AudioFlingerLock;
+ bool mSourceEmpty;
+ bool mAudioSinkOpen;
+
+ sp<MediaSource> mSource;
+
+ MediaBuffer *mInputBuffer;
+ int32_t numChannels;
+ int mSampleRate;
+ int64_t mLatencyUs;
+ size_t mFrameSize;
+
+ Mutex pmLock;
+ Mutex mLock;
+ Mutex mSeekLock;
+ Mutex a2dpSwitchLock;
+ Mutex resumeLock;
+ int64_t mNumFramesPlayed;
+
+ int64_t mPositionTimeMediaUs;
+ int64_t mPositionTimeRealUs;
+
+ bool mSeeking;
+ bool mInternalSeeking;
+ bool mReachedEOS;
+ status_t mFinalStatus;
+ int64_t mSeekTimeUs;
+ int64_t mPauseTime;
+ int64_t mNumA2DPBytesPlayed;
+ int64_t timePlayed;
+ int64_t timeStarted;
+
+ bool mStarted;
+
+ bool mIsFirstBuffer;
+ status_t mFirstBufferResult;
+ MediaBuffer *mFirstBuffer;
+ TimedEventQueue mQueue;
+ bool mQueueStarted;
+ sp<TimedEventQueue::Event> mPauseEvent;
+ bool mPauseEventPending;
+ bool mPlaybackSuspended;
+ bool mIsDriverStarted;
+ bool mIsAudioRouted;
+
+ sp<MediaPlayerBase::AudioSink> mAudioSink;
+ AwesomePlayer *mObserver;
+
+ enum A2DPState {
+ A2DP_ENABLED,
+ A2DP_DISABLED,
+ A2DP_CONNECT,
+ A2DP_DISCONNECT
+ };
+
+ size_t fillBuffer(void *data, size_t size);
+
+ int64_t getRealTimeUsLocked();
+ int64_t getTimeStamp(A2DPState state);
+
+ void reset();
+
+ void onPauseTimeOut();
+
+
+ LPAPlayer(const LPAPlayer &);
+ LPAPlayer &operator=(const LPAPlayer &);
+};
+
+struct TimedEvent : public TimedEventQueue::Event {
+ TimedEvent(LPAPlayer *player,
+ void (LPAPlayer::*method)())
+ : mPlayer(player),
+ mMethod(method) {
+ }
+
+protected:
+ virtual ~TimedEvent() {}
+
+ virtual void fire(TimedEventQueue *queue, int64_t /* now_us */) {
+ (mPlayer->*mMethod)();
+ }
+
+private:
+ LPAPlayer *mPlayer;
+ void (LPAPlayer::*mMethod)();
+
+ TimedEvent(const TimedEvent &);
+ TimedEvent &operator=(const TimedEvent &);
+};
+
+} // namespace android
+
+#endif // LPA_PLAYER_H_
+