xref: /aosp_15_r20/external/v4l2_codec2/components/include/v4l2_codec2/components/DecodeComponent.h (revision 0ec5a0ec62797f775085659156625e7f1bdb369f)
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