diff options
author | Steve Kondik <shade@chemlab.org> | 2012-05-25 08:02:21 +0400 |
---|---|---|
committer | Gerrit Code Review <gerrit@review.cyanogenmod.com> | 2012-05-25 08:02:21 +0400 |
commit | 9788e7f5e2cf5077e25bcb2115745bd79d5008d7 (patch) | |
tree | cd8960f8c78b709ae28eaa6b8deae4b99c759e16 /include | |
parent | 44a85a17befc0d42693e2957b62a9ddf068c69d1 (diff) | |
parent | ef930d1572d5baab13e6a25ea842d83a861a96e2 (diff) | |
download | frameworks_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.h | 13 | ||||
-rw-r--r-- | include/media/AudioTrack.h | 34 | ||||
-rw-r--r-- | include/media/IAudioFlinger.h | 32 | ||||
-rw-r--r-- | include/media/IAudioPolicyService.h | 9 | ||||
-rw-r--r-- | include/media/MediaPlayerInterface.h | 13 | ||||
-rw-r--r-- | include/media/stagefright/AudioPlayer.h | 18 | ||||
-rw-r--r-- | include/media/stagefright/LPAPlayer.h | 342 |
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_
+
|