</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>
<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>
<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>
/*
* Copyright (C) 2012 Intel Corporation
+ * Copyright (C) 2013 Cable Television Laboratories, Inc.
*
* This file is part of Rygel.
*
}
public bool can_seek { get { return false; } }
+ public bool can_seek_bytes { get { return false; } }
private string _content_features = "";
public string? content_features {
}
}
+ public int64 size {
+ get {
+ return 0;
+ }
+ }
+
private int64 _position = 0;
public int64 position {
get {
}
}
+ 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;
}
* 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
}
}
+ 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 {
}
}
+ 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;
}
}
+ 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;
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 () {
* 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
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);
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 ();
}
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"));
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);
}
}
+ 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);
/*
* 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
/// 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
/// 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
/// 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 {
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".
*/
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") {
/*
* 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
}
}
+ public bool can_seek_bytes {
+ get {
+ return false;
+ }
+ }
+
public double volume {
get {
return this.actual_player.volume;
}
}
+ 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;
return ret;
}
+ public bool seek_bytes (int64 bytes) {
+ return false;
+ }
+
public string[] get_protocols () {
return this.protocols;
}