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 <list> 22 #include <memory> 23 24 #include <stdint.h> 25 26 #define STRINGIFY_ENUMS 27 28 #include <media/hardware/CryptoAPI.h> 29 #include <media/hardware/HardwareAPI.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 37 namespace android { 38 class BufferChannelBase; 39 struct BufferProducerWrapper; 40 class MediaCodecBuffer; 41 struct PersistentSurface; 42 struct RenderedFrameInfo; 43 class Surface; 44 struct ICrypto; 45 namespace hardware { 46 namespace cas { 47 namespace native { 48 namespace V1_0 { 49 struct IDescrambler; 50 }}}} 51 using hardware::cas::native::V1_0::IDescrambler; 52 53 struct 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 setCallbackCodecBase200 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 setSurfaceCodecBase216 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 typedef CodecBase *(*CreateCodecFunc)(void); 226 typedef PersistentSurface *(*CreateInputSurfaceFunc)(void); 227 228 protected: 229 CodecBase() = default; 230 virtual ~CodecBase() = default; 231 232 std::unique_ptr<CodecCallback> mCallback; 233 234 private: 235 DISALLOW_EVIL_CONSTRUCTORS(CodecBase); 236 }; 237 238 /** 239 * A channel between MediaCodec and CodecBase object which manages buffer 240 * passing. Only MediaCodec is expected to call these methods, and 241 * underlying CodecBase implementation should define its own interface 242 * separately for itself. 243 * 244 * Concurrency assumptions: 245 * 246 * 1) Clients may access the object at multiple threads concurrently. 247 * 2) All methods do not call underlying CodecBase object while holding a lock. 248 * 3) Code inside critical section executes within 1ms. 249 */ 250 class BufferChannelBase { 251 public: 252 virtual ~BufferChannelBase() = default; 253 setCallback(std::unique_ptr<CodecBase::BufferCallback> && callback)254 inline void setCallback(std::unique_ptr<CodecBase::BufferCallback> &&callback) { 255 mCallback = std::move(callback); 256 } 257 258 void setCrypto(const sp<ICrypto> &crypto); 259 260 void setDescrambler(const sp<IDescrambler> &descrambler); 261 262 /** 263 * Queue an input buffer into the buffer channel. 264 * 265 * @return OK if successful; 266 * -ENOENT if the buffer is not known (TODO: this should be 267 * handled gracefully in the future, here and below). 268 */ 269 virtual status_t queueInputBuffer(const sp<MediaCodecBuffer> &buffer) = 0; 270 /** 271 * Queue a secure input buffer into the buffer channel. 272 * 273 * @return OK if successful; 274 * -ENOENT if the buffer is not known; 275 * -ENOSYS if mCrypto is not set so that decryption is not 276 * possible; 277 * other errors if decryption failed. 278 */ 279 virtual status_t queueSecureInputBuffer( 280 const sp<MediaCodecBuffer> &buffer, 281 bool secure, 282 const uint8_t *key, 283 const uint8_t *iv, 284 CryptoPlugin::Mode mode, 285 CryptoPlugin::Pattern pattern, 286 const CryptoPlugin::SubSample *subSamples, 287 size_t numSubSamples, 288 AString *errorDetailMsg) = 0; 289 /** 290 * Request buffer rendering at specified time. 291 * 292 * @param timestampNs nanosecond timestamp for rendering time. 293 * @return OK if successful; 294 * -ENOENT if the buffer is not known. 295 */ 296 virtual status_t renderOutputBuffer( 297 const sp<MediaCodecBuffer> &buffer, int64_t timestampNs) = 0; 298 /** 299 * Discard a buffer to the underlying CodecBase object. 300 * 301 * TODO: remove once this operation can be handled by just clearing the 302 * reference. 303 * 304 * @return OK if successful; 305 * -ENOENT if the buffer is not known. 306 */ 307 virtual status_t discardBuffer(const sp<MediaCodecBuffer> &buffer) = 0; 308 /** 309 * Clear and fill array with input buffers. 310 */ 311 virtual void getInputBufferArray(Vector<sp<MediaCodecBuffer>> *array) = 0; 312 /** 313 * Clear and fill array with output buffers. 314 */ 315 virtual void getOutputBufferArray(Vector<sp<MediaCodecBuffer>> *array) = 0; 316 317 protected: 318 std::unique_ptr<CodecBase::BufferCallback> mCallback; 319 sp<ICrypto> mCrypto; 320 sp<IDescrambler> mDescrambler; 321 }; 322 323 } // namespace android 324 325 #endif // CODEC_BASE_H_ 326