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