diff options
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.patch | 313 |
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 @@ +From 108fa0bb550f9b7355bfd5ae5340220fd1a4c9b5 Mon Sep 17 00:00:00 2001 +From: Don Darling <don.osc2@gmail.com> +Date: Thu, 5 Aug 2010 15:09:54 -0500 +Subject: [PATCH 7/8] Add support for pad-allocated buffers in TIDmaiVideoSink. + +This feature is currently only tested and enabled for DM365. +--- + .../ticodecplugin/src/gsttidmaibuffertransport.c | 4 +- + .../ticodecplugin/src/gsttidmaibuffertransport.h | 6 +- + .../ticodecplugin/src/gsttidmaivideosink.c | 197 ++++++++++++++++++-- + 3 files changed, 191 insertions(+), 16 deletions(-) + +diff --git a/gstreamer_ti/ti_build/ticodecplugin/src/gsttidmaibuffertransport.c b/gstreamer_ti/ti_build/ticodecplugin/src/gsttidmaibuffertransport.c +index 5fad371..9c69285 100644 +--- a/gstreamer_ti/ti_build/ticodecplugin/src/gsttidmaibuffertransport.c ++++ b/gstreamer_ti/ti_build/ticodecplugin/src/gsttidmaibuffertransport.c +@@ -136,8 +136,8 @@ static void gst_tidmaibuffertransport_finalize(GstBuffer *gstbuffer) + */ + if (Buffer_getBufTab(self->dmaiBuffer) != NULL) { + GST_LOG("clearing GStreamer useMask bit\n"); +- Buffer_freeUseMask(self->dmaiBuffer, +- gst_tidmaibuffer_GST_FREE); ++ Buffer_freeUseMask(self->dmaiBuffer, gst_tidmaibuffer_GST_FREE); ++ Buffer_freeUseMask(self->dmaiBuffer, gst_tidmaibuffer_VIDEOSINK_FREE); + } else { + GST_LOG("calling Buffer_delete()\n"); + Buffer_delete(self->dmaiBuffer); +diff --git a/gstreamer_ti/ti_build/ticodecplugin/src/gsttidmaibuffertransport.h b/gstreamer_ti/ti_build/ticodecplugin/src/gsttidmaibuffertransport.h +index 0265e70..20945f3 100644 +--- a/gstreamer_ti/ti_build/ticodecplugin/src/gsttidmaibuffertransport.h ++++ b/gstreamer_ti/ti_build/ticodecplugin/src/gsttidmaibuffertransport.h +@@ -52,8 +52,10 @@ G_BEGIN_DECLS + GstTIDmaiBufferTransportClass)) + + /* Use mask flags that keep track of where buffer is in use */ +-#define gst_tidmaibuffer_GST_FREE 0x1 +-#define gst_tidmaibuffer_CODEC_FREE 0x2 ++#define gst_tidmaibuffer_GST_FREE 0x1 ++#define gst_tidmaibuffer_CODEC_FREE 0x2 ++#define gst_tidmaibuffer_VIDEOSINK_FREE 0x4 ++#define gst_tidmaibuffer_DISPLAY_FREE 0x8 + + typedef struct _GstTIDmaiBufferTransport GstTIDmaiBufferTransport; + typedef struct _GstTIDmaiBufferTransportClass GstTIDmaiBufferTransportClass; +diff --git a/gstreamer_ti/ti_build/ticodecplugin/src/gsttidmaivideosink.c b/gstreamer_ti/ti_build/ticodecplugin/src/gsttidmaivideosink.c +index 0125ed2..7b84a8e 100644 +--- a/gstreamer_ti/ti_build/ticodecplugin/src/gsttidmaivideosink.c ++++ b/gstreamer_ti/ti_build/ticodecplugin/src/gsttidmaivideosink.c +@@ -151,6 +151,9 @@ static GstStateChangeReturn + gst_tidmaivideosink_change_state(GstElement * element, + GstStateChange transition); + static GstFlowReturn ++ gst_tidmaivideosink_buffer_alloc(GstBaseSink * bsink, guint64 offset, ++ guint size, GstCaps * caps, GstBuffer ** buf); ++static GstFlowReturn + gst_tidmaivideosink_preroll(GstBaseSink * bsink, GstBuffer * buffer); + static int + gst_tidmaivideosink_videostd_get_attrs(VideoStd_Type videoStd, +@@ -353,6 +356,13 @@ static void gst_tidmaivideosink_class_init(GstTIDmaiVideoSinkClass * klass) + GST_DEBUG_FUNCPTR(gst_tidmaivideosink_preroll); + gstbase_sink_class->render = + GST_DEBUG_FUNCPTR(gst_tidmaivideosink_render); ++ gstbase_sink_class->buffer_alloc = ++ GST_DEBUG_FUNCPTR(gst_tidmaivideosink_buffer_alloc); ++ ++ /* Pad-buffer allocation is currently only supported for DM365 */ ++ #if !defined(Platform_dm365) ++ gstbase_sink_class->buffer_alloc = NULL; ++ #endif + } + + +@@ -663,6 +673,132 @@ static gboolean gst_tidmaivideosink_event(GstBaseSink * bsink, + + + /****************************************************************************** ++ * gst_tidmaivideosink_buffer_alloc ++ ******************************************************************************/ ++static GstFlowReturn gst_tidmaivideosink_buffer_alloc(GstBaseSink * bsink, ++ guint64 offset, guint size, GstCaps * caps, ++ GstBuffer ** buf) ++{ ++ GstTIDmaiVideoSink *dmaisink = GST_TIDMAIVIDEOSINK(bsink); ++ BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT; ++ gboolean alloc_unref = FALSE; ++ Buffer_Handle hDispBuf = NULL; ++ GstCaps *alloc_caps; ++ ++ *buf = NULL; ++ ++ GST_LOG_OBJECT(dmaisink, ++ "a buffer of %d bytes was requested with caps %" GST_PTR_FORMAT ++ " and offset %" G_GUINT64_FORMAT, size, caps, offset); ++ ++ /* assume we're going to alloc what was requested, keep track of wheter we ++ * need to unref or not. When we suggest a new format upstream we will ++ * create a new caps that we need to unref. */ ++ alloc_caps = caps; ++ ++ /* Process the buffer caps */ ++ if (!gst_tidmaivideosink_process_caps(bsink, alloc_caps)) { ++ return GST_FLOW_UNEXPECTED; ++ } ++ ++ /* Pad buffer allocation requires that we use user-allocated display ++ * buffers. ++ */ ++ if (!dmaisink->useUserptrBufs && dmaisink->hDisplay) { ++ GST_ELEMENT_ERROR(dmaisink, RESOURCE, FAILED, ++ ("Cannot use pad buffer allocation after mmap buffers already " ++ "in use\n"), (NULL)); ++ return GST_FLOW_UNEXPECTED; ++ } ++ else { ++ dmaisink->useUserptrBufs = TRUE; ++ } ++ ++ /* Allocate the display buffers */ ++ if (!dmaisink->hDispBufTab && dmaisink->useUserptrBufs) { ++ ++ /* Set the display attributes now so we can allocate display buffers */ ++ if (!gst_tidmaivideosink_set_display_attrs(dmaisink, ++ dmaisink->dGfxAttrs.colorSpace)) { ++ GST_ERROR("Error while trying to set the display attributes\n"); ++ return GST_FLOW_UNEXPECTED; ++ } ++ ++ if (!gst_tidmaivideosink_alloc_display_buffers(dmaisink, size)) { ++ GST_ERROR("Failed to allocate display buffers"); ++ return GST_FLOW_UNEXPECTED; ++ } ++ } ++ ++ /* Get a buffer from the BufTab or display driver */ ++ if (!(hDispBuf = gst_tidmaibuftab_get_buf(dmaisink->hDispBufTab))) { ++ if (dmaisink->hDisplay && ++ Display_get(dmaisink->hDisplay, &hDispBuf) < 0) { ++ GST_ELEMENT_ERROR(dmaisink, RESOURCE, FAILED, ++ ("Failed to get display buffer\n"), (NULL)); ++ return GST_FLOW_UNEXPECTED; ++ } ++ } ++ ++ /* If the geometry doesn't match, generate a new caps for it */ ++ Buffer_getAttrs(hDispBuf, BufferGfx_getBufferAttrs(&gfxAttrs)); ++ ++ if (gfxAttrs.dim.width != dmaisink->dGfxAttrs.dim.width || ++ gfxAttrs.dim.height != dmaisink->dGfxAttrs.dim.height || ++ gfxAttrs.colorSpace != dmaisink->dGfxAttrs.colorSpace) { ++ ++ GstCaps *desired_caps; ++ GstStructure *desired_struct; ++ ++ /* make a copy of the incomming caps to create the new suggestion. We ++ * can't use make_writable because we might then destroy the original ++ * caps which we still need when the peer does not accept the ++ * suggestion. ++ */ ++ desired_caps = gst_caps_copy (caps); ++ desired_struct = gst_caps_get_structure (desired_caps, 0); ++ ++ GST_DEBUG ("we prefer to receive a %ldx%ld video; %ldx%ld was requested", ++ gfxAttrs.dim.width, gfxAttrs.dim.height, ++ dmaisink->dGfxAttrs.dim.width, dmaisink->dGfxAttrs.dim.height); ++ gst_structure_set (desired_struct, "width", G_TYPE_INT, ++ gfxAttrs.dim.width, NULL); ++ gst_structure_set (desired_struct, "height", G_TYPE_INT, ++ gfxAttrs.dim.height, NULL); ++ ++ if (gst_pad_peer_accept_caps (GST_VIDEO_SINK_PAD (dmaisink), ++ desired_caps)) { ++ alloc_caps = desired_caps; ++ alloc_unref = TRUE; ++ ++ if (!gst_tidmaivideosink_process_caps(bsink, alloc_caps)) { ++ return GST_FLOW_UNEXPECTED; ++ } ++ GST_DEBUG ("peer pad accepts our desired caps %" GST_PTR_FORMAT, ++ desired_caps); ++ } ++ else { ++ GST_DEBUG ("peer pad does not accept our desired caps %" ++ GST_PTR_FORMAT, desired_caps); ++ } ++ } ++ ++ /* Return the display buffer */ ++ BufferGfx_resetDimensions(hDispBuf); ++ Buffer_freeUseMask(hDispBuf, gst_tidmaibuffer_DISPLAY_FREE); ++ *buf = gst_tidmaibuffertransport_new(hDispBuf, NULL); ++ gst_buffer_set_caps(*buf, alloc_caps); ++ ++ /* If we allocated new caps, unref them now */ ++ if (alloc_unref) { ++ gst_caps_unref (alloc_caps); ++ } ++ ++ return GST_FLOW_OK; ++} ++ ++ ++/****************************************************************************** + * gst_tidmaivideosink_preroll + ******************************************************************************/ + static GstFlowReturn gst_tidmaivideosink_preroll(GstBaseSink * bsink, +@@ -1282,6 +1418,18 @@ static gboolean gst_tidmaivideosink_init_display(GstTIDmaiVideoSink * sink) + return FALSE; + } + ++ /* If we own the display buffers, tell DMAI to delay starting the ++ * display until we call Display_put for the first time. ++ */ ++ if (sink->hDispBufTab) { ++ #if defined(Platform_dm365) ++ sink->dAttrs.delayStreamon = TRUE; ++ #else ++ GST_ERROR("delayed V4L2 streamon not supported\n"); ++ return FALSE; ++ #endif ++ } ++ + /* Allocate user-allocated display buffers, if requested */ + if (!sink->hDispBufTab && sink->useUserptrBufs) { + if (!gst_tidmaivideosink_alloc_display_buffers(sink, 0)) { +@@ -1416,9 +1564,6 @@ static gboolean gst_tidmaivideosink_process_caps(GstBaseSink * bsink, + gst_structure_get_fraction(structure, "framerate", &framerateNum, + &framerateDen); + +- /* Error check new values against existing ones */ +- /* TBD */ +- + /* Populate the display graphics attributes */ + dmaisink->dGfxAttrs.bAttrs.reference = dmaisink->contiguousInputFrame; + dmaisink->dGfxAttrs.dim.width = width; +@@ -1445,9 +1590,10 @@ static gboolean gst_tidmaivideosink_process_caps(GstBaseSink * bsink, + static GstFlowReturn gst_tidmaivideosink_render(GstBaseSink * bsink, + GstBuffer * buf) + { +- Buffer_Handle hDispBuf = NULL; +- Buffer_Handle inBuf = NULL; +- GstTIDmaiVideoSink *sink = GST_TIDMAIVIDEOSINK(bsink); ++ Buffer_Handle hDispBuf = NULL; ++ Buffer_Handle inBuf = NULL; ++ gboolean inBufIsOurs = FALSE; ++ GstTIDmaiVideoSink *sink = GST_TIDMAIVIDEOSINK(bsink); + BufferGfx_Dimensions dim; + gchar dur_str[64]; + gchar ts_str[64]; +@@ -1470,7 +1616,10 @@ static GstFlowReturn gst_tidmaivideosink_render(GstBaseSink * bsink, + * generated via videotestsrc plugin. + */ + if (GST_IS_TIDMAIBUFFERTRANSPORT(buf)) { +- inBuf = GST_TIDMAIBUFFERTRANSPORT_DMAIBUF(buf); ++ inBuf = GST_TIDMAIBUFFERTRANSPORT_DMAIBUF(buf); ++ inBufIsOurs = (sink->hDispBufTab && ++ GST_TIDMAIBUFTAB_BUFTAB(sink->hDispBufTab) == ++ Buffer_getBufTab(inBuf)); + } else { + /* allocate DMAI buffer */ + if (sink->tempDmaiBuf == NULL) { +@@ -1532,11 +1681,33 @@ static GstFlowReturn gst_tidmaivideosink_render(GstBaseSink * bsink, + */ + for (i = 0; i < sink->framerepeat; i++) { + +- /* Get a buffer from the display driver */ +- if (Display_get(sink->hDisplay, &hDispBuf) < 0) { +- GST_ELEMENT_ERROR(sink, RESOURCE, FAILED, +- ("Failed to get display buffer\n"), (NULL)); +- goto cleanup; ++ /* If the input buffer originated from this element via pad allocation, ++ * simply give it back to the display and continue. ++ */ ++ if (inBufIsOurs) { ++ ++ /* Mark buffer as in-use by the display so it can't be re-used ++ * until it comes back from Display_get */ ++ Buffer_setUseMask(inBuf, Buffer_getUseMask(inBuf) | ++ gst_tidmaibuffer_DISPLAY_FREE); ++ ++ if (Display_put(sink->hDisplay, inBuf) < 0) { ++ GST_ELEMENT_ERROR(sink, RESOURCE, FAILED, ++ ("Failed to put display buffer\n"), (NULL)); ++ goto cleanup; ++ } ++ continue; ++ } ++ ++ /* Otherwise, our input buffer originated from up-stream. Retrieve a ++ * display buffer to copy the contents into. ++ */ ++ else { ++ if (Display_get(sink->hDisplay, &hDispBuf) < 0) { ++ GST_ELEMENT_ERROR(sink, RESOURCE, FAILED, ++ ("Failed to get display buffer\n"), (NULL)); ++ goto cleanup; ++ } + } + + /* Retrieve the dimensions of the display buffer */ +@@ -1844,8 +2015,10 @@ static gboolean gst_tidmaivideosink_alloc_display_buffers( + gfxAttrs.dim.height, gfxAttrs.dim.lineLength, gfxAttrs.colorSpace); + } + ++ gfxAttrs.bAttrs.useMask = gst_tidmaibuffer_VIDEOSINK_FREE; + sink->hDispBufTab = gst_tidmaibuftab_new(sink->dAttrs.numBufs, bufSize, + BufferGfx_getBufferAttrs(&gfxAttrs)); ++ gst_tidmaibuftab_set_blocking(sink->hDispBufTab, FALSE); + + return TRUE; + } +-- +1.7.0.4 + |