Handle ERROR or EOS in my gst-rtsp-server application
Aniket Hande via gstreamer-devel <[email protected]>
| Newsgroups | gmane.comp.video.gstreamer.devel |
|---|---|
| Message-ID | <CAF5waX_X295OG=j9v2donNRzN=LFY9hsJm8mQSkr7Us3CzT6_g@mail.gmail.com> |
Hello, I'm trying to write a custom error or eos handler in my gstreamer rtsp server application. The reason is I wanted to catch the "error" signal raised by my watchdog element. I have created a pipeline bin and overriden the create_element method of GstRTSPMediaFactory class. Then I tried to add a watch to my pipeline but it didn't work. I also tried to attach "media-configure" signal to the factory object and do the bus watch thing inside the signal handler but that didn't work either. Has anyone done something like this? I'm attaching code for reference. Any help would be appreciated, thanks in advance.
test-launch.c
(text/x-csrc, 3.2 KB)
#include <gst/gst.h>
#include <gst/rtsp-server/rtsp-server.h>
#include <gst/rtsp-server/rtsp-media-factory.h>
#define DEFAULT_RTSP_PORT "8554"
#define DEFAULT_DISABLE_RTCP FALSE
static char *port = (char *) DEFAULT_RTSP_PORT;
GstElement *pipeline_bin;
struct Data {
GstRTSPServer *server;
GMainLoop *loop;
};
// Override function
GstElement *custom_create_element(GstRTSPMediaFactory *factory, const GstRTSPUrl *url)
{
return pipeline_bin;
}
// Override class
GstRTSPMediaFactory *custom_pipeline_factory()
{
GstRTSPMediaFactory *factory = gst_rtsp_media_factory_new();
GstRTSPMediaFactoryClass *klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS(factory);
klass->create_element = custom_create_element;
return factory;
}
void on_error_signal(GstBus *bus_, GstMessage *msg_, gpointer loop_)
{
g_print ("Got %s message from %s on bus\n", GST_MESSAGE_TYPE_NAME(msg_), GST_MESSAGE_SRC_NAME(msg_));
g_main_loop_quit ((GMainLoop *)loop_);
}
void on_eos_signal(GstBus *bus_, GstMessage *msg_, gpointer loop_)
{
g_print ("Got %s message on bus\n", GST_MESSAGE_TYPE_NAME(msg_));
g_main_loop_quit ((GMainLoop *)loop_);
}
static void
media_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
{
GstElement *element;
GstBus *bus;
element = gst_rtsp_media_get_element (media);
bus = gst_pipeline_get_bus (GST_PIPELINE(element));
gst_bus_add_signal_watch (bus);
g_signal_connect (bus, "message::error",
(GCallback) on_error_signal, NULL);
g_signal_connect (bus, "message::eos",
(GCallback) on_eos_signal, NULL);
gst_object_unref (bus);
gst_object_unref (element);
}
int
main (int argc, char *argv[])
{
struct Data data;
GstRTSPMediaFactory *factory;
GstRTSPMountPoints *mounts;
gst_init (&argc, &argv);
/* create the main loop */
data.loop = g_main_loop_new (NULL, FALSE);
/* create a server instance */
data.server = gst_rtsp_server_new ();
g_object_set (data.server, "service", port, NULL);
/* mount the path */
mounts = gst_rtsp_server_get_mount_points (data.server);
/* create media factory */
factory = custom_pipeline_factory();
gst_rtsp_media_factory_set_shared (factory, TRUE);
/* create launch pipeline */
const gchar *launchline = "( udpsrc port=8989 ! watchdog timeout=4000 ! x264enc ! h264parse ! rtph264pay name=pay0 config-interval=1 )";
GError *error = NULL;
pipeline_bin = gst_parse_launch_full(launchline, NULL, GST_PARSE_FLAG_PLACE_IN_BIN, &error);
if (pipeline_bin == NULL)
g_critical ("could not parse launch syntax (%s): %s", launchline,
(error ? error->message : "unknown reason"));
if (error)
g_error_free (error);
gst_rtsp_mount_points_add_factory (mounts, "/test", factory);
g_object_unref (mounts);
g_signal_connect (factory, "media-configure", (GCallback) media_configure, NULL);
guint id;
/* attach the server to the default maincontext */
if ((id = gst_rtsp_server_attach (data.server, g_main_loop_get_context(data.loop))) == 0)
{
g_print ("failed to attach the server\n");
return -1;
}
else {
g_print ("stream ready at rtsp://127.0.0.1:%s/test\n", port);
}
g_main_loop_run (data.loop);
g_object_unref(data.server);
g_print("Exitting...\n");
return 0;
}