diff options
author | Christian Pointner <equinox@helsinki.at> | 2011-02-15 13:35:30 (GMT) |
---|---|---|
committer | Christian Pointner <equinox@helsinki.at> | 2011-02-15 13:35:30 (GMT) |
commit | 4d0498e4a7533307241a807cac6de1eb0c56ba18 (patch) | |
tree | ac41ad38882bf1597e9e2675f6313a13073eccda | |
parent | cef04da3c24cdcf1c1ffeb214c74f6ef0aaaa0ad (diff) |
first gstreamer pipeline
-rw-r--r-- | README | 2 | ||||
-rw-r--r-- | src/Makefile | 1 | ||||
-rwxr-xr-x | src/configure | 9 | ||||
-rw-r--r-- | src/rharchive.c | 118 | ||||
-rw-r--r-- | src/sig_handler.c | 152 | ||||
-rw-r--r-- | src/sig_handler.h | 35 |
6 files changed, 101 insertions, 216 deletions
@@ -13,6 +13,8 @@ Linux core: build-essential + libgstreamer0.10-dev + pkg-config if you want to rebuild the manpage: asciidoc diff --git a/src/Makefile b/src/Makefile index 80c312a..79c2a82 100644 --- a/src/Makefile +++ b/src/Makefile @@ -35,7 +35,6 @@ C_OBJS := log.o \ options.o \ slist.o \ string_list.o \ - sig_handler.o \ rharchive.o C_SRCS := $(C_OBJS:%.o=%.c) diff --git a/src/configure b/src/configure index 6aee62a..ef6e03a 100755 --- a/src/configure +++ b/src/configure @@ -91,8 +91,11 @@ if [ -n "$ERRORS" ] && [ $EBUILD_COMPAT -ne 1 ]; then exit 1 fi -rm -f version.h +CFLAGS="$CFLAGS $(pkg-config --cflags gstreamer-0.10)" +LDFLAGS="$LDFLAGS $(pkg-config --libs gstreamer-0.10)" + rm -f include.mk +rm -f config.h case $TARGET in Linux) ;; @@ -118,7 +121,7 @@ if [ -z "$MANDIR" ]; then MANDIR=$PREFIX/share/man fi -cat >> include.mk <<EOF +cat > include.mk <<EOF # this file was created automatically # do not edit this file directly # use ./configure instead @@ -154,7 +157,7 @@ fi HOSTNAME=`hostname` DATE=`date +"%d.%m.%Y %H:%M:%S %Z"` -cat >> config.h <<EOF +cat > config.h <<EOF /* * rharchive config header * diff --git a/src/rharchive.c b/src/rharchive.c index 0c92b5c..36743e2 100644 --- a/src/rharchive.c +++ b/src/rharchive.c @@ -31,44 +31,99 @@ #include <string.h> #include <sys/select.h> +#include <gst/gst.h> + #include "datatypes.h" #include "options.h" #include "string_list.h" #include "log.h" #include "daemon.h" + + +static gboolean bus_call(GstBus *bus, GstMessage *msg, gpointer data) +{ + GMainLoop *loop = (GMainLoop *)data; + + switch (GST_MESSAGE_TYPE(msg)) { + case GST_MESSAGE_EOS: { + log_printf(NOTICE, "End of stream"); // thread safety... + g_main_loop_quit (loop); + break; + } + case GST_MESSAGE_ERROR: { + gchar *debug; + GError *error; + + gst_message_parse_error(msg, &error, &debug); + g_free(debug); + log_printf(ERROR, "%s", error->message); // thread safety... + g_error_free(error); + g_main_loop_quit(loop); + break; + } + default: + break; + } + return TRUE; +} + + +static void on_pad_added (GstElement *element, GstPad *pad, gpointer data) +{ + GstPad *sinkpad; + GstElement *decoder = (GstElement *)data; + + log_printf(INFO, "Dynamic pad created, linking demuxer/decoder"); // thread safety... + sinkpad = gst_element_get_static_pad(decoder, "sink"); + gst_pad_link(pad, sinkpad); + gst_object_unref(sinkpad); +} + int main_loop(options_t* opt) { log_printf(INFO, "entering main loop"); - int sig_fd = signal_init(); - if(sig_fd < 0) - return -1; - - int return_value = 0; - while(!return_value) { - fd_set readfds, writefds; - FD_ZERO(&readfds); - FD_ZERO(&writefds); - FD_SET(sig_fd, &readfds); - int nfds = sig_fd; - int ret = select(nfds + 1, &readfds, &writefds, NULL, NULL); - if(ret == -1 && errno != EINTR) { - log_printf(ERROR, "select returned with error: %s", strerror(errno)); - return_value = -1; - break; - } - if(!ret || ret == -1) - continue; + GMainLoop *loop; - if(FD_ISSET(sig_fd, &readfds)) { - return_value = signal_handle(); - if(return_value == 1) break; - } + GstElement *pipeline, *source, *demuxer, *decoder, *conv, *sink; + GstBus *bus; + + loop = g_main_loop_new (NULL, FALSE); + + pipeline = gst_pipeline_new("audio-player"); + source = gst_element_factory_make("filesrc", "file-source"); + demuxer = gst_element_factory_make("oggdemux", "ogg-demuxer"); + decoder = gst_element_factory_make("vorbisdec", "vorbis-decoder"); + conv = gst_element_factory_make("audioconvert", "converter"); + sink = gst_element_factory_make("autoaudiosink", "audio-output"); + + if(!pipeline || !source || !demuxer || !decoder || !conv || !sink) { + log_printf(ERROR, "One element could not be created. Exiting."); + return -1; } + g_object_set(G_OBJECT(source), "location", "file.ogg", NULL); + + bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline)); + gst_bus_add_watch(bus, bus_call, loop); + gst_object_unref(bus); - signal_stop(); - return return_value; + 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); + + log_printf(INFO, "Set State: Playing"); + gst_element_set_state(pipeline, GST_STATE_PLAYING); + + g_main_loop_run (loop); + + log_printf(INFO, "Stopping pipeline"); + gst_element_set_state (pipeline, GST_STATE_NULL); + gst_object_unref (GST_OBJECT (pipeline)); + + return 0; } int main(int argc, char* argv[]) @@ -160,6 +215,18 @@ 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); + if (nano == 1) + nano_str = "(CVS)"; + else if (nano == 2) + nano_str = "(Prerelease)"; + else + nano_str = ""; + log_printf(NOTICE, "rharchive linked against GStreamer %d.%d.%d %s", major, minor, micro, nano_str); + ret = main_loop(&opt); options_clear(&opt); @@ -171,6 +238,7 @@ int main(int argc, char* argv[]) else log_printf(NOTICE, "shutdown after signal"); + gst_deinit(); log_close(); return ret; diff --git a/src/sig_handler.c b/src/sig_handler.c deleted file mode 100644 index 79e2a2d..0000000 --- a/src/sig_handler.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * rharchive - * - * rharchive is a simple tcp connection proxy which combines the - * features of rinetd and 6tunnel. rharchive supports IPv4 and - * IPv6 and also supports connections from IPv6 to IPv4 - * endpoints and vice versa. - * - * - * Copyright (C) 2010-2011 Christian Pointner <equinox@helsinki.at> - * - * This file is part of rharchive. - * - * rharchive is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * rharchive is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with rharchive. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "datatypes.h" - -#include "log.h" - -#include "sig_handler.h" -#include <errno.h> - -#include <signal.h> -#include <unistd.h> -#include <fcntl.h> - -static int sig_pipe_fds[2]; - -static void sig_handler(int sig) -{ - sigset_t set; - int ret = read(sig_pipe_fds[0], &set, sizeof(sigset_t)); - if(ret != sizeof(sigset_t)) - sigemptyset(&set); - - sigaddset(&set, sig); - ret = write(sig_pipe_fds[1], &set, sizeof(sigset_t)); -} - - -int signal_init() -{ - if(pipe(sig_pipe_fds)) { - log_printf(ERROR, "signal handling init failed (pipe error: %s)", strerror(errno)); - return -1; - } - - int i; - for(i=0; i<2; ++i) { - int fd_flags = fcntl(sig_pipe_fds[i], F_GETFL); - if(fd_flags == -1) { - log_printf(ERROR, "signal handling init failed (pipe fd[%d] read flags error: %s)", i, strerror(errno)); - return -1; - } - if(fcntl(sig_pipe_fds[i], F_SETFL, fd_flags | O_NONBLOCK) == -1){ - log_printf(ERROR, "signal handling init failed (pipe fd[%d] write flags error: %s)", i, strerror(errno)); - return -1; - } - } - - struct sigaction act, act_ign; - act.sa_handler = sig_handler; - sigfillset(&act.sa_mask); - act.sa_flags = 0; - act_ign.sa_handler = SIG_IGN; - sigfillset(&act_ign.sa_mask); - act_ign.sa_flags = 0; - - if((sigaction(SIGINT, &act, NULL) < 0) || - (sigaction(SIGQUIT, &act, NULL) < 0) || - (sigaction(SIGTERM, &act, NULL) < 0) || - (sigaction(SIGHUP, &act, NULL) < 0) || - (sigaction(SIGUSR1, &act, NULL) < 0) || - (sigaction(SIGUSR2, &act, NULL) < 0) || - (sigaction(SIGPIPE, &act_ign, NULL) < 0)) { - - log_printf(ERROR, "signal handling init failed (sigaction error: %s)", strerror(errno)); - close(sig_pipe_fds[0]); - close(sig_pipe_fds[1]); - } - - return sig_pipe_fds[0]; -} - -int signal_handle() -{ - sigset_t set, oldset, tmpset; - - sigemptyset(&tmpset); - sigaddset(&tmpset, SIGINT); - sigaddset(&tmpset, SIGQUIT); - sigaddset(&tmpset, SIGTERM); - sigaddset(&tmpset, SIGHUP); - sigaddset(&tmpset, SIGUSR1); - sigaddset(&tmpset, SIGUSR2); - sigprocmask(SIG_BLOCK, &tmpset, &oldset); - - int ret = read(sig_pipe_fds[0], &set, sizeof(sigset_t)); - if(ret != sizeof(sigset_t)) - sigemptyset(&set); - - int return_value = 0; - int sig; - for(sig=1; sig < NSIG; ++sig) { - if(sigismember(&set, sig)) { - switch(sig) { - case SIGINT: log_printf(NOTICE, "SIG-Int caught, exitting"); return_value = 1; break; - case SIGQUIT: log_printf(NOTICE, "SIG-Quit caught, exitting"); return_value = 1; break; - case SIGTERM: log_printf(NOTICE, "SIG-Term caught, exitting"); return_value = 1; break; - case SIGHUP: log_printf(NOTICE, "SIG-Hup caught"); return_value = 2; break; - case SIGUSR1: log_printf(NOTICE, "SIG-Usr1 caught"); return_value = 3; break; - case SIGUSR2: log_printf(NOTICE, "SIG-Usr2 caught"); return_value = 4; break; - default: log_printf(WARNING, "unknown signal %d caught, ignoring", sig); break; - } - sigdelset(&set, sig); - } - } - - sigprocmask(SIG_SETMASK, &oldset, NULL); - return return_value; -} - -void signal_stop() -{ - struct sigaction act; - act.sa_handler = SIG_DFL; - sigemptyset(&act.sa_mask); - act.sa_flags = 0; - - sigaction(SIGINT, &act, NULL); - sigaction(SIGQUIT, &act, NULL); - sigaction(SIGTERM, &act, NULL); - sigaction(SIGHUP, &act, NULL); - sigaction(SIGUSR1, &act, NULL); - sigaction(SIGUSR2, &act, NULL); - sigaction(SIGPIPE, &act, NULL); - - close(sig_pipe_fds[0]); - close(sig_pipe_fds[1]); -} diff --git a/src/sig_handler.h b/src/sig_handler.h deleted file mode 100644 index 10c9637..0000000 --- a/src/sig_handler.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * rharchive - * - * rharchive is a simple tcp connection proxy which combines the - * features of rinetd and 6tunnel. rharchive supports IPv4 and - * IPv6 and also supports connections from IPv6 to IPv4 - * endpoints and vice versa. - * - * - * Copyright (C) 2010-2011 Christian Pointner <equinox@helsinki.at> - * - * This file is part of rharchive. - * - * rharchive is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * rharchive is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with rharchive. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef RHARCHIVE_sig_handler_h_INCLUDED -#define RHARCHIVE_sig_handler_h_INCLUDED - -int signal_init(); -int signal_handle(); -void signal_stop(); - -#endif |