video: don't perform subsampling while packing

Don't perform subsampling when packing but let this be done by a
separate subsampling step.
This commit is contained in:
Wim Taymans 2013-04-01 16:16:27 +02:00
parent 4f2e1b46a7
commit 2924365020
3 changed files with 65 additions and 82 deletions

View file

@ -318,13 +318,13 @@ pack_v210 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
y4 = s[4 * (i + 4) + 1] >> 6; y4 = s[4 * (i + 4) + 1] >> 6;
y5 = s[4 * (i + 5) + 1] >> 6; y5 = s[4 * (i + 5) + 1] >> 6;
u0 = (s[4 * (i + 0) + 2] + s[4 * (i + 1) + 2] + 1) >> 7; u0 = s[4 * (i + 0) + 2] >> 6;
u1 = (s[4 * (i + 2) + 2] + s[4 * (i + 3) + 2] + 1) >> 7; u1 = s[4 * (i + 2) + 2] >> 6;
u2 = (s[4 * (i + 4) + 2] + s[4 * (i + 5) + 2] + 1) >> 7; u2 = s[4 * (i + 4) + 2] >> 6;
v0 = (s[4 * (i + 0) + 3] + s[4 * (i + 1) + 3] + 1) >> 7; v0 = s[4 * (i + 0) + 3] >> 6;
v1 = (s[4 * (i + 2) + 3] + s[4 * (i + 3) + 3] + 1) >> 7; v1 = s[4 * (i + 2) + 3] >> 6;
v2 = (s[4 * (i + 4) + 3] + s[4 * (i + 5) + 3] + 1) >> 7; v2 = s[4 * (i + 4) + 3] >> 6;
a0 = u0 | (y0 << 10) | (v0 << 20); a0 = u0 | (y0 << 10) | (v0 << 20);
a1 = y1 | (u1 << 10) | (y2 << 20); a1 = y1 | (u1 << 10) | (y2 << 20);
@ -402,10 +402,8 @@ pack_Y41B (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
destY[i + 2] = s[i * 4 + 9]; destY[i + 2] = s[i * 4 + 9];
destY[i + 3] = s[i * 4 + 13]; destY[i + 3] = s[i * 4 + 13];
destU[i >> 2] = destU[i >> 2] = s[i * 4 + 2];
(s[i * 4 + 2] + s[i * 4 + 6] + s[i * 4 + 10] + s[i * 4 + 14] + 2) >> 2; destV[i >> 2] = s[i * 4 + 3];
destV[i >> 2] =
(s[i * 4 + 3] + s[i * 4 + 7] + s[i * 4 + 11] + s[i * 4 + 15] + 2) >> 2;
} }
if (i == width - 3) { if (i == width - 3) {
@ -413,14 +411,14 @@ pack_Y41B (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
destY[i + 1] = s[i * 4 + 5]; destY[i + 1] = s[i * 4 + 5];
destY[i + 2] = s[i * 4 + 9]; destY[i + 2] = s[i * 4 + 9];
destU[i >> 2] = (s[i * 4 + 2] + s[i * 4 + 6] + s[i * 4 + 10] + 1) / 3; destU[i >> 2] = s[i * 4 + 2];
destV[i >> 2] = (s[i * 4 + 3] + s[i * 4 + 7] + s[i * 4 + 11] + 1) / 3; destV[i >> 2] = s[i * 4 + 3];
} else if (i == width - 2) { } else if (i == width - 2) {
destY[i] = s[i * 4 + 1]; destY[i] = s[i * 4 + 1];
destY[i + 1] = s[i * 4 + 5]; destY[i + 1] = s[i * 4 + 5];
destU[i >> 2] = (s[i * 4 + 2] + s[i * 4 + 6] + 1) >> 1; destU[i >> 2] = s[i * 4 + 2];
destV[i >> 2] = (s[i * 4 + 3] + s[i * 4 + 7] + 1) >> 1; destV[i >> 2] = s[i * 4 + 3];
} else if (i == width - 1) { } else if (i == width - 1) {
destY[i + 1] = s[i * 4 + 5]; destY[i + 1] = s[i * 4 + 5];
@ -997,8 +995,8 @@ pack_UYVP (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
y0 = s[4 * (i + 0) + 1]; y0 = s[4 * (i + 0) + 1];
y1 = s[4 * (i + 1) + 1]; y1 = s[4 * (i + 1) + 1];
u0 = (s[4 * (i + 0) + 2] + s[4 * (i + 1) + 2] + 1) >> 1; u0 = s[4 * (i + 0) + 2];
v0 = (s[4 * (i + 0) + 3] + s[4 * (i + 1) + 3] + 1) >> 1; v0 = s[4 * (i + 0) + 3];
d[(i / 2) * 5 + 0] = u0 >> 8; d[(i / 2) * 5 + 0] = u0 >> 8;
d[(i / 2) * 5 + 1] = (u0 & 0xc0) | y0 >> 10; d[(i / 2) * 5 + 1] = (u0 & 0xc0) | y0 >> 10;
@ -1151,10 +1149,8 @@ pack_410 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
destY[i + 2] = s[i * 4 + 9]; destY[i + 2] = s[i * 4 + 9];
destY[i + 3] = s[i * 4 + 13]; destY[i + 3] = s[i * 4 + 13];
if (y % 4 == 0) { if (y % 4 == 0) {
destU[i >> 2] = destU[i >> 2] = s[i * 4 + 2];
(s[i * 4 + 2] + s[i * 4 + 6] + s[i * 4 + 10] + s[i * 4 + 14]) >> 2; destV[i >> 2] = s[i * 4 + 3];
destV[i >> 2] =
(s[i * 4 + 3] + s[i * 4 + 7] + s[i * 4 + 11] + s[i * 4 + 15]) >> 2;
} }
} }
@ -1163,15 +1159,15 @@ pack_410 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
destY[i + 1] = s[i * 4 + 5]; destY[i + 1] = s[i * 4 + 5];
destY[i + 2] = s[i * 4 + 9]; destY[i + 2] = s[i * 4 + 9];
if (y % 4 == 0) { if (y % 4 == 0) {
destU[i >> 2] = (s[i * 4 + 2] + s[i * 4 + 6] + s[i * 4 + 10]) / 3; destU[i >> 2] = s[i * 4 + 2];
destV[i >> 2] = (s[i * 4 + 3] + s[i * 4 + 7] + s[i * 4 + 11]) / 3; destV[i >> 2] = s[i * 4 + 3];
} }
} else if (i == width - 2) { } else if (i == width - 2) {
destY[i] = s[i * 4 + 1]; destY[i] = s[i * 4 + 1];
destY[i + 1] = s[i * 4 + 5]; destY[i + 1] = s[i * 4 + 5];
if (y % 4 == 0) { if (y % 4 == 0) {
destU[i >> 2] = (s[i * 4 + 2] + s[i * 4 + 6]) >> 1; destU[i >> 2] = s[i * 4 + 2];
destV[i >> 2] = (s[i * 4 + 3] + s[i * 4 + 7]) >> 1; destV[i >> 2] = s[i * 4 + 3];
} }
} else if (i == width - 1) { } else if (i == width - 1) {
destY[i] = s[i * 4 + 1]; destY[i] = s[i * 4 + 1];
@ -1244,23 +1240,21 @@ pack_IYU1 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
d[(i >> 2) * 6 + 2] = s[i * 4 + 5]; d[(i >> 2) * 6 + 2] = s[i * 4 + 5];
d[(i >> 2) * 6 + 4] = s[i * 4 + 9]; d[(i >> 2) * 6 + 4] = s[i * 4 + 9];
d[(i >> 2) * 6 + 5] = s[i * 4 + 13]; d[(i >> 2) * 6 + 5] = s[i * 4 + 13];
d[(i >> 2) * 6 + 0] = d[(i >> 2) * 6 + 0] = s[i * 4 + 2];
(s[i * 4 + 2] + s[i * 4 + 6] + s[i * 4 + 10] + s[i * 4 + 14]) >> 2; d[(i >> 2) * 6 + 3] = s[i * 4 + 3];
d[(i >> 2) * 6 + 3] =
(s[i * 4 + 3] + s[i * 4 + 7] + s[i * 4 + 11] + s[i * 4 + 15]) >> 2;
} }
if (i == width - 3) { if (i == width - 3) {
d[(i >> 2) * 6 + 1] = s[i * 4 + 1]; d[(i >> 2) * 6 + 1] = s[i * 4 + 1];
d[(i >> 2) * 6 + 2] = s[i * 4 + 5]; d[(i >> 2) * 6 + 2] = s[i * 4 + 5];
d[(i >> 2) * 6 + 4] = s[i * 4 + 9]; d[(i >> 2) * 6 + 4] = s[i * 4 + 9];
d[(i >> 2) * 6 + 0] = (s[i * 4 + 2] + s[i * 4 + 6] + s[i * 4 + 10]) / 3; d[(i >> 2) * 6 + 0] = s[i * 4 + 2];
d[(i >> 2) * 6 + 3] = (s[i * 4 + 3] + s[i * 4 + 7] + s[i * 4 + 11]) / 3; d[(i >> 2) * 6 + 3] = s[i * 4 + 3];
} else if (i == width - 2) { } else if (i == width - 2) {
d[(i >> 2) * 6 + 1] = s[i * 4 + 1]; d[(i >> 2) * 6 + 1] = s[i * 4 + 1];
d[(i >> 2) * 6 + 2] = s[i * 4 + 5]; d[(i >> 2) * 6 + 2] = s[i * 4 + 5];
d[(i >> 2) * 6 + 0] = (s[i * 4 + 2] + s[i * 4 + 6]) >> 1; d[(i >> 2) * 6 + 0] = s[i * 4 + 2];
d[(i >> 2) * 6 + 3] = (s[i * 4 + 3] + s[i * 4 + 7]) >> 1; d[(i >> 2) * 6 + 3] = s[i * 4 + 3];
} else if (i == width - 1) { } else if (i == width - 1) {
d[(i >> 2) * 6 + 1] = s[i * 4 + 1]; d[(i >> 2) * 6 + 1] = s[i * 4 + 1];
d[(i >> 2) * 6 + 0] = s[i * 4 + 2]; d[(i >> 2) * 6 + 0] = s[i * 4 + 2];
@ -1586,10 +1580,10 @@ pack_I420_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
const guint16 *s = src; const guint16 *s = src;
for (i = 0; i < width - 1; i += 2) { for (i = 0; i < width - 1; i += 2) {
Y0 = (s[i * 4 + 1]) >> 6; Y0 = s[i * 4 + 1] >> 6;
Y1 = (s[i * 4 + 5]) >> 6; Y1 = s[i * 4 + 5] >> 6;
U = ((s[i * 4 + 2] + s[i * 4 + 6] + 1) >> 1) >> 6; U = s[i * 4 + 2] >> 6;
V = ((s[i * 4 + 3] + s[i * 4 + 7] + 1) >> 1) >> 6; V = s[i * 4 + 3] >> 6;
GST_WRITE_UINT16_LE (destY + i + 0, Y0); GST_WRITE_UINT16_LE (destY + i + 0, Y0);
GST_WRITE_UINT16_LE (destY + i + 1, Y1); GST_WRITE_UINT16_LE (destY + i + 1, Y1);
@ -1655,8 +1649,8 @@ pack_I420_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
for (i = 0; i < width - 1; i += 2) { for (i = 0; i < width - 1; i += 2) {
Y0 = s[i * 4 + 1] >> 6; Y0 = s[i * 4 + 1] >> 6;
Y1 = s[i * 4 + 5] >> 6; Y1 = s[i * 4 + 5] >> 6;
U = ((s[i * 4 + 2] + s[i * 4 + 6] + 1) >> 1) >> 6; U = s[i * 4 + 2] >> 6;
V = ((s[i * 4 + 3] + s[i * 4 + 7] + 1) >> 1) >> 6; V = s[i * 4 + 3] >> 6;
GST_WRITE_UINT16_BE (destY + i + 0, Y0); GST_WRITE_UINT16_BE (destY + i + 0, Y0);
GST_WRITE_UINT16_BE (destY + i + 1, Y1); GST_WRITE_UINT16_BE (destY + i + 1, Y1);
@ -1718,10 +1712,10 @@ pack_I422_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
const guint16 *s = src; const guint16 *s = src;
for (i = 0; i < width - 1; i += 2) { for (i = 0; i < width - 1; i += 2) {
Y0 = (s[i * 4 + 1]) >> 6; Y0 = s[i * 4 + 1] >> 6;
Y1 = (s[i * 4 + 5]) >> 6; Y1 = s[i * 4 + 5] >> 6;
U = ((s[i * 4 + 2] + s[i * 4 + 6] + 1) >> 1) >> 6; U = s[i * 4 + 2] >> 6;
V = ((s[i * 4 + 3] + s[i * 4 + 7] + 1) >> 1) >> 6; V = s[i * 4 + 3] >> 6;
GST_WRITE_UINT16_LE (destY + i + 0, Y0); GST_WRITE_UINT16_LE (destY + i + 0, Y0);
GST_WRITE_UINT16_LE (destY + i + 1, Y1); GST_WRITE_UINT16_LE (destY + i + 1, Y1);
@ -1785,8 +1779,8 @@ pack_I422_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
for (i = 0; i < width - 1; i += 2) { for (i = 0; i < width - 1; i += 2) {
Y0 = s[i * 4 + 1] >> 6; Y0 = s[i * 4 + 1] >> 6;
Y1 = s[i * 4 + 5] >> 6; Y1 = s[i * 4 + 5] >> 6;
U = ((s[i * 4 + 2] + s[i * 4 + 6] + 1) >> 1) >> 6; U = s[i * 4 + 2] >> 6;
V = ((s[i * 4 + 3] + s[i * 4 + 7] + 1) >> 1) >> 6; V = s[i * 4 + 3] >> 6;
GST_WRITE_UINT16_BE (destY + i + 0, Y0); GST_WRITE_UINT16_BE (destY + i + 0, Y0);
GST_WRITE_UINT16_BE (destY + i + 1, Y1); GST_WRITE_UINT16_BE (destY + i + 1, Y1);

View file

@ -231,6 +231,10 @@ typedef enum
* format @info. The pixels will be unpacked into @dest which each component * format @info. The pixels will be unpacked into @dest which each component
* interleaved. @dest should at least be big enough to hold @width * * interleaved. @dest should at least be big enough to hold @width *
* n_components * size(unpack_format) bytes. * n_components * size(unpack_format) bytes.
*
* For subsampled formats, the components will be duplicated in the destination
* array. Reconstruction of the missing components can be performed in a
* separate step after unpacking.
*/ */
typedef void (*GstVideoFormatUnpack) (const GstVideoFormatInfo *info, typedef void (*GstVideoFormatUnpack) (const GstVideoFormatInfo *info,
GstVideoPackFlags flags, gpointer dest, GstVideoPackFlags flags, gpointer dest,
@ -245,7 +249,7 @@ typedef void (*GstVideoFormatUnpack) (const GstVideoFormatInfo *info,
* @sstride: the source array stride * @sstride: the source array stride
* @data: pointers to the destination data planes * @data: pointers to the destination data planes
* @stride: strides of the destination planes * @stride: strides of the destination planes
* @chroma_site: the chroma siting of the target when subsampled * @chroma_site: the chroma siting of the target when subsampled (not used)
* @y: the y position in the image to pack to * @y: the y position in the image to pack to
* @width: the amount of pixels to pack. * @width: the amount of pixels to pack.
* *
@ -256,6 +260,9 @@ typedef void (*GstVideoFormatUnpack) (const GstVideoFormatInfo *info,
* This function operates on pack_lines lines, meaning that @src should * This function operates on pack_lines lines, meaning that @src should
* contain at least pack_lines lines with a stride of @sstride and @y * contain at least pack_lines lines with a stride of @sstride and @y
* should be a multiple of pack_lines. * should be a multiple of pack_lines.
*
* Subsampled formats will use the horizontally cosited component in the
* destination. Subsampling should be performed before packing.
*/ */
typedef void (*GstVideoFormatPack) (const GstVideoFormatInfo *info, typedef void (*GstVideoFormatPack) (const GstVideoFormatInfo *info,
GstVideoPackFlags flags, GstVideoPackFlags flags,

View file

@ -93,10 +93,8 @@ mergewl d, ay, uv
x2 splitlw uv, ay, ayuv x2 splitlw uv, ay, ayuv
x2 select1wb y, ay x2 select1wb y, ay
x2 splitwb vv, uu, uv x2 splitwb vv, uu, uv
splitwb t1, t2, uu select0wb u, uu
avgub u, t1, t2 select0wb v, vv
splitwb t1, t2, vv
avgub v, t1, t2
.function video_orc_unpack_YUY2 .function video_orc_unpack_YUY2
.dest 8 ayuv guint8 .dest 8 ayuv guint8
@ -117,32 +115,28 @@ x2 mergewl ayuv, ayay, uvuv
.dest 4 yuy2 guint8 .dest 4 yuy2 guint8
.source 8 ayuv guint8 .source 8 ayuv guint8
.temp 2 yy .temp 2 yy
.temp 2 uv1 .temp 2 uv
.temp 2 uv2
.temp 4 ayay .temp 4 ayay
.temp 4 uvuv .temp 4 uvuv
x2 splitlw uvuv, ayay, ayuv x2 splitlw uvuv, ayay, ayuv
splitlw uv1, uv2, uvuv select0lw uv, uvuv
x2 avgub uv1, uv1, uv2
x2 select1wb yy, ayay x2 select1wb yy, ayay
x2 mergebw yuy2, yy, uv1 x2 mergebw yuy2, yy, uv
.function video_orc_pack_UYVY .function video_orc_pack_UYVY
.dest 4 yuy2 guint8 .dest 4 yuy2 guint8
.source 8 ayuv guint8 .source 8 ayuv guint8
.temp 2 yy .temp 2 yy
.temp 2 uv1 .temp 2 uv
.temp 2 uv2
.temp 4 ayay .temp 4 ayay
.temp 4 uvuv .temp 4 uvuv
x2 splitlw uvuv, ayay, ayuv x2 splitlw uvuv, ayay, ayuv
splitlw uv1, uv2, uvuv select0lw uv, uvuv
x2 avgub uv1, uv1, uv2
x2 select1wb yy, ayay x2 select1wb yy, ayay
x2 mergebw yuy2, uv1, yy x2 mergebw yuy2, uv, yy
.function video_orc_unpack_UYVY .function video_orc_unpack_UYVY
@ -180,17 +174,15 @@ x2 mergewl ayuv, ayay, uvuv
.dest 4 yuy2 guint8 .dest 4 yuy2 guint8
.source 8 ayuv guint8 .source 8 ayuv guint8
.temp 2 yy .temp 2 yy
.temp 2 uv1 .temp 2 uv
.temp 2 uv2
.temp 4 ayay .temp 4 ayay
.temp 4 uvuv .temp 4 uvuv
x2 splitlw uvuv, ayay, ayuv x2 splitlw uvuv, ayay, ayuv
splitlw uv1, uv2, uvuv select0lw uv, uvuv
x2 avgub uv1, uv1, uv2
x2 select1wb yy, ayay x2 select1wb yy, ayay
swapw uv1, uv1 swapw uv, uv
x2 mergebw yuy2, yy, uv1 x2 mergebw yuy2, yy, uv
.function video_orc_unpack_YUV9 .function video_orc_unpack_YUV9
@ -236,13 +228,11 @@ x2 mergewl ayuv, ayay, uvuv
.source 8 ayuv guint8 .source 8 ayuv guint8
.temp 4 ayay .temp 4 ayay
.temp 4 uvuv .temp 4 uvuv
.temp 2 uv1 .temp 2 uv
.temp 2 uv2
x2 splitlw uvuv, ayay, ayuv x2 splitlw uvuv, ayay, ayuv
splitlw uv1, uv2, uvuv select0lw uv, uvuv
x2 avgub uv1, uv1, uv2 splitwb v, u, uv
splitwb v, u, uv1
x2 select1wb y, ayay x2 select1wb y, ayay
@ -405,8 +395,7 @@ x2 mergewl d, ay, uvuv
x2 splitlw uvuv, ay, ayuv x2 splitlw uvuv, ay, ayuv
x2 select1wb y, ay x2 select1wb y, ay
splitlw uv1, uv2, uvuv select0lw uv, uvuv
x2 avgub uv, uv1, uv2
.function video_orc_unpack_NV21 .function video_orc_unpack_NV21
.dest 8 d guint8 .dest 8 d guint8
@ -429,14 +418,11 @@ x2 mergewl d, ay, uvuv
.source 8 ayuv guint8 .source 8 ayuv guint8
.temp 4 ay .temp 4 ay
.temp 4 uvuv .temp 4 uvuv
.temp 2 uv1
.temp 2 uv2
.temp 2 uv .temp 2 uv
x2 splitlw uvuv, ay, ayuv x2 splitlw uvuv, ay, ayuv
x2 select1wb y, ay x2 select1wb y, ay
splitlw uv1, uv2, uvuv select0lw uv, uvuv
x2 avgub uv, uv1, uv2
swapw vu, uv swapw vu, uv
@ -491,17 +477,13 @@ mergewl d, ay, uv
.temp 4 uv .temp 4 uv
.temp 2 uu .temp 2 uu
.temp 2 vv .temp 2 vv
.temp 1 t1
.temp 1 t2
x2 splitlw uv, ay, ayuv x2 splitlw uv, ay, ayuv
x2 select1wb y, ay x2 select1wb y, ay
x2 select0wb a, ay x2 select0wb a, ay
x2 splitwb vv, uu, uv x2 splitwb vv, uu, uv
splitwb t1, t2, uu select0wb u, uu
avgub u, t1, t2 select0wb v, vv
splitwb t1, t2, vv
avgub v, t1, t2
.function video_orc_resample_bilinear_u32 .function video_orc_resample_bilinear_u32
.dest 4 d1 guint8 .dest 4 d1 guint8