diff --git a/lib/airplay_video.c b/lib/airplay_video.c index 3aa6b3c..2656666 100644 --- a/lib/airplay_video.c +++ b/lib/airplay_video.c @@ -52,7 +52,7 @@ struct airplay_video_s { }; // initialize airplay_video service. -airplay_video_t *airplay_video_service_init(raop_t *raop, unsigned short http_port, +airplay_video_t *airplay_video_init(raop_t *raop, unsigned short http_port, const char *lang, const char *session_id) { char uri[] = "http://localhost:xxxxx"; assert(raop); @@ -96,7 +96,7 @@ airplay_video_t *airplay_video_service_init(raop_t *raop, unsigned short http_po // destroy the airplay_video service void -airplay_video_service_destroy(airplay_video_t *airplay_video) +airplay_video_destroy(airplay_video_t *airplay_video) { if (airplay_video->uri_prefix) { diff --git a/lib/airplay_video.h b/lib/airplay_video.h index 12db0f9..868819d 100644 --- a/lib/airplay_video.h +++ b/lib/airplay_video.h @@ -52,7 +52,7 @@ char *get_media_playlist(airplay_video_t *airplay_video, const char *uri); void destroy_media_data_store(airplay_video_t *airplay_video); void create_media_data_store(airplay_video_t * airplay_video, char ** media_data_store, int num_uri); -void airplay_video_service_destroy(airplay_video_t *airplay_video); +void airplay_video_destroy(airplay_video_t *airplay_video); // C wrappers for c++ class MediaDataStore //create the media_data_store, return a pointer to it. diff --git a/lib/http_handlers.h b/lib/http_handlers.h index 7807c1b..1df4827 100644 --- a/lib/http_handlers.h +++ b/lib/http_handlers.h @@ -98,7 +98,7 @@ http_handler_server_info(raop_conn_t *conn, http_request_t *request, http_respon exit(1); } - airplay_video_t *airplay_video = airplay_video_service_init(conn->raop, conn->raop->port, conn->raop->lang, session_id); + airplay_video_t *airplay_video = airplay_video_init(conn->raop, conn->raop->port, conn->raop->lang, session_id); if (airplay_video) { conn->raop->current_video = id; conn->raop->airplay_video[id] = airplay_video; diff --git a/lib/raop.c b/lib/raop.c index 527287a..1fbaa21 100644 --- a/lib/raop.c +++ b/lib/raop.c @@ -657,7 +657,7 @@ raop_init2(raop_t *raop, int nohold, const char *device_id, const char *keyfile) void raop_destroy(raop_t *raop) { if (raop) { - raop_destroy_airplay_video(raop); + raop_destroy_airplay_video(raop, -1); raop_stop_httpd(raop); pairing_destroy(raop->pairing); httpd_destroy(raop->httpd); @@ -820,10 +820,14 @@ void raop_remove_hls_connections(raop_t * raop) { httpd_remove_connections_by_type(raop->httpd, CONNECTION_TYPE_AIRPLAY); } -void raop_destroy_airplay_video(raop_t *raop) { +void raop_destroy_airplay_video(raop_t *raop, int id) { + assert (id < MAX_AIRPLAY_VIDEO); for (int i = 0; i < MAX_AIRPLAY_VIDEO; i++) { + if (id >= 0 && id != i) { + continue; + } if (raop->airplay_video[i]) { - airplay_video_service_destroy(raop->airplay_video[i]); + airplay_video_destroy(raop->airplay_video[i]); raop->airplay_video[i] = NULL; } } diff --git a/lib/raop.h b/lib/raop.h index b490e23..2dda6c8 100644 --- a/lib/raop.h +++ b/lib/raop.h @@ -105,7 +105,7 @@ raop_ntp_t *raop_ntp_init(logger_t *logger, raop_callbacks_t *callbacks, const c int remote_addr_len, unsigned short timing_rport, timing_protocol_t *time_protocol); -airplay_video_t *airplay_video_service_init(raop_t *raop, unsigned short port, const char *lang, const char *session_id); +airplay_video_t *airplay_video_init(raop_t *raop, unsigned short port, const char *lang, const char *session_id); char *raop_get_lang(raop_t *raop); uint64_t get_local_time(); @@ -127,7 +127,7 @@ RAOP_API void raop_set_dnssd(raop_t *raop, dnssd_t *dnssd); RAOP_API void raop_destroy(raop_t *raop); RAOP_API void raop_remove_known_connections(raop_t * raop); RAOP_API void raop_remove_hls_connections(raop_t * raop); -RAOP_API void raop_destroy_airplay_video(raop_t *raop); +RAOP_API void raop_destroy_airplay_video(raop_t *raop, int id); #ifdef __cplusplus } diff --git a/renderers/video_renderer.c b/renderers/video_renderer.c index 96ce25e..e8fe0f5 100644 --- a/renderers/video_renderer.c +++ b/renderers/video_renderer.c @@ -23,6 +23,7 @@ #include #include #include "video_renderer.h" +#include "../lib/raop.h" #define SECOND_IN_NSECS 1000000000UL #define SECOND_IN_MICROSECS 1000000 @@ -76,6 +77,7 @@ typedef enum { } GstPlayFlags; #define NCODECS 3 /* renderers for h264,h265, and jpeg images */ +static raop_t * raop = NULL; struct video_renderer_s { GstElement *appsrc, *pipeline; @@ -229,6 +231,7 @@ void video_renderer_init(logger_t *render_logger, const char *server_name, video GstCaps *caps = NULL; bool rtp = (bool) strlen(rtp_pipeline); hls_video = (uri != NULL); + raop = NULL; /* videosink choices that are auto */ auto_videosink = (strstr(videosink, "autovideosink") || strstr(videosink, "fpsdisplaysink")); @@ -310,7 +313,7 @@ void video_renderer_init(logger_t *render_logger, const char *server_name, video flags |= GST_PLAY_FLAG_DOWNLOAD; flags |= GST_PLAY_FLAG_BUFFERING; // set by default in playbin3, but not in playbin2; is it needed? g_object_set(renderer_type[i]->pipeline, "flags", flags, NULL); - g_object_set (G_OBJECT (renderer_type[i]->pipeline), "uri", uri, NULL); + //g_object_set (G_OBJECT (renderer_type[i]->pipeline), "uri", uri, NULL); } else { bool jpeg_pipeline = false; if (i == type_264) { @@ -472,10 +475,12 @@ void video_renderer_resume() { } } -void video_renderer_start() { +void video_renderer_start( void * opaque, const char * uri) { GstState state; const gchar *state_name; if (hls_video) { + raop = (raop_t *) opaque; + g_object_set (G_OBJECT (renderer->pipeline), "uri", uri, NULL); gst_element_set_state (renderer->pipeline, GST_STATE_PAUSED); gst_element_get_state(renderer->pipeline, &state, NULL, 1000 * GST_MSECOND); state_name = gst_element_state_get_name(state); @@ -483,6 +488,7 @@ void video_renderer_start() { return; } /* when not hls, start both h264 and h265 pipelines; will shut down the "wrong" one when we know the codec */ + raop = NULL; for (int i = 0; i < n_renderers; i++) { gst_element_set_state (renderer_type[i]->pipeline, GST_STATE_PAUSED); gst_element_get_state(renderer_type[i]->pipeline, &state, NULL, 1000 * GST_MSECOND); diff --git a/renderers/video_renderer.h b/renderers/video_renderer.h index d280592..e931f54 100644 --- a/renderers/video_renderer.h +++ b/renderers/video_renderer.h @@ -51,7 +51,7 @@ typedef struct video_renderer_s video_renderer_t; const char *decoder, const char *converter, const char *videosink, const char *videosink_options, bool initial_fullscreen, bool video_sync, bool h265_support, bool coverart_support, guint playbin_version, const char *uri); -void video_renderer_start (); +void video_renderer_start (void *raop, const char *uri); void video_renderer_stop (); void video_renderer_pause (); void video_renderer_seek(float position); diff --git a/uxplay.cpp b/uxplay.cpp index 3481e96..d11d32d 100644 --- a/uxplay.cpp +++ b/uxplay.cpp @@ -2048,7 +2048,7 @@ extern "C" void video_reset(void *cls, bool hls_shutdown) { video_renderer_stop(); if (hls_shutdown) { url.erase(); - raop_destroy_airplay_video(raop); + raop_destroy_airplay_video(raop, -1); raop_remove_hls_connections(raop); preserve_connections = true; } @@ -2978,11 +2978,11 @@ int main (int argc, char *argv[]) { LOGI("audio_disabled"); } if (use_video) { - video_renderer_init(render_logger, server_name.c_str(), videoflip, video_parser.c_str(), rtp_pipeline.c_str(), + video_renderer_init(render_logger, server_name.c_str(), videoflip, video_parser.c_str(), rtp_pipeline.c_str(), video_decoder.c_str(), video_converter.c_str(), videosink.c_str(), videosink_options.c_str(), fullscreen, video_sync, h265_support, render_coverart, playbin_version, NULL); - video_renderer_start(); + video_renderer_start(NULL, NULL); #ifdef __OpenBSD__ } else { if (pledge("stdio rpath wpath cpath inet unix prot_exec", NULL) == -1) { @@ -3075,7 +3075,7 @@ int main (int argc, char *argv[]) { if (use_video && (close_window || preserve_connections)) { video_renderer_destroy(); if (!preserve_connections) { - raop_destroy_airplay_video(raop); + raop_destroy_airplay_video(raop, -1); url.erase(); raop_remove_known_connections(raop); } @@ -3084,7 +3084,7 @@ int main (int argc, char *argv[]) { video_decoder.c_str(), video_converter.c_str(), videosink.c_str(), videosink_options.c_str(), fullscreen, video_sync, h265_support, render_coverart, playbin_version, uri); - video_renderer_start(); + video_renderer_start((void *) raop, uri); } if (reset_httpd) { unsigned short port = raop_get_port(raop);