diff --git a/lib/raop_rtp_mirror.c b/lib/raop_rtp_mirror.c index 8ccdcda..c53394d 100755 --- a/lib/raop_rtp_mirror.c +++ b/lib/raop_rtp_mirror.c @@ -178,7 +178,7 @@ raop_rtp_mirror_thread(void *arg) /* Set timeout value to 5ms */ tv.tv_sec = 0; - tv.tv_usec = 5000; + tv.tv_usec = 1000; /* Get the correct nfds value and set rfds */ FD_ZERO(&rfds); @@ -213,7 +213,7 @@ raop_rtp_mirror_thread(void *arg) // We're calling recv for a certain amount of data, so we need a timeout struct timeval tv; tv.tv_sec = 0; - tv.tv_usec = 5000; + tv.tv_usec = 1000; if (setsockopt(stream_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) { logger_log(raop_rtp_mirror->logger, LOGGER_ERR, "raop_rtp_mirror could not set stream socket timeout %d %s", errno, strerror(errno)); break; @@ -331,8 +331,11 @@ raop_rtp_mirror_thread(void *arg) // The information in the payload contains an SPS and a PPS NAL float width_source = byteutils_get_float(packet, 40); + printf("source-width: %f", width_source); float height_source = byteutils_get_float(packet, 44); float width = byteutils_get_float(packet, 56); + printf("width: %f", width); + float height = byteutils_get_float(packet, 60); logger_log(raop_rtp_mirror->logger, LOGGER_DEBUG, "raop_rtp_mirror width_source = %f height_source = %f width = %f height = %f", width_source, height_source, width, height); diff --git a/renderers/video_renderer.h b/renderers/video_renderer.h index b4e97e5..9fa0ff4 100644 --- a/renderers/video_renderer.h +++ b/renderers/video_renderer.h @@ -35,6 +35,7 @@ extern "C" { #include "../lib/logger.h" #include "../lib/raop_ntp.h" + typedef enum background_mode_e { BACKGROUND_MODE_ON, // Always show background BACKGROUND_MODE_AUTO, // Only show background while there's an active connection diff --git a/renderers/video_renderer_gstreamer.c b/renderers/video_renderer_gstreamer.c index 7427092..05cc7d1 100644 --- a/renderers/video_renderer_gstreamer.c +++ b/renderers/video_renderer_gstreamer.c @@ -29,16 +29,10 @@ #include -//#include -//#include -//#include - struct video_renderer_s { logger_t *logger; - GstElement *appsrc, *pipeline, *sink; + GstElement *appsrc, *pipeline, *sink, *decodebin, *videoconvert, *queue; - //GtkWidget *main_window, *video_window; - //GdkWindow *window; }; video_renderer_t *video_renderer_init(logger_t *logger, background_mode_t background_mode, bool low_latency) { @@ -52,7 +46,26 @@ video_renderer_t *video_renderer_init(logger_t *logger, background_mode_t backgr renderer->logger = logger; - renderer->pipeline = gst_parse_launch("appsrc name=video_source is-live=true ! queue ! decodebin ! videoconvert ! autovideosink name=video_sink sync=false", &error); + renderer->pipeline = gst_parse_launch("appsrc name=video_source is-live=true ! queue ! decodebin ! videoconvert ! xvimagesink name=video_sink", &error); + + /* + renderer->pipeline = gst_pipeline_new(NULL); + renderer->appsrc = gst_element_factory_make("appsrc","video_source"); + g_object_set (renderer->appsrc, "is_live", true, NULL); + renderer->sink = gst_element_factory_make("autovideosink","video_sink"); + g_object_set (renderer->sink, "sync", false, NULL); + renderer->queue = gst_element_factory_make("queue",NULL); + renderer->decodebin = gst_element_factory_make("decodebin",NULL); + renderer->videoconvert = gst_element_factory_make("videoconvert",NULL); + gst_bin_add_many(GST_BIN (renderer->pipeline), + renderer->appsrc, + renderer->queue, + renderer->decodebin, + renderer->videoconvert, + renderer->sink, + NULL); + //gst_element_link (renderer->appsrc, renderer->sink); + */ g_assert (renderer->pipeline); @@ -60,22 +73,6 @@ video_renderer_t *video_renderer_init(logger_t *logger, background_mode_t backgr renderer->sink = gst_bin_get_by_name (GST_BIN (renderer->pipeline), "video_sink"); - /* - //GTK - gtk_init (NULL, NULL); - - renderer->main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - g_signal_connect (G_OBJECT (renderer->main_window), "delete-event", G_CALLBACK (video_renderer_destroy), renderer); - gtk_window_set_title (GTK_WINDOW (renderer->main_window), "AirplayServer"); - renderer->video_window = gtk_drawing_area_new (); - gtk_container_add (GTK_CONTAINER (renderer->main_window), renderer->video_window); - gtk_container_set_border_width (GTK_CONTAINER (renderer->main_window), 16); - //gtk_widget_set_double_buffered (renderer->video_window, FALSE); - gtk_widget_show_all (renderer->main_window); - renderer->window = gtk_widget_get_window (renderer->video_window); - gulong embed_xid = GDK_WINDOW_XID (renderer->window); - gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (renderer->appsrc), embed_xid); - */ return renderer; } diff --git a/uxplay.cpp b/uxplay.cpp index 95d3b05..b532cd4 100755 --- a/uxplay.cpp +++ b/uxplay.cpp @@ -33,15 +33,68 @@ #include "renderers/video_renderer.h" #include "renderers/audio_renderer.h" +#include +#include + +#ifdef GDK_WINDOWING_X11 +#include // for GDK_WINDOW_XID +#endif +#ifdef GDK_WINDOWING_WIN32 +#include // for GDK_WINDOW_HWND +#endif + #define VERSION "1.2" -#define DEFAULT_NAME "UxPlay" +#define DEFAULT_NAME "AirPlayLinux" #define DEFAULT_BACKGROUND_MODE BACKGROUND_MODE_ON #define DEFAULT_AUDIO_DEVICE AUDIO_DEVICE_HDMI #define DEFAULT_LOW_LATENCY false #define DEFAULT_DEBUG_LOG false #define DEFAULT_HW_ADDRESS { (char) 0x48, (char) 0x5d, (char) 0x60, (char) 0x7c, (char) 0xee, (char) 0x22 } + +static guintptr video_window_handle = 0; + +static GstBusSyncReply bus_sync_handler (GstBus * bus, GstMessage * message, gpointer user_data) { + // ignore anything but 'prepare-window-handle' element messages + if (!gst_is_video_overlay_prepare_window_handle_message (message)) + return GST_BUS_PASS; + + if (video_window_handle != 0) { + GstVideoOverlay *overlay; + + // GST_MESSAGE_SRC (message) will be the video sink element + overlay = GST_VIDEO_OVERLAY (GST_MESSAGE_SRC (message)); + gst_video_overlay_set_window_handle (overlay, video_window_handle); + } else { + g_warning ("Should have obtained video_window_handle by now!"); + } + + gst_message_unref (message); + return GST_BUS_DROP; +} + +static void video_widget_realize_cb (GtkWidget * widget, gpointer data) { + + printf("Hallo"); + #ifdef GDK_WINDOWING_X11 + { + gulong xid = GDK_WINDOW_XID (gtk_widget_get_window (widget)); + video_window_handle = xid; + } + #endif + #ifdef GDK_WINDOWING_WIN32 + { + HWND wnd = GDK_WINDOW_HWND (gtk_widget_get_window (widget)); + video_window_handle = (guintptr) wnd; + } + #endif +} + + + + + int start_server(std::vector hw_addr, std::string name, background_mode_t background_mode, audio_device_t audio_device, bool low_latency, bool debug_log); @@ -104,6 +157,10 @@ void print_info(char *name) { printf("-v/-h Displays this help and version information\n"); } +static void gtk_destroy (GtkWidget * widget, gpointer data) { + gtk_main_quit(); +} + int main(int argc, char *argv[]) { init_signals(); @@ -157,7 +214,28 @@ int main(int argc, char *argv[]) { return 1; } - running = true; + /* + //GTK + gtk_init (&argc, &argv); + GtkWidget *video_window; + GtkWidget *app_window; + app_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title (GTK_WINDOW (app_window), "AirplayLinux"); + video_window = gtk_drawing_area_new (); + g_signal_connect (video_window, "realize",G_CALLBACK (video_widget_realize_cb), NULL); + g_signal_connect (video_window, "destroy",G_CALLBACK (gtk_destroy), NULL); + gtk_widget_set_double_buffered (video_window, FALSE); + gtk_container_add (GTK_CONTAINER (app_window), video_window); + gtk_widget_show_all (app_window); + gtk_widget_realize (video_window); + g_assert (video_window_handle != 0); + + gulong xid = GDK_WINDOW_XID (gtk_widget_get_window (video_window)); + video_window_handle = xid; + gtk_main(); + */ + + bool running = true; while (running) { sleep(1); }