mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-19 14:56:36 +00:00
vp8enc: Add property to manually specify the timebase of the encoder
https://bugzilla.gnome.org/show_bug.cgi?id=695709
This commit is contained in:
parent
7a3df1ab31
commit
5532989728
2 changed files with 45 additions and 11 deletions
|
@ -146,6 +146,8 @@ gst_vp8_enc_user_data_free (GstVP8EncUserData * user_data)
|
|||
#define DEFAULT_TUNING VP8_TUNE_PSNR
|
||||
#define DEFAULT_CQ_LEVEL 10
|
||||
#define DEFAULT_MAX_INTRA_BITRATE_PCT 0
|
||||
#define DEFAULT_TIMEBASE_N 0
|
||||
#define DEFAULT_TIMEBASE_D 1
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -192,7 +194,8 @@ enum
|
|||
PROP_ARNR_TYPE,
|
||||
PROP_TUNING,
|
||||
PROP_CQ_LEVEL,
|
||||
PROP_MAX_INTRA_BITRATE_PCT
|
||||
PROP_MAX_INTRA_BITRATE_PCT,
|
||||
PROP_TIMEBASE
|
||||
};
|
||||
|
||||
#define GST_VP8_ENC_END_USAGE_TYPE (gst_vp8_enc_end_usage_get_type())
|
||||
|
@ -393,8 +396,7 @@ GST_STATIC_PAD_TEMPLATE ("src",
|
|||
#define parent_class gst_vp8_enc_parent_class
|
||||
G_DEFINE_TYPE_WITH_CODE (GstVP8Enc, gst_vp8_enc, GST_TYPE_VIDEO_ENCODER,
|
||||
G_IMPLEMENT_INTERFACE (GST_TYPE_TAG_SETTER, NULL);
|
||||
G_IMPLEMENT_INTERFACE (GST_TYPE_PRESET, NULL);
|
||||
);
|
||||
G_IMPLEMENT_INTERFACE (GST_TYPE_PRESET, NULL););
|
||||
|
||||
static void
|
||||
gst_vp8_enc_class_init (GstVP8EncClass * klass)
|
||||
|
@ -700,6 +702,12 @@ gst_vp8_enc_class_init (GstVP8EncClass * klass)
|
|||
0, G_MAXINT, DEFAULT_MAX_INTRA_BITRATE_PCT,
|
||||
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_TIMEBASE,
|
||||
gst_param_spec_fraction ("timebase", "Shortest interframe time",
|
||||
"Fraction of one second that is the shortest interframe time - normally left as zero which will default to the framerate",
|
||||
0, 1, G_MAXINT, 1, DEFAULT_TIMEBASE_N, DEFAULT_TIMEBASE_D,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (gst_vp8enc_debug, "vp8enc", 0, "VP8 Encoder");
|
||||
}
|
||||
|
||||
|
@ -768,6 +776,8 @@ gst_vp8_enc_init (GstVP8Enc * gst_vp8_enc)
|
|||
gst_vp8_enc->tuning = DEFAULT_TUNING;
|
||||
gst_vp8_enc->cq_level = DEFAULT_CQ_LEVEL;
|
||||
gst_vp8_enc->max_intra_bitrate_pct = DEFAULT_MAX_INTRA_BITRATE_PCT;
|
||||
gst_vp8_enc->timebase_n = DEFAULT_TIMEBASE_N;
|
||||
gst_vp8_enc->timebase_d = DEFAULT_TIMEBASE_D;
|
||||
|
||||
gst_vp8_enc->cfg.g_profile = DEFAULT_PROFILE;
|
||||
|
||||
|
@ -1162,6 +1172,10 @@ gst_vp8_enc_set_property (GObject * object, guint prop_id,
|
|||
}
|
||||
}
|
||||
break;
|
||||
case PROP_TIMEBASE:
|
||||
gst_vp8_enc->timebase_n = gst_value_get_fraction_numerator (value);
|
||||
gst_vp8_enc->timebase_d = gst_value_get_fraction_denominator (value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1379,6 +1393,10 @@ gst_vp8_enc_get_property (GObject * object, guint prop_id, GValue * value,
|
|||
case PROP_MAX_INTRA_BITRATE_PCT:
|
||||
g_value_set_int (value, gst_vp8_enc->max_intra_bitrate_pct);
|
||||
break;
|
||||
case PROP_TIMEBASE:
|
||||
gst_value_set_fraction (value, gst_vp8_enc->timebase_n,
|
||||
gst_vp8_enc->timebase_d);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -1508,16 +1526,29 @@ gst_vp8_enc_set_format (GstVideoEncoder * video_encoder,
|
|||
|
||||
encoder->cfg.g_w = GST_VIDEO_INFO_WIDTH (info);
|
||||
encoder->cfg.g_h = GST_VIDEO_INFO_HEIGHT (info);
|
||||
if (GST_VIDEO_INFO_FPS_D (info) == 0 || GST_VIDEO_INFO_FPS_N (info) == 0) {
|
||||
/* Zero framerate but still need to setup the timebase so we
|
||||
* presume this is RTP - VP8 payload draft states clock rate of 90000
|
||||
* see specification http://tools.ietf.org/html/draft-ietf-payload-vp8-01
|
||||
* section 6.3.1 */
|
||||
encoder->cfg.g_timebase.num = 1;
|
||||
encoder->cfg.g_timebase.den = 90000;
|
||||
} else {
|
||||
|
||||
if (encoder->timebase_n != 0 && encoder->timebase_d != 0) {
|
||||
GST_DEBUG_OBJECT (video_encoder, "Using timebase configuration");
|
||||
encoder->cfg.g_timebase.num = encoder->timebase_n;
|
||||
encoder->cfg.g_timebase.den = encoder->timebase_d;
|
||||
} else if (GST_VIDEO_INFO_FPS_D (info) != 0
|
||||
&& GST_VIDEO_INFO_FPS_N (info) != 0) {
|
||||
/* GstVideoInfo holds either the framerate or max-framerate (if framerate
|
||||
* is 0) in FPS so this will be used if max-framerate or framerate
|
||||
* is set */
|
||||
GST_DEBUG_OBJECT (video_encoder, "Setting timebase from framerate");
|
||||
encoder->cfg.g_timebase.num = GST_VIDEO_INFO_FPS_D (info);
|
||||
encoder->cfg.g_timebase.den = GST_VIDEO_INFO_FPS_N (info);
|
||||
} else {
|
||||
/* Zero framerate and max-framerate but still need to setup the timebase to avoid
|
||||
* a divide by zero error. Presuming the lowest common denominator will be RTP -
|
||||
* VP8 payload draft states clock rate of 90000 which should work for anyone where
|
||||
* FPS < 90000 (shouldn't be too many cases where it's higher) though wouldn't be optimal. RTP specification
|
||||
* http://tools.ietf.org/html/draft-ietf-payload-vp8-01 section 6.3.1 */
|
||||
GST_WARNING_OBJECT (encoder,
|
||||
"No timebase and zero framerate setting timebase to 1/90000");
|
||||
encoder->cfg.g_timebase.num = 1;
|
||||
encoder->cfg.g_timebase.den = 90000;
|
||||
}
|
||||
|
||||
if (encoder->cfg.g_pass == VPX_RC_FIRST_PASS) {
|
||||
|
|
|
@ -87,6 +87,9 @@ struct _GstVP8Enc
|
|||
vp8e_tuning tuning;
|
||||
unsigned int cq_level;
|
||||
unsigned int max_intra_bitrate_pct;
|
||||
/* Timebase - a value of 0 will use the framerate */
|
||||
unsigned int timebase_n;
|
||||
unsigned int timebase_d;
|
||||
|
||||
/* state */
|
||||
gboolean inited;
|
||||
|
|
Loading…
Reference in a new issue