From 4d0498e4a7533307241a807cac6de1eb0c56ba18 Mon Sep 17 00:00:00 2001
From: Christian Pointner <equinox@helsinki.at>
Date: Tue, 15 Feb 2011 13:35:30 +0000
Subject: first gstreamer pipeline


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
-- 
cgit v0.10.2