mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 17:50:36 +00:00
invtelecine: Add 4:2:2 formats
This commit is contained in:
parent
750cdc912b
commit
c439a6bc36
1 changed files with 92 additions and 45 deletions
|
@ -92,7 +92,7 @@ static GstStaticPadTemplate gst_invtelecine_src_template =
|
||||||
GST_STATIC_PAD_TEMPLATE ("src",
|
GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
GST_PAD_SRC,
|
GST_PAD_SRC,
|
||||||
GST_PAD_ALWAYS,
|
GST_PAD_ALWAYS,
|
||||||
GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420")
|
GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("{YUY2,UYVY,I420,YV12}")
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ static GstStaticPadTemplate gst_invtelecine_sink_template =
|
||||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
GST_PAD_SINK,
|
GST_PAD_SINK,
|
||||||
GST_PAD_ALWAYS,
|
GST_PAD_ALWAYS,
|
||||||
GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420")
|
GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("{YUY2,UYVY,I420,YV12}")
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -270,23 +270,52 @@ gst_invtelecine_compare_fields (GstInvtelecine * invtelecine, int field1,
|
||||||
if (j == 0 || j == invtelecine->height - 1)
|
if (j == 0 || j == invtelecine->height - 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
data1 = GST_BUFFER_DATA (invtelecine->fifo[field1].buffer) +
|
if (invtelecine->format == GST_VIDEO_FORMAT_I420 ||
|
||||||
invtelecine->width * j;
|
invtelecine->format == GST_VIDEO_FORMAT_YV12) {
|
||||||
data2_1 =
|
data1 = GST_BUFFER_DATA (invtelecine->fifo[field1].buffer) +
|
||||||
GST_BUFFER_DATA (invtelecine->fifo[field2].buffer) +
|
invtelecine->width * j;
|
||||||
invtelecine->width * (j - 1);
|
data2_1 =
|
||||||
data2_2 =
|
GST_BUFFER_DATA (invtelecine->fifo[field2].buffer) +
|
||||||
GST_BUFFER_DATA (invtelecine->fifo[field2].buffer) +
|
invtelecine->width * (j - 1);
|
||||||
invtelecine->width * (j + 1);
|
data2_2 =
|
||||||
|
GST_BUFFER_DATA (invtelecine->fifo[field2].buffer) +
|
||||||
|
invtelecine->width * (j + 1);
|
||||||
|
|
||||||
linesum = 0;
|
/* planar 4:2:0 */
|
||||||
for (i = 1; i < invtelecine->width - 1; i++) {
|
linesum = 0;
|
||||||
have = data1[i - 1] + data1[i + 1];
|
for (i = 1; i < invtelecine->width - 1; i++) {
|
||||||
hdiff = abs (data1[i - 1] - data1[i + 1]);
|
have = data1[i - 1] + data1[i + 1];
|
||||||
vave = data2_1[i] + data2_2[i];
|
hdiff = abs (data1[i - 1] - data1[i + 1]);
|
||||||
vdiff = abs (data2_1[i] - data2_2[i]);
|
vave = data2_1[i] + data2_2[i];
|
||||||
den = MAX (1, MAX (hdiff, vdiff));
|
vdiff = abs (data2_1[i] - data2_2[i]);
|
||||||
linesum += (have - vave) * (have - vave) / (den * den);
|
den = MAX (1, MAX (hdiff, vdiff));
|
||||||
|
linesum += (have - vave) * (have - vave) / (den * den);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
data1 = GST_BUFFER_DATA (invtelecine->fifo[field1].buffer) +
|
||||||
|
invtelecine->width * 2 * j;
|
||||||
|
data2_1 =
|
||||||
|
GST_BUFFER_DATA (invtelecine->fifo[field2].buffer) +
|
||||||
|
invtelecine->width * 2 * (j - 1);
|
||||||
|
data2_2 =
|
||||||
|
GST_BUFFER_DATA (invtelecine->fifo[field2].buffer) +
|
||||||
|
invtelecine->width * 2 * (j + 1);
|
||||||
|
if (invtelecine->format == GST_VIDEO_FORMAT_UYVY) {
|
||||||
|
data1++;
|
||||||
|
data2_1++;
|
||||||
|
data2_2++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* packed 4:2:2 */
|
||||||
|
linesum = 0;
|
||||||
|
for (i = 1; i < invtelecine->width - 1; i++) {
|
||||||
|
have = data1[(i - 1) * 2] + data1[(i + 1) * 2];
|
||||||
|
hdiff = abs (data1[(i - 1) * 2] - data1[(i + 1) * 2]);
|
||||||
|
vave = data2_1[i * 2] + data2_2[i * 2];
|
||||||
|
vdiff = abs (data2_1[i * 2] - data2_2[i * 2]);
|
||||||
|
den = MAX (1, MAX (hdiff, vdiff));
|
||||||
|
linesum += (have - vave) * (have - vave) / (den * den);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sum += linesum;
|
sum += linesum;
|
||||||
}
|
}
|
||||||
|
@ -669,31 +698,44 @@ gst_invtelecine_process (GstInvtelecine * invtelecine, gboolean flush)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
copy_field (GstBuffer * d, GstBuffer * s, int field_index, int width,
|
copy_field (GstInvtelecine * invtelecine, GstBuffer * d, GstBuffer * s,
|
||||||
int height)
|
int field_index)
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
guint8 *dest;
|
guint8 *dest;
|
||||||
guint8 *src;
|
guint8 *src;
|
||||||
|
int width = invtelecine->width;
|
||||||
|
int height = invtelecine->height;
|
||||||
|
|
||||||
for (j = field_index; j < height; j += 2) {
|
if (invtelecine->format == GST_VIDEO_FORMAT_I420 ||
|
||||||
dest = GST_BUFFER_DATA (d) + j * width;
|
invtelecine->format == GST_VIDEO_FORMAT_YV12) {
|
||||||
src = GST_BUFFER_DATA (s) + j * width;
|
/* planar 4:2:0 */
|
||||||
memcpy (dest, src, width);
|
for (j = field_index; j < height; j += 2) {
|
||||||
}
|
dest = GST_BUFFER_DATA (d) + j * width;
|
||||||
for (j = field_index; j < height / 2; j += 2) {
|
src = GST_BUFFER_DATA (s) + j * width;
|
||||||
dest = GST_BUFFER_DATA (d) + width * height + j * width / 2;
|
memcpy (dest, src, width);
|
||||||
src = GST_BUFFER_DATA (s) + width * height + j * width / 2;
|
}
|
||||||
memcpy (dest, src, width / 2);
|
for (j = field_index; j < height / 2; j += 2) {
|
||||||
}
|
dest = GST_BUFFER_DATA (d) + width * height + j * width / 2;
|
||||||
for (j = field_index; j < height / 2; j += 2) {
|
src = GST_BUFFER_DATA (s) + width * height + j * width / 2;
|
||||||
dest =
|
memcpy (dest, src, width / 2);
|
||||||
GST_BUFFER_DATA (d) + width * height + width / 2 * height / 2 +
|
}
|
||||||
j * width / 2;
|
for (j = field_index; j < height / 2; j += 2) {
|
||||||
src =
|
dest =
|
||||||
GST_BUFFER_DATA (s) + width * height + width / 2 * height / 2 +
|
GST_BUFFER_DATA (d) + width * height + width / 2 * height / 2 +
|
||||||
j * width / 2;
|
j * width / 2;
|
||||||
memcpy (dest, src, width / 2);
|
src =
|
||||||
|
GST_BUFFER_DATA (s) + width * height + width / 2 * height / 2 +
|
||||||
|
j * width / 2;
|
||||||
|
memcpy (dest, src, width / 2);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* packed 4:2:2 */
|
||||||
|
for (j = field_index; j < height; j += 2) {
|
||||||
|
dest = GST_BUFFER_DATA (d) + j * width * 2;
|
||||||
|
src = GST_BUFFER_DATA (s) + j * width * 2;
|
||||||
|
memcpy (dest, src, width * 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -705,14 +747,19 @@ gst_invtelecine_output_fields (GstInvtelecine * invtelecine, int num_fields)
|
||||||
|
|
||||||
field_index = invtelecine->fifo[0].field_index;
|
field_index = invtelecine->fifo[0].field_index;
|
||||||
|
|
||||||
buffer =
|
if (invtelecine->format == GST_VIDEO_FORMAT_I420 ||
|
||||||
gst_buffer_new_and_alloc (invtelecine->width * invtelecine->height * 3 /
|
invtelecine->format == GST_VIDEO_FORMAT_YV12) {
|
||||||
2);
|
buffer =
|
||||||
|
gst_buffer_new_and_alloc (invtelecine->width * invtelecine->height * 3 /
|
||||||
|
2);
|
||||||
|
} else {
|
||||||
|
buffer =
|
||||||
|
gst_buffer_new_and_alloc (invtelecine->width * invtelecine->height * 2);
|
||||||
|
}
|
||||||
|
|
||||||
copy_field (buffer, invtelecine->fifo[0].buffer, field_index,
|
copy_field (invtelecine, buffer, invtelecine->fifo[0].buffer, field_index);
|
||||||
invtelecine->width, invtelecine->height);
|
copy_field (invtelecine, buffer, invtelecine->fifo[1].buffer,
|
||||||
copy_field (buffer, invtelecine->fifo[1].buffer, field_index ^ 1,
|
field_index ^ 1);
|
||||||
invtelecine->width, invtelecine->height);
|
|
||||||
|
|
||||||
gst_buffer_set_caps (buffer, GST_BUFFER_CAPS (invtelecine->fifo[0].buffer));
|
gst_buffer_set_caps (buffer, GST_BUFFER_CAPS (invtelecine->fifo[0].buffer));
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue