2 * Copyright (C) 2003 Michael Niedermayer <michaelni@gmx.at>
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 #undef HAVE_AV_CONFIG_H
30 #include "swscale_internal.h"
33 static uint64_t getSSD(uint8_t *src1
, uint8_t *src2
, int stride1
, int stride2
, int w
, int h
){
37 //printf("%d %d\n", w, h);
41 int d
= src1
[x
+ y
*stride1
] - src2
[x
+ y
*stride2
];
43 //printf("%d", abs(src1[x + y*stride1] - src2[x + y*stride2])/26 );
50 // test by ref -> src -> dst -> out & compare out against ref
52 static int doTest(uint8_t *ref
[3], int refStride
[3], int w
, int h
, int srcFormat
, int dstFormat
,
53 int srcW
, int srcH
, int dstW
, int dstH
, int flags
){
57 int srcStride
[3], dstStride
[3];
59 uint64_t ssdY
, ssdU
, ssdV
;
60 struct SwsContext
*srcContext
, *dstContext
, *outContext
;
65 // avoid stride % bpp != 0
66 if (srcFormat
==PIX_FMT_RGB24
|| srcFormat
==PIX_FMT_BGR24
)
71 if (dstFormat
==PIX_FMT_RGB24
|| dstFormat
==PIX_FMT_BGR24
)
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
);
79 if ((src
[i
] == NULL
) || (dst
[i
] == NULL
) || (out
[i
] == NULL
)) {
87 dstContext
= outContext
= NULL
;
88 srcContext
= sws_getContext(w
, h
, PIX_FMT_YUV420P
, srcW
, srcH
, srcFormat
, flags
, NULL
, NULL
, NULL
);
89 if (srcContext
== NULL
) {
90 fprintf(stderr
, "Failed to get %s ---> %s\n",
91 sws_format_name(PIX_FMT_YUV420P
),
92 sws_format_name(srcFormat
));
97 dstContext
= sws_getContext(srcW
, srcH
, srcFormat
, dstW
, dstH
, dstFormat
, flags
, NULL
, NULL
, NULL
);
98 if (dstContext
== NULL
) {
99 fprintf(stderr
, "Failed to get %s ---> %s\n",
100 sws_format_name(srcFormat
),
101 sws_format_name(dstFormat
));
106 outContext
= sws_getContext(dstW
, dstH
, dstFormat
, w
, h
, PIX_FMT_YUV420P
, flags
, NULL
, NULL
, NULL
);
107 if (outContext
== NULL
) {
108 fprintf(stderr
, "Failed to get %s ---> %s\n",
109 sws_format_name(dstFormat
),
110 sws_format_name(PIX_FMT_YUV420P
));
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]);
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
);
122 #if defined(ARCH_X86)
123 asm volatile ("emms\n\t");
126 ssdY
= getSSD(ref
[0], out
[0], refStride
[0], refStride
[0], w
, h
);
127 ssdU
= getSSD(ref
[1], out
[1], refStride
[1], refStride
[1], (w
+1)>>1, (h
+1)>>1);
128 ssdV
= getSSD(ref
[2], out
[2], refStride
[2], refStride
[2], (w
+1)>>1, (h
+1)>>1);
130 if (srcFormat
== PIX_FMT_GRAY8
|| dstFormat
==PIX_FMT_GRAY8
) ssdU
=ssdV
=0; //FIXME check that output is really gray
136 if (ssdY
>100 || ssdU
>100 || ssdV
>100){
137 printf(" %s %dx%d -> %s %4dx%4d flags=%2d SSD=%5lld,%5lld,%5lld\n",
138 sws_format_name(srcFormat
), srcW
, srcH
,
139 sws_format_name(dstFormat
), dstW
, dstH
,
146 sws_freeContext(srcContext
);
147 sws_freeContext(dstContext
);
148 sws_freeContext(outContext
);
159 void fast_memcpy(void *a
, void *b
, int s
){ //FIXME
163 static void selfTest(uint8_t *src
[3], int stride
[3], int w
, int h
){
164 enum PixelFormat srcFormat
, dstFormat
;
165 int srcW
, srcH
, dstW
, dstH
;
168 for (srcFormat
= 0; srcFormat
< PIX_FMT_NB
; srcFormat
++) {
169 for (dstFormat
= 0; dstFormat
< PIX_FMT_NB
; dstFormat
++) {
171 sws_format_name(srcFormat
),
172 sws_format_name(dstFormat
));
176 for (dstW
=w
- w
/3; dstW
<= 4*w
/3; dstW
+= w
/3){
177 for (dstH
=h
- h
/3; dstH
<= 4*h
/3; dstH
+= h
/3){
178 for (flags
=1; flags
<33; flags
*=2) {
181 res
= doTest(src
, stride
, w
, h
, srcFormat
, dstFormat
,
182 srcW
, srcH
, dstW
, dstH
, flags
);
198 int main(int argc
, char **argv
){
199 uint8_t *rgb_data
= malloc (W
*H
*4);
200 uint8_t *rgb_src
[3]= {rgb_data
, NULL
, NULL
};
201 int rgb_stride
[3]={4*W
, 0, 0};
202 uint8_t *data
= malloc (3*W
*H
);
203 uint8_t *src
[3]= {data
, data
+W
*H
, data
+W
*H
*2};
204 int stride
[3]={W
, W
, W
};
206 struct SwsContext
*sws
;
208 sws
= sws_getContext(W
/12, H
/12, PIX_FMT_RGB32
, W
, H
, PIX_FMT_YUV420P
, 2, NULL
, NULL
, NULL
);
211 for (x
=0; x
<W
*4; x
++){
212 rgb_data
[ x
+ y
*4*W
]= random();
215 #if defined(ARCH_X86)
216 sws_rgb2rgb_init(SWS_CPU_CAPS_MMX
*0);
220 sws_scale(sws
, rgb_src
, rgb_stride
, 0, H
, src
, stride
);
222 #if defined(ARCH_X86)
223 asm volatile ("emms\n\t");
226 selfTest(src
, stride
, W
, H
);