FFmpeg
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
floatimg_cmp.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <math.h>
23 #include <inttypes.h>
24 #include <float.h>
25 
26 #include "libavutil/avutil.h"
27 #include "libavutil/imgutils.h"
28 #include "libavutil/intfloat.h"
29 #include "libavutil/intreadwrite.h"
30 #include "libavutil/lfg.h"
31 #include "libavutil/mem.h"
32 #include "libavutil/parseutils.h"
33 #include "libavutil/pixdesc.h"
34 
35 #include "libswscale/swscale.h"
36 
37 #define DEFAULT_W 96
38 #define DEFAULT_H 96
39 
40 static const enum AVPixelFormat pix_fmts[] = {
60 };
61 
62 const char *usage = "floatimg_cmp -pixel_format <pix_fmt> -size <image_size> -ref <testfile>\n";
63 
64 int main(int argc, char **argv)
65 {
66  enum AVPixelFormat inFormat = AV_PIX_FMT_NONE;
67  enum AVPixelFormat dstFormat = AV_PIX_FMT_NONE;
68  const AVPixFmtDescriptor *desc;
69  uint8_t *ptr;
70  uint32_t *in, *out;
71 
72  uint8_t *rgbIn[4] = {NULL, NULL, NULL, NULL};
73  uint8_t *rgbOut[4] = {NULL, NULL, NULL, NULL};
74  int rgbStride[4];
75 
76  uint8_t *dst[4] = {NULL, NULL, NULL, NULL};
77  int dstStride[4];
78 
79  int i, x, y, p, size, count;
80  int res = -1;
81  int w = -1;
82  int h = -1;
83  union av_intfloat32 v0, v1;
84 
85  double sum;
86  float minimum, maximum, diff;
87 
88  SwsContext *sws = NULL;
89  AVLFG rand;
90  FILE *fp = NULL;
91 
92  for (i = 1; i < argc; i += 2) {
93  if (argv[i][0] != '-' || i + 1 == argc)
94  goto bad_option;
95  if (!strcmp(argv[i], "-ref")) {
96  fp = fopen(argv[i + 1], "rb");
97  if (!fp) {
98  fprintf(stderr, "could not open '%s'\n", argv[i + 1]);
99  goto end;
100  }
101  } else if (!strcmp(argv[i], "-size")) {
102  res = av_parse_video_size(&w, &h, argv[i + 1]);
103  if (res < 0) {
104  fprintf(stderr, "invalid video size %s\n", argv[i + 1]);
105  goto end;
106  }
107  } else if (!strcmp(argv[i], "-pixel_format")) {
108  inFormat = av_get_pix_fmt(argv[i + 1]);
109  if (inFormat == AV_PIX_FMT_NONE) {
110  fprintf(stderr, "invalid pixel format %s\n", argv[i + 1]);
111  goto end;
112  }
113  } else {
114 bad_option:
115  fprintf(stderr, "%s", usage);
116  fprintf(stderr, "bad option or argument missing (%s)\n", argv[i]);
117  goto end;
118  };
119  }
120 
121  if (!fp) {
122  inFormat = AV_PIX_FMT_GBRPF32LE;
123  w = DEFAULT_W;
124  h = DEFAULT_H;
125  }
126 
127  if (w <= 0 || h <= 0) {
128  fprintf(stderr, "%s", usage);
129  fprintf(stderr, "invalid -video_size\n");
130  goto end;
131  }
132 
133  if (inFormat == AV_PIX_FMT_NONE) {
134  fprintf(stderr, "%s", usage);
135  fprintf(stderr, "invalid input pixel format\n");
136  goto end;
137  }
138 
139  desc = av_pix_fmt_desc_get(inFormat);
140  if (!(desc->flags & AV_PIX_FMT_FLAG_FLOAT)) {
141  fprintf(stderr, "input pixel format not floating point.\n");
142  goto end;
143  }
144 
145  res = av_image_fill_linesizes(rgbStride, inFormat, w);
146  if (res < 0) {
147  fprintf(stderr, "av_image_fill_linesizes failed\n");
148  goto end;
149  }
150  for (p = 0; p < 4; p++) {
151  rgbStride[p] = FFALIGN(rgbStride[p], 16);
152  if (rgbStride[p]) {
153  rgbIn[p] = av_mallocz(rgbStride[p] * h + 16);
154  rgbOut[p] = av_mallocz(rgbStride[p] * h + 16);
155  }
156  if (rgbStride[p] && (!rgbIn[p] || !rgbOut[p])) {
157  goto end;
158  }
159  }
160 
161  for (i = 0; i < FF_ARRAY_ELEMS(pix_fmts); i++) {
162  dstFormat = pix_fmts[i];
163  if (fp) {
164  fseek(fp, 0, SEEK_SET);
165  for (p = 0; p < 4; p++) {
166  if (!rgbStride[p])
167  continue;
168 
169  ptr = rgbIn[p];
170  for (y = 0; y < h; y++) {
171  size = fread(ptr, 1, w*4, fp);
172  if (size != w*4) {
173  fprintf(stderr, "read error: %d\n", size);
174  goto end;
175  }
176  ptr += rgbStride[p];
177  }
178  }
179  } else {
180  // fill src with random values between 0.0 - 1.0
181  av_lfg_init(&rand, 1);
182  for (p = 0; p < 4; p++) {
183  if (!rgbStride[p])
184  continue;
185 
186  for (y = 0; y < h; y++) {
187  in = (uint32_t*)(rgbIn[p] + y * rgbStride[p]);
188  for (x = 0; x < w; x++) {
189  v0.f = (float)av_lfg_get(&rand)/(float)(UINT32_MAX);
190  *in++ = AV_RL32(&v0.i);
191  }
192  }
193  }
194  }
195 
196  // setup intermediate image
197  for (p = 0; p < 4; p++) {
198  av_freep(&dst[p]);
199  }
200 
201  res = av_image_fill_linesizes(dstStride, dstFormat, w);
202  if (res < 0) {
203  fprintf(stderr, "av_image_fill_linesizes failed\n");
204  goto end;
205  }
206  for (p = 0; p < 4; p++) {
207  dstStride[p] = FFALIGN(dstStride[p], 16);
208  if (dstStride[p]) {
209  dst[p] = av_mallocz(dstStride[p] * h + 16);
210  }
211  if (dstStride[p] && !dst[p]) {
212  goto end;
213  }
214  }
215 
216  // srcFormat -> dstFormat
217  sws = sws_getContext(w, h, inFormat, w, h,
218  dstFormat, SWS_BILINEAR, NULL, NULL, NULL);
219  if (!sws) {
220  fprintf(stderr, "Failed to get %s -> %s\n", av_get_pix_fmt_name(inFormat), av_get_pix_fmt_name(dstFormat) );
221  goto end;
222  }
223 
224  res = sws_scale(sws, (const uint8_t *const *)rgbIn, rgbStride, 0, h, dst, dstStride);
225  if (res < 0 || res != h) {
226  fprintf(stderr, "sws_scale failed\n");
227  res = -1;
228  goto end;
229  }
231 
232  // dstFormat -> srcFormat
233  sws = sws_getContext(w, h, dstFormat, w, h,
234  inFormat, SWS_BILINEAR, NULL, NULL, NULL);
235  if(!sws) {
236  fprintf(stderr, "Failed to get %s -> %s\n", av_get_pix_fmt_name(dstFormat), av_get_pix_fmt_name(inFormat) );
237  goto end;
238  }
239 
240  res = sws_scale(sws, (const uint8_t *const *)dst, dstStride, 0, h, rgbOut, rgbStride);
241  if (res < 0 || res != h) {
242  fprintf(stderr, "sws_scale failed\n");
243  res = -1;
244  goto end;
245  }
247  sws = NULL;
248 
249  minimum = FLT_MAX;
250  maximum = -FLT_MAX;
251  count = 0;
252  sum = 0.0;
253 
254  for (p = 0; p < 4; p++) {
255  if (!rgbStride[p])
256  continue;
257 
258  for (y = 0; y < h; y++) {
259  in = (uint32_t*)(rgbIn[p] + y * rgbStride[p]);
260  out = (uint32_t*)(rgbOut[p] + y * rgbStride[p]);
261  for (x = 0; x < w; x++) {
262  if (desc->flags & AV_PIX_FMT_FLAG_BE) {
263  v0.i = AV_RB32(in);
264  v1.i = AV_RB32(out);
265  } else {
266  v0.i = AV_RL32(in);
267  v1.i = AV_RL32(out);
268  }
269 
270  diff = fabsf(v0.f - v1.f);
271  sum += diff;
272  minimum = FFMIN(minimum, diff);
273  maximum = FFMAX(maximum, diff);
274 
275  count++;
276  in++;
277  out++;
278  }
279  }
280  }
281 
282  fprintf(stdout, "%s -> %s -> %s\n", av_get_pix_fmt_name(inFormat), av_get_pix_fmt_name(dstFormat), av_get_pix_fmt_name(inFormat) );
283  fprintf(stdout, "avg diff: %f\nmin diff: %f\nmax diff: %f\n", sum / count, minimum, maximum);
284  res = 0;
285  }
286 
287 end:
289  for (p = 0; p < 4; p++) {
290  av_freep(&rgbIn[p]);
291  av_freep(&rgbOut[p]);
292  av_freep(&dst[p]);
293  }
294  if (fp)
295  fclose(fp);
296 
297  return res;
298 }
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
AV_PIX_FMT_BGR48LE
@ AV_PIX_FMT_BGR48LE
packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as lit...
Definition: pixfmt.h:146
out
FILE * out
Definition: movenc.c:55
av_lfg_init
av_cold void av_lfg_init(AVLFG *c, unsigned int seed)
Definition: lfg.c:32
main
int main(int argc, char **argv)
Definition: floatimg_cmp.c:64
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3441
AV_PIX_FMT_FLAG_FLOAT
#define AV_PIX_FMT_FLAG_FLOAT
The pixel format contains IEEE-754 floating point values.
Definition: pixdesc.h:158
sws_freeContext
void sws_freeContext(SwsContext *swsContext)
Free the swscaler context swsContext.
Definition: utils.c:2244
pixdesc.h
w
uint8_t w
Definition: llviddspenc.c:38
av_intfloat32::i
uint32_t i
Definition: intfloat.h:28
SWS_BILINEAR
@ SWS_BILINEAR
bilinear filtering
Definition: swscale.h:99
DEFAULT_H
#define DEFAULT_H
Definition: floatimg_cmp.c:38
float.h
AV_PIX_FMT_BGR24
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:76
AV_PIX_FMT_BGRA
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:102
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
intfloat.h
AV_PIX_FMT_YUV444P16LE
@ AV_PIX_FMT_YUV444P16LE
planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:132
AV_PIX_FMT_GBRAP12LE
@ AV_PIX_FMT_GBRAP12LE
planar GBR 4:4:4:4 48bpp, little-endian
Definition: pixfmt.h:311
AV_PIX_FMT_GBRAP
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:212
fabsf
static __device__ float fabsf(float a)
Definition: cuda_runtime.h:181
DEFAULT_W
#define DEFAULT_W
Definition: floatimg_cmp.c:37
AV_PIX_FMT_YUV444P12LE
@ AV_PIX_FMT_YUV444P12LE
planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:276
AV_PIX_FMT_YUV444P14LE
@ AV_PIX_FMT_YUV444P14LE
planar YUV 4:4:4,42bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:278
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
float
float
Definition: af_crystalizer.c:122
av_image_fill_linesizes
int av_image_fill_linesizes(int linesizes[4], enum AVPixelFormat pix_fmt, int width)
Fill plane linesizes for an image with pixel format pix_fmt and width width.
Definition: imgutils.c:89
intreadwrite.h
AV_PIX_FMT_GBRP16LE
@ AV_PIX_FMT_GBRP16LE
planar GBR 4:4:4 48bpp, little-endian
Definition: pixfmt.h:172
av_lfg_get
static unsigned int av_lfg_get(AVLFG *c)
Get the next random unsigned 32-bit number using an ALFG.
Definition: lfg.h:53
lfg.h
AV_PIX_FMT_GBRP12LE
@ AV_PIX_FMT_GBRP12LE
planar GBR 4:4:4 36bpp, little-endian
Definition: pixfmt.h:280
AV_PIX_FMT_GBRP10LE
@ AV_PIX_FMT_GBRP10LE
planar GBR 4:4:4 30bpp, little-endian
Definition: pixfmt.h:170
AV_PIX_FMT_RGBA
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:100
AV_PIX_FMT_YUV444P10LE
@ AV_PIX_FMT_YUV444P10LE
planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:162
AV_PIX_FMT_GBRP10MSBLE
@ AV_PIX_FMT_GBRP10MSBLE
planar GBR 4:4:4 30bpp, lowest bits zero, little-endian
Definition: pixfmt.h:496
NULL
#define NULL
Definition: coverity.c:32
AV_PIX_FMT_RGB48LE
@ AV_PIX_FMT_RGB48LE
packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as lit...
Definition: pixfmt.h:110
AV_PIX_FMT_RGBA64LE
@ AV_PIX_FMT_RGBA64LE
packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is st...
Definition: pixfmt.h:203
parseutils.h
AV_PIX_FMT_BGR0
@ AV_PIX_FMT_BGR0
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
Definition: pixfmt.h:265
av_intfloat32
Definition: intfloat.h:27
AV_PIX_FMT_GBRP12MSBLE
@ AV_PIX_FMT_GBRP12MSBLE
planar GBR 4:4:4 36bpp, lowest bits zero, little-endian
Definition: pixfmt.h:498
AV_PIX_FMT_ABGR
@ AV_PIX_FMT_ABGR
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition: pixfmt.h:101
usage
const char * usage
Definition: floatimg_cmp.c:62
AV_PIX_FMT_YUV444P10MSBLE
@ AV_PIX_FMT_YUV444P10MSBLE
planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), lowest bits zero, little-endian
Definition: pixfmt.h:492
AVLFG
Context structure for the Lagged Fibonacci PRNG.
Definition: lfg.h:33
AV_PIX_FMT_RGB24
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:75
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
size
int size
Definition: twinvq_data.h:10344
AV_RB32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:96
diff
static av_always_inline int diff(const struct color_info *a, const struct color_info *b, const int trans_thresh)
Definition: vf_paletteuse.c:166
AV_PIX_FMT_GBRP9LE
@ AV_PIX_FMT_GBRP9LE
planar GBR 4:4:4 27bpp, little-endian
Definition: pixfmt.h:168
AV_PIX_FMT_GBRAP10LE
@ AV_PIX_FMT_GBRAP10LE
planar GBR 4:4:4:4 40bpp, little-endian
Definition: pixfmt.h:314
AV_PIX_FMT_RGB0
@ AV_PIX_FMT_RGB0
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
Definition: pixfmt.h:263
av_parse_video_size
int av_parse_video_size(int *width_ptr, int *height_ptr, const char *str)
Parse str and put in width_ptr and height_ptr the detected values.
Definition: parseutils.c:150
AV_PIX_FMT_ARGB
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:99
AV_PIX_FMT_BGRA64LE
@ AV_PIX_FMT_BGRA64LE
packed RGBA 16:16:16:16, 64bpp, 16B, 16G, 16R, 16A, the 2-byte value for each R/G/B/A component is st...
Definition: pixfmt.h:205
sws
static SwsContext * sws[3]
Definition: swscale.c:73
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AV_PIX_FMT_FLAG_BE
#define AV_PIX_FMT_FLAG_BE
Pixel format is big-endian.
Definition: pixdesc.h:116
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
AV_PIX_FMT_GBRPF32LE
@ AV_PIX_FMT_GBRPF32LE
IEEE-754 single precision planar GBR 4:4:4, 96bpp, little-endian.
Definition: pixfmt.h:342
AV_PIX_FMT_GBRAP16LE
@ AV_PIX_FMT_GBRAP16LE
planar GBRA 4:4:4:4 64bpp, little-endian
Definition: pixfmt.h:214
AV_PIX_FMT_0BGR
@ AV_PIX_FMT_0BGR
packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined
Definition: pixfmt.h:264
sws_getContext
SwsContext * sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat, int dstW, int dstH, enum AVPixelFormat dstFormat, int flags, SwsFilter *srcFilter, SwsFilter *dstFilter, const double *param)
Allocate and return an SwsContext.
Definition: utils.c:1913
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:92
av_get_pix_fmt
enum AVPixelFormat av_get_pix_fmt(const char *name)
Return the pixel format corresponding to name.
Definition: pixdesc.c:3373
sws_scale
int attribute_align_arg sws_scale(SwsContext *sws, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[])
swscale wrapper, so we don't need to export the SwsContext.
Definition: swscale.c:1502
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
AV_PIX_FMT_YUV444P9LE
@ AV_PIX_FMT_YUV444P9LE
planar YUV 4:4:4, 27bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:160
AV_PIX_FMT_YUV444P
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:78
av_intfloat32::f
float f
Definition: intfloat.h:29
AV_PIX_FMT_GBRP
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:165
desc
const char * desc
Definition: libsvtav1.c:79
avutil.h
mem.h
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
AV_PIX_FMT_GBRP14LE
@ AV_PIX_FMT_GBRP14LE
planar GBR 4:4:4 42bpp, little-endian
Definition: pixfmt.h:282
AV_PIX_FMT_YUV444P12MSBLE
@ AV_PIX_FMT_YUV444P12MSBLE
planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), lowest bits zero, little-endian
Definition: pixfmt.h:494
imgutils.h
AV_PIX_FMT_0RGB
@ AV_PIX_FMT_0RGB
packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined
Definition: pixfmt.h:262
h
h
Definition: vp9dsp_template.c:2070
SwsContext
Main external API structure.
Definition: swscale.h:182
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: floatimg_cmp.c:40
swscale.h
av_get_pix_fmt_name
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.
Definition: pixdesc.c:3361