#include "libavutil/x86/asm.h"
#include "libavutil/x86/cpu.h"
-// We have to implement deprecated functions until they are removed, this is the
-// simplest way to prevent warnings
-#undef attribute_deprecated
-#define attribute_deprecated
-
#include "rgb2rgb.h"
#include "swscale.h"
#include "swscale_internal.h"
-#if !FF_API_SWS_VECTOR
static SwsVector *sws_getIdentityVec(void);
static void sws_addVec(SwsVector *a, SwsVector *b);
static void sws_shiftVec(SwsVector *a, int shift);
static void sws_printVec2(SwsVector *a, AVClass *log_ctx, int log_level);
-#endif
static void handle_formats(SwsContext *c);
const char *swscale_license(void)
{
#define LICENSE_PREFIX "libswscale license: "
- return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
+ return &LICENSE_PREFIX FFMPEG_LICENSE[sizeof(LICENSE_PREFIX) - 1];
}
typedef struct FormatEntry {
uint8_t is_supported_endianness :1;
} FormatEntry;
-static const FormatEntry format_entries[AV_PIX_FMT_NB] = {
+static const FormatEntry format_entries[] = {
[AV_PIX_FMT_YUV420P] = { 1, 1 },
[AV_PIX_FMT_YUYV422] = { 1, 1 },
[AV_PIX_FMT_RGB24] = { 1, 1 },
[AV_PIX_FMT_GBRP14BE] = { 1, 1 },
[AV_PIX_FMT_GBRP16LE] = { 1, 1 },
[AV_PIX_FMT_GBRP16BE] = { 1, 1 },
+ [AV_PIX_FMT_GBRPF32LE] = { 1, 1 },
+ [AV_PIX_FMT_GBRPF32BE] = { 1, 1 },
+ [AV_PIX_FMT_GBRAPF32LE] = { 1, 1 },
+ [AV_PIX_FMT_GBRAPF32BE] = { 1, 1 },
[AV_PIX_FMT_GBRAP] = { 1, 1 },
[AV_PIX_FMT_GBRAP16LE] = { 1, 1 },
[AV_PIX_FMT_GBRAP16BE] = { 1, 1 },
[AV_PIX_FMT_P016BE] = { 1, 1 },
[AV_PIX_FMT_GRAYF32LE] = { 1, 1 },
[AV_PIX_FMT_GRAYF32BE] = { 1, 1 },
+ [AV_PIX_FMT_YUVA422P12BE] = { 1, 1 },
+ [AV_PIX_FMT_YUVA422P12LE] = { 1, 1 },
+ [AV_PIX_FMT_YUVA444P12BE] = { 1, 1 },
+ [AV_PIX_FMT_YUVA444P12LE] = { 1, 1 },
+ [AV_PIX_FMT_NV24] = { 1, 1 },
+ [AV_PIX_FMT_NV42] = { 1, 1 },
+ [AV_PIX_FMT_Y210LE] = { 1, 0 },
+ [AV_PIX_FMT_X2RGB10LE] = { 1, 1 },
};
int sws_isSupportedInput(enum AVPixelFormat pix_fmt)
{
- return (unsigned)pix_fmt < AV_PIX_FMT_NB ?
+ return (unsigned)pix_fmt < FF_ARRAY_ELEMS(format_entries) ?
format_entries[pix_fmt].is_supported_in : 0;
}
int sws_isSupportedOutput(enum AVPixelFormat pix_fmt)
{
- return (unsigned)pix_fmt < AV_PIX_FMT_NB ?
+ return (unsigned)pix_fmt < FF_ARRAY_ELEMS(format_entries) ?
format_entries[pix_fmt].is_supported_out : 0;
}
int sws_isSupportedEndiannessConversion(enum AVPixelFormat pix_fmt)
{
- return (unsigned)pix_fmt < AV_PIX_FMT_NB ?
+ return (unsigned)pix_fmt < FF_ARRAY_ELEMS(format_entries) ?
format_entries[pix_fmt].is_supported_endianness : 0;
}
emms_c(); // FIXME should not be required but IS (even for non-MMX versions)
// NOTE: the +3 is for the MMX(+1) / SSE(+3) scaler which reads over the end
- FF_ALLOC_ARRAY_OR_GOTO(NULL, *filterPos, (dstW + 3), sizeof(**filterPos), fail);
+ if (!FF_ALLOC_TYPED_ARRAY(*filterPos, dstW + 3))
+ goto nomem;
if (FFABS(xInc - 0x10000) < 10 && srcPos == dstPos) { // unscaled
int i;
filterSize = 1;
- FF_ALLOCZ_ARRAY_OR_GOTO(NULL, filter,
- dstW, sizeof(*filter) * filterSize, fail);
+ if (!FF_ALLOCZ_TYPED_ARRAY(filter, dstW * filterSize))
+ goto nomem;
for (i = 0; i < dstW; i++) {
filter[i * filterSize] = fone;
int i;
int64_t xDstInSrc;
filterSize = 1;
- FF_ALLOC_ARRAY_OR_GOTO(NULL, filter,
- dstW, sizeof(*filter) * filterSize, fail);
+ if (!FF_ALLOC_TYPED_ARRAY(filter, dstW * filterSize))
+ goto nomem;
xDstInSrc = ((dstPos*(int64_t)xInc)>>8) - ((srcPos*0x8000LL)>>7);
for (i = 0; i < dstW; i++) {
int i;
int64_t xDstInSrc;
filterSize = 2;
- FF_ALLOC_ARRAY_OR_GOTO(NULL, filter,
- dstW, sizeof(*filter) * filterSize, fail);
+ if (!FF_ALLOC_TYPED_ARRAY(filter, dstW * filterSize))
+ goto nomem;
xDstInSrc = ((dstPos*(int64_t)xInc)>>8) - ((srcPos*0x8000LL)>>7);
for (i = 0; i < dstW; i++) {
(*filterPos)[i] = xx;
// bilinear upscale / linear interpolate / area averaging
for (j = 0; j < filterSize; j++) {
- int64_t coeff= fone - FFABS(((int64_t)xx<<16) - xDstInSrc)*(fone>>16);
+ int64_t coeff = fone - FFABS((int64_t)xx * (1 << 16) - xDstInSrc) * (fone >> 16);
if (coeff < 0)
coeff = 0;
filter[i * filterSize + j] = coeff;
filterSize = FFMIN(filterSize, srcW - 2);
filterSize = FFMAX(filterSize, 1);
- FF_ALLOC_ARRAY_OR_GOTO(NULL, filter,
- dstW, sizeof(*filter) * filterSize, fail);
-
+ if (!FF_ALLOC_TYPED_ARRAY(filter, dstW * filterSize))
+ goto nomem;
xDstInSrc = ((dstPos*(int64_t)xInc)>>7) - ((srcPos*0x10000LL)>>7);
for (i = 0; i < dstW; i++) {
int xx = (xDstInSrc - (filterSize - 2) * (1LL<<16)) / (1 << 17);
if (dstFilter)
filter2Size += dstFilter->length - 1;
av_assert0(filter2Size > 0);
- FF_ALLOCZ_ARRAY_OR_GOTO(NULL, filter2, dstW, filter2Size * sizeof(*filter2), fail);
-
+ if (!FF_ALLOCZ_TYPED_ARRAY(filter2, dstW * filter2Size))
+ goto nomem;
for (i = 0; i < dstW; i++) {
int j, k;
av_assert0(filterSize > 0);
filter = av_malloc_array(dstW, filterSize * sizeof(*filter));
if (!filter)
- goto fail;
+ goto nomem;
if (filterSize >= MAX_FILTER_SIZE * 16 /
((flags & SWS_ACCURATE_RND) ? APCK_SIZE : 16)) {
ret = RETCODE_USE_CASCADE;
// Note the +1 is for the MMX scaler which reads over the end
/* align at 16 for AltiVec (needed by hScale_altivec_real) */
- FF_ALLOCZ_ARRAY_OR_GOTO(NULL, *outFilter,
- (dstW + 3), *outFilterSize * sizeof(int16_t), fail);
+ if (!FF_ALLOCZ_TYPED_ARRAY(*outFilter, *outFilterSize * (dstW + 3)))
+ goto nomem;
/* normalize & store in outFilter */
for (i = 0; i < dstW; i++) {
}
ret = 0;
-
+ goto done;
+nomem:
+ ret = AVERROR(ENOMEM);
fail:
if(ret < 0)
av_log(NULL, ret == RETCODE_USE_CASCADE ? AV_LOG_DEBUG : AV_LOG_ERROR, "sws: initFilter failed\n");
+done:
av_free(filter);
av_free(filter2);
return ret;
}
}
+static int range_override_needed(enum AVPixelFormat format)
+{
+ return !isYUV(format) && !isGray(format);
+}
+
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)
desc_dst = av_pix_fmt_desc_get(c->dstFormat);
desc_src = av_pix_fmt_desc_get(c->srcFormat);
- if(!isYUV(c->dstFormat) && !isGray(c->dstFormat))
+ if(range_override_needed(c->dstFormat))
dstRange = 0;
- if(!isYUV(c->srcFormat) && !isGray(c->srcFormat))
+ if(range_override_needed(c->srcFormat))
srcRange = 0;
if (c->srcRange != srcRange ||
*inv_table = c->srcColorspaceTable;
*table = c->dstColorspaceTable;
- *srcRange = c->srcRange;
- *dstRange = c->dstRange;
+ *srcRange = range_override_needed(c->srcFormat) ? 1 : c->srcRange;
+ *dstRange = range_override_needed(c->dstFormat) ? 1 : c->dstRange;
*brightness = c->brightness;
*contrast = c->contrast;
*saturation = c->saturation;
srcFormat != AV_PIX_FMT_GBRP14BE && srcFormat != AV_PIX_FMT_GBRP14LE &&
srcFormat != AV_PIX_FMT_GBRP16BE && srcFormat != AV_PIX_FMT_GBRP16LE &&
srcFormat != AV_PIX_FMT_GBRAP16BE && srcFormat != AV_PIX_FMT_GBRAP16LE &&
+ srcFormat != AV_PIX_FMT_GBRPF32BE && srcFormat != AV_PIX_FMT_GBRPF32LE &&
+ srcFormat != AV_PIX_FMT_GBRAPF32BE && srcFormat != AV_PIX_FMT_GBRAPF32LE &&
((dstW >> c->chrDstHSubSample) <= (srcW >> 1) ||
(flags & SWS_FAST_BILINEAR)))
c->chrSrcHSubSample = 1;
c->chrDstW = AV_CEIL_RSHIFT(dstW, c->chrDstHSubSample);
c->chrDstH = AV_CEIL_RSHIFT(dstH, c->chrDstVSubSample);
- FF_ALLOCZ_OR_GOTO(c, c->formatConvBuffer, FFALIGN(srcW*2+78, 16) * 2, fail);
+ if (!FF_ALLOCZ_TYPED_ARRAY(c->formatConvBuffer, FFALIGN(srcW * 2 + 78, 16) * 2))
+ goto nomem;
c->srcBpc = desc_src->comp[0].depth;
if (c->srcBpc < 8)
srcW, srcH, tmpFmt,
flags, NULL, NULL, c->param);
if (!c->cascaded_context[0]) {
- return -1;
+ return AVERROR(ENOMEM);
}
c->cascaded_context[1] = sws_getContext(srcW, srcH, tmpFmt,
flags, srcFilter, dstFilter, c->param);
if (!c->cascaded_context[1])
- return -1;
+ return AVERROR(ENOMEM);
c2 = c->cascaded_context[1];
c2->is_internal_gamma = 1;
// to properly create the gamma convert FilterDescriptor
// we have to re-initialize it
ff_free_filters(c2);
- if (ff_init_filters(c2) < 0) {
+ if ((ret = ff_init_filters(c2)) < 0) {
sws_freeContext(c2);
- return -1;
+ c->cascaded_context[1] = NULL;
+ return ret;
}
c->cascaded_context[2] = NULL;
dstW, dstH, dstFormat,
flags, NULL, NULL, c->param);
if (!c->cascaded_context[2])
- return -1;
+ return AVERROR(ENOMEM);
}
return 0;
}
if (isBayer(srcFormat)) {
if (!unscaled ||
- (dstFormat != AV_PIX_FMT_RGB24 && dstFormat != AV_PIX_FMT_YUV420P)) {
- enum AVPixelFormat tmpFormat = AV_PIX_FMT_RGB24;
+ (dstFormat != AV_PIX_FMT_RGB24 && dstFormat != AV_PIX_FMT_YUV420P &&
+ dstFormat != AV_PIX_FMT_RGB48)) {
+ enum AVPixelFormat tmpFormat = isBayer16BPS(srcFormat) ? AV_PIX_FMT_RGB48 : AV_PIX_FMT_RGB24;
ret = av_image_alloc(c->cascaded_tmp, c->cascaded_tmpStride,
srcW, srcH, tmpFormat, 64);
srcW, srcH, tmpFormat,
flags, srcFilter, NULL, c->param);
if (!c->cascaded_context[0])
- return -1;
+ return AVERROR(ENOMEM);
c->cascaded_context[1] = sws_getContext(srcW, srcH, tmpFormat,
dstW, dstH, dstFormat,
flags, NULL, dstFilter, c->param);
if (!c->cascaded_context[1])
- return -1;
+ return AVERROR(ENOMEM);
return 0;
}
}
if (CONFIG_SWSCALE_ALPHA && isALPHA(srcFormat) && !isALPHA(dstFormat)) {
enum AVPixelFormat tmpFormat = alphaless_fmt(srcFormat);
- if (tmpFormat != AV_PIX_FMT_NONE && c->alphablend != SWS_ALPHA_BLEND_NONE)
- if (!unscaled ||
- dstFormat != tmpFormat ||
- usesHFilter || usesVFilter ||
- c->srcRange != c->dstRange
- ) {
- c->cascaded_mainindex = 1;
- ret = av_image_alloc(c->cascaded_tmp, c->cascaded_tmpStride,
- srcW, srcH, tmpFormat, 64);
- if (ret < 0)
- return ret;
-
- c->cascaded_context[0] = sws_alloc_set_opts(srcW, srcH, srcFormat,
- srcW, srcH, tmpFormat,
- flags, c->param);
- if (!c->cascaded_context[0])
- return -1;
- c->cascaded_context[0]->alphablend = c->alphablend;
- ret = sws_init_context(c->cascaded_context[0], NULL , NULL);
- if (ret < 0)
- return ret;
-
- c->cascaded_context[1] = sws_alloc_set_opts(srcW, srcH, tmpFormat,
- dstW, dstH, dstFormat,
- flags, c->param);
- if (!c->cascaded_context[1])
- return -1;
-
- c->cascaded_context[1]->srcRange = c->srcRange;
- c->cascaded_context[1]->dstRange = c->dstRange;
- ret = sws_init_context(c->cascaded_context[1], srcFilter , dstFilter);
- if (ret < 0)
- return ret;
-
- return 0;
+ if (tmpFormat != AV_PIX_FMT_NONE && c->alphablend != SWS_ALPHA_BLEND_NONE) {
+ if (!unscaled ||
+ dstFormat != tmpFormat ||
+ usesHFilter || usesVFilter ||
+ c->srcRange != c->dstRange
+ ) {
+ c->cascaded_mainindex = 1;
+ ret = av_image_alloc(c->cascaded_tmp, c->cascaded_tmpStride,
+ srcW, srcH, tmpFormat, 64);
+ if (ret < 0)
+ return ret;
+
+ c->cascaded_context[0] = sws_alloc_set_opts(srcW, srcH, srcFormat,
+ srcW, srcH, tmpFormat,
+ flags, c->param);
+ if (!c->cascaded_context[0])
+ return AVERROR(EINVAL);
+ c->cascaded_context[0]->alphablend = c->alphablend;
+ ret = sws_init_context(c->cascaded_context[0], NULL , NULL);
+ if (ret < 0)
+ return ret;
+
+ c->cascaded_context[1] = sws_alloc_set_opts(srcW, srcH, tmpFormat,
+ dstW, dstH, dstFormat,
+ flags, c->param);
+ if (!c->cascaded_context[1])
+ return AVERROR(EINVAL);
+
+ c->cascaded_context[1]->srcRange = c->srcRange;
+ c->cascaded_context[1]->dstRange = c->dstRange;
+ ret = sws_init_context(c->cascaded_context[1], srcFilter , dstFilter);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+ }
}
}
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);
+ if (!FF_ALLOCZ_TYPED_ARRAY(c->hLumFilter, dstW / 8 + 8) ||
+ !FF_ALLOCZ_TYPED_ARRAY(c->hChrFilter, c->chrDstW / 4 + 8) ||
+ !FF_ALLOCZ_TYPED_ARRAY(c->hLumFilterPos, dstW / 2 / 8 + 8) ||
+ !FF_ALLOCZ_TYPED_ARRAY(c->hChrFilterPos, c->chrDstW / 2 / 4 + 8))
+ goto nomem;
ff_init_hscaler_mmxext( dstW, c->lumXInc, c->lumMmxextFilterCode,
c->hLumFilter, (uint32_t*)c->hLumFilterPos, 8);
if ( mprotect(c->lumMmxextFilterCode, c->lumMmxextFilterCodeSize, PROT_EXEC | PROT_READ) == -1
|| mprotect(c->chrMmxextFilterCode, c->chrMmxextFilterCodeSize, PROT_EXEC | PROT_READ) == -1) {
av_log(c, AV_LOG_ERROR, "mprotect failed, cannot use fast bilinear scaler\n");
+ ret = AVERROR(EINVAL);
goto fail;
}
#endif
goto fail;
#if HAVE_ALTIVEC
- FF_ALLOC_OR_GOTO(c, c->vYCoeffsBank, sizeof(vector signed short) * c->vLumFilterSize * c->dstH, fail);
- FF_ALLOC_OR_GOTO(c, c->vCCoeffsBank, sizeof(vector signed short) * c->vChrFilterSize * c->chrDstH, fail);
+ if (!FF_ALLOC_TYPED_ARRAY(c->vYCoeffsBank, c->vLumFilterSize * c->dstH) ||
+ !FF_ALLOC_TYPED_ARRAY(c->vCCoeffsBank, c->vChrFilterSize * c->chrDstH))
+ goto nomem;
for (i = 0; i < c->vLumFilterSize * c->dstH; i++) {
int j;
}
for (i = 0; i < 4; i++)
- FF_ALLOCZ_OR_GOTO(c, c->dither_error[i], (c->dstW+2) * sizeof(int), fail);
+ if (!FF_ALLOCZ_TYPED_ARRAY(c->dither_error[i], c->dstW + 2))
+ goto nomem;
c->needAlpha = (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat) && isALPHA(c->dstFormat)) ? 1 : 0;
c->swscale = ff_getSwsFunc(c);
return ff_init_filters(c);
+nomem:
+ ret = AVERROR(ENOMEM);
fail: // FIXME replace things by appropriate error codes
if (ret == RETCODE_USE_CASCADE) {
int tmpW = sqrt(srcW * (int64_t)dstW);
tmpW, tmpH, tmpFormat,
flags, srcFilter, NULL, c->param);
if (!c->cascaded_context[0])
- return -1;
+ return AVERROR(ENOMEM);
c->cascaded_context[1] = sws_getContext(tmpW, tmpH, tmpFormat,
dstW, dstH, dstFormat,
flags, NULL, dstFilter, c->param);
if (!c->cascaded_context[1])
- return -1;
+ return AVERROR(ENOMEM);
return 0;
}
- return -1;
+ return ret;
}
SwsContext *sws_alloc_set_opts(int srcW, int srcH, enum AVPixelFormat srcFormat,
* Allocate and return a vector with length coefficients, all
* with the same value c.
*/
-#if !FF_API_SWS_VECTOR
static
-#endif
SwsVector *sws_getConstVec(double c, int length)
{
int i;
* Allocate and return a vector with just one coefficient, with
* value 1.0.
*/
-#if !FF_API_SWS_VECTOR
static
-#endif
SwsVector *sws_getIdentityVec(void)
{
return sws_getConstVec(1.0, 1);
sws_scaleVec(a, height / sws_dcVec(a));
}
-#if FF_API_SWS_VECTOR
-static SwsVector *sws_getConvVec(SwsVector *a, SwsVector *b)
-{
- int length = a->length + b->length - 1;
- int i, j;
- SwsVector *vec = sws_getConstVec(0.0, length);
-
- if (!vec)
- return NULL;
-
- for (i = 0; i < a->length; i++) {
- for (j = 0; j < b->length; j++) {
- vec->coeff[i + j] += a->coeff[i] * b->coeff[j];
- }
- }
-
- return vec;
-}
-#endif
-
static SwsVector *sws_sumVec(SwsVector *a, SwsVector *b)
{
int length = FFMAX(a->length, b->length);
return vec;
}
-#if FF_API_SWS_VECTOR
-static SwsVector *sws_diffVec(SwsVector *a, SwsVector *b)
-{
- int length = FFMAX(a->length, b->length);
- int i;
- SwsVector *vec = sws_getConstVec(0.0, length);
-
- if (!vec)
- return NULL;
-
- for (i = 0; i < a->length; i++)
- vec->coeff[i + (length - 1) / 2 - (a->length - 1) / 2] += a->coeff[i];
- for (i = 0; i < b->length; i++)
- vec->coeff[i + (length - 1) / 2 - (b->length - 1) / 2] -= b->coeff[i];
-
- return vec;
-}
-#endif
-
/* shift left / or right if "shift" is negative */
static SwsVector *sws_getShiftedVec(SwsVector *a, int shift)
{
return vec;
}
-#if !FF_API_SWS_VECTOR
static
-#endif
void sws_shiftVec(SwsVector *a, int shift)
{
SwsVector *shifted = sws_getShiftedVec(a, shift);
av_free(shifted);
}
-#if !FF_API_SWS_VECTOR
static
-#endif
void sws_addVec(SwsVector *a, SwsVector *b)
{
SwsVector *sum = sws_sumVec(a, b);
av_free(sum);
}
-#if FF_API_SWS_VECTOR
-void sws_subVec(SwsVector *a, SwsVector *b)
-{
- SwsVector *diff = sws_diffVec(a, b);
- if (!diff) {
- makenan_vec(a);
- return;
- }
- av_free(a->coeff);
- a->coeff = diff->coeff;
- a->length = diff->length;
- av_free(diff);
-}
-
-void sws_convVec(SwsVector *a, SwsVector *b)
-{
- SwsVector *conv = sws_getConvVec(a, b);
- if (!conv) {
- makenan_vec(a);
- return;
- }
- av_free(a->coeff);
- a->coeff = conv->coeff;
- a->length = conv->length;
- av_free(conv);
-}
-
-SwsVector *sws_cloneVec(SwsVector *a)
-{
- SwsVector *vec = sws_allocVec(a->length);
-
- if (!vec)
- return NULL;
-
- memcpy(vec->coeff, a->coeff, a->length * sizeof(*a->coeff));
-
- return vec;
-}
-#endif
-
/**
* Print with av_log() a textual representation of the vector a
* if log_level <= av_log_level.
*/
-#if !FF_API_SWS_VECTOR
static
-#endif
void sws_printVec2(SwsVector *a, AVClass *log_ctx, int log_level)
{
int i;