1 /*
2  *  Copyright (c) 2019 The WebM project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include <assert.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include "vpx_util/vpx_debug_util.h"
15 
16 #if CONFIG_BITSTREAM_DEBUG || CONFIG_MISMATCH_DEBUG
17 static int frame_idx_w = 0;
18 static int frame_idx_r = 0;
19 
bitstream_queue_set_frame_write(int frame_idx)20 void bitstream_queue_set_frame_write(int frame_idx) { frame_idx_w = frame_idx; }
21 
bitstream_queue_get_frame_write(void)22 int bitstream_queue_get_frame_write(void) { return frame_idx_w; }
23 
bitstream_queue_set_frame_read(int frame_idx)24 void bitstream_queue_set_frame_read(int frame_idx) { frame_idx_r = frame_idx; }
25 
bitstream_queue_get_frame_read(void)26 int bitstream_queue_get_frame_read(void) { return frame_idx_r; }
27 #endif
28 
29 #if CONFIG_BITSTREAM_DEBUG
30 #define QUEUE_MAX_SIZE 2000000
31 static int result_queue[QUEUE_MAX_SIZE];
32 static int prob_queue[QUEUE_MAX_SIZE];
33 
34 static int queue_r = 0;
35 static int queue_w = 0;
36 static int queue_prev_w = -1;
37 static int skip_r = 0;
38 static int skip_w = 0;
bitstream_queue_set_skip_write(int skip)39 void bitstream_queue_set_skip_write(int skip) { skip_w = skip; }
40 
bitstream_queue_set_skip_read(int skip)41 void bitstream_queue_set_skip_read(int skip) { skip_r = skip; }
42 
bitstream_queue_record_write(void)43 void bitstream_queue_record_write(void) { queue_prev_w = queue_w; }
44 
bitstream_queue_reset_write(void)45 void bitstream_queue_reset_write(void) { queue_w = queue_prev_w; }
46 
bitstream_queue_get_write(void)47 int bitstream_queue_get_write(void) { return queue_w; }
48 
bitstream_queue_get_read(void)49 int bitstream_queue_get_read(void) { return queue_r; }
50 
bitstream_queue_pop(int * result,int * prob)51 void bitstream_queue_pop(int *result, int *prob) {
52   if (!skip_r) {
53     if (queue_w == queue_r) {
54       printf("buffer underflow queue_w %d queue_r %d\n", queue_w, queue_r);
55       assert(0);
56     }
57     *result = result_queue[queue_r];
58     *prob = prob_queue[queue_r];
59     queue_r = (queue_r + 1) % QUEUE_MAX_SIZE;
60   }
61 }
62 
bitstream_queue_push(int result,const int prob)63 void bitstream_queue_push(int result, const int prob) {
64   if (!skip_w) {
65     result_queue[queue_w] = result;
66     prob_queue[queue_w] = prob;
67     queue_w = (queue_w + 1) % QUEUE_MAX_SIZE;
68     if (queue_w == queue_r) {
69       printf("buffer overflow queue_w %d queue_r %d\n", queue_w, queue_r);
70       assert(0);
71     }
72   }
73 }
74 #endif  // CONFIG_BITSTREAM_DEBUG
75 
76 #if CONFIG_MISMATCH_DEBUG
77 static int frame_buf_idx_r = 0;
78 static int frame_buf_idx_w = 0;
79 #define MAX_FRAME_BUF_NUM 20
80 #define MAX_FRAME_STRIDE 1920
81 #define MAX_FRAME_HEIGHT 1080
82 static uint16_t
83     frame_pre[MAX_FRAME_BUF_NUM][3]
84              [MAX_FRAME_STRIDE * MAX_FRAME_HEIGHT];  // prediction only
85 static uint16_t
86     frame_tx[MAX_FRAME_BUF_NUM][3]
87             [MAX_FRAME_STRIDE * MAX_FRAME_HEIGHT];  // prediction + txfm
88 static int frame_stride = MAX_FRAME_STRIDE;
89 static int frame_height = MAX_FRAME_HEIGHT;
90 static int frame_size = MAX_FRAME_STRIDE * MAX_FRAME_HEIGHT;
mismatch_move_frame_idx_w(void)91 void mismatch_move_frame_idx_w(void) {
92   frame_buf_idx_w = (frame_buf_idx_w + 1) % MAX_FRAME_BUF_NUM;
93   if (frame_buf_idx_w == frame_buf_idx_r) {
94     printf("frame_buf overflow\n");
95     assert(0);
96   }
97 }
98 
mismatch_reset_frame(int num_planes)99 void mismatch_reset_frame(int num_planes) {
100   int plane;
101   for (plane = 0; plane < num_planes; ++plane) {
102     memset(frame_pre[frame_buf_idx_w][plane], 0,
103            sizeof(frame_pre[frame_buf_idx_w][plane][0]) * frame_size);
104     memset(frame_tx[frame_buf_idx_w][plane], 0,
105            sizeof(frame_tx[frame_buf_idx_w][plane][0]) * frame_size);
106   }
107 }
108 
mismatch_move_frame_idx_r(void)109 void mismatch_move_frame_idx_r(void) {
110   if (frame_buf_idx_w == frame_buf_idx_r) {
111     printf("frame_buf underflow\n");
112     assert(0);
113   }
114   frame_buf_idx_r = (frame_buf_idx_r + 1) % MAX_FRAME_BUF_NUM;
115 }
116 
mismatch_record_block_pre(const uint8_t * src,int src_stride,int plane,int pixel_c,int pixel_r,int blk_w,int blk_h,int highbd)117 void mismatch_record_block_pre(const uint8_t *src, int src_stride, int plane,
118                                int pixel_c, int pixel_r, int blk_w, int blk_h,
119                                int highbd) {
120   const uint16_t *src16 = highbd ? CONVERT_TO_SHORTPTR(src) : NULL;
121   int r, c;
122 
123   if (pixel_c + blk_w >= frame_stride || pixel_r + blk_h >= frame_height) {
124     printf("frame_buf undersized\n");
125     assert(0);
126   }
127 
128   for (r = 0; r < blk_h; ++r) {
129     for (c = 0; c < blk_w; ++c) {
130       frame_pre[frame_buf_idx_w][plane]
131                [(r + pixel_r) * frame_stride + c + pixel_c] =
132                    src16 ? src16[r * src_stride + c] : src[r * src_stride + c];
133     }
134   }
135 #if 0
136   {
137     int ref_frame_idx = 3;
138     int ref_plane = 1;
139     int ref_pixel_c = 162;
140     int ref_pixel_r = 16;
141     if (frame_idx_w == ref_frame_idx && plane == ref_plane &&
142         ref_pixel_c >= pixel_c && ref_pixel_c < pixel_c + blk_w &&
143         ref_pixel_r >= pixel_r && ref_pixel_r < pixel_r + blk_h) {
144       printf(
145           "\nrecord_block_pre frame_idx %d plane %d pixel_c %d pixel_r %d blk_w"
146           " %d blk_h %d\n",
147           frame_idx_w, plane, pixel_c, pixel_r, blk_w, blk_h);
148     }
149   }
150 #endif
151 }
mismatch_record_block_tx(const uint8_t * src,int src_stride,int plane,int pixel_c,int pixel_r,int blk_w,int blk_h,int highbd)152 void mismatch_record_block_tx(const uint8_t *src, int src_stride, int plane,
153                               int pixel_c, int pixel_r, int blk_w, int blk_h,
154                               int highbd) {
155   const uint16_t *src16 = highbd ? CONVERT_TO_SHORTPTR(src) : NULL;
156   int r, c;
157   if (pixel_c + blk_w >= frame_stride || pixel_r + blk_h >= frame_height) {
158     printf("frame_buf undersized\n");
159     assert(0);
160   }
161 
162   for (r = 0; r < blk_h; ++r) {
163     for (c = 0; c < blk_w; ++c) {
164       frame_tx[frame_buf_idx_w][plane]
165               [(r + pixel_r) * frame_stride + c + pixel_c] =
166                   src16 ? src16[r * src_stride + c] : src[r * src_stride + c];
167     }
168   }
169 #if 0
170   {
171     int ref_frame_idx = 3;
172     int ref_plane = 1;
173     int ref_pixel_c = 162;
174     int ref_pixel_r = 16;
175     if (frame_idx_w == ref_frame_idx && plane == ref_plane &&
176         ref_pixel_c >= pixel_c && ref_pixel_c < pixel_c + blk_w &&
177         ref_pixel_r >= pixel_r && ref_pixel_r < pixel_r + blk_h) {
178       printf(
179           "\nrecord_block_tx frame_idx %d plane %d pixel_c %d pixel_r %d blk_w "
180           "%d blk_h %d\n",
181           frame_idx_w, plane, pixel_c, pixel_r, blk_w, blk_h);
182     }
183   }
184 #endif
185 }
mismatch_check_block_pre(const uint8_t * src,int src_stride,int plane,int pixel_c,int pixel_r,int blk_w,int blk_h,int highbd)186 void mismatch_check_block_pre(const uint8_t *src, int src_stride, int plane,
187                               int pixel_c, int pixel_r, int blk_w, int blk_h,
188                               int highbd) {
189   const uint16_t *src16 = highbd ? CONVERT_TO_SHORTPTR(src) : NULL;
190   int mismatch = 0;
191   int r, c;
192   if (pixel_c + blk_w >= frame_stride || pixel_r + blk_h >= frame_height) {
193     printf("frame_buf undersized\n");
194     assert(0);
195   }
196 
197   for (r = 0; r < blk_h; ++r) {
198     for (c = 0; c < blk_w; ++c) {
199       if (frame_pre[frame_buf_idx_r][plane]
200                    [(r + pixel_r) * frame_stride + c + pixel_c] !=
201           (uint16_t)(src16 ? src16[r * src_stride + c]
202                            : src[r * src_stride + c])) {
203         mismatch = 1;
204       }
205     }
206   }
207   if (mismatch) {
208     int rr, cc;
209     printf(
210         "\ncheck_block_pre failed frame_idx %d plane %d "
211         "pixel_c %d pixel_r "
212         "%d blk_w %d blk_h %d\n",
213         frame_idx_r, plane, pixel_c, pixel_r, blk_w, blk_h);
214     printf("enc\n");
215     for (rr = 0; rr < blk_h; ++rr) {
216       for (cc = 0; cc < blk_w; ++cc) {
217         printf("%d ", frame_pre[frame_buf_idx_r][plane]
218                                [(rr + pixel_r) * frame_stride + cc + pixel_c]);
219       }
220       printf("\n");
221     }
222 
223     printf("dec\n");
224     for (rr = 0; rr < blk_h; ++rr) {
225       for (cc = 0; cc < blk_w; ++cc) {
226         printf("%d ",
227                src16 ? src16[rr * src_stride + cc] : src[rr * src_stride + cc]);
228       }
229       printf("\n");
230     }
231     assert(0);
232   }
233 }
mismatch_check_block_tx(const uint8_t * src,int src_stride,int plane,int pixel_c,int pixel_r,int blk_w,int blk_h,int highbd)234 void mismatch_check_block_tx(const uint8_t *src, int src_stride, int plane,
235                              int pixel_c, int pixel_r, int blk_w, int blk_h,
236                              int highbd) {
237   const uint16_t *src16 = highbd ? CONVERT_TO_SHORTPTR(src) : NULL;
238   int mismatch = 0;
239   int r, c;
240   if (pixel_c + blk_w >= frame_stride || pixel_r + blk_h >= frame_height) {
241     printf("frame_buf undersized\n");
242     assert(0);
243   }
244 
245   for (r = 0; r < blk_h; ++r) {
246     for (c = 0; c < blk_w; ++c) {
247       if (frame_tx[frame_buf_idx_r][plane]
248                   [(r + pixel_r) * frame_stride + c + pixel_c] !=
249           (uint16_t)(src16 ? src16[r * src_stride + c]
250                            : src[r * src_stride + c])) {
251         mismatch = 1;
252       }
253     }
254   }
255   if (mismatch) {
256     int rr, cc;
257     printf(
258         "\ncheck_block_tx failed frame_idx %d plane %d pixel_c "
259         "%d pixel_r "
260         "%d blk_w %d blk_h %d\n",
261         frame_idx_r, plane, pixel_c, pixel_r, blk_w, blk_h);
262     printf("enc\n");
263     for (rr = 0; rr < blk_h; ++rr) {
264       for (cc = 0; cc < blk_w; ++cc) {
265         printf("%d ", frame_tx[frame_buf_idx_r][plane]
266                               [(rr + pixel_r) * frame_stride + cc + pixel_c]);
267       }
268       printf("\n");
269     }
270 
271     printf("dec\n");
272     for (rr = 0; rr < blk_h; ++rr) {
273       for (cc = 0; cc < blk_w; ++cc) {
274         printf("%d ",
275                src16 ? src16[rr * src_stride + cc] : src[rr * src_stride + cc]);
276       }
277       printf("\n");
278     }
279     assert(0);
280   }
281 }
282 #endif  // CONFIG_MISMATCH_DEBUG
283