summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean DuBois <sean@siobud.com>2018-02-05 08:52:55 +0000
committerSebastian Dröge <sebastian@centricular.com>2018-02-14 10:19:40 +0200
commita8ffc56f842e1a267bcfbc42950dcc8c4bf74a4b (patch)
treed2bb2859eec7f2cc6537569a2d337e796dbbd65e
parent3cf4a70dbc7af93eaf4198cfd20683ff61206405 (diff)
downloadgstreamer-plugins-bad-a8ffc56f842e1a267bcfbc42950dcc8c4bf74a4b.tar.gz
aom: Implement cpu-used in av1enc
https://bugzilla.gnome.org/show_bug.cgi?id=791674
-rw-r--r--ext/aom/gstav1enc.c43
-rw-r--r--ext/aom/gstav1enc.h10
2 files changed, 47 insertions, 6 deletions
diff --git a/ext/aom/gstav1enc.c b/ext/aom/gstav1enc.c
index 748b3eeeb..84b4b93ee 100644
--- a/ext/aom/gstav1enc.c
+++ b/ext/aom/gstav1enc.c
@@ -38,6 +38,14 @@
#include <gst/video/gstvideometa.h>
#include <gst/base/base.h>
+#define GST_AV1_ENC_APPLY_CODEC_CONTROL(av1enc, flag, value) \
+ if (av1enc->encoder_inited) { \
+ if (aom_codec_control (&av1enc->encoder, flag, \
+ value) != AOM_CODEC_OK) { \
+ gst_av1_codec_error (&av1enc->encoder, "Failed to set " #flag); \
+ } \
+ }
+
GST_DEBUG_CATEGORY_STATIC (av1_enc_debug);
#define GST_CAT_DEFAULT av1_enc_debug
@@ -48,9 +56,12 @@ enum
enum
{
- PROP_0
+ PROP_0,
+ PROP_CPU_USED
};
+#define PROP_CPU_USED_DEFAULT 0
+
static void gst_av1_enc_finalize (GObject * object);
static void gst_av1_enc_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
@@ -124,6 +135,12 @@ gst_av1_enc_class_init (GstAV1EncClass * klass)
klass->codec_algo = &aom_codec_av1_cx_algo;
GST_DEBUG_CATEGORY_INIT (av1_enc_debug, "av1enc", 0, "AV1 encoding element");
+
+ g_object_class_install_property (gobject_class, PROP_CPU_USED,
+ g_param_spec_int ("cpu-used", "CPU Used",
+ "CPU Used. A Value greater than 0 will increase encoder speed at the expense of quality.",
+ 0, 8, PROP_CPU_USED_DEFAULT,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}
static void
@@ -139,8 +156,12 @@ gst_av1_enc_init (GstAV1Enc * av1enc)
{
GST_PAD_SET_ACCEPT_TEMPLATE (GST_VIDEO_ENCODER_SINK_PAD (av1enc));
- av1enc->keyframe_dist = 30;
av1enc->encoder_inited = FALSE;
+
+ av1enc->keyframe_dist = 30;
+ av1enc->cpu_used = PROP_CPU_USED_DEFAULT;
+
+ g_mutex_init (&av1enc->encoder_lock);
}
static void
@@ -154,6 +175,7 @@ gst_av1_enc_finalize (GObject * object)
av1enc->input_state = NULL;
gst_av1_enc_destroy_encoder (av1enc);
+ g_mutex_clear (&av1enc->encoder_lock);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -253,6 +275,7 @@ gst_av1_enc_set_format (GstVideoEncoder * encoder, GstVideoCodecState * state)
gst_av1_enc_set_latency (av1enc);
+ g_mutex_lock (&av1enc->encoder_lock);
if (aom_codec_enc_config_default (av1enc_class->codec_algo, &av1enc->aom_cfg,
0)) {
gst_av1_codec_error (&av1enc->encoder,
@@ -281,6 +304,9 @@ gst_av1_enc_set_format (GstVideoEncoder * encoder, GstVideoCodecState * state)
}
av1enc->encoder_inited = TRUE;
+ GST_AV1_ENC_APPLY_CODEC_CONTROL (av1enc, AOME_SET_CPUUSED, av1enc->cpu_used);
+ g_mutex_unlock (&av1enc->encoder_lock);
+
return TRUE;
}
@@ -359,11 +385,13 @@ gst_av1_enc_handle_frame (GstVideoEncoder * encoder, GstVideoCodecFrame * frame)
}
av1enc->keyframe_dist++;
+ g_mutex_lock (&av1enc->encoder_lock);
if (aom_codec_encode (&av1enc->encoder, &raw, frame->pts, 1, flags)
!= AOM_CODEC_OK) {
gst_av1_codec_error (&av1enc->encoder, "Failed to encode frame");
ret = GST_FLOW_ERROR;
}
+ g_mutex_unlock (&av1enc->encoder_lock);
aom_img_free (&raw);
gst_video_codec_frame_unref (frame);
@@ -377,10 +405,12 @@ gst_av1_enc_handle_frame (GstVideoEncoder * encoder, GstVideoCodecFrame * frame)
static void
gst_av1_enc_destroy_encoder (GstAV1Enc * av1enc)
{
+ g_mutex_lock (&av1enc->encoder_lock);
if (av1enc->encoder_inited) {
aom_codec_destroy (&av1enc->encoder);
av1enc->encoder_inited = FALSE;
}
+ g_mutex_unlock (&av1enc->encoder_lock);
}
static gboolean
@@ -400,11 +430,18 @@ gst_av1_enc_set_property (GObject * object, guint prop_id,
GST_OBJECT_LOCK (av1enc);
+ g_mutex_lock (&av1enc->encoder_lock);
switch (prop_id) {
+ case PROP_CPU_USED:
+ av1enc->cpu_used = g_value_get_int (value);
+ GST_AV1_ENC_APPLY_CODEC_CONTROL (av1enc, AOME_SET_CPUUSED,
+ av1enc->cpu_used);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
+ g_mutex_unlock (&av1enc->encoder_lock);
GST_OBJECT_UNLOCK (av1enc);
}
@@ -418,6 +455,8 @@ gst_av1_enc_get_property (GObject * object, guint prop_id, GValue * value,
GST_OBJECT_LOCK (av1enc);
switch (prop_id) {
+ case PROP_CPU_USED:
+ g_value_set_int (value, av1enc->cpu_used);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
diff --git a/ext/aom/gstav1enc.h b/ext/aom/gstav1enc.h
index 60fb79435..dcb7590f6 100644
--- a/ext/aom/gstav1enc.h
+++ b/ext/aom/gstav1enc.h
@@ -53,14 +53,16 @@ struct _GstAV1Enc
{
GstVideoEncoder base_video_encoder;
- gboolean encoder_inited;
-
+ /* properties */
guint keyframe_dist;
+ gint cpu_used;
+ /* state */
+ gboolean encoder_inited;
+ GstVideoCodecState *input_state;
aom_codec_enc_cfg_t aom_cfg;
aom_codec_ctx_t encoder;
-
- GstVideoCodecState *input_state;
+ GMutex encoder_lock;
};
struct _GstAV1EncClass