[rygel] renderer: Implement DLNA byte seeking
- From: Jens Georg <jensgeorg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [rygel] renderer: Implement DLNA byte seeking
- Date: Sun, 10 Nov 2013 13:55:57 +0000 (UTC)
commit 0347a67d128438dcce66b9ae8785c543c8ef6b1b
Author: Jussi Kukkonen <jussi kukkonen intel com>
Date: Tue Oct 22 14:05:49 2013 +0300
renderer: Implement DLNA byte seeking
Adds X_DLNA_GetBytePositionInfo() method, the required state variables
and the missing SeekModes for Seek() to AVTransport2 implementation.
https://bugzilla.gnome.org/show_bug.cgi?id=710368
https://bugzilla.gnome.org/show_bug.cgi?id=707058
https://bugzilla.gnome.org/show_bug.cgi?id=707059
https://bugzilla.gnome.org/show_bug.cgi?id=707541
data/xml/AVTransport2.xml.in | 44 +++++++++++
.../renderer-plugins/vala/example-player-vala.vala | 18 +++++
.../rygel-playbin-player.vala | 80 ++++++++++++++++++--
src/librygel-renderer/rygel-av-transport.vala | 70 ++++++++++++++++-
src/librygel-renderer/rygel-media-player.vala | 18 ++++-
src/librygel-renderer/rygel-player-controller.vala | 6 ++
src/plugins/mpris/rygel-mpris-player.vala | 25 ++++++
7 files changed, 249 insertions(+), 12 deletions(-)
---
diff --git a/data/xml/AVTransport2.xml.in b/data/xml/AVTransport2.xml.in
index 1b799fd..e9d929b 100644
--- a/data/xml/AVTransport2.xml.in
+++ b/data/xml/AVTransport2.xml.in
@@ -364,6 +364,32 @@
</argument>
</argumentList>
</action>
+
+ <action>
+ <name>X_DLNA_GetBytePositionInfo</name>
+ <argumentList>
+ <argument>
+ <name>InstanceID</name>
+ <direction>in</direction>
+ <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>TrackSize</name>
+ <direction>out</direction>
+ <relatedStateVariable>X_DLNA_CurrentTrackSize</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>RelByte</name>
+ <direction>out</direction>
+ <relatedStateVariable>X_DLNA_RelativeBytePosition</relatedStateVariable>
+ </argument>
+ <argument>
+ <name>AbsByte</name>
+ <direction>out</direction>
+ <relatedStateVariable>X_DLNA_AbsoluteBytePosition</relatedStateVariable>
+ </argument>
+ </argumentList>
+ </action>
</actionList>
<serviceStateTable>
@@ -650,6 +676,9 @@
<allowedValue>ABS_TIME</allowedValue>
<allowedValue>REL_TIME</allowedValue>
<allowedValue>TRACK_NR</allowedValue>
+ <allowedValue>ABS_COUNT</allowedValue>
+ <allowedValue>REL_COUNT</allowedValue>
+ <allowedValue>X_DLNA_REL_BYTE</allowedValue>
</allowedValueList>
</stateVariable>
@@ -662,6 +691,21 @@
<name>A_ARG_TYPE_InstanceID</name>
<dataType>ui4</dataType>
</stateVariable>
+
+ <stateVariable sendEvents="no">
+ <name>X_DLNA_RelativeBytePosition</name>
+ <dataType>string</dataType>
+ </stateVariable>
+
+ <stateVariable sendEvents="no">
+ <name>X_DLNA_AbsoluteBytePosition</name>
+ <dataType>string</dataType>
+ </stateVariable>
+
+ <stateVariable sendEvents="no">
+ <name>X_DLNA_CurrentTrackSize</name>
+ <dataType>string</dataType>
+ </stateVariable>
</serviceStateTable>
</scpd>
diff --git a/examples/renderer-plugins/vala/example-player-vala.vala
b/examples/renderer-plugins/vala/example-player-vala.vala
index 6771e43..660e956 100644
--- a/examples/renderer-plugins/vala/example-player-vala.vala
+++ b/examples/renderer-plugins/vala/example-player-vala.vala
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2012 Intel Corporation
+ * Copyright (C) 2013 Cable Television Laboratories, Inc.
*
* This file is part of Rygel.
*
@@ -140,6 +141,7 @@ public class Rygel.Example.PlayerVala : GLib.Object, Rygel.MediaPlayer {
}
public bool can_seek { get { return false; } }
+ public bool can_seek_bytes { get { return false; } }
private string _content_features = "";
public string? content_features {
@@ -171,6 +173,12 @@ public class Rygel.Example.PlayerVala : GLib.Object, Rygel.MediaPlayer {
}
}
+ public int64 size {
+ get {
+ return 0;
+ }
+ }
+
private int64 _position = 0;
public int64 position {
get {
@@ -178,10 +186,20 @@ public class Rygel.Example.PlayerVala : GLib.Object, Rygel.MediaPlayer {
}
}
+ public int64 byte_position {
+ get {
+ return 0;
+ }
+ }
+
public bool seek (int64 time) {
return false;
}
+ public bool seek_bytes (int64 bytes) {
+ return false;
+ }
+
public string[] get_protocols () {
return PROTOCOLS;
}
diff --git a/src/librygel-renderer-gst/rygel-playbin-player.vala
b/src/librygel-renderer-gst/rygel-playbin-player.vala
index cd35041..3a9cf4b 100644
--- a/src/librygel-renderer-gst/rygel-playbin-player.vala
+++ b/src/librygel-renderer-gst/rygel-playbin-player.vala
@@ -3,11 +3,14 @@
* Copyright (C) 2009,2010,2011,2012 Nokia Corporation.
* Copyright (C) 2012 Openismus GmbH
* Copyright (C) 2012,2013 Intel Corporation.
+ * Copyright (C) 2013 Cable Television Laboratories, Inc.
*
* Author: Jorn Baayen <jorn openedhand com>
* Zeeshan Ali (Khattak) <zeeshanak gnome org>
* <zeeshan ali nokia com>
* Jens Georg <jensg openismus com>
+ * Neha Shanbhag <N Shanbhag cablelabs com>
+ * Sivakumar Mani <siva orexel com>
*
* 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
@@ -233,6 +236,13 @@ public class Rygel.Playbin.Player : GLib.Object, Rygel.MediaPlayer {
}
}
+ public bool can_seek_bytes {
+ get {
+ return this.transfer_mode != TRANSFER_MODE_INTERACTIVE &&
+ ! this.mime_type.has_prefix ("image/");
+ }
+ }
+
private string _content_features = "";
private ProtocolInfo protocol_info;
public string? content_features {
@@ -284,6 +294,18 @@ public class Rygel.Playbin.Player : GLib.Object, Rygel.MediaPlayer {
}
}
+ public int64 size {
+ get {
+ int64 dur;
+
+ if (this.playbin.source.query_duration (Format.BYTES, out dur)) {
+ return dur;
+ } else {
+ return 0;
+ }
+ }
+ }
+
public int64 position {
get {
int64 pos;
@@ -296,6 +318,18 @@ public class Rygel.Playbin.Player : GLib.Object, Rygel.MediaPlayer {
}
}
+ public int64 byte_position {
+ get {
+ int64 pos;
+
+ if (this.playbin.source.query_position (Format.BYTES, out pos)) {
+ return pos;
+ } else {
+ return 0;
+ }
+ }
+ }
+
private Player () {
this.playbin = ElementFactory.make ("playbin", null);
this.foreign = false;
@@ -320,20 +354,52 @@ public class Rygel.Playbin.Player : GLib.Object, Rygel.MediaPlayer {
return player;
}
+ private bool seek_with_format (Format format, int64 target) {
+ bool seeked;
+
+ var speed = this.play_speed_to_double (this._playback_speed);
+ if (speed > 0) {
+ seeked = this.playbin.seek (speed,
+ format,
+ SeekFlags.FLUSH | SeekFlags.SKIP | SeekFlags.ACCURATE,
+ Gst.SeekType.SET,
+ target,
+ Gst.SeekType.NONE,
+ -1);
+ } else {
+ seeked = this.playbin.seek (speed,
+ format,
+ SeekFlags.FLUSH | SeekFlags.SKIP | SeekFlags.ACCURATE,
+ Gst.SeekType.SET,
+ 0,
+ Gst.SeekType.SET,
+ target);
+ }
+
+ return seeked;
+ }
+
public bool seek (int64 time) {
+ debug ("Seeking %lld usec, play speed %s", time, this._new_playback_speed);
+
// Playbin doesn't return false when seeking beyond the end of the
// file
if (time > this.duration) {
return false;
}
- return this.playbin.seek (1.0,
- Format.TIME,
- SeekFlags.FLUSH,
- Gst.SeekType.SET,
- time * Gst.USECOND,
- Gst.SeekType.NONE,
- -1);
+ return this.seek_with_format (Format.TIME, time * Gst.USECOND);
+ }
+
+ public bool seek_bytes (int64 bytes) {
+ debug ("Seeking %lld bytes, play speed %s", bytes, this._new_playback_speed);
+
+ int64 size = this.size;
+ if (size > 0 && bytes > size) {
+ return false;
+ }
+
+ return this.seek_with_format (Format.BYTES, bytes);
}
public string[] get_protocols () {
diff --git a/src/librygel-renderer/rygel-av-transport.vala b/src/librygel-renderer/rygel-av-transport.vala
index d534d91..a423067 100644
--- a/src/librygel-renderer/rygel-av-transport.vala
+++ b/src/librygel-renderer/rygel-av-transport.vala
@@ -2,11 +2,14 @@
* Copyright (C) 2008 OpenedHand Ltd.
* Copyright (C) 2009,2010 Nokia Corporation.
* Copyright (C) 2012 Openismus GmbH.
+ * Copyright (C) 2013 Cable Television Laboratories, Inc.
*
* Author: Jorn Baayen <jorn openedhand com>
* Zeeshan Ali (Khattak) <zeeshanak gnome org>
* <zeeshan ali nokia com>
* Jens Georg <jensg openismus com>
+ * Neha Shanbhag <N Shanbhag cablelabs com>
+ * Sivakumar Mani <siva orexel com>
*
* 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
@@ -135,6 +138,8 @@ internal class Rygel.AVTransport : Service {
action_invoked["Seek"].connect (this.seek_cb);
action_invoked["Next"].connect (this.next_cb);
action_invoked["Previous"].connect (this.previous_cb);
+ action_invoked["X_DLNA_GetBytePositionInfo"].connect
+ (this.x_dlna_get_byte_position_info_cb);
this.controller.notify["playback-state"].connect (this.notify_state_cb);
this.controller.notify["n-tracks"].connect (this.notify_n_tracks_cb);
@@ -558,8 +563,9 @@ internal class Rygel.AVTransport : Service {
return;
}
- this.player.playback_state = "PLAYING";
+ // Speed change will take effect when playback state is changed
this.player.playback_speed = speed;
+ this.player.playback_state = "PLAYING";
action.return ();
}
@@ -596,12 +602,11 @@ internal class Rygel.AVTransport : Service {
switch (unit) {
case "ABS_TIME":
case "REL_TIME":
- debug ("Seeking %s to %s.", unit, target);
-
var seek_target = TimeUtils.time_from_string (target);
- if (unit == "REL_TIME") {
+ if (unit != "ABS_TIME") {
seek_target += this.player.position;
}
+ debug ("Seeking to %lld sec", seek_target / TimeSpan.SECOND);
if (!this.player.can_seek) {
action.return_error (710, _("Seek mode not supported"));
@@ -618,6 +623,31 @@ internal class Rygel.AVTransport : Service {
action.return ();
return;
+ case "REL_COUNT":
+ case "X_DLNA_REL_BYTE":
+ case "ABS_COUNT":
+ var seek_target = int64.parse (target);
+
+ if (unit != "ABS_COUNT") {
+ seek_target += this.player.byte_position;
+ }
+ debug ("Seeking to %lld bytes.", seek_target);
+
+ if (!this.player.can_seek_bytes) {
+ action.return_error (710, _("Seek mode not supported"));
+
+ return;
+ }
+
+ if (!this.player.seek_bytes (seek_target)) {
+ action.return_error (711, _("Illegal seek target"));
+
+ return;
+ }
+
+ action.return ();
+
+ return;
case "TRACK_NR":
debug ("Setting track to %s.", target);
var track = int.parse (target);
@@ -656,6 +686,38 @@ internal class Rygel.AVTransport : Service {
}
}
+ private void x_dlna_get_byte_position_info_cb (Service service,
+ ServiceAction action) {
+ if (!this.check_instance_id (action)) {
+ return;
+ }
+
+ if (this.controller.uri == "") {
+ action.set ("TrackSize",
+ typeof (string),
+ "",
+ "RelByte",
+ typeof (string),
+ "",
+ "AbsByte",
+ typeof (string),
+ "");
+ } else {
+ var position = this.player.byte_position.to_string ();
+ action.set ("TrackSize",
+ typeof (string),
+ this.player.size.to_string (),
+ "RelByte",
+ typeof (string),
+ position,
+ "AbsByte",
+ typeof (string),
+ position);
+ }
+
+ action.return ();
+ }
+
private void notify_state_cb (Object player, ParamSpec p) {
var state = this.player.playback_state;
this.changelog.log ("TransportState", state);
diff --git a/src/librygel-renderer/rygel-media-player.vala b/src/librygel-renderer/rygel-media-player.vala
index 181ffeb..1efcf05 100644
--- a/src/librygel-renderer/rygel-media-player.vala
+++ b/src/librygel-renderer/rygel-media-player.vala
@@ -1,11 +1,13 @@
/*
* Copyright (C) 2008 OpenedHand Ltd.
* Copyright (C) 2009,2010 Nokia Corporation.
- * Copyright (C) 2012 Intel Corporation.
+ * Copyright (C) 2012,2013 Intel Corporation.
+ * Copyright (C) 2013 Cable Television Laboratories, Inc.
*
* Author: Jorn Baayen <jorn openedhand com>
* Zeeshan Ali (Khattak) <zeeshanak gnome org>
* <zeeshan ali nokia com>
+ * Sivakumar Mani <siva orexel com>
*
* 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
@@ -51,6 +53,9 @@ public interface Rygel.MediaPlayer : GLib.Object {
/// Duration of the current media in microseconds
public abstract int64 duration { get; }
+ /// Size of the current media in bytes
+ public abstract int64 size { get; }
+
/**
* A DIDLLite document describing the current media URI or null.
* The document is either the one received from a UPnP control point or
@@ -64,6 +69,9 @@ public interface Rygel.MediaPlayer : GLib.Object {
/// The current media supports time-based seeking
public abstract bool can_seek { get; }
+ /// The current media supports byte-based seeking
+ public abstract bool can_seek_bytes { get; }
+
/**
* The contents of the contentFeatures.dlna.org HTTP header,
* containing the 4th field of the protocol info for the current
@@ -82,6 +90,9 @@ public interface Rygel.MediaPlayer : GLib.Object {
/// Position in the current media in microseconds
public abstract int64 position { get; }
+ ///Position in the current media in bytes
+ public abstract int64 byte_position { get; }
+
/// The position as a human-readable string, in HH:MM:SS format
public string position_as_str {
owned get {
@@ -96,6 +107,11 @@ public interface Rygel.MediaPlayer : GLib.Object {
public abstract bool seek (int64 time);
/**
+ * Seek to a byte position in the current media.
+ */
+ public abstract bool seek_bytes (int64 bytes);
+
+ /**
* Return the protocols supported by this renderer,
* such as "http-get" and "rtsp".
*/
diff --git a/src/librygel-renderer/rygel-player-controller.vala
b/src/librygel-renderer/rygel-player-controller.vala
index d2fc496..0d91640 100644
--- a/src/librygel-renderer/rygel-player-controller.vala
+++ b/src/librygel-renderer/rygel-player-controller.vala
@@ -106,7 +106,13 @@ internal class Rygel.PlayerController : Object {
if (this.player.can_seek) {
actions += ",X_DLNA_SeekTime";
+ }
+ if (actions != null && this.player.can_seek_bytes) {
+ actions += ",X_DLNA_SeekByte";
+ }
+ if (actions != null &&
+ this.player.allowed_playback_speeds.length > 1) {
string play_speeds = "";
foreach (var speed in this.player.allowed_playback_speeds) {
if (speed != "1") {
diff --git a/src/plugins/mpris/rygel-mpris-player.vala b/src/plugins/mpris/rygel-mpris-player.vala
index ba7afaf..8fab6e6 100644
--- a/src/plugins/mpris/rygel-mpris-player.vala
+++ b/src/plugins/mpris/rygel-mpris-player.vala
@@ -1,10 +1,12 @@
/*
* Copyright (C) 2008 OpenedHand Ltd.
* Copyright (C) 2009 Nokia Corporation.
+ * Copyright (C) 2013 Cable Television Laboratories, Inc.
*
* Author: Jorn Baayen <jorn openedhand com>
* Zeeshan Ali (Khattak) <zeeshanak gnome org>
* <zeeshan ali nokia com>
+ * Sivakumar Mani <siva orexel com>
*
* 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
@@ -128,6 +130,12 @@ public class Rygel.MPRIS.Player : GLib.Object, Rygel.MediaPlayer {
}
}
+ public bool can_seek_bytes {
+ get {
+ return false;
+ }
+ }
+
public double volume {
get {
return this.actual_player.volume;
@@ -151,12 +159,25 @@ public class Rygel.MPRIS.Player : GLib.Object, Rygel.MediaPlayer {
}
}
+ public int64 size {
+ get {
+ return 0;
+ }
+ }
+
public int64 position {
get {
return this.actual_player.position;
}
}
+ public int64 byte_position {
+ get {
+ return 0;
+ }
+ }
+
+
public Player (Plugin plugin) {
this.actual_player = plugin.actual_player;
this.mime_types = plugin.mime_types;
@@ -176,6 +197,10 @@ public class Rygel.MPRIS.Player : GLib.Object, Rygel.MediaPlayer {
return ret;
}
+ public bool seek_bytes (int64 bytes) {
+ return false;
+ }
+
public string[] get_protocols () {
return this.protocols;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]