• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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