#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
+#include "libavutil/ppc/cpu.h"
#include "libavutil/x86/asm.h"
#include "libavutil/x86/cpu.h"
#include "rgb2rgb.h"
#define RET 0xC3 // near return opcode for x86
typedef struct FormatEntry {
- int is_supported_in, is_supported_out;
+ uint8_t is_supported_in :1;
+ uint8_t is_supported_out :1;
+ uint8_t is_supported_endianness :1;
} FormatEntry;
static const FormatEntry format_entries[AV_PIX_FMT_NB] = {
[AV_PIX_FMT_YUVJ420P] = { 1, 1 },
[AV_PIX_FMT_YUVJ422P] = { 1, 1 },
[AV_PIX_FMT_YUVJ444P] = { 1, 1 },
+ [AV_PIX_FMT_YVYU422] = { 1, 1 },
[AV_PIX_FMT_UYVY422] = { 1, 1 },
[AV_PIX_FMT_UYYVYY411] = { 0, 0 },
[AV_PIX_FMT_BGR8] = { 1, 1 },
[AV_PIX_FMT_YUVA444P16LE]= { 1, 1 },
[AV_PIX_FMT_RGB48BE] = { 1, 1 },
[AV_PIX_FMT_RGB48LE] = { 1, 1 },
+ [AV_PIX_FMT_RGBA64BE] = { 0, 0, 1 },
+ [AV_PIX_FMT_RGBA64LE] = { 0, 0, 1 },
[AV_PIX_FMT_RGB565BE] = { 1, 1 },
[AV_PIX_FMT_RGB565LE] = { 1, 1 },
[AV_PIX_FMT_RGB555BE] = { 1, 1 },
[AV_PIX_FMT_RGB444BE] = { 1, 1 },
[AV_PIX_FMT_BGR444LE] = { 1, 1 },
[AV_PIX_FMT_BGR444BE] = { 1, 1 },
- [AV_PIX_FMT_Y400A] = { 1, 0 },
+ [AV_PIX_FMT_YA8] = { 1, 0 },
+ [AV_PIX_FMT_YA16BE] = { 1, 0 },
+ [AV_PIX_FMT_YA16LE] = { 1, 0 },
[AV_PIX_FMT_BGR48BE] = { 1, 1 },
[AV_PIX_FMT_BGR48LE] = { 1, 1 },
+ [AV_PIX_FMT_BGRA64BE] = { 0, 0, 1 },
+ [AV_PIX_FMT_BGRA64LE] = { 0, 0, 1 },
[AV_PIX_FMT_YUV420P9BE] = { 1, 1 },
[AV_PIX_FMT_YUV420P9LE] = { 1, 1 },
[AV_PIX_FMT_YUV420P10BE] = { 1, 1 },
[AV_PIX_FMT_GBRP10BE] = { 1, 1 },
[AV_PIX_FMT_GBRP16LE] = { 1, 0 },
[AV_PIX_FMT_GBRP16BE] = { 1, 0 },
+ [AV_PIX_FMT_GBRAP] = { 1, 1 },
+ [AV_PIX_FMT_GBRAP16LE] = { 1, 0 },
+ [AV_PIX_FMT_GBRAP16BE] = { 1, 0 },
+ [AV_PIX_FMT_XYZ12BE] = { 0, 0, 1 },
+ [AV_PIX_FMT_XYZ12LE] = { 0, 0, 1 },
};
int sws_isSupportedInput(enum AVPixelFormat pix_fmt)
format_entries[pix_fmt].is_supported_out : 0;
}
-extern const int32_t ff_yuv2rgb_coeffs[8][4];
+int sws_isSupportedEndiannessConversion(enum AVPixelFormat pix_fmt)
+{
+ return (unsigned)pix_fmt < AV_PIX_FMT_NB ?
+ format_entries[pix_fmt].is_supported_endianness : 0;
+}
const char *sws_format_name(enum AVPixelFormat format)
{
xDstInSrc = xInc - 0x10000;
for (i = 0; i < dstW; i++) {
- int xx = (xDstInSrc - ((filterSize - 2) << 16)) / (1 << 17);
+ int xx = (xDstInSrc - ((int64_t)(filterSize - 2) << 16)) / (1 << 17);
int j;
(*filterPos)[i] = xx;
for (j = 0; j < filterSize; j++) {
minFilterSize = min;
}
- if (HAVE_ALTIVEC && cpu_flags & AV_CPU_FLAG_ALTIVEC) {
+ if (PPC_ALTIVEC(cpu_flags)) {
// we can handle the special case 4, so we don't want to go the full 8
if (minFilterSize < 5)
filterAlign = 4;
contrast, saturation);
// FIXME factorize
- if (HAVE_ALTIVEC && av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC)
- ff_yuv2rgb_init_tables_altivec(c, inv_table, brightness,
- contrast, saturation);
+ if (ARCH_PPC)
+ ff_yuv2rgb_init_tables_ppc(c, inv_table, brightness,
+ contrast, saturation);
return 0;
}
unscaled = (srcW == dstW && srcH == dstH);
+ if (!(unscaled && sws_isSupportedEndiannessConversion(srcFormat) &&
+ av_pix_fmt_swap_endianness(srcFormat) == dstFormat)) {
if (!sws_isSupportedInput(srcFormat)) {
av_log(c, AV_LOG_ERROR, "%s is not supported as input pixel format\n",
sws_format_name(srcFormat));
sws_format_name(dstFormat));
return AVERROR(EINVAL);
}
+ }
i = flags & (SWS_POINT |
SWS_AREA |
SWS_SINC |
SWS_SPLINE |
SWS_BICUBLIN);
- if (!i || (i & (i - 1))) {
+
+ /* provide a default scaler if not set by caller */
+ if (!i) {
+ if (dstW < srcW && dstH < srcH)
+ flags |= SWS_GAUSS;
+ else if (dstW > srcW && dstH > srcH)
+ flags |= SWS_SINC;
+ else
+ flags |= SWS_LANCZOS;
+ c->flags = flags;
+ } else if (i & (i - 1)) {
av_log(c, AV_LOG_ERROR,
"Exactly one scaler algorithm must be chosen\n");
return AVERROR(EINVAL);
(c->srcRange == c->dstRange || isAnyRGB(dstFormat))) {
ff_get_unscaled_swscale(c);
- if (c->swScale) {
+ if (c->swscale) {
if (flags & SWS_PRINT_INFO)
av_log(c, AV_LOG_INFO,
"using unscaled %s -> %s special converter\n",
}
}
- c->srcBpc = 1 + desc_src->comp[0].depth_minus1;
+ c->srcBpc = desc_src->comp[0].depth;
if (c->srcBpc < 8)
c->srcBpc = 8;
- c->dstBpc = 1 + desc_dst->comp[0].depth_minus1;
+ c->dstBpc = desc_dst->comp[0].depth;
if (c->dstBpc < 8)
c->dstBpc = 8;
if (c->dstBpc == 16)
} else
#endif /* HAVE_MMXEXT_INLINE */
{
- const int filterAlign =
- (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) ? 4 :
- (HAVE_ALTIVEC && cpu_flags & AV_CPU_FLAG_ALTIVEC) ? 8 :
- 1;
+ const int filterAlign = X86_MMX(cpu_flags) ? 4 :
+ PPC_ALTIVEC(cpu_flags) ? 8 : 1;
if (initFilter(&c->hLumFilter, &c->hLumFilterPos,
&c->hLumFilterSize, c->lumXInc,
/* precalculate vertical scaler filter coefficients */
{
- const int filterAlign =
- (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) ? 2 :
- (HAVE_ALTIVEC && cpu_flags & AV_CPU_FLAG_ALTIVEC) ? 8 :
- 1;
+ const int filterAlign = X86_MMX(cpu_flags) ? 2 :
+ PPC_ALTIVEC(cpu_flags) ? 8 : 1;
if (initFilter(&c->vLumFilter, &c->vLumFilterPos, &c->vLumFilterSize,
c->lumYInc, srcH, dstH, filterAlign, (1 << 12),
av_log(c, AV_LOG_INFO, "using 3DNOW\n");
else if (INLINE_MMX(cpu_flags))
av_log(c, AV_LOG_INFO, "using MMX\n");
- else if (HAVE_ALTIVEC && cpu_flags & AV_CPU_FLAG_ALTIVEC)
+ else if (PPC_ALTIVEC(cpu_flags))
av_log(c, AV_LOG_INFO, "using AltiVec\n");
else
av_log(c, AV_LOG_INFO, "using C\n");
c->chrXInc, c->chrYInc);
}
- c->swScale = ff_getSwsFunc(c);
+ c->swscale = ff_getSwsFunc(c);
return 0;
fail: // FIXME replace things by appropriate error codes
return -1;
}
-#if FF_API_SWS_GETCONTEXT
SwsContext *sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat,
int dstW, int dstH, enum AVPixelFormat dstFormat,
int flags, SwsFilter *srcFilter,
return c;
}
-#endif
SwsFilter *sws_getDefaultFilter(float lumaGBlur, float chromaGBlur,
float lumaSharpen, float chromaSharpen,
filter->chrV = sws_getIdentityVec();
}
+ if (!filter->lumH || !filter->lumV || !filter->chrH || !filter->chrV)
+ goto fail;
+
if (chromaSharpen != 0.0) {
SwsVector *id = sws_getIdentityVec();
+ if (!id)
+ goto fail;
sws_scaleVec(filter->chrH, -chromaSharpen);
sws_scaleVec(filter->chrV, -chromaSharpen);
sws_addVec(filter->chrH, id);
if (lumaSharpen != 0.0) {
SwsVector *id = sws_getIdentityVec();
+ if (!id)
+ goto fail;
sws_scaleVec(filter->lumH, -lumaSharpen);
sws_scaleVec(filter->lumV, -lumaSharpen);
sws_addVec(filter->lumH, id);
sws_printVec2(filter->lumH, NULL, AV_LOG_DEBUG);
return filter;
+
+fail:
+ sws_freeVec(filter->lumH);
+ sws_freeVec(filter->lumV);
+ sws_freeVec(filter->chrH);
+ sws_freeVec(filter->chrV);
+ av_freep(&filter);
+ return NULL;
}
SwsVector *sws_allocVec(int length)