summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleksij Rempel <linux@rempel-privat.de>2015-07-09 09:51:26 +0200
committerTim-Philipp Müller <tim@centricular.com>2015-08-14 11:40:58 +0100
commitabc33c928fc39ab58ec7f8f3784b72b4266242ae (patch)
tree72b357b2a2674341756e50049386f68157138405
parent23b5a346751df9a4bc4f8e3a4c8196f51ea052db (diff)
vp8enc: provide support for multiple pass cache files
Some files may provide different caps insight of one stream. Since vp8enc 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 ... https://bugzilla.gnome.org/show_bug.cgi?id=747728
-rw-r--r--ext/vpx/gstvp8enc.c51
-rw-r--r--ext/vpx/gstvp8enc.h2
2 files changed, 38 insertions, 15 deletions
diff --git a/ext/vpx/gstvp8enc.c b/ext/vpx/gstvp8enc.c
index 364bfa3fe..f203cdc07 100644
--- a/ext/vpx/gstvp8enc.c
+++ b/ext/vpx/gstvp8enc.c
@@ -557,7 +557,9 @@ gst_vp8_enc_class_init (GstVP8EncClass * 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)));
@@ -759,7 +761,9 @@ gst_vp8_enc_init (GstVP8Enc * gst_vp8_enc)
gst_vp8_enc->cfg.kf_mode = DEFAULT_KF_MODE;
gst_vp8_enc->cfg.kf_max_dist = DEFAULT_KF_MAX_DIST;
gst_vp8_enc->cfg.g_pass = DEFAULT_MULTIPASS_MODE;
- gst_vp8_enc->multipass_cache_file = g_strdup (DEFAULT_MULTIPASS_CACHE_FILE);
+ gst_vp8_enc->multipass_cache_prefix = g_strdup (DEFAULT_MULTIPASS_CACHE_FILE);
+ gst_vp8_enc->multipass_cache_file = NULL;
+ gst_vp8_enc->multipass_cache_idx = 0;
gst_vp8_enc->cfg.ts_number_layers = DEFAULT_TS_NUMBER_LAYERS;
gst_vp8_enc->n_ts_target_bitrate = 0;
gst_vp8_enc->n_ts_rate_decimator = 0;
@@ -801,8 +805,10 @@ gst_vp8_enc_finalize (GObject * object)
g_return_if_fail (GST_IS_VP8_ENC (object));
gst_vp8_enc = GST_VP8_ENC (object);
+ g_free (gst_vp8_enc->multipass_cache_prefix);
g_free (gst_vp8_enc->multipass_cache_file);
- gst_vp8_enc->multipass_cache_file = NULL;
+ gst_vp8_enc->multipass_cache_idx = 0;
+
if (gst_vp8_enc->input_state)
gst_video_codec_state_unref (gst_vp8_enc->input_state);
@@ -904,9 +910,9 @@ gst_vp8_enc_set_property (GObject * object, guint prop_id,
global = TRUE;
break;
case PROP_MULTIPASS_CACHE_FILE:
- if (gst_vp8_enc->multipass_cache_file)
- g_free (gst_vp8_enc->multipass_cache_file);
- gst_vp8_enc->multipass_cache_file = g_value_dup_string (value);
+ if (gst_vp8_enc->multipass_cache_prefix)
+ g_free (gst_vp8_enc->multipass_cache_prefix);
+ gst_vp8_enc->multipass_cache_prefix = g_value_dup_string (value);
break;
case PROP_TS_NUMBER_LAYERS:
gst_vp8_enc->cfg.ts_number_layers = g_value_get_int (value);
@@ -1264,7 +1270,7 @@ gst_vp8_enc_get_property (GObject * object, guint prop_id, GValue * value,
g_value_set_enum (value, gst_vp8_enc->cfg.g_pass);
break;
case PROP_MULTIPASS_CACHE_FILE:
- g_value_set_string (value, gst_vp8_enc->multipass_cache_file);
+ g_value_set_string (value, gst_vp8_enc->multipass_cache_prefix);
break;
case PROP_TS_NUMBER_LAYERS:
g_value_set_int (value, gst_vp8_enc->cfg.ts_number_layers);
@@ -1520,6 +1526,7 @@ gst_vp8_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);
}
@@ -1550,20 +1557,34 @@ gst_vp8_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;
diff --git a/ext/vpx/gstvp8enc.h b/ext/vpx/gstvp8enc.h
index d70f383a3..3f0464648 100644
--- a/ext/vpx/gstvp8enc.h
+++ b/ext/vpx/gstvp8enc.h
@@ -73,6 +73,8 @@ struct _GstVP8Enc
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 */