• 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 <rect.h>
17 #include <size.h>
18 #include <v4l2_codec2/common/VideoTypes.h>
19 #include <v4l2_codec2/components/VideoDecoder.h>
20 #include <v4l2_codec2/components/VideoFrame.h>
21 #include <v4l2_codec2/components/VideoFramePool.h>
22 #include <v4l2_device.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, GetPoolCB getPoolCB,
30             OutputCB outputCb, ErrorCB errorCb,
31             scoped_refptr<::base::SequencedTaskRunner> taskRunner);
32     ~V4L2Decoder() override;
33 
34     void decode(std::unique_ptr<BitstreamBuffer> 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<BitstreamBuffer> buffer, DecodeCB decodeCb)
49               : buffer(std::move(buffer)), decodeCb(std::move(decodeCb)) {}
50         DecodeRequest(DecodeRequest&&) = default;
51         ~DecodeRequest() = default;
52         DecodeRequest& operator=(DecodeRequest&&);
53 
54         std::unique_ptr<BitstreamBuffer> buffer;  // nullptr means Drain
55         DecodeCB decodeCb;
56     };
57 
58     V4L2Decoder(scoped_refptr<::base::SequencedTaskRunner> taskRunner);
59     bool start(const VideoCodec& codec, const size_t inputBufferSize, GetPoolCB getPoolCb,
60                OutputCB outputCb, 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 
68     void tryFetchVideoFrame();
69     void onVideoFrameReady(std::optional<VideoFramePool::FrameWithBlockId> frameWithBlockId);
70 
71     std::optional<size_t> getNumOutputBuffers();
72     std::optional<struct v4l2_format> getFormatInfo();
73     media::Rect getVisibleRect(const media::Size& codedSize);
74     bool sendV4L2DecoderCmd(bool start);
75 
76     void setState(State newState);
77     void onError();
78 
79     std::unique_ptr<VideoFramePool> mVideoFramePool;
80 
81     scoped_refptr<media::V4L2Device> mDevice;
82     scoped_refptr<media::V4L2Queue> mInputQueue;
83     scoped_refptr<media::V4L2Queue> mOutputQueue;
84 
85     std::queue<DecodeRequest> mDecodeRequests;
86     std::map<int32_t, DecodeCB> mPendingDecodeCbs;
87 
88     GetPoolCB mGetPoolCb;
89     OutputCB mOutputCb;
90     DecodeCB mDrainCb;
91     ErrorCB mErrorCb;
92 
93     media::Size mCodedSize;
94     media::Rect mVisibleRect;
95 
96     std::map<size_t, std::unique_ptr<VideoFrame>> mFrameAtDevice;
97 
98     // Block IDs can be arbitrarily large, but we only have a limited number of
99     // buffers. This maintains an association between a block ID and a specific
100     // V4L2 buffer index.
101     std::map<size_t, size_t> mBlockIdToV4L2Id;
102 
103     State mState = State::Idle;
104 
105     scoped_refptr<::base::SequencedTaskRunner> mTaskRunner;
106 
107     ::base::WeakPtr<V4L2Decoder> mWeakThis;
108     ::base::WeakPtrFactory<V4L2Decoder> mWeakThisFactory{this};
109 };
110 
111 }  // namespace android
112 
113 #endif  // ANDROID_V4L2_CODEC2_COMPONENTS_V4L2_DECODER_H
114