[FFmpeg-devel] [PATCH/WIP]Add an unscaled GBRAP16 -> RGB48/64 wrapper
Carl Eugen Hoyos
cehoyos at ag.or.at
Sun Jun 9 00:56:39 CEST 2013
On Saturday 08 June 2013 05:27:06 am Carl Eugen Hoyos wrote:
> Hi!
>
> I only realize now that attached patch is difficult to test
I used attached patch to test the first one which works fine.
Ok to commit the first patch?
Carl Eugen
-------------- next part --------------
diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c
index 7c65dac..361bc1c 100644
--- a/libswscale/swscale_unscaled.c
+++ b/libswscale/swscale_unscaled.c
@@ -389,6 +389,249 @@ static int palToRgbWrapper(SwsContext *c, const uint8_t *src[], int srcStride[],
return srcSliceH;
}
+static void packed16togbra16(const uint8_t *src, int srcStride,
+ uint16_t *dst[], int dstStride[], int srcSliceH,
+ int alpha, int swap, int width)
+{
+ int x, h, i;
+ for (h = 0; h < srcSliceH; h++) {
+ uint16_t *src_line = (uint16_t *)(src + srcStride * h);
+ switch (alpha) {
+ case 3:
+ if (swap) {
+ for (x = 0; x < width; x++) {
+ dst[0][x] = av_bswap16(*src_line++);
+ dst[1][x] = av_bswap16(*src_line++);
+ dst[2][x] = av_bswap16(*src_line++);
+ dst[3][x] = av_bswap16(*src_line++);
+ }
+ } else {
+ for (x = 0; x < width; x++) {
+ dst[0][x] = *src_line++;
+ dst[1][x] = *src_line++;
+ dst[2][x] = *src_line++;
+ dst[3][x] = *src_line++;
+ }
+ }
+ break;
+ case 2:
+ if (swap) {
+ for (x = 0; x < width; x++) {
+ dst[0][x] = av_bswap16(*src_line++);
+ dst[1][x] = av_bswap16(*src_line++);
+ dst[2][x] = av_bswap16(*src_line++);
+ src_line++;
+ }
+ } else {
+ for (x = 0; x < width; x++) {
+ dst[0][x] = *src_line++;
+ dst[1][x] = *src_line++;
+ dst[2][x] = *src_line++;
+ src_line++;
+ }
+ }
+ break;
+ case 1:
+ if (swap) {
+ for (x = 0; x < width; x++) {
+ dst[0][x] = av_bswap16(*src_line++);
+ dst[1][x] = av_bswap16(*src_line++);
+ dst[2][x] = av_bswap16(*src_line++);
+ dst[3][x] = 0xFFFF;
+ }
+ } else {
+ for (x = 0; x < width; x++) {
+ dst[0][x] = *src_line++;
+ dst[1][x] = *src_line++;
+ dst[2][x] = *src_line++;
+ dst[3][x] = 0xFFFF;
+ }
+ }
+ break;
+ default:
+ if (swap) {
+ for (x = 0; x < width; x++) {
+ dst[0][x] = av_bswap16(*src_line++);
+ dst[1][x] = av_bswap16(*src_line++);
+ dst[2][x] = av_bswap16(*src_line++);
+ }
+ } else {
+ for (x = 0; x < width; x++) {
+ dst[0][x] = *src_line++;
+ dst[1][x] = *src_line++;
+ dst[2][x] = *src_line++;
+ }
+ }
+ }
+ for (i = 0; i < 4; i++)
+ dst[i] += dstStride[i] >> 1;
+ }
+}
+
+static int Rgb16ToPlanarRgb16Wrapper(SwsContext *c, const uint8_t *src[],
+ int srcStride[], int srcSliceY, int srcSliceH,
+ uint8_t *dst[], int dstStride[])
+{
+ uint16_t *dst2013[] = { (uint16_t *)dst[2], (uint16_t *)dst[0], (uint16_t *)dst[1], (uint16_t *)dst[3] };
+ uint16_t *dst1023[] = { (uint16_t *)dst[1], (uint16_t *)dst[0], (uint16_t *)dst[2], (uint16_t *)dst[3] };
+ int stride2013[] = { dstStride[2], dstStride[0], dstStride[1], dstStride[3] };
+ int stride1023[] = { dstStride[1], dstStride[0], dstStride[2], dstStride[3] };
+ const AVPixFmtDescriptor *src_format = av_pix_fmt_desc_get(c->srcFormat);
+ const AVPixFmtDescriptor *dst_format = av_pix_fmt_desc_get(c->dstFormat);
+ int alpha = 0;
+ int swap = (src_format->flags & AV_PIX_FMT_FLAG_BE) !=
+ (dst_format->flags & AV_PIX_FMT_FLAG_BE);
+ if (src_format->flags & AV_PIX_FMT_FLAG_ALPHA)
+ alpha += 2;
+ if (dst_format->flags & AV_PIX_FMT_FLAG_ALPHA)
+ alpha++;
+
+ if (dst_format->flags & (AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB) !=
+ (AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB) ||
+ dst_format->comp[0].depth_minus1 != 15) {
+ av_log(c, AV_LOG_ERROR, "unsupported conversion to planar RGB %s -> %s\n",
+ src_format->name, dst_format->name);
+ return srcSliceH;
+ }
+ switch (c->srcFormat) {
+ case AV_PIX_FMT_RGB48LE:
+ case AV_PIX_FMT_RGB48BE:
+ case AV_PIX_FMT_RGBA64LE:
+ case AV_PIX_FMT_RGBA64BE:
+ packed16togbra16(src[0] + srcSliceY * srcStride[0], srcStride[0],
+ dst2013, stride2013, srcSliceH, alpha, swap, c->srcW);
+ break;
+ case AV_PIX_FMT_BGR48LE:
+ case AV_PIX_FMT_BGR48BE:
+ case AV_PIX_FMT_BGRA64LE:
+ case AV_PIX_FMT_BGRA64BE:
+ packed16togbra16(src[0] + srcSliceY * srcStride[0], srcStride[0],
+ dst1023, stride1023, srcSliceH, alpha, swap, c->srcW);
+ break;
+ default:
+ av_log(c, AV_LOG_ERROR,
+ "unsupported conversion to planar RGB %s -> %s\n",
+ src_format->name, dst_format->name);
+ }
+
+ return srcSliceH;
+}
+
+static void gbra16ptopacked16(const uint16_t *src[], int srcStride[],
+ uint8_t *dst, int dstStride, int srcSliceH,
+ int alpha, int swap, int width)
+{
+ int x, h, i;
+ for (h = 0; h < srcSliceH; h++) {
+ uint16_t *dest = (uint16_t *)(dst + dstStride * h);
+
+ switch(alpha) {
+ case 3:
+ if (swap) {
+ for (x = 0; x < width; x++) {
+ *dest++ = av_bswap16(src[0][x]);
+ *dest++ = av_bswap16(src[1][x]);
+ *dest++ = av_bswap16(src[2][x]);
+ *dest++ = av_bswap16(src[3][x]);
+ }
+ } else {
+ for (x = 0; x < width; x++) {
+ *dest++ = src[0][x];
+ *dest++ = src[1][x];
+ *dest++ = src[2][x];
+ *dest++ = src[3][x];
+ }
+ }
+ break;
+ case 1:
+ if (swap) {
+ for (x = 0; x < width; x++) {
+ *dest++ = av_bswap16(src[0][x]);
+ *dest++ = av_bswap16(src[1][x]);
+ *dest++ = av_bswap16(src[2][x]);
+ *dest++ = 0xFFFF;
+ }
+ } else {
+ for (x = 0; x < width; x++) {
+ *dest++ = src[0][x];
+ *dest++ = src[1][x];
+ *dest++ = src[2][x];
+ *dest++ = 0xFFFF;
+ }
+ }
+ break;
+ default:
+ if (swap) {
+ for (x = 0; x < width; x++) {
+ *dest++ = av_bswap16(src[0][x]);
+ *dest++ = av_bswap16(src[1][x]);
+ *dest++ = av_bswap16(src[2][x]);
+ }
+ } else {
+ for (x = 0; x < width; x++) {
+ *dest++ = src[0][x];
+ *dest++ = src[1][x];
+ *dest++ = src[2][x];
+ }
+ }
+ break;
+ }
+ for (i = 0; i < 4; i++)
+ src[i] += srcStride[i] >> 1;
+ }
+}
+
+static int planarRgba16ToRgb16Wrapper(SwsContext *c, const uint8_t *src[],
+ int srcStride[], int srcSliceY, int srcSliceH,
+ uint8_t *dst[], int dstStride[])
+{
+ const uint16_t *src1023[] = { (uint16_t *)src[1], (uint16_t *)src[0], (uint16_t *)src[2], (uint16_t *)src[3] };
+ const uint16_t *src2013[] = { (uint16_t *)src[2], (uint16_t *)src[0], (uint16_t *)src[1], (uint16_t *)src[3] };
+ int stride1023[] = { srcStride[1], srcStride[0], srcStride[2], srcStride[3] };
+ int stride2013[] = { srcStride[2], srcStride[0], srcStride[1], srcStride[3] };
+ const AVPixFmtDescriptor *src_format = av_pix_fmt_desc_get(c->srcFormat);
+ const AVPixFmtDescriptor *dst_format = av_pix_fmt_desc_get(c->dstFormat);
+ int alpha = 0;
+ int swap = (src_format->flags & AV_PIX_FMT_FLAG_BE) !=
+ (dst_format->flags & AV_PIX_FMT_FLAG_BE);
+ if (src_format->flags & AV_PIX_FMT_FLAG_ALPHA)
+ alpha += 2;
+ if (dst_format->flags & AV_PIX_FMT_FLAG_ALPHA)
+ alpha++;
+
+ if (src_format->flags & (AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB) !=
+ (AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB) ||
+ src_format->comp[0].depth_minus1 != 15) {
+ av_log(c, AV_LOG_ERROR, "unsupported planar RGB conversion %s -> %s\n",
+ src_format->name, dst_format->name);
+ return srcSliceH;
+ }
+ switch (c->dstFormat) {
+ case AV_PIX_FMT_RGB48LE:
+ case AV_PIX_FMT_RGB48BE:
+ case AV_PIX_FMT_RGBA64LE:
+ case AV_PIX_FMT_RGBA64BE:
+ gbra16ptopacked16(src2013, stride2013,
+ dst[0] + srcSliceY * dstStride[0], dstStride[0],
+ srcSliceH, alpha, swap, c->srcW);
+ break;
+ case AV_PIX_FMT_BGR48LE:
+ case AV_PIX_FMT_BGR48BE:
+ case AV_PIX_FMT_BGRA64LE:
+ case AV_PIX_FMT_BGRA64BE:
+ gbra16ptopacked16(src1023, stride1023,
+ dst[0] + srcSliceY * dstStride[0], dstStride[0],
+ srcSliceH, alpha, swap, c->srcW);
+ break;
+ default:
+ av_log(c, AV_LOG_ERROR,
+ "unsupported planar RGB conversion %s -> %s\n",
+ src_format->name, dst_format->name);
+ }
+
+ return srcSliceH;
+}
+
static void gbr16ptopacked16(const uint16_t *src[], int srcStride[],
uint8_t *dst, int dstStride, int srcSliceH,
int alpha, int swap, int bpp, int width)
@@ -1215,8 +1458,23 @@ void ff_get_unscaled_swscale(SwsContext *c)
if (srcFormat == AV_PIX_FMT_GBRP && isPlanar(srcFormat) && isByteRGB(dstFormat))
c->swScale = planarRgbToRgbWrapper;
+ if ((srcFormat == AV_PIX_FMT_RGB48LE || srcFormat == AV_PIX_FMT_RGB48BE ||
+ srcFormat == AV_PIX_FMT_BGR48LE || srcFormat == AV_PIX_FMT_BGR48BE ||
+ srcFormat == AV_PIX_FMT_RGBA64LE || srcFormat == AV_PIX_FMT_RGBA64BE ||
+ srcFormat == AV_PIX_FMT_BGRA64LE || srcFormat == AV_PIX_FMT_BGRA64BE) &&
+ (dstFormat == AV_PIX_FMT_GBRAP16LE || dstFormat == AV_PIX_FMT_GBRAP16BE ||
+ dstFormat == AV_PIX_FMT_GBRP16LE || dstFormat == AV_PIX_FMT_GBRP16BE ))
+ c->swScale = Rgb16ToPlanarRgb16Wrapper;
+
+ if ((srcFormat == AV_PIX_FMT_GBRAP16LE || srcFormat == AV_PIX_FMT_GBRAP16BE ||
+ srcFormat == AV_PIX_FMT_GBRP16LE || srcFormat == AV_PIX_FMT_GBRP16BE ) &&
+ (dstFormat == AV_PIX_FMT_RGB48LE || dstFormat == AV_PIX_FMT_RGB48BE ||
+ dstFormat == AV_PIX_FMT_BGR48LE || dstFormat == AV_PIX_FMT_BGR48BE ||
+ dstFormat == AV_PIX_FMT_RGBA64LE || dstFormat == AV_PIX_FMT_RGBA64BE ||
+ dstFormat == AV_PIX_FMT_BGRA64LE || dstFormat == AV_PIX_FMT_BGRA64BE))
+ c->swScale = planarRgba16ToRgb16Wrapper;
+
if ((srcFormat == AV_PIX_FMT_GBRP9LE || srcFormat == AV_PIX_FMT_GBRP9BE ||
- srcFormat == AV_PIX_FMT_GBRP16LE || srcFormat == AV_PIX_FMT_GBRP16BE ||
srcFormat == AV_PIX_FMT_GBRP10LE || srcFormat == AV_PIX_FMT_GBRP10BE ||
srcFormat == AV_PIX_FMT_GBRP12LE || srcFormat == AV_PIX_FMT_GBRP12BE ||
srcFormat == AV_PIX_FMT_GBRP14LE || srcFormat == AV_PIX_FMT_GBRP14BE) &&
diff --git a/libswscale/utils.c b/libswscale/utils.c
index 6324bc8..4c5bda7 100644
--- a/libswscale/utils.c
+++ b/libswscale/utils.c
@@ -197,13 +197,13 @@ static const FormatEntry format_entries[AV_PIX_FMT_NB] = {
[AV_PIX_FMT_GBRP12BE] = { 1, 1 },
[AV_PIX_FMT_GBRP14LE] = { 1, 1 },
[AV_PIX_FMT_GBRP14BE] = { 1, 1 },
- [AV_PIX_FMT_GBRP16LE] = { 1, 0 },
- [AV_PIX_FMT_GBRP16BE] = { 1, 0 },
+ [AV_PIX_FMT_GBRP16LE] = { 1, 1 },
+ [AV_PIX_FMT_GBRP16BE] = { 1, 1 },
[AV_PIX_FMT_XYZ12BE] = { 1, 0, 1 },
[AV_PIX_FMT_XYZ12LE] = { 1, 0, 1 },
[AV_PIX_FMT_GBRAP] = { 1, 1 },
- [AV_PIX_FMT_GBRAP16LE] = { 1, 0 },
- [AV_PIX_FMT_GBRAP16BE] = { 1, 0 },
+ [AV_PIX_FMT_GBRAP16LE] = { 1, 1 },
+ [AV_PIX_FMT_GBRAP16BE] = { 1, 1 },
};
int sws_isSupportedInput(enum AVPixelFormat pix_fmt)
More information about the ffmpeg-devel
mailing list