diff --git a/src/gstducatih264enc.c b/src/gstducatih264enc.c
index 7fbdccb4ac2d70997eb3d4cc20552b2cffcc15cb..683a311b5a60b4f2a32ac3bbd44cb0900dc67d12 100644 (file)
--- a/src/gstducatih264enc.c
+++ b/src/gstducatih264enc.c
#define GST_CAT_DEFAULT gst_ducati_debug
-#define DEFAULT_PROFILE GST_DUCATI_H264ENC_PROFILE_HIGH
-#define DEFAULT_LEVEL GST_DUCATI_H264ENC_LEVEL_40
-#define DEFAULT_BITRATE 2048
-#define DEFAULT_RATE_PRESET GST_DUCATI_H264ENC_RATE_PRESET_LOW_DELAY
+#define DEFAULT_PROFILE IH264_HIGH_PROFILE
+#define DEFAULT_LEVEL IH264_LEVEL_40
+#define DEFAULT_QPI 28
+#define DEFAULT_QP_MAX_I 36
+#define DEFAULT_QP_MIN_I 10
+/* 2 x targetBitRate for VBR Rate Control */
+#define DEFAULT_HRD_BUFFER_SIZE 40960000
+#define DEFAULT_INTER_INTERVAL 4
#define GST_TYPE_DUCATI_H264ENC_PROFILE (gst_ducati_h264enc_profile_get_type ())
#define GST_TYPE_DUCATI_H264ENC_LEVEL (gst_ducati_h264enc_level_get_type ())
-#define GST_TYPE_DUCATI_H264ENC_RATE_PRESET (gst_ducati_h264enc_rate_preset_get_type ())
+#define GST_TYPE_DUCATI_H264ENC_RCPP (gst_ducati_h264enc_get_rate_control_params_preset_type ())
+#define GST_TYPE_DUCATI_H264ENC_RATE_CONTROL_ALGO (gst_ducati_h264enc_get_rate_control_algo_type ())
+#define GST_TYPE_DUCATI_H264ENC_ENTROPY_CODING_MODE (gst_ducati_h264enc_get_entropy_coding_mode_type ())
+#define GST_TYPE_DUCATI_H264ENC_SLICE_MODE (gst_ducati_h264enc_get_slice_mode_type ())
enum
PROP_0,
PROP_PROFILE,
PROP_LEVEL,
- PROP_BITRATE,
- PROP_RATE_PRESET
+ PROP_RATE_CONTROL_PARAMS_PRESET,
+ PROP_RATE_CONTROL_ALGO,
+ PROP_QPI,
+ PROP_QP_MAX_I,
+ PROP_QP_MIN_I,
+ PROP_HRD_BUFFER_SIZE,
+ PROP_ENTROPY_CODING_MODE,
+ PROP_INTER_INTERVAL,
+ PROP_SLICE_MODE,
};
static void gst_ducati_h264enc_set_property (GObject * object, guint prop_id,
static void gst_ducati_h264enc_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
-static gboolean gst_ducati_h264enc_set_format (GstBaseVideoEncoder *
- base_video_encoder, GstVideoState * state);
-static gboolean gst_ducati_h264enc_start (GstBaseVideoEncoder *
- base_video_encoder);
-static gboolean gst_ducati_h264enc_stop (GstBaseVideoEncoder *
- base_video_encoder);
-static GstFlowReturn gst_ducati_h264enc_finish (GstBaseVideoEncoder *
- base_video_encoder);
-static GstFlowReturn gst_ducati_h264enc_handle_frame (GstBaseVideoEncoder *
- base_video_encoder, GstVideoFrame * frame);
+static gboolean gst_ducati_h264enc_allocate_params (GstDucatiVidEnc *
+ self, gint params_sz, gint dynparams_sz, gint status_sz, gint inargs_sz,
+ gint outargs_sz);
+static gboolean gst_ducati_h264enc_configure (GstDucatiVidEnc * self);
+static gboolean gst_ducati_h264enc_is_sync_point (GstDucatiVidEnc * enc,
+ int type);
+
static GstStaticPadTemplate gst_ducati_h264enc_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("video/x-h264")
+ GST_STATIC_CAPS
+ ("video/x-h264, alignment=(string)au, stream-format=(string)byte-stream")
);
-GST_BOILERPLATE (GstDucatiH264Enc, gst_ducati_h264enc, GstBaseVideoEncoder,
- GST_TYPE_BASE_VIDEO_ENCODER);
-
+GST_BOILERPLATE (GstDucatiH264Enc, gst_ducati_h264enc, GstDucatiVidEnc,
+ GST_TYPE_DUCATIVIDENC);
-/* the values for the following enums are taken from the codec */
-enum
+static GType
+gst_ducati_h264enc_profile_get_type (void)
{
- GST_DUCATI_H264ENC_PROFILE_BASELINE = 66, /**< BaseLine Profile */
- GST_DUCATI_H264ENC_PROFILE_MAIN = 77, /**< Main Profile */
- GST_DUCATI_H264ENC_PROFILE_EXTENDED = 88, /**< Extended Profile */
- GST_DUCATI_H264ENC_PROFILE_HIGH = 100, /**< High Profile */
- GST_DUCATI_H264ENC_PROFILE_HIGH_10 = 110, /**< High 10 Profile */
- GST_DUCATI_H264ENC_PROFILE_HIGH_422 = 122 /**< High 4:2:2 Profile */
-};
+ static GType type = 0;
-enum
-{
- GST_DUCATI_H264ENC_LEVEL_10 = 10, /**< Level 1.0 */
- GST_DUCATI_H264ENC_LEVEL_1b = 9, /**< Level 1.b */
- GST_DUCATI_H264ENC_LEVEL_11 = 11, /**< Level 1.1 */
- GST_DUCATI_H264ENC_LEVEL_12 = 12, /**< Level 1.2 */
- GST_DUCATI_H264ENC_LEVEL_13 = 13, /**< Level 1.3 */
- GST_DUCATI_H264ENC_LEVEL_20 = 20, /**< Level 2.0 */
- GST_DUCATI_H264ENC_LEVEL_21 = 21, /**< Level 2.1 */
- GST_DUCATI_H264ENC_LEVEL_22 = 22, /**< Level 2.2 */
- GST_DUCATI_H264ENC_LEVEL_30 = 30, /**< Level 3.0 */
- GST_DUCATI_H264ENC_LEVEL_31 = 31, /**< Level 3.1 */
- GST_DUCATI_H264ENC_LEVEL_32 = 32, /**< Level 3.2 */
- GST_DUCATI_H264ENC_LEVEL_40 = 40, /**< Level 4.0 */
- GST_DUCATI_H264ENC_LEVEL_41 = 41, /**< Level 4.1 */
- GST_DUCATI_H264ENC_LEVEL_42 = 42, /**< Level 4.2 */
- GST_DUCATI_H264ENC_LEVEL_50 = 50, /**< Level 5.0 */
- GST_DUCATI_H264ENC_LEVEL_51 = 51 /**< Level 5.1 */
-};
+ if (!type) {
+ static const GEnumValue vals[] = {
+ {IH264_BASELINE_PROFILE, "Base Profile", "baseline"},
+ {IH264_MAIN_PROFILE, "Main Profile", "main"},
+ {IH264_EXTENDED_PROFILE, "Extended Profile", "extended"},
+ {IH264_HIGH_PROFILE, "High Profile", "high"},
+ {IH264_HIGH10_PROFILE, "High 10 Profile", "high-10"},
+ {IH264_HIGH422_PROFILE, "High 4:2:2 Profile", "high-422"},
+ {0, NULL, NULL},
+ };
-enum
+ type = g_enum_register_static ("GstDucatiH264EncProfile", vals);
+ }
+
+ return type;
+}
+
+static GType
+gst_ducati_h264enc_get_rate_control_params_preset_type (void)
{
- GST_DUCATI_H264ENC_RATE_PRESET_LOW_DELAY = 1, /**< CBR rate control for video conferencing. */
- GST_DUCATI_H264ENC_RATE_PRESET_STORAGE = 2, /**< VBR rate control for local storage (DVD)
- * recording.
- */
- GST_DUCATI_H264ENC_RATE_PRESET_TWOPASS = 3, /**< Two pass rate control for non real time
- * applications.
- */
- GST_DUCATI_H264ENC_RATE_PRESET_NONE = 4, /**< No configurable video rate control
- * mechanism.
- */
- GST_DUCATI_H264ENC_RATE_PRESET_USER_DEFINED = 5,/**< User defined configuration using extended
- * parameters.
- */
-};
+ static GType type = 0;
+
+ if (!type) {
+ static const GEnumValue vals[] = {
+ {IH264_RATECONTROLPARAMS_DEFAULT, "Rate Control params preset default",
+ "rate-control-params-preset-default"},
+ {IH264_RATECONTROLPARAMS_USERDEFINED, "User defined rate control",
+ "rate-control-params-preset-user-defined"},
+ {IH264_RATECONTROLPARAMS_EXISTING, "Existing rate control params",
+ "rate-control-params-preset-existing"},
+ {0, NULL, NULL},
+ };
+
+ type = g_enum_register_static ("GstDucatiH264EncRateControlParams", vals);
+ }
+
+ return type;
+}
static GType
-gst_ducati_h264enc_profile_get_type (void)
+gst_ducati_h264enc_get_rate_control_algo_type (void)
{
static GType type = 0;
if (!type) {
static const GEnumValue vals[] = {
- {GST_DUCATI_H264ENC_PROFILE_BASELINE, "Base Profile", "baseline"},
- {GST_DUCATI_H264ENC_PROFILE_MAIN, "Main Profile", "main"},
- {GST_DUCATI_H264ENC_PROFILE_EXTENDED, "Extended Profile", "extended"},
- {GST_DUCATI_H264ENC_PROFILE_HIGH, "High Profile", "high"},
- {GST_DUCATI_H264ENC_PROFILE_HIGH_10, "High 10 Profile", "high-10"},
- {GST_DUCATI_H264ENC_PROFILE_HIGH_422, "High 4:2:2 Profile", "high-422"},
+ {IH264_RATECONTROL_PRC, "Perceptual rate control",
+ "perceptual-rate-control"},
+ {IH264_RATECONTROL_PRC_LOW_DELAY, "Low delay rate control",
+ "low-delay-rate-control"},
{0, NULL, NULL},
};
- type = g_enum_register_static ("GstDucatiH264EncProfile", vals);
+ type = g_enum_register_static ("GstDucatiH264EncRateControlAlgo", vals);
}
return type;
if (!type) {
static const GEnumValue vals[] = {
- {GST_DUCATI_H264ENC_LEVEL_10, "Level 1", "level-1"},
- {GST_DUCATI_H264ENC_LEVEL_1b, "Level 1b", "level-1b"},
- {GST_DUCATI_H264ENC_LEVEL_11, "Level 11", "level-11"},
- {GST_DUCATI_H264ENC_LEVEL_12, "Level 12", "level-12"},
- {GST_DUCATI_H264ENC_LEVEL_13, "Level 13", "level-13"},
- {GST_DUCATI_H264ENC_LEVEL_20, "Level 2", "level-2"},
- {GST_DUCATI_H264ENC_LEVEL_21, "Level 21", "level-21"},
- {GST_DUCATI_H264ENC_LEVEL_22, "Level 22", "level-22"},
- {GST_DUCATI_H264ENC_LEVEL_30, "Level 3", "level-3"},
- {GST_DUCATI_H264ENC_LEVEL_31, "Level 31", "level-31"},
- {GST_DUCATI_H264ENC_LEVEL_32, "Level 32", "level-32"},
- {GST_DUCATI_H264ENC_LEVEL_40, "Level 4", "level-4"},
- {GST_DUCATI_H264ENC_LEVEL_41, "Level 41", "level-41"},
- {GST_DUCATI_H264ENC_LEVEL_42, "Level 42", "level-42"},
- {GST_DUCATI_H264ENC_LEVEL_50, "Level 5", "level-5"},
- {GST_DUCATI_H264ENC_LEVEL_51, "Level 51", "level-51"},
+ {IH264_LEVEL_10, "Level 1", "level-1"},
+ {IH264_LEVEL_1b, "Level 1b", "level-1b"},
+ {IH264_LEVEL_11, "Level 11", "level-11"},
+ {IH264_LEVEL_12, "Level 12", "level-12"},
+ {IH264_LEVEL_13, "Level 13", "level-13"},
+ {IH264_LEVEL_20, "Level 2", "level-2"},
+ {IH264_LEVEL_21, "Level 21", "level-21"},
+ {IH264_LEVEL_22, "Level 22", "level-22"},
+ {IH264_LEVEL_30, "Level 3", "level-3"},
+ {IH264_LEVEL_31, "Level 31", "level-31"},
+ {IH264_LEVEL_32, "Level 32", "level-32"},
+ {IH264_LEVEL_40, "Level 4", "level-4"},
+ {IH264_LEVEL_41, "Level 41", "level-41"},
+ {IH264_LEVEL_42, "Level 42", "level-42"},
+ {IH264_LEVEL_50, "Level 5", "level-5"},
+ {IH264_LEVEL_51, "Level 51", "level-51"},
{0, NULL, NULL},
};
}
static GType
-gst_ducati_h264enc_rate_preset_get_type (void)
+gst_ducati_h264enc_get_entropy_coding_mode_type (void)
{
static GType type = 0;
if (!type) {
static const GEnumValue vals[] = {
- {GST_DUCATI_H264ENC_RATE_PRESET_LOW_DELAY, "Low Delay", "low-delay"},
- {GST_DUCATI_H264ENC_RATE_PRESET_STORAGE, "Storage", "storage"},
- {GST_DUCATI_H264ENC_RATE_PRESET_TWOPASS, "Two-Pass", "two-pass"},
+ {IH264_ENTROPYCODING_CAVLC, "CAVLC coding type", "cavlc"},
+ {IH264_ENTROPYCODING_CABAC, "Cabac coding mode", "cabac"},
{0, NULL, NULL},
};
- type = g_enum_register_static ("GstDucatiH264EncRatePreset", vals);
+ type = g_enum_register_static ("GstDucatiEntropyCodingMode", vals);
+ }
+
+ return type;
+}
+
+static GType
+gst_ducati_h264enc_get_slice_mode_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ static const GEnumValue vals[] = {
+ {IH264_SLICEMODE_NONE, "No slice mode", "none"},
+ {IH264_SLICEMODE_MBUNIT,
+ "Slices are controlled based upon number of Macroblocks", "mbunit"},
+ {IH264_SLICEMODE_BYTES,
+ "Slices are controlled based upon number of bytes", "bytes"},
+ {IH264_SLICEMODE_OFFSET,
+ "Slices are controlled based upon user defined offset unit of Row",
+ "offset"},
+ {0, NULL, NULL},
+ };
+
+ type = g_enum_register_static ("GstDucatiSliceMode", vals);
}
return type;
"Codec/Encoder/Video",
"Encode raw video into H264 stream",
"Alessandro Decina <alessandro.decina@collabora.com>");
+
+ GST_DUCATIVIDENC_CLASS (element_class)->codec_name = "ivahd_h264enc";
}
static void
gst_ducati_h264enc_class_init (GstDucatiH264EncClass * klass)
{
GObjectClass *gobject_class;
- GstBaseVideoEncoderClass *basevideocoder_class;
+ GstDucatiVidEncClass *videnc_class;
gobject_class = G_OBJECT_CLASS (klass);
- basevideocoder_class = GST_BASE_VIDEO_ENCODER_CLASS (klass);
+ videnc_class = GST_DUCATIVIDENC_CLASS (klass);
gobject_class->set_property = gst_ducati_h264enc_set_property;
gobject_class->get_property = gst_ducati_h264enc_get_property;
- basevideocoder_class->set_format =
- GST_DEBUG_FUNCPTR (gst_ducati_h264enc_set_format);
- basevideocoder_class->start = GST_DEBUG_FUNCPTR (gst_ducati_h264enc_start);
- basevideocoder_class->stop = GST_DEBUG_FUNCPTR (gst_ducati_h264enc_stop);
- basevideocoder_class->finish = GST_DEBUG_FUNCPTR (gst_ducati_h264enc_finish);
- basevideocoder_class->handle_frame =
- GST_DEBUG_FUNCPTR (gst_ducati_h264enc_handle_frame);
+ videnc_class->allocate_params = gst_ducati_h264enc_allocate_params;
+ videnc_class->configure = gst_ducati_h264enc_configure;
+ videnc_class->is_sync_point = gst_ducati_h264enc_is_sync_point;
g_object_class_install_property (gobject_class, PROP_PROFILE,
g_param_spec_enum ("profile", "H.264 Profile", "H.264 Profile",
g_param_spec_enum ("level", "H.264 Level", "H.264 Level",
GST_TYPE_DUCATI_H264ENC_LEVEL, DEFAULT_LEVEL, G_PARAM_READWRITE));
- g_object_class_install_property (gobject_class, PROP_BITRATE,
- g_param_spec_int ("bitrate", "Bitrate", "Bitrate in kbit/sec", -1,
- 100 * 1024, DEFAULT_BITRATE, G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class, PROP_INTER_INTERVAL,
+ g_param_spec_uint ("inter-interval", "Inter-frame interval",
+ "Max inter frame interval (B frames are allowed between them if > 1)",
+ 1, 31, DEFAULT_INTER_INTERVAL, G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_RATE_CONTROL_PARAMS_PRESET,
+ g_param_spec_enum ("rate-control-params-preset",
+ "H.264 rate control params preset",
+ "This preset controls the USER_DEFINED versus "
+ "DEFAULT mode. If you are not aware about the "
+ "fields, it should be set as 'rate-control-params-preset-default'",
+ GST_TYPE_DUCATI_H264ENC_RCPP, IH264_RATECONTROLPARAMS_DEFAULT,
+ G_PARAM_READWRITE));
- g_object_class_install_property (gobject_class, PROP_RATE_PRESET,
- g_param_spec_enum ("rate-preset", "H.264 Rate Control",
- "H.264 Rate Control",
- GST_TYPE_DUCATI_H264ENC_RATE_PRESET, DEFAULT_RATE_PRESET,
+ g_object_class_install_property (gobject_class, PROP_RATE_CONTROL_ALGO,
+ g_param_spec_enum ("rate-control-algo", "H.264 rate control algorithm",
+ "This defines the rate control algorithm to be used. Only useful if "
+ " 'rate-control-params-preset' is set as "
+ "'rate-control-params-preset-user-defined'",
+ GST_TYPE_DUCATI_H264ENC_RATE_CONTROL_ALGO, IH264_RATECONTROL_DEFAULT,
G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_QPI,
+ g_param_spec_int ("qpi", "Initial quantization parameter",
+ "Initial quantization parameter for I/IDR frames.", -1, 51,
+ DEFAULT_QPI, G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_QP_MIN_I,
+ g_param_spec_int ("qp-min-i", "Minimum quantization parameter",
+ "Minimum quantization parameter for I/IDR frames.", 0, 51,
+ DEFAULT_QP_MIN_I, G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_QP_MAX_I,
+ g_param_spec_int ("qp-max-i", "Maximum quantization parameter",
+ "Maximum quantization parameter for I/IDR frames.", 0, 51,
+ DEFAULT_QP_MAX_I, G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_HRD_BUFFER_SIZE,
+ g_param_spec_uint ("hrd-buffer-size",
+ "Hypothetical reference decoder buffer size",
+ "Hypothetical reference decoder buffer size. This "
+ "size controls the frame skip logic of the encoder. "
+ "For low delay applications this size should be "
+ "small. This size is in bits. Maximum Value is level "
+ "dependant and min value is 4096",
+ 4096, G_MAXUINT, DEFAULT_HRD_BUFFER_SIZE, G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_ENTROPY_CODING_MODE,
+ g_param_spec_enum ("entropy-coding-mode", "H.264 entropy coding mode",
+ "Controls the entropy coding type.",
+ GST_TYPE_DUCATI_H264ENC_ENTROPY_CODING_MODE,
+ IH264_ENTROPYCODING_DEFAULT, G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_SLICE_MODE,
+ g_param_spec_enum ("slice-mode", "H.264 slice mode",
+ "This defines the control mechanism to split a picture in slices."
+ " It can be either MB based or bytes based",
+ GST_TYPE_DUCATI_H264ENC_SLICE_MODE,
+ IH264_SLICEMODE_DEFAULT, G_PARAM_READWRITE));
+
}
static void
@@ -274,33 +352,15 @@ gst_ducati_h264enc_init (GstDucatiH264Enc * self, GstDucatiH264EncClass * klass)
{
GST_DEBUG ("gst_ducati_h264enc_init");
- self->engine = NULL;
- self->codec = NULL;
- self->params = NULL;
- self->status = NULL;
- self->inBufs = NULL;
- self->outBufs = NULL;
- self->inArgs = NULL;
- self->outArgs = NULL;
- self->configure = FALSE;
- self->input_pool = NULL;
- self->output_pool = NULL;
-
self->profile = DEFAULT_PROFILE;
self->level = DEFAULT_LEVEL;
- self->bitrate = DEFAULT_BITRATE * 1000;
- self->rate_preset = DEFAULT_RATE_PRESET;
-}
-
-static gboolean
-gst_ducati_h264enc_set_format (GstBaseVideoEncoder * base_video_encoder,
- GstVideoState * state)
-{
- GstDucatiH264Enc *self = GST_DUCATIH264ENC (base_video_encoder);
-
- self->configure = TRUE;
-
- return TRUE;
+ self->rate_control_params_preset = IH264_RATECONTROLPARAMS_DEFAULT;
+ self->rate_control_algo = IH264_RATECONTROL_DEFAULT;
+ self->qpi = DEFAULT_QPI;
+ self->qp_min_i = DEFAULT_QP_MIN_I;
+ self->qp_max_i = DEFAULT_QP_MAX_I;
+ self->hrd_buffer_size = DEFAULT_HRD_BUFFER_SIZE;
+ self->inter_interval = DEFAULT_INTER_INTERVAL;
}
static void
const GValue * value, GParamSpec * pspec)
{
GstDucatiH264Enc *self = GST_DUCATIH264ENC (object);
+ GstDucatiVidEnc *venc = GST_DUCATIVIDENC (object);
+ IH264ENC_DynamicParams *dynParams =
+ (IH264ENC_DynamicParams *) venc->dynParams;
- g_return_if_fail (GST_IS_DUCATIH264ENC (object));
self = GST_DUCATIH264ENC (object);
switch (prop_id) {
case PROP_LEVEL:
self->level = g_value_get_enum (value);
break;
- case PROP_BITRATE:
- self->bitrate = g_value_get_int (value) * 1000;
+ case PROP_RATE_CONTROL_PARAMS_PRESET:
+ self->rate_control_params_preset = g_value_get_enum (value);
+ if (dynParams)
+ dynParams->rateControlParams.rateControlParamsPreset =
+ self->rate_control_params_preset;
break;
- case PROP_RATE_PRESET:
- self->rate_preset = g_value_get_enum (value);
+ case PROP_RATE_CONTROL_ALGO:
+ self->rate_control_algo = g_value_get_enum (value);
+
+ if (self->rate_control_params_preset !=
+ IH264_RATECONTROLPARAMS_USERDEFINED)
+ GST_INFO_OBJECT (self,
+ "Setting rcAlgo but rateControlParamsPreset not "
+ "'rate-control-params-preset-user-defined' config won't be taken "
+ "into account");
+
+ if (dynParams)
+ dynParams->rateControlParams.rcAlgo = self->rate_control_algo;
+ break;
+ case PROP_QPI:
+ self->qpi = g_value_get_int (value);
+ if (dynParams)
+ dynParams->rateControlParams.qpI = self->qpi;
+
+ break;
+ case PROP_QP_MIN_I:
+ self->qp_min_i = g_value_get_int (value);
+ if (dynParams)
+ dynParams->rateControlParams.qpMinI = self->qp_min_i;
+ break;
+ case PROP_QP_MAX_I:
+ self->qp_max_i = g_value_get_int (value);
+ if (dynParams)
+ dynParams->rateControlParams.qpMaxI = self->qp_max_i;
+ break;
+ case PROP_HRD_BUFFER_SIZE:
+ self->hrd_buffer_size = g_value_get_uint (value);
+ break;
+ case PROP_ENTROPY_CODING_MODE:
+ self->entropy_coding_mode = g_value_get_enum (value);
+ break;
+ case PROP_SLICE_MODE:
+ self->slice_mode = g_value_get_enum (value);
+ break;
+ case PROP_INTER_INTERVAL:
+ self->inter_interval = g_value_get_uint (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
case PROP_LEVEL:
g_value_set_enum (value, self->level);
break;
- case PROP_BITRATE:
- g_value_set_int (value, self->bitrate / 1000);
+ case PROP_RATE_CONTROL_PARAMS_PRESET:
+ g_value_set_enum (value, self->rate_control_params_preset);
+ break;
+ case PROP_RATE_CONTROL_ALGO:
+ g_value_set_enum (value, self->rate_control_algo);
+ break;
+ case PROP_QPI:
+ g_value_set_int (value, self->qpi);
+ break;
+ case PROP_QP_MIN_I:
+ g_value_set_int (value, self->qp_min_i);
break;
- case PROP_RATE_PRESET:
- g_value_set_enum (value, self->rate_preset);
+ case PROP_QP_MAX_I:
+ g_value_set_int (value, self->qp_max_i);
+ break;
+ case PROP_HRD_BUFFER_SIZE:
+ g_value_set_uint (value, self->hrd_buffer_size);
+ break;
+ case PROP_ENTROPY_CODING_MODE:
+ g_value_set_enum (value, self->entropy_coding_mode);
+ break;
+ case PROP_SLICE_MODE:
+ g_value_set_enum (value, self->slice_mode);
+ break;
+ case PROP_INTER_INTERVAL:
+ g_value_set_uint (value, self->inter_interval);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
-static gboolean
-gst_ducati_h264enc_configure (GstDucatiH264Enc * self)
+static const char *
+get_profile_name (guint profile)
{
- int err, i, max_out_size = 0;
- VIDENC2_DynamicParams *dynParams;
- VIDENC2_Params *baseParams;
- IH264ENC_Params *params;
- const GstVideoState *state;
-
- state = gst_base_video_encoder_get_state (GST_BASE_VIDEO_ENCODER (self));
-
- params = self->params;
- baseParams = (VIDENC2_Params *) self->params;
- baseParams->encodingPreset = 0x03; /* ??? */
- baseParams->rateControlPreset = self->rate_preset;
- baseParams->maxHeight = state->height;
- baseParams->maxWidth = state->width;
- baseParams->dataEndianness = XDM_BYTE;
- baseParams->maxInterFrameInterval = 1;
- baseParams->maxBitRate = self->bitrate;
- baseParams->minBitRate = 0;
- baseParams->inputChromaFormat = XDM_YUV_420SP;
- baseParams->inputContentType = IVIDEO_PROGRESSIVE;
- baseParams->operatingMode = IVIDEO_ENCODE_ONLY;
- baseParams->profile = self->profile;
- baseParams->level = self->level;
- baseParams->inputDataMode = IVIDEO_ENTIREFRAME;
- baseParams->outputDataMode = IVIDEO_ENTIREFRAME;
- baseParams->numInputDataUnits = 1;
- baseParams->numOutputDataUnits = 1;
- for (i = 0; i < IVIDEO_MAX_NUM_METADATA_PLANES; i++) {
- baseParams->metadataType[i] = IVIDEO_METADATAPLANE_NONE;
- }
-
- /* this is the only non-base field strictly required */
- params->maxIntraFrameInterval = 0x7fffffff;
-
- if (self->codec == NULL) {
- self->codec = VIDENC2_create (self->engine,
- (String) "ivahd_h264enc", baseParams);
- if (self->codec == NULL) {
- GST_ERROR_OBJECT (self, "couldn't create codec");
- return FALSE;
- }
- }
-
- dynParams = self->dynParams;
- dynParams = (VIDENC2_DynamicParams *) self->dynParams;
- dynParams->size = sizeof (IVIDENC2_DynamicParams);
-
- dynParams->refFrameRate =
- gst_util_uint64_scale (1000, state->fps_n, state->fps_d);
- dynParams->targetFrameRate = dynParams->refFrameRate;
- dynParams->inputWidth = state->width;
- dynParams->inputHeight = state->height;
- dynParams->targetBitRate = self->bitrate;
- dynParams->intraFrameInterval = 15;
- dynParams->captureWidth = dynParams->inputWidth;
- dynParams->forceFrame = IVIDEO_NA_FRAME;
- dynParams->interFrameInterval = 1;
- dynParams->mvAccuracy = IVIDENC2_MOTIONVECTOR_QUARTERPEL;
- dynParams->sampleAspectRatioHeight = 1;
- dynParams->sampleAspectRatioWidth = 1;
- dynParams->generateHeader = XDM_ENCODE_AU;
- dynParams->ignoreOutbufSizeFlag = 1;
- dynParams->lateAcquireArg = -1;
-
- err = VIDENC2_control (self->codec,
- XDM_SETPARAMS, dynParams, self->status);
- if (err) {
- GST_ERROR_OBJECT (self, "XDM_SETPARAMS err=%d, extendedError=%08x",
- err, self->status->extendedError);
-
- return FALSE;
- }
-
- err = VIDENC2_control (self->codec,
- XDM_GETBUFINFO, dynParams, self->status);
- if (err) {
- GST_ERROR_OBJECT (self, "XDM_GETBUFINFO err=%d, extendedError=%08x",
- err, self->status->extendedError);
-
- return FALSE;
- }
-
- self->inBufs->chromaFormat = XDM_YUV_420SP;
- self->inBufs->numPlanes = 2;
-
- self->outBufs->numBufs = self->status->bufInfo.minNumOutBufs;
- for (i = 0; i < self->outBufs->numBufs; i++) {
- int size = self->status->bufInfo.minOutBufSize[i].bytes;
- if (size > max_out_size)
- max_out_size = size;
+ switch (profile) {
+ case IH264_BASELINE_PROFILE:
+ return "baseline";
+ case IH264_MAIN_PROFILE:
+ return "main";
+ case IH264_EXTENDED_PROFILE:
+ return "extended";
+ case IH264_HIGH_PROFILE:
+ return "high";
+ case IH264_HIGH10_PROFILE:
+ return "high-10";
+ case IH264_HIGH422_PROFILE:
+ return "high-422";
+ default:
+ return NULL;
}
-
- g_assert (self->input_pool == NULL);
- self->input_pool =
- gst_ducati_bufferpool_new (GST_ELEMENT (self), NULL,
- state->bytes_per_picture);
-
- g_assert (self->output_pool == NULL);
- self->output_pool =
- gst_ducati_bufferpool_new (GST_ELEMENT (self), NULL, max_out_size);
-
- GST_INFO_OBJECT (self, "configured");
-
- self->configure = FALSE;
-
- return TRUE;
}
-static gboolean
-gst_ducati_h264enc_alloc_dce (GstDucatiH264Enc * self)
+static const char *
+get_level_name (guint level)
{
- self->engine = Engine_open ((String) "ivahd_vidsvr", NULL, NULL);
- if (self->engine == NULL) {
- GST_ERROR_OBJECT (self, "couldn't open engine");
- return FALSE;
+ switch (level) {
+ case IH264_LEVEL_10:
+ return "1";
+ case IH264_LEVEL_1b:
+ return "1b";
+ case IH264_LEVEL_11:
+ return "1.1";
+ case IH264_LEVEL_12:
+ return "1.2";
+ case IH264_LEVEL_13:
+ return "1.3";
+ case IH264_LEVEL_20:
+ return "2";
+ case IH264_LEVEL_21:
+ return "2.1";
+ case IH264_LEVEL_22:
+ return "2.2";
+ case IH264_LEVEL_30:
+ return "3";
+ case IH264_LEVEL_31:
+ return "3.1";
+ case IH264_LEVEL_32:
+ return "3.2";
+ case IH264_LEVEL_40:
+ return "4";
+ case IH264_LEVEL_41:
+ return "4.1";
+ case IH264_LEVEL_42:
+ return "4.2";
+ case IH264_LEVEL_50:
+ return "5";
+ case IH264_LEVEL_51:
+ return "5.1";
+ default:
+ return NULL;
}
-
- self->params = dce_alloc (sizeof (IH264ENC_Params));
- memset (self->params, 0, sizeof (IH264ENC_Params));
- self->params->videnc2Params.size = sizeof (IH264ENC_Params);
-
- self->codec = NULL;
-
- self->dynParams = dce_alloc (sizeof (IVIDENC2_DynamicParams));
- memset (self->dynParams, 0, sizeof (IVIDENC2_DynamicParams));
- self->dynParams->size = sizeof (IVIDENC2_DynamicParams);
-
- self->status = dce_alloc (sizeof (IVIDENC2_Status));
- memset (self->status, 0, sizeof (IVIDENC2_Status));
- self->status->size = sizeof (IVIDENC2_Status);
-
- self->inBufs = dce_alloc (sizeof (IVIDEO2_BufDesc));
- memset (self->inBufs, 0, sizeof (IVIDEO2_BufDesc));
-
- self->outBufs = dce_alloc (sizeof (XDM2_BufDesc));
- memset (self->outBufs, 0, sizeof (XDM2_BufDesc));
-
- self->inArgs = dce_alloc (sizeof (IVIDENC2_InArgs));
- memset (self->inArgs, 0, sizeof (IVIDENC2_InArgs));
- self->inArgs->size = sizeof (IVIDENC2_InArgs);
-
- self->outArgs = dce_alloc (sizeof (IVIDENC2_OutArgs));
- memset (self->outArgs, 0, sizeof (IVIDENC2_OutArgs));
- self->outArgs->size = sizeof (IVIDENC2_OutArgs);
-
- GST_INFO_OBJECT (self, "started");
-
- return TRUE;
}
static gboolean
-gst_ducati_h264enc_free_dce (GstDucatiH264Enc * self)
+gst_ducati_h264enc_configure (GstDucatiVidEnc * videnc)
{
- if (self->params) {
- dce_free (self->params);
- self->params = NULL;
- }
-
- if (self->dynParams) {
- dce_free (self->dynParams);
- self->dynParams = NULL;
- }
-
- if (self->inArgs) {
- dce_free (self->inArgs);
- self->inArgs = NULL;
- }
-
- if (self->outArgs) {
- dce_free (self->outArgs);
- self->outArgs = NULL;
- }
-
- if (self->status) {
- dce_free (self->status);
- self->status = NULL;
- }
-
- if (self->inBufs) {
- dce_free (self->inBufs);
- self->inBufs = NULL;
- }
-
- if (self->outBufs) {
- dce_free (self->outBufs);
- self->inBufs = NULL;
- }
-
- if (self->codec) {
- VIDENC2_delete (self->codec);
- self->codec = NULL;
- }
-
- if (self->engine) {
- Engine_close (self->engine);
- self->engine = NULL;
- }
-
- return TRUE;
-}
+ GstDucatiH264Enc *self = GST_DUCATIH264ENC (videnc);
+ IH264ENC_Params *params;
+ IH264ENC_DynamicParams *dynParams;
+ gboolean ret;
+ const char *s;
+ const GstVideoState *state;
+ GstCaps *caps;
+ int inter_interval;
-static gboolean
-gst_ducati_h264enc_start (GstBaseVideoEncoder * base_video_encoder)
-{
- GstDucatiH264Enc *self = GST_DUCATIH264ENC (base_video_encoder);
+ ret = GST_DUCATIVIDENC_CLASS (parent_class)->configure (videnc);
+ if (!ret)
+ return FALSE;
- if (!gst_ducati_h264enc_alloc_dce (self))
- goto fail;
+ videnc->params->profile = self->profile;
+ videnc->params->level = self->level;
- return TRUE;
+ inter_interval = self->inter_interval;
+ if (self->profile == IH264_BASELINE_PROFILE)
+ inter_interval = 1;
+ else if (videnc->rate_preset == IVIDEO_LOW_DELAY)
+ inter_interval = 1;
-fail:
- gst_ducati_h264enc_free_dce (self);
- return FALSE;
+ params = (IH264ENC_Params *) videnc->params;
+ /* this is the only non-base field strictly required */
+ params->maxIntraFrameInterval = 0x7fffffff;
+ params->IDRFrameInterval = 1;
+ params->numTemporalLayer = 1;
+ params->entropyCodingMode = self->entropy_coding_mode;
+ videnc->params->maxInterFrameInterval = inter_interval;
+
+ /* Dynamic params */
+ dynParams = (IH264ENC_DynamicParams *) videnc->dynParams;
+ dynParams->rateControlParams.rateControlParamsPreset =
+ self->rate_control_params_preset;
+ dynParams->rateControlParams.rcAlgo = self->rate_control_algo;
+ dynParams->rateControlParams.qpI = self->qpi;
+ dynParams->rateControlParams.qpMaxI = self->qp_max_i;
+ dynParams->rateControlParams.qpMinI = self->qp_min_i;
+ dynParams->rateControlParams.HRDBufferSize = self->hrd_buffer_size;
+ dynParams->sliceCodingParams.sliceMode = self->slice_mode;
+ videnc->dynParams->interFrameInterval = inter_interval;
+
+ state = gst_base_video_encoder_get_state (GST_BASE_VIDEO_ENCODER (videnc));
+ caps = gst_caps_new_simple ("video/x-h264",
+ "width", G_TYPE_INT, videnc->rect.w,
+ "height", G_TYPE_INT, videnc->rect.h,
+ "framerate", GST_TYPE_FRACTION, state->fps_n, state->fps_d,
+ "pixel-aspect-ratio", GST_TYPE_FRACTION, state->par_n, state->par_d,
+ "stream-format", G_TYPE_STRING, "byte-stream",
+ "align", G_TYPE_STRING, "au",
+ "num-reorder-frames", G_TYPE_INT, inter_interval - 1, NULL);
+ s = get_profile_name (self->profile);
+ if (s)
+ gst_caps_set_simple (caps, "profile", G_TYPE_STRING, s, NULL);
+ s = get_level_name (self->level);
+ if (s)
+ gst_caps_set_simple (caps, "level", G_TYPE_STRING, s, NULL);
+ ret = gst_pad_set_caps (GST_BASE_VIDEO_CODEC_SRC_PAD (self), caps);
+
+ return ret;
}
static gboolean
-gst_ducati_h264enc_stop (GstBaseVideoEncoder * base_video_encoder)
+gst_ducati_h264enc_allocate_params (GstDucatiVidEnc *
+ videnc, gint params_sz, gint dynparams_sz, gint status_sz, gint inargs_sz,
+ gint outargs_sz)
{
- GstDucatiH264Enc *self = GST_DUCATIH264ENC (base_video_encoder);
-
- gst_ducati_h264enc_free_dce (self);
-
- if (self->input_pool) {
- gst_ducati_bufferpool_destroy (self->input_pool);
- self->input_pool = NULL;
+ gboolean ret = GST_DUCATIVIDENC_CLASS (parent_class)->allocate_params (videnc,
+ sizeof (IH264ENC_Params), sizeof (IH264ENC_DynamicParams),
+ sizeof (IVIDENC2_Status), sizeof (IVIDENC2_InArgs),
+ sizeof (IVIDENC2_OutArgs));
+
+ GstDucatiH264Enc *self = GST_DUCATIH264ENC (videnc);
+
+ if (ret == TRUE) {
+ IH264ENC_DynamicParams *dynParams =
+ (IH264ENC_DynamicParams *) videnc->dynParams;
+
+ dynParams->rateControlParams.rateControlParamsPreset =
+ self->rate_control_params_preset;
+ dynParams->rateControlParams.rcAlgo = self->rate_control_algo;
+ dynParams->rateControlParams.qpI = self->qpi;
+ dynParams->rateControlParams.qpMaxI = self->qp_max_i;
+ dynParams->rateControlParams.qpMinI = self->qp_min_i;
+ dynParams->rateControlParams.HRDBufferSize = self->hrd_buffer_size;
+ dynParams->sliceCodingParams.sliceMode = self->slice_mode;
}
- if (self->output_pool) {
- gst_ducati_bufferpool_destroy (self->output_pool);
- self->output_pool = NULL;
- }
-
- return TRUE;
-}
-
-static GstFlowReturn
-gst_ducati_h264enc_finish (GstBaseVideoEncoder * base_video_encoder)
-{
- GstDucatiH264Enc *self = GST_DUCATIH264ENC (base_video_encoder);
-
- GST_DEBUG_OBJECT (self, "finish");
-
- return GST_FLOW_OK;
+ return ret;
}
-static GstFlowReturn
-gst_ducati_h264enc_handle_frame (GstBaseVideoEncoder * base_video_encoder,
- GstVideoFrame * frame)
+static gboolean
+gst_ducati_h264enc_is_sync_point (GstDucatiVidEnc * enc, int type)
{
- GstDucatiH264Enc *self = GST_DUCATIH264ENC (base_video_encoder);
- GstBuffer *inbuf, *outbuf;
- guint8 *y_vaddr, *uv_vaddr;
- SSPtr y_paddr, uv_paddr, outbuf_paddr;
- XDAS_Int32 err;
- const GstVideoState *state;
- int i;
-
- state = gst_base_video_encoder_get_state (base_video_encoder);
-
- if (G_UNLIKELY (self->configure)) {
- if (!gst_ducati_h264enc_configure (self)) {
- GST_DEBUG_OBJECT (self, "configure failed");
- GST_ELEMENT_ERROR (self, STREAM, ENCODE, (NULL), (NULL));
-
- return GST_FLOW_ERROR;
- }
- }
-
- inbuf = GST_BUFFER (gst_ducati_bufferpool_get (self->input_pool, NULL));
- memcpy (GST_BUFFER_DATA (inbuf), GST_BUFFER_DATA (frame->sink_buffer),
- GST_BUFFER_SIZE (frame->sink_buffer));
- outbuf = GST_BUFFER (gst_ducati_bufferpool_get (self->output_pool, NULL));
-
- y_vaddr = GST_BUFFER_DATA (inbuf);
- uv_vaddr = y_vaddr + gst_video_format_get_component_offset (state->format,
- 1, state->width, state->height);
-
- y_paddr = TilerMem_VirtToPhys (y_vaddr);
- uv_paddr = TilerMem_VirtToPhys (uv_vaddr);
-
- outbuf_paddr = TilerMem_VirtToPhys (GST_BUFFER_DATA (outbuf));
-
- self->inBufs->planeDesc[0].buf = (XDAS_Int8 *) y_paddr;
- self->inBufs->planeDesc[0].memType = XDM_MEMTYPE_TILEDPAGE;
- self->inBufs->planeDesc[0].bufSize.tileMem.width = state->width;
- self->inBufs->planeDesc[0].bufSize.tileMem.height = state->height;
- self->inBufs->planeDesc[1].buf = (XDAS_Int8 *) uv_paddr;
- self->inBufs->planeDesc[1].memType = XDM_MEMTYPE_TILEDPAGE;
- self->inBufs->planeDesc[1].bufSize.tileMem.width = state->width;
- self->inBufs->planeDesc[1].bufSize.tileMem.height = state->height / 2;
- self->inBufs->imagePitch[0] = state->width;
- self->inBufs->imagePitch[1] = state->width;
- self->inBufs->imageRegion.bottomRight.x = state->width;
- self->inBufs->activeFrameRegion.bottomRight.x = state->width;
- self->inBufs->imageRegion.bottomRight.y = state->height;
- self->inBufs->activeFrameRegion.bottomRight.y = state->height;
- self->inBufs->topFieldFirstFlag = TRUE;
-
- self->outBufs->numBufs = 1;
- self->outBufs->descs[0].buf = (XDAS_Int8 *) outbuf_paddr;
- self->outBufs->descs[0].bufSize.bytes = GST_BUFFER_SIZE (outbuf);
-
- self->inArgs->inputID = GPOINTER_TO_INT (inbuf);
-
- err = VIDENC2_process (self->codec, self->inBufs, self->outBufs,
- self->inArgs, self->outArgs);
- if (err) {
- GST_WARNING_OBJECT (self, "process failed: err=%d, extendedError=%08x",
- err, self->status->extendedError);
-
- err = VIDENC2_control (self->codec,
- XDM_GETSTATUS, (IVIDENC2_DynamicParams *) self->dynParams,
- self->status);
-
- GST_WARNING_OBJECT (self, "XDM_GETSTATUS: err=%d, extendedError=%08x",
- err, self->status->extendedError);
-
- return GST_FLOW_ERROR;
- }
-
- frame->src_buffer = gst_buffer_new_and_alloc (self->outArgs->bytesGenerated);
- memcpy (GST_BUFFER_DATA (frame->src_buffer),
- GST_BUFFER_DATA (outbuf), self->outArgs->bytesGenerated);
-
- gst_buffer_unref (outbuf);
-
- for (i = 0; self->outArgs->freeBufID[i]; i++) {
- GstBuffer *buf = (GstBuffer *) self->outArgs->freeBufID[i];
-
- GST_LOG_OBJECT (self, "free buffer: %p", buf);
- gst_buffer_unref (buf);
- }
-
- return gst_base_video_encoder_finish_frame (base_video_encoder, frame);
+ return type == IVIDEO_IDR_FRAME;
}