mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 22:36:33 +00:00
openh264enc: Add some more encoding properties
Merged from https://github.com/EricssonResearch/openwebrtc-gst-plugins based on a patchset by Robert Swain <robert.swain@ericsson.com>
This commit is contained in:
parent
aea08e86a5
commit
c43b9aad66
1 changed files with 167 additions and 7 deletions
|
@ -85,6 +85,53 @@ gst_openh264enc_rc_modes_get_type (void)
|
||||||
return rc_modes_type;
|
return rc_modes_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef enum _GstOpenh264encDeblockingMode
|
||||||
|
{
|
||||||
|
GST_OPENH264_DEBLOCKING_ON = 0,
|
||||||
|
GST_OPENH264_DEBLOCKING_OFF = 1,
|
||||||
|
GST_OPENH264_DEBLOCKING_NOT_SLICE_BOUNDARIES = 2
|
||||||
|
} GstOpenh264encDeblockingMode;
|
||||||
|
|
||||||
|
#define GST_TYPE_OPENH264ENC_DEBLOCKING_MODE (gst_openh264enc_deblocking_mode_get_type ())
|
||||||
|
static GType
|
||||||
|
gst_openh264enc_deblocking_mode_get_type (void)
|
||||||
|
{
|
||||||
|
static const GEnumValue types[] = {
|
||||||
|
{GST_OPENH264_DEBLOCKING_ON, "Deblocking on", "on"},
|
||||||
|
{GST_OPENH264_DEBLOCKING_OFF, "Deblocking off", "off"},
|
||||||
|
{GST_OPENH264_DEBLOCKING_NOT_SLICE_BOUNDARIES,
|
||||||
|
"Deblocking on, except for slice boundaries", "not-slice-boundaries"},
|
||||||
|
{0, NULL, NULL},
|
||||||
|
};
|
||||||
|
static volatile GType id = 0;
|
||||||
|
|
||||||
|
if (g_once_init_enter ((gsize *) & id)) {
|
||||||
|
GType _id = g_enum_register_static ("GstOpenh264encDeblockingModes", types);
|
||||||
|
g_once_init_leave ((gsize *) & id, _id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GST_TYPE_OPENH264ENC_SLICE_MODE (gst_openh264enc_slice_mode_get_type ())
|
||||||
|
static GType
|
||||||
|
gst_openh264enc_slice_mode_get_type (void)
|
||||||
|
{
|
||||||
|
static const GEnumValue types[] = {
|
||||||
|
{SM_FIXEDSLCNUM_SLICE, "num-slices slices", "n-slices"},
|
||||||
|
{SM_AUTO_SLICE, "Number of slices equal to number of threads", "auto"},
|
||||||
|
{0, NULL, NULL},
|
||||||
|
};
|
||||||
|
static volatile GType id = 0;
|
||||||
|
|
||||||
|
if (g_once_init_enter ((gsize *) & id)) {
|
||||||
|
GType _id = g_enum_register_static ("GstOpenh264encSliceModes", types);
|
||||||
|
g_once_init_leave ((gsize *) & id, _id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
|
|
||||||
static void gst_openh264enc_set_property (GObject * object,
|
static void gst_openh264enc_set_property (GObject * object,
|
||||||
|
@ -117,6 +164,12 @@ static void gst_openh264enc_set_rate_control (GstOpenh264Enc * openh264enc,
|
||||||
#define DEFAULT_MULTI_THREAD 0
|
#define DEFAULT_MULTI_THREAD 0
|
||||||
#define DEFAULT_ENABLE_DENOISE FALSE
|
#define DEFAULT_ENABLE_DENOISE FALSE
|
||||||
#define DEFAULT_ENABLE_FRAME_SKIP FALSE
|
#define DEFAULT_ENABLE_FRAME_SKIP FALSE
|
||||||
|
#define DEFAULT_DEBLOCKING_MODE GST_OPENH264_DEBLOCKING_ON
|
||||||
|
#define DEFAULT_BACKGROUND_DETECTION TRUE
|
||||||
|
#define DEFAULT_ADAPTIVE_QUANTIZATION TRUE
|
||||||
|
#define DEFAULT_SCENE_CHANGE_DETECTION TRUE
|
||||||
|
#define DEFAULT_SLICE_MODE SM_AUTO_SLICE
|
||||||
|
#define DEFAULT_NUM_SLICES 1
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -129,6 +182,12 @@ enum
|
||||||
PROP_MULTI_THREAD,
|
PROP_MULTI_THREAD,
|
||||||
PROP_ENABLE_DENOISE,
|
PROP_ENABLE_DENOISE,
|
||||||
PROP_ENABLE_FRAME_SKIP,
|
PROP_ENABLE_FRAME_SKIP,
|
||||||
|
PROP_DEBLOCKING_MODE,
|
||||||
|
PROP_BACKGROUND_DETECTION,
|
||||||
|
PROP_ADAPTIVE_QUANTIZATION,
|
||||||
|
PROP_SCENE_CHANGE_DETECTION,
|
||||||
|
PROP_SLICE_MODE,
|
||||||
|
PROP_NUM_SLICES,
|
||||||
N_PROPERTIES
|
N_PROPERTIES
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -149,6 +208,12 @@ struct _GstOpenh264EncPrivate
|
||||||
guint64 time_per_frame;
|
guint64 time_per_frame;
|
||||||
guint64 frame_count;
|
guint64 frame_count;
|
||||||
guint64 previous_timestamp;
|
guint64 previous_timestamp;
|
||||||
|
GstOpenh264encDeblockingMode deblocking_mode;
|
||||||
|
gboolean background_detection;
|
||||||
|
gboolean adaptive_quantization;
|
||||||
|
gboolean scene_change_detection;
|
||||||
|
SliceModeEnum slice_mode;
|
||||||
|
guint num_slices;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* pad templates */
|
/* pad templates */
|
||||||
|
@ -253,6 +318,39 @@ gst_openh264enc_class_init (GstOpenh264EncClass * klass)
|
||||||
"The maximum size of one slice (in bytes).",
|
"The maximum size of one slice (in bytes).",
|
||||||
0, G_MAXUINT, DEFAULT_MAX_SLICE_SIZE,
|
0, G_MAXUINT, DEFAULT_MAX_SLICE_SIZE,
|
||||||
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
|
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
|
||||||
|
|
||||||
|
g_object_class_install_property (G_OBJECT_CLASS (klass),
|
||||||
|
PROP_DEBLOCKING_MODE, g_param_spec_enum ("deblocking",
|
||||||
|
"Deblocking mode", "Deblocking mode",
|
||||||
|
GST_TYPE_OPENH264ENC_DEBLOCKING_MODE, DEFAULT_DEBLOCKING_MODE,
|
||||||
|
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class, PROP_BACKGROUND_DETECTION,
|
||||||
|
g_param_spec_boolean ("background-detection", "Background detection",
|
||||||
|
"Background detection", DEFAULT_BACKGROUND_DETECTION,
|
||||||
|
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class, PROP_ADAPTIVE_QUANTIZATION,
|
||||||
|
g_param_spec_boolean ("adaptive-quantization", "Adaptive quantization",
|
||||||
|
"Adaptive quantization", DEFAULT_ADAPTIVE_QUANTIZATION,
|
||||||
|
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class, PROP_SCENE_CHANGE_DETECTION,
|
||||||
|
g_param_spec_boolean ("scene-change-detection",
|
||||||
|
"Scene change detection", "Scene change detection",
|
||||||
|
DEFAULT_SCENE_CHANGE_DETECTION,
|
||||||
|
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
|
||||||
|
|
||||||
|
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SLICE_MODE,
|
||||||
|
g_param_spec_enum ("slice-mode", "Slice mode", "Slice mode",
|
||||||
|
GST_TYPE_OPENH264ENC_SLICE_MODE, DEFAULT_SLICE_MODE,
|
||||||
|
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class, PROP_NUM_SLICES,
|
||||||
|
g_param_spec_uint ("num-slices", "Number of slices",
|
||||||
|
"The number of slices (needs slice-mode=n-slices)",
|
||||||
|
0, G_MAXUINT, DEFAULT_NUM_SLICES,
|
||||||
|
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -273,6 +371,12 @@ gst_openh264enc_init (GstOpenh264Enc * openh264enc)
|
||||||
openh264enc->priv->drop_bitrate = DROP_BITRATE;
|
openh264enc->priv->drop_bitrate = DROP_BITRATE;
|
||||||
openh264enc->priv->enable_denoise = DEFAULT_ENABLE_DENOISE;
|
openh264enc->priv->enable_denoise = DEFAULT_ENABLE_DENOISE;
|
||||||
openh264enc->priv->enable_frame_skip = DEFAULT_ENABLE_FRAME_SKIP;
|
openh264enc->priv->enable_frame_skip = DEFAULT_ENABLE_FRAME_SKIP;
|
||||||
|
openh264enc->priv->deblocking_mode = DEFAULT_DEBLOCKING_MODE;
|
||||||
|
openh264enc->priv->background_detection = DEFAULT_BACKGROUND_DETECTION;
|
||||||
|
openh264enc->priv->adaptive_quantization = DEFAULT_ADAPTIVE_QUANTIZATION;
|
||||||
|
openh264enc->priv->scene_change_detection = DEFAULT_SCENE_CHANGE_DETECTION;
|
||||||
|
openh264enc->priv->slice_mode = DEFAULT_SLICE_MODE;
|
||||||
|
openh264enc->priv->num_slices = DEFAULT_NUM_SLICES;
|
||||||
openh264enc->priv->encoder = NULL;
|
openh264enc->priv->encoder = NULL;
|
||||||
gst_openh264enc_set_usage_type (openh264enc, CAMERA_VIDEO_REAL_TIME);
|
gst_openh264enc_set_usage_type (openh264enc, CAMERA_VIDEO_REAL_TIME);
|
||||||
gst_openh264enc_set_rate_control (openh264enc, RC_QUALITY_MODE);
|
gst_openh264enc_set_rate_control (openh264enc, RC_QUALITY_MODE);
|
||||||
|
@ -355,6 +459,31 @@ gst_openh264enc_set_property (GObject * object, guint property_id,
|
||||||
openh264enc->priv->max_slice_size = g_value_get_uint (value);
|
openh264enc->priv->max_slice_size = g_value_get_uint (value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_DEBLOCKING_MODE:
|
||||||
|
openh264enc->priv->deblocking_mode =
|
||||||
|
(GstOpenh264encDeblockingMode) g_value_get_enum (value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_BACKGROUND_DETECTION:
|
||||||
|
openh264enc->priv->background_detection = g_value_get_boolean (value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_ADAPTIVE_QUANTIZATION:
|
||||||
|
openh264enc->priv->adaptive_quantization = g_value_get_boolean (value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_SCENE_CHANGE_DETECTION:
|
||||||
|
openh264enc->priv->scene_change_detection = g_value_get_boolean (value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_SLICE_MODE:
|
||||||
|
openh264enc->priv->slice_mode = (SliceModeEnum) g_value_get_enum (value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_NUM_SLICES:
|
||||||
|
openh264enc->priv->num_slices = g_value_get_uint (value);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -402,6 +531,30 @@ gst_openh264enc_get_property (GObject * object, guint property_id,
|
||||||
g_value_set_uint (value, openh264enc->priv->max_slice_size);
|
g_value_set_uint (value, openh264enc->priv->max_slice_size);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_DEBLOCKING_MODE:
|
||||||
|
g_value_set_enum (value, openh264enc->priv->deblocking_mode);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_BACKGROUND_DETECTION:
|
||||||
|
g_value_set_boolean (value, openh264enc->priv->background_detection);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_ADAPTIVE_QUANTIZATION:
|
||||||
|
g_value_set_boolean (value, openh264enc->priv->adaptive_quantization);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_SCENE_CHANGE_DETECTION:
|
||||||
|
g_value_set_boolean (value, openh264enc->priv->scene_change_detection);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_SLICE_MODE:
|
||||||
|
g_value_set_enum (value, openh264enc->priv->slice_mode);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_NUM_SLICES:
|
||||||
|
g_value_set_uint (value, openh264enc->priv->num_slices);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -518,19 +671,26 @@ gst_openh264enc_set_format (GstVideoEncoder * encoder,
|
||||||
enc_params.iMultipleThreadIdc = openh264enc->priv->multi_thread;
|
enc_params.iMultipleThreadIdc = openh264enc->priv->multi_thread;
|
||||||
enc_params.bEnableDenoise = openh264enc->priv->enable_denoise;
|
enc_params.bEnableDenoise = openh264enc->priv->enable_denoise;
|
||||||
enc_params.uiIntraPeriod = priv->gop_size;
|
enc_params.uiIntraPeriod = priv->gop_size;
|
||||||
enc_params.bEnableBackgroundDetection = 1;
|
enc_params.bEnableBackgroundDetection =
|
||||||
enc_params.bEnableAdaptiveQuant = 1;
|
openh264enc->priv->background_detection;
|
||||||
|
enc_params.bEnableAdaptiveQuant = openh264enc->priv->adaptive_quantization;
|
||||||
|
enc_params.bEnableSceneChangeDetect =
|
||||||
|
openh264enc->priv->scene_change_detection;
|
||||||
enc_params.bEnableFrameSkip = openh264enc->priv->enable_frame_skip;
|
enc_params.bEnableFrameSkip = openh264enc->priv->enable_frame_skip;
|
||||||
enc_params.bEnableLongTermReference = 0;
|
enc_params.bEnableLongTermReference = 0;
|
||||||
enc_params.bEnableSpsPpsIdAddition = 1;
|
enc_params.bEnableSpsPpsIdAddition = 1;
|
||||||
enc_params.bPrefixNalAddingCtrl = 0;
|
enc_params.bPrefixNalAddingCtrl = 0;
|
||||||
enc_params.fMaxFrameRate = fps_n * 1.0 / fps_d;
|
enc_params.fMaxFrameRate = fps_n * 1.0 / fps_d;
|
||||||
|
enc_params.iLoopFilterDisableIdc = openh264enc->priv->deblocking_mode;
|
||||||
enc_params.sSpatialLayers[0].uiProfileIdc = PRO_BASELINE;
|
enc_params.sSpatialLayers[0].uiProfileIdc = PRO_BASELINE;
|
||||||
enc_params.sSpatialLayers[0].iVideoWidth = width;
|
enc_params.sSpatialLayers[0].iVideoWidth = width;
|
||||||
enc_params.sSpatialLayers[0].iVideoHeight = height;
|
enc_params.sSpatialLayers[0].iVideoHeight = height;
|
||||||
enc_params.sSpatialLayers[0].fFrameRate = fps_n * 1.0 / fps_d;
|
enc_params.sSpatialLayers[0].fFrameRate = fps_n * 1.0 / fps_d;
|
||||||
enc_params.sSpatialLayers[0].iSpatialBitrate = openh264enc->priv->bitrate;
|
enc_params.sSpatialLayers[0].iSpatialBitrate = openh264enc->priv->bitrate;
|
||||||
enc_params.sSpatialLayers[0].sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;
|
enc_params.sSpatialLayers[0].sSliceCfg.uiSliceMode =
|
||||||
|
openh264enc->priv->slice_mode;
|
||||||
|
enc_params.sSpatialLayers[0].sSliceCfg.sSliceArgument.uiSliceNum =
|
||||||
|
openh264enc->priv->num_slices;
|
||||||
|
|
||||||
priv->framerate = (1 + fps_n / fps_d);
|
priv->framerate = (1 + fps_n / fps_d);
|
||||||
|
|
||||||
|
@ -604,8 +764,8 @@ gst_openh264enc_propose_allocation (GstVideoEncoder * encoder, GstQuery * query)
|
||||||
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
|
return
|
||||||
GST_VIDEO_ENCODER_CLASS (gst_openh264enc_parent_class)->propose_allocation
|
GST_VIDEO_ENCODER_CLASS
|
||||||
(encoder, query);
|
(gst_openh264enc_parent_class)->propose_allocation (encoder, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
|
@ -719,8 +879,8 @@ gst_openh264enc_handle_frame (GstVideoEncoder * encoder,
|
||||||
* guess based on the input */
|
* guess based on the input */
|
||||||
frame = gst_video_encoder_get_oldest_frame (base_encoder);
|
frame = gst_video_encoder_get_oldest_frame (base_encoder);
|
||||||
if (!frame) {
|
if (!frame) {
|
||||||
GST_ELEMENT_ERROR (openh264enc, STREAM, ENCODE, ("Could not encode frame"),
|
GST_ELEMENT_ERROR (openh264enc, STREAM, ENCODE,
|
||||||
("openh264enc returned %d", ret));
|
("Could not encode frame"), ("openh264enc returned %d", ret));
|
||||||
gst_video_codec_frame_unref (frame);
|
gst_video_codec_frame_unref (frame);
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue