From 660a2dc378ec22bbdabfc2bd9558755d8e3b4c37 Mon Sep 17 00:00:00 2001 From: thiccaxe <51303986+thiccaxe@users.noreply.github.com> Date: Mon, 4 Sep 2023 15:12:55 -0700 Subject: [PATCH] pause/resume gstreamer stream when video stream stops/starts --- lib/raop.h | 2 ++ lib/raop_rtp_mirror.c | 3 ++- renderers/video_renderer.h | 3 +++ renderers/video_renderer_gstreamer.c | 19 +++++++++++++++++++ uxplay.cpp | 15 +++++++++++++++ 5 files changed, 41 insertions(+), 1 deletion(-) diff --git a/lib/raop.h b/lib/raop.h index 493f1b0..e04ad35 100644 --- a/lib/raop.h +++ b/lib/raop.h @@ -53,6 +53,8 @@ struct raop_callbacks_s { void (*audio_process)(void *cls, raop_ntp_t *ntp, audio_decode_struct *data); void (*video_process)(void *cls, raop_ntp_t *ntp, h264_decode_struct *data); + void (*video_pause)(void *cls); + void (*video_resume)(void *cls); /* Optional but recommended callback functions */ void (*conn_init)(void *cls); diff --git a/lib/raop_rtp_mirror.c b/lib/raop_rtp_mirror.c index 90ec092..009834d 100644 --- a/lib/raop_rtp_mirror.c +++ b/lib/raop_rtp_mirror.c @@ -510,6 +510,7 @@ raop_rtp_mirror_thread(void *arg) h264_data.nal_count += 2; prepend_sps_pps = false; } + raop_rtp_mirror->callbacks.video_resume(raop_rtp_mirror->callbacks.cls); raop_rtp_mirror->callbacks.video_process(raop_rtp_mirror->callbacks.cls, raop_rtp_mirror->ntp, &h264_data); free(payload_out); break; @@ -600,7 +601,7 @@ raop_rtp_mirror_thread(void *arg) // h264.pps_size = pps_size; // h264.picture_parameter_set = malloc(h264.pps_size); // memcpy(h264.picture_parameter_set, picture_parameter_set, pps_size); - + raop_rtp_mirror->callbacks.video_pause(raop_rtp_mirror->callbacks.cls); break; case 0x02: logger_log(raop_rtp_mirror->logger, LOGGER_DEBUG, "\nReceived old-protocol once-per-second packet from client:" diff --git a/renderers/video_renderer.h b/renderers/video_renderer.h index 31f123f..fdbd035 100644 --- a/renderers/video_renderer.h +++ b/renderers/video_renderer.h @@ -52,6 +52,9 @@ void video_renderer_init (logger_t *logger, const char *server_name, videoflip_t const bool *video_sync); void video_renderer_start (); void video_renderer_stop (); +void video_renderer_pause (); +void video_renderer_resume (); +bool video_renderer_is_paused(); void video_renderer_render_buffer (unsigned char* data, int *data_len, int *nal_count, uint64_t *ntp_time); void video_renderer_flush (); unsigned int video_renderer_listen(void *loop); diff --git a/renderers/video_renderer_gstreamer.c b/renderers/video_renderer_gstreamer.c index f4764e3..9c27c91 100644 --- a/renderers/video_renderer_gstreamer.c +++ b/renderers/video_renderer_gstreamer.c @@ -221,6 +221,25 @@ void video_renderer_init(logger_t *render_logger, const char *server_name, vide } } +void video_renderer_pause() { + logger_log(logger, LOGGER_DEBUG, "video renderer paused"); + gst_element_set_state(renderer->pipeline, GST_STATE_PAUSED); +} + +void video_renderer_resume() { + if (video_renderer_is_paused()) { + logger_log(logger, LOGGER_DEBUG, "video renderer resumed"); + gst_element_set_state (renderer->pipeline, GST_STATE_PLAYING); + gst_video_pipeline_base_time = gst_element_get_base_time(renderer->appsrc); + } +} + +bool video_renderer_is_paused() { + GstState state; + gst_element_get_state(renderer->pipeline, &state, NULL, 0); + return (state == GST_STATE_PAUSED); +} + void video_renderer_start() { gst_element_set_state (renderer->pipeline, GST_STATE_PLAYING); gst_video_pipeline_base_time = gst_element_get_base_time(renderer->appsrc); diff --git a/uxplay.cpp b/uxplay.cpp index 3dddaa4..3850a17 100644 --- a/uxplay.cpp +++ b/uxplay.cpp @@ -1120,6 +1120,19 @@ extern "C" void video_process (void *cls, raop_ntp_t *ntp, h264_decode_struct *d } } +extern "C" void video_pause (void *cls) { + if (use_video) { + video_renderer_pause(); + } +} + +extern "C" void video_resume (void *cls) { + if (use_video) { + video_renderer_resume(); + } +} + + extern "C" void audio_flush (void *cls) { if (use_audio) { audio_renderer_flush(); @@ -1254,6 +1267,8 @@ int start_raop_server (unsigned short display[5], unsigned short tcp[3], unsigne raop_cbs.video_process = video_process; raop_cbs.audio_flush = audio_flush; raop_cbs.video_flush = video_flush; + raop_cbs.video_pause = video_pause; + raop_cbs.video_resume = video_resume; raop_cbs.audio_set_volume = audio_set_volume; raop_cbs.audio_get_format = audio_get_format; raop_cbs.video_report_size = video_report_size;