FFmpeg
Loading...
Searching...
No Matches
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"
30#include "libavutil/lfg.h"
31#include "libavutil/mem.h"
33#include "libavutil/pixdesc.h"
34
35#include "libswscale/swscale.h"
36
37#define DEFAULT_W 96
38#define DEFAULT_H 96
39
61
62const char *usage = "floatimg_cmp -pixel_format <pix_fmt> -size <image_size> -ref <testfile>\n";
63
64int main(int argc, char **argv)
65{
66 enum AVPixelFormat inFormat = AV_PIX_FMT_NONE;
67 enum AVPixelFormat dstFormat = AV_PIX_FMT_NONE;
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 {
114bad_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 }
230 sws_freeContext(sws);
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 }
246 sws_freeContext(sws);
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
287end:
288 sws_freeContext(sws);
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}
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
Convenience header that includes libavutil's core.
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define NULL
Definition coverity.c:32
static __device__ float fabsf(float a)
int main
Definition dovi_rpuenc.c:38
#define DEFAULT_H
#define DEFAULT_W
const char * usage
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
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:1626
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:1919
void sws_freeContext(SwsContext *swsContext)
Free the swscaler context swsContext.
Definition utils.c:2250
@ SWS_BILINEAR
bilinear filtering
Definition swscale.h:198
misc image utilities
#define AV_RL32(p)
#define AV_RB32(p)
av_cold void av_lfg_init(AVLFG *c, unsigned int seed)
Definition lfg.c:32
static unsigned int av_lfg_get(AVLFG *c)
Get the next random unsigned 32-bit number using an ALFG.
Definition lfg.h:53
static enum AVPixelFormat pix_fmts[]
Definition libkvazaar.c:296
const char * desc
Definition libsvtav1.c:83
uint8_t w
Definition llvidencdsp.c:39
#define FFMIN(a, b)
Definition macros.h:49
#define FFMAX(a, b)
Definition macros.h:47
#define FFALIGN(x, a)
Definition macros.h:78
Memory handling functions.
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
misc parsing utilities
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:3380
enum AVPixelFormat av_get_pix_fmt(const char *name)
Return the pixel format corresponding to name.
Definition pixdesc.c:3392
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3460
#define AV_PIX_FMT_FLAG_FLOAT
The pixel format contains IEEE-754 floating point values.
Definition pixdesc.h:158
#define AV_PIX_FMT_FLAG_BE
Pixel format is big-endian.
Definition pixdesc.h:116
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ AV_PIX_FMT_NONE
Definition pixfmt.h:72
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition pixfmt.h:75
@ AV_PIX_FMT_BGR0
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
Definition pixfmt.h:265
@ AV_PIX_FMT_GBRP9LE
planar GBR 4:4:4 27bpp, little-endian
Definition pixfmt.h:168
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition pixfmt.h:99
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition pixfmt.h:102
@ AV_PIX_FMT_ABGR
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition pixfmt.h:101
@ 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
@ AV_PIX_FMT_0BGR
packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined
Definition pixfmt.h:264
@ AV_PIX_FMT_YUV444P14LE
planar YUV 4:4:4,42bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition pixfmt.h:278
@ AV_PIX_FMT_GBRPF32LE
IEEE-754 single precision planar GBR 4:4:4, 96bpp, little-endian.
Definition pixfmt.h:342
@ AV_PIX_FMT_GBRP10MSBLE
planar GBR 4:4:4 30bpp, lowest bits zero, little-endian
Definition pixfmt.h:496
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition pixfmt.h:100
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition pixfmt.h:78
@ 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_GBRAP
planar GBRA 4:4:4:4 32bpp
Definition pixfmt.h:212
@ AV_PIX_FMT_GBRP12LE
planar GBR 4:4:4 36bpp, little-endian
Definition pixfmt.h:280
@ 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
@ AV_PIX_FMT_GBRAP12LE
planar GBR 4:4:4:4 48bpp, little-endian
Definition pixfmt.h:311
@ 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_GBRP12MSBLE
planar GBR 4:4:4 36bpp, lowest bits zero, little-endian
Definition pixfmt.h:498
@ 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
@ AV_PIX_FMT_GBRP14LE
planar GBR 4:4:4 42bpp, little-endian
Definition pixfmt.h:282
@ AV_PIX_FMT_RGB0
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
Definition pixfmt.h:263
@ AV_PIX_FMT_GBRP10LE
planar GBR 4:4:4 30bpp, little-endian
Definition pixfmt.h:170
@ 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
@ 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
@ AV_PIX_FMT_GBRAP10LE
planar GBR 4:4:4:4 40bpp, little-endian
Definition pixfmt.h:314
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition pixfmt.h:76
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
Definition pixfmt.h:165
@ AV_PIX_FMT_GBRAP16LE
planar GBRA 4:4:4:4 64bpp, little-endian
Definition pixfmt.h:214
@ 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_0RGB
packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined
Definition pixfmt.h:262
@ AV_PIX_FMT_GBRP16LE
planar GBR 4:4:4 48bpp, little-endian
Definition pixfmt.h:172
@ 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_YUV444P12LE
planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition pixfmt.h:276
#define FF_ARRAY_ELEMS(a)
Context structure for the Lagged Fibonacci PRNG.
Definition lfg.h:33
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition pixdesc.h:69
Main external API structure.
Definition swscale.h:227
external API header
#define av_mallocz(s)
#define av_freep(p)
static FILE * out
Definition movenc.c:55
int size
uint32_t i
Definition intfloat.h:28
static av_always_inline int diff(const struct color_info *a, const struct color_info *b, const int trans_thresh)