diff options
author | Olivier CrĂȘte <olivier.crete@collabora.co.uk> | 2010-09-21 18:57:42 -0400 |
---|---|---|
committer | Olivier CrĂȘte <olivier.crete@collabora.co.uk> | 2010-09-22 11:41:13 -0400 |
commit | 91f89f490cf9bab23f7eaab21273b4914cbf662d (patch) | |
tree | 76ce9e8bf106e0b6035757d07385d2c92edc3766 /ext | |
parent | 6ecbdab1feb6877585c491f8a0115858eae8f88f (diff) |
theoraenc: Make the bitrate/quality dynamically modifiable
https://bugzilla.gnome.org/show_bug.cgi?id=630303
Diffstat (limited to 'ext')
-rw-r--r-- | ext/theora/gsttheoraenc.c | 54 | ||||
-rw-r--r-- | ext/theora/gsttheoraenc.h | 2 |
2 files changed, 48 insertions, 8 deletions
diff --git a/ext/theora/gsttheoraenc.c b/ext/theora/gsttheoraenc.c index acc26e0f6..0c310f329 100644 --- a/ext/theora/gsttheoraenc.c +++ b/ext/theora/gsttheoraenc.c @@ -52,7 +52,7 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include "config.h" #endif #include "gsttheoraenc.h" @@ -259,11 +259,13 @@ gst_theora_enc_class_init (GstTheoraEncClass * klass) g_object_class_install_property (gobject_class, PROP_BITRATE, g_param_spec_int ("bitrate", "Bitrate", "Compressed video bitrate (kbps)", 0, (1 << 24) - 1, THEORA_DEF_BITRATE, - (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | + GST_PARAM_MUTABLE_PLAYING)); g_object_class_install_property (gobject_class, PROP_QUALITY, g_param_spec_int ("quality", "Quality", "Video quality", 0, 63, THEORA_DEF_QUALITY, - (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + (GParamFlags) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | + GST_PARAM_MUTABLE_PLAYING)); g_object_class_install_property (gobject_class, PROP_QUICK, g_param_spec_boolean ("quick", "Quick", "ignored and kept for API compat only", TRUE, @@ -462,6 +464,13 @@ theora_enc_reset (GstTheoraEnc * enc) ogg_uint32_t keyframe_force; int rate_flags; + GST_OBJECT_LOCK (enc); + enc->info.target_bitrate = enc->video_bitrate; + enc->info.quality = enc->video_quality; + enc->bitrate_changed = FALSE; + enc->quality_changed = FALSE; + GST_OBJECT_UNLOCK (enc); + if (enc->encoder) th_encode_free (enc->encoder); enc->encoder = th_encode_alloc (&enc->info); @@ -633,8 +642,6 @@ theora_enc_sink_setcaps (GstPad * pad, GstCaps * caps) } enc->info.colorspace = TH_CS_UNSPECIFIED; - enc->info.target_bitrate = enc->video_bitrate; - enc->info.quality = enc->video_quality; /* as done in theora */ enc->info.keyframe_granule_shift = _ilog (enc->keyframe_force - 1); @@ -1071,8 +1078,24 @@ theora_enc_chain (GstPad * pad, GstBuffer * buffer) return GST_FLOW_OK; } - /* see if we need to schedule a keyframe */ GST_OBJECT_LOCK (enc); + if (enc->bitrate_changed) { + long int bitrate = enc->video_bitrate; + + th_encode_ctl (enc->encoder, TH_ENCCTL_SET_BITRATE, &bitrate, + sizeof (long int)); + enc->bitrate_changed = FALSE; + } + + if (enc->quality_changed) { + long int quality = enc->video_quality; + + th_encode_ctl (enc->encoder, TH_ENCCTL_SET_QUALITY, &quality, + sizeof (long int)); + enc->quality_changed = FALSE; + } + + /* see if we need to schedule a keyframe */ force_keyframe = enc->force_keyframe; enc->force_keyframe = FALSE; GST_OBJECT_UNLOCK (enc); @@ -1353,12 +1376,23 @@ theora_enc_set_property (GObject * object, guint prop_id, /* kept for API compat, but ignored */ break; case PROP_BITRATE: + GST_OBJECT_LOCK (enc); enc->video_bitrate = g_value_get_int (value) * 1000; enc->video_quality = 0; + enc->bitrate_changed = TRUE; + GST_OBJECT_UNLOCK (enc); break; case PROP_QUALITY: - enc->video_quality = g_value_get_int (value); - enc->video_bitrate = 0; + GST_OBJECT_LOCK (enc); + if (GST_STATE (enc) >= GST_STATE_PAUSED && enc->video_quality == 0) { + GST_WARNING_OBJECT (object, "Can't change from bitrate to quality mode" + " while playing"); + } else { + enc->video_quality = g_value_get_int (value); + enc->video_bitrate = 0; + enc->quality_changed = TRUE; + } + GST_OBJECT_UNLOCK (enc); break; case PROP_KEYFRAME_AUTO: enc->keyframe_auto = g_value_get_boolean (value); @@ -1413,10 +1447,14 @@ theora_enc_get_property (GObject * object, guint prop_id, g_value_set_enum (value, BORDER_BLACK); break; case PROP_BITRATE: + GST_OBJECT_LOCK (enc); g_value_set_int (value, enc->video_bitrate / 1000); + GST_OBJECT_UNLOCK (enc); break; case PROP_QUALITY: + GST_OBJECT_LOCK (enc); g_value_set_int (value, enc->video_quality); + GST_OBJECT_UNLOCK (enc); break; case PROP_QUICK: g_value_set_boolean (value, TRUE); diff --git a/ext/theora/gsttheoraenc.h b/ext/theora/gsttheoraenc.h index 385f4e390..08707d85b 100644 --- a/ext/theora/gsttheoraenc.h +++ b/ext/theora/gsttheoraenc.h @@ -92,7 +92,9 @@ struct _GstTheoraEnc gboolean initialised; gint video_bitrate; /* bitrate target for Theora video */ + gboolean bitrate_changed; gint video_quality; /* Theora quality selector 0 = low, 63 = high */ + gboolean quality_changed; gboolean keyframe_auto; gint keyframe_freq; gint keyframe_force; |