Merge remote-tracking branch 'qatar/master'

* qatar/master:
  swscale: K&R formatting cosmetics (part II)
  tiffdec: Add a malloc check and refactor another.
  faxcompr: Check malloc results and unify return path
  configure: escape colons in values written to config.fate
  ac3dsp: call femms/emms at the end of float_to_fixed24() for 3DNow and SSE
  matroska: Fix leaking memory allocated for laces.
  pthread: Fix crash due to fctx->delaying not being cleared.
  vp3: Assert on invalid filter_limit values.
  h264: fix 10bit biweight functions after recent x86inc.asm fixes.
  ffv1: Fix size mismatch in encode_line.
  movenc: Remove a dead initialization
  git-howto: Explain how to avoid Windows line endings in git checkouts.
  build: Move all arch OBJS declarations into arch subdirectory Makefiles.

Conflicts:
	configure
	libavcodec/vp3.c
	libavformat/matroskadec.c
	libavutil/Makefile
	libswscale/Makefile
	libswscale/swscale.c
	libswscale/swscale_internal.h
	libswscale/utils.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
Michael Niedermayer 2012-04-13 21:21:15 +02:00
commit 367d9b2957
20 changed files with 1178 additions and 953 deletions

6
configure vendored
View File

@ -2803,7 +2803,11 @@ case $target_os in
;; ;;
esac esac
echo "config:$arch:$subarch:$cpu:$target_os:$cc_ident:$FFMPEG_CONFIGURATION" >config.fate esc(){
echo "$*" | sed 's/%/%25/g;s/:/%3a/g'
}
echo "config:$arch:$subarch:$cpu:$target_os:$(esc $cc_ident):$(esc $FFMPEG_CONFIGURATION)" >config.fate
check_cpp_condition stdlib.h "defined(__PIC__) || defined(__pic__) || defined(PIC)" && enable pic check_cpp_condition stdlib.h "defined(__PIC__) || defined(__pic__) || defined(PIC)" && enable pic

View File

@ -65,6 +65,14 @@ git clone git@@source.ffmpeg.org:ffmpeg <target>
This will put the FFmpeg sources into the directory @var{<target>} and let This will put the FFmpeg sources into the directory @var{<target>} and let
you push back your changes to the remote repository. you push back your changes to the remote repository.
Make sure that you do not have Windows line endings in your checkouts,
otherwise you may experience spurious compilation failures. One way to
achieve this is to run
@example
git config --global core.autocrlf false
@end example
@section Updating the source tree to the latest revision @section Updating the source tree to the latest revision

View File

@ -275,12 +275,17 @@ int ff_ccitt_unpack(AVCodecContext *avctx,
{ {
int j; int j;
GetBitContext gb; GetBitContext gb;
int *runs, *ref, *runend; int *runs, *ref = NULL, *runend;
int ret; int ret;
int runsize= avctx->width + 2; int runsize= avctx->width + 2;
int err = 0;
runs = av_malloc(runsize * sizeof(runs[0])); runs = av_malloc(runsize * sizeof(runs[0]));
ref = av_malloc(runsize * sizeof(ref[0])); ref = av_malloc(runsize * sizeof(ref[0]));
if (!runs || ! ref) {
err = AVERROR(ENOMEM);
goto fail;
}
ref[0] = avctx->width; ref[0] = avctx->width;
ref[1] = 0; ref[1] = 0;
ref[2] = 0; ref[2] = 0;
@ -290,9 +295,8 @@ int ff_ccitt_unpack(AVCodecContext *avctx,
if(compr == TIFF_G4){ if(compr == TIFF_G4){
ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs, runend, ref); ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs, runend, ref);
if(ret < 0){ if(ret < 0){
av_free(runs); err = -1;
av_free(ref); goto fail;
return -1;
} }
}else{ }else{
int g3d1 = (compr == TIFF_G3) && !(opts & 1); int g3d1 = (compr == TIFF_G3) && !(opts & 1);
@ -313,7 +317,8 @@ int ff_ccitt_unpack(AVCodecContext *avctx,
} }
dst += stride; dst += stride;
} }
fail:
av_free(runs); av_free(runs);
av_free(ref); av_free(ref);
return 0; return err;
} }

View File

@ -445,7 +445,7 @@ static inline int get_vlc_symbol(GetBitContext *gb, VlcState * const state, int
#if CONFIG_FFV1_ENCODER #if CONFIG_FFV1_ENCODER
static av_always_inline int encode_line(FFV1Context *s, int w, static av_always_inline int encode_line(FFV1Context *s, int w,
int16_t *sample[2], int16_t *sample[3],
int plane_index, int bits) int plane_index, int bits)
{ {
PlaneContext * const p= &s->plane[plane_index]; PlaneContext * const p= &s->plane[plane_index];

View File

@ -145,13 +145,18 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, const uin
int c, line, pixels, code; int c, line, pixels, code;
const uint8_t *ssrc = src; const uint8_t *ssrc = src;
int width = ((s->width * s->bpp) + 7) >> 3; int width = ((s->width * s->bpp) + 7) >> 3;
#if CONFIG_ZLIB
uint8_t *zbuf; unsigned long outlen;
if (size <= 0)
return AVERROR_INVALIDDATA;
#if CONFIG_ZLIB
if(s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE){ if(s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE){
uint8_t *zbuf; unsigned long outlen;
int ret; int ret;
outlen = width * lines; outlen = width * lines;
zbuf = av_malloc(outlen); zbuf = av_malloc(outlen);
if (!zbuf)
return AVERROR(ENOMEM);
ret = tiff_uncompress(zbuf, &outlen, src, size); ret = tiff_uncompress(zbuf, &outlen, src, size);
if(ret != Z_OK){ if(ret != Z_OK){
av_log(s->avctx, AV_LOG_ERROR, "Uncompressing failed (%lu of %lu) with error %d\n", outlen, (unsigned long)width * lines, ret); av_log(s->avctx, AV_LOG_ERROR, "Uncompressing failed (%lu of %lu) with error %d\n", outlen, (unsigned long)width * lines, ret);
@ -180,11 +185,11 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, const uin
} }
if(s->compr == TIFF_CCITT_RLE || s->compr == TIFF_G3 || s->compr == TIFF_G4){ if(s->compr == TIFF_CCITT_RLE || s->compr == TIFF_G3 || s->compr == TIFF_G4){
int i, ret = 0; int i, ret = 0;
uint8_t *src2 = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); uint8_t *src2 = av_malloc((unsigned)size + FF_INPUT_BUFFER_PADDING_SIZE);
if(!src2 || (unsigned)size + FF_INPUT_BUFFER_PADDING_SIZE < (unsigned)size){ if (!src2) {
av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n"); av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");
return -1; return AVERROR(ENOMEM);
} }
if(s->fax_opts & 2){ if(s->fax_opts & 2){
av_log(s->avctx, AV_LOG_ERROR, "Uncompressed fax mode is not supported (yet)\n"); av_log(s->avctx, AV_LOG_ERROR, "Uncompressed fax mode is not supported (yet)\n");

View File

@ -223,7 +223,8 @@ cglobal float_to_fixed24_3dnow, 3,3,0, dst, src, len
add dstq, 32 add dstq, 32
sub lend, 8 sub lend, 8
ja .loop ja .loop
REP_RET femms
RET
INIT_XMM INIT_XMM
cglobal float_to_fixed24_sse, 3,3,3, dst, src, len cglobal float_to_fixed24_sse, 3,3,3, dst, src, len
@ -247,7 +248,8 @@ cglobal float_to_fixed24_sse, 3,3,3, dst, src, len
add dstq, 32 add dstq, 32
sub lend, 8 sub lend, 8
ja .loop ja .loop
REP_RET emms
RET
INIT_XMM INIT_XMM
cglobal float_to_fixed24_sse2, 3,3,9, dst, src, len cglobal float_to_fixed24_sse2, 3,3,9, dst, src, len

View File

@ -155,7 +155,7 @@ WEIGHT_FUNC_HALF_MM sse4
%if ARCH_X86_32 %if ARCH_X86_32
DECLARE_REG_TMP 3 DECLARE_REG_TMP 3
%else %else
DECLARE_REG_TMP 10 DECLARE_REG_TMP 7
%endif %endif
%macro BIWEIGHT_PROLOGUE 0 %macro BIWEIGHT_PROLOGUE 0
@ -218,7 +218,7 @@ DECLARE_REG_TMP 10
%endmacro %endmacro
%macro BIWEIGHT_FUNC_DBL 1 %macro BIWEIGHT_FUNC_DBL 1
cglobal h264_biweight_16_10_%1 cglobal h264_biweight_16_10_%1, 0, 8, 8
BIWEIGHT_PROLOGUE BIWEIGHT_PROLOGUE
BIWEIGHT_SETUP %1 BIWEIGHT_SETUP %1
.nextrow .nextrow
@ -238,7 +238,7 @@ BIWEIGHT_FUNC_DBL sse2
BIWEIGHT_FUNC_DBL sse4 BIWEIGHT_FUNC_DBL sse4
%macro BIWEIGHT_FUNC 1 %macro BIWEIGHT_FUNC 1
cglobal h264_biweight_8_10_%1 cglobal h264_biweight_8_10_%1, 0, 8, 8
BIWEIGHT_PROLOGUE BIWEIGHT_PROLOGUE
BIWEIGHT_SETUP %1 BIWEIGHT_SETUP %1
.nextrow .nextrow
@ -256,7 +256,7 @@ BIWEIGHT_FUNC sse2
BIWEIGHT_FUNC sse4 BIWEIGHT_FUNC sse4
%macro BIWEIGHT_FUNC_HALF 1 %macro BIWEIGHT_FUNC_HALF 1
cglobal h264_biweight_4_10_%1 cglobal h264_biweight_4_10_%1, 0, 8, 8
BIWEIGHT_PROLOGUE BIWEIGHT_PROLOGUE
BIWEIGHT_SETUP %1 BIWEIGHT_SETUP %1
sar r3d, 1 sar r3d, 1

View File

@ -1940,8 +1940,8 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
if (size < cfs * h / 2) { if (size < cfs * h / 2) {
av_log(matroska->ctx, AV_LOG_ERROR, av_log(matroska->ctx, AV_LOG_ERROR,
"Corrupt int4 RM-style audio packet size\n"); "Corrupt int4 RM-style audio packet size\n");
av_free(lace_size); res = AVERROR_INVALIDDATA;
return AVERROR_INVALIDDATA; goto end;
} }
for (x=0; x<h/2; x++) for (x=0; x<h/2; x++)
memcpy(track->audio.buf+x*2*w+y*cfs, memcpy(track->audio.buf+x*2*w+y*cfs,
@ -1950,16 +1950,16 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
if (size < w) { if (size < w) {
av_log(matroska->ctx, AV_LOG_ERROR, av_log(matroska->ctx, AV_LOG_ERROR,
"Corrupt sipr RM-style audio packet size\n"); "Corrupt sipr RM-style audio packet size\n");
av_free(lace_size); res = AVERROR_INVALIDDATA;
return AVERROR_INVALIDDATA; goto end;
} }
memcpy(track->audio.buf + y*w, data, w); memcpy(track->audio.buf + y*w, data, w);
} else { } else {
if (size < sps * w / sps) { if (size < sps * w / sps) {
av_log(matroska->ctx, AV_LOG_ERROR, av_log(matroska->ctx, AV_LOG_ERROR,
"Corrupt generic RM-style audio packet size\n"); "Corrupt generic RM-style audio packet size\n");
av_free(lace_size); res = AVERROR_INVALIDDATA;
return AVERROR_INVALIDDATA; goto end;
} }
for (x=0; x<w/sps; x++) for (x=0; x<w/sps; x++)
memcpy(track->audio.buf+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), data+x*sps, sps); memcpy(track->audio.buf+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), data+x*sps, sps);
@ -2049,6 +2049,7 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
} }
} }
end:
av_free(lace_size); av_free(lace_size);
return res; return res;
} }

View File

@ -939,7 +939,7 @@ static const AVCodecTag codec_3gp_tags[] = {
static int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track) static int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
{ {
int tag = track->enc->codec_tag; int tag;
if (track->mode == MODE_MP4 || track->mode == MODE_PSP) if (track->mode == MODE_MP4 || track->mode == MODE_PSP)
tag = mp4_get_codec_tag(s, track); tag = mp4_get_codec_tag(s, track);

View File

@ -79,9 +79,6 @@ OBJS = adler32.o \
tree.o \ tree.o \
utils.o \ utils.o \
OBJS-$(ARCH_PPC) += ppc/cpu.o
OBJS-$(ARCH_X86) += x86/cpu.o
TESTPROGS = adler32 aes avstring base64 bprint cpu crc des eval file fifo \ TESTPROGS = adler32 aes avstring base64 bprint cpu crc des eval file fifo \
lfg lls md5 opt pca parseutils random_seed rational sha tree lfg lls md5 opt pca parseutils random_seed rational sha tree
TESTPROGS-$(HAVE_LZO1X_999_COMPRESS) += lzo TESTPROGS-$(HAVE_LZO1X_999_COMPRESS) += lzo

1
libavutil/ppc/Makefile Normal file
View File

@ -0,0 +1 @@
OBJS += ppc/cpu.o \

1
libavutil/x86/Makefile Normal file
View File

@ -0,0 +1 @@
OBJS += x86/cpu.o \

View File

@ -14,22 +14,4 @@ OBJS = input.o \
utils.o \ utils.o \
yuv2rgb.o \ yuv2rgb.o \
OBJS-$(ARCH_BFIN) += bfin/internal_bfin.o \
bfin/swscale_bfin.o \
bfin/yuv2rgb_bfin.o
ALTIVEC-OBJS += ppc/swscale_altivec.o \
ppc/yuv2rgb_altivec.o \
ppc/yuv2yuv_altivec.o
MMX-OBJS += x86/rgb2rgb.o \
x86/swscale_mmx.o \
x86/yuv2rgb_mmx.o
VIS-OBJS += sparc/yuv2rgb_vis.o
YASM-OBJS += x86/input.o \
x86/output.o \
x86/scale.o
$(SUBDIR)x86/swscale_mmx.o: CFLAGS += $(NOREDZONE_FLAGS)
OBJS-$(CONFIG_XMM_CLOBBER_TEST) += x86/w64xmmtest.o
TESTPROGS = colorspace swscale TESTPROGS = colorspace swscale

3
libswscale/bfin/Makefile Normal file
View File

@ -0,0 +1,3 @@
OBJS += bfin/internal_bfin.o \
bfin/swscale_bfin.o \
bfin/yuv2rgb_bfin.o \

3
libswscale/ppc/Makefile Normal file
View File

@ -0,0 +1,3 @@
ALTIVEC-OBJS += ppc/swscale_altivec.o \
ppc/yuv2rgb_altivec.o \
ppc/yuv2yuv_altivec.o \

View File

@ -0,0 +1 @@
VIS-OBJS += sparc/yuv2rgb_vis.o \

View File

@ -18,51 +18,52 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include <assert.h>
#include <inttypes.h> #include <inttypes.h>
#include <string.h>
#include <math.h> #include <math.h>
#include <stdio.h> #include <stdio.h>
#include "config.h" #include <string.h>
#include <assert.h>
#include "swscale.h"
#include "swscale_internal.h"
#include "rgb2rgb.h"
#include "libavutil/avassert.h" #include "libavutil/avassert.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/cpu.h"
#include "libavutil/avutil.h" #include "libavutil/avutil.h"
#include "libavutil/mathematics.h"
#include "libavutil/bswap.h" #include "libavutil/bswap.h"
#include "libavutil/cpu.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/mathematics.h"
#include "libavutil/pixdesc.h" #include "libavutil/pixdesc.h"
#include "config.h"
#include "rgb2rgb.h"
#include "swscale_internal.h"
#include "swscale.h"
DECLARE_ALIGNED(8, const uint8_t, dither_8x8_128)[8][8] = { DECLARE_ALIGNED(8, const uint8_t, dither_8x8_128)[8][8] = {
{ 36, 68, 60, 92, 34, 66, 58, 90,}, { 36, 68, 60, 92, 34, 66, 58, 90, },
{ 100, 4,124, 28, 98, 2,122, 26,}, { 100, 4, 124, 28, 98, 2, 122, 26, },
{ 52, 84, 44, 76, 50, 82, 42, 74,}, { 52, 84, 44, 76, 50, 82, 42, 74, },
{ 116, 20,108, 12,114, 18,106, 10,}, { 116, 20, 108, 12, 114, 18, 106, 10, },
{ 32, 64, 56, 88, 38, 70, 62, 94,}, { 32, 64, 56, 88, 38, 70, 62, 94, },
{ 96, 0,120, 24,102, 6,126, 30,}, { 96, 0, 120, 24, 102, 6, 126, 30, },
{ 48, 80, 40, 72, 54, 86, 46, 78,}, { 48, 80, 40, 72, 54, 86, 46, 78, },
{ 112, 16,104, 8,118, 22,110, 14,}, { 112, 16, 104, 8, 118, 22, 110, 14, },
}; };
DECLARE_ALIGNED(8, const uint8_t, ff_sws_pb_64)[8] =
{ 64, 64, 64, 64, 64, 64, 64, 64 };
DECLARE_ALIGNED(8, const uint8_t, ff_sws_pb_64)[8] = {
64, 64, 64, 64, 64, 64, 64, 64
};
static av_always_inline void fillPlane(uint8_t* plane, int stride, static av_always_inline void fillPlane(uint8_t *plane, int stride, int width,
int width, int height, int height, int y, uint8_t val)
int y, uint8_t val)
{ {
int i; int i;
uint8_t *ptr = plane + stride*y; uint8_t *ptr = plane + stride * y;
for (i=0; i<height; i++) { for (i = 0; i < height; i++) {
memset(ptr, val, width); memset(ptr, val, width);
ptr += stride; ptr += stride;
} }
} }
static void hScale16To19_c(SwsContext *c, int16_t *_dst, int dstW, const uint8_t *_src, static void hScale16To19_c(SwsContext *c, int16_t *_dst, int dstW,
const int16_t *filter, const uint8_t *_src, const int16_t *filter,
const int32_t *filterPos, int filterSize) const int32_t *filterPos, int filterSize)
{ {
int i; int i;
@ -87,8 +88,8 @@ static void hScale16To19_c(SwsContext *c, int16_t *_dst, int dstW, const uint8_t
} }
} }
static void hScale16To15_c(SwsContext *c, int16_t *dst, int dstW, const uint8_t *_src, static void hScale16To15_c(SwsContext *c, int16_t *dst, int dstW,
const int16_t *filter, const uint8_t *_src, const int16_t *filter,
const int32_t *filterPos, int filterSize) const int32_t *filterPos, int filterSize)
{ {
int i; int i;
@ -112,72 +113,71 @@ static void hScale16To15_c(SwsContext *c, int16_t *dst, int dstW, const uint8_t
} }
// bilinear / bicubic scaling // bilinear / bicubic scaling
static void hScale8To15_c(SwsContext *c, int16_t *dst, int dstW, const uint8_t *src, static void hScale8To15_c(SwsContext *c, int16_t *dst, int dstW,
const int16_t *filter, const int32_t *filterPos, const uint8_t *src, const int16_t *filter,
int filterSize) const int32_t *filterPos, int filterSize)
{ {
int i; int i;
for (i=0; i<dstW; i++) { for (i = 0; i < dstW; i++) {
int j; int j;
int srcPos= filterPos[i]; int srcPos = filterPos[i];
int val=0; int val = 0;
for (j=0; j<filterSize; j++) { for (j = 0; j < filterSize; j++) {
val += ((int)src[srcPos + j])*filter[filterSize*i + j]; val += ((int)src[srcPos + j]) * filter[filterSize * i + j];
} }
//filter += hFilterSize; dst[i] = FFMIN(val >> 7, (1 << 15) - 1); // the cubic equation does overflow ...
dst[i] = FFMIN(val>>7, (1<<15)-1); // the cubic equation does overflow ...
//dst[i] = val>>7;
} }
} }
static void hScale8To19_c(SwsContext *c, int16_t *_dst, int dstW, const uint8_t *src, static void hScale8To19_c(SwsContext *c, int16_t *_dst, int dstW,
const int16_t *filter, const int32_t *filterPos, const uint8_t *src, const int16_t *filter,
int filterSize) const int32_t *filterPos, int filterSize)
{ {
int i; int i;
int32_t *dst = (int32_t *) _dst; int32_t *dst = (int32_t *) _dst;
for (i=0; i<dstW; i++) { for (i = 0; i < dstW; i++) {
int j; int j;
int srcPos= filterPos[i]; int srcPos = filterPos[i];
int val=0; int val = 0;
for (j=0; j<filterSize; j++) { for (j = 0; j < filterSize; j++) {
val += ((int)src[srcPos + j])*filter[filterSize*i + j]; val += ((int)src[srcPos + j]) * filter[filterSize * i + j];
} }
//filter += hFilterSize; dst[i] = FFMIN(val >> 3, (1 << 19) - 1); // the cubic equation does overflow ...
dst[i] = FFMIN(val>>3, (1<<19)-1); // the cubic equation does overflow ...
//dst[i] = val>>7;
} }
} }
//FIXME all pal and rgb srcFormats could do this convertion as well // FIXME all pal and rgb srcFormats could do this convertion as well
//FIXME all scalers more complex than bilinear could do half of this transform // 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) static void chrRangeToJpeg_c(int16_t *dstU, int16_t *dstV, int width)
{ {
int i; int i;
for (i = 0; i < width; i++) { for (i = 0; i < width; i++) {
dstU[i] = (FFMIN(dstU[i],30775)*4663 - 9289992)>>12; //-264 dstU[i] = (FFMIN(dstU[i], 30775) * 4663 - 9289992) >> 12; // -264
dstV[i] = (FFMIN(dstV[i],30775)*4663 - 9289992)>>12; //-264 dstV[i] = (FFMIN(dstV[i], 30775) * 4663 - 9289992) >> 12; // -264
} }
} }
static void chrRangeFromJpeg_c(int16_t *dstU, int16_t *dstV, int width) static void chrRangeFromJpeg_c(int16_t *dstU, int16_t *dstV, int width)
{ {
int i; int i;
for (i = 0; i < width; i++) { for (i = 0; i < width; i++) {
dstU[i] = (dstU[i]*1799 + 4081085)>>11; //1469 dstU[i] = (dstU[i] * 1799 + 4081085) >> 11; // 1469
dstV[i] = (dstV[i]*1799 + 4081085)>>11; //1469 dstV[i] = (dstV[i] * 1799 + 4081085) >> 11; // 1469
} }
} }
static void lumRangeToJpeg_c(int16_t *dst, int width) static void lumRangeToJpeg_c(int16_t *dst, int width)
{ {
int i; int i;
for (i = 0; i < width; i++) for (i = 0; i < width; i++)
dst[i] = (FFMIN(dst[i],30189)*19077 - 39057361)>>14; dst[i] = (FFMIN(dst[i], 30189) * 19077 - 39057361) >> 14;
} }
static void lumRangeFromJpeg_c(int16_t *dst, int width) static void lumRangeFromJpeg_c(int16_t *dst, int width)
{ {
int i; int i;
for (i = 0; i < width; i++) for (i = 0; i < width; i++)
dst[i] = (dst[i]*14071 + 33561947)>>14; dst[i] = (dst[i] * 14071 + 33561947) >> 14;
} }
static void chrRangeToJpeg16_c(int16_t *_dstU, int16_t *_dstV, int width) static void chrRangeToJpeg16_c(int16_t *_dstU, int16_t *_dstV, int width)
@ -186,27 +186,30 @@ static void chrRangeToJpeg16_c(int16_t *_dstU, int16_t *_dstV, int width)
int32_t *dstU = (int32_t *) _dstU; int32_t *dstU = (int32_t *) _dstU;
int32_t *dstV = (int32_t *) _dstV; int32_t *dstV = (int32_t *) _dstV;
for (i = 0; i < width; i++) { for (i = 0; i < width; i++) {
dstU[i] = (FFMIN(dstU[i],30775<<4)*4663 - (9289992<<4))>>12; //-264 dstU[i] = (FFMIN(dstU[i], 30775 << 4) * 4663 - (9289992 << 4)) >> 12; // -264
dstV[i] = (FFMIN(dstV[i],30775<<4)*4663 - (9289992<<4))>>12; //-264 dstV[i] = (FFMIN(dstV[i], 30775 << 4) * 4663 - (9289992 << 4)) >> 12; // -264
} }
} }
static void chrRangeFromJpeg16_c(int16_t *_dstU, int16_t *_dstV, int width) static void chrRangeFromJpeg16_c(int16_t *_dstU, int16_t *_dstV, int width)
{ {
int i; int i;
int32_t *dstU = (int32_t *) _dstU; int32_t *dstU = (int32_t *) _dstU;
int32_t *dstV = (int32_t *) _dstV; int32_t *dstV = (int32_t *) _dstV;
for (i = 0; i < width; i++) { for (i = 0; i < width; i++) {
dstU[i] = (dstU[i]*1799 + (4081085<<4))>>11; //1469 dstU[i] = (dstU[i] * 1799 + (4081085 << 4)) >> 11; // 1469
dstV[i] = (dstV[i]*1799 + (4081085<<4))>>11; //1469 dstV[i] = (dstV[i] * 1799 + (4081085 << 4)) >> 11; // 1469
} }
} }
static void lumRangeToJpeg16_c(int16_t *_dst, int width) static void lumRangeToJpeg16_c(int16_t *_dst, int width)
{ {
int i; int i;
int32_t *dst = (int32_t *) _dst; int32_t *dst = (int32_t *) _dst;
for (i = 0; i < width; i++) for (i = 0; i < width; i++)
dst[i] = (FFMIN(dst[i],30189<<4)*4769 - (39057361<<2))>>12; dst[i] = (FFMIN(dst[i], 30189 << 4) * 4769 - (39057361 << 2)) >> 12;
} }
static void lumRangeFromJpeg16_c(int16_t *_dst, int width) static void lumRangeFromJpeg16_c(int16_t *_dst, int width)
{ {
int i; int i;
@ -219,12 +222,12 @@ static void hyscale_fast_c(SwsContext *c, int16_t *dst, int dstWidth,
const uint8_t *src, int srcW, int xInc) const uint8_t *src, int srcW, int xInc)
{ {
int i; int i;
unsigned int xpos=0; unsigned int xpos = 0;
for (i=0;i<dstWidth;i++) { for (i = 0; i < dstWidth; i++) {
register unsigned int xx=xpos>>16; register unsigned int xx = xpos >> 16;
register unsigned int xalpha=(xpos&0xFFFF)>>9; register unsigned int xalpha = (xpos & 0xFFFF) >> 9;
dst[i]= (src[xx]<<7) + (src[xx+1] - src[xx])*xalpha; dst[i] = (src[xx] << 7) + (src[xx + 1] - src[xx]) * xalpha;
xpos+=xInc; xpos += xInc;
} }
for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--) for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--)
dst[i] = src[srcW-1]*128; dst[i] = src[srcW-1]*128;
@ -232,26 +235,30 @@ static void hyscale_fast_c(SwsContext *c, int16_t *dst, int dstWidth,
// *** horizontal scale Y line to temp buffer // *** horizontal scale Y line to temp buffer
static av_always_inline void hyscale(SwsContext *c, int16_t *dst, int dstWidth, static av_always_inline void hyscale(SwsContext *c, int16_t *dst, int dstWidth,
const uint8_t *src_in[4], int srcW, int xInc, const uint8_t *src_in[4],
int srcW, int xInc,
const int16_t *hLumFilter, const int16_t *hLumFilter,
const int32_t *hLumFilterPos, int hLumFilterSize, const int32_t *hLumFilterPos,
int hLumFilterSize,
uint8_t *formatConvBuffer, uint8_t *formatConvBuffer,
uint32_t *pal, int isAlpha) uint32_t *pal, int isAlpha)
{ {
void (*toYV12)(uint8_t *, const uint8_t *, const uint8_t *, const uint8_t *, int, uint32_t *) = isAlpha ? c->alpToYV12 : c->lumToYV12; void (*toYV12)(uint8_t *, const uint8_t *, const uint8_t *, const uint8_t *, int, uint32_t *) =
isAlpha ? c->alpToYV12 : c->lumToYV12;
void (*convertRange)(int16_t *, int) = isAlpha ? NULL : c->lumConvertRange; void (*convertRange)(int16_t *, int) = isAlpha ? NULL : c->lumConvertRange;
const uint8_t *src = src_in[isAlpha ? 3 : 0]; const uint8_t *src = src_in[isAlpha ? 3 : 0];
if (toYV12) { if (toYV12) {
toYV12(formatConvBuffer, src, src_in[1], src_in[2], srcW, pal); toYV12(formatConvBuffer, src, src_in[1], src_in[2], srcW, pal);
src= formatConvBuffer; src = formatConvBuffer;
} else if (c->readLumPlanar && !isAlpha) { } else if (c->readLumPlanar && !isAlpha) {
c->readLumPlanar(formatConvBuffer, src_in, srcW); c->readLumPlanar(formatConvBuffer, src_in, srcW);
src = formatConvBuffer; src = formatConvBuffer;
} }
if (!c->hyscale_fast) { if (!c->hyscale_fast) {
c->hyScale(c, dst, dstWidth, src, hLumFilter, hLumFilterPos, hLumFilterSize); c->hyScale(c, dst, dstWidth, src, hLumFilter,
hLumFilterPos, hLumFilterSize);
} else { // fast bilinear upscale / crap downscale } else { // fast bilinear upscale / crap downscale
c->hyscale_fast(c, dst, dstWidth, src, srcW, xInc); c->hyscale_fast(c, dst, dstWidth, src, srcW, xInc);
} }
@ -265,13 +272,13 @@ static void hcscale_fast_c(SwsContext *c, int16_t *dst1, int16_t *dst2,
const uint8_t *src2, int srcW, int xInc) const uint8_t *src2, int srcW, int xInc)
{ {
int i; int i;
unsigned int xpos=0; unsigned int xpos = 0;
for (i=0;i<dstWidth;i++) { for (i = 0; i < dstWidth; i++) {
register unsigned int xx=xpos>>16; register unsigned int xx = xpos >> 16;
register unsigned int xalpha=(xpos&0xFFFF)>>9; register unsigned int xalpha = (xpos & 0xFFFF) >> 9;
dst1[i]=(src1[xx]*(xalpha^127)+src1[xx+1]*xalpha); dst1[i] = (src1[xx] * (xalpha ^ 127) + src1[xx + 1] * xalpha);
dst2[i]=(src2[xx]*(xalpha^127)+src2[xx+1]*xalpha); dst2[i] = (src2[xx] * (xalpha ^ 127) + src2[xx + 1] * xalpha);
xpos+=xInc; xpos += xInc;
} }
for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--) { for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--) {
dst1[i] = src1[srcW-1]*128; dst1[i] = src1[srcW-1]*128;
@ -279,23 +286,28 @@ static void hcscale_fast_c(SwsContext *c, int16_t *dst1, int16_t *dst2,
} }
} }
static av_always_inline void hcscale(SwsContext *c, int16_t *dst1, int16_t *dst2, int dstWidth, static av_always_inline void hcscale(SwsContext *c, int16_t *dst1,
int16_t *dst2, int dstWidth,
const uint8_t *src_in[4], const uint8_t *src_in[4],
int srcW, int xInc, const int16_t *hChrFilter, int srcW, int xInc,
const int32_t *hChrFilterPos, int hChrFilterSize, const int16_t *hChrFilter,
const int32_t *hChrFilterPos,
int hChrFilterSize,
uint8_t *formatConvBuffer, uint32_t *pal) uint8_t *formatConvBuffer, uint32_t *pal)
{ {
const uint8_t *src1 = src_in[1], *src2 = src_in[2]; const uint8_t *src1 = src_in[1], *src2 = src_in[2];
if (c->chrToYV12) { if (c->chrToYV12) {
uint8_t *buf2 = formatConvBuffer + FFALIGN(srcW*2+78, 16); uint8_t *buf2 = formatConvBuffer +
FFALIGN(srcW*2+78, 16);
c->chrToYV12(formatConvBuffer, buf2, src_in[0], src1, src2, srcW, pal); c->chrToYV12(formatConvBuffer, buf2, src_in[0], src1, src2, srcW, pal);
src1= formatConvBuffer; src1= formatConvBuffer;
src2= buf2; src2= buf2;
} else if (c->readChrPlanar) { } else if (c->readChrPlanar) {
uint8_t *buf2 = formatConvBuffer + FFALIGN(srcW*2+78, 16); uint8_t *buf2 = formatConvBuffer +
FFALIGN(srcW*2+78, 16);
c->readChrPlanar(formatConvBuffer, buf2, src_in, srcW); c->readChrPlanar(formatConvBuffer, buf2, src_in, srcW);
src1= formatConvBuffer; src1 = formatConvBuffer;
src2= buf2; src2 = buf2;
} }
if (!c->hcscale_fast) { if (!c->hcscale_fast) {
@ -310,88 +322,97 @@ static av_always_inline void hcscale(SwsContext *c, int16_t *dst1, int16_t *dst2
} }
#define DEBUG_SWSCALE_BUFFERS 0 #define DEBUG_SWSCALE_BUFFERS 0
#define DEBUG_BUFFERS(...) if (DEBUG_SWSCALE_BUFFERS) av_log(c, AV_LOG_DEBUG, __VA_ARGS__) #define DEBUG_BUFFERS(...) \
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 srcStride[], int srcSliceY,
int srcSliceH, uint8_t* dst[], int dstStride[]) int srcSliceH, uint8_t *dst[], int dstStride[])
{ {
/* load a few things into local vars to make the code more readable? and faster */ /* load a few things into local vars to make the code more readable?
const int srcW= c->srcW; * and faster */
const int dstW= c->dstW; const int srcW = c->srcW;
const int dstH= c->dstH; const int dstW = c->dstW;
const int chrDstW= c->chrDstW; const int dstH = c->dstH;
const int chrSrcW= c->chrSrcW; const int chrDstW = c->chrDstW;
const int lumXInc= c->lumXInc; const int chrSrcW = c->chrSrcW;
const int chrXInc= c->chrXInc; const int lumXInc = c->lumXInc;
const enum PixelFormat dstFormat= c->dstFormat; const int chrXInc = c->chrXInc;
const int flags= c->flags; const enum PixelFormat dstFormat = c->dstFormat;
int32_t *vLumFilterPos= c->vLumFilterPos; const int flags = c->flags;
int32_t *vChrFilterPos= c->vChrFilterPos; int32_t *vLumFilterPos = c->vLumFilterPos;
int32_t *hLumFilterPos= c->hLumFilterPos; int32_t *vChrFilterPos = c->vChrFilterPos;
int32_t *hChrFilterPos= c->hChrFilterPos; int32_t *hLumFilterPos = c->hLumFilterPos;
int16_t *hLumFilter= c->hLumFilter; int32_t *hChrFilterPos = c->hChrFilterPos;
int16_t *hChrFilter= c->hChrFilter; int16_t *vLumFilter = c->vLumFilter;
int32_t *lumMmxFilter= c->lumMmxFilter; int16_t *vChrFilter = c->vChrFilter;
int32_t *chrMmxFilter= c->chrMmxFilter; int16_t *hLumFilter = c->hLumFilter;
const int vLumFilterSize= c->vLumFilterSize; int16_t *hChrFilter = c->hChrFilter;
const int vChrFilterSize= c->vChrFilterSize; int32_t *lumMmxFilter = c->lumMmxFilter;
const int hLumFilterSize= c->hLumFilterSize; int32_t *chrMmxFilter = c->chrMmxFilter;
const int hChrFilterSize= c->hChrFilterSize; const int vLumFilterSize = c->vLumFilterSize;
int16_t **lumPixBuf= c->lumPixBuf; const int vChrFilterSize = c->vChrFilterSize;
int16_t **chrUPixBuf= c->chrUPixBuf; const int hLumFilterSize = c->hLumFilterSize;
int16_t **chrVPixBuf= c->chrVPixBuf; const int hChrFilterSize = c->hChrFilterSize;
int16_t **alpPixBuf= c->alpPixBuf; int16_t **lumPixBuf = c->lumPixBuf;
const int vLumBufSize= c->vLumBufSize; int16_t **chrUPixBuf = c->chrUPixBuf;
const int vChrBufSize= c->vChrBufSize; int16_t **chrVPixBuf = c->chrVPixBuf;
uint8_t *formatConvBuffer= c->formatConvBuffer; int16_t **alpPixBuf = c->alpPixBuf;
const int chrSrcSliceY= srcSliceY >> c->chrSrcVSubSample; const int vLumBufSize = c->vLumBufSize;
const int chrSrcSliceH= -((-srcSliceH) >> c->chrSrcVSubSample); const int vChrBufSize = c->vChrBufSize;
int lastDstY; uint8_t *formatConvBuffer = c->formatConvBuffer;
uint32_t *pal=c->pal_yuv; uint32_t *pal = c->pal_yuv;
int should_dither= isNBPS(c->srcFormat) || is16BPS(c->srcFormat);
yuv2planar1_fn yuv2plane1 = c->yuv2plane1; yuv2planar1_fn yuv2plane1 = c->yuv2plane1;
yuv2planarX_fn yuv2planeX = c->yuv2planeX; yuv2planarX_fn yuv2planeX = c->yuv2planeX;
yuv2interleavedX_fn yuv2nv12cX = c->yuv2nv12cX; yuv2interleavedX_fn yuv2nv12cX = c->yuv2nv12cX;
yuv2packed1_fn yuv2packed1 = c->yuv2packed1; yuv2packed1_fn yuv2packed1 = c->yuv2packed1;
yuv2packed2_fn yuv2packed2 = c->yuv2packed2; yuv2packed2_fn yuv2packed2 = c->yuv2packed2;
yuv2packedX_fn yuv2packedX = c->yuv2packedX; yuv2packedX_fn yuv2packedX = c->yuv2packedX;
const int chrSrcSliceY = srcSliceY >> c->chrSrcVSubSample;
const int chrSrcSliceH = -((-srcSliceH) >> c->chrSrcVSubSample);
int should_dither = is9_OR_10BPS(c->srcFormat) ||
is16BPS(c->srcFormat);
int lastDstY;
/* vars which will change and which we need to store back in the context */ /* vars which will change and which we need to store back in the context */
int dstY= c->dstY; int dstY = c->dstY;
int lumBufIndex= c->lumBufIndex; int lumBufIndex = c->lumBufIndex;
int chrBufIndex= c->chrBufIndex; int chrBufIndex = c->chrBufIndex;
int lastInLumBuf= c->lastInLumBuf; int lastInLumBuf = c->lastInLumBuf;
int lastInChrBuf= c->lastInChrBuf; int lastInChrBuf = c->lastInChrBuf;
if (isPacked(c->srcFormat)) { if (isPacked(c->srcFormat)) {
src[0]= src[0] =
src[1]= src[1] =
src[2]= src[2] =
src[3]= src[0]; src[3] = src[0];
srcStride[0]= srcStride[0] =
srcStride[1]= srcStride[1] =
srcStride[2]= srcStride[2] =
srcStride[3]= srcStride[0]; srcStride[3] = srcStride[0];
} }
srcStride[1]<<= c->vChrDrop; srcStride[1] <<= c->vChrDrop;
srcStride[2]<<= 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], src[0], srcStride[0], src[1], srcStride[1],
dst[0], dstStride[0], dst[1], dstStride[1], dst[2], dstStride[2], dst[3], dstStride[3]); src[2], srcStride[2], src[3], srcStride[3],
dst[0], dstStride[0], dst[1], dstStride[1],
dst[2], dstStride[2], dst[3], dstStride[3]);
DEBUG_BUFFERS("srcSliceY: %d srcSliceH: %d dstY: %d dstH: %d\n", DEBUG_BUFFERS("srcSliceY: %d srcSliceH: %d dstY: %d dstH: %d\n",
srcSliceY, srcSliceH, dstY, dstH); srcSliceY, srcSliceH, dstY, dstH);
DEBUG_BUFFERS("vLumFilterSize: %d vLumBufSize: %d vChrFilterSize: %d vChrBufSize: %d\n", DEBUG_BUFFERS("vLumFilterSize: %d vLumBufSize: %d vChrFilterSize: %d vChrBufSize: %d\n",
vLumFilterSize, vLumBufSize, vChrFilterSize, vChrBufSize); vLumFilterSize, vLumBufSize, vChrFilterSize, vChrBufSize);
if (dstStride[0]%16 !=0 || dstStride[1]%16 !=0 || dstStride[2]%16 !=0 || dstStride[3]%16 != 0) { if (dstStride[0]%16 !=0 || dstStride[1]%16 !=0 ||
static int warnedAlready=0; //FIXME move this into the context perhaps dstStride[2]%16 !=0 || dstStride[3]%16 != 0) {
static int warnedAlready = 0; // FIXME maybe move this into the context
if (flags & SWS_PRINT_INFO && !warnedAlready) { if (flags & SWS_PRINT_INFO && !warnedAlready) {
av_log(c, AV_LOG_WARNING, "Warning: dstStride is not aligned!\n" av_log(c, AV_LOG_WARNING,
"Warning: dstStride is not aligned!\n"
" ->cannot do aligned memory accesses anymore\n"); " ->cannot do aligned memory accesses anymore\n");
warnedAlready=1; warnedAlready = 1;
} }
} }
@ -408,23 +429,23 @@ static int swScale(SwsContext *c, const uint8_t* src[],
} }
/* Note the user might start scaling the picture in the middle so this /* Note the user might start scaling the picture in the middle so this
will not get executed. This is not really intended but works * will not get executed. This is not really intended but works
currently, so people might do it. */ * currently, so people might do it. */
if (srcSliceY ==0) { if (srcSliceY == 0) {
lumBufIndex=-1; lumBufIndex = -1;
chrBufIndex=-1; chrBufIndex = -1;
dstY=0; dstY = 0;
lastInLumBuf= -1; lastInLumBuf = -1;
lastInChrBuf= -1; lastInChrBuf = -1;
} }
if (!should_dither) { if (!should_dither) {
c->chrDither8 = c->lumDither8 = ff_sws_pb_64; c->chrDither8 = c->lumDither8 = ff_sws_pb_64;
} }
lastDstY= dstY; lastDstY = dstY;
for (;dstY < dstH; dstY++) { for (; dstY < dstH; dstY++) {
const int chrDstY= dstY>>c->chrDstVSubSample; const int chrDstY = dstY >> c->chrDstVSubSample;
uint8_t *dest[4] = { uint8_t *dest[4] = {
dst[0] + dstStride[0] * dstY, dst[0] + dstStride[0] * dstY,
dst[1] + dstStride[1] * chrDstY, dst[1] + dstStride[1] * chrDstY,
@ -433,9 +454,11 @@ static int swScale(SwsContext *c, const uint8_t* src[],
}; };
int use_mmx_vfilter= c->use_mmx_vfilter; int use_mmx_vfilter= c->use_mmx_vfilter;
const int firstLumSrcY= FFMAX(1 - vLumFilterSize, vLumFilterPos[dstY]); //First line needed as input // First line needed as input
const int firstLumSrcY2= FFMAX(1 - vLumFilterSize, vLumFilterPos[FFMIN(dstY | ((1<<c->chrDstVSubSample) - 1), dstH-1)]); const int firstLumSrcY = FFMAX(1 - vLumFilterSize, vLumFilterPos[dstY]);
const int firstChrSrcY= FFMAX(1 - vChrFilterSize, vChrFilterPos[chrDstY]); //First line needed as input const int firstLumSrcY2 = FFMAX(1 - vLumFilterSize, vLumFilterPos[FFMIN(dstY | ((1 << c->chrDstVSubSample) - 1), dstH - 1)]);
// First line needed as input
const int firstChrSrcY = FFMAX(1 - vChrFilterSize, vChrFilterPos[chrDstY]);
// Last line needed as input // Last line needed as input
int lastLumSrcY = FFMIN(c->srcH, firstLumSrcY + vLumFilterSize) - 1; int lastLumSrcY = FFMIN(c->srcH, firstLumSrcY + vLumFilterSize) - 1;
@ -443,9 +466,11 @@ static int swScale(SwsContext *c, const uint8_t* src[],
int lastChrSrcY = FFMIN(c->chrSrcH, firstChrSrcY + vChrFilterSize) - 1; int lastChrSrcY = FFMIN(c->chrSrcH, firstChrSrcY + vChrFilterSize) - 1;
int enough_lines; int enough_lines;
//handle holes (FAST_BILINEAR & weird filters) // handle holes (FAST_BILINEAR & weird filters)
if (firstLumSrcY > lastInLumBuf) lastInLumBuf= firstLumSrcY-1; if (firstLumSrcY > lastInLumBuf)
if (firstChrSrcY > lastInChrBuf) lastInChrBuf= firstChrSrcY-1; lastInLumBuf = firstLumSrcY - 1;
if (firstChrSrcY > lastInChrBuf)
lastInChrBuf = firstChrSrcY - 1;
assert(firstLumSrcY >= lastInLumBuf - vLumBufSize + 1); assert(firstLumSrcY >= lastInLumBuf - vLumBufSize + 1);
assert(firstChrSrcY >= lastInChrBuf - vChrBufSize + 1); assert(firstChrSrcY >= lastInChrBuf - vChrBufSize + 1);
@ -456,7 +481,8 @@ static int swScale(SwsContext *c, const uint8_t* src[],
firstChrSrcY, lastChrSrcY, lastInChrBuf); firstChrSrcY, lastChrSrcY, lastInChrBuf);
// Do we have enough lines in this slice to output the dstY line // Do we have enough lines in this slice to output the dstY line
enough_lines = lastLumSrcY2 < srcSliceY + srcSliceH && lastChrSrcY < -((-srcSliceY - srcSliceH)>>c->chrSrcVSubSample); enough_lines = lastLumSrcY2 < srcSliceY + srcSliceH &&
lastChrSrcY < -((-srcSliceY - srcSliceH) >> c->chrSrcVSubSample);
if (!enough_lines) { if (!enough_lines) {
lastLumSrcY = srcSliceY + srcSliceH - 1; lastLumSrcY = srcSliceY + srcSliceH - 1;
@ -465,8 +491,8 @@ static int swScale(SwsContext *c, const uint8_t* src[],
lastLumSrcY, lastChrSrcY); lastLumSrcY, lastChrSrcY);
} }
//Do horizontal scaling // Do horizontal scaling
while(lastInLumBuf < lastLumSrcY) { while (lastInLumBuf < lastLumSrcY) {
const uint8_t *src1[4] = { const uint8_t *src1[4] = {
src[0] + (lastInLumBuf + 1 - srcSliceY) * srcStride[0], src[0] + (lastInLumBuf + 1 - srcSliceY) * srcStride[0],
src[1] + (lastInLumBuf + 1 - srcSliceY) * srcStride[1], src[1] + (lastInLumBuf + 1 - srcSliceY) * srcStride[1],
@ -474,23 +500,21 @@ static int swScale(SwsContext *c, const uint8_t* src[],
src[3] + (lastInLumBuf + 1 - srcSliceY) * srcStride[3], src[3] + (lastInLumBuf + 1 - srcSliceY) * srcStride[3],
}; };
lumBufIndex++; lumBufIndex++;
assert(lumBufIndex < 2*vLumBufSize); assert(lumBufIndex < 2 * vLumBufSize);
assert(lastInLumBuf + 1 - srcSliceY < srcSliceH); assert(lastInLumBuf + 1 - srcSliceY < srcSliceH);
assert(lastInLumBuf + 1 - srcSliceY >= 0); assert(lastInLumBuf + 1 - srcSliceY >= 0);
hyscale(c, lumPixBuf[ lumBufIndex ], dstW, src1, srcW, lumXInc, hyscale(c, lumPixBuf[lumBufIndex], dstW, src1, srcW, lumXInc,
hLumFilter, hLumFilterPos, hLumFilterSize, hLumFilter, hLumFilterPos, hLumFilterSize,
formatConvBuffer, formatConvBuffer, pal, 0);
pal, 0);
if (CONFIG_SWSCALE_ALPHA && alpPixBuf) if (CONFIG_SWSCALE_ALPHA && alpPixBuf)
hyscale(c, alpPixBuf[ lumBufIndex ], dstW, src1, srcW, hyscale(c, alpPixBuf[lumBufIndex], dstW, src1, srcW,
lumXInc, hLumFilter, hLumFilterPos, hLumFilterSize, lumXInc, hLumFilter, hLumFilterPos, hLumFilterSize,
formatConvBuffer, formatConvBuffer, pal, 1);
pal, 1);
lastInLumBuf++; lastInLumBuf++;
DEBUG_BUFFERS("\t\tlumBufIndex %d: lastInLumBuf: %d\n", DEBUG_BUFFERS("\t\tlumBufIndex %d: lastInLumBuf: %d\n",
lumBufIndex, lastInLumBuf); lumBufIndex, lastInLumBuf);
} }
while(lastInChrBuf < lastChrSrcY) { while (lastInChrBuf < lastChrSrcY) {
const uint8_t *src1[4] = { const uint8_t *src1[4] = {
src[0] + (lastInChrBuf + 1 - chrSrcSliceY) * srcStride[0], src[0] + (lastInChrBuf + 1 - chrSrcSliceY) * srcStride[0],
src[1] + (lastInChrBuf + 1 - chrSrcSliceY) * srcStride[1], src[1] + (lastInChrBuf + 1 - chrSrcSliceY) * srcStride[1],
@ -498,10 +522,10 @@ static int swScale(SwsContext *c, const uint8_t* src[],
src[3] + (lastInChrBuf + 1 - chrSrcSliceY) * srcStride[3], src[3] + (lastInChrBuf + 1 - chrSrcSliceY) * srcStride[3],
}; };
chrBufIndex++; chrBufIndex++;
assert(chrBufIndex < 2*vChrBufSize); assert(chrBufIndex < 2 * vChrBufSize);
assert(lastInChrBuf + 1 - chrSrcSliceY < (chrSrcSliceH)); assert(lastInChrBuf + 1 - chrSrcSliceY < (chrSrcSliceH));
assert(lastInChrBuf + 1 - chrSrcSliceY >= 0); assert(lastInChrBuf + 1 - chrSrcSliceY >= 0);
//FIXME replace parameters through context struct (some at least) // FIXME replace parameters through context struct (some at least)
if (c->needs_hcscale) if (c->needs_hcscale)
hcscale(c, chrUPixBuf[chrBufIndex], chrVPixBuf[chrBufIndex], hcscale(c, chrUPixBuf[chrBufIndex], chrVPixBuf[chrBufIndex],
@ -512,36 +536,42 @@ static int swScale(SwsContext *c, const uint8_t* src[],
DEBUG_BUFFERS("\t\tchrBufIndex %d: lastInChrBuf: %d\n", DEBUG_BUFFERS("\t\tchrBufIndex %d: lastInChrBuf: %d\n",
chrBufIndex, lastInChrBuf); chrBufIndex, lastInChrBuf);
} }
//wrap buf index around to stay inside the ring buffer // wrap buf index around to stay inside the ring buffer
if (lumBufIndex >= vLumBufSize) lumBufIndex-= vLumBufSize; if (lumBufIndex >= vLumBufSize)
if (chrBufIndex >= vChrBufSize) chrBufIndex-= vChrBufSize; lumBufIndex -= vLumBufSize;
if (chrBufIndex >= vChrBufSize)
chrBufIndex -= vChrBufSize;
if (!enough_lines) if (!enough_lines)
break; //we can't output a dstY line so let's try with the next slice break; // we can't output a dstY line so let's try with the next slice
#if HAVE_MMX #if HAVE_MMX
updateMMXDitherTables(c, dstY, lumBufIndex, chrBufIndex, lastInLumBuf, lastInChrBuf); updateMMXDitherTables(c, dstY, lumBufIndex, chrBufIndex,
lastInLumBuf, lastInChrBuf);
#endif #endif
if (should_dither) { if (should_dither) {
c->chrDither8 = dither_8x8_128[chrDstY & 7]; c->chrDither8 = dither_8x8_128[chrDstY & 7];
c->lumDither8 = dither_8x8_128[dstY & 7]; c->lumDither8 = dither_8x8_128[dstY & 7];
} }
if (dstY >= dstH-2) { if (dstY >= dstH - 2) {
// hmm looks like we can't use MMX here without overwriting this array's tail /* hmm looks like we can't use MMX here without overwriting
* this array's tail */
ff_sws_init_output_funcs(c, &yuv2plane1, &yuv2planeX, &yuv2nv12cX, ff_sws_init_output_funcs(c, &yuv2plane1, &yuv2planeX, &yuv2nv12cX,
&yuv2packed1, &yuv2packed2, &yuv2packedX); &yuv2packed1, &yuv2packed2, &yuv2packedX);
use_mmx_vfilter= 0; use_mmx_vfilter= 0;
} }
{ {
const int16_t **lumSrcPtr= (const int16_t **)(void*) lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize; const int16_t **lumSrcPtr = (const int16_t **)(void*) lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize;
const int16_t **chrUSrcPtr= (const int16_t **)(void*) chrUPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize; const int16_t **chrUSrcPtr = (const int16_t **)(void*) chrUPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
const int16_t **chrVSrcPtr= (const int16_t **)(void*) chrVPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize; const int16_t **chrVSrcPtr = (const int16_t **)(void*) chrVPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
const int16_t **alpSrcPtr= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? (const int16_t **)(void*) alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL; const int16_t **alpSrcPtr = (CONFIG_SWSCALE_ALPHA && alpPixBuf) ?
int16_t *vLumFilter= c->vLumFilter; (const int16_t **)(void*) alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL;
int16_t *vChrFilter= c->vChrFilter; int16_t *vLumFilter = c->vLumFilter;
int16_t *vChrFilter = c->vChrFilter;
if (isPlanarYUV(dstFormat) || (isGray(dstFormat) && !isALPHA(dstFormat))) { //YV12 like if (isPlanarYUV(dstFormat) ||
const int chrSkipMask= (1<<c->chrDstVSubSample)-1; (isGray(dstFormat) && !isALPHA(dstFormat))) { // YV12 like
const int chrSkipMask = (1 << c->chrDstVSubSample) - 1;
vLumFilter += dstY * vLumFilterSize; vLumFilter += dstY * vLumFilterSize;
vChrFilter += chrDstY * vChrFilterSize; vChrFilter += chrDstY * vChrFilterSize;
@ -564,53 +594,62 @@ static int swScale(SwsContext *c, const uint8_t* src[],
yuv2plane1(lumSrcPtr[0], dest[0], dstW, c->lumDither8, 0); yuv2plane1(lumSrcPtr[0], dest[0], dstW, c->lumDither8, 0);
} else { } else {
yuv2planeX(vLumFilter, vLumFilterSize, yuv2planeX(vLumFilter, vLumFilterSize,
lumSrcPtr, dest[0], dstW, c->lumDither8, 0); lumSrcPtr, dest[0],
dstW, c->lumDither8, 0);
} }
if (!((dstY&chrSkipMask) || isGray(dstFormat))) { if (!((dstY & chrSkipMask) || isGray(dstFormat))) {
if (yuv2nv12cX) { if (yuv2nv12cX) {
yuv2nv12cX(c, vChrFilter, vChrFilterSize, chrUSrcPtr, chrVSrcPtr, dest[1], chrDstW); yuv2nv12cX(c, vChrFilter,
vChrFilterSize, chrUSrcPtr, chrVSrcPtr,
dest[1], chrDstW);
} else if (vChrFilterSize == 1) { } else if (vChrFilterSize == 1) {
yuv2plane1(chrUSrcPtr[0], dest[1], chrDstW, c->chrDither8, 0); yuv2plane1(chrUSrcPtr[0], dest[1], chrDstW, c->chrDither8, 0);
yuv2plane1(chrVSrcPtr[0], dest[2], chrDstW, c->chrDither8, 3); yuv2plane1(chrVSrcPtr[0], dest[2], chrDstW, c->chrDither8, 3);
} else { } else {
yuv2planeX(vChrFilter, vChrFilterSize, yuv2planeX(vChrFilter,
chrUSrcPtr, dest[1], chrDstW, c->chrDither8, 0); vChrFilterSize, chrUSrcPtr, dest[1],
yuv2planeX(vChrFilter, vChrFilterSize, chrDstW, c->chrDither8, 0);
chrVSrcPtr, dest[2], chrDstW, c->chrDither8, use_mmx_vfilter ? (c->uv_offx2 >> 1) : 3); yuv2planeX(vChrFilter,
vChrFilterSize, chrVSrcPtr, dest[2],
chrDstW, c->chrDither8, use_mmx_vfilter ? (c->uv_offx2 >> 1) : 3);
} }
} }
if (CONFIG_SWSCALE_ALPHA && alpPixBuf){ if (CONFIG_SWSCALE_ALPHA && alpPixBuf) {
if(use_mmx_vfilter){ if(use_mmx_vfilter){
vLumFilter= c->alpMmxFilter; vLumFilter= c->alpMmxFilter;
} }
if (vLumFilterSize == 1) { if (vLumFilterSize == 1) {
yuv2plane1(alpSrcPtr[0], dest[3], dstW, c->lumDither8, 0); yuv2plane1(alpSrcPtr[0], dest[3], dstW,
c->lumDither8, 0);
} else { } else {
yuv2planeX(vLumFilter, vLumFilterSize, yuv2planeX(vLumFilter,
alpSrcPtr, dest[3], dstW, c->lumDither8, 0); vLumFilterSize, alpSrcPtr, dest[3],
dstW, c->lumDither8, 0);
} }
} }
} else { } else {
assert(lumSrcPtr + vLumFilterSize - 1 < lumPixBuf + vLumBufSize*2); assert(lumSrcPtr + vLumFilterSize - 1 < lumPixBuf + vLumBufSize * 2);
assert(chrUSrcPtr + vChrFilterSize - 1 < chrUPixBuf + vChrBufSize*2); assert(chrUSrcPtr + vChrFilterSize - 1 < chrUPixBuf + vChrBufSize * 2);
if (c->yuv2packed1 && vLumFilterSize == 1 && vChrFilterSize <= 2) { //unscaled RGB if (c->yuv2packed1 && vLumFilterSize == 1 &&
vChrFilterSize <= 2) { // unscaled RGB
int chrAlpha = vChrFilterSize == 1 ? 0 : vChrFilter[2 * dstY + 1]; int chrAlpha = vChrFilterSize == 1 ? 0 : vChrFilter[2 * dstY + 1];
yuv2packed1(c, *lumSrcPtr, chrUSrcPtr, chrVSrcPtr, yuv2packed1(c, *lumSrcPtr, chrUSrcPtr, chrVSrcPtr,
alpPixBuf ? *alpSrcPtr : NULL, alpPixBuf ? *alpSrcPtr : NULL,
dest[0], dstW, chrAlpha, dstY); dest[0], dstW, chrAlpha, dstY);
} else if (c->yuv2packed2 && vLumFilterSize == 2 && vChrFilterSize == 2) { //bilinear upscale RGB } else if (c->yuv2packed2 && vLumFilterSize == 2 &&
vChrFilterSize == 2) { // bilinear upscale RGB
int lumAlpha = vLumFilter[2 * dstY + 1]; int lumAlpha = vLumFilter[2 * dstY + 1];
int chrAlpha = vChrFilter[2 * dstY + 1]; int chrAlpha = vChrFilter[2 * dstY + 1];
lumMmxFilter[2] = lumMmxFilter[2] =
lumMmxFilter[3] = vLumFilter[2 * dstY ] * 0x10001; lumMmxFilter[3] = vLumFilter[2 * dstY] * 0x10001;
chrMmxFilter[2] = chrMmxFilter[2] =
chrMmxFilter[3] = vChrFilter[2 * chrDstY] * 0x10001; chrMmxFilter[3] = vChrFilter[2 * chrDstY] * 0x10001;
yuv2packed2(c, lumSrcPtr, chrUSrcPtr, chrVSrcPtr, yuv2packed2(c, lumSrcPtr, chrUSrcPtr, chrVSrcPtr,
alpPixBuf ? alpSrcPtr : NULL, alpPixBuf ? alpSrcPtr : NULL,
dest[0], dstW, lumAlpha, chrAlpha, dstY); dest[0], dstW, lumAlpha, chrAlpha, dstY);
} else { //general RGB } else { // general RGB
yuv2packedX(c, vLumFilter + dstY * vLumFilterSize, yuv2packedX(c, vLumFilter + dstY * vLumFilterSize,
lumSrcPtr, vLumFilterSize, lumSrcPtr, vLumFilterSize,
vChrFilter + dstY * vChrFilterSize, vChrFilter + dstY * vChrFilterSize,
@ -622,20 +661,20 @@ static int swScale(SwsContext *c, const uint8_t* src[],
} }
if (isPlanar(dstFormat) && isALPHA(dstFormat) && !alpPixBuf) if (isPlanar(dstFormat) && isALPHA(dstFormat) && !alpPixBuf)
fillPlane(dst[3], dstStride[3], dstW, dstY-lastDstY, lastDstY, 255); fillPlane(dst[3], dstStride[3], dstW, dstY - lastDstY, lastDstY, 255);
#if HAVE_MMX2 #if HAVE_MMX2
if (av_get_cpu_flags() & AV_CPU_FLAG_MMX2) if (av_get_cpu_flags() & AV_CPU_FLAG_MMX2)
__asm__ volatile("sfence":::"memory"); __asm__ volatile ("sfence" ::: "memory");
#endif #endif
emms_c(); emms_c();
/* store changed local vars back in the context */ /* store changed local vars back in the context */
c->dstY= dstY; c->dstY = dstY;
c->lumBufIndex= lumBufIndex; c->lumBufIndex = lumBufIndex;
c->chrBufIndex= chrBufIndex; c->chrBufIndex = chrBufIndex;
c->lastInLumBuf= lastInLumBuf; c->lastInLumBuf = lastInLumBuf;
c->lastInChrBuf= lastInChrBuf; c->lastInChrBuf = lastInChrBuf;
return dstY - lastDstY; return dstY - lastDstY;
} }
@ -662,7 +701,8 @@ static av_cold void sws_init_swScale_c(SwsContext *c)
c->hyScale = c->hcScale = hScale8To19_c; c->hyScale = c->hcScale = hScale8To19_c;
} }
} else { } else {
c->hyScale = c->hcScale = c->dstBpc > 10 ? hScale16To19_c : hScale16To15_c; c->hyScale = c->hcScale = c->dstBpc > 10 ? hScale16To19_c
: hScale16To15_c;
} }
if (c->srcRange != c->dstRange && !isAnyRGB(c->dstFormat)) { if (c->srcRange != c->dstRange && !isAnyRGB(c->dstFormat)) {

File diff suppressed because it is too large Load Diff

11
libswscale/x86/Makefile Normal file
View File

@ -0,0 +1,11 @@
$(SUBDIR)x86/swscale_mmx.o: CFLAGS += $(NOREDZONE_FLAGS)
OBJS-$(CONFIG_XMM_CLOBBER_TEST) += x86/w64xmmtest.o
MMX-OBJS += x86/rgb2rgb.o \
x86/swscale_mmx.o \
x86/yuv2rgb_mmx.o \
YASM-OBJS += x86/input.o \
x86/output.o \
x86/scale.o \