Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ sudo apt install libcamera0.5 libmosquitto1 pulseaudio libavformat59 libswscale6

Get the latest [release binary](https://github.com/TzuHuanTai/RaspberryPi-WebRTC/releases) .
```bash
wget https://github.com/TzuHuanTai/RaspberryPi-WebRTC/releases/latest/download/pi-webrtc-v1.1.1_raspios-bookworm-arm64.tar.gz
tar -xzf pi-webrtc-v1.1.1_raspios-bookworm-arm64.tar.gz
wget https://github.com/TzuHuanTai/RaspberryPi-WebRTC/releases/latest/download/pi-webrtc-v1.1.2_raspios-bookworm-arm64.tar.gz
tar -xzf pi-webrtc-v1.1.2_raspios-bookworm-arm64.tar.gz
```

### 4. MQTT Signaling
Expand Down
13 changes: 9 additions & 4 deletions src/capturer/libcamera_capturer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ int LibcameraCapturer::width() const { return width_; }

int LibcameraCapturer::height() const { return height_; }

bool LibcameraCapturer::is_dma_capture() const { return false; }
bool LibcameraCapturer::is_dma_capture() const { return true; }

uint32_t LibcameraCapturer::format() const { return format_; }

Expand All @@ -188,6 +188,12 @@ LibcameraCapturer &LibcameraCapturer::SetResolution(int width, int height) {
camera_config_->at(0).pixelFormat = libcamera::formats::YUV420;
camera_config_->at(0).bufferCount = buffer_count_;

if (width >= 1280 || height >= 720) {
camera_config_->at(0).colorSpace = libcamera::ColorSpace::Rec709;
} else {
camera_config_->at(0).colorSpace = libcamera::ColorSpace::Smpte170m;
}

auto validation = camera_config_->validate();
if (validation == libcamera::CameraConfiguration::Status::Valid) {
INFO_PRINT("camera validated format: %s.", camera_config_->at(0).toString().c_str());
Expand Down Expand Up @@ -292,15 +298,14 @@ void LibcameraCapturer::RequestComplete(libcamera::Request *request) {
auto &buffers = request->buffers();
auto *buffer = buffers.begin()->second;

auto &plane = buffer->planes()[0];
int fd = plane.fd.get();
int fd = buffer->planes()[0].fd.get();
void *data = mapped_buffers_[fd].first;
int length = mapped_buffers_[fd].second;
timeval tv = {};
tv.tv_sec = buffer->metadata().timestamp / 1000000000;
tv.tv_usec = (buffer->metadata().timestamp % 1000000000) / 1000;

auto v4l2_buffer = V4L2Buffer::FromLibcamera((uint8_t *)data, length, tv, format_);
auto v4l2_buffer = V4L2Buffer::FromLibcamera((uint8_t *)data, length, fd, tv, format_);
frame_buffer_ = V4L2FrameBuffer::Create(width_, height_, v4l2_buffer);
NextFrameBuffer(frame_buffer_);

Expand Down
5 changes: 3 additions & 2 deletions src/common/v4l2_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include <errno.h>
#include <fcntl.h>
#include <stdexcept>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
Expand Down Expand Up @@ -37,7 +38,7 @@ int V4L2Util::OpenDevice(const char *file) {
int fd = open(file, O_RDWR);
if (fd < 0) {
ERROR_PRINT("v4l2 open(%s): %s", file, strerror(errno));
exit(-1);
throw std::runtime_error("failed to open v4l2 device");
}
DEBUG_PRINT("Open file %s fd(%d) success!", file, fd);
return fd;
Expand Down Expand Up @@ -170,7 +171,7 @@ bool V4L2Util::SetFormat(int fd, V4L2BufferGroup *gbuffer, int width, int height
if (fmt.fmt.pix_mp.width != width || fmt.fmt.pix_mp.height != height) {
ERROR_PRINT("fd(%d) input size (%dx%d) doesn't match driver's output size (%dx%d): %s", fd,
width, height, fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, strerror(EINVAL));
exit(0);
throw std::runtime_error("the frame size doesn't match");
}

return true;
Expand Down
4 changes: 3 additions & 1 deletion src/common/v4l2_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,11 @@ struct V4L2Buffer {
return buf;
}

static V4L2Buffer FromLibcamera(void *start, int length, timeval timestamp, uint32_t fmt) {
static V4L2Buffer FromLibcamera(void *start, int length, int dmafd, timeval timestamp,
uint32_t fmt) {
V4L2Buffer buf;
buf.start = start;
buf.dmafd = dmafd;
buf.pix_fmt = fmt;
buf.length = length;
buf.timestamp = timestamp;
Expand Down
5 changes: 3 additions & 2 deletions test/test_libcamera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ int main(int argc, char *argv[]) {

auto capturer = LibcameraCapturer::Create(args);

auto observer = capturer->AsRawBufferObservable();
observer->Subscribe([&](V4L2Buffer buffer) {
auto observer = capturer->AsFrameBufferObservable();
observer->Subscribe([&](rtc::scoped_refptr<V4L2FrameBuffer> frame_buffer) {
if (i < images_nb) {
auto buffer = frame_buffer->GetRawBuffer();
WriteImage(buffer.start, buffer.length, ++i);
} else {
is_finished = true;
Expand Down
14 changes: 7 additions & 7 deletions test/test_v4l2_encoder.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include "args.h"
#include "capturer/v4l2_capturer.h"
#include "capturer/libcamera_capturer.h"
#include "codecs/v4l2/v4l2_encoder.h"

#include <chrono>
Expand All @@ -15,20 +15,20 @@ int main(int argc, char *argv[]) {
bool is_finished = false;
bool has_first_keyframe_ = false;
int images_nb = 0;
int record_sec = 10;
int record_sec = 100;
Args args{
.cameraId = 0,
.fps = 30,
.width = 1280,
.height = 960,
.format = V4L2_PIX_FMT_YUYV,
.width = 1920,
.height = 1080,
.format = V4L2_PIX_FMT_YUV420,
.hw_accel = true,
};

auto capturer = V4L2Capturer::Create(args);
auto capturer = LibcameraCapturer::Create(args);
auto observer = capturer->AsFrameBufferObservable();

auto encoder = V4L2Encoder::Create(args.width, args.height, V4L2_PIX_FMT_YUYV, false);
auto encoder = V4L2Encoder::Create(args.width, args.height, V4L2_PIX_FMT_YUV420, true);

int cam_frame_count = 0;
auto cam_start_time = std::chrono::steady_clock::now();
Expand Down