1/* 2 * originally by Andreas ��man (andoma) 3 * some changes by Alexander Strange 4 */ 5 6#include <string.h> 7#include <stdlib.h> 8#include <inttypes.h> 9#include <stdio.h> 10#include <sys/stat.h> 11#include <fcntl.h> 12 13#if HAVE_UNISTD_H 14#include <unistd.h> 15#endif 16 17int 18main(int argc, char **argv) 19{ 20 int fd[2]; 21 int print_pixels = 0; 22 int dump_blocks = 0; 23 24 int width; 25 int height; 26 int to_skip = 0; 27 28 if (argc < 6) { 29 fprintf(stderr, "%s [YUV file 1] [YUV file 2] width height pixelcmp|blockdump (# to skip)\n", argv[0]); 30 return 1; 31 } 32 33 width = atoi(argv[3]); 34 height = atoi(argv[4]); 35 if (argc > 6) 36 to_skip = atoi(argv[6]); 37 38 uint8_t *Y[2], *C[2][2]; 39 int i, v, c, p; 40 int lsiz = width * height; 41 int csiz = width * height / 4; 42 int x, y; 43 int cwidth = width / 2; 44 int fr = to_skip; 45 int mb; 46 char *mberrors; 47 int mb_x, mb_y; 48 uint8_t *a; 49 uint8_t *b; 50 int die = 0; 51 52 print_pixels = strstr(argv[5], "pixelcmp") ? 1 : 0; 53 dump_blocks = strstr(argv[5], "blockdump") ? 1 : 0; 54 55 for(i = 0; i < 2; i++) { 56 Y[i] = malloc(lsiz); 57 C[0][i] = malloc(csiz); 58 C[1][i] = malloc(csiz); 59 60 fd[i] = open(argv[1 + i], O_RDONLY); 61 if(fd[i] == -1) { 62 perror("open"); 63 exit(1); 64 } 65 fcntl(fd[i], F_NOCACHE, 1); 66 67 if (to_skip) 68 lseek(fd[i], to_skip * (lsiz + 2*csiz), SEEK_SET); 69 } 70 71 mb_x = width / 16; 72 mb_y = height / 16; 73 74 mberrors = malloc(mb_x * mb_y); 75 76 while(!die) { 77 memset(mberrors, 0, mb_x * mb_y); 78 79 printf("Loading frame %d\n", ++fr); 80 81 for(i = 0; i < 2; i++) { 82 v = read(fd[i], Y[i], lsiz); 83 if(v != lsiz) { 84 fprintf(stderr, "Unable to read Y from file %d, exiting\n", i + 1); 85 return 1; 86 } 87 } 88 89 90 for(c = 0; c < lsiz; c++) { 91 if(Y[0][c] != Y[1][c]) { 92 x = c % width; 93 y = c / width; 94 95 mb = x / 16 + (y / 16) * mb_x; 96 97 if(print_pixels) 98 printf("Luma diff 0x%02x != 0x%02x at pixel (%4d,%-4d) mb(%d,%d) #%d\n", 99 Y[0][c], 100 Y[1][c], 101 x, y, 102 x / 16, 103 y / 16, 104 mb); 105 106 mberrors[mb] |= 1; 107 } 108 } 109 110 /* Chroma planes */ 111 112 for(p = 0; p < 2; p++) { 113 114 for(i = 0; i < 2; i++) { 115 v = read(fd[i], C[p][i], csiz); 116 if(v != csiz) { 117 fprintf(stderr, "Unable to read %c from file %d, exiting\n", 118 "UV"[p], i + 1); 119 return 1; 120 } 121 } 122 123 for(c = 0; c < csiz; c++) { 124 if(C[p][0][c] != C[p][1][c]) { 125 x = c % cwidth; 126 y = c / cwidth; 127 128 mb = x / 8 + (y / 8) * mb_x; 129 130 mberrors[mb] |= 2 << p; 131 132 if(print_pixels) 133 134 printf("c%c diff 0x%02x != 0x%02x at pixel (%4d,%-4d) " 135 "mb(%3d,%-3d) #%d\n", 136 p ? 'r' : 'b', 137 C[p][0][c], 138 C[p][1][c], 139 140 x, y, 141 x / 8, 142 y / 8, 143 x / 8 + y / 8 * cwidth / 8); 144 } 145 } 146 } 147 148 for(i = 0; i < mb_x * mb_y; i++) { 149 x = i % mb_x; 150 y = i / mb_x; 151 152 if(mberrors[i]) { 153 die = 1; 154 155 printf("MB (%3d,%-3d) %4d %d %c%c%c damaged\n", 156 x, y, i, mberrors[i], 157 mberrors[i] & 1 ? 'Y' : ' ', 158 mberrors[i] & 2 ? 'U' : ' ', 159 mberrors[i] & 4 ? 'V' : ' '); 160 161 if(dump_blocks) { 162 a = Y[0] + x * 16 + y * 16 * width; 163 b = Y[1] + x * 16 + y * 16 * width; 164 165 for(y = 0; y < 16; y++) { 166 printf("%c ", "TB"[y&1]); 167 for(x = 0; x < 16; x++) 168 printf("%02x%c", a[x + y * width], 169 a[x + y * width] != b[x + y * width] ? '<' : ' '); 170 171 printf("| "); 172 for(x = 0; x < 16; x++) 173 printf("%02x%c", b[x + y * width], 174 a[x + y * width] != b[x + y * width] ? '<' : ' '); 175 176 printf("\n"); 177 } 178 } 179 } 180 } 181 } 182 183 return 0; 184} 185