summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--omx/gstomx.c35
-rw-r--r--omx/gstomx.h2
-rw-r--r--omx/gstomxbufferpool.c144
-rw-r--r--omx/gstomxvideoenc.c187
-rw-r--r--omx/gstomxvideoenc.h3
5 files changed, 309 insertions, 62 deletions
diff --git a/omx/gstomx.c b/omx/gstomx.c
index 8f99f82..cb9b392 100644
--- a/omx/gstomx.c
+++ b/omx/gstomx.c
@@ -418,7 +418,11 @@ gst_omx_component_handle_messages (GstOMXComponent * comp)
port->eos = TRUE;
}
- g_queue_push_tail (&port->pending_buffers, buf);
+ /* If an input port is managed by a pool, the buffer will be ready to be
+ * filled again once it's been released to the pool. */
+ if (port->port_def.eDir == OMX_DirOutput || !port->using_pool) {
+ g_queue_push_tail (&port->pending_buffers, buf);
+ }
break;
}
@@ -1097,6 +1101,7 @@ gst_omx_component_add_port (GstOMXComponent * comp, guint32 index)
port->enabled_pending = FALSE;
port->disabled_pending = FALSE;
port->eos = FALSE;
+ port->using_pool = FALSE;
if (port->port_def.eDir == OMX_DirInput)
comp->n_in_ports++;
@@ -2631,6 +2636,34 @@ gst_omx_port_ensure_buffer_count_actual (GstOMXPort * port, guint extra)
}
gboolean
+gst_omx_port_update_buffer_count_actual (GstOMXPort * port, guint nb)
+{
+ OMX_PARAM_PORTDEFINITIONTYPE port_def;
+
+ gst_omx_port_get_port_definition (port, &port_def);
+
+ if (nb < port_def.nBufferCountMin) {
+ GST_DEBUG_OBJECT (port->comp->parent,
+ "Requested to use %d buffers on port %d but it's minimum is %d", nb,
+ (guint) port->index, (guint) port_def.nBufferCountMin);
+
+ nb = port_def.nBufferCountMin;
+ }
+
+ if (port_def.nBufferCountActual != nb) {
+ port_def.nBufferCountActual = nb;
+
+ GST_DEBUG_OBJECT (port->comp->parent,
+ "set port %d nBufferCountActual to %d", (guint) port->index, nb);
+
+ if (gst_omx_port_update_port_definition (port, &port_def) != OMX_ErrorNone)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean
gst_omx_port_set_dmabuf (GstOMXPort * port, gboolean dmabuf)
{
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
diff --git a/omx/gstomx.h b/omx/gstomx.h
index c43e2d7..d61303c 100644
--- a/omx/gstomx.h
+++ b/omx/gstomx.h
@@ -324,6 +324,7 @@ struct _GstOMXPort {
gboolean disabled_pending; /* was done until it took effect */
gboolean eos; /* TRUE after a buffer with EOS flag was received */
GstOMXBufferAllocation allocation;
+ gboolean using_pool; /* TRUE if the buffers of this port are managed by a pool */
/* Increased whenever the settings of these port change.
* If settings_cookie != configured_settings_cookie
@@ -467,6 +468,7 @@ OMX_ERRORTYPE gst_omx_port_set_enabled (GstOMXPort * port, gboolean enabled)
OMX_ERRORTYPE gst_omx_port_wait_enabled (GstOMXPort * port, GstClockTime timeout);
gboolean gst_omx_port_is_enabled (GstOMXPort * port);
gboolean gst_omx_port_ensure_buffer_count_actual (GstOMXPort * port, guint extra);
+gboolean gst_omx_port_update_buffer_count_actual (GstOMXPort * port, guint nb);
gboolean gst_omx_port_set_dmabuf (GstOMXPort * port, gboolean dmabuf);
diff --git a/omx/gstomxbufferpool.c b/omx/gstomxbufferpool.c
index f2e6300..7bb31f5 100644
--- a/omx/gstomxbufferpool.c
+++ b/omx/gstomxbufferpool.c
@@ -36,6 +36,14 @@ typedef struct _GstOMXMemory GstOMXMemory;
typedef struct _GstOMXMemoryAllocator GstOMXMemoryAllocator;
typedef struct _GstOMXMemoryAllocatorClass GstOMXMemoryAllocatorClass;
+enum
+{
+ SIG_ALLOCATE,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
struct _GstOMXMemory
{
GstMemory mem;
@@ -171,11 +179,14 @@ gst_omx_memory_allocator_alloc (GstAllocator * allocator, GstMemoryFlags flags,
* pool to the OMX port or provide the OMX buffers directly to other
* elements.
*
- *
- * A buffer is in the pool if it is currently owned by the port,
- * i.e. after OMX_{Fill,Empty}ThisBuffer(). A buffer is outside
+ * An output buffer is in the pool if it is currently owned by the port,
+ * i.e. after OMX_FillThisBuffer(). An output buffer is outside
* the pool after it was taken from the port after it was handled
- * by the port, i.e. {Empty,Fill}BufferDone.
+ * by the port, i.e. FillBufferDone.
+ *
+ * An input buffer is in the pool if it is currently available to be filled
+ * upstream. It will be put back into the pool when it has been processed by
+ * OMX, (EmptyBufferDone).
*
* Buffers can be allocated by us (OMX_AllocateBuffer()) or allocated
* by someone else and (temporarily) passed to this pool
@@ -188,7 +199,7 @@ gst_omx_memory_allocator_alloc (GstAllocator * allocator, GstMemoryFlags flags,
* They correspond 1:1 to the OMX buffers of the port, which are allocated
* before the pool is started.
*
- * Acquiring a buffer from this pool happens after the OMX buffer has
+ * Acquiring an output buffer from this pool happens after the OMX buffer has
* been acquired from the port. gst_buffer_pool_acquire_buffer() is
* supposed to return the buffer that corresponds to the OMX buffer.
*
@@ -217,6 +228,9 @@ static gboolean
gst_omx_buffer_pool_start (GstBufferPool * bpool)
{
GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool);
+ gboolean has_buffers;
+ GstStructure *config;
+ guint min, max;
/* Only allow to start the pool if we still are attached
* to a component and port */
@@ -225,8 +239,39 @@ gst_omx_buffer_pool_start (GstBufferPool * bpool)
GST_OBJECT_UNLOCK (pool);
return FALSE;
}
+
+ pool->port->using_pool = TRUE;
+
+ has_buffers = (pool->port->buffers != NULL);
GST_OBJECT_UNLOCK (pool);
+ config = gst_buffer_pool_get_config (bpool);
+ gst_buffer_pool_config_get_params (config, NULL, NULL, &min, &max);
+ gst_structure_free (config);
+ if (max > min) {
+ GST_WARNING_OBJECT (bpool,
+ "max (%d) cannot be higher than min (%d) as pool cannot allocate buffers on the fly",
+ max, min);
+ return FALSE;
+ }
+
+ if (!has_buffers) {
+ gboolean result = FALSE;
+
+ GST_DEBUG_OBJECT (bpool, "Buffers not yet allocated on port %d of %s",
+ pool->port->index, pool->component->name);
+
+ g_signal_emit (pool, signals[SIG_ALLOCATE], 0, &result);
+
+ if (!result) {
+ GST_WARNING_OBJECT (bpool,
+ "Element failed to allocate buffers, can't start pool");
+ return FALSE;
+ }
+ }
+
+ g_assert (pool->port->buffers);
+
return
GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->start (bpool);
}
@@ -237,12 +282,17 @@ gst_omx_buffer_pool_stop (GstBufferPool * bpool)
GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool);
gint i = 0;
- /* When not using the default GstBufferPool::GstAtomicQueue then
- * GstBufferPool::free_buffer is not called while stopping the pool
- * (because the queue is empty) */
- for (i = 0; i < pool->buffers->len; i++)
- GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->release_buffer
- (bpool, g_ptr_array_index (pool->buffers, i));
+ if (pool->buffers) {
+ /* When not using the default GstBufferPool::GstAtomicQueue then
+ * GstBufferPool::free_buffer is not called while stopping the pool
+ * (because the queue is empty) */
+ for (i = 0; i < pool->buffers->len; i++)
+ GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->release_buffer
+ (bpool, g_ptr_array_index (pool->buffers, i));
+
+ /* Remove any buffers that are there */
+ g_ptr_array_set_size (pool->buffers, 0);
+ }
/* Remove any buffers that are there */
g_ptr_array_set_size (pool->buffers, 0);
@@ -255,6 +305,8 @@ gst_omx_buffer_pool_stop (GstBufferPool * bpool)
pool->caps = NULL;
pool->add_videometa = FALSE;
+ pool->deactivated = TRUE;
+ pool->port->using_pool = TRUE;
return GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->stop (bpool);
}
@@ -284,10 +336,11 @@ gst_omx_buffer_pool_set_config (GstBufferPool * bpool, GstStructure * config)
{
GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool);
GstCaps *caps;
+ guint size, min;
GST_OBJECT_LOCK (pool);
- if (!gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL))
+ if (!gst_buffer_pool_config_get_params (config, &caps, &size, &min, NULL))
goto wrong_config;
if (caps == NULL)
@@ -314,6 +367,9 @@ gst_omx_buffer_pool_set_config (GstBufferPool * bpool, GstStructure * config)
gst_caps_unref (pool->caps);
pool->caps = gst_caps_ref (caps);
+ /* Ensure max=min as the pool won't be able to allocate more buffers while active */
+ gst_buffer_pool_config_set_params (config, caps, size, min, min);
+
GST_OBJECT_UNLOCK (pool);
return GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->set_config
@@ -520,6 +576,21 @@ gst_omx_buffer_pool_free_buffer (GstBufferPool * bpool, GstBuffer * buffer)
buffer);
}
+static GstBuffer *
+find_buffer_from_omx_buffer (GstOMXBufferPool * pool, GstOMXBuffer * omx_buf)
+{
+ guint i;
+
+ for (i = 0; i < pool->buffers->len; i++) {
+ GstBuffer *buf = g_ptr_array_index (pool->buffers, i);
+
+ if (gst_omx_buffer_get_omx_buf (buf) == omx_buf)
+ return buf;
+ }
+
+ return NULL;
+}
+
static GstFlowReturn
gst_omx_buffer_pool_acquire_buffer (GstBufferPool * bpool,
GstBuffer ** buffer, GstBufferPoolAcquireParams * params)
@@ -557,9 +628,23 @@ gst_omx_buffer_pool_acquire_buffer (GstBufferPool * bpool,
}
} else {
/* Acquire any buffer that is available to be filled by upstream */
- ret =
- GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->acquire_buffer
- (bpool, buffer, params);
+ GstOMXBuffer *omx_buf;
+ GstOMXAcquireBufferReturn r;
+ GstOMXWait wait = GST_OMX_WAIT;
+
+ if (params && (params->flags & GST_BUFFER_POOL_ACQUIRE_FLAG_DONTWAIT))
+ wait = GST_OMX_DONT_WAIT;
+
+ r = gst_omx_port_acquire_buffer (pool->port, &omx_buf, wait);
+ if (r == GST_OMX_ACQUIRE_BUFFER_OK) {
+ *buffer = find_buffer_from_omx_buffer (pool, omx_buf);
+ g_return_val_if_fail (*buffer, GST_FLOW_ERROR);
+ return GST_FLOW_OK;
+ } else if (r == GST_OMX_ACQUIRE_BUFFER_FLUSHING) {
+ return GST_FLOW_FLUSHING;
+ } else {
+ return GST_FLOW_ERROR;
+ }
}
return ret;
@@ -574,9 +659,10 @@ gst_omx_buffer_pool_release_buffer (GstBufferPool * bpool, GstBuffer * buffer)
g_assert (pool->component && pool->port);
- if (!pool->allocating && !pool->deactivated) {
+ if (!pool->allocating) {
omx_buf = gst_omx_buffer_get_omx_buf (buffer);
- if (pool->port->port_def.eDir == OMX_DirOutput && !omx_buf->used) {
+ if (pool->port->port_def.eDir == OMX_DirOutput && !omx_buf->used &&
+ !pool->deactivated) {
/* Release back to the port, can be filled again */
err = gst_omx_port_release_buffer (pool->port, omx_buf);
if (err != OMX_ErrorNone) {
@@ -584,24 +670,8 @@ gst_omx_buffer_pool_release_buffer (GstBufferPool * bpool, GstBuffer * buffer)
("Failed to relase output buffer to component: %s (0x%08x)",
gst_omx_error_to_string (err), err));
}
- } else if (!omx_buf->used) {
- /* TODO: Implement.
- *
- * If not used (i.e. was not passed to the component) this should do
- * the same as EmptyBufferDone.
- * If it is used (i.e. was passed to the component) this should do
- * nothing until EmptyBufferDone.
- *
- * EmptyBufferDone should release the buffer to the pool so it can
- * be allocated again
- *
- * Needs something to call back here in EmptyBufferDone, like keeping
- * a ref on the buffer in GstOMXBuffer until EmptyBufferDone... which
- * would ensure that the buffer is always unused when this is called.
- */
- g_assert_not_reached ();
- GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->release_buffer
- (bpool, buffer);
+ } else if (pool->port->port_def.eDir == OMX_DirInput) {
+ g_queue_push_tail (&pool->port->pending_buffers, omx_buf);
}
}
}
@@ -653,6 +723,10 @@ gst_omx_buffer_pool_class_init (GstOMXBufferPoolClass * klass)
gstbufferpool_class->release_buffer = gst_omx_buffer_pool_release_buffer;
GST_DEBUG_CATEGORY_GET (CAT_PERFORMANCE, "GST_PERFORMANCE");
+
+ signals[SIG_ALLOCATE] = g_signal_new ("allocate",
+ G_TYPE_FROM_CLASS (gobject_class), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
+ G_TYPE_BOOLEAN, 0);
}
static void
diff --git a/omx/gstomxvideoenc.c b/omx/gstomxvideoenc.c
index 6da94a7..9aa3a98 100644
--- a/omx/gstomxvideoenc.c
+++ b/omx/gstomxvideoenc.c
@@ -28,6 +28,7 @@
#include <string.h>
+#include "gstomxbufferpool.h"
#include "gstomxvideo.h"
#include "gstomxvideoenc.h"
@@ -917,7 +918,9 @@ gst_omx_video_enc_open (GstVideoEncoder * encoder)
static gboolean
gst_omx_video_enc_deallocate_in_buffers (GstOMXVideoEnc * self)
{
- if (gst_omx_port_deallocate_buffers (self->enc_in_port) != OMX_ErrorNone)
+ /* Pool will take care of deallocating buffers when deactivated upstream */
+ if (!self->in_pool_used
+ && gst_omx_port_deallocate_buffers (self->enc_in_port) != OMX_ErrorNone)
return FALSE;
return TRUE;
@@ -1659,6 +1662,7 @@ gst_omx_video_enc_start (GstVideoEncoder * encoder)
self->last_upstream_ts = 0;
self->downstream_flow_ret = GST_FLOW_OK;
self->nb_downstream_buffers = 0;
+ self->in_pool_used = FALSE;
return TRUE;
}
@@ -2036,40 +2040,66 @@ gst_omx_video_enc_set_to_idle (GstOMXVideoEnc * self)
}
static gboolean
+buffer_is_from_input_pool (GstOMXVideoEnc * self, GstBuffer * buffer)
+{
+ /* Buffer from our input pool will already have a GstOMXBuffer associated
+ * with our input port. */
+ GstOMXBuffer *buf;
+
+ buf = gst_omx_buffer_get_omx_buf (buffer);
+ if (!buf)
+ return FALSE;
+
+ return buf->port == self->enc_in_port;
+}
+
+static gboolean
gst_omx_video_enc_enable (GstOMXVideoEnc * self, GstBuffer * input)
{
GstOMXVideoEncClass *klass;
klass = GST_OMX_VIDEO_ENC_GET_CLASS (self);
- if (!gst_omx_video_enc_configure_input_buffer (self, input))
- return FALSE;
+ /* Is downstream using our buffer pool? */
+ if (buffer_is_from_input_pool (self, input)) {
+ /* We're done allocating as we received the first buffer from upstream */
+ GST_OMX_BUFFER_POOL (input->pool)->allocating = FALSE;
+ self->in_pool_used = TRUE;
+ }
- self->input_allocation = gst_omx_video_enc_pick_input_allocation_mode (self,
- input);
- self->input_dmabuf = FALSE;
+ if (!self->in_pool_used) {
+ if (!gst_omx_video_enc_configure_input_buffer (self, input))
+ return FALSE;
+
+ self->input_allocation = gst_omx_video_enc_pick_input_allocation_mode (self,
+ input);
+ self->input_dmabuf = FALSE;
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
- if (gst_is_dmabuf_memory (gst_buffer_peek_memory (input, 0))) {
- if (self->input_allocation == GST_OMX_BUFFER_ALLOCATION_USE_BUFFER_DYNAMIC) {
- GST_DEBUG_OBJECT (self, "Configure encoder input to import dmabuf");
- gst_omx_port_set_dmabuf (self->enc_in_port, TRUE);
- } else {
- GST_DEBUG_OBJECT (self,
- "Wrong input allocation mode (%d); dynamic buffers are required to use dmabuf import",
- self->input_allocation);
- }
+ if (gst_is_dmabuf_memory (gst_buffer_peek_memory (input, 0))) {
+ if (self->input_allocation ==
+ GST_OMX_BUFFER_ALLOCATION_USE_BUFFER_DYNAMIC) {
+ GST_DEBUG_OBJECT (self, "Configure encoder input to import dmabuf");
+ gst_omx_port_set_dmabuf (self->enc_in_port, TRUE);
+ } else {
+ GST_DEBUG_OBJECT (self,
+ "Wrong input allocation mode (%d); dynamic buffers are required to use dmabuf import",
+ self->input_allocation);
+ }
- self->input_dmabuf = TRUE;
- }
+ self->input_dmabuf = TRUE;
+ }
#endif
+ }
GST_DEBUG_OBJECT (self, "Enabling component");
- if (!gst_omx_video_enc_ensure_nb_in_buffers (self))
- return FALSE;
- if (!gst_omx_video_enc_ensure_nb_out_buffers (self))
- return FALSE;
+ if (!self->in_pool_used) {
+ if (!gst_omx_video_enc_ensure_nb_in_buffers (self))
+ return FALSE;
+ if (!gst_omx_video_enc_ensure_nb_out_buffers (self))
+ return FALSE;
+ }
if (self->disabled) {
if (gst_omx_port_set_enabled (self->enc_in_port, TRUE) != OMX_ErrorNone)
@@ -2094,8 +2124,11 @@ gst_omx_video_enc_enable (GstOMXVideoEnc * self, GstBuffer * input)
if (gst_omx_port_mark_reconfigured (self->enc_in_port) != OMX_ErrorNone)
return FALSE;
} else {
- if (!gst_omx_video_enc_set_to_idle (self))
- return FALSE;
+ /* If the input pool is active we already allocated buffers and set the component to Idle. */
+ if (!self->in_pool_used) {
+ if (!gst_omx_video_enc_set_to_idle (self))
+ return FALSE;
+ }
if (gst_omx_component_set_state (self->enc,
OMX_StateExecuting) != OMX_ErrorNone)
@@ -2668,12 +2701,32 @@ gst_omx_video_enc_handle_frame (GstVideoEncoder * encoder,
while (acq_ret != GST_OMX_ACQUIRE_BUFFER_OK) {
GstClockTime timestamp, duration;
+ gboolean fill_buffer = TRUE;
/* Make sure to release the base class stream lock, otherwise
* _loop() can't call _finish_frame() and we might block forever
* because no input buffers are released */
GST_VIDEO_ENCODER_STREAM_UNLOCK (self);
- acq_ret = gst_omx_port_acquire_buffer (port, &buf, GST_OMX_WAIT);
+
+ if (buffer_is_from_input_pool (self, frame->input_buffer)) {
+ /* Receiving a buffer from our input pool */
+ buf = gst_omx_buffer_get_omx_buf (frame->input_buffer);
+
+ GST_LOG_OBJECT (self,
+ "Input buffer %p already has a OMX buffer associated: %p",
+ frame->input_buffer, buf);
+
+ g_assert (!buf->input_buffer);
+ /* Prevent the buffer to be released to the pool while it's being
+ * processed by OMX. The reference will be dropped in EmptyBufferDone() */
+ buf->input_buffer = gst_buffer_ref (frame->input_buffer);
+
+ acq_ret = GST_OMX_ACQUIRE_BUFFER_OK;
+ fill_buffer = FALSE;
+ buf->omx_buf->nFilledLen = gst_buffer_get_size (frame->input_buffer);
+ } else {
+ acq_ret = gst_omx_port_acquire_buffer (port, &buf, GST_OMX_WAIT);
+ }
if (acq_ret == GST_OMX_ACQUIRE_BUFFER_ERROR) {
GST_VIDEO_ENCODER_STREAM_LOCK (self);
@@ -2789,7 +2842,8 @@ gst_omx_video_enc_handle_frame (GstVideoEncoder * encoder,
/* Copy the buffer content in chunks of size as requested
* by the port */
- if (!gst_omx_video_enc_fill_buffer (self, frame->input_buffer, buf)) {
+ if (fill_buffer
+ && !gst_omx_video_enc_fill_buffer (self, frame->input_buffer, buf)) {
gst_omx_port_release_buffer (port, buf);
goto buffer_fill_error;
}
@@ -2968,6 +3022,71 @@ gst_omx_video_enc_drain (GstOMXVideoEnc * self)
return GST_FLOW_OK;
}
+#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
+static gboolean
+pool_request_allocate_cb (GstBufferPool * pool, GstOMXVideoEnc * self)
+{
+ GstStructure *config;
+ guint min;
+
+ gst_omx_port_set_dmabuf (self->enc_in_port, TRUE);
+
+ config = gst_buffer_pool_get_config (pool);
+
+ if (!gst_buffer_pool_config_get_params (config, NULL, NULL, &min, NULL)) {
+ gst_structure_free (config);
+ return FALSE;
+ }
+ gst_structure_free (config);
+
+ GST_DEBUG_OBJECT (self,
+ "input pool configured for %d buffers, adjust nBufferCountActual", min);
+
+ if (!gst_omx_port_update_buffer_count_actual (self->enc_in_port, min))
+ return FALSE;
+
+ if (!gst_omx_video_enc_set_to_idle (self))
+ return FALSE;
+
+ self->input_allocation = GST_OMX_BUFFER_ALLOCATION_ALLOCATE_BUFFER;
+ self->input_dmabuf = TRUE;
+
+ /* gst_omx_port_acquire_buffer() will fail if the input port is stil flushing
+ * which will prevent upstream from acquiring buffers. */
+ gst_omx_port_set_flushing (self->enc_in_port, 5 * GST_SECOND, FALSE);
+
+ return TRUE;
+}
+
+static GstBufferPool *
+create_input_pool (GstOMXVideoEnc * self, GstCaps * caps, guint num_buffers)
+{
+ GstBufferPool *pool;
+ GstStructure *config;
+
+ pool =
+ gst_omx_buffer_pool_new (GST_ELEMENT_CAST (self), self->enc,
+ self->enc_in_port, GST_OMX_BUFFER_MODE_DMABUF);
+ GST_OMX_BUFFER_POOL (pool)->allocating = TRUE;
+
+ g_signal_connect_object (pool, "allocate",
+ G_CALLBACK (pool_request_allocate_cb), self, 0);
+
+ config = gst_buffer_pool_get_config (pool);
+
+ gst_buffer_pool_config_set_params (config, caps,
+ self->enc_in_port->port_def.nBufferSize, num_buffers, 0);
+
+ if (!gst_buffer_pool_set_config (pool, config)) {
+ GST_INFO_OBJECT (self, "Failed to set config on input pool");
+ gst_object_unref (pool);
+ return NULL;
+ }
+
+ return pool;
+}
+#endif
+
static gboolean
gst_omx_video_enc_propose_allocation (GstVideoEncoder * encoder,
GstQuery * query)
@@ -2976,6 +3095,7 @@ gst_omx_video_enc_propose_allocation (GstVideoEncoder * encoder,
guint num_buffers;
GstCaps *caps;
GstVideoInfo info;
+ GstBufferPool *pool = NULL;
gst_query_parse_allocation (query, &caps, NULL);
@@ -2992,10 +3112,25 @@ gst_omx_video_enc_propose_allocation (GstVideoEncoder * encoder,
gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
num_buffers = self->enc_in_port->port_def.nBufferCountMin + 1;
+
+#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
+ /* dmabuf export is currently only supported on Zynqultrascaleplus */
+ pool = create_input_pool (self, caps, num_buffers);
+ if (!pool) {
+ GST_WARNING_OBJECT (self, "Failed to create and configure pool");
+ return FALSE;
+ }
+#endif
+
GST_DEBUG_OBJECT (self,
"request at least %d buffers of size %" G_GSIZE_FORMAT, num_buffers,
info.size);
- gst_query_add_allocation_pool (query, NULL, info.size, num_buffers, 0);
+ gst_query_add_allocation_pool (query, pool,
+ self->enc_in_port->port_def.nBufferSize, num_buffers, 0);
+
+ self->in_pool_used = FALSE;
+
+ g_clear_object (&pool);
return
GST_VIDEO_ENCODER_CLASS
diff --git a/omx/gstomxvideoenc.h b/omx/gstomxvideoenc.h
index 370b290..c84e62a 100644
--- a/omx/gstomxvideoenc.h
+++ b/omx/gstomxvideoenc.h
@@ -104,6 +104,9 @@ struct _GstOMXVideoEnc
/* Number of buffers requested downstream */
guint nb_downstream_buffers;
+ /* TRUE if input buffers are from the pool we proposed to upstream */
+ gboolean in_pool_used;
+
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
GEnumClass *alg_roi_quality_enum_class;
#endif