From: Niklas Haas <g...@haasn.dev> Following in the footsteps of the work in the previous commit, it's now relatively straightforward to expose the options struct publicly as SwsContext. This is a step towards making this more user friendly, as well as following API conventions established elsewhere.
Sponsored-by: Sovereign Tech Fund Signed-off-by: Niklas Haas <g...@haasn.dev> --- libswscale/swscale.h | 93 +++++++++++++++++++++++-- libswscale/swscale_internal.h | 45 +------------ libswscale/utils.c | 123 +++++++++++++++------------------- 3 files changed, 144 insertions(+), 117 deletions(-) diff --git a/libswscale/swscale.h b/libswscale/swscale.h index 50c705ae06..4baef532b6 100644 --- a/libswscale/swscale.h +++ b/libswscale/swscale.h @@ -42,8 +42,6 @@ #include "version.h" #endif -typedef struct SwsContext SwsContext; - /** * @defgroup libsws libswscale * Color conversion and scaling library. @@ -65,17 +63,98 @@ const char *swscale_configuration(void); const char *swscale_license(void); /** - * Get the AVClass for swsContext. It can be used in combination with + * Get the AVClass for SwsContext. It can be used in combination with * AV_OPT_SEARCH_FAKE_OBJ for examining options. * * @see av_opt_find(). */ const AVClass *sws_get_class(void); -/** - * Allocate an empty SwsContext. This must be filled and passed to - * sws_init_context(). For filling see AVOptions, options.c and - * sws_setColorspaceDetails(). +/****************************** + * Flags and quality settings * + ******************************/ + +typedef enum SwsDither { + SWS_DITHER_NONE = 0, /* disable dithering */ + SWS_DITHER_AUTO, /* auto-select from preset */ + SWS_DITHER_BAYER, /* ordered dither matrix */ + SWS_DITHER_ED, /* error diffusion */ + SWS_DITHER_A_DITHER, /* arithmetic addition */ + SWS_DITHER_X_DITHER, /* arithmetic xor */ + SWS_DITHER_NB, /* not part of the ABI */ +} SwsDither; + +typedef enum SwsAlphaBlend { + SWS_ALPHA_BLEND_NONE = 0, + SWS_ALPHA_BLEND_UNIFORM, + SWS_ALPHA_BLEND_CHECKERBOARD, + SWS_ALPHA_BLEND_NB, /* not part of the ABI */ +} SwsAlphaBlend; + +/*********************************** + * Context creation and management * + ***********************************/ + +/** + * Main external API structure. New fields can be added to the end with + * minor version bumps. Removal, reordering and changes to existing fields + * require a major version bump. sizeof(SwsContext) is not part of the ABI. + */ +typedef struct SwsContext { + const AVClass *av_class; + + /** + * Private data of the user, can be used to carry app specific stuff. + */ + void *opaque; + + /** + * Bitmask of SWS_*. + */ + unsigned flags; + + /** + * Extra parameters for fine-tuning certain scalers. + */ + double scaler_params[2]; + + /** + * How many threads to use for processing, or 0 for automatic selection. + */ + int threads; + + /** + * Dither mode. + */ + SwsDither dither; + + /** + * Alpha blending mode. See `SwsAlphaBlend` for details. + */ + SwsAlphaBlend alpha_blend; + + /** + * Use gamma correct scaling. + */ + int gamma_flag; + + /** + * Frame property overrides. + */ + int src_w, src_h; ///< Width and height of the source frame + int dst_w, dst_h; ///< Width and height of the destination frame + int src_format; ///< Source pixel format + int dst_format; ///< Destination pixel format + int src_range; ///< Source is full range + int dst_range; ///< Destination is full range + int src_v_chr_pos; ///< Source vertical chroma position in luma grid / 256 + int src_h_chr_pos; ///< Source horizontal chroma position + int dst_v_chr_pos; ///< Destination vertical chroma position + int dst_h_chr_pos; ///< Destination horizontal chroma position +} SwsContext; + +/** + * Allocate an empty SwsContext and set its fields to default values. */ SwsContext *sws_alloc_context(void); diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index 643177d14d..5218ab0921 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -73,23 +73,6 @@ static inline SwsInternal *sws_internal(const SwsContext *sws) return (SwsInternal *) sws; } -typedef enum SwsDither { - SWS_DITHER_NONE = 0, - SWS_DITHER_AUTO, - SWS_DITHER_BAYER, - SWS_DITHER_ED, - SWS_DITHER_A_DITHER, - SWS_DITHER_X_DITHER, - SWS_DITHER_NB, -} SwsDither; - -typedef enum SwsAlphaBlend { - SWS_ALPHA_BLEND_NONE = 0, - SWS_ALPHA_BLEND_UNIFORM, - SWS_ALPHA_BLEND_CHECKERBOARD, - SWS_ALPHA_BLEND_NB, -} SwsAlphaBlend; - typedef struct Range { unsigned int start; unsigned int len; @@ -329,32 +312,10 @@ struct SwsFilterDescriptor; /* This struct should be aligned on at least a 32-byte boundary. */ struct SwsInternal { - /* 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; + /* Currently active user-facing options. Also contains AVClass */ + SwsContext opts; + /* Parent context (for slice contexts) */ SwsContext *parent; AVSliceThread *slicethread; diff --git a/libswscale/utils.c b/libswscale/utils.c index 465302a9fa..ce9807d401 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -293,22 +293,20 @@ static SwsContext *alloc_set_opts(int srcW, int srcH, enum AVPixelFormat srcForm int flags, const double *param) { SwsContext *sws = sws_alloc_context(); - SwsInternal *c = sws_internal(sws); - - if (!c) + if (!sws) return NULL; - 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; + sws->flags = flags; + sws->src_w = srcW; + sws->src_h = srcH; + sws->dst_w = dstW; + sws->dst_h = dstH; + sws->src_format = srcFormat; + sws->dst_format = dstFormat; if (param) { - c->opts.scaler_params[0] = param[0]; - c->opts.scaler_params[1] = param[1]; + sws->scaler_params[0] = param[0]; + sws->scaler_params[1] = param[1]; } return sws; @@ -1228,16 +1226,16 @@ int sws_getColorspaceDetails(SwsContext *sws, int **inv_table, SwsContext *sws_alloc_context(void) { - SwsInternal *c = av_mallocz(sizeof(SwsInternal)); + SwsInternal *c = (SwsInternal *) av_mallocz(sizeof(SwsInternal)); + if (!c) + return NULL; - if (c) { - 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); - } + 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); - return (SwsContext *) c; + return &c->opts; } static uint16_t * alloc_gamma_tbl(double e) @@ -2523,7 +2521,7 @@ void sws_freeContext(SwsContext *sws) ff_free_filters(c); - av_free(sws); + av_free(c); } void sws_free_context(SwsContext **pctx) @@ -2536,7 +2534,7 @@ void sws_free_context(SwsContext **pctx) *pctx = NULL; } -SwsContext *sws_getCachedContext(SwsContext *sws, int srcW, +SwsContext *sws_getCachedContext(SwsContext *prev, int srcW, int srcH, enum AVPixelFormat srcFormat, int dstW, int dstH, enum AVPixelFormat dstFormat, int flags, @@ -2544,59 +2542,48 @@ SwsContext *sws_getCachedContext(SwsContext *sws, int srcW, SwsFilter *dstFilter, const double *param) { - SwsInternal *context; - + SwsContext *sws; static const double default_param[2] = { SWS_PARAM_DEFAULT, SWS_PARAM_DEFAULT }; - int64_t src_h_chr_pos = -513, dst_h_chr_pos = -513, - src_v_chr_pos = -513, dst_v_chr_pos = -513; if (!param) param = default_param; - if ((context = sws_internal(sws)) && - (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); - av_opt_get_int(context, "dst_h_chr_pos", 0, &dst_h_chr_pos); - av_opt_get_int(context, "dst_v_chr_pos", 0, &dst_v_chr_pos); - sws_freeContext(sws); - sws = NULL; - } - - if (!sws) { - if (!(sws = sws_alloc_context())) - return NULL; - context = sws_internal(sws); - 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); - av_opt_set_int(context, "dst_h_chr_pos", dst_h_chr_pos, 0); - av_opt_set_int(context, "dst_v_chr_pos", dst_v_chr_pos, 0); - - if (sws_init_context(sws, srcFilter, dstFilter) < 0) { - sws_freeContext(sws); - return NULL; - } + if (prev && (prev->src_w == srcW || + prev->src_h == srcH || + prev->src_format == srcFormat || + prev->dst_w == dstW || + prev->dst_h == dstH || + prev->dst_format == dstFormat || + prev->flags == flags || + prev->scaler_params[0] == param[0] || + prev->scaler_params[1] == param[1])) { + return prev; } + + if (!(sws = sws_alloc_context())) { + sws_free_context(&prev); + return NULL; + } + + if (prev) { + av_opt_copy(sws, prev); + sws_free_context(&prev); + } + + sws->src_w = srcW; + sws->src_h = srcH; + sws->src_format = srcFormat; + sws->dst_w = dstW; + sws->dst_h = dstH; + sws->dst_format = dstFormat; + sws->flags = flags; + sws->scaler_params[0] = param[0]; + sws->scaler_params[1] = param[1]; + + if (sws_init_context(sws, srcFilter, dstFilter) < 0) + sws_free_context(&sws); + return sws; } -- 2.47.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".