aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2019-08-09 15:54:44 +0200
committerdec05eba <dec05eba@protonmail.com>2019-08-09 15:55:18 +0200
commit322513ac417aa7002946a3f203ae1a65f959677a (patch)
tree95144d28741e79b637159c8ddb1a11fe6accf6ef
parent10fcdec298ccef4971dc6d109222079a0f438004 (diff)
Wait until mpv process dies (prevent zombie), fix crash that happens sometimes when quiting video
-rw-r--r--include/Program.h3
-rw-r--r--src/Program.c13
-rw-r--r--src/QuickMedia.cpp48
-rw-r--r--src/VideoPlayer.cpp4
4 files changed, 57 insertions, 11 deletions
diff --git a/include/Program.h b/include/Program.h
index 69ee564..6a6d038 100644
--- a/include/Program.h
+++ b/include/Program.h
@@ -22,6 +22,9 @@ typedef int (*ProgramOutputCallback)(char *data, int size, void *userdata);
*/
int exec_program(const char **args, ProgramOutputCallback output_callback, void *userdata);
+// Return the exit status, or a negative value if waiting failed
+int wait_program(pid_t process_id);
+
/*
@args need to have at least 2 arguments. The first which is the program name
and the last which is NULL, which indicates end of args
diff --git a/src/Program.c b/src/Program.c
index a863fcd..8d20d43 100644
--- a/src/Program.c
+++ b/src/Program.c
@@ -87,6 +87,19 @@ int exec_program(const char **args, ProgramOutputCallback output_callback, void
}
}
+int wait_program(pid_t process_id) {
+ int status;
+ if(waitpid(process_id, &status, WUNTRACED) == -1) {
+ perror("waitpid failed");
+ return -errno;
+ }
+
+ if(!WIFEXITED(status))
+ return -4;
+
+ return WEXITSTATUS(status);
+}
+
int exec_program_async(const char **args, pid_t *result_process_id) {
/* 1 arguments */
if(args[0] == NULL)
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index db2eeb0..eb77aef 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -373,6 +373,19 @@ namespace QuickMedia {
throw std::runtime_error("Failed to open display to X11 server");
XDisplayScope display_scope(disp);
+ int screen = DefaultScreen(disp);
+ Window video_player_window_id = XCreateWindow(disp, RootWindow(disp, screen),
+ 0, 0, window.getSize().x, window.getSize().y, 0,
+ DefaultDepth(disp, screen),
+ InputOutput,
+ DefaultVisual(disp, screen),
+ 0, NULL);
+
+ XReparentWindow(disp, video_player_window_id, window.getSystemHandle(), 0, 0);
+ XMapWindow(disp, video_player_window_id);
+ XFlush(disp);
+ std::unique_ptr<sf::RenderWindow> video_player_window = std::make_unique<sf::RenderWindow>(video_player_window_id);
+
std::unique_ptr<sf::RenderWindow> video_player_ui_window;
auto on_window_create = [disp, &video_player_ui_window](sf::WindowHandle video_player_window) {
int screen = DefaultScreen(disp);
@@ -396,7 +409,7 @@ namespace QuickMedia {
std::unique_ptr<VideoPlayer> video_player;
- auto play_video = [this, &video_player, &play_next_video, &on_window_create, &video_player_ui_window, &ui_resize]() {
+ auto play_video = [this, &video_player, &play_next_video, &on_window_create, &video_player_ui_window, &ui_resize, &video_player_window]() {
printf("Playing video: %s\n", content_url.c_str());
watched_videos.insert(content_url);
video_player = std::make_unique<VideoPlayer>([this, &play_next_video, &video_player_ui_window, &ui_resize](const char *event_name) {
@@ -428,7 +441,7 @@ namespace QuickMedia {
}
}, on_window_create);
- VideoPlayer::Error err = video_player->load_video(content_url.c_str(), window.getSystemHandle());
+ VideoPlayer::Error err = video_player->load_video(content_url.c_str(), video_player_window->getSystemHandle());
if(err != VideoPlayer::Error::OK) {
std::string err_msg = "Failed to play url: ";
err_msg += content_url;
@@ -455,20 +468,32 @@ namespace QuickMedia {
sf::Clock get_progress_timer;
double progress = 0.0;
+ // We want a black screen before video starts playing, instead of being frozen at previous UI
+ video_player_window->clear();
+ video_player_window->display();
+
while (current_page == Page::VIDEO_CONTENT) {
if(play_next_video) {
play_next_video = false;
play_video();
}
- while (window.pollEvent(event)) {
- base_event_handler(event, Page::SEARCH_SUGGESTION);
- if(event.type == sf::Event::Resized) {
+ while (video_player_window->pollEvent(event)) {
+ if (event.type == sf::Event::Closed) {
+ current_page = Page::EXIT;
+ } else if(event.type == sf::Event::Resized) {
+ window_size.x = event.size.width;
+ window_size.y = event.size.height;
+ video_player_window->setSize(sf::Vector2u(window_size.x, window_size.y));
if(video_player_ui_window)
ui_resize = true;
- } else if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Space) {
- if(video_player->toggle_pause() != VideoPlayer::Error::OK) {
- fprintf(stderr, "Failed to toggle pause!\n");
+ } else if(event.type == sf::Event::KeyPressed) {
+ if(event.key.code == sf::Keyboard::Escape)
+ current_page = Page::SEARCH_SUGGESTION;
+ else if(event.key.code == sf::Keyboard::Space) {
+ if(video_player->toggle_pause() != VideoPlayer::Error::OK) {
+ fprintf(stderr, "Failed to toggle pause!\n");
+ }
}
} else if(event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Left) {
if(time_since_last_left_click.restart().asMilliseconds() <= DOUBLE_CLICK_TIME) {
@@ -509,8 +534,8 @@ namespace QuickMedia {
}
// TODO: Show loading video animation
- //window.clear();
- //window.display();
+ //video_player_window->clear();
+ //video_player_window->display();
if(get_progress_timer.getElapsedTime().asMilliseconds() >= 500) {
get_progress_timer.restart();
@@ -547,6 +572,9 @@ namespace QuickMedia {
}
}
}
+
+ video_player_ui_window.reset();
+ video_player_window.reset();
}
enum class TrackMediaType {
diff --git a/src/VideoPlayer.cpp b/src/VideoPlayer.cpp
index 0e6735a..65bbb67 100644
--- a/src/VideoPlayer.cpp
+++ b/src/VideoPlayer.cpp
@@ -38,8 +38,10 @@ namespace QuickMedia {
}
VideoPlayer::~VideoPlayer() {
- if(video_process_id != -1)
+ if(video_process_id != -1) {
kill(video_process_id, SIGTERM);
+ wait_program(video_process_id);
+ }
if(ipc_socket != -1)
close(ipc_socket);