1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <media/IStreamSource.h>
18 #include <binder/IServiceManager.h>
19 #include "android/android_GenericMediaPlayer.h"
20 
21 // number of SLuint32 fields to store a buffer event message in an item, by mapping each
22 //   to the item key (SLuint32), the item size (SLuint32), and the item data (mask on SLuint32)
23 #define NB_BUFFEREVENT_ITEM_FIELDS 3
24 
25 //--------------------------------------------------------------------------------------------------
26 namespace android {
27 
28 //--------------------------------------------------------------------------------------------------
29 class StreamPlayer;
30 
31 class StreamSourceAppProxy : public BnStreamSource {
32 public:
33     StreamSourceAppProxy(
34             IAndroidBufferQueue *androidBufferQueue,
35             const sp<CallbackProtector> &callbackProtector,
36             StreamPlayer *player);
37     virtual ~StreamSourceAppProxy();
38 
39     // store an item structure to indicate a processed buffer
40     static const SLuint32 kItemProcessed[NB_BUFFEREVENT_ITEM_FIELDS];
41 
42     // IStreamSource implementation
43     virtual void setListener(const sp<IStreamListener> &listener); // mediaserver calls exactly once
44     virtual void setBuffers(const Vector<sp<IMemory> > &buffers);  // mediaserver calls exactly once
45     virtual void onBufferAvailable(size_t index);
46 
47     // Consumption from ABQ
48     void pullFromBuffQueue();
49 
50 private:
51     void receivedCmd_l(IStreamListener::Command cmd, const sp<AMessage> &msg = NULL);
52     void receivedBuffer_l(size_t buffIndex, size_t buffLength);
53 
54 public:
55     // Call at least once prior to releasing the last strong reference to this object. It causes
56     // the player to release all of its resources, similar to android.media.MediaPlayer disconnect.
57     void disconnect();
58 
59 private:
60     // protects mListener, mBuffers, mBuffersHasBeenSet, and mAvailableBuffers
61     Mutex mLock;
62 
63     sp<IStreamListener> mListener;
64     // array of shared memory buffers
65     Vector<sp<IMemory> > mBuffers;
66     bool mBuffersHasBeenSet;
67     // list of available buffers in shared memory, identified by their index
68     List<size_t> mAvailableBuffers;
69 
70     // the Android Buffer Queue from which data is consumed and written to shared memory
71     IAndroidBufferQueue* const mAndroidBufferQueue;
72 
73     const sp<CallbackProtector> mCallbackProtector;
74     const wp<StreamPlayer> mPlayer;
75 
76     DISALLOW_EVIL_CONSTRUCTORS(StreamSourceAppProxy);
77 };
78 
79 
80 //--------------------------------------------------------------------------------------------------
81 class StreamPlayer : public GenericMediaPlayer
82 {
83 public:
84     StreamPlayer(const AudioPlayback_Parameters* params, bool hasVideo,
85            IAndroidBufferQueue *androidBufferQueue, const sp<CallbackProtector> &callbackProtector);
86     virtual ~StreamPlayer();
87 
88     // overridden from GenericPlayer
89     virtual void onMessageReceived(const sp<AMessage> &msg);
90     virtual void preDestroy();
91 
92     void queueRefilled();
93     // Called after AndroidBufferQueue::Clear.
94     // The "_l" indicates the caller still has it's (now empty) AndroidBufferQueue locked.
95     void appClear_l();
96 
97 protected:
98 
99     enum {
100         // message to asynchronously notify mAppProxy it should try to pull from the Android
101         //    Buffer Queue and push to shared memory (media server), either because the buffer queue
102         //    was refilled, or because during playback, the shared memory buffers should remain
103         //    filled to prevent it from draining (this can happen if the ABQ is not ready
104         //    whenever a shared memory buffer becomes available)
105         kWhatPullFromAbq    = 'plfq',
106         kWhatStopForDestroy = 's4ds'
107     };
108 
109     const sp<StreamSourceAppProxy> mAppProxy; // application proxy for the shared memory source
110 
111     // overridden from GenericMediaPlayer
112     virtual void onPrepare();
113     virtual void onPlay();
114 
115     void onPullFromAndroidBufferQueue();
116 
117 private:
118     void onStopForDestroy();
119 
120     Mutex mStopForDestroyLock;
121     Condition mStopForDestroyCondition;
122     bool mStopForDestroyCompleted;
123 
124     DISALLOW_EVIL_CONSTRUCTORS(StreamPlayer);
125 };
126 
127 } // namespace android
128