vp8enc: add mode property to switch between CBR/VBR

Always using CBR when bitrate is used isn't that great, VBR mode
can produce meaningful results too.
This commit is contained in:
Philip Jägenstedt 2010-05-21 15:17:46 +02:00 committed by Sebastian Dröge
parent b740f4c8dd
commit 17ab21dae3

View file

@ -72,6 +72,7 @@ struct _GstVP8Enc
/* properties */ /* properties */
int bitrate; int bitrate;
enum vpx_rc_mode mode;
double quality; double quality;
gboolean error_resilient; gboolean error_resilient;
int max_latency; int max_latency;
@ -108,6 +109,7 @@ enum
}; };
#define DEFAULT_BITRATE 0 #define DEFAULT_BITRATE 0
#define DEFAULT_MODE VPX_VBR
#define DEFAULT_QUALITY 5 #define DEFAULT_QUALITY 5
#define DEFAULT_ERROR_RESILIENT FALSE #define DEFAULT_ERROR_RESILIENT FALSE
#define DEFAULT_MAX_LATENCY 10 #define DEFAULT_MAX_LATENCY 10
@ -118,6 +120,7 @@ enum
{ {
PROP_0, PROP_0,
PROP_BITRATE, PROP_BITRATE,
PROP_MODE,
PROP_QUALITY, PROP_QUALITY,
PROP_ERROR_RESILIENT, PROP_ERROR_RESILIENT,
PROP_MAX_LATENCY, PROP_MAX_LATENCY,
@ -125,6 +128,28 @@ enum
PROP_SPEED PROP_SPEED
}; };
#define GST_VP8_ENC_MODE_TYPE (gst_vp8_enc_mode_get_type())
static GType
gst_vp8_enc_mode_get_type (void)
{
static const GEnumValue values[] = {
{VPX_VBR, "Variable Bit Rate (VBR) mode", "vbr"},
{VPX_CBR, "Constant Bit Rate (CBR) mode", "cbr"},
{0, NULL, NULL}
};
static volatile GType id = 0;
if (g_once_init_enter ((gsize *) & id)) {
GType _id;
_id = g_enum_register_static ("GstVP8EncMode", values);
g_once_init_leave ((gsize *) & id, _id);
}
return id;
}
static void gst_vp8_enc_finalize (GObject * object); static void gst_vp8_enc_finalize (GObject * object);
static void gst_vp8_enc_set_property (GObject * object, guint prop_id, static void gst_vp8_enc_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec); const GValue * value, GParamSpec * pspec);
@ -226,6 +251,12 @@ gst_vp8_enc_class_init (GstVP8EncClass * klass)
0, 1000000000, DEFAULT_BITRATE, 0, 1000000000, DEFAULT_BITRATE,
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (gobject_class, PROP_MODE,
g_param_spec_enum ("mode", "Mode",
"Mode",
GST_VP8_ENC_MODE_TYPE, DEFAULT_MODE,
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (gobject_class, PROP_QUALITY, g_object_class_install_property (gobject_class, PROP_QUALITY,
g_param_spec_double ("quality", "Quality", g_param_spec_double ("quality", "Quality",
"Quality", "Quality",
@ -266,6 +297,7 @@ gst_vp8_enc_init (GstVP8Enc * gst_vp8_enc, GstVP8EncClass * klass)
GST_DEBUG_OBJECT (gst_vp8_enc, "init"); GST_DEBUG_OBJECT (gst_vp8_enc, "init");
gst_vp8_enc->bitrate = DEFAULT_BITRATE; gst_vp8_enc->bitrate = DEFAULT_BITRATE;
gst_vp8_enc->mode = DEFAULT_MODE;
gst_vp8_enc->quality = DEFAULT_QUALITY; gst_vp8_enc->quality = DEFAULT_QUALITY;
gst_vp8_enc->error_resilient = DEFAULT_ERROR_RESILIENT; gst_vp8_enc->error_resilient = DEFAULT_ERROR_RESILIENT;
gst_vp8_enc->max_latency = DEFAULT_MAX_LATENCY; gst_vp8_enc->max_latency = DEFAULT_MAX_LATENCY;
@ -306,6 +338,9 @@ gst_vp8_enc_set_property (GObject * object, guint prop_id,
case PROP_BITRATE: case PROP_BITRATE:
gst_vp8_enc->bitrate = g_value_get_int (value); gst_vp8_enc->bitrate = g_value_get_int (value);
break; break;
case PROP_MODE:
gst_vp8_enc->mode = g_value_get_enum (value);
break;
case PROP_QUALITY: case PROP_QUALITY:
gst_vp8_enc->quality = g_value_get_double (value); gst_vp8_enc->quality = g_value_get_double (value);
break; break;
@ -339,6 +374,9 @@ gst_vp8_enc_get_property (GObject * object, guint prop_id, GValue * value,
case PROP_BITRATE: case PROP_BITRATE:
g_value_set_int (value, gst_vp8_enc->bitrate); g_value_set_int (value, gst_vp8_enc->bitrate);
break; break;
case PROP_MODE:
g_value_set_enum (value, gst_vp8_enc->mode);
break;
case PROP_QUALITY: case PROP_QUALITY:
g_value_set_double (value, gst_vp8_enc->quality); g_value_set_double (value, gst_vp8_enc->quality);
break; break;
@ -634,11 +672,10 @@ gst_vp8_enc_handle_frame (GstBaseVideoEncoder * base_video_encoder,
cfg.g_pass = VPX_RC_ONE_PASS; cfg.g_pass = VPX_RC_ONE_PASS;
cfg.g_lag_in_frames = encoder->max_latency; cfg.g_lag_in_frames = encoder->max_latency;
cfg.rc_end_usage = encoder->mode;
if (encoder->bitrate) { if (encoder->bitrate) {
cfg.rc_end_usage = VPX_CBR;
cfg.rc_target_bitrate = encoder->bitrate / 1000; cfg.rc_target_bitrate = encoder->bitrate / 1000;
} else { } else {
cfg.rc_end_usage = VPX_VBR;
cfg.rc_min_quantizer = 63 - encoder->quality * 5.0; cfg.rc_min_quantizer = 63 - encoder->quality * 5.0;
cfg.rc_max_quantizer = 63 - encoder->quality * 5.0; cfg.rc_max_quantizer = 63 - encoder->quality * 5.0;
cfg.rc_target_bitrate = encoder->bitrate; cfg.rc_target_bitrate = encoder->bitrate;