X-Git-Url: https://git.realraum.at/?a=blobdiff_plain;f=dart-sounds%2Fsrc%2Fdart-sounds.c;h=254dc109f6212256e7eb292efe01b9472316386e;hb=fb206ac0c5fbd2c043f80cb91519e1559e7e1d08;hp=d22ac51e34e6e0408508a168f12b69ee3819ff2e;hpb=43f6060c4fcf81a9a925cdf45d99136419ac064a;p=svn42.git diff --git a/dart-sounds/src/dart-sounds.c b/dart-sounds/src/dart-sounds.c index d22ac51..254dc10 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,89 +81,124 @@ 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) +struct play_file_param { + GstElement *pipeline; + GstElement *source; + gint* sval; + GCond* cond; + GMutex* mutex; + GAsyncQueue* queue; + const char* media_d; +}; + +static gpointer player(gpointer data) +{ + struct play_file_param *p = (struct play_file_param*)data; + GstElement* pipeline = p->pipeline; + GstElement* source = p->source; + gint* sval = p->sval; + GCond* cond = p->cond; + GMutex* mutex = p->mutex; + GAsyncQueue* queue = p->queue; + const char* media_d = p->media_d; + free(p); + + 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); + + char* path; + asprintf(&path, "%s/%s.ogg", media_d, name); + free(name); + if(!path) + return NULL; + + g_print("playing '%s'\n", path); + 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, const char* media_d, 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; + } + GstElement *pipeline = gst_pipeline_new("dart-sounds"); - *source = gst_element_factory_make("filesrc", "source"); + 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) { + 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) { + struct bus_call_param* datab = malloc(sizeof(struct bus_call_param)); + if(!datab) { 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); + 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_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; -}; - -static gpointer play_file(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; - free(p); - - g_print("playing '../media/%s.ogg'\n", name); - char* path; - asprintf(&path, "../media/%s.ogg", name); - if(!path) + 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; + datap->media_d = media_d; + g_thread_create(player, datap, 0, NULL); + } else { + g_printerr("Memory Error\n"); return NULL; + } - 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); - - 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) @@ -182,69 +217,65 @@ static gboolean stdin_read(GIOChannel* src, GIOCondition cond, gpointer data) offset+=len; if(offset > sizeof(buf)) offset = sizeof(buf); - size_t i; - for(i=0; i < offset; ++i) { + size_t i = 0; + for(;i < offset;) { if(buf[i] == '\n') { buf[i] = 0; - struct play_file_param* data = malloc(sizeof(struct play_file_param)); - if(data) { - data->name = 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)); offset -= i+1; - } else offset = 0; + i = 0; + } else { + offset = 0; + break; + } } + else i++; } return 1; } -int main(int argc, char *argv[]) +int main(int argc, char *argv[]) { - gst_init(&argc, &argv); + if(argc < 2) { + fprintf(stderr, "Please specify the path to the media directory"); + return 2; + } + char* media_d = argv[1]; - GMainLoop *loop = g_main_loop_new(NULL, FALSE); + gst_init(NULL, NULL); - gint sval = 1; - GCond* cond = g_cond_new(); - if(!cond) { - g_printerr("Condition could not be created.\n"); + GMainLoop *loop = g_main_loop_new(NULL, FALSE); + 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, media_d, 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; - if(!g_io_add_watch(chan, G_IO_IN, (GIOFunc)stdin_read, &p)) { + 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; } @@ -255,8 +286,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; }