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