mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-30 21:51:09 +00:00
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:
parent
22d6c7f106
commit
dba90631bc
1 changed files with 22 additions and 6 deletions
|
@ -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)
|
||||||
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,
|
||||||
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:
|
||||||
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_DURATION (outbuf) = self->field_duration;
|
GST_BUFFER_TIMESTAMP (outbuf) = timestamp + self->field_duration;
|
||||||
else
|
else
|
||||||
|
GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
|
||||||
|
GST_BUFFER_DURATION (outbuf) = self->field_duration;
|
||||||
|
} 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,6 +1897,9 @@ restart:
|
||||||
timestamp = GST_BUFFER_TIMESTAMP (buf);
|
timestamp = GST_BUFFER_TIMESTAMP (buf);
|
||||||
|
|
||||||
if (self->fields == GST_DEINTERLACE_ALL) {
|
if (self->fields == GST_DEINTERLACE_ALL) {
|
||||||
|
if (self->segment.rate < 0)
|
||||||
|
GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
|
||||||
|
else
|
||||||
GST_BUFFER_TIMESTAMP (outbuf) = timestamp + self->field_duration;
|
GST_BUFFER_TIMESTAMP (outbuf) = timestamp + self->field_duration;
|
||||||
GST_BUFFER_DURATION (outbuf) = self->field_duration;
|
GST_BUFFER_DURATION (outbuf) = self->field_duration;
|
||||||
} else {
|
} else {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue