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