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