• 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 <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