Split alloc and init of context so that parameters can be set in the context
authorMichael Niedermayer <michaelni@gmx.at>
Sun, 26 Sep 2010 19:33:57 +0000 (19:33 +0000)
committerMichael Niedermayer <michaelni@gmx.at>
Sun, 26 Sep 2010 19:33:57 +0000 (19:33 +0000)
instead of requireing being passed through function parameters. This also
makes sws work with AVOptions.

Originally committed as revision 32368 to svn://svn.mplayerhq.hu/mplayer/trunk/libswscale

libswscale/swscale.h
libswscale/utils.c

index 4e11c9a..fb5b6de 100644 (file)
@@ -143,6 +143,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,
index dfb4806..d243856 100644 (file)
@@ -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,