On 7 August 2015 at 09:16, Yuqing Zhu <b54...@freescale.com> wrote: > Make memory copy when video buffer's memory is read only > > Signed-off-by: Yuqing Zhu <b54...@freescale.com> > --- > ...rlay-make-memory-copy-when-video-buffer-s.patch | 129 > +++++++++++++++++++++ > .../gstreamer/gstreamer1.0-plugins-base_1.4.5.bb | 1 + > 2 files changed, 130 insertions(+) > create mode 100644 > meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-base/0001-basetextoverlay-make-memory-copy-when-video-buffer-s.patch > > diff --git > a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-base/0001-basetextoverlay-make-memory-copy-when-video-buffer-s.patch > > b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-base/0001-basetextoverlay-make-memory-copy-when-video-buffer-s.patch > new file mode 100644 > index 0000000..03dca95 > --- /dev/null > +++ > b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-base/0001-basetextoverlay-make-memory-copy-when-video-buffer-s.patch > @@ -0,0 +1,129 @@ > +From 3781d40940d46d7e6a502092d24aac7997f6da5b Mon Sep 17 00:00:00 2001 > +From: Mingke Wang <mingke.w...@freescale.com> > +Date: Thu, 5 Mar 2015 12:06:23 +0800 > +Subject: [PATCH 1/4] basetextoverlay: make memory copy when video buffer's > + memory is ready only > + > +1. since gst_buffer_make_writable just lookup the refcount to determine if > + a buffer is writable, and it will use _gst_buffer_copy() which don't > + perform a deep memory copy even if the flag of a memory is set to > + GST_MEMORY_FLAG_READONLY. So, we detect the memory flag and use > + gst_buffer_copy_region with GST_BUFFER_COPY_DEEP parameter to perform > + deep memory copy. if the allocator of a memory don't support mem_copy > + interface, the it will return NULL, if this case, we can use > + gst_buffer_make_writable() to get a shared memory buffer or the orignal > + buffer if the buffer's refcount is 1. > +2. new feature is no added if caps has no feature during caps negotiation > + > +Upstream-Status: Submitted > [https://bugzilla.gnome.org/show_bug.cgi?id=747495]
I'd like to thank you for providing good upstream links: they're very helpful. In this particular case it shows that gstreamer developers have doubts about the patch and it seems likely the patch will not be accepted as is, or possibly at all: Tim and Nicolas don't seem convinced yet that this is fixing an actual bug. - Jussi > + > +Signed-off-by: Mingke Wang <mingke.w...@freescale.com> > + > +diff --git a/ext/pango/gstbasetextoverlay.c b/ext/pango/gstbasetextoverlay.c > +index c919861..3c0a1d7 100755 > +--- a/ext/pango/gstbasetextoverlay.c > ++++ b/ext/pango/gstbasetextoverlay.c > +@@ -747,6 +747,7 @@ gst_base_text_overlay_negotiate (GstBaseTextOverlay * > overlay, GstCaps * caps) > + if (f == NULL) { > + f = gst_caps_features_new > + (GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, NULL); > ++ gst_caps_set_features(overlay_caps, 0, f); > + } else { > + gst_caps_features_add (f, > + GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION); > +@@ -1890,16 +1891,71 @@ gst_base_text_overlay_push_frame (GstBaseTextOverlay > * overlay, > + if (gst_pad_check_reconfigure (overlay->srcpad)) > + gst_base_text_overlay_negotiate (overlay, NULL); > + > +- video_frame = gst_buffer_make_writable (video_frame); > +- > + if (overlay->attach_compo_to_buffer) { > + GST_DEBUG_OBJECT (overlay, "Attaching text overlay image to video > buffer"); > ++ video_frame = gst_buffer_make_writable (video_frame); > + gst_buffer_add_video_overlay_composition_meta (video_frame, > + overlay->composition); > + /* FIXME: emulate shaded background box if want_shading=true */ > + goto done; > + } > + > ++ gint m = gst_buffer_n_memory(video_frame); > ++ gboolean mem_rdonly = FALSE; > ++ GstMemory *mem; > ++ GstBuffer *orig = video_frame; > ++ > ++ while (--m>=0) { > ++ mem = gst_buffer_get_memory(video_frame, m); > ++ if (GST_MEMORY_IS_READONLY(mem)) { > ++ mem_rdonly = TRUE; > ++ gst_memory_unref (mem); > ++ break; > ++ } > ++ gst_memory_unref (mem); > ++ } > ++ > ++ if (mem_rdonly) { > ++ // since gst_buffer_make_writable just lookup the refcount to determine > if > ++ // a buffer is writable, and it will use _gst_buffer_copy() which don't > ++ // perform a deep memory copy even if the flag of a memory is set to > ++ // GST_MEMORY_FLAG_READONLY. So, we detect the memory flag and use > ++ // gst_buffer_copy_region with GST_BUFFER_COPY_DEEP parameter to perform > ++ // deep memory copy. if the allocator of a memory don't support mem_copy > ++ // interface, the it will return NULL, if this case, we can use > ++ // gst_buffer_make_writable() to get a shared memory buffer or the > orignal > ++ // buffer if the buffer's refcount is 1. > ++ GstBuffer *new_buf = gst_buffer_copy_region (video_frame, > ++ GST_BUFFER_COPY_ALL | GST_BUFFER_COPY_DEEP, 0, -1); > ++ > ++ GST_DEBUG_OBJECT (overlay, "copy %s video frame buffer %p -> %p", > ++ g_type_name (GST_MINI_OBJECT_TYPE (video_frame)), video_frame, > new_buf); > ++ > ++ if (!new_buf) { > ++ //maybe the allocator don't support mem_copy interface, the we just > use > ++ //gst_buffer_make_writable() to get a writable buffer. > ++ video_frame = gst_buffer_make_writable (video_frame); > ++ } else { > ++ gst_mini_object_unref (video_frame); > ++ GST_BUFFER_FLAG_UNSET (new_buf, GST_BUFFER_FLAG_TAG_MEMORY); > ++ video_frame = new_buf; > ++ } > ++ > ++ if (!video_frame) { > ++ GST_WARNING_OBJECT (overlay, "make writable buffer failed"); > ++ return GST_FLOW_OK; > ++ } > ++ > ++ m = gst_buffer_n_memory(video_frame); > ++ while (--m>=0) { > ++ mem = gst_buffer_get_memory(video_frame, m); > ++ GST_MEMORY_FLAG_UNSET (mem, GST_MEMORY_FLAG_READONLY); > ++ gst_memory_unref (mem); > ++ } > ++ } else { > ++ video_frame = gst_buffer_make_writable (video_frame); > ++ } > ++ > + if (!gst_video_frame_map (&frame, &overlay->info, video_frame, > + GST_MAP_READWRITE)) > + goto invalid_frame; > +@@ -1918,6 +1974,18 @@ gst_base_text_overlay_push_frame (GstBaseTextOverlay > * overlay, > + > + gst_video_frame_unmap (&frame); > + > ++ if (mem_rdonly && orig == video_frame) { > ++ //if we used the original buffer and it's mem is set to read only, > ++ //recover the memory ready only flag since we unset it before > ++ // gst_video_frame_map () > ++ m = gst_buffer_n_memory(video_frame); > ++ while (--m>=0) { > ++ mem = gst_buffer_get_memory(video_frame, m); > ++ GST_MEMORY_FLAGS(mem) |= (GST_MEMORY_FLAG_READONLY); > ++ gst_memory_unref (mem); > ++ } > ++ } > ++ > + done: > + > + return gst_pad_push (overlay->srcpad, video_frame); > +-- > +1.7.9.5 > + > diff --git > a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-base_1.4.5.bb > b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-base_1.4.5.bb > index 37bef6d..7aba40d 100644 > --- a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-base_1.4.5.bb > +++ b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-base_1.4.5.bb > @@ -17,6 +17,7 @@ SRC_URI += > "file://do-not-change-eos-event-to-gap-event-if.patch \ > > file://videoencoder-Keep-sticky-events-around-when-doing-a-soft-.patch \ > file://do-not-change-eos-event-to-gap-event2.patch \ > file://do-not-change-eos-event-to-gap-event3.patch \ > + > file://0001-basetextoverlay-make-memory-copy-when-video-buffer-s.patch \ > " > > SRC_URI[md5sum] = "357165af625c0ca353ab47c5d843920e" > -- > 1.9.1 > > -- > _______________________________________________ > Openembedded-core mailing list > Openembedded-core@lists.openembedded.org > http://lists.openembedded.org/mailman/listinfo/openembedded-core -- _______________________________________________ Openembedded-core mailing list Openembedded-core@lists.openembedded.org http://lists.openembedded.org/mailman/listinfo/openembedded-core