00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <string.h>
00024 #include <inttypes.h>
00025 #include <stdarg.h>
00026
00027 #undef HAVE_AV_CONFIG_H
00028 #include "avutil.h"
00029 #include "swscale.h"
00030 #include "swscale_internal.h"
00031 #include "rgb2rgb.h"
00032
00033 static uint64_t getSSD(uint8_t *src1, uint8_t *src2, int stride1, int stride2, int w, int h){
00034 int x,y;
00035 uint64_t ssd=0;
00036
00037
00038
00039 for (y=0; y<h; y++){
00040 for (x=0; x<w; x++){
00041 int d= src1[x + y*stride1] - src2[x + y*stride2];
00042 ssd+= d*d;
00043
00044 }
00045
00046 }
00047 return ssd;
00048 }
00049
00050
00051
00052 static int doTest(uint8_t *ref[3], int refStride[3], int w, int h, int srcFormat, int dstFormat,
00053 int srcW, int srcH, int dstW, int dstH, int flags){
00054 uint8_t *src[3];
00055 uint8_t *dst[3];
00056 uint8_t *out[3];
00057 int srcStride[3], dstStride[3];
00058 int i;
00059 uint64_t ssdY, ssdU, ssdV;
00060 struct SwsContext *srcContext, *dstContext, *outContext;
00061 int res;
00062
00063 res = 0;
00064 for (i=0; i<3; i++){
00065
00066 if (srcFormat==PIX_FMT_RGB24 || srcFormat==PIX_FMT_BGR24)
00067 srcStride[i]= srcW*3;
00068 else
00069 srcStride[i]= srcW*4;
00070
00071 if (dstFormat==PIX_FMT_RGB24 || dstFormat==PIX_FMT_BGR24)
00072 dstStride[i]= dstW*3;
00073 else
00074 dstStride[i]= dstW*4;
00075
00076 src[i]= (uint8_t*) malloc(srcStride[i]*srcH);
00077 dst[i]= (uint8_t*) malloc(dstStride[i]*dstH);
00078 out[i]= (uint8_t*) malloc(refStride[i]*h);
00079 if (!src[i] || !dst[i] || !out[i]) {
00080 perror("Malloc");
00081 res = -1;
00082
00083 goto end;
00084 }
00085 }
00086
00087 dstContext = outContext = NULL;
00088 srcContext= sws_getContext(w, h, PIX_FMT_YUV420P, srcW, srcH, srcFormat, flags, NULL, NULL, NULL);
00089 if (!srcContext) {
00090 fprintf(stderr, "Failed to get %s ---> %s\n",
00091 sws_format_name(PIX_FMT_YUV420P),
00092 sws_format_name(srcFormat));
00093 res = -1;
00094
00095 goto end;
00096 }
00097 dstContext= sws_getContext(srcW, srcH, srcFormat, dstW, dstH, dstFormat, flags, NULL, NULL, NULL);
00098 if (!dstContext) {
00099 fprintf(stderr, "Failed to get %s ---> %s\n",
00100 sws_format_name(srcFormat),
00101 sws_format_name(dstFormat));
00102 res = -1;
00103
00104 goto end;
00105 }
00106 outContext= sws_getContext(dstW, dstH, dstFormat, w, h, PIX_FMT_YUV420P, flags, NULL, NULL, NULL);
00107 if (!outContext) {
00108 fprintf(stderr, "Failed to get %s ---> %s\n",
00109 sws_format_name(dstFormat),
00110 sws_format_name(PIX_FMT_YUV420P));
00111 res = -1;
00112
00113 goto end;
00114 }
00115
00116
00117
00118 sws_scale(srcContext, ref, refStride, 0, h , src, srcStride);
00119 sws_scale(dstContext, src, srcStride, 0, srcH, dst, dstStride);
00120 sws_scale(outContext, dst, dstStride, 0, dstH, out, refStride);
00121
00122 #if defined(ARCH_X86)
00123 asm volatile ("emms\n\t");
00124 #endif
00125
00126 ssdY= getSSD(ref[0], out[0], refStride[0], refStride[0], w, h);
00127 ssdU= getSSD(ref[1], out[1], refStride[1], refStride[1], (w+1)>>1, (h+1)>>1);
00128 ssdV= getSSD(ref[2], out[2], refStride[2], refStride[2], (w+1)>>1, (h+1)>>1);
00129
00130 if (srcFormat == PIX_FMT_GRAY8 || dstFormat==PIX_FMT_GRAY8) ssdU=ssdV=0;
00131
00132 ssdY/= w*h;
00133 ssdU/= w*h/4;
00134 ssdV/= w*h/4;
00135
00136 if (ssdY>100 || ssdU>100 || ssdV>100){
00137 printf(" %s %dx%d -> %s %4dx%4d flags=%2d SSD=%5lld,%5lld,%5lld\n",
00138 sws_format_name(srcFormat), srcW, srcH,
00139 sws_format_name(dstFormat), dstW, dstH,
00140 flags,
00141 ssdY, ssdU, ssdV);
00142 }
00143
00144 end:
00145
00146 sws_freeContext(srcContext);
00147 sws_freeContext(dstContext);
00148 sws_freeContext(outContext);
00149
00150 for (i=0; i<3; i++){
00151 free(src[i]);
00152 free(dst[i]);
00153 free(out[i]);
00154 }
00155
00156 return res;
00157 }
00158
00159 void fast_memcpy(void *a, void *b, int s){
00160 memcpy(a, b, s);
00161 }
00162
00163 static void selfTest(uint8_t *src[3], int stride[3], int w, int h){
00164 enum PixelFormat srcFormat, dstFormat;
00165 int srcW, srcH, dstW, dstH;
00166 int flags;
00167
00168 for (srcFormat = 0; srcFormat < PIX_FMT_NB; srcFormat++) {
00169 for (dstFormat = 0; dstFormat < PIX_FMT_NB; dstFormat++) {
00170 printf("%s -> %s\n",
00171 sws_format_name(srcFormat),
00172 sws_format_name(dstFormat));
00173
00174 srcW= w;
00175 srcH= h;
00176 for (dstW=w - w/3; dstW<= 4*w/3; dstW+= w/3){
00177 for (dstH=h - h/3; dstH<= 4*h/3; dstH+= h/3){
00178 for (flags=1; flags<33; flags*=2) {
00179 int res;
00180
00181 res = doTest(src, stride, w, h, srcFormat, dstFormat,
00182 srcW, srcH, dstW, dstH, flags);
00183 if (res < 0) {
00184 dstW = 4 * w / 3;
00185 dstH = 4 * h / 3;
00186 flags = 33;
00187 }
00188 }
00189 }
00190 }
00191 }
00192 }
00193 }
00194
00195 #define W 96
00196 #define H 96
00197
00198 int main(int argc, char **argv){
00199 uint8_t *rgb_data = malloc (W*H*4);
00200 uint8_t *rgb_src[3]= {rgb_data, NULL, NULL};
00201 int rgb_stride[3]={4*W, 0, 0};
00202 uint8_t *data = malloc (3*W*H);
00203 uint8_t *src[3]= {data, data+W*H, data+W*H*2};
00204 int stride[3]={W, W, W};
00205 int x, y;
00206 struct SwsContext *sws;
00207
00208 sws= sws_getContext(W/12, H/12, PIX_FMT_RGB32, W, H, PIX_FMT_YUV420P, 2, NULL, NULL, NULL);
00209
00210 for (y=0; y<H; y++){
00211 for (x=0; x<W*4; x++){
00212 rgb_data[ x + y*4*W]= random();
00213 }
00214 }
00215 #if defined(ARCH_X86)
00216 sws_rgb2rgb_init(SWS_CPU_CAPS_MMX*0);
00217 #else
00218 sws_rgb2rgb_init(0);
00219 #endif
00220 sws_scale(sws, rgb_src, rgb_stride, 0, H, src, stride);
00221
00222 #if defined(ARCH_X86)
00223 asm volatile ("emms\n\t");
00224 #endif
00225
00226 selfTest(src, stride, W, H);
00227
00228 return 123;
00229 }