1 // Copyright 2023 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef ANDROID_V4L2_CODEC2_COMPONENTS_DECODE_COMPONENT_H 6 #define ANDROID_V4L2_CODEC2_COMPONENTS_DECODE_COMPONENT_H 7 8 #include <atomic> 9 #include <memory> 10 11 #include <C2Component.h> 12 #include <C2ComponentFactory.h> 13 #include <C2Work.h> 14 #include <base/memory/scoped_refptr.h> 15 #include <base/memory/weak_ptr.h> 16 #include <base/sequenced_task_runner.h> 17 #include <base/synchronization/waitable_event.h> 18 #include <base/threading/thread.h> 19 20 #include <v4l2_codec2/components/DecodeInterface.h> 21 #include <v4l2_codec2/components/VideoDecoder.h> 22 #include <v4l2_codec2/components/VideoFramePool.h> 23 24 namespace android { 25 26 class DecodeComponent : public C2Component, public std::enable_shared_from_this<DecodeComponent> { 27 public: 28 DecodeComponent(uint32_t debugStreamId, const std::string& name, c2_node_id_t id, 29 const std::shared_ptr<DecodeInterface>& intfImpl); 30 virtual ~DecodeComponent() override; 31 32 // Implementation of C2Component. 33 c2_status_t start() override; 34 c2_status_t stop() override; 35 c2_status_t reset() override; 36 c2_status_t release() override; 37 c2_status_t setListener_vb(const std::shared_ptr<Listener>& listener, 38 c2_blocking_t mayBlock) override; 39 c2_status_t queue_nb(std::list<std::unique_ptr<C2Work>>* const items) override; 40 c2_status_t announce_nb(const std::vector<C2WorkOutline>& items) override; 41 c2_status_t flush_sm(flush_mode_t mode, 42 std::list<std::unique_ptr<C2Work>>* const flushedWork) override; 43 c2_status_t drain_nb(drain_mode_t mode) override; 44 std::shared_ptr<C2ComponentInterface> intf() override; 45 46 protected: 47 // The C2Component state machine. 48 enum class ComponentState { 49 STOPPED, 50 RUNNING, 51 RELEASED, 52 ERROR, 53 }; 54 static const char* ComponentStateToString(ComponentState state); 55 56 // Handle C2Component's public methods on |mDecoderTaskRunner|. 57 virtual void startTask(c2_status_t* status, ::base::WaitableEvent* done) = 0; 58 void stopTask(); 59 void releaseTask(); 60 void queueTask(std::unique_ptr<C2Work> work); 61 void flushTask(); 62 void drainTask(); 63 void setListenerTask(const std::shared_ptr<Listener>& listener, ::base::WaitableEvent* done); 64 65 // Try to process pending works at |mPendingWorks|. Paused when |mIsDraining| is set. 66 void pumpPendingWorks(); 67 68 void processCSDWork(const int32_t bitstreamId, const C2Work* work); 69 void processWork(const int32_t bitstreamId, const C2Work* work); 70 void processWorkBuffer(const int32_t bitstreamId, const C2ConstLinearBlock& linearBlock); 71 72 // Get the buffer pool. 73 std::unique_ptr<VideoFramePool> getVideoFramePool(const ui::Size& size, 74 HalPixelFormat pixelFormat, 75 size_t numBuffers); 76 // Detect and report works with no-show frame, only used at VP8 and VP9. 77 void detectNoShowFrameWorksAndReportIfFinished(const C2WorkOrdinalStruct& currOrdinal); 78 79 // Finish callbacks of each method. 80 void onOutputFrameReady(std::unique_ptr<VideoFrame> frame); 81 void onDecodeDone(int32_t bitstreamId, VideoDecoder::DecodeStatus status); 82 void onDrainDone(VideoDecoder::DecodeStatus status); 83 void onFlushDone(); 84 85 // Try to process decoding works at |mPendingWorks|. 86 void pumpReportWork(); 87 // Report finished work. 88 bool reportWorkIfFinished(int32_t bitstreamId); 89 bool reportEOSWork(); 90 void reportAbandonedWorks(); 91 bool reportWork(std::unique_ptr<C2Work> work); 92 // Report error when any error occurs. 93 void reportError(c2_status_t error); 94 95 // Identifier used for debugging purposes. 96 uint32_t mDebugStreamId; 97 98 // The pointer of component interface implementation. 99 std::shared_ptr<DecodeInterface> mIntfImpl; 100 // The pointer of component interface. 101 const std::shared_ptr<C2ComponentInterface> mIntf; 102 // The pointer of component listener. 103 std::shared_ptr<Listener> mListener; 104 105 std::unique_ptr<VideoDecoder> mDecoder; 106 // The queue of works that haven't processed and sent to |mDecoder|. 107 std::queue<std::unique_ptr<C2Work>> mPendingWorks; 108 // The works whose input buffers are sent to |mDecoder|. The key is the 109 // bitstream ID of work's input buffer. 110 std::map<int32_t, std::unique_ptr<C2Work>> mWorksAtDecoder; 111 // The bitstream ID of the works that output frames have been returned from |mDecoder|. 112 // The order is display order. 113 std::queue<int32_t> mOutputBitstreamIds; 114 115 // Set to true when decoding the protected playback. 116 bool mIsSecure = false; 117 // The component state. 118 std::atomic<ComponentState> mComponentState{ComponentState::STOPPED}; 119 // Whether we are currently draining the component. This is set when the component is processing 120 // the drain request, and unset either after reportEOSWork() (EOS is outputted), or 121 // reportAbandonedWorks() (drain is cancelled and works are abandoned). 122 bool mIsDraining = false; 123 124 // The mutex lock to synchronize start/stop/reset/release calls. 125 std::mutex mStartStopLock; 126 127 // The color aspects parameter for current decoded output buffers. 128 std::shared_ptr<C2StreamColorAspectsInfo::output> mCurrentColorAspects; 129 // The flag of pending color aspects change. This should be set once we have parsed color 130 // aspects from bitstream by parseCodedColorAspects(), at the same time recorded input frame 131 // index into |mPendingColorAspectsChangeFrameIndex|. 132 // When this flag is true and the corresponding frame index is not less than 133 // |mPendingColorAspectsChangeFrameIndex| for the output buffer in onOutputBufferDone(), update 134 // |mCurrentColorAspects| from component interface and reset the flag. 135 bool mPendingColorAspectsChange = false; 136 // The record of frame index to update color aspects. Details as above. 137 uint64_t mPendingColorAspectsChangeFrameIndex; 138 139 // The device task runner and its sequence checker. We should interact with 140 // |mDevice| on this. 141 ::base::Thread mDecoderThread{"DecodeComponentDecoderThread"}; 142 scoped_refptr<::base::SequencedTaskRunner> mDecoderTaskRunner; 143 144 ::base::WeakPtrFactory<DecodeComponent> mWeakThisFactory{this}; 145 ::base::WeakPtr<DecodeComponent> mWeakThis; 146 }; 147 148 } // namespace android 149 150 #endif // ANDROID_V4L2_CODEC2_COMPONENTS_DECODE_COMPONENT_H 151