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