1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-01-13 21:28:01 +02:00

swscale: expose SwsContext publicly

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 <git@haasn.dev>
This commit is contained in:
Niklas Haas 2024-10-24 12:07:46 +02:00
parent 4472dec51d
commit ed5dd67562
5 changed files with 146 additions and 116 deletions

View File

@ -2,6 +2,9 @@ The last version increases of all libraries were on 2024-03-07
API changes, most recent first:
2024-11-25 - xxxxxxxxxx - lsws 8.10.100 - swscale.h
Publicly expose struct SwsContext, enum SwsDither, and enum SwsAlphaBlend.
2024-11-16 - xxxxxxxxxx - lavu 59.47.101 - frame.h
av_frame_get_buffer() now also aligns the data pointers according to
the requested alignment.

View File

@ -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);
/******************************
* 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 *
***********************************/
/**
* Allocate an empty SwsContext. This must be filled and passed to
* sws_init_context(). For filling see AVOptions, options.c and
* sws_setColorspaceDetails().
* 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);

View File

@ -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;

View File

@ -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 (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) {
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 (!(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;
}

View File

@ -28,8 +28,8 @@
#include "version_major.h"
#define LIBSWSCALE_VERSION_MINOR 9
#define LIBSWSCALE_VERSION_MICRO 101
#define LIBSWSCALE_VERSION_MINOR 10
#define LIBSWSCALE_VERSION_MICRO 100
#define LIBSWSCALE_VERSION_INT AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \
LIBSWSCALE_VERSION_MINOR, \