aom: Fix all definite leaks in av1enc

Track if the encoder has been inited, and cleanup if needed. Also unref
input_state if has been set

https://bugzilla.gnome.org/show_bug.cgi?id=791674
This commit is contained in:
Sean DuBois 2018-02-02 06:56:17 +00:00 committed by Sebastian Dröge
parent 327586bd26
commit 86abe6b1e6
2 changed files with 62 additions and 29 deletions

View file

@ -52,14 +52,13 @@ enum
}; };
static void gst_av1_enc_finalize (GObject * object); static void gst_av1_enc_finalize (GObject * object);
static void gst_av1_enc_set_property (GObject * object, guint prop_id, static void gst_av1_enc_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec); const GValue * value, GParamSpec * pspec);
static void gst_av1_enc_get_property (GObject * object, guint prop_id, static void gst_av1_enc_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec); GValue * value, GParamSpec * pspec);
static gboolean gst_av1_enc_start (GstVideoEncoder * benc); static gboolean gst_av1_enc_start (GstVideoEncoder * encoder);
static gboolean gst_av1_enc_stop (GstVideoEncoder * benc); static gboolean gst_av1_enc_stop (GstVideoEncoder * encoder);
static gboolean gst_av1_enc_set_format (GstVideoEncoder * encoder, static gboolean gst_av1_enc_set_format (GstVideoEncoder * encoder,
GstVideoCodecState * state); GstVideoCodecState * state);
static GstFlowReturn gst_av1_enc_handle_frame (GstVideoEncoder * encoder, static GstFlowReturn gst_av1_enc_handle_frame (GstVideoEncoder * encoder,
@ -67,6 +66,8 @@ static GstFlowReturn gst_av1_enc_handle_frame (GstVideoEncoder * encoder,
static gboolean gst_av1_enc_propose_allocation (GstVideoEncoder * encoder, static gboolean gst_av1_enc_propose_allocation (GstVideoEncoder * encoder,
GstQuery * query); GstQuery * query);
static void gst_av1_enc_destroy_encoder (GstAV1Enc * av1enc);
#define gst_av1_enc_parent_class parent_class #define gst_av1_enc_parent_class parent_class
G_DEFINE_TYPE (GstAV1Enc, gst_av1_enc, GST_TYPE_VIDEO_ENCODER); G_DEFINE_TYPE (GstAV1Enc, gst_av1_enc, GST_TYPE_VIDEO_ENCODER);
@ -137,11 +138,23 @@ static void
gst_av1_enc_init (GstAV1Enc * av1enc) gst_av1_enc_init (GstAV1Enc * av1enc)
{ {
GST_PAD_SET_ACCEPT_TEMPLATE (GST_VIDEO_ENCODER_SINK_PAD (av1enc)); GST_PAD_SET_ACCEPT_TEMPLATE (GST_VIDEO_ENCODER_SINK_PAD (av1enc));
av1enc->keyframe_dist = 30;
av1enc->encoder_inited = FALSE;
} }
static void static void
gst_av1_enc_finalize (GObject * object) gst_av1_enc_finalize (GObject * object)
{ {
GstAV1Enc *av1enc = GST_AV1_ENC (object);
if (av1enc->input_state) {
gst_video_codec_state_unref (av1enc->input_state);
}
av1enc->input_state = NULL;
gst_av1_enc_destroy_encoder (av1enc);
G_OBJECT_CLASS (parent_class)->finalize (object); G_OBJECT_CLASS (parent_class)->finalize (object);
} }
@ -222,10 +235,25 @@ gst_av1_enc_debug_encoder_cfg (struct aom_codec_enc_cfg *cfg)
} }
static gboolean static gboolean
gst_av1_enc_init_aom (GstAV1Enc * av1enc) gst_av1_enc_set_format (GstVideoEncoder * encoder, GstVideoCodecState * state)
{ {
GstVideoCodecState *output_state;
GstAV1Enc *av1enc = GST_AV1_ENC_CAST (encoder);
GstAV1EncClass *av1enc_class = GST_AV1_ENC_GET_CLASS (av1enc); GstAV1EncClass *av1enc_class = GST_AV1_ENC_GET_CLASS (av1enc);
output_state =
gst_video_encoder_set_output_state (encoder,
gst_pad_get_pad_template_caps (GST_VIDEO_ENCODER_SRC_PAD (encoder)),
state);
gst_video_codec_state_unref (output_state);
if (av1enc->input_state) {
gst_video_codec_state_unref (av1enc->input_state);
}
av1enc->input_state = gst_video_codec_state_ref (state);
gst_av1_enc_set_latency (av1enc);
if (aom_codec_enc_config_default (av1enc_class->codec_algo, &av1enc->aom_cfg, if (aom_codec_enc_config_default (av1enc_class->codec_algo, &av1enc->aom_cfg,
0)) { 0)) {
gst_av1_codec_error (&av1enc->encoder, gst_av1_codec_error (&av1enc->encoder,
@ -252,31 +280,11 @@ gst_av1_enc_init_aom (GstAV1Enc * av1enc)
gst_av1_codec_error (&av1enc->encoder, "Failed to initialize encoder"); gst_av1_codec_error (&av1enc->encoder, "Failed to initialize encoder");
return FALSE; return FALSE;
} }
av1enc->encoder_inited = TRUE;
return TRUE; return TRUE;
} }
static gboolean
gst_av1_enc_set_format (GstVideoEncoder * encoder, GstVideoCodecState * state)
{
GstVideoCodecState *output_state;
GstAV1Enc *av1enc = GST_AV1_ENC_CAST (encoder);
av1enc->keyframe_dist = 30;
output_state =
gst_video_encoder_set_output_state (encoder,
gst_pad_get_pad_template_caps (GST_VIDEO_ENCODER_SRC_PAD (encoder)),
state);
gst_video_codec_state_unref (output_state);
av1enc->input_state = gst_video_codec_state_ref (state);
gst_av1_enc_set_latency (av1enc);
return gst_av1_enc_init_aom (av1enc);
}
static GstFlowReturn static GstFlowReturn
gst_av1_enc_process (GstAV1Enc * encoder) gst_av1_enc_process (GstAV1Enc * encoder)
{ {
@ -332,7 +340,7 @@ gst_av1_enc_handle_frame (GstVideoEncoder * encoder, GstVideoCodecFrame * frame)
GstAV1Enc *av1enc = GST_AV1_ENC_CAST (encoder); GstAV1Enc *av1enc = GST_AV1_ENC_CAST (encoder);
aom_image_t raw; aom_image_t raw;
int flags = 0; int flags = 0;
GstFlowReturn ret; GstFlowReturn ret = GST_FLOW_OK;
GstVideoFrame vframe; GstVideoFrame vframe;
if (!aom_img_alloc (&raw, AOM_IMG_FMT_I420, av1enc->aom_cfg.g_w, if (!aom_img_alloc (&raw, AOM_IMG_FMT_I420, av1enc->aom_cfg.g_w,
@ -355,11 +363,25 @@ gst_av1_enc_handle_frame (GstVideoEncoder * encoder, GstVideoCodecFrame * frame)
if (aom_codec_encode (&av1enc->encoder, &raw, frame->pts, 1, flags) if (aom_codec_encode (&av1enc->encoder, &raw, frame->pts, 1, flags)
!= AOM_CODEC_OK) { != AOM_CODEC_OK) {
gst_av1_codec_error (&av1enc->encoder, "Failed to encode frame"); gst_av1_codec_error (&av1enc->encoder, "Failed to encode frame");
ret = GST_FLOW_ERROR;
} }
ret = gst_av1_enc_process (av1enc);
aom_img_free (&raw); aom_img_free (&raw);
return ret; gst_video_codec_frame_unref (frame);
if (ret == GST_FLOW_ERROR) {
return ret;
}
return gst_av1_enc_process (av1enc);
}
static void
gst_av1_enc_destroy_encoder (GstAV1Enc * av1enc)
{
if (av1enc->encoder_inited) {
aom_codec_destroy (&av1enc->encoder);
av1enc->encoder_inited = FALSE;
}
} }
static gboolean static gboolean
@ -413,7 +435,16 @@ gst_av1_enc_start (GstVideoEncoder * encoder)
} }
static gboolean static gboolean
gst_av1_enc_stop (GstVideoEncoder * benc) gst_av1_enc_stop (GstVideoEncoder * encoder)
{ {
GstAV1Enc *av1enc = GST_AV1_ENC_CAST (encoder);
if (av1enc->input_state) {
gst_video_codec_state_unref (av1enc->input_state);
}
av1enc->input_state = NULL;
gst_av1_enc_destroy_encoder (av1enc);
return TRUE; return TRUE;
} }

View file

@ -53,6 +53,8 @@ struct _GstAV1Enc
{ {
GstVideoEncoder base_video_encoder; GstVideoEncoder base_video_encoder;
gboolean encoder_inited;
guint keyframe_dist; guint keyframe_dist;
aom_codec_enc_cfg_t aom_cfg; aom_codec_enc_cfg_t aom_cfg;