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 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 * Notify MediaCodec that there are metrics to be updated. 187 * 188 * @param updatedMetrics metrics need to be updated. 189 */ 190 virtual void onMetricsUpdated(const sp<AMessage> &updatedMetrics) = 0; 191 }; 192 193 /** 194 * This interface defines events firing from BufferChannelBase back to MediaCodec. 195 * All methods must not block. 196 */ 197 class BufferCallback { 198 public: 199 virtual ~BufferCallback() = default; 200 201 /** 202 * Notify MediaCodec that an input buffer is available with given index. 203 * When BufferChannelBase::getInputBufferArray() is not called, 204 * BufferChannelBase may report different buffers with the same index if 205 * MediaCodec already queued/discarded the buffer. After calling 206 * BufferChannelBase::getInputBufferArray(), the buffer and index match the 207 * returned array. 208 */ 209 virtual void onInputBufferAvailable( 210 size_t index, const sp<MediaCodecBuffer> &buffer) = 0; 211 /** 212 * Notify MediaCodec that an output buffer is available with given index. 213 * When BufferChannelBase::getOutputBufferArray() is not called, 214 * BufferChannelBase may report different buffers with the same index if 215 * MediaCodec already queued/discarded the buffer. After calling 216 * BufferChannelBase::getOutputBufferArray(), the buffer and index match the 217 * returned array. 218 */ 219 virtual void onOutputBufferAvailable( 220 size_t index, const sp<MediaCodecBuffer> &buffer) = 0; 221 }; 222 enum { 223 kMaxCodecBufferSize = 8192 * 4096 * 4, // 8K RGBA 224 }; 225 setCallbackCodecBase226 inline void setCallback(std::unique_ptr<CodecCallback> &&callback) { 227 mCallback = std::move(callback); 228 } 229 virtual std::shared_ptr<BufferChannelBase> getBufferChannel() = 0; 230 231 virtual void initiateAllocateComponent(const sp<AMessage> &msg) = 0; 232 virtual void initiateConfigureComponent(const sp<AMessage> &msg) = 0; 233 virtual void initiateCreateInputSurface() = 0; 234 virtual void initiateSetInputSurface( 235 const sp<PersistentSurface> &surface) = 0; 236 virtual void initiateStart() = 0; 237 virtual void initiateShutdown(bool keepComponentAllocated = false) = 0; 238 239 // require an explicit message handler 240 virtual void onMessageReceived(const sp<AMessage> &msg) = 0; 241 setSurfaceCodecBase242 virtual status_t setSurface(const sp<Surface>& /*surface*/) { return INVALID_OPERATION; } 243 244 virtual void signalFlush() = 0; 245 virtual void signalResume() = 0; 246 247 virtual void signalRequestIDRFrame() = 0; 248 virtual void signalSetParameters(const sp<AMessage> &msg) = 0; 249 virtual void signalEndOfInputStream() = 0; 250 251 /** 252 * Query supported parameters from this instance, and fill |names| with the 253 * names of the parameters. 254 * 255 * \param names string vector to fill with supported parameters. 256 * \return OK if successful; 257 * BAD_VALUE if |names| is null; 258 * INVALID_OPERATION if already released; 259 * ERROR_UNSUPPORTED if not supported. 260 */ 261 virtual status_t querySupportedParameters(std::vector<std::string> *names); 262 /** 263 * Fill |desc| with description of the parameter with |name|. 264 * 265 * \param name name of the parameter to describe 266 * \param desc pointer to CodecParameterDescriptor to be filled 267 * \return OK if successful; 268 * BAD_VALUE if |desc| is null; 269 * NAME_NOT_FOUND if |name| is not recognized by the component; 270 * INVALID_OPERATION if already released; 271 * ERROR_UNSUPPORTED if not supported. 272 */ 273 virtual status_t describeParameter( 274 const std::string &name, 275 CodecParameterDescriptor *desc); 276 /** 277 * Subscribe to parameters in |names| and get output format change event 278 * when they change. 279 * Unrecognized / already subscribed parameters are ignored. 280 * 281 * \param names names of parameters to subscribe 282 * \return OK if successful; 283 * INVALID_OPERATION if already released; 284 * ERROR_UNSUPPORTED if not supported. 285 */ 286 virtual status_t subscribeToParameters(const std::vector<std::string> &names); 287 /** 288 * Unsubscribe from parameters in |names| and no longer get 289 * output format change event when they change. 290 * Unrecognized / already unsubscribed parameters are ignored. 291 * 292 * \param names names of parameters to unsubscribe 293 * \return OK if successful; 294 * INVALID_OPERATION if already released; 295 * ERROR_UNSUPPORTED if not supported. 296 */ 297 virtual status_t unsubscribeFromParameters(const std::vector<std::string> &names); 298 299 typedef CodecBase *(*CreateCodecFunc)(void); 300 typedef PersistentSurface *(*CreateInputSurfaceFunc)(void); 301 302 protected: 303 CodecBase() = default; 304 virtual ~CodecBase() = default; 305 306 std::unique_ptr<CodecCallback> mCallback; 307 308 private: 309 DISALLOW_EVIL_CONSTRUCTORS(CodecBase); 310 }; 311 312 /** 313 * A channel between MediaCodec and CodecBase object which manages buffer 314 * passing. Only MediaCodec is expected to call these methods, and 315 * underlying CodecBase implementation should define its own interface 316 * separately for itself. 317 * 318 * Concurrency assumptions: 319 * 320 * 1) Clients may access the object at multiple threads concurrently. 321 * 2) All methods do not call underlying CodecBase object while holding a lock. 322 * 3) Code inside critical section executes within 1ms. 323 */ 324 class BufferChannelBase { 325 public: 326 BufferChannelBase() = default; 327 virtual ~BufferChannelBase() = default; 328 setCallback(std::unique_ptr<CodecBase::BufferCallback> && callback)329 inline void setCallback(std::unique_ptr<CodecBase::BufferCallback> &&callback) { 330 mCallback = std::move(callback); 331 } 332 setCrypto(const sp<ICrypto> &)333 virtual void setCrypto(const sp<ICrypto> &) {} setDescrambler(const sp<IDescrambler> &)334 virtual void setDescrambler(const sp<IDescrambler> &) {} 335 336 /** 337 * Queue an input buffer into the buffer channel. 338 * 339 * @return OK if successful; 340 * -ENOENT if the buffer is not known (TODO: this should be 341 * handled gracefully in the future, here and below). 342 */ 343 virtual status_t queueInputBuffer(const sp<MediaCodecBuffer> &buffer) = 0; 344 /** 345 * Queue a secure input buffer into the buffer channel. 346 * 347 * @return OK if successful; 348 * -ENOENT if the buffer is not known; 349 * -ENOSYS if mCrypto is not set so that decryption is not 350 * possible; 351 * other errors if decryption failed. 352 */ 353 virtual status_t queueSecureInputBuffer( 354 const sp<MediaCodecBuffer> &buffer, 355 bool secure, 356 const uint8_t *key, 357 const uint8_t *iv, 358 CryptoPlugin::Mode mode, 359 CryptoPlugin::Pattern pattern, 360 const CryptoPlugin::SubSample *subSamples, 361 size_t numSubSamples, 362 AString *errorDetailMsg) = 0; 363 /** 364 * Attach a Codec 2.0 buffer to MediaCodecBuffer. 365 * 366 * @return OK if successful; 367 * -ENOENT if index is not recognized 368 * -ENOSYS if attaching buffer is not possible or not supported 369 */ attachBuffer(const std::shared_ptr<C2Buffer> & c2Buffer,const sp<MediaCodecBuffer> & buffer)370 virtual status_t attachBuffer( 371 const std::shared_ptr<C2Buffer> &c2Buffer, 372 const sp<MediaCodecBuffer> &buffer) { 373 (void)c2Buffer; 374 (void)buffer; 375 return -ENOSYS; 376 } 377 /** 378 * Attach an encrypted HidlMemory buffer to an index 379 * 380 * @return OK if successful; 381 * -ENOENT if index is not recognized 382 * -ENOSYS if attaching buffer is not possible or not supported 383 */ 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)384 virtual status_t attachEncryptedBuffer( 385 const sp<hardware::HidlMemory> &memory, 386 bool secure, 387 const uint8_t *key, 388 const uint8_t *iv, 389 CryptoPlugin::Mode mode, 390 CryptoPlugin::Pattern pattern, 391 size_t offset, 392 const CryptoPlugin::SubSample *subSamples, 393 size_t numSubSamples, 394 const sp<MediaCodecBuffer> &buffer, 395 AString* errorDetailMsg) { 396 (void)memory; 397 (void)secure; 398 (void)key; 399 (void)iv; 400 (void)mode; 401 (void)pattern; 402 (void)offset; 403 (void)subSamples; 404 (void)numSubSamples; 405 (void)buffer; 406 (void)errorDetailMsg; 407 return -ENOSYS; 408 } 409 /** 410 * Request buffer rendering at specified time. 411 * 412 * @param timestampNs nanosecond timestamp for rendering time. 413 * @return OK if successful; 414 * -ENOENT if the buffer is not known. 415 */ 416 virtual status_t renderOutputBuffer( 417 const sp<MediaCodecBuffer> &buffer, int64_t timestampNs) = 0; 418 419 /** 420 * Poll for updates about rendered buffers. 421 * 422 * Triggers callbacks to CodecCallback::onOutputFramesRendered. 423 */ 424 virtual void pollForRenderedBuffers() = 0; 425 426 /** 427 * Discard a buffer to the underlying CodecBase object. 428 * 429 * TODO: remove once this operation can be handled by just clearing the 430 * reference. 431 * 432 * @return OK if successful; 433 * -ENOENT if the buffer is not known. 434 */ 435 virtual status_t discardBuffer(const sp<MediaCodecBuffer> &buffer) = 0; 436 /** 437 * Clear and fill array with input buffers. 438 */ 439 virtual void getInputBufferArray(Vector<sp<MediaCodecBuffer>> *array) = 0; 440 /** 441 * Clear and fill array with output buffers. 442 */ 443 virtual void getOutputBufferArray(Vector<sp<MediaCodecBuffer>> *array) = 0; 444 445 /** 446 * Convert binder IMemory to drm SharedBuffer 447 * 448 * \param memory IMemory object to store encrypted content. 449 * \param heapSeqNum Heap sequence number from ICrypto; -1 if N/A 450 * \param buf SharedBuffer structure to fill. 451 */ 452 static void IMemoryToSharedBuffer( 453 const sp<IMemory> &memory, 454 int32_t heapSeqNum, 455 hardware::drm::V1_0::SharedBuffer *buf); 456 457 protected: 458 std::unique_ptr<CodecBase::BufferCallback> mCallback; 459 }; 460 461 } // namespace android 462 463 #endif // CODEC_BASE_H_ 464