summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Waters <matthew@centricular.com>2016-04-07 23:24:47 +1000
committerMatthew Waters <matthew@centricular.com>2016-04-08 15:08:18 +1000
commit065f4dceb1e2869e092d3460d042591811839710 (patch)
tree87871398c11e04be2ddee80160f3164ee6d6e188
parentc45fc2ef53813d67115872c519263da325a4006b (diff)
nvenc: move codec config initialization from the implementation to the base class
Supports a better separation of configuration parameters
-rw-r--r--sys/nvenc/gstnvbaseenc.c135
-rw-r--r--sys/nvenc/gstnvbaseenc.h6
-rw-r--r--sys/nvenc/gstnvh264enc.c152
3 files changed, 139 insertions, 154 deletions
diff --git a/sys/nvenc/gstnvbaseenc.c b/sys/nvenc/gstnvbaseenc.c
index 53761de48..6efd51414 100644
--- a/sys/nvenc/gstnvbaseenc.c
+++ b/sys/nvenc/gstnvbaseenc.c
@@ -969,22 +969,136 @@ gst_nv_base_enc_set_format (GstVideoEncoder * enc, GstVideoCodecState * state)
GstNvBaseEnc *nvenc = GST_NV_BASE_ENC (enc);
GstVideoInfo *info = &state->info;
GstVideoCodecState *old_state = nvenc->input_state;
+ NV_ENC_RECONFIGURE_PARAMS reconfigure_params = { 0, };
+ NV_ENC_INITIALIZE_PARAMS init_params = { 0, };
+ NV_ENC_INITIALIZE_PARAMS *params;
+ NV_ENC_PRESET_CONFIG preset_config = { 0, };
NVENCSTATUS nv_ret;
- g_assert (nvenc_class->initialize_encoder);
+ if (old_state) {
+ reconfigure_params.version = NV_ENC_RECONFIGURE_PARAMS_VER;
+ params = &reconfigure_params.reInitEncodeParams;
+ } else {
+ params = &init_params;
+ }
- G_LOCK (initialization_lock);
- if (!nvenc_class->initialize_encoder (nvenc, old_state, state)) {
- GST_ERROR_OBJECT (enc, "Subclass failed to reconfigure encoder");
- G_UNLOCK (initialization_lock);
+ params->version = NV_ENC_INITIALIZE_PARAMS_VER;
+ params->encodeGUID = nvenc_class->codec_id;
+ params->encodeWidth = GST_VIDEO_INFO_WIDTH (info);
+ params->encodeHeight = GST_VIDEO_INFO_HEIGHT (info);
+
+ {
+ guint32 n_presets;
+ GUID *presets;
+ guint32 i;
+
+ nv_ret =
+ NvEncGetEncodePresetCount (nvenc->encoder,
+ params->encodeGUID, &n_presets);
+ if (nv_ret != NV_ENC_SUCCESS) {
+ GST_ELEMENT_ERROR (nvenc, LIBRARY, SETTINGS, (NULL),
+ ("Failed to get encoder presets"));
+ return FALSE;
+ }
+
+ presets = g_new0 (GUID, n_presets);
+ nv_ret =
+ NvEncGetEncodePresetGUIDs (nvenc->encoder,
+ params->encodeGUID, presets, n_presets, &n_presets);
+ if (nv_ret != NV_ENC_SUCCESS) {
+ GST_ELEMENT_ERROR (nvenc, LIBRARY, SETTINGS, (NULL),
+ ("Failed to get encoder presets"));
+ g_free (presets);
+ return FALSE;
+ }
+
+ for (i = 0; i < n_presets; i++) {
+ if (gst_nvenc_cmp_guid (presets[i], nvenc->selected_preset))
+ break;
+ }
+ g_free (presets);
+ if (i >= n_presets) {
+ GST_ELEMENT_ERROR (nvenc, LIBRARY, SETTINGS, (NULL),
+ ("Selected preset not supported"));
+ return FALSE;
+ }
+
+ params->presetGUID = nvenc->selected_preset;
+ }
+
+ params->enablePTD = 1;
+ if (!old_state) {
+ /* this sets the required buffer size and the maximum allowed size on
+ * subsequent reconfigures */
+ /* FIXME: propertise this */
+ params->maxEncodeWidth = GST_VIDEO_INFO_WIDTH (info);
+ params->maxEncodeHeight = GST_VIDEO_INFO_HEIGHT (info);
+ gst_nv_base_enc_set_max_encode_size (nvenc, params->maxEncodeWidth,
+ params->maxEncodeHeight);
+ } else {
+ guint max_width, max_height;
+
+ gst_nv_base_enc_get_max_encode_size (nvenc, &max_width, &max_height);
+
+ if (GST_VIDEO_INFO_WIDTH (info) > max_width
+ || GST_VIDEO_INFO_HEIGHT (info) > max_height) {
+ GST_ELEMENT_ERROR (nvenc, STREAM, FORMAT, ("%s", "Requested stream "
+ "size is larger than the maximum configured size"), (NULL));
+ return FALSE;
+ }
+ }
+
+ preset_config.version = NV_ENC_PRESET_CONFIG_VER;
+ preset_config.presetCfg.version = NV_ENC_CONFIG_VER;
+
+ nv_ret =
+ NvEncGetEncodePresetConfig (nvenc->encoder,
+ params->encodeGUID, params->presetGUID, &preset_config);
+ if (nv_ret != NV_ENC_SUCCESS) {
+ GST_ELEMENT_ERROR (nvenc, LIBRARY, SETTINGS, (NULL),
+ ("Failed to get encode preset configuration: %d", nv_ret));
return FALSE;
}
+
+ if (GST_VIDEO_INFO_IS_INTERLACED (info)) {
+ if (GST_VIDEO_INFO_INTERLACE_MODE (info) ==
+ GST_VIDEO_INTERLACE_MODE_INTERLEAVED
+ || GST_VIDEO_INFO_INTERLACE_MODE (info) ==
+ GST_VIDEO_INTERLACE_MODE_MIXED) {
+ preset_config.presetCfg.frameFieldMode =
+ NV_ENC_PARAMS_FRAME_FIELD_MODE_FIELD;
+ }
+ }
+
+ if (info->fps_d > 0 && info->fps_n > 0) {
+ params->frameRateNum = info->fps_n;
+ params->frameRateDen = info->fps_d;
+ } else {
+ GST_FIXME_OBJECT (nvenc, "variable framerate");
+ }
+
+ params->encodeConfig = &preset_config.presetCfg;
+
+ g_assert (nvenc_class->set_encoder_config);
+ if (!nvenc_class->set_encoder_config (nvenc, state, params->encodeConfig)) {
+ GST_ERROR_OBJECT (enc, "Subclass failed to set encoder configuration");
+ return FALSE;
+ }
+
+ G_LOCK (initialization_lock);
+ if (old_state) {
+ nv_ret = NvEncReconfigureEncoder (nvenc->encoder, &reconfigure_params);
+ } else {
+ nv_ret = NvEncInitializeEncoder (nvenc->encoder, params);
+ }
G_UNLOCK (initialization_lock);
- if (!nvenc->max_encode_width && !nvenc->max_encode_height) {
- gst_nv_base_enc_set_max_encode_size (nvenc, GST_VIDEO_INFO_WIDTH (info),
- GST_VIDEO_INFO_HEIGHT (info));
+ if (nv_ret != NV_ENC_SUCCESS) {
+ GST_ELEMENT_ERROR (nvenc, LIBRARY, SETTINGS, (NULL),
+ ("Failed to %sinit encoder: %d", old_state ? "re" : "", nv_ret));
+ return FALSE;
}
+ GST_INFO_OBJECT (nvenc, "configured encoder");
if (!old_state) {
nvenc->input_info = *info;
@@ -1268,9 +1382,8 @@ _map_gl_input_buffer (GstGLContext * context, struct map_gl_input *data)
}
cuda_ret =
- cudaGraphicsResourceGetMappedPointer (&data->
- in_gl_resource->cuda_plane_pointers[i],
- &data->in_gl_resource->cuda_num_bytes,
+ cudaGraphicsResourceGetMappedPointer (&data->in_gl_resource->
+ cuda_plane_pointers[i], &data->in_gl_resource->cuda_num_bytes,
data->in_gl_resource->cuda_texture);
if (cuda_ret != cudaSuccess) {
GST_ERROR_OBJECT (data->nvenc, "failed to get mapped pointer of map GL "
diff --git a/sys/nvenc/gstnvbaseenc.h b/sys/nvenc/gstnvbaseenc.h
index 6debe8eae..934826b16 100644
--- a/sys/nvenc/gstnvbaseenc.h
+++ b/sys/nvenc/gstnvbaseenc.h
@@ -104,14 +104,14 @@ typedef struct {
GUID codec_id;
- gboolean (*initialize_encoder) (GstNvBaseEnc * nvenc,
- GstVideoCodecState * old_state,
- GstVideoCodecState * state);
gboolean (*set_src_caps) (GstNvBaseEnc * nvenc,
GstVideoCodecState * state);
gboolean (*set_pic_params) (GstNvBaseEnc * nvenc,
GstVideoCodecFrame * frame,
NV_ENC_PIC_PARAMS * pic_params);
+ gboolean (*set_encoder_config) (GstNvBaseEnc * nvenc,
+ GstVideoCodecState * state,
+ NV_ENC_CONFIG * config);
} GstNvBaseEncClass;
G_GNUC_INTERNAL
diff --git a/sys/nvenc/gstnvh264enc.c b/sys/nvenc/gstnvh264enc.c
index 4c7a9846d..2e60b3da7 100644
--- a/sys/nvenc/gstnvh264enc.c
+++ b/sys/nvenc/gstnvh264enc.c
@@ -57,8 +57,8 @@ static GstCaps *gst_nv_h264_enc_getcaps (GstVideoEncoder * enc,
GstCaps * filter);
static gboolean gst_nv_h264_enc_set_src_caps (GstNvBaseEnc * nvenc,
GstVideoCodecState * state);
-static gboolean gst_nv_h264_enc_initialize_encoder (GstNvBaseEnc * nvenc,
- GstVideoCodecState * old_state, GstVideoCodecState * state);
+static gboolean gst_nv_h264_enc_set_encoder_config (GstNvBaseEnc * nvenc,
+ GstVideoCodecState * state, NV_ENC_CONFIG * config);
static gboolean gst_nv_h264_enc_set_pic_params (GstNvBaseEnc * nvenc,
GstVideoCodecFrame * frame, NV_ENC_PIC_PARAMS * pic_params);
static void gst_nv_h264_enc_set_property (GObject * object, guint prop_id,
@@ -85,7 +85,7 @@ gst_nv_h264_enc_class_init (GstNvH264EncClass * klass)
videoenc_class->getcaps = GST_DEBUG_FUNCPTR (gst_nv_h264_enc_getcaps);
nvenc_class->codec_id = NV_ENC_CODEC_H264_GUID;
- nvenc_class->initialize_encoder = gst_nv_h264_enc_initialize_encoder;
+ nvenc_class->set_encoder_config = gst_nv_h264_enc_set_encoder_config;
nvenc_class->set_src_caps = gst_nv_h264_enc_set_src_caps;
nvenc_class->set_pic_params = gst_nv_h264_enc_set_pic_params;
@@ -411,28 +411,14 @@ gst_nv_h264_enc_set_src_caps (GstNvBaseEnc * nvenc, GstVideoCodecState * state)
}
static gboolean
-gst_nv_h264_enc_initialize_encoder (GstNvBaseEnc * nvenc,
- GstVideoCodecState * old_state, GstVideoCodecState * state)
+gst_nv_h264_enc_set_encoder_config (GstNvBaseEnc * nvenc,
+ GstVideoCodecState * state, NV_ENC_CONFIG * config)
{
GstNvH264Enc *h264enc = GST_NV_H264_ENC (nvenc);
- NV_ENC_RECONFIGURE_PARAMS reconfigure_params = { 0, };
- NV_ENC_INITIALIZE_PARAMS init_params = { 0, };
- NV_ENC_INITIALIZE_PARAMS *params;
- NV_ENC_PRESET_CONFIG preset_config = { 0, };
- NVENCSTATUS nv_ret;
- GstVideoInfo *info = &state->info;
GstCaps *allowed_caps, *template_caps;
GUID selected_profile = NV_ENC_CODEC_PROFILE_AUTOSELECT_GUID;
- GUID selected_preset = nvenc->selected_preset;
int level_idc = NV_ENC_LEVEL_AUTOSELECT;
-
- /* TODO: support reconfiguration */
- if (old_state) {
- reconfigure_params.version = NV_ENC_RECONFIGURE_PARAMS_VER;
- params = &reconfigure_params.reInitEncodeParams;
- } else {
- params = &init_params;
- }
+ GstVideoInfo *info = &state->info;
template_caps = gst_static_pad_template_get_caps (&src_factory);
allowed_caps = gst_pad_get_allowed_caps (GST_VIDEO_ENCODER_SRC_PAD (h264enc));
@@ -482,133 +468,19 @@ gst_nv_h264_enc_initialize_encoder (GstNvBaseEnc * nvenc,
}
gst_caps_unref (template_caps);
- params->version = NV_ENC_INITIALIZE_PARAMS_VER;
- params->encodeGUID = NV_ENC_CODEC_H264_GUID;
- params->encodeWidth = GST_VIDEO_INFO_WIDTH (info);
- params->encodeHeight = GST_VIDEO_INFO_HEIGHT (info);
-
- {
- guint32 n_presets;
- GUID *presets;
- guint32 i;
-
- nv_ret =
- NvEncGetEncodePresetCount (GST_NV_BASE_ENC (h264enc)->encoder,
- params->encodeGUID, &n_presets);
- if (nv_ret != NV_ENC_SUCCESS) {
- GST_ELEMENT_ERROR (h264enc, LIBRARY, SETTINGS, (NULL),
- ("Failed to get encoder presets"));
- return FALSE;
- }
-
- presets = g_new0 (GUID, n_presets);
- nv_ret =
- NvEncGetEncodePresetGUIDs (GST_NV_BASE_ENC (h264enc)->encoder,
- params->encodeGUID, presets, n_presets, &n_presets);
- if (nv_ret != NV_ENC_SUCCESS) {
- GST_ELEMENT_ERROR (h264enc, LIBRARY, SETTINGS, (NULL),
- ("Failed to get encoder presets"));
- g_free (presets);
- return FALSE;
- }
-
- for (i = 0; i < n_presets; i++) {
- if (gst_nvenc_cmp_guid (presets[i], selected_preset))
- break;
- }
- g_free (presets);
- if (i >= n_presets) {
- GST_ELEMENT_ERROR (h264enc, LIBRARY, SETTINGS, (NULL),
- ("Selected preset not supported"));
- return FALSE;
- }
-
- params->presetGUID = selected_preset;
- }
- params->enablePTD = 1;
- if (!old_state) {
- /* this sets the required buffer size and the maximum allowed size on
- * subsequent reconfigures */
- /* FIXME: propertise this */
- params->maxEncodeWidth = GST_VIDEO_INFO_WIDTH (info);
- params->maxEncodeHeight = GST_VIDEO_INFO_HEIGHT (info);
- gst_nv_base_enc_set_max_encode_size (GST_NV_BASE_ENC (h264enc),
- params->maxEncodeWidth, params->maxEncodeHeight);
- } else {
- guint max_width, max_height;
-
- gst_nv_base_enc_get_max_encode_size (GST_NV_BASE_ENC (h264enc),
- &max_width, &max_height);
-
- if (GST_VIDEO_INFO_WIDTH (info) > max_width
- || GST_VIDEO_INFO_HEIGHT (info) > max_height) {
- GST_ELEMENT_ERROR (h264enc, STREAM, FORMAT, ("%s", "Requested stream "
- "size is larger than the maximum configured size"), (NULL));
- return FALSE;
- }
- }
-
- preset_config.version = NV_ENC_PRESET_CONFIG_VER;
- preset_config.presetCfg.version = NV_ENC_CONFIG_VER;
-
- nv_ret =
- NvEncGetEncodePresetConfig (GST_NV_BASE_ENC (h264enc)->encoder,
- params->encodeGUID, params->presetGUID, &preset_config);
- if (nv_ret != NV_ENC_SUCCESS) {
- GST_ELEMENT_ERROR (h264enc, LIBRARY, SETTINGS, (NULL),
- ("Failed to get encode preset configuration: %d", nv_ret));
- return FALSE;
- }
- params->encodeConfig = &preset_config.presetCfg;
-
/* override some defaults */
GST_LOG_OBJECT (h264enc, "setting parameters");
- preset_config.presetCfg.version = NV_ENC_CONFIG_VER;
- preset_config.presetCfg.profileGUID = selected_profile;
- preset_config.presetCfg.encodeCodecConfig.h264Config.level = level_idc;
- preset_config.presetCfg.encodeCodecConfig.h264Config.chromaFormatIDC = 1;
+ config->profileGUID = selected_profile;
+ config->encodeCodecConfig.h264Config.level = level_idc;
+ config->encodeCodecConfig.h264Config.chromaFormatIDC = 1;
if (GST_VIDEO_INFO_FORMAT (info) == GST_VIDEO_FORMAT_Y444) {
GST_DEBUG_OBJECT (h264enc, "have Y444 input, setting config accordingly");
- preset_config.presetCfg.encodeCodecConfig.h264Config.
- separateColourPlaneFlag = 1;
- preset_config.presetCfg.encodeCodecConfig.h264Config.chromaFormatIDC = 3;
+ config->encodeCodecConfig.h264Config.separateColourPlaneFlag = 1;
+ config->encodeCodecConfig.h264Config.chromaFormatIDC = 3;
}
/* FIXME: make property */
- preset_config.presetCfg.encodeCodecConfig.h264Config.outputAUD = 1;
-
- if (GST_VIDEO_INFO_IS_INTERLACED (info)) {
- if (GST_VIDEO_INFO_INTERLACE_MODE (info) ==
- GST_VIDEO_INTERLACE_MODE_INTERLEAVED
- || GST_VIDEO_INFO_INTERLACE_MODE (info) ==
- GST_VIDEO_INTERLACE_MODE_MIXED) {
- preset_config.presetCfg.frameFieldMode =
- NV_ENC_PARAMS_FRAME_FIELD_MODE_FIELD;
- }
- }
-
- if (info->fps_d > 0 && info->fps_n > 0) {
- params->frameRateNum = info->fps_n;
- params->frameRateDen = info->fps_d;
- } else {
- GST_FIXME_OBJECT (h264enc, "variable framerate");
- }
-
- if (old_state) {
- nv_ret =
- NvEncReconfigureEncoder (GST_NV_BASE_ENC (h264enc)->encoder,
- &reconfigure_params);
- } else {
- nv_ret =
- NvEncInitializeEncoder (GST_NV_BASE_ENC (h264enc)->encoder, params);
- }
-
- if (nv_ret != NV_ENC_SUCCESS) {
- GST_ELEMENT_ERROR (h264enc, LIBRARY, SETTINGS, (NULL),
- ("Failed to %sinit encoder: %d", old_state ? "re" : "", nv_ret));
- return FALSE;
- }
- GST_INFO_OBJECT (h264enc, "configured encoder");
+ config->encodeCodecConfig.h264Config.outputAUD = 1;
return TRUE;
}