summaryrefslogtreecommitdiffstats
path: root/extras/recipes-ti/gstreamer-ti/gstreamer-ti/0007-Add-support-for-pad-allocated-buffers-in-TIDmaiVideo.patch
diff options
context:
space:
mode:
Diffstat (limited to 'extras/recipes-ti/gstreamer-ti/gstreamer-ti/0007-Add-support-for-pad-allocated-buffers-in-TIDmaiVideo.patch')
-rw-r--r--extras/recipes-ti/gstreamer-ti/gstreamer-ti/0007-Add-support-for-pad-allocated-buffers-in-TIDmaiVideo.patch313
1 files changed, 313 insertions, 0 deletions
diff --git a/extras/recipes-ti/gstreamer-ti/gstreamer-ti/0007-Add-support-for-pad-allocated-buffers-in-TIDmaiVideo.patch b/extras/recipes-ti/gstreamer-ti/gstreamer-ti/0007-Add-support-for-pad-allocated-buffers-in-TIDmaiVideo.patch
new file mode 100644
index 00000000..863bd34d
--- /dev/null
+++ b/extras/recipes-ti/gstreamer-ti/gstreamer-ti/0007-Add-support-for-pad-allocated-buffers-in-TIDmaiVideo.patch
@@ -0,0 +1,313 @@
1From 108fa0bb550f9b7355bfd5ae5340220fd1a4c9b5 Mon Sep 17 00:00:00 2001
2From: Don Darling <don.osc2@gmail.com>
3Date: Thu, 5 Aug 2010 15:09:54 -0500
4Subject: [PATCH 7/8] Add support for pad-allocated buffers in TIDmaiVideoSink.
5
6This feature is currently only tested and enabled for DM365.
7---
8 .../ticodecplugin/src/gsttidmaibuffertransport.c | 4 +-
9 .../ticodecplugin/src/gsttidmaibuffertransport.h | 6 +-
10 .../ticodecplugin/src/gsttidmaivideosink.c | 197 ++++++++++++++++++--
11 3 files changed, 191 insertions(+), 16 deletions(-)
12
13diff --git a/gstreamer_ti/ti_build/ticodecplugin/src/gsttidmaibuffertransport.c b/gstreamer_ti/ti_build/ticodecplugin/src/gsttidmaibuffertransport.c
14index 5fad371..9c69285 100644
15--- a/gstreamer_ti/ti_build/ticodecplugin/src/gsttidmaibuffertransport.c
16+++ b/gstreamer_ti/ti_build/ticodecplugin/src/gsttidmaibuffertransport.c
17@@ -136,8 +136,8 @@ static void gst_tidmaibuffertransport_finalize(GstBuffer *gstbuffer)
18 */
19 if (Buffer_getBufTab(self->dmaiBuffer) != NULL) {
20 GST_LOG("clearing GStreamer useMask bit\n");
21- Buffer_freeUseMask(self->dmaiBuffer,
22- gst_tidmaibuffer_GST_FREE);
23+ Buffer_freeUseMask(self->dmaiBuffer, gst_tidmaibuffer_GST_FREE);
24+ Buffer_freeUseMask(self->dmaiBuffer, gst_tidmaibuffer_VIDEOSINK_FREE);
25 } else {
26 GST_LOG("calling Buffer_delete()\n");
27 Buffer_delete(self->dmaiBuffer);
28diff --git a/gstreamer_ti/ti_build/ticodecplugin/src/gsttidmaibuffertransport.h b/gstreamer_ti/ti_build/ticodecplugin/src/gsttidmaibuffertransport.h
29index 0265e70..20945f3 100644
30--- a/gstreamer_ti/ti_build/ticodecplugin/src/gsttidmaibuffertransport.h
31+++ b/gstreamer_ti/ti_build/ticodecplugin/src/gsttidmaibuffertransport.h
32@@ -52,8 +52,10 @@ G_BEGIN_DECLS
33 GstTIDmaiBufferTransportClass))
34
35 /* Use mask flags that keep track of where buffer is in use */
36-#define gst_tidmaibuffer_GST_FREE 0x1
37-#define gst_tidmaibuffer_CODEC_FREE 0x2
38+#define gst_tidmaibuffer_GST_FREE 0x1
39+#define gst_tidmaibuffer_CODEC_FREE 0x2
40+#define gst_tidmaibuffer_VIDEOSINK_FREE 0x4
41+#define gst_tidmaibuffer_DISPLAY_FREE 0x8
42
43 typedef struct _GstTIDmaiBufferTransport GstTIDmaiBufferTransport;
44 typedef struct _GstTIDmaiBufferTransportClass GstTIDmaiBufferTransportClass;
45diff --git a/gstreamer_ti/ti_build/ticodecplugin/src/gsttidmaivideosink.c b/gstreamer_ti/ti_build/ticodecplugin/src/gsttidmaivideosink.c
46index 0125ed2..7b84a8e 100644
47--- a/gstreamer_ti/ti_build/ticodecplugin/src/gsttidmaivideosink.c
48+++ b/gstreamer_ti/ti_build/ticodecplugin/src/gsttidmaivideosink.c
49@@ -151,6 +151,9 @@ static GstStateChangeReturn
50 gst_tidmaivideosink_change_state(GstElement * element,
51 GstStateChange transition);
52 static GstFlowReturn
53+ gst_tidmaivideosink_buffer_alloc(GstBaseSink * bsink, guint64 offset,
54+ guint size, GstCaps * caps, GstBuffer ** buf);
55+static GstFlowReturn
56 gst_tidmaivideosink_preroll(GstBaseSink * bsink, GstBuffer * buffer);
57 static int
58 gst_tidmaivideosink_videostd_get_attrs(VideoStd_Type videoStd,
59@@ -353,6 +356,13 @@ static void gst_tidmaivideosink_class_init(GstTIDmaiVideoSinkClass * klass)
60 GST_DEBUG_FUNCPTR(gst_tidmaivideosink_preroll);
61 gstbase_sink_class->render =
62 GST_DEBUG_FUNCPTR(gst_tidmaivideosink_render);
63+ gstbase_sink_class->buffer_alloc =
64+ GST_DEBUG_FUNCPTR(gst_tidmaivideosink_buffer_alloc);
65+
66+ /* Pad-buffer allocation is currently only supported for DM365 */
67+ #if !defined(Platform_dm365)
68+ gstbase_sink_class->buffer_alloc = NULL;
69+ #endif
70 }
71
72
73@@ -663,6 +673,132 @@ static gboolean gst_tidmaivideosink_event(GstBaseSink * bsink,
74
75
76 /******************************************************************************
77+ * gst_tidmaivideosink_buffer_alloc
78+ ******************************************************************************/
79+static GstFlowReturn gst_tidmaivideosink_buffer_alloc(GstBaseSink * bsink,
80+ guint64 offset, guint size, GstCaps * caps,
81+ GstBuffer ** buf)
82+{
83+ GstTIDmaiVideoSink *dmaisink = GST_TIDMAIVIDEOSINK(bsink);
84+ BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT;
85+ gboolean alloc_unref = FALSE;
86+ Buffer_Handle hDispBuf = NULL;
87+ GstCaps *alloc_caps;
88+
89+ *buf = NULL;
90+
91+ GST_LOG_OBJECT(dmaisink,
92+ "a buffer of %d bytes was requested with caps %" GST_PTR_FORMAT
93+ " and offset %" G_GUINT64_FORMAT, size, caps, offset);
94+
95+ /* assume we're going to alloc what was requested, keep track of wheter we
96+ * need to unref or not. When we suggest a new format upstream we will
97+ * create a new caps that we need to unref. */
98+ alloc_caps = caps;
99+
100+ /* Process the buffer caps */
101+ if (!gst_tidmaivideosink_process_caps(bsink, alloc_caps)) {
102+ return GST_FLOW_UNEXPECTED;
103+ }
104+
105+ /* Pad buffer allocation requires that we use user-allocated display
106+ * buffers.
107+ */
108+ if (!dmaisink->useUserptrBufs && dmaisink->hDisplay) {
109+ GST_ELEMENT_ERROR(dmaisink, RESOURCE, FAILED,
110+ ("Cannot use pad buffer allocation after mmap buffers already "
111+ "in use\n"), (NULL));
112+ return GST_FLOW_UNEXPECTED;
113+ }
114+ else {
115+ dmaisink->useUserptrBufs = TRUE;
116+ }
117+
118+ /* Allocate the display buffers */
119+ if (!dmaisink->hDispBufTab && dmaisink->useUserptrBufs) {
120+
121+ /* Set the display attributes now so we can allocate display buffers */
122+ if (!gst_tidmaivideosink_set_display_attrs(dmaisink,
123+ dmaisink->dGfxAttrs.colorSpace)) {
124+ GST_ERROR("Error while trying to set the display attributes\n");
125+ return GST_FLOW_UNEXPECTED;
126+ }
127+
128+ if (!gst_tidmaivideosink_alloc_display_buffers(dmaisink, size)) {
129+ GST_ERROR("Failed to allocate display buffers");
130+ return GST_FLOW_UNEXPECTED;
131+ }
132+ }
133+
134+ /* Get a buffer from the BufTab or display driver */
135+ if (!(hDispBuf = gst_tidmaibuftab_get_buf(dmaisink->hDispBufTab))) {
136+ if (dmaisink->hDisplay &&
137+ Display_get(dmaisink->hDisplay, &hDispBuf) < 0) {
138+ GST_ELEMENT_ERROR(dmaisink, RESOURCE, FAILED,
139+ ("Failed to get display buffer\n"), (NULL));
140+ return GST_FLOW_UNEXPECTED;
141+ }
142+ }
143+
144+ /* If the geometry doesn't match, generate a new caps for it */
145+ Buffer_getAttrs(hDispBuf, BufferGfx_getBufferAttrs(&gfxAttrs));
146+
147+ if (gfxAttrs.dim.width != dmaisink->dGfxAttrs.dim.width ||
148+ gfxAttrs.dim.height != dmaisink->dGfxAttrs.dim.height ||
149+ gfxAttrs.colorSpace != dmaisink->dGfxAttrs.colorSpace) {
150+
151+ GstCaps *desired_caps;
152+ GstStructure *desired_struct;
153+
154+ /* make a copy of the incomming caps to create the new suggestion. We
155+ * can't use make_writable because we might then destroy the original
156+ * caps which we still need when the peer does not accept the
157+ * suggestion.
158+ */
159+ desired_caps = gst_caps_copy (caps);
160+ desired_struct = gst_caps_get_structure (desired_caps, 0);
161+
162+ GST_DEBUG ("we prefer to receive a %ldx%ld video; %ldx%ld was requested",
163+ gfxAttrs.dim.width, gfxAttrs.dim.height,
164+ dmaisink->dGfxAttrs.dim.width, dmaisink->dGfxAttrs.dim.height);
165+ gst_structure_set (desired_struct, "width", G_TYPE_INT,
166+ gfxAttrs.dim.width, NULL);
167+ gst_structure_set (desired_struct, "height", G_TYPE_INT,
168+ gfxAttrs.dim.height, NULL);
169+
170+ if (gst_pad_peer_accept_caps (GST_VIDEO_SINK_PAD (dmaisink),
171+ desired_caps)) {
172+ alloc_caps = desired_caps;
173+ alloc_unref = TRUE;
174+
175+ if (!gst_tidmaivideosink_process_caps(bsink, alloc_caps)) {
176+ return GST_FLOW_UNEXPECTED;
177+ }
178+ GST_DEBUG ("peer pad accepts our desired caps %" GST_PTR_FORMAT,
179+ desired_caps);
180+ }
181+ else {
182+ GST_DEBUG ("peer pad does not accept our desired caps %"
183+ GST_PTR_FORMAT, desired_caps);
184+ }
185+ }
186+
187+ /* Return the display buffer */
188+ BufferGfx_resetDimensions(hDispBuf);
189+ Buffer_freeUseMask(hDispBuf, gst_tidmaibuffer_DISPLAY_FREE);
190+ *buf = gst_tidmaibuffertransport_new(hDispBuf, NULL);
191+ gst_buffer_set_caps(*buf, alloc_caps);
192+
193+ /* If we allocated new caps, unref them now */
194+ if (alloc_unref) {
195+ gst_caps_unref (alloc_caps);
196+ }
197+
198+ return GST_FLOW_OK;
199+}
200+
201+
202+/******************************************************************************
203 * gst_tidmaivideosink_preroll
204 ******************************************************************************/
205 static GstFlowReturn gst_tidmaivideosink_preroll(GstBaseSink * bsink,
206@@ -1282,6 +1418,18 @@ static gboolean gst_tidmaivideosink_init_display(GstTIDmaiVideoSink * sink)
207 return FALSE;
208 }
209
210+ /* If we own the display buffers, tell DMAI to delay starting the
211+ * display until we call Display_put for the first time.
212+ */
213+ if (sink->hDispBufTab) {
214+ #if defined(Platform_dm365)
215+ sink->dAttrs.delayStreamon = TRUE;
216+ #else
217+ GST_ERROR("delayed V4L2 streamon not supported\n");
218+ return FALSE;
219+ #endif
220+ }
221+
222 /* Allocate user-allocated display buffers, if requested */
223 if (!sink->hDispBufTab && sink->useUserptrBufs) {
224 if (!gst_tidmaivideosink_alloc_display_buffers(sink, 0)) {
225@@ -1416,9 +1564,6 @@ static gboolean gst_tidmaivideosink_process_caps(GstBaseSink * bsink,
226 gst_structure_get_fraction(structure, "framerate", &framerateNum,
227 &framerateDen);
228
229- /* Error check new values against existing ones */
230- /* TBD */
231-
232 /* Populate the display graphics attributes */
233 dmaisink->dGfxAttrs.bAttrs.reference = dmaisink->contiguousInputFrame;
234 dmaisink->dGfxAttrs.dim.width = width;
235@@ -1445,9 +1590,10 @@ static gboolean gst_tidmaivideosink_process_caps(GstBaseSink * bsink,
236 static GstFlowReturn gst_tidmaivideosink_render(GstBaseSink * bsink,
237 GstBuffer * buf)
238 {
239- Buffer_Handle hDispBuf = NULL;
240- Buffer_Handle inBuf = NULL;
241- GstTIDmaiVideoSink *sink = GST_TIDMAIVIDEOSINK(bsink);
242+ Buffer_Handle hDispBuf = NULL;
243+ Buffer_Handle inBuf = NULL;
244+ gboolean inBufIsOurs = FALSE;
245+ GstTIDmaiVideoSink *sink = GST_TIDMAIVIDEOSINK(bsink);
246 BufferGfx_Dimensions dim;
247 gchar dur_str[64];
248 gchar ts_str[64];
249@@ -1470,7 +1616,10 @@ static GstFlowReturn gst_tidmaivideosink_render(GstBaseSink * bsink,
250 * generated via videotestsrc plugin.
251 */
252 if (GST_IS_TIDMAIBUFFERTRANSPORT(buf)) {
253- inBuf = GST_TIDMAIBUFFERTRANSPORT_DMAIBUF(buf);
254+ inBuf = GST_TIDMAIBUFFERTRANSPORT_DMAIBUF(buf);
255+ inBufIsOurs = (sink->hDispBufTab &&
256+ GST_TIDMAIBUFTAB_BUFTAB(sink->hDispBufTab) ==
257+ Buffer_getBufTab(inBuf));
258 } else {
259 /* allocate DMAI buffer */
260 if (sink->tempDmaiBuf == NULL) {
261@@ -1532,11 +1681,33 @@ static GstFlowReturn gst_tidmaivideosink_render(GstBaseSink * bsink,
262 */
263 for (i = 0; i < sink->framerepeat; i++) {
264
265- /* Get a buffer from the display driver */
266- if (Display_get(sink->hDisplay, &hDispBuf) < 0) {
267- GST_ELEMENT_ERROR(sink, RESOURCE, FAILED,
268- ("Failed to get display buffer\n"), (NULL));
269- goto cleanup;
270+ /* If the input buffer originated from this element via pad allocation,
271+ * simply give it back to the display and continue.
272+ */
273+ if (inBufIsOurs) {
274+
275+ /* Mark buffer as in-use by the display so it can't be re-used
276+ * until it comes back from Display_get */
277+ Buffer_setUseMask(inBuf, Buffer_getUseMask(inBuf) |
278+ gst_tidmaibuffer_DISPLAY_FREE);
279+
280+ if (Display_put(sink->hDisplay, inBuf) < 0) {
281+ GST_ELEMENT_ERROR(sink, RESOURCE, FAILED,
282+ ("Failed to put display buffer\n"), (NULL));
283+ goto cleanup;
284+ }
285+ continue;
286+ }
287+
288+ /* Otherwise, our input buffer originated from up-stream. Retrieve a
289+ * display buffer to copy the contents into.
290+ */
291+ else {
292+ if (Display_get(sink->hDisplay, &hDispBuf) < 0) {
293+ GST_ELEMENT_ERROR(sink, RESOURCE, FAILED,
294+ ("Failed to get display buffer\n"), (NULL));
295+ goto cleanup;
296+ }
297 }
298
299 /* Retrieve the dimensions of the display buffer */
300@@ -1844,8 +2015,10 @@ static gboolean gst_tidmaivideosink_alloc_display_buffers(
301 gfxAttrs.dim.height, gfxAttrs.dim.lineLength, gfxAttrs.colorSpace);
302 }
303
304+ gfxAttrs.bAttrs.useMask = gst_tidmaibuffer_VIDEOSINK_FREE;
305 sink->hDispBufTab = gst_tidmaibuftab_new(sink->dAttrs.numBufs, bufSize,
306 BufferGfx_getBufferAttrs(&gfxAttrs));
307+ gst_tidmaibuftab_set_blocking(sink->hDispBufTab, FALSE);
308
309 return TRUE;
310 }
311--
3121.7.0.4
313