x264enc: Allow changing the bitrate and quantitizers dynamically
https://bugzilla.gnome.org/show_bug.cgi?id=621663
This commit is contained in:
parent
a4df8f9031
commit
62e35a6b40
@ -574,12 +574,14 @@ gst_x264_enc_class_init (GstX264EncClass * klass)
|
|||||||
g_object_class_install_property (gobject_class, ARG_BITRATE,
|
g_object_class_install_property (gobject_class, ARG_BITRATE,
|
||||||
g_param_spec_uint ("bitrate", "Bitrate", "Bitrate in kbit/sec", 1,
|
g_param_spec_uint ("bitrate", "Bitrate", "Bitrate in kbit/sec", 1,
|
||||||
100 * 1024, ARG_BITRATE_DEFAULT,
|
100 * 1024, ARG_BITRATE_DEFAULT,
|
||||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
||||||
|
GST_PARAM_MUTABLE_PLAYING));
|
||||||
g_object_class_install_property (gobject_class, ARG_VBV_BUF_CAPACITY,
|
g_object_class_install_property (gobject_class, ARG_VBV_BUF_CAPACITY,
|
||||||
g_param_spec_uint ("vbv-buf-capacity", "VBV buffer capacity",
|
g_param_spec_uint ("vbv-buf-capacity", "VBV buffer capacity",
|
||||||
"Size of the VBV buffer in milliseconds",
|
"Size of the VBV buffer in milliseconds",
|
||||||
0, 10000, ARG_VBV_BUF_CAPACITY_DEFAULT,
|
0, 10000, ARG_VBV_BUF_CAPACITY_DEFAULT,
|
||||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
|
||||||
|
GST_PARAM_MUTABLE_PLAYING));
|
||||||
|
|
||||||
#ifdef X264_PRESETS
|
#ifdef X264_PRESETS
|
||||||
g_object_class_install_property (gobject_class, ARG_SPEED_PRESET,
|
g_object_class_install_property (gobject_class, ARG_SPEED_PRESET,
|
||||||
@ -1209,6 +1211,8 @@ gst_x264_enc_init_encoder (GstX264Enc * encoder)
|
|||||||
}
|
}
|
||||||
#endif /* X264_PRESETS */
|
#endif /* X264_PRESETS */
|
||||||
|
|
||||||
|
encoder->reconfig = FALSE;
|
||||||
|
|
||||||
GST_OBJECT_UNLOCK (encoder);
|
GST_OBJECT_UNLOCK (encoder);
|
||||||
|
|
||||||
encoder->x264enc = x264_encoder_open (&encoder->x264param);
|
encoder->x264enc = x264_encoder_open (&encoder->x264param);
|
||||||
@ -1621,6 +1625,14 @@ gst_x264_enc_encode_frame (GstX264Enc * encoder, x264_picture_t * pic_in,
|
|||||||
if (G_UNLIKELY (encoder->x264enc == NULL))
|
if (G_UNLIKELY (encoder->x264enc == NULL))
|
||||||
return GST_FLOW_NOT_NEGOTIATED;
|
return GST_FLOW_NOT_NEGOTIATED;
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (encoder);
|
||||||
|
if (encoder->reconfig) {
|
||||||
|
encoder->reconfig = FALSE;
|
||||||
|
if (x264_encoder_reconfig (encoder->x264enc, &encoder->x264param) < 0)
|
||||||
|
GST_WARNING_OBJECT (encoder, "Could not reconfigure");
|
||||||
|
}
|
||||||
|
GST_OBJECT_UNLOCK (encoder);
|
||||||
|
|
||||||
encoder_return = x264_encoder_encode (encoder->x264enc,
|
encoder_return = x264_encoder_encode (encoder->x264enc,
|
||||||
&nal, i_nal, pic_in, &pic_out);
|
&nal, i_nal, pic_in, &pic_out);
|
||||||
|
|
||||||
@ -1759,6 +1771,35 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_x264_enc_reconfig (GstX264Enc * encoder)
|
||||||
|
{
|
||||||
|
switch (encoder->pass) {
|
||||||
|
case GST_X264_ENC_PASS_QUAL:
|
||||||
|
encoder->x264param.rc.f_rf_constant = encoder->quantizer;
|
||||||
|
encoder->x264param.rc.i_vbv_max_bitrate = encoder->bitrate;
|
||||||
|
encoder->x264param.rc.i_vbv_buffer_size
|
||||||
|
= encoder->x264param.rc.i_vbv_max_bitrate
|
||||||
|
* encoder->vbv_buf_capacity / 1000;
|
||||||
|
break;
|
||||||
|
case GST_X264_ENC_PASS_CBR:
|
||||||
|
case GST_X264_ENC_PASS_PASS1:
|
||||||
|
case GST_X264_ENC_PASS_PASS2:
|
||||||
|
case GST_X264_ENC_PASS_PASS3:
|
||||||
|
default:
|
||||||
|
encoder->x264param.rc.i_bitrate = encoder->bitrate;
|
||||||
|
encoder->x264param.rc.i_vbv_max_bitrate = encoder->bitrate;
|
||||||
|
encoder->x264param.rc.i_vbv_buffer_size
|
||||||
|
= encoder->x264param.rc.i_vbv_max_bitrate
|
||||||
|
* encoder->vbv_buf_capacity / 1000;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
encoder->reconfig = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_x264_enc_set_property (GObject * object, guint prop_id,
|
gst_x264_enc_set_property (GObject * object, guint prop_id,
|
||||||
const GValue * value, GParamSpec * pspec)
|
const GValue * value, GParamSpec * pspec)
|
||||||
@ -1773,8 +1814,10 @@ gst_x264_enc_set_property (GObject * object, guint prop_id,
|
|||||||
GST_OBJECT_LOCK (encoder);
|
GST_OBJECT_LOCK (encoder);
|
||||||
/* state at least matters for sps, bytestream, pass,
|
/* state at least matters for sps, bytestream, pass,
|
||||||
* and so by extension ... */
|
* and so by extension ... */
|
||||||
|
|
||||||
state = GST_STATE (encoder);
|
state = GST_STATE (encoder);
|
||||||
if (state != GST_STATE_READY && state != GST_STATE_NULL)
|
if ((state != GST_STATE_READY && state != GST_STATE_NULL) &&
|
||||||
|
!(pspec->flags & GST_PARAM_MUTABLE_PLAYING))
|
||||||
goto wrong_state;
|
goto wrong_state;
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
@ -1783,12 +1826,15 @@ gst_x264_enc_set_property (GObject * object, guint prop_id,
|
|||||||
break;
|
break;
|
||||||
case ARG_QUANTIZER:
|
case ARG_QUANTIZER:
|
||||||
encoder->quantizer = g_value_get_uint (value);
|
encoder->quantizer = g_value_get_uint (value);
|
||||||
|
gst_x264_enc_reconfig (encoder);
|
||||||
break;
|
break;
|
||||||
case ARG_BITRATE:
|
case ARG_BITRATE:
|
||||||
encoder->bitrate = g_value_get_uint (value);
|
encoder->bitrate = g_value_get_uint (value);
|
||||||
|
gst_x264_enc_reconfig (encoder);
|
||||||
break;
|
break;
|
||||||
case ARG_VBV_BUF_CAPACITY:
|
case ARG_VBV_BUF_CAPACITY:
|
||||||
encoder->vbv_buf_capacity = g_value_get_uint (value);
|
encoder->vbv_buf_capacity = g_value_get_uint (value);
|
||||||
|
gst_x264_enc_reconfig (encoder);
|
||||||
break;
|
break;
|
||||||
case ARG_SPEED_PRESET:
|
case ARG_SPEED_PRESET:
|
||||||
encoder->speed_preset = g_value_get_enum (value);
|
encoder->speed_preset = g_value_get_enum (value);
|
||||||
@ -1971,7 +2017,7 @@ gst_x264_enc_set_property (GObject * object, guint prop_id,
|
|||||||
/* ERROR */
|
/* ERROR */
|
||||||
wrong_state:
|
wrong_state:
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (encoder, "setting property in wrong state");
|
GST_WARNING_OBJECT (encoder, "setting property in wrong state");
|
||||||
GST_OBJECT_UNLOCK (encoder);
|
GST_OBJECT_UNLOCK (encoder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,6 +112,9 @@ struct _GstX264Enc
|
|||||||
|
|
||||||
gint i_type;
|
gint i_type;
|
||||||
GstEvent *forcekeyunit_event;
|
GstEvent *forcekeyunit_event;
|
||||||
|
|
||||||
|
/* configuration changed while playing */
|
||||||
|
gboolean reconfig;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstX264EncClass
|
struct _GstX264EncClass
|
||||||
|
Loading…
x
Reference in New Issue
Block a user