aboutsummaryrefslogtreecommitdiffstats
path: root/libswscale/utils.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2011-07-11 04:00:41 +0200
committerMichael Niedermayer <michaelni@gmx.at>2011-07-11 04:01:01 +0200
commit3b2d285afbd6304505a96b71877cdfda13f4565c (patch)
tree95ec289a13aae12e8bbb9e880031f02f6ee46dd2 /libswscale/utils.c
parent3743ea1fe3761ddbf8bfaae31c6acbf59a8cdc0a (diff)
parent46b32b51979af94f645f8780c78bb12944d04790 (diff)
downloadffmpeg-3b2d285afbd6304505a96b71877cdfda13f4565c.tar.gz
Merge branch 'sws_32bit_integration'
* sws_32bit_integration: regtests/sws: update checksums for recent changes sws: dont mess with XInc when the code needing it isnt used sws: Fix chroma init for 32bit buffers. swscale: error dithering for 16/9/10-bit to 8-bit. swscale: fix overflow in 16-bit vertical scaling. swscale: fix crash in 8-bpc bilinear output without alpha. swscale: fix 16-bit scaling when output is 8-bits. sws: fix non native endian 9-15 bit input with 16bit out sws: disable scale16 when int32 is used sws: fix rgb -> 16bit sws: fix uv overwrite in 32bt sws: fix gray16_1 sws:ix yuv2rgb48_1_c_template() sws: fix 16/32 bug from merge swscale: for >8bit scaling, read in native bit-depth. swscale: fix another yuv range conversion overflow in 16bit scaling. (cherry picked from commit 81cc7d0bd1eab0aa782ff8dd49e087025a42cdee) swscale: fix yuv range correction when using 16-bit scaling. (cherry picked from commit e0b8fff6c7a293e35079ba1931bd19372686b3f6) swscale: implement >8bit scaling support. Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libswscale/utils.c')
-rw-r--r--libswscale/utils.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/libswscale/utils.c b/libswscale/utils.c
index bff9f4d3c6..62839ee8e5 100644
--- a/libswscale/utils.c
+++ b/libswscale/utils.c
@@ -46,6 +46,7 @@
#include "libavutil/bswap.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
+#include "libavutil/avassert.h"
unsigned swscale_version(void)
{
@@ -777,7 +778,7 @@ SwsContext *sws_alloc_context(void)
int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter)
{
- int i;
+ int i, j;
int usesVFilter, usesHFilter;
int unscaled;
SwsFilter dummyFilter= {NULL, NULL, NULL, NULL};
@@ -785,7 +786,7 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter)
int srcH= c->srcH;
int dstW= c->dstW;
int dstH= c->dstH;
- int dst_stride = FFALIGN(dstW * sizeof(int16_t)+66, 16), dst_stride_px = dst_stride >> 1;
+ int dst_stride = FFALIGN(dstW * sizeof(int16_t)+66, 16);
int flags, cpu_flags;
enum PixelFormat srcFormat= c->srcFormat;
enum PixelFormat dstFormat= c->dstFormat;
@@ -882,8 +883,14 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter)
}
}
+ c->scalingBpp = FFMAX(av_pix_fmt_descriptors[srcFormat].comp[0].depth_minus1,
+ av_pix_fmt_descriptors[dstFormat].comp[0].depth_minus1) >= 15 ? 16 : 8;
+
+ if (c->scalingBpp == 16)
+ dst_stride <<= 1;
+ av_assert0(c->scalingBpp<=16);
FF_ALLOC_OR_GOTO(c, c->formatConvBuffer, FFALIGN(srcW*2+78, 16) * 2, fail);
- if (HAVE_MMX2 && cpu_flags & AV_CPU_FLAG_MMX2) {
+ if (HAVE_MMX2 && cpu_flags & AV_CPU_FLAG_MMX2 && c->scalingBpp == 8) {
c->canMMX2BeUsed= (dstW >=srcW && (dstW&31)==0 && (srcW&15)==0) ? 1 : 0;
if (!c->canMMX2BeUsed && dstW >=srcW && (srcW&15)==0 && (flags&SWS_FAST_BILINEAR)) {
if (flags&SWS_PRINT_INFO)
@@ -909,7 +916,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) {
+ else if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX && c->scalingBpp == 8) {
c->lumXInc = ((srcW-2)<<16)/(dstW-2) - 20;
c->chrXInc = ((c->chrSrcW-2)<<16)/(c->chrDstW-2) - 20;
}
@@ -1040,12 +1047,12 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter)
FF_ALLOCZ_OR_GOTO(c, c->lumPixBuf[i+c->vLumBufSize], dst_stride+1, fail);
c->lumPixBuf[i] = c->lumPixBuf[i+c->vLumBufSize];
}
- c->uv_off = dst_stride_px;
+ c->uv_off = dst_stride>>1;
c->uv_offx2 = dst_stride;
for (i=0; i<c->vChrBufSize; i++) {
FF_ALLOC_OR_GOTO(c, c->chrUPixBuf[i+c->vChrBufSize], dst_stride*2+1, fail);
c->chrUPixBuf[i] = c->chrUPixBuf[i+c->vChrBufSize];
- c->chrVPixBuf[i] = c->chrVPixBuf[i+c->vChrBufSize] = c->chrUPixBuf[i] + dst_stride_px;
+ c->chrVPixBuf[i] = c->chrVPixBuf[i+c->vChrBufSize] = c->chrUPixBuf[i] + (dst_stride >> 1);
}
if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf)
for (i=0; i<c->vLumBufSize; i++) {
@@ -1055,7 +1062,13 @@ 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++)
- memset(c->chrUPixBuf[i], 64, dst_stride*2+1);
+ if(av_pix_fmt_descriptors[c->dstFormat].comp[0].depth_minus1 == 15){
+ av_assert0(c->scalingBpp == 16);
+ for(j=0; j<dst_stride/2+1; j++)
+ ((int32_t*)(c->chrUPixBuf[i]))[j] = 1<<18;
+ } else
+ for(j=0; j<dst_stride+1; j++)
+ ((int16_t*)(c->chrUPixBuf[i]))[j] = 1<<14;
assert(c->chrDstH <= dstH);