Go to the documentation of this file.
   29 #undef HAVE_AV_CONFIG_H 
   82     return ratio > 10.00 ? 
"\033[1;94m" : 
 
   83            ratio >  2.00 ? 
"\033[1;32m" : 
 
   84            ratio >  1.02 ? 
"\033[32m"   : 
 
   86            ratio >  0.90 ? 
"\033[33m"   : 
 
   87            ratio >  0.75 ? 
"\033[31m"   : 
 
   95         printf(
"Overall speedup=%.3fx %s%s\033[0m, min=%.3fx max=%.3fx\n", ratio,
 
  107     float variance = 1.0 / 12;
 
  108     if (
desc->comp[0].depth < 8) {
 
  110         variance *= (8 - 
desc->comp[0].depth);
 
  116         const float r = 0.299 / (1 << 
desc->comp[0].depth);
 
  117         const float g = 0.587 / (1 << 
desc->comp[1].depth);
 
  118         const float b = 0.114 / (1 << 
desc->comp[2].depth);
 
  119         return (
r * 
r + 
g * 
g + 
b * 
b) * variance;
 
  121         const float y = 1.0 / (1 << 
desc->comp[0].depth);
 
  122         return y * y * variance;
 
  129     int comps = 
desc->nb_components >= 3 ? 0x7 : 0x1;
 
  141     for (
int p = 0; 
p < 4; 
p++) {
 
  142         const int stride_a = 
out->linesize[
p];
 
  143         const int stride_b = 
ref->linesize[
p];
 
  144         const int w = 
out->width;
 
  145         const int h = 
out->height;
 
  147         const int is_chroma = 
p == 1 || 
p == 2;
 
  148         const uint8_t def = is_chroma ? 128 : 0xFF;
 
  149         const int has_ref = comps & (1 << 
p);
 
  154         for (
int y = 0; y < (
h & ~3); y += 4) {
 
  155             for (
int x = 0; x < (
w & ~3); x += 4) {
 
  156                 const float c1 = .01 * .01 * 255 * 255 * 64;
 
  157                 const float c2 = .03 * .03 * 255 * 255 * 64 * 63;
 
  158                 int s1 = 0, s2 = 0, 
ss = 0, s12 = 0, var, covar;
 
  160                 for (
int yy = 0; yy < 4; yy++) {
 
  161                     for (
int xx = 0; xx < 4; xx++) {
 
  162                         int a = 
out->data[
p][(y + yy) * stride_a + x + xx];
 
  163                         int b = has_ref ? 
ref->data[
p][(y + yy) * stride_b + x + xx] : def;
 
  171                 var = 
ss * 64 - s1 * s1 - s2 * s2;
 
  172                 covar = s12 * 64 - s1 * s2;
 
  173                 sum += (2 * s1 * s2 + 
c1) * (2 * covar + 
c2) /
 
  174                        ((s1 * s1 + s2 * s2 + 
c1) * (var + 
c2));
 
  179         ssim[
p] = count ? sum / count : 0.0;
 
  185     const float weights[3] = { 0.8, 0.1, 0.1 }; 
 
  188     for (
int i = 0; 
i < 3; 
i++)
 
  218     for (
int i = 0; 
ret >= 0 && 
i < 
opts.iters; 
i++)
 
  232     float ssim[4], ssim_sws[4];
 
  238     const float c1 = 0.01 * 0.01; 
 
  239     const float ref_var = 1.0 / 12.0; 
 
  243     const float total_var = src_var + dst_var + out_var;
 
  244     const float ssim_luma = (2 * ref_var + 
c1) / (2 * ref_var + total_var + 
c1);
 
  245     const float ssim_expected[4] = { ssim_luma, 1, 1, 1 }; 
 
  246     const float expected_loss = 
get_loss(ssim_expected);
 
  260     out->format = 
ref->format;
 
  261     src->format = src_fmt;
 
  262     dst->format = dst_fmt;
 
  278     for (
int i = 0; 
i < 
opts.iters; 
i++) {
 
  295     printf(
"%s %dx%d -> %s %3dx%3d, flags=0x%x dither=%u, " 
  296            "SSIM {Y=%f U=%f V=%f A=%f}\n",
 
  300            ssim[0], ssim[1], ssim[2], ssim[3]);
 
  303     if (loss - expected_loss > 1e-4 && dst_w >= 
ref->width && dst_h >= 
ref->height) {
 
  304         int bad = loss - expected_loss > 1e-2;
 
  305         printf(
"\033[1;31m  loss %g is %s by %g, expected loss %g\033[0m\n",
 
  306                loss, 
bad ? 
"WORSE" : 
"worse", loss - expected_loss, expected_loss);
 
  332         if (src_var > dst_var) {
 
  333             const float src_loss = (2 * ref_var + 
c1) / (2 * ref_var + src_var + 
c1);
 
  334             ssim_sws[0] = 
FFMIN(ssim_sws[0], src_loss);
 
  341         const float loss_ref = 
get_loss(ssim_ref);
 
  342         if (loss - loss_ref > 1e-4) {
 
  343             int bad = loss - loss_ref > 1e-2;
 
  344             printf(
"\033[1;31m  loss %g is %s by %g, ref loss %g, " 
  345                    "SSIM {Y=%f U=%f V=%f A=%f}\033[0m\n",
 
  346                    loss, 
bad ? 
"WORSE" : 
"worse", loss - loss_ref, loss_ref,
 
  347                    ssim_ref[0], ssim_ref[1], ssim_ref[2], ssim_ref[3]);
 
  353     if (
opts.bench && time_ref) {
 
  354         double ratio = (
double) time_ref / time;
 
  355         if (
FFMIN(time, time_ref) > 100 ) {
 
  362         printf(
"  time=%"PRId64
" us, ref=%"PRId64
" us, speedup=%.3fx %s%s\033[0m\n",
 
  363                time / 
opts.iters, time_ref / 
opts.iters, ratio,
 
  365     } 
else if (
opts.bench) {
 
  366         printf(
"  time=%"PRId64
" us\n", time / 
opts.iters);
 
  396         src_fmt_min = src_fmt_max = 
opts.src_fmt;
 
  398         dst_fmt_min = dst_fmt_max = 
opts.dst_fmt;
 
  400     for (src_fmt = src_fmt_min; src_fmt <= src_fmt_max; src_fmt++) {
 
  405         for (dst_fmt = dst_fmt_min; dst_fmt <= dst_fmt_max; dst_fmt++) {
 
  421                         if (
run_test(src_fmt, dst_fmt, dst_w[
w], dst_h[
h],
 
  425                         if (
opts.flags >= 0 || 
opts.unscaled)
 
  445     while (fgets(buf, 
sizeof(buf), fp)) {
 
  446         char src_fmt_str[21], dst_fmt_str[21];
 
  454                      "%20s %dx%d -> %20s %dx%d, flags=0x%x dither=%u, " 
  455                      "SSIM {Y=%f U=%f V=%f A=%f}\n",
 
  456                      src_fmt_str, &sw, &sh, dst_fmt_str, &dw, &dh,
 
  458                      &ssim[0], &ssim[1], &ssim[2], &ssim[3]);
 
  467             sw != 
ref->width || sh != 
ref->height || dw > 8192 || dh > 8192 ||
 
  469             fprintf(stderr, 
"malformed input file\n");
 
  484 int main(
int argc, 
char **argv)
 
  503     for (
int i = 1; 
i < argc; 
i += 2) {
 
  504         if (!strcmp(argv[
i], 
"-help") || !strcmp(argv[
i], 
"--help")) {
 
  506                     "swscale [options...]\n" 
  510                     "       Uses file as reference to compare tests againsts. Tests that have become worse will contain the string worse or WORSE\n" 
  511                     "   -p <number between 0.0 and 1.0>\n" 
  512                     "       The percentage of tests or comparisons to perform. Doing all tests will take long and generate over a hundred MB text output\n" 
  513                     "       It is often convenient to perform a random subset\n" 
  515                     "       Only test the specified destination pixel format\n" 
  517                     "       Only test the specified source pixel format\n" 
  519                     "       Run benchmarks with the specified number of iterations. This mode also increases the size of the test images\n" 
  521                     "       Test with a specific combination of flags\n" 
  523                     "       Test with a specific dither mode\n" 
  524                     "   -unscaled <1 or 0>\n" 
  525                     "       If 1, test only conversions that do not involve scaling\n" 
  526                     "   -threads <threads>\n" 
  527                     "       Use the specified number of threads\n" 
  528                     "   -cpuflags <cpuflags>\n" 
  529                     "       Uses the specified cpuflags in the tests\n" 
  531                     "       Enable log verbosity at given level\n" 
  535         if (argv[
i][0] != 
'-' || 
i + 1 == argc)
 
  537         if (!strcmp(argv[
i], 
"-ref")) {
 
  538             fp = fopen(argv[
i + 1], 
"r");
 
  540                 fprintf(stderr, 
"could not open '%s'\n", argv[
i + 1]);
 
  543         } 
else if (!strcmp(argv[
i], 
"-cpuflags")) {
 
  547                 fprintf(stderr, 
"invalid cpu flags %s\n", argv[
i + 1]);
 
  551         } 
else if (!strcmp(argv[
i], 
"-src")) {
 
  554                 fprintf(stderr, 
"invalid pixel format %s\n", argv[
i + 1]);
 
  557         } 
else if (!strcmp(argv[
i], 
"-dst")) {
 
  560                 fprintf(stderr, 
"invalid pixel format %s\n", argv[
i + 1]);
 
  563         } 
else if (!strcmp(argv[
i], 
"-bench")) {
 
  565             opts.iters = atoi(argv[
i + 1]);
 
  569         } 
else if (!strcmp(argv[
i], 
"-flags")) {
 
  570             opts.flags = strtol(argv[
i + 1], 
NULL, 0);
 
  571         } 
else if (!strcmp(argv[
i], 
"-dither")) {
 
  572             opts.dither = atoi(argv[
i + 1]);
 
  573         } 
else if (!strcmp(argv[
i], 
"-unscaled")) {
 
  574             opts.unscaled = atoi(argv[
i + 1]);
 
  575         } 
else if (!strcmp(argv[
i], 
"-threads")) {
 
  576             opts.threads = atoi(argv[
i + 1]);
 
  577         } 
else if (!strcmp(argv[
i], 
"-p")) {
 
  578             opts.prob = atof(argv[
i + 1]);
 
  579         } 
else if (!strcmp(argv[
i], 
"-v")) {
 
  583             fprintf(stderr, 
"bad option or argument missing (%s) see -help\n", argv[
i]);
 
  592     for (
int i = 0; 
i < 3; 
i++) {
 
  608     for (
int y = 0; y < 
rgb->height; y++) {
 
  609         for (
int x = 0; x < 
rgb->width; x++) {
 
  610             for (
int c = 0; 
c < 4; 
c++)
 
  630     for (
int i = 0; 
i < 3; 
i++)
 
  
static void error(const char *err)
 
void av_force_cpu_flags(int arg)
Disables cpu detection and forces the specified flags.
 
int64_t av_gettime_relative(void)
Get the current time in microseconds since some unspecified starting point.
 
AVPixelFormat
Pixel format.
 
__device__ int printf(const char *,...)
 
static int scale_legacy(AVFrame *dst, const AVFrame *src, struct mode mode, struct options opts)
 
#define sws_isSupportedOutput(x)
 
int av_frame_get_buffer(AVFrame *frame, int align)
Allocate new buffer(s) for audio or video data.
 
av_cold void av_lfg_init(AVLFG *c, unsigned int seed)
 
static int fmt_is_subsampled(enum AVPixelFormat fmt)
 
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
 
int src_w
Deprecated frame property overrides, for the legacy API only.
 
static float estimate_quantization_noise(enum AVPixelFormat fmt)
 
#define AV_PIX_FMT_FLAG_FLOAT
The pixel format contains IEEE-754 floating point values.
 
void sws_freeContext(SwsContext *swsContext)
Free the swscaler context swsContext.
 
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
 
This structure describes decoded (raw) audio or video data.
 
static const char * speedup_color(double ratio)
 
@ SWS_BILINEAR
bilinear filtering
 
static void ff_sfc64_init(FFSFC64 *s, uint64_t seeda, uint64_t seedb, uint64_t seedc, int rounds)
Initialize sfc64 with up to 3 seeds.
 
unsigned flags
Bitmask of SWS_*.
 
int av_get_cpu_flags(void)
Return the flags which specify extensions supported by the CPU.
 
static FFSFC64 prng_state
 
static int run_file_tests(const AVFrame *ref, FILE *fp, struct options opts)
 
static double speedup_max
 
@ AV_PIX_FMT_NB
number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of...
 
@ SWS_FAST_BILINEAR
Scaler selection options.
 
@ SWS_FULL_CHR_H_INP
Perform full chroma interpolation when downscaling RGB sources.
 
int av_parse_cpu_caps(unsigned *flags, const char *s)
Parse CPU caps from a string and update the given AV_CPU_* flags based on that.
 
av_warn_unused_result int sws_init_context(SwsContext *sws_context, SwsFilter *srcFilter, SwsFilter *dstFilter)
Initialize the swscaler context sws_context.
 
#define ss(width, name, subs,...)
 
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
 
enum AVPixelFormat dst_fmt
 
#define FF_ARRAY_ELEMS(a)
 
static double speedup_min
 
SwsDither dither
Dither mode.
 
int threads
How many threads to use for processing, or 0 for automatic selection.
 
static unsigned int av_lfg_get(AVLFG *c)
Get the next random unsigned 32-bit number using an ALFG.
 
static int run_self_tests(const AVFrame *ref, struct options opts)
 
#define AV_PIX_FMT_FLAG_ALPHA
The pixel format has an alpha channel.
 
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
 
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
 
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
 
@ SWS_BICUBIC
2-tap cubic B-spline
 
static int run_test(enum AVPixelFormat src_fmt, enum AVPixelFormat dst_fmt, int dst_w, int dst_h, struct mode mode, struct options opts, const AVFrame *ref, const float ssim_ref[4])
 
int sws_test_format(enum AVPixelFormat format, int output)
Test if a given pixel format is supported.
 
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
 
enum AVPixelFormat src_fmt
 
Context structure for the Lagged Fibonacci PRNG.
 
SwsContext * sws_alloc_context(void)
Allocate an empty SwsContext and set its fields to default values.
 
#define AV_PIX_FMT_FLAG_RGB
The pixel format contains RGB-like data (as opposed to YUV/grayscale).
 
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
 
@ SWS_POINT
nearest neighbor
 
int src_h
Width and height of the source frame.
 
static void exit_handler(int sig)
 
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
 
static float get_loss(const float ssim[4])
 
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
 
int dst_format
Destination pixel format.
 
#define sws_isSupportedInput(x)
 
static SwsContext * sws[3]
 
void av_log_set_level(int level)
Set the log level.
 
#define i(width, name, range_min, range_max)
 
static const int weights[]
 
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
 
int dst_h
Width and height of the destination frame.
 
static uint64_t ff_sfc64_get(FFSFC64 *s)
 
@ SWS_FULL_CHR_H_INT
Perform full chroma upsampling when upscaling to RGB.
 
static void get_ssim(float ssim[4], const AVFrame *out, const AVFrame *ref, int comps)
 
enum AVPixelFormat av_get_pix_fmt(const char *name)
Return the pixel format corresponding to name.
 
int main(int argc, char **argv)
 
static int ref[MAX_W *MAX_W]
 
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
 
static int bad(InterplayACMContext *s, unsigned ind, unsigned col)
 
int src_format
Source pixel format.
 
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
 
void sws_free_context(SwsContext **ctx)
Free the context and everything associated with it, and write NULL to the provided pointer.
 
int sws_scale_frame(SwsContext *sws, AVFrame *dst, const AVFrame *src)
Scale source data from src and write the output to dst.
 
@ SWS_ACCURATE_RND
Force bit-exact output.
 
Main external API structure.
 
static int fmt_comps(enum AVPixelFormat fmt)
 
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
 
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
 
static double speedup_logavg