Commit dba90631 authored by Sebastian Dröge's avatar Sebastian Dröge
Browse files

deinterlace: Fix field ordering for reverse playback

And actually calculate the field duration instead of a frame duration so
that we can properly timestamp output frames in fields=all mode.

This is probably still broken for reverse playback in telecine mode.
parent 22d6c7f1
...@@ -1081,7 +1081,7 @@ gst_deinterlace_push_history (GstDeinterlace * self, GstBuffer * buffer) ...@@ -1081,7 +1081,7 @@ gst_deinterlace_push_history (GstDeinterlace * self, GstBuffer * buffer)
GstVideoFrame *frame = NULL; GstVideoFrame *frame = NULL;
GstVideoFrame *field1, *field2 = NULL; GstVideoFrame *field1, *field2 = NULL;
guint fields_to_push; guint fields_to_push;
gint field1_flags, field2_flags; guint field1_flags, field2_flags;
GstVideoInterlaceMode interlacing_mode; GstVideoInterlaceMode interlacing_mode;
guint8 buf_state; guint8 buf_state;
...@@ -1151,6 +1151,13 @@ gst_deinterlace_push_history (GstDeinterlace * self, GstBuffer * buffer) ...@@ -1151,6 +1151,13 @@ gst_deinterlace_push_history (GstDeinterlace * self, GstBuffer * buffer)
field2_flags = PICTURE_INTERLACED_TOP; field2_flags = PICTURE_INTERLACED_TOP;
} }
/* Swap for reverse playback */
if (self->segment.rate < 0) {
field1_flags = field1_flags ^ field2_flags;
field2_flags = field1_flags ^ field2_flags;
field1_flags = field1_flags ^ field2_flags;
}
if (!onefield) { if (!onefield) {
GST_DEBUG_OBJECT (self, "Two fields"); GST_DEBUG_OBJECT (self, "Two fields");
self->field_history[1].frame = field1; self->field_history[1].frame = field1;
...@@ -1283,6 +1290,7 @@ gst_deinterlace_fix_timestamps (GstDeinterlace * self, ...@@ -1283,6 +1290,7 @@ gst_deinterlace_fix_timestamps (GstDeinterlace * self,
GstVideoFrame *field3, *field4; GstVideoFrame *field3, *field4;
GstVideoInterlaceMode interlacing_mode; GstVideoInterlaceMode interlacing_mode;
/* FIXME: This is broken for rate < 0 */
if (self->pattern_lock && self->pattern > -1) { if (self->pattern_lock && self->pattern > -1) {
/* accurate pattern-locked timestamp adjustment */ /* accurate pattern-locked timestamp adjustment */
if (!self->pattern_count) if (!self->pattern_count)
...@@ -1742,11 +1750,16 @@ restart: ...@@ -1742,11 +1750,16 @@ restart:
if (!IS_TELECINE (interlacing_mode)) { if (!IS_TELECINE (interlacing_mode)) {
timestamp = GST_BUFFER_TIMESTAMP (buf); timestamp = GST_BUFFER_TIMESTAMP (buf);
GST_BUFFER_TIMESTAMP (outbuf) = timestamp; if (self->fields == GST_DEINTERLACE_ALL) {
if (self->fields == GST_DEINTERLACE_ALL) if (self->segment.rate < 0)
GST_BUFFER_TIMESTAMP (outbuf) = timestamp + self->field_duration;
else
GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
GST_BUFFER_DURATION (outbuf) = self->field_duration; GST_BUFFER_DURATION (outbuf) = self->field_duration;
else } else {
GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
GST_BUFFER_DURATION (outbuf) = 2 * self->field_duration; GST_BUFFER_DURATION (outbuf) = 2 * self->field_duration;
}
GST_DEBUG_OBJECT (self, GST_DEBUG_OBJECT (self,
"[ADJUST] ts %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT ", end %" "[ADJUST] ts %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT ", end %"
GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)), GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
...@@ -1884,7 +1897,10 @@ restart: ...@@ -1884,7 +1897,10 @@ restart:
timestamp = GST_BUFFER_TIMESTAMP (buf); timestamp = GST_BUFFER_TIMESTAMP (buf);
if (self->fields == GST_DEINTERLACE_ALL) { if (self->fields == GST_DEINTERLACE_ALL) {
GST_BUFFER_TIMESTAMP (outbuf) = timestamp + self->field_duration; if (self->segment.rate < 0)
GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
else
GST_BUFFER_TIMESTAMP (outbuf) = timestamp + self->field_duration;
GST_BUFFER_DURATION (outbuf) = self->field_duration; GST_BUFFER_DURATION (outbuf) = self->field_duration;
} else { } else {
GST_BUFFER_TIMESTAMP (outbuf) = timestamp; GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
...@@ -2747,7 +2763,7 @@ gst_deinterlace_setcaps (GstDeinterlace * self, GstPad * pad, GstCaps * caps) ...@@ -2747,7 +2763,7 @@ gst_deinterlace_setcaps (GstDeinterlace * self, GstPad * pad, GstCaps * caps)
} }
if (fps_n != 0) { if (fps_n != 0) {
self->field_duration = gst_util_uint64_scale (GST_SECOND, fps_d, fps_n); self->field_duration = gst_util_uint64_scale (GST_SECOND, fps_d, 2 * fps_n);
} else { } else {
self->field_duration = 0; self->field_duration = 0;
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment