FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
yuvcmp.c
Go to the documentation of this file.
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 
17 int
18 main(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 }