deinterlace: Fix telecine

This only affects behaviour in telecine cases with pattern locking
enabled. The default case should be untouched.

This works with the output from fieldanalysis at least, but the field
order looks swapped for telecine mixed buffers with the
David_slides_Schleef clip.
This commit is contained in:
Robert Swain 2012-09-25 10:41:44 +02:00
parent e39fd693d7
commit 33dd81569f

View file

@ -1710,7 +1710,8 @@ restart:
if ((self->field_history[self->cur_field_idx].flags == PICTURE_INTERLACED_TOP
&& (self->fields == GST_DEINTERLACE_TF
|| IS_TELECINE (interlacing_mode)))
|| self->fields == GST_DEINTERLACE_ALL) {
|| (self->fields == GST_DEINTERLACE_ALL
&& !IS_TELECINE (interlacing_mode))) {
GST_DEBUG_OBJECT (self, "deinterlacing top field");
/* create new buffer */
@ -1740,8 +1741,10 @@ restart:
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf) +
GST_BUFFER_DURATION (outbuf)));
} else {
GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buf);
GST_BUFFER_TIMESTAMP (outbuf) =
GST_BUFFER_TIMESTAMP (field1->frame->buffer);
GST_BUFFER_DURATION (outbuf) =
GST_BUFFER_DURATION (field1->frame->buffer);
}
/* Check if we need to drop the frame because of QoS */
@ -1779,9 +1782,12 @@ restart:
gst_video_frame_unmap_and_free (outframe);
self->cur_field_idx--;
if (self->cur_field_idx + 1 +
gst_deinterlace_method_get_latency (self->method)
< self->history_count || flushing) {
/* need to remove the field in the telecine weaving case */
if ((IS_TELECINE (interlacing_mode)
&& self->method_id == GST_DEINTERLACE_WEAVE)
|| self->cur_field_idx + 1 +
gst_deinterlace_method_get_latency (self->method) <
self->history_count || flushing) {
gst_video_frame_unmap_and_free (gst_deinterlace_pop_history (self));
}
@ -1801,7 +1807,7 @@ restart:
outbuf = NULL;
if (ret != GST_FLOW_OK)
return ret;
if (interlacing_mode == GST_VIDEO_INTERLACE_MODE_MIXED
if (IS_TELECINE (interlacing_mode)
&& self->method_id == GST_DEINTERLACE_WEAVE) {
/* pop off the second field */
GST_DEBUG_OBJECT (self, "Removing unused field (count: %d)",
@ -1842,7 +1848,8 @@ restart:
if ((self->field_history[self->cur_field_idx].flags ==
PICTURE_INTERLACED_BOTTOM && (self->fields == GST_DEINTERLACE_BF
|| IS_TELECINE (interlacing_mode)))
|| self->fields == GST_DEINTERLACE_ALL) {
|| (self->fields == GST_DEINTERLACE_ALL
&& !IS_TELECINE (interlacing_mode))) {
GST_DEBUG_OBJECT (self, "deinterlacing bottom field");
/* create new buffer */
@ -1873,8 +1880,10 @@ restart:
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf) +
GST_BUFFER_DURATION (outbuf)));
} else {
GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buf);
GST_BUFFER_TIMESTAMP (outbuf) =
GST_BUFFER_TIMESTAMP (field1->frame->buffer);
GST_BUFFER_DURATION (outbuf) =
GST_BUFFER_DURATION (field1->frame->buffer);
}
/* Check if we need to drop the frame because of QoS */
@ -1898,9 +1907,12 @@ restart:
gst_video_frame_unmap_and_free (outframe);
self->cur_field_idx--;
if (self->cur_field_idx + 1 +
gst_deinterlace_method_get_latency (self->method)
< self->history_count) {
/* need to remove the field in the telecine weaving case */
if ((IS_TELECINE (interlacing_mode)
&& self->method_id == GST_DEINTERLACE_WEAVE)
|| self->cur_field_idx + 1 +
gst_deinterlace_method_get_latency (self->method) <
self->history_count) {
gst_video_frame_unmap_and_free (gst_deinterlace_pop_history (self));
}
@ -1920,7 +1932,7 @@ restart:
outbuf = NULL;
if (ret != GST_FLOW_OK)
return ret;
if (interlacing_mode == GST_VIDEO_INTERLACE_MODE_MIXED
if (IS_TELECINE (interlacing_mode)
&& self->method_id == GST_DEINTERLACE_WEAVE) {
/* pop off the second field */
GST_DEBUG_OBJECT (self, "Removing unused field (count: %d)",