summaryrefslogtreecommitdiff
path: root/libswscale/utils.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michael@niedermayer.cc>2015-08-06 16:36:05 +0200
committerMichael Niedermayer <michael@niedermayer.cc>2015-08-08 13:24:52 +0200
commitd0e0757e9a965549a63fa7f6f7c4542883f80d18 (patch)
treeba1a633ea8651ddac9078622c24a5b84dc5fd78c /libswscale/utils.c
parentc382d9e8cbee7635755a559fcd03834aa3daa3a7 (diff)
swscale: Implement alphablendaway for planar 4:4:4 formats
Fixes Ticket4746 Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Diffstat (limited to 'libswscale/utils.c')
-rw-r--r--libswscale/utils.c101
1 files changed, 101 insertions, 0 deletions
diff --git a/libswscale/utils.c b/libswscale/utils.c
index 106101ab0b..d00164361b 100644
--- a/libswscale/utils.c
+++ b/libswscale/utils.c
@@ -979,6 +979,58 @@ static uint16_t * alloc_gamma_tbl(double e)
return tbl;
}
+static enum AVPixelFormat alphaless_fmt(enum AVPixelFormat fmt)
+{
+ switch(fmt) {
+// case AV_PIX_FMT_ARGB: return AV_PIX_FMT_RGB24;
+// case AV_PIX_FMT_RGBA: return AV_PIX_FMT_RGB24;
+// case AV_PIX_FMT_ABGR: return AV_PIX_FMT_BGR24;
+// case AV_PIX_FMT_BGRA: return AV_PIX_FMT_BGR24;
+// case AV_PIX_FMT_YA8: return AV_PIX_FMT_GRAY8;
+//
+// case AV_PIX_FMT_YUVA420P: return AV_PIX_FMT_YUV420P;
+// case AV_PIX_FMT_YUVA422P: return AV_PIX_FMT_YUV422P;
+ case AV_PIX_FMT_YUVA444P: return AV_PIX_FMT_YUV444P;
+
+ case AV_PIX_FMT_GBRAP: return AV_PIX_FMT_GBRP;
+
+ case AV_PIX_FMT_GBRAP16LE: return AV_PIX_FMT_GBRP16;
+ case AV_PIX_FMT_GBRAP16BE: return AV_PIX_FMT_GBRP16;
+
+// case AV_PIX_FMT_RGBA64LE: return AV_PIX_FMT_RGB48;
+// case AV_PIX_FMT_RGBA64BE: return AV_PIX_FMT_RGB48;
+// case AV_PIX_FMT_BGRA64LE: return AV_PIX_FMT_BGR48;
+// case AV_PIX_FMT_BGRA64BE: return AV_PIX_FMT_BGR48;
+
+// case AV_PIX_FMT_YA16BE: return AV_PIX_FMT_GRAY16;
+// case AV_PIX_FMT_YA16LE: return AV_PIX_FMT_GRAY16;
+
+// case AV_PIX_FMT_YUVA420P9BE: return AV_PIX_FMT_YUV420P9;
+// case AV_PIX_FMT_YUVA422P9BE: return AV_PIX_FMT_YUV422P9;
+ case AV_PIX_FMT_YUVA444P9BE: return AV_PIX_FMT_YUV444P9;
+// case AV_PIX_FMT_YUVA420P9LE: return AV_PIX_FMT_YUV420P9;
+// case AV_PIX_FMT_YUVA422P9LE: return AV_PIX_FMT_YUV422P9;
+ case AV_PIX_FMT_YUVA444P9LE: return AV_PIX_FMT_YUV444P9;
+// case AV_PIX_FMT_YUVA420P10BE: return AV_PIX_FMT_YUV420P10;
+// case AV_PIX_FMT_YUVA422P10BE: return AV_PIX_FMT_YUV422P10;
+ case AV_PIX_FMT_YUVA444P10BE: return AV_PIX_FMT_YUV444P10;
+// case AV_PIX_FMT_YUVA420P10LE: return AV_PIX_FMT_YUV420P10;
+// case AV_PIX_FMT_YUVA422P10LE: return AV_PIX_FMT_YUV422P10;
+ case AV_PIX_FMT_YUVA444P10LE: return AV_PIX_FMT_YUV444P10;
+// case AV_PIX_FMT_YUVA420P16BE: return AV_PIX_FMT_YUV420P16;
+// case AV_PIX_FMT_YUVA422P16BE: return AV_PIX_FMT_YUV422P16;
+ case AV_PIX_FMT_YUVA444P16BE: return AV_PIX_FMT_YUV444P16;
+// case AV_PIX_FMT_YUVA420P16LE: return AV_PIX_FMT_YUV420P16;
+// case AV_PIX_FMT_YUVA422P16LE: return AV_PIX_FMT_YUV422P16;
+ case AV_PIX_FMT_YUVA444P16LE: return AV_PIX_FMT_YUV444P16;
+
+// case AV_PIX_FMT_AYUV64LE:
+// case AV_PIX_FMT_AYUV64BE:
+// case AV_PIX_FMT_PAL8:
+ default: return AV_PIX_FMT_NONE;
+ }
+}
+
av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter,
SwsFilter *dstFilter)
{
@@ -1340,6 +1392,39 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter,
}
}
+ if (CONFIG_SWSCALE_ALPHA && isALPHA(srcFormat) && !isALPHA(dstFormat)) {
+ enum AVPixelFormat tmpFormat = alphaless_fmt(srcFormat);
+
+ if (tmpFormat != AV_PIX_FMT_NONE && c->alphablend != SWS_ALPHA_BLEND_NONE)
+ if (!unscaled ||
+ dstFormat != tmpFormat ||
+ usesHFilter || usesVFilter ||
+ c->srcRange != c->dstRange
+ ) {
+ ret = av_image_alloc(c->cascaded_tmp, c->cascaded_tmpStride,
+ srcW, srcH, tmpFormat, 64);
+ if (ret < 0)
+ return ret;
+
+ c->cascaded_context[0] = sws_alloc_set_opts(srcW, srcH, srcFormat,
+ srcW, srcH, tmpFormat,
+ flags, c->param);
+ if (!c->cascaded_context[0])
+ return -1;
+ c->cascaded_context[0]->alphablend = c->alphablend;
+ ret = sws_init_context(c->cascaded_context[0], NULL , NULL);
+ if (ret < 0)
+ return ret;
+
+ c->cascaded_context[1] = sws_getContext(srcW, srcH, tmpFormat,
+ dstW, dstH, dstFormat,
+ flags, srcFilter, dstFilter, c->param);
+ if (!c->cascaded_context[1])
+ return -1;
+ return 0;
+ }
+ }
+
#define USE_MMAP (HAVE_MMAP && HAVE_MPROTECT && defined MAP_ANONYMOUS)
/* precalculate horizontal scaler filter coefficients */
@@ -1586,6 +1671,22 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter,
c->chrXInc, c->chrYInc);
}
+ /* alpha blend special case, note this has been split via cascaded contexts if its scaled */
+ if (unscaled && !usesHFilter && !usesVFilter &&
+ c->alphablend != SWS_ALPHA_BLEND_NONE &&
+ isALPHA(srcFormat) &&
+ (c->srcRange == c->dstRange || isAnyRGB(dstFormat)) &&
+ alphaless_fmt(srcFormat) == dstFormat
+ ) {
+ c->swscale = ff_sws_alphablendaway;
+
+ if (flags & SWS_PRINT_INFO)
+ av_log(c, AV_LOG_INFO,
+ "using alpha blendaway %s -> %s special converter\n",
+ av_get_pix_fmt_name(srcFormat), av_get_pix_fmt_name(dstFormat));
+ return 0;
+ }
+
/* unscaled special cases */
if (unscaled && !usesHFilter && !usesVFilter &&
(c->srcRange == c->dstRange || isAnyRGB(dstFormat))) {