summaryrefslogtreecommitdiff
path: root/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_h264enc.c
diff options
context:
space:
mode:
Diffstat (limited to 'gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_h264enc.c')
-rw-r--r--gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_h264enc.c374
1 files changed, 360 insertions, 14 deletions
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_h264enc.c b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_h264enc.c
index 82a2d65..6d4e9c5 100644
--- a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_h264enc.c
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_h264enc.c
@@ -3,6 +3,9 @@
*
* Author: Felipe Contreras <felipe.contreras@nokia.com>
*
+ * Modified by: David Soto <david.soto@ridgerun.com>
+ * Copyright (C) 2011 RidgeRun
+ *
* 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
@@ -21,6 +24,8 @@
#include "gstomx_h264enc.h"
#include "gstomx.h"
+#include <OMX_TI_Index.h>
+#include <OMX_TI_Video.h>
#include <string.h> /* for memset */
@@ -32,11 +37,18 @@ enum
ARG_BYTESTREAM,
ARG_PROFILE,
ARG_LEVEL,
+ ARG_I_PERIOD,
+ ARG_IDR_PERIOD,
+ ARG_FORCE_IDR,
+ ARG_ENCODING_PRESET,
+ ARG_RATECONTROL_PRESET,
};
#define DEFAULT_BYTESTREAM FALSE
-#define DEFAULT_PROFILE OMX_VIDEO_AVCProfileHigh
-#define DEFAULT_LEVEL OMX_VIDEO_AVCLevel4
+#define DEFAULT_PROFILE OMX_VIDEO_AVCProfileBaseline
+#define DEFAULT_LEVEL OMX_VIDEO_AVCLevel42
+#define DEFAULT_ENCODE_PRESET OMX_Video_Enc_High_Speed_Med_Quality
+#define DEFAULT_RATECONTROL_PRESET OMX_Video_RC_Low_Delay
#define GST_TYPE_OMX_VIDEO_AVCPROFILETYPE (gst_omx_video_avcprofiletype_get_type ())
static GType
@@ -99,6 +111,54 @@ gst_omx_video_avcleveltype_get_type ()
return type;
}
+#define GST_TYPE_OMX_VIDEO_ENCODE_PRESETTYPE (gst_omx_video_enocdepreset_get_type ())
+static GType
+gst_omx_video_enocdepreset_get_type ()
+{
+ static GType type = 0;
+
+ if (!type)
+ {
+ static const GEnumValue vals[] =
+ {
+ {OMX_Video_Enc_High_Quality, "High Quality", "hq"},
+ {OMX_Video_Enc_User_Defined, "User Defined", "user"},
+ {OMX_Video_Enc_High_Speed_Med_Quality, "High Speed Med Qual", "hsmq"},
+ {OMX_Video_Enc_Med_Speed_Med_Quality, "Med Speed Med Qaul", "msmq"},
+ {OMX_Video_Enc_Med_Speed_High_Quality, "Med Speed High Qaul", "mshq"},
+ {OMX_Video_Enc_High_Speed, "High Speed", "hs"},
+ {0, NULL, NULL },
+ };
+
+ type = g_enum_register_static ("GstOmxVideoEncoderPreset", vals);
+ }
+
+ return type;
+}
+
+#define GST_TYPE_OMX_VIDEO_RATECONTROL_PRESETTYPE (gst_omx_video_ratecontrolpreset_get_type ())
+static GType
+gst_omx_video_ratecontrolpreset_get_type ()
+{
+ static GType type = 0;
+
+ if (!type)
+ {
+ static const GEnumValue vals[] =
+ {
+ {OMX_Video_RC_Low_Delay, "Low Delay", "low-delay"},
+ {OMX_Video_RC_Storage, "Storage", "storage"},
+ {OMX_Video_RC_Twopass, "Two Pass", "two-pass"},
+ {OMX_Video_RC_None, "none", "none"},
+ {0, NULL, NULL },
+ };
+
+ type = g_enum_register_static ("GstOmxVideoRateControlPreset", vals);
+ }
+
+ return type;
+}
+
static GstCaps *
generate_src_template (void)
{
@@ -108,6 +168,8 @@ generate_src_template (void)
"width", GST_TYPE_INT_RANGE, 16, 4096,
"height", GST_TYPE_INT_RANGE, 16, 4096,
"framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1,
+ "stream-format", G_TYPE_STRING, "byte-stream",
+ "alignment", G_TYPE_STRING, "au",
NULL);
return caps;
@@ -150,11 +212,9 @@ set_property (GObject *obj,
{
GstOmxBaseFilter *omx_base;
GstOmxH264Enc *self;
- GOmxCore *gomx;
omx_base = GST_OMX_BASE_FILTER (obj);
self = GST_OMX_H264ENC (obj);
- gomx = (GOmxCore*) omx_base->gomx;
switch (prop_id)
{
@@ -162,15 +222,14 @@ set_property (GObject *obj,
self->bytestream = g_value_get_boolean (value);
break;
case ARG_PROFILE:
+ #if 0
{
OMX_VIDEO_PARAM_PROFILELEVELTYPE tProfileLevel;
- GOmxCore *gomx;
OMX_ERRORTYPE error_val = OMX_ErrorNone;
- gomx = (GOmxCore *) omx_base->gomx;
_G_OMX_INIT_PARAM (&tProfileLevel);
tProfileLevel.nPortIndex = omx_base->out_port->port_index;
- error_val = OMX_GetParameter (gomx->omx_handle,
+ error_val = OMX_GetParameter (g_omx_core_get_handle (omx_base->gomx),
OMX_IndexParamVideoProfileLevelCurrent,
&tProfileLevel);
g_assert (error_val == OMX_ErrorNone);
@@ -178,22 +237,25 @@ set_property (GObject *obj,
GST_DEBUG_OBJECT (self, "Profile: param=%d",
(gint)tProfileLevel.eProfile);
- error_val = OMX_SetParameter (gomx->omx_handle,
+ error_val = OMX_SetParameter (g_omx_core_get_handle (omx_base->gomx),
OMX_IndexParamVideoProfileLevelCurrent,
&tProfileLevel);
g_assert (error_val == OMX_ErrorNone);
break;
}
+ #else
+ self->profile = g_value_get_enum(value);
+ break;
+ #endif
case ARG_LEVEL:
+ #if 0
{
OMX_VIDEO_PARAM_PROFILELEVELTYPE tProfileLevel;
- GOmxCore *gomx;
OMX_ERRORTYPE error_val = OMX_ErrorNone;
- gomx = (GOmxCore *) omx_base->gomx;
_G_OMX_INIT_PARAM (&tProfileLevel);
tProfileLevel.nPortIndex = omx_base->out_port->port_index;
- error_val = OMX_GetParameter (gomx->omx_handle,
+ error_val = OMX_GetParameter (g_omx_core_get_handle (omx_base->gomx),
OMX_IndexParamVideoProfileLevelCurrent,
&tProfileLevel);
g_assert (error_val == OMX_ErrorNone);
@@ -201,12 +263,101 @@ set_property (GObject *obj,
GST_DEBUG_OBJECT (self, "Level: param=%d",
(gint)tProfileLevel.eLevel);
- error_val = OMX_SetParameter (gomx->omx_handle,
+ error_val = OMX_SetParameter (g_omx_core_get_handle (omx_base->gomx),
OMX_IndexParamVideoProfileLevelCurrent,
&tProfileLevel);
g_assert (error_val == OMX_ErrorNone);
break;
}
+ #else
+ self->level = g_value_get_enum(value);
+ break;
+ #endif
+ case ARG_I_PERIOD:
+ #if 0
+ {
+ OMX_VIDEO_CONFIG_AVCINTRAPERIOD avcIntraPeriod;
+ OMX_ERRORTYPE error_val = OMX_ErrorNone;
+
+ _G_OMX_INIT_PARAM (&avcIntraPeriod);
+ avcIntraPeriod.nPortIndex = omx_base->out_port->port_index;
+ error_val = OMX_GetConfig (g_omx_core_get_handle (omx_base->gomx),
+ OMX_IndexConfigVideoAVCIntraPeriod,
+ (OMX_PTR)&avcIntraPeriod);
+ g_assert (error_val == OMX_ErrorNone);
+ avcIntraPeriod.nPFrames = g_value_get_uint (value);
+
+ if(value>0)
+ {
+ error_val = OMX_SetConfig (g_omx_core_get_handle (omx_base->gomx),
+ OMX_IndexConfigVideoAVCIntraPeriod,
+ &avcIntraPeriod);
+ }
+ g_assert (error_val == OMX_ErrorNone);
+ break;
+ }
+ #else
+ self->i_period = g_value_get_uint (value);
+ break;
+ #endif
+ case ARG_IDR_PERIOD:
+ {
+ self->idr_period = g_value_get_uint (value);
+ break;
+ }
+ case ARG_FORCE_IDR:
+ {
+ self->force_idr = g_value_get_boolean (value);
+ break;
+ }
+ case ARG_ENCODING_PRESET:
+ {
+ #if 0
+ OMX_ERRORTYPE error_val = OMX_ErrorNone;
+ OMX_VIDEO_PARAM_ENCODER_PRESETTYPE tEncoderPreset;
+ _G_OMX_INIT_PARAM(&tEncoderPreset);
+ tEncoderPreset.nPortIndex = omx_base->out_port->port_index;
+
+ error_val =
+ OMX_GetParameter(g_omx_core_get_handle (omx_base->gomx),
+ OMX_TI_IndexParamVideoEncoderPreset,
+ &tEncoderPreset);
+ g_assert (error_val == OMX_ErrorNone);
+
+ tEncoderPreset.eEncodingModePreset = g_value_get_enum (value);
+ error_val = OMX_SetParameter(g_omx_core_get_handle (omx_base->gomx),
+ OMX_TI_IndexParamVideoEncoderPreset,
+ &tEncoderPreset);
+ g_assert (error_val == OMX_ErrorNone);
+ #else
+ self->encodingPreset = g_value_get_enum(value);
+ #endif
+ break;
+ }
+ case ARG_RATECONTROL_PRESET:
+ {
+ #if 0
+ OMX_ERRORTYPE error_val = OMX_ErrorNone;
+ OMX_VIDEO_PARAM_ENCODER_PRESETTYPE tEncoderPreset;
+ _G_OMX_INIT_PARAM(&tEncoderPreset);
+ tEncoderPreset.nPortIndex = omx_base->out_port->port_index;
+
+ error_val =
+ OMX_GetParameter(g_omx_core_get_handle (omx_base->gomx),
+ OMX_TI_IndexParamVideoEncoderPreset,
+ &tEncoderPreset);
+ g_assert (error_val == OMX_ErrorNone);
+
+ tEncoderPreset.eRateControlPreset = g_value_get_enum (value);
+ error_val = OMX_SetParameter(g_omx_core_get_handle (omx_base->gomx),
+ OMX_TI_IndexParamVideoEncoderPreset,
+ &tEncoderPreset);
+ g_assert (error_val == OMX_ErrorNone);
+ #else
+ self->ratecontrolPreset = g_value_get_enum(value);
+ #endif
+ break;
+ }
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
@@ -231,6 +382,7 @@ get_property (GObject *obj,
g_value_set_boolean (value, self->bytestream);
break;
case ARG_PROFILE:
+ #if 0
{
OMX_VIDEO_PARAM_PROFILELEVELTYPE tProfileLevel;
GOmxCore *gomx;
@@ -250,7 +402,12 @@ get_property (GObject *obj,
break;
}
+ #else
+ g_value_set_enum(value, self->profile);
+ break;
+ #endif
case ARG_LEVEL:
+ #if 0
{
OMX_VIDEO_PARAM_PROFILELEVELTYPE tProfileLevel;
GOmxCore *gomx;
@@ -270,6 +427,82 @@ get_property (GObject *obj,
break;
}
+ #else
+ g_value_set_enum(value, self->level);
+ break;
+ #endif
+ case ARG_I_PERIOD:
+ #if 0
+ {
+ OMX_VIDEO_CONFIG_AVCINTRAPERIOD avcIntraPeriod;
+ GOmxCore *gomx;
+
+ gomx = (GOmxCore *) omx_base->gomx;
+ _G_OMX_INIT_PARAM (&avcIntraPeriod);
+ avcIntraPeriod.nPortIndex = omx_base->out_port->port_index;
+ OMX_GetConfig (gomx->omx_handle,
+ OMX_IndexConfigVideoAVCIntraPeriod,
+ &avcIntraPeriod);
+ g_value_set_uint (value, (gint)avcIntraPeriod.nPFrames);
+
+ break;
+ }
+ #else
+ g_value_set_uint(value, self->i_period);
+ break;
+ #endif
+ case ARG_IDR_PERIOD:
+ {
+ g_value_set_uint (value, self->idr_period);
+
+ break;
+ }
+ case ARG_FORCE_IDR:
+ {
+ g_value_set_boolean (value, self->force_idr);
+
+ break;
+ }
+ case ARG_ENCODING_PRESET:
+ {
+ #if 0
+ OMX_VIDEO_PARAM_ENCODER_PRESETTYPE tEncoderPreset;
+ GOmxCore *gomx;
+ OMX_ERRORTYPE error_val = OMX_ErrorNone;
+
+ gomx = (GOmxCore *) omx_base->gomx;
+ error_val = OMX_GetParameter(gomx->omx_handle, OMX_TI_IndexParamVideoEncoderPreset,
+ &tEncoderPreset);
+
+ g_value_set_enum (value, tEncoderPreset.eEncodingModePreset);
+
+ GST_DEBUG_OBJECT (self, "Encoding Preset: param=%d",
+ (gint)tEncoderPreset.eEncodingModePreset);
+ #else
+ g_value_set_enum(value, self->encodingPreset);
+ #endif
+ break;
+ }
+ case ARG_RATECONTROL_PRESET:
+ {
+ #if 0
+ OMX_VIDEO_PARAM_ENCODER_PRESETTYPE tEncoderPreset;
+ GOmxCore *gomx;
+ OMX_ERRORTYPE error_val = OMX_ErrorNone;
+
+ gomx = (GOmxCore *) omx_base->gomx;
+ error_val = OMX_GetParameter(gomx->omx_handle, OMX_TI_IndexParamVideoEncoderPreset,
+ &tEncoderPreset);
+
+ g_value_set_enum (value, tEncoderPreset.eRateControlPreset);
+
+ GST_DEBUG_OBJECT (self, "RateControl Preset: param=%d",
+ (gint)tEncoderPreset.eRateControlPreset);
+ #else
+ g_value_set_enum(value, self->ratecontrolPreset);
+ #endif
+ break;
+ }
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
@@ -304,8 +537,73 @@ type_class_init (gpointer g_class,
GST_TYPE_OMX_VIDEO_AVCLEVELTYPE,
DEFAULT_LEVEL,
G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class, ARG_I_PERIOD,
+ g_param_spec_uint ("i-period", "Specifies periodicity of I frames",
+ "Specifies periodicity of I frames (0:Disable)",
+ 0, G_MAXINT32, 90, G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class, ARG_IDR_PERIOD,
+ g_param_spec_uint ("force-idr-period", "Specifies periodicity of IDR frames",
+ "Specifies periodicity of IDR frames (0:Disable)",
+ 0, G_MAXINT32, 0, G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class, ARG_FORCE_IDR,
+ g_param_spec_boolean ("force-idr", "force-idr", "force next frame to be IDR",
+ FALSE, G_PARAM_WRITABLE));
+ g_object_class_install_property (gobject_class, ARG_ENCODING_PRESET,
+ g_param_spec_enum ("encodingPreset", "Specifies which encoding preset to use",
+ "Specifies which encoding preset to use",
+ GST_TYPE_OMX_VIDEO_ENCODE_PRESETTYPE,
+ DEFAULT_ENCODE_PRESET,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class, ARG_RATECONTROL_PRESET,
+ g_param_spec_enum ("rateControlPreset", "Specifies what rate control preset to use",
+ "Specifies what rate control preset to use",
+ GST_TYPE_OMX_VIDEO_RATECONTROL_PRESETTYPE,
+ DEFAULT_RATECONTROL_PRESET,
+ G_PARAM_READWRITE));
+
+ }
+}
+
+static void
+omx_h264_push_cb (GstOmxBaseFilter *omx_base, GstBuffer *buf)
+{
+ GstOmxH264Enc *self;
+ self = GST_OMX_H264ENC (omx_base);
+ /* Currently we use this logic to handle IDR period since the latest
+ * EZSDK version doesn't have support for OMX_IndexConfigVideoAVCIntraPeriod
+ */
+ if ((self->idr_period > 0) || (self->force_idr))
+ {
+ if ((self->cont == self->idr_period) || (self->force_idr))
+ {
+ OMX_CONFIG_INTRAREFRESHVOPTYPE confIntraRefreshVOP;
+
+ _G_OMX_INIT_PARAM (&confIntraRefreshVOP);
+ confIntraRefreshVOP.nPortIndex = omx_base->out_port->port_index;
+
+ OMX_GetConfig (g_omx_core_get_handle (omx_base->gomx),
+ OMX_IndexConfigVideoIntraVOPRefresh,
+ &confIntraRefreshVOP);
+ confIntraRefreshVOP.IntraRefreshVOP = TRUE;
+
+ OMX_SetConfig (g_omx_core_get_handle (omx_base->gomx),
+ OMX_IndexConfigVideoIntraVOPRefresh,
+ &confIntraRefreshVOP);
+
+ if (self->cont == self->idr_period)
+ self->cont = 0;
+
+ if (self->force_idr)
+ {
+ self->force_idr = FALSE;
+ self->cont++;
+ }
+ } else {
+ self->cont++;
+ }
}
+ GST_BUFFER_CAPS(buf) = gst_caps_ref(GST_PAD_CAPS(omx_base->srcpad));
}
static void
@@ -313,7 +611,9 @@ omx_setup (GstOmxBaseFilter *omx_base)
{
GstOmxBaseVideoEnc *self;
GOmxCore *gomx;
+ GstOmxH264Enc *h264enc;
+ h264enc = GST_OMX_H264ENC (omx_base);
self = GST_OMX_BASE_VIDEOENC (omx_base);
gomx = (GOmxCore *) omx_base->gomx;
@@ -325,9 +625,7 @@ omx_setup (GstOmxBaseFilter *omx_base)
if (OMX_GetExtensionIndex (gomx->omx_handle, "OMX.TI.VideoEncode.Config.NALFormat", &index) == OMX_ErrorNone)
{
OMX_U32 nal_format;
- GstOmxH264Enc *h264enc;
- h264enc = GST_OMX_H264ENC (omx_base);
nal_format = h264enc->bytestream ? 0 : 1;
GST_DEBUG_OBJECT (omx_base, "setting 'OMX.TI.VideoEncode.Config.NALFormat' to %ld", nal_format);
@@ -339,6 +637,36 @@ omx_setup (GstOmxBaseFilter *omx_base)
}
}
+ {
+ OMX_VIDEO_PARAM_AVCTYPE tAVCParams;
+
+ _G_OMX_INIT_PARAM (&tAVCParams);
+
+ tAVCParams.nPortIndex = OMX_DirOutput;
+ OMX_GetParameter(gomx->omx_handle, OMX_IndexParamVideoAvc, &tAVCParams);
+
+ tAVCParams.eLevel = h264enc->level;
+ tAVCParams.eProfile = h264enc->profile;
+ tAVCParams.nPFrames = h264enc->i_period - 1;
+ tAVCParams.nBFrames = 0;
+
+ OMX_SetParameter(gomx->omx_handle, OMX_IndexParamVideoAvc, &tAVCParams);
+ }
+
+ {
+ OMX_VIDEO_PARAM_ENCODER_PRESETTYPE tEncoderPreset;
+
+ _G_OMX_INIT_PARAM(&tEncoderPreset);
+ tEncoderPreset.nPortIndex = omx_base->out_port->port_index;
+
+ OMX_GetParameter(gomx->omx_handle, OMX_TI_IndexParamVideoEncoderPreset, &tEncoderPreset);
+
+ tEncoderPreset.eEncodingModePreset = h264enc->encodingPreset;
+ tEncoderPreset.eRateControlPreset = h264enc->ratecontrolPreset;
+
+ OMX_SetParameter(gomx->omx_handle, OMX_TI_IndexParamVideoEncoderPreset, &tEncoderPreset);
+ }
+
GST_INFO_OBJECT (omx_base, "end");
}
@@ -371,6 +699,8 @@ settings_changed_cb (GOmxCore *core)
"height", G_TYPE_INT, height,
"framerate", GST_TYPE_FRACTION,
omx_base->framerate_num, omx_base->framerate_denom,
+ "stream-format", G_TYPE_STRING, "byte-stream",
+ "alignment", G_TYPE_STRING, "au",
NULL);
GST_INFO_OBJECT (omx_base, "caps are: %" GST_PTR_FORMAT, new_caps);
@@ -384,13 +714,29 @@ type_instance_init (GTypeInstance *instance,
{
GstOmxBaseFilter *omx_base_filter;
GstOmxBaseVideoEnc *omx_base;
+ GstOmxBaseFilterClass *bclass;
+ GstOmxH264Enc *self;
omx_base_filter = GST_OMX_BASE_FILTER (instance);
omx_base = GST_OMX_BASE_VIDEOENC (instance);
+ self = GST_OMX_H264ENC (instance);
+ bclass = GST_OMX_BASE_FILTER_CLASS (g_class);
omx_base->omx_setup = omx_setup;
+ omx_base_filter->push_cb = omx_h264_push_cb;
+
omx_base->compression_format = OMX_VIDEO_CodingAVC;
omx_base_filter->gomx->settings_changed_cb = settings_changed_cb;
+
+ self->idr_period = 0;
+ self->cont = 0;
+ self->force_idr = FALSE;
+
+ self->i_period = 90;
+ self->profile = DEFAULT_PROFILE;
+ self->level = DEFAULT_LEVEL;
+ self->encodingPreset = OMX_Video_Enc_High_Speed_Med_Quality;
+ self->ratecontrolPreset = OMX_Video_RC_Low_Delay;
}