Commit 61884d19 authored by Michael Niedermayer's avatar Michael Niedermayer

sws: GBRP output support

Reviewed-by: 's avatarDerek Buitenhuis <derek.buitenhuis@gmail.com>
Signed-off-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parent c8f25caf
...@@ -1372,13 +1372,69 @@ YUV2RGBWRAPPERX(yuv2, rgb_full, rgb4_byte_full, AV_PIX_FMT_RGB4_BYTE, 0) ...@@ -1372,13 +1372,69 @@ YUV2RGBWRAPPERX(yuv2, rgb_full, rgb4_byte_full, AV_PIX_FMT_RGB4_BYTE, 0)
YUV2RGBWRAPPERX(yuv2, rgb_full, bgr8_full, AV_PIX_FMT_BGR8, 0) YUV2RGBWRAPPERX(yuv2, rgb_full, bgr8_full, AV_PIX_FMT_BGR8, 0)
YUV2RGBWRAPPERX(yuv2, rgb_full, rgb8_full, AV_PIX_FMT_RGB8, 0) YUV2RGBWRAPPERX(yuv2, rgb_full, rgb8_full, AV_PIX_FMT_RGB8, 0)
static void
yuv2gbrp_full_X_c(SwsContext *c, const int16_t *lumFilter,
const int16_t **lumSrc, int lumFilterSize,
const int16_t *chrFilter, const int16_t **chrUSrc,
const int16_t **chrVSrc, int chrFilterSize,
const int16_t **alpSrc, uint8_t **dest,
int dstW, int y)
{
int i;
int hasAlpha = 0;
for (i = 0; i < dstW; i++) {
int j;
int Y = 1<<9;
int U = (1<<9)-(128 << 19);
int V = (1<<9)-(128 << 19);
int R, G, B, A;
for (j = 0; j < lumFilterSize; j++) {
Y += lumSrc[j][i] * lumFilter[j];
}
for (j = 0; j < chrFilterSize; j++) {
U += chrUSrc[j][i] * chrFilter[j];
V += chrVSrc[j][i] * chrFilter[j];
}
Y >>= 10;
U >>= 10;
V >>= 10;
if (hasAlpha) {
A = 1 << 18;
for (j = 0; j < lumFilterSize; j++) {
A += alpSrc[j][i] * lumFilter[j];
}
A >>= 19;
if (A & 0x100)
A = av_clip_uint8(A);
}
Y -= c->yuv2rgb_y_offset;
Y *= c->yuv2rgb_y_coeff;
Y += 1 << 21;
R = Y + V*c->yuv2rgb_v2r_coeff;
G = Y + V*c->yuv2rgb_v2g_coeff + U*c->yuv2rgb_u2g_coeff;
B = Y + U*c->yuv2rgb_u2b_coeff;
if ((R | G | B) & 0xC0000000) {
R = av_clip_uintp2(R, 30);
G = av_clip_uintp2(G, 30);
B = av_clip_uintp2(B, 30);
}
dest[0][i] = G >> 22;
dest[1][i] = B >> 22;
dest[2][i] = R >> 22;
}
}
av_cold void ff_sws_init_output_funcs(SwsContext *c, av_cold void ff_sws_init_output_funcs(SwsContext *c,
yuv2planar1_fn *yuv2plane1, yuv2planar1_fn *yuv2plane1,
yuv2planarX_fn *yuv2planeX, yuv2planarX_fn *yuv2planeX,
yuv2interleavedX_fn *yuv2nv12cX, yuv2interleavedX_fn *yuv2nv12cX,
yuv2packed1_fn *yuv2packed1, yuv2packed1_fn *yuv2packed1,
yuv2packed2_fn *yuv2packed2, yuv2packed2_fn *yuv2packed2,
yuv2packedX_fn *yuv2packedX) yuv2packedX_fn *yuv2packedX,
yuv2anyX_fn *yuv2anyX)
{ {
enum AVPixelFormat dstFormat = c->dstFormat; enum AVPixelFormat dstFormat = c->dstFormat;
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(dstFormat); const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(dstFormat);
...@@ -1484,8 +1540,11 @@ av_cold void ff_sws_init_output_funcs(SwsContext *c, ...@@ -1484,8 +1540,11 @@ av_cold void ff_sws_init_output_funcs(SwsContext *c,
case AV_PIX_FMT_RGB8: case AV_PIX_FMT_RGB8:
*yuv2packedX = yuv2rgb8_full_X_c; *yuv2packedX = yuv2rgb8_full_X_c;
break; break;
case AV_PIX_FMT_GBRP:
*yuv2anyX = yuv2gbrp_full_X_c;
break;
} }
if(!*yuv2packedX) if (!*yuv2packedX && !*yuv2anyX)
goto YUV_PACKED; goto YUV_PACKED;
} else { } else {
YUV_PACKED: YUV_PACKED:
......
...@@ -369,6 +369,7 @@ static int swScale(SwsContext *c, const uint8_t *src[], ...@@ -369,6 +369,7 @@ static int swScale(SwsContext *c, const uint8_t *src[],
yuv2packed1_fn yuv2packed1 = c->yuv2packed1; yuv2packed1_fn yuv2packed1 = c->yuv2packed1;
yuv2packed2_fn yuv2packed2 = c->yuv2packed2; yuv2packed2_fn yuv2packed2 = c->yuv2packed2;
yuv2packedX_fn yuv2packedX = c->yuv2packedX; yuv2packedX_fn yuv2packedX = c->yuv2packedX;
yuv2anyX_fn yuv2anyX = c->yuv2anyX;
const int chrSrcSliceY = srcSliceY >> c->chrSrcVSubSample; const int chrSrcSliceY = srcSliceY >> c->chrSrcVSubSample;
const int chrSrcSliceH = -((-srcSliceH) >> c->chrSrcVSubSample); const int chrSrcSliceH = -((-srcSliceH) >> c->chrSrcVSubSample);
int should_dither = is9_OR_10BPS(c->srcFormat) || int should_dither = is9_OR_10BPS(c->srcFormat) ||
...@@ -557,7 +558,7 @@ static int swScale(SwsContext *c, const uint8_t *src[], ...@@ -557,7 +558,7 @@ static int swScale(SwsContext *c, const uint8_t *src[],
/* hmm looks like we can't use MMX here without overwriting /* hmm looks like we can't use MMX here without overwriting
* this array's tail */ * this array's tail */
ff_sws_init_output_funcs(c, &yuv2plane1, &yuv2planeX, &yuv2nv12cX, ff_sws_init_output_funcs(c, &yuv2plane1, &yuv2planeX, &yuv2nv12cX,
&yuv2packed1, &yuv2packed2, &yuv2packedX); &yuv2packed1, &yuv2packed2, &yuv2packedX, &yuv2anyX);
use_mmx_vfilter= 0; use_mmx_vfilter= 0;
} }
...@@ -630,7 +631,7 @@ static int swScale(SwsContext *c, const uint8_t *src[], ...@@ -630,7 +631,7 @@ static int swScale(SwsContext *c, const uint8_t *src[],
dstW, c->lumDither8, 0); dstW, c->lumDither8, 0);
} }
} }
} else { } else if (yuv2packedX) {
av_assert1(lumSrcPtr + vLumFilterSize - 1 < lumPixBuf + vLumBufSize * 2); av_assert1(lumSrcPtr + vLumFilterSize - 1 < lumPixBuf + vLumBufSize * 2);
av_assert1(chrUSrcPtr + vChrFilterSize - 1 < chrUPixBuf + vChrBufSize * 2); av_assert1(chrUSrcPtr + vChrFilterSize - 1 < chrUPixBuf + vChrBufSize * 2);
if (c->yuv2packed1 && vLumFilterSize == 1 && if (c->yuv2packed1 && vLumFilterSize == 1 &&
...@@ -657,6 +658,13 @@ static int swScale(SwsContext *c, const uint8_t *src[], ...@@ -657,6 +658,13 @@ static int swScale(SwsContext *c, const uint8_t *src[],
chrUSrcPtr, chrVSrcPtr, vChrFilterSize, chrUSrcPtr, chrVSrcPtr, vChrFilterSize,
alpSrcPtr, dest[0], dstW, dstY); alpSrcPtr, dest[0], dstW, dstY);
} }
} else {
av_assert1(!yuv2packed1 && !yuv2packed2);
yuv2anyX(c, vLumFilter + dstY * vLumFilterSize,
lumSrcPtr, vLumFilterSize,
vChrFilter + dstY * vChrFilterSize,
chrUSrcPtr, chrVSrcPtr, vChrFilterSize,
alpSrcPtr, dest, dstW, dstY);
} }
} }
} }
...@@ -695,7 +703,7 @@ static av_cold void sws_init_swScale_c(SwsContext *c) ...@@ -695,7 +703,7 @@ static av_cold void sws_init_swScale_c(SwsContext *c)
ff_sws_init_output_funcs(c, &c->yuv2plane1, &c->yuv2planeX, ff_sws_init_output_funcs(c, &c->yuv2plane1, &c->yuv2planeX,
&c->yuv2nv12cX, &c->yuv2packed1, &c->yuv2nv12cX, &c->yuv2packed1,
&c->yuv2packed2, &c->yuv2packedX); &c->yuv2packed2, &c->yuv2packedX, &c->yuv2anyX);
ff_sws_init_input_funcs(c); ff_sws_init_input_funcs(c);
......
...@@ -223,6 +223,40 @@ typedef void (*yuv2packedX_fn)(struct SwsContext *c, const int16_t *lumFilter, ...@@ -223,6 +223,40 @@ typedef void (*yuv2packedX_fn)(struct SwsContext *c, const int16_t *lumFilter,
const int16_t **alpSrc, uint8_t *dest, const int16_t **alpSrc, uint8_t *dest,
int dstW, int y); int dstW, int y);
/**
* Write one line of horizontally scaled Y/U/V/A to YUV/RGB
* output by doing multi-point vertical scaling between input pixels.
*
* @param c SWS scaling context
* @param lumFilter vertical luma/alpha scaling coefficients, 12bit [0,4096]
* @param lumSrc scaled luma (Y) source data, 15bit for 8-10bit output,
* 19-bit for 16bit output (in int32_t)
* @param lumFilterSize number of vertical luma/alpha input lines to scale
* @param chrFilter vertical chroma scaling coefficients, 12bit [0,4096]
* @param chrUSrc scaled chroma (U) source data, 15bit for 8-10bit output,
* 19-bit for 16bit output (in int32_t)
* @param chrVSrc scaled chroma (V) source data, 15bit for 8-10bit output,
* 19-bit for 16bit output (in int32_t)
* @param chrFilterSize number of vertical chroma input lines to scale
* @param alpSrc scaled alpha (A) source data, 15bit for 8-10bit output,
* 19-bit for 16bit output (in int32_t)
* @param dest pointer to the output planes. For 16bit output, this is
* uint16_t
* @param dstW width of lumSrc and alpSrc in pixels, number of pixels
* to write into dest[]
* @param y vertical line number for this output. This does not need
* to be used to calculate the offset in the destination,
* but can be used to generate comfort noise using dithering
* or some output formats.
*/
typedef void (*yuv2anyX_fn)(struct SwsContext *c, const int16_t *lumFilter,
const int16_t **lumSrc, int lumFilterSize,
const int16_t *chrFilter,
const int16_t **chrUSrc,
const int16_t **chrVSrc, int chrFilterSize,
const int16_t **alpSrc, uint8_t **dest,
int dstW, int y);
/* This struct should be aligned on at least a 32-byte boundary. */ /* This struct should be aligned on at least a 32-byte boundary. */
typedef struct SwsContext { typedef struct SwsContext {
/** /**
...@@ -437,6 +471,7 @@ typedef struct SwsContext { ...@@ -437,6 +471,7 @@ typedef struct SwsContext {
yuv2packed1_fn yuv2packed1; yuv2packed1_fn yuv2packed1;
yuv2packed2_fn yuv2packed2; yuv2packed2_fn yuv2packed2;
yuv2packedX_fn yuv2packedX; yuv2packedX_fn yuv2packedX;
yuv2anyX_fn yuv2anyX;
/// Unscaled conversion of luma plane to YV12 for horizontal scaler. /// Unscaled conversion of luma plane to YV12 for horizontal scaler.
void (*lumToYV12)(uint8_t *dst, const uint8_t *src, const uint8_t *src2, const uint8_t *src3, void (*lumToYV12)(uint8_t *dst, const uint8_t *src, const uint8_t *src2, const uint8_t *src3,
...@@ -768,7 +803,8 @@ void ff_sws_init_output_funcs(SwsContext *c, ...@@ -768,7 +803,8 @@ void ff_sws_init_output_funcs(SwsContext *c,
yuv2interleavedX_fn *yuv2nv12cX, yuv2interleavedX_fn *yuv2nv12cX,
yuv2packed1_fn *yuv2packed1, yuv2packed1_fn *yuv2packed1,
yuv2packed2_fn *yuv2packed2, yuv2packed2_fn *yuv2packed2,
yuv2packedX_fn *yuv2packedX); yuv2packedX_fn *yuv2packedX,
yuv2anyX_fn *yuv2anyX);
void ff_sws_init_swScale_altivec(SwsContext *c); void ff_sws_init_swScale_altivec(SwsContext *c);
void ff_sws_init_swScale_mmx(SwsContext *c); void ff_sws_init_swScale_mmx(SwsContext *c);
......
...@@ -185,7 +185,7 @@ static const FormatEntry format_entries[AV_PIX_FMT_NB] = { ...@@ -185,7 +185,7 @@ static const FormatEntry format_entries[AV_PIX_FMT_NB] = {
[AV_PIX_FMT_YUV444P12LE] = { 1, 1 }, [AV_PIX_FMT_YUV444P12LE] = { 1, 1 },
[AV_PIX_FMT_YUV444P14BE] = { 1, 1 }, [AV_PIX_FMT_YUV444P14BE] = { 1, 1 },
[AV_PIX_FMT_YUV444P14LE] = { 1, 1 }, [AV_PIX_FMT_YUV444P14LE] = { 1, 1 },
[AV_PIX_FMT_GBRP] = { 1, 0 }, [AV_PIX_FMT_GBRP] = { 1, 1 },
[AV_PIX_FMT_GBRP9LE] = { 1, 0 }, [AV_PIX_FMT_GBRP9LE] = { 1, 0 },
[AV_PIX_FMT_GBRP9BE] = { 1, 0 }, [AV_PIX_FMT_GBRP9BE] = { 1, 0 },
[AV_PIX_FMT_GBRP10LE] = { 1, 0 }, [AV_PIX_FMT_GBRP10LE] = { 1, 0 },
...@@ -1019,11 +1019,21 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, ...@@ -1019,11 +1019,21 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter,
c->flags = flags; c->flags = flags;
} }
} }
if(dstFormat == AV_PIX_FMT_GBRP) {
if (!(flags & SWS_FULL_CHR_H_INT)) {
av_log(c, AV_LOG_DEBUG,
"%s output is not supported with half chroma resolution, switching to full\n",
av_get_pix_fmt_name(dstFormat));
flags |= SWS_FULL_CHR_H_INT;
c->flags = flags;
}
}
/* reuse chroma for 2 pixels RGB/BGR unless user wants full /* reuse chroma for 2 pixels RGB/BGR unless user wants full
* chroma interpolation */ * chroma interpolation */
if (flags & SWS_FULL_CHR_H_INT && if (flags & SWS_FULL_CHR_H_INT &&
isAnyRGB(dstFormat) && isAnyRGB(dstFormat) &&
dstFormat != AV_PIX_FMT_GBRP &&
dstFormat != AV_PIX_FMT_RGBA && dstFormat != AV_PIX_FMT_RGBA &&
dstFormat != AV_PIX_FMT_ARGB && dstFormat != AV_PIX_FMT_ARGB &&
dstFormat != AV_PIX_FMT_BGRA && dstFormat != AV_PIX_FMT_BGRA &&
......
...@@ -15,6 +15,7 @@ bgr565be bf955b9a035af0e613cf1de249f55f9d ...@@ -15,6 +15,7 @@ bgr565be bf955b9a035af0e613cf1de249f55f9d
bgr565le 6dd85cd5e19266c53a54cbcf06d396a7 bgr565le 6dd85cd5e19266c53a54cbcf06d396a7
bgr8 9669f6974f0fc1c0afa1c7d4df093c0b bgr8 9669f6974f0fc1c0afa1c7d4df093c0b
bgra f7cabae31dd7465dab2203f45db646f8 bgra f7cabae31dd7465dab2203f45db646f8
gbrp 55eab469e3e02ccc5a358565d9b1eaa7
gray 66a09b53f7d3f79dcb6096f3ec3740c5 gray 66a09b53f7d3f79dcb6096f3ec3740c5
gray16be a447af6482b922c9997ac02e5d3535f1 gray16be a447af6482b922c9997ac02e5d3535f1
gray16le c1dd0db327295898ff282d07f48c105d gray16le c1dd0db327295898ff282d07f48c105d
......
...@@ -15,6 +15,7 @@ bgr565be 13a36d6502be88fc0c2aec05b8d2d501 ...@@ -15,6 +15,7 @@ bgr565be 13a36d6502be88fc0c2aec05b8d2d501
bgr565le ed027571692aecd522aa65a90cc7e09b bgr565le ed027571692aecd522aa65a90cc7e09b
bgr8 71ef789609c746c2e7e4be9dec29062c bgr8 71ef789609c746c2e7e4be9dec29062c
bgra 0364b074268682ea46168742a8239f7d bgra 0364b074268682ea46168742a8239f7d
gbrp 89d6e4b116e3bd542fa09a19a977ad16
gray 1e5e2b8548843a6898eedd9c974c422c gray 1e5e2b8548843a6898eedd9c974c422c
gray16be 389f4e5a8ab413b3af32767b59ed7f9e gray16be 389f4e5a8ab413b3af32767b59ed7f9e
gray16le a1f912941247e45b394b9cf4f0e81130 gray16le a1f912941247e45b394b9cf4f0e81130
......
...@@ -15,6 +15,7 @@ bgr565be 13a36d6502be88fc0c2aec05b8d2d501 ...@@ -15,6 +15,7 @@ bgr565be 13a36d6502be88fc0c2aec05b8d2d501
bgr565le ed027571692aecd522aa65a90cc7e09b bgr565le ed027571692aecd522aa65a90cc7e09b
bgr8 71ef789609c746c2e7e4be9dec29062c bgr8 71ef789609c746c2e7e4be9dec29062c
bgra 0364b074268682ea46168742a8239f7d bgra 0364b074268682ea46168742a8239f7d
gbrp 89d6e4b116e3bd542fa09a19a977ad16
gray 1e5e2b8548843a6898eedd9c974c422c gray 1e5e2b8548843a6898eedd9c974c422c
gray16be 389f4e5a8ab413b3af32767b59ed7f9e gray16be 389f4e5a8ab413b3af32767b59ed7f9e
gray16le a1f912941247e45b394b9cf4f0e81130 gray16le a1f912941247e45b394b9cf4f0e81130
......
...@@ -5,6 +5,7 @@ argb e5fbb7bb282a80897b8f730627f68876 ...@@ -5,6 +5,7 @@ argb e5fbb7bb282a80897b8f730627f68876
bgr0 c55368036cccbb0af471d6bd82abe02a bgr0 c55368036cccbb0af471d6bd82abe02a
bgr24 67f9fd70dc6d9896b7122976b33932b4 bgr24 67f9fd70dc6d9896b7122976b33932b4
bgra c8dd017b5a3b55e8b9d0ac1cdcf327bd bgra c8dd017b5a3b55e8b9d0ac1cdcf327bd
gbrp 74f83deee9866bbdce3f91fa2aeddaaa
gray b1abadae3718522aa57a7972da8cbe17 gray b1abadae3718522aa57a7972da8cbe17
rgb0 b1977b45634c4db58a183a07feb2acff rgb0 b1977b45634c4db58a183a07feb2acff
rgb24 e73de9dc0fdd78f4853c168603cc7aba rgb24 e73de9dc0fdd78f4853c168603cc7aba
......
...@@ -15,6 +15,7 @@ bgr565be 13a36d6502be88fc0c2aec05b8d2d501 ...@@ -15,6 +15,7 @@ bgr565be 13a36d6502be88fc0c2aec05b8d2d501
bgr565le ed027571692aecd522aa65a90cc7e09b bgr565le ed027571692aecd522aa65a90cc7e09b
bgr8 71ef789609c746c2e7e4be9dec29062c bgr8 71ef789609c746c2e7e4be9dec29062c
bgra 0364b074268682ea46168742a8239f7d bgra 0364b074268682ea46168742a8239f7d
gbrp 89d6e4b116e3bd542fa09a19a977ad16
gray 1e5e2b8548843a6898eedd9c974c422c gray 1e5e2b8548843a6898eedd9c974c422c
gray16be 389f4e5a8ab413b3af32767b59ed7f9e gray16be 389f4e5a8ab413b3af32767b59ed7f9e
gray16le a1f912941247e45b394b9cf4f0e81130 gray16le a1f912941247e45b394b9cf4f0e81130
......
...@@ -15,6 +15,7 @@ bgr565be fca6f07daf23d9dd84381dd4c9afd959 ...@@ -15,6 +15,7 @@ bgr565be fca6f07daf23d9dd84381dd4c9afd959
bgr565le f524e9f16bdd68b247dbcb621e543fc0 bgr565le f524e9f16bdd68b247dbcb621e543fc0
bgr8 68a3a395043dc57335ad1f8e891229c5 bgr8 68a3a395043dc57335ad1f8e891229c5
bgra 3eaf5489b8aa13a3388aad3751b597bf bgra 3eaf5489b8aa13a3388aad3751b597bf
gbrp 7b83ae32c1f76bd634e50f4797a74e92
gray 045c35e6cc7d41460f2b96b3e254deab gray 045c35e6cc7d41460f2b96b3e254deab
gray16be 70064f9acdc5e3935ccda67e765bf2fb gray16be 70064f9acdc5e3935ccda67e765bf2fb
gray16le 578241fb43029e5ae841a3c94d940dce gray16le 578241fb43029e5ae841a3c94d940dce
......
...@@ -15,6 +15,7 @@ bgr565be 7100c2ddfee42e7efafec1ccefecf7c6 ...@@ -15,6 +15,7 @@ bgr565be 7100c2ddfee42e7efafec1ccefecf7c6
bgr565le 9fab295d966386d4ef99d5b43066da47 bgr565le 9fab295d966386d4ef99d5b43066da47
bgr8 275ce12eeb05de67a6915f67cbb43ce5 bgr8 275ce12eeb05de67a6915f67cbb43ce5
bgra d29c35871248c476c366e678db580982 bgra d29c35871248c476c366e678db580982
gbrp 7852e9bbe52cfad9bab8081a5c7a5a31
gray a53528cdf80ed31c9897042a2ea16618 gray a53528cdf80ed31c9897042a2ea16618
gray16be 9b23f3e79c54a6ccb62e0135a32e3045 gray16be 9b23f3e79c54a6ccb62e0135a32e3045
gray16le 93cfa8fbb2a86ead275ce1817444e6d5 gray16le 93cfa8fbb2a86ead275ce1817444e6d5
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment