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