MediaCodec.h revision 55c3bd0cacfb6e1601cd03fdba814be544a34326
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 setInputSurface(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    // used by ResourceManagerClient
168    status_t reclaim();
169    friend struct ResourceManagerClient;
170
171private:
172    enum State {
173        UNINITIALIZED,
174        INITIALIZING,
175        INITIALIZED,
176        CONFIGURING,
177        CONFIGURED,
178        STARTING,
179        STARTED,
180        FLUSHING,
181        FLUSHED,
182        STOPPING,
183        RELEASING,
184    };
185
186    enum {
187        kPortIndexInput         = 0,
188        kPortIndexOutput        = 1,
189    };
190
191    enum {
192        kWhatInit                           = 'init',
193        kWhatConfigure                      = 'conf',
194        kWhatSetSurface                     = 'sSur',
195        kWhatCreateInputSurface             = 'cisf',
196        kWhatSetInputSurface                = 'sisf',
197        kWhatStart                          = 'strt',
198        kWhatStop                           = 'stop',
199        kWhatRelease                        = 'rele',
200        kWhatDequeueInputBuffer             = 'deqI',
201        kWhatQueueInputBuffer               = 'queI',
202        kWhatDequeueOutputBuffer            = 'deqO',
203        kWhatReleaseOutputBuffer            = 'relO',
204        kWhatSignalEndOfInputStream         = 'eois',
205        kWhatGetBuffers                     = 'getB',
206        kWhatFlush                          = 'flus',
207        kWhatGetOutputFormat                = 'getO',
208        kWhatGetInputFormat                 = 'getI',
209        kWhatDequeueInputTimedOut           = 'dITO',
210        kWhatDequeueOutputTimedOut          = 'dOTO',
211        kWhatCodecNotify                    = 'codc',
212        kWhatRequestIDRFrame                = 'ridr',
213        kWhatRequestActivityNotification    = 'racN',
214        kWhatGetName                        = 'getN',
215        kWhatSetParameters                  = 'setP',
216        kWhatSetCallback                    = 'setC',
217    };
218
219    enum {
220        kFlagUsesSoftwareRenderer       = 1,
221        kFlagOutputFormatChanged        = 2,
222        kFlagOutputBuffersChanged       = 4,
223        kFlagStickyError                = 8,
224        kFlagDequeueInputPending        = 16,
225        kFlagDequeueOutputPending       = 32,
226        kFlagIsSecure                   = 64,
227        kFlagSawMediaServerDie          = 128,
228        kFlagIsEncoder                  = 256,
229        kFlagGatherCodecSpecificData    = 512,
230        kFlagIsAsync                    = 1024,
231        kFlagIsComponentAllocated       = 2048,
232        kFlagPushBlankBuffersOnShutdown = 4096,
233    };
234
235    struct BufferInfo {
236        uint32_t mBufferID;
237        sp<ABuffer> mData;
238        sp<ABuffer> mEncryptedData;
239        sp<IMemory> mSharedEncryptedBuffer;
240        sp<AMessage> mNotify;
241        sp<AMessage> mFormat;
242        bool mOwnedByClient;
243    };
244
245    struct ResourceManagerServiceProxy : public IBinder::DeathRecipient {
246        ResourceManagerServiceProxy();
247        ~ResourceManagerServiceProxy();
248
249        void init();
250
251        // implements DeathRecipient
252        virtual void binderDied(const wp<IBinder>& /*who*/);
253
254        void addResource(
255                int pid,
256                int64_t clientId,
257                const sp<IResourceManagerClient> client,
258                const Vector<MediaResource> &resources);
259
260        void removeResource(int64_t clientId);
261
262        bool reclaimResource(int callingPid, const Vector<MediaResource> &resources);
263
264    private:
265        Mutex mLock;
266        sp<IResourceManagerService> mService;
267    };
268
269    State mState;
270    bool mReleasedByResourceManager;
271    sp<ALooper> mLooper;
272    sp<ALooper> mCodecLooper;
273    sp<CodecBase> mCodec;
274    AString mComponentName;
275    sp<AReplyToken> mReplyID;
276    uint32_t mFlags;
277    status_t mStickyError;
278    sp<Surface> mSurface;
279    SoftwareRenderer *mSoftRenderer;
280    sp<AMessage> mOutputFormat;
281    sp<AMessage> mInputFormat;
282    sp<AMessage> mCallback;
283    sp<MemoryDealer> mDealer;
284
285    sp<IResourceManagerClient> mResourceManagerClient;
286    sp<ResourceManagerServiceProxy> mResourceManagerService;
287
288    bool mBatteryStatNotified;
289    bool mIsVideo;
290    int32_t mVideoWidth;
291    int32_t mVideoHeight;
292
293    // initial create parameters
294    AString mInitName;
295    bool mInitNameIsType;
296    bool mInitIsEncoder;
297
298    // configure parameter
299    sp<AMessage> mConfigureMsg;
300
301    // Used only to synchronize asynchronous getBufferAndFormat
302    // across all the other (synchronous) buffer state change
303    // operations, such as de/queueIn/OutputBuffer, start and
304    // stop/flush/reset/release.
305    Mutex mBufferLock;
306
307    List<size_t> mAvailPortBuffers[2];
308    Vector<BufferInfo> mPortBuffers[2];
309
310    int32_t mDequeueInputTimeoutGeneration;
311    sp<AReplyToken> mDequeueInputReplyID;
312
313    int32_t mDequeueOutputTimeoutGeneration;
314    sp<AReplyToken> mDequeueOutputReplyID;
315
316    sp<ICrypto> mCrypto;
317
318    List<sp<ABuffer> > mCSD;
319
320    sp<AMessage> mActivityNotify;
321
322    bool mHaveInputSurface;
323    bool mHavePendingInputBuffers;
324
325    MediaCodec(const sp<ALooper> &looper);
326
327    static status_t PostAndAwaitResponse(
328            const sp<AMessage> &msg, sp<AMessage> *response);
329
330    void PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err);
331
332    status_t init(const AString &name, bool nameIsType, bool encoder);
333
334    void setState(State newState);
335    void returnBuffersToCodec();
336    void returnBuffersToCodecOnPort(int32_t portIndex);
337    size_t updateBuffers(int32_t portIndex, const sp<AMessage> &msg);
338    status_t onQueueInputBuffer(const sp<AMessage> &msg);
339    status_t onReleaseOutputBuffer(const sp<AMessage> &msg);
340    ssize_t dequeuePortBuffer(int32_t portIndex);
341
342    status_t getBufferAndFormat(
343            size_t portIndex, size_t index,
344            sp<ABuffer> *buffer, sp<AMessage> *format);
345
346    bool handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool newRequest = false);
347    bool handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest = false);
348    void cancelPendingDequeueOperations();
349
350    void extractCSD(const sp<AMessage> &format);
351    status_t queueCSDInputBuffer(size_t bufferIndex);
352
353    status_t handleSetSurface(const sp<Surface> &surface);
354    status_t connectToSurface(const sp<Surface> &surface);
355    status_t disconnectFromSurface();
356
357    void postActivityNotificationIfPossible();
358
359    void onInputBufferAvailable();
360    void onOutputBufferAvailable();
361    void onError(status_t err, int32_t actionCode, const char *detail = NULL);
362    void onOutputFormatChanged();
363
364    status_t onSetParameters(const sp<AMessage> &params);
365
366    status_t amendOutputFormatWithCodecSpecificData(const sp<ABuffer> &buffer);
367    void updateBatteryStat();
368    bool isExecuting() const;
369
370    uint64_t getGraphicBufferSize();
371    void addResource(const String8 &type, const String8 &subtype, uint64_t value);
372
373    /* called to get the last codec error when the sticky flag is set.
374     * if no such codec error is found, returns UNKNOWN_ERROR.
375     */
376    inline status_t getStickyError() const {
377        return mStickyError != 0 ? mStickyError : UNKNOWN_ERROR;
378    }
379
380    inline void setStickyError(status_t err) {
381        mFlags |= kFlagStickyError;
382        mStickyError = err;
383    }
384
385    DISALLOW_EVIL_CONSTRUCTORS(MediaCodec);
386};
387
388}  // namespace android
389
390#endif  // MEDIA_CODEC_H_
391