Hello everyone
I have a simple use case where we just need a video feed which we receive via udp. No scrubbing etc needed, just the video feed in real time. I can start the stream and it works as expected and I get the video feed. But I can't get the code to stop when the app is entering the background. I have not found any solution to this problem in this list. I suspect this has to do with my GStreamerBackend not cleaning up properly. I have attached the source code that I use for starting and stopping the stream. It is heavily based on the iOS Tutorial 3, so the start and stop functions are left like they are. It streams like expected and I get a stable Videofeed that I can play and pause. But when calling stop I get a BAD ACCESS. Namely in 'CA::Layer::retain_parent:' For the layer I use the EaglUIView like in the Tutorial. The error occurs when i stop the stream with -(void) stop { if (main_loop) { g_main_loop_quit(main_loop); } } and the app enters the background. Any help would be much appreciated. I'm using gstreamer 1.17.2 (because 1.16.4 had UI-manipulation from a background thread that caused other issues) My start_bus function below. /* Main method for the bus monitoring code */ -(void) start_bus { GstBus *bus; GSource *bus_source; GError *error = NULL; GST_DEBUG ("Creating pipeline"); /* Create our own GLib Main Context and make it the default one */ context = g_main_context_new (); g_main_context_push_thread_default(context); /* Build pipeline */ // ORIGINAL: "videotestsrc ! warptv ! videoconvert ! autovideosink" pipeline = gst_parse_launch("udpsrc multicast-group=224.1.1.1 auto-multicast=true port=1234 multicast-iface=wlp10s0 ! application/x-rtp,encoding-name=JPEG,payload=26 ! rtpjpegdepay ! jpegdec ! autovideosink", &error); if (error) { gchar *message = g_strdup_printf("Unable to build pipeline: %s", error->message); g_clear_error (&error); [self gstreamerReceivedError:message]; g_free (message); return; } /* Set the pipeline to READY, so it can already accept a window handle */ gst_element_set_state(pipeline, GST_STATE_READY); video_sink = gst_bin_get_by_interface(GST_BIN(pipeline), GST_TYPE_VIDEO_OVERLAY); if (!video_sink) { GST_ERROR ("Could not retrieve video sink"); return; } gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(video_sink), (guintptr) (id) ui_video_view); /* Instruct the bus to emit signals for each received message, and connect to the interesting signals */ bus = gst_element_get_bus (pipeline); bus_source = gst_bus_create_watch (bus); g_source_set_callback (bus_source, (GSourceFunc) gst_bus_async_signal_func, NULL, NULL); g_source_attach (bus_source, context); g_source_unref (bus_source); g_signal_connect (G_OBJECT (bus), "message::error", (GCallback)error_cb, (__bridge void *)self); g_signal_connect (G_OBJECT (bus), "message::state-changed", (GCallback)state_changed_cb, (__bridge void *)self); gst_object_unref (bus); /* Create a GLib Main Loop and set it to run */ GST_DEBUG ("Entering main loop..."); main_loop = g_main_loop_new (context, FALSE); [self check_initialization_complete]; g_main_loop_run (main_loop); GST_DEBUG ("Exited main loop"); g_main_loop_unref (main_loop); main_loop = NULL; /* Free resources */ g_main_context_pop_thread_default(context); g_main_context_unref (context); gst_element_set_state (pipeline, GST_STATE_NULL); gst_object_unref (pipeline); pipeline = NULL; gst_object_unref (video_sink); video_sink = NULL; // ##### I suspect I'm not cleaning up properly here. Ev some callback cancelation is missing but I really can't figure out what exactly. ##### // g_signal_stop_emission_by_name(G_OBJECT (bus), "message::error"); // g_signal_stop_emission_by_name(G_OBJECT (bus), "message::state-changed"); // g_source_set_dummy_callback(bus_source); ui_delegate = NULL; ui_video_view = NULL; return; } _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Free forum by Nabble | Edit this page |