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 <memory> 9 10 #include <C2Component.h> 11 #include <C2ComponentFactory.h> 12 #include <C2Work.h> 13 #include <base/memory/scoped_refptr.h> 14 #include <base/memory/weak_ptr.h> 15 #include <base/sequenced_task_runner.h> 16 #include <base/synchronization/waitable_event.h> 17 #include <base/threading/thread.h> 18 19 #include <v4l2_codec2/components/V4L2DecodeInterface.h> 20 #include <v4l2_codec2/components/VideoDecoder.h> 21 #include <v4l2_codec2/components/VideoFramePool.h> 22 #include <v4l2_device.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 destroyTask(); 63 void startTask(c2_status_t* status); 64 void stopTask(); 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 void getVideoFramePool(std::unique_ptr<VideoFramePool>* pool, const media::Size& size, 74 HalPixelFormat pixelFormat, size_t numBuffers); 75 // Detect and report works with no-show frame, only used at VP8 and VP9. 76 void detectNoShowFrameWorksAndReportIfFinished(const C2WorkOrdinalStruct& currOrdinal); 77 78 // Finish callbacks of each method. 79 void onOutputFrameReady(std::unique_ptr<VideoFrame> frame); 80 void onDecodeDone(int32_t bitstreamId, VideoDecoder::DecodeStatus status); 81 void onDrainDone(VideoDecoder::DecodeStatus status); 82 void onFlushDone(); 83 84 // Try to process decoding works at |mPendingWorks|. 85 void pumpReportWork(); 86 // Report finished work. 87 bool reportWorkIfFinished(int32_t bitstreamId); 88 bool reportEOSWork(); 89 void reportAbandonedWorks(); 90 bool reportWork(std::unique_ptr<C2Work> work); 91 // Report error when any error occurs. 92 void reportError(c2_status_t error); 93 94 // The pointer of component interface implementation. 95 std::shared_ptr<V4L2DecodeInterface> mIntfImpl; 96 // The pointer of component interface. 97 const std::shared_ptr<C2ComponentInterface> mIntf; 98 // The pointer of component listener. 99 std::shared_ptr<Listener> mListener; 100 101 std::unique_ptr<VideoDecoder> mDecoder; 102 // The queue of works that haven't processed and sent to |mDecoder|. 103 std::queue<std::unique_ptr<C2Work>> mPendingWorks; 104 // The works whose input buffers are sent to |mDecoder|. The key is the 105 // bitstream ID of work's input buffer. 106 std::map<int32_t, std::unique_ptr<C2Work>> mWorksAtDecoder; 107 // The bitstream ID of the works that output frames have been returned from |mDecoder|. 108 // The order is display order. 109 std::queue<int32_t> mOutputBitstreamIds; 110 111 // Set to true when decoding the protected playback. 112 bool mIsSecure = false; 113 // The component state. 114 std::atomic<ComponentState> mComponentState{ComponentState::STOPPED}; 115 // Whether we are currently draining the component. This is set when the component is processing 116 // the drain request, and unset either after reportEOSWork() (EOS is outputted), or 117 // reportAbandonedWorks() (drain is cancelled and works are abandoned). 118 bool mIsDraining = false; 119 120 // The mutex lock to synchronize start/stop/reset/release calls. 121 std::mutex mStartStopLock; 122 ::base::WaitableEvent mStartStopDone; 123 124 // The color aspects parameter for current decoded output buffers. 125 std::shared_ptr<C2StreamColorAspectsInfo::output> mCurrentColorAspects; 126 // The flag of pending color aspects change. This should be set once we have parsed color 127 // aspects from bitstream by parseCodedColorAspects(), at the same time recorded input frame 128 // index into |mPendingColorAspectsChangeFrameIndex|. 129 // When this flag is true and the corresponding frame index is not less than 130 // |mPendingColorAspectsChangeFrameIndex| for the output buffer in onOutputBufferDone(), update 131 // |mCurrentColorAspects| from component interface and reset the flag. 132 bool mPendingColorAspectsChange = false; 133 // The record of frame index to update color aspects. Details as above. 134 uint64_t mPendingColorAspectsChangeFrameIndex; 135 136 // The device task runner and its sequence checker. We should interact with 137 // |mDevice| on this. 138 ::base::Thread mDecoderThread{"V4L2DecodeComponentDecoderThread"}; 139 scoped_refptr<::base::SequencedTaskRunner> mDecoderTaskRunner; 140 141 ::base::WeakPtrFactory<V4L2DecodeComponent> mWeakThisFactory{this}; 142 ::base::WeakPtr<V4L2DecodeComponent> mWeakThis; 143 }; 144 145 } // namespace android 146 147 #endif // ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_DECODE_COMPONENT_H 148