From 8e860fffd9e2ff48375b30e36801efd13b283335 Mon Sep 17 00:00:00 2001 From: Yeongjin Jeong Date: Tue, 5 Mar 2019 18:55:16 +0900 Subject: [PATCH] nvenc: Fix GValue leaks GValue should be freed with g_value_unset() --- sys/nvenc/gstnvbaseenc.c | 25 +++++++++++++++---------- sys/nvenc/gstnvh264enc.c | 11 +++++++++-- sys/nvenc/gstnvh265enc.c | 9 +++++++-- 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/sys/nvenc/gstnvbaseenc.c b/sys/nvenc/gstnvbaseenc.c index 7e9c8f7..51e75eb 100644 --- a/sys/nvenc/gstnvbaseenc.c +++ b/sys/nvenc/gstnvbaseenc.c @@ -291,9 +291,11 @@ _get_supported_input_formats (GstNvBaseEnc * nvenc) guint64 format_mask = 0; uint32_t i, num = 0; NV_ENC_BUFFER_FORMAT formats[64]; - GValue list = G_VALUE_INIT; GValue val = G_VALUE_INIT; + if (nvenc->input_formats) + return TRUE; + NvEncGetInputFormats (nvenc->encoder, nvenc_class->codec_id, formats, G_N_ELEMENTS (formats), &num); @@ -360,30 +362,30 @@ _get_supported_input_formats (GstNvBaseEnc * nvenc) if (format_mask == 0) return FALSE; + GST_OBJECT_LOCK (nvenc); + nvenc->input_formats = g_new0 (GValue, 1); + /* process a second time so we can add formats in the order we want */ - g_value_init (&list, GST_TYPE_LIST); + g_value_init (nvenc->input_formats, GST_TYPE_LIST); g_value_init (&val, G_TYPE_STRING); if ((format_mask & (1 << GST_VIDEO_FORMAT_NV12))) { g_value_set_static_string (&val, "NV12"); - gst_value_list_append_value (&list, &val); + gst_value_list_append_value (nvenc->input_formats, &val); } if ((format_mask & (1 << GST_VIDEO_FORMAT_YV12))) { g_value_set_static_string (&val, "YV12"); - gst_value_list_append_value (&list, &val); + gst_value_list_append_value (nvenc->input_formats, &val); } if ((format_mask & (1 << GST_VIDEO_FORMAT_I420))) { g_value_set_static_string (&val, "I420"); - gst_value_list_append_value (&list, &val); + gst_value_list_append_value (nvenc->input_formats, &val); } if ((format_mask & (1 << GST_VIDEO_FORMAT_Y444))) { g_value_set_static_string (&val, "Y444"); - gst_value_list_append_value (&list, &val); + gst_value_list_append_value (nvenc->input_formats, &val); } g_value_unset (&val); - GST_OBJECT_LOCK (nvenc); - g_free (nvenc->input_formats); - nvenc->input_formats = g_memdup (&list, sizeof (GValue)); GST_OBJECT_UNLOCK (nvenc); return TRUE; @@ -559,7 +561,7 @@ _get_interlace_modes (GstNvBaseEnc * nvenc) g_value_set_static_string (&val, "interleaved"); gst_value_list_append_value (list, &val); g_value_set_static_string (&val, "mixed"); - gst_value_list_append_value (list, &val); + gst_value_list_append_and_take_value (list, &val); } /* TODO: figure out what nvenc frame based interlacing means in gst terms */ @@ -584,6 +586,7 @@ gst_nv_base_enc_getcaps (GstVideoEncoder * enc, GstCaps * filter) val = _get_interlace_modes (nvenc); gst_caps_set_value (supported_incaps, "interlace-mode", val); + g_value_unset (val); g_free (val); GST_LOG_OBJECT (enc, "codec input caps %" GST_PTR_FORMAT, supported_incaps); @@ -625,6 +628,8 @@ gst_nv_base_enc_close (GstVideoEncoder * enc) } GST_OBJECT_LOCK (nvenc); + if (nvenc->input_formats) + g_value_unset (nvenc->input_formats); g_free (nvenc->input_formats); nvenc->input_formats = NULL; GST_OBJECT_UNLOCK (nvenc); diff --git a/sys/nvenc/gstnvh264enc.c b/sys/nvenc/gstnvh264enc.c index 366fb21..84641c9 100644 --- a/sys/nvenc/gstnvh264enc.c +++ b/sys/nvenc/gstnvh264enc.c @@ -147,6 +147,9 @@ _get_supported_profiles (GstNvH264Enc * nvenc) GValue val = G_VALUE_INIT; guint i, n, n_profiles; + if (nvenc->supported_profiles) + return TRUE; + nv_ret = NvEncGetEncodeProfileGUIDCount (GST_NV_BASE_ENC (nvenc)->encoder, NV_ENC_CODEC_H264_GUID, &n); @@ -189,8 +192,8 @@ _get_supported_profiles (GstNvH264Enc * nvenc) return FALSE; GST_OBJECT_LOCK (nvenc); - g_free (nvenc->supported_profiles); - nvenc->supported_profiles = g_memdup (&list, sizeof (GValue)); + nvenc->supported_profiles = g_new0 (GValue, 1); + *nvenc->supported_profiles = list; GST_OBJECT_UNLOCK (nvenc); return TRUE; @@ -239,6 +242,8 @@ gst_nv_h264_enc_close (GstVideoEncoder * enc) GstNvH264Enc *nvenc = GST_NV_H264_ENC (enc); GST_OBJECT_LOCK (nvenc); + if (nvenc->supported_profiles) + g_value_unset (nvenc->supported_profiles); g_free (nvenc->supported_profiles); nvenc->supported_profiles = NULL; GST_OBJECT_UNLOCK (nvenc); @@ -272,6 +277,7 @@ _get_interlace_modes (GstNvH264Enc * nvenc) gst_value_list_append_value (list, &val); g_value_set_static_string (&val, "mixed"); gst_value_list_append_value (list, &val); + g_value_unset (&val); } /* TODO: figure out what nvenc frame based interlacing means in gst terms */ @@ -297,6 +303,7 @@ gst_nv_h264_enc_getcaps (GstVideoEncoder * enc, GstCaps * filter) val = _get_interlace_modes (nvenc); gst_caps_set_value (supported_incaps, "interlace-mode", val); + g_value_unset (val); g_free (val); GST_LOG_OBJECT (enc, "codec input caps %" GST_PTR_FORMAT, supported_incaps); diff --git a/sys/nvenc/gstnvh265enc.c b/sys/nvenc/gstnvh265enc.c index 0a67a35..f05313e 100644 --- a/sys/nvenc/gstnvh265enc.c +++ b/sys/nvenc/gstnvh265enc.c @@ -147,6 +147,9 @@ _get_supported_profiles (GstNvH265Enc * nvenc) GValue val = G_VALUE_INIT; guint i, n, n_profiles; + if (nvenc->supported_profiles) + return TRUE; + nv_ret = NvEncGetEncodeProfileGUIDCount (GST_NV_BASE_ENC (nvenc)->encoder, NV_ENC_CODEC_HEVC_GUID, &n); @@ -178,8 +181,8 @@ _get_supported_profiles (GstNvH265Enc * nvenc) return FALSE; GST_OBJECT_LOCK (nvenc); - g_free (nvenc->supported_profiles); - nvenc->supported_profiles = g_memdup (&list, sizeof (GValue)); + nvenc->supported_profiles = g_new0 (GValue, 1); + *nvenc->supported_profiles = list; GST_OBJECT_UNLOCK (nvenc); return TRUE; @@ -228,6 +231,8 @@ gst_nv_h265_enc_close (GstVideoEncoder * enc) GstNvH265Enc *nvenc = GST_NV_H265_ENC (enc); GST_OBJECT_LOCK (nvenc); + if (nvenc->supported_profiles) + g_value_unset (nvenc->supported_profiles); g_free (nvenc->supported_profiles); nvenc->supported_profiles = NULL; GST_OBJECT_UNLOCK (nvenc); -- 2.7.4