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.
This commit is contained in:
Sebastian Dröge 2016-09-12 20:08:36 +02:00
parent 22d6c7f106
commit dba90631bc

View file

@ -1081,7 +1081,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;
@ -1151,6 +1151,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;
@ -1283,6 +1290,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)
@ -1742,11 +1750,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)),
@ -1884,7 +1897,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;
@ -2747,7 +2763,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;
}