From 5f9dfffc60e022ee7da315e9dc891fc0e4622001 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Wed, 25 May 2016 23:50:32 +0200 Subject: further cleanups, improved options parser based on glib --- src/gstdvbbackend.c | 150 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 111 insertions(+), 39 deletions(-) (limited to 'src/gstdvbbackend.c') diff --git a/src/gstdvbbackend.c b/src/gstdvbbackend.c index 277d16b..a58d570 100644 --- a/src/gstdvbbackend.c +++ b/src/gstdvbbackend.c @@ -23,11 +23,13 @@ * along with gstdvbbackend. If not, see . */ +#define _GNU_SOURCE #include #include #include #include -#include +#include +#include #include #include @@ -35,7 +37,6 @@ #include "datatypes.h" #include "options.h" -#include "string_list.h" #include "log.h" #include "daemon.h" #include "streamer.h" @@ -59,6 +60,18 @@ static gboolean bus_call(GstBus *bus, GstMessage *msg, gpointer data) g_main_loop_quit(loop); break; } + case GST_MESSAGE_APPLICATION: { + log_printf(DEBUG, "Got Application Message!"); + const GstStructure* ms = gst_message_get_structure(msg); + gboolean quit; + gst_structure_get_boolean(ms, "quit", &quit); + if(quit) { + const gchar* reason = gst_structure_get_string (ms, "reason"); + log_printf(NOTICE, "closing due to message: %s", reason); + g_main_loop_quit(loop); + } + break; + } case GST_MESSAGE_INFO: { GError *info; gst_message_parse_info(msg, &info, NULL); @@ -81,29 +94,86 @@ static gboolean bus_call(GstBus *bus, GstMessage *msg, gpointer data) g_main_loop_quit(loop); break; } - default: + case GST_MESSAGE_STATE_CHANGED: { + GstState old_state, new_state; + gst_message_parse_state_changed(msg, &old_state, &new_state, NULL); + log_printf(DEBUG, "Element '%s' changed state from %s to %s", + (msg->src ? GST_OBJECT_NAME(msg->src) : "NULL"), + gst_element_state_get_name(old_state), + gst_element_state_get_name(new_state)); + break; + } + case GST_MESSAGE_NEW_CLOCK: + { + GstClock *clock; + gst_message_parse_new_clock(msg, &clock); + log_printf(NOTICE, "New clock: %s", (clock ? GST_OBJECT_NAME (clock) : "NULL")); break; } + case GST_MESSAGE_QOS: { + guint64 running_time, stream_time, timestamp, duration; + gst_message_parse_qos(msg, NULL, &running_time, &stream_time, ×tamp, &duration); + log_printf(WARNING, "Element '%s' dropped frames running_time=%lu, stream_time=%lu, timestamp=%lu, duration=%lu", + (msg->src ? GST_OBJECT_NAME(msg->src) : "NULL"), running_time, stream_time, timestamp, duration); + break; + } + /* case GST_MESSAGE_STREAM_STATUS: */ + /* { */ + /* GstStreamStatusType type; */ + /* GstElement *owner; */ + /* const GValue *val; */ + /* gchar *path, *ownerstr; */ + /* GstTask *task = NULL; */ + + /* gst_message_parse_stream_status (msg, &type, &owner); */ + /* val = gst_message_get_stream_status_object (msg); */ + + /* path = gst_object_get_path_string (GST_MESSAGE_SRC (msg)); */ + /* ownerstr = gst_object_get_path_string (GST_OBJECT (owner)); */ + /* log_printf(DEBUG,"Recevied Stream-Status message type: %d, source: %s, owner: %s, object: type %s, value %p", */ + /* type, path, ownerstr, G_VALUE_TYPE_NAME (val), g_value_get_object (val)); */ + /* g_free (path); */ + /* g_free (ownerstr); */ + + /* /\* see if we know how to deal with this object *\/ */ + /* if (G_VALUE_TYPE (val) == GST_TYPE_TASK) { */ + /* task = g_value_get_object (val); */ + /* } */ + + /* switch (type) { */ + /* case GST_STREAM_STATUS_TYPE_CREATE: */ + /* log_printf(DEBUG," created task %p", task); */ + /* break; */ + /* case GST_STREAM_STATUS_TYPE_ENTER: */ + /* /\* log_printf(DEBUG," raising task priority"); *\/ */ + /* /\* setpriority (PRIO_PROCESS, 0, -10); *\/ */ + /* break; */ + /* case GST_STREAM_STATUS_TYPE_LEAVE: */ + /* break; */ + /* default: */ + /* break; */ + /* } */ + /* break; */ + /* } */ + default: + /* log_printf(DEBUG, "unkonwn message %s from %s", GST_MESSAGE_TYPE_NAME(msg), GST_MESSAGE_SRC_NAME(msg)); */ + return TRUE; + } return TRUE; } int main_loop(options_t* opt) { - log_printf(INFO, "entering main loop"); - - GMainLoop *loop; - GstElement *pipeline, *source; - GstBus *bus; - streamer_t streamer; + log_printf(NOTICE, "entering main loop"); - loop = g_main_loop_new(NULL, FALSE); - pipeline = gst_pipeline_new("gstdvbbackend"); + GMainLoop *loop = g_main_loop_new(NULL, FALSE); + GstElement *pipeline = gst_pipeline_new("gstdvbbackend"); if(!pipeline || !loop) { log_printf(ERROR, "the pipeline/loop object could not be created. Exiting."); return -1; } - source = gst_element_factory_make ("dvbsrc", "dvb-source"); + GstElement *source = gst_element_factory_make ("dvbsrc", "dvb-source"); if(!source) { log_printf(ERROR, "Error creating dvb source"); gst_object_unref(GST_OBJECT(pipeline)); @@ -119,6 +189,7 @@ int main_loop(options_t* opt) g_object_set(G_OBJECT(source), "trans-mode", 1, NULL); // 8k g_object_set(G_OBJECT(source), "guard", 4, NULL); // AUTO + streamer_t streamer; int ret = streamer_init(&streamer, loop, opt->host_, opt->port_); if(ret) { gst_object_unref(GST_OBJECT(pipeline)); @@ -128,13 +199,20 @@ int main_loop(options_t* opt) gst_bin_add_many(GST_BIN(pipeline), source, streamer.sink_, NULL); gst_element_link_many(source, streamer.sink_, NULL); - bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline)); + + GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline)); gst_bus_add_watch(bus, bus_call, loop); - gst_object_unref(bus); + gst_object_unref(GST_OBJECT(bus)); + + gulong deep_notify_id = 0; + if(opt->debug_) { + deep_notify_id = g_signal_connect(pipeline, "deep-notify", + G_CALLBACK(gst_object_default_deep_notify), NULL); + } - log_printf(INFO, "Set State: Paused"); + log_printf(NOTICE, "Set State: Paused"); gst_element_set_state(pipeline, GST_STATE_PAUSED); - log_printf(INFO, "Set State: Playing"); + log_printf(NOTICE, "Set State: Playing"); gst_element_set_state(pipeline, GST_STATE_PLAYING); ret = streamer_start(&streamer); @@ -146,8 +224,11 @@ int main_loop(options_t* opt) streamer_stop(&streamer); } + if (deep_notify_id != 0) + g_signal_handler_disconnect(pipeline, deep_notify_id); + log_printf(NOTICE, "Stopping pipeline"); - gst_element_set_state (pipeline, GST_STATE_NULL); + gst_element_set_state(pipeline, GST_STATE_NULL); gst_object_unref(GST_OBJECT(pipeline)); return 0; @@ -160,45 +241,37 @@ int main(int argc, char* argv[]) options_t opt; int ret = options_parse(&opt, argc, argv); if(ret) { - if(ret > 0) - fprintf(stderr, "syntax error near: %s\n\n", argv[ret]); - if(ret == -2) - fprintf(stderr, "memory error on options_parse, exitting\n"); - if(ret == -3) + if(ret == -1) { options_print_version(); - if(ret == -4) - fprintf(stderr, "value out of range\n"); - - if(ret != -2 && ret != -3 && ret != -4) - options_print_usage(); - - if(ret == -1 || ret == -3) ret = 0; - + } options_clear(&opt); log_close(); exit(ret); } - slist_element_t* tmp = opt.log_targets_.first_; - while(tmp) { - ret = log_add_target(tmp->data_); + + guint len = g_strv_length(opt.log_targets_); + guint i; + for(i = 0; i < len; ++i) { + ret = log_add_target(opt.log_targets_[i]); if(ret) { switch(ret) { case -2: fprintf(stderr, "memory error on log_add_target, exitting\n"); break; - case -3: fprintf(stderr, "unknown log target: '%s', exitting\n", (char*)(tmp->data_)); break; - case -4: fprintf(stderr, "this log target is only allowed once: '%s', exitting\n", (char*)(tmp->data_)); break; - default: fprintf(stderr, "syntax error near: '%s', exitting\n", (char*)(tmp->data_)); break; + case -3: fprintf(stderr, "unknown log target: '%s', exitting\n", (char*)(opt.log_targets_[i])); break; + case -4: fprintf(stderr, "this log target is only allowed once: '%s', exitting\n", (char*)(opt.log_targets_[i])); break; + default: fprintf(stderr, "syntax error near: '%s', exitting\n", (char*)(opt.log_targets_[i])); break; } options_clear(&opt); log_close(); exit(ret); } - tmp = tmp->next_; } log_printf(NOTICE, "just started..."); - options_parse_post(&opt); + + if(opt.debug_) + options_print(&opt); priv_info_t priv; if(opt.username_) @@ -241,7 +314,6 @@ int main(int argc, char* argv[]) fclose(pid_file); } - gst_init(NULL, NULL); const gchar *nano_str; guint major, minor, micro, nano; gst_version(&major, &minor, µ, &nano); -- cgit v1.2.3