diff --git a/app/src/fps_counter.c b/app/src/fps_counter.c index 281c58cf..bbf71887 100644 --- a/app/src/fps_counter.c +++ b/app/src/fps_counter.c @@ -150,6 +150,10 @@ fps_counter_interrupt(struct fps_counter *counter) { void fps_counter_join(struct fps_counter *counter) { if (counter->thread_started) { + // interrupted must be set by the thread calling join(), so no need to + // lock for the assertion + assert(counter->interrupted); + sc_thread_join(&counter->thread, NULL); } } diff --git a/app/src/input_manager.c b/app/src/input_manager.c index 94086616..55b5fae2 100644 --- a/app/src/input_manager.c +++ b/app/src/input_manager.c @@ -517,7 +517,7 @@ input_manager_process_key(struct input_manager *im, return; case SDLK_i: if (!shift && !repeat && down) { - switch_fps_counter_state(im->fps_counter); + switch_fps_counter_state(&im->screen->fps_counter); } return; case SDLK_n: diff --git a/app/src/input_manager.h b/app/src/input_manager.h index 5c7e2b91..76690757 100644 --- a/app/src/input_manager.h +++ b/app/src/input_manager.h @@ -14,7 +14,6 @@ struct input_manager { struct controller *controller; - struct fps_counter *fps_counter; struct screen *screen; // SDL reports repeated events as a boolean, but Android expects the actual diff --git a/app/src/scrcpy.c b/app/src/scrcpy.c index 1cb66bc1..e7a349d8 100644 --- a/app/src/scrcpy.c +++ b/app/src/scrcpy.c @@ -18,7 +18,6 @@ #include "device.h" #include "events.h" #include "file_handler.h" -#include "fps_counter.h" #include "input_manager.h" #include "recorder.h" #include "screen.h" @@ -33,7 +32,6 @@ static struct server server; static struct screen screen; -static struct fps_counter fps_counter; static struct stream stream; static struct decoder decoder; static struct recorder recorder; @@ -45,7 +43,6 @@ static struct file_handler file_handler; static struct input_manager input_manager = { .controller = &controller, - .fps_counter = &fps_counter, .screen = &screen, .repeat = 0, @@ -260,7 +257,6 @@ scrcpy(const struct scrcpy_options *options) { bool ret = false; bool server_started = false; - bool fps_counter_initialized = false; bool file_handler_initialized = false; bool recorder_initialized = false; #ifdef HAVE_V4L2 @@ -314,19 +310,12 @@ scrcpy(const struct scrcpy_options *options) { goto end; } - if (options->display) { - if (!fps_counter_init(&fps_counter)) { + if (options->display && options->control) { + if (!file_handler_init(&file_handler, server.serial, + options->push_target)) { goto end; } - fps_counter_initialized = true; - - if (options->control) { - if (!file_handler_init(&file_handler, server.serial, - options->push_target)) { - goto end; - } - file_handler_initialized = true; - } + file_handler_initialized = true; } struct decoder *dec = NULL; @@ -396,7 +385,7 @@ scrcpy(const struct scrcpy_options *options) { .fullscreen = options->fullscreen, }; - if (!screen_init(&screen, &fps_counter, &screen_params)) { + if (!screen_init(&screen, &screen_params)) { goto end; } screen_initialized = true; @@ -451,8 +440,8 @@ end: if (file_handler_initialized) { file_handler_stop(&file_handler); } - if (fps_counter_initialized) { - fps_counter_interrupt(&fps_counter); + if (screen_initialized) { + screen_interrupt(&screen); } if (server_started) { @@ -475,6 +464,7 @@ end: // Destroy the screen only after the stream is guaranteed to be finished, // because otherwise the screen could receive new frames after destruction if (screen_initialized) { + screen_join(&screen); screen_destroy(&screen); } @@ -494,11 +484,6 @@ end: file_handler_destroy(&file_handler); } - if (fps_counter_initialized) { - fps_counter_join(&fps_counter); - fps_counter_destroy(&fps_counter); - } - server_destroy(&server); return ret; diff --git a/app/src/screen.c b/app/src/screen.c index 55a832ef..12ad7d0a 100644 --- a/app/src/screen.c +++ b/app/src/screen.c @@ -277,7 +277,7 @@ screen_frame_sink_push(struct sc_frame_sink *sink, const AVFrame *frame) { } if (previous_frame_skipped) { - fps_counter_add_skipped_frame(screen->fps_counter); + fps_counter_add_skipped_frame(&screen->fps_counter); // The EVENT_NEW_FRAME triggered for the previous frame will consume // this new frame instead } else { @@ -293,10 +293,7 @@ screen_frame_sink_push(struct sc_frame_sink *sink, const AVFrame *frame) { } bool -screen_init(struct screen *screen, struct fps_counter *fps_counter, - const struct screen_params *params) { - screen->fps_counter = fps_counter; - +screen_init(struct screen *screen, const struct screen_params *params) { screen->resize_pending = false; screen->has_frame = false; screen->fullscreen = false; @@ -308,6 +305,12 @@ screen_init(struct screen *screen, struct fps_counter *fps_counter, return false; } + if (!fps_counter_init(&screen->fps_counter)) { + LOGE("Could not initialize FPS counter"); + video_buffer_destroy(&screen->vb); + return false; + } + screen->frame_size = params->frame_size; screen->rotation = params->rotation; if (screen->rotation) { @@ -344,6 +347,7 @@ screen_init(struct screen *screen, struct fps_counter *fps_counter, window_flags); if (!screen->window) { LOGC("Could not create window: %s", SDL_GetError()); + fps_counter_destroy(&screen->fps_counter); video_buffer_destroy(&screen->vb); return false; } @@ -353,6 +357,7 @@ screen_init(struct screen *screen, struct fps_counter *fps_counter, if (!screen->renderer) { LOGC("Could not create renderer: %s", SDL_GetError()); SDL_DestroyWindow(screen->window); + fps_counter_destroy(&screen->fps_counter); video_buffer_destroy(&screen->vb); return false; } @@ -405,6 +410,7 @@ screen_init(struct screen *screen, struct fps_counter *fps_counter, LOGC("Could not create texture: %s", SDL_GetError()); SDL_DestroyRenderer(screen->renderer); SDL_DestroyWindow(screen->window); + fps_counter_destroy(&screen->fps_counter); video_buffer_destroy(&screen->vb); return false; } @@ -415,6 +421,7 @@ screen_init(struct screen *screen, struct fps_counter *fps_counter, SDL_DestroyTexture(screen->texture); SDL_DestroyRenderer(screen->renderer); SDL_DestroyWindow(screen->window); + fps_counter_destroy(&screen->fps_counter); video_buffer_destroy(&screen->vb); return false; } @@ -459,6 +466,16 @@ screen_hide_window(struct screen *screen) { SDL_HideWindow(screen->window); } +void +screen_interrupt(struct screen *screen) { + fps_counter_interrupt(&screen->fps_counter); +} + +void +screen_join(struct screen *screen) { + fps_counter_join(&screen->fps_counter); +} + void screen_destroy(struct screen *screen) { #ifndef NDEBUG @@ -468,6 +485,7 @@ screen_destroy(struct screen *screen) { SDL_DestroyTexture(screen->texture); SDL_DestroyRenderer(screen->renderer); SDL_DestroyWindow(screen->window); + fps_counter_destroy(&screen->fps_counter); video_buffer_destroy(&screen->vb); } @@ -577,7 +595,7 @@ screen_update_frame(struct screen *screen) { video_buffer_consume(&screen->vb, screen->frame); AVFrame *frame = screen->frame; - fps_counter_add_rendered_frame(screen->fps_counter); + fps_counter_add_rendered_frame(&screen->fps_counter); struct size new_frame_size = {frame->width, frame->height}; if (!prepare_for_frame(screen, new_frame_size)) { diff --git a/app/src/screen.h b/app/src/screen.h index 2921c701..e2a43da7 100644 --- a/app/src/screen.h +++ b/app/src/screen.h @@ -20,7 +20,7 @@ struct screen { #endif struct video_buffer vb; - struct fps_counter *fps_counter; + struct fps_counter fps_counter; SDL_Window *window; SDL_Renderer *renderer; @@ -66,8 +66,16 @@ struct screen_params { // initialize screen, create window, renderer and texture (window is hidden) bool -screen_init(struct screen *screen, struct fps_counter *fps_counter, - const struct screen_params *params); +screen_init(struct screen *screen, const struct screen_params *params); + +// request to interrupt any inner thread +// must be called before screen_join() +void +screen_interrupt(struct screen *screen); + +// join any inner thread +void +screen_join(struct screen *screen); // destroy window, renderer and texture (if any) void