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