From fa36f33422ebcf02c84328ea852ecda68d93d830 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 3 Jul 2012 04:10:11 +0200 Subject: sws: support 12&14 bit planar colorspaces Reviewed-by: Paul B Mahol Signed-off-by: Michael Niedermayer --- libswscale/input.c | 92 +++++++++++++++++++++++++++++++++++++++ libswscale/ppc/swscale_altivec.c | 2 +- libswscale/swscale.c | 6 +-- libswscale/swscale_internal.h | 4 +- libswscale/utils.c | 22 ++++++++-- libswscale/x86/swscale_mmx.c | 14 +++--- libswscale/x86/swscale_template.c | 2 +- 7 files changed, 126 insertions(+), 16 deletions(-) (limited to 'libswscale') diff --git a/libswscale/input.c b/libswscale/input.c index c9c91d0bca..9d03c681ac 100644 --- a/libswscale/input.c +++ b/libswscale/input.c @@ -727,6 +727,26 @@ static void planar_rgb10be_to_y(uint8_t *dst, const uint8_t *src[4], int w) planar_rgb16_to_y(dst, src, w, 10, 1); } +static void planar_rgb12le_to_y(uint8_t *dst, const uint8_t *src[4], int w) +{ + planar_rgb16_to_y(dst, src, w, 12, 0); +} + +static void planar_rgb12be_to_y(uint8_t *dst, const uint8_t *src[4], int w) +{ + planar_rgb16_to_y(dst, src, w, 12, 1); +} + +static void planar_rgb14le_to_y(uint8_t *dst, const uint8_t *src[4], int w) +{ + planar_rgb16_to_y(dst, src, w, 14, 0); +} + +static void planar_rgb14be_to_y(uint8_t *dst, const uint8_t *src[4], int w) +{ + planar_rgb16_to_y(dst, src, w, 14, 1); +} + static void planar_rgb16le_to_y(uint8_t *dst, const uint8_t *src[4], int w) { planar_rgb16_to_y(dst, src, w, 16, 0); @@ -780,6 +800,30 @@ static void planar_rgb10be_to_uv(uint8_t *dstU, uint8_t *dstV, planar_rgb16_to_uv(dstU, dstV, src, w, 10, 1); } +static void planar_rgb12le_to_uv(uint8_t *dstU, uint8_t *dstV, + const uint8_t *src[4], int w) +{ + planar_rgb16_to_uv(dstU, dstV, src, w, 12, 0); +} + +static void planar_rgb12be_to_uv(uint8_t *dstU, uint8_t *dstV, + const uint8_t *src[4], int w) +{ + planar_rgb16_to_uv(dstU, dstV, src, w, 12, 1); +} + +static void planar_rgb14le_to_uv(uint8_t *dstU, uint8_t *dstV, + const uint8_t *src[4], int w) +{ + planar_rgb16_to_uv(dstU, dstV, src, w, 14, 0); +} + +static void planar_rgb14be_to_uv(uint8_t *dstU, uint8_t *dstV, + const uint8_t *src[4], int w) +{ + planar_rgb16_to_uv(dstU, dstV, src, w, 14, 1); +} + static void planar_rgb16le_to_uv(uint8_t *dstU, uint8_t *dstV, const uint8_t *src[4], int w) { @@ -823,6 +867,12 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case PIX_FMT_GBRP10LE: c->readChrPlanar = planar_rgb10le_to_uv; break; + case PIX_FMT_GBRP12LE: + c->readChrPlanar = planar_rgb12le_to_uv; + break; + case PIX_FMT_GBRP14LE: + c->readChrPlanar = planar_rgb14le_to_uv; + break; case PIX_FMT_GBRP16LE: c->readChrPlanar = planar_rgb16le_to_uv; break; @@ -832,6 +882,12 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case PIX_FMT_GBRP10BE: c->readChrPlanar = planar_rgb10be_to_uv; break; + case PIX_FMT_GBRP12BE: + c->readChrPlanar = planar_rgb12be_to_uv; + break; + case PIX_FMT_GBRP14BE: + c->readChrPlanar = planar_rgb14be_to_uv; + break; case PIX_FMT_GBRP16BE: c->readChrPlanar = planar_rgb16be_to_uv; break; @@ -845,6 +901,12 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case PIX_FMT_YUV422P10LE: case PIX_FMT_YUV444P10LE: case PIX_FMT_YUV420P10LE: + case PIX_FMT_YUV422P12LE: + case PIX_FMT_YUV444P12LE: + case PIX_FMT_YUV420P12LE: + case PIX_FMT_YUV422P14LE: + case PIX_FMT_YUV444P14LE: + case PIX_FMT_YUV420P14LE: case PIX_FMT_YUV420P16LE: case PIX_FMT_YUV422P16LE: case PIX_FMT_YUV444P16LE: @@ -857,6 +919,12 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case PIX_FMT_YUV444P10BE: case PIX_FMT_YUV422P10BE: case PIX_FMT_YUV420P10BE: + case PIX_FMT_YUV444P12BE: + case PIX_FMT_YUV422P12BE: + case PIX_FMT_YUV420P12BE: + case PIX_FMT_YUV444P14BE: + case PIX_FMT_YUV422P14BE: + case PIX_FMT_YUV420P14BE: case PIX_FMT_YUV420P16BE: case PIX_FMT_YUV422P16BE: case PIX_FMT_YUV444P16BE: @@ -1028,6 +1096,12 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case PIX_FMT_GBRP10LE: c->readLumPlanar = planar_rgb10le_to_y; break; + case PIX_FMT_GBRP12LE: + c->readLumPlanar = planar_rgb12le_to_y; + break; + case PIX_FMT_GBRP14LE: + c->readLumPlanar = planar_rgb14le_to_y; + break; case PIX_FMT_GBRP16LE: c->readLumPlanar = planar_rgb16le_to_y; break; @@ -1037,6 +1111,12 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case PIX_FMT_GBRP10BE: c->readLumPlanar = planar_rgb10be_to_y; break; + case PIX_FMT_GBRP12BE: + c->readLumPlanar = planar_rgb12be_to_y; + break; + case PIX_FMT_GBRP14BE: + c->readLumPlanar = planar_rgb14be_to_y; + break; case PIX_FMT_GBRP16BE: c->readLumPlanar = planar_rgb16be_to_y; break; @@ -1050,6 +1130,12 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case PIX_FMT_YUV444P10LE: case PIX_FMT_YUV422P10LE: case PIX_FMT_YUV420P10LE: + case PIX_FMT_YUV444P12LE: + case PIX_FMT_YUV422P12LE: + case PIX_FMT_YUV420P12LE: + case PIX_FMT_YUV444P14LE: + case PIX_FMT_YUV422P14LE: + case PIX_FMT_YUV420P14LE: case PIX_FMT_YUV420P16LE: case PIX_FMT_YUV422P16LE: case PIX_FMT_YUV444P16LE: @@ -1063,6 +1149,12 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case PIX_FMT_YUV444P10BE: case PIX_FMT_YUV422P10BE: case PIX_FMT_YUV420P10BE: + case PIX_FMT_YUV444P12BE: + case PIX_FMT_YUV422P12BE: + case PIX_FMT_YUV420P12BE: + case PIX_FMT_YUV444P14BE: + case PIX_FMT_YUV422P14BE: + case PIX_FMT_YUV420P14BE: case PIX_FMT_YUV420P16BE: case PIX_FMT_YUV422P16BE: case PIX_FMT_YUV444P16BE: diff --git a/libswscale/ppc/swscale_altivec.c b/libswscale/ppc/swscale_altivec.c index df8afb0ba2..694c8d8b9a 100644 --- a/libswscale/ppc/swscale_altivec.c +++ b/libswscale/ppc/swscale_altivec.c @@ -317,7 +317,7 @@ void ff_sws_init_swScale_altivec(SwsContext *c) if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC)) return; - if (c->srcBpc == 8 && c->dstBpc <= 10) { + if (c->srcBpc == 8 && c->dstBpc <= 14) { c->hyScale = c->hcScale = hScale_altivec_real; } if (!is16BPS(dstFormat) && !is9_OR_10BPS(dstFormat) && diff --git a/libswscale/swscale.c b/libswscale/swscale.c index 5dd4124eba..1f807852d5 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -691,7 +691,7 @@ static av_cold void sws_init_swScale_c(SwsContext *c) if (c->srcBpc == 8) { - if (c->dstBpc <= 10) { + if (c->dstBpc <= 14) { c->hyScale = c->hcScale = hScale8To15_c; if (c->flags & SWS_FAST_BILINEAR) { c->hyscale_fast = hyscale_fast_c; @@ -701,12 +701,12 @@ static av_cold void sws_init_swScale_c(SwsContext *c) c->hyScale = c->hcScale = hScale8To19_c; } } else { - c->hyScale = c->hcScale = c->dstBpc > 10 ? hScale16To19_c + c->hyScale = c->hcScale = c->dstBpc > 14 ? hScale16To19_c : hScale16To15_c; } if (c->srcRange != c->dstRange && !isAnyRGB(c->dstFormat)) { - if (c->dstBpc <= 10) { + if (c->dstBpc <= 14) { if (c->srcRange) { c->lumConvertRange = lumRangeFromJpeg_c; c->chrConvertRange = chrRangeFromJpeg_c; diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index ae53b88e7f..5a584f04ca 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -558,8 +558,8 @@ const char *sws_format_name(enum PixelFormat format); (av_pix_fmt_descriptors[x].comp[0].depth_minus1 == 15) #define is9_OR_10BPS(x) \ - (av_pix_fmt_descriptors[x].comp[0].depth_minus1 == 8 || \ - av_pix_fmt_descriptors[x].comp[0].depth_minus1 == 9) + (av_pix_fmt_descriptors[x].comp[0].depth_minus1 >= 8 && \ + av_pix_fmt_descriptors[x].comp[0].depth_minus1 <= 13) #define isNBPS(x) is9_OR_10BPS(x) diff --git a/libswscale/utils.c b/libswscale/utils.c index 9508413664..4047fb57ee 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -145,19 +145,35 @@ static const FormatEntry format_entries[PIX_FMT_NB] = { [PIX_FMT_YUV420P9LE] = { 1, 1 }, [PIX_FMT_YUV420P10BE] = { 1, 1 }, [PIX_FMT_YUV420P10LE] = { 1, 1 }, + [PIX_FMT_YUV420P12BE] = { 1, 1 }, + [PIX_FMT_YUV420P12LE] = { 1, 1 }, + [PIX_FMT_YUV420P14BE] = { 1, 1 }, + [PIX_FMT_YUV420P14LE] = { 1, 1 }, [PIX_FMT_YUV422P9BE] = { 1, 1 }, [PIX_FMT_YUV422P9LE] = { 1, 1 }, [PIX_FMT_YUV422P10BE] = { 1, 1 }, [PIX_FMT_YUV422P10LE] = { 1, 1 }, + [PIX_FMT_YUV422P12BE] = { 1, 1 }, + [PIX_FMT_YUV422P12LE] = { 1, 1 }, + [PIX_FMT_YUV422P14BE] = { 1, 1 }, + [PIX_FMT_YUV422P14LE] = { 1, 1 }, [PIX_FMT_YUV444P9BE] = { 1, 1 }, [PIX_FMT_YUV444P9LE] = { 1, 1 }, [PIX_FMT_YUV444P10BE] = { 1, 1 }, [PIX_FMT_YUV444P10LE] = { 1, 1 }, + [PIX_FMT_YUV444P12BE] = { 1, 1 }, + [PIX_FMT_YUV444P12LE] = { 1, 1 }, + [PIX_FMT_YUV444P14BE] = { 1, 1 }, + [PIX_FMT_YUV444P14LE] = { 1, 1 }, [PIX_FMT_GBRP] = { 1, 0 }, [PIX_FMT_GBRP9LE] = { 1, 0 }, [PIX_FMT_GBRP9BE] = { 1, 0 }, [PIX_FMT_GBRP10LE] = { 1, 0 }, [PIX_FMT_GBRP10BE] = { 1, 0 }, + [PIX_FMT_GBRP12LE] = { 1, 0 }, + [PIX_FMT_GBRP12BE] = { 1, 0 }, + [PIX_FMT_GBRP14LE] = { 1, 0 }, + [PIX_FMT_GBRP14BE] = { 1, 0 }, [PIX_FMT_GBRP16LE] = { 1, 0 }, [PIX_FMT_GBRP16BE] = { 1, 0 }, }; @@ -1006,7 +1022,7 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) dst_stride <<= 1; FF_ALLOC_OR_GOTO(c, c->formatConvBuffer, FFALIGN(srcW*2+78, 16) * 2, fail); if (HAVE_MMX2 && cpu_flags & AV_CPU_FLAG_MMX2 && - c->srcBpc == 8 && c->dstBpc <= 10) { + c->srcBpc == 8 && c->dstBpc <= 14) { c->canMMX2BeUsed = (dstW >= srcW && (dstW & 31) == 0 && (srcW & 15) == 0) ? 1 : 0; if (!c->canMMX2BeUsed && dstW >= srcW && (srcW & 15) == 0 @@ -1036,7 +1052,7 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) c->chrXInc += 20; } // we don't use the x86 asm scaler if MMX is available - else if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX && c->dstBpc <= 10) { + else if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX && c->dstBpc <= 14) { c->lumXInc = ((int64_t)(srcW - 2) << 16) / (dstW - 2) - 20; c->chrXInc = ((int64_t)(c->chrSrcW - 2) << 16) / (c->chrDstW - 2) - 20; } @@ -1207,7 +1223,7 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) // try to avoid drawing green stuff between the right end and the stride end for (i = 0; i < c->vChrBufSize; i++) if(av_pix_fmt_descriptors[c->dstFormat].comp[0].depth_minus1 == 15){ - av_assert0(c->dstBpc > 10); + av_assert0(c->dstBpc > 14); for(j=0; jchrUPixBuf[i]))[j] = 1<<18; } else diff --git a/libswscale/x86/swscale_mmx.c b/libswscale/x86/swscale_mmx.c index 9f7aa80e2b..bb88d3478a 100644 --- a/libswscale/x86/swscale_mmx.c +++ b/libswscale/x86/swscale_mmx.c @@ -22,6 +22,7 @@ #include "config.h" #include "libswscale/swscale.h" #include "libswscale/swscale_internal.h" +#include "libavutil/avassert.h" #include "libavutil/intreadwrite.h" #include "libavutil/x86_cpu.h" #include "libavutil/cpu.h" @@ -378,19 +379,19 @@ void ff_sws_init_swScale_mmx(SwsContext *c) #if HAVE_YASM #define ASSIGN_SCALE_FUNC2(hscalefn, filtersize, opt1, opt2) do { \ if (c->srcBpc == 8) { \ - hscalefn = c->dstBpc <= 10 ? ff_hscale8to15_ ## filtersize ## _ ## opt2 : \ + hscalefn = c->dstBpc <= 14 ? ff_hscale8to15_ ## filtersize ## _ ## opt2 : \ ff_hscale8to19_ ## filtersize ## _ ## opt1; \ } else if (c->srcBpc == 9) { \ - hscalefn = c->dstBpc <= 10 ? ff_hscale9to15_ ## filtersize ## _ ## opt2 : \ + hscalefn = c->dstBpc <= 14 ? ff_hscale9to15_ ## filtersize ## _ ## opt2 : \ ff_hscale9to19_ ## filtersize ## _ ## opt1; \ } else if (c->srcBpc == 10) { \ - hscalefn = c->dstBpc <= 10 ? ff_hscale10to15_ ## filtersize ## _ ## opt2 : \ + hscalefn = c->dstBpc <= 14 ? ff_hscale10to15_ ## filtersize ## _ ## opt2 : \ ff_hscale10to19_ ## filtersize ## _ ## opt1; \ } else if (c->srcBpc == 14 || ((c->srcFormat==PIX_FMT_PAL8||isAnyRGB(c->srcFormat)) && av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1<15)) { \ - hscalefn = c->dstBpc <= 10 ? ff_hscale14to15_ ## filtersize ## _ ## opt2 : \ + hscalefn = c->dstBpc <= 14 ? ff_hscale14to15_ ## filtersize ## _ ## opt2 : \ ff_hscale14to19_ ## filtersize ## _ ## opt1; \ } else { /* c->srcBpc == 16 */ \ - hscalefn = c->dstBpc <= 10 ? ff_hscale16to15_ ## filtersize ## _ ## opt2 : \ + hscalefn = c->dstBpc <= 14 ? ff_hscale16to15_ ## filtersize ## _ ## opt2 : \ ff_hscale16to19_ ## filtersize ## _ ## opt1; \ } \ } while (0) @@ -412,7 +413,8 @@ switch(c->dstBpc){ \ case 16: if (!isBE(c->dstFormat)) vscalefn = ff_yuv2plane1_16_ ## opt1; break; \ case 10: if (!isBE(c->dstFormat) && opt2chk) vscalefn = ff_yuv2plane1_10_ ## opt2; break; \ case 9: if (!isBE(c->dstFormat) && opt2chk) vscalefn = ff_yuv2plane1_9_ ## opt2; break; \ - default: vscalefn = ff_yuv2plane1_8_ ## opt1; break; \ + case 8: vscalefn = ff_yuv2plane1_8_ ## opt1; break; \ + default: av_assert0(c->dstBpc>8); \ } #define case_rgb(x, X, opt) \ case PIX_FMT_ ## X: \ diff --git a/libswscale/x86/swscale_template.c b/libswscale/x86/swscale_template.c index cf8e802229..245bfdeadd 100644 --- a/libswscale/x86/swscale_template.c +++ b/libswscale/x86/swscale_template.c @@ -1689,7 +1689,7 @@ static av_cold void RENAME(sws_init_swScale)(SwsContext *c) } } - if (c->srcBpc == 8 && c->dstBpc <= 10) { + if (c->srcBpc == 8 && c->dstBpc <= 14) { // Use the new MMX scaler if the MMX2 one can't be used (it is faster than the x86 ASM one). #if COMPILE_TEMPLATE_MMX2 if (c->flags & SWS_FAST_BILINEAR && c->canMMX2BeUsed) -- cgit v1.2.3