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 <media/stagefright/ResourceInfo.h> 35 #include <system/graphics.h> 36 #include <utils/NativeHandle.h> 37 38 class C2Buffer; 39 40 namespace android { 41 class BufferChannelBase; 42 struct BufferProducerWrapper; 43 class MediaCodecBuffer; 44 struct PersistentSurface; 45 class RenderedFrameInfo; 46 class Surface; 47 struct ICrypto; 48 class IMemory; 49 50 namespace hardware { 51 class HidlMemory; 52 namespace cas { 53 namespace native { 54 namespace V1_0 { 55 struct IDescrambler; 56 }}} 57 namespace drm { 58 namespace V1_0 { 59 struct SharedBuffer; 60 }} 61 } 62 63 using hardware::cas::native::V1_0::IDescrambler; 64 65 struct AccessUnitInfo { 66 uint32_t mFlags; 67 uint32_t mSize; 68 int64_t mTimestamp; AccessUnitInfoAccessUnitInfo69 AccessUnitInfo(uint32_t flags, uint32_t size, int64_t ptsUs) 70 :mFlags(flags), mSize(size), mTimestamp(ptsUs) { 71 } ~AccessUnitInfoAccessUnitInfo72 ~AccessUnitInfo() {} 73 }; 74 75 struct CodecCryptoInfo { 76 size_t mNumSubSamples{0}; 77 CryptoPlugin::SubSample *mSubSamples{nullptr}; 78 uint8_t *mIv{nullptr}; 79 uint8_t *mKey{nullptr}; 80 enum CryptoPlugin::Mode mMode; 81 CryptoPlugin::Pattern mPattern; 82 ~CodecCryptoInfoCodecCryptoInfo83 virtual ~CodecCryptoInfo() {} 84 protected: CodecCryptoInfoCodecCryptoInfo85 CodecCryptoInfo(): 86 mNumSubSamples(0), 87 mSubSamples(nullptr), 88 mIv(nullptr), 89 mKey(nullptr), 90 mMode{CryptoPlugin::kMode_Unencrypted}, 91 mPattern{0, 0} { 92 } 93 }; 94 95 struct CodecParameterDescriptor { 96 std::string name; 97 AMessage::Type type; 98 }; 99 100 struct CodecBase : public AHandler, /* static */ ColorUtils { 101 /** 102 * This interface defines events firing from CodecBase back to MediaCodec. 103 * All methods must not block. 104 */ 105 class CodecCallback { 106 public: 107 virtual ~CodecCallback() = default; 108 109 /** 110 * Notify MediaCodec for seeing an output EOS. 111 * 112 * @param err the underlying cause of the EOS. If the value is neither 113 * OK nor ERROR_END_OF_STREAM, the EOS is declared 114 * prematurely for that error. 115 */ 116 virtual void onEos(status_t err) = 0; 117 /** 118 * Notify MediaCodec that start operation is complete. 119 */ 120 virtual void onStartCompleted() = 0; 121 /** 122 * Notify MediaCodec that stop operation is complete. 123 */ 124 virtual void onStopCompleted() = 0; 125 /** 126 * Notify MediaCodec that release operation is complete. 127 */ 128 virtual void onReleaseCompleted() = 0; 129 /** 130 * Notify MediaCodec that flush operation is complete. 131 */ 132 virtual void onFlushCompleted() = 0; 133 /** 134 * Notify MediaCodec that an error is occurred. 135 * 136 * @param err an error code for the occurred error. 137 * @param actionCode an action code for severity of the error. 138 */ 139 virtual void onError(status_t err, enum ActionCode actionCode) = 0; 140 /** 141 * Notify MediaCodec that the underlying component is allocated. 142 * 143 * @param componentName the unique name of the component specified in 144 * MediaCodecList. 145 */ 146 virtual void onComponentAllocated(const char *componentName) = 0; 147 /** 148 * Notify MediaCodec that the underlying component is configured. 149 * 150 * @param inputFormat an input format at configure time. 151 * @param outputFormat an output format at configure time. 152 */ 153 virtual void onComponentConfigured( 154 const sp<AMessage> &inputFormat, const sp<AMessage> &outputFormat) = 0; 155 /** 156 * Notify MediaCodec that the input surface is created. 157 * 158 * @param inputFormat an input format at surface creation. Formats 159 * could change from the previous state as a result 160 * of creating a surface. 161 * @param outputFormat an output format at surface creation. 162 * @param inputSurface the created surface. 163 */ 164 virtual void onInputSurfaceCreated( 165 const sp<AMessage> &inputFormat, 166 const sp<AMessage> &outputFormat, 167 const sp<BufferProducerWrapper> &inputSurface) = 0; 168 /** 169 * Notify MediaCodec that the input surface creation is failed. 170 * 171 * @param err an error code of the cause. 172 */ 173 virtual void onInputSurfaceCreationFailed(status_t err) = 0; 174 /** 175 * Notify MediaCodec that the component accepted the provided input 176 * surface. 177 * 178 * @param inputFormat an input format at surface assignment. Formats 179 * could change from the previous state as a result 180 * of assigning a surface. 181 * @param outputFormat an output format at surface assignment. 182 */ 183 virtual void onInputSurfaceAccepted( 184 const sp<AMessage> &inputFormat, 185 const sp<AMessage> &outputFormat) = 0; 186 /** 187 * Notify MediaCodec that the component declined the provided input 188 * surface. 189 * 190 * @param err an error code of the cause. 191 */ 192 virtual void onInputSurfaceDeclined(status_t err) = 0; 193 /** 194 * Noitfy MediaCodec that the requested input EOS is sent to the input 195 * surface. 196 * 197 * @param err an error code returned from the surface. If there is no 198 * input surface, the value is INVALID_OPERATION. 199 */ 200 virtual void onSignaledInputEOS(status_t err) = 0; 201 /** 202 * Notify MediaCodec that output frames are rendered with information on 203 * those frames. 204 * 205 * @param done a list of rendered frames. 206 */ 207 virtual void onOutputFramesRendered(const std::list<RenderedFrameInfo> &done) = 0; 208 /** 209 * Notify MediaCodec that output buffers are changed. 210 */ 211 virtual void onOutputBuffersChanged() = 0; 212 /** 213 * Notify MediaCodec that the first tunnel frame is ready. 214 */ 215 virtual void onFirstTunnelFrameReady() = 0; 216 /** 217 * Notify MediaCodec that there are metrics to be updated. 218 * 219 * @param updatedMetrics metrics need to be updated. 220 */ 221 virtual void onMetricsUpdated(const sp<AMessage> &updatedMetrics) = 0; 222 /** 223 * Notify MediaCodec that there is a change in the required resources. 224 */ 225 virtual void onRequiredResourcesChanged() = 0; 226 }; 227 228 /** 229 * This interface defines events firing from BufferChannelBase back to MediaCodec. 230 * All methods must not block. 231 */ 232 class BufferCallback { 233 public: 234 virtual ~BufferCallback() = default; 235 236 /** 237 * Notify MediaCodec that an input buffer is available with given index. 238 * When BufferChannelBase::getInputBufferArray() is not called, 239 * BufferChannelBase may report different buffers with the same index if 240 * MediaCodec already queued/discarded the buffer. After calling 241 * BufferChannelBase::getInputBufferArray(), the buffer and index match the 242 * returned array. 243 */ 244 virtual void onInputBufferAvailable( 245 size_t index, const sp<MediaCodecBuffer> &buffer) = 0; 246 /** 247 * Notify MediaCodec that an output buffer is available with given index. 248 * When BufferChannelBase::getOutputBufferArray() is not called, 249 * BufferChannelBase may report different buffers with the same index if 250 * MediaCodec already queued/discarded the buffer. After calling 251 * BufferChannelBase::getOutputBufferArray(), the buffer and index match the 252 * returned array. 253 */ 254 virtual void onOutputBufferAvailable( 255 size_t index, const sp<MediaCodecBuffer> &buffer) = 0; 256 }; 257 enum { 258 kMaxCodecBufferSize = 8192 * 4096 * 4, // 8K RGBA 259 }; 260 setCallbackCodecBase261 inline void setCallback(std::unique_ptr<CodecCallback> &&callback) { 262 mCallback = std::move(callback); 263 } 264 virtual std::shared_ptr<BufferChannelBase> getBufferChannel() = 0; 265 266 virtual void initiateAllocateComponent(const sp<AMessage> &msg) = 0; 267 virtual void initiateConfigureComponent(const sp<AMessage> &msg) = 0; 268 virtual void initiateCreateInputSurface() = 0; 269 virtual void initiateSetInputSurface( 270 const sp<PersistentSurface> &surface) = 0; 271 virtual void initiateStart() = 0; 272 virtual void initiateShutdown(bool keepComponentAllocated = false) = 0; 273 274 // require an explicit message handler 275 virtual void onMessageReceived(const sp<AMessage> &msg) = 0; 276 setSurfaceCodecBase277 virtual status_t setSurface(const sp<Surface>& /*surface*/, uint32_t /*generation*/) { 278 return INVALID_OPERATION; 279 } 280 281 virtual void signalFlush() = 0; 282 virtual void signalResume() = 0; 283 284 virtual void signalRequestIDRFrame() = 0; 285 virtual void signalSetParameters(const sp<AMessage> &msg) = 0; 286 virtual void signalEndOfInputStream() = 0; 287 288 /** 289 * Query supported parameters from this instance, and fill |names| with the 290 * names of the parameters. 291 * 292 * \param names string vector to fill with supported parameters. 293 * \return OK if successful; 294 * BAD_VALUE if |names| is null; 295 * INVALID_OPERATION if already released; 296 * ERROR_UNSUPPORTED if not supported. 297 */ 298 virtual status_t querySupportedParameters(std::vector<std::string> *names); 299 /** 300 * Fill |desc| with description of the parameter with |name|. 301 * 302 * \param name name of the parameter to describe 303 * \param desc pointer to CodecParameterDescriptor to be filled 304 * \return OK if successful; 305 * BAD_VALUE if |desc| is null; 306 * NAME_NOT_FOUND if |name| is not recognized by the component; 307 * INVALID_OPERATION if already released; 308 * ERROR_UNSUPPORTED if not supported. 309 */ 310 virtual status_t describeParameter( 311 const std::string &name, 312 CodecParameterDescriptor *desc); 313 /** 314 * Subscribe to parameters in |names| and get output format change event 315 * when they change. 316 * Unrecognized / already subscribed parameters are ignored. 317 * 318 * \param names names of parameters to subscribe 319 * \return OK if successful; 320 * INVALID_OPERATION if already released; 321 * ERROR_UNSUPPORTED if not supported. 322 */ 323 virtual status_t subscribeToParameters(const std::vector<std::string> &names); 324 /** 325 * Unsubscribe from parameters in |names| and no longer get 326 * output format change event when they change. 327 * Unrecognized / already unsubscribed parameters are ignored. 328 * 329 * \param names names of parameters to unsubscribe 330 * \return OK if successful; 331 * INVALID_OPERATION if already released; 332 * ERROR_UNSUPPORTED if not supported. 333 */ 334 virtual status_t unsubscribeFromParameters(const std::vector<std::string> &names); 335 336 /** 337 * Get the required resources for the compomemt at the current 338 * configuration. 339 * 340 */ 341 virtual std::vector<InstanceResourceInfo> getRequiredSystemResources(); 342 343 typedef CodecBase *(*CreateCodecFunc)(void); 344 typedef PersistentSurface *(*CreateInputSurfaceFunc)(void); 345 346 protected: 347 CodecBase() = default; 348 virtual ~CodecBase() = default; 349 350 std::unique_ptr<CodecCallback> mCallback; 351 352 private: 353 DISALLOW_EVIL_CONSTRUCTORS(CodecBase); 354 }; 355 356 /** 357 * A channel between MediaCodec and CodecBase object which manages buffer 358 * passing. Only MediaCodec is expected to call these methods, and 359 * underlying CodecBase implementation should define its own interface 360 * separately for itself. 361 * 362 * Concurrency assumptions: 363 * 364 * 1) Clients may access the object at multiple threads concurrently. 365 * 2) All methods do not call underlying CodecBase object while holding a lock. 366 * 3) Code inside critical section executes within 1ms. 367 */ 368 class BufferChannelBase { 369 public: 370 BufferChannelBase() = default; 371 virtual ~BufferChannelBase() = default; 372 setCallback(std::unique_ptr<CodecBase::BufferCallback> && callback)373 inline void setCallback(std::unique_ptr<CodecBase::BufferCallback> &&callback) { 374 mCallback = std::move(callback); 375 } 376 setCrypto(const sp<ICrypto> &)377 virtual void setCrypto(const sp<ICrypto> &) {} setDescrambler(const sp<IDescrambler> &)378 virtual void setDescrambler(const sp<IDescrambler> &) {} 379 380 /** 381 * Queue an input buffer into the buffer channel. 382 * 383 * @return OK if successful; 384 * -ENOENT if the buffer is not known (TODO: this should be 385 * handled gracefully in the future, here and below). 386 */ 387 virtual status_t queueInputBuffer(const sp<MediaCodecBuffer> &buffer) = 0; 388 /** 389 * Queue a secure input buffer into the buffer channel. 390 * 391 * @return OK if successful; 392 * -ENOENT if the buffer is not known; 393 * -ENOSYS if mCrypto is not set so that decryption is not 394 * possible; 395 * other errors if decryption failed. 396 */ 397 virtual status_t queueSecureInputBuffer( 398 const sp<MediaCodecBuffer> &buffer, 399 bool secure, 400 const uint8_t *key, 401 const uint8_t *iv, 402 CryptoPlugin::Mode mode, 403 CryptoPlugin::Pattern pattern, 404 const CryptoPlugin::SubSample *subSamples, 405 size_t numSubSamples, 406 AString *errorDetailMsg) = 0; 407 408 /** 409 * Queue a secure input buffer with multiple access units into the buffer channel. 410 * 411 * @param buffer The buffer to queue. The access unit delimiters and crypto 412 * subsample information is included in the buffer metadata. 413 * @param secure Whether the buffer is secure. 414 * @param errorDetailMsg The error message to be set in case of error. 415 * @return OK if successful; 416 * -ENOENT of the buffer is not known 417 * -ENOSYS if mCrypto is not set so that decryption is not 418 * possible; 419 * other errors if decryption failed. 420 */ queueSecureInputBuffers(const sp<MediaCodecBuffer> & buffer,bool secure,AString * errorDetailMsg)421 virtual status_t queueSecureInputBuffers( 422 const sp<MediaCodecBuffer> &buffer, 423 bool secure, 424 AString *errorDetailMsg) { 425 (void)buffer; 426 (void)secure; 427 (void)errorDetailMsg; 428 return -ENOSYS; 429 } 430 431 /** 432 * Attach a Codec 2.0 buffer to MediaCodecBuffer. 433 * 434 * @return OK if successful; 435 * -ENOENT if index is not recognized 436 * -ENOSYS if attaching buffer is not possible or not supported 437 */ attachBuffer(const std::shared_ptr<C2Buffer> & c2Buffer,const sp<MediaCodecBuffer> & buffer)438 virtual status_t attachBuffer( 439 const std::shared_ptr<C2Buffer> &c2Buffer, 440 const sp<MediaCodecBuffer> &buffer) { 441 (void)c2Buffer; 442 (void)buffer; 443 return -ENOSYS; 444 } 445 /** 446 * Attach an encrypted HidlMemory buffer to an index 447 * 448 * @return OK if successful; 449 * -ENOENT if index is not recognized 450 * -ENOSYS if attaching buffer is not possible or not supported 451 */ 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,AString * errorDetailMsg)452 virtual status_t attachEncryptedBuffer( 453 const sp<hardware::HidlMemory> &memory, 454 bool secure, 455 const uint8_t *key, 456 const uint8_t *iv, 457 CryptoPlugin::Mode mode, 458 CryptoPlugin::Pattern pattern, 459 size_t offset, 460 const CryptoPlugin::SubSample *subSamples, 461 size_t numSubSamples, 462 const sp<MediaCodecBuffer> &buffer, 463 AString* errorDetailMsg) { 464 (void)memory; 465 (void)secure; 466 (void)key; 467 (void)iv; 468 (void)mode; 469 (void)pattern; 470 (void)offset; 471 (void)subSamples; 472 (void)numSubSamples; 473 (void)buffer; 474 (void)errorDetailMsg; 475 return -ENOSYS; 476 } 477 478 /** 479 * Attach an encrypted HidlMemory buffer containing multiple access units to an index 480 * 481 * @param memory The memory to attach. 482 * @param offset index??? 483 * @param buffer The MediaCodecBuffer to attach the memory to. The access 484 * unit delimiters and crypto subsample information is included 485 * in the buffer metadata. 486 * @param secure Whether the buffer is secure. 487 * @param errorDetailMsg The error message to be set if an error occurs. 488 * @return OK if successful; 489 * -ENOENT if index is not recognized 490 * -ENOSYS if attaching buffer is not possible or not supported 491 */ attachEncryptedBuffers(const sp<hardware::HidlMemory> & memory,size_t offset,const sp<MediaCodecBuffer> & buffer,bool secure,AString * errorDetailMsg)492 virtual status_t attachEncryptedBuffers( 493 const sp<hardware::HidlMemory> &memory, 494 size_t offset, 495 const sp<MediaCodecBuffer> &buffer, 496 bool secure, 497 AString* errorDetailMsg) { 498 (void)memory; 499 (void)offset; 500 (void)buffer; 501 (void)secure; 502 (void)errorDetailMsg; 503 return -ENOSYS; 504 } 505 /** 506 * Request buffer rendering at specified time. 507 * 508 * @param timestampNs nanosecond timestamp for rendering time. 509 * @return OK if successful; 510 * -ENOENT if the buffer is not known. 511 */ 512 virtual status_t renderOutputBuffer( 513 const sp<MediaCodecBuffer> &buffer, int64_t timestampNs) = 0; 514 515 /** 516 * Poll for updates about rendered buffers. 517 * 518 * Triggers callbacks to CodecCallback::onOutputFramesRendered. 519 */ 520 virtual void pollForRenderedBuffers() = 0; 521 522 /** 523 * Notify a buffer is released from output surface. 524 * 525 * @param generation MediaCodec's surface specifier 526 */ onBufferReleasedFromOutputSurface(uint32_t)527 virtual void onBufferReleasedFromOutputSurface(uint32_t /*generation*/) { 528 // default: no-op 529 }; 530 531 /** 532 * Notify a buffer is attached to output surface. 533 * 534 * @param generation MediaCodec's surface specifier 535 */ onBufferAttachedToOutputSurface(uint32_t)536 virtual void onBufferAttachedToOutputSurface(uint32_t /*generation*/) { 537 // default: no-op 538 }; 539 540 /** 541 * Discard a buffer to the underlying CodecBase object. 542 * 543 * TODO: remove once this operation can be handled by just clearing the 544 * reference. 545 * 546 * @return OK if successful; 547 * -ENOENT if the buffer is not known. 548 */ 549 virtual status_t discardBuffer(const sp<MediaCodecBuffer> &buffer) = 0; 550 /** 551 * Clear and fill array with input buffers. 552 */ 553 virtual void getInputBufferArray(Vector<sp<MediaCodecBuffer>> *array) = 0; 554 /** 555 * Clear and fill array with output buffers. 556 */ 557 virtual void getOutputBufferArray(Vector<sp<MediaCodecBuffer>> *array) = 0; 558 559 /** 560 * Convert binder IMemory to drm SharedBuffer 561 * 562 * \param memory IMemory object to store encrypted content. 563 * \param heapSeqNum Heap sequence number from ICrypto; -1 if N/A 564 * \param buf SharedBuffer structure to fill. 565 */ 566 static void IMemoryToSharedBuffer( 567 const sp<IMemory> &memory, 568 int32_t heapSeqNum, 569 hardware::drm::V1_0::SharedBuffer *buf); 570 571 protected: 572 std::unique_ptr<CodecBase::BufferCallback> mCallback; 573 }; 574 575 } // namespace android 576 577 #endif // CODEC_BASE_H_ 578