mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-19 14:56:36 +00:00
deinterlace2: Implement support for RFF and ONEFIELD buffer flags
This commit is contained in:
parent
e01373662a
commit
ffaef58b59
1 changed files with 54 additions and 22 deletions
|
@ -688,51 +688,83 @@ gst_deinterlace2_push_history (GstDeinterlace2 * self, GstBuffer * buffer)
|
|||
int i = 1;
|
||||
GstClockTime timestamp;
|
||||
GstDeinterlace2FieldLayout field_layout = self->field_layout;
|
||||
gboolean repeated = GST_BUFFER_FLAG_IS_SET (buffer, GST_VIDEO_BUFFER_RFF);
|
||||
gboolean tff = GST_BUFFER_FLAG_IS_SET (buffer, GST_VIDEO_BUFFER_TFF);
|
||||
gboolean onefield =
|
||||
GST_BUFFER_FLAG_IS_SET (buffer, GST_VIDEO_BUFFER_ONEFIELD);
|
||||
GstBuffer *field1, *field2;
|
||||
guint fields_to_push = (onefield) ? 1 : (!repeated) ? 2 : 3;
|
||||
gint field1_flags, field2_flags;
|
||||
|
||||
g_assert (self->history_count < MAX_FIELD_HISTORY - 2);
|
||||
g_assert (self->history_count < MAX_FIELD_HISTORY - fields_to_push);
|
||||
|
||||
for (i = MAX_FIELD_HISTORY - 1; i >= 2; i--) {
|
||||
self->field_history[i].buf = self->field_history[i - 2].buf;
|
||||
self->field_history[i].flags = self->field_history[i - 2].flags;
|
||||
for (i = MAX_FIELD_HISTORY - 1; i >= fields_to_push; i--) {
|
||||
self->field_history[i].buf = self->field_history[i - fields_to_push].buf;
|
||||
self->field_history[i].flags =
|
||||
self->field_history[i - fields_to_push].flags;
|
||||
}
|
||||
|
||||
if (field_layout == GST_DEINTERLACE2_LAYOUT_AUTO) {
|
||||
if (!self->interlaced
|
||||
|| GST_BUFFER_FLAG_IS_SET (buffer, GST_VIDEO_BUFFER_TFF))
|
||||
if (!self->interlaced) {
|
||||
GST_WARNING_OBJECT (self, "Can't detect field layout -- assuming TFF");
|
||||
field_layout = GST_DEINTERLACE2_LAYOUT_TFF;
|
||||
else
|
||||
} else if (tff) {
|
||||
field_layout = GST_DEINTERLACE2_LAYOUT_TFF;
|
||||
} else {
|
||||
field_layout = GST_DEINTERLACE2_LAYOUT_BFF;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (field_layout == GST_DEINTERLACE2_LAYOUT_TFF) {
|
||||
GST_DEBUG ("Top field first");
|
||||
self->field_history[0].buf =
|
||||
gst_buffer_create_sub (buffer, self->line_length,
|
||||
field1 = gst_buffer_ref (buffer);
|
||||
field1_flags = PICTURE_INTERLACED_TOP;
|
||||
field2 = gst_buffer_create_sub (buffer, self->line_length,
|
||||
GST_BUFFER_SIZE (buffer) - self->line_length);
|
||||
self->field_history[0].flags = PICTURE_INTERLACED_BOTTOM;
|
||||
self->field_history[1].buf = buffer;
|
||||
self->field_history[1].flags = PICTURE_INTERLACED_TOP;
|
||||
field2_flags = PICTURE_INTERLACED_BOTTOM;
|
||||
} else {
|
||||
GST_DEBUG ("Bottom field first");
|
||||
self->field_history[0].buf = buffer;
|
||||
self->field_history[0].flags = PICTURE_INTERLACED_TOP;
|
||||
self->field_history[1].buf =
|
||||
gst_buffer_create_sub (buffer, self->line_length,
|
||||
field1 = gst_buffer_create_sub (buffer, self->line_length,
|
||||
GST_BUFFER_SIZE (buffer) - self->line_length);
|
||||
self->field_history[1].flags = PICTURE_INTERLACED_BOTTOM;
|
||||
field1_flags = PICTURE_INTERLACED_BOTTOM;
|
||||
field2 = gst_buffer_ref (buffer);
|
||||
field2_flags = PICTURE_INTERLACED_TOP;
|
||||
}
|
||||
|
||||
/* Timestamps are assigned to the field buffers under the assumption that
|
||||
the timestamp of the buffer equals the first fields timestamp */
|
||||
|
||||
timestamp = GST_BUFFER_TIMESTAMP (buffer);
|
||||
GST_BUFFER_TIMESTAMP (self->field_history[0].buf) =
|
||||
timestamp + self->field_duration;
|
||||
GST_BUFFER_TIMESTAMP (self->field_history[1].buf) = timestamp;
|
||||
if (repeated) {
|
||||
GST_BUFFER_TIMESTAMP (field1) = timestamp;
|
||||
GST_BUFFER_TIMESTAMP (field2) = timestamp + 2 * self->field_duration;
|
||||
} else {
|
||||
GST_BUFFER_TIMESTAMP (field1) = timestamp;
|
||||
GST_BUFFER_TIMESTAMP (field2) = timestamp + self->field_duration;
|
||||
}
|
||||
|
||||
self->history_count += 2;
|
||||
if (repeated) {
|
||||
self->field_history[0].buf = field2;
|
||||
self->field_history[0].flags = field2_flags;
|
||||
self->field_history[1].buf = gst_buffer_ref (field1);
|
||||
self->field_history[1].flags = field1_flags;
|
||||
self->field_history[2].buf = field1;
|
||||
self->field_history[2].flags = field1_flags;
|
||||
} else if (!onefield) {
|
||||
self->field_history[0].buf = field2;
|
||||
self->field_history[0].flags = field2_flags;
|
||||
self->field_history[1].buf = field1;
|
||||
self->field_history[1].flags = field1_flags;
|
||||
} else { /* onefield */
|
||||
self->field_history[0].buf = field1;
|
||||
self->field_history[0].flags = field1_flags;
|
||||
gst_buffer_unref (field2);
|
||||
}
|
||||
|
||||
self->history_count += fields_to_push;
|
||||
GST_DEBUG ("push, size(history): %d", self->history_count);
|
||||
|
||||
gst_buffer_unref (buffer);
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
|
|
Loading…
Reference in a new issue