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