1 // Copyright 2020 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_V4L2_DECODE_COMPONENT_H 6 #define ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_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/V4L2DecodeInterface.h> 21 #include <v4l2_codec2/components/VideoDecoder.h> 22 #include <v4l2_codec2/components/VideoFramePool.h> 23 24 namespace android { 25 26 class V4L2DecodeComponent : public C2Component, 27 public std::enable_shared_from_this<V4L2DecodeComponent> { 28 public: 29 static std::shared_ptr<C2Component> create(const std::string& name, c2_node_id_t id, 30 const std::shared_ptr<C2ReflectorHelper>& helper, 31 C2ComponentFactory::ComponentDeleter deleter); 32 V4L2DecodeComponent(const std::string& name, c2_node_id_t id, 33 const std::shared_ptr<C2ReflectorHelper>& helper, 34 const std::shared_ptr<V4L2DecodeInterface>& intfImpl); 35 ~V4L2DecodeComponent() override; 36 37 // Implementation of C2Component. 38 c2_status_t start() override; 39 c2_status_t stop() override; 40 c2_status_t reset() override; 41 c2_status_t release() override; 42 c2_status_t setListener_vb(const std::shared_ptr<Listener>& listener, 43 c2_blocking_t mayBlock) override; 44 c2_status_t queue_nb(std::list<std::unique_ptr<C2Work>>* const items) override; 45 c2_status_t announce_nb(const std::vector<C2WorkOutline>& items) override; 46 c2_status_t flush_sm(flush_mode_t mode, 47 std::list<std::unique_ptr<C2Work>>* const flushedWork) override; 48 c2_status_t drain_nb(drain_mode_t mode) override; 49 std::shared_ptr<C2ComponentInterface> intf() override; 50 51 private: 52 // The C2Component state machine. 53 enum class ComponentState { 54 STOPPED, 55 RUNNING, 56 RELEASED, 57 ERROR, 58 }; 59 static const char* ComponentStateToString(ComponentState state); 60 61 // Handle C2Component's public methods on |mDecoderTaskRunner|. 62 void startTask(c2_status_t* status, ::base::WaitableEvent* done); 63 void stopTask(); 64 void releaseTask(); 65 void queueTask(std::unique_ptr<C2Work> work); 66 void flushTask(); 67 void drainTask(); 68 void setListenerTask(const std::shared_ptr<Listener>& listener, ::base::WaitableEvent* done); 69 70 // Try to process pending works at |mPendingWorks|. Paused when |mIsDraining| is set. 71 void pumpPendingWorks(); 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 static std::atomic<int32_t> sConcurrentInstances; 96 97 // The pointer of component interface implementation. 98 std::shared_ptr<V4L2DecodeInterface> mIntfImpl; 99 // The pointer of component interface. 100 const std::shared_ptr<C2ComponentInterface> mIntf; 101 // The pointer of component listener. 102 std::shared_ptr<Listener> mListener; 103 104 std::unique_ptr<VideoDecoder> mDecoder; 105 // The queue of works that haven't processed and sent to |mDecoder|. 106 std::queue<std::unique_ptr<C2Work>> mPendingWorks; 107 // The works whose input buffers are sent to |mDecoder|. The key is the 108 // bitstream ID of work's input buffer. 109 std::map<int32_t, std::unique_ptr<C2Work>> mWorksAtDecoder; 110 // The bitstream ID of the works that output frames have been returned from |mDecoder|. 111 // The order is display order. 112 std::queue<int32_t> mOutputBitstreamIds; 113 114 // Set to true when decoding the protected playback. 115 bool mIsSecure = false; 116 // The component state. 117 std::atomic<ComponentState> mComponentState{ComponentState::STOPPED}; 118 // Whether we are currently draining the component. This is set when the component is processing 119 // the drain request, and unset either after reportEOSWork() (EOS is outputted), or 120 // reportAbandonedWorks() (drain is cancelled and works are abandoned). 121 bool mIsDraining = false; 122 123 // The mutex lock to synchronize start/stop/reset/release calls. 124 std::mutex mStartStopLock; 125 126 // The color aspects parameter for current decoded output buffers. 127 std::shared_ptr<C2StreamColorAspectsInfo::output> mCurrentColorAspects; 128 // The flag of pending color aspects change. This should be set once we have parsed color 129 // aspects from bitstream by parseCodedColorAspects(), at the same time recorded input frame 130 // index into |mPendingColorAspectsChangeFrameIndex|. 131 // When this flag is true and the corresponding frame index is not less than 132 // |mPendingColorAspectsChangeFrameIndex| for the output buffer in onOutputBufferDone(), update 133 // |mCurrentColorAspects| from component interface and reset the flag. 134 bool mPendingColorAspectsChange = false; 135 // The record of frame index to update color aspects. Details as above. 136 uint64_t mPendingColorAspectsChangeFrameIndex; 137 138 // The device task runner and its sequence checker. We should interact with 139 // |mDevice| on this. 140 ::base::Thread mDecoderThread{"V4L2DecodeComponentDecoderThread"}; 141 scoped_refptr<::base::SequencedTaskRunner> mDecoderTaskRunner; 142 143 ::base::WeakPtrFactory<V4L2DecodeComponent> mWeakThisFactory{this}; 144 ::base::WeakPtr<V4L2DecodeComponent> mWeakThis; 145 }; 146 147 } // namespace android 148 149 #endif // ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_DECODE_COMPONENT_H 150