svtav1enc: Fix indentation

This commit is contained in:
Sebastian Dröge 2023-02-03 21:20:56 +02:00
parent 7890a1f8c7
commit 5bc92375c9

View File

@ -30,7 +30,9 @@ GST_DEBUG_CATEGORY_STATIC(gst_svtav1enc_debug_category);
#define GST_CAT_DEFAULT gst_svtav1enc_debug_category #define GST_CAT_DEFAULT gst_svtav1enc_debug_category
#define GST_SVTAV1ENC_TYPE_INTRA_REFRESH_TYPE (gst_svtav1enc_intra_refresh_type_get_type()) #define GST_SVTAV1ENC_TYPE_INTRA_REFRESH_TYPE (gst_svtav1enc_intra_refresh_type_get_type())
static GType gst_svtav1enc_intra_refresh_type_get_type(void) { static GType
gst_svtav1enc_intra_refresh_type_get_type (void)
{
static GType intra_refresh_type = 0; static GType intra_refresh_type = 0;
static const GEnumValue intra_refresh[] = { static const GEnumValue intra_refresh[] = {
{SVT_AV1_FWDKF_REFRESH, "Open GOP", "CRA"}, {SVT_AV1_FWDKF_REFRESH, "Open GOP", "CRA"},
@ -39,41 +41,45 @@ static GType gst_svtav1enc_intra_refresh_type_get_type(void) {
}; };
if (!intra_refresh_type) { if (!intra_refresh_type) {
intra_refresh_type = g_enum_register_static("GstSvtAv1EncIntraRefreshType", intra_refresh); intra_refresh_type =
g_enum_register_static ("GstSvtAv1EncIntraRefreshType", intra_refresh);
} }
return intra_refresh_type; return intra_refresh_type;
} }
/* prototypes */ /* prototypes */
static void gst_svtav1enc_set_property(GObject *object, guint property_id, const GValue *value, static void gst_svtav1enc_set_property (GObject * object, guint property_id,
GParamSpec *pspec); const GValue * value, GParamSpec * pspec);
static void gst_svtav1enc_get_property(GObject *object, guint property_id, GValue *value, static void gst_svtav1enc_get_property (GObject * object, guint property_id,
GParamSpec *pspec); GValue * value, GParamSpec * pspec);
static void gst_svtav1enc_finalize (GObject * object); static void gst_svtav1enc_finalize (GObject * object);
static void gst_svtav1enc_allocate_svt_buffers (GstSvtAv1Enc * svtav1enc); static void gst_svtav1enc_allocate_svt_buffers (GstSvtAv1Enc * svtav1enc);
static void gst_svtav1enc_deallocate_svt_buffers (GstSvtAv1Enc * svtav1enc); static void gst_svtav1enc_deallocate_svt_buffers (GstSvtAv1Enc * svtav1enc);
static gboolean gst_svtav1enc_configure_svt (GstSvtAv1Enc * svtav1enc); static gboolean gst_svtav1enc_configure_svt (GstSvtAv1Enc * svtav1enc);
static GstFlowReturn gst_svtav1enc_encode(GstSvtAv1Enc *svtav1enc, GstVideoCodecFrame *frame); static GstFlowReturn gst_svtav1enc_encode (GstSvtAv1Enc * svtav1enc,
GstVideoCodecFrame * frame);
static gboolean gst_svtav1enc_send_eos (GstSvtAv1Enc * svtav1enc); static gboolean gst_svtav1enc_send_eos (GstSvtAv1Enc * svtav1enc);
static GstFlowReturn gst_svtav1enc_dequeue_encoded_frames(GstSvtAv1Enc *svtav1enc, static GstFlowReturn gst_svtav1enc_dequeue_encoded_frames (GstSvtAv1Enc *
gboolean closing_encoder, svtav1enc, gboolean closing_encoder, gboolean output_frames);
gboolean output_frames);
static gboolean gst_svtav1enc_open (GstVideoEncoder * encoder); static gboolean gst_svtav1enc_open (GstVideoEncoder * encoder);
static gboolean gst_svtav1enc_close (GstVideoEncoder * encoder); static gboolean gst_svtav1enc_close (GstVideoEncoder * encoder);
static gboolean gst_svtav1enc_start (GstVideoEncoder * encoder); static gboolean gst_svtav1enc_start (GstVideoEncoder * encoder);
static gboolean gst_svtav1enc_stop (GstVideoEncoder * encoder); static gboolean gst_svtav1enc_stop (GstVideoEncoder * encoder);
static gboolean gst_svtav1enc_set_format(GstVideoEncoder *encoder, GstVideoCodecState *state); static gboolean gst_svtav1enc_set_format (GstVideoEncoder * encoder,
GstVideoCodecState * state);
static GstFlowReturn gst_svtav1enc_handle_frame (GstVideoEncoder * encoder, static GstFlowReturn gst_svtav1enc_handle_frame (GstVideoEncoder * encoder,
GstVideoCodecFrame * frame); GstVideoCodecFrame * frame);
static GstFlowReturn gst_svtav1enc_finish (GstVideoEncoder * encoder); static GstFlowReturn gst_svtav1enc_finish (GstVideoEncoder * encoder);
static gboolean gst_svtav1enc_propose_allocation(GstVideoEncoder *encoder, GstQuery *query); static gboolean gst_svtav1enc_propose_allocation (GstVideoEncoder * encoder,
GstQuery * query);
static gboolean gst_svtav1enc_flush (GstVideoEncoder * encoder); static gboolean gst_svtav1enc_flush (GstVideoEncoder * encoder);
static void gst_svtav1enc_parse_parameters_string (GstSvtAv1Enc * svtav1enc); static void gst_svtav1enc_parse_parameters_string (GstSvtAv1Enc * svtav1enc);
enum { enum
{
PROP_0, PROP_0,
PROP_PRESET, PROP_PRESET,
PROP_TARGET_BITRATE, PROP_TARGET_BITRATE,
@ -111,22 +117,17 @@ enum {
#endif #endif
/* pad templates */ /* pad templates */
static GstStaticPadTemplate gst_svtav1enc_sink_pad_template = GST_STATIC_PAD_TEMPLATE( static GstStaticPadTemplate gst_svtav1enc_sink_pad_template =
"sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
GST_STATIC_CAPS("video/x-raw, " GST_STATIC_CAPS ("video/x-raw, " "format = (string) {I420, " FORMAT_I420_10
"format = (string) {I420, " FORMAT_I420_10 "}, " "}, " "width = (int) [64, 16384], " "height = (int) [64, 8704], "
"width = (int) [64, 16384], "
"height = (int) [64, 8704], "
"framerate = (fraction) [0, MAX]")); "framerate = (fraction) [0, MAX]"));
static GstStaticPadTemplate gst_svtav1enc_src_pad_template = GST_STATIC_PAD_TEMPLATE( static GstStaticPadTemplate gst_svtav1enc_src_pad_template =
"src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
GST_STATIC_CAPS("video/x-av1, " GST_STATIC_CAPS ("video/x-av1, " "stream-format = (string) obu-stream, "
"stream-format = (string) obu-stream, " "alignment = (string) tu, " "width = (int) [64, 16384], "
"alignment = (string) tu, " "height = (int) [64, 8704], " "framerate = (fraction) [0, MAX]"));
"width = (int) [64, 16384], "
"height = (int) [64, 8704], "
"framerate = (fraction) [0, MAX]"));
/* class initialization */ /* class initialization */
G_DEFINE_TYPE_WITH_CODE (GstSvtAv1Enc, gst_svtav1enc, GST_TYPE_VIDEO_ENCODER, G_DEFINE_TYPE_WITH_CODE (GstSvtAv1Enc, gst_svtav1enc, GST_TYPE_VIDEO_ENCODER,
@ -136,7 +137,9 @@ G_DEFINE_TYPE_WITH_CODE(GstSvtAv1Enc, gst_svtav1enc, GST_TYPE_VIDEO_ENCODER,
/* this mutex is required to avoid race conditions in SVT-AV1 memory allocations, which aren't thread-safe */ /* this mutex is required to avoid race conditions in SVT-AV1 memory allocations, which aren't thread-safe */
G_LOCK_DEFINE_STATIC (init_mutex); G_LOCK_DEFINE_STATIC (init_mutex);
static void gst_svtav1enc_class_init(GstSvtAv1EncClass *klass) { static void
gst_svtav1enc_class_init (GstSvtAv1EncClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstVideoEncoderClass *video_encoder_class = GST_VIDEO_ENCODER_CLASS (klass); GstVideoEncoderClass *video_encoder_class = GST_VIDEO_ENCODER_CLASS (klass);
@ -146,8 +149,7 @@ static void gst_svtav1enc_class_init(GstSvtAv1EncClass *klass) {
gst_element_class_add_static_pad_template (GST_ELEMENT_CLASS (klass), gst_element_class_add_static_pad_template (GST_ELEMENT_CLASS (klass),
&gst_svtav1enc_sink_pad_template); &gst_svtav1enc_sink_pad_template);
gst_element_class_set_static_metadata( gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass),
GST_ELEMENT_CLASS(klass),
"SvtAv1Enc", "SvtAv1Enc",
"Codec/Encoder/Video", "Codec/Encoder/Video",
"Scalable Video Technology for AV1 Encoder (SVT-AV1 Encoder)", "Scalable Video Technology for AV1 Encoder (SVT-AV1 Encoder)",
@ -160,14 +162,16 @@ static void gst_svtav1enc_class_init(GstSvtAv1EncClass *klass) {
video_encoder_class->close = GST_DEBUG_FUNCPTR (gst_svtav1enc_close); video_encoder_class->close = GST_DEBUG_FUNCPTR (gst_svtav1enc_close);
video_encoder_class->start = GST_DEBUG_FUNCPTR (gst_svtav1enc_start); video_encoder_class->start = GST_DEBUG_FUNCPTR (gst_svtav1enc_start);
video_encoder_class->stop = GST_DEBUG_FUNCPTR (gst_svtav1enc_stop); video_encoder_class->stop = GST_DEBUG_FUNCPTR (gst_svtav1enc_stop);
video_encoder_class->set_format = GST_DEBUG_FUNCPTR(gst_svtav1enc_set_format); video_encoder_class->set_format =
video_encoder_class->handle_frame = GST_DEBUG_FUNCPTR(gst_svtav1enc_handle_frame); GST_DEBUG_FUNCPTR (gst_svtav1enc_set_format);
video_encoder_class->handle_frame =
GST_DEBUG_FUNCPTR (gst_svtav1enc_handle_frame);
video_encoder_class->finish = GST_DEBUG_FUNCPTR (gst_svtav1enc_finish); video_encoder_class->finish = GST_DEBUG_FUNCPTR (gst_svtav1enc_finish);
video_encoder_class->propose_allocation = GST_DEBUG_FUNCPTR(gst_svtav1enc_propose_allocation); video_encoder_class->propose_allocation =
GST_DEBUG_FUNCPTR (gst_svtav1enc_propose_allocation);
video_encoder_class->flush = GST_DEBUG_FUNCPTR (gst_svtav1enc_flush); video_encoder_class->flush = GST_DEBUG_FUNCPTR (gst_svtav1enc_flush);
g_object_class_install_property( g_object_class_install_property (gobject_class,
gobject_class,
PROP_PRESET, PROP_PRESET,
g_param_spec_uint ("preset", g_param_spec_uint ("preset",
"Preset", "Preset",
@ -175,12 +179,9 @@ static void gst_svtav1enc_class_init(GstSvtAv1EncClass *klass) {
" that the encoding is to be performed at" " that the encoding is to be performed at"
" (0 is the highest quality, 13 is the highest speed) ", " (0 is the highest quality, 13 is the highest speed) ",
0, 0,
13, 13, PROP_PRESET_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
PROP_PRESET_DEFAULT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property( g_object_class_install_property (gobject_class,
gobject_class,
PROP_TARGET_BITRATE, PROP_TARGET_BITRATE,
g_param_spec_uint ("target-bitrate", g_param_spec_uint ("target-bitrate",
"Target bitrate", "Target bitrate",
@ -190,8 +191,7 @@ static void gst_svtav1enc_class_init(GstSvtAv1EncClass *klass) {
PROP_TARGET_BITRATE_DEFAULT, PROP_TARGET_BITRATE_DEFAULT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property( g_object_class_install_property (gobject_class,
gobject_class,
PROP_MAX_BITRATE, PROP_MAX_BITRATE,
g_param_spec_uint ("max-bitrate", g_param_spec_uint ("max-bitrate",
"Maximum bitrate", "Maximum bitrate",
@ -200,53 +200,42 @@ static void gst_svtav1enc_class_init(GstSvtAv1EncClass *klass) {
0, 0,
100000, 100000,
PROP_MAX_BITRATE_DEFAULT, PROP_MAX_BITRATE_DEFAULT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_MUTABLE_PLAYING)); G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
GST_PARAM_MUTABLE_PLAYING));
g_object_class_install_property( g_object_class_install_property (gobject_class,
gobject_class,
PROP_MAX_QP_ALLOWED, PROP_MAX_QP_ALLOWED,
g_param_spec_uint ("max-qp-allowed", g_param_spec_uint ("max-qp-allowed",
"Max Quantization parameter", "Max Quantization parameter",
"Maximum QP value allowed for rate control use" "Maximum QP value allowed for rate control use"
" Only used in CBR and VBR mode.", " Only used in CBR and VBR mode.",
0, 0,
63, 63, PROP_MAX_QP_ALLOWED, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
PROP_MAX_QP_ALLOWED,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property( g_object_class_install_property (gobject_class,
gobject_class,
PROP_MIN_QP_ALLOWED, PROP_MIN_QP_ALLOWED,
g_param_spec_uint ("min-qp-allowed", g_param_spec_uint ("min-qp-allowed",
"Min Quantization parameter", "Min Quantization parameter",
"Minimum QP value allowed for rate control use" "Minimum QP value allowed for rate control use"
" Only used in CBR and VBR mode.", " Only used in CBR and VBR mode.",
0, 0,
63, 63, PROP_MIN_QP_ALLOWED, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
PROP_MIN_QP_ALLOWED,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property( g_object_class_install_property (gobject_class,
gobject_class,
PROP_CQP, PROP_CQP,
g_param_spec_int ("cqp", g_param_spec_int ("cqp",
"Quantization parameter", "Quantization parameter",
"Quantization parameter used in CQP mode (-1 is disabled)", "Quantization parameter used in CQP mode (-1 is disabled)",
-1, -1,
63, 63, PROP_CQP_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
PROP_CQP_DEFAULT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property( g_object_class_install_property (gobject_class,
gobject_class,
PROP_CRF, PROP_CRF,
g_param_spec_int ("crf", g_param_spec_int ("crf",
"Constant Rate Factor", "Constant Rate Factor",
"Quantization parameter used in CRF mode (-1 is disabled)", "Quantization parameter used in CRF mode (-1 is disabled)",
-1, -1,
63, 63, PROP_CRF_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
PROP_CRF_DEFAULT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, g_object_class_install_property (gobject_class,
PROP_MAXIMUM_BUFFER_SIZE, PROP_MAXIMUM_BUFFER_SIZE,
@ -259,8 +248,7 @@ static void gst_svtav1enc_class_init(GstSvtAv1EncClass *klass) {
PROP_MAXIMUM_BUFFER_SIZE_DEFAULT, PROP_MAXIMUM_BUFFER_SIZE_DEFAULT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property( g_object_class_install_property (gobject_class,
gobject_class,
PROP_INTRA_PERIOD_LENGTH, PROP_INTRA_PERIOD_LENGTH,
g_param_spec_int ("intra-period-length", g_param_spec_int ("intra-period-length",
"Intra Period Length", "Intra Period Length",
@ -280,8 +268,7 @@ static void gst_svtav1enc_class_init(GstSvtAv1EncClass *klass) {
PROP_INTRA_REFRESH_TYPE_DEFAULT, PROP_INTRA_REFRESH_TYPE_DEFAULT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property( g_object_class_install_property (gobject_class,
gobject_class,
PROP_LOGICAL_PROCESSORS, PROP_LOGICAL_PROCESSORS,
g_param_spec_uint ("logical-processors", g_param_spec_uint ("logical-processors",
"Logical Processors", "Logical Processors",
@ -291,8 +278,7 @@ static void gst_svtav1enc_class_init(GstSvtAv1EncClass *klass) {
PROP_LOGICAL_PROCESSORS_DEFAULT, PROP_LOGICAL_PROCESSORS_DEFAULT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property( g_object_class_install_property (gobject_class,
gobject_class,
PROP_TARGET_SOCKET, PROP_TARGET_SOCKET,
g_param_spec_int ("target-socket", g_param_spec_int ("target-socket",
"Target socket", "Target socket",
@ -302,18 +288,18 @@ static void gst_svtav1enc_class_init(GstSvtAv1EncClass *klass) {
PROP_TARGET_SOCKET_DEFAULT, PROP_TARGET_SOCKET_DEFAULT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property( g_object_class_install_property (gobject_class,
gobject_class,
PROP_PARAMETERS_STRING, PROP_PARAMETERS_STRING,
g_param_spec_string( g_param_spec_string ("parameters-string",
"parameters-string",
"Parameters String", "Parameters String",
"Colon-delimited list of key=value pairs of additional parameters to set", "Colon-delimited list of key=value pairs of additional parameters to set",
PROP_PARAMETERS_STRING_DEFAULT, PROP_PARAMETERS_STRING_DEFAULT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
} }
static void gst_svtav1enc_init(GstSvtAv1Enc *svtav1enc) { static void
gst_svtav1enc_init (GstSvtAv1Enc * svtav1enc)
{
svtav1enc->svt_config = g_new0 (EbSvtAv1EncConfiguration, 1); svtav1enc->svt_config = g_new0 (EbSvtAv1EncConfiguration, 1);
svtav1enc->preset = PROP_PRESET_DEFAULT; svtav1enc->preset = PROP_PRESET_DEFAULT;
svtav1enc->target_bitrate = PROP_TARGET_BITRATE_DEFAULT; svtav1enc->target_bitrate = PROP_TARGET_BITRATE_DEFAULT;
@ -330,8 +316,10 @@ static void gst_svtav1enc_init(GstSvtAv1Enc *svtav1enc) {
svtav1enc->parameters_string = PROP_PARAMETERS_STRING_DEFAULT; svtav1enc->parameters_string = PROP_PARAMETERS_STRING_DEFAULT;
} }
static void gst_svtav1enc_set_property(GObject *object, guint property_id, const GValue *value, static void
GParamSpec *pspec) { gst_svtav1enc_set_property (GObject * object, guint property_id,
const GValue * value, GParamSpec * pspec)
{
GstSvtAv1Enc *svtav1enc = GST_SVTAV1ENC (object); GstSvtAv1Enc *svtav1enc = GST_SVTAV1ENC (object);
/* TODO: support reconfiguring on the fly when possible */ /* TODO: support reconfiguring on the fly when possible */
@ -344,52 +332,110 @@ static void gst_svtav1enc_set_property(GObject *object, guint property_id, const
GST_LOG_OBJECT (svtav1enc, "setting property %u", property_id); GST_LOG_OBJECT (svtav1enc, "setting property %u", property_id);
switch (property_id) { switch (property_id) {
case PROP_PRESET: svtav1enc->preset = g_value_get_uint(value); break; case PROP_PRESET:
case PROP_TARGET_BITRATE: svtav1enc->target_bitrate = g_value_get_uint(value) * 1000; break; svtav1enc->preset = g_value_get_uint (value);
case PROP_MAX_BITRATE: svtav1enc->max_bitrate = g_value_get_uint(value) * 1000; break; break;
case PROP_MAX_QP_ALLOWED: svtav1enc->max_qp_allowed = g_value_get_uint(value); break; case PROP_TARGET_BITRATE:
case PROP_MIN_QP_ALLOWED: svtav1enc->min_qp_allowed = g_value_get_uint(value); break; svtav1enc->target_bitrate = g_value_get_uint (value) * 1000;
case PROP_CQP: svtav1enc->cqp = g_value_get_int(value); break; break;
case PROP_CRF: svtav1enc->crf = g_value_get_int(value); break; case PROP_MAX_BITRATE:
case PROP_MAXIMUM_BUFFER_SIZE: svtav1enc->maximum_buffer_size = g_value_get_uint(value); break; svtav1enc->max_bitrate = g_value_get_uint (value) * 1000;
case PROP_INTRA_PERIOD_LENGTH: svtav1enc->intra_period_length = g_value_get_int(value); break; break;
case PROP_INTRA_REFRESH_TYPE: svtav1enc->intra_refresh_type = g_value_get_enum(value); break; case PROP_MAX_QP_ALLOWED:
case PROP_LOGICAL_PROCESSORS: svtav1enc->logical_processors = g_value_get_uint(value); break; svtav1enc->max_qp_allowed = g_value_get_uint (value);
case PROP_TARGET_SOCKET: svtav1enc->target_socket = g_value_get_int(value); break; break;
case PROP_MIN_QP_ALLOWED:
svtav1enc->min_qp_allowed = g_value_get_uint (value);
break;
case PROP_CQP:
svtav1enc->cqp = g_value_get_int (value);
break;
case PROP_CRF:
svtav1enc->crf = g_value_get_int (value);
break;
case PROP_MAXIMUM_BUFFER_SIZE:
svtav1enc->maximum_buffer_size = g_value_get_uint (value);
break;
case PROP_INTRA_PERIOD_LENGTH:
svtav1enc->intra_period_length = g_value_get_int (value);
break;
case PROP_INTRA_REFRESH_TYPE:
svtav1enc->intra_refresh_type = g_value_get_enum (value);
break;
case PROP_LOGICAL_PROCESSORS:
svtav1enc->logical_processors = g_value_get_uint (value);
break;
case PROP_TARGET_SOCKET:
svtav1enc->target_socket = g_value_get_int (value);
break;
case PROP_PARAMETERS_STRING:{ case PROP_PARAMETERS_STRING:{
g_free (svtav1enc->parameters_string); g_free (svtav1enc->parameters_string);
svtav1enc->parameters_string = g_value_dup_string (value); svtav1enc->parameters_string = g_value_dup_string (value);
break; break;
} }
default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); break; default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
} }
} }
static void gst_svtav1enc_get_property(GObject *object, guint property_id, GValue *value, static void
GParamSpec *pspec) { gst_svtav1enc_get_property (GObject * object, guint property_id, GValue * value,
GParamSpec * pspec)
{
GstSvtAv1Enc *svtav1enc = GST_SVTAV1ENC (object); GstSvtAv1Enc *svtav1enc = GST_SVTAV1ENC (object);
GST_LOG_OBJECT (svtav1enc, "getting property %u", property_id); GST_LOG_OBJECT (svtav1enc, "getting property %u", property_id);
switch (property_id) { switch (property_id) {
case PROP_PRESET: g_value_set_uint(value, svtav1enc->preset); break; case PROP_PRESET:
case PROP_TARGET_BITRATE: g_value_set_uint(value, svtav1enc->target_bitrate / 1000); break; g_value_set_uint (value, svtav1enc->preset);
case PROP_MAX_BITRATE: g_value_set_uint(value, svtav1enc->max_bitrate / 1000); break; break;
case PROP_MAX_QP_ALLOWED: g_value_set_uint(value, svtav1enc->max_qp_allowed); break; case PROP_TARGET_BITRATE:
case PROP_MIN_QP_ALLOWED: g_value_set_uint(value, svtav1enc->min_qp_allowed); break; g_value_set_uint (value, svtav1enc->target_bitrate / 1000);
case PROP_CQP: g_value_set_int(value, svtav1enc->cqp); break; break;
case PROP_CRF: g_value_set_int(value, svtav1enc->crf); break; case PROP_MAX_BITRATE:
case PROP_MAXIMUM_BUFFER_SIZE: g_value_set_uint(value, svtav1enc->maximum_buffer_size); break; g_value_set_uint (value, svtav1enc->max_bitrate / 1000);
case PROP_INTRA_PERIOD_LENGTH: g_value_set_int(value, svtav1enc->intra_period_length); break; break;
case PROP_INTRA_REFRESH_TYPE: g_value_set_enum(value, svtav1enc->intra_refresh_type); break; case PROP_MAX_QP_ALLOWED:
case PROP_LOGICAL_PROCESSORS: g_value_set_uint(value, svtav1enc->logical_processors); break; g_value_set_uint (value, svtav1enc->max_qp_allowed);
case PROP_TARGET_SOCKET: g_value_set_int(value, svtav1enc->target_socket); break; break;
case PROP_PARAMETERS_STRING: g_value_set_string(value, svtav1enc->parameters_string); break; case PROP_MIN_QP_ALLOWED:
default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); break; g_value_set_uint (value, svtav1enc->min_qp_allowed);
break;
case PROP_CQP:
g_value_set_int (value, svtav1enc->cqp);
break;
case PROP_CRF:
g_value_set_int (value, svtav1enc->crf);
break;
case PROP_MAXIMUM_BUFFER_SIZE:
g_value_set_uint (value, svtav1enc->maximum_buffer_size);
break;
case PROP_INTRA_PERIOD_LENGTH:
g_value_set_int (value, svtav1enc->intra_period_length);
break;
case PROP_INTRA_REFRESH_TYPE:
g_value_set_enum (value, svtav1enc->intra_refresh_type);
break;
case PROP_LOGICAL_PROCESSORS:
g_value_set_uint (value, svtav1enc->logical_processors);
break;
case PROP_TARGET_SOCKET:
g_value_set_int (value, svtav1enc->target_socket);
break;
case PROP_PARAMETERS_STRING:
g_value_set_string (value, svtav1enc->parameters_string);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
} }
} }
static void gst_svtav1enc_finalize(GObject *object) { static void
gst_svtav1enc_finalize (GObject * object)
{
GstSvtAv1Enc *svtav1enc = GST_SVTAV1ENC (object); GstSvtAv1Enc *svtav1enc = GST_SVTAV1ENC (object);
GST_DEBUG_OBJECT (svtav1enc, "finalizing svtav1enc"); GST_DEBUG_OBJECT (svtav1enc, "finalizing svtav1enc");
@ -400,7 +446,9 @@ static void gst_svtav1enc_finalize(GObject *object) {
G_OBJECT_CLASS (gst_svtav1enc_parent_class)->finalize (object); G_OBJECT_CLASS (gst_svtav1enc_parent_class)->finalize (object);
} }
static void gst_svtav1enc_allocate_svt_buffers(GstSvtAv1Enc *svtav1enc) { static void
gst_svtav1enc_allocate_svt_buffers (GstSvtAv1Enc * svtav1enc)
{
svtav1enc->input_buf = g_new0 (EbBufferHeaderType, 1); svtav1enc->input_buf = g_new0 (EbBufferHeaderType, 1);
svtav1enc->input_buf->p_buffer = (guint8 *) g_new0 (EbSvtIOFormat, 1); svtav1enc->input_buf->p_buffer = (guint8 *) g_new0 (EbSvtIOFormat, 1);
svtav1enc->input_buf->size = sizeof (EbBufferHeaderType); svtav1enc->input_buf->size = sizeof (EbBufferHeaderType);
@ -409,7 +457,9 @@ static void gst_svtav1enc_allocate_svt_buffers(GstSvtAv1Enc *svtav1enc) {
svtav1enc->input_buf->metadata = NULL; svtav1enc->input_buf->metadata = NULL;
} }
static void gst_svtav1enc_deallocate_svt_buffers(GstSvtAv1Enc *svtav1enc) { static void
gst_svtav1enc_deallocate_svt_buffers (GstSvtAv1Enc * svtav1enc)
{
if (svtav1enc->input_buf) { if (svtav1enc->input_buf) {
g_free (svtav1enc->input_buf->p_buffer); g_free (svtav1enc->input_buf->p_buffer);
svtav1enc->input_buf->p_buffer = NULL; svtav1enc->input_buf->p_buffer = NULL;
@ -418,7 +468,9 @@ static void gst_svtav1enc_deallocate_svt_buffers(GstSvtAv1Enc *svtav1enc) {
} }
} }
static gboolean gst_svtav1enc_configure_svt(GstSvtAv1Enc *svtav1enc) { static gboolean
gst_svtav1enc_configure_svt (GstSvtAv1Enc * svtav1enc)
{
if (!svtav1enc->state) { if (!svtav1enc->state) {
GST_WARNING_OBJECT (svtav1enc, "no state, can't configure encoder yet"); GST_WARNING_OBJECT (svtav1enc, "no state, can't configure encoder yet");
return FALSE; return FALSE;
@ -433,17 +485,16 @@ static gboolean gst_svtav1enc_configure_svt(GstSvtAv1Enc *svtav1enc) {
"Enabling VBR mode (br %u max-br %u max-qp %u min-qp %u)", "Enabling VBR mode (br %u max-br %u max-qp %u min-qp %u)",
svtav1enc->target_bitrate, svtav1enc->target_bitrate,
svtav1enc->max_bitrate, svtav1enc->max_bitrate,
svtav1enc->max_qp_allowed, svtav1enc->max_qp_allowed, svtav1enc->min_qp_allowed);
svtav1enc->min_qp_allowed);
svtav1enc->svt_config->max_bit_rate = svtav1enc->max_bitrate; svtav1enc->svt_config->max_bit_rate = svtav1enc->max_bitrate;
svtav1enc->svt_config->rate_control_mode = SVT_AV1_RC_MODE_VBR; svtav1enc->svt_config->rate_control_mode = SVT_AV1_RC_MODE_VBR;
} else { } else {
GST_DEBUG_OBJECT (svtav1enc, GST_DEBUG_OBJECT (svtav1enc,
"Enabling CBR mode (br %u max-bs %u)", "Enabling CBR mode (br %u max-bs %u)",
svtav1enc->target_bitrate, svtav1enc->target_bitrate, svtav1enc->maximum_buffer_size);
svtav1enc->maximum_buffer_size);
svtav1enc->svt_config->rate_control_mode = SVT_AV1_RC_MODE_CBR; svtav1enc->svt_config->rate_control_mode = SVT_AV1_RC_MODE_CBR;
svtav1enc->svt_config->maximum_buffer_size_ms = svtav1enc->maximum_buffer_size; svtav1enc->svt_config->maximum_buffer_size_ms =
svtav1enc->maximum_buffer_size;
} }
svtav1enc->svt_config->max_qp_allowed = svtav1enc->max_qp_allowed; svtav1enc->svt_config->max_qp_allowed = svtav1enc->max_qp_allowed;
svtav1enc->svt_config->min_qp_allowed = svtav1enc->min_qp_allowed; svtav1enc->svt_config->min_qp_allowed = svtav1enc->min_qp_allowed;
@ -470,14 +521,15 @@ static gboolean gst_svtav1enc_configure_svt(GstSvtAv1Enc *svtav1enc) {
/* set properties out of GstVideoInfo */ /* set properties out of GstVideoInfo */
const GstVideoInfo *info = &svtav1enc->state->info; const GstVideoInfo *info = &svtav1enc->state->info;
svtav1enc->svt_config->encoder_bit_depth = GST_VIDEO_INFO_COMP_DEPTH(info, 0); svtav1enc->svt_config->encoder_bit_depth =
GST_VIDEO_INFO_COMP_DEPTH (info, 0);
svtav1enc->svt_config->source_width = GST_VIDEO_INFO_WIDTH (info); svtav1enc->svt_config->source_width = GST_VIDEO_INFO_WIDTH (info);
svtav1enc->svt_config->source_height = GST_VIDEO_INFO_HEIGHT (info); svtav1enc->svt_config->source_height = GST_VIDEO_INFO_HEIGHT (info);
svtav1enc->svt_config->frame_rate_numerator = GST_VIDEO_INFO_FPS_N (info) > 0 svtav1enc->svt_config->frame_rate_numerator = GST_VIDEO_INFO_FPS_N (info) > 0
? GST_VIDEO_INFO_FPS_N (info) ? GST_VIDEO_INFO_FPS_N (info)
: 1; : 1;
svtav1enc->svt_config->frame_rate_denominator = GST_VIDEO_INFO_FPS_D(info) > 0 svtav1enc->svt_config->frame_rate_denominator =
? GST_VIDEO_INFO_FPS_D(info) GST_VIDEO_INFO_FPS_D (info) > 0 ? GST_VIDEO_INFO_FPS_D (info)
: 1; : 1;
GST_LOG_OBJECT (svtav1enc, GST_LOG_OBJECT (svtav1enc,
"width %d, height %d, framerate %d/%d", "width %d, height %d, framerate %d/%d",
@ -517,7 +569,9 @@ static gboolean gst_svtav1enc_configure_svt(GstSvtAv1Enc *svtav1enc) {
case GST_VIDEO_COLOR_PRIMARIES_EBU3213: case GST_VIDEO_COLOR_PRIMARIES_EBU3213:
svtav1enc->svt_config->color_primaries = EB_CICP_CP_EBU_3213; svtav1enc->svt_config->color_primaries = EB_CICP_CP_EBU_3213;
break; break;
default: svtav1enc->svt_config->color_primaries = EB_CICP_CP_UNSPECIFIED; break; default:
svtav1enc->svt_config->color_primaries = EB_CICP_CP_UNSPECIFIED;
break;
} }
switch (GST_VIDEO_INFO_COLORIMETRY (info).transfer) { switch (GST_VIDEO_INFO_COLORIMETRY (info).transfer) {
@ -542,18 +596,21 @@ static gboolean gst_svtav1enc_configure_svt(GstSvtAv1Enc *svtav1enc) {
svtav1enc->svt_config->transfer_characteristics = EB_CICP_TC_LOG_100; svtav1enc->svt_config->transfer_characteristics = EB_CICP_TC_LOG_100;
break; break;
case GST_VIDEO_TRANSFER_LOG316: case GST_VIDEO_TRANSFER_LOG316:
svtav1enc->svt_config->transfer_characteristics = EB_CICP_TC_LOG_100_SQRT10; svtav1enc->svt_config->transfer_characteristics =
EB_CICP_TC_LOG_100_SQRT10;
break; break;
case GST_VIDEO_TRANSFER_SRGB: case GST_VIDEO_TRANSFER_SRGB:
svtav1enc->svt_config->transfer_characteristics = EB_CICP_TC_SRGB; svtav1enc->svt_config->transfer_characteristics = EB_CICP_TC_SRGB;
break; break;
#if GST_CHECK_VERSION(1, 18, 0) #if GST_CHECK_VERSION(1, 18, 0)
case GST_VIDEO_TRANSFER_BT2020_10: case GST_VIDEO_TRANSFER_BT2020_10:
svtav1enc->svt_config->transfer_characteristics = EB_CICP_TC_BT_2020_10_BIT; svtav1enc->svt_config->transfer_characteristics =
EB_CICP_TC_BT_2020_10_BIT;
break; break;
#endif #endif
case GST_VIDEO_TRANSFER_BT2020_12: case GST_VIDEO_TRANSFER_BT2020_12:
svtav1enc->svt_config->transfer_characteristics = EB_CICP_TC_BT_2020_12_BIT; svtav1enc->svt_config->transfer_characteristics =
EB_CICP_TC_BT_2020_12_BIT;
break; break;
#if GST_CHECK_VERSION(1, 18, 0) #if GST_CHECK_VERSION(1, 18, 0)
case GST_VIDEO_TRANSFER_SMPTE2084: case GST_VIDEO_TRANSFER_SMPTE2084:
@ -563,7 +620,9 @@ static gboolean gst_svtav1enc_configure_svt(GstSvtAv1Enc *svtav1enc) {
svtav1enc->svt_config->transfer_characteristics = EB_CICP_TC_HLG; svtav1enc->svt_config->transfer_characteristics = EB_CICP_TC_HLG;
break; break;
#endif #endif
default: svtav1enc->svt_config->transfer_characteristics = EB_CICP_TC_UNSPECIFIED; break; default:
svtav1enc->svt_config->transfer_characteristics = EB_CICP_TC_UNSPECIFIED;
break;
} }
switch (GST_VIDEO_INFO_COLORIMETRY (info).matrix) { switch (GST_VIDEO_INFO_COLORIMETRY (info).matrix) {
@ -586,7 +645,9 @@ static gboolean gst_svtav1enc_configure_svt(GstSvtAv1Enc *svtav1enc) {
svtav1enc->svt_config->matrix_coefficients = EB_CICP_MC_BT_2020_NCL; svtav1enc->svt_config->matrix_coefficients = EB_CICP_MC_BT_2020_NCL;
break; break;
default: svtav1enc->svt_config->matrix_coefficients = EB_CICP_MC_UNSPECIFIED; break; default:
svtav1enc->svt_config->matrix_coefficients = EB_CICP_MC_UNSPECIFIED;
break;
} }
if (GST_VIDEO_INFO_COLORIMETRY (info).range == GST_VIDEO_COLOR_RANGE_0_255) { if (GST_VIDEO_INFO_COLORIMETRY (info).range == GST_VIDEO_COLOR_RANGE_0_255) {
@ -602,20 +663,30 @@ static gboolean gst_svtav1enc_configure_svt(GstSvtAv1Enc *svtav1enc) {
case GST_VIDEO_CHROMA_SITE_COSITED: case GST_VIDEO_CHROMA_SITE_COSITED:
svtav1enc->svt_config->chroma_sample_position = EB_CSP_COLOCATED; svtav1enc->svt_config->chroma_sample_position = EB_CSP_COLOCATED;
break; break;
default: svtav1enc->svt_config->chroma_sample_position = EB_CSP_UNKNOWN; default:
svtav1enc->svt_config->chroma_sample_position = EB_CSP_UNKNOWN;
} }
#if GST_CHECK_VERSION(1, 18, 0) #if GST_CHECK_VERSION(1, 18, 0)
GstVideoMasteringDisplayInfo master_display_info; GstVideoMasteringDisplayInfo master_display_info;
if (gst_video_mastering_display_info_from_caps(&master_display_info, svtav1enc->state->caps)) { if (gst_video_mastering_display_info_from_caps (&master_display_info,
svtav1enc->svt_config->mastering_display.r.x = master_display_info.display_primaries[0].x; svtav1enc->state->caps)) {
svtav1enc->svt_config->mastering_display.r.y = master_display_info.display_primaries[0].y; svtav1enc->svt_config->mastering_display.r.x =
svtav1enc->svt_config->mastering_display.g.x = master_display_info.display_primaries[1].x; master_display_info.display_primaries[0].x;
svtav1enc->svt_config->mastering_display.g.y = master_display_info.display_primaries[1].y; svtav1enc->svt_config->mastering_display.r.y =
svtav1enc->svt_config->mastering_display.b.x = master_display_info.display_primaries[2].x; master_display_info.display_primaries[0].y;
svtav1enc->svt_config->mastering_display.b.y = master_display_info.display_primaries[2].y; svtav1enc->svt_config->mastering_display.g.x =
svtav1enc->svt_config->mastering_display.white_point.x = master_display_info.white_point.x; master_display_info.display_primaries[1].x;
svtav1enc->svt_config->mastering_display.white_point.y = master_display_info.white_point.y; svtav1enc->svt_config->mastering_display.g.y =
master_display_info.display_primaries[1].y;
svtav1enc->svt_config->mastering_display.b.x =
master_display_info.display_primaries[2].x;
svtav1enc->svt_config->mastering_display.b.y =
master_display_info.display_primaries[2].y;
svtav1enc->svt_config->mastering_display.white_point.x =
master_display_info.white_point.x;
svtav1enc->svt_config->mastering_display.white_point.y =
master_display_info.white_point.y;
svtav1enc->svt_config->mastering_display.max_luma = svtav1enc->svt_config->mastering_display.max_luma =
master_display_info.max_display_mastering_luminance; master_display_info.max_display_mastering_luminance;
svtav1enc->svt_config->mastering_display.min_luma = svtav1enc->svt_config->mastering_display.min_luma =
@ -623,68 +694,75 @@ static gboolean gst_svtav1enc_configure_svt(GstSvtAv1Enc *svtav1enc) {
svtav1enc->svt_config->high_dynamic_range_input = TRUE; svtav1enc->svt_config->high_dynamic_range_input = TRUE;
} else { } else {
memset (&svtav1enc->svt_config->mastering_display, memset (&svtav1enc->svt_config->mastering_display,
0, 0, sizeof (svtav1enc->svt_config->mastering_display));
sizeof(svtav1enc->svt_config->mastering_display));
svtav1enc->svt_config->high_dynamic_range_input = FALSE; svtav1enc->svt_config->high_dynamic_range_input = FALSE;
} }
GstVideoContentLightLevel content_light_level; GstVideoContentLightLevel content_light_level;
if (gst_video_content_light_level_from_caps(&content_light_level, svtav1enc->state->caps)) { if (gst_video_content_light_level_from_caps (&content_light_level,
svtav1enc->state->caps)) {
svtav1enc->svt_config->content_light_level.max_cll = svtav1enc->svt_config->content_light_level.max_cll =
content_light_level.max_content_light_level; content_light_level.max_content_light_level;
svtav1enc->svt_config->content_light_level.max_fall = svtav1enc->svt_config->content_light_level.max_fall =
content_light_level.max_frame_average_light_level; content_light_level.max_frame_average_light_level;
} else { } else {
memset (&svtav1enc->svt_config->content_light_level, memset (&svtav1enc->svt_config->content_light_level,
0, 0, sizeof (svtav1enc->svt_config->content_light_level));
sizeof(svtav1enc->svt_config->content_light_level));
} }
#endif #endif
EbErrorType res = svt_av1_enc_set_parameter(svtav1enc->svt_encoder, svtav1enc->svt_config); EbErrorType res =
svt_av1_enc_set_parameter (svtav1enc->svt_encoder, svtav1enc->svt_config);
if (res != EB_ErrorNone) { if (res != EB_ErrorNone) {
GST_ELEMENT_ERROR (svtav1enc, GST_ELEMENT_ERROR (svtav1enc,
LIBRARY, LIBRARY,
INIT, INIT, (NULL), ("svt_av1_enc_set_parameter failed with error %d", res));
(NULL),
("svt_av1_enc_set_parameter failed with error %d", res));
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }
static gboolean gst_svtav1enc_start_svt(GstSvtAv1Enc *svtav1enc) { static gboolean
gst_svtav1enc_start_svt (GstSvtAv1Enc * svtav1enc)
{
G_LOCK (init_mutex); G_LOCK (init_mutex);
EbErrorType res = svt_av1_enc_init (svtav1enc->svt_encoder); EbErrorType res = svt_av1_enc_init (svtav1enc->svt_encoder);
G_UNLOCK (init_mutex); G_UNLOCK (init_mutex);
if (res != EB_ErrorNone) { if (res != EB_ErrorNone) {
GST_ELEMENT_ERROR( GST_ELEMENT_ERROR (svtav1enc, LIBRARY, INIT, (NULL),
svtav1enc, LIBRARY, INIT, (NULL), ("svt_av1_enc_init failed with error %d", res)); ("svt_av1_enc_init failed with error %d", res));
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }
static GstFlowReturn gst_svtav1enc_encode(GstSvtAv1Enc *svtav1enc, GstVideoCodecFrame *frame) { static GstFlowReturn
gst_svtav1enc_encode (GstSvtAv1Enc * svtav1enc, GstVideoCodecFrame * frame)
{
GstFlowReturn ret = GST_FLOW_OK; GstFlowReturn ret = GST_FLOW_OK;
EbErrorType res = EB_ErrorNone; EbErrorType res = EB_ErrorNone;
EbBufferHeaderType *input_buffer = svtav1enc->input_buf; EbBufferHeaderType *input_buffer = svtav1enc->input_buf;
EbSvtIOFormat *input_picture_buffer = (EbSvtIOFormat *)svtav1enc->input_buf->p_buffer; EbSvtIOFormat *input_picture_buffer =
(EbSvtIOFormat *) svtav1enc->input_buf->p_buffer;
GstVideoFrame video_frame; GstVideoFrame video_frame;
if (!gst_video_frame_map( if (!gst_video_frame_map (&video_frame, &svtav1enc->state->info,
&video_frame, &svtav1enc->state->info, frame->input_buffer, GST_MAP_READ)) { frame->input_buffer, GST_MAP_READ)) {
GST_ELEMENT_ERROR(svtav1enc, LIBRARY, ENCODE, (NULL), ("couldn't map input frame")); GST_ELEMENT_ERROR (svtav1enc, LIBRARY, ENCODE, (NULL),
("couldn't map input frame"));
return GST_FLOW_ERROR; return GST_FLOW_ERROR;
} }
input_picture_buffer->y_stride = GST_VIDEO_FRAME_COMP_STRIDE(&video_frame, 0) / input_picture_buffer->y_stride =
GST_VIDEO_FRAME_COMP_PSTRIDE(&video_frame, 0); GST_VIDEO_FRAME_COMP_STRIDE (&video_frame,
input_picture_buffer->cb_stride = GST_VIDEO_FRAME_COMP_STRIDE(&video_frame, 1) / 0) / GST_VIDEO_FRAME_COMP_PSTRIDE (&video_frame, 0);
GST_VIDEO_FRAME_COMP_PSTRIDE(&video_frame, 1); input_picture_buffer->cb_stride =
input_picture_buffer->cr_stride = GST_VIDEO_FRAME_COMP_STRIDE(&video_frame, 2) / GST_VIDEO_FRAME_COMP_STRIDE (&video_frame,
GST_VIDEO_FRAME_COMP_PSTRIDE(&video_frame, 2); 1) / GST_VIDEO_FRAME_COMP_PSTRIDE (&video_frame, 1);
input_picture_buffer->cr_stride =
GST_VIDEO_FRAME_COMP_STRIDE (&video_frame,
2) / GST_VIDEO_FRAME_COMP_PSTRIDE (&video_frame, 2);
input_picture_buffer->luma = GST_VIDEO_FRAME_PLANE_DATA (&video_frame, 0); input_picture_buffer->luma = GST_VIDEO_FRAME_PLANE_DATA (&video_frame, 0);
input_picture_buffer->cb = GST_VIDEO_FRAME_PLANE_DATA (&video_frame, 1); input_picture_buffer->cb = GST_VIDEO_FRAME_PLANE_DATA (&video_frame, 1);
@ -706,8 +784,8 @@ static GstFlowReturn gst_svtav1enc_encode(GstSvtAv1Enc *svtav1enc, GstVideoCodec
res = svt_av1_enc_send_picture (svtav1enc->svt_encoder, input_buffer); res = svt_av1_enc_send_picture (svtav1enc->svt_encoder, input_buffer);
if (res != EB_ErrorNone) { if (res != EB_ErrorNone) {
GST_ELEMENT_ERROR( GST_ELEMENT_ERROR (svtav1enc, LIBRARY, ENCODE, (NULL),
svtav1enc, LIBRARY, ENCODE, (NULL), ("error in sending picture to encoder")); ("error in sending picture to encoder"));
ret = GST_FLOW_ERROR; ret = GST_FLOW_ERROR;
} }
gst_video_frame_unmap (&video_frame); gst_video_frame_unmap (&video_frame);
@ -715,7 +793,9 @@ static GstFlowReturn gst_svtav1enc_encode(GstSvtAv1Enc *svtav1enc, GstVideoCodec
return ret; return ret;
} }
static gboolean gst_svtav1enc_send_eos(GstSvtAv1Enc *svtav1enc) { static gboolean
gst_svtav1enc_send_eos (GstSvtAv1Enc * svtav1enc)
{
EbErrorType ret = EB_ErrorNone; EbErrorType ret = EB_ErrorNone;
EbBufferHeaderType input_buffer; EbBufferHeaderType input_buffer;
@ -730,22 +810,28 @@ static gboolean gst_svtav1enc_send_eos(GstSvtAv1Enc *svtav1enc) {
ret = svt_av1_enc_send_picture (svtav1enc->svt_encoder, &input_buffer); ret = svt_av1_enc_send_picture (svtav1enc->svt_encoder, &input_buffer);
if (ret != EB_ErrorNone) { if (ret != EB_ErrorNone) {
GST_ELEMENT_ERROR(svtav1enc, LIBRARY, ENCODE, (NULL), ("couldn't send EOS frame.")); GST_ELEMENT_ERROR (svtav1enc, LIBRARY, ENCODE, (NULL),
("couldn't send EOS frame."));
return FALSE; return FALSE;
} }
return (ret == EB_ErrorNone); return (ret == EB_ErrorNone);
} }
static gboolean gst_svtav1enc_flush(GstVideoEncoder *encoder) { static gboolean
GstFlowReturn ret = gst_svtav1enc_dequeue_encoded_frames(GST_SVTAV1ENC(encoder), TRUE, FALSE); gst_svtav1enc_flush (GstVideoEncoder * encoder)
{
GstFlowReturn ret =
gst_svtav1enc_dequeue_encoded_frames (GST_SVTAV1ENC (encoder), TRUE,
FALSE);
return (ret != GST_FLOW_ERROR); return (ret != GST_FLOW_ERROR);
} }
static GstFlowReturn gst_svtav1enc_dequeue_encoded_frames(GstSvtAv1Enc *svtav1enc, static GstFlowReturn
gboolean done_sending_pics, gst_svtav1enc_dequeue_encoded_frames (GstSvtAv1Enc * svtav1enc,
gboolean output_frames) { gboolean done_sending_pics, gboolean output_frames)
{
GstFlowReturn ret = GST_FLOW_OK; GstFlowReturn ret = GST_FLOW_OK;
EbErrorType res = EB_ErrorNone; EbErrorType res = EB_ErrorNone;
gboolean encode_at_eos = FALSE; gboolean encode_at_eos = FALSE;
@ -754,44 +840,48 @@ static GstFlowReturn gst_svtav1enc_dequeue_encoded_frames(GstSvtAv1Enc *svtav1en
GstVideoCodecFrame *frame = NULL; GstVideoCodecFrame *frame = NULL;
EbBufferHeaderType *output_buf = NULL; EbBufferHeaderType *output_buf = NULL;
res = svt_av1_enc_get_packet(svtav1enc->svt_encoder, &output_buf, done_sending_pics); res =
svt_av1_enc_get_packet (svtav1enc->svt_encoder, &output_buf,
done_sending_pics);
if (output_buf != NULL) if (output_buf != NULL)
encode_at_eos = ((output_buf->flags & EB_BUFFERFLAG_EOS) == EB_BUFFERFLAG_EOS); encode_at_eos =
((output_buf->flags & EB_BUFFERFLAG_EOS) == EB_BUFFERFLAG_EOS);
if (res == EB_ErrorMax) { if (res == EB_ErrorMax) {
GST_ELEMENT_ERROR (svtav1enc, LIBRARY, ENCODE, (NULL), ("encode failed")); GST_ELEMENT_ERROR (svtav1enc, LIBRARY, ENCODE, (NULL), ("encode failed"));
return GST_FLOW_ERROR; return GST_FLOW_ERROR;
} else if (res != EB_NoErrorEmptyQueue && output_frames && output_buf) { } else if (res != EB_NoErrorEmptyQueue && output_frames && output_buf) {
// AV1 has no frame re-ordering so always get the oldest frame // AV1 has no frame re-ordering so always get the oldest frame
frame = gst_video_encoder_get_oldest_frame(GST_VIDEO_ENCODER(svtav1enc)); frame =
if (output_buf->pic_type == EB_AV1_KEY_PICTURE || gst_video_encoder_get_oldest_frame (GST_VIDEO_ENCODER (svtav1enc));
output_buf->pic_type == EB_AV1_INTRA_ONLY_PICTURE) { if (output_buf->pic_type == EB_AV1_KEY_PICTURE
|| output_buf->pic_type == EB_AV1_INTRA_ONLY_PICTURE) {
GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame); GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame);
} }
if ((ret = gst_video_encoder_allocate_output_frame( if ((ret =
GST_VIDEO_ENCODER(svtav1enc), frame, output_buf->n_filled_len)) != gst_video_encoder_allocate_output_frame (GST_VIDEO_ENCODER
GST_FLOW_OK) { (svtav1enc), frame,
output_buf->n_filled_len)) != GST_FLOW_OK) {
svt_av1_enc_release_out_buffer (&output_buf); svt_av1_enc_release_out_buffer (&output_buf);
gst_video_codec_frame_unref (frame); gst_video_codec_frame_unref (frame);
return ret; return ret;
} }
gst_buffer_fill( gst_buffer_fill (frame->output_buffer, 0, output_buf->p_buffer,
frame->output_buffer, 0, output_buf->p_buffer, output_buf->n_filled_len); output_buf->n_filled_len);
frame->pts = frame->output_buffer->pts = output_buf->pts; frame->pts = frame->output_buffer->pts = output_buf->pts;
GST_LOG_OBJECT (svtav1enc, GST_LOG_OBJECT (svtav1enc,
"#frame:%u pts:%" G_GINT64_FORMAT " SliceType:%d\n", "#frame:%u pts:%" G_GINT64_FORMAT " SliceType:%d\n",
frame->system_frame_number, frame->system_frame_number, (frame->pts), output_buf->pic_type);
(frame->pts),
output_buf->pic_type);
svt_av1_enc_release_out_buffer (&output_buf); svt_av1_enc_release_out_buffer (&output_buf);
output_buf = NULL; output_buf = NULL;
ret = gst_video_encoder_finish_frame(GST_VIDEO_ENCODER(svtav1enc), frame); ret =
gst_video_encoder_finish_frame (GST_VIDEO_ENCODER (svtav1enc), frame);
} }
} while (res == EB_ErrorNone && !encode_at_eos && ret == GST_FLOW_OK); } while (res == EB_ErrorNone && !encode_at_eos && ret == GST_FLOW_OK);
@ -799,24 +889,28 @@ static GstFlowReturn gst_svtav1enc_dequeue_encoded_frames(GstSvtAv1Enc *svtav1en
return ret; return ret;
} }
static gboolean gst_svtav1enc_open(GstVideoEncoder *encoder) { static gboolean
gst_svtav1enc_open (GstVideoEncoder * encoder)
{
GstSvtAv1Enc *svtav1enc = GST_SVTAV1ENC (encoder); GstSvtAv1Enc *svtav1enc = GST_SVTAV1ENC (encoder);
GST_DEBUG_OBJECT (svtav1enc, "open"); GST_DEBUG_OBJECT (svtav1enc, "open");
EbErrorType res = svt_av1_enc_init_handle(&svtav1enc->svt_encoder, NULL, svtav1enc->svt_config); EbErrorType res = svt_av1_enc_init_handle (&svtav1enc->svt_encoder, NULL,
svtav1enc->svt_config);
if (res != EB_ErrorNone) { if (res != EB_ErrorNone) {
GST_ELEMENT_ERROR (svtav1enc, GST_ELEMENT_ERROR (svtav1enc,
LIBRARY, LIBRARY,
INIT, INIT, (NULL), ("svt_av1_enc_init_handle failed with error %d", res));
(NULL),
("svt_av1_enc_init_handle failed with error %d", res));
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }
static gboolean gst_svtav1enc_close(GstVideoEncoder *encoder) {
static gboolean
gst_svtav1enc_close (GstVideoEncoder * encoder)
{
GstSvtAv1Enc *svtav1enc = GST_SVTAV1ENC (encoder); GstSvtAv1Enc *svtav1enc = GST_SVTAV1ENC (encoder);
GST_DEBUG_OBJECT (svtav1enc, "close"); GST_DEBUG_OBJECT (svtav1enc, "close");
@ -826,7 +920,9 @@ static gboolean gst_svtav1enc_close(GstVideoEncoder *encoder) {
return TRUE; return TRUE;
} }
static gboolean gst_svtav1enc_start(GstVideoEncoder *encoder) { static gboolean
gst_svtav1enc_start (GstVideoEncoder * encoder)
{
GstSvtAv1Enc *svtav1enc = GST_SVTAV1ENC (encoder); GstSvtAv1Enc *svtav1enc = GST_SVTAV1ENC (encoder);
GST_DEBUG_OBJECT (svtav1enc, "start"); GST_DEBUG_OBJECT (svtav1enc, "start");
@ -835,7 +931,9 @@ static gboolean gst_svtav1enc_start(GstVideoEncoder *encoder) {
return TRUE; return TRUE;
} }
static gboolean gst_svtav1enc_stop(GstVideoEncoder *encoder) { static gboolean
gst_svtav1enc_stop (GstVideoEncoder * encoder)
{
GstSvtAv1Enc *svtav1enc = GST_SVTAV1ENC (encoder); GstSvtAv1Enc *svtav1enc = GST_SVTAV1ENC (encoder);
GST_DEBUG_OBJECT (svtav1enc, "stop"); GST_DEBUG_OBJECT (svtav1enc, "stop");
@ -850,7 +948,9 @@ static gboolean gst_svtav1enc_stop(GstVideoEncoder *encoder) {
return TRUE; return TRUE;
} }
static gboolean gst_svtav1enc_set_format(GstVideoEncoder *encoder, GstVideoCodecState *state) { static gboolean
gst_svtav1enc_set_format (GstVideoEncoder * encoder, GstVideoCodecState * state)
{
GstSvtAv1Enc *svtav1enc = GST_SVTAV1ENC (encoder); GstSvtAv1Enc *svtav1enc = GST_SVTAV1ENC (encoder);
GstClockTime min_latency_frames = 0; GstClockTime min_latency_frames = 0;
GstCaps *src_caps = NULL; GstCaps *src_caps = NULL;
@ -878,21 +978,24 @@ static gboolean gst_svtav1enc_set_format(GstVideoEncoder *encoder, GstVideoCodec
gst_video_encoder_set_latency (encoder, gst_video_encoder_set_latency (encoder,
min_latency_frames * GST_SECOND / min_latency_frames * GST_SECOND /
(svtav1enc->svt_config->frame_rate_numerator / (svtav1enc->svt_config->frame_rate_numerator /
svtav1enc->svt_config->frame_rate_denominator), svtav1enc->svt_config->frame_rate_denominator), -1);
-1);
src_caps = gst_static_pad_template_get_caps (&gst_svtav1enc_src_pad_template); src_caps = gst_static_pad_template_get_caps (&gst_svtav1enc_src_pad_template);
output_state = gst_video_encoder_set_output_state( output_state =
GST_VIDEO_ENCODER(encoder), src_caps, svtav1enc->state); gst_video_encoder_set_output_state (GST_VIDEO_ENCODER (encoder), src_caps,
svtav1enc->state);
gst_video_codec_state_unref (output_state); gst_video_codec_state_unref (output_state);
GST_DEBUG_OBJECT(svtav1enc, "output caps: %" GST_PTR_FORMAT, svtav1enc->state->caps); GST_DEBUG_OBJECT (svtav1enc, "output caps: %" GST_PTR_FORMAT,
svtav1enc->state->caps);
return gst_video_encoder_negotiate (encoder); return gst_video_encoder_negotiate (encoder);
} }
static GstFlowReturn gst_svtav1enc_handle_frame(GstVideoEncoder *encoder, static GstFlowReturn
GstVideoCodecFrame *frame) { gst_svtav1enc_handle_frame (GstVideoEncoder * encoder,
GstVideoCodecFrame * frame)
{
GstSvtAv1Enc *svtav1enc = GST_SVTAV1ENC (encoder); GstSvtAv1Enc *svtav1enc = GST_SVTAV1ENC (encoder);
GstFlowReturn ret = GST_FLOW_OK; GstFlowReturn ret = GST_FLOW_OK;
@ -908,7 +1011,9 @@ static GstFlowReturn gst_svtav1enc_handle_frame(GstVideoEncoder *encoder,
return gst_svtav1enc_dequeue_encoded_frames (svtav1enc, FALSE, TRUE); return gst_svtav1enc_dequeue_encoded_frames (svtav1enc, FALSE, TRUE);
} }
static GstFlowReturn gst_svtav1enc_finish(GstVideoEncoder *encoder) { static GstFlowReturn
gst_svtav1enc_finish (GstVideoEncoder * encoder)
{
GstSvtAv1Enc *svtav1enc = GST_SVTAV1ENC (encoder); GstSvtAv1Enc *svtav1enc = GST_SVTAV1ENC (encoder);
GST_DEBUG_OBJECT (svtav1enc, "finish"); GST_DEBUG_OBJECT (svtav1enc, "finish");
@ -918,17 +1023,23 @@ static GstFlowReturn gst_svtav1enc_finish(GstVideoEncoder *encoder) {
return gst_svtav1enc_dequeue_encoded_frames (svtav1enc, TRUE, TRUE); return gst_svtav1enc_dequeue_encoded_frames (svtav1enc, TRUE, TRUE);
} }
static gboolean gst_svtav1enc_propose_allocation(GstVideoEncoder *encoder, GstQuery *query) { static gboolean
gst_svtav1enc_propose_allocation (GstVideoEncoder * encoder, GstQuery * query)
{
GstSvtAv1Enc *svtav1enc = GST_SVTAV1ENC (encoder); GstSvtAv1Enc *svtav1enc = GST_SVTAV1ENC (encoder);
GST_DEBUG_OBJECT (svtav1enc, "propose_allocation"); GST_DEBUG_OBJECT (svtav1enc, "propose_allocation");
gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
return GST_VIDEO_ENCODER_CLASS(gst_svtav1enc_parent_class)->propose_allocation(encoder, query); return
GST_VIDEO_ENCODER_CLASS (gst_svtav1enc_parent_class)->propose_allocation
(encoder, query);
} }
static void gst_svtav1enc_parse_parameters_string(GstSvtAv1Enc *svtav1enc) { static void
gst_svtav1enc_parse_parameters_string (GstSvtAv1Enc * svtav1enc)
{
gchar **key_values, **p; gchar **key_values, **p;
if (!svtav1enc->parameters_string) if (!svtav1enc->parameters_string)
@ -952,7 +1063,8 @@ static void gst_svtav1enc_parse_parameters_string(GstSvtAv1Enc *svtav1enc) {
res = svt_av1_enc_parse_parameter (svtav1enc->svt_config, *p, equals); res = svt_av1_enc_parse_parameter (svtav1enc->svt_config, *p, equals);
if (res != EB_ErrorNone) { if (res != EB_ErrorNone) {
GST_WARNING_OBJECT(svtav1enc, "Failed to set parameter %s=%s: %d", *p, equals, res); GST_WARNING_OBJECT (svtav1enc, "Failed to set parameter %s=%s: %d", *p,
equals, res);
} }
p++; p++;
@ -961,8 +1073,11 @@ static void gst_svtav1enc_parse_parameters_string(GstSvtAv1Enc *svtav1enc) {
g_strfreev (key_values); g_strfreev (key_values);
} }
static gboolean plugin_init(GstPlugin *plugin) { static gboolean
return gst_element_register(plugin, "svtav1enc", GST_RANK_SECONDARY, GST_TYPE_SVTAV1ENC); plugin_init (GstPlugin * plugin)
{
return gst_element_register (plugin, "svtav1enc", GST_RANK_SECONDARY,
GST_TYPE_SVTAV1ENC);
} }
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, svtav1, GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, svtav1,