CodecBase.h revision 3b2847fa5506dc265d2e46f067bfbb66ae209f74
1/*
2 * Copyright (C) 2014 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 CODEC_BASE_H_
18
19#define CODEC_BASE_H_
20
21#include <memory>
22
23#include <stdint.h>
24
25#define STRINGIFY_ENUMS
26
27#include <media/ICrypto.h>
28#include <media/IOMX.h>
29#include <media/MediaCodecInfo.h>
30#include <media/stagefright/MediaErrors.h>
31#include <media/stagefright/foundation/AHandler.h>
32#include <media/stagefright/foundation/ColorUtils.h>
33#include <media/hardware/HardwareAPI.h>
34
35#include <utils/NativeHandle.h>
36
37#include <system/graphics.h>
38#include <android/media/IDescrambler.h>
39
40namespace android {
41using namespace media;
42class BufferChannelBase;
43class BufferProducerWrapper;
44class MediaCodecBuffer;
45struct PersistentSurface;
46struct RenderedFrameInfo;
47class Surface;
48
49struct CodecBase : public AHandler, /* static */ ColorUtils {
50    /**
51     * This interface defines events firing from CodecBase back to MediaCodec.
52     * All methods must not block.
53     */
54    class CodecCallback {
55    public:
56        virtual ~CodecCallback() = default;
57
58        /**
59         * Notify MediaCodec for seeing an output EOS.
60         *
61         * @param err the underlying cause of the EOS. If the value is neither
62         *            OK nor ERROR_END_OF_STREAM, the EOS is declared
63         *            prematurely for that error.
64         */
65        virtual void onEos(status_t err) = 0;
66        /**
67         * Notify MediaCodec that start operation is complete.
68         */
69        virtual void onStartCompleted() = 0;
70        /**
71         * Notify MediaCodec that stop operation is complete.
72         */
73        virtual void onStopCompleted() = 0;
74        /**
75         * Notify MediaCodec that release operation is complete.
76         */
77        virtual void onReleaseCompleted() = 0;
78        /**
79         * Notify MediaCodec that flush operation is complete.
80         */
81        virtual void onFlushCompleted() = 0;
82        /**
83         * Notify MediaCodec that an error is occurred.
84         *
85         * @param err         an error code for the occurred error.
86         * @param actionCode  an action code for severity of the error.
87         */
88        virtual void onError(status_t err, enum ActionCode actionCode) = 0;
89        /**
90         * Notify MediaCodec that the underlying component is allocated.
91         *
92         * @param componentName the unique name of the component specified in
93         *                      MediaCodecList.
94         */
95        virtual void onComponentAllocated(const char *componentName) = 0;
96        /**
97         * Notify MediaCodec that the underlying component is configured.
98         *
99         * @param inputFormat   an input format at configure time.
100         * @param outputFormat  an output format at configure time.
101         */
102        virtual void onComponentConfigured(
103                const sp<AMessage> &inputFormat, const sp<AMessage> &outputFormat) = 0;
104        /**
105         * Notify MediaCodec that the input surface is created.
106         *
107         * @param inputFormat   an input format at surface creation. Formats
108         *                      could change from the previous state as a result
109         *                      of creating a surface.
110         * @param outputFormat  an output format at surface creation.
111         * @param inputSurface  the created surface.
112         */
113        virtual void onInputSurfaceCreated(
114                const sp<AMessage> &inputFormat,
115                const sp<AMessage> &outputFormat,
116                const sp<BufferProducerWrapper> &inputSurface) = 0;
117        /**
118         * Notify MediaCodec that the input surface creation is failed.
119         *
120         * @param err an error code of the cause.
121         */
122        virtual void onInputSurfaceCreationFailed(status_t err) = 0;
123        /**
124         * Notify MediaCodec that the component accepted the provided input
125         * surface.
126         *
127         * @param inputFormat   an input format at surface assignment. Formats
128         *                      could change from the previous state as a result
129         *                      of assigning a surface.
130         * @param outputFormat  an output format at surface assignment.
131         */
132        virtual void onInputSurfaceAccepted(
133                const sp<AMessage> &inputFormat,
134                const sp<AMessage> &outputFormat) = 0;
135        /**
136         * Notify MediaCodec that the component declined the provided input
137         * surface.
138         *
139         * @param err an error code of the cause.
140         */
141        virtual void onInputSurfaceDeclined(status_t err) = 0;
142        /**
143         * Noitfy MediaCodec that the requested input EOS is sent to the input
144         * surface.
145         *
146         * @param err an error code returned from the surface. If there is no
147         *            input surface, the value is INVALID_OPERATION.
148         */
149        virtual void onSignaledInputEOS(status_t err) = 0;
150        /**
151         * Notify MediaCodec that output frames are rendered with information on
152         * those frames.
153         *
154         * @param done  a list of rendered frames.
155         */
156        virtual void onOutputFramesRendered(const std::list<RenderedFrameInfo> &done) = 0;
157        /**
158         * Notify MediaCodec that output buffers are changed.
159         */
160        virtual void onOutputBuffersChanged() = 0;
161    };
162
163    /**
164     * This interface defines events firing from BufferChannelBase back to MediaCodec.
165     * All methods must not block.
166     */
167    class BufferCallback {
168    public:
169        virtual ~BufferCallback() = default;
170
171        /**
172         * Notify MediaCodec that an input buffer is available with given index.
173         * When BufferChannelBase::getInputBufferArray() is not called,
174         * BufferChannelBase may report different buffers with the same index if
175         * MediaCodec already queued/discarded the buffer. After calling
176         * BufferChannelBase::getInputBufferArray(), the buffer and index match the
177         * returned array.
178         */
179        virtual void onInputBufferAvailable(
180                size_t index, const sp<MediaCodecBuffer> &buffer) = 0;
181        /**
182         * Notify MediaCodec that an output buffer is available with given index.
183         * When BufferChannelBase::getOutputBufferArray() is not called,
184         * BufferChannelBase may report different buffers with the same index if
185         * MediaCodec already queued/discarded the buffer. After calling
186         * BufferChannelBase::getOutputBufferArray(), the buffer and index match the
187         * returned array.
188         */
189        virtual void onOutputBufferAvailable(
190                size_t index, const sp<MediaCodecBuffer> &buffer) = 0;
191    };
192    enum {
193        kMaxCodecBufferSize = 8192 * 4096 * 4, // 8K RGBA
194    };
195
196    inline void setCallback(std::unique_ptr<CodecCallback> &&callback) {
197        mCallback = std::move(callback);
198    }
199    virtual std::shared_ptr<BufferChannelBase> getBufferChannel() = 0;
200
201    virtual void initiateAllocateComponent(const sp<AMessage> &msg) = 0;
202    virtual void initiateConfigureComponent(const sp<AMessage> &msg) = 0;
203    virtual void initiateCreateInputSurface() = 0;
204    virtual void initiateSetInputSurface(
205            const sp<PersistentSurface> &surface) = 0;
206    virtual void initiateStart() = 0;
207    virtual void initiateShutdown(bool keepComponentAllocated = false) = 0;
208
209    // require an explicit message handler
210    virtual void onMessageReceived(const sp<AMessage> &msg) = 0;
211
212    virtual status_t queryCapabilities(
213            const AString& /*name*/, const AString& /*mime*/, bool /*isEncoder*/,
214            sp<MediaCodecInfo::Capabilities>* /*caps*/ /* nonnull */) { return INVALID_OPERATION; }
215
216    virtual status_t setSurface(const sp<Surface>& /*surface*/) { return INVALID_OPERATION; }
217
218    virtual void signalFlush() = 0;
219    virtual void signalResume() = 0;
220
221    virtual void signalRequestIDRFrame() = 0;
222    virtual void signalSetParameters(const sp<AMessage> &msg) = 0;
223    virtual void signalEndOfInputStream() = 0;
224
225    /*
226     * Codec-related defines
227     */
228
229protected:
230    CodecBase() = default;
231    virtual ~CodecBase() = default;
232
233    std::unique_ptr<CodecCallback> mCallback;
234
235private:
236    DISALLOW_EVIL_CONSTRUCTORS(CodecBase);
237};
238
239/**
240 * A channel between MediaCodec and CodecBase object which manages buffer
241 * passing. Only MediaCodec is expected to call these methods, and
242 * underlying CodecBase implementation should define its own interface
243 * separately for itself.
244 *
245 * Concurrency assumptions:
246 *
247 * 1) Clients may access the object at multiple threads concurrently.
248 * 2) All methods do not call underlying CodecBase object while holding a lock.
249 * 3) Code inside critical section executes within 1ms.
250 */
251class BufferChannelBase {
252public:
253    virtual ~BufferChannelBase() = default;
254
255    inline void setCallback(std::unique_ptr<CodecBase::BufferCallback> &&callback) {
256        mCallback = std::move(callback);
257    }
258
259    inline void setCrypto(const sp<ICrypto> &crypto) {
260        mCrypto = crypto;
261    }
262
263    inline void setDescrambler(const sp<IDescrambler> &descrambler) {
264        mDescrambler = descrambler;
265    }
266
267    /**
268     * Queue an input buffer into the buffer channel.
269     *
270     * @return    OK if successful;
271     *            -ENOENT if the buffer is not known (TODO: this should be
272     *            handled gracefully in the future, here and below).
273     */
274    virtual status_t queueInputBuffer(const sp<MediaCodecBuffer> &buffer) = 0;
275    /**
276     * Queue a secure input buffer into the buffer channel.
277     *
278     * @return    OK if successful;
279     *            -ENOENT if the buffer is not known;
280     *            -ENOSYS if mCrypto is not set so that decryption is not
281     *            possible;
282     *            other errors if decryption failed.
283     */
284    virtual status_t queueSecureInputBuffer(
285            const sp<MediaCodecBuffer> &buffer,
286            bool secure,
287            const uint8_t *key,
288            const uint8_t *iv,
289            CryptoPlugin::Mode mode,
290            CryptoPlugin::Pattern pattern,
291            const CryptoPlugin::SubSample *subSamples,
292            size_t numSubSamples,
293            AString *errorDetailMsg) = 0;
294    /**
295     * Request buffer rendering at specified time.
296     *
297     * @param     timestampNs   nanosecond timestamp for rendering time.
298     * @return    OK if successful;
299     *            -ENOENT if the buffer is not known.
300     */
301    virtual status_t renderOutputBuffer(
302            const sp<MediaCodecBuffer> &buffer, int64_t timestampNs) = 0;
303    /**
304     * Discard a buffer to the underlying CodecBase object.
305     *
306     * TODO: remove once this operation can be handled by just clearing the
307     * reference.
308     *
309     * @return    OK if successful;
310     *            -ENOENT if the buffer is not known.
311     */
312    virtual status_t discardBuffer(const sp<MediaCodecBuffer> &buffer) = 0;
313    /**
314     * Clear and fill array with input buffers.
315     */
316    virtual void getInputBufferArray(Vector<sp<MediaCodecBuffer>> *array) = 0;
317    /**
318     * Clear and fill array with output buffers.
319     */
320    virtual void getOutputBufferArray(Vector<sp<MediaCodecBuffer>> *array) = 0;
321
322protected:
323    std::unique_ptr<CodecBase::BufferCallback> mCallback;
324    sp<ICrypto> mCrypto;
325    sp<IDescrambler> mDescrambler;
326};
327
328}  // namespace android
329
330#endif  // CODEC_BASE_H_
331
332