diff options
-rw-r--r-- | configure.ac | 7 | ||||
-rw-r--r-- | src/media-engines/Makefile.am | 2 | ||||
-rw-r--r-- | src/media-engines/simple/Makefile.am | 15 | ||||
-rw-r--r-- | src/media-engines/simple/rygel-simple-data-source.vala | 151 | ||||
-rw-r--r-- | src/media-engines/simple/rygel-simple-media-engine.vala | 43 |
5 files changed, 217 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac index ef438651..19ad57bd 100644 --- a/configure.ac +++ b/configure.ac @@ -64,6 +64,8 @@ PKG_CHECK_MODULES(UUID, uuid >= $UUID_REQUIRED) PKG_CHECK_MODULES(LIBSOUP, libsoup-2.4 >= $LIBSOUP_REQUIRED) dnl Media engine to use +BUILT_ENGINES="librygel-media-engine-simple" + AC_ARG_WITH([media_engine], AS_HELP_STRING( [--with-media-engine=@<:@gstreamer|none@:>@], @@ -79,9 +81,11 @@ AS_IF([test "x$with_media_engine" = "xgstreamer"], PKG_CHECK_MODULES(GST_PBU, gstreamer-pbutils-0.10 >= $GSTPBU_REQUIRED) RYGEL_ADD_STAMP([src/librygel-renderer-gst/librygel_renderer_gst_1_0_la_vala.stamp]) enable_gstreamer="yes" + BUILT_ENGINES="$BUILT_ENGINES;librygel-media-engine-gst" ], [enable_gstreamer="no"]) AM_CONDITIONAL([HAVE_GSTREAMER],[test "x$enable_gstreamer" = "xyes"]) +AC_SUBST([BUILT_ENGINES]) dnl Add plugins RYGEL_ADD_PLUGIN([external],[MediaServer2 DBus consumer],[yes]) @@ -95,6 +99,7 @@ AS_IF([test "x$with_media_engine" = "xgstreamer"], RYGEL_ADD_PLUGIN([playbin],[GStreamer playbin],[yes]) RYGEL_ADD_PLUGIN([media-export],[MediaExport],[yes]) RYGEL_ADD_PLUGIN([gst-launch],[GStreamer launchline],[no]) + RYGEL_ADD_STAMP([src/media-engines/gstreamer/librygel_media_engine_gst_la_vala.stamp]) ], [ RYGEL_DISABLE_PLUGIN([test]) @@ -109,6 +114,7 @@ RYGEL_ADD_STAMP([src/librygel-server/librygel_server_1_0_la_vala.stamp]) RYGEL_ADD_STAMP([src/librygel-renderer/librygel_renderer_1_0_la_vala.stamp]) RYGEL_ADD_STAMP([src/rygel/rygel_vala.stamp]) RYGEL_ADD_STAMP([src/ui/rygel_preferences_vala.stamp]) +RYGEL_ADD_STAMP([src/media-engines/simple/librygel_media_engine_simple_la_vala.stamp]) RYGEL_CHECK_VALA([$VALA_REQUIRED], [gupnp-1.0 @@ -271,6 +277,7 @@ src/rygel/Makefile src/ui/Makefile src/media-engines/Makefile src/media-engines/gstreamer/Makefile +src/media-engines/simple/Makefile src/plugins/Makefile data/Makefile data/xml/Makefile diff --git a/src/media-engines/Makefile.am b/src/media-engines/Makefile.am index 9cf45e9a..ed2f1010 100644 --- a/src/media-engines/Makefile.am +++ b/src/media-engines/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS= +SUBDIRS=simple if HAVE_GSTREAMER SUBDIRS += gstreamer diff --git a/src/media-engines/simple/Makefile.am b/src/media-engines/simple/Makefile.am new file mode 100644 index 00000000..039a8921 --- /dev/null +++ b/src/media-engines/simple/Makefile.am @@ -0,0 +1,15 @@ +include $(top_srcdir)/common.am + +engine_LTLIBRARIES = librygel-media-engine-simple.la + +AM_CFLAGS += -DG_LOG_DOMAIN='"MediaEngine-Simple"' + +librygel_media_engine_simple_la_SOURCES = \ + rygel-simple-media-engine.vala \ + rygel-simple-data-source.vala + +librygel_media_engine_simple_la_VALAFLAGS = \ + $(RYGEL_COMMON_SERVER_PLUGIN_VALAFLAGS) + +librygel_media_engine_simple_la_LIBADD = $(RYGEL_COMMON_SERVER_LIBS) +librygel_media_engine_simple_la_LDFLAGS = $(RYGEL_PLUGIN_LINKER_FLAGS) diff --git a/src/media-engines/simple/rygel-simple-data-source.vala b/src/media-engines/simple/rygel-simple-data-source.vala new file mode 100644 index 00000000..b578002c --- /dev/null +++ b/src/media-engines/simple/rygel-simple-data-source.vala @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2012 Intel Corporation. + * + * Author: Jens Georg <jensg@openismus.com> + * + * This file is part of Rygel. + * + * Rygel is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Rygel 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +internal class Rygel.SimpleDataSource : DataSource, Object { + private string uri; + private Thread<void*> thread; + private Mutex mutex = Mutex (); + private Cond cond = Cond (); + private uint64 first_byte = 0; + private uint64 last_byte = 0; + private bool frozen = false; + private bool stop_thread = false; + private HTTPSeek offsets = null; + + public SimpleDataSource (string uri) { + debug ("Creating new data source for %s", uri); + this.uri = uri; + } + + ~SimpleDataSource () { + this.stop (); + } + + public void start (HTTPSeek? offsets) throws Error { + if (offsets != null) { + if (offsets.seek_type == HTTPSeekType.TIME) { + throw new DataSourceError.SEEK_FAILED + (_("Time-based seek not supported")); + + } + } + + this.offsets = offsets; + + debug ("Starting data source for uri %s", this.uri); + + // TODO: Convert to use a thread pool + this.thread = new Thread<void*> ("Rygel Serving thread", + this.thread_func); + } + + public void freeze () { + if (this.frozen) { + return; + } + + this.mutex.lock (); + this.frozen = true; + this.mutex.unlock (); + } + + public void thaw () { + if (!this.frozen) { + return; + } + + this.mutex.lock (); + this.frozen = false; + this.cond.broadcast (); + this.mutex.unlock (); + } + + public void stop () { + if (this.stop_thread) { + return; + } + + this.mutex.lock (); + this.frozen = false; + this.stop_thread = true; + this.cond.broadcast (); + this.mutex.unlock (); + } + + private void* thread_func () { + var file = File.new_for_commandline_arg (this.uri); + debug ("Spawning new thread for streaming file %s", this.uri); + try { + var mapped = new MappedFile (file.get_path (), false); + if (this.offsets != null) { + this.first_byte = this.offsets.start; + this.last_byte = this.offsets.stop + 1; + } else { + this.last_byte = mapped.get_length (); + } + + while (true) { + bool exit; + this.mutex.lock (); + while (this.frozen) { + this.cond.wait (this.mutex); + } + + exit = this.stop_thread; + this.mutex.unlock (); + + if (exit || this.first_byte == this.last_byte) { + debug ("Done streaming!"); + + break; + } + + var start = this.first_byte; + var stop = start + uint16.MAX; + if (stop > this.last_byte) { + stop = this.last_byte; + } + + unowned uint8[] data = (uint8[]) mapped.get_contents (); + data.length = (int) mapped.get_length (); + uint8[] slice = data[start:stop]; + this.first_byte = stop; + + // There's a potential race condition here. + Idle.add ( () => { + if (!this.stop_thread) { + this.data_available (slice); + } + + return false; + }); + } + } catch (Error error) { + warning ("Failed to map file: %s", error.message); + } + + // signalize we're done streaming + Idle.add ( () => { this.done (); return false; }); + + return null; + } +} diff --git a/src/media-engines/simple/rygel-simple-media-engine.vala b/src/media-engines/simple/rygel-simple-media-engine.vala new file mode 100644 index 00000000..c26faede --- /dev/null +++ b/src/media-engines/simple/rygel-simple-media-engine.vala @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2012 Intel Corporation. + * + * Author: Jens Georg <jensg@openismus.com> + * + * This file is part of Rygel. + * + * Rygel is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Rygel 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +internal class Rygel.SimpleMediaEngine : MediaEngine { + private List<DLNAProfile> profiles = new List<DLNAProfile> (); + + public SimpleMediaEngine () { } + + public override unowned List<DLNAProfile> get_dlna_profiles () { + return this.profiles; + } + + public override unowned List<Transcoder>? get_transcoders () { + return null; + } + + public override DataSource create_data_source (string uri) { + return new SimpleDataSource (uri); + } +} + +public static Rygel.MediaEngine module_get_instance () { + return new Rygel.SimpleMediaEngine (); +} |