[MOVED FROM BAD 24/56] gst/deinterlace2/gstdeinterlace2.*: Include latency of the method in the returned latency.

Original commit message from CVS:
* gst/deinterlace2/gstdeinterlace2.c:
(gst_deinterlace_method_get_latency),
(gst_deinterlace2_set_method), (gst_deinterlace2_class_init),
(gst_deinterlace2_push_history), (gst_deinterlace2_chain),
(gst_deinterlace2_setcaps), (gst_deinterlace2_src_query):
* gst/deinterlace2/gstdeinterlace2.h:
Include latency of the method in the returned latency.
Fix outputting of all fields, i.e. doubling of the framerate.
This commit is contained in:
Sebastian Dröge 2008-07-05 19:11:56 +00:00 committed by Sebastian Dröge
parent fb7f06ad04
commit 0b9cd418b3
2 changed files with 47 additions and 37 deletions

View file

@ -80,6 +80,14 @@ gst_deinterlace_method_get_fields_required (GstDeinterlaceMethod * self)
return klass->fields_required; return klass->fields_required;
} }
static gint
gst_deinterlace_method_get_latency (GstDeinterlaceMethod * self)
{
GstDeinterlaceMethodClass *klass = GST_DEINTERLACE_METHOD_GET_CLASS (self);
return klass->latency;
}
#define GST_TYPE_DEINTERLACE2_METHODS (gst_deinterlace2_methods_get_type ()) #define GST_TYPE_DEINTERLACE2_METHODS (gst_deinterlace2_methods_get_type ())
static GType static GType
gst_deinterlace2_methods_get_type (void) gst_deinterlace2_methods_get_type (void)
@ -227,10 +235,6 @@ gst_deinterlace2_set_method (GstDeinterlace2 * object,
gst_object_set_parent (GST_OBJECT (object->method), GST_OBJECT (object)); gst_object_set_parent (GST_OBJECT (object->method), GST_OBJECT (object));
gst_child_proxy_child_added (GST_OBJECT (object), gst_child_proxy_child_added (GST_OBJECT (object),
GST_OBJECT (object->method)); GST_OBJECT (object->method));
/* TODO: if current method requires less fields in the history,
pop the diff from field_history.
*/
} }
static void static void
@ -279,7 +283,7 @@ gst_deinterlace2_class_init (GstDeinterlace2Class * klass)
GST_DEINTERLACE2_ALL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS) GST_DEINTERLACE2_ALL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
); );
g_object_class_install_property (gobject_class, ARG_FIELDS, g_object_class_install_property (gobject_class, ARG_FIELD_LAYOUT,
g_param_spec_enum ("tff", g_param_spec_enum ("tff",
"tff", "tff",
"Deinterlace top field first", "Deinterlace top field first",
@ -496,7 +500,6 @@ gst_deinterlace2_push_history (GstDeinterlace2 * object, GstBuffer * buffer)
{ {
int i = 1; int i = 1;
GstClockTime timestamp; GstClockTime timestamp;
GstClockTime field_diff;
g_assert (object->history_count < MAX_FIELD_HISTORY - 2); g_assert (object->history_count < MAX_FIELD_HISTORY - 2);
@ -533,8 +536,8 @@ gst_deinterlace2_push_history (GstDeinterlace2 * object, GstBuffer * buffer)
the timestamp of the buffer equals the first fields timestamp */ the timestamp of the buffer equals the first fields timestamp */
timestamp = GST_BUFFER_TIMESTAMP (buffer); timestamp = GST_BUFFER_TIMESTAMP (buffer);
field_diff = GST_SECOND / (object->frame_rate_d * 2) / object->frame_rate_n; GST_BUFFER_TIMESTAMP (object->field_history[0].buf) =
GST_BUFFER_TIMESTAMP (object->field_history[0].buf) = timestamp + field_diff; timestamp + object->field_duration;
GST_BUFFER_TIMESTAMP (object->field_history[1].buf) = timestamp; GST_BUFFER_TIMESTAMP (object->field_history[1].buf) = timestamp;
object->history_count += 2; object->history_count += 2;
@ -548,16 +551,14 @@ gst_deinterlace2_chain (GstPad * pad, GstBuffer * buf)
GstClockTime timestamp; GstClockTime timestamp;
GstFlowReturn ret = GST_FLOW_OK; GstFlowReturn ret = GST_FLOW_OK;
gint fields_required = 0; gint fields_required = 0;
gint cur_field_idx = 0;
object = GST_DEINTERLACE2 (GST_PAD_PARENT (pad)); object = GST_DEINTERLACE2 (GST_PAD_PARENT (pad));
gst_deinterlace2_push_history (object, buf); gst_deinterlace2_push_history (object, buf);
buf = NULL; buf = NULL;
if (object->method != NULL) { fields_required = gst_deinterlace_method_get_fields_required (object->method);
int cur_field_idx = 0;
fields_required =
gst_deinterlace_method_get_fields_required (object->method);
/* Not enough fields in the history */ /* Not enough fields in the history */
if (object->history_count < fields_required + 1) { if (object->history_count < fields_required + 1) {
@ -566,6 +567,7 @@ gst_deinterlace2_chain (GstPad * pad, GstBuffer * buf)
return GST_FLOW_OK; return GST_FLOW_OK;
} }
while (object->history_count >= fields_required) {
if (object->fields == GST_DEINTERLACE2_ALL) if (object->fields == GST_DEINTERLACE2_ALL)
GST_DEBUG ("All fields"); GST_DEBUG ("All fields");
if (object->fields == GST_DEINTERLACE2_TF) if (object->fields == GST_DEINTERLACE2_TF)
@ -595,11 +597,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_BUFFER_DURATION (object->out_buf) =
GST_SECOND / object->frame_rate_d / object->frame_rate_n;
if (object->fields == GST_DEINTERLACE2_ALL) if (object->fields == GST_DEINTERLACE2_ALL)
GST_BUFFER_DURATION (object->out_buf) = GST_BUFFER_DURATION (object->out_buf) = object->field_duration;
GST_BUFFER_DURATION (object->out_buf) / 2; else
GST_BUFFER_DURATION (object->out_buf) = 2 * object->field_duration;
ret = gst_pad_push (object->srcpad, object->out_buf); ret = gst_pad_push (object->srcpad, object->out_buf);
object->out_buf = NULL; object->out_buf = NULL;
@ -615,6 +616,8 @@ gst_deinterlace2_chain (GstPad * pad, GstBuffer * buf)
} }
cur_field_idx = object->history_count - fields_required; cur_field_idx = object->history_count - fields_required;
if (object->history_count < fields_required)
break;
/* deinterlace bottom_field */ /* deinterlace bottom_field */
if ((object->field_history[cur_field_idx].flags == PICTURE_INTERLACED_BOTTOM if ((object->field_history[cur_field_idx].flags == PICTURE_INTERLACED_BOTTOM
@ -637,11 +640,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_BUFFER_DURATION (object->out_buf) =
GST_SECOND / object->frame_rate_d / object->frame_rate_n;
if (object->fields == GST_DEINTERLACE2_ALL) if (object->fields == GST_DEINTERLACE2_ALL)
GST_BUFFER_DURATION (object->out_buf) = GST_BUFFER_DURATION (object->out_buf) = object->field_duration;
GST_BUFFER_DURATION (object->out_buf) / 2; else
GST_BUFFER_DURATION (object->out_buf) = 2 * object->field_duration;
ret = gst_pad_push (object->srcpad, object->out_buf); ret = gst_pad_push (object->srcpad, object->out_buf);
object->out_buf = NULL; object->out_buf = NULL;
@ -656,13 +658,8 @@ gst_deinterlace2_chain (GstPad * pad, GstBuffer * buf)
buf = gst_deinterlace2_pop_history (object); buf = gst_deinterlace2_pop_history (object);
gst_buffer_unref (buf); gst_buffer_unref (buf);
} }
} else {
object->out_buf = gst_deinterlace2_pop_history (object);
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 ret; return ret;
@ -732,6 +729,15 @@ gst_deinterlace2_setcaps (GstPad * pad, GstCaps * caps)
gst_video_format_get_size (fmt, object->frame_width, gst_video_format_get_size (fmt, object->frame_width,
object->frame_height); object->frame_height);
if (object->fields == GST_DEINTERLACE2_ALL && otherpad == object->srcpad)
object->field_duration =
gst_util_uint64_scale (GST_SECOND, object->frame_rate_d,
object->frame_rate_n);
else
object->field_duration =
gst_util_uint64_scale (GST_SECOND, object->frame_rate_d,
2 * object->frame_rate_n);
GST_DEBUG_OBJECT (object, "Set caps: %" GST_PTR_FORMAT, caps); GST_DEBUG_OBJECT (object, "Set caps: %" GST_PTR_FORMAT, caps);
done: done:
@ -848,10 +854,14 @@ gst_deinterlace2_src_query (GstPad * pad, GstQuery * query)
if ((res = gst_pad_query (peer, query))) { if ((res = gst_pad_query (peer, query))) {
GstClockTime latency; GstClockTime latency;
gint fields_required = 0; gint fields_required = 0;
gint method_latency = 0;
if (object->method) if (object->method) {
fields_required = fields_required =
gst_deinterlace_method_get_fields_required (object->method); gst_deinterlace_method_get_fields_required (object->method);
method_latency =
gst_deinterlace_method_get_latency (object->method);
}
gst_query_parse_latency (query, &live, &min, &max); gst_query_parse_latency (query, &live, &min, &max);
@ -860,10 +870,7 @@ gst_deinterlace2_src_query (GstPad * pad, GstQuery * query)
GST_TIME_ARGS (min), GST_TIME_ARGS (max)); GST_TIME_ARGS (min), GST_TIME_ARGS (max));
/* add our own latency */ /* add our own latency */
latency = latency = (fields_required + method_latency) * object->field_duration;
gst_util_uint64_scale (fields_required *
GST_SECOND, object->frame_rate_d, object->frame_rate_n);
latency /= 2;
GST_DEBUG ("Our latency: min %" GST_TIME_FORMAT GST_DEBUG ("Our latency: min %" GST_TIME_FORMAT
", max %" GST_TIME_FORMAT, ", max %" GST_TIME_FORMAT,

View file

@ -129,6 +129,9 @@ struct _GstDeinterlace2
guint frame_size; guint frame_size;
gint frame_rate_n, frame_rate_d; gint frame_rate_n, frame_rate_d;
/* Duration of one field */
GstClockTime field_duration;
GstDeinterlace2Fields fields; GstDeinterlace2Fields fields;
GstDeinterlace2Methods method_id; GstDeinterlace2Methods method_id;