mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-28 04:31:06 +00:00
[MOVED FROM BAD 06/56] gst/deinterlace2/gstdeinterlace2.*: Reset element state on PAUSED->READY properly, don't leak any buffers when finali...
Original commit message from CVS: * gst/deinterlace2/gstdeinterlace2.c: (gst_deinterlace2_class_init), (gst_deinterlace2_init), (gst_deinterlace2_reset_history), (gst_deinterlace2_reset), (gst_deinterlace2_finalize), (gst_deinterlace2_chain), (gst_deinterlace2_sink_event), (gst_deinterlace2_change_state), (gst_deinterlace2_src_query): * gst/deinterlace2/gstdeinterlace2.h: Reset element state on PAUSED->READY properly, don't leak any buffers when finalizing, allocate buffers with gst_pad_alloc_buffer() and properly return flow returns from gst_pad_push() instead of ignoring them.
This commit is contained in:
parent
478f17052f
commit
e094cde977
2 changed files with 67 additions and 26 deletions
|
@ -30,6 +30,8 @@
|
||||||
#include "tvtime/plugins.h"
|
#include "tvtime/plugins.h"
|
||||||
#include "tvtime/speedy.h"
|
#include "tvtime/speedy.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_STATIC (deinterlace2_debug);
|
GST_DEBUG_CATEGORY_STATIC (deinterlace2_debug);
|
||||||
#define GST_CAT_DEFAULT (deinterlace2_debug)
|
#define GST_CAT_DEFAULT (deinterlace2_debug)
|
||||||
|
|
||||||
|
@ -146,6 +148,8 @@ static const GstQueryType *gst_deinterlace2_src_query_types (GstPad * pad);
|
||||||
|
|
||||||
static void gst_deinterlace2_deinterlace_scanlines (GstDeinterlace2 * object);
|
static void gst_deinterlace2_deinterlace_scanlines (GstDeinterlace2 * object);
|
||||||
|
|
||||||
|
static void gst_deinterlace2_reset (GstDeinterlace2 * object);
|
||||||
|
|
||||||
GST_BOILERPLATE (GstDeinterlace2, gst_deinterlace2, GstElement,
|
GST_BOILERPLATE (GstDeinterlace2, gst_deinterlace2, GstElement,
|
||||||
GST_TYPE_ELEMENT);
|
GST_TYPE_ELEMENT);
|
||||||
|
|
||||||
|
@ -183,7 +187,7 @@ gst_deinterlace2_class_init (GstDeinterlace2Class * klass)
|
||||||
"Method",
|
"Method",
|
||||||
"Deinterlace Method",
|
"Deinterlace Method",
|
||||||
GST_TYPE_DEINTERLACE2_METHOD,
|
GST_TYPE_DEINTERLACE2_METHOD,
|
||||||
GST_DEINTERLACE2_GREEDY_H, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
|
GST_DEINTERLACE2_TOM, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
|
||||||
);
|
);
|
||||||
|
|
||||||
g_object_class_install_property (gobject_class, ARG_FIELDS,
|
g_object_class_install_property (gobject_class, ARG_FIELDS,
|
||||||
|
@ -243,22 +247,45 @@ gst_deinterlace2_init (GstDeinterlace2 * object, GstDeinterlace2Class * klass)
|
||||||
object->pMemcpy = speedy_memcpy;
|
object->pMemcpy = speedy_memcpy;
|
||||||
|
|
||||||
object->method = dscaler_tomsmocomp_get_method ();
|
object->method = dscaler_tomsmocomp_get_method ();
|
||||||
|
|
||||||
object->history_count = 0;
|
|
||||||
|
|
||||||
object->field_layout = GST_DEINTERLACE2_LAYOUT_AUTO;
|
object->field_layout = GST_DEINTERLACE2_LAYOUT_AUTO;
|
||||||
|
object->fields = GST_DEINTERLACE2_ALL;
|
||||||
|
|
||||||
|
gst_deinterlace2_reset (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_deinterlace2_reset_history (GstDeinterlace2 * object)
|
||||||
|
{
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
for (i = 0; i < object->history_count; i++) {
|
||||||
|
if (object->field_history[i].buf) {
|
||||||
|
gst_buffer_unref (object->field_history[i].buf);
|
||||||
|
object->field_history[i].buf = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
memset (object->field_history, 0, MAX_FIELD_HISTORY * sizeof (GstPicture));
|
||||||
|
object->history_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_deinterlace2_reset (GstDeinterlace2 * object)
|
||||||
|
{
|
||||||
|
if (object->out_buf) {
|
||||||
|
gst_buffer_unref (object->out_buf);
|
||||||
|
object->out_buf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
object->out_buf = NULL;
|
|
||||||
object->output_stride = 0;
|
object->output_stride = 0;
|
||||||
object->line_length = 0;
|
object->line_length = 0;
|
||||||
object->frame_width = 0;
|
object->frame_width = 0;
|
||||||
object->frame_height = 0;
|
object->frame_height = 0;
|
||||||
|
object->frame_rate_n = 0;
|
||||||
|
object->frame_rate_d = 0;
|
||||||
object->field_height = 0;
|
object->field_height = 0;
|
||||||
object->field_stride = 0;
|
object->field_stride = 0;
|
||||||
|
|
||||||
object->fields = GST_DEINTERLACE2_ALL;
|
gst_deinterlace2_reset_history (object);
|
||||||
|
|
||||||
object->bottom_field = TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -349,7 +376,9 @@ gst_deinterlace2_get_property (GObject * _object, guint prop_id,
|
||||||
static void
|
static void
|
||||||
gst_deinterlace2_finalize (GObject * object)
|
gst_deinterlace2_finalize (GObject * object)
|
||||||
{
|
{
|
||||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
gst_deinterlace2_reset (GST_DEINTERLACE2 (object));
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstBuffer *
|
static GstBuffer *
|
||||||
|
@ -544,12 +573,11 @@ gst_deinterlace2_deinterlace_scanlines (GstDeinterlace2 * object)
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_deinterlace2_chain (GstPad * pad, GstBuffer * buf)
|
gst_deinterlace2_chain (GstPad * pad, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
//GstBuffer *out_buf = NULL;
|
|
||||||
GstDeinterlace2 *object = NULL;
|
GstDeinterlace2 *object = NULL;
|
||||||
|
|
||||||
GstClockTime timestamp;
|
GstClockTime timestamp;
|
||||||
|
|
||||||
//GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
|
|
||||||
object = GST_DEINTERLACE2 (GST_PAD_PARENT (pad));
|
object = GST_DEINTERLACE2 (GST_PAD_PARENT (pad));
|
||||||
|
|
||||||
|
@ -581,8 +609,11 @@ gst_deinterlace2_chain (GstPad * pad, GstBuffer * buf)
|
||||||
GST_DEBUG ("deinterlacing top field");
|
GST_DEBUG ("deinterlacing top field");
|
||||||
|
|
||||||
/* create new buffer */
|
/* create new buffer */
|
||||||
object->out_buf = gst_buffer_new_and_alloc (object->frame_size);
|
ret = gst_pad_alloc_buffer_and_set_caps (object->srcpad,
|
||||||
gst_buffer_set_caps (object->out_buf, GST_PAD_CAPS (object->srcpad));
|
GST_BUFFER_OFFSET_NONE, object->frame_size,
|
||||||
|
GST_PAD_CAPS (object->srcpad), &object->out_buf);
|
||||||
|
if (ret != GST_FLOW_OK)
|
||||||
|
return ret;
|
||||||
|
|
||||||
/* do magic calculus */
|
/* do magic calculus */
|
||||||
if (object->method->deinterlace_frame != NULL) {
|
if (object->method->deinterlace_frame != NULL) {
|
||||||
|
@ -593,7 +624,10 @@ gst_deinterlace2_chain (GstPad * pad, GstBuffer * buf)
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
|
|
||||||
GST_BUFFER_TIMESTAMP (object->out_buf) = timestamp;
|
GST_BUFFER_TIMESTAMP (object->out_buf) = timestamp;
|
||||||
gst_pad_push (object->srcpad, object->out_buf);
|
ret = gst_pad_push (object->srcpad, object->out_buf);
|
||||||
|
object->out_buf = NULL;
|
||||||
|
if (ret != GST_FLOW_OK)
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* no calculation done: remove excess field */
|
/* no calculation done: remove excess field */
|
||||||
|
@ -613,8 +647,11 @@ gst_deinterlace2_chain (GstPad * pad, GstBuffer * buf)
|
||||||
GST_DEBUG ("deinterlacing bottom field");
|
GST_DEBUG ("deinterlacing bottom field");
|
||||||
|
|
||||||
/* create new buffer */
|
/* create new buffer */
|
||||||
object->out_buf = gst_buffer_new_and_alloc (object->frame_size);
|
ret = gst_pad_alloc_buffer_and_set_caps (object->srcpad,
|
||||||
gst_buffer_set_caps (object->out_buf, GST_PAD_CAPS (object->srcpad));
|
GST_BUFFER_OFFSET_NONE, object->frame_size,
|
||||||
|
GST_PAD_CAPS (object->srcpad), &object->out_buf);
|
||||||
|
if (ret != GST_FLOW_OK)
|
||||||
|
return ret;
|
||||||
|
|
||||||
/* do magic calculus */
|
/* do magic calculus */
|
||||||
if (object->method->deinterlace_frame != NULL) {
|
if (object->method->deinterlace_frame != NULL) {
|
||||||
|
@ -625,7 +662,11 @@ gst_deinterlace2_chain (GstPad * pad, GstBuffer * buf)
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
|
|
||||||
GST_BUFFER_TIMESTAMP (object->out_buf) = timestamp;
|
GST_BUFFER_TIMESTAMP (object->out_buf) = timestamp;
|
||||||
gst_pad_push (object->srcpad, object->out_buf);
|
ret = gst_pad_push (object->srcpad, object->out_buf);
|
||||||
|
object->out_buf = NULL;
|
||||||
|
|
||||||
|
if (ret != GST_FLOW_OK)
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* no calculation done: remove excess field */
|
/* no calculation done: remove excess field */
|
||||||
|
@ -639,11 +680,14 @@ gst_deinterlace2_chain (GstPad * pad, GstBuffer * buf)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
object->out_buf = gst_deinterlace2_pop_history (object);
|
object->out_buf = gst_deinterlace2_pop_history (object);
|
||||||
gst_pad_push (object->srcpad, object->out_buf);
|
ret = gst_pad_push (object->srcpad, object->out_buf);
|
||||||
|
object->out_buf = NULL;
|
||||||
|
if (ret != GST_FLOW_OK)
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
GST_DEBUG ("----chain end ----\n\n");
|
GST_DEBUG ("----chain end ----\n\n");
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -729,7 +773,7 @@ gst_deinterlace2_sink_event (GstPad * pad, GstEvent * event)
|
||||||
case GST_EVENT_FLUSH_STOP:
|
case GST_EVENT_FLUSH_STOP:
|
||||||
case GST_EVENT_EOS:
|
case GST_EVENT_EOS:
|
||||||
case GST_EVENT_NEWSEGMENT:
|
case GST_EVENT_NEWSEGMENT:
|
||||||
/* TODO: reset history */
|
gst_deinterlace2_reset_history (object);
|
||||||
|
|
||||||
/* fall through */
|
/* fall through */
|
||||||
default:
|
default:
|
||||||
|
@ -746,6 +790,8 @@ gst_deinterlace2_change_state (GstElement * element, GstStateChange transition)
|
||||||
{
|
{
|
||||||
GstStateChangeReturn ret;
|
GstStateChangeReturn ret;
|
||||||
|
|
||||||
|
GstDeinterlace2 *object = GST_DEINTERLACE2 (element);
|
||||||
|
|
||||||
switch (transition) {
|
switch (transition) {
|
||||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||||
break;
|
break;
|
||||||
|
@ -765,7 +811,7 @@ gst_deinterlace2_change_state (GstElement * element, GstStateChange transition)
|
||||||
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
|
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
|
||||||
break;
|
break;
|
||||||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||||
/* TODO: reset history, clean up, etc */
|
gst_deinterlace2_reset (object);
|
||||||
break;
|
break;
|
||||||
case GST_STATE_CHANGE_READY_TO_NULL:
|
case GST_STATE_CHANGE_READY_TO_NULL:
|
||||||
default:
|
default:
|
||||||
|
@ -823,10 +869,7 @@ gst_deinterlace2_src_query (GstPad * pad, GstQuery * query)
|
||||||
GST_TIME_FORMAT " max %" GST_TIME_FORMAT,
|
GST_TIME_FORMAT " max %" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (min), GST_TIME_ARGS (max));
|
GST_TIME_ARGS (min), GST_TIME_ARGS (max));
|
||||||
|
|
||||||
/* TODO: calculate our own latency from framerate
|
|
||||||
* and object->method->fields_required */
|
|
||||||
/* add our own latency */
|
/* add our own latency */
|
||||||
|
|
||||||
latency =
|
latency =
|
||||||
gst_util_uint64_scale (object->method->fields_required *
|
gst_util_uint64_scale (object->method->fields_required *
|
||||||
GST_SECOND, object->frame_rate_d, object->frame_rate_n);
|
GST_SECOND, object->frame_rate_d, object->frame_rate_n);
|
||||||
|
|
|
@ -252,8 +252,6 @@ struct _GstDeinterlace2
|
||||||
need not match the pixel width
|
need not match the pixel width
|
||||||
*/
|
*/
|
||||||
guint field_stride;
|
guint field_stride;
|
||||||
|
|
||||||
gboolean bottom_field;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstDeinterlace2Class
|
struct _GstDeinterlace2Class
|
||||||
|
|
Loading…
Reference in a new issue