summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorOlivier CrĂȘte <olivier.crete@collabora.co.uk>2010-09-21 18:57:42 -0400
committerOlivier CrĂȘte <olivier.crete@collabora.co.uk>2010-09-22 11:41:13 -0400
commit91f89f490cf9bab23f7eaab21273b4914cbf662d (patch)
tree76ce9e8bf106e0b6035757d07385d2c92edc3766 /ext
parent6ecbdab1feb6877585c491f8a0115858eae8f88f (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.c54
-rw-r--r--ext/theora/gsttheoraenc.h2
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;