imperxsdi: add direct conversion to v210 pixel format
This matches the decklink plugin format.
This commit is contained in:
parent
995bcca23b
commit
0fc4bc182c
@ -89,7 +89,7 @@ static GstStaticPadTemplate gst_imperxsdisrc_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_MAKE ("{ AYUV64, YUY2, BGR }"))
|
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ v210, AYUV64, YUY2, BGR }"))
|
||||||
);
|
);
|
||||||
|
|
||||||
/* class initialization */
|
/* class initialization */
|
||||||
@ -464,6 +464,45 @@ unpack_YVYU10 (gpointer dest, const gpointer data,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
repack_YVYU10_to_v210 (gpointer dest, const gpointer data,
|
||||||
|
const gint stride, gint x, gint y, gint width)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const guint8 *restrict s = (guint8 *) (data) + stride * y;
|
||||||
|
guint32 *restrict d = (guint32 *) dest;
|
||||||
|
guint32 a0, a1, a2, a3;
|
||||||
|
guint16 y0, y1, y2, y3, y4, y5;
|
||||||
|
guint16 u0, u2, u4;
|
||||||
|
guint16 v0, v2, v4;
|
||||||
|
|
||||||
|
s += x * 2;
|
||||||
|
for (i = 0; i < width; i += 4) {
|
||||||
|
a0 = GST_READ_UINT32_LE (s + (i / 4) * 16 + 0);
|
||||||
|
a1 = GST_READ_UINT32_LE (s + (i / 4) * 16 + 4);
|
||||||
|
a2 = GST_READ_UINT32_LE (s + (i / 4) * 16 + 8);
|
||||||
|
a3 = GST_READ_UINT32_LE (s + (i / 4) * 16 + 12);
|
||||||
|
|
||||||
|
y0 = ((a0 >> 0) & 0x3ff);
|
||||||
|
u0 = ((a0 >> 10) & 0x3ff);
|
||||||
|
y1 = ((a0 >> 20) & 0x3ff);
|
||||||
|
v0 = (((a0 >> 30) | (a1 << 2)) & 0x3ff);
|
||||||
|
y2 = ((a1 >> 8) & 0x3ff);
|
||||||
|
u2 = ((a1 >> 18) & 0x3ff);
|
||||||
|
|
||||||
|
y3 = ((a2 >> 0) & 0x3ff);
|
||||||
|
v2 = ((a2 >> 10) & 0x3ff);
|
||||||
|
y4 = ((a2 >> 20) & 0x3ff);
|
||||||
|
u4 = (((a2 >> 30) | (a3 << 2)) & 0x3ff);
|
||||||
|
y5 = ((a3 >> 8) & 0x3ff);
|
||||||
|
v4 = ((a3 >> 18) & 0x3ff);
|
||||||
|
|
||||||
|
d[i + 0] = (v0 << 20) | (y0 << 10) | u0;
|
||||||
|
d[i + 1] = (y2 << 20) | (u2 << 10) | y1;
|
||||||
|
d[i + 2] = (u4 << 20) | (y3 << 10) | v2;
|
||||||
|
d[i + 3] = (y5 << 20) | (v4 << 10) | y4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static GstBuffer *
|
static GstBuffer *
|
||||||
gst_imperxsdisrc_create_buffer_from_frameinfo (GstImperxSdiSrc * src,
|
gst_imperxsdisrc_create_buffer_from_frameinfo (GstImperxSdiSrc * src,
|
||||||
@ -473,7 +512,8 @@ gst_imperxsdisrc_create_buffer_from_frameinfo (GstImperxSdiSrc * src,
|
|||||||
GstBuffer *buf;
|
GstBuffer *buf;
|
||||||
int buffer_size;
|
int buffer_size;
|
||||||
|
|
||||||
if (src->is_interlaced && src->format != GST_VIDEO_FORMAT_AYUV64) {
|
if (src->is_interlaced
|
||||||
|
&& src->camera_data.Format != VCESDI_OutputFormat_YCrCb10) {
|
||||||
VCESDI_Decode (&src->camera_data, NULL, NULL, &src->imperx_stride,
|
VCESDI_Decode (&src->camera_data, NULL, NULL, &src->imperx_stride,
|
||||||
src->camera_data.Format, NULL, NULL);
|
src->camera_data.Format, NULL, NULL);
|
||||||
buffer_size = src->camera_data.CameraStatus.Height * src->imperx_stride;
|
buffer_size = src->camera_data.CameraStatus.Height * src->imperx_stride;
|
||||||
@ -490,7 +530,8 @@ gst_imperxsdisrc_create_buffer_from_frameinfo (GstImperxSdiSrc * src,
|
|||||||
pFrameInfo->bufferSize, src->imperx_stride, minfo.size, src->gst_stride,
|
pFrameInfo->bufferSize, src->imperx_stride, minfo.size, src->gst_stride,
|
||||||
pFrameInfo->number, pFrameInfo->timestamp);
|
pFrameInfo->number, pFrameInfo->timestamp);
|
||||||
|
|
||||||
if (src->is_interlaced && src->format != GST_VIDEO_FORMAT_AYUV64) {
|
if (src->is_interlaced
|
||||||
|
&& src->camera_data.Format != VCESDI_OutputFormat_YCrCb10) {
|
||||||
VCESDI_Decode (&src->camera_data, pFrameInfo->lpRawBuffer, minfo.data,
|
VCESDI_Decode (&src->camera_data, pFrameInfo->lpRawBuffer, minfo.data,
|
||||||
&src->imperx_stride, src->camera_data.Format, NULL, NULL);
|
&src->imperx_stride, src->camera_data.Format, NULL, NULL);
|
||||||
} else {
|
} else {
|
||||||
@ -512,6 +553,24 @@ gst_imperxsdisrc_create_buffer_from_frameinfo (GstImperxSdiSrc * src,
|
|||||||
pFrameInfo->lpRawBuffer, src->imperx_stride, 0, row, src->width);
|
pFrameInfo->lpRawBuffer, src->imperx_stride, 0, row, src->width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (src->format == GST_VIDEO_FORMAT_v210) {
|
||||||
|
gint row;
|
||||||
|
if (src->is_interlaced) {
|
||||||
|
gint hh = src->height / 2;
|
||||||
|
/* assumes even number of rows, which is the case for all formats */
|
||||||
|
for (row = 0; row < hh; row++) {
|
||||||
|
repack_YVYU10_to_v210 (minfo.data + src->gst_stride * (row * 2),
|
||||||
|
pFrameInfo->lpRawBuffer, src->imperx_stride, 0, row, src->width);
|
||||||
|
repack_YVYU10_to_v210 (minfo.data + src->gst_stride * (row * 2 + 1),
|
||||||
|
pFrameInfo->lpRawBuffer, src->imperx_stride, 0, row + hh,
|
||||||
|
src->width);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (row = 0; row < src->height; row++) {
|
||||||
|
repack_YVYU10_to_v210 (minfo.data + src->gst_stride * row,
|
||||||
|
pFrameInfo->lpRawBuffer, src->imperx_stride, 0, row, src->width);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* all supported formats should already be 4-byte aligned */
|
/* all supported formats should already be 4-byte aligned */
|
||||||
g_assert (pFrameInfo->bufferSize >= minfo.size);
|
g_assert (pFrameInfo->bufferSize >= minfo.size);
|
||||||
@ -610,6 +669,7 @@ gst_imperxsdisrc_start_grab (GstImperxSdiSrc * src)
|
|||||||
|
|
||||||
src->format = GST_VIDEO_INFO_FORMAT (&vinfo);
|
src->format = GST_VIDEO_INFO_FORMAT (&vinfo);
|
||||||
switch (src->format) {
|
switch (src->format) {
|
||||||
|
case GST_VIDEO_FORMAT_v210:
|
||||||
case GST_VIDEO_FORMAT_AYUV64:
|
case GST_VIDEO_FORMAT_AYUV64:
|
||||||
src->camera_data.Format = VCESDI_OutputFormat_YCrCb10;
|
src->camera_data.Format = VCESDI_OutputFormat_YCrCb10;
|
||||||
/* 12 components (6 pixels), in 16 bytes */
|
/* 12 components (6 pixels), in 16 bytes */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user