summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@helsinki.at>2011-02-15 13:35:30 (GMT)
committerChristian Pointner <equinox@helsinki.at>2011-02-15 13:35:30 (GMT)
commit4d0498e4a7533307241a807cac6de1eb0c56ba18 (patch)
treeac41ad38882bf1597e9e2675f6313a13073eccda
parentcef04da3c24cdcf1c1ffeb214c74f6ef0aaaa0ad (diff)
first gstreamer pipeline
-rw-r--r--README2
-rw-r--r--src/Makefile1
-rwxr-xr-xsrc/configure9
-rw-r--r--src/rharchive.c118
-rw-r--r--src/sig_handler.c152
-rw-r--r--src/sig_handler.h35
6 files changed, 101 insertions, 216 deletions
diff --git a/README b/README
index f8c2930..ca9427f 100644
--- a/README
+++ b/README
@@ -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, &micro, &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