meta-agl-bsp: backport: gstreamer1.0 v1.4.5 recipes
[AGL/meta-agl.git] / meta-agl-bsp / meta-rcar-gen3 / recipes-multimedia / gstreamer / gstreamer1.0-plugins-base / 0001-basetextoverlay-make-memory-copy-when-video-buffer-s.patch
1 From 3781d40940d46d7e6a502092d24aac7997f6da5b Mon Sep 17 00:00:00 2001
2 From: Mingke Wang <mingke.wang@freescale.com>
3 Date: Thu, 5 Mar 2015 12:06:23 +0800
4 Subject: [PATCH 1/4] basetextoverlay: make memory copy when video buffer's
5  memory is ready only
6
7 1. since gst_buffer_make_writable just lookup the refcount to determine if
8    a buffer is writable, and it will use _gst_buffer_copy() which don't
9    perform a deep memory copy even if the flag of a memory is set to
10    GST_MEMORY_FLAG_READONLY. So, we detect the memory flag and use
11    gst_buffer_copy_region with GST_BUFFER_COPY_DEEP parameter to perform
12    deep memory copy. if the allocator of a memory don't support mem_copy
13    interface, the it will return NULL, if this case, we can use
14    gst_buffer_make_writable() to get a shared memory buffer or the orignal
15    buffer if the buffer's refcount is 1.
16 2.  new feature is no added if caps has no feature during caps negotiation
17
18 Upstream-Status: Submitted [https://bugzilla.gnome.org/show_bug.cgi?id=747495]
19
20 Signed-off-by: Mingke Wang <mingke.wang@freescale.com>
21
22 diff --git a/ext/pango/gstbasetextoverlay.c b/ext/pango/gstbasetextoverlay.c
23 index c919861..3c0a1d7 100755
24 --- a/ext/pango/gstbasetextoverlay.c
25 +++ b/ext/pango/gstbasetextoverlay.c
26 @@ -747,6 +747,7 @@ gst_base_text_overlay_negotiate (GstBaseTextOverlay * overlay, GstCaps * caps)
27      if (f == NULL) {
28        f = gst_caps_features_new
29            (GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, NULL);
30 +      gst_caps_set_features(overlay_caps, 0, f);
31      } else {
32        gst_caps_features_add (f,
33            GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION);
34 @@ -1890,16 +1891,71 @@ gst_base_text_overlay_push_frame (GstBaseTextOverlay * overlay,
35    if (gst_pad_check_reconfigure (overlay->srcpad))
36      gst_base_text_overlay_negotiate (overlay, NULL);
37  
38 -  video_frame = gst_buffer_make_writable (video_frame);
39 -
40    if (overlay->attach_compo_to_buffer) {
41      GST_DEBUG_OBJECT (overlay, "Attaching text overlay image to video buffer");
42 +    video_frame = gst_buffer_make_writable (video_frame);
43      gst_buffer_add_video_overlay_composition_meta (video_frame,
44          overlay->composition);
45      /* FIXME: emulate shaded background box if want_shading=true */
46      goto done;
47    }
48  
49 +  gint m = gst_buffer_n_memory(video_frame);
50 +  gboolean mem_rdonly = FALSE;
51 +  GstMemory *mem;
52 +  GstBuffer *orig = video_frame;
53 +
54 +  while (--m>=0) {
55 +    mem = gst_buffer_get_memory(video_frame, m);
56 +    if (GST_MEMORY_IS_READONLY(mem)) {
57 +      mem_rdonly = TRUE;
58 +      gst_memory_unref (mem);
59 +      break;
60 +    }
61 +    gst_memory_unref (mem);
62 +  }
63 +
64 +  if (mem_rdonly) {
65 +    // since gst_buffer_make_writable just lookup the refcount to determine if
66 +    // a buffer is writable, and it will use _gst_buffer_copy() which don't
67 +    // perform a deep memory copy even if the flag of a memory is set to
68 +    // GST_MEMORY_FLAG_READONLY. So, we detect the memory flag and use
69 +    // gst_buffer_copy_region with GST_BUFFER_COPY_DEEP parameter to perform
70 +    // deep memory copy. if the allocator of a memory don't support mem_copy
71 +    // interface, the it will return NULL, if this case, we can use
72 +    // gst_buffer_make_writable() to get a shared memory buffer or the orignal
73 +    // buffer if the buffer's refcount is 1.
74 +    GstBuffer *new_buf = gst_buffer_copy_region (video_frame,
75 +        GST_BUFFER_COPY_ALL | GST_BUFFER_COPY_DEEP, 0, -1);
76 +
77 +    GST_DEBUG_OBJECT (overlay, "copy %s video frame buffer %p -> %p",
78 +        g_type_name (GST_MINI_OBJECT_TYPE (video_frame)), video_frame, new_buf);
79 +
80 +    if (!new_buf) {
81 +      //maybe the allocator don't support mem_copy interface, the we just use
82 +      //gst_buffer_make_writable() to get a writable buffer.
83 +      video_frame = gst_buffer_make_writable (video_frame);
84 +    } else {
85 +      gst_mini_object_unref (video_frame);
86 +      GST_BUFFER_FLAG_UNSET (new_buf, GST_BUFFER_FLAG_TAG_MEMORY);
87 +      video_frame = new_buf;
88 +    }
89 +
90 +    if (!video_frame) {
91 +      GST_WARNING_OBJECT (overlay, "make writable buffer failed");
92 +      return GST_FLOW_OK;
93 +    }
94 +
95 +    m = gst_buffer_n_memory(video_frame);
96 +    while (--m>=0) {
97 +      mem = gst_buffer_get_memory(video_frame, m);
98 +      GST_MEMORY_FLAG_UNSET (mem, GST_MEMORY_FLAG_READONLY);
99 +      gst_memory_unref (mem);
100 +    }
101 +  } else {
102 +    video_frame = gst_buffer_make_writable (video_frame);
103 +  }
104 +
105    if (!gst_video_frame_map (&frame, &overlay->info, video_frame,
106            GST_MAP_READWRITE))
107      goto invalid_frame;
108 @@ -1918,6 +1974,18 @@ gst_base_text_overlay_push_frame (GstBaseTextOverlay * overlay,
109  
110    gst_video_frame_unmap (&frame);
111  
112 +  if (mem_rdonly && orig == video_frame) {
113 +    //if we used the original buffer and it's mem is set to read only,
114 +    //recover the memory ready only flag since we unset it before
115 +    // gst_video_frame_map ()
116 +    m = gst_buffer_n_memory(video_frame);
117 +    while (--m>=0) {
118 +      mem = gst_buffer_get_memory(video_frame, m);
119 +      GST_MEMORY_FLAGS(mem) |= (GST_MEMORY_FLAG_READONLY);
120 +      gst_memory_unref (mem);
121 +    }
122 +  }
123 +
124  done:
125  
126    return gst_pad_push (overlay->srcpad, video_frame);
127 -- 
128 1.7.9.5
129