mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 18:05:37 +00:00
x264enc: Add option-string property
Adds support for an x264 format option-string to specify advanced parameters Addresses part of bug #607798
This commit is contained in:
parent
d462cdee4d
commit
f2be62695c
2 changed files with 87 additions and 1 deletions
|
@ -121,7 +121,8 @@ enum
|
||||||
ARG_RC_MB_TREE,
|
ARG_RC_MB_TREE,
|
||||||
ARG_RC_LOOKAHEAD,
|
ARG_RC_LOOKAHEAD,
|
||||||
ARG_NR,
|
ARG_NR,
|
||||||
ARG_INTERLACED
|
ARG_INTERLACED,
|
||||||
|
ARG_OPTION_STRING
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ARG_THREADS_DEFAULT 1
|
#define ARG_THREADS_DEFAULT 1
|
||||||
|
@ -159,6 +160,8 @@ enum
|
||||||
#define ARG_RC_LOOKAHEAD_DEFAULT 40
|
#define ARG_RC_LOOKAHEAD_DEFAULT 40
|
||||||
#define ARG_INTRA_REFRESH_DEFAULT FALSE
|
#define ARG_INTRA_REFRESH_DEFAULT FALSE
|
||||||
|
|
||||||
|
#define ARG_OPTION_STRING_DEFAULT ""
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
GST_X264_ENC_PASS_CBR = 0,
|
GST_X264_ENC_PASS_CBR = 0,
|
||||||
|
@ -318,6 +321,11 @@ gst_x264_enc_class_init (GstX264EncClass * klass)
|
||||||
gstelement_class->change_state =
|
gstelement_class->change_state =
|
||||||
GST_DEBUG_FUNCPTR (gst_x264_enc_change_state);
|
GST_DEBUG_FUNCPTR (gst_x264_enc_change_state);
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class, ARG_OPTION_STRING,
|
||||||
|
g_param_spec_string ("option-string", "Option string",
|
||||||
|
"String of x264 options (overridden by element properties)",
|
||||||
|
ARG_OPTION_STRING_DEFAULT, G_PARAM_READWRITE));
|
||||||
|
|
||||||
g_object_class_install_property (gobject_class, ARG_THREADS,
|
g_object_class_install_property (gobject_class, ARG_THREADS,
|
||||||
g_param_spec_uint ("threads", "Threads",
|
g_param_spec_uint ("threads", "Threads",
|
||||||
"Number of threads used by the codec (0 for automatic)",
|
"Number of threads used by the codec (0 for automatic)",
|
||||||
|
@ -546,6 +554,7 @@ gst_x264_enc_init (GstX264Enc * encoder, GstX264EncClass * klass)
|
||||||
encoder->rc_lookahead = ARG_RC_LOOKAHEAD_DEFAULT;
|
encoder->rc_lookahead = ARG_RC_LOOKAHEAD_DEFAULT;
|
||||||
encoder->noise_reduction = ARG_NR_DEFAULT;
|
encoder->noise_reduction = ARG_NR_DEFAULT;
|
||||||
encoder->interlaced = ARG_INTERLACED_DEFAULT;
|
encoder->interlaced = ARG_INTERLACED_DEFAULT;
|
||||||
|
encoder->option_string_prop = g_string_new (ARG_OPTION_STRING_DEFAULT);
|
||||||
|
|
||||||
/* resources */
|
/* resources */
|
||||||
encoder->delay = g_queue_new ();
|
encoder->delay = g_queue_new ();
|
||||||
|
@ -588,6 +597,14 @@ gst_x264_enc_finalize (GObject * object)
|
||||||
{
|
{
|
||||||
GstX264Enc *encoder = GST_X264_ENC (object);
|
GstX264Enc *encoder = GST_X264_ENC (object);
|
||||||
|
|
||||||
|
#define FREE_STRING(ptr) \
|
||||||
|
if (ptr) \
|
||||||
|
ptr = (GString *)g_string_free (ptr, TRUE);
|
||||||
|
|
||||||
|
FREE_STRING (encoder->option_string_prop);
|
||||||
|
|
||||||
|
#undef FREE_STRING
|
||||||
|
|
||||||
g_free (encoder->mp_cache_file);
|
g_free (encoder->mp_cache_file);
|
||||||
encoder->mp_cache_file = NULL;
|
encoder->mp_cache_file = NULL;
|
||||||
g_free (encoder->buffer);
|
g_free (encoder->buffer);
|
||||||
|
@ -600,6 +617,54 @@ gst_x264_enc_finalize (GObject * object)
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* gst_x264_enc_parse_options
|
||||||
|
* @encoder: Encoder to which options are assigned
|
||||||
|
* @str: Option string
|
||||||
|
*
|
||||||
|
* Parse option string and assign to x264 parameters
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static gboolean
|
||||||
|
gst_x264_enc_parse_options (GstX264Enc * encoder, const gchar * str)
|
||||||
|
{
|
||||||
|
GStrv kvpairs;
|
||||||
|
guint npairs, i;
|
||||||
|
gint parse_result = 0, ret = 0;
|
||||||
|
gchar *options = (gchar *) str;
|
||||||
|
|
||||||
|
while (*options == ':')
|
||||||
|
options++;
|
||||||
|
|
||||||
|
kvpairs = g_strsplit (options, ":", 0);
|
||||||
|
npairs = g_strv_length (kvpairs);
|
||||||
|
|
||||||
|
for (i = 0; i < npairs; i++) {
|
||||||
|
GStrv key_val = g_strsplit (kvpairs[i], "=", 2);
|
||||||
|
|
||||||
|
parse_result =
|
||||||
|
x264_param_parse (&encoder->x264param, key_val[0], key_val[1]);
|
||||||
|
|
||||||
|
if (parse_result == X264_PARAM_BAD_NAME) {
|
||||||
|
GST_ERROR_OBJECT (encoder, "Bad name for option %s=%s",
|
||||||
|
key_val[0] ? key_val[0] : "", key_val[1] ? key_val[1] : "");
|
||||||
|
}
|
||||||
|
if (parse_result == X264_PARAM_BAD_VALUE) {
|
||||||
|
GST_ERROR_OBJECT (encoder,
|
||||||
|
"Bad value for option %s=%s (Note: a NULL value for a non-boolean triggers this)",
|
||||||
|
key_val[0] ? key_val[0] : "", key_val[1] ? key_val[1] : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
g_strfreev (key_val);
|
||||||
|
|
||||||
|
if (parse_result)
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_strfreev (kvpairs);
|
||||||
|
return !ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* gst_x264_enc_init_encoder
|
* gst_x264_enc_init_encoder
|
||||||
* @encoder: Encoder which should be initialized.
|
* @encoder: Encoder which should be initialized.
|
||||||
|
@ -623,6 +688,16 @@ gst_x264_enc_init_encoder (GstX264Enc * encoder)
|
||||||
encoder->x264param.b_sliced_threads = encoder->sliced_threads;
|
encoder->x264param.b_sliced_threads = encoder->sliced_threads;
|
||||||
encoder->x264param.i_sync_lookahead = encoder->sync_lookahead;
|
encoder->x264param.i_sync_lookahead = encoder->sync_lookahead;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* apply user set properties */
|
||||||
|
if (encoder->option_string_prop && encoder->option_string_prop->len
|
||||||
|
&& gst_x264_enc_parse_options (encoder,
|
||||||
|
encoder->option_string_prop->str) == FALSE) {
|
||||||
|
GST_DEBUG_OBJECT (encoder, "Your option-string contains errors.");
|
||||||
|
goto unlock_and_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set up encoder parameters */
|
||||||
encoder->x264param.i_fps_num = encoder->fps_num;
|
encoder->x264param.i_fps_num = encoder->fps_num;
|
||||||
encoder->x264param.i_fps_den = encoder->fps_den;
|
encoder->x264param.i_fps_den = encoder->fps_den;
|
||||||
encoder->x264param.i_width = encoder->width;
|
encoder->x264param.i_width = encoder->width;
|
||||||
|
@ -760,6 +835,10 @@ gst_x264_enc_init_encoder (GstX264Enc * encoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
unlock_and_return:
|
||||||
|
GST_OBJECT_UNLOCK (encoder);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* gst_x264_enc_close_encoder
|
/* gst_x264_enc_close_encoder
|
||||||
|
@ -1291,6 +1370,9 @@ gst_x264_enc_set_property (GObject * object, guint prop_id,
|
||||||
goto wrong_state;
|
goto wrong_state;
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
|
case ARG_OPTION_STRING:
|
||||||
|
g_string_assign (encoder->option_string_prop, g_value_get_string (value));
|
||||||
|
break;
|
||||||
case ARG_THREADS:
|
case ARG_THREADS:
|
||||||
encoder->threads = g_value_get_uint (value);
|
encoder->threads = g_value_get_uint (value);
|
||||||
break;
|
break;
|
||||||
|
@ -1518,6 +1600,9 @@ gst_x264_enc_get_property (GObject * object, guint prop_id,
|
||||||
case ARG_INTERLACED:
|
case ARG_INTERLACED:
|
||||||
g_value_set_boolean (value, encoder->interlaced);
|
g_value_set_boolean (value, encoder->interlaced);
|
||||||
break;
|
break;
|
||||||
|
case ARG_OPTION_STRING:
|
||||||
|
g_value_set_string (value, encoder->option_string_prop->str);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -87,6 +87,7 @@ struct _GstX264Enc
|
||||||
gint rc_lookahead;
|
gint rc_lookahead;
|
||||||
guint noise_reduction;
|
guint noise_reduction;
|
||||||
gboolean interlaced;
|
gboolean interlaced;
|
||||||
|
GString *option_string_prop; /* option-string property */
|
||||||
|
|
||||||
/* input description */
|
/* input description */
|
||||||
GstVideoFormat format;
|
GstVideoFormat format;
|
||||||
|
|
Loading…
Reference in a new issue