Skip to content

Commit 76a4819

Browse files
committed
refactor: remove raw buffer event and need src fmt for creating new codecs
1 parent ddeb036 commit 76a4819

36 files changed

+265
-246
lines changed

src/capturer/libcamera_capturer.cpp

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -300,8 +300,9 @@ void LibcameraCapturer::RequestComplete(libcamera::Request *request) {
300300
tv.tv_sec = buffer->metadata().timestamp / 1000000000;
301301
tv.tv_usec = (buffer->metadata().timestamp % 1000000000) / 1000;
302302

303-
V4L2Buffer v4l2_buffer((uint8_t *)data, length, V4L2_BUF_FLAG_KEYFRAME, tv);
304-
NextBuffer(v4l2_buffer);
303+
auto v4l2_buffer = V4L2Buffer::FromLibcamera((uint8_t *)data, length, tv, format_);
304+
frame_buffer_ = V4L2FrameBuffer::Create(width_, height_, v4l2_buffer);
305+
NextFrameBuffer(frame_buffer_);
305306

306307
request->reuse(libcamera::Request::ReuseBuffers);
307308

@@ -317,12 +318,6 @@ rtc::scoped_refptr<webrtc::I420BufferInterface> LibcameraCapturer::GetI420Frame(
317318
return frame_buffer_->ToI420();
318319
}
319320

320-
void LibcameraCapturer::NextBuffer(V4L2Buffer &buffer) {
321-
frame_buffer_ = V4L2FrameBuffer::Create(width_, height_, buffer, format_);
322-
NextFrameBuffer(frame_buffer_);
323-
NextRawBuffer(buffer);
324-
}
325-
326321
void LibcameraCapturer::StartCapture() {
327322
int ret = camera_->configure(camera_config_.get());
328323
if (ret < 0) {

src/capturer/libcamera_capturer.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ class LibcameraCapturer : public VideoCapturer {
5050
std::map<int, std::pair<void *, unsigned int>> mapped_buffers_;
5151

5252
rtc::scoped_refptr<V4L2FrameBuffer> frame_buffer_;
53-
void NextBuffer(V4L2Buffer &raw_buffer);
5453

5554
LibcameraCapturer &SetResolution(int width, int height) override;
5655
LibcameraCapturer &SetFps(int fps) override;

src/capturer/v4l2_capturer.cpp

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,7 @@ void V4L2Capturer::CaptureImage() {
143143
return;
144144
}
145145

146-
V4L2Buffer buffer((uint8_t *)capture_.buffers[buf.index].start, buf.bytesused, buf.flags,
147-
buf.timestamp);
146+
auto buffer = V4L2Buffer::FromV4L2((uint8_t *)capture_.buffers[buf.index].start, buf, format_);
148147
NextBuffer(buffer);
149148

150149
if (!V4L2Util::QueueBuffer(fd_, &buf)) {
@@ -162,35 +161,32 @@ rtc::scoped_refptr<webrtc::I420BufferInterface> V4L2Capturer::GetI420Frame() {
162161
}
163162

164163
void V4L2Capturer::NextBuffer(V4L2Buffer &buffer) {
165-
if (hw_accel_) {
166-
// hardware encoding
164+
if (hw_accel_ && format_ == V4L2_PIX_FMT_H264) {
165+
has_first_keyframe_ = (buffer.flags & V4L2_BUF_FLAG_KEYFRAME) != 0;
167166
if (!has_first_keyframe_) {
168-
has_first_keyframe_ = (buffer.flags & V4L2_BUF_FLAG_KEYFRAME) != 0;
167+
return;
169168
}
169+
}
170170

171-
if (IsCompressedFormat()) {
172-
decoder_->EmplaceBuffer(buffer, [this](V4L2Buffer decoded_buffer) {
173-
frame_buffer_ =
174-
V4L2FrameBuffer::Create(width_, height_, decoded_buffer, V4L2_PIX_FMT_YUV420);
175-
NextFrameBuffer(frame_buffer_);
176-
});
177-
} else {
178-
frame_buffer_ = V4L2FrameBuffer::Create(width_, height_, buffer, format_);
179-
NextFrameBuffer(frame_buffer_);
180-
}
171+
if (!hw_accel_ && format_ == V4L2_PIX_FMT_H264) {
172+
INFO_PRINT("Software decoding H264 camera source is not supported.");
173+
exit(EXIT_FAILURE);
174+
}
175+
176+
if (hw_accel_ && IsCompressedFormat()) {
177+
decoder_->EmplaceBuffer(buffer, [this, buffer](V4L2Buffer &decoded_buffer) {
178+
// hw decoder doesn't output timestamps.
179+
decoded_buffer.timestamp = buffer.timestamp;
180+
HandleDecodedBuffer(decoded_buffer);
181+
});
181182
} else {
182-
// software decoding
183-
if (format_ != V4L2_PIX_FMT_H264) {
184-
frame_buffer_ = V4L2FrameBuffer::Create(width_, height_, buffer, format_);
185-
NextFrameBuffer(frame_buffer_);
186-
} else {
187-
// todo: h264 decoding
188-
INFO_PRINT("Software decoding h264 camera source is not support now.");
189-
exit(1);
190-
}
183+
HandleDecodedBuffer(buffer);
191184
}
185+
}
192186

193-
NextRawBuffer(buffer);
187+
void V4L2Capturer::HandleDecodedBuffer(V4L2Buffer &buffer) {
188+
frame_buffer_ = V4L2FrameBuffer::Create(width_, height_, buffer);
189+
NextFrameBuffer(frame_buffer_);
194190
}
195191

196192
void V4L2Capturer::StartCapture() {

src/capturer/v4l2_capturer.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,7 @@ class V4L2Capturer : public VideoCapturer {
4141
V4L2BufferGroup capture_;
4242
std::unique_ptr<Worker> worker_;
4343
std::unique_ptr<V4L2Decoder> decoder_;
44-
4544
rtc::scoped_refptr<V4L2FrameBuffer> frame_buffer_;
46-
void NextBuffer(V4L2Buffer &raw_buffer);
4745

4846
V4L2Capturer &SetResolution(int width, int height) override;
4947
V4L2Capturer &SetFps(int fps) override;
@@ -54,6 +52,8 @@ class V4L2Capturer : public VideoCapturer {
5452
void CaptureImage();
5553
bool CheckMatchingDevice(std::string unique_name);
5654
int GetCameraIndex(webrtc::VideoCaptureModule::DeviceInfo *device_info);
55+
void NextBuffer(V4L2Buffer &buffer);
56+
void HandleDecodedBuffer(V4L2Buffer &buffer);
5757
};
5858

5959
#endif

src/capturer/video_capturer.h

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,7 @@
1414
class VideoCapturer {
1515
public:
1616
VideoCapturer() = default;
17-
~VideoCapturer() {
18-
raw_buffer_subject_.UnSubscribe();
19-
frame_buffer_subject_.UnSubscribe();
20-
}
17+
~VideoCapturer() { frame_buffer_subject_.UnSubscribe(); }
2118

2219
virtual int fps() const = 0;
2320
virtual int width() const = 0;
@@ -33,23 +30,16 @@ class VideoCapturer {
3330
virtual VideoCapturer &SetRotation(int angle) = 0;
3431
virtual VideoCapturer &SetControls(int key, int value) = 0;
3532

36-
std::shared_ptr<Observable<V4L2Buffer>> AsRawBufferObservable() {
37-
return raw_buffer_subject_.AsObservable();
38-
}
39-
4033
std::shared_ptr<Observable<rtc::scoped_refptr<V4L2FrameBuffer>>> AsFrameBufferObservable() {
4134
return frame_buffer_subject_.AsObservable();
4235
}
4336

4437
protected:
45-
void NextRawBuffer(V4L2Buffer raw_buffer) { raw_buffer_subject_.Next(raw_buffer); }
46-
4738
void NextFrameBuffer(rtc::scoped_refptr<V4L2FrameBuffer> frame_buffer) {
4839
frame_buffer_subject_.Next(frame_buffer);
4940
}
5041

5142
private:
52-
Subject<V4L2Buffer> raw_buffer_subject_;
5343
Subject<rtc::scoped_refptr<V4L2FrameBuffer>> frame_buffer_subject_;
5444
};
5545

src/codecs/v4l2/v4l2_codec.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
V4L2Codec::V4L2Codec()
77
: fd_(0),
8+
dst_fmt_(0),
89
abort_(false) {}
910

1011
V4L2Codec::~V4L2Codec() {
@@ -48,6 +49,7 @@ bool V4L2Codec::PrepareBuffer(V4L2BufferGroup *gbuffer, int width, int height, u
4849
output_buffer_index_.push(i);
4950
}
5051
} else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
52+
dst_fmt_ = pix_fmt;
5153
if (!V4L2Util::QueueBuffers(fd_, gbuffer)) {
5254
return false;
5355
}
@@ -57,6 +59,11 @@ bool V4L2Codec::PrepareBuffer(V4L2BufferGroup *gbuffer, int width, int height, u
5759
}
5860

5961
void V4L2Codec::Start() {
62+
if (dst_fmt_ == 0) {
63+
ERROR_PRINT("The target format is not set.");
64+
exit(EXIT_FAILURE);
65+
}
66+
6067
abort_ = false;
6168
worker_ = std::make_unique<Worker>(file_name_ + std::to_string(pthread_self()), [this]() {
6269
CaptureBuffer();
@@ -137,11 +144,9 @@ bool V4L2Codec::CaptureBuffer() {
137144
return false;
138145
}
139146

140-
V4L2Buffer buffer;
141-
buffer.start = capture_.buffers[buf.index].start;
142-
buffer.length = buf.m.planes[0].bytesused;
143-
buffer.dmafd = capture_.buffers[buf.index].dmafd;
144-
buffer.flags = buf.flags;
147+
auto buffer = V4L2Buffer::FromCapturedPlane(
148+
capture_.buffers[buf.index].start, buf.m.planes[0].bytesused,
149+
capture_.buffers[buf.index].dmafd, buf.flags, dst_fmt_);
145150

146151
if (abort_) {
147152
return false;

src/codecs/v4l2/v4l2_codec.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class V4L2Codec {
2424
void Start();
2525

2626
private:
27+
uint32_t dst_fmt_;
2728
std::atomic<bool> abort_;
2829
std::unique_ptr<Worker> worker_;
2930
ThreadSafeQueue<int> output_buffer_index_;

src/codecs/v4l2/v4l2_decoder.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ void V4L2Decoder::HandleEvent() {
4242
DEBUG_PRINT("Source changed!");
4343
V4L2Util::StreamOff(fd_, capture_.type);
4444
V4L2Util::DeallocateBuffer(fd_, &capture_);
45-
V4L2Util::SetFormat(fd_, &capture_, 0, 0, 0);
45+
V4L2Util::SetFormat(fd_, &capture_, 0, 0, capture_format_);
4646
V4L2Util::AllocateBuffer(fd_, &capture_, BUFFER_NUM);
4747
V4L2Util::StreamOn(fd_, capture_.type);
4848
break;

src/codecs/v4l2/v4l2_decoder.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ class V4L2Decoder : public V4L2Codec {
1111
protected:
1212
bool Configure(int width, int height, uint32_t src_pix_fmt, bool is_dma_dst);
1313
void HandleEvent() override;
14+
15+
private:
16+
uint32_t capture_format_ = V4L2_PIX_FMT_YUV420;
1417
};
1518

1619
#endif // V4L2_DECODER_H_

src/codecs/v4l2/v4l2_encoder.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22
#include "common/logging.h"
33

44
const char *ENCODER_FILE = "/dev/video11";
5-
const int BUFFER_NUM = 4;
5+
const int BUFFER_NUM = 2;
66
const int KEY_FRAME_INTERVAL = 600;
77

8-
std::unique_ptr<V4L2Encoder> V4L2Encoder::Create(int width, int height, bool is_dma_src) {
8+
std::unique_ptr<V4L2Encoder> V4L2Encoder::Create(int width, int height, uint32_t src_pix_fmt,
9+
bool is_dma_src) {
910
auto encoder = std::make_unique<V4L2Encoder>();
10-
encoder->Configure(width, height, is_dma_src);
11+
encoder->Configure(width, height, src_pix_fmt, is_dma_src);
1112
encoder->Start();
1213
return encoder;
1314
}
@@ -17,7 +18,7 @@ V4L2Encoder::V4L2Encoder()
1718
framerate_(30),
1819
bitrate_bps_(10000000) {}
1920

20-
bool V4L2Encoder::Configure(int width, int height, bool is_dma_src) {
21+
bool V4L2Encoder::Configure(int width, int height, uint32_t src_pix_fmt, bool is_dma_src) {
2122
if (!Open(ENCODER_FILE)) {
2223
DEBUG_PRINT("Failed to turn on encoder: %s", ENCODER_FILE);
2324
return false;
@@ -30,7 +31,7 @@ bool V4L2Encoder::Configure(int width, int height, bool is_dma_src) {
3031
V4L2Util::SetExtCtrl(fd_, V4L2_CID_MPEG_VIDEO_H264_I_PERIOD, KEY_FRAME_INTERVAL);
3132

3233
auto src_memory = is_dma_src ? V4L2_MEMORY_DMABUF : V4L2_MEMORY_MMAP;
33-
PrepareBuffer(&output_, width, height, V4L2_PIX_FMT_YUV420, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
34+
PrepareBuffer(&output_, width, height, src_pix_fmt, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
3435
src_memory, BUFFER_NUM);
3536
PrepareBuffer(&capture_, width, height, V4L2_PIX_FMT_H264, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
3637
V4L2_MEMORY_MMAP, BUFFER_NUM);

0 commit comments

Comments
 (0)