• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2012, 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 #ifndef MEDIA_CODEC_H_
18 
19 #define MEDIA_CODEC_H_
20 
21 #include <gui/IGraphicBufferProducer.h>
22 #include <media/hardware/CryptoAPI.h>
23 #include <media/stagefright/foundation/AHandler.h>
24 #include <utils/Vector.h>
25 
26 namespace android {
27 
28 struct ABuffer;
29 struct AMessage;
30 struct AString;
31 struct CodecBase;
32 struct ICrypto;
33 struct IBatteryStats;
34 struct SoftwareRenderer;
35 struct Surface;
36 
37 struct MediaCodec : public AHandler {
38     enum ConfigureFlags {
39         CONFIGURE_FLAG_ENCODE   = 1,
40     };
41 
42     enum BufferFlags {
43         BUFFER_FLAG_SYNCFRAME   = 1,
44         BUFFER_FLAG_CODECCONFIG = 2,
45         BUFFER_FLAG_EOS         = 4,
46     };
47 
48     enum {
49         CB_INPUT_AVAILABLE = 1,
50         CB_OUTPUT_AVAILABLE = 2,
51         CB_ERROR = 3,
52         CB_OUTPUT_FORMAT_CHANGED = 4,
53     };
54 
55     struct BatteryNotifier;
56 
57     static sp<MediaCodec> CreateByType(
58             const sp<ALooper> &looper, const char *mime, bool encoder, status_t *err = NULL);
59 
60     static sp<MediaCodec> CreateByComponentName(
61             const sp<ALooper> &looper, const char *name, status_t *err = NULL);
62 
63     status_t configure(
64             const sp<AMessage> &format,
65             const sp<Surface> &nativeWindow,
66             const sp<ICrypto> &crypto,
67             uint32_t flags);
68 
69     status_t setCallback(const sp<AMessage> &callback);
70 
71     status_t createInputSurface(sp<IGraphicBufferProducer>* bufferProducer);
72 
73     status_t start();
74 
75     // Returns to a state in which the component remains allocated but
76     // unconfigured.
77     status_t stop();
78 
79     // Resets the codec to the INITIALIZED state.  Can be called after an error
80     // has occured to make the codec usable.
81     status_t reset();
82 
83     // Client MUST call release before releasing final reference to this
84     // object.
85     status_t release();
86 
87     status_t flush();
88 
89     status_t queueInputBuffer(
90             size_t index,
91             size_t offset,
92             size_t size,
93             int64_t presentationTimeUs,
94             uint32_t flags,
95             AString *errorDetailMsg = NULL);
96 
97     status_t queueSecureInputBuffer(
98             size_t index,
99             size_t offset,
100             const CryptoPlugin::SubSample *subSamples,
101             size_t numSubSamples,
102             const uint8_t key[16],
103             const uint8_t iv[16],
104             CryptoPlugin::Mode mode,
105             int64_t presentationTimeUs,
106             uint32_t flags,
107             AString *errorDetailMsg = NULL);
108 
109     status_t dequeueInputBuffer(size_t *index, int64_t timeoutUs = 0ll);
110 
111     status_t dequeueOutputBuffer(
112             size_t *index,
113             size_t *offset,
114             size_t *size,
115             int64_t *presentationTimeUs,
116             uint32_t *flags,
117             int64_t timeoutUs = 0ll);
118 
119     status_t renderOutputBufferAndRelease(size_t index, int64_t timestampNs);
120     status_t renderOutputBufferAndRelease(size_t index);
121     status_t releaseOutputBuffer(size_t index);
122 
123     status_t signalEndOfInputStream();
124 
125     status_t getOutputFormat(sp<AMessage> *format) const;
126     status_t getInputFormat(sp<AMessage> *format) const;
127 
128     status_t getInputBuffers(Vector<sp<ABuffer> > *buffers) const;
129     status_t getOutputBuffers(Vector<sp<ABuffer> > *buffers) const;
130 
131     status_t getOutputBuffer(size_t index, sp<ABuffer> *buffer);
132     status_t getOutputFormat(size_t index, sp<AMessage> *format);
133     status_t getInputBuffer(size_t index, sp<ABuffer> *buffer);
134 
135     status_t requestIDRFrame();
136 
137     // Notification will be posted once there "is something to do", i.e.
138     // an input/output buffer has become available, a format change is
139     // pending, an error is pending.
140     void requestActivityNotification(const sp<AMessage> &notify);
141 
142     status_t getName(AString *componentName) const;
143 
144     status_t setParameters(const sp<AMessage> &params);
145 
146 protected:
147     virtual ~MediaCodec();
148     virtual void onMessageReceived(const sp<AMessage> &msg);
149 
150 private:
151     enum State {
152         UNINITIALIZED,
153         INITIALIZING,
154         INITIALIZED,
155         CONFIGURING,
156         CONFIGURED,
157         STARTING,
158         STARTED,
159         FLUSHING,
160         FLUSHED,
161         STOPPING,
162         RELEASING,
163     };
164 
165     enum {
166         kPortIndexInput         = 0,
167         kPortIndexOutput        = 1,
168     };
169 
170     enum {
171         kWhatInit                           = 'init',
172         kWhatConfigure                      = 'conf',
173         kWhatCreateInputSurface             = 'cisf',
174         kWhatStart                          = 'strt',
175         kWhatStop                           = 'stop',
176         kWhatRelease                        = 'rele',
177         kWhatDequeueInputBuffer             = 'deqI',
178         kWhatQueueInputBuffer               = 'queI',
179         kWhatDequeueOutputBuffer            = 'deqO',
180         kWhatReleaseOutputBuffer            = 'relO',
181         kWhatSignalEndOfInputStream         = 'eois',
182         kWhatGetBuffers                     = 'getB',
183         kWhatFlush                          = 'flus',
184         kWhatGetOutputFormat                = 'getO',
185         kWhatGetInputFormat                 = 'getI',
186         kWhatDequeueInputTimedOut           = 'dITO',
187         kWhatDequeueOutputTimedOut          = 'dOTO',
188         kWhatCodecNotify                    = 'codc',
189         kWhatRequestIDRFrame                = 'ridr',
190         kWhatRequestActivityNotification    = 'racN',
191         kWhatGetName                        = 'getN',
192         kWhatSetParameters                  = 'setP',
193         kWhatSetCallback                    = 'setC',
194     };
195 
196     enum {
197         kFlagIsSoftwareCodec            = 1,
198         kFlagOutputFormatChanged        = 2,
199         kFlagOutputBuffersChanged       = 4,
200         kFlagStickyError                = 8,
201         kFlagDequeueInputPending        = 16,
202         kFlagDequeueOutputPending       = 32,
203         kFlagIsSecure                   = 64,
204         kFlagSawMediaServerDie          = 128,
205         kFlagIsEncoder                  = 256,
206         kFlagGatherCodecSpecificData    = 512,
207         kFlagIsAsync                    = 1024,
208         kFlagIsComponentAllocated       = 2048,
209     };
210 
211     struct BufferInfo {
212         uint32_t mBufferID;
213         sp<ABuffer> mData;
214         sp<ABuffer> mEncryptedData;
215         sp<AMessage> mNotify;
216         sp<AMessage> mFormat;
217         bool mOwnedByClient;
218     };
219 
220     State mState;
221     sp<ALooper> mLooper;
222     sp<ALooper> mCodecLooper;
223     sp<CodecBase> mCodec;
224     AString mComponentName;
225     uint32_t mReplyID;
226     uint32_t mFlags;
227     status_t mStickyError;
228     sp<Surface> mNativeWindow;
229     SoftwareRenderer *mSoftRenderer;
230     sp<AMessage> mOutputFormat;
231     sp<AMessage> mInputFormat;
232     sp<AMessage> mCallback;
233 
234     bool mBatteryStatNotified;
235     bool mIsVideo;
236 
237     // initial create parameters
238     AString mInitName;
239     bool mInitNameIsType;
240     bool mInitIsEncoder;
241 
242     // Used only to synchronize asynchronous getBufferAndFormat
243     // across all the other (synchronous) buffer state change
244     // operations, such as de/queueIn/OutputBuffer, start and
245     // stop/flush/reset/release.
246     Mutex mBufferLock;
247 
248     List<size_t> mAvailPortBuffers[2];
249     Vector<BufferInfo> mPortBuffers[2];
250 
251     int32_t mDequeueInputTimeoutGeneration;
252     uint32_t mDequeueInputReplyID;
253 
254     int32_t mDequeueOutputTimeoutGeneration;
255     uint32_t mDequeueOutputReplyID;
256 
257     sp<ICrypto> mCrypto;
258 
259     List<sp<ABuffer> > mCSD;
260 
261     sp<AMessage> mActivityNotify;
262 
263     bool mHaveInputSurface;
264 
265     MediaCodec(const sp<ALooper> &looper);
266 
267     static status_t PostAndAwaitResponse(
268             const sp<AMessage> &msg, sp<AMessage> *response);
269 
270     static void PostReplyWithError(int32_t replyID, int32_t err);
271 
272     status_t init(const AString &name, bool nameIsType, bool encoder);
273 
274     void setState(State newState);
275     void returnBuffersToCodec();
276     void returnBuffersToCodecOnPort(int32_t portIndex);
277     size_t updateBuffers(int32_t portIndex, const sp<AMessage> &msg);
278     status_t onQueueInputBuffer(const sp<AMessage> &msg);
279     status_t onReleaseOutputBuffer(const sp<AMessage> &msg);
280     ssize_t dequeuePortBuffer(int32_t portIndex);
281 
282     status_t getBufferAndFormat(
283             size_t portIndex, size_t index,
284             sp<ABuffer> *buffer, sp<AMessage> *format);
285 
286     bool handleDequeueInputBuffer(uint32_t replyID, bool newRequest = false);
287     bool handleDequeueOutputBuffer(uint32_t replyID, bool newRequest = false);
288     void cancelPendingDequeueOperations();
289 
290     void extractCSD(const sp<AMessage> &format);
291     status_t queueCSDInputBuffer(size_t bufferIndex);
292 
293     status_t setNativeWindow(
294             const sp<Surface> &surface);
295 
296     void postActivityNotificationIfPossible();
297 
298     void onInputBufferAvailable();
299     void onOutputBufferAvailable();
300     void onError(status_t err, int32_t actionCode, const char *detail = NULL);
301     void onOutputFormatChanged();
302 
303     status_t onSetParameters(const sp<AMessage> &params);
304 
305     status_t amendOutputFormatWithCodecSpecificData(const sp<ABuffer> &buffer);
306     void updateBatteryStat();
307     bool isExecuting() const;
308 
309     /* called to get the last codec error when the sticky flag is set.
310      * if no such codec error is found, returns UNKNOWN_ERROR.
311      */
getStickyErrorMediaCodec312     inline status_t getStickyError() const {
313         return mStickyError != 0 ? mStickyError : UNKNOWN_ERROR;
314     }
315 
setStickyErrorMediaCodec316     inline void setStickyError(status_t err) {
317         mFlags |= kFlagStickyError;
318         mStickyError = err;
319     }
320 
321     DISALLOW_EVIL_CONSTRUCTORS(MediaCodec);
322 };
323 
324 }  // namespace android
325 
326 #endif  // MEDIA_CODEC_H_
327