gst/videorate/gstvideorate.c: Don't leak incoming buffer if gst_pad_push() returns a non-OK flow. Fixes #432755.

Original commit message from CVS:
Patch by: Dan Williams <dcbw redhat com>
* gst/videorate/gstvideorate.c: (gst_video_rate_chain):
Don't leak incoming buffer if gst_pad_push() returns a
non-OK flow. Fixes #432755.
* tests/check/elements/videorate.c: (GST_START_TEST),
(videorate_suite):
Unit test for the above by Yours Truly.
This commit is contained in:
Dan Williams 2007-04-24 15:00:07 +00:00 committed by Tim-Philipp Müller
parent d24aff28b2
commit 37a334ddb7
3 changed files with 68 additions and 20 deletions

View file

@ -1,3 +1,15 @@
2007-04-24 Tim-Philipp Müller <tim at centricular dot net>
Patch by: Dan Williams <dcbw redhat com>
* gst/videorate/gstvideorate.c: (gst_video_rate_chain):
Don't leak incoming buffer if gst_pad_push() returns a
non-OK flow. Fixes #432755.
* tests/check/elements/videorate.c: (GST_START_TEST),
(videorate_suite):
Unit test for the above by Yours Truly.
2007-04-23 Stefan Kost <ensonic@users.sf.net>
* gst/adder/gstadder.c: (gst_adder_setcaps), (gst_adder_src_event),

View file

@ -560,7 +560,7 @@ gst_video_rate_chain (GstPad * pad, GstBuffer * buffer)
GstFlowReturn res = GST_FLOW_OK;
GstClockTime intime, in_ts;
videorate = GST_VIDEO_RATE (gst_pad_get_parent (pad));
videorate = GST_VIDEO_RATE (GST_PAD_PARENT (pad));
/* make sure the denominators are not 0 */
if (videorate->from_rate_denominator == 0 ||
@ -636,8 +636,10 @@ gst_video_rate_chain (GstPad * pad, GstBuffer * buffer)
count++;
/* on error the _flush function posted a warning already */
if ((res = gst_video_rate_flush_prev (videorate)) != GST_FLOW_OK)
if ((res = gst_video_rate_flush_prev (videorate)) != GST_FLOW_OK) {
gst_buffer_unref (buffer);
goto done;
}
}
/* continue while the first one was the best */
}
@ -671,7 +673,6 @@ gst_video_rate_chain (GstPad * pad, GstBuffer * buffer)
gst_video_rate_swap_prev (videorate, buffer, intime);
}
done:
gst_object_unref (videorate);
return res;
/* ERRORS */

View file

@ -609,7 +609,56 @@ GST_START_TEST (test_changing_size)
}
GST_END_TEST;
Suite *
GST_START_TEST (test_non_ok_flow)
{
GstElement *videorate;
GstClockTime ts;
GstBuffer *buf;
GstCaps *caps;
videorate = setup_videorate ();
fail_unless (gst_element_set_state (videorate,
GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
"could not set to playing");
buf = gst_buffer_new_and_alloc (4);
memset (GST_BUFFER_DATA (buf), 0, 4);
caps = gst_caps_from_string (VIDEO_CAPS_STRING);
gst_buffer_set_caps (buf, caps);
gst_caps_unref (caps);
ASSERT_BUFFER_REFCOUNT (buf, "inbuffer", 1);
/* push a few 'normal' buffers */
for (ts = 0; ts < 100 * GST_SECOND; ts += GST_SECOND / 33) {
GstBuffer *inbuf;
inbuf = gst_buffer_copy (buf);
GST_BUFFER_TIMESTAMP (inbuf) = ts;
fail_unless_equals_int (gst_pad_push (mysrcpad, inbuf), GST_FLOW_OK);
}
/* we should have buffers according to the output framerate of 25/1 */
fail_unless_equals_int (g_list_length (buffers), 100 * 25);
/* now deactivate pad so we get a WRONG_STATE flow return */
gst_pad_set_active (mysinkpad, FALSE);
/* push buffer on deactivated pad */
fail_unless (gst_buffer_is_metadata_writable (buf));
GST_BUFFER_TIMESTAMP (buf) = ts;
/* pushing gives away our reference */
fail_unless_equals_int (gst_pad_push (mysrcpad, buf), GST_FLOW_WRONG_STATE);
/* cleanup */
cleanup_videorate (videorate);
}
GST_END_TEST;
static Suite *
videorate_suite (void)
{
Suite *s = suite_create ("videorate");
@ -622,23 +671,9 @@ videorate_suite (void)
tcase_add_test (tc_chain, test_wrong_order);
tcase_add_test (tc_chain, test_no_framerate);
tcase_add_test (tc_chain, test_changing_size);
tcase_add_test (tc_chain, test_non_ok_flow);
return s;
}
int
main (int argc, char **argv)
{
int nf;
Suite *s = videorate_suite ();
SRunner *sr = srunner_create (s);
gst_check_init (&argc, &argv);
srunner_run_all (sr, CK_NORMAL);
nf = srunner_ntests_failed (sr);
srunner_free (sr);
return nf;
}
GST_CHECK_MAIN (videorate)