diff options
Diffstat (limited to 'libswscale/utils.c')
-rw-r--r-- | libswscale/utils.c | 101 |
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))) { |