Libav
|
00001 /* 00002 * Copyright (C) 2002 Michael Niedermayer <michaelni@gmx.at> 00003 * 00004 * This file is part of FFmpeg. 00005 * 00006 * FFmpeg is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * FFmpeg is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with FFmpeg; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00020 00021 #include <stdio.h> 00022 #include <string.h> /* for memset() */ 00023 #include <unistd.h> 00024 #include <stdlib.h> 00025 #include <inttypes.h> 00026 00027 #include "swscale.h" 00028 #include "rgb2rgb.h" 00029 00030 #define SIZE 1000 00031 #define srcByte 0x55 00032 #define dstByte 0xBB 00033 00034 #define FUNC(s,d,n) {s,d,#n,n} 00035 00036 static int cpu_caps; 00037 00038 static char *args_parse(int argc, char *argv[]) 00039 { 00040 int o; 00041 00042 while ((o = getopt(argc, argv, "m23")) != -1) { 00043 switch (o) { 00044 case 'm': 00045 cpu_caps |= SWS_CPU_CAPS_MMX; 00046 break; 00047 case '2': 00048 cpu_caps |= SWS_CPU_CAPS_MMX2; 00049 break; 00050 case '3': 00051 cpu_caps |= SWS_CPU_CAPS_3DNOW; 00052 break; 00053 default: 00054 av_log(NULL, AV_LOG_ERROR, "Unknown option %c\n", o); 00055 } 00056 } 00057 00058 return argv[optind]; 00059 } 00060 00061 int main(int argc, char **argv) 00062 { 00063 int i, funcNum; 00064 uint8_t *srcBuffer= (uint8_t*)av_malloc(SIZE); 00065 uint8_t *dstBuffer= (uint8_t*)av_malloc(SIZE); 00066 int failedNum=0; 00067 int passedNum=0; 00068 00069 if (!srcBuffer || !dstBuffer) 00070 return -1; 00071 00072 av_log(NULL, AV_LOG_INFO, "memory corruption test ...\n"); 00073 args_parse(argc, argv); 00074 av_log(NULL, AV_LOG_INFO, "CPU capabilities forced to %x\n", cpu_caps); 00075 sws_rgb2rgb_init(cpu_caps); 00076 00077 for(funcNum=0; ; funcNum++) { 00078 struct func_info_s { 00079 int src_bpp; 00080 int dst_bpp; 00081 const char *name; 00082 void (*func)(const uint8_t *src, uint8_t *dst, long src_size); 00083 } func_info[] = { 00084 FUNC(2, 2, rgb15to16), 00085 FUNC(2, 3, rgb15to24), 00086 FUNC(2, 4, rgb15to32), 00087 FUNC(2, 3, rgb16to24), 00088 FUNC(2, 4, rgb16to32), 00089 FUNC(3, 2, rgb24to15), 00090 FUNC(3, 2, rgb24to16), 00091 FUNC(3, 4, rgb24to32), 00092 FUNC(4, 2, rgb32to15), 00093 FUNC(4, 2, rgb32to16), 00094 FUNC(4, 3, rgb32to24), 00095 FUNC(2, 2, rgb16to15), 00096 FUNC(2, 2, rgb15tobgr15), 00097 FUNC(2, 2, rgb15tobgr16), 00098 FUNC(2, 3, rgb15tobgr24), 00099 FUNC(2, 4, rgb15tobgr32), 00100 FUNC(2, 2, rgb16tobgr15), 00101 FUNC(2, 2, rgb16tobgr16), 00102 FUNC(2, 3, rgb16tobgr24), 00103 FUNC(2, 4, rgb16tobgr32), 00104 FUNC(3, 2, rgb24tobgr15), 00105 FUNC(3, 2, rgb24tobgr16), 00106 FUNC(3, 3, rgb24tobgr24), 00107 FUNC(3, 4, rgb24tobgr32), 00108 FUNC(4, 2, rgb32tobgr15), 00109 FUNC(4, 2, rgb32tobgr16), 00110 FUNC(4, 3, rgb32tobgr24), 00111 FUNC(4, 4, rgb32tobgr32), 00112 FUNC(0, 0, NULL) 00113 }; 00114 int width; 00115 int failed=0; 00116 int srcBpp=0; 00117 int dstBpp=0; 00118 00119 if (!func_info[funcNum].func) break; 00120 00121 av_log(NULL, AV_LOG_INFO,"."); 00122 memset(srcBuffer, srcByte, SIZE); 00123 00124 for(width=63; width>0; width--) { 00125 int dstOffset; 00126 for(dstOffset=128; dstOffset<196; dstOffset+=4) { 00127 int srcOffset; 00128 memset(dstBuffer, dstByte, SIZE); 00129 00130 for(srcOffset=128; srcOffset<196; srcOffset+=4) { 00131 uint8_t *src= srcBuffer+srcOffset; 00132 uint8_t *dst= dstBuffer+dstOffset; 00133 const char *name=NULL; 00134 00135 if(failed) break; //don't fill the screen with shit ... 00136 00137 srcBpp = func_info[funcNum].src_bpp; 00138 dstBpp = func_info[funcNum].dst_bpp; 00139 name = func_info[funcNum].name; 00140 00141 func_info[funcNum].func(src, dst, width*srcBpp); 00142 00143 if(!srcBpp) break; 00144 00145 for(i=0; i<SIZE; i++) { 00146 if(srcBuffer[i]!=srcByte) { 00147 av_log(NULL, AV_LOG_INFO, "src damaged at %d w:%d src:%d dst:%d %s\n", 00148 i, width, srcOffset, dstOffset, name); 00149 failed=1; 00150 break; 00151 } 00152 } 00153 for(i=0; i<dstOffset; i++) { 00154 if(dstBuffer[i]!=dstByte) { 00155 av_log(NULL, AV_LOG_INFO, "dst damaged at %d w:%d src:%d dst:%d %s\n", 00156 i, width, srcOffset, dstOffset, name); 00157 failed=1; 00158 break; 00159 } 00160 } 00161 for(i=dstOffset + width*dstBpp; i<SIZE; i++) { 00162 if(dstBuffer[i]!=dstByte) { 00163 av_log(NULL, AV_LOG_INFO, "dst damaged at %d w:%d src:%d dst:%d %s\n", 00164 i, width, srcOffset, dstOffset, name); 00165 failed=1; 00166 break; 00167 } 00168 } 00169 } 00170 } 00171 } 00172 if(failed) failedNum++; 00173 else if(srcBpp) passedNum++; 00174 } 00175 00176 av_log(NULL, AV_LOG_INFO, "\n%d converters passed, %d converters randomly overwrote memory\n", passedNum, failedNum); 00177 return failedNum; 00178 }