Use thread for SEM render 76/214676/6
authorGilbok Lee <gilbok.lee@samsung.com>
Wed, 25 Sep 2019 07:19:45 +0000 (16:19 +0900)
committerGilbok Lee <gilbok.lee@samsung.com>
Tue, 1 Oct 2019 07:45:29 +0000 (16:45 +0900)
Change-Id: Ic225988096e49700a3f30d13e8354a1c098a1e32

12 files changed:
include/rose_tizen.h
include/rose_tizen_ctlinfo_parse.h
include/rose_tizen_parse_xml.h
include/rose_tizen_priv.h
include/rose_tizen_sem_parse.h
media_player/rose_tizen_mplayer.h
media_player/rose_tizen_mplayer_interface.h
packaging/capi-media-rose-tizen.spec
src/rose_tizen.c
src/rose_tizen_ctlinfo_parse.c
src/rose_tizen_sem_parse.c
test/rose_tizen_test.c

index dd96ee5f66a9a28525e9bcfe206d58492c17a783..4b9d13e541c8b0b981fbeb73284567fbbb6562c3 100644 (file)
@@ -14,8 +14,8 @@
 * limitations under the License.
 */
 
-#ifndef __TIZEN_MEDIA_ROSE_H__
-#define __TIZEN_MEDIA_ROSE_H__
+#ifndef __TIZEN_MEDIA_ROSE_TIZEN_H__
+#define __TIZEN_MEDIA_ROSE_TIZEN_H__
 
 #include <tizen.h>
 #include <stdbool.h>
@@ -62,7 +62,7 @@ int rose_unprepare(rose_h rose);
 int rose_start(rose_h rose);
 int rose_stop(rose_h rose);
 int rose_pause(rose_h rose);
-int rose_set_play_position(rose_h rose, int msec, bool accurate);
+//int rose_set_play_position(rose_h rose, int msec, bool accurate);
 int rose_get_play_position(rose_h rose, int *msec);
 //int rose_get_state(rose_h rose, rose_state_e *state);
 int rose_set_display(rose_h rose, rose_display_type_e type, void *display);
@@ -73,4 +73,4 @@ int rose_set_control_info_path(rose_h rose, const char *path);
 #ifdef __cplusplus
 }
 #endif
-#endif /* __TIZEN_MEDIA_ROSE_H__ */
+#endif /* __TIZEN_MEDIA_ROSE_TIZEN_H__ */
index 29892fce046320552d5a07cda02f70127f91f232..2508112902c1dd1fc0e11c91d25bc06029b76933 100644 (file)
@@ -14,8 +14,8 @@
 * limitations under the License.
 */
 
-#ifndef __TIZEN_MEDIA_ROSE_CTLINFO_H__
-#define __TIZEN_MEDIA_ROSE_CTLINFO_H__
+#ifndef __TIZEN_MEDIA_ROSE_TIZEN_CTLINFO_PARSE_H__
+#define __TIZEN_MEDIA_ROSE_TIZEN_CTLINFO_PARSE_H__
 
 #include <glib.h>
 #include <libxml/parser.h>
@@ -117,8 +117,11 @@ struct _rose_control_info {
 int rose_ctl_info_parse(xmlNode * a_node, rose_control_info ** ctl_info);
 void rose_ctl_info_free(rose_control_info * ctl_info);
 
+/* The number of devices and information of the device are needed. */
+guint rose_ctl_get_total_delay_time(rose_control_info * ctl_info, rose_sdc_type_e type);
+
 #ifdef __cplusplus
 }
 #endif
 
-#endif /* __TIZEN_MEDIA_ROSE_CTLINFO_H__ */
+#endif /* __TIZEN_MEDIA_ROSE_TIZEN_CTLINFO_PARSE_H__ */
index 4948190a54f6025d392a7ba312920f44eb3438c0..1ca380b99146b36113427e041d3110cb718e914d 100644 (file)
@@ -14,8 +14,8 @@
 * limitations under the License.
 */
 
-#ifndef __TIZEN_MEDIA_ROSE_XML_H__
-#define __TIZEN_MEDIA_ROSE_XML_H__
+#ifndef __TIZEN_MEDIA_ROSE_TIZEN_PARSE_XML_H__
+#define __TIZEN_MEDIA_ROSE_TIZEN_PARSE_XML_H__
 
 #include <glib.h>
 #include <libxml/parser.h>
@@ -34,4 +34,4 @@ gboolean _get_xml_prop_float(xmlNode * node, const gchar * prop_name, gfloat * p
 #ifdef __cplusplus
 }
 #endif
-#endif /* __TIZEN_MEDIA_ROSE_XML_H__ */
+#endif /* __TIZEN_MEDIA_ROSE_TIZEN_PARSE_XML_H__ */
index 166856b9fd06be150f9f0c0f9887ae5015015186..fe902d05e058e7939230383fc698049882011aa3 100644 (file)
 * limitations under the License.
 */
 
-#ifndef __TIZEN_MEDIA_ROSE_PRIVATE_H__
-#define __TIZEN_MEDIA_ROSE_PRIVATE_H__
+#ifndef __TIZEN_MEDIA_ROSE_TIZEN_PRIV_H__
+#define __TIZEN_MEDIA_ROSE_TIZEN_PRIV_H__
 
 #include <glib.h>
 #include <dlog.h>
+#include <time.h>
 #include "rose_tizen.h"
 #include "rose_tizen_sem_parse.h"
 #include "rose_tizen_ctlinfo_parse.h"
@@ -33,16 +34,21 @@ extern "C" {
 #endif
 #define LOG_TAG "TIZEN_N_ROSE"
 
+#define ROSE_GET_SEM(handle)          ((rose_s *)handle)->sem
+#define ROSE_GET_RENDERER(handle)     ((rose_s *)handle)->renderer
+#define ROSE_GET_MPLAYER_INTF(handle) ((rose_s *)handle)->mplayer_intf
+#define ROSE_GET_CTL_INFO(hanlde)     ((rose_s *)handle)->ctl_info
+
 #define ROSE_CHECK_CONDITION(condition, error, msg) \
 do { \
-       if (condition) {} else { \
-               LOGE("[%s] %s(0x%08x)", __FUNCTION__, msg, error); \
+       if (!condition) { \
+               LOGE("%s return %s", msg, #error); \
                return error; \
        } \
 } while (0)
 
 #define ROSE_CHECK_INSTANCE(rose) \
-       ROSE_CHECK_CONDITION(rose != NULL, ROSE_ERROR_INVALID_PARAMETER, \
+       ROSE_CHECK_CONDITION(rose, ROSE_ERROR_INVALID_PARAMETER, \
                "ROSE_ERROR_INVALID_PARAMETER")
 
 #define ROSE_CHECK_NULL(arg) \
@@ -73,16 +79,88 @@ do { \
                return ROSE_ERROR_INVALID_STATE; \
        } \
 } while (0)
+
+#define ROSE_SET_STATE(x_rose, x_state)  \
+do { \
+       LOGD("setting state [%s:%d]", #x_state, x_state); \
+       ((rose_s *)(x_rose))->state = x_state; \
+} while (0)
+
+#define ROSE_CHECK_NULL_GOTO(arg, error) \
+do { \
+       if (!arg) { \
+               LOGE("[%s] input arg is NULL goto %s", #arg, #error); \
+               goto error; \
+       } \
+} while (0)
+
+#define ROSE_G_FREE_IF(x) \
+do { \
+       if (x) { \
+               g_free(x); \
+               x = NULL; \
+       } \
+} while (0)
+
+#define _RENDER_MUTEX_INIT(x_render) g_mutex_init(&((rose_render *)x_render)->mutex)
+#define _RENDER_MUTEX_LOCK(x_render) g_mutex_lock(&((rose_render *)x_render)->mutex)
+#define _RENDER_MUTEX_UNLOCK(x_render) g_mutex_unlock(&((rose_render *)x_render)->mutex)
+
+#define _RENDER_PAUSE_MUTEX_INIT(x_render) g_mutex_init(&((rose_render *)x_render)->pause_mutex)
+#define _RENDER_PAUSE_MUTEX_LOCK(x_render) g_mutex_lock(&((rose_render *)x_render)->pause_mutex)
+#define _RENDER_PAUSE_MUTEX_UNLOCK(x_render) g_mutex_unlock(&((rose_render *)x_render)->pause_mutex)
+
+#define _RENDER_CLOCK_MUTEX_INIT(x_render) g_mutex_init(&((rose_render *)x_render)->clock_mutex)
+#define _RENDER_CLOCK_MUTEX_LOCK(x_render) g_mutex_lock(&((rose_render *)x_render)->clock_mutex)
+#define _RENDER_CLOCK_MUTEX_UNLOCK(x_render) g_mutex_unlock(&((rose_render *)x_render)->clock_mutex)
+
+#define _RENDER_COND_INIT(x_render) g_cond_init(&((rose_render *)x_render)->cond)
+#define _RENDER_COND_WAIT(x_render) g_cond_wait(&((rose_render *)x_render)->cond, &((rose_render *)x_render)->mutex)
+#define _RENDER_COND_SIGNAL(x_render) g_cond_signal(&((rose_render *)x_render)->cond)
+
+#define _RENDER_PAUSE_COND_INIT(x_render) g_cond_init(&((rose_render *)x_render)->pause_cond)
+#define _RENDER_PAUSE_COND_WAIT(x_render) g_cond_wait(&((rose_render *)x_render)->pause_cond, &((rose_render *)x_render)->pause_mutex)
+#define _RENDER_PAUSE_COND_SIGNAL(x_render) g_cond_signal(&((rose_render *)x_render)->pause_cond)
+
+#define DEFAULT_CHECK_TIME_MS 100
+
+typedef struct _rose_render {
+       GMutex mutex;
+       GCond cond;
+
+       GMutex pause_mutex;
+       GCond pause_cond;
+
+       GMutex clock_mutex;
+
+       gboolean thread_exit;
+       gboolean thread_pause;
+
+       gboolean mplayer_is_started;
+
+       gint64 base_clock;
+       gint64 time_offset;
+
+       guint wait_timer;
+
+       GList *cur_sem_list;
+       GList *last_sem_list;
+
+       GThread *thread;
+} rose_render;
+
 typedef struct _rose_s {
        rose_state_e state;
        gchar *sem_path;
        gchar *media_path;
+       gchar *ctl_info_path;
        rose_sem *sem;
        rose_control_info *ctl_info;
        mplayer_interface *mplayer_intf;
+       rose_render *renderer;
 } rose_s;
 
 #ifdef __cplusplus
 }
 #endif
-#endif /* __TIZEN_MEDIA_ROSE_PRIVATE_H__ */
+#endif /* __TIZEN_MEDIA_ROSE_TIZEN_PRIV_H__ */
index 3cf70f81cd870bc72628ebc8d8f36887a5af6a4a..0ea41ff5bd40fe123082707576144b71834e4258 100644 (file)
@@ -14,8 +14,8 @@
 * limitations under the License.
 */
 
-#ifndef __TIZEN_MEDIA_ROSE_SEM_H__
-#define __TIZEN_MEDIA_ROSE_SEM_H__
+#ifndef __TIZEN_MEDIA_ROSE_TIZEN_SEM_PARSE_H__
+#define __TIZEN_MEDIA_ROSE_TIZEN_SEM_PARSE_H__
 
 #include <glib.h>
 #include <libxml/parser.h>
@@ -40,9 +40,9 @@ typedef enum {
        SEM_EFFECT_NONE,
        SEM_EFFECT_LIGHT,
        SEM_EFFECT_FLASH,
-       SEM_EFFECT_TEMPERATURE,
        SEM_EFFECT_WIND,
        SEM_EFFECT_VIBRATION,
+       SEM_EFFECT_TEMPERATURE,
        SEM_EFFECT_MAX,
 } rose_sem_effect_type_e;
 
@@ -69,7 +69,6 @@ struct _rose_sem {
        rose_sem_si_attr *si_attr;
        /* effect_elements is rose_sem_effect_elements */
        GList *effect_elements;
-
 };
 
 struct _rose_sem_si_attr {
@@ -112,14 +111,24 @@ struct _rose_sem_effect_elements {
 
        rose_sem_base_attr *base_attr;
        rose_sem_si_attr *si_attr;
+
+       guint delay_time;
 };
 
 
 int rose_sem_parse(xmlNode * a_node, rose_sem ** sem);
 void rose_sem_free(rose_sem * sem);
 
+guint _rose_sem_get_pts(rose_sem_effect_elements *effect, guint time_scale);
+gint64 _rose_sem_get_render_time(rose_sem_effect_elements *effect, guint time_scale);
+void _rose_sem_sort_pts_with_delay(rose_sem *sem);
+
+#ifdef __FOR_DEBUG
+void _print_sem_data (rose_sem_effect_elements *effect, guint pts);
+#endif
+
 #ifdef __cplusplus
 }
 #endif
 
-#endif /* __TIZEN_MEDIA_ROSE_SEM_H__ */
+#endif /* __TIZEN_MEDIA_ROSE_TIZEN_SEM_PARSE_H__ */
index 0a50d3bb93ecff11ae32456f1863b79d279c0f12..60d7db38f5706d65a3bbdc3c4f5c1518d1c8fa70 100644 (file)
@@ -14,8 +14,8 @@
 * limitations under the License.
 */
 
-#ifndef __TIZEN_MEDIA_ROSE_MPLAYER__
-#define __TIZEN_MEDIA_ROSE_MPLAYER__
+#ifndef __TIZEN_MEDIA_ROSE_TIZEN_MPLAYER_H__
+#define __TIZEN_MEDIA_ROSE_TIZEN_MPLAYER_H__
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -89,4 +89,4 @@ mplayer_error_t mplayer_get_play_position(void *mplayer_handle, int *msec);
 }
 #endif /* __cplusplus */
 
-#endif /* __TIZEN_MEDIA_ROSE_MPLAYER__ */
\ No newline at end of file
+#endif /* __TIZEN_MEDIA_ROSE_TIZEN_MPLAYER_H__ */
\ No newline at end of file
index 0305cfee917a1d0a24ad33bb8d16b47a922379e7..49f9964946c93e54d8a8e2a6af07906496d22bff 100644 (file)
@@ -15,8 +15,8 @@
 */
 
 
-#ifndef __TIZEN_MEDIA_ROSE_MPLAYER_INTF__
-#define __TIZEN_MEDIA_ROSE_MPLAYER_INTF__
+#ifndef __TIZEN_MEDIA_ROSE_TIZEN_MPLAYER_INTERFACE_H__
+#define __TIZEN_MEDIA_ROSE_TIZEN_MPLAYER_INTERFACE_H__
 
 #include <stdint.h>
 #include <stdbool.h>
@@ -49,4 +49,4 @@ int _rose_mplayer_get_position(mplayer_interface *handle, int *msec);
 }
 #endif /* __cplusplus */
 
-#endif /* __TIZEN_MEDIA_ROSE_MPLAYER_INTF__ */
\ No newline at end of file
+#endif /* __TIZEN_MEDIA_ROSE_TIZEN_MPLAYER_INTERFACE_H__ */
\ No newline at end of file
index 00337cf2f0cdd437f0f8065e4c16a5e1263670c5..9cca1c23323efd813d65cf36c400e836df24d3db 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-rose-tizen
 Summary:    For RoSE(Representation Of Sensory Effect) APIs
-Version:    0.0.5
+Version:    0.0.6
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index c4828a9fcbca120f72ac348b59a49b204f20480c..de4f0db6339eeb21724b8abc63433e98043fad7d 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 #include "rose_tizen_priv.h"
-//#include "rose_tizen_parse_xml.h"
-//#include "rose_tizen_sem_parse.h"
+
+static gpointer _rose_render_thread (gpointer data);
+static gint _wait_to_render(gpointer data);
+static gboolean _create_render_thread(rose_s *handle);
+static void _destroy_render_thread(rose_s *handle);
+static gint64 _get_running_time(rose_render *renderer);
+static void _rose_apply_delay(rose_s *handle);
+static void _start_mplayer(rose_s *handle);
+static guint _calc_wait_time(gint64 next_pts, gint64 cur_pts);
 
 int rose_create(rose_h * rose)
 {
@@ -35,12 +42,11 @@ int rose_create(rose_h * rose)
        ret = _rose_mplayer_create(&handle->mplayer_intf);
        if (ret) {
                LOGE("Failed to create mplayer handle %d", ret);
-               g_free(handle);
-               *rose = NULL;
+               ROSE_G_FREE_IF(handle);
                return ROSE_ERROR_INVALID_OPERATION;
        }
 
-       handle->state = ROSE_STATE_IDLE;
+       ROSE_SET_STATE(handle, ROSE_STATE_IDLE);
 
        *rose = (rose_h) handle;
 
@@ -69,7 +75,10 @@ int rose_destroy(rose_h rose)
        if (ret) // need to check error handling
                LOGE("Failed to destroy mplayer handle %d", ret);
 
-       g_free(handle);
+       ROSE_G_FREE_IF(handle->sem_path);
+       ROSE_G_FREE_IF(handle->media_path);
+       ROSE_G_FREE_IF(handle->ctl_info_path);
+       ROSE_G_FREE_IF(handle);
 
        return ROSE_ERROR_NONE;
 }
@@ -88,6 +97,10 @@ int rose_set_sem_path(rose_h rose, const char *path)
        SECURE_LOGD("input sem path is %s", path);
        // need to check file path is valid
 
+       ROSE_G_FREE_IF(handle->sem_path);
+
+       handle->sem_path = g_strndup(path, strlen(path));
+
        // check validate SEM
        doc = xmlReadFile(path, "UTF-8", 0);
        if (!doc) {
@@ -133,6 +146,10 @@ int rose_set_control_info_path(rose_h rose, const char *path)
        SECURE_LOGD("input control info path is %s", path);
        // need to check file path is valid
 
+       ROSE_G_FREE_IF(handle->ctl_info_path);
+
+       handle->ctl_info_path = g_strndup(path, strlen(path));
+
        // check validate ControlInfo
        doc = xmlReadFile(path, "UTF-8", 0);
        if (!doc) {
@@ -174,6 +191,10 @@ int rose_set_media_path(rose_h rose, const char *path)
        ROSE_CHECK_INSTANCE(handle->mplayer_intf);
        ROSE_CHECK_STATE(handle, ROSE_STATE_IDLE);
 
+       ROSE_G_FREE_IF(handle->media_path);
+
+       handle->media_path = g_strndup(path, strlen(path));
+
        ret = _rose_mplayer_set_uri(handle->mplayer_intf, path);
        if (ret)
                LOGE("Failed to set uri %d", ret);
@@ -207,10 +228,30 @@ int rose_prepare(rose_h rose)
        ROSE_CHECK_INSTANCE(handle->mplayer_intf);
        ROSE_CHECK_STATE(handle, ROSE_STATE_IDLE);
 
+       handle->renderer = (rose_render *) g_new0(rose_render, 1);
+       handle->renderer->thread_pause = TRUE;
+       if (!_create_render_thread(handle)) {
+               LOGE("Failed to create render thread");
+               ret = ROSE_ERROR_INVALID_OPERATION;
+               goto ERROR;
+       }
+
+       _rose_apply_delay(handle);
+
        ret = _rose_mplayer_prepare(handle->mplayer_intf);
-       if (ret)
+       if (ret) {
                LOGE("Failed to prepare player %d", ret);
+               goto ERROR;
+       }
+
+       ROSE_SET_STATE(handle, ROSE_STATE_READY);
+
+       return ret;
 
+ERROR:
+       _rose_mplayer_unprepare(handle->mplayer_intf);
+       _destroy_render_thread(handle);
+       ROSE_G_FREE_IF(handle->renderer);
        return ret;
 }
 
@@ -227,6 +268,10 @@ int rose_unprepare(rose_h rose)
        if (ret)
                LOGE("Failed to unprepare player %d", ret);
 
+       _destroy_render_thread(handle);
+
+       ROSE_SET_STATE(handle, ROSE_STATE_IDLE);
+
        return ret;
 }
 
@@ -237,72 +282,388 @@ int rose_start(rose_h rose)
 
        ROSE_CHECK_INSTANCE(handle);
        ROSE_CHECK_INSTANCE(handle->mplayer_intf);
+       ROSE_CHECK_INSTANCE(handle->renderer);
        ROSE_CHECK_STATE(handle, ROSE_STATE_READY);
 
-       ret = _rose_mplayer_start(handle->mplayer_intf);
-       if (ret)
-               LOGE("Failed to start player %d", ret);
+       _RENDER_PAUSE_MUTEX_LOCK(handle->renderer);
+       handle->renderer->thread_pause = FALSE;
+       _RENDER_PAUSE_COND_SIGNAL(handle->renderer);
+       _RENDER_PAUSE_MUTEX_UNLOCK(handle->renderer);
+
+       ROSE_SET_STATE(handle, ROSE_STATE_PLAYING);
 
        return ret;
 }
+
 int rose_stop(rose_h rose)
 {
        int ret = ROSE_ERROR_NONE;
        rose_s *handle = (rose_s *)rose;
+       rose_render *renderer;
 
        ROSE_CHECK_INSTANCE(handle);
        ROSE_CHECK_INSTANCE(handle->mplayer_intf);
+       ROSE_CHECK_INSTANCE(handle->renderer);
        ROSE_CHECK_STATE(handle, ROSE_STATE_PLAYING);
 
-       ret = _rose_mplayer_stop(handle->mplayer_intf);
-       if (ret)
-               LOGE("Failed to stop player %d", ret);
+       /* pause render thread*/
+       renderer = ROSE_GET_RENDERER(handle);
+       renderer->thread_pause = TRUE;
+       if (renderer->wait_timer != 0) {
+               g_source_remove(renderer->wait_timer);
+               renderer->wait_timer = 0;
+       }
+       renderer->cur_sem_list = NULL;
+       renderer->last_sem_list = NULL;
+       _RENDER_COND_SIGNAL(renderer);
+       if (renderer->mplayer_is_started) {
+               ret = _rose_mplayer_stop(handle->mplayer_intf);
+               if (ret) {
+                       LOGE("Failed to stop player %d", ret);
+                       return ret;
+               }
+               renderer->mplayer_is_started = FALSE;
+       }
+
+       ROSE_SET_STATE(handle, ROSE_STATE_READY);
 
        return ret;
 }
+
 int rose_pause(rose_h rose)
 {
        int ret = ROSE_ERROR_NONE;
        rose_s *handle = (rose_s *)rose;
+       rose_render *renderer;
 
        ROSE_CHECK_INSTANCE(handle);
        ROSE_CHECK_INSTANCE(handle->mplayer_intf);
+       ROSE_CHECK_INSTANCE(handle->renderer);
        ROSE_CHECK_STATE(handle, ROSE_STATE_PLAYING);
 
-       ret = _rose_mplayer_pause(handle->mplayer_intf);
-       if (ret)
-               LOGE("Failed to pause player %d", ret);
+       /* pause render thread*/
+       renderer = ROSE_GET_RENDERER(handle);
+       renderer->thread_pause = TRUE;
+       if (renderer->wait_timer != 0) {
+               g_source_remove(renderer->wait_timer);
+               renderer->wait_timer = 0;
+       }
+       _RENDER_COND_SIGNAL(renderer);
+       if (renderer->mplayer_is_started) {
+               ret = _rose_mplayer_pause(handle->mplayer_intf);
+               if (ret)
+                       LOGE("Failed to pause player %d", ret);
+               renderer->mplayer_is_started = FALSE;
+       }
+
+       ROSE_SET_STATE(handle, ROSE_STATE_PAUSED);
 
        return ret;
 }
 
-int rose_set_play_position(rose_h rose, int msec, bool accurate)
+int rose_get_play_position(rose_h rose, int *msec)
 {
        int ret = ROSE_ERROR_NONE;
        rose_s *handle = (rose_s *)rose;
+       int get_msec = 0;
 
        ROSE_CHECK_INSTANCE(handle);
        ROSE_CHECK_STATE(handle, ROSE_STATE_READY);
-       ret = _rose_mplayer_set_position(handle->mplayer_intf, msec, accurate);
+       ret = _rose_mplayer_get_position(handle->mplayer_intf, &get_msec);
        if (ret)
-               LOGE("Failed to set play position %d", ret);
+               LOGE("Failed to get play position %d", ret);
+
+       *msec = get_msec;
 
        return ret;
 }
 
-int rose_get_play_position(rose_h rose, int *msec)
+static void _resync_base_time(rose_s *handle)
 {
        int ret = ROSE_ERROR_NONE;
-       rose_s *handle = (rose_s *)rose;
        int get_msec = 0;
+       rose_render *renderer = NULL;
+
+       ROSE_CHECK_NULL_VOID(handle);
+       ROSE_CHECK_NULL_VOID(handle->renderer);
+       ROSE_CHECK_NULL_VOID(handle->mplayer_intf);
+
+       renderer = ROSE_GET_RENDERER(handle);
+
+       if (renderer->base_clock == 0) {
+               _RENDER_CLOCK_MUTEX_LOCK(renderer);
+               renderer->base_clock = g_get_monotonic_time() + renderer->time_offset * G_GINT64_CONSTANT (1000);
+               _RENDER_CLOCK_MUTEX_UNLOCK(renderer);
+               return;
+       }
+
+       if (_get_running_time(renderer) <= 0)
+               return;
 
-       ROSE_CHECK_INSTANCE(handle);
-       ROSE_CHECK_STATE(handle, ROSE_STATE_READY);
        ret = _rose_mplayer_get_position(handle->mplayer_intf, &get_msec);
-       if (ret)
-               LOGE("Failed to set play position %d", ret);
+       if (ret) {
+               LOGE("Failed to get play position %d", ret);
+               get_msec = 0;
+       }
 
-       *msec = get_msec;
+       _RENDER_CLOCK_MUTEX_LOCK(renderer);
+       renderer->base_clock = g_get_monotonic_time()
+                                                       + renderer->time_offset * G_GINT64_CONSTANT (1000)
+                                                       - (gint64)(get_msec * G_GINT64_CONSTANT (1000));
+       _RENDER_CLOCK_MUTEX_UNLOCK(renderer);
+}
 
-       return ret;
+static gpointer _rose_render_thread (gpointer data)
+{
+       rose_s *handle = (rose_s *)data;
+       rose_render *renderer = NULL;
+       rose_sem *sem = NULL;
+       gint64 cur_pts = 0;
+       gint64 next_pts = 0;
+       guint wait_time = 0;
+       guint time_scale = 0;
+
+       GList *cur_list = NULL;
+       GList *next_list = NULL;
+
+       ROSE_CHECK_CONDITION(handle, NULL, "handle is NULL");
+       ROSE_CHECK_CONDITION(handle->sem, NULL, "sem is NULL");
+       ROSE_CHECK_CONDITION(handle->renderer, NULL, "renderer is NULL");
+
+       sem = ROSE_GET_SEM(handle);
+       renderer = ROSE_GET_RENDERER(handle);
+
+       time_scale = sem->time_scale;
+
+       _RENDER_MUTEX_LOCK(renderer);
+       while (!renderer->thread_exit) {
+               /* need to check pause state */
+               _RENDER_PAUSE_MUTEX_LOCK(renderer);
+               while (renderer->thread_pause) {
+                       LOGD("Pause render thread");
+                       _RENDER_PAUSE_COND_WAIT(renderer);
+                       _resync_base_time(handle);
+                       LOGD("restart render thread");
+               }
+               _RENDER_PAUSE_MUTEX_UNLOCK(renderer);
+               if (renderer->thread_exit)
+                       break;
+
+               /* check list */
+               if (renderer->last_sem_list) {
+                       cur_list = renderer->last_sem_list;
+                       next_list = cur_list->next;
+                       if (!next_list)
+                               break;
+
+               } else {
+                       cur_list = NULL;
+                       cur_pts = 0;
+                       next_list = g_list_first(sem->effect_elements);
+               }
+
+               _start_mplayer(handle);
+
+               next_pts = _rose_sem_get_render_time(next_list->data, time_scale);
+               LOGD("Next render pts = %" G_GINT64_FORMAT " ms", next_pts);
+               cur_pts = _get_running_time(renderer);
+
+               if (cur_pts <= 0 && next_pts >= 0 && !renderer->mplayer_is_started) {
+                       wait_time = _calc_wait_time(0, cur_pts);
+                       LOGD("Need to mplayer start");
+                       LOGD("add wait timer %u ms", wait_time);
+                       renderer->wait_timer = g_timeout_add((guint)wait_time,
+                                                                       (GSourceFunc)_wait_to_render, handle);
+                       _RENDER_COND_WAIT(renderer);
+                       _start_mplayer(handle);
+                       cur_pts = 0;
+                       if (renderer->thread_pause || renderer->thread_exit)
+                               continue;
+               }
+
+               wait_time = _calc_wait_time(next_pts, cur_pts);
+               LOGD("add wait timer %u ms", wait_time);
+               renderer->cur_sem_list = next_list;
+               renderer->wait_timer = g_timeout_add((guint)wait_time,
+                                                               (GSourceFunc)_wait_to_render, handle);
+               _RENDER_COND_WAIT(renderer);
+               if (renderer->thread_pause || renderer->thread_exit)
+                       continue;
+
+               cur_list = next_list;
+               renderer->last_sem_list = cur_list;
+
+               if (renderer->thread_exit)
+                       break;
+
+               cur_list = cur_list->next;
+       }
+
+       _RENDER_MUTEX_UNLOCK(renderer);
+       LOGD("exit render thread");
+
+       return NULL;
+}
+
+static gint _wait_to_render(gpointer data)
+{
+       rose_s *handle = (rose_s *)data;
+       gint64 render_time = 0;
+       gint64 running_time = 0;
+       rose_render *renderer = NULL;
+       rose_sem *sem = NULL;
+
+       ROSE_CHECK_NULL_GOTO(handle, ERROR);
+       ROSE_CHECK_NULL_GOTO(handle->sem, ERROR);
+       ROSE_CHECK_NULL_GOTO(handle->renderer, ERROR);
+       ROSE_CHECK_NULL_GOTO(handle->renderer->cur_sem_list, ERROR);
+
+       sem = ROSE_GET_SEM(handle);
+       renderer = ROSE_GET_RENDERER(handle);
+
+       LOGD("Called wait_render timer");
+       g_usleep(1000);
+       //_resync_base_time(handle);
+
+       if (!renderer->mplayer_is_started)
+               render_time = 0;
+       else
+               render_time = _rose_sem_get_render_time(renderer->cur_sem_list->data, sem->time_scale);
+
+       while (1) {
+               running_time = _get_running_time(renderer);
+               if (running_time >= render_time)
+                       break;
+               g_usleep((render_time - running_time) * G_GINT64_CONSTANT (1000));
+       }
+
+ERROR:
+       _RENDER_COND_SIGNAL(renderer);
+
+       return FALSE;
+}
+
+static gint64 _get_running_time(rose_render *renderer)
+{
+       gint64 running_time = -1;
+       ROSE_CHECK_CONDITION(renderer, -1, "Renderer is NULL");
+       _RENDER_CLOCK_MUTEX_LOCK(renderer);
+       running_time = (g_get_monotonic_time() - renderer->base_clock ) / G_GINT64_CONSTANT (1000);
+       _RENDER_CLOCK_MUTEX_UNLOCK(renderer);
+       return running_time;
+}
+
+static gboolean _create_render_thread(rose_s *handle)
+{
+       ROSE_CHECK_NULL_FALSE(handle);
+       ROSE_CHECK_NULL_FALSE(handle->renderer);
+
+       _RENDER_MUTEX_INIT(handle->renderer);
+       _RENDER_PAUSE_MUTEX_INIT(handle->renderer);
+       _RENDER_CLOCK_MUTEX_INIT(handle->renderer);
+
+       _RENDER_COND_INIT(handle->renderer);
+       _RENDER_PAUSE_COND_INIT(handle->renderer);
+
+       handle->renderer->thread = g_thread_new ("thread",
+                                                                       (GThreadFunc)_rose_render_thread, handle);
+       if (handle->renderer->thread == NULL) {
+               LOGE("Failed to create render thread");
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+static void _destroy_render_thread(rose_s *handle)
+{
+       rose_render *renderer;
+       ROSE_CHECK_NULL_VOID(handle);
+       ROSE_CHECK_NULL_VOID(handle->renderer);
+       ROSE_CHECK_NULL_VOID(handle->renderer->thread);
+
+       renderer = ROSE_GET_RENDERER(handle);
+
+       renderer->thread_exit = TRUE;
+       renderer->thread_pause = FALSE;
+       if (renderer->wait_timer > 0) {
+               g_source_remove(renderer->wait_timer);
+               renderer->wait_timer = 0;
+       }
+       _RENDER_COND_SIGNAL(renderer);
+       _RENDER_PAUSE_COND_SIGNAL(renderer);
+       g_thread_join(renderer->thread);
+       renderer->thread = NULL;
+}
+
+static void _rose_apply_delay(rose_s *handle)
+{
+       GList *sem_node;
+       rose_sem_effect_elements *sem_element;
+       guint delay = 0;
+       rose_sem *sem;
+       rose_control_info *ctl_info;
+       guint first_pts = 0;
+       gint64 time_offset = 0;
+
+       ROSE_CHECK_NULL_VOID(handle);
+       ROSE_CHECK_NULL_VOID(handle->sem);
+       ROSE_CHECK_NULL_VOID(handle->ctl_info);
+       ROSE_CHECK_NULL_VOID(handle->renderer);
+
+       sem = handle->sem;
+       ctl_info = handle->ctl_info;
+
+       sem_node = sem->effect_elements;
+
+       for (; sem_node; sem_node = sem_node->next) {
+               sem_element = (rose_sem_effect_elements *)sem_node->data;
+               delay = rose_ctl_get_total_delay_time(ctl_info, (int) sem_element->type);
+               if (delay != G_MAXUINT)
+                       sem_element->delay_time = delay;
+       }
+
+       _rose_sem_sort_pts_with_delay(sem);
+
+       sem_element = (g_list_first(sem->effect_elements))->data;
+
+       first_pts = _rose_sem_get_pts(sem_element, sem->time_scale);
+       time_offset = (gint64)first_pts - sem_element->delay_time;
+
+       if (time_offset < 0)
+               handle->renderer->time_offset = time_offset;
+
+       LOGD("Time offset = [%" G_GINT64_FORMAT "]", time_offset);
+
+}
+
+static void _start_mplayer(rose_s *handle)
+{
+       rose_render *renderer;
+       int ret;
+       ROSE_CHECK_NULL_VOID(handle);
+       ROSE_CHECK_NULL_VOID(handle->sem);
+       ROSE_CHECK_NULL_VOID(handle->renderer);
+
+       renderer = ROSE_GET_RENDERER(handle);
+
+       if (!renderer->mplayer_is_started && (_get_running_time(renderer) >= 0)) {
+               ret = _rose_mplayer_start(handle->mplayer_intf);
+               if (ret) {
+                       LOGE("Failed to start player %d", ret);
+                       return;
+               }
+               LOGD("Started mplayer");
+               renderer->mplayer_is_started = TRUE;
+       }
+}
+
+static guint _calc_wait_time(gint64 next_pts, gint64 cur_pts)
+{
+       guint wait_time = 0;
+
+       if ((next_pts - cur_pts - DEFAULT_CHECK_TIME_MS) > 0)
+               wait_time = next_pts - cur_pts - DEFAULT_CHECK_TIME_MS;
+
+       return wait_time;
 }
\ No newline at end of file
index bc8393df28a48dc195ca000820ec48d46b8179a7..420563cf9cac446a242082ee1256a6d011da4989 100644 (file)
@@ -80,8 +80,9 @@ int rose_ctl_info_parse(xmlNode * node, rose_control_info ** ctl_info)
        int ret = ROSE_ERROR_NONE;
        gboolean exist = FALSE;
 
+       ROSE_CHECK_INSTANCE(ctl_info);
+
        rose_ctl_info_free(*ctl_info);
-       *ctl_info = NULL;
 
        new_ctl_info = g_slice_new0(rose_control_info);
 
@@ -108,6 +109,8 @@ int rose_ctl_info_parse(xmlNode * node, rose_control_info ** ctl_info)
                ret = ROSE_ERROR_INVALID_OPERATION;
        }
 
+       *ctl_info = new_ctl_info;
+
        return ret;
 }
 
@@ -152,11 +155,12 @@ static gboolean _parse_sdc_element(xmlNode * node, rose_control_info *ctl_info)
 
        if (new_sdc_element->sdc_type > SDC_TYPE_NONE) {
                switch (new_sdc_element->sdc_type) {
-               case SDC_TYPE_LIGHT:
-                       exist |= _parse_sdc_light_type(node, &new_sdc_element->light);
                case SDC_TYPE_FLASH:
                        exist |= _parse_sdc_flash_type(node, &new_sdc_element->flash);
                        break;
+               case SDC_TYPE_LIGHT:
+                       exist |= _parse_sdc_light_type(node, &new_sdc_element->light);
+                       break;
                case SDC_TYPE_WIND:
                        exist |= _parse_sdc_wind_type(node, &new_sdc_element->wind);
                        break;
@@ -219,6 +223,8 @@ static gboolean _parse_sdc_light_type(xmlNode * node, rose_sdc_light **light)
        gboolean exist = FALSE;
        // xmlNode *cur_node;
 
+       ROSE_CHECK_NULL_FALSE(light);
+
        new_light = g_slice_new0(rose_sdc_light);
 
        exist |= new_light->unit_flag =
@@ -247,6 +253,9 @@ static gboolean _parse_sdc_light_type(xmlNode * node, rose_sdc_light **light)
                return FALSE;
        }
 
+       _free_sdc_light_type(*light);
+       *light = new_light;
+
        return TRUE;
 }
 
@@ -255,6 +264,8 @@ static gboolean _parse_sdc_flash_type(xmlNode * node, rose_sdc_flash **flash)
        rose_sdc_flash *new_flash = NULL;
        gboolean exist = FALSE;
 
+       ROSE_CHECK_NULL_FALSE(flash);
+
        new_flash = g_slice_new0(rose_sdc_flash);
 
        exist |= new_flash->max_freq_flag
@@ -272,6 +283,9 @@ static gboolean _parse_sdc_flash_type(xmlNode * node, rose_sdc_flash **flash)
                return FALSE;
        }
 
+       _free_sdc_flash_type(*flash);
+       *flash = new_flash;
+
        return TRUE;
 }
 
@@ -280,6 +294,8 @@ static gboolean _parse_sdc_wind_type(xmlNode * node, rose_sdc_wind **wind)
        rose_sdc_wind *new_wind = NULL;
        gboolean exist = FALSE;
 
+       ROSE_CHECK_NULL_FALSE(wind);
+
        new_wind = g_slice_new0(rose_sdc_wind);
 
        exist |= new_wind->unit_flag =
@@ -299,6 +315,9 @@ static gboolean _parse_sdc_wind_type(xmlNode * node, rose_sdc_wind **wind)
                return FALSE;
        }
 
+       _free_sdc_wind_type(*wind);
+       *wind = new_wind;
+
        return TRUE;
 }
 
@@ -307,6 +326,8 @@ static gboolean _parse_sdc_vibration_type(xmlNode * node, rose_sdc_vibration **v
        rose_sdc_vibration *new_vibration = NULL;
        gboolean exist = FALSE;
 
+       ROSE_CHECK_NULL_FALSE(vibration);
+
        new_vibration = g_slice_new0(rose_sdc_vibration);
 
        exist |= new_vibration->unit_flag =
@@ -326,6 +347,9 @@ static gboolean _parse_sdc_vibration_type(xmlNode * node, rose_sdc_vibration **v
                return FALSE;
        }
 
+       _free_sdc_vibration_type(*vibration);
+       *vibration = new_vibration;
+
        return TRUE;
 }
 
@@ -386,3 +410,31 @@ void rose_ctl_info_free(rose_control_info * ctl_info)
        g_slice_free(rose_control_info, ctl_info);
 }
 
+static gint _compare_type(rose_sdc_element *a, rose_sdc_type_e *type)
+{
+       if (a && type) {
+               if (a->sdc_type == *type)
+                       return 0;
+       }
+
+       return 1;
+}
+
+guint rose_ctl_get_total_delay_time(rose_control_info * ctl_info, rose_sdc_type_e type)
+{
+       GList *r_list = NULL;
+       rose_sdc_element *sdc_elem;
+       guint delay_time = G_MAXUINT;
+       ROSE_CHECK_CONDITION(ctl_info, G_MAXUINT, "ctl_info is NULL");
+
+       r_list = g_list_find_custom (ctl_info->sdc_elements, &type, (GCompareFunc) _compare_type);
+       if (!r_list) {
+               LOGW("[%d] type is not on the list", type);
+               return delay_time;
+       }
+
+       sdc_elem = (rose_sdc_element *)r_list->data;
+       delay_time = sdc_elem->firstorderdelaytime + sdc_elem->zerothorderdelaytime;
+       LOGD("[%d type] delay time is [%u]", type, delay_time);
+       return delay_time;
+}
\ No newline at end of file
index 891d28e774d19528a8c4b4cbf0f7480ac772bfac..66f32248aa93c752448ba5135cf13475ede736ac 100644 (file)
@@ -467,3 +467,133 @@ static void _free_effect_elements(rose_sem_effect_elements * elements)
 
 }
 
+guint _rose_sem_get_pts(rose_sem_effect_elements *effect, guint time_scale)
+{
+       guint pts = 0;
+       guint apply_time_scale = time_scale;
+       ROSE_CHECK_CONDITION(effect, G_MAXUINT, "effect data is NULL");
+       ROSE_CHECK_CONDITION(effect->si_attr, G_MAXUINT, "effect si attribute is NULL");
+
+       if (effect->si_attr->time_scale_flag)
+               apply_time_scale = effect->si_attr->time_scale;
+
+       if (apply_time_scale != 0)
+               pts = effect->si_attr->pts / apply_time_scale;
+       else
+               pts = effect->si_attr->pts;
+
+       return pts * 1000;
+}
+
+gint64 _rose_sem_get_render_time(rose_sem_effect_elements *effect, guint time_scale)
+{
+       gint64 time_with_delay = G_MAXINT64;
+       guint time_pts = 0;
+       time_pts = _rose_sem_get_pts(effect, time_scale);
+       if (time_pts != G_MAXUINT) {
+               time_with_delay = (gint64)time_pts - effect->delay_time;
+               LOGD("pts with delay = %" G_GINT64_FORMAT "ms", time_with_delay);
+       }
+
+       return time_with_delay;
+}
+
+gint _sort_element_pts (rose_sem_effect_elements *e1, rose_sem_effect_elements *e2, rose_sem *sem)
+{
+       gint64 time1 = 0;
+       gint64 time2 = 0;
+
+       ROSE_CHECK_CONDITION(e1, 0, "1st arg is NULL");
+       ROSE_CHECK_CONDITION(e2, 0, "2nd arg is NULL");
+       ROSE_CHECK_CONDITION(sem, 0, "rose sem is NULL");
+
+       time1 = _rose_sem_get_pts(e1, sem->time_scale) - e1->delay_time;
+       time2 = _rose_sem_get_pts(e2, sem->time_scale) - e2->delay_time;
+
+       return (time1 - time2);
+}
+
+void _rose_sem_sort_pts_with_delay(rose_sem *sem)
+{
+       ROSE_CHECK_NULL_VOID(sem);
+       sem->effect_elements = g_list_sort_with_data(sem->effect_elements,
+                                                                       (GCompareDataFunc)_sort_element_pts, sem);
+       return;
+}
+
+#ifdef __FOR_DEBUG
+const char * _convert_type_to_str(rose_sem_effect_type_e type)
+{
+       const char *msg;
+       switch (type) {
+               case SEM_EFFECT_LIGHT:
+                       msg = "SEM_EFFECT_LIGHT";
+                       break;
+               case SEM_EFFECT_FLASH:
+                       msg = "SEM_EFFECT_FLASH";
+                       break;
+               case SEM_EFFECT_TEMPERATURE:
+                       msg = "SEM_EFFECT_TEMPERATURE";
+                       break;
+               case SEM_EFFECT_WIND:
+                       msg = "SEM_EFFECT_WIND";
+                       break;
+               case SEM_EFFECT_VIBRATION:
+                       msg = "SEM_EFFECT_VIBRATION";
+                       break;
+               default:
+                       msg = "SEM_EFFECT_UNKNOWN";
+                       break;
+       }
+       return msg;
+}
+
+void _print_sem_data (rose_sem_effect_elements *effect, guint time_scale)
+{
+       ROSE_CHECK_NULL_VOID(effect);
+       // GString *string = g_string_new(NULL);
+       LOGI("-----------------------------------------------------------------------");
+       LOGD("%s", _convert_type_to_str(effect->type));
+
+       if (effect->color_type_flag)
+               LOGD("color type = [%s]", effect->color_type);
+
+       if (effect->frequency_flag)
+               LOGD("frequency = [%u]", effect->frequency);
+
+       if (effect->intensity_value_flag)
+               LOGD("intensity_value = [%f]", effect->intensity_value);
+
+       if (effect->intensity_range_flag)
+               LOGD("intensity_range = [%f - %f]", effect->min_intensity, effect->max_intensity);
+
+       if (effect->base_attr) {
+               rose_sem_base_attr *base_attr = effect->base_attr;
+               if (base_attr->activate_flag)
+                       LOGD("%s", base_attr->activate ? "activate" : "deactivate");
+               if (base_attr->duration_flag)
+                       LOGD("duration = [%u]", base_attr->duration);
+               if (base_attr->fade_flag)
+                       LOGD("fade = [%u]", base_attr->fade);
+               if (base_attr->priority_flag)
+                       LOGD("priority = [%u]", base_attr->priority);
+               if (base_attr->location_flag)
+                       LOGD("location = [%s]", base_attr->location);
+       }
+
+       if (effect->si_attr) {
+               rose_sem_si_attr *si_attr = effect->si_attr;
+               if (si_attr->time_scale_flag)
+                       LOGD("\ntime_scale = [%u]", si_attr->time_scale);
+               if (si_attr->pts_delta_flag)
+                       LOGD("pts_delta = [%u]", si_attr->pts_delta);
+               if (si_attr->abs_time_flag)
+                       LOGD("abs_time = [%s]", si_attr->abs_time);
+               if (si_attr->pts_flag) {
+                       LOGD("pts = [%u]", si_attr->pts);
+                       if (time_scale != 0)
+                               LOGD("-> with delay pts = [%d ms]", (si_attr->pts / time_scale) * 1000 - effect->delay_time);
+               }
+       }
+}
+#endif
\ No newline at end of file
index 3357da3c30cebef033320c3cc01a7022a8458277..1399986cc07dd0e27b85298699431adba82c5b69 100644 (file)
@@ -49,8 +49,6 @@ enum {
        CURRENT_STATUS_SEM_FILE_PATH,
        CURRENT_STATUS_CTL_INFO_FILE_PATH,
        CURRENT_STATUS_DISPLAY_SURFACE_CHANGE,
-       CURRENT_STATUS_POSITION_TIME,
-       CURRENT_STATUS_POSITION_ACCURATE,
 };
 
 /* for video display */
@@ -221,11 +219,6 @@ static void change_surface(int option)
                return;
        }
 
-       // player_state_e player_state = PLAYER_STATE_NONE;
-       // ret = player_get_state(g_player[0], &player_state);
-       // if (ret)
-       //      g_print("failed to player_get_state(), ret(0x%x)\n", ret);
-
        if (surface_type == ROSE_DISPLAY_TYPE_OVERLAY) {
 
                        if (!g_win_id) {
@@ -352,14 +345,6 @@ int test_rose_pause()
        return ret;
 }
 
-int test_rose_set_position(int time, bool accurate)
-{
-       int ret = 0;
-       LOGD("test_rose_set_position");
-       ret = rose_set_play_position(rose, time, accurate);
-       return ret;
-}
-
 int test_rose_get_position()
 {
        int ret = 0;
@@ -371,8 +356,6 @@ int test_rose_get_position()
        return ret;
 }
 
-// int rose_seek(rose_h rose, int64_t nanoseconds);
-// int rose_get_state(rose_h rose, rose_state_e *state);
 int rose_set_display(rose_h rose, rose_display_type_e type, void *display);
 
 /*-----------------------------------------------------------------------
@@ -416,8 +399,6 @@ void _interpret_main_menu(char *cmd)
                        test_rose_stop();
                } else if (strncmp(cmd, "e", 1) == 0) {
                        test_rose_pause();
-               } else if (strncmp(cmd, "j", 1) == 0) {
-                       g_menu_state = CURRENT_STATUS_POSITION_TIME;
                } else if (strncmp(cmd, "l", 1) == 0) {
                        test_rose_get_position();
                } else if (strncmp(cmd, "q", 1) == 0) {
@@ -457,10 +438,6 @@ static void displaymenu(void)
                g_print("*** input media path.\n");
        } else if (g_menu_state == CURRENT_STATUS_DISPLAY_SURFACE_CHANGE) {
                g_print("*** input display surface type.(0: Wayland surface, 1: EVAS surface, 2: No use surface (e.g: audio playback)) \n");
-       } else if (g_menu_state == CURRENT_STATUS_POSITION_TIME) {
-               g_print("*** input position value(msec)\n");
-       } else if (g_menu_state == CURRENT_STATUS_POSITION_ACCURATE) {
-               g_print("*** input accurate value(0/1)\n");
        } else {
                g_print("*** unknown status.\n");
                /*  exit(0); */
@@ -521,16 +498,6 @@ static void interpret(char *cmd)
                reset_menu_state();
                break;
        }
-       case CURRENT_STATUS_POSITION_TIME: {
-               value1 = atoi(cmd);
-               g_menu_state = CURRENT_STATUS_POSITION_ACCURATE;
-               break;
-       }
-       case CURRENT_STATUS_POSITION_ACCURATE: {
-               test_rose_set_position(value1, ((atoi(cmd) != 0) ? (true) : (false)));
-               reset_menu_state();
-               break;
-       }
        default:
                break;
        }