Commit 0e10e929 authored by Tim-Philipp Müller's avatar Tim-Philipp Müller 🐠

vp9enc: provide support for multiple pass cache files

Some files may provide different caps insight of one stream. Since
vp9enc support caps reinit, we should support cache reinit too.
If more then file cache file will be created, the naming will be:
cache cache.1 cache.2 ...

Based on patch by: Oleksij Rempel <linux@rempel-privat.de>

https://bugzilla.gnome.org/show_bug.cgi?id=747728
parent 2b1db231
......@@ -529,7 +529,9 @@ gst_vp9_enc_class_init (GstVP9EncClass * klass)
g_object_class_install_property (gobject_class, PROP_MULTIPASS_CACHE_FILE,
g_param_spec_string ("multipass-cache-file", "Multipass Cache File",
"Multipass cache file",
"Multipass cache file. "
"If stream caps reinited, multiple files will be created: "
"file, file.1, file.2, ... and so on.",
DEFAULT_MULTIPASS_CACHE_FILE,
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
......@@ -731,7 +733,9 @@ gst_vp9_enc_init (GstVP9Enc * gst_vp9_enc)
gst_vp9_enc->cfg.kf_mode = DEFAULT_KF_MODE;
gst_vp9_enc->cfg.kf_max_dist = DEFAULT_KF_MAX_DIST;
gst_vp9_enc->cfg.g_pass = DEFAULT_MULTIPASS_MODE;
gst_vp9_enc->multipass_cache_file = g_strdup (DEFAULT_MULTIPASS_CACHE_FILE);
gst_vp9_enc->multipass_cache_prefix = g_strdup (DEFAULT_MULTIPASS_CACHE_FILE);
gst_vp9_enc->multipass_cache_file = NULL;
gst_vp9_enc->multipass_cache_idx = 0;
gst_vp9_enc->cfg.ts_number_layers = DEFAULT_TS_NUMBER_LAYERS;
gst_vp9_enc->n_ts_target_bitrate = 0;
gst_vp9_enc->n_ts_rate_decimator = 0;
......@@ -773,8 +777,9 @@ gst_vp9_enc_finalize (GObject * object)
g_return_if_fail (GST_IS_VP9_ENC (object));
gst_vp9_enc = GST_VP9_ENC (object);
g_free (gst_vp9_enc->multipass_cache_prefix);
g_free (gst_vp9_enc->multipass_cache_file);
gst_vp9_enc->multipass_cache_file = NULL;
gst_vp9_enc->multipass_cache_idx = 0;
if (gst_vp9_enc->input_state)
gst_video_codec_state_unref (gst_vp9_enc->input_state);
......@@ -876,9 +881,9 @@ gst_vp9_enc_set_property (GObject * object, guint prop_id,
global = TRUE;
break;
case PROP_MULTIPASS_CACHE_FILE:
if (gst_vp9_enc->multipass_cache_file)
g_free (gst_vp9_enc->multipass_cache_file);
gst_vp9_enc->multipass_cache_file = g_value_dup_string (value);
if (gst_vp9_enc->multipass_cache_prefix)
g_free (gst_vp9_enc->multipass_cache_prefix);
gst_vp9_enc->multipass_cache_prefix = g_value_dup_string (value);
break;
case PROP_TS_NUMBER_LAYERS:
gst_vp9_enc->cfg.ts_number_layers = g_value_get_int (value);
......@@ -1238,7 +1243,7 @@ gst_vp9_enc_get_property (GObject * object, guint prop_id, GValue * value,
g_value_set_enum (value, gst_vp9_enc->cfg.g_pass);
break;
case PROP_MULTIPASS_CACHE_FILE:
g_value_set_string (value, gst_vp9_enc->multipass_cache_file);
g_value_set_string (value, gst_vp9_enc->multipass_cache_prefix);
break;
case PROP_TS_NUMBER_LAYERS:
g_value_set_int (value, gst_vp9_enc->cfg.ts_number_layers);
......@@ -1493,6 +1498,7 @@ gst_vp9_enc_set_format (GstVideoEncoder * video_encoder,
g_mutex_lock (&encoder->encoder_lock);
vpx_codec_destroy (&encoder->encoder);
encoder->inited = FALSE;
encoder->multipass_cache_idx++;
} else {
g_mutex_lock (&encoder->encoder_lock);
}
......@@ -1523,20 +1529,34 @@ gst_vp9_enc_set_format (GstVideoEncoder * video_encoder,
encoder->cfg.g_timebase.den = 90000;
}
if (encoder->cfg.g_pass == VPX_RC_FIRST_PASS) {
if (encoder->first_pass_cache_content == NULL) {
encoder->first_pass_cache_content = g_byte_array_sized_new (4096);
}
} else if (encoder->cfg.g_pass == VPX_RC_LAST_PASS) {
GError *err = NULL;
if (!encoder->multipass_cache_file) {
if (encoder->cfg.g_pass == VPX_RC_FIRST_PASS ||
encoder->cfg.g_pass == VPX_RC_LAST_PASS) {
if (!encoder->multipass_cache_prefix) {
GST_ELEMENT_ERROR (encoder, RESOURCE, OPEN_READ,
("No multipass cache file provided"), (NULL));
g_mutex_unlock (&encoder->encoder_lock);
return FALSE;
}
g_free (encoder->multipass_cache_file);
if (encoder->multipass_cache_idx > 0)
encoder->multipass_cache_file = g_strdup_printf ("%s.%u",
encoder->multipass_cache_prefix, encoder->multipass_cache_idx);
else
encoder->multipass_cache_file =
g_strdup (encoder->multipass_cache_prefix);
}
if (encoder->cfg.g_pass == VPX_RC_FIRST_PASS) {
if (encoder->first_pass_cache_content != NULL)
g_byte_array_free (encoder->first_pass_cache_content, TRUE);
encoder->first_pass_cache_content = g_byte_array_sized_new (4096);
} else if (encoder->cfg.g_pass == VPX_RC_LAST_PASS) {
GError *err = NULL;
if (encoder->cfg.rc_twopass_stats_in.buf != NULL) {
g_free (encoder->cfg.rc_twopass_stats_in.buf);
encoder->cfg.rc_twopass_stats_in.buf = NULL;
......
......@@ -73,6 +73,8 @@ struct _GstVP9Enc
gint n_ts_layer_id;
/* Global two-pass options */
gchar *multipass_cache_file;
gchar *multipass_cache_prefix;
guint multipass_cache_idx;
GByteArray *first_pass_cache_content;
/* Encode parameter */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment