raster pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=6458ca32bc80062e95337c5ebb36593723567a37

commit 6458ca32bc80062e95337c5ebb36593723567a37
Author: Carsten Haitzler (Rasterman) <ras...@rasterman.com>
Date:   Mon Apr 20 12:12:27 2015 +0900

    emotion - gst1 module - handle long standing bad map/unmap of gst buf
    
    this fixes a pending XXX where we didnt keep the buffer mapped as long
    as the evas image object pointed to the video pixel data. this fixes
    this along with less over-zealous refinf to make things more obvious
    (now last_buffer actualyl really matters and if it was mapped and
    refed).
    
    @fix
---
 src/modules/emotion/gstreamer1/emotion_gstreamer.h |  2 +
 src/modules/emotion/gstreamer1/emotion_sink.c      | 46 +++++++++++++++++-----
 2 files changed, 39 insertions(+), 9 deletions(-)

diff --git a/src/modules/emotion/gstreamer1/emotion_gstreamer.h 
b/src/modules/emotion/gstreamer1/emotion_gstreamer.h
index 080ab77..dfee8e4 100644
--- a/src/modules/emotion/gstreamer1/emotion_gstreamer.h
+++ b/src/modules/emotion/gstreamer1/emotion_gstreamer.h
@@ -109,6 +109,7 @@ struct _EmotionVideoSinkPrivate {
 
     /* We need to keep a copy of the last inserted buffer as evas doesn't copy 
YUV data around */
    GstBuffer        *last_buffer;
+   GstMapInfo        map_info;
 
    int frames;
    int flapse;
@@ -124,6 +125,7 @@ struct _EmotionVideoSinkPrivate {
    //
    // Protected by the buffer mutex
    Eina_Bool unlocked : 1;
+   Eina_Bool mapped : 1;
 };
 
 struct _Emotion_Gstreamer_Buffer
diff --git a/src/modules/emotion/gstreamer1/emotion_sink.c 
b/src/modules/emotion/gstreamer1/emotion_sink.c
index 5e6f3be..6c410f8 100644
--- a/src/modules/emotion/gstreamer1/emotion_sink.c
+++ b/src/modules/emotion/gstreamer1/emotion_sink.c
@@ -137,6 +137,22 @@ emotion_video_sink_dispose(GObject* object)
    sink = EMOTION_VIDEO_SINK(object);
    priv = sink->priv;
 
+   if ((priv->mapped) && (priv->last_buffer))
+     {
+        if (priv->evas_object)
+          {
+             evas_object_image_size_set(priv->evas_object, 1, 1);
+             evas_object_image_data_set(priv->evas_object, NULL);
+          }
+        gst_buffer_unmap(priv->last_buffer, &(priv->map_info));
+        priv->mapped = EINA_FALSE;
+     }
+   if (priv->last_buffer)
+     {
+        if (priv->last_buffer) gst_buffer_unref(priv->last_buffer);
+        priv->last_buffer = NULL;
+     }
+
    eina_lock_free(&priv->m);
    eina_condition_free(&priv->c);
 
@@ -210,9 +226,21 @@ emotion_video_sink_stop(GstBaseSink* base_sink)
 
    INF("sink stop");
 
-   gst_buffer_replace(&priv->last_buffer, NULL);
-
    eina_lock_take(&priv->m);
+   if (priv->last_buffer)
+     {
+        if (priv->evas_object)
+          {
+             evas_object_image_size_set(priv->evas_object, 1, 1);
+             evas_object_image_data_set(priv->evas_object, NULL);
+          }
+        if (priv->mapped)
+          gst_buffer_unmap(priv->last_buffer, &(priv->map_info));
+        priv->mapped = EINA_FALSE;
+        if (priv->last_buffer) gst_buffer_unref(priv->last_buffer);
+        priv->last_buffer = NULL;
+     }
+
    /* If there still is a pending frame, neutralize it */
    if (priv->send)
      {
@@ -371,8 +399,6 @@ emotion_video_sink_main_render(void *data)
 
    buffer = gst_buffer_ref(send->frame);
 
-   // XXX: need to map buffer and KEEP MAPPED until we set new video data or
-   // on the evas image object or release the object
    if (!gst_buffer_map(buffer, &map, GST_MAP_READ))
      goto exit_point;
 
@@ -391,9 +417,6 @@ emotion_video_sink_main_render(void *data)
    else
      WRN("No way to decode %x colorspace !", send->eformat);
 
-   // XXX: this unmap here is broken
-   gst_buffer_unmap(buffer, &map);
-
    evas_object_image_data_set(priv->evas_object, evas_data);
    evas_object_image_data_update_add(priv->evas_object, 0, 0, 
send->info.width, send->eheight);
    evas_object_image_pixels_dirty_set(priv->evas_object, 0);
@@ -405,7 +428,13 @@ emotion_video_sink_main_render(void *data)
 
    _emotion_frame_resize(priv->emotion_object, send->info.width, 
send->eheight, ratio);
 
-   gst_buffer_replace(&priv->last_buffer, buffer);
+   if ((priv->mapped) && (priv->last_buffer))
+     gst_buffer_unmap(priv->last_buffer, &(priv->map_info));
+   priv->map_info = map;
+   priv->mapped = EINA_TRUE;
+
+   if (priv->last_buffer) gst_buffer_unref(priv->last_buffer);
+   priv->last_buffer = buffer;
 
    _emotion_frame_new(priv->emotion_object);
 
@@ -415,7 +444,6 @@ emotion_video_sink_main_render(void *data)
 
    eina_lock_release(&priv->m);
 
-   if (buffer) gst_buffer_unref(buffer);
    emotion_gstreamer_buffer_free(send);
 
    _emotion_pending_ecore_end();

-- 


Reply via email to