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