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