in-port-index=0
out-port-index=1
in-port-usebuffer=1
-out-port-usebuffer=1
+out-port-usebuffer=0
hacks=no-disable-outport;no-component-role
sink-template-caps=video/x-raw, format=(string)SN12, width=(int) [1,1920], height=(int) [1,1080], framerate=(fraction)[0/1, MAX]
src-template-caps=video/x-h264, width=(int) [1,1920], height=(int) [1,1080], framerate=(fraction) [0/1, MAX], alignment=(string) au, stream-format = (string){ avc, byte-stream }
+[omxenc_h265]
+type-name=GstOMXH265Enc
+core-name=/usr/lib/libExynosOMX_Core.so
+component-name=OMX.Exynos.HEVC.Encoder
+rank=258
+in-port-index=0
+out-port-index=1
+in-port-usebuffer=1
+out-port-usebuffer=0
+hacks=no-disable-outport;no-component-role
+
[omxenc_mpeg4]
type-name=GstOMXMPEG4VideoEnc
core-name=/usr/lib/libExynosOMX_Core.so
in-port-index=0
out-port-index=1
in-port-usebuffer=1
-out-port-usebuffer=1
+out-port-usebuffer=0
hacks=no-component-role;no-disable-outport
[omxenc_h263]
in-port-index=0
out-port-index=1
in-port-usebuffer=1
-out-port-usebuffer=1
+out-port-usebuffer=0
hacks=no-component-role;no-disable-outport
endif
if HAVE_HEVC
-HEVC_C_FILES=gstomxh265dec.c
-HEVC_H_FILES=gstomxh265dec.h
+HEVC_C_FILES=gstomxh265dec.c \
+ gstomxh265enc.c
+HEVC_H_FILES=gstomxh265dec.h \
+ gstomxh265enc.h
endif
libgstomx_la_SOURCES = \
#include "gstomxtheoradec.h"
#include "gstomxwmvdec.h"
#include "gstomxmpeg4videoenc.h"
+#include "gstomxh265enc.h"
#include "gstomxh264enc.h"
#include "gstomxh263enc.h"
#include "gstomxaacdec.h"
err = OMX_EmptyThisBuffer (comp->handle, buf->omx_buf);
} else {
GST_LOG_OBJECT (comp->parent,"Calling OMX_FillThisBuffer. dmabuf_fd : [%d(%p)]\n",
- buf->mm_vbuffer->handle.dmabuf_fd[0], buf);
+ buf->mm_vbuffer ? buf->mm_vbuffer->handle.dmabuf_fd[0] : 0, buf);
err = OMX_FillThisBuffer (comp->handle, buf->omx_buf);
}
GST_DEBUG_OBJECT (comp->parent, "Released buffer %p to %s port %u: %s "
/* NOTE: Uses comp->lock and comp->messages_lock */
OMX_ERRORTYPE
-gst_omx_port_tbm_allocate_enc_buffers (GstOMXPort * port, tbm_bufmgr bufmgr, int eCompressionFormat)
+gst_omx_port_tbm_allocate_enc_buffers (GstOMXPort * port, tbm_bufmgr bufmgr, int eCompressionFormat, gboolean use_buffer)
{
int y_size = 0;
int uv_size = 0;
OMX_ERRORTYPE err = OMX_ErrorNone;
guint n = 0;
+ gint num = 0;
GList *buffers = NULL;
tbm_bo_handle handle_bo;
MMVideoBuffer *mm_vbuffer[MAX_INPUT_BUFFER];
/*deallocate previous allocated buffers...*/
if (port->buffers)
- gst_omx_port_deallocate_buffers(port);
+ gst_omx_port_deallocate_buffers (port);
n = port->port_def.nBufferCountActual;
- for (int i = 0; i < n; i++) {
- mm_vbuffer[i] = (MMVideoBuffer*)malloc(sizeof(MMVideoBuffer));
+ if (use_buffer) {
+ for (int i = 0; i < n; i++) {
+ mm_vbuffer[i] = (MMVideoBuffer*)malloc(sizeof(MMVideoBuffer));
- if (port->index == 1) {
- mm_vbuffer[i]->handle.bo[0] = tbm_bo_alloc(bufmgr, port->port_def.nBufferSize, TBM_BO_WC);
- handle_bo = tbm_bo_get_handle(mm_vbuffer[i]->handle.bo[0], TBM_DEVICE_MM);
- mm_vbuffer[i]->handle.dmabuf_fd[0] = handle_bo.u32;
+ if (port->index == 1) {
+ mm_vbuffer[i]->handle.bo[0] = tbm_bo_alloc (bufmgr, port->port_def.nBufferSize, TBM_BO_WC);
+ handle_bo = tbm_bo_get_handle (mm_vbuffer[i]->handle.bo[0], TBM_DEVICE_MM);
+ mm_vbuffer[i]->handle.dmabuf_fd[0] = handle_bo.u32;
- handle_bo = tbm_bo_get_handle(mm_vbuffer[i]->handle.bo[0], TBM_DEVICE_CPU);
- mm_vbuffer[i]->data[0] = handle_bo.ptr;
- mm_vbuffer[i]->type = MM_VIDEO_BUFFER_TYPE_TBM_BO;
- mm_vbuffer[i]->size[0] = port->port_def.nBufferSize;
- mm_vbuffer[i]->handle_num = 1;
+ handle_bo = tbm_bo_get_handle (mm_vbuffer[i]->handle.bo[0], TBM_DEVICE_CPU);
+ mm_vbuffer[i]->data[0] = handle_bo.ptr;
+ mm_vbuffer[i]->type = MM_VIDEO_BUFFER_TYPE_TBM_BO;
+ mm_vbuffer[i]->size[0] = port->port_def.nBufferSize;
+ mm_vbuffer[i]->handle_num = 1;
+ }
+ buffers = g_list_append (buffers, (gpointer)mm_vbuffer[i]);
}
- buffers = g_list_append(buffers,(gpointer)mm_vbuffer[i]);
}
- n = g_list_length ((GList *) buffers);
+ num = use_buffer ? g_list_length ((GList *) buffers) : -1;
err = gst_omx_port_allocate_buffers_unlocked (port, buffers, NULL, n);
g_mutex_unlock (&port->comp->lock);
#endif
#ifdef HAVE_HEVC
, gst_omx_h265_dec_get_type
+ , gst_omx_h265_enc_get_type
#endif
#ifdef HAVE_THEORA
, gst_omx_theora_dec_get_type
(st)->nVersion.s.nStep = OMX_VERSION_STEP; \
} G_STMT_END
+#ifdef USE_OMX_TARGET_EXYNOS
+#define OMX_INIT_PARAM(param) G_STMT_START { \
+ memset (&(param), 0, sizeof ((param))); \
+ (param).nSize = sizeof (param); \
+ (param).nVersion.s.nVersionMajor = 1; \
+ (param).nVersion.s.nVersionMinor = 1; \
+} G_STMT_END
+#endif
+
/* Different hacks that are required to work around
* bugs in different OpenMAX implementations
*/
typedef struct _TBMBuffer TBMBuffer;
typedef struct _TBMInputBuffer TBMInputBuffer;
typedef struct _TBMOutputBuffer TBMOutputBuffer;
+typedef struct _EnableGemBuffersParams EnableGemBuffersParams;
struct _TBMBuffer
{
GList *buffers;
};
-typedef struct _EnableGemBuffersParams EnableGemBuffersParams;
-
struct _EnableGemBuffersParams
{
OMX_U32 nSize;
OMX_ERRORTYPE gst_omx_port_allocate_buffers (GstOMXPort *port);
#ifdef TIZEN_FEATURE_OMX
OMX_ERRORTYPE gst_omx_port_tbm_allocate_dec_buffers (GstOMXPort * port, tbm_bufmgr bufMgr, int eCompressionFormat, gboolean use_buffer);
-OMX_ERRORTYPE gst_omx_port_tbm_allocate_enc_buffers (GstOMXPort * port, tbm_bufmgr bufMgr, int eCompressionFormat);
+OMX_ERRORTYPE gst_omx_port_tbm_allocate_enc_buffers (GstOMXPort * port, tbm_bufmgr bufMgr, int eCompressionFormat, gboolean use_buffer);
#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);
#ifdef USE_OMX_TARGET_RPI
PROP_INLINESPSPPSHEADERS,
#endif
+#ifdef USE_OMX_TARGET_EXYNOS
+ PROP_NUM_REF_FRAME,
+ PROP_NUM_B_FRAME,
+#endif
PROP_PERIODICITYOFIDRFRAMES,
PROP_INTERVALOFCODINGINTRAFRAMES
};
#ifdef USE_OMX_TARGET_RPI
#define GST_OMX_H264_VIDEO_ENC_INLINE_SPS_PPS_HEADERS_DEFAULT TRUE
#endif
+#ifdef USE_OMX_TARGET_EXYNOS
+#define GST_OMX_VIDEO_ENC_NUM_REF_FRAME_DEFAULT (0x00000001)
+#define GST_OMX_VIDEO_ENC_NUM_REF_FRAME_MAX (0x00000002)
+#define GST_OMX_VIDEO_ENC_NUM_B_FRAME_DEFAULT (0x00000001)
+#define GST_OMX_VIDEO_ENC_NUM_B_FRAME_MAX (0x00000002)
+#endif
#define GST_OMX_H264_VIDEO_ENC_PERIODICITY_OF_IDR_FRAMES_DEFAULT (0xffffffff)
#define GST_OMX_H264_VIDEO_ENC_INTERVAL_OF_CODING_INTRA_FRAMES_DEFAULT (0xffffffff)
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
GST_PARAM_MUTABLE_READY));
#endif
+#ifdef USE_OMX_TARGET_EXYNOS
+ g_object_class_install_property (gobject_class, PROP_NUM_REF_FRAME,
+ g_param_spec_uint ("reference-frame", "set number of reference frame",
+ "The number of reference frame (0x00000001=component default)",
+ GST_OMX_VIDEO_ENC_NUM_REF_FRAME_DEFAULT, GST_OMX_VIDEO_ENC_NUM_REF_FRAME_MAX,
+ GST_OMX_VIDEO_ENC_NUM_REF_FRAME_DEFAULT,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+ GST_PARAM_MUTABLE_READY));
+ g_object_class_install_property (gobject_class, PROP_NUM_B_FRAME,
+ g_param_spec_uint ("b-frame", "set number of b frame",
+ "The number of reference frame (0x00000001=component default)",
+ GST_OMX_VIDEO_ENC_NUM_B_FRAME_DEFAULT, GST_OMX_VIDEO_ENC_NUM_B_FRAME_MAX,
+ GST_OMX_VIDEO_ENC_NUM_B_FRAME_DEFAULT,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+ GST_PARAM_MUTABLE_READY));
+#endif
g_object_class_install_property (gobject_class, PROP_PERIODICITYOFIDRFRAMES,
g_param_spec_uint ("periodicty-idr", "Target Bitrate",
"Periodicity of IDR frames (0xffffffff=component default)",
self->inline_sps_pps_headers = g_value_get_boolean (value);
break;
#endif
+#ifdef USE_OMX_TARGET_EXYNOS
+ case PROP_NUM_REF_FRAME:
+ self->reference_frame = g_value_get_int (value);
+ break;
+ case PROP_NUM_B_FRAME:
+ self->b_frame = g_value_get_int (value);
+ break;
+#endif
case PROP_PERIODICITYOFIDRFRAMES:
self->periodicty_idr = g_value_get_uint (value);
break;
g_value_set_boolean (value, self->inline_sps_pps_headers);
break;
#endif
+#ifdef USE_OMX_TARGET_EXYNOS
+ case PROP_NUM_REF_FRAME:
+ g_value_set_uint (value, self->reference_frame);
+ break;
+ case PROP_NUM_B_FRAME:
+ g_value_set_uint (value, self->b_frame);
+ break;
+#endif
case PROP_PERIODICITYOFIDRFRAMES:
g_value_set_uint (value, self->periodicty_idr);
break;
self->inline_sps_pps_headers =
GST_OMX_H264_VIDEO_ENC_INLINE_SPS_PPS_HEADERS_DEFAULT;
#endif
+#ifdef USE_OMX_TARGET_EXYNOS
+ self->reference_frame = GST_OMX_VIDEO_ENC_NUM_REF_FRAME_DEFAULT;
+#endif
self->periodicty_idr =
GST_OMX_H264_VIDEO_ENC_PERIODICITY_OF_IDR_FRAMES_DEFAULT;
self->interval_intraframes =
#ifdef USE_OMX_TARGET_RPI
OMX_CONFIG_PORTBOOLEANTYPE config_inline_header;
#endif
+#ifdef USE_OMX_TARGET_EXYNOS
+ OMX_VIDEO_PARAM_AVCTYPE avc_param;
+#endif
OMX_ERRORTYPE err;
const gchar *profile_string, *level_string;
return FALSE;
}
#endif
+#ifdef USE_OMX_TARGET_EXYNOS
+ GST_OMX_INIT_STRUCT (&avc_param);
+
+ err =
+ gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
+ OMX_IndexParamVideoAvc, &avc_param);
+ if (err != OMX_ErrorNone) {
+ GST_ERROR_OBJECT (self,
+ "can't get OMX_IndexParamVideoAvc %s (0x%08x)",
+ gst_omx_error_to_string (err), err);
+ return FALSE;
+ }
+
+ GST_DEBUG_OBJECT (self, "default nRefFrames:%u, nBFrames:%u",
+ (guint) avc_param.nRefFrames,
+ (guint) avc_param.nBFrames);
+
+ avc_param.nRefFrames = self->reference_frame;
+ avc_param.nBFrames = self->b_frame;
+ err =
+ gst_omx_component_set_parameter (GST_OMX_VIDEO_ENC (self)->enc,
+ OMX_IndexParamVideoAvc, &avc_param);
+ if (err != OMX_ErrorNone) {
+ GST_ERROR_OBJECT (self,
+ "can't set OMX_IndexParamVideoAvc %s (0x%08x)",
+ gst_omx_error_to_string (err), err);
+ return FALSE;
+ }
+
+#endif
if (self->periodicty_idr !=
GST_OMX_H264_VIDEO_ENC_PERIODICITY_OF_IDR_FRAMES_DEFAULT
#ifdef USE_OMX_TARGET_RPI
gboolean inline_sps_pps_headers;
#endif
+#ifdef USE_OMX_TARGET_EXYNOS
+ guint32 reference_frame;
+ guint32 b_frame;
+#endif
guint32 periodicty_idr;
guint32 interval_intraframes;
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Author: Sejun Park <sejun79.park@samsung.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gst/gst.h>
+
+#include "gstomxh265enc.h"
+
+#ifdef USE_OMX_TARGET_RPI
+#include <OMX_Broadcom.h>
+#include <OMX_Index.h>
+#endif
+
+GST_DEBUG_CATEGORY_STATIC (gst_omx_h265_enc_debug_category);
+#define GST_CAT_DEFAULT gst_omx_h265_enc_debug_category
+
+/* prototypes */
+static gboolean gst_omx_h265_enc_set_format (GstOMXVideoEnc * enc,
+ GstOMXPort * port, GstVideoCodecState * state);
+static GstCaps *gst_omx_h265_enc_get_caps (GstOMXVideoEnc * enc,
+ GstOMXPort * port, GstVideoCodecState * state);
+static GstFlowReturn gst_omx_h265_enc_handle_output_frame (GstOMXVideoEnc *
+ self, GstOMXPort * port, GstOMXBuffer * buf, GstVideoCodecFrame * frame);
+static gboolean gst_omx_h265_enc_flush (GstVideoEncoder * enc);
+static gboolean gst_omx_h265_enc_stop (GstVideoEncoder * enc);
+static void gst_omx_h265_enc_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec);
+static void gst_omx_h265_enc_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec);
+
+enum
+{
+ PROP_0,
+#ifdef USE_OMX_TARGET_RPI
+ PROP_INLINESPSPPSHEADERS,
+#endif
+ PROP_PERIODICITYOFIDRFRAMES,
+ PROP_INTERVALOFCODINGINTRAFRAMES
+};
+
+#ifdef USE_OMX_TARGET_RPI
+#define GST_OMX_H265_VIDEO_ENC_INLINE_SPS_PPS_HEADERS_DEFAULT TRUE
+#endif
+#define GST_OMX_H265_VIDEO_ENC_PERIODICITY_OF_IDR_FRAMES_DEFAULT (0xffffffff)
+#define GST_OMX_H265_VIDEO_ENC_INTERVAL_OF_CODING_INTRA_FRAMES_DEFAULT (0xffffffff)
+
+
+/* class initialization */
+
+#define DEBUG_INIT \
+ GST_DEBUG_CATEGORY_INIT (gst_omx_h265_enc_debug_category, "omxh265enc", 0, \
+ "debug category for gst-omx video encoder base class");
+
+#define parent_class gst_omx_h265_enc_parent_class
+G_DEFINE_TYPE_WITH_CODE (GstOMXH265Enc, gst_omx_h265_enc,
+ GST_TYPE_OMX_VIDEO_ENC, DEBUG_INIT);
+
+static void
+gst_omx_h265_enc_class_init (GstOMXH265EncClass * klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+ GstVideoEncoderClass *basevideoenc_class = GST_VIDEO_ENCODER_CLASS (klass);
+ GstOMXVideoEncClass *videoenc_class = GST_OMX_VIDEO_ENC_CLASS (klass);
+
+ videoenc_class->set_format = GST_DEBUG_FUNCPTR (gst_omx_h265_enc_set_format);
+ videoenc_class->get_caps = GST_DEBUG_FUNCPTR (gst_omx_h265_enc_get_caps);
+
+ gobject_class->set_property = gst_omx_h265_enc_set_property;
+ gobject_class->get_property = gst_omx_h265_enc_get_property;
+
+#ifdef USE_OMX_TARGET_RPI
+ g_object_class_install_property (gobject_class, PROP_INLINESPSPPSHEADERS,
+ g_param_spec_boolean ("inline-header",
+ "Inline SPS/PPS headers before IDR",
+ "Inline SPS/PPS header before IDR",
+ GST_OMX_H265_VIDEO_ENC_INLINE_SPS_PPS_HEADERS_DEFAULT,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+ GST_PARAM_MUTABLE_READY));
+#endif
+
+ g_object_class_install_property (gobject_class, PROP_PERIODICITYOFIDRFRAMES,
+ g_param_spec_uint ("periodicty-idr", "Target Bitrate",
+ "Periodicity of IDR frames (0xffffffff=component default)",
+ 0, G_MAXUINT,
+ GST_OMX_H265_VIDEO_ENC_PERIODICITY_OF_IDR_FRAMES_DEFAULT,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+ GST_PARAM_MUTABLE_READY));
+
+ g_object_class_install_property (gobject_class,
+ PROP_INTERVALOFCODINGINTRAFRAMES,
+ g_param_spec_uint ("interval-intraframes",
+ "Interval of coding Intra frames",
+ "Interval of coding Intra frames (0xffffffff=component default)", 0,
+ G_MAXUINT,
+ GST_OMX_H265_VIDEO_ENC_INTERVAL_OF_CODING_INTRA_FRAMES_DEFAULT,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+ GST_PARAM_MUTABLE_READY));
+
+ basevideoenc_class->flush = gst_omx_h265_enc_flush;
+ basevideoenc_class->stop = gst_omx_h265_enc_stop;
+
+ videoenc_class->cdata.default_src_template_caps = "video/x-h265, "
+ "width=(int) [ 1, MAX ], " "height=(int) [ 1, MAX ],"
+ "framerate = (fraction) [0, MAX], "
+ "stream-format=(string) { byte-stream }, "
+ "alignment=(string) au ";
+ videoenc_class->handle_output_frame =
+ GST_DEBUG_FUNCPTR (gst_omx_h265_enc_handle_output_frame);
+
+ gst_element_class_set_static_metadata (element_class,
+ "OpenMAX H.265 Video Encoder",
+ "Codec/Encoder/Video",
+ "Encode H.265 video streams",
+ "Sejun Park <sejun79.park@samsung.com>");
+
+ gst_omx_set_default_role (&videoenc_class->cdata, "video_encoder.hevc");
+}
+
+static void
+gst_omx_h265_enc_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ GstOMXH265Enc *self = GST_OMX_H265_ENC (object);
+
+ switch (prop_id) {
+#ifdef USE_OMX_TARGET_RPI
+ case PROP_INLINESPSPPSHEADERS:
+ self->inline_sps_pps_headers = g_value_get_boolean (value);
+ break;
+#endif
+ case PROP_PERIODICITYOFIDRFRAMES:
+ self->periodicty_idr = g_value_get_uint (value);
+ break;
+ case PROP_INTERVALOFCODINGINTRAFRAMES:
+ self->interval_intraframes = g_value_get_uint (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_omx_h265_enc_get_property (GObject * object, guint prop_id, GValue * value,
+ GParamSpec * pspec)
+{
+ GstOMXH265Enc *self = GST_OMX_H265_ENC (object);
+
+ switch (prop_id) {
+#ifdef USE_OMX_TARGET_RPI
+ case PROP_INLINESPSPPSHEADERS:
+ g_value_set_boolean (value, self->inline_sps_pps_headers);
+ break;
+#endif
+ case PROP_PERIODICITYOFIDRFRAMES:
+ g_value_set_uint (value, self->periodicty_idr);
+ break;
+ case PROP_INTERVALOFCODINGINTRAFRAMES:
+ g_value_set_uint (value, self->interval_intraframes);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_omx_h265_enc_init (GstOMXH265Enc * self)
+{
+#ifdef USE_OMX_TARGET_RPI
+ self->inline_sps_pps_headers =
+ GST_OMX_H265_VIDEO_ENC_INLINE_SPS_PPS_HEADERS_DEFAULT;
+#endif
+ self->periodicty_idr =
+ GST_OMX_H265_VIDEO_ENC_PERIODICITY_OF_IDR_FRAMES_DEFAULT;
+ self->interval_intraframes =
+ GST_OMX_H265_VIDEO_ENC_INTERVAL_OF_CODING_INTRA_FRAMES_DEFAULT;
+}
+
+static gboolean
+gst_omx_h265_enc_flush (GstVideoEncoder * enc)
+{
+ GstOMXH265Enc *self = GST_OMX_H265_ENC (enc);
+
+ g_list_free_full (self->headers, (GDestroyNotify) gst_buffer_unref);
+ self->headers = NULL;
+
+ return GST_VIDEO_ENCODER_CLASS (parent_class)->flush (enc);
+}
+
+static gboolean
+gst_omx_h265_enc_stop (GstVideoEncoder * enc)
+{
+ GstOMXH265Enc *self = GST_OMX_H265_ENC (enc);
+
+ g_list_free_full (self->headers, (GDestroyNotify) gst_buffer_unref);
+ self->headers = NULL;
+
+ return GST_VIDEO_ENCODER_CLASS (parent_class)->stop (enc);
+}
+
+static gboolean
+gst_omx_h265_enc_set_format (GstOMXVideoEnc * enc, GstOMXPort * port,
+ GstVideoCodecState * state)
+{
+ GstOMXH265Enc *self = GST_OMX_H265_ENC (enc);
+ GstCaps *peercaps;
+ OMX_PARAM_PORTDEFINITIONTYPE port_def;
+ OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
+ OMX_VIDEO_CONFIG_AVCINTRAPERIOD config_avcintraperiod;
+#ifdef USE_OMX_TARGET_RPI
+ OMX_CONFIG_PORTBOOLEANTYPE config_inline_header;
+#endif
+ OMX_ERRORTYPE err;
+ const gchar *profile_string, *level_string;
+
+#ifdef USE_OMX_TARGET_RPI
+ GST_OMX_INIT_STRUCT (&config_inline_header);
+ config_inline_header.nPortIndex =
+ GST_OMX_VIDEO_ENC (self)->enc_out_port->index;
+ err =
+ gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
+ OMX_IndexParamBrcmVideoAVCInlineHeaderEnable, &config_inline_header);
+ if (err != OMX_ErrorNone) {
+ GST_ERROR_OBJECT (self,
+ "can't get OMX_IndexParamBrcmVideoAVCInlineHeaderEnable %s (0x%08x)",
+ gst_omx_error_to_string (err), err);
+ return FALSE;
+ }
+
+ if (self->inline_sps_pps_headers) {
+ config_inline_header.bEnabled = OMX_TRUE;
+ } else {
+ config_inline_header.bEnabled = OMX_FALSE;
+ }
+
+ err =
+ gst_omx_component_set_parameter (GST_OMX_VIDEO_ENC (self)->enc,
+ OMX_IndexParamBrcmVideoAVCInlineHeaderEnable, &config_inline_header);
+ if (err != OMX_ErrorNone) {
+ GST_ERROR_OBJECT (self,
+ "can't set OMX_IndexParamBrcmVideoAVCInlineHeaderEnable %s (0x%08x)",
+ gst_omx_error_to_string (err), err);
+ return FALSE;
+ }
+#endif
+
+ if (self->periodicty_idr !=
+ GST_OMX_H265_VIDEO_ENC_PERIODICITY_OF_IDR_FRAMES_DEFAULT
+ || self->interval_intraframes !=
+ GST_OMX_H265_VIDEO_ENC_INTERVAL_OF_CODING_INTRA_FRAMES_DEFAULT) {
+
+
+ GST_OMX_INIT_STRUCT (&config_avcintraperiod);
+ config_avcintraperiod.nPortIndex =
+ GST_OMX_VIDEO_ENC (self)->enc_out_port->index;
+ err =
+ gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
+ OMX_IndexConfigVideoAVCIntraPeriod, &config_avcintraperiod);
+ if (err != OMX_ErrorNone) {
+ GST_ERROR_OBJECT (self,
+ "can't get OMX_IndexConfigVideoAVCIntraPeriod %s (0x%08x)",
+ gst_omx_error_to_string (err), err);
+ return FALSE;
+ }
+
+ GST_DEBUG_OBJECT (self, "default nPFrames:%u, nIDRPeriod:%u",
+ (guint) config_avcintraperiod.nPFrames,
+ (guint) config_avcintraperiod.nIDRPeriod);
+
+ if (self->periodicty_idr !=
+ GST_OMX_H265_VIDEO_ENC_PERIODICITY_OF_IDR_FRAMES_DEFAULT) {
+ config_avcintraperiod.nIDRPeriod = self->periodicty_idr;
+ }
+
+ if (self->interval_intraframes !=
+ GST_OMX_H265_VIDEO_ENC_INTERVAL_OF_CODING_INTRA_FRAMES_DEFAULT) {
+ config_avcintraperiod.nPFrames = self->interval_intraframes;
+ }
+
+ err =
+ gst_omx_component_set_parameter (GST_OMX_VIDEO_ENC (self)->enc,
+ OMX_IndexConfigVideoAVCIntraPeriod, &config_avcintraperiod);
+ if (err != OMX_ErrorNone) {
+ GST_ERROR_OBJECT (self,
+ "can't set OMX_IndexConfigVideoAVCIntraPeriod %s (0x%08x)",
+ gst_omx_error_to_string (err), err);
+ return FALSE;
+ }
+ }
+
+ gst_omx_port_get_port_definition (GST_OMX_VIDEO_ENC (self)->enc_out_port,
+ &port_def);
+ port_def.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
+ err =
+ gst_omx_port_update_port_definition (GST_OMX_VIDEO_ENC
+ (self)->enc_out_port, &port_def);
+ if (err != OMX_ErrorNone)
+ return FALSE;
+
+ GST_OMX_INIT_STRUCT (¶m);
+ param.nPortIndex = GST_OMX_VIDEO_ENC (self)->enc_out_port->index;
+
+ err =
+ gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
+ OMX_IndexParamVideoProfileLevelCurrent, ¶m);
+ if (err != OMX_ErrorNone) {
+ GST_WARNING_OBJECT (self,
+ "Setting profile/level not supported by component");
+ return TRUE;
+ }
+
+ peercaps = gst_pad_peer_query_caps (GST_VIDEO_ENCODER_SRC_PAD (enc),
+ gst_pad_get_pad_template_caps (GST_VIDEO_ENCODER_SRC_PAD (enc)));
+ if (peercaps) {
+ GstStructure *s;
+
+ if (gst_caps_is_empty (peercaps)) {
+ gst_caps_unref (peercaps);
+ GST_ERROR_OBJECT (self, "Empty caps");
+ return FALSE;
+ }
+
+ s = gst_caps_get_structure (peercaps, 0);
+ profile_string = gst_structure_get_string (s, "profile");
+ if (profile_string) {
+ if (g_str_equal (profile_string, "main")) {
+ param.eProfile = OMX_VIDEO_HEVCProfileMain;
+ } else if (g_str_equal (profile_string, "main-10")) {
+ param.eProfile = OMX_VIDEO_HEVCProfileMain10;
+ } else {
+ goto unsupported_profile;
+ }
+ }
+ level_string = gst_structure_get_string (s, "level");
+ if (level_string) {
+ if (g_str_equal (level_string, "main1")) {
+ param.eLevel = OMX_VIDEO_HEVCMainTierLevel1;
+ } else if (g_str_equal (level_string, "high1")) {
+ param.eLevel = OMX_VIDEO_HEVCHighTierLevel1;
+ } else if (g_str_equal (level_string, "main2")) {
+ param.eLevel = OMX_VIDEO_HEVCMainTierLevel2;
+ } else if (g_str_equal (level_string, "high2")) {
+ param.eLevel = OMX_VIDEO_HEVCHighTierLevel2;
+ } else if (g_str_equal (level_string, "main2.1")) {
+ param.eLevel = OMX_VIDEO_HEVCMainTierLevel21;
+ } else if (g_str_equal (level_string, "high2.1")) {
+ param.eLevel = OMX_VIDEO_HEVCHighTierLevel21;
+ } else if (g_str_equal (level_string, "main3")) {
+ param.eLevel = OMX_VIDEO_HEVCMainTierLevel3;
+ } else if (g_str_equal (level_string, "high3")) {
+ param.eLevel = OMX_VIDEO_HEVCHighTierLevel3;
+ } else if (g_str_equal (level_string, "main3.1")) {
+ param.eLevel = OMX_VIDEO_HEVCMainTierLevel31;
+ } else if (g_str_equal (level_string, "high3.1")) {
+ param.eLevel = OMX_VIDEO_HEVCHighTierLevel31;
+ } else if (g_str_equal (level_string, "main4")) {
+ param.eLevel = OMX_VIDEO_HEVCMainTierLevel4;
+ } else if (g_str_equal (level_string, "high4")) {
+ param.eLevel = OMX_VIDEO_HEVCHighTierLevel4;
+ } else if (g_str_equal (level_string, "main4.1")) {
+ param.eLevel = OMX_VIDEO_HEVCMainTierLevel41;
+ } else if (g_str_equal (level_string, "high4.1")) {
+ param.eLevel = OMX_VIDEO_HEVCHighTierLevel41;
+ } else if (g_str_equal (level_string, "main5")) {
+ param.eLevel = OMX_VIDEO_HEVCMainTierLevel5;
+ } else if (g_str_equal (level_string, "high5")) {
+ param.eLevel = OMX_VIDEO_HEVCHighTierLevel5;
+ } else if (g_str_equal (level_string, "main5.1")) {
+ param.eLevel = OMX_VIDEO_HEVCMainTierLevel51;
+ } else if (g_str_equal (level_string, "high5.1")) {
+ param.eLevel = OMX_VIDEO_HEVCHighTierLevel51;
+ } else if (g_str_equal (level_string, "main5.2")) {
+ param.eLevel = OMX_VIDEO_HEVCMainTierLevel52;
+ } else if (g_str_equal (level_string, "high5.2")) {
+ param.eLevel = OMX_VIDEO_HEVCHighTierLevel52;
+ } else if (g_str_equal (level_string, "main6")) {
+ param.eLevel = OMX_VIDEO_HEVCMainTierLevel6;
+ } else if (g_str_equal (level_string, "high6")) {
+ param.eLevel = OMX_VIDEO_HEVCHighTierLevel6;
+ } else if (g_str_equal (level_string, "main61")) {
+ param.eLevel = OMX_VIDEO_HEVCMainTierLevel61;
+ } else if (g_str_equal (level_string, "high61")) {
+ param.eLevel = OMX_VIDEO_HEVCHighTierLevel61;
+ } else if (g_str_equal (level_string, "main62")) {
+ param.eLevel = OMX_VIDEO_HEVCMainTierLevel62;
+ } else if (g_str_equal (level_string, "high62")) {
+ param.eLevel = OMX_VIDEO_HEVCHighTierLevel62;
+ } else {
+ goto unsupported_level;
+ }
+ }
+ gst_caps_unref (peercaps);
+ }
+
+ err =
+ gst_omx_component_set_parameter (GST_OMX_VIDEO_ENC (self)->enc,
+ OMX_IndexParamVideoProfileLevelCurrent, ¶m);
+ if (err == OMX_ErrorUnsupportedIndex) {
+ GST_WARNING_OBJECT (self,
+ "Setting profile/level not supported by component");
+ } else if (err != OMX_ErrorNone) {
+ GST_ERROR_OBJECT (self,
+ "Error setting profile %u and level %u: %s (0x%08x)",
+ (guint) param.eProfile, (guint) param.eLevel,
+ gst_omx_error_to_string (err), err);
+ return FALSE;
+ }
+
+ return TRUE;
+
+unsupported_profile:
+ GST_ERROR_OBJECT (self, "Unsupported profile %s", profile_string);
+ gst_caps_unref (peercaps);
+ return FALSE;
+
+unsupported_level:
+ GST_ERROR_OBJECT (self, "Unsupported level %s", level_string);
+ gst_caps_unref (peercaps);
+ return FALSE;
+}
+
+static GstCaps *
+gst_omx_h265_enc_get_caps (GstOMXVideoEnc * enc, GstOMXPort * port,
+ GstVideoCodecState * state)
+{
+ GstOMXH265Enc *self = GST_OMX_H265_ENC (enc);
+ GstCaps *caps;
+ OMX_ERRORTYPE err;
+ OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
+ const gchar *profile, *level;
+
+ caps = gst_caps_new_simple ("video/x-h265",
+ "stream-format", G_TYPE_STRING, "byte-stream",
+ "alignment", G_TYPE_STRING, "au", NULL);
+
+ GST_OMX_INIT_STRUCT (¶m);
+ param.nPortIndex = GST_OMX_VIDEO_ENC (self)->enc_out_port->index;
+
+ err =
+ gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->enc,
+ OMX_IndexParamVideoProfileLevelCurrent, ¶m);
+ if (err != OMX_ErrorNone && err != OMX_ErrorUnsupportedIndex)
+ return NULL;
+
+ if (err == OMX_ErrorNone) {
+ switch (param.eProfile) {
+ case OMX_VIDEO_HEVCProfileMain:
+ profile = "main";
+ break;
+ case OMX_VIDEO_HEVCProfileMain10:
+ profile = "main-10";
+ break;
+ default:
+ g_assert_not_reached ();
+ return NULL;
+ }
+
+ switch (param.eLevel) {
+ case OMX_VIDEO_HEVCMainTierLevel1:
+ level = "main1";
+ break;
+ case OMX_VIDEO_HEVCHighTierLevel1:
+ level = "high1";
+ break;
+ case OMX_VIDEO_HEVCMainTierLevel2:
+ level = "main2";
+ break;
+ case OMX_VIDEO_HEVCHighTierLevel2:
+ level = "high2";
+ break;
+ case OMX_VIDEO_HEVCMainTierLevel21:
+ level = "main2.1";
+ break;
+ case OMX_VIDEO_HEVCHighTierLevel21:
+ level = "high2.1";
+ break;
+ case OMX_VIDEO_HEVCMainTierLevel3:
+ level = "main3";
+ break;
+ case OMX_VIDEO_HEVCHighTierLevel3:
+ level = "high3";
+ break;
+ case OMX_VIDEO_HEVCMainTierLevel31:
+ level = "main3.1";
+ break;
+ case OMX_VIDEO_HEVCHighTierLevel31:
+ level = "high3.1";
+ break;
+ case OMX_VIDEO_HEVCMainTierLevel4:
+ level = "main4";
+ break;
+ case OMX_VIDEO_HEVCHighTierLevel4:
+ level = "high4";
+ break;
+ case OMX_VIDEO_HEVCMainTierLevel41:
+ level = "main4.1";
+ break;
+ case OMX_VIDEO_HEVCHighTierLevel41:
+ level = "high4.1";
+ break;
+ case OMX_VIDEO_HEVCMainTierLevel5:
+ level = "main5";
+ break;
+ case OMX_VIDEO_HEVCHighTierLevel5:
+ level = "high5";
+ break;
+ case OMX_VIDEO_HEVCMainTierLevel51:
+ level = "main5.1";
+ break;
+ case OMX_VIDEO_HEVCHighTierLevel51:
+ level = "high5.1";
+ break;
+ case OMX_VIDEO_HEVCMainTierLevel52:
+ level = "main5.2";
+ break;
+ case OMX_VIDEO_HEVCHighTierLevel52:
+ level = "high5.2";
+ break;
+ case OMX_VIDEO_HEVCMainTierLevel6:
+ level = "main6";
+ break;
+ case OMX_VIDEO_HEVCHighTierLevel6:
+ level = "high6";
+ break;
+ case OMX_VIDEO_HEVCMainTierLevel61:
+ level = "main6.1";
+ break;
+ case OMX_VIDEO_HEVCHighTierLevel61:
+ level = "high6.1";
+ break;
+ case OMX_VIDEO_HEVCMainTierLevel62:
+ level = "main6.2";
+ break;
+ case OMX_VIDEO_HEVCHighTierLevel62:
+ level = "high6.2";
+ break;
+ default:
+ g_assert_not_reached ();
+ return NULL;
+ }
+
+ gst_caps_set_simple (caps,
+ "profile", G_TYPE_STRING, profile, "level", G_TYPE_STRING, level, NULL);
+ }
+
+ return caps;
+}
+
+static GstFlowReturn
+gst_omx_h265_enc_handle_output_frame (GstOMXVideoEnc * enc, GstOMXPort * port,
+ GstOMXBuffer * buf, GstVideoCodecFrame * frame)
+{
+ GstOMXH265Enc *self = GST_OMX_H265_ENC (enc);
+
+ if (buf->omx_buf->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
+ /* The codec data is SPS/PPS with a startcode => bytestream stream format
+ * For bytestream stream format the SPS/PPS is only in-stream and not
+ * in the caps!
+ */
+ if (buf->omx_buf->nFilledLen >= 4 &&
+ GST_READ_UINT32_BE (buf->omx_buf->pBuffer +
+ buf->omx_buf->nOffset) == 0x00000001) {
+ GstBuffer *hdrs;
+ GstMapInfo map = GST_MAP_INFO_INIT;
+
+ GST_DEBUG_OBJECT (self, "got codecconfig in byte-stream format");
+
+ hdrs = gst_buffer_new_and_alloc (buf->omx_buf->nFilledLen);
+
+ gst_buffer_map (hdrs, &map, GST_MAP_WRITE);
+ memcpy (map.data,
+ buf->omx_buf->pBuffer + buf->omx_buf->nOffset,
+ buf->omx_buf->nFilledLen);
+ gst_buffer_unmap (hdrs, &map);
+ self->headers = g_list_append (self->headers, hdrs);
+
+ if (frame)
+ gst_video_codec_frame_unref (frame);
+
+ return GST_FLOW_OK;
+ }
+ } else if (self->headers) {
+ gst_video_encoder_set_headers (GST_VIDEO_ENCODER (self), self->headers);
+ self->headers = NULL;
+ }
+
+ return
+ GST_OMX_VIDEO_ENC_CLASS
+ (gst_omx_h265_enc_parent_class)->handle_output_frame (enc, port, buf,
+ frame);
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Author: Sejun Park <sejun79.park@samsung.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef __GST_OMX_H265_ENC_H__
+#define __GST_OMX_H265_ENC_H__
+
+#include <gst/gst.h>
+#include "gstomxvideoenc.h"
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_OMX_H265_ENC \
+ (gst_omx_h265_enc_get_type())
+#define GST_OMX_H265_ENC(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMX_H265_ENC,GstOMXH265Enc))
+#define GST_OMX_H265_ENC_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMX_H265_ENC,GstOMXH265EncClass))
+#define GST_OMX_H265_ENC_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_OMX_H265_ENC,GstOMXH265EncClass))
+#define GST_IS_OMX_H265_ENC(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMX_H265_ENC))
+#define GST_IS_OMX_H265_ENC_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_H265_ENC))
+
+typedef struct _GstOMXH265Enc GstOMXH265Enc;
+typedef struct _GstOMXH265EncClass GstOMXH265EncClass;
+
+struct _GstOMXH265Enc
+{
+ GstOMXVideoEnc parent;
+
+#ifdef USE_OMX_TARGET_RPI
+ gboolean inline_sps_pps_headers;
+#endif
+ guint32 periodicty_idr;
+ guint32 interval_intraframes;
+
+ GList *headers;
+};
+
+struct _GstOMXH265EncClass
+{
+ GstOMXVideoEncClass parent_class;
+};
+
+GType gst_omx_h265_enc_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GST_OMX_H265_ENC_H__ */
+
#ifdef TIZEN_FEATURE_OMX
self->bufmgr = tbm_bufmgr_init(self->drm_fd);
- if(self->bufmgr == NULL) {
+ if (self->bufmgr == NULL) {
GST_ERROR_OBJECT (self, "TBM initialization failed.");
return FALSE;
}
#ifdef TIZEN_FEATURE_OMX
gchar *format_tmp;
int i;
- EnableGemBuffersParams gemBuffers;
- EnableGemBuffersParams config;
+ EnableGemBuffersParams gem_param;
#endif
GST_DEBUG_OBJECT (self, "Trying to negotiate a video format with downstream");
/* Set platform specific buffer settings. to avoid plane support error.. */
#ifdef TIZEN_FEATURE_OMX
- OMX_INIT_STRUCTURE(gemBuffers);
- gemBuffers.enable = OMX_TRUE;
- gemBuffers.nPortIndex = 1;
+ OMX_INIT_PARAM (gem_param);
+ gem_param.enable = OMX_TRUE;
+ gem_param.nPortIndex = 1;
OMX_INDEXTYPE index = OMX_IndexComponentStartUnused;
- err = OMX_GetExtensionIndex(self->dec->handle, "OMX.SEC.index.enablePlatformSpecificBuffers", &index);
+ err = OMX_GetExtensionIndex (self->dec->handle, "OMX.SEC.index.enablePlatformSpecificBuffers", &index);
if (err != OMX_ErrorNone || index == OMX_IndexComponentStartUnused) {
GST_INFO_OBJECT (self, "can not get index for OMX_GetExtensionIndex enablePlatformSpecificBuffers");
}
- err = gst_omx_component_set_parameter(self->dec, index, &gemBuffers);
+ err = gst_omx_component_set_parameter(self->dec, index, &gem_param);
#if 0
err =
gst_omx_error_to_string (err), err);
}
- OMX_INIT_STRUCTURE(config);
- config.enable = OMX_TRUE;
- config.nPortIndex = 0;
+ OMX_INIT_PARAM (gem_param);
+ gem_param.enable = OMX_TRUE;
+ gem_param.nPortIndex = 0;
err =
gst_omx_component_set_parameter (self->dec,
- OMX_IndexParamEnableTimestampReorder, &config);
+ OMX_IndexParamEnableTimestampReorder, &gem_param);
if (err != OMX_ErrorNone) {
GST_ERROR_OBJECT (self, "Failed to set timestamp reorder: %s (0x%08x)",
#include "gstomx.h"
-#define OMX_VERSION_MAJOR 1
-#define OMX_VERSION_MINOR 1
-#define OMX_VERSION_REVISION 2
-#define OMX_VERSION_STEP 0
-#define EXTRA_DECODER_OUTPUT_BUF 4
-
-#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 \
#define GST_IS_OMX_VIDEO_DEC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMX_VIDEO_DEC))
+#define EXTRA_DECODER_OUTPUT_BUF 4
+
typedef struct _GstOMXVideoDec GstOMXVideoDec;
typedef struct _GstOMXVideoDecClass GstOMXVideoDecClass;
#define GST_OMX_VIDEO_ENC_QUANT_P_FRAMES_DEFAULT (0xffffffff)
#define GST_OMX_VIDEO_ENC_QUANT_B_FRAMES_DEFAULT (0xffffffff)
+
/* class initialization */
#define DEBUG_INIT \
g_mutex_init (&self->drain_lock);
g_cond_init (&self->drain_cond);
#ifdef TIZEN_FEATURE_OMX
- self->hTBMBufMgr = NULL;
+ self->bufmgr = NULL;
self->drm_fd = -1;
#endif
}
}
#endif
+#ifdef TIZEN_FEATURE_OMX
+static void
+set_enable_platformSpecificBuffer(GstOMXVideoEnc * self)
+{
+ OMX_INDEXTYPE index = OMX_IndexComponentStartUnused;
+ OMX_ERRORTYPE err = OMX_ErrorNone;
+ EnableGemBuffersParams params;
+
+ GST_LOG_OBJECT (self, "set_enable_platformSpecificBuffer enter");
+
+ err = OMX_GetExtensionIndex(self->enc->handle, "OMX.SEC.index.enablePlatformSpecificBuffers", &index);
+ if (err != OMX_ErrorNone || index == OMX_IndexComponentStartUnused) {
+ GST_INFO_OBJECT (self, "can not get index for OMX_GetExtensionIndex enablePlatformSpecificBuffers");
+ return;
+ }
+
+ GST_INFO ("index= %x", index);
+
+ OMX_INIT_PARAM (params);
+
+ params.nPortIndex = self->enc_in_port->index;
+ params.enable = OMX_TRUE;
+
+ err = OMX_SetParameter(self->enc->handle, index, ¶ms);
+ if (err == OMX_ErrorNone) {
+ GST_INFO_OBJECT (self, "set_enable_platformSpecificBuffer success.");
+ }
+ else {
+ GST_ERROR_OBJECT (self, "set OMX_IndexParamEnablePlatformSpecificBuffers failed with error %d (0x%08x)", err, err);
+ }
+
+ return;
+}
+#endif
+
static gboolean
gst_omx_video_enc_open (GstVideoEncoder * encoder)
{
self->enc_in_port = gst_omx_component_add_port (self->enc, in_port_index);
self->enc_out_port = gst_omx_component_add_port (self->enc, out_port_index);
+#ifdef TIZEN_FEATURE_OMX
+ /* get extension index and set platform specific buffer enable */
+ set_enable_platformSpecificBuffer (self);
+#endif
+
if (!self->enc_in_port || !self->enc_out_port)
return FALSE;
if (self->quant_b_frames != 0xffffffff)
quant_param.nQpB = self->quant_b_frames;
+#ifdef TIZEN_FEATURE_OMX
+ quant_param.nQpI = 20;
+ quant_param.nQpP = 20;
+ quant_param.nQpB = 20;
+#endif
err =
gst_omx_component_set_parameter (self->enc,
OMX_IndexParamVideoQuantization, &quant_param);
}
}
+/*
+#ifdef TIZEN_FEATURE_OMX
+ {
+ OMX_VIDEO_PARAM_AVCTYPE param;
+
+ GST_OMX_INIT_STRUCT (¶m);
+ param.nPortIndex = self->enc_out_port->index;
+ err = gst_omx_component_get_parameter (self->enc, OMX_IndexParamVideoAvc, ¶m);
+ if (err != OMX_ErrorNone)
+ GST_ERROR_OBJECT (self, "Failed to get OMX_IndexParamVideoAvc parameter. ret = %d", err);
+
+ param.nPFrames = self->idr_period - 1;
+ err = gst_omx_component_set_parameter (self->enc, OMX_IndexParamVideoAvc, ¶m);
+ if (err != OMX_ErrorNone)
+ GST_ERROR_OBJECT (self, "Failed to set OMX_IndexParamVideoAvc. IDR period = %d ret = %d", self->idr_period, err);
+ }
+#endif
+*/
}
#ifdef TIZEN_FEATURE_OMX
- self->hTBMBufMgr = tbm_bufmgr_init(self->drm_fd);
- if(self->hTBMBufMgr == NULL){
+ self->bufmgr = tbm_bufmgr_init (self->drm_fd);
+ if (self->bufmgr == NULL){
GST_ERROR_OBJECT (self, "TBM initialization failed.");
return FALSE;
}
+
+ self->enc_in_port->use_buffer = klass->cdata.in_port_usebuffer;
+ self->enc_out_port->use_buffer = klass->cdata.out_port_usebuffer;
#endif
return TRUE;
}
self->input_state);
state->codec_data = codec_data;
gst_video_codec_state_unref (state);
+#ifdef TIZEN_FEATURE_OMX
+ /*Modification : codec data already set_caps, so unref frame whenever negotiate ok or not*/
+ if (!gst_video_encoder_negotiate (GST_VIDEO_ENCODER (self)))
+ flow_ret = GST_FLOW_NOT_NEGOTIATED;
+ else
+ flow_ret = GST_FLOW_OK;
+ gst_video_codec_frame_unref (frame);
+#else
if (!gst_video_encoder_negotiate (GST_VIDEO_ENCODER (self))) {
gst_video_codec_frame_unref (frame);
return GST_FLOW_NOT_NEGOTIATED;
}
flow_ret = GST_FLOW_OK;
+#endif
} else if (buf->omx_buf->nFilledLen > 0) {
GstBuffer *outbuf;
GstMapInfo map = GST_MAP_INFO_INIT;
if (err != OMX_ErrorNone)
goto reconfigure_error;
#ifdef TIZEN_FEATURE_OMX
- err = gst_omx_port_tbm_allocate_enc_buffers(port, self->hTBMBufMgr,
- self->enc_in_port->port_def.format.video.eCompressionFormat);
+ err = gst_omx_port_tbm_allocate_enc_buffers(port, self->bufmgr,
+ self->enc_in_port->port_def.format.video.eCompressionFormat, port->use_buffer);
#else
err = gst_omx_port_allocate_buffers (port);
#endif
}
port_def.format.video.nFrameWidth = info->width;
+#ifdef TIZEN_FEATURE_OMX
+ port_def.format.video.nStride = ALIGN(info->width, 16);
+#else
if (port_def.nBufferAlignment)
port_def.format.video.nStride =
(info->width + port_def.nBufferAlignment - 1) &
(~(port_def.nBufferAlignment - 1));
else
port_def.format.video.nStride = GST_ROUND_UP_4 (info->width); /* safe (?) default */
+#endif
port_def.format.video.nFrameHeight = info->height;
+#ifdef TIZEN_FEATURE_OMX
+ port_def.format.video.nSliceHeight = ALIGN(info->width, 16);
+#else
port_def.format.video.nSliceHeight = info->height;
+#endif
switch (port_def.format.video.eColorFormat) {
case OMX_COLOR_FormatYUV420Planar:
&port_def) != OMX_ErrorNone)
return FALSE;
+#ifdef TIZEN_FEATURE_OMX
+ /*MODIFICATION : Output port configuration*/
+ GST_DEBUG_OBJECT (self, "Updating outport port definition");
+ gst_omx_port_get_port_definition (self->enc_out_port, &port_def);
+
+ port_def.format.video.nFrameWidth = info->width;
+ port_def.format.video.nFrameHeight = info->height;
+
+ if (gst_omx_port_update_port_definition (self->enc_out_port, &port_def) != OMX_ErrorNone)
+ return FALSE;
+#endif
+
#ifdef USE_OMX_TARGET_RPI
/* aspect ratio */
{
if (gst_omx_port_set_enabled (self->enc_in_port, TRUE) != OMX_ErrorNone)
return FALSE;
#ifdef TIZEN_FEATURE_OMX
- if(gst_omx_port_tbm_allocate_enc_buffers(self->enc_in_port, self->hTBMBufMgr,
- self->enc_in_port->port_def.format.video.eCompressionFormat) != OMX_ErrorNone)
+ if (gst_omx_port_tbm_allocate_enc_buffers (self->enc_in_port, self->bufmgr,
+ self->enc_in_port->port_def.format.video.eCompressionFormat,
+ self->enc_in_port->use_buffer) != OMX_ErrorNone)
return FALSE;
#else
if (gst_omx_port_allocate_buffers (self->enc_in_port) != OMX_ErrorNone)
/* Need to allocate buffers to reach Idle state */
#ifdef TIZEN_FEATURE_OMX
- if(gst_omx_port_tbm_allocate_enc_buffers(self->enc_in_port, self->hTBMBufMgr,
- self->enc_in_port->port_def.format.video.eCompressionFormat) != OMX_ErrorNone)
+ if (gst_omx_port_tbm_allocate_enc_buffers(self->enc_in_port, self->bufmgr,
+ self->enc_in_port->port_def.format.video.eCompressionFormat,
+ self->enc_in_port->use_buffer) != OMX_ErrorNone)
return FALSE;
#else
if (gst_omx_port_allocate_buffers (self->enc_in_port) != OMX_ErrorNone)
#endif
#ifdef TIZEN_FEATURE_OMX
- if(gst_omx_port_tbm_allocate_enc_buffers(self->enc_out_port, self->hTBMBufMgr,
- self->enc_out_port->port_def.format.video.eCompressionFormat) != OMX_ErrorNone)
+ if (gst_omx_port_tbm_allocate_enc_buffers(self->enc_out_port, self->bufmgr,
+ self->enc_out_port->port_def.format.video.eCompressionFormat,
+ self->enc_out_port->use_buffer) != OMX_ErrorNone)
#else
if (gst_omx_port_allocate_buffers (self->enc_out_port) != OMX_ErrorNone)
#endif
goto reconfigure_error;
}
#ifdef TIZEN_FEATURE_OMX
- err = gst_omx_port_tbm_allocate_enc_buffers(port, self->hTBMBufMgr,
- self->enc_in_port->port_def.format.video.eCompressionFormat);
+ err = gst_omx_port_tbm_allocate_enc_buffers (port, self->bufmgr,
+ self->enc_in_port->port_def.format.video.eCompressionFormat, port->use_buffer);
#else
err = gst_omx_port_allocate_buffers (port);
#endif
GstFlowReturn downstream_flow_ret;
#ifdef TIZEN_FEATURE_OMX
gint drm_fd;
- tbm_bufmgr hTBMBufMgr;
+ tbm_bufmgr bufmgr;
#endif
};