diff options
Diffstat (limited to 'meta/recipes-multimedia')
2 files changed, 130 insertions, 0 deletions
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 0000000000..03dca956a8 --- /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 @@ | |||
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 | |||
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 37bef6d051..7aba40d504 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 \ | |||
17 | file://videoencoder-Keep-sticky-events-around-when-doing-a-soft-.patch \ | 17 | file://videoencoder-Keep-sticky-events-around-when-doing-a-soft-.patch \ |
18 | file://do-not-change-eos-event-to-gap-event2.patch \ | 18 | file://do-not-change-eos-event-to-gap-event2.patch \ |
19 | file://do-not-change-eos-event-to-gap-event3.patch \ | 19 | file://do-not-change-eos-event-to-gap-event3.patch \ |
20 | file://0001-basetextoverlay-make-memory-copy-when-video-buffer-s.patch \ | ||
20 | " | 21 | " |
21 | 22 | ||
22 | SRC_URI[md5sum] = "357165af625c0ca353ab47c5d843920e" | 23 | SRC_URI[md5sum] = "357165af625c0ca353ab47c5d843920e" |