Commit | Line | Data |
---|---|---|
c9b99ea6 | 1 | /* |
d026b45e DB |
2 | * Copyright (C) 2003 Michael Niedermayer <michaelni@gmx.at> |
3 | * | |
4 | * This file is part of FFmpeg. | |
5 | * | |
54e3ae2e DB |
6 | * FFmpeg is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU Lesser General Public | |
8 | * License as published by the Free Software Foundation; either | |
9 | * version 2.1 of the License, or (at your option) any later version. | |
d026b45e DB |
10 | * |
11 | * FFmpeg is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
54e3ae2e DB |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | * Lesser General Public License for more details. | |
d026b45e | 15 | * |
54e3ae2e DB |
16 | * You should have received a copy of the GNU Lesser General Public |
17 | * License along with FFmpeg; if not, write to the Free Software | |
b19bcbaa | 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
d026b45e | 19 | */ |
c9b99ea6 MN |
20 | |
21 | #include <stdio.h> | |
22 | #include <stdlib.h> | |
23 | #include <string.h> | |
24 | #include <inttypes.h> | |
25 | #include <stdarg.h> | |
26 | ||
e9e12f0e | 27 | #undef HAVE_AV_CONFIG_H |
83da2c6f | 28 | #include "libavutil/avutil.h" |
9a034dde | 29 | #include "libavutil/lfg.h" |
c9b99ea6 | 30 | #include "swscale.h" |
8335a9f0 | 31 | #include "swscale_internal.h" |
c9b99ea6 | 32 | |
c9b99ea6 | 33 | static uint64_t getSSD(uint8_t *src1, uint8_t *src2, int stride1, int stride2, int w, int h){ |
221b804f DB |
34 | int x,y; |
35 | uint64_t ssd=0; | |
c9b99ea6 MN |
36 | |
37 | //printf("%d %d\n", w, h); | |
6a4970ab | 38 | |
221b804f DB |
39 | for (y=0; y<h; y++){ |
40 | for (x=0; x<w; x++){ | |
41 | int d= src1[x + y*stride1] - src2[x + y*stride2]; | |
42 | ssd+= d*d; | |
c9b99ea6 | 43 | //printf("%d", abs(src1[x + y*stride1] - src2[x + y*stride2])/26 ); |
221b804f | 44 | } |
c9b99ea6 | 45 | //printf("\n"); |
221b804f DB |
46 | } |
47 | return ssd; | |
c9b99ea6 MN |
48 | } |
49 | ||
50 | // test by ref -> src -> dst -> out & compare out against ref | |
51 | // ref & out are YV12 | |
6a4970ab | 52 | static int doTest(uint8_t *ref[3], int refStride[3], int w, int h, int srcFormat, int dstFormat, |
221b804f DB |
53 | int srcW, int srcH, int dstW, int dstH, int flags){ |
54 | uint8_t *src[3]; | |
55 | uint8_t *dst[3]; | |
56 | uint8_t *out[3]; | |
57 | int srcStride[3], dstStride[3]; | |
58 | int i; | |
59 | uint64_t ssdY, ssdU, ssdV; | |
60 | struct SwsContext *srcContext, *dstContext, *outContext; | |
61 | int res; | |
62 | ||
63 | res = 0; | |
64 | for (i=0; i<3; i++){ | |
65 | // avoid stride % bpp != 0 | |
66 | if (srcFormat==PIX_FMT_RGB24 || srcFormat==PIX_FMT_BGR24) | |
67 | srcStride[i]= srcW*3; | |
68 | else | |
69 | srcStride[i]= srcW*4; | |
70 | ||
71 | if (dstFormat==PIX_FMT_RGB24 || dstFormat==PIX_FMT_BGR24) | |
72 | dstStride[i]= dstW*3; | |
73 | else | |
74 | dstStride[i]= dstW*4; | |
75 | ||
76 | src[i]= (uint8_t*) malloc(srcStride[i]*srcH); | |
77 | dst[i]= (uint8_t*) malloc(dstStride[i]*dstH); | |
78 | out[i]= (uint8_t*) malloc(refStride[i]*h); | |
1b0a4572 | 79 | if (!src[i] || !dst[i] || !out[i]) { |
221b804f DB |
80 | perror("Malloc"); |
81 | res = -1; | |
82 | ||
83 | goto end; | |
84 | } | |
85 | } | |
86 | ||
87 | dstContext = outContext = NULL; | |
88 | srcContext= sws_getContext(w, h, PIX_FMT_YUV420P, srcW, srcH, srcFormat, flags, NULL, NULL, NULL); | |
1b0a4572 | 89 | if (!srcContext) { |
221b804f DB |
90 | fprintf(stderr, "Failed to get %s ---> %s\n", |
91 | sws_format_name(PIX_FMT_YUV420P), | |
92 | sws_format_name(srcFormat)); | |
93 | res = -1; | |
94 | ||
95 | goto end; | |
96 | } | |
97 | dstContext= sws_getContext(srcW, srcH, srcFormat, dstW, dstH, dstFormat, flags, NULL, NULL, NULL); | |
1b0a4572 | 98 | if (!dstContext) { |
221b804f DB |
99 | fprintf(stderr, "Failed to get %s ---> %s\n", |
100 | sws_format_name(srcFormat), | |
101 | sws_format_name(dstFormat)); | |
102 | res = -1; | |
103 | ||
104 | goto end; | |
105 | } | |
106 | outContext= sws_getContext(dstW, dstH, dstFormat, w, h, PIX_FMT_YUV420P, flags, NULL, NULL, NULL); | |
1b0a4572 | 107 | if (!outContext) { |
221b804f DB |
108 | fprintf(stderr, "Failed to get %s ---> %s\n", |
109 | sws_format_name(dstFormat), | |
110 | sws_format_name(PIX_FMT_YUV420P)); | |
111 | res = -1; | |
112 | ||
113 | goto end; | |
114 | } | |
115 | // printf("test %X %X %X -> %X %X %X\n", (int)ref[0], (int)ref[1], (int)ref[2], | |
116 | // (int)src[0], (int)src[1], (int)src[2]); | |
117 | ||
118 | sws_scale(srcContext, ref, refStride, 0, h , src, srcStride); | |
119 | sws_scale(dstContext, src, srcStride, 0, srcH, dst, dstStride); | |
120 | sws_scale(outContext, dst, dstStride, 0, dstH, out, refStride); | |
27161c06 | 121 | |
221b804f DB |
122 | ssdY= getSSD(ref[0], out[0], refStride[0], refStride[0], w, h); |
123 | ssdU= getSSD(ref[1], out[1], refStride[1], refStride[1], (w+1)>>1, (h+1)>>1); | |
124 | ssdV= getSSD(ref[2], out[2], refStride[2], refStride[2], (w+1)>>1, (h+1)>>1); | |
6a4970ab | 125 | |
221b804f | 126 | if (srcFormat == PIX_FMT_GRAY8 || dstFormat==PIX_FMT_GRAY8) ssdU=ssdV=0; //FIXME check that output is really gray |
6a4970ab | 127 | |
221b804f DB |
128 | ssdY/= w*h; |
129 | ssdU/= w*h/4; | |
130 | ssdV/= w*h/4; | |
6a4970ab | 131 | |
ed2164f3 DB |
132 | printf(" %s %dx%d -> %s %4dx%4d flags=%2d SSD=%5lld,%5lld,%5lld\n", |
133 | sws_format_name(srcFormat), srcW, srcH, | |
134 | sws_format_name(dstFormat), dstW, dstH, | |
135 | flags, ssdY, ssdU, ssdV); | |
136 | fflush(stdout); | |
c9b99ea6 | 137 | |
221b804f | 138 | end: |
6a4970ab | 139 | |
221b804f DB |
140 | sws_freeContext(srcContext); |
141 | sws_freeContext(dstContext); | |
142 | sws_freeContext(outContext); | |
c9b99ea6 | 143 | |
221b804f DB |
144 | for (i=0; i<3; i++){ |
145 | free(src[i]); | |
146 | free(dst[i]); | |
147 | free(out[i]); | |
148 | } | |
c9b99ea6 | 149 | |
221b804f | 150 | return res; |
c9b99ea6 MN |
151 | } |
152 | ||
c9b99ea6 | 153 | static void selfTest(uint8_t *src[3], int stride[3], int w, int h){ |
221b804f DB |
154 | enum PixelFormat srcFormat, dstFormat; |
155 | int srcW, srcH, dstW, dstH; | |
156 | int flags; | |
157 | ||
158 | for (srcFormat = 0; srcFormat < PIX_FMT_NB; srcFormat++) { | |
159 | for (dstFormat = 0; dstFormat < PIX_FMT_NB; dstFormat++) { | |
160 | printf("%s -> %s\n", | |
161 | sws_format_name(srcFormat), | |
162 | sws_format_name(dstFormat)); | |
ae9e0e83 | 163 | fflush(stdout); |
221b804f DB |
164 | |
165 | srcW= w; | |
166 | srcH= h; | |
167 | for (dstW=w - w/3; dstW<= 4*w/3; dstW+= w/3){ | |
168 | for (dstH=h - h/3; dstH<= 4*h/3; dstH+= h/3){ | |
169 | for (flags=1; flags<33; flags*=2) { | |
170 | int res; | |
171 | ||
172 | res = doTest(src, stride, w, h, srcFormat, dstFormat, | |
173 | srcW, srcH, dstW, dstH, flags); | |
174 | if (res < 0) { | |
175 | dstW = 4 * w / 3; | |
176 | dstH = 4 * h / 3; | |
177 | flags = 33; | |
178 | } | |
179 | } | |
180 | } | |
181 | } | |
182 | } | |
183 | } | |
c9b99ea6 MN |
184 | } |
185 | ||
186 | #define W 96 | |
187 | #define H 96 | |
188 | ||
189 | int main(int argc, char **argv){ | |
221b804f DB |
190 | uint8_t *rgb_data = malloc (W*H*4); |
191 | uint8_t *rgb_src[3]= {rgb_data, NULL, NULL}; | |
192 | int rgb_stride[3]={4*W, 0, 0}; | |
193 | uint8_t *data = malloc (3*W*H); | |
194 | uint8_t *src[3]= {data, data+W*H, data+W*H*2}; | |
195 | int stride[3]={W, W, W}; | |
196 | int x, y; | |
197 | struct SwsContext *sws; | |
9a034dde | 198 | AVLFG rand; |
221b804f DB |
199 | |
200 | sws= sws_getContext(W/12, H/12, PIX_FMT_RGB32, W, H, PIX_FMT_YUV420P, 2, NULL, NULL, NULL); | |
201 | ||
9a034dde RP |
202 | av_lfg_init(&rand, 1); |
203 | ||
221b804f DB |
204 | for (y=0; y<H; y++){ |
205 | for (x=0; x<W*4; x++){ | |
9a034dde | 206 | rgb_data[ x + y*4*W]= av_lfg_get(&rand); |
221b804f DB |
207 | } |
208 | } | |
e5091488 | 209 | sws_scale(sws, rgb_src, rgb_stride, 0, H, src, stride); |
27161c06 | 210 | |
e5091488 | 211 | selfTest(src, stride, W, H); |
516b1f82 | 212 | |
221b804f | 213 | return 123; |
c9b99ea6 | 214 | } |