[rygel] server: Add MediaResource class
- From: Jens Georg <jensgeorg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [rygel] server: Add MediaResource class
- Date: Sun, 8 Feb 2015 13:24:57 +0000 (UTC)
commit 35071fee90a4c3eb279b28a6652ea363ca856f6d
Author: Jens Georg <mail jensge org>
Date: Thu Nov 13 14:59:02 2014 +0100
server: Add MediaResource class
Based on Cablelabs's CVP-2 implementation
Signed-off-by: Jens Georg <mail jensge org>
src/librygel-server/filelist.am | 1 +
src/librygel-server/rygel-media-resource.vala | 360 +++++++++++++++++++++++++
2 files changed, 361 insertions(+), 0 deletions(-)
---
diff --git a/src/librygel-server/filelist.am b/src/librygel-server/filelist.am
index 21a71db..6364270 100644
--- a/src/librygel-server/filelist.am
+++ b/src/librygel-server/filelist.am
@@ -16,6 +16,7 @@ LIBRYGEL_SERVER_VAPI_SOURCE_FILES = \
rygel-media-item.vala \
rygel-media-file-item.vala \
rygel-media-object.vala \
+ rygel-media-resource.vala \
rygel-media-server-plugin.vala \
rygel-search-expression.vala \
rygel-searchable-container.vala \
diff --git a/src/librygel-server/rygel-media-resource.vala b/src/librygel-server/rygel-media-resource.vala
new file mode 100644
index 0000000..8bbf226
--- /dev/null
+++ b/src/librygel-server/rygel-media-resource.vala
@@ -0,0 +1,360 @@
+/*
+ * Copyright (C) 2013 Cable Television Laboratories, Inc.
+ *
+ * Author: Craig Pratt <craig ecaspia 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.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CABLE TELEVISION LABORATORIES
+ * INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using GUPnP;
+using Gee;
+
+/**
+ * Represents a media resource (Music, Video, Image, etc).
+ */
+public class Rygel.MediaResource : GLib.Object {
+ private string name;
+
+ // Res block fields
+ public string uri { get; set; }
+ public string import_uri { get; set; }
+ public string extension { get; set; default = null; }
+ public int64 size { get; set; default = -1; } // In bytes
+ public int64 cleartext_size { get; set; default = -1; } // In bytes
+ public long duration { get; set; default = -1; } // In seconds
+ public int bitrate { get; set; default = -1; } // In bits per second
+ public int bits_per_sample { get; set; default = -1; }
+ public int color_depth { get; set; default = -1; } // In bits
+ public int width { get; set; default = -1; } // In pixels
+ public int height { get; set; default = -1; } // In pixels
+ public int audio_channels { get; set; default = -1; }
+ public int sample_freq { get; set; default = -1; } // In Hz
+
+ // ProtocolInfo fields
+ public string protocol { get; set; default = null; }
+ public string mime_type { get; set; default = null; }
+ public string dlna_profile { get; set; default = null; }
+ public string network { get; set; default = null; }
+ public string[] play_speeds = null;
+ public DLNAConversion dlna_conversion { get; set; default = DLNAConversion.NONE; }
+ public DLNAFlags dlna_flags { get; set; default = DLNAFlags.NONE; }
+ public DLNAOperation dlna_operation { get; set; default = DLNAOperation.NONE; }
+
+ // I know gupnp-av DIDLLiteResource and ProtocolInfo structures have the above fields.
+ // But both proved to be problematic in their current form. This class can be
+ // refactored if/when these classes are made more more flexible. For now, this class
+ // needs to serve the needs of Rygel first and foremost...
+
+ public MediaResource (string name) {
+ this.name = name;
+ }
+
+ /**
+ * Copy constructor
+ */
+ public MediaResource.from_resource (string name, MediaResource that) {
+ this.name = name;
+ // res block
+ this.uri = that.uri;
+ this.import_uri = that.uri;
+ this.extension = that.extension;
+ this.size = that.size;
+ this.cleartext_size = that.cleartext_size;
+ this.duration = that.duration;
+ this.bitrate = that.bitrate;
+ this.bits_per_sample = that.bits_per_sample;
+ this.color_depth = that.color_depth;
+ this.width = that.width;
+ this.height = that.height;
+ this.audio_channels = that.audio_channels;
+ this.sample_freq = that.sample_freq;
+ // protocol info
+ this.protocol = that.protocol;
+ this.mime_type = that.mime_type;
+ this.dlna_profile = that.dlna_profile;
+ this.network = that.network;
+ this.play_speeds = copy_speeds (that.play_speeds);
+ this.dlna_conversion = that.dlna_conversion;
+ this.dlna_flags = that.dlna_flags;
+ this.dlna_operation = that.dlna_operation;
+ }
+
+ public static string []? copy_speeds (string? [] src) {
+ if (src == null) {
+ return null;
+ }
+ var new_speeds = new string[src.length];
+ int speed_index = 0;
+ foreach (var speed in src) {
+ new_speeds[speed_index++] = speed;
+ }
+
+ return new_speeds;
+ }
+
+ public string get_name () {
+ return this.name;
+ }
+
+ private HashMap<string,string> property_table = new HashMap<string,string> ();
+
+ public void set_custom_property (string ? name, string ? value) {
+ property_table.set (name,value);
+ }
+
+ public string get_custom_property (string ? name) {
+ return property_table.get (name);
+ }
+
+ public Set get_custom_property_names () {
+ return property_table.keys;
+ }
+
+ public void apply_didl_lite (DIDLLiteResource didl_resource) {
+ // Populate the MediaResource from the given DIDLLiteResource
+ // Note: For a DIDLLiteResource, a value of -1/null also signals "not set"
+ this.uri = didl_resource.uri;
+ this.size = didl_resource.size64;
+ this.cleartext_size = didl_resource.cleartext_size;
+ this.duration = didl_resource.duration;
+ this.bitrate = didl_resource.bitrate;
+ this.bits_per_sample = didl_resource.bits_per_sample;
+ this.color_depth = didl_resource.color_depth;
+ this.width = didl_resource.width;
+ this.height = didl_resource.height;
+ this.audio_channels = didl_resource.audio_channels;
+ this.sample_freq = didl_resource.sample_freq;
+ if (didl_resource.protocol_info != null) {
+ this.protocol = didl_resource.protocol_info.protocol;
+ this.mime_type = didl_resource.protocol_info.mime_type;
+ this.dlna_profile = didl_resource.protocol_info.dlna_profile;
+ this.network = didl_resource.protocol_info.network;
+ this.play_speeds = copy_speeds (didl_resource.protocol_info.play_speeds);
+ this.dlna_conversion = didl_resource.protocol_info.dlna_conversion;
+ this.dlna_flags = didl_resource.protocol_info.dlna_flags;
+ this.dlna_operation = didl_resource.protocol_info.dlna_operation;
+ }
+ }
+
+ public DIDLLiteResource serialize (DIDLLiteResource didl_resource) {
+ // Note: For a DIDLLiteResource, a value of -1/null also signals "not set"
+ didl_resource.uri = this.uri;
+ didl_resource.size64 = this.size;
+ didl_resource.cleartext_size = this.cleartext_size;
+ didl_resource.duration = this.duration;
+ didl_resource.bitrate = this.bitrate;
+ didl_resource.bits_per_sample = this.bits_per_sample;
+ didl_resource.color_depth = this.color_depth;
+ didl_resource.width = this.width;
+ didl_resource.height = this.height;
+ didl_resource.audio_channels = this.audio_channels;
+ didl_resource.sample_freq = this.sample_freq;
+ didl_resource.protocol_info = get_protocol_info ();
+
+ return didl_resource;
+ }
+
+ public void set_protocol_info (ProtocolInfo pi) {
+ this.protocol = pi.protocol;
+ this.network = pi.network;
+ this.mime_type = pi.mime_type;
+ this.dlna_profile = pi.dlna_profile;
+ this.dlna_conversion = pi.dlna_conversion;
+ this.dlna_operation = pi.dlna_operation;
+ this.dlna_flags = pi.dlna_flags;
+ this.play_speeds = copy_speeds (pi.play_speeds);
+ }
+
+ public ProtocolInfo get_protocol_info () {
+ var new_pi = new ProtocolInfo ();
+
+ new_pi.protocol = this.protocol;
+ new_pi.network = this.network;
+ new_pi.mime_type = this.mime_type;
+ new_pi.dlna_profile = this.dlna_profile;
+ new_pi.dlna_conversion = this.dlna_conversion;
+ new_pi.dlna_operation = this.dlna_operation;
+ new_pi.dlna_flags = this.dlna_flags;
+ // ProtocolInfo doesn't like having play_speeds set to null
+ if (this.play_speeds != null) {
+ new_pi.play_speeds = copy_speeds (this.play_speeds);
+ }
+
+ return new_pi;
+ }
+
+ public bool supports_arbitrary_byte_seek () {
+ return is_dlna_operation_mode_set (DLNAOperation.RANGE);
+ }
+
+ public bool supports_arbitrary_time_seek () {
+ return is_dlna_operation_mode_set (DLNAOperation.TIMESEEK);
+ }
+
+ public bool supports_limited_byte_seek () {
+ return is_dlna_protocol_flag_set (DLNAFlags.BYTE_BASED_SEEK);
+ }
+
+ public bool supports_limited_time_seek () {
+ return is_dlna_protocol_flag_set (DLNAFlags.TIME_BASED_SEEK);
+ }
+
+ public bool supports_limited_cleartext_byte_seek () {
+ return is_dlna_protocol_flag_set (DLNAFlags.LOP_CLEARTEXT_BYTESEEK);
+ }
+
+ public bool supports_full_cleartext_byte_seek () {
+ return is_dlna_protocol_flag_set (DLNAFlags.CLEARTEXT_BYTESEEK_FULL);
+ }
+
+ public bool is_link_protection_enabled () {
+ return is_dlna_protocol_flag_set (DLNAFlags.LINK_PROTECTED_CONTENT);
+ }
+
+ public bool is_dlna_content () {
+ return (this.dlna_profile != null);
+ }
+
+ public string get_default_transfer_mode () {
+ if (is_dlna_protocol_flag_set (DLNAFlags.STREAMING_TRANSFER_MODE)) {
+ return "Streaming";
+ } else {
+ return "Interactive";
+ }
+ }
+
+ public bool supports_transfer_mode (string transfer_mode) {
+ if (!this.is_dlna_content ()) {
+ return true;
+ }
+
+ switch (transfer_mode) {
+ case "Streaming" :
+ return is_dlna_protocol_flag_set (DLNAFlags.STREAMING_TRANSFER_MODE);
+ case "Interactive" :
+ return is_dlna_protocol_flag_set (DLNAFlags.INTERACTIVE_TRANSFER_MODE);
+ case "Background" :
+ return is_dlna_protocol_flag_set (DLNAFlags.BACKGROUND_TRANSFER_MODE);
+ default:
+ return false;
+ }
+ }
+
+ public bool is_streamable () {
+ return is_dlna_protocol_flag_set (DLNAFlags.STREAMING_TRANSFER_MODE);
+ }
+
+ // This is to check if any of the cleartext byte seek operations are supported.
+ public bool is_cleartext_range_support_enabled () {
+ return ( is_dlna_protocol_flag_set (DLNAFlags.CLEARTEXT_BYTESEEK_FULL
+ | DLNAFlags.LOP_CLEARTEXT_BYTESEEK) );
+ }
+
+ public bool supports_playspeed () {
+ return (this.play_speeds.length > 0);
+ }
+
+ public bool is_dlna_protocol_flag_set (long flags) {
+ return ((this.dlna_flags & flags) != 0);
+ }
+
+ public bool is_dlna_operation_mode_set (long flags) {
+ return ((this.dlna_operation & flags) != 0);
+ }
+
+ public string to_string () {
+ var strbuf = new StringBuilder ();
+ strbuf.append (name).append_unichar ('(');
+ if (this.size >= 0) {
+ strbuf.append ("size ").append (this.size.to_string ())
+ .append_unichar (',');
+ }
+ if (this.cleartext_size >= 0) {
+ strbuf.append ("cleartextsize ").append (this.cleartext_size.to_string ())
+ .append_unichar (',');
+ }
+ if (this.duration >= 0) {
+ strbuf.append ("duration ").append (this.duration.to_string ())
+ .append_unichar (',');
+ }
+ if (this.bitrate >= 0) {
+ strbuf.append ("bitrate ").append (this.bitrate.to_string ())
+ .append_unichar (',');
+ }
+ if (this.bits_per_sample >= 0) {
+ strbuf.append ("bits_per_sample ").append (this.bits_per_sample.to_string ())
+ .append_unichar (',');
+ }
+ if (this.width >= 0) {
+ strbuf.append ("width ").append (this.width.to_string ())
+ .append_unichar (',');
+ }
+ if (this.height >= 0) {
+ strbuf.append ("height ").append (this.height.to_string ())
+ .append_unichar (',');
+ }
+ if (this.color_depth >= 0) {
+ strbuf.append ("color_depth ").append (this.color_depth.to_string ())
+ .append_unichar (',');
+ }
+ if (this.audio_channels >= 0) {
+ strbuf.append ("audio_channels ").append (this.audio_channels.to_string ())
+ .append_unichar (',');
+ }
+ if (this.sample_freq >= 0) {
+ strbuf.append ("sample_freq ").append (this.sample_freq.to_string ())
+ .append_unichar (',');
+ }
+ if (this.network != null) {
+ strbuf.append ("network ").append (this.network).append_unichar (',');
+ }
+ strbuf.append ("protocol ")
+ .append (this.protocol == null ? "null" : this.protocol)
+ .append_unichar (',');
+ strbuf.append ("mime_type ")
+ .append (this.mime_type == null ? "null" : this.mime_type)
+ .append_unichar (',');
+ strbuf.append ("dlna_profile ")
+ .append (this.dlna_profile == null ? "null" : this.dlna_profile)
+ .append_unichar (',');
+ strbuf.append_printf ("dlna_flags %.8X,", this.dlna_flags);
+ if (this.dlna_conversion != DLNAConversion.NONE) {
+ strbuf.append_printf ("dlna_conversion %1d,", this.dlna_conversion);
+ }
+ if (this.dlna_operation != DLNAOperation.NONE) {
+ strbuf.append_printf ("dlna_operation %.2X,", this.dlna_operation);
+ }
+ if (this.play_speeds != null) {
+ strbuf.append ("play_speeds [");
+ foreach (var speed in this.play_speeds) {
+ strbuf.append (speed).append_unichar (',');
+ }
+ strbuf.overwrite (strbuf.len-1,"]"); // Replace comma
+ }
+ strbuf.append (",uri ").append (this.uri == null ? "null" : this.uri);
+ strbuf.append_unichar (')');
+
+ return strbuf.str;
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]