summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Guiraud <christophe.guiraud@intel.com>2013-09-11 17:45:24 +0200
committerChristophe Guiraud <christophe.guiraud@intel.com>2013-09-17 15:42:56 +0200
commitdfda858b5ae63914b45fc35fcbbc47b63d215b04 (patch)
tree187a400ff686cb496474218fcaae91fa599bd243
parent7df1714b593e73533cfb50a4ece623267d94df79 (diff)
downloaddleyna-renderer-dfda858b5ae63914b45fc35fcbbc47b63d215b04.tar.gz
[Device] Fix dlr_device_seek implementation
dlr_device_seek was incorrectly implemented. Modify the current implemention to retrieve the current position with the right method depending on the unit (time or byte) and add it to the delta specified in Seek request, and then call dlr_device_set_position(). so now we have: - TIME SEEK OPERATIONS Seek(offset) -> current_position = UPNP GetPositionInfo["RelTime"] -> UPNP Seek["REL_TIME", current_position + offset] SetPosition(position) -> UPNP Seek["REL_TIME", position] - BYTE SEEK OPERATIONS ByteSeek(offset) -> current_position = UPNP X_DLNA_GetBytePositionInfo["RelByte"] -> UPNP Seek["X_DLNA_REL_BYTE", current_position + offset] SetBytePosition(position) -> UPNP Seek["X_DLNA_REL_BYTE", position] Partial fix for issue: https://github.com/01org/dleyna-renderer/issues/115 Signed-off-by: Christophe Guiraud <christophe.guiraud@intel.com>
-rw-r--r--doc/server/dbus/API.txt4
-rw-r--r--libdleyna/renderer/device.c116
2 files changed, 111 insertions, 9 deletions
diff --git a/doc/server/dbus/API.txt b/doc/server/dbus/API.txt
index bfd2721..7556b6a 100644
--- a/doc/server/dbus/API.txt
+++ b/doc/server/dbus/API.txt
@@ -344,8 +344,8 @@ ByteSeek(x Offset) -> void
SetBytePosition(o TrackID, x Position) -> void
Same as Seek and SetPosition but last parameter (Offset and Position) is not
-expressed in second but in byte, and allows to set the seekmode to respectively
-“REL_COUNT” and “ABS_COUNT” . New in version 0.2.1
+expressed in second but in byte, and allows to set the seekmode by using
+“X_DLNA_REL_BYTE” unit. New in version 0.2.1
org.mpris.MediaPlayer2.TrackList and org.mpris.MediaPlayer2.Playlists
diff --git a/libdleyna/renderer/device.c b/libdleyna/renderer/device.c
index 0c24963..4f22eef 100644
--- a/libdleyna/renderer/device.c
+++ b/libdleyna/renderer/device.c
@@ -3029,28 +3029,130 @@ static void prv_device_set_position(dlr_device_t *device, dlr_task_t *task,
g_free(position);
}
+static void prv_device_seek_set_position(dlr_device_t *device, dlr_task_t *task,
+ const gchar *pos_type,
+ dlr_upnp_task_complete_t cb)
+{
+ dlr_async_task_t *cb_data = (dlr_async_task_t *)task;
+ dlr_task_seek_t *seek_data = &task->ut.seek;
+ gchar *position;
+
+ cb_data->cb = cb;
+ cb_data->device = device;
+
+ if (g_strrstr(pos_type, "_TIME") != NULL)
+ position = prv_int64_to_duration(seek_data->position);
+ else
+ position = g_strdup_printf("%llu",
+ (long long unsigned int)seek_data->counter_position);
+
+ DLEYNA_LOG_INFO("set %s position : %s", pos_type, position);
+
+ cb_data->action =
+ gupnp_service_proxy_begin_action(cb_data->proxy,
+ "Seek",
+ prv_simple_call_cb,
+ cb_data,
+ "InstanceID", G_TYPE_INT, 0,
+ "Unit", G_TYPE_STRING,
+ pos_type,
+ "Target",
+ G_TYPE_STRING, position,
+ NULL);
+
+ g_free(position);
+}
+
+static void prv_complete_seek_get_position(GUPnPServiceProxy *proxy,
+ GUPnPServiceProxyAction *action,
+ gpointer user_data)
+{
+ gchar *result = NULL;
+ const gchar *message;
+ gboolean end;
+ GError *error = NULL;
+ dlr_async_task_t *cb_data = user_data;
+ dlr_task_t *task = &cb_data->task;
+ dlr_task_seek_t *seek_data = &task->ut.seek;
+ guint64 count;
+
+ end = gupnp_service_proxy_end_action(
+ proxy, action, &error,
+ (task->type == DLR_TASK_SEEK) ?
+ "RelTime" : "RelByte",
+ G_TYPE_STRING, &result,
+ NULL);
+
+ if (!end || (result == NULL)) {
+ message = (error != NULL) ? error->message : "Invalid result";
+ cb_data->error =
+ g_error_new(
+ DLEYNA_SERVER_ERROR,
+ DLEYNA_ERROR_OPERATION_FAILED,
+ "%s operation failed: %s",
+ (task->type == DLR_TASK_SEEK) ?
+ "GetPositionInfo" : "X_DLNA_GetBytePositionInfo",
+ message);
+
+ if (error != NULL)
+ g_error_free(error);
+
+ goto on_error;
+ }
+
+ g_strstrip(result);
+
+ if (task->type == DLR_TASK_SEEK) {
+ seek_data->position += prv_duration_to_int64(result);
+
+ prv_device_seek_set_position(cb_data->device, task,
+ "REL_TIME", cb_data->cb);
+ } else {
+ count = strtoull(result, NULL, 10);
+
+ seek_data->counter_position += count;
+
+ prv_device_seek_set_position(cb_data->device, task,
+ "X_DLNA_REL_BYTE", cb_data->cb);
+ }
+
+ g_free(result);
+
+ return;
+
+on_error:
+
+ (void) g_idle_add(dlr_async_task_complete, task);
+ g_cancellable_disconnect(cb_data->cancellable, cb_data->cancel_id);
+}
+
void dlr_device_seek(dlr_device_t *device, dlr_task_t *task,
dlr_upnp_task_complete_t cb)
{
- if (task->type == DLR_TASK_SEEK)
- prv_device_set_position(device, task, "REL_TIME", cb);
- else
- prv_device_set_position(device, task, "REL_COUNT", cb);
+ dlr_async_task_t *cb_data = (dlr_async_task_t *)task;
+
+ cb_data->cb = cb;
+ cb_data->device = device;
+
+ prv_get_position_info(cb_data,
+ (task->type == DLR_TASK_SEEK) ?
+ "GetPositionInfo" : "X_DLNA_GetBytePositionInfo",
+ prv_complete_seek_get_position);
}
void dlr_device_set_position(dlr_device_t *device, dlr_task_t *task,
dlr_upnp_task_complete_t cb)
{
if (task->type == DLR_TASK_SET_POSITION)
- prv_device_set_position(device, task, "REL_TIME", cb);
+ prv_device_set_position(device, task, "REL_TIME", cb);
else
- prv_device_set_position(device, task, "X_DLNA_REL_BYTE", cb);
+ prv_device_set_position(device, task, "X_DLNA_REL_BYTE", cb);
}
void dlr_device_goto_track(dlr_device_t *device, dlr_task_t *task,
dlr_upnp_task_complete_t cb)
{
- prv_device_set_position(device, task, "TRACK_NR", cb);
+ prv_device_set_position(device, task, "TRACK_NR", cb);
}
void dlr_device_host_uri(dlr_device_t *device, dlr_task_t *task,