From 82e45e5d2a2da33ae22bda79f6a391641065a120 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Fri, 1 Jul 2011 04:15:14 +0000 Subject: [PATCH] mostly working --- dart-sounds/src/dart-sounds.c | 198 +++++++++++++++++++++-------------------- 1 file changed, 103 insertions(+), 95 deletions(-) diff --git a/dart-sounds/src/dart-sounds.c b/dart-sounds/src/dart-sounds.c index 58931ac..25482a7 100644 --- a/dart-sounds/src/dart-sounds.c +++ b/dart-sounds/src/dart-sounds.c @@ -45,7 +45,7 @@ static gboolean bus_call(GstBus *bus, GstMessage *msg, gpointer data) { case GST_MESSAGE_EOS: g_mutex_lock(p->mutex); - (*(p->sval))++; + *(p->sval) = 1; g_mutex_unlock(p->mutex); g_cond_signal(p->cond); break; @@ -54,9 +54,9 @@ static gboolean bus_call(GstBus *bus, GstMessage *msg, gpointer data) GError *error; gst_message_parse_error(msg, &error, NULL); g_printerr("Error: %s\n", error->message); - if(error->domain = GST_RESOURCE_ERROR) { + if(error->domain == GST_RESOURCE_ERROR || error->domain == GST_STREAM_ERROR) { g_mutex_lock(p->mutex); - (*(p->sval))++; + *(p->sval) = 1; g_mutex_unlock(p->mutex); g_cond_signal(p->cond); } else g_main_loop_quit(p->loop); @@ -81,93 +81,121 @@ static void on_pad_added(GstElement *element, GstPad *pad, gpointer data) gst_object_unref(sinkpad); } -GstElement* init(GMainLoop *loop, gint* sval, GCond* cond, GMutex* mutex, GstElement** source) -{ - GstElement *pipeline = gst_pipeline_new("dart-sounds"); - *source = gst_element_factory_make("filesrc", "source"); - GstElement *demuxer = gst_element_factory_make("oggdemux", "demuxer"); - GstElement *decoder = gst_element_factory_make("vorbisdec", "decoder"); - GstElement *conv = gst_element_factory_make("audioconvert", "converter"); - GstElement *sink = gst_element_factory_make("autoaudiosink", "sink"); - - if (!pipeline || !(*source) || !demuxer || !decoder || !conv || !sink) { - g_printerr("One element could not be created. Exiting.\n"); - return NULL; - } - - GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE (pipeline)); - struct bus_call_param* data = malloc(sizeof(struct bus_call_param)); - if(!data) { - g_printerr("Memory error\n"); - return NULL; - } - data->loop = loop; - data->sval = sval; - data->cond = cond; - data->mutex = mutex; - gst_bus_add_watch(bus, bus_call, data); - gst_object_unref(bus); - - gst_bin_add_many(GST_BIN(pipeline), *source, demuxer, decoder, conv, sink, NULL); - - gst_element_link(*source, demuxer); - gst_element_link_many(decoder, conv, sink, NULL); - g_signal_connect(demuxer, "pad-added", G_CALLBACK(on_pad_added), decoder); - - return pipeline; -} - struct play_file_param { - char* name; GstElement *pipeline; GstElement *source; gint* sval; GCond* cond; GMutex* mutex; + GAsyncQueue* queue; }; -static gpointer play_file(gpointer data) +static gpointer player(gpointer data) { struct play_file_param *p = (struct play_file_param*)data; - char* name = p->name; GstElement* pipeline = p->pipeline; GstElement* source = p->source; gint* sval = p->sval; GCond* cond = p->cond; GMutex* mutex = p->mutex; + GAsyncQueue* queue = p->queue; free(p); - if(!name) + g_printf("Player thread started\n"); + + for(;;) { + g_mutex_lock(mutex); + while((*sval) < 1) + g_cond_wait(cond, mutex); + *sval = 0; + g_mutex_unlock(mutex); + + char* name = (char*)g_async_queue_pop(queue); + if(!name) + return NULL; + + gst_element_set_state(pipeline, GST_STATE_READY); + + g_print("playing '../media/%s.ogg'\n", name); + char* path; + asprintf(&path, "../media/%s.ogg", name); + free(name); + if(!path) + return NULL; + + g_object_set(G_OBJECT(source), "location", path, NULL); + free(path); + gst_element_set_state(pipeline, GST_STATE_PLAYING); + } + + return NULL; +} + +GstElement* init_pipeline(GMainLoop *loop, GAsyncQueue* queue, gint* sval) +{ + GCond* cond = g_cond_new(); + if(!cond) { + g_printerr("Condition could not be created.\n"); + return NULL; + } + GMutex* mutex = g_mutex_new(); + if(!cond) { + g_printerr("Mutex could not be created.\n"); return NULL; + } - g_print("playing '../media/%s.ogg'\n", name); - char* path; - asprintf(&path, "../media/%s.ogg", name); - free(name); - if(!path) + GstElement *pipeline = gst_pipeline_new("dart-sounds"); + GstElement *source = gst_element_factory_make("filesrc", "source"); + GstElement *demuxer = gst_element_factory_make("oggdemux", "demuxer"); + GstElement *decoder = gst_element_factory_make("vorbisdec", "decoder"); + GstElement *conv = gst_element_factory_make("audioconvert", "converter"); + GstElement *sink = gst_element_factory_make("autoaudiosink", "sink"); + + if (!pipeline || !source || !demuxer || !decoder || !conv || !sink) { + g_printerr("One element could not be created. Exiting.\n"); + return NULL; + } + + GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE (pipeline)); + struct bus_call_param* datab = malloc(sizeof(struct bus_call_param)); + if(!datab) { + g_printerr("Memory error\n"); return NULL; + } + datab->loop = loop; + datab->sval = sval; + datab->cond = cond; + datab->mutex = mutex; + gst_bus_add_watch(bus, bus_call, datab); + gst_object_unref(bus); + + gst_bin_add_many(GST_BIN(pipeline), source, demuxer, decoder, conv, sink, NULL); + gst_element_link(source, demuxer); + gst_element_link_many(decoder, conv, sink, NULL); + g_signal_connect(demuxer, "pad-added", G_CALLBACK(on_pad_added), decoder); - g_mutex_lock(mutex); - while((*sval) < 1) - g_cond_wait(cond, mutex); - (*sval)--; - g_mutex_unlock(mutex); - gst_element_set_state(pipeline, GST_STATE_READY); + struct play_file_param* datap = malloc(sizeof(struct play_file_param)); + if(datap) { + datap->pipeline = pipeline; + datap->source = source; + datap->sval = sval; + datap->cond = cond; + datap->mutex = mutex; + datap->queue = queue; + g_thread_create(player, datap, 0, NULL); + } else { + g_printerr("Memory Error\n"); + return NULL; + } - g_object_set(G_OBJECT(source), "location", path, NULL); - free(path); - gst_element_set_state(pipeline, GST_STATE_PLAYING); + return pipeline; } struct stdin_read_param { GMainLoop *loop; - GstElement *pipeline; - GstElement *source; - gint* sval; - GCond* cond; - GMutex* mutex; + GAsyncQueue *queue; }; static gboolean stdin_read(GIOChannel* src, GIOCondition cond, gpointer data) @@ -183,8 +211,6 @@ static gboolean stdin_read(GIOChannel* src, GIOCondition cond, gpointer data) g_main_loop_quit(p->loop); } - g_print("read %d bytes from STDIN\n", len); - offset+=len; if(offset > sizeof(buf)) offset = sizeof(buf); @@ -193,16 +219,8 @@ static gboolean stdin_read(GIOChannel* src, GIOCondition cond, gpointer data) if(buf[i] == '\n') { buf[i] = 0; - struct play_file_param* data = malloc(sizeof(struct play_file_param)); - if(data) { - data->name = strdup(buf); - data->pipeline = p->pipeline; - data->source = p->source; - data->sval = p->sval; - data->cond = p->cond; - data->mutex = p->mutex; - g_thread_create(play_file, data, 0, NULL); - } + char* tmp = strdup(buf); + if(tmp) g_async_queue_push(p->queue, tmp); if(i < offset) { memmove(buf, &(buf[i+1]), offset - (i+1)); @@ -219,42 +237,35 @@ static gboolean stdin_read(GIOChannel* src, GIOCondition cond, gpointer data) return 1; } -int main(int argc, char *argv[]) +int main(int argc, char *argv[]) { gst_init(&argc, &argv); GMainLoop *loop = g_main_loop_new(NULL, FALSE); - - gint sval = 1; - GCond* cond = g_cond_new(); - if(!cond) { - g_printerr("Condition could not be created.\n"); + if(!loop) { + g_printerr("MainLoop could not be created.\n"); return 1; } - GMutex* mutex = g_mutex_new(); - if(!cond) { - g_printerr("Mutex could not be created.\n"); + + GAsyncQueue *queue = g_async_queue_new(); + if(!queue) { + g_printerr("Async queue could not be created.\n"); return 1; } - GstElement *source; - GstElement *pipeline = init(loop, &sval, cond, mutex, &source); + gint sval = 1; + GstElement *pipeline = init_pipeline(loop, queue, &sval); if(!pipeline) return 1; - GMainContext *ctx = g_main_loop_get_context(loop); + GIOChannel* chan = g_io_channel_unix_new(0); if(!chan) { g_printerr("IO Channel could not be created.\n"); return 1; } - struct stdin_read_param p; p.loop = loop; - p.pipeline = pipeline; - p.source = source; - p.sval = &sval; - p.cond = cond; - p.mutex = mutex; + p.queue = queue; if(!g_io_add_watch(chan, G_IO_IN | G_IO_ERR | G_IO_HUP, (GIOFunc)stdin_read, &p)) { g_printerr("watch for IO Channel could not be added.\n"); return 1; @@ -266,8 +277,5 @@ int main(int argc, char *argv[]) g_print("finished, stopping playback\n"); gst_element_set_state(pipeline, GST_STATE_NULL); - g_print("Deleting pipeline\n"); - gst_object_unref(GST_OBJECT (pipeline)); - return 0; } -- 1.7.10.4