diff options
author | Sebastian Dröge <sebastian@centricular.com> | 2016-09-12 20:08:36 +0200 |
---|---|---|
committer | Sebastian Dröge <sebastian@centricular.com> | 2016-09-30 13:44:57 +0300 |
commit | aea184359307d62e44597f93ba4af0ce29abde26 (patch) | |
tree | 79e81bc951e954d40e54a08a590aad3e8c212c69 | |
parent | 59085d948aab662a9bfef9ba0c7d646799a84f7e (diff) |
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.
-rw-r--r-- | gst/deinterlace/gstdeinterlace.c | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/gst/deinterlace/gstdeinterlace.c b/gst/deinterlace/gstdeinterlace.c index 6e0589352..c2a31a8c2 100644 --- a/gst/deinterlace/gstdeinterlace.c +++ b/gst/deinterlace/gstdeinterlace.c @@ -1074,7 +1074,7 @@ gst_deinterlace_push_history (GstDeinterlace * self, GstBuffer * buffer) GstVideoFrame *frame = NULL; GstVideoFrame *field1, *field2 = NULL; guint fields_to_push; - gint field1_flags, field2_flags; + guint field1_flags, field2_flags; GstVideoInterlaceMode interlacing_mode; guint8 buf_state; @@ -1144,6 +1144,13 @@ gst_deinterlace_push_history (GstDeinterlace * self, GstBuffer * buffer) 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) { GST_DEBUG_OBJECT (self, "Two fields"); self->field_history[1].frame = field1; @@ -1276,6 +1283,7 @@ gst_deinterlace_fix_timestamps (GstDeinterlace * self, GstVideoFrame *field3, *field4; GstVideoInterlaceMode interlacing_mode; + /* FIXME: This is broken for rate < 0 */ if (self->pattern_lock && self->pattern > -1) { /* accurate pattern-locked timestamp adjustment */ if (!self->pattern_count) @@ -1731,11 +1739,16 @@ restart: if (!IS_TELECINE (interlacing_mode)) { 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; - else + } else { + GST_BUFFER_TIMESTAMP (outbuf) = timestamp; GST_BUFFER_DURATION (outbuf) = 2 * self->field_duration; + } GST_DEBUG_OBJECT (self, "[ADJUST] ts %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT ", end %" GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)), @@ -1869,7 +1882,10 @@ restart: timestamp = GST_BUFFER_TIMESTAMP (buf); 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; } else { GST_BUFFER_TIMESTAMP (outbuf) = timestamp; @@ -2683,7 +2699,7 @@ gst_deinterlace_setcaps (GstDeinterlace * self, GstPad * pad, GstCaps * caps) } 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 { self->field_duration = 0; } |