X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libswscale%2Fswscale.c;h=7756e1b52e65d241e7251e2ba97ea6141d9e24b2;hb=91d305790ea0f6fe0f54b48236da42181c39c18b;hp=0f8ef2b15cbdb1714f26a8ed49b08cc150525d25;hpb=8e5d71d1109bb509ae75d04682f326fe740a413f;p=ffmpeg diff --git a/libswscale/swscale.c b/libswscale/swscale.c index 0f8ef2b15cb..7756e1b52e6 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -35,7 +35,7 @@ #include "swscale_internal.h" #include "swscale.h" -DECLARE_ALIGNED(8, const uint8_t, dither_8x8_128)[8][8] = { +DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_128)[8][8] = { { 36, 68, 60, 92, 34, 66, 58, 90, }, { 100, 4, 124, 28, 98, 2, 122, 26, }, { 52, 84, 44, 76, 50, 82, 42, 74, }, @@ -46,7 +46,7 @@ DECLARE_ALIGNED(8, const uint8_t, dither_8x8_128)[8][8] = { { 112, 16, 104, 8, 118, 22, 110, 14, }, }; -DECLARE_ALIGNED(8, const uint8_t, ff_sws_pb_64)[8] = { +DECLARE_ALIGNED(8, static const uint8_t, sws_pb_64)[8] = { 64, 64, 64, 64, 64, 64, 64, 64 }; @@ -61,14 +61,37 @@ static av_always_inline void fillPlane(uint8_t *plane, int stride, int width, } } +static void fill_plane9or10(uint8_t *plane, int stride, int width, + int height, int y, uint8_t val, + const int dst_depth, const int big_endian) +{ + int i, j; + uint16_t *dst = (uint16_t *) (plane + stride * y); +#define FILL8TO9_OR_10(wfunc) \ + for (i = 0; i < height; i++) { \ + for (j = 0; j < width; j++) { \ + wfunc(&dst[j], (val << (dst_depth - 8)) | \ + (val >> (16 - dst_depth))); \ + } \ + dst += stride / 2; \ + } + if (big_endian) { + FILL8TO9_OR_10(AV_WB16); + } else { + FILL8TO9_OR_10(AV_WL16); + } +} + + static void hScale16To19_c(SwsContext *c, int16_t *_dst, int dstW, const uint8_t *_src, const int16_t *filter, const int32_t *filterPos, int filterSize) { + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat); int i; int32_t *dst = (int32_t *) _dst; const uint16_t *src = (const uint16_t *) _src; - int bits = av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1; + int bits = desc->comp[0].depth_minus1; int sh = bits - 4; for (i = 0; i < dstW; i++) { @@ -88,9 +111,10 @@ static void hScale16To15_c(SwsContext *c, int16_t *dst, int dstW, const uint8_t *_src, const int16_t *filter, const int32_t *filterPos, int filterSize) { + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat); int i; const uint16_t *src = (const uint16_t *) _src; - int sh = av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1; + int sh = desc->comp[0].depth_minus1; for (i = 0; i < dstW; i++) { int j; @@ -139,7 +163,7 @@ static void hScale8To19_c(SwsContext *c, int16_t *_dst, int dstW, } } -// FIXME all pal and rgb srcFormats could do this convertion as well +// FIXME all pal and rgb srcFormats could do this conversion as well // FIXME all scalers more complex than bilinear could do half of this transform static void chrRangeToJpeg_c(int16_t *dstU, int16_t *dstV, int width) { @@ -313,7 +337,7 @@ static av_always_inline void hcscale(SwsContext *c, int16_t *dst1, if (DEBUG_SWSCALE_BUFFERS) \ av_log(c, AV_LOG_DEBUG, __VA_ARGS__) -static int swScale(SwsContext *c, const uint8_t *src[], +static int swscale(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[]) { @@ -326,7 +350,7 @@ static int swScale(SwsContext *c, const uint8_t *src[], const int chrSrcW = c->chrSrcW; const int lumXInc = c->lumXInc; const int chrXInc = c->chrXInc; - const enum PixelFormat dstFormat = c->dstFormat; + const enum AVPixelFormat dstFormat = c->dstFormat; const int flags = c->flags; int32_t *vLumFilterPos = c->vLumFilterPos; int32_t *vChrFilterPos = c->vChrFilterPos; @@ -356,6 +380,7 @@ static int swScale(SwsContext *c, const uint8_t *src[], yuv2packed1_fn yuv2packed1 = c->yuv2packed1; yuv2packed2_fn yuv2packed2 = c->yuv2packed2; yuv2packedX_fn yuv2packedX = c->yuv2packedX; + yuv2anyX_fn yuv2anyX = c->yuv2anyX; const int chrSrcSliceY = srcSliceY >> c->chrSrcVSubSample; const int chrSrcSliceH = -((-srcSliceH) >> c->chrSrcVSubSample); int should_dither = is9_OR_10BPS(c->srcFormat) || @@ -382,7 +407,7 @@ static int swScale(SwsContext *c, const uint8_t *src[], srcStride[1] <<= c->vChrDrop; srcStride[2] <<= c->vChrDrop; - DEBUG_BUFFERS("swScale() %p[%d] %p[%d] %p[%d] %p[%d] -> %p[%d] %p[%d] %p[%d] %p[%d]\n", + DEBUG_BUFFERS("swscale() %p[%d] %p[%d] %p[%d] %p[%d] -> %p[%d] %p[%d] %p[%d] %p[%d]\n", src[0], srcStride[0], src[1], srcStride[1], src[2], srcStride[2], src[3], srcStride[3], dst[0], dstStride[0], dst[1], dstStride[1], @@ -415,7 +440,7 @@ static int swScale(SwsContext *c, const uint8_t *src[], } if (!should_dither) { - c->chrDither8 = c->lumDither8 = ff_sws_pb_64; + c->chrDither8 = c->lumDither8 = sws_pb_64; } lastDstY = dstY; @@ -518,19 +543,19 @@ static int swScale(SwsContext *c, const uint8_t *src[], if (!enough_lines) break; // we can't output a dstY line so let's try with the next slice -#if HAVE_MMX && HAVE_INLINE_ASM +#if HAVE_MMX_INLINE updateMMXDitherTables(c, dstY, lumBufIndex, chrBufIndex, lastInLumBuf, lastInChrBuf); #endif if (should_dither) { - c->chrDither8 = dither_8x8_128[chrDstY & 7]; - c->lumDither8 = dither_8x8_128[dstY & 7]; + c->chrDither8 = ff_dither_8x8_128[chrDstY & 7]; + c->lumDither8 = ff_dither_8x8_128[dstY & 7]; } if (dstY >= dstH - 2) { /* hmm looks like we can't use MMX here without overwriting * this array's tail */ ff_sws_init_output_funcs(c, &yuv2plane1, &yuv2planeX, &yuv2nv12cX, - &yuv2packed1, &yuv2packed2, &yuv2packedX); + &yuv2packed1, &yuv2packed2, &yuv2packedX, &yuv2anyX); } { @@ -627,9 +652,7 @@ static int swScale(SwsContext *c, const uint8_t *src[], dstW, c->lumDither8, 0); } } - } else { - assert(lumSrcPtr + vLumFilterSize - 1 < lumPixBuf + vLumBufSize * 2); - assert(chrUSrcPtr + vChrFilterSize - 1 < chrUPixBuf + vChrBufSize * 2); + } else if (yuv2packedX) { if (c->yuv2packed1 && vLumFilterSize == 1 && vChrFilterSize <= 2) { // unscaled RGB int chrAlpha = vChrFilterSize == 1 ? 0 : vChrFilter[2 * dstY + 1]; @@ -654,15 +677,33 @@ static int swScale(SwsContext *c, const uint8_t *src[], chrUSrcPtr, chrVSrcPtr, vChrFilterSize, alpSrcPtr, dest[0], dstW, dstY); } + } else { + yuv2anyX(c, vLumFilter + dstY * vLumFilterSize, + lumSrcPtr, vLumFilterSize, + vChrFilter + dstY * vChrFilterSize, + chrUSrcPtr, chrVSrcPtr, vChrFilterSize, + alpSrcPtr, dest, dstW, dstY); } } } - if (isPlanar(dstFormat) && isALPHA(dstFormat) && !alpPixBuf) - fillPlane(dst[3], dstStride[3], dstW, dstY - lastDstY, lastDstY, 255); + if (isPlanar(dstFormat) && isALPHA(dstFormat) && !alpPixBuf) { + int length = dstW; + int height = dstY - lastDstY; + if (is16BPS(c->dstFormat)) + length *= 2; + + if (is9_OR_10BPS(dstFormat)) { + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(dstFormat); + fill_plane9or10(dst[3], dstStride[3], length, height, lastDstY, + 255, desc->comp[3].depth_minus1 + 1, + isBE(dstFormat)); + } else + fillPlane(dst[3], dstStride[3], length, height, lastDstY, 255); + } -#if HAVE_MMX2 && HAVE_INLINE_ASM - if (av_get_cpu_flags() & AV_CPU_FLAG_MMX2) +#if HAVE_MMXEXT_INLINE + if (av_get_cpu_flags() & AV_CPU_FLAG_MMXEXT) __asm__ volatile ("sfence" ::: "memory"); #endif emms_c(); @@ -677,13 +718,13 @@ static int swScale(SwsContext *c, const uint8_t *src[], return dstY - lastDstY; } -static av_cold void sws_init_swScale_c(SwsContext *c) +static av_cold void sws_init_swscale(SwsContext *c) { - enum PixelFormat srcFormat = c->srcFormat; + enum AVPixelFormat srcFormat = c->srcFormat; ff_sws_init_output_funcs(c, &c->yuv2plane1, &c->yuv2planeX, &c->yuv2nv12cX, &c->yuv2packed1, - &c->yuv2packed2, &c->yuv2packedX); + &c->yuv2packed2, &c->yuv2packedX, &c->yuv2anyX); ff_sws_init_input_funcs(c); @@ -723,18 +764,18 @@ static av_cold void sws_init_swScale_c(SwsContext *c) } if (!(isGray(srcFormat) || isGray(c->dstFormat) || - srcFormat == PIX_FMT_MONOBLACK || srcFormat == PIX_FMT_MONOWHITE)) + srcFormat == AV_PIX_FMT_MONOBLACK || srcFormat == AV_PIX_FMT_MONOWHITE)) c->needs_hcscale = 1; } SwsFunc ff_getSwsFunc(SwsContext *c) { - sws_init_swScale_c(c); + sws_init_swscale(c); - if (HAVE_MMX) - ff_sws_init_swScale_mmx(c); - if (HAVE_ALTIVEC) - ff_sws_init_swScale_altivec(c); + if (ARCH_PPC) + ff_sws_init_swscale_ppc(c); + if (ARCH_X86) + ff_sws_init_swscale_x86(c); - return swScale; + return swscale; }