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:
parent
4472dec51d
commit
ed5dd67562
@ -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.
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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, \
|
||||
|
Loading…
Reference in New Issue
Block a user