#endif
#include <gst/gst.h>
+#include <gst/allocators/gstdmabuf.h>
#include <string.h>
#include "gstomx.h"
if (buffer->input_frame_mapped) {
g_assert (!buffer->input_mem);
g_assert (!buffer->input_buffer);
+ g_assert (!buffer->input_buffer_mapped);
gst_video_frame_unmap (&buffer->input_frame);
buffer->input_frame_mapped = FALSE;
} else if (buffer->input_mem) {
g_assert (!buffer->input_buffer);
+ g_assert (!buffer->input_buffer_mapped);
gst_memory_unmap (buffer->input_mem, &buffer->map);
g_clear_pointer (&buffer->input_mem, gst_memory_unref);
} else if (buffer->input_buffer) {
- gst_buffer_unmap (buffer->input_buffer, &buffer->map);
+ if (buffer->input_buffer_mapped)
+ gst_buffer_unmap (buffer->input_buffer, &buffer->map);
+ buffer->input_buffer_mapped = FALSE;
g_clear_pointer (&buffer->input_buffer, gst_buffer_unref);
}
}
g_return_val_if_fail (!buffer->input_frame_mapped, FALSE);
g_return_val_if_fail (!buffer->input_mem, FALSE);
g_return_val_if_fail (!buffer->input_buffer, FALSE);
+ g_return_val_if_fail (!buffer->input_buffer_mapped, FALSE);
if (!gst_video_frame_map (&buffer->input_frame, info, input, GST_MAP_READ))
return FALSE;
g_return_val_if_fail (!buffer->input_frame_mapped, FALSE);
g_return_val_if_fail (!buffer->input_mem, FALSE);
g_return_val_if_fail (!buffer->input_buffer, FALSE);
+ g_return_val_if_fail (!buffer->input_buffer_mapped, FALSE);
if (!gst_memory_map (mem, &buffer->map, GST_MAP_READ))
return FALSE;
}
gboolean
+gst_omx_buffer_import_fd (GstOMXBuffer * buffer, GstBuffer * input)
+{
+ gint fd;
+ GstMemory *mem;
+
+ g_return_val_if_fail (buffer != NULL, FALSE);
+ g_return_val_if_fail (input != NULL, FALSE);
+ g_return_val_if_fail (!buffer->input_frame_mapped, FALSE);
+ g_return_val_if_fail (!buffer->input_mem, FALSE);
+ g_return_val_if_fail (!buffer->input_buffer, FALSE);
+ g_return_val_if_fail (!buffer->input_buffer_mapped, FALSE);
+
+ mem = gst_buffer_peek_memory (input, 0);
+ g_return_val_if_fail (gst_is_dmabuf_memory (mem), FALSE);
+
+ fd = gst_dmabuf_memory_get_fd (mem);
+
+ buffer->input_buffer = gst_buffer_ref (input);
+ buffer->omx_buf->pBuffer = GUINT_TO_POINTER (fd);
+ buffer->omx_buf->nAllocLen = gst_memory_get_sizes (mem, NULL, NULL);
+ buffer->omx_buf->nFilledLen = buffer->omx_buf->nAllocLen;
+
+ return TRUE;
+}
+
+gboolean
gst_omx_buffer_map_buffer (GstOMXBuffer * buffer, GstBuffer * input)
{
g_return_val_if_fail (buffer != NULL, FALSE);
g_return_val_if_fail (!buffer->input_frame_mapped, FALSE);
g_return_val_if_fail (!buffer->input_mem, FALSE);
g_return_val_if_fail (!buffer->input_buffer, FALSE);
+ g_return_val_if_fail (!buffer->input_buffer_mapped, FALSE);
if (!gst_buffer_map (input, &buffer->map, GST_MAP_READ))
return FALSE;
+ buffer->input_buffer_mapped = TRUE;
buffer->input_buffer = gst_buffer_ref (input);
buffer->omx_buf->pBuffer = buffer->map.data;
buffer->omx_buf->nAllocLen = buffer->map.size;
gboolean input_frame_mapped; /* TRUE if input_frame is valid */
GstMemory *input_mem;
GstBuffer *input_buffer;
+ gboolean input_buffer_mapped;
GstMapInfo map;
};
gboolean gst_omx_buffer_map_frame (GstOMXBuffer * buffer, GstBuffer * input, GstVideoInfo * info);
gboolean gst_omx_buffer_map_memory (GstOMXBuffer * buffer, GstMemory * mem);
gboolean gst_omx_buffer_map_buffer (GstOMXBuffer * buffer, GstBuffer * input);
+gboolean gst_omx_buffer_import_fd (GstOMXBuffer * buffer, GstBuffer * input);
void gst_omx_set_default_role (GstOMXClassData *class_data, const gchar *default_role);
#include <gst/gst.h>
#include <gst/video/gstvideometa.h>
+#include <gst/allocators/gstdmabuf.h>
+
#include <string.h>
#include "gstomxvideo.h"
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) {
+ OMX_ALG_PORT_PARAM_BUFFER_MODE buffer_mode;
+ OMX_ERRORTYPE err;
+
+ GST_OMX_INIT_STRUCT (&buffer_mode);
+ buffer_mode.nPortIndex = self->enc_in_port->index;
+ buffer_mode.eMode = OMX_ALG_BUF_DMA;
+
+ GST_DEBUG_OBJECT (self, "Configure encoder to import dmabuf");
+
+ err =
+ gst_omx_component_set_parameter (self->enc,
+ (OMX_INDEXTYPE) OMX_ALG_IndexPortParamBufferMode, &buffer_mode);
+ if (err != OMX_ErrorNone)
+ GST_WARNING_OBJECT (self,
+ "Failed to set output buffer mode: %s (0x%08x)",
+ gst_omx_error_to_string (err), err);
+ } 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;
+ }
+#endif
GST_DEBUG_OBJECT (self, "Enabling component");
if (self->disabled) {
return FALSE;
}
- /* Map and keep a ref on the buffer while it's being processed
- * by the OMX component. */
- if (!gst_omx_buffer_map_frame (outbuf, inbuf, info)) {
- GST_ELEMENT_ERROR (self, STREAM, FORMAT, (NULL),
- ("failed to map input buffer"));
- return FALSE;
- }
+ if (!self->input_dmabuf) {
+ /* Map and keep a ref on the buffer while it's being processed
+ * by the OMX component. */
+ if (!gst_omx_buffer_map_frame (outbuf, inbuf, info)) {
+ GST_ELEMENT_ERROR (self, STREAM, FORMAT, (NULL),
+ ("failed to map input buffer"));
+ return FALSE;
+ }
- if (!check_input_alignment (self, &outbuf->input_frame.map[0])) {
- GST_ELEMENT_ERROR (self, STREAM, FORMAT, (NULL),
- ("input buffer now has wrong alignment/stride, can't use dynamic allocation any more"));
- return FALSE;
- }
+ if (!check_input_alignment (self, &outbuf->input_frame.map[0])) {
+ GST_ELEMENT_ERROR (self, STREAM, FORMAT, (NULL),
+ ("input buffer now has wrong alignment/stride, can't use dynamic allocation any more"));
+ return FALSE;
+ }
- GST_LOG_OBJECT (self, "Transfer buffer of %" G_GSIZE_FORMAT " bytes",
- gst_buffer_get_size (inbuf));
+ GST_LOG_OBJECT (self, "Transfer buffer of %" G_GSIZE_FORMAT " bytes",
+ gst_buffer_get_size (inbuf));
+ } else {
+ /* dmabuf input */
+ if (!gst_omx_buffer_import_fd (outbuf, inbuf)) {
+ GST_ELEMENT_ERROR (self, STREAM, FORMAT, (NULL),
+ ("failed to import dmabuf"));
+ return FALSE;
+ }
+
+ GST_LOG_OBJECT (self, "Import dmabuf of %" G_GSIZE_FORMAT " bytes",
+ gst_buffer_get_size (inbuf));
+ }
ret = TRUE;
goto done;
GstFlowReturn downstream_flow_ret;
GstOMXBufferAllocation input_allocation;
+ /* TRUE if encoder is passing dmabuf's fd directly to the OMX component */
+ gboolean input_dmabuf;
};
struct _GstOMXVideoEncClass