MediaCodec.h revision dc9f58dc23a86d0635fd8601d1cbc8d47bab0303
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 IBatteryStats;
34struct SoftwareRenderer;
35struct Surface;
36
37struct 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
146protected:
147    virtual ~MediaCodec();
148    virtual void onMessageReceived(const sp<AMessage> &msg);
149
150private:
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    };
209
210    struct BufferInfo {
211        uint32_t mBufferID;
212        sp<ABuffer> mData;
213        sp<ABuffer> mEncryptedData;
214        sp<AMessage> mNotify;
215        sp<AMessage> mFormat;
216        bool mOwnedByClient;
217    };
218
219    State mState;
220    sp<ALooper> mLooper;
221    sp<ALooper> mCodecLooper;
222    sp<CodecBase> mCodec;
223    AString mComponentName;
224    uint32_t mReplyID;
225    uint32_t mFlags;
226    status_t mStickyError;
227    sp<Surface> mNativeWindow;
228    SoftwareRenderer *mSoftRenderer;
229    sp<AMessage> mOutputFormat;
230    sp<AMessage> mInputFormat;
231    sp<AMessage> mCallback;
232
233    bool mBatteryStatNotified;
234    bool mIsVideo;
235
236    // initial create parameters
237    AString mInitName;
238    bool mInitNameIsType;
239    bool mInitIsEncoder;
240
241    // Used only to synchronize asynchronous getBufferAndFormat
242    // across all the other (synchronous) buffer state change
243    // operations, such as de/queueIn/OutputBuffer, start and
244    // stop/flush/reset/release.
245    Mutex mBufferLock;
246
247    List<size_t> mAvailPortBuffers[2];
248    Vector<BufferInfo> mPortBuffers[2];
249
250    int32_t mDequeueInputTimeoutGeneration;
251    uint32_t mDequeueInputReplyID;
252
253    int32_t mDequeueOutputTimeoutGeneration;
254    uint32_t mDequeueOutputReplyID;
255
256    sp<ICrypto> mCrypto;
257
258    List<sp<ABuffer> > mCSD;
259
260    sp<AMessage> mActivityNotify;
261
262    bool mHaveInputSurface;
263
264    MediaCodec(const sp<ALooper> &looper);
265
266    static status_t PostAndAwaitResponse(
267            const sp<AMessage> &msg, sp<AMessage> *response);
268
269    static void PostReplyWithError(int32_t replyID, int32_t err);
270
271    status_t init(const AString &name, bool nameIsType, bool encoder);
272
273    void setState(State newState);
274    void returnBuffersToCodec();
275    void returnBuffersToCodecOnPort(int32_t portIndex);
276    size_t updateBuffers(int32_t portIndex, const sp<AMessage> &msg);
277    status_t onQueueInputBuffer(const sp<AMessage> &msg);
278    status_t onReleaseOutputBuffer(const sp<AMessage> &msg);
279    ssize_t dequeuePortBuffer(int32_t portIndex);
280
281    status_t getBufferAndFormat(
282            size_t portIndex, size_t index,
283            sp<ABuffer> *buffer, sp<AMessage> *format);
284
285    bool handleDequeueInputBuffer(uint32_t replyID, bool newRequest = false);
286    bool handleDequeueOutputBuffer(uint32_t replyID, bool newRequest = false);
287    void cancelPendingDequeueOperations();
288
289    void extractCSD(const sp<AMessage> &format);
290    status_t queueCSDInputBuffer(size_t bufferIndex);
291
292    status_t setNativeWindow(
293            const sp<Surface> &surface);
294
295    void postActivityNotificationIfPossible();
296
297    void onInputBufferAvailable();
298    void onOutputBufferAvailable();
299    void onError(status_t err, int32_t actionCode, const char *detail = NULL);
300    void onOutputFormatChanged();
301
302    status_t onSetParameters(const sp<AMessage> &params);
303
304    status_t amendOutputFormatWithCodecSpecificData(const sp<ABuffer> &buffer);
305    void updateBatteryStat();
306    bool isExecuting() const;
307
308    /* called to get the last codec error when the sticky flag is set.
309     * if no such codec error is found, returns UNKNOWN_ERROR.
310     */
311    inline status_t getStickyError() const {
312        return mStickyError != 0 ? mStickyError : UNKNOWN_ERROR;
313    }
314
315    inline void setStickyError(status_t err) {
316        mFlags |= kFlagStickyError;
317        mStickyError = err;
318    }
319
320    DISALLOW_EVIL_CONSTRUCTORS(MediaCodec);
321};
322
323}  // namespace android
324
325#endif  // MEDIA_CODEC_H_
326