-SUBDIRS = bellagio rpi
+EXTRA_DIST = gstomx.conf
+
+if USE_OMX_TARGET_ODROID
+configdir = $(sysconfdir)/xdg
+config_DATA = gstomx.conf
+endif
--- /dev/null
+[omxmpeg4videodec]
+type-name=GstOMXMPEG4VideoDec
+core-name=/usr/lib/libExynosOMX_Core.so
+component-name=OMX.Exynos.MPEG4.Decoder
+rank=256
+in-port-index=0
+out-port-index=1
+hacks=no-component-role
+
+[omxh263dec]
+type-name=GstOMXH263Dec
+core-name=/usr/lib/libExynosOMX_Core.so
+component-name=OMX.Exynos.H263.Decoder
+rank=256
+in-port-index=0
+out-port-index=1
+hacks=no-component-role
+
+[omxh264dec]
+type-name=GstOMXH264Dec
+core-name=/usr/lib/libExynosOMX_Core.so
+component-name=OMX.Exynos.AVC.Decoder
+rank=257
+in-port-index=0
+out-port-index=1
+hacks=no-component-role
+
+[omxvc1dec]
+type-name=GstOMXWMVDec
+core-name=/usr/lib/libExynosOMX_Core.so
+component-name=OMX.Exynos.WMV.Decoder
+rank=256
+in-port-index=0
+out-port-index=1
+hacks=no-component-role
+sink-template-caps=video/x-wmv,wmvversion=(int)3,format=(string){WMV3,WVC1},width=(int)[1,MAX],height=(int)[1,MAX]
+
+[omxh264enc]
+type-name=GstOMXH264Enc
+core-name=/usr/lib/libExynosOMX_Core.so
+component-name=OMX.Exynos.AVC.Encoder
+rank=257
+in-port-index=0
+out-port-index=1
+hacks=no-component-role
+
+[omxmpeg4enc]
+type-name=GstOMXMPEG4VideoEnc
+core-name=/usr/lib/libExynosOMX_Core.so
+component-name=OMX.Exynos.MPEG4.Encoder
+rank=254
+in-port-index=0
+out-port-index=1
+hacks=no-component-role
+
+[omxih263enc]
+type-name=GstOMXH263Enc
+core-name=/usr/lib/libExynosOMX_Core.so
+component-name=OMX.Exynos.H263.Encoder
+rank=254
+in-port-index=0
+out-port-index=1
+hacks=no-component-role
$(OMX_INCLUDEPATH) \
$(GST_PLUGINS_BASE_CFLAGS) \
$(GST_BASE_CFLAGS) \
- $(GST_CFLAGS)
+ $(GST_CFLAGS) \
+ $(TBM_CFLAGS) \
+ $(X11_CFLAGS) \
+ $(DRI2_CFLAGS) \
+ $(DRM_SLP_CFLAGS) \
+ $(XFIXES_CFLAGS)
libgstomx_la_LIBADD = \
$(GST_PLUGINS_BASE_LIBS) \
-lgstaudio-@GST_API_VERSION@ \
-lgstpbutils-@GST_API_VERSION@ \
-lgstvideo-@GST_API_VERSION@ \
$(GST_BASE_LIBS) \
- $(GST_LIBS)
-libgstomx_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
+ $(GST_LIBS) \
+ $(TBM_LIBS) \
+ $(X11_LIBS) \
+ $(DRI2_LIBS) \
+ $(DRM_SLP_LIBS) \
+ $(XFIXES_LIBS)
+libgstomx_la_LDFLAGS = \
+ $(GST_PLUGIN_LDFLAGS) \
+ $(TBM_LDFLAGS) \
+ $(X11_LDFLAGS) \
+ $(DRI2_LDFLAGS) \
+ $(DRM_SLP_LDFLAGS) \
+ $(XFIXES_LDFLAGS)
+
EXTRA_DIST = \
openmax \
G_LOCK_DEFINE_STATIC (core_handles);
static GHashTable *core_handles;
+
+
GstOMXCore *
gst_omx_core_acquire (const gchar * filename)
{
#ifdef USE_OMX_TARGET_RPI
{
#else
+#ifdef USE_OMX_TARGET_ODROID
+ if (g_str_has_suffix (filename, "usr/lib/libExynosOMX_Core.so")) {
+#else
if (g_str_has_suffix (filename, "vc/lib/libopenmaxil.so")) {
#endif
+#endif
gchar *bcm_host_filename;
gchar *bcm_host_path;
GModule *bcm_host_module;
OMX_U32 index = msg->content.port_settings_changed.port;
GList *outports = NULL, *l, *k;
- GST_DEBUG_OBJECT (comp->parent, "%s settings changed (port %u)",
+ GST_ERROR_OBJECT (comp->parent, "%s settings changed (port %u)",
comp->name, index);
/* FIXME: This probably can be done better */
GstOMXMessage *msg;
/* Yes, this really happens... */
- if (nData1 == OMX_ErrorNone)
+ if (nData2 == OMX_ErrorNone)
break;
msg = g_slice_new (GstOMXMessage);
buf->used = TRUE;
if (port->port_def.eDir == OMX_DirInput) {
+ GST_LOG_OBJECT (comp->parent,"\n[SRI-D] Calling OMX_EmptyThisBuffer. BufHeader:[%p]\n",buf->omx_buf);
err = OMX_EmptyThisBuffer (comp->handle, buf->omx_buf);
} else {
+ GST_ERROR_OBJECT (comp->parent,"\n[SRI-D] Calling OMX_FillThisBuffer. BufHeader:[%p]\n",buf->omx_buf);
err = OMX_FillThisBuffer (comp->handle, buf->omx_buf);
}
GST_DEBUG_OBJECT (comp->parent, "Released buffer %p to %s port %u: %s "
buf->port = port;
buf->used = FALSE;
buf->settings_cookie = port->settings_cookie;
+
+#ifdef USE_TBM
+ buf->scmn_buffer = (SCMN_IMGB*) l->data;
+#endif
+
g_ptr_array_add (port->buffers, buf);
if (buffers) {
+#ifdef USE_TBM
+ if(port->index == 0)
+ err =
+ OMX_UseBuffer (comp->handle, &buf->omx_buf, port->index, buf,
+ port->port_def.nBufferSize, buf->scmn_buffer->a[0]);
+ else
+#endif
err =
OMX_UseBuffer (comp->handle, &buf->omx_buf, port->index, buf,
port->port_def.nBufferSize, l->data);
g_assert (buf->omx_buf->pAppPrivate == buf);
/* In the beginning all buffers are not owned by the component */
+ GST_DEBUG_OBJECT (comp->parent, "[SRI-D]: Pushing pending_buffers, port:[%d], Buffer:[%p]",
+ port->index, buf);
g_queue_push_tail (&port->pending_buffers, buf);
+
if (buffers || images)
l = l->next;
}
return err;
}
+#ifdef USE_TBM
+/* NOTE: Uses comp->lock and comp->messages_lock */
+OMX_ERRORTYPE
+gst_omx_port_tbm_allocate_dec_buffers (tbm_bufmgr bufMgr, GstOMXPort * port)
+{
+ OMX_ERRORTYPE err = OMX_ErrorNone;
+ guint n = 0;
+ GList *buffers = NULL;
+ SCMN_IMGB *ptr = NULL;
+ int y_size = 0;
+ int uv_size = 0;
+
+ g_return_val_if_fail (port != NULL, OMX_ErrorUndefined);
+
+ g_mutex_lock (&port->comp->lock);
+
+ //GST_ERROR_OBJECT (port->comp->parent, "\n[SRI-D]: %s : 1",__func__);
+ n = port->port_def.nBufferCountActual;
+
+ for(int i = 0; i < n; i++) {
+ //GST_ERROR_OBJECT (port->comp->parent, "\n[SRI-D]: %s : 2",__func__);
+ ptr = (SCMN_IMGB*) malloc(sizeof(SCMN_IMGB));
+ //GST_ERROR_OBJECT (port->comp->parent, "\n[SRI-D]: %s : 3",__func__);
+ memset(ptr,0,sizeof(SCMN_IMGB));
+ //GST_ERROR_OBJECT (port->comp->parent, "\n[SRI-D]: %s : 4",__func__);
+ if(port->index == 0) {
+
+ ptr->bo[0] = gst_omx_tbm_allocate_bo(bufMgr, port->port_def.nBufferSize);
+ ptr->fd[0] = gst_omx_tbm_get_bo_fd(ptr->bo[0]);
+ ptr->a[0] = gst_omx_tbm_get_bo_ptr(ptr->bo[0]);
+ }
+ else { /* output port */
+
+ y_size = calc_plane(port->port_def.format.video.nFrameWidth,port->port_def.format.video.nFrameHeight);
+ ptr->bo[0] = gst_omx_tbm_allocate_bo(bufMgr, y_size);
+ ptr->fd[0] = gst_omx_tbm_get_bo_fd(ptr->bo[0]);
+ ptr->a[0] = gst_omx_tbm_get_bo_ptr(ptr->bo[0]);
+
+ uv_size = calc_plane(port->port_def.format.video.nFrameWidth,port->port_def.format.video.nFrameHeight >> 1);
+ ptr->bo[1] = gst_omx_tbm_allocate_bo(bufMgr, uv_size);
+ ptr->fd[1] = gst_omx_tbm_get_bo_fd(ptr->bo[1]);
+ ptr->a[1] = gst_omx_tbm_get_bo_ptr(ptr->bo[1]);
+
+ ptr->y_size = y_size;
+ ptr->uv_size = uv_size;
+ ptr->buf_share_method = BUF_SHARE_METHOD_FD;
+
+// GST_ERROR_OBJECT(self, "\n[SRI-D] Buffer count: [%d] Video width:[%d],Video Height:[%d]",port->port_def.nBufferCountActual,
+ }
+ //GST_ERROR_OBJECT (port->comp->parent, "\n[SRI-D]: %s : 5",__func__);
+ buffers = g_list_append(buffers,(gpointer)ptr);
+ //GST_ERROR_OBJECT (port->comp->parent, "\n[SRI-D]: %s : 6",__func__);
+ }
+
+ n = g_list_length ((GList *) buffers);
+ err = gst_omx_port_allocate_buffers_unlocked (port, buffers, NULL, n);
+ g_mutex_unlock (&port->comp->lock);
+
+ return err;
+}
+
+#endif
/* NOTE: Uses comp->lock and comp->messages_lock */
OMX_ERRORTYPE
gst_omx_port_use_buffers (GstOMXPort * port, const GList * buffers)
"port %u", buf, comp->name, port->index);
}
+#ifdef USE_TBM
+ /* deallocate tbm buffers */
+ if(buf->scmn_buffer != NULL) {
+
+ gst_omx_tbm_deallocate_bo(buf->scmn_buffer->bo[0]);
+ if(port->index == 1) /* output port */
+ gst_omx_tbm_deallocate_bo(buf->scmn_buffer->bo[1]);
+ }
+#endif
/* omx_buf can be NULL if allocation failed earlier
* and we're just shutting down
*
* valid anymore after the buffer was consumed
*/
buf->omx_buf->nFlags = 0;
-
+ GST_ERROR_OBJECT(comp->parent,"Calling OMX_FillThisBuffer. buffer[%p]. function:[%s]",buf->omx_buf,__func__);
err = OMX_FillThisBuffer (comp->handle, buf->omx_buf);
if (err != OMX_ErrorNone) {
class_data->component_role = default_role;
}
+#ifdef USE_TBM
+
+int
+calc_plane(int width, int height)
+{
+ int mbX, mbY;
+
+ mbX = ALIGN(width, S5P_FIMV_NV12MT_HALIGN);
+ mbY = ALIGN(height, S5P_FIMV_NV12MT_VALIGN);
+
+ return ALIGN(mbX * mbY, S5P_FIMV_DEC_BUF_ALIGN);
+}
+
+int
+calc_yplane(int width, int height)
+{
+ int mbX, mbY;
+
+ mbX = ALIGN(width + 24, S5P_FIMV_NV12MT_HALIGN);
+ mbY = ALIGN(height + 16, S5P_FIMV_NV12MT_VALIGN);
+
+ return ALIGN(mbX * mbY, S5P_FIMV_DEC_BUF_ALIGN);
+}
+
+int
+calc_uvplane(int width, int height)
+{
+ int mbX, mbY;
+
+ mbX = ALIGN(width + 16, S5P_FIMV_NV12MT_HALIGN);
+ mbY = ALIGN(height + 4, S5P_FIMV_NV12MT_VALIGN);
+
+ return ALIGN(mbX * mbY, S5P_FIMV_DEC_BUF_ALIGN);
+}
+
+tbm_bo
+gst_omx_tbm_allocate_bo(tbm_bufmgr hBufmgr, int size)
+{
+ return tbm_bo_alloc(hBufmgr,size, TBM_BO_WC);
+}
+
+void
+gst_omx_tbm_deallocate_bo(tbm_bo bo)
+{
+ tbm_bo_unmap(bo);
+ tbm_bo_unref(bo);
+}
+
+OMX_U32
+gst_omx_tbm_get_bo_fd(tbm_bo bo)
+{
+ tbm_bo_handle TBMBoHandle;
+ TBMBoHandle = tbm_bo_get_handle(bo, TBM_DEVICE_MM);
+ if(TBMBoHandle.ptr != NULL)
+ return TBMBoHandle.u32;
+ return 0;
+}
+
+OMX_PTR
+gst_omx_tbm_get_bo_ptr(tbm_bo bo)
+{
+ tbm_bo_handle TBMBoHandle;
+ TBMBoHandle = tbm_bo_map(bo, TBM_DEVICE_CPU,TBM_OPTION_WRITE);
+ if(TBMBoHandle.ptr != NULL)
+ return TBMBoHandle.ptr;
+ return NULL;
+}
+
+#endif
+
static void
_class_init (gpointer g_class, gpointer data)
{
#include <OMX_Core.h>
#include <OMX_Component.h>
+#include <tbm_type.h>
+#include <tbm_surface.h>
+#include <tbm_bufmgr.h>
#ifdef GST_OMX_STRUCT_PACKING
#pragma pack()
#endif
typedef struct _GstOMXClassData GstOMXClassData;
typedef struct _GstOMXMessage GstOMXMessage;
+/* MODIFICATION */
+typedef enum GOmxVendor GOmxVendor; /* check omx vender */
+
+/* using common scmn_imgb format */
+#define SCMN_IMGB_MAX_PLANE (4) /* max channel count */
+
+/* image buffer definition
+ +------------------------------------------+ ---
+ | | ^
+ | a[], p[] | |
+ | +---------------------------+ --- | |
+ | | | ^ | |
+ | |<---------- w[] ---------->| | | |
+ | | | | | |
+ | | | |
+ | | | h[] | e[]
+ | | | |
+ | | | | | |
+ | | | | | |
+ | | | v | |
+ | +---------------------------+ --- | |
+ | | v
+ +------------------------------------------+ ---
+
+ |<----------------- s[] ------------------>|
+*/
+
+typedef struct
+{
+ int w[SCMN_IMGB_MAX_PLANE]; /* width of each image plane */
+ int h[SCMN_IMGB_MAX_PLANE]; /* height of each image plane */
+ int s[SCMN_IMGB_MAX_PLANE]; /* stride of each image plane */
+ int e[SCMN_IMGB_MAX_PLANE]; /* elevation of each image plane */
+ void * a[SCMN_IMGB_MAX_PLANE]; /* user space address of each image plane */
+ void * p[SCMN_IMGB_MAX_PLANE]; /* physical address of each image plane, if needs */
+ int cs; /* color space type of image */
+ int x; /* left postion, if needs */
+ int y; /* top position, if needs */
+ int __dummy2; /* to align memory */
+ int data[16]; /* arbitrary data */
+
+ int fd[SCMN_IMGB_MAX_PLANE]; /* DMABUF fd of each image plane */
+ int buf_share_method;
+
+ int y_size; /* Y plane size in case of ST12 */
+ int uv_size; /* UV plane size in case of ST12 */
+ //void *bo[SCMN_IMGB_MAX_PLANE]; /* Tizen buffer object of each image plane */
+ tbm_bo bo[SCMN_IMGB_MAX_PLANE];
+
+ void *jpeg_data; /* JPEG data */
+ int jpeg_size; /* JPEG size */
+
+ int tz_enable; /* tzmem buffer */
+} SCMN_IMGB;
+
+#ifdef USE_TBM
+
+#define MFC_INPUT_BUFFER_PLANE 1
+#define MFC_OUTPUT_BUFFER_PLANE 2
+
+#define MAX_INPUT_BUFFER 16
+#define MAX_OUTPUT_BUFFER 16
+
+typedef struct _TBMBuffer TBMBuffer;
+typedef struct _TBMInputBuffer TBMInputBuffer;
+typedef struct _TBMOutputBuffer TBMOutputBuffer;
+
+struct _TBMBuffer
+{
+ OMX_U32 mBufFD;
+ tbm_bo mBo;
+ OMX_PTR mPtr;
+ OMX_U32 nAllocLen;
+};
+
+struct _TBMInputBuffer
+{
+ struct _TBMBuffer tbmBuffer[MAX_INPUT_BUFFER];
+ OMX_U32 allocatedCount;
+ GList *buffers;
+};
+
+struct _TBMOutputBuffer
+{
+ SCMN_IMGB *tbmBuffer[MAX_OUTPUT_BUFFER];
+ OMX_U32 allocatedCount;
+ GList *buffers;
+};
+
+typedef struct EnableGemBuffersParams EnableGemBuffersParams;
+
+struct EnableGemBuffersParams
+{
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL enable;
+};
+
+
+#endif
+
+enum
+{
+ BUF_SHARE_METHOD_PADDR = 0,
+ BUF_SHARE_METHOD_FD = 1,
+ BUF_SHARE_METHOD_TIZEN_BUFFER = 2,
+ BUF_SHARE_METHOD_FLUSH_BUFFER = 3,
+}; /* buf_share_method */
+
+/* Extended color formats */
+enum {
+ OMX_EXT_COLOR_FormatNV12TPhysicalAddress = 0x7F000001, /**< Reserved region for introducing Vendor Extensions */
+ OMX_EXT_COLOR_FormatNV12LPhysicalAddress = 0x7F000002,
+ OMX_EXT_COLOR_FormatNV12Tiled = 0x7FC00002,
+ OMX_EXT_COLOR_FormatNV12TFdValue = 0x7F000012,
+ OMX_EXT_COLOR_FormatNV12LFdValue = 0x7F000013
+};
+
+#ifdef USE_TBM
+/* Extended port settings. */
+enum {
+ OMX_IndexParamEnablePlatformSpecificBuffers = 0x7F000011
+};
+#endif
+
+/* modification: Add_component_vendor */
+enum GOmxVendor
+{
+ GOMX_VENDOR_DEFAULT,
+ GOMX_VENDOR_SLSI_SEC,
+ GOMX_VENDOR_SLSI_EXYNOS,
+ GOMX_VENDOR_QCT,
+ GOMX_VENDOR_SPRD
+};
+
typedef enum {
/* Everything good and the buffer is valid */
GST_OMX_ACQUIRE_BUFFER_OK = 0,
GMutex lock;
gint user_count; /* LOCK */
+ /* MODIFICATION */
+ GOmxVendor component_vendor; /* to check omx vender */
+ gboolean secure; /* trust zone */
+
/* OpenMAX core library functions, protected with LOCK */
OMX_ERRORTYPE (*init) (void);
OMX_ERRORTYPE (*deinit) (void);
/* TRUE if this is an EGLImage */
gboolean eglimage;
+
+#ifdef USE_TBM
+ /* SCMN_IMGB array to use TBM buffers */
+ SCMN_IMGB *scmn_buffer;
+#endif
};
struct _GstOMXClassData {
gboolean gst_omx_port_is_flushing (GstOMXPort *port);
OMX_ERRORTYPE gst_omx_port_allocate_buffers (GstOMXPort *port);
+#ifdef USE_TBM
+OMX_ERRORTYPE gst_omx_port_tbm_allocate_dec_buffers (tbm_bufmgr bufMgr, GstOMXPort * port);
+#endif
OMX_ERRORTYPE gst_omx_port_use_buffers (GstOMXPort *port, const GList *buffers);
OMX_ERRORTYPE gst_omx_port_use_eglimages (GstOMXPort *port, const GList *images);
OMX_ERRORTYPE gst_omx_port_deallocate_buffers (GstOMXPort *port);
void gst_omx_set_default_role (GstOMXClassData *class_data, const gchar *default_role);
+#ifdef USE_TBM
+
+/*MFC Buffer alignment macros*/\r
+#define S5P_FIMV_DEC_BUF_ALIGN (8 * 1024)\r
+#define S5P_FIMV_ENC_BUF_ALIGN (8 * 1024)\r
+#define S5P_FIMV_NV12M_HALIGN 16\r
+#define S5P_FIMV_NV12M_LVALIGN 16\r
+#define S5P_FIMV_NV12M_CVALIGN 8\r
+#define S5P_FIMV_NV12MT_HALIGN 128\r
+#define S5P_FIMV_NV12MT_VALIGN 64\r
+#define S5P_FIMV_NV12M_SALIGN 2048\r
+#define S5P_FIMV_NV12MT_SALIGN 8192
+
+#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
+
+int calc_plane(int width, int height);
+int calc_yplane(int width, int height);
+int calc_uvplane(int width, int height);
+
+tbm_bo gst_omx_tbm_allocate_bo(tbm_bufmgr hBufmgr, int size);
+void gst_omx_tbm_deallocate_bo(tbm_bo bo);
+OMX_U32 gst_omx_tbm_get_bo_fd(tbm_bo bo);
+OMX_PTR gst_omx_tbm_get_bo_ptr(tbm_bo bo);
+
+#endif
+
G_END_DECLS
GST_DEBUG_CATEGORY_STATIC (gst_omx_video_dec_debug_category);
#define GST_CAT_DEFAULT gst_omx_video_dec_debug_category
-/* using common scmn_imgb format */
-#define SCMN_IMGB_MAX_PLANE (4) /* max channel count */
-
-/* image buffer definition
- +------------------------------------------+ ---
- | | ^
- | a[], p[] | |
- | +---------------------------+ --- | |
- | | | ^ | |
- | |<---------- w[] ---------->| | | |
- | | | | | |
- | | | |
- | | | h[] | e[]
- | | | |
- | | | | | |
- | | | | | |
- | | | v | |
- | +---------------------------+ --- | |
- | | v
- +------------------------------------------+ ---
-
- |<----------------- s[] ------------------>|
-*/
-
-typedef struct
-{
- int w[SCMN_IMGB_MAX_PLANE]; /* width of each image plane */
- int h[SCMN_IMGB_MAX_PLANE]; /* height of each image plane */
- int s[SCMN_IMGB_MAX_PLANE]; /* stride of each image plane */
- int e[SCMN_IMGB_MAX_PLANE]; /* elevation of each image plane */
- void * a[SCMN_IMGB_MAX_PLANE]; /* user space address of each image plane */
- void * p[SCMN_IMGB_MAX_PLANE]; /* physical address of each image plane, if needs */
- int cs; /* color space type of image */
- int x; /* left postion, if needs */
- int y; /* top position, if needs */
- int __dummy2; /* to align memory */
- int data[16]; /* arbitrary data */
-
- /* dmabuf fd */
- int fd[SCMN_IMGB_MAX_PLANE];
-
- /* flag for buffer share */
- int buf_share_method;
-} SCMN_IMGB;
-
-/* Extended color formats */
-enum {
- OMX_EXT_COLOR_FormatNV12TPhysicalAddress = 0x7F000001, /**< Reserved region for introducing Vendor Extensions */
- OMX_EXT_COLOR_FormatNV12LPhysicalAddress = 0x7F000002,
- OMX_EXT_COLOR_FormatNV12Tiled = 0x7FC00002,
- OMX_EXT_COLOR_FormatNV12TFdValue = 0x7F000012,
- OMX_EXT_COLOR_FormatNV12LFdValue = 0x7F000013
-};
-
typedef struct _GstOMXMemory GstOMXMemory;
typedef struct _GstOMXMemoryAllocator GstOMXMemoryAllocator;
typedef struct _GstOMXMemoryAllocatorClass GstOMXMemoryAllocatorClass;
+
struct _GstOMXMemory
{
GstMemory mem;
GstOMXComponent *component;
GstOMXPort *port;
- /* For handling OpenMAX allocated memory */
GstAllocator *allocator;
/* Set from outside this pool */
g_mutex_init (&self->drain_lock);
g_cond_init (&self->drain_cond);
+
+#ifdef USE_TBM
+ self->hTBMBufMgr = NULL;
+ self->drm_fd = -1;
+#endif
}
static gboolean
if (!self->dec_in_port || !self->dec_out_port)
return FALSE;
+#ifdef USE_TBM
+
+ self->hTBMBufMgr = tbm_bufmgr_init(self->drm_fd);
+ if(self->hTBMBufMgr == NULL){
+ GST_ERROR_OBJECT (self, "TBM initialization failed.");
+ return FALSE;
+ }
+#endif
+
GST_DEBUG_OBJECT (self, "Opened decoder");
return TRUE;
gst_omx_component_get_state (self->dec, 5 * GST_SECOND);
}
+#ifdef USE_TBM
+ /* uninitialize tbm buffer manager */
+ if(self->hTBMBufMgr != NULL){
+ tbm_bufmgr_deinit(self->hTBMBufMgr);
+ self->hTBMBufMgr = NULL;
+ }
+
+ if(self->drm_fd != -1) {
+ GST_DEBUG_OBJECT (self, "close drm fd");
+ close(self->drm_fd);
+ self->drm_fd = -1;
+ }
+#endif
+
return TRUE;
}
}
/* Same strides and everything */
+#if 0 //ENS:a
if (gst_buffer_get_size (outbuf) == inbuf->omx_buf->nFilledLen) {
GstMapInfo map = GST_MAP_INFO_INIT;
ret = TRUE;
goto done;
}
+#endif //ENS:a
/* Different strides */
void *imgb_data = NULL;
out_imgb = (SCMN_IMGB*)(inbuf->omx_buf->pBuffer);
- if (out_imgb->buf_share_method == 1) {
+ if (out_imgb->buf_share_method == BUF_SHARE_METHOD_FD) {
GST_LOG_OBJECT (self, "dec output buf: fd[0]:%d fd[1]:%d fd[2]:%d w[0]:%d h[0]:%d buf_share_method:%d",
out_imgb->fd[0], out_imgb->fd[1], out_imgb->fd[2], out_imgb->w[0], out_imgb->h[0], out_imgb->buf_share_method);
- } else if (out_imgb->buf_share_method == 0) {
+ } else if (out_imgb->buf_share_method == BUF_SHARE_METHOD_PADDR) {
GST_LOG_OBJECT (self, "dec output uses hw addr");
} else {
GST_WARNING_OBJECT (self, "dec output buf has wrong buf_share_method");
imgb_data = imgb_info.data;
gst_memory_unmap(mem_imgb, &imgb_info);
}
- memcpy(imgb_data, out_imgb, sizeof(*out_imgb));
+ memcpy(imgb_data, out_imgb, sizeof(SCMN_IMGB));
ret = TRUE;
break;
}
}
was_enabled = FALSE;
}
-
+#ifdef USE_TBM
+ //GST_ERROR_OBJECT (self, "1. USE_TBM");
+ err = gst_omx_port_tbm_allocate_dec_buffers(self->hTBMBufMgr,port);
+#else
+ //GST_ERROR_OBJECT (self, "1. NOT USE_TBM");
err = gst_omx_port_allocate_buffers (port);
+#endif
if (err != OMX_ErrorNone && min > port->port_def.nBufferCountMin) {
GST_ERROR_OBJECT (self,
"Failed to allocate required number of buffers %d, trying less and copying",
goto done;
}
}
-
+#ifdef USE_TBM
+ //GST_ERROR_OBJECT (self, "2. USE_TBM");
+ err = gst_omx_port_tbm_allocate_dec_buffers(self->hTBMBufMgr,port);
+#else
+ //GST_ERROR_OBJECT (self, "2. NOT USE_TBM");
err = gst_omx_port_allocate_buffers (port);
-
+#endif
/* Can't provide buffers downstream in this case */
gst_caps_replace (&caps, NULL);
}
switch (port_def.format.video.eColorFormat) {
case OMX_COLOR_FormatYUV420Planar:
case OMX_COLOR_FormatYUV420PackedPlanar:
- GST_DEBUG_OBJECT (self, "Output is I420 (%d)",
+ GST_ERROR_OBJECT (self, "Output is I420 (%d)",
port_def.format.video.eColorFormat);
format = GST_VIDEO_FORMAT_I420;
break;
case OMX_COLOR_FormatYUV420SemiPlanar:
- GST_DEBUG_OBJECT (self, "Output is NV12 (%d)",
+ GST_ERROR_OBJECT (self, "Output is NV12 (%d)",
port_def.format.video.eColorFormat);
format = GST_VIDEO_FORMAT_NV12;
break;
case OMX_EXT_COLOR_FormatNV12TPhysicalAddress:
- GST_DEBUG_OBJECT (self, "Output is ST12 (%d)",
+ GST_ERROR_OBJECT (self, "Output is ST12 (%d)",
port_def.format.video.eColorFormat);
format = GST_VIDEO_FORMAT_ST12;
break;
}
GST_DEBUG_OBJECT (self,
- "Setting output state: format %s, width %d, height %d",
+ "Setting output state: format %s, width %lu, height %lu",
gst_video_format_to_string (format),
port_def.format.video.nFrameWidth, port_def.format.video.nFrameHeight);
* is called at the wrong time
*/
if (gst_omx_port_is_flushing (self->dec_out_port)) {
- GST_DEBUG_OBJECT (self, "Flushing");
+ GST_ERROR_OBJECT (self, "Flushing");
gst_omx_port_release_buffer (self->dec_out_port, buf);
goto flushing;
}
- GST_DEBUG_OBJECT (self, "Handling buffer: 0x%08x %lu",
- buf->omx_buf->nFlags, buf->omx_buf->nTimeStamp);
+ GST_DEBUG_OBJECT (self, "Handling buffer: 0x%08lx %" G_GUINT64_FORMAT,
+ buf->omx_buf->nFlags, (guint64) buf->omx_buf->nTimeStamp);
GST_VIDEO_DECODER_STREAM_LOCK (self);
frame = _find_nearest_frame (self, buf);
m->format = GST_VIDEO_FORMAT_I420;
m->type = param.eColorFormat;
negotiation_map = g_list_append (negotiation_map, m);
- GST_DEBUG_OBJECT (self, "Component supports I420 (%d) at index %d",
+ GST_DEBUG_OBJECT (self, "Component supports I420 (%d) at index %lu",
param.eColorFormat, param.nIndex);
break;
case OMX_COLOR_FormatYUV420SemiPlanar:
m->format = GST_VIDEO_FORMAT_NV12;
m->type = param.eColorFormat;
negotiation_map = g_list_append (negotiation_map, m);
- GST_DEBUG_OBJECT (self, "Component supports NV12 (%d) at index %d",
+ GST_DEBUG_OBJECT (self, "Component supports NV12 (%d) at index %lu",
param.eColorFormat, param.nIndex);
break;
case OMX_EXT_COLOR_FormatNV12TPhysicalAddress:
default:
GST_DEBUG_OBJECT (self,
- "Component supports unsupported color format %d at index %d",
+ "Component supports unsupported color format %d at index %lu",
param.eColorFormat, param.nIndex);
break;
}
GstVideoFormat format;
GstStructure *s;
const gchar *format_str;
+ gchar *format_tmp;
+ int i;
+ EnableGemBuffersParams gemBuffers;
GST_DEBUG_OBJECT (self, "Trying to negotiate a video format with downstream");
return FALSE;
}
- intersection = gst_caps_truncate (intersection);
- intersection = gst_caps_fixate (intersection);
+ for(i=0; i<gst_caps_get_size(intersection); i++)
+ {
+ s = gst_caps_get_structure (intersection, i);
+ format_tmp = gst_structure_get_string (s, "format");
+
+ if(!strncmp(format_tmp, "S", 1)) {
+ format_str = format_tmp;
+ GST_DEBUG_OBJECT (self, "SEC format found");
+ break;
+ }
+ }
+
+ if(!format_str) {
+ intersection = gst_caps_truncate (intersection);
+ intersection = gst_caps_fixate (intersection);
+
+ s = gst_caps_get_structure (intersection, 0);
+ format_str = gst_structure_get_string (s, "format");
+ GST_DEBUG_OBJECT (self, "first structure will be fixated");
+ }
- s = gst_caps_get_structure (intersection, 0);
- format_str = gst_structure_get_string (s, "format");
if (!format_str ||
(format =
gst_video_format_from_string (format_str)) ==
gst_omx_error_to_string (err), err);
}
+ /* set plateform specific gem buffer settings. */
+
+ /* Set platform specific buffer settings. to avoid plane support error.. */\r
+#ifdef USE_TBM\r
+ OMX_INIT_STRUCTURE(gemBuffers);\r
+ gemBuffers.enable = OMX_TRUE;\r
+ gemBuffers.nPortIndex = 1;\r
+ err =
+ gst_omx_component_set_parameter (self->dec,\r
+ OMX_IndexParamEnablePlatformSpecificBuffers,&gemBuffers);\r
+ if (err != OMX_ErrorNone) {
+ GST_ERROR_OBJECT (self, "Failed to set video port format: %s (0x%08x)",
+ gst_omx_error_to_string (err), err);
+ }
+#endif
return (err == OMX_ErrorNone);
}
GST_DEBUG_OBJECT (self, "Enabling component");
if (needs_disable) {
+ // printf("\n[SRI-D] needs_disable");
if (gst_omx_port_set_enabled (self->dec_in_port, TRUE) != OMX_ErrorNone)
return FALSE;
+#ifdef USE_TBM
+ //GST_ERROR_OBJECT (self, "\n3. USE_TBM");
+ if(gst_omx_port_tbm_allocate_dec_buffers(self->hTBMBufMgr,self->dec_in_port) != OMX_ErrorNone)
+ return FALSE;
+#else
+ //GST_ERROR_OBJECT (self, "\n3. NOT USE_TBM");
if (gst_omx_port_allocate_buffers (self->dec_in_port) != OMX_ErrorNone)
return FALSE;
+#endif
+
if (gst_omx_port_wait_enabled (self->dec_in_port,
5 * GST_SECOND) != OMX_ErrorNone)
return FALSE;
+
if (gst_omx_port_mark_reconfigured (self->dec_in_port) != OMX_ErrorNone)
return FALSE;
} else {
return FALSE;
/* Need to allocate buffers to reach Idle state */
+ //printf("\n[SRI-D] outside needs_disable\n");
+#ifdef USE_TBM
+ //GST_ERROR_OBJECT (self, "\n4. USE_TBM");
+ if(gst_omx_port_tbm_allocate_dec_buffers(self->hTBMBufMgr,self->dec_in_port) != OMX_ErrorNone)
+ return FALSE;
+#else
+ //GST_ERROR_OBJECT (self, "\n4. NOT USE_TBM");
if (gst_omx_port_allocate_buffers (self->dec_in_port) != OMX_ErrorNone)
return FALSE;
+#endif
-#ifdef EXYNOS_SPECIFIC
- /*Specific for exynos processors*/
- if (gst_omx_port_allocate_buffers (self->dec_out_port) != OMX_ErrorNone)
+#ifdef USE_TBM
+ //GST_ERROR_OBJECT (self, "\n5. USE_TBM");
+ if(gst_omx_port_tbm_allocate_dec_buffers(self->hTBMBufMgr,self->dec_out_port) != OMX_ErrorNone)
+ return FALSE;
#else
+ //GST_ERROR_OBJECT (self, "\n5. NOT USE_TBM");
+ if (gst_omx_port_allocate_buffers (self->dec_out_port) != OMX_ErrorNone)
+ return FALSE
+#endif
+#if 0
+ GST_ERROR_OBJECT (self, "\n6. DISABLE OUTPUT PORT\n");
/* And disable output port */
if (gst_omx_port_set_enabled (self->dec_out_port, FALSE) != OMX_ErrorNone)
return FALSE;
-
+ GST_ERROR_OBJECT (self, "\n7. DISABLE OUTPUT PORT WAIT\n");
if (gst_omx_port_wait_enabled (self->dec_out_port,
1 * GST_SECOND) != OMX_ErrorNone)
-#endif
return FALSE;
-
+#endif
+ //GST_ERROR_OBJECT (self, "\n7. GET COMPONENT STATE\n");
if (gst_omx_component_get_state (self->dec,
GST_CLOCK_TIME_NONE) != OMX_StateIdle)
return FALSE;
-
+ //GST_ERROR_OBJECT (self, "\n8. SET COMPONENT STATE TO EXECUTING\n");
if (gst_omx_component_set_state (self->dec,
OMX_StateExecuting) != OMX_ErrorNone)
return FALSE;
-
+ GST_ERROR_OBJECT (self, "\n9. GET COMPONENT STATE\n");
if (gst_omx_component_get_state (self->dec,
GST_CLOCK_TIME_NONE) != OMX_StateExecuting)
return FALSE;
}
/* Unset flushing to allow ports to accept data again */
+ //GST_ERROR_OBJECT (self, "\n10. FLUSHING INPUT PORT\n");
gst_omx_port_set_flushing (self->dec_in_port, 5 * GST_SECOND, FALSE);
+ //GST_ERROR_OBJECT (self, "\n11. FLUSHING OUTPUT PORT\n");
gst_omx_port_set_flushing (self->dec_out_port, 5 * GST_SECOND, FALSE);
if (gst_omx_component_get_last_error (self->dec) != OMX_ErrorNone) {
return FALSE;
}
+ //GST_ERROR_OBJECT (self, "\n12. STARTING TASK AGAIN\n");
/* Start the srcpad loop again */
GST_DEBUG_OBJECT (self, "Starting task again");
GST_VIDEO_DECODER_STREAM_LOCK (self);
goto reconfigure_error;
}
-
+#ifdef USE_TBM
+ err = gst_omx_port_tbm_allocate_dec_buffers(self->hTBMBufMgr,port);
+#else
err = gst_omx_port_allocate_buffers (port);
+#endif
if (err != OMX_ErrorNone) {
GST_VIDEO_DECODER_STREAM_LOCK (self);
goto reconfigure_error;
buf->omx_buf->nFlags |= OMX_BUFFERFLAG_CODECCONFIG;
buf->omx_buf->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
buf->omx_buf->nFilledLen = gst_buffer_get_size (codec_data);;
+#ifdef USE_TBM
+ //GST_ERROR_OBJECT(self,"\n[SRI-D] extract from codec_data\n");
+ gst_buffer_extract (codec_data, 0,
+ buf->scmn_buffer->a[0] + buf->omx_buf->nOffset,
+ buf->omx_buf->nFilledLen);
+#else
gst_buffer_extract (codec_data, 0,
buf->omx_buf->pBuffer + buf->omx_buf->nOffset,
buf->omx_buf->nFilledLen);
-
+#endif
+ //GST_ERROR_OBJECT(self,"\n[SRI-D] extract from codec_data SUCCESS\n");
if (GST_CLOCK_TIME_IS_VALID (timestamp))
buf->omx_buf->nTimeStamp =
gst_util_uint64_scale (timestamp, OMX_TICKS_PER_SECOND, GST_SECOND);
* by the port */
buf->omx_buf->nFilledLen =
MIN (size - offset, buf->omx_buf->nAllocLen - buf->omx_buf->nOffset);
+ GST_DEBUG_OBJECT (self, "nFilledLen %d, %p", buf->omx_buf->nFilledLen, buf->omx_buf->pBuffer);
+
+ /*GST_ERROR_OBJECT (self, "[SRI-D] frame->input_buffer:[%p], offset:[%d], buf->scmn_buffer->a[0]:[%p],offset:[%d], buf->omx_buf->nFilledLen:[%d]",
+ frame->input_buffer, offset, buf->scmn_buffer->a[0], buf->omx_buf->nOffset, buf->omx_buf->nFilledLen);*/
+#ifdef USE_TBM
+ //GST_ERROR_OBJECT(self,"\n[SRI-D] extract from frame->input_buffer\n");
+ gst_buffer_extract (frame->input_buffer, offset,
+ buf->scmn_buffer->a[0] + buf->omx_buf->nOffset,
+ buf->omx_buf->nFilledLen);
+#else
gst_buffer_extract (frame->input_buffer, offset,
buf->omx_buf->pBuffer + buf->omx_buf->nOffset,
buf->omx_buf->nFilledLen);
-
+#endif
+ //GST_ERROR_OBJECT(self,"\n[SRI-D] extract from frame->input_buffer SUCCESS\n");
if (timestamp != GST_CLOCK_TIME_NONE) {
buf->omx_buf->nTimeStamp =
gst_util_uint64_scale (timestamp, OMX_TICKS_PER_SECOND, GST_SECOND);
return TRUE;
}
+
#include "gstomx.h"
+#define OMX_VERSION_MAJOR 1
+#define OMX_VERSION_MINOR 1
+#define OMX_VERSION_REVISION 2
+#define OMX_VERSION_STEP 0
+
+#define OMX_VERSION ((OMX_VERSION_STEP<<24) | (OMX_VERSION_REVISION<<16) | (OMX_VERSION_MINOR<<8) | OMX_VERSION_MAJOR)
+
+#define OMX_INIT_STRUCTURE(a) \
+ memset(&(a), 0, sizeof(a)); \
+ (a).nSize = sizeof(a); \
+ (a).nVersion.nVersion = OMX_VERSION; \
+ (a).nVersion.s.nVersionMajor = OMX_VERSION_MAJOR; \
+ (a).nVersion.s.nVersionMinor = OMX_VERSION_MINOR; \
+ (a).nVersion.s.nRevision = OMX_VERSION_REVISION; \
+ (a).nVersion.s.nStep = OMX_VERSION_STEP
+
G_BEGIN_DECLS
#define GST_TYPE_OMX_VIDEO_DEC \
gboolean eos;
GstFlowReturn downstream_flow_ret;
+#ifdef USE_TBM
+ gint drm_fd;
+ tbm_bufmgr hTBMBufMgr;
+#endif
};
struct _GstOMXVideoDecClass
PROP_QUANT_B_FRAMES
};
-/* using common scmn_imgb format */
-#define SCMN_IMGB_MAX_PLANE (4) /* max channel count */
-
-/* image buffer definition
- +------------------------------------------+ ---
- | | ^
- | a[], p[] | |
- | +---------------------------+ --- | |
- | | | ^ | |
- | |<---------- w[] ---------->| | | |
- | | | | | |
- | | | |
- | | | h[] | e[]
- | | | |
- | | | | | |
- | | | | | |
- | | | v | |
- | +---------------------------+ --- | |
- | | v
- +------------------------------------------+ ---
-
- |<----------------- s[] ------------------>|
-*/
-
-typedef struct
-{
- int w[SCMN_IMGB_MAX_PLANE]; /* width of each image plane */
- int h[SCMN_IMGB_MAX_PLANE]; /* height of each image plane */
- int s[SCMN_IMGB_MAX_PLANE]; /* stride of each image plane */
- int e[SCMN_IMGB_MAX_PLANE]; /* elevation of each image plane */
- void * a[SCMN_IMGB_MAX_PLANE]; /* user space address of each image plane */
- void * p[SCMN_IMGB_MAX_PLANE]; /* physical address of each image plane, if needs */
- int cs; /* color space type of image */
- int x; /* left postion, if needs */
- int y; /* top position, if needs */
- int __dummy2; /* to align memory */
- int data[16]; /* arbitrary data */
-
- /* dmabuf fd */
- int fd[SCMN_IMGB_MAX_PLANE];
-
- /* flag for buffer share */
- int buf_share_method;
-} SCMN_IMGB;
-
-/* Extended color formats */
-enum {
- OMX_EXT_COLOR_FormatNV12TPhysicalAddress = 0x7F000001, /**< Reserved region for introducing Vendor Extensions */
- OMX_EXT_COLOR_FormatNV12LPhysicalAddress = 0x7F000002,
- OMX_EXT_COLOR_FormatNV12Tiled = 0x7FC00002,
- OMX_EXT_COLOR_FormatNV12TFdValue = 0x7F000012,
- OMX_EXT_COLOR_FormatNV12LFdValue = 0x7F000013
-};
-
/* FIXME: Better defaults */
#define GST_OMX_VIDEO_ENC_CONTROL_RATE_DEFAULT (0xffffffff)
#define GST_OMX_VIDEO_ENC_TARGET_BITRATE_DEFAULT (0xffffffff)
GST_WARNING_OBJECT (self, "enc input buf has wrong buf_share_method");
}
- memcpy (outbuf->omx_buf->pBuffer, ext_buf, sizeof(*ext_buf));
- outbuf->omx_buf->nAllocLen = sizeof(*ext_buf);
- outbuf->omx_buf->nFilledLen = sizeof(*ext_buf);
+ outbuf->omx_buf->nAllocLen = sizeof(SCMN_IMGB);
+ outbuf->omx_buf->nFilledLen = sizeof(SCMN_IMGB);
+ memcpy (outbuf->omx_buf->pBuffer, ext_buf, sizeof(SCMN_IMGB));
ret = TRUE;
break;
}
#include <gst/gst.h>
#include <gst/video/video.h>
#include <gst/video/gstvideoencoder.h>
+#include <tbm_bufmgr.h>
#include "gstomx.h"
BuildRequires: pkgconfig(gstreamer-1.0)
BuildRequires: pkgconfig(gstreamer-plugins-base-1.0)
+BuildRequires: pkgconfig(x11)
+BuildRequires: pkgconfig(dri2proto)
+BuildRequires: pkgconfig(libdri2)
+BuildRequires: pkgconfig(libdrm)
+BuildRequires: pkgconfig(libtbm)
+BuildRequires: pkgconfig(xfixes)
+
%description
gst-openmax is a GStreamer plug-in that allows communication with OpenMAX IL components.
Multiple OpenMAX IL implementations can be used.
%ifarch %{arm}
export CFLAGS+=" -DEXYNOS_SPECIFIC"
+export CFLAGS+=" -DUSE_TBM"
%endif
%configure --disable-static --prefix=/usr
%install
rm -rf %{buildroot}
+mkdir -p %{buildroot}/usr/share/license
+cp COPYING %{buildroot}/usr/share/license/%{name}
+mkdir -p %{buildroot}/root/.config
+cp -arf config/odroid/gstomx.conf %{buildroot}/root/.config
%make_install
%files
%manifest gst-omx.manifest
+%defattr(-,root,root,-)
%{_libdir}/gstreamer-1.0/libgstomx.so
+/root/.config/gstomx.conf
+/usr/share/license/%{name}