summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorMikhail Burakov <mburakov@mailbox.org>2023-10-15 09:28:50 +0200
committerMikhail Burakov <mburakov@mailbox.org>2023-10-15 16:36:02 +0200
commit9adec996efea0356547e797b36046103bec449e0 (patch)
tree456ee32048b38ba73085eb0487b1376088f320a7 /main.c
parent0e3c61abed24e2fec2148b22fe204e28074f1e90 (diff)
Preparations for adding wlr capturing
Diffstat (limited to 'main.c')
-rw-r--r--main.c122
1 files changed, 48 insertions, 74 deletions
diff --git a/main.c b/main.c
index bc737fc..2e0ddc4 100644
--- a/main.c
+++ b/main.c
@@ -22,8 +22,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/timerfd.h>
-#include <time.h>
#include <unistd.h>
#include "capture.h"
@@ -41,20 +39,18 @@
// https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/183
static const enum YuvColorspace colorspace = kItuRec601;
static const enum YuvRange range = kNarrowRange;
-static const int capture_period = 1000000000 / 60;
static volatile sig_atomic_t g_signal;
static void OnSignal(int status) { g_signal = status; }
struct Contexts {
+ struct GpuContext* gpu_context;
struct IoMuxer io_muxer;
- int timer_fd;
int server_fd;
- struct GpuContext* gpu_context;
- struct CaptureContext* capture_context;
int client_fd;
struct InputHandler* input_handler;
+ struct CaptureContext* capture_context;
struct EncodeContext* encode_context;
};
@@ -93,11 +89,14 @@ rollback_sock:
}
static void MaybeDropClient(struct Contexts* contexts) {
- static const struct itimerspec spec = {0};
if (contexts->encode_context) {
EncodeContextDestroy(contexts->encode_context);
contexts->encode_context = NULL;
}
+ if (contexts->capture_context) {
+ CaptureContextDestroy(contexts->capture_context);
+ contexts->capture_context = NULL;
+ }
if (contexts->input_handler) {
IoMuxerForget(&contexts->io_muxer,
InputHandlerGetEventsFd(contexts->input_handler));
@@ -111,38 +110,10 @@ static void MaybeDropClient(struct Contexts* contexts) {
}
}
-static void OnTimerExpire(void* user) {
+static void OnCaptureContextFrameReady(void* user,
+ const struct GpuFrame* captured_frame) {
struct Contexts* contexts = user;
- if (!IoMuxerOnRead(&contexts->io_muxer, contexts->timer_fd, &OnTimerExpire,
- user)) {
- LOG("Failed to reschedule timer (%s)", strerror(errno));
- g_signal = SIGABRT;
- return;
- }
- uint64_t expirations;
- if (read(contexts->timer_fd, &expirations, sizeof(expirations)) !=
- sizeof(expirations)) {
- LOG("Failed to read timer expirations (%s)", strerror(errno));
- g_signal = SIGABRT;
- return;
- }
- if (contexts->client_fd == -1) {
- // mburakov: Timer must disarm itself AFTER reading.
- static const struct itimerspec spec = {0};
- if (timerfd_settime(contexts->timer_fd, 0, &spec, NULL)) {
- LOG("Failed to disarm timer (%s)", strerror(errno));
- g_signal = SIGABRT;
- }
- return;
- }
-
unsigned long long timestamp = MicrosNow();
- const struct GpuFrame* captured_frame =
- CaptureContextGetFrame(contexts->capture_context);
- if (!captured_frame) {
- LOG("Failed to capture frame");
- goto drop_client;
- }
if (!contexts->encode_context) {
contexts->encode_context =
@@ -198,11 +169,29 @@ static void OnInputEvents(void* user) {
if (!IoMuxerOnRead(&contexts->io_muxer,
InputHandlerGetEventsFd(contexts->input_handler),
&OnInputEvents, user)) {
- LOG("Failed to reschedule events reading (%s)", strerror(errno));
+ LOG("Failed to reschedule input events reading (%s)", strerror(errno));
goto drop_client;
}
if (!InputHandlerProcessEvents(contexts->input_handler)) {
- LOG("Failed to process events");
+ LOG("Failed to process input events");
+ goto drop_client;
+ }
+ return;
+
+drop_client:
+ MaybeDropClient(contexts);
+}
+
+static void OnCaptureContextEvents(void* user) {
+ struct Contexts* contexts = user;
+ if (!IoMuxerOnRead(&contexts->io_muxer,
+ CaptureContextGetEventsFd(contexts->capture_context),
+ &OnCaptureContextEvents, user)) {
+ LOG("Failed to reschedule capture events reading (%s)", strerror(errno));
+ goto drop_client;
+ }
+ if (!CaptureContextProcessEvents(contexts->capture_context)) {
+ LOG("Failed to process capture events");
goto drop_client;
}
return;
@@ -246,15 +235,22 @@ static void OnClientConnecting(void* user) {
if (!IoMuxerOnRead(&contexts->io_muxer,
InputHandlerGetEventsFd(contexts->input_handler),
&OnInputEvents, user)) {
- LOG("Failed to schedule events reading (%s)", strerror(errno));
+ LOG("Failed to schedule input events reading (%s)", strerror(errno));
goto drop_client;
}
- static const struct itimerspec spec = {
- .it_interval.tv_nsec = capture_period,
- .it_value.tv_nsec = capture_period,
+ static const struct CaptureContextCallbacks kCaptureContextCallbacks = {
+ .OnFrameReady = OnCaptureContextFrameReady,
};
- if (timerfd_settime(contexts->timer_fd, 0, &spec, NULL)) {
- LOG("Failed to arm timer (%s)", strerror(errno));
+ contexts->capture_context = CaptureContextCreate(
+ contexts->gpu_context, &kCaptureContextCallbacks, user);
+ if (!contexts->capture_context) {
+ LOG("Failed to create capture context");
+ goto drop_client;
+ }
+ if (!IoMuxerOnRead(&contexts->io_muxer,
+ CaptureContextGetEventsFd(contexts->capture_context),
+ &OnCaptureContextEvents, user)) {
+ LOG("Failed to schedule capture events reading (%s)", strerror(errno));
goto drop_client;
}
return;
@@ -276,41 +272,24 @@ int main(int argc, char* argv[]) {
}
struct Contexts contexts = {
- .timer_fd = -1,
.server_fd = -1,
.client_fd = -1,
};
+ contexts.gpu_context = GpuContextCreate(colorspace, range);
+ if (!contexts.gpu_context) {
+ LOG("Failed to create gpu context");
+ return EXIT_FAILURE;
+ }
IoMuxerCreate(&contexts.io_muxer);
contexts.server_fd = CreateServerSocket(argv[1]);
if (contexts.server_fd == -1) {
LOG("Failed to create server socket");
goto rollback_io_muxer;
}
- contexts.timer_fd = timerfd_create(CLOCK_MONOTONIC, 0);
- if (contexts.timer_fd == -1) {
- LOG("Failed to create timer (%s)", strerror(errno));
- goto rollback_server_fd;
- }
- contexts.gpu_context = GpuContextCreate(colorspace, range);
- if (!contexts.gpu_context) {
- LOG("Failed to create gpu context");
- goto rollback_timer_fd;
- }
- contexts.capture_context = CaptureContextCreate(contexts.gpu_context);
- if (!contexts.capture_context) {
- LOG("Failed to create capture context");
- goto rollback_gpu_context;
- }
-
- if (!IoMuxerOnRead(&contexts.io_muxer, contexts.timer_fd, &OnTimerExpire,
- &contexts)) {
- LOG("Failed to schedule timer (%s)", strerror(errno));
- goto rollback_capture_context;
- }
if (!IoMuxerOnRead(&contexts.io_muxer, contexts.server_fd,
&OnClientConnecting, &contexts)) {
LOG("Failed to schedule accept (%s)", strerror(errno));
- goto rollback_capture_context;
+ goto rollback_server_fd;
}
while (!g_signal) {
if (IoMuxerIterate(&contexts.io_muxer, -1) && errno != EINTR) {
@@ -320,16 +299,11 @@ int main(int argc, char* argv[]) {
}
MaybeDropClient(&contexts);
-rollback_capture_context:
- CaptureContextDestroy(contexts.capture_context);
-rollback_gpu_context:
- GpuContextDestroy(contexts.gpu_context);
-rollback_timer_fd:
- close(contexts.timer_fd);
rollback_server_fd:
close(contexts.server_fd);
rollback_io_muxer:
IoMuxerDestroy(&contexts.io_muxer);
+ GpuContextDestroy(contexts.gpu_context);
bool result = g_signal == SIGINT || g_signal == SIGTERM;
return result ? EXIT_SUCCESS : EXIT_FAILURE;
}