Hi,

The slider emits a "changed"  signal when its internal representation
of value really changes. It does not know whether the user dragged it
or internal updates caused the value change. Most internal incremental
updates when trimmed to the current resolution of the slider, do not
cause a value change and the signal is not emitted on every "set".

This behaviour causes a 'feedback-loop' in that the "changed" signal
from an internal update, being undifferentiated from a "user-drag",
causes a delayed reposition command to the emotion engine. The result
is a nice 'track-jump-repeat' which in some extreme cases, a
'stuck-in-a-groove' effect.

The foll. patch is a solution to this problem; and also reduces the
frequency of slider updates. An alternate solution would be to use
_smart_callback_del() before actually updating slider in
elc_player.c:_update_slider(), and re-installing it back - but this
could open the door to race conditions.

Arvind
---

diff -uprN a/src/lib/elc_player.c b/src/lib/elc_player.c
--- a/src/lib/elc_player.c      2013-02-01 21:59:39.000000000 +0530
+++ b/src/lib/elc_player.c      2013-02-01 21:59:54.000000000 +0530
@@ -163,12 +163,35 @@ _update_slider(void *data,
    ELM_PLAYER_DATA_GET(data, sd);

    seekable = elm_video_is_seekable_get(sd->video);
+   if (seekable == sd->disabled)
+    elm_object_disabled_set(sd->slider, !seekable);
+
    length = elm_video_play_length_get(sd->video);
-   pos = elm_video_play_position_get(sd->video);

-   elm_object_disabled_set(sd->slider, !seekable);
-   elm_slider_min_max_set(sd->slider, 0, length);
-   elm_slider_value_set(sd->slider, pos);
+   if (sd->length != length) {
+       sd->length = length;
+       elm_slider_min_max_set(sd->slider, 0, length);
+   }
+
+   if (sd->frames < 0) {
+       pos = elm_video_play_position_get(sd->video);
+       if (fabs(sd->pos - pos) > 0.5) {
+               sd->pos = pos;
+               sd->frames = 30;
+               elm_slider_value_set(sd->slider, pos);
+       }
+   }
+}
+
+static void
+_frame_decoded_cb(void *data,
+               Evas_Object *obj __UNUSED__,
+               void *event_info __UNUSED__)
+{
+   ELM_PLAYER_DATA_GET(data, sd);
+   /* do not update slider on every frame */
+   if (--sd->frames < 0)
+       _update_slider(data, obj, event_info);
 }

 static void
@@ -176,9 +199,24 @@ _update_position(void *data,
                  Evas_Object *obj __UNUSED__,
                  void *event_info __UNUSED__)
 {
+   /*
+    * called wnenever the value of the slider is changed.
+       *  - irespective of user drags
+       *    or
+       *    internal increments larger than the slider resolution.
+       * the 2nd case causes an inadvertent repositioning of stream
+       * which some engines respond to (xine).
+       * This is a feedback loop that needs to be broken.
+       */
+   double pos;
+
    ELM_PLAYER_DATA_GET(data, sd);

-   elm_video_play_position_set(sd->video, elm_slider_value_get(sd->slider));
+   pos = elm_slider_value_get(sd->slider);
+   if (fabs(sd->pos - pos) > 0.25) {
+       elm_video_play_position_set(sd->video, pos);
+       sd->pos = pos;
+   }
 }

 static void
@@ -455,7 +493,7 @@ _elm_player_smart_content_set(Eo *obj, v
    else elm_layout_signal_emit(obj, "elm,player,pause", "elm");

    evas_object_smart_callback_add(sd->emotion, "frame_decode",
-                                  _update_slider, obj);
+                                  _frame_decoded_cb, obj);
    evas_object_smart_callback_add(sd->emotion, "frame_resize",
                                   _update_slider, obj);
    evas_object_smart_callback_add(sd->emotion, "length_change",
@@ -495,9 +533,13 @@ _elm_player_smart_add(Eo *obj, void *_pd
      (priv->slider, _double_to_time, _str_free);
    elm_slider_units_format_function_set
      (priv->slider, _double_to_time, _str_free);
-   elm_slider_min_max_set(priv->slider, 0, 0);
+   elm_slider_min_max_set(priv->slider, 0, 1);
    elm_slider_value_set(priv->slider, 0);
    elm_object_disabled_set(priv->slider, EINA_TRUE);
+   priv->disabled = EINA_TRUE;
+   priv->length = 0.0;
+   priv->frames = 0;
+   priv->pos = 0.0;
    evas_object_size_hint_align_set(priv->slider, EVAS_HINT_FILL, 0.5);
    evas_object_size_hint_weight_set
      (priv->slider, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
diff -uprN a/src/lib/elm_widget_player.h b/src/lib/elm_widget_player.h
--- a/src/lib/elm_widget_player.h       2012-11-26 12:02:53.000000000 +0530
+++ b/src/lib/elm_widget_player.h       2013-02-01 21:59:54.000000000 +0530
@@ -33,6 +33,11 @@ struct _Elm_Player_Smart_Data
    Evas_Object          *rewind;
    Evas_Object          *stop;
    Evas_Object          *slider;
+
+   Eina_Bool   disabled; /* used for only-when-must changes */
+   double              length;   /*         --- ditto ---           */
+   short               frames;   /* used to reduce update frequency */
+   double              pos;      /* inter-callback communication to break 
slider
feedback loop */
 };

 /**

------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_jan
_______________________________________________
enlightenment-users mailing list
enlightenment-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-users

Reply via email to