#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"
#include "swscale.h"
#include "swscale_internal.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[PIX_FMT_NB] = {
- [PIX_FMT_YUV420P] = { 1, 1 },
- [PIX_FMT_YUYV422] = { 1, 1 },
- [PIX_FMT_RGB24] = { 1, 1 },
- [PIX_FMT_BGR24] = { 1, 1 },
- [PIX_FMT_YUV422P] = { 1, 1 },
- [PIX_FMT_YUV444P] = { 1, 1 },
- [PIX_FMT_YUV410P] = { 1, 1 },
- [PIX_FMT_YUV411P] = { 1, 1 },
- [PIX_FMT_GRAY8] = { 1, 1 },
- [PIX_FMT_MONOWHITE] = { 1, 1 },
- [PIX_FMT_MONOBLACK] = { 1, 1 },
- [PIX_FMT_PAL8] = { 1, 0 },
- [PIX_FMT_YUVJ420P] = { 1, 1 },
- [PIX_FMT_YUVJ422P] = { 1, 1 },
- [PIX_FMT_YUVJ444P] = { 1, 1 },
- [PIX_FMT_UYVY422] = { 1, 1 },
- [PIX_FMT_UYYVYY411] = { 0, 0 },
- [PIX_FMT_BGR8] = { 1, 1 },
- [PIX_FMT_BGR4] = { 0, 1 },
- [PIX_FMT_BGR4_BYTE] = { 1, 1 },
- [PIX_FMT_RGB8] = { 1, 1 },
- [PIX_FMT_RGB4] = { 0, 1 },
- [PIX_FMT_RGB4_BYTE] = { 1, 1 },
- [PIX_FMT_NV12] = { 1, 1 },
- [PIX_FMT_NV21] = { 1, 1 },
- [PIX_FMT_ARGB] = { 1, 1 },
- [PIX_FMT_RGBA] = { 1, 1 },
- [PIX_FMT_ABGR] = { 1, 1 },
- [PIX_FMT_BGRA] = { 1, 1 },
- [PIX_FMT_GRAY16BE] = { 1, 1 },
- [PIX_FMT_GRAY16LE] = { 1, 1 },
- [PIX_FMT_YUV440P] = { 1, 1 },
- [PIX_FMT_YUVJ440P] = { 1, 1 },
- [PIX_FMT_YUVA420P] = { 1, 1 },
- [PIX_FMT_RGB48BE] = { 1, 1 },
- [PIX_FMT_RGB48LE] = { 1, 1 },
- [PIX_FMT_RGB565BE] = { 1, 1 },
- [PIX_FMT_RGB565LE] = { 1, 1 },
- [PIX_FMT_RGB555BE] = { 1, 1 },
- [PIX_FMT_RGB555LE] = { 1, 1 },
- [PIX_FMT_BGR565BE] = { 1, 1 },
- [PIX_FMT_BGR565LE] = { 1, 1 },
- [PIX_FMT_BGR555BE] = { 1, 1 },
- [PIX_FMT_BGR555LE] = { 1, 1 },
- [PIX_FMT_YUV420P16LE] = { 1, 1 },
- [PIX_FMT_YUV420P16BE] = { 1, 1 },
- [PIX_FMT_YUV422P16LE] = { 1, 1 },
- [PIX_FMT_YUV422P16BE] = { 1, 1 },
- [PIX_FMT_YUV444P16LE] = { 1, 1 },
- [PIX_FMT_YUV444P16BE] = { 1, 1 },
- [PIX_FMT_RGB444LE] = { 1, 1 },
- [PIX_FMT_RGB444BE] = { 1, 1 },
- [PIX_FMT_BGR444LE] = { 1, 1 },
- [PIX_FMT_BGR444BE] = { 1, 1 },
- [PIX_FMT_Y400A] = { 1, 0 },
- [PIX_FMT_BGR48BE] = { 1, 1 },
- [PIX_FMT_BGR48LE] = { 1, 1 },
- [PIX_FMT_YUV420P9BE] = { 1, 1 },
- [PIX_FMT_YUV420P9LE] = { 1, 1 },
- [PIX_FMT_YUV420P10BE] = { 1, 1 },
- [PIX_FMT_YUV420P10LE] = { 1, 1 },
- [PIX_FMT_YUV422P9BE] = { 1, 1 },
- [PIX_FMT_YUV422P9LE] = { 1, 1 },
- [PIX_FMT_YUV422P10BE] = { 1, 1 },
- [PIX_FMT_YUV422P10LE] = { 1, 1 },
- [PIX_FMT_YUV444P9BE] = { 1, 1 },
- [PIX_FMT_YUV444P9LE] = { 1, 1 },
- [PIX_FMT_YUV444P10BE] = { 1, 1 },
- [PIX_FMT_YUV444P10LE] = { 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_GBRP16LE] = { 1, 0 },
- [PIX_FMT_GBRP16BE] = { 1, 0 },
+static const FormatEntry format_entries[AV_PIX_FMT_NB] = {
+ [AV_PIX_FMT_YUV420P] = { 1, 1 },
+ [AV_PIX_FMT_YUYV422] = { 1, 1 },
+ [AV_PIX_FMT_RGB24] = { 1, 1 },
+ [AV_PIX_FMT_BGR24] = { 1, 1 },
+ [AV_PIX_FMT_YUV422P] = { 1, 1 },
+ [AV_PIX_FMT_YUV444P] = { 1, 1 },
+ [AV_PIX_FMT_YUV410P] = { 1, 1 },
+ [AV_PIX_FMT_YUV411P] = { 1, 1 },
+ [AV_PIX_FMT_GRAY8] = { 1, 1 },
+ [AV_PIX_FMT_MONOWHITE] = { 1, 1 },
+ [AV_PIX_FMT_MONOBLACK] = { 1, 1 },
+ [AV_PIX_FMT_PAL8] = { 1, 0 },
+ [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_BGR4] = { 0, 1 },
+ [AV_PIX_FMT_BGR4_BYTE] = { 1, 1 },
+ [AV_PIX_FMT_RGB8] = { 1, 1 },
+ [AV_PIX_FMT_RGB4] = { 0, 1 },
+ [AV_PIX_FMT_RGB4_BYTE] = { 1, 1 },
+ [AV_PIX_FMT_NV12] = { 1, 1 },
+ [AV_PIX_FMT_NV21] = { 1, 1 },
+ [AV_PIX_FMT_ARGB] = { 1, 1 },
+ [AV_PIX_FMT_RGBA] = { 1, 1 },
+ [AV_PIX_FMT_ABGR] = { 1, 1 },
+ [AV_PIX_FMT_BGRA] = { 1, 1 },
+ [AV_PIX_FMT_GRAY16BE] = { 1, 1 },
+ [AV_PIX_FMT_GRAY16LE] = { 1, 1 },
+ [AV_PIX_FMT_YUV440P] = { 1, 1 },
+ [AV_PIX_FMT_YUVJ440P] = { 1, 1 },
+ [AV_PIX_FMT_YUVA420P] = { 1, 1 },
+ [AV_PIX_FMT_YUVA422P] = { 1, 1 },
+ [AV_PIX_FMT_YUVA444P] = { 1, 1 },
+ [AV_PIX_FMT_YUVA420P9BE] = { 1, 1 },
+ [AV_PIX_FMT_YUVA420P9LE] = { 1, 1 },
+ [AV_PIX_FMT_YUVA422P9BE] = { 1, 1 },
+ [AV_PIX_FMT_YUVA422P9LE] = { 1, 1 },
+ [AV_PIX_FMT_YUVA444P9BE] = { 1, 1 },
+ [AV_PIX_FMT_YUVA444P9LE] = { 1, 1 },
+ [AV_PIX_FMT_YUVA420P10BE]= { 1, 1 },
+ [AV_PIX_FMT_YUVA420P10LE]= { 1, 1 },
+ [AV_PIX_FMT_YUVA422P10BE]= { 1, 1 },
+ [AV_PIX_FMT_YUVA422P10LE]= { 1, 1 },
+ [AV_PIX_FMT_YUVA444P10BE]= { 1, 1 },
+ [AV_PIX_FMT_YUVA444P10LE]= { 1, 1 },
+ [AV_PIX_FMT_YUVA420P16BE]= { 1, 1 },
+ [AV_PIX_FMT_YUVA420P16LE]= { 1, 1 },
+ [AV_PIX_FMT_YUVA422P16BE]= { 1, 1 },
+ [AV_PIX_FMT_YUVA422P16LE]= { 1, 1 },
+ [AV_PIX_FMT_YUVA444P16BE]= { 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_RGB555LE] = { 1, 1 },
+ [AV_PIX_FMT_BGR565BE] = { 1, 1 },
+ [AV_PIX_FMT_BGR565LE] = { 1, 1 },
+ [AV_PIX_FMT_BGR555BE] = { 1, 1 },
+ [AV_PIX_FMT_BGR555LE] = { 1, 1 },
+ [AV_PIX_FMT_YUV420P16LE] = { 1, 1 },
+ [AV_PIX_FMT_YUV420P16BE] = { 1, 1 },
+ [AV_PIX_FMT_YUV422P16LE] = { 1, 1 },
+ [AV_PIX_FMT_YUV422P16BE] = { 1, 1 },
+ [AV_PIX_FMT_YUV444P16LE] = { 1, 1 },
+ [AV_PIX_FMT_YUV444P16BE] = { 1, 1 },
+ [AV_PIX_FMT_RGB444LE] = { 1, 1 },
+ [AV_PIX_FMT_RGB444BE] = { 1, 1 },
+ [AV_PIX_FMT_BGR444LE] = { 1, 1 },
+ [AV_PIX_FMT_BGR444BE] = { 1, 1 },
+ [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_YUV420P10LE] = { 1, 1 },
+ [AV_PIX_FMT_YUV422P9BE] = { 1, 1 },
+ [AV_PIX_FMT_YUV422P9LE] = { 1, 1 },
+ [AV_PIX_FMT_YUV422P10BE] = { 1, 1 },
+ [AV_PIX_FMT_YUV422P10LE] = { 1, 1 },
+ [AV_PIX_FMT_YUV444P9BE] = { 1, 1 },
+ [AV_PIX_FMT_YUV444P9LE] = { 1, 1 },
+ [AV_PIX_FMT_YUV444P10BE] = { 1, 1 },
+ [AV_PIX_FMT_YUV444P10LE] = { 1, 1 },
+ [AV_PIX_FMT_GBRP] = { 1, 1 },
+ [AV_PIX_FMT_GBRP9LE] = { 1, 1 },
+ [AV_PIX_FMT_GBRP9BE] = { 1, 1 },
+ [AV_PIX_FMT_GBRP10LE] = { 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 PixelFormat pix_fmt)
+int sws_isSupportedInput(enum AVPixelFormat pix_fmt)
{
- return (unsigned)pix_fmt < PIX_FMT_NB ?
+ return (unsigned)pix_fmt < AV_PIX_FMT_NB ?
format_entries[pix_fmt].is_supported_in : 0;
}
-int sws_isSupportedOutput(enum PixelFormat pix_fmt)
+int sws_isSupportedOutput(enum AVPixelFormat pix_fmt)
{
- return (unsigned)pix_fmt < PIX_FMT_NB ?
+ return (unsigned)pix_fmt < AV_PIX_FMT_NB ?
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 PixelFormat format)
+const char *sws_format_name(enum AVPixelFormat format)
{
- if ((unsigned)format < PIX_FMT_NB && av_pix_fmt_descriptors[format].name)
- return av_pix_fmt_descriptors[format].name;
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(format);
+ if (desc)
+ return desc->name;
else
return "Unknown format";
}
dist - 1.0);
}
-static int initFilter(int16_t **outFilter, int32_t **filterPos,
- int *outFilterSize, int xInc, int srcW, int dstW,
- int filterAlign, int one, int flags, int cpu_flags,
- SwsVector *srcFilter, SwsVector *dstFilter,
- double param[2], int is_horizontal)
+static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos,
+ int *outFilterSize, int xInc, int srcW,
+ int dstW, int filterAlign, int one,
+ int flags, int cpu_flags,
+ SwsVector *srcFilter, SwsVector *dstFilter,
+ double param[2], int is_horizontal)
{
int i;
int filterSize;
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;
filterAlign = 1;
}
- if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) {
+ if (INLINE_MMX(cpu_flags)) {
// special case for unscaled vertical filtering
if (minFilterSize == 1 && filterAlign == 2)
filterAlign = 1;
}
#if HAVE_MMXEXT_INLINE
-static int initMMX2HScaler(int dstW, int xInc, uint8_t *filterCode,
- int16_t *filter, int32_t *filterPos, int numSplits)
+static av_cold int init_hscaler_mmxext(int dstW, int xInc, uint8_t *filterCode,
+ int16_t *filter, int32_t *filterPos,
+ int numSplits)
{
uint8_t *fragmentA;
x86_reg imm8OfPShufW1A;
int xpos, i;
// create an optimized horizontal scaling routine
- /* This scaler is made of runtime-generated MMX2 code using specially tuned
+ /* This scaler is made of runtime-generated MMXEXT code using specially tuned
* pshufw instructions. For every four output pixels, if four input pixels
* are enough for the fast bilinear scaling, then a chunk of fragmentB is
* used. If five input pixels are needed, then a chunk of fragmentA is used.
}
#endif /* HAVE_MMXEXT_INLINE */
-static void getSubSampleFactors(int *h, int *v, enum PixelFormat format)
+static void getSubSampleFactors(int *h, int *v, enum AVPixelFormat format)
{
- *h = av_pix_fmt_descriptors[format].log2_chroma_w;
- *v = av_pix_fmt_descriptors[format].log2_chroma_h;
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(format);
+ *h = desc->log2_chroma_w;
+ *v = desc->log2_chroma_h;
}
int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4],
int srcRange, const int table[4], int dstRange,
int brightness, int contrast, int saturation)
{
+ const AVPixFmtDescriptor *desc_dst = av_pix_fmt_desc_get(c->dstFormat);
+ const AVPixFmtDescriptor *desc_src = av_pix_fmt_desc_get(c->srcFormat);
memcpy(c->srcColorspaceTable, inv_table, sizeof(int) * 4);
memcpy(c->dstColorspaceTable, table, sizeof(int) * 4);
if (isYUV(c->dstFormat) || isGray(c->dstFormat))
return -1;
- c->dstFormatBpp = av_get_bits_per_pixel(&av_pix_fmt_descriptors[c->dstFormat]);
- c->srcFormatBpp = av_get_bits_per_pixel(&av_pix_fmt_descriptors[c->srcFormat]);
+ c->dstFormatBpp = av_get_bits_per_pixel(desc_dst);
+ c->srcFormatBpp = av_get_bits_per_pixel(desc_src);
ff_yuv2rgb_c_init_tables(c, inv_table, srcRange, brightness,
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;
}
return 0;
}
-static int handle_jpeg(enum PixelFormat *format)
+static int handle_jpeg(enum AVPixelFormat *format)
{
switch (*format) {
- case PIX_FMT_YUVJ420P:
- *format = PIX_FMT_YUV420P;
+ case AV_PIX_FMT_YUVJ420P:
+ *format = AV_PIX_FMT_YUV420P;
return 1;
- case PIX_FMT_YUVJ422P:
- *format = PIX_FMT_YUV422P;
+ case AV_PIX_FMT_YUVJ422P:
+ *format = AV_PIX_FMT_YUV422P;
return 1;
- case PIX_FMT_YUVJ444P:
- *format = PIX_FMT_YUV444P;
+ case AV_PIX_FMT_YUVJ444P:
+ *format = AV_PIX_FMT_YUV444P;
return 1;
- case PIX_FMT_YUVJ440P:
- *format = PIX_FMT_YUV440P;
+ case AV_PIX_FMT_YUVJ440P:
+ *format = AV_PIX_FMT_YUV440P;
return 1;
default:
return 0;
{
SwsContext *c = av_mallocz(sizeof(SwsContext));
- c->av_class = &sws_context_class;
- av_opt_set_defaults(c);
+ if (c) {
+ c->av_class = &sws_context_class;
+ av_opt_set_defaults(c);
+ }
return c;
}
int dst_stride = FFALIGN(dstW * sizeof(int16_t) + 16, 16);
int dst_stride_px = dst_stride >> 1;
int flags, cpu_flags;
- enum PixelFormat srcFormat = c->srcFormat;
- enum PixelFormat dstFormat = c->dstFormat;
+ enum AVPixelFormat srcFormat = c->srcFormat;
+ enum AVPixelFormat dstFormat = c->dstFormat;
+ const AVPixFmtDescriptor *desc_src = av_pix_fmt_desc_get(srcFormat);
+ const AVPixFmtDescriptor *desc_dst = av_pix_fmt_desc_get(dstFormat);
cpu_flags = av_get_cpu_flags();
flags = c->flags;
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->lumXInc = (((int64_t)srcW << 16) + (dstW >> 1)) / dstW;
c->lumYInc = (((int64_t)srcH << 16) + (dstH >> 1)) / dstH;
- c->dstFormatBpp = av_get_bits_per_pixel(&av_pix_fmt_descriptors[dstFormat]);
- c->srcFormatBpp = av_get_bits_per_pixel(&av_pix_fmt_descriptors[srcFormat]);
+ c->dstFormatBpp = av_get_bits_per_pixel(desc_dst);
+ c->srcFormatBpp = av_get_bits_per_pixel(desc_src);
c->vRounder = 4 * 0x0001000100010001ULL;
usesVFilter = (srcFilter->lumV && srcFilter->lumV->length > 1) ||
getSubSampleFactors(&c->chrSrcHSubSample, &c->chrSrcVSubSample, srcFormat);
getSubSampleFactors(&c->chrDstHSubSample, &c->chrDstVSubSample, dstFormat);
+ if (isPlanarRGB(dstFormat)) {
+ if (!(flags & SWS_FULL_CHR_H_INT)) {
+ av_log(c, AV_LOG_DEBUG,
+ "%s output is not supported with half chroma resolution, switching to full\n",
+ av_get_pix_fmt_name(dstFormat));
+ flags |= SWS_FULL_CHR_H_INT;
+ c->flags = flags;
+ }
+ }
+
/* reuse chroma for 2 pixels RGB/BGR unless user wants full
* chroma interpolation */
if (flags & SWS_FULL_CHR_H_INT &&
isAnyRGB(dstFormat) &&
- dstFormat != PIX_FMT_RGBA &&
- dstFormat != PIX_FMT_ARGB &&
- dstFormat != PIX_FMT_BGRA &&
- dstFormat != PIX_FMT_ABGR &&
- dstFormat != PIX_FMT_RGB24 &&
- dstFormat != PIX_FMT_BGR24) {
+ !isPlanarRGB(dstFormat) &&
+ dstFormat != AV_PIX_FMT_RGBA &&
+ dstFormat != AV_PIX_FMT_ARGB &&
+ dstFormat != AV_PIX_FMT_BGRA &&
+ dstFormat != AV_PIX_FMT_ABGR &&
+ dstFormat != AV_PIX_FMT_RGB24 &&
+ dstFormat != AV_PIX_FMT_BGR24) {
av_log(c, AV_LOG_ERROR,
"full chroma interpolation for destination format '%s' not yet implemented\n",
sws_format_name(dstFormat));
/* drop every other pixel for chroma calculation unless user
* wants full chroma */
if (isAnyRGB(srcFormat) && !(flags & SWS_FULL_CHR_H_INP) &&
- srcFormat != PIX_FMT_RGB8 && srcFormat != PIX_FMT_BGR8 &&
- srcFormat != PIX_FMT_RGB4 && srcFormat != PIX_FMT_BGR4 &&
- srcFormat != PIX_FMT_RGB4_BYTE && srcFormat != PIX_FMT_BGR4_BYTE &&
+ srcFormat != AV_PIX_FMT_RGB8 && srcFormat != AV_PIX_FMT_BGR8 &&
+ srcFormat != AV_PIX_FMT_RGB4 && srcFormat != AV_PIX_FMT_BGR4 &&
+ srcFormat != AV_PIX_FMT_RGB4_BYTE && srcFormat != AV_PIX_FMT_BGR4_BYTE &&
+ srcFormat != AV_PIX_FMT_GBRP9BE && srcFormat != AV_PIX_FMT_GBRP9LE &&
+ srcFormat != AV_PIX_FMT_GBRP10BE && srcFormat != AV_PIX_FMT_GBRP10LE &&
+ srcFormat != AV_PIX_FMT_GBRP16BE && srcFormat != AV_PIX_FMT_GBRP16LE &&
((dstW >> c->chrDstHSubSample) <= (srcW >> 1) ||
(flags & SWS_FAST_BILINEAR)))
c->chrSrcHSubSample = 1;
(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 + av_pix_fmt_descriptors[srcFormat].comp[0].depth_minus1;
+ c->srcBpc = desc_src->comp[0].depth;
if (c->srcBpc < 8)
c->srcBpc = 8;
- c->dstBpc = 1 + av_pix_fmt_descriptors[dstFormat].comp[0].depth_minus1;
+ c->dstBpc = desc_dst->comp[0].depth;
if (c->dstBpc < 8)
c->dstBpc = 8;
if (c->dstBpc == 16)
FF_ALLOC_OR_GOTO(c, c->formatConvBuffer,
(FFALIGN(srcW, 16) * 2 * FFALIGN(c->srcBpc, 8) >> 3) + 16,
fail);
- if (HAVE_MMXEXT && HAVE_INLINE_ASM && cpu_flags & AV_CPU_FLAG_MMXEXT &&
- c->srcBpc == 8 && c->dstBpc <= 10) {
- c->canMMX2BeUsed = (dstW >= srcW && (dstW & 31) == 0 &&
- (srcW & 15) == 0) ? 1 : 0;
- if (!c->canMMX2BeUsed && dstW >= srcW && (srcW & 15) == 0
+ if (INLINE_MMXEXT(cpu_flags) && c->srcBpc == 8 && c->dstBpc <= 10) {
+ c->canMMXEXTBeUsed = (dstW >= srcW && (dstW & 31) == 0 &&
+ (srcW & 15) == 0) ? 1 : 0;
+ if (!c->canMMXEXTBeUsed && dstW >= srcW && (srcW & 15) == 0
&& (flags & SWS_FAST_BILINEAR)) {
if (flags & SWS_PRINT_INFO)
av_log(c, AV_LOG_INFO,
- "output width is not a multiple of 32 -> no MMX2 scaler\n");
+ "output width is not a multiple of 32 -> no MMXEXT scaler\n");
}
if (usesHFilter)
- c->canMMX2BeUsed = 0;
+ c->canMMXEXTBeUsed = 0;
} else
- c->canMMX2BeUsed = 0;
+ c->canMMXEXTBeUsed = 0;
c->chrXInc = (((int64_t)c->chrSrcW << 16) + (c->chrDstW >> 1)) / c->chrDstW;
c->chrYInc = (((int64_t)c->chrSrcH << 16) + (c->chrDstH >> 1)) / c->chrDstH;
* correct variant would be like the vertical one, but that would require
* some special code for the first and last pixel */
if (flags & SWS_FAST_BILINEAR) {
- if (c->canMMX2BeUsed) {
+ if (c->canMMXEXTBeUsed) {
c->lumXInc += 20;
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 (INLINE_MMX(cpu_flags)) {
c->lumXInc = ((int64_t)(srcW - 2) << 16) / (dstW - 2) - 20;
c->chrXInc = ((int64_t)(c->chrSrcW - 2) << 16) / (c->chrDstW - 2) - 20;
}
}
+#define USE_MMAP (HAVE_MMAP && HAVE_MPROTECT && defined MAP_ANONYMOUS)
+
/* precalculate horizontal scaler filter coefficients */
{
#if HAVE_MMXEXT_INLINE
// can't downscale !!!
- if (c->canMMX2BeUsed && (flags & SWS_FAST_BILINEAR)) {
- c->lumMmx2FilterCodeSize = initMMX2HScaler(dstW, c->lumXInc, NULL,
- NULL, NULL, 8);
- c->chrMmx2FilterCodeSize = initMMX2HScaler(c->chrDstW, c->chrXInc,
- NULL, NULL, NULL, 4);
-
-#ifdef MAP_ANONYMOUS
- c->lumMmx2FilterCode = mmap(NULL, c->lumMmx2FilterCodeSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- c->chrMmx2FilterCode = mmap(NULL, c->chrMmx2FilterCodeSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (c->canMMXEXTBeUsed && (flags & SWS_FAST_BILINEAR)) {
+ c->lumMmxextFilterCodeSize = init_hscaler_mmxext(dstW, c->lumXInc, NULL,
+ NULL, NULL, 8);
+ c->chrMmxextFilterCodeSize = init_hscaler_mmxext(c->chrDstW, c->chrXInc,
+ NULL, NULL, NULL, 4);
+
+#if USE_MMAP
+ c->lumMmxextFilterCode = mmap(NULL, c->lumMmxextFilterCodeSize,
+ PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS,
+ -1, 0);
+ c->chrMmxextFilterCode = mmap(NULL, c->chrMmxextFilterCodeSize,
+ PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS,
+ -1, 0);
#elif HAVE_VIRTUALALLOC
- c->lumMmx2FilterCode = VirtualAlloc(NULL, c->lumMmx2FilterCodeSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
- c->chrMmx2FilterCode = VirtualAlloc(NULL, c->chrMmx2FilterCodeSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
+ c->lumMmxextFilterCode = VirtualAlloc(NULL,
+ c->lumMmxextFilterCodeSize,
+ MEM_COMMIT,
+ PAGE_EXECUTE_READWRITE);
+ c->chrMmxextFilterCode = VirtualAlloc(NULL,
+ c->chrMmxextFilterCodeSize,
+ MEM_COMMIT,
+ PAGE_EXECUTE_READWRITE);
#else
- c->lumMmx2FilterCode = av_malloc(c->lumMmx2FilterCodeSize);
- c->chrMmx2FilterCode = av_malloc(c->chrMmx2FilterCodeSize);
+ c->lumMmxextFilterCode = av_malloc(c->lumMmxextFilterCodeSize);
+ c->chrMmxextFilterCode = av_malloc(c->chrMmxextFilterCodeSize);
#endif
- if (!c->lumMmx2FilterCode || !c->chrMmx2FilterCode)
+ if (!c->lumMmxextFilterCode || !c->chrMmxextFilterCode)
return AVERROR(ENOMEM);
FF_ALLOCZ_OR_GOTO(c, c->hLumFilter, (dstW / 8 + 8) * sizeof(int16_t), fail);
FF_ALLOCZ_OR_GOTO(c, c->hChrFilter, (c->chrDstW / 4 + 8) * sizeof(int16_t), fail);
FF_ALLOCZ_OR_GOTO(c, c->hLumFilterPos, (dstW / 2 / 8 + 8) * sizeof(int32_t), fail);
FF_ALLOCZ_OR_GOTO(c, c->hChrFilterPos, (c->chrDstW / 2 / 4 + 8) * sizeof(int32_t), fail);
- initMMX2HScaler(dstW, c->lumXInc, c->lumMmx2FilterCode,
- c->hLumFilter, c->hLumFilterPos, 8);
- initMMX2HScaler(c->chrDstW, c->chrXInc, c->chrMmx2FilterCode,
- c->hChrFilter, c->hChrFilterPos, 4);
+ init_hscaler_mmxext(dstW, c->lumXInc, c->lumMmxextFilterCode,
+ c->hLumFilter, c->hLumFilterPos, 8);
+ init_hscaler_mmxext(c->chrDstW, c->chrXInc, c->chrMmxextFilterCode,
+ c->hChrFilter, c->hChrFilterPos, 4);
-#ifdef MAP_ANONYMOUS
- mprotect(c->lumMmx2FilterCode, c->lumMmx2FilterCodeSize, PROT_EXEC | PROT_READ);
- mprotect(c->chrMmx2FilterCode, c->chrMmx2FilterCodeSize, PROT_EXEC | PROT_READ);
+#if USE_MMAP
+ mprotect(c->lumMmxextFilterCode, c->lumMmxextFilterCodeSize, PROT_EXEC | PROT_READ);
+ mprotect(c->chrMmxextFilterCode, c->chrMmxextFilterCodeSize, PROT_EXEC | PROT_READ);
#endif
} 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, "from %s to %s%s ",
sws_format_name(srcFormat),
#ifdef DITHER1XBPP
- dstFormat == PIX_FMT_BGR555 || dstFormat == PIX_FMT_BGR565 ||
- dstFormat == PIX_FMT_RGB444BE || dstFormat == PIX_FMT_RGB444LE ||
- dstFormat == PIX_FMT_BGR444BE || dstFormat == PIX_FMT_BGR444LE ?
+ dstFormat == AV_PIX_FMT_BGR555 || dstFormat == AV_PIX_FMT_BGR565 ||
+ dstFormat == AV_PIX_FMT_RGB444BE || dstFormat == AV_PIX_FMT_RGB444LE ||
+ dstFormat == AV_PIX_FMT_BGR444BE || dstFormat == AV_PIX_FMT_BGR444LE ?
"dithered " : "",
#else
"",
#endif
sws_format_name(dstFormat));
- if (HAVE_MMXEXT && cpu_flags & AV_CPU_FLAG_MMXEXT)
- av_log(c, AV_LOG_INFO, "using MMX2\n");
- else if (HAVE_AMD3DNOW && cpu_flags & AV_CPU_FLAG_3DNOW)
+ if (INLINE_MMXEXT(cpu_flags))
+ av_log(c, AV_LOG_INFO, "using MMXEXT\n");
+ else if (INLINE_AMD3DNOW(cpu_flags))
av_log(c, AV_LOG_INFO, "using 3DNOW\n");
- else if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX)
+ 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 PixelFormat srcFormat,
- int dstW, int dstH, enum PixelFormat dstFormat,
+SwsContext *sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat,
+ int dstW, int dstH, enum AVPixelFormat dstFormat,
int flags, SwsFilter *srcFilter,
SwsFilter *dstFilter, const double *param)
{
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)
av_freep(&c->hChrFilterPos);
#if HAVE_MMX_INLINE
-#ifdef MAP_ANONYMOUS
- if (c->lumMmx2FilterCode)
- munmap(c->lumMmx2FilterCode, c->lumMmx2FilterCodeSize);
- if (c->chrMmx2FilterCode)
- munmap(c->chrMmx2FilterCode, c->chrMmx2FilterCodeSize);
+#if USE_MMAP
+ if (c->lumMmxextFilterCode)
+ munmap(c->lumMmxextFilterCode, c->lumMmxextFilterCodeSize);
+ if (c->chrMmxextFilterCode)
+ munmap(c->chrMmxextFilterCode, c->chrMmxextFilterCodeSize);
#elif HAVE_VIRTUALALLOC
- if (c->lumMmx2FilterCode)
- VirtualFree(c->lumMmx2FilterCode, 0, MEM_RELEASE);
- if (c->chrMmx2FilterCode)
- VirtualFree(c->chrMmx2FilterCode, 0, MEM_RELEASE);
+ if (c->lumMmxextFilterCode)
+ VirtualFree(c->lumMmxextFilterCode, 0, MEM_RELEASE);
+ if (c->chrMmxextFilterCode)
+ VirtualFree(c->chrMmxextFilterCode, 0, MEM_RELEASE);
#else
- av_free(c->lumMmx2FilterCode);
- av_free(c->chrMmx2FilterCode);
+ av_free(c->lumMmxextFilterCode);
+ av_free(c->chrMmxextFilterCode);
#endif
- c->lumMmx2FilterCode = NULL;
- c->chrMmx2FilterCode = NULL;
+ c->lumMmxextFilterCode = NULL;
+ c->chrMmxextFilterCode = NULL;
#endif /* HAVE_MMX_INLINE */
av_freep(&c->yuvTable);
}
struct SwsContext *sws_getCachedContext(struct SwsContext *context, int srcW,
- int srcH, enum PixelFormat srcFormat,
+ int srcH, enum AVPixelFormat srcFormat,
int dstW, int dstH,
- enum PixelFormat dstFormat, int flags,
+ enum AVPixelFormat dstFormat, int flags,
SwsFilter *srcFilter,
SwsFilter *dstFilter,
const double *param)