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