mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
videoencoder: Fix leak when pre_push does not return OK
https://bugzilla.gnome.org/show_bug.cgi?id=761951
This commit is contained in:
parent
9d66b7cdd2
commit
85f297d648
2 changed files with 49 additions and 6 deletions
|
@ -2183,7 +2183,8 @@ gst_video_encoder_finish_frame (GstVideoEncoder * encoder,
|
|||
|
||||
/* Get an additional ref to the buffer, which is going to be pushed
|
||||
* downstream, the original ref is owned by the frame */
|
||||
buffer = gst_buffer_ref (frame->output_buffer);
|
||||
if (ret == GST_FLOW_OK)
|
||||
buffer = gst_buffer_ref (frame->output_buffer);
|
||||
|
||||
/* Release frame so the buffer is writable when we push it downstream
|
||||
* if possible, i.e. if the subclass does not hold additional references
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#endif
|
||||
#include <gst/gst.h>
|
||||
#include <gst/check/gstcheck.h>
|
||||
#include <gst/check/gstharness.h>
|
||||
#include <gst/video/video.h>
|
||||
#include <gst/app/app.h>
|
||||
|
||||
|
@ -45,6 +46,8 @@ typedef struct _GstVideoEncoderTesterClass GstVideoEncoderTesterClass;
|
|||
struct _GstVideoEncoderTester
|
||||
{
|
||||
GstVideoEncoder parent;
|
||||
|
||||
GstFlowReturn pre_push_result;
|
||||
};
|
||||
|
||||
struct _GstVideoEncoderTesterClass
|
||||
|
@ -102,6 +105,15 @@ gst_video_encoder_tester_handle_frame (GstVideoEncoder * dec,
|
|||
return gst_video_encoder_finish_frame (dec, frame);
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_video_encoder_tester_pre_push (GstVideoEncoder * enc,
|
||||
GstVideoCodecFrame * frame)
|
||||
{
|
||||
GstVideoEncoderTester *tester = (GstVideoEncoderTester *) enc;
|
||||
|
||||
return tester->pre_push_result;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_video_encoder_tester_class_init (GstVideoEncoderTesterClass * klass)
|
||||
{
|
||||
|
@ -127,12 +139,14 @@ gst_video_encoder_tester_class_init (GstVideoEncoderTesterClass * klass)
|
|||
videoencoder_class->start = gst_video_encoder_tester_start;
|
||||
videoencoder_class->stop = gst_video_encoder_tester_stop;
|
||||
videoencoder_class->handle_frame = gst_video_encoder_tester_handle_frame;
|
||||
videoencoder_class->pre_push = gst_video_encoder_tester_pre_push;
|
||||
videoencoder_class->set_format = gst_video_encoder_tester_set_format;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_video_encoder_tester_init (GstVideoEncoderTester * tester)
|
||||
{
|
||||
tester->pre_push_result = GST_FLOW_OK;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -199,6 +213,15 @@ create_test_buffer (guint64 num)
|
|||
return buffer;
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
create_test_caps (void)
|
||||
{
|
||||
return gst_caps_new_simple ("video/x-raw", "width", G_TYPE_INT,
|
||||
TEST_VIDEO_WIDTH, "height", G_TYPE_INT, TEST_VIDEO_HEIGHT, "framerate",
|
||||
GST_TYPE_FRACTION, TEST_VIDEO_FPS_N, TEST_VIDEO_FPS_D,
|
||||
"format", G_TYPE_STRING, "GRAY8", NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
send_startup_events (void)
|
||||
{
|
||||
|
@ -208,11 +231,7 @@ send_startup_events (void)
|
|||
gst_event_new_stream_start ("randomvalue")));
|
||||
|
||||
/* push caps */
|
||||
caps =
|
||||
gst_caps_new_simple ("video/x-raw", "width", G_TYPE_INT,
|
||||
TEST_VIDEO_WIDTH, "height", G_TYPE_INT, TEST_VIDEO_HEIGHT, "framerate",
|
||||
GST_TYPE_FRACTION, TEST_VIDEO_FPS_N, TEST_VIDEO_FPS_D,
|
||||
"format", G_TYPE_STRING, "GRAY8", NULL);
|
||||
caps = create_test_caps ();
|
||||
fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_caps (caps)));
|
||||
gst_caps_unref (caps);
|
||||
}
|
||||
|
@ -495,6 +514,28 @@ GST_START_TEST (videoencoder_flush_events)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
/* When pre_push fails the correct GstFlowReturn should be returned and there
|
||||
* should be no leaks */
|
||||
GST_START_TEST (videoencoder_pre_push_fails)
|
||||
{
|
||||
GstVideoEncoderTester *tester;
|
||||
GstHarness *h;
|
||||
|
||||
tester = g_object_new (GST_VIDEO_ENCODER_TESTER_TYPE, NULL);
|
||||
tester->pre_push_result = GST_FLOW_ERROR;
|
||||
|
||||
h = gst_harness_new_with_element (GST_ELEMENT (tester), "sink", "src");
|
||||
gst_harness_set_src_caps (h, create_test_caps ());
|
||||
|
||||
fail_unless_equals_int (gst_harness_push (h, create_test_buffer (0)),
|
||||
GST_FLOW_ERROR);
|
||||
|
||||
gst_harness_teardown (h);
|
||||
gst_object_unref (tester);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
static Suite *
|
||||
gst_videoencoder_suite (void)
|
||||
{
|
||||
|
@ -507,6 +548,7 @@ gst_videoencoder_suite (void)
|
|||
tcase_add_test (tc, videoencoder_tags_before_eos);
|
||||
tcase_add_test (tc, videoencoder_events_before_eos);
|
||||
tcase_add_test (tc, videoencoder_flush_events);
|
||||
tcase_add_test (tc, videoencoder_pre_push_fails);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue