Group components into struct scrcpy

This avoids to refer to many structs globally.
This commit is contained in:
Romain Vimont 2021-05-28 21:29:14 +02:00
parent 6fd7e89da1
commit 506f918fb7

View file

@ -29,17 +29,19 @@
# include "v4l2_sink.h" # include "v4l2_sink.h"
#endif #endif
static struct server server; struct scrcpy {
static struct screen screen; struct server server;
static struct stream stream; struct screen screen;
static struct decoder decoder; struct stream stream;
static struct recorder recorder; struct decoder decoder;
struct recorder recorder;
#ifdef HAVE_V4L2 #ifdef HAVE_V4L2
static struct sc_v4l2_sink v4l2_sink; struct sc_v4l2_sink v4l2_sink;
#endif #endif
static struct controller controller; struct controller controller;
static struct file_handler file_handler; struct file_handler file_handler;
static struct input_manager input_manager; struct input_manager input_manager;
};
#ifdef _WIN32 #ifdef _WIN32
BOOL WINAPI windows_ctrl_handler(DWORD ctrl_type) { BOOL WINAPI windows_ctrl_handler(DWORD ctrl_type) {
@ -129,7 +131,8 @@ enum event_result {
}; };
static enum event_result static enum event_result
handle_event(SDL_Event *event, const struct scrcpy_options *options) { handle_event(struct scrcpy *s, const struct scrcpy_options *options,
SDL_Event *event) {
switch (event->type) { switch (event->type) {
case EVENT_STREAM_STOPPED: case EVENT_STREAM_STOPPED:
LOGD("Video stream stopped"); LOGD("Video stream stopped");
@ -154,17 +157,17 @@ handle_event(SDL_Event *event, const struct scrcpy_options *options) {
} else { } else {
action = ACTION_PUSH_FILE; action = ACTION_PUSH_FILE;
} }
file_handler_request(&file_handler, action, file); file_handler_request(&s->file_handler, action, file);
goto end; goto end;
} }
} }
bool consumed = screen_handle_event(&screen, event); bool consumed = screen_handle_event(&s->screen, event);
if (consumed) { if (consumed) {
goto end; goto end;
} }
consumed = input_manager_handle_event(&input_manager, event); consumed = input_manager_handle_event(&s->input_manager, event);
(void) consumed; (void) consumed;
end: end:
@ -172,10 +175,10 @@ end:
} }
static bool static bool
event_loop(const struct scrcpy_options *options) { event_loop(struct scrcpy *s, const struct scrcpy_options *options) {
SDL_Event event; SDL_Event event;
while (SDL_WaitEvent(&event)) { while (SDL_WaitEvent(&event)) {
enum event_result result = handle_event(&event, options); enum event_result result = handle_event(s, options, &event);
switch (result) { switch (result) {
case EVENT_RESULT_STOPPED_BY_USER: case EVENT_RESULT_STOPPED_BY_USER:
return true; return true;
@ -237,7 +240,10 @@ stream_on_eos(struct stream *stream, void *userdata) {
bool bool
scrcpy(const struct scrcpy_options *options) { scrcpy(const struct scrcpy_options *options) {
if (!server_init(&server)) { static struct scrcpy scrcpy;
struct scrcpy *s = &scrcpy;
if (!server_init(&s->server)) {
return false; return false;
} }
@ -273,7 +279,7 @@ scrcpy(const struct scrcpy_options *options) {
.force_adb_forward = options->force_adb_forward, .force_adb_forward = options->force_adb_forward,
.power_off_on_close = options->power_off_on_close, .power_off_on_close = options->power_off_on_close,
}; };
if (!server_start(&server, &params)) { if (!server_start(&s->server, &params)) {
goto end; goto end;
} }
@ -287,12 +293,12 @@ scrcpy(const struct scrcpy_options *options) {
char device_name[DEVICE_NAME_FIELD_LENGTH]; char device_name[DEVICE_NAME_FIELD_LENGTH];
struct size frame_size; struct size frame_size;
if (!server_connect_to(&server, device_name, &frame_size)) { if (!server_connect_to(&s->server, device_name, &frame_size)) {
goto end; goto end;
} }
if (options->display && options->control) { if (options->display && options->control) {
if (!file_handler_init(&file_handler, server.serial, if (!file_handler_init(&s->file_handler, s->server.serial,
options->push_target)) { options->push_target)) {
goto end; goto end;
} }
@ -305,19 +311,19 @@ scrcpy(const struct scrcpy_options *options) {
needs_decoder |= !!options->v4l2_device; needs_decoder |= !!options->v4l2_device;
#endif #endif
if (needs_decoder) { if (needs_decoder) {
decoder_init(&decoder); decoder_init(&s->decoder);
dec = &decoder; dec = &s->decoder;
} }
struct recorder *rec = NULL; struct recorder *rec = NULL;
if (record) { if (record) {
if (!recorder_init(&recorder, if (!recorder_init(&s->recorder,
options->record_filename, options->record_filename,
options->record_format, options->record_format,
frame_size)) { frame_size)) {
goto end; goto end;
} }
rec = &recorder; rec = &s->recorder;
recorder_initialized = true; recorder_initialized = true;
} }
@ -326,24 +332,24 @@ scrcpy(const struct scrcpy_options *options) {
const struct stream_callbacks stream_cbs = { const struct stream_callbacks stream_cbs = {
.on_eos = stream_on_eos, .on_eos = stream_on_eos,
}; };
stream_init(&stream, server.video_socket, &stream_cbs, NULL); stream_init(&s->stream, s->server.video_socket, &stream_cbs, NULL);
if (dec) { if (dec) {
stream_add_sink(&stream, &dec->packet_sink); stream_add_sink(&s->stream, &dec->packet_sink);
} }
if (rec) { if (rec) {
stream_add_sink(&stream, &rec->packet_sink); stream_add_sink(&s->stream, &rec->packet_sink);
} }
if (options->display) { if (options->display) {
if (options->control) { if (options->control) {
if (!controller_init(&controller, server.control_socket)) { if (!controller_init(&s->controller, s->server.control_socket)) {
goto end; goto end;
} }
controller_initialized = true; controller_initialized = true;
if (!controller_start(&controller)) { if (!controller_start(&s->controller)) {
goto end; goto end;
} }
controller_started = true; controller_started = true;
@ -366,19 +372,19 @@ scrcpy(const struct scrcpy_options *options) {
.fullscreen = options->fullscreen, .fullscreen = options->fullscreen,
}; };
if (!screen_init(&screen, &screen_params)) { if (!screen_init(&s->screen, &screen_params)) {
goto end; goto end;
} }
screen_initialized = true; screen_initialized = true;
decoder_add_sink(&decoder, &screen.frame_sink); decoder_add_sink(&s->decoder, &s->screen.frame_sink);
if (options->turn_screen_off) { if (options->turn_screen_off) {
struct control_msg msg; struct control_msg msg;
msg.type = CONTROL_MSG_TYPE_SET_SCREEN_POWER_MODE; msg.type = CONTROL_MSG_TYPE_SET_SCREEN_POWER_MODE;
msg.set_screen_power_mode.mode = SCREEN_POWER_MODE_OFF; msg.set_screen_power_mode.mode = SCREEN_POWER_MODE_OFF;
if (!controller_push_msg(&controller, &msg)) { if (!controller_push_msg(&s->controller, &msg)) {
LOGW("Could not request 'set screen power mode'"); LOGW("Could not request 'set screen power mode'");
} }
} }
@ -386,11 +392,11 @@ scrcpy(const struct scrcpy_options *options) {
#ifdef HAVE_V4L2 #ifdef HAVE_V4L2
if (options->v4l2_device) { if (options->v4l2_device) {
if (!sc_v4l2_sink_init(&v4l2_sink, options->v4l2_device, frame_size)) { if (!sc_v4l2_sink_init(&s->v4l2_sink, options->v4l2_device, frame_size)) {
goto end; goto end;
} }
decoder_add_sink(&decoder, &v4l2_sink.frame_sink); decoder_add_sink(&s->decoder, &s->v4l2_sink.frame_sink);
v4l2_sink_initialized = true; v4l2_sink_initialized = true;
} }
@ -398,74 +404,74 @@ scrcpy(const struct scrcpy_options *options) {
// now we consumed the header values, the socket receives the video stream // now we consumed the header values, the socket receives the video stream
// start the stream // start the stream
if (!stream_start(&stream)) { if (!stream_start(&s->stream)) {
goto end; goto end;
} }
stream_started = true; stream_started = true;
input_manager_init(&input_manager, &controller, &screen, options); input_manager_init(&s->input_manager, &s->controller, &s->screen, options);
ret = event_loop(options); ret = event_loop(s, options);
LOGD("quit..."); LOGD("quit...");
// Close the window immediately on closing, because screen_destroy() may // Close the window immediately on closing, because screen_destroy() may
// only be called once the stream thread is joined (it may take time) // only be called once the stream thread is joined (it may take time)
screen_hide_window(&screen); screen_hide_window(&s->screen);
end: end:
// The stream is not stopped explicitly, because it will stop by itself on // The stream is not stopped explicitly, because it will stop by itself on
// end-of-stream // end-of-stream
if (controller_started) { if (controller_started) {
controller_stop(&controller); controller_stop(&s->controller);
} }
if (file_handler_initialized) { if (file_handler_initialized) {
file_handler_stop(&file_handler); file_handler_stop(&s->file_handler);
} }
if (screen_initialized) { if (screen_initialized) {
screen_interrupt(&screen); screen_interrupt(&s->screen);
} }
if (server_started) { if (server_started) {
// shutdown the sockets and kill the server // shutdown the sockets and kill the server
server_stop(&server); server_stop(&s->server);
} }
// now that the sockets are shutdown, the stream and controller are // now that the sockets are shutdown, the stream and controller are
// interrupted, we can join them // interrupted, we can join them
if (stream_started) { if (stream_started) {
stream_join(&stream); stream_join(&s->stream);
} }
#ifdef HAVE_V4L2 #ifdef HAVE_V4L2
if (v4l2_sink_initialized) { if (v4l2_sink_initialized) {
sc_v4l2_sink_destroy(&v4l2_sink); sc_v4l2_sink_destroy(&s->v4l2_sink);
} }
#endif #endif
// Destroy the screen only after the stream is guaranteed to be finished, // Destroy the screen only after the stream is guaranteed to be finished,
// because otherwise the screen could receive new frames after destruction // because otherwise the screen could receive new frames after destruction
if (screen_initialized) { if (screen_initialized) {
screen_join(&screen); screen_join(&s->screen);
screen_destroy(&screen); screen_destroy(&s->screen);
} }
if (controller_started) { if (controller_started) {
controller_join(&controller); controller_join(&s->controller);
} }
if (controller_initialized) { if (controller_initialized) {
controller_destroy(&controller); controller_destroy(&s->controller);
} }
if (recorder_initialized) { if (recorder_initialized) {
recorder_destroy(&recorder); recorder_destroy(&s->recorder);
} }
if (file_handler_initialized) { if (file_handler_initialized) {
file_handler_join(&file_handler); file_handler_join(&s->file_handler);
file_handler_destroy(&file_handler); file_handler_destroy(&s->file_handler);
} }
server_destroy(&server); server_destroy(&s->server);
return ret; return ret;
} }