diff --git a/libswscale/aarch64/swscale.c b/libswscale/aarch64/swscale.c
index 4c31b78ed8..1037eccf85 100644
--- a/libswscale/aarch64/swscale.c
+++ b/libswscale/aarch64/swscale.c
@@ -45,11 +45,11 @@ static void ff_hscale16to15_4_neon(SwsInternal *c, int16_t *_dst, int dstW,
                       const uint8_t *_src, const int16_t *filter,
                       const int32_t *filterPos, int filterSize)
 {
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat);
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->opts.src_format);
     int sh              = desc->comp[0].depth - 1;
 
     if (sh<15) {
-        sh = isAnyRGB(c->srcFormat) || c->srcFormat==AV_PIX_FMT_PAL8 ? 13 : (desc->comp[0].depth - 1);
+        sh = isAnyRGB(c->opts.src_format) || c->opts.src_format==AV_PIX_FMT_PAL8 ? 13 : (desc->comp[0].depth - 1);
     } else if (desc->flags & AV_PIX_FMT_FLAG_FLOAT) { /* float input are process like uint 16bpc */
         sh = 16 - 1;
     }
@@ -61,11 +61,11 @@ static void ff_hscale16to15_X8_neon(SwsInternal *c, int16_t *_dst, int dstW,
                       const uint8_t *_src, const int16_t *filter,
                       const int32_t *filterPos, int filterSize)
 {
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat);
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->opts.src_format);
     int sh              = desc->comp[0].depth - 1;
 
     if (sh<15) {
-        sh = isAnyRGB(c->srcFormat) || c->srcFormat==AV_PIX_FMT_PAL8 ? 13 : (desc->comp[0].depth - 1);
+        sh = isAnyRGB(c->opts.src_format) || c->opts.src_format==AV_PIX_FMT_PAL8 ? 13 : (desc->comp[0].depth - 1);
     } else if (desc->flags & AV_PIX_FMT_FLAG_FLOAT) { /* float input are process like uint 16bpc */
         sh = 16 - 1;
     }
@@ -77,11 +77,11 @@ static void ff_hscale16to15_X4_neon(SwsInternal *c, int16_t *_dst, int dstW,
                       const uint8_t *_src, const int16_t *filter,
                       const int32_t *filterPos, int filterSize)
 {
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat);
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->opts.src_format);
     int sh              = desc->comp[0].depth - 1;
 
     if (sh<15) {
-        sh = isAnyRGB(c->srcFormat) || c->srcFormat==AV_PIX_FMT_PAL8 ? 13 : (desc->comp[0].depth - 1);
+        sh = isAnyRGB(c->opts.src_format) || c->opts.src_format==AV_PIX_FMT_PAL8 ? 13 : (desc->comp[0].depth - 1);
     } else if (desc->flags & AV_PIX_FMT_FLAG_FLOAT) { /* float input are process like uint 16bpc */
         sh = 16 - 1;
     }
@@ -92,11 +92,11 @@ static void ff_hscale16to19_4_neon(SwsInternal *c, int16_t *_dst, int dstW,
                            const uint8_t *_src, const int16_t *filter,
                            const int32_t *filterPos, int filterSize)
 {
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat);
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->opts.src_format);
     int bits            = desc->comp[0].depth - 1;
     int sh              = bits - 4;
 
-    if ((isAnyRGB(c->srcFormat) || c->srcFormat==AV_PIX_FMT_PAL8) && desc->comp[0].depth<16) {
+    if ((isAnyRGB(c->opts.src_format) || c->opts.src_format==AV_PIX_FMT_PAL8) && desc->comp[0].depth<16) {
         sh = 9;
     } else if (desc->flags & AV_PIX_FMT_FLAG_FLOAT) { /* float input are process like uint 16bpc */
         sh = 16 - 1 - 4;
@@ -110,11 +110,11 @@ static void ff_hscale16to19_X8_neon(SwsInternal *c, int16_t *_dst, int dstW,
                            const uint8_t *_src, const int16_t *filter,
                            const int32_t *filterPos, int filterSize)
 {
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat);
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->opts.src_format);
     int bits            = desc->comp[0].depth - 1;
     int sh              = bits - 4;
 
-    if ((isAnyRGB(c->srcFormat) || c->srcFormat==AV_PIX_FMT_PAL8) && desc->comp[0].depth<16) {
+    if ((isAnyRGB(c->opts.src_format) || c->opts.src_format==AV_PIX_FMT_PAL8) && desc->comp[0].depth<16) {
         sh = 9;
     } else if (desc->flags & AV_PIX_FMT_FLAG_FLOAT) { /* float input are process like uint 16bpc */
         sh = 16 - 1 - 4;
@@ -128,11 +128,11 @@ static void ff_hscale16to19_X4_neon(SwsInternal *c, int16_t *_dst, int dstW,
                            const uint8_t *_src, const int16_t *filter,
                            const int32_t *filterPos, int filterSize)
 {
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat);
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->opts.src_format);
     int bits            = desc->comp[0].depth - 1;
     int sh              = bits - 4;
 
-    if ((isAnyRGB(c->srcFormat) || c->srcFormat==AV_PIX_FMT_PAL8) && desc->comp[0].depth<16) {
+    if ((isAnyRGB(c->opts.src_format) || c->opts.src_format==AV_PIX_FMT_PAL8) && desc->comp[0].depth<16) {
         sh = 9;
     } else if (desc->flags & AV_PIX_FMT_FLAG_FLOAT) { /* float input are process like uint 16bpc */
         sh = 16 - 1 - 4;
@@ -225,9 +225,9 @@ void ff_chrRangeToJpeg_neon(int16_t *dstU, int16_t *dstV, int width);
 
 av_cold void ff_sws_init_range_convert_aarch64(SwsInternal *c)
 {
-    if (c->srcRange != c->dstRange && !isAnyRGB(c->dstFormat)) {
+    if (c->opts.src_range != c->opts.dst_range && !isAnyRGB(c->opts.dst_format)) {
         if (c->dstBpc <= 14) {
-            if (c->srcRange) {
+            if (c->opts.src_range) {
                 c->lumConvertRange = ff_lumRangeFromJpeg_neon;
                 c->chrConvertRange = ff_chrRangeFromJpeg_neon;
             } else {
@@ -249,7 +249,7 @@ av_cold void ff_sws_init_swscale_aarch64(SwsInternal *c)
         if (c->dstBpc == 8) {
             c->yuv2planeX = ff_yuv2planeX_8_neon;
         }
-        switch (c->srcFormat) {
+        switch (c->opts.src_format) {
         case AV_PIX_FMT_ABGR:
             c->lumToYV12 = ff_abgr32ToY_neon;
             if (c->chrSrcHSubSample)
diff --git a/libswscale/aarch64/swscale_unscaled.c b/libswscale/aarch64/swscale_unscaled.c
index 4f54120445..fdecafd94b 100644
--- a/libswscale/aarch64/swscale_unscaled.c
+++ b/libswscale/aarch64/swscale_unscaled.c
@@ -43,7 +43,7 @@ static int ifmt##_to_##ofmt##_neon_wrapper(SwsInternal *c, const uint8_t *const
                                            const int dstStride[]) {                         \
     const int16_t yuv2rgb_table[] = { YUV_TO_RGB_TABLE };                                   \
                                                                                             \
-    return ff_##ifmt##_to_##ofmt##_neon(c->srcW, srcSliceH,                                 \
+    return ff_##ifmt##_to_##ofmt##_neon(c->opts.src_w, srcSliceH,                           \
                                         dst[0] + srcSliceY * dstStride[0], dstStride[0],    \
                                         src[0], srcStride[0],                               \
                                         src[1], srcStride[1],                               \
@@ -71,7 +71,7 @@ static int ifmt##_to_##ofmt##_neon_wrapper(SwsInternal *c, const uint8_t *const
                                            const int dstStride[]) {                         \
     const int16_t yuv2rgb_table[] = { YUV_TO_RGB_TABLE };                                   \
                                                                                             \
-    return ff_##ifmt##_to_##ofmt##_neon(c->srcW, srcSliceH,                                 \
+    return ff_##ifmt##_to_##ofmt##_neon(c->opts.src_w, srcSliceH,                           \
                                         dst[0] + srcSliceY * dstStride[0], dstStride[0],    \
                                         src[0], srcStride[0],                               \
                                         src[1], srcStride[1],                               \
@@ -108,7 +108,7 @@ static int ifmt##_to_##ofmt##_neon_wrapper(SwsInternal *c, const uint8_t *const
                                            const int dstStride[]) {                         \
     const int16_t yuv2rgb_table[] = { YUV_TO_RGB_TABLE };                                   \
                                                                                             \
-    return ff_##ifmt##_to_##ofmt##_neon(c->srcW, srcSliceH,                                 \
+    return ff_##ifmt##_to_##ofmt##_neon(c->opts.src_w, srcSliceH,                           \
                                         dst[0] + srcSliceY * dstStride[0], dstStride[0],    \
                                         src[0], srcStride[0], src[1], srcStride[1],         \
                                         yuv2rgb_table,                                      \
@@ -133,7 +133,7 @@ static int ifmt##_to_##ofmt##_neon_wrapper(SwsInternal *c, const uint8_t *const
                                            const int dstStride[]) {                         \
     const int16_t yuv2rgb_table[] = { YUV_TO_RGB_TABLE };                                   \
                                                                                             \
-    return ff_##ifmt##_to_##ofmt##_neon(c->srcW, srcSliceH,                                 \
+    return ff_##ifmt##_to_##ofmt##_neon(c->opts.src_w, srcSliceH,                           \
                                         dst[0] + srcSliceY * dstStride[0], dstStride[0],    \
                                         src[0], srcStride[0], src[1], srcStride[1],         \
                                         yuv2rgb_table,                                      \
@@ -155,15 +155,17 @@ static int nv24_to_yuv420p_neon_wrapper(SwsInternal *c, const uint8_t *const src
     uint8_t *dst1 = dst[1] + dstStride[1] * srcSliceY / 2;
     uint8_t *dst2 = dst[2] + dstStride[2] * srcSliceY / 2;
 
-    ff_copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
+    ff_copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->opts.src_w,
                  dst[0], dstStride[0]);
 
-    if (c->srcFormat == AV_PIX_FMT_NV24)
+    if (c->opts.src_format == AV_PIX_FMT_NV24)
         ff_nv24_to_yuv420p_chroma_neon(dst1, dstStride[1], dst2, dstStride[2],
-                                       src[1], srcStride[1], c->srcW / 2, srcSliceH);
+                                       src[1], srcStride[1], c->opts.src_w / 2,
+                                       srcSliceH);
     else
         ff_nv24_to_yuv420p_chroma_neon(dst2, dstStride[2], dst1, dstStride[1],
-                                       src[1], srcStride[1], c->srcW / 2, srcSliceH);
+                                       src[1], srcStride[1], c->opts.src_w / 2,
+                                       srcSliceH);
 
     return srcSliceH;
 }
@@ -183,10 +185,10 @@ DECLARE_FF_NVX_TO_ALL_RGBX_FUNCS(nv21)
  * assembly might be writing as much as 4*15=60 extra bytes at the end of the
  * line, which won't fit the 32-bytes buffer alignment. */
 #define SET_FF_NVX_TO_RGBX_FUNC(ifmt, IFMT, ofmt, OFMT, accurate_rnd) do {                  \
-    if (c->srcFormat == AV_PIX_FMT_##IFMT                                                   \
-        && c->dstFormat == AV_PIX_FMT_##OFMT                                                \
-        && !(c->srcH & 1)                                                                   \
-        && !(c->srcW & 15)                                                                  \
+    if (c->opts.src_format == AV_PIX_FMT_##IFMT                                             \
+        && c->opts.dst_format == AV_PIX_FMT_##OFMT                                          \
+        && !(c->opts.src_h & 1)                                                             \
+        && !(c->opts.src_w & 15)                                                            \
         && !accurate_rnd)                                                                   \
         c->convert_unscaled = ifmt##_to_##ofmt##_neon_wrapper;                              \
 } while (0)
@@ -200,16 +202,16 @@ DECLARE_FF_NVX_TO_ALL_RGBX_FUNCS(nv21)
 } while (0)
 
 static void get_unscaled_swscale_neon(SwsInternal *c) {
-    int accurate_rnd = c->flags & SWS_ACCURATE_RND;
+    int accurate_rnd = c->opts.flags & SWS_ACCURATE_RND;
 
     SET_FF_NVX_TO_ALL_RGBX_FUNC(nv12, NV12, accurate_rnd);
     SET_FF_NVX_TO_ALL_RGBX_FUNC(nv21, NV21, accurate_rnd);
     SET_FF_NVX_TO_ALL_RGBX_FUNC(yuv420p, YUV420P, accurate_rnd);
     SET_FF_NVX_TO_ALL_RGBX_FUNC(yuv422p, YUV422P, accurate_rnd);
 
-    if (c->dstFormat == AV_PIX_FMT_YUV420P &&
-        (c->srcFormat == AV_PIX_FMT_NV24 || c->srcFormat == AV_PIX_FMT_NV42) &&
-        !(c->srcH & 1) && !(c->srcW & 15) && !accurate_rnd)
+    if (c->opts.dst_format == AV_PIX_FMT_YUV420P &&
+        (c->opts.src_format == AV_PIX_FMT_NV24 || c->opts.src_format == AV_PIX_FMT_NV42) &&
+        !(c->opts.src_h & 1) && !(c->opts.src_w & 15) && !accurate_rnd)
         c->convert_unscaled = nv24_to_yuv420p_neon_wrapper;
 }
 
diff --git a/libswscale/alphablend.c b/libswscale/alphablend.c
index 4ee23d3aee..f9484bcc91 100644
--- a/libswscale/alphablend.c
+++ b/libswscale/alphablend.c
@@ -24,10 +24,10 @@ int ff_sws_alphablendaway(SwsInternal *c, const uint8_t *const src[],
                           const int srcStride[], int srcSliceY, int srcSliceH,
                           uint8_t *const dst[], const int dstStride[])
 {
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat);
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->opts.src_format);
     int nb_components = desc->nb_components;
     int plane, x, ysrc;
-    int plane_count = isGray(c->srcFormat) ? 1 : 3;
+    int plane_count = isGray(c->opts.src_format) ? 1 : 3;
     int sixteen_bits = desc->comp[0].depth >= 9;
     unsigned off    = 1<<(desc->comp[0].depth - 1);
     unsigned shift  = desc->comp[0].depth;
@@ -36,7 +36,7 @@ int ff_sws_alphablendaway(SwsInternal *c, const uint8_t *const src[],
 
     for (plane = 0; plane < plane_count; plane++) {
         int a = 0, b = 0;
-        if (c->alphablend == SWS_ALPHA_BLEND_CHECKERBOARD) {
+        if (c->opts.alpha_blend == SWS_ALPHA_BLEND_CHECKERBOARD) {
             a = (1<<(desc->comp[0].depth - 1))/2;
             b = 3*(1<<(desc->comp[0].depth-1))/2;
         }
@@ -47,7 +47,7 @@ int ff_sws_alphablendaway(SwsInternal *c, const uint8_t *const src[],
     av_assert0(plane_count == nb_components - 1);
     if (desc->flags & AV_PIX_FMT_FLAG_PLANAR) {
         for (plane = 0; plane < plane_count; plane++) {
-            int w = plane ? c->chrSrcW : c->srcW;
+            int w = plane ? c->chrSrcW : c->opts.src_w;
             int x_subsample = plane ? desc->log2_chroma_w: 0;
             int y_subsample = plane ? desc->log2_chroma_h: 0;
             for (ysrc = 0; ysrc < AV_CEIL_RSHIFT(srcSliceH, y_subsample); ysrc++) {
@@ -60,7 +60,7 @@ int ff_sws_alphablendaway(SwsInternal *c, const uint8_t *const src[],
                         const uint16_t *s = (const uint16_t *)(src[plane      ] +  srcStride[plane      ] * ysrc);
                         const uint16_t *a = (const uint16_t *)(src[plane_count] + (srcStride[plane_count] * ysrc << y_subsample));
                               uint16_t *d = (      uint16_t *)(dst[plane      ] +  dstStride[plane      ] * y);
-                        if ((!isBE(c->srcFormat)) == !HAVE_BIGENDIAN) {
+                        if ((!isBE(c->opts.src_format)) == !HAVE_BIGENDIAN) {
                             for (x = 0; x < w; x++) {
                                 if (y_subsample) {
                                     alpha = (a[2*x]              + a[2*x + 1] + 2 +
@@ -101,7 +101,7 @@ int ff_sws_alphablendaway(SwsInternal *c, const uint8_t *const src[],
                     const uint16_t *s = (const uint16_t *)(src[plane      ] + srcStride[plane      ] * ysrc);
                     const uint16_t *a = (const uint16_t *)(src[plane_count] + srcStride[plane_count] * ysrc);
                           uint16_t *d = (      uint16_t *)(dst[plane      ] + dstStride[plane      ] * y);
-                    if ((!isBE(c->srcFormat)) == !HAVE_BIGENDIAN) {
+                    if ((!isBE(c->opts.src_format)) == !HAVE_BIGENDIAN) {
                         for (x = 0; x < w; x++) {
                             unsigned u = s[x]*a[x] + target_table[((x^y)>>5)&1][plane]*(max-a[x]) + off;
                             d[x] = av_clip((u + (u >> shift)) >> shift, 0, max);
@@ -127,14 +127,14 @@ int ff_sws_alphablendaway(SwsInternal *c, const uint8_t *const src[],
         }
     } else {
         int alpha_pos = desc->comp[plane_count].offset;
-        int w = c->srcW;
+        int w = c->opts.src_w;
         for (ysrc = 0; ysrc < srcSliceH; ysrc++) {
             int y = ysrc + srcSliceY;
             if (sixteen_bits) {
                 const uint16_t *s = (const uint16_t *)(src[0] + srcStride[0] * ysrc + 2*!alpha_pos);
                 const uint16_t *a = (const uint16_t *)(src[0] + srcStride[0] * ysrc +    alpha_pos);
                       uint16_t *d = (      uint16_t *)(dst[0] + dstStride[0] * y);
-                if ((!isBE(c->srcFormat)) == !HAVE_BIGENDIAN) {
+                if ((!isBE(c->opts.src_format)) == !HAVE_BIGENDIAN) {
                     for (x = 0; x < w; x++) {
                         for (plane = 0; plane < plane_count; plane++) {
                             int x_index = (plane_count + 1) * x;
diff --git a/libswscale/arm/swscale_unscaled.c b/libswscale/arm/swscale_unscaled.c
index 14685dbc50..5c3074a0cd 100644
--- a/libswscale/arm/swscale_unscaled.c
+++ b/libswscale/arm/swscale_unscaled.c
@@ -41,7 +41,7 @@ static int rgbx_to_nv12_neon_32_wrapper(SwsInternal *context, const uint8_t *con
     rgbx_to_nv12_neon_32(src[0] + srcSliceY * srcStride[0],
             dst[0] + srcSliceY * dstStride[0],
             dst[1] + (srcSliceY / 2) * dstStride[1],
-            context->srcW, srcSliceH,
+            context->opts.src_w, srcSliceH,
             dstStride[0], dstStride[1], srcStride[0],
             context->input_rgb2yuv_table);
 
@@ -55,7 +55,7 @@ static int rgbx_to_nv12_neon_16_wrapper(SwsInternal *context, const uint8_t *con
     rgbx_to_nv12_neon_16(src[0] + srcSliceY * srcStride[0],
             dst[0] + srcSliceY * dstStride[0],
             dst[1] + (srcSliceY / 2) * dstStride[1],
-            context->srcW, srcSliceH,
+            context->opts.src_w, srcSliceH,
             dstStride[0], dstStride[1], srcStride[0],
             context->input_rgb2yuv_table);
 
@@ -84,7 +84,7 @@ static int ifmt##_to_##ofmt##_neon_wrapper(SwsInternal *c, const uint8_t *const
                                            const int dstStride[]) {                         \
     const int16_t yuv2rgb_table[] = { YUV_TO_RGB_TABLE };                                   \
                                                                                             \
-    ff_##ifmt##_to_##ofmt##_neon(c->srcW, srcSliceH,                                        \
+    ff_##ifmt##_to_##ofmt##_neon(c->opts.src_w, srcSliceH,                                  \
                                  dst[0] + srcSliceY * dstStride[0], dstStride[0],           \
                                  src[0], srcStride[0],                                      \
                                  src[1], srcStride[1],                                      \
@@ -120,7 +120,7 @@ static int ifmt##_to_##ofmt##_neon_wrapper(SwsInternal *c, const uint8_t *const
                                            const int dstStride[]) {                         \
     const int16_t yuv2rgb_table[] = { YUV_TO_RGB_TABLE };                                   \
                                                                                             \
-    ff_##ifmt##_to_##ofmt##_neon(c->srcW, srcSliceH,                                        \
+    ff_##ifmt##_to_##ofmt##_neon(c->opts.src_w, srcSliceH,                                  \
                                  dst[0] + srcSliceY * dstStride[0], dstStride[0],           \
                                  src[0], srcStride[0], src[1], srcStride[1],                \
                                  yuv2rgb_table,                                             \
@@ -144,10 +144,10 @@ DECLARE_FF_NVX_TO_ALL_RGBX_FUNCS(nv21)
  * assembly might be writing as much as 4*15=60 extra bytes at the end of the
  * line, which won't fit the 32-bytes buffer alignment. */
 #define SET_FF_NVX_TO_RGBX_FUNC(ifmt, IFMT, ofmt, OFMT, accurate_rnd) do {                  \
-    if (c->srcFormat == AV_PIX_FMT_##IFMT                                                   \
-        && c->dstFormat == AV_PIX_FMT_##OFMT                                                \
-        && !(c->srcH & 1)                                                                   \
-        && !(c->srcW & 15)                                                                  \
+    if (c->opts.src_format == AV_PIX_FMT_##IFMT                                             \
+        && c->opts.dst_format == AV_PIX_FMT_##OFMT                                          \
+        && !(c->opts.src_h & 1)                                                             \
+        && !(c->opts.src_w & 15)                                                            \
         && !accurate_rnd) {                                                                 \
         c->convert_unscaled = ifmt##_to_##ofmt##_neon_wrapper;                              \
     }                                                                                       \
@@ -161,10 +161,10 @@ DECLARE_FF_NVX_TO_ALL_RGBX_FUNCS(nv21)
 } while (0)
 
 static void get_unscaled_swscale_neon(SwsInternal *c) {
-    int accurate_rnd = c->flags & SWS_ACCURATE_RND;
-    if (c->srcFormat == AV_PIX_FMT_RGBA
-            && c->dstFormat == AV_PIX_FMT_NV12
-            && (c->srcW >= 16)) {
+    int accurate_rnd = c->opts.flags & SWS_ACCURATE_RND;
+    if (c->opts.src_format == AV_PIX_FMT_RGBA
+            && c->opts.dst_format == AV_PIX_FMT_NV12
+            && (c->opts.src_w >= 16)) {
         c->convert_unscaled = accurate_rnd ? rgbx_to_nv12_neon_32_wrapper
                                            : rgbx_to_nv12_neon_16_wrapper;
     }
diff --git a/libswscale/input.c b/libswscale/input.c
index 15bd9fbe2d..5d90d9b303 100644
--- a/libswscale/input.c
+++ b/libswscale/input.c
@@ -1547,7 +1547,7 @@ av_cold void ff_sws_init_input_funcs(SwsInternal *c,
                                      planarX_YV12_fn *readAlpPlanar,
                                      planarX2_YV12_fn *readChrPlanar)
 {
-    enum AVPixelFormat srcFormat = c->srcFormat;
+    enum AVPixelFormat srcFormat = c->opts.src_format;
 
     *chrToYV12 = NULL;
     switch (srcFormat) {
diff --git a/libswscale/loongarch/input_lasx.c b/libswscale/loongarch/input_lasx.c
index b682179c6e..046f395ae5 100644
--- a/libswscale/loongarch/input_lasx.c
+++ b/libswscale/loongarch/input_lasx.c
@@ -203,7 +203,7 @@ void planar_rgb_to_y_lasx(uint8_t *_dst, const uint8_t *src[4], int width,
 
 av_cold void ff_sws_init_input_lasx(SwsInternal *c)
 {
-    enum AVPixelFormat srcFormat = c->srcFormat;
+    enum AVPixelFormat srcFormat = c->opts.src_format;
 
     switch (srcFormat) {
     case AV_PIX_FMT_YUYV422:
diff --git a/libswscale/loongarch/input_lsx.c b/libswscale/loongarch/input_lsx.c
index 2bc7577961..c0e5627690 100644
--- a/libswscale/loongarch/input_lsx.c
+++ b/libswscale/loongarch/input_lsx.c
@@ -23,7 +23,7 @@
 
 av_cold void ff_sws_init_input_lsx(SwsInternal *c)
 {
-    enum AVPixelFormat srcFormat = c->srcFormat;
+    enum AVPixelFormat srcFormat = c->opts.src_format;
 
     switch (srcFormat) {
     case AV_PIX_FMT_YUYV422:
diff --git a/libswscale/loongarch/output_lasx.c b/libswscale/loongarch/output_lasx.c
index 4e5ad3d802..21d0a501b0 100644
--- a/libswscale/loongarch/output_lasx.c
+++ b/libswscale/loongarch/output_lasx.c
@@ -888,7 +888,7 @@ static av_always_inline void yuv2rgb_write_full(SwsInternal *c,
     {
         int r,g,b;
 
-        switch (c->dither) {
+        switch (c->opts.dither) {
         default:
         case SWS_DITHER_AUTO:
         case SWS_DITHER_ED:
@@ -1784,7 +1784,7 @@ av_cold void ff_sws_init_output_lasx(SwsInternal *c,
                                      yuv2packedX_fn *yuv2packedX,
                                      yuv2anyX_fn *yuv2anyX)
 {
-    enum AVPixelFormat dstFormat = c->dstFormat;
+    enum AVPixelFormat dstFormat = c->opts.dst_format;
 
     /* Add initialization once optimized */
     if (isSemiPlanarYUV(dstFormat) && isDataInHighBits(dstFormat)) {
@@ -1797,8 +1797,8 @@ av_cold void ff_sws_init_output_lasx(SwsInternal *c,
         *yuv2planeX = yuv2planeX_8_lasx;
     }
 
-    if(c->flags & SWS_FULL_CHR_H_INT) {
-        switch (c->dstFormat) {
+    if(c->opts.flags & SWS_FULL_CHR_H_INT) {
+        switch (c->opts.dst_format) {
         case AV_PIX_FMT_RGBA:
 #if CONFIG_SMALL
             c->yuv2packedX = yuv2rgba32_full_X_lasx;
@@ -1911,7 +1911,7 @@ av_cold void ff_sws_init_output_lasx(SwsInternal *c,
             break;
     }
     } else {
-        switch (c->dstFormat) {
+        switch (c->opts.dst_format) {
         case AV_PIX_FMT_RGB32:
         case AV_PIX_FMT_BGR32:
 #if CONFIG_SMALL
diff --git a/libswscale/loongarch/output_lsx.c b/libswscale/loongarch/output_lsx.c
index 29fe30758a..24e6de5535 100644
--- a/libswscale/loongarch/output_lsx.c
+++ b/libswscale/loongarch/output_lsx.c
@@ -838,7 +838,7 @@ static av_always_inline void yuv2rgb_write_full(SwsInternal *c,
     {
         int r,g,b;
 
-        switch (c->dither) {
+        switch (c->opts.dither) {
         default:
         case SWS_DITHER_AUTO:
         case SWS_DITHER_ED:
@@ -1633,7 +1633,7 @@ av_cold void ff_sws_init_output_lsx(SwsInternal *c,
                                     yuv2packedX_fn *yuv2packedX,
                                     yuv2anyX_fn *yuv2anyX)
 {
-    enum AVPixelFormat dstFormat = c->dstFormat;
+    enum AVPixelFormat dstFormat = c->opts.dst_format;
 
     /* Add initialization once optimized */
     if (isSemiPlanarYUV(dstFormat) && isDataInHighBits(dstFormat)) {
@@ -1646,8 +1646,8 @@ av_cold void ff_sws_init_output_lsx(SwsInternal *c,
         *yuv2planeX = yuv2planeX_8_lsx;
     }
 
-    if(c->flags & SWS_FULL_CHR_H_INT) {
-        switch (c->dstFormat) {
+    if(c->opts.flags & SWS_FULL_CHR_H_INT) {
+        switch (c->opts.dst_format) {
         case AV_PIX_FMT_RGBA:
 #if CONFIG_SMALL
             c->yuv2packedX = yuv2rgba32_full_X_lsx;
@@ -1760,7 +1760,7 @@ av_cold void ff_sws_init_output_lsx(SwsInternal *c,
             break;
     }
     } else {
-        switch (c->dstFormat) {
+        switch (c->opts.dst_format) {
         case AV_PIX_FMT_RGB32:
         case AV_PIX_FMT_BGR32:
 #if CONFIG_SMALL
diff --git a/libswscale/loongarch/swscale_init_loongarch.c b/libswscale/loongarch/swscale_init_loongarch.c
index 7cc92be216..374b0a6f32 100644
--- a/libswscale/loongarch/swscale_init_loongarch.c
+++ b/libswscale/loongarch/swscale_init_loongarch.c
@@ -29,9 +29,9 @@ av_cold void ff_sws_init_range_convert_loongarch(SwsInternal *c)
     int cpu_flags = av_get_cpu_flags();
 
     if (have_lsx(cpu_flags)) {
-        if (c->srcRange != c->dstRange && !isAnyRGB(c->dstFormat)) {
+        if (c->opts.src_range != c->opts.dst_range && !isAnyRGB(c->opts.dst_format)) {
             if (c->dstBpc <= 14) {
-                if (c->srcRange) {
+                if (c->opts.src_range) {
                     c->lumConvertRange = lumRangeFromJpeg_lsx;
                     c->chrConvertRange = chrRangeFromJpeg_lsx;
                 } else {
@@ -43,9 +43,9 @@ av_cold void ff_sws_init_range_convert_loongarch(SwsInternal *c)
     }
 #if HAVE_LASX
     if (have_lasx(cpu_flags)) {
-        if (c->srcRange != c->dstRange && !isAnyRGB(c->dstFormat)) {
+        if (c->opts.src_range != c->opts.dst_range && !isAnyRGB(c->opts.dst_format)) {
             if (c->dstBpc <= 14) {
-                if (c->srcRange) {
+                if (c->opts.src_range) {
                     c->lumConvertRange = lumRangeFromJpeg_lasx;
                     c->chrConvertRange = chrRangeFromJpeg_lasx;
                 } else {
@@ -112,29 +112,29 @@ av_cold SwsFunc ff_yuv2rgb_init_loongarch(SwsInternal *c)
     int cpu_flags = av_get_cpu_flags();
 #if HAVE_LASX
     if (have_lasx(cpu_flags)) {
-        if (c->srcFormat == AV_PIX_FMT_YUV420P) {
-            switch (c->dstFormat) {
+        if (c->opts.src_format == AV_PIX_FMT_YUV420P) {
+            switch (c->opts.dst_format) {
                 case AV_PIX_FMT_RGB24:
                     return yuv420_rgb24_lasx;
                 case AV_PIX_FMT_BGR24:
                     return yuv420_bgr24_lasx;
                 case AV_PIX_FMT_RGBA:
-                    if (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat)) {
+                    if (CONFIG_SWSCALE_ALPHA && isALPHA(c->opts.src_format)) {
                         break;
                     } else
                         return yuv420_rgba32_lasx;
                 case AV_PIX_FMT_ARGB:
-                    if (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat)) {
+                    if (CONFIG_SWSCALE_ALPHA && isALPHA(c->opts.src_format)) {
                         break;
                     } else
                         return yuv420_argb32_lasx;
                 case AV_PIX_FMT_BGRA:
-                    if (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat)) {
+                    if (CONFIG_SWSCALE_ALPHA && isALPHA(c->opts.src_format)) {
                         break;
                     } else
                         return yuv420_bgra32_lasx;
                 case AV_PIX_FMT_ABGR:
-                    if (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat)) {
+                    if (CONFIG_SWSCALE_ALPHA && isALPHA(c->opts.src_format)) {
                         break;
                     } else
                         return yuv420_abgr32_lasx;
@@ -143,29 +143,29 @@ av_cold SwsFunc ff_yuv2rgb_init_loongarch(SwsInternal *c)
     }
 #endif // #if HAVE_LASX
     if (have_lsx(cpu_flags)) {
-        if (c->srcFormat == AV_PIX_FMT_YUV420P) {
-            switch (c->dstFormat) {
+        if (c->opts.src_format == AV_PIX_FMT_YUV420P) {
+            switch (c->opts.dst_format) {
                 case AV_PIX_FMT_RGB24:
                     return yuv420_rgb24_lsx;
                 case AV_PIX_FMT_BGR24:
                     return yuv420_bgr24_lsx;
                 case AV_PIX_FMT_RGBA:
-                    if (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat)) {
+                    if (CONFIG_SWSCALE_ALPHA && isALPHA(c->opts.src_format)) {
                         break;
                     } else
                         return yuv420_rgba32_lsx;
                 case AV_PIX_FMT_ARGB:
-                    if (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat)) {
+                    if (CONFIG_SWSCALE_ALPHA && isALPHA(c->opts.src_format)) {
                         break;
                     } else
                         return yuv420_argb32_lsx;
                 case AV_PIX_FMT_BGRA:
-                    if (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat)) {
+                    if (CONFIG_SWSCALE_ALPHA && isALPHA(c->opts.src_format)) {
                         break;
                     } else
                         return yuv420_bgra32_lsx;
                 case AV_PIX_FMT_ABGR:
-                    if (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat)) {
+                    if (CONFIG_SWSCALE_ALPHA && isALPHA(c->opts.src_format)) {
                         break;
                     } else
                         return yuv420_abgr32_lsx;
diff --git a/libswscale/loongarch/swscale_lasx.c b/libswscale/loongarch/swscale_lasx.c
index 79fa4c64b0..fcaca3123b 100644
--- a/libswscale/loongarch/swscale_lasx.c
+++ b/libswscale/loongarch/swscale_lasx.c
@@ -677,7 +677,7 @@ void ff_hscale_16_to_15_lasx(SwsInternal *c, int16_t *dst, int dstW,
                              const uint8_t *_src, const int16_t *filter,
                              const int32_t *filterPos, int filterSize)
 {
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat);
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->opts.src_format);
     int i;
     const uint16_t *src = (const uint16_t *) _src;
     int sh              = desc->comp[0].depth - 1;
@@ -688,7 +688,7 @@ void ff_hscale_16_to_15_lasx(SwsInternal *c, int16_t *dst, int dstW,
     __m256i zero = __lasx_xvldi(0);
 
     if (sh < 15) {
-        sh = isAnyRGB(c->srcFormat) || c->srcFormat==AV_PIX_FMT_PAL8 ? 13 :
+        sh = isAnyRGB(c->opts.src_format) || c->opts.src_format==AV_PIX_FMT_PAL8 ? 13 :
                       (desc->comp[0].depth - 1);
     } else if (desc->flags && AV_PIX_FMT_FLAG_FLOAT) {
         sh = 15;
@@ -824,7 +824,7 @@ void ff_hscale_16_to_19_lasx(SwsInternal *c, int16_t *_dst, int dstW,
                              const uint8_t *_src, const int16_t *filter,
                              const int32_t *filterPos, int filterSize)
 {
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat);
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->opts.src_format);
     int i;
     int32_t *dst        = (int32_t *) _dst;
     const uint16_t *src = (const uint16_t *) _src;
@@ -835,7 +835,7 @@ void ff_hscale_16_to_19_lasx(SwsInternal *c, int16_t *_dst, int dstW,
     __m256i shift;
     __m256i zero = __lasx_xvldi(0);
 
-    if ((isAnyRGB(c->srcFormat) || c->srcFormat == AV_PIX_FMT_PAL8)
+    if ((isAnyRGB(c->opts.src_format) || c->opts.src_format == AV_PIX_FMT_PAL8)
          && desc->comp[0].depth<16) {
         sh = 9;
     } else if (desc->flags & AV_PIX_FMT_FLAG_FLOAT) {
diff --git a/libswscale/loongarch/swscale_lsx.c b/libswscale/loongarch/swscale_lsx.c
index dbdaf18de6..fce09800fe 100644
--- a/libswscale/loongarch/swscale_lsx.c
+++ b/libswscale/loongarch/swscale_lsx.c
@@ -27,11 +27,11 @@ void ff_hscale_16_to_15_lsx(SwsInternal *c, int16_t *_dst, int dstW,
                             const uint8_t *_src, const int16_t *filter,
                             const int32_t *filterPos, int filterSize)
 {
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat);
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->opts.src_format);
     int sh              = desc->comp[0].depth - 1;
 
     if (sh < 15) {
-        sh = isAnyRGB(c->srcFormat) || c->srcFormat==AV_PIX_FMT_PAL8 ? 13 :
+        sh = isAnyRGB(c->opts.src_format) || c->opts.src_format==AV_PIX_FMT_PAL8 ? 13 :
                       (desc->comp[0].depth - 1);
     } else if (desc->flags && AV_PIX_FMT_FLAG_FLOAT) {
         sh = 15;
@@ -43,11 +43,11 @@ void ff_hscale_16_to_19_lsx(SwsInternal *c, int16_t *_dst, int dstW,
                             const uint8_t *_src, const int16_t *filter,
                             const int32_t *filterPos, int filterSize)
 {
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat);
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->opts.src_format);
     int bits            = desc->comp[0].depth - 1;
     int sh              = bits - 4;
 
-    if ((isAnyRGB(c->srcFormat) || c->srcFormat==AV_PIX_FMT_PAL8) && desc->comp[0].depth<16) {
+    if ((isAnyRGB(c->opts.src_format) || c->opts.src_format==AV_PIX_FMT_PAL8) && desc->comp[0].depth<16) {
 
         sh = 9;
     } else if (desc->flags & AV_PIX_FMT_FLAG_FLOAT) { /* float input are process like uint 16bpc */
diff --git a/libswscale/loongarch/yuv2rgb_lasx.c b/libswscale/loongarch/yuv2rgb_lasx.c
index 1b36d617b5..e9e4a63a0a 100644
--- a/libswscale/loongarch/yuv2rgb_lasx.c
+++ b/libswscale/loongarch/yuv2rgb_lasx.c
@@ -173,11 +173,11 @@
     __m256i shuf3 = {0x1E0F0E1C0D0C1A0B, 0x0101010101010101,                        \
                      0x1E0F0E1C0D0C1A0B, 0x0101010101010101};                       \
     YUV2RGB_LOAD_COE                                                                \
-    y      = (c->dstW + 7) & ~7;                                                    \
+    y      = (c->opts.dst_w + 7) & ~7;                                              \
     h_size = y >> 4;                                                                \
     res    = y & 15;                                                                \
                                                                                     \
-    vshift = c->srcFormat != AV_PIX_FMT_YUV422P;                                    \
+    vshift = c->opts.src_format != AV_PIX_FMT_YUV422P;                              \
     for (y = 0; y < srcSliceH; y += 2) {                                            \
         dst_type *image1    = (dst_type *)(dst[0] + (y + srcSliceY) * dstStride[0]);\
         dst_type *image2    = (dst_type *)(image1 +                   dstStride[0]);\
@@ -199,11 +199,11 @@
     __m256i a = __lasx_xvldi(0xFF);                                                 \
                                                                                     \
     YUV2RGB_LOAD_COE                                                                \
-    y      = (c->dstW + 7) & ~7;                                                    \
+    y      = (c->opts.dst_w + 7) & ~7;                                              \
     h_size = y >> 4;                                                                \
     res    = y & 15;                                                                \
                                                                                     \
-    vshift = c->srcFormat != AV_PIX_FMT_YUV422P;                                    \
+    vshift = c->opts.src_format != AV_PIX_FMT_YUV422P;                              \
     for (y = 0; y < srcSliceH; y += 2) {                                            \
         int yd = y + srcSliceY;                                                     \
         dst_type av_unused *r, *g, *b;                                              \
diff --git a/libswscale/loongarch/yuv2rgb_lsx.c b/libswscale/loongarch/yuv2rgb_lsx.c
index f2f424265f..6339d07d6c 100644
--- a/libswscale/loongarch/yuv2rgb_lsx.c
+++ b/libswscale/loongarch/yuv2rgb_lsx.c
@@ -128,9 +128,9 @@
                                                                                     \
     YUV2RGB_LOAD_COE                                                                \
                                                                                     \
-    h_size = c->dstW >> 4;                                                          \
-    res = (c->dstW & 15) >> 1;                                                      \
-    vshift = c->srcFormat != AV_PIX_FMT_YUV422P;                                    \
+    h_size = c->opts.dst_w >> 4;                                                    \
+    res = (c->opts.dst_w & 15) >> 1;                                                \
+    vshift = c->opts.src_format != AV_PIX_FMT_YUV422P;                              \
     for (y = 0; y < srcSliceH; y += 2) {                                            \
         dst_type av_unused *r, *g, *b;                                              \
         dst_type *image1    = (dst_type *)(dst[0] + (y + srcSliceY) * dstStride[0]);\
@@ -156,9 +156,9 @@
                                                                                     \
     YUV2RGB_LOAD_COE                                                                \
                                                                                     \
-    h_size = c->dstW >> 4;                                                          \
-    res = (c->dstW & 15) >> 1;                                                      \
-    vshift = c->srcFormat != AV_PIX_FMT_YUV422P;                                    \
+    h_size = c->opts.dst_w >> 4;                                                    \
+    res = (c->opts.dst_w & 15) >> 1;                                                \
+    vshift = c->opts.src_format != AV_PIX_FMT_YUV422P;                              \
     for (y = 0; y < srcSliceH; y += 2) {                                            \
         int yd = y + srcSliceY;                                                     \
         dst_type av_unused *r, *g, *b;                                              \
diff --git a/libswscale/options.c b/libswscale/options.c
index e64e289cf3..6248e5f4b5 100644
--- a/libswscale/options.c
+++ b/libswscale/options.c
@@ -27,7 +27,7 @@ static const char *sws_context_to_name(void *ptr)
     return "swscaler";
 }
 
-#define OFFSET(x) offsetof(SwsInternal, x)
+#define OFFSET(x) offsetof(SwsInternal, opts.x)
 #define DEFAULT 0
 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
 
@@ -51,18 +51,18 @@ static const AVOption swscale_options[] = {
         { "bitexact",        "bit-exact mode",                0,  AV_OPT_TYPE_CONST, { .i64 = SWS_BITEXACT       }, .flags = VE, .unit = "sws_flags" },
         { "error_diffusion", "error diffusion dither",        0,  AV_OPT_TYPE_CONST, { .i64 = SWS_ERROR_DIFFUSION}, .flags = VE, .unit = "sws_flags" },
 
-    { "param0",              "scaler param 0", OFFSET(param[0]),  AV_OPT_TYPE_DOUBLE, { .dbl = SWS_PARAM_DEFAULT  }, INT_MIN, INT_MAX, VE },
-    { "param1",              "scaler param 1", OFFSET(param[1]),  AV_OPT_TYPE_DOUBLE, { .dbl = SWS_PARAM_DEFAULT  }, INT_MIN, INT_MAX, VE },
+    { "param0",          "scaler param 0", OFFSET(scaler_params[0]), AV_OPT_TYPE_DOUBLE, { .dbl = SWS_PARAM_DEFAULT  }, INT_MIN, INT_MAX, VE },
+    { "param1",          "scaler param 1", OFFSET(scaler_params[1]), AV_OPT_TYPE_DOUBLE, { .dbl = SWS_PARAM_DEFAULT  }, INT_MIN, INT_MAX, VE },
 
-    { "srcw",            "source width",                  OFFSET(srcW),      AV_OPT_TYPE_INT,    { .i64 = 16                 }, 1,       INT_MAX, VE },
-    { "srch",            "source height",                 OFFSET(srcH),      AV_OPT_TYPE_INT,    { .i64 = 16                 }, 1,       INT_MAX, VE },
-    { "dstw",            "destination width",             OFFSET(dstW),      AV_OPT_TYPE_INT,    { .i64 = 16                 }, 1,       INT_MAX, VE },
-    { "dsth",            "destination height",            OFFSET(dstH),      AV_OPT_TYPE_INT,    { .i64 = 16                 }, 1,       INT_MAX, VE },
-    { "src_format",      "source format",                 OFFSET(srcFormat), AV_OPT_TYPE_PIXEL_FMT,{ .i64 = DEFAULT          }, 0,       INT_MAX, VE },
-    { "dst_format",      "destination format",            OFFSET(dstFormat), AV_OPT_TYPE_PIXEL_FMT,{ .i64 = DEFAULT          }, 0,       INT_MAX, VE },
-    { "src_range",       "source is full range",          OFFSET(srcRange),  AV_OPT_TYPE_BOOL,   { .i64 = DEFAULT            }, 0,       1,       VE },
-    { "dst_range",       "destination is full range",     OFFSET(dstRange),  AV_OPT_TYPE_BOOL,   { .i64 = DEFAULT            }, 0,       1,       VE },
-    { "gamma",           "gamma correct scaling",         OFFSET(gamma_flag),AV_OPT_TYPE_BOOL,   { .i64  = 0                 }, 0,       1,       VE },
+    { "srcw",            "source width",                  OFFSET(src_w),      AV_OPT_TYPE_INT,       { .i64 = 16      }, 1, INT_MAX, VE },
+    { "srch",            "source height",                 OFFSET(src_h),      AV_OPT_TYPE_INT,       { .i64 = 16      }, 1, INT_MAX, VE },
+    { "dstw",            "destination width",             OFFSET(dst_w),      AV_OPT_TYPE_INT,       { .i64 = 16      }, 1, INT_MAX, VE },
+    { "dsth",            "destination height",            OFFSET(dst_h),      AV_OPT_TYPE_INT,       { .i64 = 16      }, 1, INT_MAX, VE },
+    { "src_format",      "source format",                 OFFSET(src_format), AV_OPT_TYPE_PIXEL_FMT, { .i64 = DEFAULT }, 0, INT_MAX, VE },
+    { "dst_format",      "destination format",            OFFSET(dst_format), AV_OPT_TYPE_PIXEL_FMT, { .i64 = DEFAULT }, 0, INT_MAX, VE },
+    { "src_range",       "source is full range",          OFFSET(src_range),  AV_OPT_TYPE_BOOL,      { .i64 = DEFAULT }, 0, 1,       VE },
+    { "dst_range",       "destination is full range",     OFFSET(dst_range),  AV_OPT_TYPE_BOOL,      { .i64 = DEFAULT }, 0, 1,       VE },
+    { "gamma",           "gamma correct scaling",         OFFSET(gamma_flag), AV_OPT_TYPE_BOOL,      { .i64  = 0      }, 0, 1,       VE },
 
     { "src_v_chr_pos",   "source vertical chroma position in luma grid/256"  ,      OFFSET(src_v_chr_pos), AV_OPT_TYPE_INT, { .i64 = -513 }, -513, 1024, VE },
     { "src_h_chr_pos",   "source horizontal chroma position in luma grid/256",      OFFSET(src_h_chr_pos), AV_OPT_TYPE_INT, { .i64 = -513 }, -513, 1024, VE },
@@ -76,13 +76,13 @@ static const AVOption swscale_options[] = {
         { "a_dither",    "arithmetic addition dither",    0,                 AV_OPT_TYPE_CONST,  { .i64  = SWS_DITHER_A_DITHER }, .flags = VE, .unit = "sws_dither" },
         { "x_dither",    "arithmetic xor dither",         0,                 AV_OPT_TYPE_CONST,  { .i64  = SWS_DITHER_X_DITHER }, .flags = VE, .unit = "sws_dither" },
 
-    { "alphablend",          "mode for alpha -> non alpha",   OFFSET(alphablend),  AV_OPT_TYPE_INT,    { .i64  = SWS_ALPHA_BLEND_NONE},         .flags = VE, .unit = "alphablend", .max = SWS_ALPHA_BLEND_NB - 1 },
+    { "alphablend",          "mode for alpha -> non alpha",   OFFSET(alpha_blend), AV_OPT_TYPE_INT,    { .i64  = SWS_ALPHA_BLEND_NONE},         .flags = VE, .unit = "alphablend", .max = SWS_ALPHA_BLEND_NB - 1 },
         { "none",            "ignore alpha",                  0,                   AV_OPT_TYPE_CONST,  { .i64  = SWS_ALPHA_BLEND_NONE},         .flags = VE, .unit = "alphablend" },
         { "uniform_color",   "blend onto a uniform color",    0,                   AV_OPT_TYPE_CONST,  { .i64  = SWS_ALPHA_BLEND_UNIFORM},      .flags = VE, .unit = "alphablend" },
         { "checkerboard",    "blend onto a checkerboard",     0,                   AV_OPT_TYPE_CONST,  { .i64  = SWS_ALPHA_BLEND_CHECKERBOARD}, .flags = VE, .unit = "alphablend" },
 
-    { "threads",         "number of threads",             OFFSET(nb_threads),   AV_OPT_TYPE_INT, {.i64 = 1 }, 0, INT_MAX, VE, .unit = "threads" },
-        { "auto",        "automatic selection",           0,                  AV_OPT_TYPE_CONST, {.i64 = 0 },    .flags = VE, .unit = "threads" },
+    { "threads",         "number of threads",             OFFSET(threads),   AV_OPT_TYPE_INT,   {.i64 = 1 }, .flags = VE, .unit = "threads", .max = INT_MAX },
+        { "auto",        "automatic selection",           0,                 AV_OPT_TYPE_CONST, {.i64 = 0 }, .flags = VE, .unit = "threads" },
 
     { NULL }
 };
@@ -91,7 +91,7 @@ const AVClass ff_sws_context_class = {
     .class_name = "SWScaler",
     .item_name  = sws_context_to_name,
     .option     = swscale_options,
-    .parent_log_context_offset = OFFSET(parent),
+    .parent_log_context_offset = offsetof(SwsInternal, parent),
     .category   = AV_CLASS_CATEGORY_SWSCALER,
     .version    = LIBAVUTIL_VERSION_INT,
 };
diff --git a/libswscale/output.c b/libswscale/output.c
index b22db2e48d..a5184a9c22 100644
--- a/libswscale/output.c
+++ b/libswscale/output.c
@@ -624,7 +624,7 @@ yuv2mono_X_c_template(SwsInternal *c, const int16_t *lumFilter,
             Y1 = av_clip_uint8(Y1);
             Y2 = av_clip_uint8(Y2);
         }
-        if (c->dither == SWS_DITHER_ED) {
+        if (c->opts.dither == SWS_DITHER_ED) {
             Y1 += (7*err + 1*c->dither_error[0][i] + 5*c->dither_error[0][i+1] + 3*c->dither_error[0][i+2] + 8 - 256)>>4;
             c->dither_error[0][i] = err;
             acc = 2*acc + (Y1 >= 128);
@@ -662,7 +662,7 @@ yuv2mono_2_c_template(SwsInternal *c, const int16_t *buf[2],
     int i;
     av_assert2(yalpha  <= 4096U);
 
-    if (c->dither == SWS_DITHER_ED) {
+    if (c->opts.dither == SWS_DITHER_ED) {
         int err = 0;
         int acc = 0;
         for (i = 0; i < dstW; i +=2) {
@@ -719,7 +719,7 @@ yuv2mono_1_c_template(SwsInternal *c, const int16_t *buf0,
     const uint8_t * const d128 = ff_dither_8x8_220[y & 7];
     int i;
 
-    if (c->dither == SWS_DITHER_ED) {
+    if (c->opts.dither == SWS_DITHER_ED) {
         int err = 0;
         int acc = 0;
         for (i = 0; i < dstW; i +=2) {
@@ -1976,7 +1976,7 @@ static av_always_inline void yuv2rgb_write_full(SwsInternal *c,
     {
         int r,g,b;
 
-        switch (c->dither) {
+        switch (c->opts.dither) {
         case SWS_DITHER_NONE:
             if (isrgb8) {
                 r = av_clip_uintp2(R >> 27, 3);
@@ -2249,7 +2249,7 @@ yuv2gbrp_full_X_c(SwsInternal *c, const int16_t *lumFilter,
                   const int16_t **alpSrc, uint8_t **dest,
                   int dstW, int y)
 {
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->dstFormat);
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->opts.dst_format);
     int i;
     int hasAlpha = (desc->flags & AV_PIX_FMT_FLAG_ALPHA) && alpSrc;
     uint16_t **dest16 = (uint16_t**)dest;
@@ -2312,7 +2312,7 @@ yuv2gbrp_full_X_c(SwsInternal *c, const int16_t *lumFilter,
                 dest[3][i] = A >> 19;
         }
     }
-    if (SH != 22 && (!isBE(c->dstFormat)) != (!HAVE_BIGENDIAN)) {
+    if (SH != 22 && (!isBE(c->opts.dst_format)) != (!HAVE_BIGENDIAN)) {
         for (i = 0; i < dstW; i++) {
             dest16[0][i] = av_bswap16(dest16[0][i]);
             dest16[1][i] = av_bswap16(dest16[1][i]);
@@ -2331,7 +2331,7 @@ yuv2gbrp16_full_X_c(SwsInternal *c, const int16_t *lumFilter,
                     const int16_t **alpSrcx, uint8_t **dest,
                     int dstW, int y)
 {
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->dstFormat);
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->opts.dst_format);
     int i;
     int hasAlpha = (desc->flags & AV_PIX_FMT_FLAG_ALPHA) && alpSrcx;
     uint16_t **dest16 = (uint16_t**)dest;
@@ -2384,7 +2384,7 @@ yuv2gbrp16_full_X_c(SwsInternal *c, const int16_t *lumFilter,
         if (hasAlpha)
             dest16[3][i] = av_clip_uintp2(A, 30) >> 14;
     }
-    if ((!isBE(c->dstFormat)) != (!HAVE_BIGENDIAN)) {
+    if ((!isBE(c->opts.dst_format)) != (!HAVE_BIGENDIAN)) {
         for (i = 0; i < dstW; i++) {
             dest16[0][i] = av_bswap16(dest16[0][i]);
             dest16[1][i] = av_bswap16(dest16[1][i]);
@@ -2403,7 +2403,7 @@ yuv2gbrpf32_full_X_c(SwsInternal *c, const int16_t *lumFilter,
                     const int16_t **alpSrcx, uint8_t **dest,
                     int dstW, int y)
 {
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->dstFormat);
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->opts.dst_format);
     int i;
     int hasAlpha = (desc->flags & AV_PIX_FMT_FLAG_ALPHA) && alpSrcx;
     uint32_t **dest32 = (uint32_t**)dest;
@@ -2460,7 +2460,7 @@ yuv2gbrpf32_full_X_c(SwsInternal *c, const int16_t *lumFilter,
         if (hasAlpha)
             dest32[3][i] = av_float2int(float_mult * (float)(av_clip_uintp2(A, 30) >> 14));
     }
-    if ((!isBE(c->dstFormat)) != (!HAVE_BIGENDIAN)) {
+    if ((!isBE(c->opts.dst_format)) != (!HAVE_BIGENDIAN)) {
         for (i = 0; i < dstW; i++) {
             dest32[0][i] = av_bswap32(dest32[0][i]);
             dest32[1][i] = av_bswap32(dest32[1][i]);
@@ -3154,7 +3154,7 @@ av_cold void ff_sws_init_output_funcs(SwsInternal *c,
                                       yuv2packedX_fn *yuv2packedX,
                                       yuv2anyX_fn *yuv2anyX)
 {
-    enum AVPixelFormat dstFormat = c->dstFormat;
+    enum AVPixelFormat dstFormat = c->opts.dst_format;
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(dstFormat);
 
     if (isSemiPlanarYUV(dstFormat) && isDataInHighBits(dstFormat)) {
@@ -3202,7 +3202,7 @@ av_cold void ff_sws_init_output_funcs(SwsInternal *c,
             *yuv2nv12cX = yuv2nv12cX_c;
     }
 
-    if(c->flags & SWS_FULL_CHR_H_INT) {
+    if(c->opts.flags & SWS_FULL_CHR_H_INT) {
         switch (dstFormat) {
             case AV_PIX_FMT_RGBA:
 #if CONFIG_SMALL
diff --git a/libswscale/ppc/swscale_altivec.c b/libswscale/ppc/swscale_altivec.c
index 836aaab1f8..c76c0b6d78 100644
--- a/libswscale/ppc/swscale_altivec.c
+++ b/libswscale/ppc/swscale_altivec.c
@@ -232,7 +232,7 @@ yuv2plane1_float(yuv2plane1_float_bswap_altivec, uint32_t, BE)
 av_cold void ff_sws_init_swscale_ppc(SwsInternal *c)
 {
 #if HAVE_ALTIVEC
-    enum AVPixelFormat dstFormat = c->dstFormat;
+    enum AVPixelFormat dstFormat = c->opts.dst_format;
 
     if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))
         return;
@@ -256,8 +256,8 @@ av_cold void ff_sws_init_swscale_ppc(SwsInternal *c)
 
     /* The following list of supported dstFormat values should
      * match what's found in the body of ff_yuv2packedX_altivec() */
-    if (!(c->flags & (SWS_BITEXACT | SWS_FULL_CHR_H_INT)) && !c->needAlpha) {
-        switch (c->dstFormat) {
+    if (!(c->opts.flags & (SWS_BITEXACT | SWS_FULL_CHR_H_INT)) && !c->needAlpha) {
+        switch (c->opts.dst_format) {
         case AV_PIX_FMT_ABGR:
             c->yuv2packedX = ff_yuv2abgr_X_altivec;
             break;
diff --git a/libswscale/ppc/swscale_vsx.c b/libswscale/ppc/swscale_vsx.c
index f83bb96ec9..5ea3407644 100644
--- a/libswscale/ppc/swscale_vsx.c
+++ b/libswscale/ppc/swscale_vsx.c
@@ -1862,7 +1862,7 @@ static void hScale16To19_vsx(SwsInternal *c, int16_t *_dst, int dstW,
                              const uint8_t *_src, const int16_t *filter,
                              const int32_t *filterPos, int filterSize)
 {
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat);
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->opts.src_format);
     int i, j;
     int32_t *dst        = (int32_t *) _dst;
     const uint16_t *src = (const uint16_t *) _src;
@@ -1891,7 +1891,7 @@ static void hScale16To19_vsx(SwsInternal *c, int16_t *_dst, int dstW,
     };
     const vec_u8 vunused = vunusedtab[filterSize % 8];
 
-    if ((isAnyRGB(c->srcFormat) || c->srcFormat==AV_PIX_FMT_PAL8) && desc->comp[0].depth<16) {
+    if ((isAnyRGB(c->opts.src_format) || c->opts.src_format==AV_PIX_FMT_PAL8) && desc->comp[0].depth<16) {
         sh = 9;
     } else if (desc->flags & AV_PIX_FMT_FLAG_FLOAT) { /* float input are process like uint 16bpc */
         sh = 16 - 1 - 4;
@@ -1940,7 +1940,7 @@ static void hScale16To15_vsx(SwsInternal *c, int16_t *dst, int dstW,
                              const uint8_t *_src, const int16_t *filter,
                              const int32_t *filterPos, int filterSize)
 {
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat);
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->opts.src_format);
     int i, j;
     const uint16_t *src = (const uint16_t *) _src;
     int sh              = desc->comp[0].depth - 1;
@@ -1968,7 +1968,7 @@ static void hScale16To15_vsx(SwsInternal *c, int16_t *dst, int dstW,
     const vec_u8 vunused = vunusedtab[filterSize % 8];
 
     if (sh<15) {
-        sh = isAnyRGB(c->srcFormat) || c->srcFormat==AV_PIX_FMT_PAL8 ? 13 : (desc->comp[0].depth - 1);
+        sh = isAnyRGB(c->opts.src_format) || c->opts.src_format==AV_PIX_FMT_PAL8 ? 13 : (desc->comp[0].depth - 1);
     } else if (desc->flags & AV_PIX_FMT_FLAG_FLOAT) { /* float input are process like uint 16bpc */
         sh = 16 - 1;
     }
@@ -2019,7 +2019,7 @@ static void hScale16To15_vsx(SwsInternal *c, int16_t *dst, int dstW,
 av_cold void ff_sws_init_swscale_vsx(SwsInternal *c)
 {
 #if HAVE_VSX
-    enum AVPixelFormat dstFormat = c->dstFormat;
+    enum AVPixelFormat dstFormat = c->opts.dst_format;
     const int cpu_flags = av_get_cpu_flags();
     const unsigned char power8 = HAVE_POWER8 && cpu_flags & AV_CPU_FLAG_POWER8;
 
@@ -2030,7 +2030,7 @@ av_cold void ff_sws_init_swscale_vsx(SwsInternal *c)
     if (c->srcBpc == 8) {
         if (c->dstBpc <= 14) {
             c->hyScale = c->hcScale = hScale_real_vsx;
-            if (c->flags & SWS_FAST_BILINEAR && c->dstW >= c->srcW && c->chrDstW >= c->chrSrcW) {
+            if (c->opts.flags & SWS_FAST_BILINEAR && c->opts.dst_w >= c->opts.src_w && c->chrDstW >= c->chrSrcW) {
                 c->hyscale_fast = hyscale_fast_vsx;
                 c->hcscale_fast = hcscale_fast_vsx;
             }
@@ -2048,7 +2048,7 @@ av_cold void ff_sws_init_swscale_vsx(SwsInternal *c)
     }
 #endif
 
-    if (!(c->flags & (SWS_BITEXACT | SWS_FULL_CHR_H_INT)) && !c->needAlpha) {
+    if (!(c->opts.flags & (SWS_BITEXACT | SWS_FULL_CHR_H_INT)) && !c->needAlpha) {
         switch (c->dstBpc) {
         case 8:
             c->yuv2plane1 = yuv2plane1_8_vsx;
@@ -2082,11 +2082,11 @@ av_cold void ff_sws_init_swscale_vsx(SwsInternal *c)
         }
     }
 
-    if (c->flags & SWS_BITEXACT)
+    if (c->opts.flags & SWS_BITEXACT)
         return;
 
 #if !HAVE_BIGENDIAN
-    if (c->flags & SWS_FULL_CHR_H_INT) {
+    if (c->opts.flags & SWS_FULL_CHR_H_INT) {
         switch (dstFormat) {
             case AV_PIX_FMT_RGB24:
                 if (power8) {
diff --git a/libswscale/ppc/yuv2rgb_altivec.c b/libswscale/ppc/yuv2rgb_altivec.c
index 9db305f43f..57574c4ab3 100644
--- a/libswscale/ppc/yuv2rgb_altivec.c
+++ b/libswscale/ppc/yuv2rgb_altivec.c
@@ -299,7 +299,7 @@ static int altivec_ ## name(SwsInternal *c, const unsigned char *const *in,   \
                             const int *instrides, int srcSliceY, int srcSliceH,   \
                             unsigned char *const *oplanes, const int *outstrides) \
 {                                                                             \
-    int w = c->srcW;                                                          \
+    int w = c->opts.src_w;                                                    \
     int h = srcSliceH;                                                        \
     int i, j;                                                                 \
     int instrides_scl[3];                                                     \
@@ -475,7 +475,7 @@ static int altivec_uyvy_rgb32(SwsInternal *c, const unsigned char *const *in,
                               const int *instrides, int srcSliceY, int srcSliceH,
                               unsigned char *const *oplanes, const int *outstrides)
 {
-    int w = c->srcW;
+    int w = c->opts.src_w;
     int h = srcSliceH;
     int i, j;
     vector unsigned char uyvy;
@@ -545,20 +545,20 @@ av_cold SwsFunc ff_yuv2rgb_init_ppc(SwsInternal *c)
      * boom with X11 bad match.
      *
      */
-    if ((c->srcW & 0xf) != 0)
+    if ((c->opts.src_w & 0xf) != 0)
         return NULL;
 
-    switch (c->srcFormat) {
+    switch (c->opts.src_format) {
     case AV_PIX_FMT_YUV410P:
     case AV_PIX_FMT_YUV420P:
     /*case IMGFMT_CLPL:        ??? */
     case AV_PIX_FMT_GRAY8:
     case AV_PIX_FMT_NV12:
     case AV_PIX_FMT_NV21:
-        if ((c->srcH & 0x1) != 0)
+        if ((c->opts.src_h & 0x1) != 0)
             return NULL;
 
-        switch (c->dstFormat) {
+        switch (c->opts.dst_format) {
         case AV_PIX_FMT_RGB24:
             av_log(c, AV_LOG_WARNING, "ALTIVEC: Color Space RGB24\n");
             return altivec_yuv2_rgb24;
@@ -582,7 +582,7 @@ av_cold SwsFunc ff_yuv2rgb_init_ppc(SwsInternal *c)
         break;
 
     case AV_PIX_FMT_UYVY422:
-        switch (c->dstFormat) {
+        switch (c->opts.dst_format) {
         case AV_PIX_FMT_BGR32:
             av_log(c, AV_LOG_WARNING, "ALTIVEC: Color Space UYVY -> RGB32\n");
             return altivec_uyvy_rgb32;
@@ -742,7 +742,7 @@ static av_always_inline void yuv2packedX_altivec(SwsInternal *c,
             if (!printed_error_message) {
                 av_log(c, AV_LOG_ERROR,
                        "altivec_yuv2packedX doesn't support %s output\n",
-                       av_get_pix_fmt_name(c->dstFormat));
+                       av_get_pix_fmt_name(c->opts.dst_format));
                 printed_error_message = 1;
             }
             return;
@@ -830,7 +830,7 @@ static av_always_inline void yuv2packedX_altivec(SwsInternal *c,
             /* Unreachable, I think. */
             av_log(c, AV_LOG_ERROR,
                    "altivec_yuv2packedX doesn't support %s output\n",
-                   av_get_pix_fmt_name(c->dstFormat));
+                   av_get_pix_fmt_name(c->opts.dst_format));
             return;
         }
 
diff --git a/libswscale/ppc/yuv2yuv_altivec.c b/libswscale/ppc/yuv2yuv_altivec.c
index 0ae5223760..7884c38d69 100644
--- a/libswscale/ppc/yuv2yuv_altivec.c
+++ b/libswscale/ppc/yuv2yuv_altivec.c
@@ -37,12 +37,12 @@ static int yv12toyuy2_unscaled_altivec(SwsInternal *c, const uint8_t *const src[
                                        const int dstStride_a[])
 {
     uint8_t *dst = dstParam[0] + dstStride_a[0] * srcSliceY;
-    // yv12toyuy2(src[0], src[1], src[2], dst, c->srcW, srcSliceH,
+    // yv12toyuy2(src[0], src[1], src[2], dst, c->opts.src_w, srcSliceH,
     //            srcStride[0], srcStride[1], dstStride[0]);
     const uint8_t *ysrc   = src[0];
     const uint8_t *usrc   = src[1];
     const uint8_t *vsrc   = src[2];
-    const int width       = c->srcW;
+    const int width       = c->opts.src_w;
     const int height      = srcSliceH;
     const int lumStride   = srcStride[0];
     const int chromStride = srcStride[1];
@@ -113,12 +113,12 @@ static int yv12touyvy_unscaled_altivec(SwsInternal *c, const uint8_t *const src[
                                        const int dstStride_a[])
 {
     uint8_t *dst = dstParam[0] + dstStride_a[0] * srcSliceY;
-    // yv12toyuy2(src[0], src[1], src[2], dst, c->srcW, srcSliceH,
+    // yv12toyuy2(src[0], src[1], src[2], dst, c->opts.src_w, srcSliceH,
     //            srcStride[0], srcStride[1], dstStride[0]);
     const uint8_t *ysrc              = src[0];
     const uint8_t *usrc              = src[1];
     const uint8_t *vsrc              = src[2];
-    const int width                  = c->srcW;
+    const int width                  = c->opts.src_w;
     const int height                 = srcSliceH;
     const int lumStride              = srcStride[0];
     const int chromStride            = srcStride[1];
@@ -190,9 +190,9 @@ av_cold void ff_get_unscaled_swscale_ppc(SwsInternal *c)
     if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))
         return;
 
-    if (!(c->srcW & 15) && !(c->flags & SWS_BITEXACT) &&
-        c->srcFormat == AV_PIX_FMT_YUV420P) {
-        enum AVPixelFormat dstFormat = c->dstFormat;
+    if (!(c->opts.src_w & 15) && !(c->opts.flags & SWS_BITEXACT) &&
+        c->opts.src_format == AV_PIX_FMT_YUV420P) {
+        enum AVPixelFormat dstFormat = c->opts.dst_format;
 
         // unscaled YV12 -> packed YUV, we want speed
         if (dstFormat == AV_PIX_FMT_YUYV422)
diff --git a/libswscale/riscv/swscale.c b/libswscale/riscv/swscale.c
index 8ed9ce969e..eca5769c4e 100644
--- a/libswscale/riscv/swscale.c
+++ b/libswscale/riscv/swscale.c
@@ -37,10 +37,10 @@ av_cold static void ff_sws_init_range_convert_riscv(SwsInternal *c, int flags)
         { ff_range_lum_from_jpeg_16_rvv, ff_range_chr_from_jpeg_16_rvv },
     };
 
-    if (c->srcRange != c->dstRange && !isAnyRGB(c->dstFormat) &&
+    if (c->opts.src_range != c->opts.dst_range && !isAnyRGB(c->opts.dst_format) &&
         c->dstBpc <= 14 &&
         (flags & AV_CPU_FLAG_RVV_I32) && (flags & AV_CPU_FLAG_RVB)) {
-        bool from = c->srcRange != 0;
+        bool from = c->opts.src_range != 0;
 
         c->lumConvertRange = convs[from].lum;
         c->chrConvertRange = convs[from].chr;
@@ -71,7 +71,7 @@ av_cold void ff_sws_init_swscale_riscv(SwsInternal *c)
 
 #if HAVE_RVV
     if ((flags & AV_CPU_FLAG_RVV_I32) && (flags & AV_CPU_FLAG_RVB)) {
-        switch (c->srcFormat) {
+        switch (c->opts.src_format) {
             case AV_PIX_FMT_ABGR:
                 c->lumToYV12 = ff_abgr32ToY_rvv;
                 if (c->chrSrcHSubSample)
diff --git a/libswscale/slice.c b/libswscale/slice.c
index f13a839f98..72e88be318 100644
--- a/libswscale/slice.c
+++ b/libswscale/slice.c
@@ -221,7 +221,7 @@ static void fill_ones(SwsSlice *s, int n, int bpc)
 static void get_min_buffer_size(SwsInternal *c, int *out_lum_size, int *out_chr_size)
 {
     int lumY;
-    int dstH = c->dstH;
+    int dstH = c->opts.dst_h;
     int chrDstH = c->chrDstH;
     int *lumFilterPos = c->vLumFilterPos;
     int *chrFilterPos = c->vChrFilterPos;
@@ -253,14 +253,14 @@ int ff_init_filters(SwsInternal * c)
     int index;
     int num_ydesc;
     int num_cdesc;
-    int num_vdesc = isPlanarYUV(c->dstFormat) && !isGray(c->dstFormat) ? 2 : 1;
+    int num_vdesc = isPlanarYUV(c->opts.dst_format) && !isGray(c->opts.dst_format) ? 2 : 1;
     int need_lum_conv = c->lumToYV12 || c->readLumPlanar || c->alpToYV12 || c->readAlpPlanar;
     int need_chr_conv = c->chrToYV12 || c->readChrPlanar;
     int need_gamma = c->is_internal_gamma;
     int srcIdx, dstIdx;
-    int dst_stride = FFALIGN(c->dstW * sizeof(int16_t) + 66, 16);
+    int dst_stride = FFALIGN(c->opts.dst_w * sizeof(int16_t) + 66, 16);
 
-    uint32_t * pal = usePal(c->srcFormat) ? c->pal_yuv : (uint32_t*)c->input_rgb2yuv_table;
+    uint32_t * pal = usePal(c->opts.src_format) ? c->pal_yuv : (uint32_t*)c->input_rgb2yuv_table;
     int res = 0;
 
     int lumBufSize;
@@ -284,7 +284,7 @@ int ff_init_filters(SwsInternal * c)
     c->descIndex[0] = num_ydesc + (need_gamma ? 1 : 0);
     c->descIndex[1] = num_ydesc + num_cdesc + (need_gamma ? 1 : 0);
 
-    if (isFloat16(c->srcFormat)) {
+    if (isFloat16(c->opts.src_format)) {
         c->h2f_tables = av_malloc(sizeof(*c->h2f_tables));
         if (!c->h2f_tables)
             return AVERROR(ENOMEM);
@@ -301,25 +301,25 @@ int ff_init_filters(SwsInternal * c)
         goto cleanup;
     }
 
-    res = alloc_slice(&c->slice[0], c->srcFormat, c->srcH, c->chrSrcH, c->chrSrcHSubSample, c->chrSrcVSubSample, 0);
+    res = alloc_slice(&c->slice[0], c->opts.src_format, c->opts.src_h, c->chrSrcH, c->chrSrcHSubSample, c->chrSrcVSubSample, 0);
     if (res < 0) goto cleanup;
     for (i = 1; i < c->numSlice-2; ++i) {
-        res = alloc_slice(&c->slice[i], c->srcFormat, lumBufSize, chrBufSize, c->chrSrcHSubSample, c->chrSrcVSubSample, 0);
+        res = alloc_slice(&c->slice[i], c->opts.src_format, lumBufSize, chrBufSize, c->chrSrcHSubSample, c->chrSrcVSubSample, 0);
         if (res < 0) goto cleanup;
-        res = alloc_lines(&c->slice[i], FFALIGN(c->srcW*2+78, 16), c->srcW);
+        res = alloc_lines(&c->slice[i], FFALIGN(c->opts.src_w*2+78, 16), c->opts.src_w);
         if (res < 0) goto cleanup;
     }
     // horizontal scaler output
-    res = alloc_slice(&c->slice[i], c->srcFormat, lumBufSize, chrBufSize, c->chrDstHSubSample, c->chrDstVSubSample, 1);
+    res = alloc_slice(&c->slice[i], c->opts.src_format, lumBufSize, chrBufSize, c->chrDstHSubSample, c->chrDstVSubSample, 1);
     if (res < 0) goto cleanup;
-    res = alloc_lines(&c->slice[i], dst_stride, c->dstW);
+    res = alloc_lines(&c->slice[i], dst_stride, c->opts.dst_w);
     if (res < 0) goto cleanup;
 
     fill_ones(&c->slice[i], dst_stride>>1, c->dstBpc);
 
     // vertical scaler output
     ++i;
-    res = alloc_slice(&c->slice[i], c->dstFormat, c->dstH, c->chrDstH, c->chrDstHSubSample, c->chrDstVSubSample, 0);
+    res = alloc_slice(&c->slice[i], c->opts.dst_format, c->opts.dst_h, c->chrDstH, c->chrDstHSubSample, c->chrDstVSubSample, 0);
     if (res < 0) goto cleanup;
 
     index = 0;
diff --git a/libswscale/swscale.c b/libswscale/swscale.c
index e0a9e0279f..ea4c7b00d1 100644
--- a/libswscale/swscale.c
+++ b/libswscale/swscale.c
@@ -66,14 +66,14 @@ static void hScale16To19_c(SwsInternal *c, int16_t *_dst, int dstW,
                            const uint8_t *_src, const int16_t *filter,
                            const int32_t *filterPos, int filterSize)
 {
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat);
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->opts.src_format);
     int i;
     int32_t *dst        = (int32_t *) _dst;
     const uint16_t *src = (const uint16_t *) _src;
     int bits            = desc->comp[0].depth - 1;
     int sh              = bits - 4;
 
-    if ((isAnyRGB(c->srcFormat) || c->srcFormat==AV_PIX_FMT_PAL8) && desc->comp[0].depth<16) {
+    if ((isAnyRGB(c->opts.src_format) || c->opts.src_format==AV_PIX_FMT_PAL8) && desc->comp[0].depth<16) {
         sh = 9;
     } else if (desc->flags & AV_PIX_FMT_FLAG_FLOAT) { /* float input are process like uint 16bpc */
         sh = 16 - 1 - 4;
@@ -96,13 +96,13 @@ static void hScale16To15_c(SwsInternal *c, int16_t *dst, int dstW,
                            const uint8_t *_src, const int16_t *filter,
                            const int32_t *filterPos, int filterSize)
 {
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat);
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->opts.src_format);
     int i;
     const uint16_t *src = (const uint16_t *) _src;
     int sh              = desc->comp[0].depth - 1;
 
     if (sh<15) {
-        sh = isAnyRGB(c->srcFormat) || c->srcFormat==AV_PIX_FMT_PAL8 ? 13 : (desc->comp[0].depth - 1);
+        sh = isAnyRGB(c->opts.src_format) || c->opts.src_format==AV_PIX_FMT_PAL8 ? 13 : (desc->comp[0].depth - 1);
     } else if (desc->flags & AV_PIX_FMT_FLAG_FLOAT) { /* float input are process like uint 16bpc */
         sh = 16 - 1;
     }
@@ -237,15 +237,15 @@ int ff_swscale(SwsInternal *c, const uint8_t *const src[], const int srcStride[]
                int srcSliceY, int srcSliceH, uint8_t *const dst[],
                const int dstStride[], int dstSliceY, int dstSliceH)
 {
-    const int scale_dst = dstSliceY > 0 || dstSliceH < c->dstH;
+    const int scale_dst = dstSliceY > 0 || dstSliceH < c->opts.dst_h;
 
     /* load a few things into local vars to make the code more readable?
      * and faster */
-    const int dstW                   = c->dstW;
-    int dstH                         = c->dstH;
+    const int dstW                   = c->opts.dst_w;
+    int dstH                         = c->opts.dst_h;
 
-    const enum AVPixelFormat dstFormat = c->dstFormat;
-    const int flags                  = c->flags;
+    const enum AVPixelFormat dstFormat = c->opts.dst_format;
+    const int flags                  = c->opts.flags;
     int32_t *vLumFilterPos           = c->vLumFilterPos;
     int32_t *vChrFilterPos           = c->vChrFilterPos;
 
@@ -261,8 +261,8 @@ int ff_swscale(SwsInternal *c, const uint8_t *const src[], const int srcStride[]
     yuv2anyX_fn yuv2anyX             = c->yuv2anyX;
     const int chrSrcSliceY           =                srcSliceY >> c->chrSrcVSubSample;
     const int chrSrcSliceH           = AV_CEIL_RSHIFT(srcSliceH,   c->chrSrcVSubSample);
-    int should_dither                = isNBPS(c->srcFormat) ||
-                                       is16BPS(c->srcFormat);
+    int should_dither                = isNBPS(c->opts.src_format) ||
+                                       is16BPS(c->opts.src_format);
     int lastDstY;
 
     /* vars which will change and which we need to store back in the context */
@@ -289,7 +289,7 @@ int ff_swscale(SwsInternal *c, const uint8_t *const src[], const int srcStride[]
     const uint8_t *src2[4];
     int srcStride2[4];
 
-    if (isPacked(c->srcFormat)) {
+    if (isPacked(c->opts.src_format)) {
         src2[0] =
         src2[1] =
         src2[2] =
@@ -364,10 +364,10 @@ int ff_swscale(SwsInternal *c, const uint8_t *const src[], const int srcStride[]
     ff_init_vscale_pfn(c, yuv2plane1, yuv2planeX, yuv2nv12cX,
                    yuv2packed1, yuv2packed2, yuv2packedX, yuv2anyX, c->use_mmx_vfilter);
 
-    ff_init_slice_from_src(src_slice, (uint8_t**)src2, srcStride2, c->srcW,
+    ff_init_slice_from_src(src_slice, (uint8_t**)src2, srcStride2, c->opts.src_w,
             srcSliceY, srcSliceH, chrSrcSliceY, chrSrcSliceH, 1);
 
-    ff_init_slice_from_src(vout_slice, (uint8_t**)dst, dstStride, c->dstW,
+    ff_init_slice_from_src(vout_slice, (uint8_t**)dst, dstStride, c->opts.dst_w,
             dstY, dstSliceH, dstY >> c->chrDstVSubSample,
             AV_CEIL_RSHIFT(dstSliceH, c->chrDstVSubSample), scale_dst);
     if (srcSliceY == 0) {
@@ -389,13 +389,13 @@ int ff_swscale(SwsInternal *c, const uint8_t *const src[], const int srcStride[]
 
         // First line needed as input
         const int firstLumSrcY  = FFMAX(1 - vLumFilterSize, vLumFilterPos[dstY]);
-        const int firstLumSrcY2 = FFMAX(1 - vLumFilterSize, vLumFilterPos[FFMIN(dstY | ((1 << c->chrDstVSubSample) - 1), c->dstH - 1)]);
+        const int firstLumSrcY2 = FFMAX(1 - vLumFilterSize, vLumFilterPos[FFMIN(dstY | ((1 << c->chrDstVSubSample) - 1), c->opts.dst_h - 1)]);
         // First line needed as input
         const int firstChrSrcY  = FFMAX(1 - vChrFilterSize, vChrFilterPos[chrDstY]);
 
         // Last line needed as input
-        int lastLumSrcY  = FFMIN(c->srcH,    firstLumSrcY  + vLumFilterSize) - 1;
-        int lastLumSrcY2 = FFMIN(c->srcH,    firstLumSrcY2 + vLumFilterSize) - 1;
+        int lastLumSrcY  = FFMIN(c->opts.src_h,    firstLumSrcY  + vLumFilterSize) - 1;
+        int lastLumSrcY2 = FFMIN(c->opts.src_h,    firstLumSrcY2 + vLumFilterSize) - 1;
         int lastChrSrcY  = FFMIN(c->chrSrcH, firstChrSrcY  + vChrFilterSize) - 1;
         int enough_lines;
 
@@ -488,13 +488,13 @@ int ff_swscale(SwsInternal *c, const uint8_t *const src[], const int srcStride[]
 
 #if HAVE_MMX_INLINE
         ff_updateMMXDitherTables(c, dstY);
-        c->dstW_mmx = c->dstW;
+        c->dstW_mmx = c->opts.dst_w;
 #endif
         if (should_dither) {
             c->chrDither8 = ff_dither_8x8_128[chrDstY & 7];
             c->lumDither8 = ff_dither_8x8_128[dstY    & 7];
         }
-        if (dstY >= c->dstH - 2) {
+        if (dstY >= c->opts.dst_h - 2) {
             /* hmm looks like we can't use MMX here without overwriting
              * this array's tail */
             ff_sws_init_output_funcs(c, &yuv2plane1, &yuv2planeX, &yuv2nv12cX,
@@ -544,9 +544,9 @@ av_cold void ff_sws_init_range_convert(SwsInternal *c)
 {
     c->lumConvertRange = NULL;
     c->chrConvertRange = NULL;
-    if (c->srcRange != c->dstRange && !isAnyRGB(c->dstFormat)) {
+    if (c->opts.src_range != c->opts.dst_range && !isAnyRGB(c->opts.dst_format)) {
         if (c->dstBpc <= 14) {
-            if (c->srcRange) {
+            if (c->opts.src_range) {
                 c->lumConvertRange = lumRangeFromJpeg_c;
                 c->chrConvertRange = chrRangeFromJpeg_c;
             } else {
@@ -554,7 +554,7 @@ av_cold void ff_sws_init_range_convert(SwsInternal *c)
                 c->chrConvertRange = chrRangeToJpeg_c;
             }
         } else {
-            if (c->srcRange) {
+            if (c->opts.src_range) {
                 c->lumConvertRange = lumRangeFromJpeg16_c;
                 c->chrConvertRange = chrRangeFromJpeg16_c;
             } else {
@@ -567,7 +567,7 @@ av_cold void ff_sws_init_range_convert(SwsInternal *c)
 
 static av_cold void sws_init_swscale(SwsInternal *c)
 {
-    enum AVPixelFormat srcFormat = c->srcFormat;
+    enum AVPixelFormat srcFormat = c->opts.src_format;
 
     ff_sws_init_output_funcs(c, &c->yuv2plane1, &c->yuv2planeX,
                              &c->yuv2nv12cX, &c->yuv2packed1,
@@ -579,7 +579,7 @@ static av_cold void sws_init_swscale(SwsInternal *c)
     if (c->srcBpc == 8) {
         if (c->dstBpc <= 14) {
             c->hyScale = c->hcScale = hScale8To15_c;
-            if (c->flags & SWS_FAST_BILINEAR) {
+            if (c->opts.flags & SWS_FAST_BILINEAR) {
                 c->hyscale_fast = ff_hyscale_fast_c;
                 c->hcscale_fast = ff_hcscale_fast_c;
             }
@@ -593,7 +593,7 @@ static av_cold void sws_init_swscale(SwsInternal *c)
 
     ff_sws_init_range_convert(c);
 
-    if (!(isGray(srcFormat) || isGray(c->dstFormat) ||
+    if (!(isGray(srcFormat) || isGray(c->opts.dst_format) ||
           srcFormat == AV_PIX_FMT_MONOBLACK || srcFormat == AV_PIX_FMT_MONOWHITE))
         c->needs_hcscale = 1;
 }
@@ -649,7 +649,7 @@ static int check_image_pointers(const uint8_t * const data[4], enum AVPixelForma
 void ff_xyz12Torgb48(const SwsInternal *c, uint8_t *dst, int dst_stride,
                      const uint8_t *src, int src_stride, int w, int h)
 {
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat);
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->opts.src_format);
 
     for (int yp = 0; yp < h; yp++) {
         const uint16_t *src16 = (const uint16_t *) src;
@@ -708,7 +708,7 @@ void ff_xyz12Torgb48(const SwsInternal *c, uint8_t *dst, int dst_stride,
 void ff_rgb48Toxyz12(const SwsInternal *c, uint8_t *dst, int dst_stride,
                      const uint8_t *src, int src_stride, int w, int h)
 {
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->dstFormat);
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->opts.dst_format);
 
     for (int yp = 0; yp < h; yp++) {
         uint16_t *src16 = (uint16_t *) src;
@@ -768,28 +768,28 @@ void ff_update_palette(SwsInternal *c, const uint32_t *pal)
 {
     for (int i = 0; i < 256; i++) {
         int r, g, b, y, u, v, a = 0xff;
-        if (c->srcFormat == AV_PIX_FMT_PAL8) {
+        if (c->opts.src_format == AV_PIX_FMT_PAL8) {
             uint32_t p = pal[i];
             a = (p >> 24) & 0xFF;
             r = (p >> 16) & 0xFF;
             g = (p >>  8) & 0xFF;
             b =  p        & 0xFF;
-        } else if (c->srcFormat == AV_PIX_FMT_RGB8) {
+        } else if (c->opts.src_format == AV_PIX_FMT_RGB8) {
             r = ( i >> 5     ) * 36;
             g = ((i >> 2) & 7) * 36;
             b = ( i       & 3) * 85;
-        } else if (c->srcFormat == AV_PIX_FMT_BGR8) {
+        } else if (c->opts.src_format == AV_PIX_FMT_BGR8) {
             b = ( i >> 6     ) * 85;
             g = ((i >> 3) & 7) * 36;
             r = ( i       & 7) * 36;
-        } else if (c->srcFormat == AV_PIX_FMT_RGB4_BYTE) {
+        } else if (c->opts.src_format == AV_PIX_FMT_RGB4_BYTE) {
             r = ( i >> 3     ) * 255;
             g = ((i >> 1) & 3) * 85;
             b = ( i       & 1) * 255;
-        } else if (c->srcFormat == AV_PIX_FMT_GRAY8 || c->srcFormat == AV_PIX_FMT_GRAY8A) {
+        } else if (c->opts.src_format == AV_PIX_FMT_GRAY8 || c->opts.src_format == AV_PIX_FMT_GRAY8A) {
             r = g = b = i;
         } else {
-            av_assert1(c->srcFormat == AV_PIX_FMT_BGR4_BYTE);
+            av_assert1(c->opts.src_format == AV_PIX_FMT_BGR4_BYTE);
             b = ( i >> 3     ) * 255;
             g = ((i >> 1) & 3) * 85;
             r = ( i       & 1) * 255;
@@ -810,7 +810,7 @@ void ff_update_palette(SwsInternal *c, const uint32_t *pal)
         v = av_clip_uint8((RV * r + GV * g + BV * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
         c->pal_yuv[i]= y + (u<<8) + (v<<16) + ((unsigned)a<<24);
 
-        switch (c->dstFormat) {
+        switch (c->opts.dst_format) {
         case AV_PIX_FMT_BGR32:
 #if !HAVE_BIGENDIAN
         case AV_PIX_FMT_RGB24:
@@ -853,7 +853,7 @@ static int scale_gamma(SwsInternal *c,
 {
     int ret = scale_internal(c->cascaded_context[0],
                              srcSlice, srcStride, srcSliceY, srcSliceH,
-                             c->cascaded_tmp[0], c->cascaded_tmpStride[0], 0, c->srcH);
+                             c->cascaded_tmp[0], c->cascaded_tmpStride[0], 0, c->opts.src_h);
 
     if (ret < 0)
         return ret;
@@ -861,7 +861,7 @@ static int scale_gamma(SwsInternal *c,
     if (c->cascaded_context[2])
         ret = scale_internal(c->cascaded_context[1], (const uint8_t * const *)c->cascaded_tmp[0],
                              c->cascaded_tmpStride[0], srcSliceY, srcSliceH,
-                             c->cascaded_tmp[1], c->cascaded_tmpStride[1], 0, c->dstH);
+                             c->cascaded_tmp[1], c->cascaded_tmpStride[1], 0, c->opts.dst_h);
     else
         ret = scale_internal(c->cascaded_context[1], (const uint8_t * const *)c->cascaded_tmp[0],
                              c->cascaded_tmpStride[0], srcSliceY, srcSliceH,
@@ -885,7 +885,7 @@ static int scale_cascaded(SwsInternal *c,
                           uint8_t * const dstSlice[], const int dstStride[],
                           int dstSliceY, int dstSliceH)
 {
-    const int dstH0 = sws_internal(c->cascaded_context[0])->dstH;
+    const int dstH0 = sws_internal(c->cascaded_context[0])->opts.dst_h;
     int ret = scale_internal(c->cascaded_context[0],
                              srcSlice, srcStride, srcSliceY, srcSliceH,
                              c->cascaded_tmp[0], c->cascaded_tmpStride[0],
@@ -905,13 +905,13 @@ static int scale_internal(SwsContext *sws,
                           int dstSliceY, int dstSliceH)
 {
     SwsInternal *c = sws_internal(sws);
-    const int scale_dst = dstSliceY > 0 || dstSliceH < c->dstH;
+    const int scale_dst = dstSliceY > 0 || dstSliceH < c->opts.dst_h;
     const int frame_start = scale_dst || !c->sliceDir;
     int i, ret;
     const uint8_t *src2[4];
     uint8_t *dst2[4];
-    int macro_height_src = isBayer(c->srcFormat) ? 2 : (1 << c->chrSrcVSubSample);
-    int macro_height_dst = isBayer(c->dstFormat) ? 2 : (1 << c->chrDstVSubSample);
+    int macro_height_src = isBayer(c->opts.src_format) ? 2 : (1 << c->chrSrcVSubSample);
+    int macro_height_dst = isBayer(c->opts.dst_format) ? 2 : (1 << c->chrDstVSubSample);
     // copy strides, so they can safely be modified
     int srcStride2[4];
     int dstStride2[4];
@@ -923,25 +923,25 @@ static int scale_internal(SwsContext *sws,
     }
 
     if ((srcSliceY  & (macro_height_src - 1)) ||
-        ((srcSliceH & (macro_height_src - 1)) && srcSliceY + srcSliceH != c->srcH) ||
-        srcSliceY + srcSliceH > c->srcH ||
-        (isBayer(c->srcFormat) && srcSliceH <= 1)) {
+        ((srcSliceH & (macro_height_src - 1)) && srcSliceY + srcSliceH != c->opts.src_h) ||
+        srcSliceY + srcSliceH > c->opts.src_h ||
+        (isBayer(c->opts.src_format) && srcSliceH <= 1)) {
         av_log(c, AV_LOG_ERROR, "Slice parameters %d, %d are invalid\n", srcSliceY, srcSliceH);
         return AVERROR(EINVAL);
     }
 
     if ((dstSliceY  & (macro_height_dst - 1)) ||
-        ((dstSliceH & (macro_height_dst - 1)) && dstSliceY + dstSliceH != c->dstH) ||
-        dstSliceY + dstSliceH > c->dstH) {
+        ((dstSliceH & (macro_height_dst - 1)) && dstSliceY + dstSliceH != c->opts.dst_h) ||
+        dstSliceY + dstSliceH > c->opts.dst_h) {
         av_log(c, AV_LOG_ERROR, "Slice parameters %d, %d are invalid\n", dstSliceY, dstSliceH);
         return AVERROR(EINVAL);
     }
 
-    if (!check_image_pointers(srcSlice, c->srcFormat, srcStride)) {
+    if (!check_image_pointers(srcSlice, c->opts.src_format, srcStride)) {
         av_log(c, AV_LOG_ERROR, "bad src image pointers\n");
         return AVERROR(EINVAL);
     }
-    if (!check_image_pointers((const uint8_t* const*)dstSlice, c->dstFormat, dstStride)) {
+    if (!check_image_pointers((const uint8_t* const*)dstSlice, c->opts.dst_format, dstStride)) {
         av_log(c, AV_LOG_ERROR, "bad dst image pointers\n");
         return AVERROR(EINVAL);
     }
@@ -950,22 +950,22 @@ static int scale_internal(SwsContext *sws,
     if (srcSliceH == 0)
         return 0;
 
-    if (c->gamma_flag && c->cascaded_context[0])
+    if (c->opts.gamma_flag && c->cascaded_context[0])
         return scale_gamma(c, srcSlice, srcStride, srcSliceY, srcSliceH,
                            dstSlice, dstStride, dstSliceY, dstSliceH);
 
     if (c->cascaded_context[0] && srcSliceY == 0 &&
-        srcSliceH == sws_internal(c->cascaded_context[0])->srcH)
+        srcSliceH == sws_internal(c->cascaded_context[0])->opts.src_h)
     {
         return scale_cascaded(c, srcSlice, srcStride, srcSliceY, srcSliceH,
                               dstSlice, dstStride, dstSliceY, dstSliceH);
     }
 
-    if (!srcSliceY && (c->flags & SWS_BITEXACT) && c->dither == SWS_DITHER_ED && c->dither_error[0])
+    if (!srcSliceY && (c->opts.flags & SWS_BITEXACT) && c->opts.dither == SWS_DITHER_ED && c->dither_error[0])
         for (i = 0; i < 4; i++)
-            memset(c->dither_error[i], 0, sizeof(c->dither_error[0][0]) * (c->dstW+2));
+            memset(c->dither_error[i], 0, sizeof(c->dither_error[0][0]) * (c->opts.dst_w+2));
 
-    if (usePal(c->srcFormat))
+    if (usePal(c->opts.src_format))
         ff_update_palette(c, (const uint32_t *)srcSlice[1]);
 
     memcpy(src2,       srcSlice,  sizeof(src2));
@@ -974,7 +974,7 @@ static int scale_internal(SwsContext *sws,
     memcpy(dstStride2, dstStride, sizeof(dstStride2));
 
     if (frame_start && !scale_dst) {
-        if (srcSliceY != 0 && srcSliceY + srcSliceH != c->srcH) {
+        if (srcSliceY != 0 && srcSliceY + srcSliceH != c->opts.src_h) {
             av_log(c, AV_LOG_ERROR, "Slices start in the middle!\n");
             return AVERROR(EINVAL);
         }
@@ -983,7 +983,7 @@ static int scale_internal(SwsContext *sws,
     } else if (scale_dst)
         c->sliceDir = 1;
 
-    if (c->src0Alpha && !c->dst0Alpha && isALPHA(c->dstFormat)) {
+    if (c->src0Alpha && !c->dst0Alpha && isALPHA(c->opts.dst_format)) {
         uint8_t *base;
         int x,y;
 
@@ -995,15 +995,15 @@ static int scale_internal(SwsContext *sws,
         base = srcStride[0] < 0 ? c->rgb0_scratch - srcStride[0] * (srcSliceH-1) :
                                   c->rgb0_scratch;
         for (y=0; y<srcSliceH; y++){
-            memcpy(base + srcStride[0]*y, src2[0] + srcStride[0]*y, 4*c->srcW);
-            for (x=c->src0Alpha-1; x<4*c->srcW; x+=4) {
+            memcpy(base + srcStride[0]*y, src2[0] + srcStride[0]*y, 4*c->opts.src_w);
+            for (x=c->src0Alpha-1; x<4*c->opts.src_w; x+=4) {
                 base[ srcStride[0]*y + x] = 0xFF;
             }
         }
         src2[0] = base;
     }
 
-    if (c->srcXYZ && !(c->dstXYZ && c->srcW==c->dstW && c->srcH==c->dstH)) {
+    if (c->srcXYZ && !(c->dstXYZ && c->opts.src_w==c->opts.dst_w && c->opts.src_h==c->opts.dst_h)) {
         uint8_t *base;
 
         av_fast_malloc(&c->xyz_scratch, &c->xyz_scratch_allocated,
@@ -1014,7 +1014,7 @@ static int scale_internal(SwsContext *sws,
         base = srcStride[0] < 0 ? c->xyz_scratch - srcStride[0] * (srcSliceH-1) :
                                   c->xyz_scratch;
 
-        ff_xyz12Torgb48(c, base, srcStride[0], src2[0], srcStride[0], c->srcW, srcSliceH);
+        ff_xyz12Torgb48(c, base, srcStride[0], src2[0], srcStride[0], c->opts.src_w, srcSliceH);
         src2[0] = base;
     }
 
@@ -1026,19 +1026,19 @@ static int scale_internal(SwsContext *sws,
         }
 
         src2[0] += (srcSliceH - 1) * srcStride[0];
-        if (!usePal(c->srcFormat))
+        if (!usePal(c->opts.src_format))
             src2[1] += ((srcSliceH >> c->chrSrcVSubSample) - 1) * srcStride[1];
         src2[2] += ((srcSliceH >> c->chrSrcVSubSample) - 1) * srcStride[2];
         src2[3] += (srcSliceH - 1) * srcStride[3];
-        dst2[0] += ( c->dstH                         - 1) * dstStride[0];
-        dst2[1] += ((c->dstH >> c->chrDstVSubSample) - 1) * dstStride[1];
-        dst2[2] += ((c->dstH >> c->chrDstVSubSample) - 1) * dstStride[2];
-        dst2[3] += ( c->dstH                         - 1) * dstStride[3];
+        dst2[0] += ( c->opts.dst_h                         - 1) * dstStride[0];
+        dst2[1] += ((c->opts.dst_h >> c->chrDstVSubSample) - 1) * dstStride[1];
+        dst2[2] += ((c->opts.dst_h >> c->chrDstVSubSample) - 1) * dstStride[2];
+        dst2[3] += ( c->opts.dst_h                         - 1) * dstStride[3];
 
-        srcSliceY_internal = c->srcH-srcSliceY-srcSliceH;
+        srcSliceY_internal = c->opts.src_h-srcSliceY-srcSliceH;
     }
-    reset_ptr(src2, c->srcFormat);
-    reset_ptr((void*)dst2, c->dstFormat);
+    reset_ptr(src2, c->opts.src_format);
+    reset_ptr((void*)dst2, c->opts.dst_format);
 
     if (c->convert_unscaled) {
         int offset  = srcSliceY_internal;
@@ -1048,13 +1048,13 @@ static int scale_internal(SwsContext *sws,
         if (scale_dst) {
             av_assert0(offset == 0);
             for (i = 0; i < 4 && src2[i]; i++) {
-                if (!src2[i] || (i > 0 && usePal(c->srcFormat)))
+                if (!src2[i] || (i > 0 && usePal(c->opts.src_format)))
                     break;
                 src2[i] += (dstSliceY >> ((i == 1 || i == 2) ? c->chrSrcVSubSample : 0)) * srcStride2[i];
             }
 
             for (i = 0; i < 4 && dst2[i]; i++) {
-                if (!dst2[i] || (i > 0 && usePal(c->dstFormat)))
+                if (!dst2[i] || (i > 0 && usePal(c->opts.dst_format)))
                     break;
                 dst2[i] -= (dstSliceY >> ((i == 1 || i == 2) ? c->chrDstVSubSample : 0)) * dstStride2[i];
             }
@@ -1071,7 +1071,7 @@ static int scale_internal(SwsContext *sws,
                          dst2, dstStride2, dstSliceY, dstSliceH);
     }
 
-    if (c->dstXYZ && !(c->srcXYZ && c->srcW==c->dstW && c->srcH==c->dstH)) {
+    if (c->dstXYZ && !(c->srcXYZ && c->opts.src_w==c->opts.dst_w && c->opts.src_h==c->opts.dst_h)) {
         uint8_t *dst;
 
         if (scale_dst) {
@@ -1081,16 +1081,16 @@ static int scale_internal(SwsContext *sws,
 
             av_assert0(dstY >= ret);
             av_assert0(ret >= 0);
-            av_assert0(c->dstH >= dstY);
+            av_assert0(c->opts.dst_h >= dstY);
             dst = dst2[0] + (dstY - ret) * dstStride2[0];
         }
 
         /* replace on the same data */
-        ff_rgb48Toxyz12(c, dst, dstStride2[0], dst, dstStride2[0], c->dstW, ret);
+        ff_rgb48Toxyz12(c, dst, dstStride2[0], dst, dstStride2[0], c->opts.dst_w, ret);
     }
 
     /* reset slice direction at end of frame */
-    if ((srcSliceY_internal + srcSliceH == c->srcH) || scale_dst)
+    if ((srcSliceY_internal + srcSliceH == c->opts.src_h) || scale_dst)
         c->sliceDir = 0;
 
     return ret;
@@ -1114,9 +1114,9 @@ int sws_frame_start(SwsContext *sws, AVFrame *dst, const AVFrame *src)
         return ret;
 
     if (!dst->buf[0]) {
-        dst->width  = c->dstW;
-        dst->height = c->dstH;
-        dst->format = c->dstFormat;
+        dst->width  = c->opts.dst_w;
+        dst->height = c->opts.dst_h;
+        dst->format = c->opts.dst_format;
 
         ret = av_frame_get_buffer(dst, 0);
         if (ret < 0)
@@ -1167,10 +1167,10 @@ int sws_receive_slice(SwsContext *sws, unsigned int slice_start,
     /* wait until complete input has been received */
     if (!(c->src_ranges.nb_ranges == 1        &&
           c->src_ranges.ranges[0].start == 0 &&
-          c->src_ranges.ranges[0].len == c->srcH))
+          c->src_ranges.ranges[0].len == c->opts.src_h))
         return AVERROR(EAGAIN);
 
-    if ((slice_start > 0 || slice_height < c->dstH) &&
+    if ((slice_start > 0 || slice_height < c->opts.dst_h) &&
         (slice_start % align || slice_height % align)) {
         av_log(c, AV_LOG_ERROR,
                "Incorrectly aligned output: %u/%u not multiples of %u\n",
@@ -1182,7 +1182,7 @@ int sws_receive_slice(SwsContext *sws, unsigned int slice_start,
         int nb_jobs = c->nb_slice_ctx;
         int ret = 0;
 
-        if (sws_internal(c->slice_ctx[0])->dither == SWS_DITHER_ED)
+        if (sws_internal(c->slice_ctx[0])->opts.dither == SWS_DITHER_ED)
             nb_jobs = 1;
 
         c->dst_slice_start  = slice_start;
@@ -1208,7 +1208,7 @@ int sws_receive_slice(SwsContext *sws, unsigned int slice_start,
     }
 
     return scale_internal(sws, (const uint8_t * const *)c->frame_src->data,
-                          c->frame_src->linesize, 0, c->srcH,
+                          c->frame_src->linesize, 0, c->opts.src_h,
                           dst, c->frame_dst->linesize, slice_start, slice_height);
 }
 
@@ -1246,7 +1246,7 @@ int attribute_align_arg sws_scale(SwsContext *sws,
     }
 
     return scale_internal(sws, srcSlice, srcStride, srcSliceY, srcSliceH,
-                          dst, dstStride, 0, c->dstH);
+                          dst, dstStride, 0, c->opts.dst_h);
 }
 
 void ff_sws_slice_worker(void *priv, int jobnr, int threadnr,
@@ -1274,7 +1274,7 @@ void ff_sws_slice_worker(void *priv, int jobnr, int threadnr,
         }
 
         err = scale_internal(sws, (const uint8_t * const *)parent->frame_src->data,
-                             parent->frame_src->linesize, 0, c->srcH,
+                             parent->frame_src->linesize, 0, c->opts.src_h,
                              dst, parent->frame_dst->linesize,
                              parent->dst_slice_start + slice_start, slice_end - slice_start);
     }
diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h
index 6b85ecadae..d459b79af3 100644
--- a/libswscale/swscale_internal.h
+++ b/libswscale/swscale_internal.h
@@ -329,10 +329,31 @@ struct SwsFilterDescriptor;
 
 /* This struct should be aligned on at least a 32-byte boundary. */
 struct SwsInternal {
-    /**
-     * info on struct for av_log
-     */
-    const AVClass *av_class;
+    /* Currently active user-facing options. */
+    struct {
+        const AVClass *av_class;
+
+        double scaler_params[2];       ///< Input parameters for scaling algorithms that need them.
+        int flags;                     ///< Flags passed by the user to select scaler algorithm, optimizations, subsampling, etc...
+        int threads;                   ///< Number of threads used for scaling
+
+        int src_w;                     ///< Width  of source      luma/alpha planes.
+        int src_h;                     ///< Height of source      luma/alpha planes.
+        int dst_w;                     ///< Width  of destination luma/alpha planes.
+        int dst_h;                     ///< Height of destination luma/alpha planes.
+        enum AVPixelFormat src_format; ///< Source      pixel format.
+        enum AVPixelFormat dst_format; ///< Destination pixel format.
+        int src_range;                 ///< 0 = MPG YUV range, 1 = JPG YUV range (source      image).
+        int dst_range;                 ///< 0 = MPG YUV range, 1 = JPG YUV range (destination image).
+        int src_h_chr_pos;
+        int dst_h_chr_pos;
+        int src_v_chr_pos;
+        int dst_v_chr_pos;
+        int gamma_flag;
+
+        SwsDither dither;
+        SwsAlphaBlend alpha_blend;
+    } opts;
 
     SwsContext *parent;
 
@@ -350,18 +371,12 @@ struct SwsInternal {
      * sws_scale() wrapper so they can be freely modified here.
      */
     SwsFunc convert_unscaled;
-    int srcW;                     ///< Width  of source      luma/alpha planes.
-    int srcH;                     ///< Height of source      luma/alpha planes.
-    int dstW;                     ///< Width  of destination luma/alpha planes.
-    int dstH;                     ///< Height of destination luma/alpha planes.
     int chrSrcW;                  ///< Width  of source      chroma     planes.
     int chrSrcH;                  ///< Height of source      chroma     planes.
     int chrDstW;                  ///< Width  of destination chroma     planes.
     int chrDstH;                  ///< Height of destination chroma     planes.
     int lumXInc, chrXInc;
     int lumYInc, chrYInc;
-    enum AVPixelFormat dstFormat; ///< Destination pixel format.
-    enum AVPixelFormat srcFormat; ///< Source      pixel format.
     int dstFormatBpp;             ///< Number of bits per pixel of the destination pixel format.
     int srcFormatBpp;             ///< Number of bits per pixel of the source      pixel format.
     int dstBpc, srcBpc;
@@ -371,8 +386,6 @@ struct SwsInternal {
     int chrDstVSubSample;         ///< Binary logarithm of vertical   subsampling factor between luma/alpha and chroma planes in destination image.
     int vChrDrop;                 ///< Binary logarithm of extra vertical subsampling factor in source image chroma planes specified by user.
     int sliceDir;                 ///< Direction that slices are fed to the scaler (1 = top-to-bottom, -1 = bottom-to-top).
-    int nb_threads;               ///< Number of threads used for scaling
-    double param[2];              ///< Input parameters for scaling algorithms that need them.
 
     AVFrame *frame_src;
     AVFrame *frame_dst;
@@ -389,7 +402,6 @@ struct SwsInternal {
     int cascaded_mainindex;
 
     double gamma_value;
-    int gamma_flag;
     int is_internal_gamma;
     uint16_t *gamma;
     uint16_t *inv_gamma;
@@ -459,7 +471,6 @@ struct SwsInternal {
     int warned_unuseable_bilinear;
 
     int dstY;                     ///< Last destination vertical line output from last slice.
-    int flags;                    ///< Flags passed by the user to select scaler algorithm, optimizations, subsampling, etc...
     void *yuvTable;             // pointer to the yuv->rgb table start so it can be freed()
     // alignment ensures the offset can be added in a single
     // instruction on e.g. ARM
@@ -485,16 +496,10 @@ struct SwsInternal {
     int contrast, brightness, saturation;    // for sws_getColorspaceDetails
     int srcColorspaceTable[4];
     int dstColorspaceTable[4];
-    int srcRange;                 ///< 0 = MPG YUV range, 1 = JPG YUV range (source      image).
-    int dstRange;                 ///< 0 = MPG YUV range, 1 = JPG YUV range (destination image).
     int src0Alpha;
     int dst0Alpha;
     int srcXYZ;
     int dstXYZ;
-    int src_h_chr_pos;
-    int dst_h_chr_pos;
-    int src_v_chr_pos;
-    int dst_v_chr_pos;
     int yuv2rgb_y_offset;
     int yuv2rgb_y_coeff;
     int yuv2rgb_v2r_coeff;
@@ -682,10 +687,6 @@ struct SwsInternal {
 
     int needs_hcscale; ///< Set if there are chroma planes to be converted.
 
-    SwsDither dither;
-
-    SwsAlphaBlend alphablend;
-
     // scratch buffer for converting packed rgb0 sources
     // filled with a copy of the input frame + fully opaque alpha,
     // then passed as input to further conversion
@@ -712,7 +713,7 @@ static_assert(offsetof(SwsInternal, redDither) + DITHER32_INT == offsetof(SwsInt
 #if ARCH_X86_64
 /* x86 yuv2gbrp uses the SwsInternal for yuv coefficients
    if struct offsets change the asm needs to be updated too */
-static_assert(offsetof(SwsInternal, yuv2rgb_y_offset) == 40292,
+static_assert(offsetof(SwsInternal, yuv2rgb_y_offset) == 40316,
               "yuv2rgb_y_offset must be updated in x86 asm");
 #endif
 
diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c
index a1930b9132..9572d91dd3 100644
--- a/libswscale/swscale_unscaled.c
+++ b/libswscale/swscale_unscaled.c
@@ -146,10 +146,10 @@ static int planarToNv12Wrapper(SwsInternal *c, const uint8_t *const src[],
 {
     uint8_t *dst = dstParam[1] + dstStride[1] * srcSliceY / 2;
 
-    ff_copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
+    ff_copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->opts.src_w,
                  dstParam[0], dstStride[0]);
 
-    if (c->dstFormat == AV_PIX_FMT_NV12)
+    if (c->opts.dst_format == AV_PIX_FMT_NV12)
         interleaveBytes(src[1], src[2], dst, c->chrSrcW, (srcSliceH + 1) / 2,
                         srcStride[1], srcStride[2], dstStride[1]);
     else
@@ -167,10 +167,10 @@ static int nv12ToPlanarWrapper(SwsInternal *c, const uint8_t *const src[],
     uint8_t *dst1 = dstParam[1] + dstStride[1] * srcSliceY / 2;
     uint8_t *dst2 = dstParam[2] + dstStride[2] * srcSliceY / 2;
 
-    ff_copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
+    ff_copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->opts.src_w,
                  dstParam[0], dstStride[0]);
 
-    if (c->srcFormat == AV_PIX_FMT_NV12)
+    if (c->opts.src_format == AV_PIX_FMT_NV12)
         deinterleaveBytes(src[1], dst1, dst2, c->chrSrcW, (srcSliceH + 1) / 2,
                           srcStride[1], dstStride[1], dstStride[2]);
     else
@@ -187,10 +187,10 @@ static int planarToNv24Wrapper(SwsInternal *c, const uint8_t *const src[],
 {
     uint8_t *dst = dstParam[1] + dstStride[1] * srcSliceY;
 
-    ff_copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
+    ff_copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->opts.src_w,
                  dstParam[0], dstStride[0]);
 
-    if (c->dstFormat == AV_PIX_FMT_NV24)
+    if (c->opts.dst_format == AV_PIX_FMT_NV24)
         interleaveBytes(src[1], src[2], dst, c->chrSrcW, srcSliceH,
                         srcStride[1], srcStride[2], dstStride[1]);
     else
@@ -208,10 +208,10 @@ static int nv24ToPlanarWrapper(SwsInternal *c, const uint8_t *const src[],
     uint8_t *dst1 = dstParam[1] + dstStride[1] * srcSliceY;
     uint8_t *dst2 = dstParam[2] + dstStride[2] * srcSliceY;
 
-    ff_copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
+    ff_copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->opts.src_w,
                  dstParam[0], dstStride[0]);
 
-    if (c->srcFormat == AV_PIX_FMT_NV24)
+    if (c->opts.src_format == AV_PIX_FMT_NV24)
         deinterleaveBytes(src[1], dst1, dst2, c->chrSrcW, srcSliceH,
                           srcStride[1], dstStride[1], dstStride[2]);
     else
@@ -250,15 +250,15 @@ static int nv24ToYuv420Wrapper(SwsInternal *c, const uint8_t *const src[],
     uint8_t *dst1 = dstParam[1] + dstStride[1] * srcSliceY / 2;
     uint8_t *dst2 = dstParam[2] + dstStride[2] * srcSliceY / 2;
 
-    ff_copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
+    ff_copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->opts.src_w,
                  dstParam[0], dstStride[0]);
 
-    if (c->srcFormat == AV_PIX_FMT_NV24)
+    if (c->opts.src_format == AV_PIX_FMT_NV24)
         nv24_to_yuv420p_chroma(dst1, dstStride[1], dst2, dstStride[2],
-                               src[1], srcStride[1], c->srcW / 2, srcSliceH);
+                               src[1], srcStride[1], c->opts.src_w / 2, srcSliceH);
     else
         nv24_to_yuv420p_chroma(dst2, dstStride[2], dst1, dstStride[1],
-                               src[1], srcStride[1], c->srcW / 2, srcSliceH);
+                               src[1], srcStride[1], c->opts.src_w / 2, srcSliceH);
 
     return srcSliceH;
 }
@@ -268,8 +268,8 @@ static int planarToP01xWrapper(SwsInternal *c, const uint8_t *const src8[],
                                int srcSliceH, uint8_t *const dstParam8[],
                                const int dstStride[])
 {
-    const AVPixFmtDescriptor *src_format = av_pix_fmt_desc_get(c->srcFormat);
-    const AVPixFmtDescriptor *dst_format = av_pix_fmt_desc_get(c->dstFormat);
+    const AVPixFmtDescriptor *src_format = av_pix_fmt_desc_get(c->opts.src_format);
+    const AVPixFmtDescriptor *dst_format = av_pix_fmt_desc_get(c->opts.dst_format);
     const uint16_t **src = (const uint16_t**)src8;
     uint16_t *dstY = (uint16_t*)(dstParam8[0] + dstStride[0] * srcSliceY);
     uint16_t *dstUV = (uint16_t*)(dstParam8[1] + dstStride[1] * srcSliceY / 2);
@@ -291,7 +291,7 @@ static int planarToP01xWrapper(SwsInternal *c, const uint8_t *const src8[],
     for (y = 0; y < srcSliceH; y++) {
         uint16_t *tdstY = dstY;
         const uint16_t *tsrc0 = src[0];
-        for (x = c->srcW; x > 0; x--) {
+        for (x = c->opts.src_w; x > 0; x--) {
             *tdstY++ = *tsrc0++ << shift[0];
         }
         src[0] += srcStride[0] / 2;
@@ -301,7 +301,7 @@ static int planarToP01xWrapper(SwsInternal *c, const uint8_t *const src8[],
             uint16_t *tdstUV = dstUV;
             const uint16_t *tsrc1 = src[1];
             const uint16_t *tsrc2 = src[2];
-            for (x = c->srcW / 2; x > 0; x--) {
+            for (x = c->opts.src_w / 2; x > 0; x--) {
                 *tdstUV++ = *tsrc1++ << shift[1];
                 *tdstUV++ = *tsrc2++ << shift[2];
             }
@@ -338,7 +338,7 @@ static int planar8ToP01xleWrapper(SwsInternal *c, const uint8_t *const src[],
     for (y = 0; y < srcSliceH; y++) {
         uint16_t *tdstY = dstY;
         const uint8_t *tsrc0 = src0;
-        for (x = c->srcW; x > 0; x--) {
+        for (x = c->opts.src_w; x > 0; x--) {
             t = *tsrc0++;
             output_pixel(tdstY++, t << 8);
         }
@@ -349,7 +349,7 @@ static int planar8ToP01xleWrapper(SwsInternal *c, const uint8_t *const src[],
             uint16_t *tdstUV = dstUV;
             const uint8_t *tsrc1 = src1;
             const uint8_t *tsrc2 = src2;
-            for (x = c->srcW / 2; x > 0; x--) {
+            for (x = c->opts.src_w / 2; x > 0; x--) {
                 t = *tsrc1++;
                 output_pixel(tdstUV++, t << 8);
                 t = *tsrc2++;
@@ -372,7 +372,7 @@ static int planarToYuy2Wrapper(SwsInternal *c, const uint8_t *const src[],
 {
     uint8_t *dst = dstParam[0] + dstStride[0] * srcSliceY;
 
-    yv12toyuy2(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0],
+    yv12toyuy2(src[0], src[1], src[2], dst, c->opts.src_w, srcSliceH, srcStride[0],
                srcStride[1], dstStride[0]);
 
     return srcSliceH;
@@ -384,7 +384,7 @@ static int planarToUyvyWrapper(SwsInternal *c, const uint8_t *const src[],
 {
     uint8_t *dst = dstParam[0] + dstStride[0] * srcSliceY;
 
-    yv12touyvy(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0],
+    yv12touyvy(src[0], src[1], src[2], dst, c->opts.src_w, srcSliceH, srcStride[0],
                srcStride[1], dstStride[0]);
 
     return srcSliceH;
@@ -396,7 +396,7 @@ static int yuv422pToYuy2Wrapper(SwsInternal *c, const uint8_t *const src[],
 {
     uint8_t *dst = dstParam[0] + dstStride[0] * srcSliceY;
 
-    yuv422ptoyuy2(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0],
+    yuv422ptoyuy2(src[0], src[1], src[2], dst, c->opts.src_w, srcSliceH, srcStride[0],
                   srcStride[1], dstStride[0]);
 
     return srcSliceH;
@@ -408,7 +408,7 @@ static int yuv422pToUyvyWrapper(SwsInternal *c, const uint8_t *const src[],
 {
     uint8_t *dst = dstParam[0] + dstStride[0] * srcSliceY;
 
-    yuv422ptouyvy(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0],
+    yuv422ptouyvy(src[0], src[1], src[2], dst, c->opts.src_w, srcSliceH, srcStride[0],
                   srcStride[1], dstStride[0]);
 
     return srcSliceH;
@@ -422,11 +422,11 @@ static int yuyvToYuv420Wrapper(SwsInternal *c, const uint8_t *const src[],
     uint8_t *udst = dstParam[1] + dstStride[1] * srcSliceY / 2;
     uint8_t *vdst = dstParam[2] + dstStride[2] * srcSliceY / 2;
 
-    yuyvtoyuv420(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0],
+    yuyvtoyuv420(ydst, udst, vdst, src[0], c->opts.src_w, srcSliceH, dstStride[0],
                  dstStride[1], srcStride[0]);
 
     if (dstParam[3])
-        fillPlane(dstParam[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
+        fillPlane(dstParam[3], dstStride[3], c->opts.src_w, srcSliceH, srcSliceY, 255);
 
     return srcSliceH;
 }
@@ -439,7 +439,7 @@ static int yuyvToYuv422Wrapper(SwsInternal *c, const uint8_t *const src[],
     uint8_t *udst = dstParam[1] + dstStride[1] * srcSliceY;
     uint8_t *vdst = dstParam[2] + dstStride[2] * srcSliceY;
 
-    yuyvtoyuv422(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0],
+    yuyvtoyuv422(ydst, udst, vdst, src[0], c->opts.src_w, srcSliceH, dstStride[0],
                  dstStride[1], srcStride[0]);
 
     return srcSliceH;
@@ -453,11 +453,11 @@ static int uyvyToYuv420Wrapper(SwsInternal *c, const uint8_t *const src[],
     uint8_t *udst = dstParam[1] + dstStride[1] * srcSliceY / 2;
     uint8_t *vdst = dstParam[2] + dstStride[2] * srcSliceY / 2;
 
-    uyvytoyuv420(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0],
+    uyvytoyuv420(ydst, udst, vdst, src[0], c->opts.src_w, srcSliceH, dstStride[0],
                  dstStride[1], srcStride[0]);
 
     if (dstParam[3])
-        fillPlane(dstParam[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
+        fillPlane(dstParam[3], dstStride[3], c->opts.src_w, srcSliceH, srcSliceY, 255);
 
     return srcSliceH;
 }
@@ -470,7 +470,7 @@ static int uyvyToYuv422Wrapper(SwsInternal *c, const uint8_t *const src[],
     uint8_t *udst = dstParam[1] + dstStride[1] * srcSliceY;
     uint8_t *vdst = dstParam[2] + dstStride[2] * srcSliceY;
 
-    uyvytoyuv422(ydst, udst, vdst, src[0], c->srcW, srcSliceH, dstStride[0],
+    uyvytoyuv422(ydst, udst, vdst, src[0], c->opts.src_w, srcSliceH, dstStride[0],
                  dstStride[1], srcStride[0]);
 
     return srcSliceH;
@@ -566,8 +566,8 @@ static int palToRgbWrapper(SwsInternal *c, const uint8_t *const src[], const int
                            int srcSliceY, int srcSliceH, uint8_t *const dst[],
                            const int dstStride[])
 {
-    const enum AVPixelFormat srcFormat = c->srcFormat;
-    const enum AVPixelFormat dstFormat = c->dstFormat;
+    const enum AVPixelFormat srcFormat = c->opts.src_format;
+    const enum AVPixelFormat dstFormat = c->opts.dst_format;
     void (*conv)(const uint8_t *src, uint8_t *dst, int num_pixels,
                  const uint8_t *palette) = NULL;
     int i;
@@ -599,7 +599,7 @@ static int palToRgbWrapper(SwsInternal *c, const uint8_t *const src[], const int
                av_get_pix_fmt_name(srcFormat), av_get_pix_fmt_name(dstFormat));
     else {
         for (i = 0; i < srcSliceH; i++) {
-            conv(srcPtr, dstPtr, c->srcW, (uint8_t *) c->pal_rgb);
+            conv(srcPtr, dstPtr, c->opts.src_w, (uint8_t *) c->pal_rgb);
             srcPtr += srcStride[0];
             dstPtr += dstStride[0];
         }
@@ -750,8 +750,8 @@ static int Rgb16ToPlanarRgb16Wrapper(SwsInternal *c, const uint8_t *const src[],
     uint16_t *dst1023[] = { (uint16_t *)dst[1], (uint16_t *)dst[0], (uint16_t *)dst[2], (uint16_t *)dst[3] };
     int stride2013[] = { dstStride[2], dstStride[0], dstStride[1], dstStride[3] };
     int stride1023[] = { dstStride[1], dstStride[0], dstStride[2], dstStride[3] };
-    const AVPixFmtDescriptor *src_format = av_pix_fmt_desc_get(c->srcFormat);
-    const AVPixFmtDescriptor *dst_format = av_pix_fmt_desc_get(c->dstFormat);
+    const AVPixFmtDescriptor *src_format = av_pix_fmt_desc_get(c->opts.src_format);
+    const AVPixFmtDescriptor *dst_format = av_pix_fmt_desc_get(c->opts.dst_format);
     int bpc = dst_format->comp[0].depth;
     int alpha = src_format->flags & AV_PIX_FMT_FLAG_ALPHA;
     int swap = 0;
@@ -776,14 +776,14 @@ static int Rgb16ToPlanarRgb16Wrapper(SwsInternal *c, const uint8_t *const src[],
         dst1023[i] += stride1023[i] * srcSliceY / 2;
     }
 
-    switch (c->srcFormat) {
+    switch (c->opts.src_format) {
     case AV_PIX_FMT_RGB48LE:
     case AV_PIX_FMT_RGB48BE:
     case AV_PIX_FMT_RGBA64LE:
     case AV_PIX_FMT_RGBA64BE:
         packed16togbra16(src[0], srcStride[0],
                          dst2013, stride2013, srcSliceH, alpha, swap,
-                         16 - bpc, c->srcW);
+                         16 - bpc, c->opts.src_w);
         break;
     case AV_PIX_FMT_BGR48LE:
     case AV_PIX_FMT_BGR48BE:
@@ -791,7 +791,7 @@ static int Rgb16ToPlanarRgb16Wrapper(SwsInternal *c, const uint8_t *const src[],
     case AV_PIX_FMT_BGRA64BE:
         packed16togbra16(src[0], srcStride[0],
                          dst1023, stride1023, srcSliceH, alpha, swap,
-                         16 - bpc, c->srcW);
+                         16 - bpc, c->opts.src_w);
         break;
     default:
         av_log(c, AV_LOG_ERROR,
@@ -929,8 +929,8 @@ static int planarRgb16ToRgb16Wrapper(SwsInternal *c, const uint8_t *const src[],
     const uint16_t *src201[] = { (uint16_t *)src[2], (uint16_t *)src[0], (uint16_t *)src[1], (uint16_t *)src[3] };
     int stride102[] = { srcStride[1], srcStride[0], srcStride[2], srcStride[3] };
     int stride201[] = { srcStride[2], srcStride[0], srcStride[1], srcStride[3] };
-    const AVPixFmtDescriptor *src_format = av_pix_fmt_desc_get(c->srcFormat);
-    const AVPixFmtDescriptor *dst_format = av_pix_fmt_desc_get(c->dstFormat);
+    const AVPixFmtDescriptor *src_format = av_pix_fmt_desc_get(c->opts.src_format);
+    const AVPixFmtDescriptor *dst_format = av_pix_fmt_desc_get(c->opts.dst_format);
     int bits_per_sample = src_format->comp[0].depth;
     int swap = 0;
     if ( HAVE_BIGENDIAN && !(src_format->flags & AV_PIX_FMT_FLAG_BE) ||
@@ -947,30 +947,30 @@ static int planarRgb16ToRgb16Wrapper(SwsInternal *c, const uint8_t *const src[],
                src_format->name, dst_format->name);
         return srcSliceH;
     }
-    switch (c->dstFormat) {
+    switch (c->opts.dst_format) {
     case AV_PIX_FMT_BGR48LE:
     case AV_PIX_FMT_BGR48BE:
         gbr16ptopacked16(src102, stride102,
                          dst[0] + srcSliceY * dstStride[0], dstStride[0],
-                         srcSliceH, 0, swap, bits_per_sample, c->srcW);
+                         srcSliceH, 0, swap, bits_per_sample, c->opts.src_w);
         break;
     case AV_PIX_FMT_RGB48LE:
     case AV_PIX_FMT_RGB48BE:
         gbr16ptopacked16(src201, stride201,
                          dst[0] + srcSliceY * dstStride[0], dstStride[0],
-                         srcSliceH, 0, swap, bits_per_sample, c->srcW);
+                         srcSliceH, 0, swap, bits_per_sample, c->opts.src_w);
         break;
     case AV_PIX_FMT_RGBA64LE:
     case AV_PIX_FMT_RGBA64BE:
          gbr16ptopacked16(src201, stride201,
                           dst[0] + srcSliceY * dstStride[0], dstStride[0],
-                          srcSliceH, 1, swap, bits_per_sample, c->srcW);
+                          srcSliceH, 1, swap, bits_per_sample, c->opts.src_w);
         break;
     case AV_PIX_FMT_BGRA64LE:
     case AV_PIX_FMT_BGRA64BE:
         gbr16ptopacked16(src102, stride102,
                          dst[0] + srcSliceY * dstStride[0], dstStride[0],
-                         srcSliceH, 1, swap, bits_per_sample, c->srcW);
+                         srcSliceH, 1, swap, bits_per_sample, c->opts.src_w);
         break;
     default:
         av_log(c, AV_LOG_ERROR,
@@ -1067,24 +1067,24 @@ static int planarRgbaToRgbWrapper(SwsInternal *c, const uint8_t *const src[],
     int stride102[] = { srcStride[1], srcStride[0], srcStride[2], srcStride[3] };
     int stride201[] = { srcStride[2], srcStride[0], srcStride[1], srcStride[3] };
 
-    if (c->srcFormat != AV_PIX_FMT_GBRAP) {
+    if (c->opts.src_format != AV_PIX_FMT_GBRAP) {
         av_log(c, AV_LOG_ERROR, "unsupported planar RGB conversion %s -> %s\n",
-               av_get_pix_fmt_name(c->srcFormat),
-               av_get_pix_fmt_name(c->dstFormat));
+               av_get_pix_fmt_name(c->opts.src_format),
+               av_get_pix_fmt_name(c->opts.dst_format));
         return srcSliceH;
     }
 
-    switch (c->dstFormat) {
+    switch (c->opts.dst_format) {
     case AV_PIX_FMT_BGR24:
         gbr24ptopacked24(src102, stride102,
                          dst[0] + srcSliceY * dstStride[0], dstStride[0],
-                         srcSliceH, c->srcW);
+                         srcSliceH, c->opts.src_w);
         break;
 
     case AV_PIX_FMT_RGB24:
         gbr24ptopacked24(src201, stride201,
                          dst[0] + srcSliceY * dstStride[0], dstStride[0],
-                         srcSliceH, c->srcW);
+                         srcSliceH, c->opts.src_w);
         break;
 
     case AV_PIX_FMT_ARGB:
@@ -1092,7 +1092,7 @@ static int planarRgbaToRgbWrapper(SwsInternal *c, const uint8_t *const src[],
     case AV_PIX_FMT_RGBA:
         gbraptopacked32(src201, stride201,
                         dst[0] + srcSliceY * dstStride[0], dstStride[0],
-                        srcSliceH, alpha_first, c->srcW);
+                        srcSliceH, alpha_first, c->opts.src_w);
         break;
 
     case AV_PIX_FMT_ABGR:
@@ -1100,14 +1100,14 @@ static int planarRgbaToRgbWrapper(SwsInternal *c, const uint8_t *const src[],
     case AV_PIX_FMT_BGRA:
         gbraptopacked32(src102, stride102,
                         dst[0] + srcSliceY * dstStride[0], dstStride[0],
-                        srcSliceH, alpha_first, c->srcW);
+                        srcSliceH, alpha_first, c->opts.src_w);
         break;
 
     default:
         av_log(c, AV_LOG_ERROR,
                "unsupported planar RGB conversion %s -> %s\n",
-               av_get_pix_fmt_name(c->srcFormat),
-               av_get_pix_fmt_name(c->dstFormat));
+               av_get_pix_fmt_name(c->opts.src_format),
+               av_get_pix_fmt_name(c->opts.dst_format));
     }
 
     return srcSliceH;
@@ -1123,24 +1123,24 @@ static int planarRgbToRgbWrapper(SwsInternal *c, const uint8_t *const src[],
     int stride102[] = { srcStride[1], srcStride[0], srcStride[2] };
     int stride201[] = { srcStride[2], srcStride[0], srcStride[1] };
 
-    if (c->srcFormat != AV_PIX_FMT_GBRP) {
+    if (c->opts.src_format != AV_PIX_FMT_GBRP) {
         av_log(c, AV_LOG_ERROR, "unsupported planar RGB conversion %s -> %s\n",
-               av_get_pix_fmt_name(c->srcFormat),
-               av_get_pix_fmt_name(c->dstFormat));
+               av_get_pix_fmt_name(c->opts.src_format),
+               av_get_pix_fmt_name(c->opts.dst_format));
         return srcSliceH;
     }
 
-    switch (c->dstFormat) {
+    switch (c->opts.dst_format) {
     case AV_PIX_FMT_BGR24:
         gbr24ptopacked24(src102, stride102,
                          dst[0] + srcSliceY * dstStride[0], dstStride[0],
-                         srcSliceH, c->srcW);
+                         srcSliceH, c->opts.src_w);
         break;
 
     case AV_PIX_FMT_RGB24:
         gbr24ptopacked24(src201, stride201,
                          dst[0] + srcSliceY * dstStride[0], dstStride[0],
-                         srcSliceH, c->srcW);
+                         srcSliceH, c->opts.src_w);
         break;
 
     case AV_PIX_FMT_ARGB:
@@ -1148,7 +1148,7 @@ static int planarRgbToRgbWrapper(SwsInternal *c, const uint8_t *const src[],
     case AV_PIX_FMT_RGBA:
         gbr24ptopacked32(src201, stride201,
                          dst[0] + srcSliceY * dstStride[0], dstStride[0],
-                         srcSliceH, alpha_first, c->srcW);
+                         srcSliceH, alpha_first, c->opts.src_w);
         break;
 
     case AV_PIX_FMT_ABGR:
@@ -1156,14 +1156,14 @@ static int planarRgbToRgbWrapper(SwsInternal *c, const uint8_t *const src[],
     case AV_PIX_FMT_BGRA:
         gbr24ptopacked32(src102, stride102,
                          dst[0] + srcSliceY * dstStride[0], dstStride[0],
-                         srcSliceH, alpha_first, c->srcW);
+                         srcSliceH, alpha_first, c->opts.src_w);
         break;
 
     default:
         av_log(c, AV_LOG_ERROR,
                "unsupported planar RGB conversion %s -> %s\n",
-               av_get_pix_fmt_name(c->srcFormat),
-               av_get_pix_fmt_name(c->dstFormat));
+               av_get_pix_fmt_name(c->opts.src_format),
+               av_get_pix_fmt_name(c->opts.dst_format));
     }
 
     return srcSliceH;
@@ -1174,14 +1174,14 @@ static int planarRgbToplanarRgbWrapper(SwsInternal *c,
                                        int srcSliceY, int srcSliceH,
                                        uint8_t *const dst[], const int dstStride[])
 {
-    ff_copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
+    ff_copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->opts.src_w,
                  dst[0], dstStride[0]);
-    ff_copyPlane(src[1], srcStride[1], srcSliceY, srcSliceH, c->srcW,
+    ff_copyPlane(src[1], srcStride[1], srcSliceY, srcSliceH, c->opts.src_w,
                  dst[1], dstStride[1]);
-    ff_copyPlane(src[2], srcStride[2], srcSliceY, srcSliceH, c->srcW,
+    ff_copyPlane(src[2], srcStride[2], srcSliceY, srcSliceH, c->opts.src_w,
                  dst[2], dstStride[2]);
     if (dst[3])
-        fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
+        fillPlane(dst[3], dstStride[3], c->opts.src_w, srcSliceH, srcSliceY, 255);
 
     return srcSliceH;
 }
@@ -1229,32 +1229,32 @@ static int rgbToPlanarRgbWrapper(SwsInternal *c, const uint8_t *const src[],
                           dst[0] + srcSliceY * dstStride[0],
                           dst[1] + srcSliceY * dstStride[1] };
 
-    switch (c->srcFormat) {
+    switch (c->opts.src_format) {
     case AV_PIX_FMT_RGB24:
         packedtogbr24p((const uint8_t *) src[0], srcStride[0], dst201,
-                       stride201, srcSliceH, alpha_first, 3, c->srcW);
+                       stride201, srcSliceH, alpha_first, 3, c->opts.src_w);
         break;
     case AV_PIX_FMT_BGR24:
         packedtogbr24p((const uint8_t *) src[0], srcStride[0], dst102,
-                       stride102, srcSliceH, alpha_first, 3, c->srcW);
+                       stride102, srcSliceH, alpha_first, 3, c->opts.src_w);
         break;
     case AV_PIX_FMT_ARGB:
         alpha_first = 1;
     case AV_PIX_FMT_RGBA:
         packedtogbr24p((const uint8_t *) src[0], srcStride[0], dst201,
-                       stride201, srcSliceH, alpha_first, 4, c->srcW);
+                       stride201, srcSliceH, alpha_first, 4, c->opts.src_w);
         break;
     case AV_PIX_FMT_ABGR:
         alpha_first = 1;
     case AV_PIX_FMT_BGRA:
         packedtogbr24p((const uint8_t *) src[0], srcStride[0], dst102,
-                       stride102, srcSliceH, alpha_first, 4, c->srcW);
+                       stride102, srcSliceH, alpha_first, 4, c->opts.src_w);
         break;
     default:
         av_log(c, AV_LOG_ERROR,
                "unsupported planar RGB conversion %s -> %s\n",
-               av_get_pix_fmt_name(c->srcFormat),
-               av_get_pix_fmt_name(c->dstFormat));
+               av_get_pix_fmt_name(c->opts.src_format),
+               av_get_pix_fmt_name(c->opts.dst_format));
     }
 
     return srcSliceH;
@@ -1330,7 +1330,7 @@ static int bayer_to_rgb24_wrapper(SwsInternal *c, const uint8_t *const src[],
     void (*copy)       (const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int width);
     void (*interpolate)(const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int width);
 
-    switch(c->srcFormat) {
+    switch(c->opts.src_format) {
 #define CASE(pixfmt, prefix) \
     case pixfmt: copy        = bayer_##prefix##_to_rgb24_copy; \
                  interpolate = bayer_##prefix##_to_rgb24_interpolate; \
@@ -1353,20 +1353,20 @@ static int bayer_to_rgb24_wrapper(SwsInternal *c, const uint8_t *const src[],
 
     av_assert0(srcSliceH > 1);
 
-    copy(srcPtr, srcStride[0], dstPtr, dstStride[0], c->srcW);
+    copy(srcPtr, srcStride[0], dstPtr, dstStride[0], c->opts.src_w);
     srcPtr += 2 * srcStride[0];
     dstPtr += 2 * dstStride[0];
 
     for (i = 2; i < srcSliceH - 2; i += 2) {
-        interpolate(srcPtr, srcStride[0], dstPtr, dstStride[0], c->srcW);
+        interpolate(srcPtr, srcStride[0], dstPtr, dstStride[0], c->opts.src_w);
         srcPtr += 2 * srcStride[0];
         dstPtr += 2 * dstStride[0];
     }
 
     if (i + 1 == srcSliceH) {
-        copy(srcPtr, -srcStride[0], dstPtr, -dstStride[0], c->srcW);
+        copy(srcPtr, -srcStride[0], dstPtr, -dstStride[0], c->opts.src_w);
     } else if (i < srcSliceH)
-        copy(srcPtr, srcStride[0], dstPtr, dstStride[0], c->srcW);
+        copy(srcPtr, srcStride[0], dstPtr, dstStride[0], c->opts.src_w);
     return srcSliceH;
 }
 
@@ -1380,7 +1380,7 @@ static int bayer_to_rgb48_wrapper(SwsInternal *c, const uint8_t *const src[],
     void (*copy)       (const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int width);
     void (*interpolate)(const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int width);
 
-    switch(c->srcFormat) {
+    switch(c->opts.src_format) {
 #define CASE(pixfmt, prefix) \
     case pixfmt: copy        = bayer_##prefix##_to_rgb48_copy; \
                  interpolate = bayer_##prefix##_to_rgb48_interpolate; \
@@ -1403,20 +1403,20 @@ static int bayer_to_rgb48_wrapper(SwsInternal *c, const uint8_t *const src[],
 
     av_assert0(srcSliceH > 1);
 
-    copy(srcPtr, srcStride[0], dstPtr, dstStride[0], c->srcW);
+    copy(srcPtr, srcStride[0], dstPtr, dstStride[0], c->opts.src_w);
     srcPtr += 2 * srcStride[0];
     dstPtr += 2 * dstStride[0];
 
     for (i = 2; i < srcSliceH - 2; i += 2) {
-        interpolate(srcPtr, srcStride[0], dstPtr, dstStride[0], c->srcW);
+        interpolate(srcPtr, srcStride[0], dstPtr, dstStride[0], c->opts.src_w);
         srcPtr += 2 * srcStride[0];
         dstPtr += 2 * dstStride[0];
     }
 
     if (i + 1 == srcSliceH) {
-        copy(srcPtr, -srcStride[0], dstPtr, -dstStride[0], c->srcW);
+        copy(srcPtr, -srcStride[0], dstPtr, -dstStride[0], c->opts.src_w);
     } else if (i < srcSliceH)
-        copy(srcPtr, srcStride[0], dstPtr, dstStride[0], c->srcW);
+        copy(srcPtr, srcStride[0], dstPtr, dstStride[0], c->opts.src_w);
     return srcSliceH;
 }
 
@@ -1432,7 +1432,7 @@ static int bayer_to_yv12_wrapper(SwsInternal *c, const uint8_t *const src[],
     void (*copy)       (const uint8_t *src, int src_stride, uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, int luma_stride, int width, const int32_t *rgb2yuv);
     void (*interpolate)(const uint8_t *src, int src_stride, uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, int luma_stride, int width, const int32_t *rgb2yuv);
 
-    switch(c->srcFormat) {
+    switch(c->opts.src_format) {
 #define CASE(pixfmt, prefix) \
     case pixfmt: copy        = bayer_##prefix##_to_yv12_copy; \
                  interpolate = bayer_##prefix##_to_yv12_interpolate; \
@@ -1455,14 +1455,14 @@ static int bayer_to_yv12_wrapper(SwsInternal *c, const uint8_t *const src[],
 
     av_assert0(srcSliceH > 1);
 
-    copy(srcPtr, srcStride[0], dstY, dstU, dstV, dstStride[0], c->srcW, c->input_rgb2yuv_table);
+    copy(srcPtr, srcStride[0], dstY, dstU, dstV, dstStride[0], c->opts.src_w, c->input_rgb2yuv_table);
     srcPtr += 2 * srcStride[0];
     dstY   += 2 * dstStride[0];
     dstU   +=     dstStride[1];
     dstV   +=     dstStride[1];
 
     for (i = 2; i < srcSliceH - 2; i += 2) {
-        interpolate(srcPtr, srcStride[0], dstY, dstU, dstV, dstStride[0], c->srcW, c->input_rgb2yuv_table);
+        interpolate(srcPtr, srcStride[0], dstY, dstU, dstV, dstStride[0], c->opts.src_w, c->input_rgb2yuv_table);
         srcPtr += 2 * srcStride[0];
         dstY   += 2 * dstStride[0];
         dstU   +=     dstStride[1];
@@ -1470,9 +1470,9 @@ static int bayer_to_yv12_wrapper(SwsInternal *c, const uint8_t *const src[],
     }
 
     if (i + 1 == srcSliceH) {
-        copy(srcPtr, -srcStride[0], dstY, dstU, dstV, -dstStride[0], c->srcW, c->input_rgb2yuv_table);
+        copy(srcPtr, -srcStride[0], dstY, dstU, dstV, -dstStride[0], c->opts.src_w, c->input_rgb2yuv_table);
     } else if (i < srcSliceH)
-        copy(srcPtr, srcStride[0], dstY, dstU, dstV, dstStride[0], c->srcW, c->input_rgb2yuv_table);
+        copy(srcPtr, srcStride[0], dstY, dstU, dstV, dstStride[0], c->opts.src_w, c->input_rgb2yuv_table);
     return srcSliceH;
 }
 
@@ -1501,8 +1501,8 @@ static int bayer_to_yv12_wrapper(SwsInternal *c, const uint8_t *const src[],
 typedef void (* rgbConvFn) (const uint8_t *, uint8_t *, int);
 static rgbConvFn findRgbConvFn(SwsInternal *c)
 {
-    const enum AVPixelFormat srcFormat = c->srcFormat;
-    const enum AVPixelFormat dstFormat = c->dstFormat;
+    const enum AVPixelFormat srcFormat = c->opts.src_format;
+    const enum AVPixelFormat dstFormat = c->opts.dst_format;
     const int srcId = c->srcFormatBpp;
     const int dstId = c->dstFormatBpp;
     rgbConvFn conv = NULL;
@@ -1614,7 +1614,7 @@ static rgbConvFn findRgbConvFn(SwsInternal *c)
         return NULL;
 
     // Maintain symmetry between endianness
-    if (c->flags & SWS_BITEXACT)
+    if (c->opts.flags & SWS_BITEXACT)
         if ((dstFormat == AV_PIX_FMT_RGB32   || dstFormat == AV_PIX_FMT_BGR32  ) && !isRGBA32(srcFormat) && ALT32_CORR>0)
             return NULL;
 
@@ -1627,10 +1627,10 @@ static int rgbToRgbWrapper(SwsInternal *c, const uint8_t *const src[], const int
                            const int dstStride[])
 
 {
-    const enum AVPixelFormat srcFormat = c->srcFormat;
-    const enum AVPixelFormat dstFormat = c->dstFormat;
-    const AVPixFmtDescriptor *desc_src = av_pix_fmt_desc_get(c->srcFormat);
-    const AVPixFmtDescriptor *desc_dst = av_pix_fmt_desc_get(c->dstFormat);
+    const enum AVPixelFormat srcFormat = c->opts.src_format;
+    const enum AVPixelFormat dstFormat = c->opts.dst_format;
+    const AVPixFmtDescriptor *desc_src = av_pix_fmt_desc_get(c->opts.src_format);
+    const AVPixFmtDescriptor *desc_dst = av_pix_fmt_desc_get(c->opts.dst_format);
     const int srcBpp = (c->srcFormatBpp + 7) >> 3;
     const int dstBpp = (c->dstFormatBpp + 7) >> 3;
     rgbConvFn conv = findRgbConvFn(c);
@@ -1660,20 +1660,20 @@ static int rgbToRgbWrapper(SwsInternal *c, const uint8_t *const src[], const int
         if (dstStride[0] * srcBpp == srcStride[0] * dstBpp && srcStride[0] > 0 &&
             !(srcStride[0] % srcBpp) && !dst_bswap && !src_bswap)
             conv(srcPtr, dstPtr + dstStride[0] * srcSliceY,
-                 (srcSliceH - 1) * srcStride[0] + c->srcW * srcBpp);
+                 (srcSliceH - 1) * srcStride[0] + c->opts.src_w * srcBpp);
         else {
             int i, j;
             dstPtr += dstStride[0] * srcSliceY;
 
             for (i = 0; i < srcSliceH; i++) {
                 if(src_bswap) {
-                    for(j=0; j<c->srcW; j++)
+                    for(j=0; j<c->opts.src_w; j++)
                         ((uint16_t*)c->formatConvBuffer)[j] = av_bswap16(((uint16_t*)srcPtr)[j]);
-                    conv(c->formatConvBuffer, dstPtr, c->srcW * srcBpp);
+                    conv(c->formatConvBuffer, dstPtr, c->opts.src_w * srcBpp);
                 }else
-                    conv(srcPtr, dstPtr, c->srcW * srcBpp);
+                    conv(srcPtr, dstPtr, c->opts.src_w * srcBpp);
                 if(dst_bswap)
-                    for(j=0; j<c->srcW; j++)
+                    for(j=0; j<c->opts.src_w; j++)
                         ((uint16_t*)dstPtr)[j] = av_bswap16(((uint16_t*)dstPtr)[j]);
                 srcPtr += srcStride[0];
                 dstPtr += dstStride[0];
@@ -1692,11 +1692,11 @@ static int bgr24ToYv12Wrapper(SwsInternal *c, const uint8_t *const src[],
         dst[0] +  srcSliceY       * dstStride[0],
         dst[1] + (srcSliceY >> 1) * dstStride[1],
         dst[2] + (srcSliceY >> 1) * dstStride[2],
-        c->srcW, srcSliceH,
+        c->opts.src_w, srcSliceH,
         dstStride[0], dstStride[1], srcStride[0],
         c->input_rgb2yuv_table);
     if (dst[3])
-        fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
+        fillPlane(dst[3], dstStride[3], c->opts.src_w, srcSliceH, srcSliceY, 255);
     return srcSliceH;
 }
 
@@ -1704,7 +1704,7 @@ static int yvu9ToYv12Wrapper(SwsInternal *c, const uint8_t *const src[],
                              const int srcStride[], int srcSliceY, int srcSliceH,
                              uint8_t *const dst[], const int dstStride[])
 {
-    ff_copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->srcW,
+    ff_copyPlane(src[0], srcStride[0], srcSliceY, srcSliceH, c->opts.src_w,
                  dst[0], dstStride[0]);
 
     planar2x(src[1], dst[1] + dstStride[1] * (srcSliceY >> 1), c->chrSrcW,
@@ -1712,7 +1712,7 @@ static int yvu9ToYv12Wrapper(SwsInternal *c, const uint8_t *const src[],
     planar2x(src[2], dst[2] + dstStride[2] * (srcSliceY >> 1), c->chrSrcW,
              srcSliceH >> 2, srcStride[2], dstStride[2]);
     if (dst[3])
-        fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);
+        fillPlane(dst[3], dstStride[3], c->opts.src_w, srcSliceH, srcSliceY, 255);
     return srcSliceH;
 }
 
@@ -1726,7 +1726,7 @@ static int uint_y_to_float_y_wrapper(SwsInternal *c, const uint8_t *const src[],
     float *dstPtr = (float *)(dst[0] + dstStride[0] * srcSliceY);
 
     for (y = 0; y < srcSliceH; ++y){
-        for (x = 0; x < c->srcW; ++x){
+        for (x = 0; x < c->opts.src_w; ++x){
             dstPtr[x] = c->uint2float_lut[srcPtr[x]];
         }
         srcPtr += srcStride[0];
@@ -1748,7 +1748,7 @@ static int float_y_to_uint_y_wrapper(SwsInternal *c,
     uint8_t *dstPtr = dst[0] + dstStride[0] * srcSliceY;
 
     for (y = 0; y < srcSliceH; ++y){
-        for (x = 0; x < c->srcW; ++x){
+        for (x = 0; x < c->opts.src_w; ++x){
             dstPtr[x] = av_clip_uint8(lrintf(255.0f * srcPtr[x]));
         }
         srcPtr += srcStrideFloat;
@@ -1772,9 +1772,9 @@ static int packedCopyWrapper(SwsInternal *c, const uint8_t *const src[],
         int length = 0;
 
         /* universal length finder */
-        while (length + c->srcW <= FFABS(dstStride[0]) &&
-               length + c->srcW <= FFABS(srcStride[0]))
-            length += c->srcW;
+        while (length + c->opts.src_w <= FFABS(dstStride[0]) &&
+               length + c->opts.src_w <= FFABS(srcStride[0]))
+            length += c->opts.src_w;
         av_assert1(length != 0);
 
         for (i = 0; i < srcSliceH; i++) {
@@ -1788,7 +1788,7 @@ static int packedCopyWrapper(SwsInternal *c, const uint8_t *const src[],
 
 #define DITHER_COPY(dst, dstStride, src, srcStride, bswap, dbswap)\
     unsigned shift= src_depth-dst_depth, tmp;\
-    if (c->dither == SWS_DITHER_NONE) {\
+    if (c->opts.dither == SWS_DITHER_NONE) {\
         for (i = 0; i < height; i++) {\
             for (j = 0; j < length-7; j+=8) {\
                 dst[j+0] = dbswap(bswap(src[j+0])>>shift);\
@@ -1850,31 +1850,31 @@ static int planarCopyWrapper(SwsInternal *c, const uint8_t *const src[],
                              const int srcStride[], int srcSliceY, int srcSliceH,
                              uint8_t *const dst[], const int dstStride[])
 {
-    const AVPixFmtDescriptor *desc_src = av_pix_fmt_desc_get(c->srcFormat);
-    const AVPixFmtDescriptor *desc_dst = av_pix_fmt_desc_get(c->dstFormat);
+    const AVPixFmtDescriptor *desc_src = av_pix_fmt_desc_get(c->opts.src_format);
+    const AVPixFmtDescriptor *desc_dst = av_pix_fmt_desc_get(c->opts.dst_format);
     int plane, i, j;
     for (plane = 0; plane < 4 && dst[plane] != NULL; plane++) {
-        int length = (plane == 0 || plane == 3) ? c->srcW  : AV_CEIL_RSHIFT(c->srcW,   c->chrDstHSubSample);
+        int length = (plane == 0 || plane == 3) ? c->opts.src_w  : AV_CEIL_RSHIFT(c->opts.src_w,   c->chrDstHSubSample);
         int y =      (plane == 0 || plane == 3) ? srcSliceY: AV_CEIL_RSHIFT(srcSliceY, c->chrDstVSubSample);
         int height = (plane == 0 || plane == 3) ? srcSliceH: AV_CEIL_RSHIFT(srcSliceH, c->chrDstVSubSample);
         const uint8_t *srcPtr = src[plane];
         uint8_t *dstPtr = dst[plane] + dstStride[plane] * y;
-        int shiftonly = plane == 1 || plane == 2 || (!c->srcRange && plane == 0);
+        int shiftonly = plane == 1 || plane == 2 || (!c->opts.src_range && plane == 0);
 
         // ignore palette for GRAY8
         if (plane == 1 && !dst[2]) continue;
         if (!src[plane] || (plane == 1 && !src[2])) {
-            if (is16BPS(c->dstFormat) || isNBPS(c->dstFormat)) {
+            if (is16BPS(c->opts.dst_format) || isNBPS(c->opts.dst_format)) {
                 fillPlane16(dst[plane], dstStride[plane], length, height, y,
                         plane == 3, desc_dst->comp[plane].depth,
-                        isBE(c->dstFormat));
+                        isBE(c->opts.dst_format));
             } else {
                 fillPlane(dst[plane], dstStride[plane], length, height, y,
                         (plane == 3) ? 255 : 128);
             }
         } else {
-            if(isNBPS(c->srcFormat) || isNBPS(c->dstFormat)
-               || (is16BPS(c->srcFormat) != is16BPS(c->dstFormat))
+            if(isNBPS(c->opts.src_format) || isNBPS(c->opts.dst_format)
+               || (is16BPS(c->opts.src_format) != is16BPS(c->opts.dst_format))
             ) {
                 const int src_depth = desc_src->comp[plane].depth;
                 const int dst_depth = desc_dst->comp[plane].depth;
@@ -1882,7 +1882,7 @@ static int planarCopyWrapper(SwsInternal *c, const uint8_t *const src[],
                 uint16_t *dstPtr2 = (uint16_t*)dstPtr;
 
                 if (dst_depth == 8) {
-                    if(isBE(c->srcFormat) == HAVE_BIGENDIAN){
+                    if(isBE(c->opts.src_format) == HAVE_BIGENDIAN){
                         DITHER_COPY(dstPtr, dstStride[plane], srcPtr2, srcStride[plane]/2, , )
                     } else {
                         DITHER_COPY(dstPtr, dstStride[plane], srcPtr2, srcStride[plane]/2, av_bswap16, )
@@ -1898,7 +1898,7 @@ static int planarCopyWrapper(SwsInternal *c, const uint8_t *const src[],
                                 w(&dstPtr2[j], (srcPtr[j]<<(dst_depth-8)) |\
                                                (srcPtr[j]>>(2*8-dst_depth)));\
                         }
-                        if(isBE(c->dstFormat)){
+                        if(isBE(c->opts.dst_format)){
                             COPY816(AV_WB16)
                         } else {
                             COPY816(AV_WL16)
@@ -1909,8 +1909,8 @@ static int planarCopyWrapper(SwsInternal *c, const uint8_t *const src[],
                 } else if (src_depth <= dst_depth) {
                     for (i = 0; i < height; i++) {
                         j = 0;
-                        if(isBE(c->srcFormat) == HAVE_BIGENDIAN &&
-                           isBE(c->dstFormat) == HAVE_BIGENDIAN &&
+                        if(isBE(c->opts.src_format) == HAVE_BIGENDIAN &&
+                           isBE(c->opts.dst_format) == HAVE_BIGENDIAN &&
                            shiftonly) {
                              unsigned shift = dst_depth - src_depth;
 #if HAVE_FAST_64BIT
@@ -1945,14 +1945,14 @@ static int planarCopyWrapper(SwsInternal *c, const uint8_t *const src[],
                         (v>>(2*src_depth-dst_depth)));\
         }\
     }
-                        if(isBE(c->srcFormat)){
-                            if(isBE(c->dstFormat)){
+                        if(isBE(c->opts.src_format)){
+                            if(isBE(c->opts.dst_format)){
                                 COPY_UP(AV_RB16, AV_WB16)
                             } else {
                                 COPY_UP(AV_RB16, AV_WL16)
                             }
                         } else {
-                            if(isBE(c->dstFormat)){
+                            if(isBE(c->opts.dst_format)){
                                 COPY_UP(AV_RL16, AV_WB16)
                             } else {
                                 COPY_UP(AV_RL16, AV_WL16)
@@ -1962,22 +1962,22 @@ static int planarCopyWrapper(SwsInternal *c, const uint8_t *const src[],
                         srcPtr2 += srcStride[plane]/2;
                     }
                 } else {
-                    if(isBE(c->srcFormat) == HAVE_BIGENDIAN){
-                        if(isBE(c->dstFormat) == HAVE_BIGENDIAN){
+                    if(isBE(c->opts.src_format) == HAVE_BIGENDIAN){
+                        if(isBE(c->opts.dst_format) == HAVE_BIGENDIAN){
                             DITHER_COPY(dstPtr2, dstStride[plane]/2, srcPtr2, srcStride[plane]/2, , )
                         } else {
                             DITHER_COPY(dstPtr2, dstStride[plane]/2, srcPtr2, srcStride[plane]/2, , av_bswap16)
                         }
                     }else{
-                        if(isBE(c->dstFormat) == HAVE_BIGENDIAN){
+                        if(isBE(c->opts.dst_format) == HAVE_BIGENDIAN){
                             DITHER_COPY(dstPtr2, dstStride[plane]/2, srcPtr2, srcStride[plane]/2, av_bswap16, )
                         } else {
                             DITHER_COPY(dstPtr2, dstStride[plane]/2, srcPtr2, srcStride[plane]/2, av_bswap16, av_bswap16)
                         }
                     }
                 }
-            } else if (is16BPS(c->srcFormat) && is16BPS(c->dstFormat) &&
-                      isBE(c->srcFormat) != isBE(c->dstFormat)) {
+            } else if (is16BPS(c->opts.src_format) && is16BPS(c->opts.dst_format) &&
+                      isBE(c->opts.src_format) != isBE(c->opts.dst_format)) {
 
                 for (i = 0; i < height; i++) {
                     for (j = 0; j < length; j++)
@@ -1985,8 +1985,8 @@ static int planarCopyWrapper(SwsInternal *c, const uint8_t *const src[],
                     srcPtr += srcStride[plane];
                     dstPtr += dstStride[plane];
                 }
-            } else if (isFloat(c->srcFormat) && isFloat(c->dstFormat) &&
-                       isBE(c->srcFormat) != isBE(c->dstFormat)) { /* swap float plane */
+            } else if (isFloat(c->opts.src_format) && isFloat(c->opts.dst_format) &&
+                       isBE(c->opts.src_format) != isBE(c->opts.dst_format)) { /* swap float plane */
                 for (i = 0; i < height; i++) {
                     for (j = 0; j < length; j++)
                         ((uint32_t *) dstPtr)[j] = av_bswap32(((const uint32_t *) srcPtr)[j]);
@@ -1998,7 +1998,7 @@ static int planarCopyWrapper(SwsInternal *c, const uint8_t *const src[],
                 memcpy(dst[plane] + dstStride[plane] * y, src[plane],
                        height * dstStride[plane]);
             } else {
-                if (is16BPS(c->srcFormat) && is16BPS(c->dstFormat))
+                if (is16BPS(c->opts.src_format) && is16BPS(c->opts.dst_format))
                     length *= 2;
                 else if (desc_src->comp[0].depth == 1)
                     length >>= 3; // monowhite/black
@@ -2021,11 +2021,11 @@ static int planarCopyWrapper(SwsInternal *c, const uint8_t *const src[],
 
 void ff_get_unscaled_swscale(SwsInternal *c)
 {
-    const enum AVPixelFormat srcFormat = c->srcFormat;
-    const enum AVPixelFormat dstFormat = c->dstFormat;
-    const int flags = c->flags;
-    const int dstH = c->dstH;
-    const int dstW = c->dstW;
+    const enum AVPixelFormat srcFormat = c->opts.src_format;
+    const enum AVPixelFormat dstFormat = c->opts.dst_format;
+    const int flags = c->opts.flags;
+    const int dstH = c->opts.dst_h;
+    const int dstW = c->opts.dst_w;
     int needsDither;
 
     needsDither = isAnyRGB(dstFormat) &&
@@ -2055,7 +2055,7 @@ void ff_get_unscaled_swscale(SwsInternal *c)
     /* yuv2bgr */
     if ((srcFormat == AV_PIX_FMT_YUV420P || srcFormat == AV_PIX_FMT_YUV422P ||
          srcFormat == AV_PIX_FMT_YUVA420P) && isAnyRGB(dstFormat) &&
-        !(flags & SWS_ACCURATE_RND) && (c->dither == SWS_DITHER_BAYER || c->dither == SWS_DITHER_AUTO) && !(dstH & 1)) {
+        !(flags & SWS_ACCURATE_RND) && (c->opts.dither == SWS_DITHER_BAYER || c->opts.dither == SWS_DITHER_AUTO) && !(dstH & 1)) {
         c->convert_unscaled = ff_yuv2rgb_get_func_ptr(c);
         c->dst_slice_align = 2;
     }
@@ -2088,7 +2088,7 @@ void ff_get_unscaled_swscale(SwsInternal *c)
 
     /* RGB/BGR -> RGB/BGR (no dither needed forms) */
     if (isAnyRGB(srcFormat) && isAnyRGB(dstFormat) && findRgbConvFn(c)
-        && (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT))))
+        && (!needsDither || (c->opts.flags&(SWS_FAST_BILINEAR|SWS_POINT))))
         c->convert_unscaled = rgbToRgbWrapper;
 
     /* RGB to planar RGB */
@@ -2235,7 +2235,7 @@ void ff_get_unscaled_swscale(SwsInternal *c)
     }
 
     /* LQ converters if -sws 0 or -sws 4*/
-    if (c->flags&(SWS_FAST_BILINEAR|SWS_POINT)) {
+    if (c->opts.flags&(SWS_FAST_BILINEAR|SWS_POINT)) {
         /* yv12_to_yuy2 */
         if (srcFormat == AV_PIX_FMT_YUV420P || srcFormat == AV_PIX_FMT_YUVA420P) {
             if (dstFormat == AV_PIX_FMT_YUYV422)
@@ -2271,7 +2271,7 @@ void ff_get_unscaled_swscale(SwsInternal *c)
          c->chrDstVSubSample == c->chrSrcVSubSample &&
          !isSemiPlanarYUV(srcFormat) && !isSemiPlanarYUV(dstFormat))))
     {
-        if (isPacked(c->srcFormat))
+        if (isPacked(c->opts.src_format))
             c->convert_unscaled = packedCopyWrapper;
         else /* Planar YUV or gray */
             c->convert_unscaled = planarCopyWrapper;
diff --git a/libswscale/utils.c b/libswscale/utils.c
index 87591bdabd..4bddcb43d8 100644
--- a/libswscale/utils.c
+++ b/libswscale/utils.c
@@ -296,17 +296,17 @@ static SwsContext *alloc_set_opts(int srcW, int srcH, enum AVPixelFormat srcForm
     if (!c)
         return NULL;
 
-    c->flags     = flags;
-    c->srcW      = srcW;
-    c->srcH      = srcH;
-    c->dstW      = dstW;
-    c->dstH      = dstH;
-    c->srcFormat = srcFormat;
-    c->dstFormat = dstFormat;
+    c->opts.flags = flags;
+    c->opts.src_w = srcW;
+    c->opts.src_h = srcH;
+    c->opts.dst_w = dstW;
+    c->opts.dst_h      = dstH;
+    c->opts.src_format = srcFormat;
+    c->opts.dst_format = dstFormat;
 
     if (param) {
-        c->param[0] = param[0];
-        c->param[1] = param[1];
+        c->opts.scaler_params[0] = param[0];
+        c->opts.scaler_params[1] = param[1];
     }
 
     return sws;
@@ -1028,10 +1028,10 @@ static int handle_xyz(enum AVPixelFormat *format)
 
 static void handle_formats(SwsInternal *c)
 {
-    c->src0Alpha |= handle_0alpha(&c->srcFormat);
-    c->dst0Alpha |= handle_0alpha(&c->dstFormat);
-    c->srcXYZ    |= handle_xyz(&c->srcFormat);
-    c->dstXYZ    |= handle_xyz(&c->dstFormat);
+    c->src0Alpha |= handle_0alpha(&c->opts.src_format);
+    c->dst0Alpha |= handle_0alpha(&c->opts.dst_format);
+    c->srcXYZ    |= handle_xyz(&c->opts.src_format);
+    c->dstXYZ    |= handle_xyz(&c->opts.dst_format);
     if (c->srcXYZ || c->dstXYZ)
         fill_xyztables(c);
 }
@@ -1064,16 +1064,16 @@ int sws_setColorspaceDetails(SwsContext *sws, const int inv_table[4],
     }
 
     handle_formats(c);
-    desc_dst = av_pix_fmt_desc_get(c->dstFormat);
-    desc_src = av_pix_fmt_desc_get(c->srcFormat);
+    desc_dst = av_pix_fmt_desc_get(c->opts.dst_format);
+    desc_src = av_pix_fmt_desc_get(c->opts.src_format);
 
-    if(range_override_needed(c->dstFormat))
+    if(range_override_needed(c->opts.dst_format))
         dstRange = 0;
-    if(range_override_needed(c->srcFormat))
+    if(range_override_needed(c->opts.src_format))
         srcRange = 0;
 
-    if (c->srcRange != srcRange ||
-        c->dstRange != dstRange ||
+    if (c->opts.src_range != srcRange ||
+        c->opts.dst_range != dstRange ||
         c->brightness != brightness ||
         c->contrast   != contrast ||
         c->saturation != saturation ||
@@ -1090,8 +1090,8 @@ int sws_setColorspaceDetails(SwsContext *sws, const int inv_table[4],
     c->brightness = brightness;
     c->contrast   = contrast;
     c->saturation = saturation;
-    c->srcRange   = srcRange;
-    c->dstRange   = dstRange;
+    c->opts.src_range   = srcRange;
+    c->opts.dst_range   = dstRange;
 
     if (need_reinit) {
         ff_sws_init_range_convert(c);
@@ -1113,27 +1113,27 @@ int sws_setColorspaceDetails(SwsContext *sws, const int inv_table[4],
     if (!need_reinit)
         return 0;
 
-    if ((isYUV(c->dstFormat) || isGray(c->dstFormat)) && (isYUV(c->srcFormat) || isGray(c->srcFormat))) {
+    if ((isYUV(c->opts.dst_format) || isGray(c->opts.dst_format)) && (isYUV(c->opts.src_format) || isGray(c->opts.src_format))) {
         if (!c->cascaded_context[0] &&
             memcmp(c->dstColorspaceTable, c->srcColorspaceTable, sizeof(int) * 4) &&
-            c->srcW && c->srcH && c->dstW && c->dstH) {
+            c->opts.src_w && c->opts.src_h && c->opts.dst_w && c->opts.dst_h) {
             enum AVPixelFormat tmp_format;
             int tmp_width, tmp_height;
-            int srcW = c->srcW;
-            int srcH = c->srcH;
-            int dstW = c->dstW;
-            int dstH = c->dstH;
+            int srcW = c->opts.src_w;
+            int srcH = c->opts.src_h;
+            int dstW = c->opts.dst_w;
+            int dstH = c->opts.dst_h;
             int ret;
             av_log(c, AV_LOG_VERBOSE, "YUV color matrix differs for YUV->YUV, using intermediate RGB to convert\n");
 
-            if (isNBPS(c->dstFormat) || is16BPS(c->dstFormat)) {
-                if (isALPHA(c->srcFormat) && isALPHA(c->dstFormat)) {
+            if (isNBPS(c->opts.dst_format) || is16BPS(c->opts.dst_format)) {
+                if (isALPHA(c->opts.src_format) && isALPHA(c->opts.dst_format)) {
                     tmp_format = AV_PIX_FMT_BGRA64;
                 } else {
                     tmp_format = AV_PIX_FMT_BGR48;
                 }
             } else {
-                if (isALPHA(c->srcFormat) && isALPHA(c->dstFormat)) {
+                if (isALPHA(c->opts.src_format) && isALPHA(c->opts.dst_format)) {
                     tmp_format = AV_PIX_FMT_BGRA;
                 } else {
                     tmp_format = AV_PIX_FMT_BGR24;
@@ -1153,13 +1153,14 @@ int sws_setColorspaceDetails(SwsContext *sws, const int inv_table[4],
             if (ret < 0)
                 return ret;
 
-            c->cascaded_context[0] = alloc_set_opts(srcW, srcH, c->srcFormat,
+            c->cascaded_context[0] = alloc_set_opts(srcW, srcH, c->opts.src_format,
                                                     tmp_width, tmp_height, tmp_format,
-                                                    c->flags, c->param);
+                                                    c->opts.flags,
+                                                    c->opts.scaler_params);
             if (!c->cascaded_context[0])
                 return -1;
 
-            sws_internal(c->cascaded_context[0])->alphablend = c->alphablend;
+            sws_internal(c->cascaded_context[0])->opts.alpha_blend = c->opts.alpha_blend;
             ret = sws_init_context(c->cascaded_context[0], NULL , NULL);
             if (ret < 0)
                 return ret;
@@ -1169,12 +1170,13 @@ int sws_setColorspaceDetails(SwsContext *sws, const int inv_table[4],
                                      brightness, contrast, saturation);
 
             c->cascaded_context[1] = alloc_set_opts(tmp_width, tmp_height, tmp_format,
-                                                    dstW, dstH, c->dstFormat,
-                                                    c->flags, c->param);
+                                                    dstW, dstH, c->opts.dst_format,
+                                                    c->opts.flags,
+                                                    c->opts.scaler_params);
             if (!c->cascaded_context[1])
                 return -1;
-            sws_internal(c->cascaded_context[1])->srcRange = srcRange;
-            sws_internal(c->cascaded_context[1])->dstRange = dstRange;
+            sws_internal(c->cascaded_context[1])->opts.src_range = srcRange;
+            sws_internal(c->cascaded_context[1])->opts.dst_range = dstRange;
             ret = sws_init_context(c->cascaded_context[1], NULL , NULL);
             if (ret < 0)
                 return ret;
@@ -1189,7 +1191,7 @@ int sws_setColorspaceDetails(SwsContext *sws, const int inv_table[4],
         return 0;
     }
 
-    if (!isYUV(c->dstFormat) && !isGray(c->dstFormat)) {
+    if (!isYUV(c->opts.dst_format) && !isGray(c->opts.dst_format)) {
         ff_yuv2rgb_c_init_tables(c, inv_table, srcRange, brightness,
                                  contrast, saturation);
         // FIXME factorize
@@ -1221,8 +1223,8 @@ int sws_getColorspaceDetails(SwsContext *sws, int **inv_table,
 
     *inv_table  = c->srcColorspaceTable;
     *table      = c->dstColorspaceTable;
-    *srcRange   = range_override_needed(c->srcFormat) ? 1 : c->srcRange;
-    *dstRange   = range_override_needed(c->dstFormat) ? 1 : c->dstRange;
+    *srcRange   = range_override_needed(c->opts.src_format) ? 1 : c->opts.src_range;
+    *dstRange   = range_override_needed(c->opts.dst_format) ? 1 : c->opts.dst_range;
     *brightness = c->brightness;
     *contrast   = c->contrast;
     *saturation = c->saturation;
@@ -1235,7 +1237,7 @@ SwsContext *sws_alloc_context(void)
     SwsInternal *c = av_mallocz(sizeof(SwsInternal));
 
     if (c) {
-        c->av_class = &ff_sws_context_class;
+        c->opts.av_class = &ff_sws_context_class;
         av_opt_set_defaults(c);
         atomic_init(&c->stride_unaligned_warned, 0);
         atomic_init(&c->data_unaligned_warned,   0);
@@ -1327,10 +1329,10 @@ static av_cold int sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter
     int unscaled;
     SwsInternal *c        = sws_internal(sws);
     SwsFilter dummyFilter = { NULL, NULL, NULL, NULL };
-    int srcW              = c->srcW;
-    int srcH              = c->srcH;
-    int dstW              = c->dstW;
-    int dstH              = c->dstH;
+    int srcW              = c->opts.src_w;
+    int srcH              = c->opts.src_h;
+    int dstW              = c->opts.dst_w;
+    int dstH              = c->opts.dst_h;
     int dst_stride        = FFALIGN(dstW * sizeof(int16_t) + 66, 16);
     int flags, cpu_flags;
     enum AVPixelFormat srcFormat, dstFormat;
@@ -1341,25 +1343,25 @@ static av_cold int sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter
     static const float float_mult = 1.0f / 255.0f;
 
     cpu_flags = av_get_cpu_flags();
-    flags     = c->flags;
+    flags     = c->opts.flags;
     emms_c();
 
     unscaled = (srcW == dstW && srcH == dstH);
 
     if (!c->contrast && !c->saturation && !c->dstFormatBpp)
-        sws_setColorspaceDetails(sws, ff_yuv2rgb_coeffs[SWS_CS_DEFAULT], c->srcRange,
+        sws_setColorspaceDetails(sws, ff_yuv2rgb_coeffs[SWS_CS_DEFAULT], c->opts.src_range,
                                  ff_yuv2rgb_coeffs[SWS_CS_DEFAULT],
-                                 c->dstRange, 0, 1 << 16, 1 << 16);
+                                 c->opts.dst_range, 0, 1 << 16, 1 << 16);
 
     handle_formats(c);
-    srcFormat = c->srcFormat;
-    dstFormat = c->dstFormat;
+    srcFormat = c->opts.src_format;
+    dstFormat = c->opts.dst_format;
     desc_src = av_pix_fmt_desc_get(srcFormat);
     desc_dst = av_pix_fmt_desc_get(dstFormat);
 
     // If the source has no alpha then disable alpha blendaway
     if (c->src0Alpha)
-        c->alphablend = SWS_ALPHA_BLEND_NONE;
+        c->opts.alpha_blend = SWS_ALPHA_BLEND_NONE;
 
     if (!(unscaled && sws_isSupportedEndiannessConversion(srcFormat) &&
           av_pix_fmt_swap_endianness(srcFormat) == dstFormat)) {
@@ -1396,7 +1398,7 @@ static av_cold int sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter
             flags |= SWS_BICUBIC;
         else
             flags |= SWS_BICUBIC;
-        c->flags = flags;
+        c->opts.flags = flags;
     } else if (i & (i - 1)) {
         av_log(c, AV_LOG_ERROR,
                "Exactly one scaler algorithm must be chosen, got %X\n", i);
@@ -1413,7 +1415,7 @@ static av_cold int sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter
     if (flags & SWS_FAST_BILINEAR) {
         if (srcW < 8 || dstW < 8) {
             flags ^= SWS_FAST_BILINEAR | SWS_BILINEAR;
-            c->flags = flags;
+            c->opts.flags = flags;
         }
     }
 
@@ -1446,46 +1448,46 @@ static av_cold int sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter
         if (dstW&1) {
             av_log(c, AV_LOG_DEBUG, "Forcing full internal H chroma due to odd output size\n");
             flags |= SWS_FULL_CHR_H_INT;
-            c->flags = flags;
+            c->opts.flags = flags;
         }
 
         if (   c->chrSrcHSubSample == 0
             && c->chrSrcVSubSample == 0
-            && c->dither != SWS_DITHER_BAYER //SWS_FULL_CHR_H_INT is currently not supported with SWS_DITHER_BAYER
-            && !(c->flags & SWS_FAST_BILINEAR)
+            && c->opts.dither != SWS_DITHER_BAYER //SWS_FULL_CHR_H_INT is currently not supported with SWS_DITHER_BAYER
+            && !(c->opts.flags & SWS_FAST_BILINEAR)
         ) {
             av_log(c, AV_LOG_DEBUG, "Forcing full internal H chroma due to input having non subsampled chroma\n");
             flags |= SWS_FULL_CHR_H_INT;
-            c->flags = flags;
+            c->opts.flags = flags;
         }
     }
 
-    if (c->dither == SWS_DITHER_AUTO) {
+    if (c->opts.dither == SWS_DITHER_AUTO) {
         if (flags & SWS_ERROR_DIFFUSION)
-            c->dither = SWS_DITHER_ED;
+            c->opts.dither = SWS_DITHER_ED;
     }
 
     if(dstFormat == AV_PIX_FMT_BGR4_BYTE ||
        dstFormat == AV_PIX_FMT_RGB4_BYTE ||
        dstFormat == AV_PIX_FMT_BGR8 ||
        dstFormat == AV_PIX_FMT_RGB8) {
-        if (c->dither == SWS_DITHER_AUTO)
-            c->dither = (flags & SWS_FULL_CHR_H_INT) ? SWS_DITHER_ED : SWS_DITHER_BAYER;
+        if (c->opts.dither == SWS_DITHER_AUTO)
+            c->opts.dither = (flags & SWS_FULL_CHR_H_INT) ? SWS_DITHER_ED : SWS_DITHER_BAYER;
         if (!(flags & SWS_FULL_CHR_H_INT)) {
-            if (c->dither == SWS_DITHER_ED || c->dither == SWS_DITHER_A_DITHER || c->dither == SWS_DITHER_X_DITHER || c->dither == SWS_DITHER_NONE) {
+            if (c->opts.dither == SWS_DITHER_ED || c->opts.dither == SWS_DITHER_A_DITHER || c->opts.dither == SWS_DITHER_X_DITHER || c->opts.dither == SWS_DITHER_NONE) {
                 av_log(c, AV_LOG_DEBUG,
                     "Desired dithering only supported in full chroma interpolation for destination format '%s'\n",
                     av_get_pix_fmt_name(dstFormat));
                 flags   |= SWS_FULL_CHR_H_INT;
-                c->flags = flags;
+                c->opts.flags = flags;
             }
         }
         if (flags & SWS_FULL_CHR_H_INT) {
-            if (c->dither == SWS_DITHER_BAYER) {
+            if (c->opts.dither == SWS_DITHER_BAYER) {
                 av_log(c, AV_LOG_DEBUG,
                     "Ordered dither is not supported in full chroma interpolation for destination format '%s'\n",
                     av_get_pix_fmt_name(dstFormat));
-                c->dither = SWS_DITHER_ED;
+                c->opts.dither = SWS_DITHER_ED;
             }
         }
     }
@@ -1495,7 +1497,7 @@ static av_cold int sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter
                    "%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;
+            c->opts.flags = flags;
         }
     }
 
@@ -1527,7 +1529,7 @@ static av_cold int sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter
                "full chroma interpolation for destination format '%s' not yet implemented\n",
                av_get_pix_fmt_name(dstFormat));
         flags   &= ~SWS_FULL_CHR_H_INT;
-        c->flags = flags;
+        c->opts.flags = flags;
     }
     if (isAnyRGB(dstFormat) && !(flags & SWS_FULL_CHR_H_INT))
         c->chrDstHSubSample = 1;
@@ -1589,7 +1591,7 @@ static av_cold int sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter
                 av_log(c, AV_LOG_INFO,
                        "output width is not a multiple of 32 -> no MMXEXT scaler\n");
         }
-        if (usesHFilter || isNBPS(c->srcFormat) || is16BPS(c->srcFormat) || isAnyRGB(c->srcFormat))
+        if (usesHFilter || isNBPS(c->opts.src_format) || is16BPS(c->opts.src_format) || isAnyRGB(c->opts.src_format))
             c->canMMXEXTBeUsed = 0;
     } else
         c->canMMXEXTBeUsed = 0;
@@ -1621,7 +1623,7 @@ static av_cold int sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter
     tmpFmt = AV_PIX_FMT_RGBA64LE;
 
 
-    if (!unscaled && c->gamma_flag && (srcFormat != tmpFmt || dstFormat != tmpFmt)) {
+    if (!unscaled && c->opts.gamma_flag && (srcFormat != tmpFmt || dstFormat != tmpFmt)) {
         SwsInternal *c2;
         c->cascaded_context[0] = NULL;
 
@@ -1632,14 +1634,16 @@ static av_cold int sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter
 
         c->cascaded_context[0] = sws_getContext(srcW, srcH, srcFormat,
                                                 srcW, srcH, tmpFmt,
-                                                flags, NULL, NULL, c->param);
+                                                flags, NULL, NULL,
+                                                c->opts.scaler_params);
         if (!c->cascaded_context[0]) {
             return AVERROR(ENOMEM);
         }
 
         c->cascaded_context[1] = sws_getContext(srcW, srcH, tmpFmt,
                                                 dstW, dstH, tmpFmt,
-                                                flags, srcFilter, dstFilter, c->param);
+                                                flags, srcFilter, dstFilter,
+                                                c->opts.scaler_params);
 
         if (!c->cascaded_context[1])
             return AVERROR(ENOMEM);
@@ -1669,8 +1673,9 @@ static av_cold int sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter
                 return ret;
 
             c->cascaded_context[2] = sws_getContext(dstW, dstH, tmpFmt,
-                                                dstW, dstH, dstFormat,
-                                                flags, NULL, NULL, c->param);
+                                                    dstW, dstH, dstFormat,
+                                                    flags, NULL, NULL,
+                                                    c->opts.scaler_params);
             if (!c->cascaded_context[2])
                 return AVERROR(ENOMEM);
         }
@@ -1690,13 +1695,15 @@ static av_cold int sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter
 
             c->cascaded_context[0] = sws_getContext(srcW, srcH, srcFormat,
                                                     srcW, srcH, tmpFormat,
-                                                    flags, srcFilter, NULL, c->param);
+                                                    flags, srcFilter, NULL,
+                                                    c->opts.scaler_params);
             if (!c->cascaded_context[0])
                 return AVERROR(ENOMEM);
 
             c->cascaded_context[1] = sws_getContext(srcW, srcH, tmpFormat,
                                                     dstW, dstH, dstFormat,
-                                                    flags, NULL, dstFilter, c->param);
+                                                    flags, NULL, dstFilter,
+                                                    c->opts.scaler_params);
             if (!c->cascaded_context[1])
                 return AVERROR(ENOMEM);
             return 0;
@@ -1719,11 +1726,11 @@ static av_cold int sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter
     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 (tmpFormat != AV_PIX_FMT_NONE && c->opts.alpha_blend != SWS_ALPHA_BLEND_NONE) {
             if (!unscaled ||
                 dstFormat != tmpFormat ||
                 usesHFilter || usesVFilter ||
-                c->srcRange != c->dstRange
+                c->opts.src_range != c->opts.dst_range
             ) {
                 c->cascaded_mainindex = 1;
                 ret = av_image_alloc(c->cascaded_tmp[0], c->cascaded_tmpStride[0],
@@ -1733,22 +1740,22 @@ static av_cold int sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter
 
                 c->cascaded_context[0] = alloc_set_opts(srcW, srcH, srcFormat,
                                                         srcW, srcH, tmpFormat,
-                                                        flags, c->param);
+                                                        flags, c->opts.scaler_params);
                 if (!c->cascaded_context[0])
                     return AVERROR(EINVAL);
-                sws_internal(c->cascaded_context[0])->alphablend = c->alphablend;
+                sws_internal(c->cascaded_context[0])->opts.alpha_blend = c->opts.alpha_blend;
                 ret = sws_init_context(c->cascaded_context[0], NULL , NULL);
                 if (ret < 0)
                     return ret;
 
                 c->cascaded_context[1] = alloc_set_opts(srcW, srcH, tmpFormat,
                                                         dstW, dstH, dstFormat,
-                                                        flags, c->param);
+                                                        flags, c->opts.scaler_params);
                 if (!c->cascaded_context[1])
                     return AVERROR(EINVAL);
 
-                sws_internal(c->cascaded_context[1])->srcRange = c->srcRange;
-                sws_internal(c->cascaded_context[1])->dstRange = c->dstRange;
+                sws_internal(c->cascaded_context[1])->opts.src_range = c->opts.src_range;
+                sws_internal(c->cascaded_context[1])->opts.dst_range = c->opts.dst_range;
                 ret = sws_init_context(c->cascaded_context[1], srcFilter , dstFilter);
                 if (ret < 0)
                     return ret;
@@ -1760,9 +1767,9 @@ static av_cold int sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter
 
     /* alpha blend special case, note this has been split via cascaded contexts if its scaled */
     if (unscaled && !usesHFilter && !usesVFilter &&
-        c->alphablend != SWS_ALPHA_BLEND_NONE &&
+        c->opts.alpha_blend != SWS_ALPHA_BLEND_NONE &&
         isALPHA(srcFormat) &&
-        (c->srcRange == c->dstRange || isAnyRGB(dstFormat)) &&
+        (c->opts.src_range == c->opts.dst_range || isAnyRGB(dstFormat)) &&
         alphaless_fmt(srcFormat) == dstFormat
     ) {
         c->convert_unscaled = ff_sws_alphablendaway;
@@ -1776,7 +1783,7 @@ static av_cold int sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter
 
     /* unscaled special cases */
     if (unscaled && !usesHFilter && !usesVFilter &&
-        (c->srcRange == c->dstRange || isAnyRGB(dstFormat) ||
+        (c->opts.src_range == c->opts.dst_range || isAnyRGB(dstFormat) ||
          isFloat(srcFormat) || isFloat(dstFormat) || isBayer(srcFormat))){
 
         ff_get_unscaled_swscale(c);
@@ -1872,7 +1879,7 @@ static av_cold int sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter
                            srcW, dstW, filterAlign, 1 << 14,
                            (flags & SWS_BICUBLIN) ? (flags | SWS_BICUBIC) : flags,
                            cpu_flags, srcFilter->lumH, dstFilter->lumH,
-                           c->param,
+                           c->opts.scaler_params,
                            get_local_pos(c, 0, 0, 0),
                            get_local_pos(c, 0, 0, 0))) < 0)
                 goto fail;
@@ -1883,9 +1890,9 @@ static av_cold int sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter
                            c->chrSrcW, c->chrDstW, filterAlign, 1 << 14,
                            (flags & SWS_BICUBLIN) ? (flags | SWS_BILINEAR) : flags,
                            cpu_flags, srcFilter->chrH, dstFilter->chrH,
-                           c->param,
-                           get_local_pos(c, c->chrSrcHSubSample, c->src_h_chr_pos, 0),
-                           get_local_pos(c, c->chrDstHSubSample, c->dst_h_chr_pos, 0))) < 0)
+                           c->opts.scaler_params,
+                           get_local_pos(c, c->chrSrcHSubSample, c->opts.src_h_chr_pos, 0),
+                           get_local_pos(c, c->chrDstHSubSample, c->opts.dst_h_chr_pos, 0))) < 0)
                 goto fail;
             if (ff_shuffle_filter_coefficients(c, c->hChrFilterPos, c->hChrFilterSize, c->hChrFilter, c->chrDstW) < 0)
                 goto nomem;
@@ -1902,7 +1909,7 @@ static av_cold int sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter
                        c->lumYInc, srcH, dstH, filterAlign, (1 << 12),
                        (flags & SWS_BICUBLIN) ? (flags | SWS_BICUBIC) : flags,
                        cpu_flags, srcFilter->lumV, dstFilter->lumV,
-                       c->param,
+                       c->opts.scaler_params,
                        get_local_pos(c, 0, 0, 1),
                        get_local_pos(c, 0, 0, 1))) < 0)
             goto fail;
@@ -1911,18 +1918,18 @@ static av_cold int sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter
                        filterAlign, (1 << 12),
                        (flags & SWS_BICUBLIN) ? (flags | SWS_BILINEAR) : flags,
                        cpu_flags, srcFilter->chrV, dstFilter->chrV,
-                       c->param,
-                       get_local_pos(c, c->chrSrcVSubSample, c->src_v_chr_pos, 1),
-                       get_local_pos(c, c->chrDstVSubSample, c->dst_v_chr_pos, 1))) < 0)
+                       c->opts.scaler_params,
+                       get_local_pos(c, c->chrSrcVSubSample, c->opts.src_v_chr_pos, 1),
+                       get_local_pos(c, c->chrDstVSubSample, c->opts.dst_v_chr_pos, 1))) < 0)
 
             goto fail;
 
 #if HAVE_ALTIVEC
-        if (!FF_ALLOC_TYPED_ARRAY(c->vYCoeffsBank, c->vLumFilterSize * c->dstH) ||
+        if (!FF_ALLOC_TYPED_ARRAY(c->vYCoeffsBank, c->vLumFilterSize * c->opts.dst_h) ||
             !FF_ALLOC_TYPED_ARRAY(c->vCCoeffsBank, c->vChrFilterSize * c->chrDstH))
             goto nomem;
 
-        for (i = 0; i < c->vLumFilterSize * c->dstH; i++) {
+        for (i = 0; i < c->vLumFilterSize * c->opts.dst_h; i++) {
             int j;
             short *p = (short *)&c->vYCoeffsBank[i];
             for (j = 0; j < 8; j++)
@@ -1939,10 +1946,10 @@ static av_cold int sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter
     }
 
     for (i = 0; i < 4; i++)
-        if (!FF_ALLOCZ_TYPED_ARRAY(c->dither_error[i], c->dstW + 3))
+        if (!FF_ALLOCZ_TYPED_ARRAY(c->dither_error[i], c->opts.dst_w + 3))
             goto nomem;
 
-    c->needAlpha = (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat) && isALPHA(c->dstFormat)) ? 1 : 0;
+    c->needAlpha = (CONFIG_SWSCALE_ALPHA && isALPHA(c->opts.src_format) && isALPHA(c->opts.dst_format)) ? 1 : 0;
 
     // 64 / c->scalingBpp is the same as 16 / sizeof(scaling_intermediate)
     c->uv_off   = (dst_stride>>1) + 64 / (c->dstBpc &~ 7);
@@ -1984,7 +1991,7 @@ static av_cold int sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter
         av_log(c, AV_LOG_VERBOSE, "%dx%d -> %dx%d\n", srcW, srcH, dstW, dstH);
         av_log(c, AV_LOG_DEBUG,
                "lum srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d\n",
-               c->srcW, c->srcH, c->dstW, c->dstH, c->lumXInc, c->lumYInc);
+               c->opts.src_w, c->opts.src_h, c->opts.dst_w, c->opts.dst_h, c->lumXInc, c->lumYInc);
         av_log(c, AV_LOG_DEBUG,
                "chr srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d\n",
                c->chrSrcW, c->chrSrcH, c->chrDstW, c->chrDstH,
@@ -2015,13 +2022,15 @@ fail: // FIXME replace things by appropriate error codes
 
         c->cascaded_context[0] = sws_getContext(srcW, srcH, srcFormat,
                                                 tmpW, tmpH, tmpFormat,
-                                                flags, srcFilter, NULL, c->param);
+                                                flags, srcFilter, NULL,
+                                                c->opts.scaler_params);
         if (!c->cascaded_context[0])
             return AVERROR(ENOMEM);
 
         c->cascaded_context[1] = sws_getContext(tmpW, tmpH, tmpFormat,
                                                 dstW, dstH, dstFormat,
-                                                flags, NULL, dstFilter, c->param);
+                                                flags, NULL, dstFilter,
+                                                c->opts.scaler_params);
         if (!c->cascaded_context[1])
             return AVERROR(ENOMEM);
         return 0;
@@ -2036,21 +2045,21 @@ static int context_init_threaded(SwsContext *sws,
     int ret;
 
     ret = avpriv_slicethread_create(&c->slicethread, (void*) sws,
-                                    ff_sws_slice_worker, NULL, c->nb_threads);
+                                    ff_sws_slice_worker, NULL, c->opts.threads);
     if (ret == AVERROR(ENOSYS)) {
-        c->nb_threads = 1;
+        c->opts.threads = 1;
         return 0;
     } else if (ret < 0)
         return ret;
 
-    c->nb_threads = ret;
+    c->opts.threads = ret;
 
-    c->slice_ctx = av_calloc(c->nb_threads, sizeof(*c->slice_ctx));
-    c->slice_err = av_calloc(c->nb_threads, sizeof(*c->slice_err));
+    c->slice_ctx = av_calloc(c->opts.threads, sizeof(*c->slice_ctx));
+    c->slice_err = av_calloc(c->opts.threads, sizeof(*c->slice_err));
     if (!c->slice_ctx || !c->slice_err)
         return AVERROR(ENOMEM);
 
-    for (int i = 0; i < c->nb_threads; i++) {
+    for (int i = 0; i < c->opts.threads; i++) {
         SwsInternal *c2;
         c->slice_ctx[i] = sws_alloc_context();
         if (!c->slice_ctx[i])
@@ -2064,13 +2073,13 @@ static int context_init_threaded(SwsContext *sws,
         if (ret < 0)
             return ret;
 
-        c2->nb_threads = 1;
+        c2->opts.threads = 1;
 
         ret = sws_init_single_context(c->slice_ctx[i], src_filter, dst_filter);
         if (ret < 0)
             return ret;
 
-        if (c2->dither == SWS_DITHER_ED) {
+        if (c2->opts.dither == SWS_DITHER_ED) {
             av_log(c, AV_LOG_VERBOSE,
                    "Error-diffusion dither is in use, scaling will be single-threaded.");
             break;
@@ -2096,17 +2105,17 @@ av_cold int sws_init_context(SwsContext *sws, SwsFilter *srcFilter,
     if (ff_thread_once(&rgb2rgb_once, ff_sws_rgb2rgb_init) != 0)
         return AVERROR_UNKNOWN;
 
-    src_format = c->srcFormat;
-    dst_format = c->dstFormat;
-    c->srcRange |= handle_jpeg(&c->srcFormat);
-    c->dstRange |= handle_jpeg(&c->dstFormat);
+    src_format = c->opts.src_format;
+    dst_format = c->opts.dst_format;
+    c->opts.src_range |= handle_jpeg(&c->opts.src_format);
+    c->opts.dst_range |= handle_jpeg(&c->opts.dst_format);
 
-    if (src_format != c->srcFormat || dst_format != c->dstFormat)
+    if (src_format != c->opts.src_format || dst_format != c->opts.dst_format)
         av_log(c, AV_LOG_WARNING, "deprecated pixel format used, make sure you did set range correctly\n");
 
-    if (c->nb_threads != 1) {
+    if (c->opts.threads != 1) {
         ret = context_init_threaded(sws, srcFilter, dstFilter);
-        if (ret < 0 || c->nb_threads > 1)
+        if (ret < 0 || c->opts.threads > 1)
             return ret;
         // threading disabled in this build, init as single-threaded
     }
@@ -2550,15 +2559,15 @@ SwsContext *sws_getCachedContext(SwsContext *sws, int srcW,
         param = default_param;
 
     if ((context = sws_internal(sws)) &&
-        (context->srcW      != srcW      ||
-         context->srcH      != srcH      ||
-         context->srcFormat != srcFormat ||
-         context->dstW      != dstW      ||
-         context->dstH      != dstH      ||
-         context->dstFormat != dstFormat ||
-         context->flags     != flags     ||
-         context->param[0]  != param[0]  ||
-         context->param[1]  != param[1])) {
+        (context->opts.src_w      != srcW      ||
+         context->opts.src_h      != srcH      ||
+         context->opts.src_format != srcFormat ||
+         context->opts.dst_w      != dstW      ||
+         context->opts.dst_h      != dstH      ||
+         context->opts.dst_format != dstFormat ||
+         context->opts.flags      != flags     ||
+         context->opts.scaler_params[0]  != param[0]  ||
+         context->opts.scaler_params[1]  != param[1])) {
 
         av_opt_get_int(context, "src_h_chr_pos", 0, &src_h_chr_pos);
         av_opt_get_int(context, "src_v_chr_pos", 0, &src_v_chr_pos);
@@ -2572,15 +2581,15 @@ SwsContext *sws_getCachedContext(SwsContext *sws, int srcW,
         if (!(sws = sws_alloc_context()))
             return NULL;
         context            = sws_internal(sws);
-        context->srcW      = srcW;
-        context->srcH      = srcH;
-        context->srcFormat = srcFormat;
-        context->dstW      = dstW;
-        context->dstH      = dstH;
-        context->dstFormat = dstFormat;
-        context->flags     = flags;
-        context->param[0]  = param[0];
-        context->param[1]  = param[1];
+        context->opts.src_w      = srcW;
+        context->opts.src_h      = srcH;
+        context->opts.src_format = srcFormat;
+        context->opts.dst_w      = dstW;
+        context->opts.dst_h      = dstH;
+        context->opts.dst_format = dstFormat;
+        context->opts.flags      = flags;
+        context->opts.scaler_params[0]  = param[0];
+        context->opts.scaler_params[1]  = param[1];
 
         av_opt_set_int(context, "src_h_chr_pos", src_h_chr_pos, 0);
         av_opt_set_int(context, "src_v_chr_pos", src_v_chr_pos, 0);
diff --git a/libswscale/vscale.c b/libswscale/vscale.c
index 9b700ec58e..e972bd70e2 100644
--- a/libswscale/vscale.c
+++ b/libswscale/vscale.c
@@ -93,7 +93,7 @@ static int chr_planar_vscale(SwsInternal *c, SwsFilterDescriptor *desc, int slic
         uint16_t *filter = inst->filter[0] + (inst->isMMX ? 0 : chrSliceY * inst->filter_size);
 
         if (c->yuv2nv12cX) {
-            inst->pfn.yuv2interleavedX(c->dstFormat, c->chrDither8, filter, inst->filter_size, (const int16_t**)src1, (const int16_t**)src2, dst1[0], dstW);
+            inst->pfn.yuv2interleavedX(c->opts.dst_format, c->chrDither8, filter, inst->filter_size, (const int16_t**)src1, (const int16_t**)src2, dst1[0], dstW);
         } else if (inst->filter_size == 1) {
             inst->pfn.yuv2planar1((const int16_t*)src1[0], dst1[0], dstW, c->chrDither8, 0);
             inst->pfn.yuv2planar1((const int16_t*)src2[0], dst2[0], dstW, c->chrDither8, 3);
@@ -216,7 +216,7 @@ int ff_init_vscale(SwsInternal *c, SwsFilterDescriptor *desc, SwsSlice *src, Sws
     VScalerContext *lumCtx = NULL;
     VScalerContext *chrCtx = NULL;
 
-    if (isPlanarYUV(c->dstFormat) || (isGray(c->dstFormat) && !isALPHA(c->dstFormat))) {
+    if (isPlanarYUV(c->opts.dst_format) || (isGray(c->opts.dst_format) && !isALPHA(c->opts.dst_format))) {
         lumCtx = av_mallocz(sizeof(VScalerContext));
         if (!lumCtx)
             return AVERROR(ENOMEM);
@@ -228,7 +228,7 @@ int ff_init_vscale(SwsInternal *c, SwsFilterDescriptor *desc, SwsSlice *src, Sws
         desc[0].dst = dst;
         desc[0].alpha = c->needAlpha;
 
-        if (!isGray(c->dstFormat)) {
+        if (!isGray(c->opts.dst_format)) {
             chrCtx = av_mallocz(sizeof(VScalerContext));
             if (!chrCtx)
                 return AVERROR(ENOMEM);
@@ -268,8 +268,8 @@ void ff_init_vscale_pfn(SwsInternal *c,
     VScalerContext *chrCtx = NULL;
     int idx = c->numDesc - (c->is_internal_gamma ? 2 : 1); //FIXME avoid hardcoding indexes
 
-    if (isPlanarYUV(c->dstFormat) || (isGray(c->dstFormat) && !isALPHA(c->dstFormat))) {
-        if (!isGray(c->dstFormat)) {
+    if (isPlanarYUV(c->opts.dst_format) || (isGray(c->opts.dst_format) && !isALPHA(c->opts.dst_format))) {
+        if (!isGray(c->opts.dst_format)) {
             chrCtx = c->desc[idx].instance;
 
             chrCtx->filter[0] = use_mmx ? (int16_t*)c->chrMmxFilter : c->vChrFilter;
diff --git a/libswscale/x86/output.asm b/libswscale/x86/output.asm
index 0f854e521d..dec1d27f9a 100644
--- a/libswscale/x86/output.asm
+++ b/libswscale/x86/output.asm
@@ -582,7 +582,7 @@ yuv2nv12cX_fn yuv2nv21
 
 %if ARCH_X86_64
 struc SwsInternal
-    .padding:           resb 40292 ; offsetof(SwsInternal, yuv2rgb_y_offset)
+    .padding:           resb 40316 ; offsetof(SwsInternal, yuv2rgb_y_offset)
     .yuv2rgb_y_offset:  resd 1
     .yuv2rgb_y_coeff:   resd 1
     .yuv2rgb_v2r_coeff: resd 1
diff --git a/libswscale/x86/swscale.c b/libswscale/x86/swscale.c
index 48f0aea3f2..a7a5315ed5 100644
--- a/libswscale/x86/swscale.c
+++ b/libswscale/x86/swscale.c
@@ -63,8 +63,8 @@ DECLARE_ASM_ALIGNED(8, const uint64_t, ff_w1111)        = 0x0001000100010001ULL;
 
 void ff_updateMMXDitherTables(SwsInternal *c, int dstY)
 {
-    const int dstH= c->dstH;
-    const int flags= c->flags;
+    const int dstH= c->opts.dst_h;
+    const int flags= c->opts.flags;
 
     SwsPlane *lumPlane = &c->slice[c->numSlice-2].plane[0];
     SwsPlane *chrUPlane = &c->slice[c->numSlice-2].plane[1];
@@ -85,7 +85,7 @@ void ff_updateMMXDitherTables(SwsInternal *c, int dstY)
     const int firstChrSrcY= vChrFilterPos[chrDstY]; //First line needed as input
 
     c->blueDither= ff_dither8[dstY&1];
-    if (c->dstFormat == AV_PIX_FMT_RGB555 || c->dstFormat == AV_PIX_FMT_BGR555)
+    if (c->opts.dst_format == AV_PIX_FMT_RGB555 || c->opts.dst_format == AV_PIX_FMT_BGR555)
         c->greenDither= ff_dither8[dstY&1];
     else
         c->greenDither= ff_dither4[dstY&1];
@@ -96,10 +96,10 @@ void ff_updateMMXDitherTables(SwsInternal *c, int dstY)
         const int16_t **alpSrcPtr  = (CONFIG_SWSCALE_ALPHA && hasAlpha) ? (const int16_t **)(void*) alpPlane->line + firstLumSrcY - alpPlane->sliceY : NULL;
 
         int i;
-        if (firstLumSrcY < 0 || firstLumSrcY + vLumFilterSize > c->srcH) {
+        if (firstLumSrcY < 0 || firstLumSrcY + vLumFilterSize > c->opts.src_h) {
             const int16_t **tmpY = (const int16_t **) lumPlane->tmp;
 
-            int neg = -firstLumSrcY, i, end = FFMIN(c->srcH - firstLumSrcY, vLumFilterSize);
+            int neg = -firstLumSrcY, i, end = FFMIN(c->opts.src_h - firstLumSrcY, vLumFilterSize);
             for (i = 0; i < neg;            i++)
                 tmpY[i] = lumSrcPtr[neg];
             for (     ; i < end;            i++)
@@ -453,7 +453,7 @@ INPUT_PLANAR_RGB_A_ALL_DECL(avx2);
 
 #define RANGE_CONVERT_FUNCS(opt) do {                                       \
     if (c->dstBpc <= 14) {                                                  \
-        if (c->srcRange) {                                                  \
+        if (c->opts.src_range) {                                            \
             c->lumConvertRange = ff_lumRangeFromJpeg_ ##opt;                \
             c->chrConvertRange = ff_chrRangeFromJpeg_ ##opt;                \
         } else {                                                            \
@@ -474,7 +474,7 @@ RANGE_CONVERT_FUNCS_DECL(avx2);
 
 av_cold void ff_sws_init_range_convert_x86(SwsInternal *c)
 {
-    if (c->srcRange != c->dstRange && !isAnyRGB(c->dstFormat)) {
+    if (c->opts.src_range != c->opts.dst_range && !isAnyRGB(c->opts.dst_format)) {
         int cpu_flags = av_get_cpu_flags();
         if (EXTERNAL_AVX2_FAST(cpu_flags)) {
             RANGE_CONVERT_FUNCS(avx2);
@@ -492,7 +492,7 @@ av_cold void ff_sws_init_swscale_x86(SwsInternal *c)
     if (INLINE_MMXEXT(cpu_flags))
         sws_init_swscale_mmxext(c);
 #endif
-    if(c->use_mmx_vfilter && !(c->flags & SWS_ACCURATE_RND)) {
+    if(c->use_mmx_vfilter && !(c->opts.flags & SWS_ACCURATE_RND)) {
 #if HAVE_MMXEXT_EXTERNAL
         if (EXTERNAL_MMXEXT(cpu_flags))
             c->yuv2planeX = yuv2yuvX_mmxext;
@@ -528,7 +528,7 @@ av_cold void ff_sws_init_swscale_x86(SwsInternal *c)
     } else if (c->srcBpc == 12) { \
         hscalefn = c->dstBpc <= 14 ? ff_hscale12to15_ ## filtersize ## _ ## opt2 : \
                                      ff_hscale12to19_ ## filtersize ## _ ## opt1; \
-    } else if (c->srcBpc == 14 || ((c->srcFormat==AV_PIX_FMT_PAL8||isAnyRGB(c->srcFormat)) && av_pix_fmt_desc_get(c->srcFormat)->comp[0].depth<16)) { \
+    } else if (c->srcBpc == 14 || ((c->opts.src_format==AV_PIX_FMT_PAL8||isAnyRGB(c->opts.src_format)) && av_pix_fmt_desc_get(c->opts.src_format)->comp[0].depth<16)) { \
         hscalefn = c->dstBpc <= 14 ? ff_hscale14to15_ ## filtersize ## _ ## opt2 : \
                                      ff_hscale14to19_ ## filtersize ## _ ## opt1; \
     } else { /* c->srcBpc == 16 */ \
@@ -540,15 +540,15 @@ av_cold void ff_sws_init_swscale_x86(SwsInternal *c)
 #define ASSIGN_VSCALEX_FUNC(vscalefn, opt, do_16_case, condition_8bit) \
 switch(c->dstBpc){ \
     case 16:                          do_16_case;                          break; \
-    case 10: if (!isBE(c->dstFormat) && !isSemiPlanarYUV(c->dstFormat)) vscalefn = ff_yuv2planeX_10_ ## opt; break; \
-    case 9:  if (!isBE(c->dstFormat)) vscalefn = ff_yuv2planeX_9_  ## opt; break; \
+    case 10: if (!isBE(c->opts.dst_format) && !isSemiPlanarYUV(c->opts.dst_format)) vscalefn = ff_yuv2planeX_10_ ## opt; break; \
+    case 9:  if (!isBE(c->opts.dst_format)) vscalefn = ff_yuv2planeX_9_  ## opt; break; \
     case 8: if ((condition_8bit) && !c->use_mmx_vfilter) vscalefn = ff_yuv2planeX_8_  ## opt; break; \
     }
 #define ASSIGN_VSCALE_FUNC(vscalefn, opt) \
     switch(c->dstBpc){ \
-    case 16: if (!isBE(c->dstFormat)) vscalefn = ff_yuv2plane1_16_ ## opt; break; \
-    case 10: if (!isBE(c->dstFormat) && !isSemiPlanarYUV(c->dstFormat)) vscalefn = ff_yuv2plane1_10_ ## opt; break; \
-    case 9:  if (!isBE(c->dstFormat)) vscalefn = ff_yuv2plane1_9_  ## opt;  break; \
+    case 16: if (!isBE(c->opts.dst_format)) vscalefn = ff_yuv2plane1_16_ ## opt; break; \
+    case 10: if (!isBE(c->opts.dst_format) && !isSemiPlanarYUV(c->opts.dst_format)) vscalefn = ff_yuv2plane1_10_ ## opt; break; \
+    case 9:  if (!isBE(c->opts.dst_format)) vscalefn = ff_yuv2plane1_9_  ## opt;  break; \
     case 8:                           vscalefn = ff_yuv2plane1_8_  ## opt;  break; \
     default: av_assert0(c->dstBpc>8); \
     }
@@ -571,10 +571,10 @@ switch(c->dstBpc){ \
         ASSIGN_SSE_SCALE_FUNC(c->hcScale, c->hChrFilterSize, sse2, sse2);
         ASSIGN_VSCALEX_FUNC(c->yuv2planeX, sse2, ,
                             HAVE_ALIGNED_STACK || ARCH_X86_64);
-        if (!(c->flags & SWS_ACCURATE_RND))
+        if (!(c->opts.flags & SWS_ACCURATE_RND))
             ASSIGN_VSCALE_FUNC(c->yuv2plane1, sse2);
 
-        switch (c->srcFormat) {
+        switch (c->opts.src_format) {
         case AV_PIX_FMT_YA8:
             c->lumToYV12 = ff_yuyvToY_sse2;
             if (c->needAlpha)
@@ -607,7 +607,7 @@ switch(c->dstBpc){ \
     if (EXTERNAL_SSSE3(cpu_flags)) {
         ASSIGN_SSE_SCALE_FUNC(c->hyScale, c->hLumFilterSize, ssse3, ssse3);
         ASSIGN_SSE_SCALE_FUNC(c->hcScale, c->hChrFilterSize, ssse3, ssse3);
-        switch (c->srcFormat) {
+        switch (c->opts.src_format) {
         case_rgb(rgb24, RGB24, ssse3);
         case_rgb(bgr24, BGR24, ssse3);
         default:
@@ -619,19 +619,19 @@ switch(c->dstBpc){ \
         ASSIGN_SSE_SCALE_FUNC(c->hyScale, c->hLumFilterSize, sse4, ssse3);
         ASSIGN_SSE_SCALE_FUNC(c->hcScale, c->hChrFilterSize, sse4, ssse3);
         ASSIGN_VSCALEX_FUNC(c->yuv2planeX, sse4,
-                            if (!isBE(c->dstFormat)) c->yuv2planeX = ff_yuv2planeX_16_sse4,
+                            if (!isBE(c->opts.dst_format)) c->yuv2planeX = ff_yuv2planeX_16_sse4,
                             HAVE_ALIGNED_STACK || ARCH_X86_64);
-        if (c->dstBpc == 16 && !isBE(c->dstFormat) && !(c->flags & SWS_ACCURATE_RND))
+        if (c->dstBpc == 16 && !isBE(c->opts.dst_format) && !(c->opts.flags & SWS_ACCURATE_RND))
             c->yuv2plane1 = ff_yuv2plane1_16_sse4;
     }
 
     if (EXTERNAL_AVX(cpu_flags)) {
         ASSIGN_VSCALEX_FUNC(c->yuv2planeX, avx, ,
                             HAVE_ALIGNED_STACK || ARCH_X86_64);
-        if (!(c->flags & SWS_ACCURATE_RND))
+        if (!(c->opts.flags & SWS_ACCURATE_RND))
             ASSIGN_VSCALE_FUNC(c->yuv2plane1, avx);
 
-        switch (c->srcFormat) {
+        switch (c->opts.src_format) {
         case AV_PIX_FMT_YUYV422:
             c->chrToYV12 = ff_yuyvToUV_avx;
             break;
@@ -672,7 +672,7 @@ switch(c->dstBpc){ \
 
     if (EXTERNAL_AVX2_FAST(cpu_flags)) {
         if (ARCH_X86_64)
-            switch (c->srcFormat) {
+            switch (c->opts.src_format) {
             case_rgb(rgb24, RGB24, avx2);
             case_rgb(bgr24, BGR24, avx2);
             case_rgb(bgra,  BGRA,  avx2);
@@ -680,7 +680,7 @@ switch(c->dstBpc){ \
             case_rgb(abgr,  ABGR,  avx2);
             case_rgb(argb,  ARGB,  avx2);
             }
-        switch (c->dstFormat) {
+        switch (c->opts.dst_format) {
         case AV_PIX_FMT_NV12:
         case AV_PIX_FMT_NV24:
             c->yuv2nv12cX = ff_yuv2nv12cX_avx2;
@@ -753,7 +753,7 @@ switch(c->dstBpc){ \
 
 
     if (EXTERNAL_SSE2(cpu_flags)) {
-        switch (c->srcFormat) {
+        switch (c->opts.src_format) {
         INPUT_PLANER_RGB_A_FUNC_CASE_NOBREAK(AV_PIX_FMT_GBRAP,                         rgb, sse2);
         INPUT_PLANER_RGB_UV_FUNC_CASE(     AV_PIX_FMT_GBRP,                            rgb, sse2);
         INPUT_PLANER_RGBXX_UV_FUNC_CASE(   AV_PIX_FMT_GBRP9,                          rgb9, sse2);
@@ -768,7 +768,7 @@ switch(c->dstBpc){ \
     }
 
     if (EXTERNAL_SSE4(cpu_flags)) {
-        switch (c->srcFormat) {
+        switch (c->opts.src_format) {
         case AV_PIX_FMT_GBRAP:
         INPUT_PLANER_RGB_YUV_FUNC_CASE(    AV_PIX_FMT_GBRP,                            rgb, sse4);
         INPUT_PLANER_RGBXX_YUV_FUNC_CASE(  AV_PIX_FMT_GBRP9,                          rgb9, sse4);
@@ -783,14 +783,14 @@ switch(c->dstBpc){ \
     }
 
     if (EXTERNAL_AVX2_FAST(cpu_flags)) {
-        switch (c->srcFormat) {
+        switch (c->opts.src_format) {
         INPUT_PLANER_RGB_YUVA_ALL_CASES(avx2)
         default:
             break;
         }
     }
 
-    if(c->flags & SWS_FULL_CHR_H_INT) {
+    if(c->opts.flags & SWS_FULL_CHR_H_INT) {
 
 #define YUV2ANYX_FUNC_CASE(fmt, name, opt)              \
         case fmt:                                       \
@@ -822,7 +822,7 @@ switch(c->dstBpc){ \
         YUV2ANYX_FUNC_CASE(AV_PIX_FMT_GBRAPF32BE, gbrapf32be, opt)
 
         if (EXTERNAL_SSE2(cpu_flags)) {
-            switch (c->dstFormat) {
+            switch (c->opts.dst_format) {
             YUV2ANYX_GBRAP_CASES(sse2)
             default:
                 break;
@@ -830,7 +830,7 @@ switch(c->dstBpc){ \
         }
 
         if (EXTERNAL_SSE4(cpu_flags)) {
-            switch (c->dstFormat) {
+            switch (c->opts.dst_format) {
             YUV2ANYX_GBRAP_CASES(sse4)
             default:
                 break;
@@ -838,7 +838,7 @@ switch(c->dstBpc){ \
         }
 
         if (EXTERNAL_AVX2_FAST(cpu_flags)) {
-            switch (c->dstFormat) {
+            switch (c->opts.dst_format) {
             YUV2ANYX_GBRAP_CASES(avx2)
             default:
                 break;
diff --git a/libswscale/x86/swscale_template.c b/libswscale/x86/swscale_template.c
index cffafccb24..e09310ab91 100644
--- a/libswscale/x86/swscale_template.c
+++ b/libswscale/x86/swscale_template.c
@@ -1384,15 +1384,15 @@ static void RENAME(yuv2yuyv422_1)(SwsInternal *c, const int16_t *buf0,
 }
 static av_cold void RENAME(sws_init_swscale)(SwsInternal *c)
 {
-    enum AVPixelFormat dstFormat = c->dstFormat;
+    enum AVPixelFormat dstFormat = c->opts.dst_format;
 
     c->use_mmx_vfilter= 0;
     if (!is16BPS(dstFormat) && !isNBPS(dstFormat) && !isSemiPlanarYUV(dstFormat)
         && dstFormat != AV_PIX_FMT_GRAYF32BE && dstFormat != AV_PIX_FMT_GRAYF32LE
-        && !(c->flags & SWS_BITEXACT)) {
-            if (c->flags & SWS_ACCURATE_RND) {
-                if (!(c->flags & SWS_FULL_CHR_H_INT)) {
-                    switch (c->dstFormat) {
+        && !(c->opts.flags & SWS_BITEXACT)) {
+            if (c->opts.flags & SWS_ACCURATE_RND) {
+                if (!(c->opts.flags & SWS_FULL_CHR_H_INT)) {
+                    switch (c->opts.dst_format) {
                     case AV_PIX_FMT_RGB32:   c->yuv2packedX = RENAME(yuv2rgb32_X_ar);   break;
 #if HAVE_6REGS
                     case AV_PIX_FMT_BGR24:   c->yuv2packedX = RENAME(yuv2bgr24_X_ar);   break;
@@ -1405,8 +1405,8 @@ static av_cold void RENAME(sws_init_swscale)(SwsInternal *c)
                 }
             } else {
                 c->use_mmx_vfilter= 1;
-                if (!(c->flags & SWS_FULL_CHR_H_INT)) {
-                    switch (c->dstFormat) {
+                if (!(c->opts.flags & SWS_FULL_CHR_H_INT)) {
+                    switch (c->opts.dst_format) {
                     case AV_PIX_FMT_RGB32:   c->yuv2packedX = RENAME(yuv2rgb32_X);   break;
                     case AV_PIX_FMT_BGR32:   c->yuv2packedX = RENAME(yuv2bgr32_X);   break;
 #if HAVE_6REGS
@@ -1419,8 +1419,8 @@ static av_cold void RENAME(sws_init_swscale)(SwsInternal *c)
                     }
                 }
             }
-        if (!(c->flags & SWS_FULL_CHR_H_INT)) {
-            switch (c->dstFormat) {
+        if (!(c->opts.flags & SWS_FULL_CHR_H_INT)) {
+            switch (c->opts.dst_format) {
             case AV_PIX_FMT_RGB32:
                 c->yuv2packed1 = RENAME(yuv2rgb32_1);
                 c->yuv2packed2 = RENAME(yuv2rgb32_2);
@@ -1449,7 +1449,7 @@ static av_cold void RENAME(sws_init_swscale)(SwsInternal *c)
 
     if (c->srcBpc == 8 && c->dstBpc <= 14) {
         // Use the new MMX scaler if the MMXEXT one can't be used (it is faster than the x86 ASM one).
-        if (c->flags & SWS_FAST_BILINEAR && c->canMMXEXTBeUsed) {
+        if (c->opts.flags & SWS_FAST_BILINEAR && c->canMMXEXTBeUsed) {
             c->hyscale_fast = ff_hyscale_fast_mmxext;
             c->hcscale_fast = ff_hcscale_fast_mmxext;
         } else {
diff --git a/libswscale/x86/yuv2rgb.c b/libswscale/x86/yuv2rgb.c
index 93a6b9a6e2..a1463867a2 100644
--- a/libswscale/x86/yuv2rgb.c
+++ b/libswscale/x86/yuv2rgb.c
@@ -41,11 +41,11 @@
 #if HAVE_X86ASM
 
 #define YUV2RGB_LOOP(depth)                                          \
-    h_size = (c->dstW + 7) & ~7;                                     \
+    h_size = (c->opts.dst_w + 7) & ~7;                               \
     if (h_size * depth > FFABS(dstStride[0]))                        \
         h_size -= 8;                                                 \
                                                                      \
-    vshift = c->srcFormat != AV_PIX_FMT_YUV422P;                     \
+    vshift = c->opts.src_format != AV_PIX_FMT_YUV422P;               \
                                                                      \
     for (y = 0; y < srcSliceH; y++) {                                \
         uint8_t *image    = dst[0] + (y + srcSliceY) * dstStride[0]; \
@@ -215,11 +215,11 @@ static inline int yuv420_gbrp_ssse3(SwsInternal *c, const uint8_t *const src[],
 {
     int y, h_size, vshift;
 
-    h_size = (c->dstW + 7) & ~7;
+    h_size = (c->opts.dst_w + 7) & ~7;
     if (h_size * 3 > FFABS(dstStride[0]))
         h_size -= 8;
 
-    vshift = c->srcFormat != AV_PIX_FMT_YUV422P;
+    vshift = c->opts.src_format != AV_PIX_FMT_YUV422P;
 
     for (y = 0; y < srcSliceH; y++) {
         uint8_t *dst_g    = dst[0] + (y + srcSliceY) * dstStride[0];
@@ -244,9 +244,9 @@ av_cold SwsFunc ff_yuv2rgb_init_x86(SwsInternal *c)
     int cpu_flags = av_get_cpu_flags();
 
     if (EXTERNAL_SSSE3(cpu_flags)) {
-        switch (c->dstFormat) {
+        switch (c->opts.dst_format) {
         case AV_PIX_FMT_RGB32:
-            if (c->srcFormat == AV_PIX_FMT_YUVA420P) {
+            if (c->opts.src_format == AV_PIX_FMT_YUVA420P) {
 #if CONFIG_SWSCALE_ALPHA
                 return yuva420_rgb32_ssse3;
 #endif
@@ -254,7 +254,7 @@ av_cold SwsFunc ff_yuv2rgb_init_x86(SwsInternal *c)
             } else
                 return yuv420_rgb32_ssse3;
         case AV_PIX_FMT_BGR32:
-            if (c->srcFormat == AV_PIX_FMT_YUVA420P) {
+            if (c->opts.src_format == AV_PIX_FMT_YUVA420P) {
 #if CONFIG_SWSCALE_ALPHA
                 return yuva420_bgr32_ssse3;
 #endif
diff --git a/libswscale/yuv2rgb.c b/libswscale/yuv2rgb.c
index f4fa1c0549..ff8e013da4 100644
--- a/libswscale/yuv2rgb.c
+++ b/libswscale/yuv2rgb.c
@@ -155,7 +155,7 @@ const int *sws_getCoefficients(int colorspace)
             const uint8_t av_unused *pv_1 = src[2] + (y >> !yuv422) * srcStride[2]; \
             const uint8_t av_unused *pu_2, *pv_2;                           \
             const uint8_t av_unused *pa_1, *pa_2;                           \
-            unsigned int h_size = c->dstW >> 3;                             \
+            unsigned int h_size = c->opts.dst_w >> 3;                       \
             if (nb_dst_planes > 1) {                                        \
                 dst1_1 = (dst_type *)(dst[1] + (yd)     * dstStride[1]);    \
                 dst1_2 = (dst_type *)(dst[1] + (yd + 1) * dstStride[1]);    \
@@ -195,7 +195,7 @@ const int *sws_getCoefficients(int colorspace)
         dst2_2 += dst_delta >> ss;                  \
     }                                               \
     }                                               \
-    if (c->dstW & (4 >> ss)) {                      \
+    if (c->opts.dst_w & (4 >> ss)) {                \
         int av_unused Y, U, V;                      \
 
 #define ENDYUV2RGBFUNC()                            \
@@ -485,9 +485,9 @@ YUV2RGBFUNC(yuv2rgb_c_1_ordered_dither, uint8_t, 0, 0, 1)
     dst_1 += 1;
     dst_2 += 1;
     }
-    if (c->dstW & 7) {
+    if (c->opts.dst_w & 7) {
         int av_unused Y, U, V;
-        int pixels_left = c->dstW & 7;
+        int pixels_left = c->opts.dst_w & 7;
     const uint8_t *d128 = ff_dither_8x8_220[yd & 7];
     char out_1 = 0, out_2 = 0;
     g = c->table_gU[128 + YUVRGB_TABLE_HEADROOM] + c->table_gV[128 + YUVRGB_TABLE_HEADROOM];
@@ -575,10 +575,10 @@ SwsFunc ff_yuv2rgb_get_func_ptr(SwsInternal *c)
 
     av_log(c, AV_LOG_WARNING,
            "No accelerated colorspace conversion found from %s to %s.\n",
-           av_get_pix_fmt_name(c->srcFormat), av_get_pix_fmt_name(c->dstFormat));
+           av_get_pix_fmt_name(c->opts.src_format), av_get_pix_fmt_name(c->opts.dst_format));
 
-    if (c->srcFormat == AV_PIX_FMT_YUV422P) {
-        switch (c->dstFormat) {
+    if (c->opts.src_format == AV_PIX_FMT_YUV422P) {
+        switch (c->opts.dst_format) {
         case AV_PIX_FMT_BGR48BE:
         case AV_PIX_FMT_BGR48LE:
             return yuv422p_bgr48_c;
@@ -587,11 +587,11 @@ SwsFunc ff_yuv2rgb_get_func_ptr(SwsInternal *c)
             return yuv422p_rgb48_c;
         case AV_PIX_FMT_ARGB:
         case AV_PIX_FMT_ABGR:
-            if (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat))
+            if (CONFIG_SWSCALE_ALPHA && isALPHA(c->opts.src_format))
                 return yuva422p_argb_c;
         case AV_PIX_FMT_RGBA:
         case AV_PIX_FMT_BGRA:
-            return (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat)) ? yuva422p_rgba_c : yuv422p_rgb32_c;
+            return (CONFIG_SWSCALE_ALPHA && isALPHA(c->opts.src_format)) ? yuva422p_rgba_c : yuv422p_rgb32_c;
         case AV_PIX_FMT_RGB24:
             return yuv422p_rgb24_c;
         case AV_PIX_FMT_BGR24:
@@ -620,7 +620,7 @@ SwsFunc ff_yuv2rgb_get_func_ptr(SwsInternal *c)
             return yuv422p_gbrp_c;
         }
     } else {
-        switch (c->dstFormat) {
+        switch (c->opts.dst_format) {
         case AV_PIX_FMT_BGR48BE:
         case AV_PIX_FMT_BGR48LE:
             return yuv2rgb_c_bgr48;
@@ -629,11 +629,11 @@ SwsFunc ff_yuv2rgb_get_func_ptr(SwsInternal *c)
             return yuv2rgb_c_48;
         case AV_PIX_FMT_ARGB:
         case AV_PIX_FMT_ABGR:
-            if (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat))
+            if (CONFIG_SWSCALE_ALPHA && isALPHA(c->opts.src_format))
                 return yuva2argb_c;
         case AV_PIX_FMT_RGBA:
         case AV_PIX_FMT_BGRA:
-            return (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat)) ? yuva2rgba_c : yuv2rgb_c_32;
+            return (CONFIG_SWSCALE_ALPHA && isALPHA(c->opts.src_format)) ? yuva2rgba_c : yuv2rgb_c_32;
         case AV_PIX_FMT_RGB24:
             return yuv2rgb_c_24_rgb;
         case AV_PIX_FMT_BGR24:
@@ -706,29 +706,29 @@ av_cold int ff_yuv2rgb_c_init_tables(SwsInternal *c, const int inv_table[4],
                                      int fullRange, int brightness,
                                      int contrast, int saturation)
 {
-    const int isRgb = c->dstFormat == AV_PIX_FMT_RGB32     ||
-                      c->dstFormat == AV_PIX_FMT_RGB32_1   ||
-                      c->dstFormat == AV_PIX_FMT_BGR24     ||
-                      c->dstFormat == AV_PIX_FMT_RGB565BE  ||
-                      c->dstFormat == AV_PIX_FMT_RGB565LE  ||
-                      c->dstFormat == AV_PIX_FMT_RGB555BE  ||
-                      c->dstFormat == AV_PIX_FMT_RGB555LE  ||
-                      c->dstFormat == AV_PIX_FMT_RGB444BE  ||
-                      c->dstFormat == AV_PIX_FMT_RGB444LE  ||
-                      c->dstFormat == AV_PIX_FMT_X2RGB10BE ||
-                      c->dstFormat == AV_PIX_FMT_X2RGB10LE ||
-                      c->dstFormat == AV_PIX_FMT_RGB8      ||
-                      c->dstFormat == AV_PIX_FMT_RGB4      ||
-                      c->dstFormat == AV_PIX_FMT_RGB4_BYTE ||
-                      c->dstFormat == AV_PIX_FMT_MONOBLACK;
-    const int isNotNe = c->dstFormat == AV_PIX_FMT_NE(RGB565LE, RGB565BE) ||
-                        c->dstFormat == AV_PIX_FMT_NE(RGB555LE, RGB555BE) ||
-                        c->dstFormat == AV_PIX_FMT_NE(RGB444LE, RGB444BE) ||
-                        c->dstFormat == AV_PIX_FMT_NE(BGR565LE, BGR565BE) ||
-                        c->dstFormat == AV_PIX_FMT_NE(BGR555LE, BGR555BE) ||
-                        c->dstFormat == AV_PIX_FMT_NE(BGR444LE, BGR444BE) ||
-                        c->dstFormat == AV_PIX_FMT_NE(X2RGB10LE, X2RGB10BE) ||
-                        c->dstFormat == AV_PIX_FMT_NE(X2BGR10LE, X2BGR10BE);
+    const int isRgb = c->opts.dst_format == AV_PIX_FMT_RGB32     ||
+                      c->opts.dst_format == AV_PIX_FMT_RGB32_1   ||
+                      c->opts.dst_format == AV_PIX_FMT_BGR24     ||
+                      c->opts.dst_format == AV_PIX_FMT_RGB565BE  ||
+                      c->opts.dst_format == AV_PIX_FMT_RGB565LE  ||
+                      c->opts.dst_format == AV_PIX_FMT_RGB555BE  ||
+                      c->opts.dst_format == AV_PIX_FMT_RGB555LE  ||
+                      c->opts.dst_format == AV_PIX_FMT_RGB444BE  ||
+                      c->opts.dst_format == AV_PIX_FMT_RGB444LE  ||
+                      c->opts.dst_format == AV_PIX_FMT_X2RGB10BE ||
+                      c->opts.dst_format == AV_PIX_FMT_X2RGB10LE ||
+                      c->opts.dst_format == AV_PIX_FMT_RGB8      ||
+                      c->opts.dst_format == AV_PIX_FMT_RGB4      ||
+                      c->opts.dst_format == AV_PIX_FMT_RGB4_BYTE ||
+                      c->opts.dst_format == AV_PIX_FMT_MONOBLACK;
+    const int isNotNe = c->opts.dst_format == AV_PIX_FMT_NE(RGB565LE, RGB565BE) ||
+                        c->opts.dst_format == AV_PIX_FMT_NE(RGB555LE, RGB555BE) ||
+                        c->opts.dst_format == AV_PIX_FMT_NE(RGB444LE, RGB444BE) ||
+                        c->opts.dst_format == AV_PIX_FMT_NE(BGR565LE, BGR565BE) ||
+                        c->opts.dst_format == AV_PIX_FMT_NE(BGR555LE, BGR555BE) ||
+                        c->opts.dst_format == AV_PIX_FMT_NE(BGR444LE, BGR444BE) ||
+                        c->opts.dst_format == AV_PIX_FMT_NE(X2RGB10LE, X2RGB10BE) ||
+                        c->opts.dst_format == AV_PIX_FMT_NE(X2BGR10LE, X2BGR10BE);
     const int bpp = c->dstFormatBpp;
     uint8_t *y_table;
     uint16_t *y_table16;
@@ -904,7 +904,7 @@ av_cold int ff_yuv2rgb_c_init_tables(SwsInternal *c, const int inv_table[4],
         rbase = isRgb ? 20 : 0;
         gbase = 10;
         bbase = isRgb ? 0 : 20;
-        needAlpha = CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat);
+        needAlpha = CONFIG_SWSCALE_ALPHA && isALPHA(c->opts.src_format);
         if (!needAlpha)
             abase = 30;
         ALLOC_YUV_TABLE(table_plane_size * 3 * 4);
@@ -928,12 +928,12 @@ av_cold int ff_yuv2rgb_c_init_tables(SwsInternal *c, const int inv_table[4],
         break;
     case 32:
     case 64:
-        base      = (c->dstFormat == AV_PIX_FMT_RGB32_1 ||
-                     c->dstFormat == AV_PIX_FMT_BGR32_1) ? 8 : 0;
+        base      = (c->opts.dst_format == AV_PIX_FMT_RGB32_1 ||
+                     c->opts.dst_format == AV_PIX_FMT_BGR32_1) ? 8 : 0;
         rbase     = base + (isRgb ? 16 : 0);
         gbase     = base + 8;
         bbase     = base + (isRgb ? 0 : 16);
-        needAlpha = CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat);
+        needAlpha = CONFIG_SWSCALE_ALPHA && isALPHA(c->opts.src_format);
         if (!needAlpha)
             abase = (base + 24) & 31;
         ALLOC_YUV_TABLE(table_plane_size * 3 * 4);
@@ -953,7 +953,7 @@ av_cold int ff_yuv2rgb_c_init_tables(SwsInternal *c, const int inv_table[4],
         fill_gv_table(c->table_gV, 4, cgv);
         break;
     default:
-        if(!isPlanar(c->dstFormat) || bpp <= 24)
+        if(!isPlanar(c->opts.dst_format) || bpp <= 24)
             av_log(c, AV_LOG_ERROR, "%ibpp not supported by yuv2rgb\n", bpp);
         return AVERROR(EINVAL);
     }
diff --git a/tests/checkasm/sw_gbrp.c b/tests/checkasm/sw_gbrp.c
index 039be8006b..79b2e0e82e 100644
--- a/tests/checkasm/sw_gbrp.c
+++ b/tests/checkasm/sw_gbrp.c
@@ -136,13 +136,13 @@ static void check_output_yuv2gbrp(void)
         fail();
 
     c = sws_internal(sws);
-    c->flags |= SWS_FULL_CHR_H_INT;
+    c->opts.flags |= SWS_FULL_CHR_H_INT;
 
     for (fmi = 0; fmi < FF_ARRAY_ELEMS(planar_fmts); fmi++) {
         for (fsi = 0; fsi < FILTER_SIZES; fsi++) {
             for (isi = 0; isi < INPUT_SIZES; isi++ ) {
                 desc = av_pix_fmt_desc_get(planar_fmts[fmi]);
-                c->dstFormat = planar_fmts[fmi];
+                c->opts.dst_format = planar_fmts[fmi];
 
                 dstW = input_sizes[isi];
                 luma_filter_size = filter_sizes[fsi];
@@ -232,8 +232,8 @@ static void check_input_planar_rgb_to_y(void)
     for (fmi = 0; fmi < FF_ARRAY_ELEMS(planar_fmts); fmi++) {
         for (isi = 0; isi < INPUT_SIZES; isi++ ) {
             desc = av_pix_fmt_desc_get(planar_fmts[fmi]);
-            c->srcFormat = planar_fmts[fmi];
-            c->dstFormat = AV_PIX_FMT_YUVA444P16;
+            c->opts.src_format = planar_fmts[fmi];
+            c->opts.dst_format = AV_PIX_FMT_YUVA444P16;
             byte_size = 2;
             dstW = input_sizes[isi];
 
@@ -305,8 +305,8 @@ static void check_input_planar_rgb_to_uv(void)
     for (fmi = 0; fmi < FF_ARRAY_ELEMS(planar_fmts); fmi++) {
         for (isi = 0; isi < INPUT_SIZES; isi++ ) {
             desc = av_pix_fmt_desc_get(planar_fmts[fmi]);
-            c->srcFormat = planar_fmts[fmi];
-            c->dstFormat = AV_PIX_FMT_YUVA444P16;
+            c->opts.src_format = planar_fmts[fmi];
+            c->opts.dst_format = AV_PIX_FMT_YUVA444P16;
             byte_size = 2;
             dstW = input_sizes[isi];
 
@@ -380,8 +380,8 @@ static void check_input_planar_rgb_to_a(void)
             if (!(desc->flags & AV_PIX_FMT_FLAG_ALPHA))
                 continue;
 
-            c->srcFormat = planar_fmts[fmi];
-            c->dstFormat = AV_PIX_FMT_YUVA444P16;
+            c->opts.src_format = planar_fmts[fmi];
+            c->opts.dst_format = AV_PIX_FMT_YUVA444P16;
             byte_size = 2;
             dstW = input_sizes[isi];
 
diff --git a/tests/checkasm/sw_range_convert.c b/tests/checkasm/sw_range_convert.c
index 7da29b896e..4a2cca2225 100644
--- a/tests/checkasm/sw_range_convert.c
+++ b/tests/checkasm/sw_range_convert.c
@@ -47,10 +47,10 @@ static void check_lumConvertRange(int from)
         fail();
 
     c = sws_internal(sws);
-    c->srcFormat = from ? AV_PIX_FMT_YUVJ444P : AV_PIX_FMT_YUV444P;
-    c->dstFormat = from ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P;
-    c->srcRange = from;
-    c->dstRange = !from;
+    c->opts.src_format = from ? AV_PIX_FMT_YUVJ444P : AV_PIX_FMT_YUV444P;
+    c->opts.dst_format = from ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P;
+    c->opts.src_range = from;
+    c->opts.dst_range = !from;
 
     for (int dstWi = 0; dstWi < INPUT_SIZES; dstWi++) {
         int width = input_sizes[dstWi];
@@ -95,10 +95,10 @@ static void check_chrConvertRange(int from)
         fail();
 
     c = sws_internal(sws);
-    c->srcFormat = from ? AV_PIX_FMT_YUVJ444P : AV_PIX_FMT_YUV444P;
-    c->dstFormat = from ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P;
-    c->srcRange = from;
-    c->dstRange = !from;
+    c->opts.src_format = from ? AV_PIX_FMT_YUVJ444P : AV_PIX_FMT_YUV444P;
+    c->opts.dst_format = from ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P;
+    c->opts.src_range = from;
+    c->opts.dst_range = !from;
 
     for (int dstWi = 0; dstWi < INPUT_SIZES; dstWi++) {
         int width = input_sizes[dstWi];
diff --git a/tests/checkasm/sw_rgb.c b/tests/checkasm/sw_rgb.c
index 7af82f0fc7..65f8404d3f 100644
--- a/tests/checkasm/sw_rgb.c
+++ b/tests/checkasm/sw_rgb.c
@@ -370,7 +370,7 @@ static void check_rgb_to_y(SwsInternal *ctx)
     for (int i = 0; i < FF_ARRAY_ELEMS(rgb_formats); i++) {
         const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(rgb_formats[i]);
 
-        ctx->srcFormat = rgb_formats[i];
+        ctx->opts.src_format = rgb_formats[i];
         ff_sws_init_scale(ctx);
 
         for (int j = 0; j < FF_ARRAY_ELEMS(input_sizes); j++) {
@@ -389,7 +389,7 @@ static void check_rgb_to_y(SwsInternal *ctx)
 
                 if (desc->nb_components == 3 ||
                     // only bench native endian formats
-                    (ctx->srcFormat == AV_PIX_FMT_RGB32 || ctx->srcFormat == AV_PIX_FMT_RGB32_1))
+                    (ctx->opts.src_format == AV_PIX_FMT_RGB32 || ctx->opts.src_format == AV_PIX_FMT_RGB32_1))
                     bench_new(dst1_y, src, NULL, NULL, w, ctx->input_rgb2yuv_table, NULL);
             }
         }
@@ -417,8 +417,8 @@ static void check_rgb_to_uv(SwsInternal *ctx)
         const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(src_fmt);
 
         ctx->chrSrcHSubSample = (i % 2) ? 0 : 1;
-        ctx->srcFormat = src_fmt;
-        ctx->dstFormat = ctx->chrSrcHSubSample ? AV_PIX_FMT_YUV420P : AV_PIX_FMT_YUV444P;
+        ctx->opts.src_format = src_fmt;
+        ctx->opts.dst_format = ctx->chrSrcHSubSample ? AV_PIX_FMT_YUV420P : AV_PIX_FMT_YUV444P;
         ff_sws_init_scale(ctx);
 
         for (int j = 0; j < FF_ARRAY_ELEMS(input_sizes); j++) {
@@ -441,7 +441,7 @@ static void check_rgb_to_uv(SwsInternal *ctx)
 
                 if (desc->nb_components == 3 ||
                     // only bench native endian formats
-                    (ctx->srcFormat == AV_PIX_FMT_RGB32 || ctx->srcFormat == AV_PIX_FMT_RGB32_1))
+                    (ctx->opts.src_format == AV_PIX_FMT_RGB32 || ctx->opts.src_format == AV_PIX_FMT_RGB32_1))
                     bench_new(dst1_u, dst1_v, NULL, src, src, w, ctx->input_rgb2yuv_table, NULL);
             }
         }
diff --git a/tests/checkasm/sw_scale.c b/tests/checkasm/sw_scale.c
index b383fa0930..8951ddce43 100644
--- a/tests/checkasm/sw_scale.c
+++ b/tests/checkasm/sw_scale.c
@@ -126,7 +126,7 @@ static void check_yuv2yuv1(int accurate)
     sws = sws_alloc_context();
     c = sws_internal(sws);
     if (accurate)
-        c->flags |= SWS_ACCURATE_RND;
+        c->opts.flags |= SWS_ACCURATE_RND;
     if (sws_init_context(sws, NULL, NULL) < 0)
         fail();
 
@@ -194,7 +194,7 @@ static void check_yuv2yuvX(int accurate)
     sws = sws_alloc_context();
     c = sws_internal(sws);
     if (accurate)
-        c->flags |= SWS_ACCURATE_RND;
+        c->opts.flags |= SWS_ACCURATE_RND;
     if (sws_init_context(sws, NULL, NULL) < 0)
         fail();
 
@@ -344,20 +344,20 @@ static void check_hscale(void)
 
                     filter[SRC_PIXELS * width + i] = rnd();
                 }
-                c->dstW = c->chrDstW = input_sizes[dstWi];
+                c->opts.dst_w = c->chrDstW = input_sizes[dstWi];
                 ff_sws_init_scale(c);
                 memcpy(filterAvx2, filter, sizeof(uint16_t) * (SRC_PIXELS * MAX_FILTER_WIDTH + MAX_FILTER_WIDTH));
-                ff_shuffle_filter_coefficients(c, filterPosAvx, width, filterAvx2, c->dstW);
+                ff_shuffle_filter_coefficients(c, filterPosAvx, width, filterAvx2, c->opts.dst_w);
 
-                if (check_func(c->hcScale, "hscale_%d_to_%d__fs_%d_dstW_%d", c->srcBpc, c->dstBpc + 1, width, c->dstW)) {
+                if (check_func(c->hcScale, "hscale_%d_to_%d__fs_%d_dstW_%d", c->srcBpc, c->dstBpc + 1, width, c->opts.dst_w)) {
                     memset(dst0, 0, SRC_PIXELS * sizeof(dst0[0]));
                     memset(dst1, 0, SRC_PIXELS * sizeof(dst1[0]));
 
-                    call_ref(NULL, dst0, c->dstW, src, filter, filterPos, width);
-                    call_new(NULL, dst1, c->dstW, src, filterAvx2, filterPosAvx, width);
-                    if (memcmp(dst0, dst1, c->dstW * sizeof(dst0[0])))
+                    call_ref(NULL, dst0, c->opts.dst_w, src, filter, filterPos, width);
+                    call_new(NULL, dst1, c->opts.dst_w, src, filterAvx2, filterPosAvx, width);
+                    if (memcmp(dst0, dst1, c->opts.dst_w * sizeof(dst0[0])))
                         fail();
-                    bench_new(NULL, dst0, c->dstW, src, filter, filterPosAvx, width);
+                    bench_new(NULL, dst0, c->opts.dst_w, src, filter, filterPosAvx, width);
                 }
             }
         }
