summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libswscale/swscale.h12
-rw-r--r--libswscale/utils.c114
2 files changed, 82 insertions, 44 deletions
diff --git a/libswscale/swscale.h b/libswscale/swscale.h
index 4e11c9ad82..fb5b6deaa7 100644
--- a/libswscale/swscale.h
+++ b/libswscale/swscale.h
@@ -144,6 +144,17 @@ int sws_isSupportedInput(enum PixelFormat pix_fmt);
int sws_isSupportedOutput(enum PixelFormat pix_fmt);
/**
+ * Alloctaes an empty SwsContext, this must be filled and passed to sws_init_context().
+ * For filling see AVOptions, options.c and sws_setColorspaceDetails().
+ */
+struct SwsContext *sws_alloc_context(void);
+
+/**
+ * Initializs the swscaler context sws_context.
+ */
+int sws_init_context(struct SwsContext *sws_context, SwsFilter *srcFilter, SwsFilter *dstFilter);
+
+/**
* Frees the swscaler context swsContext.
* If swsContext is NULL, then does nothing.
*/
@@ -161,6 +172,7 @@ void sws_freeContext(struct SwsContext *swsContext);
* @param dstFormat the destination image format
* @param flags specify which algorithm and options to use for rescaling
* @return a pointer to an allocated context, or NULL in case of error
+ * @deprecated use sws_alloc_context() and sws_init_context()
*/
struct SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat,
int dstW, int dstH, enum PixelFormat dstFormat,
diff --git a/libswscale/utils.c b/libswscale/utils.c
index dfb4806416..d2438560d3 100644
--- a/libswscale/utils.c
+++ b/libswscale/utils.c
@@ -672,6 +672,8 @@ static void getSubSampleFactors(int *h, int *v, enum PixelFormat format)
*v = av_pix_fmt_descriptors[format].log2_chroma_h;
}
+static int update_flags_cpu(int flags);
+
int sws_setColorspaceDetails(SwsContext *c, const int inv_table[4], int srcRange, const int table[4], int dstRange, int brightness, int contrast, int saturation)
{
memcpy(c->srcColorspaceTable, inv_table, sizeof(int)*4);
@@ -684,6 +686,10 @@ int sws_setColorspaceDetails(SwsContext *c, const int inv_table[4], int srcRange
c->dstRange = dstRange;
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->flags = update_flags_cpu(c->flags);
+
ff_yuv2rgb_c_init_tables(c, inv_table, srcRange, brightness, contrast, saturation);
//FIXME factorize
@@ -729,36 +735,43 @@ static int update_flags_cpu(int flags)
return flags;
}
-SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat,
- int dstW, int dstH, enum PixelFormat dstFormat, int flags,
- SwsFilter *srcFilter, SwsFilter *dstFilter, const double *param)
-{
- SwsContext *c;
+SwsContext *sws_alloc_context(void){
+ SwsContext *c= av_mallocz(sizeof(SwsContext));
+
+ c->av_class = &sws_context_class;
+
+ return c;
+}
+
+int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter){
int i;
int usesVFilter, usesHFilter;
int unscaled;
- int srcRange, dstRange;
SwsFilter dummyFilter= {NULL, NULL, NULL, NULL};
+ int srcW= c->srcW;
+ int srcH= c->srcH;
+ int dstW= c->dstW;
+ int dstH= c->dstH;
+ int flags;
+ enum PixelFormat srcFormat= c->srcFormat;
+ enum PixelFormat dstFormat= c->dstFormat;
+
+ flags= c->flags = update_flags_cpu(c->flags);
#if ARCH_X86
if (flags & SWS_CPU_CAPS_MMX)
__asm__ volatile("emms\n\t"::: "memory");
#endif
-
- flags = update_flags_cpu(flags);
if (!rgb15to16) sws_rgb2rgb_init(flags);
unscaled = (srcW == dstW && srcH == dstH);
- srcRange = handle_jpeg(&srcFormat);
- dstRange = handle_jpeg(&dstFormat);
-
if (!isSupportedIn(srcFormat)) {
av_log(NULL, AV_LOG_ERROR, "swScaler: %s is not supported as input pixel format\n", sws_format_name(srcFormat));
- return NULL;
+ return AVERROR(EINVAL);
}
if (!isSupportedOut(dstFormat)) {
av_log(NULL, AV_LOG_ERROR, "swScaler: %s is not supported as output pixel format\n", sws_format_name(dstFormat));
- return NULL;
+ return AVERROR(EINVAL);
}
i= flags & ( SWS_POINT
@@ -774,35 +787,24 @@ SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat,
|SWS_BICUBLIN);
if(!i || (i & (i-1))) {
av_log(NULL, AV_LOG_ERROR, "swScaler: Exactly one scaler algorithm must be chosen\n");
- return NULL;
+ return AVERROR(EINVAL);
}
-
/* sanity check */
if (srcW<4 || srcH<1 || dstW<8 || dstH<1) { //FIXME check if these are enough and try to lowwer them after fixing the relevant parts of the code
av_log(NULL, AV_LOG_ERROR, "swScaler: %dx%d -> %dx%d is invalid scaling dimension\n",
srcW, srcH, dstW, dstH);
- return NULL;
+ return AVERROR(EINVAL);
}
if(srcW > VOFW || dstW > VOFW) {
av_log(NULL, AV_LOG_ERROR, "swScaler: Compile-time maximum width is "AV_STRINGIFY(VOFW)" change VOF/VOFW and recompile\n");
- return NULL;
+ return AVERROR(EINVAL);
}
if (!dstFilter) dstFilter= &dummyFilter;
if (!srcFilter) srcFilter= &dummyFilter;
- FF_ALLOCZ_OR_GOTO(NULL, c, sizeof(SwsContext), fail);
-
- c->av_class = &sws_context_class;
- c->srcW= srcW;
- c->srcH= srcH;
- c->dstW= dstW;
- c->dstH= dstH;
c->lumXInc= ((srcW<<16) + (dstW>>1))/dstW;
c->lumYInc= ((srcH<<16) + (dstH>>1))/dstH;
- c->flags= flags;
- c->dstFormat= dstFormat;
- c->srcFormat= srcFormat;
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->vRounder= 4* 0x0001000100010001ULL;
@@ -834,31 +836,21 @@ SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat,
&& ((dstW>>c->chrDstHSubSample) <= (srcW>>1) || (flags&SWS_FAST_BILINEAR)))
c->chrSrcHSubSample=1;
- if (param) {
- c->param[0] = param[0];
- c->param[1] = param[1];
- } else {
- c->param[0] =
- c->param[1] = SWS_PARAM_DEFAULT;
- }
-
// Note the -((-x)>>y) is so that we always round toward +inf.
c->chrSrcW= -((-srcW) >> c->chrSrcHSubSample);
c->chrSrcH= -((-srcH) >> c->chrSrcVSubSample);
c->chrDstW= -((-dstW) >> c->chrDstHSubSample);
c->chrDstH= -((-dstH) >> c->chrDstVSubSample);
- sws_setColorspaceDetails(c, ff_yuv2rgb_coeffs[SWS_CS_DEFAULT], srcRange, ff_yuv2rgb_coeffs[SWS_CS_DEFAULT] /* FIXME*/, dstRange, 0, 1<<16, 1<<16);
-
/* unscaled special cases */
- if (unscaled && !usesHFilter && !usesVFilter && (srcRange == dstRange || isAnyRGB(dstFormat))) {
+ if (unscaled && !usesHFilter && !usesVFilter && (c->srcRange == c->dstRange || isAnyRGB(dstFormat))) {
ff_get_unscaled_swscale(c);
if (c->swScale) {
if (flags&SWS_PRINT_INFO)
av_log(c, AV_LOG_INFO, "using unscaled %s -> %s special converter\n",
sws_format_name(srcFormat), sws_format_name(dstFormat));
- return c;
+ return 0;
}
}
@@ -914,7 +906,7 @@ SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat,
#endif
if (!c->lumMmx2FilterCode || !c->chrMmx2FilterCode)
- goto fail;
+ 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);
@@ -1143,11 +1135,45 @@ SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat,
}
c->swScale= ff_getSwsFunc(c);
- return c;
+ return 0;
+fail: //FIXME replace things by appropriate error codes
+ return -1;
+}
-fail:
- sws_freeContext(c);
- return NULL;
+SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat,
+ int dstW, int dstH, enum PixelFormat dstFormat, int flags,
+ SwsFilter *srcFilter, SwsFilter *dstFilter, const double *param)
+{
+ SwsContext *c;
+
+ if(!(c=sws_alloc_context()))
+ return NULL;
+
+ c->flags= flags;
+ c->srcW= srcW;
+ c->srcH= srcH;
+ c->dstW= dstW;
+ c->dstH= dstH;
+ c->srcRange = handle_jpeg(&srcFormat);
+ c->dstRange = handle_jpeg(&dstFormat);
+ c->srcFormat= srcFormat;
+ c->dstFormat= dstFormat;
+
+ if (param) {
+ c->param[0] = param[0];
+ c->param[1] = param[1];
+ } else {
+ c->param[0] =
+ c->param[1] = SWS_PARAM_DEFAULT;
+ }
+ sws_setColorspaceDetails(c, ff_yuv2rgb_coeffs[SWS_CS_DEFAULT], c->srcRange, ff_yuv2rgb_coeffs[SWS_CS_DEFAULT] /* FIXME*/, c->dstRange, 0, 1<<16, 1<<16);
+
+ if(sws_init_context(c, srcFilter, dstFilter) < 0){
+ sws_freeContext(c);
+ return NULL;
+ }
+
+ return c;
}
SwsFilter *sws_getDefaultFilter(float lumaGBlur, float chromaGBlur,