• 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_DECODER_H
6 #define ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_DECODER_H
7 
8 #include <stdint.h>
9 
10 #include <memory>
11 #include <optional>
12 
13 #include <base/callback.h>
14 #include <base/memory/weak_ptr.h>
15 
16 #include <ui/Rect.h>
17 #include <ui/Size.h>
18 #include <v4l2_codec2/common/V4L2Device.h>
19 #include <v4l2_codec2/common/VideoTypes.h>
20 #include <v4l2_codec2/components/VideoDecoder.h>
21 #include <v4l2_codec2/components/VideoFrame.h>
22 #include <v4l2_codec2/components/VideoFramePool.h>
23 
24 namespace android {
25 
26 class V4L2Decoder : public VideoDecoder {
27 public:
28     static std::unique_ptr<VideoDecoder> Create(
29             const VideoCodec& codec, const size_t inputBufferSize, const size_t minNumOutputBuffers,
30             GetPoolCB getPoolCB, OutputCB outputCb, ErrorCB errorCb,
31             scoped_refptr<::base::SequencedTaskRunner> taskRunner);
32     ~V4L2Decoder() override;
33 
34     void decode(std::unique_ptr<ConstBitstreamBuffer> buffer, DecodeCB decodeCb) override;
35     void drain(DecodeCB drainCb) override;
36     void flush() override;
37 
38 private:
39     enum class State {
40         Idle,  // Not received any decode buffer after initialized, flushed, or drained.
41         Decoding,
42         Draining,
43         Error,
44     };
45     static const char* StateToString(State state);
46 
47     struct DecodeRequest {
DecodeRequestDecodeRequest48         DecodeRequest(std::unique_ptr<ConstBitstreamBuffer> buffer, DecodeCB decodeCb)
49               : buffer(std::move(buffer)), decodeCb(std::move(decodeCb)) {}
50         DecodeRequest(DecodeRequest&&) = default;
51         ~DecodeRequest() = default;
52 
53         std::unique_ptr<ConstBitstreamBuffer> buffer;  // nullptr means Drain
54         DecodeCB decodeCb;
55     };
56 
57     V4L2Decoder(scoped_refptr<::base::SequencedTaskRunner> taskRunner);
58     bool start(const VideoCodec& codec, const size_t inputBufferSize,
59                const size_t minNumOutputBuffers, GetPoolCB getPoolCb, OutputCB outputCb,
60                ErrorCB errorCb);
61     bool setupInputFormat(const uint32_t inputPixelFormat, const size_t inputBufferSize);
62     void pumpDecodeRequest();
63 
64     void serviceDeviceTask(bool event);
65     bool dequeueResolutionChangeEvent();
66     bool changeResolution();
67     bool setupOutputFormat(const ui::Size& size);
68 
69     void tryFetchVideoFrame();
70     void onVideoFrameReady(std::optional<VideoFramePool::FrameWithBlockId> frameWithBlockId);
71 
72     std::optional<size_t> getNumOutputBuffers();
73     std::optional<struct v4l2_format> getFormatInfo();
74     Rect getVisibleRect(const ui::Size& codedSize);
75     bool sendV4L2DecoderCmd(bool start);
76 
77     void setState(State newState);
78     void onError();
79 
80     std::unique_ptr<VideoFramePool> mVideoFramePool;
81 
82     scoped_refptr<V4L2Device> mDevice;
83     scoped_refptr<V4L2Queue> mInputQueue;
84     scoped_refptr<V4L2Queue> mOutputQueue;
85 
86     std::queue<DecodeRequest> mDecodeRequests;
87     std::map<int32_t, DecodeCB> mPendingDecodeCbs;
88 
89     size_t mMinNumOutputBuffers = 0;
90     GetPoolCB mGetPoolCb;
91     OutputCB mOutputCb;
92     DecodeCB mDrainCb;
93     ErrorCB mErrorCb;
94 
95     ui::Size mCodedSize;
96     Rect mVisibleRect;
97 
98     std::map<size_t, std::unique_ptr<VideoFrame>> mFrameAtDevice;
99 
100     // Block IDs can be arbitrarily large, but we only have a limited number of
101     // buffers. This maintains an association between a block ID and a specific
102     // V4L2 buffer index.
103     std::map<size_t, size_t> mBlockIdToV4L2Id;
104 
105     State mState = State::Idle;
106 
107     scoped_refptr<::base::SequencedTaskRunner> mTaskRunner;
108 
109     ::base::WeakPtr<V4L2Decoder> mWeakThis;
110     ::base::WeakPtrFactory<V4L2Decoder> mWeakThisFactory{this};
111 };
112 
113 }  // namespace android
114 
115 #endif  // ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_DECODER_H
116