1 /**
2 * RFX codec encoder test
3 *
4 * Copyright 2014-2017 Jay Sorg <jay.sorg@gmail.com>
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 #if defined(HAVE_CONFIG_H)
20 #include <config_ac.h>
21 #endif
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
27 #include <fcntl.h>
28 #include <sys/time.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31
32 #include <rfxcodec_encode.h>
33
34 static const unsigned char g_rfx_default_quantization_values[] =
35 {
36 /* LL3 LH3 HL3 HH3 LH2 HL2 HH2 LH1 HL1 HH1 */
37 0x66, 0x66, 0x77, 0x88, 0x98,
38 0x99, 0x99, 0xaa, 0xcc, 0xdc
39 };
40
41 /*****************************************************************************/
42 static int
get_mstime(void)43 get_mstime(void)
44 {
45 struct timeval tp;
46
47 gettimeofday(&tp, 0);
48 return (tp.tv_sec * 1000) + (tp.tv_usec / 1000);
49 }
50
51 /******************************************************************************/
52 static int
speed_random(int count,const char * quants)53 speed_random(int count, const char *quants)
54 {
55 void *han;
56 int error;
57 int index;
58 int cdata_bytes;
59 int fd;
60 char *cdata;
61 char *buf;
62 struct rfx_rect regions[1];
63 struct rfx_tile tiles[2];
64 int stime;
65 int etime;
66 int tiles_per_second;
67 int num_regions;
68 int num_tiles;
69 int num_quants;
70 int flags;
71
72 printf("speed_random:\n");
73 //flags = RFX_FLAGS_RLGR1 | RFX_FLAGS_NOACCEL;
74 flags = RFX_FLAGS_RLGR1;
75 //flags = RFX_FLAGS_RLGR3;
76 //flags = RFX_FLAGS_RLGR1 | RFX_FLAGS_ALPHAV1;
77 error = rfxcodec_encode_create_ex(1920, 1024, RFX_FORMAT_BGRA, flags, &han);
78 if (error != 0)
79 {
80 printf("speed_random: rfxcodec_encode_create_ex failed\n");
81 return 1;
82 }
83 printf("speed_random: rfxcodec_encode_create_ex ok\n");
84 cdata = (char *) malloc(128 * 64 * 4);
85 cdata_bytes = 128 * 64 * 4;
86 buf = (char *) malloc(128 * 64 * 4);
87 #if 1
88 fd = open("/dev/urandom", O_RDONLY);
89 //fd = open("/dev/zero", O_RDONLY);
90 if (read(fd, buf, 128 * 64 * 4) != 128 * 64 * 4)
91 {
92 printf("speed_random: read error\n");
93 }
94 close(fd);
95 #else
96 memset(buf, 0x7f, 128 * 64 * 4);
97 #endif
98 regions[0].x = 0;
99 regions[0].y = 0;
100 regions[0].cx = 128;
101 regions[0].cy = 64;
102 num_regions = 1;
103 tiles[0].x = 0;
104 tiles[0].y = 0;
105 tiles[0].cx = 64;
106 tiles[0].cy = 64;
107 tiles[0].quant_y = 0;
108 tiles[0].quant_cb = 0;
109 tiles[0].quant_cr = 0;
110 tiles[1].x = 64;
111 tiles[1].y = 0;
112 tiles[1].cx = 64;
113 tiles[1].cy = 64;
114 tiles[1].quant_y = 0;
115 tiles[1].quant_cb = 0;
116 tiles[1].quant_cr = 0;
117 num_tiles = 1;
118 num_quants = 1;
119 error = 0;
120 stime = get_mstime();
121 flags = 0;
122 //flags = RFX_FLAGS_ALPHAV1;
123 for (index = 0; index < count; index++)
124 {
125 error = rfxcodec_encode_ex(han, cdata, &cdata_bytes, buf, 64, 64, 64 * 4,
126 regions, num_regions, tiles, num_tiles,
127 quants, num_quants, flags);
128 if (error != 0)
129 {
130 break;
131 }
132 }
133 etime = get_mstime();
134 tiles_per_second = count * num_tiles * 1000 / (etime - stime + 1);
135 printf("speed_random: cdata_bytes %d count %d ms time %d "
136 "tiles_per_second %d\n",
137 cdata_bytes, count, etime - stime, tiles_per_second);
138 rfxcodec_encode_destroy(han);
139 free(buf);
140 free(cdata);
141 return 0;
142 }
143
144 struct bmp_magic
145 {
146 char magic[2];
147 };
148
149 struct bmp_hdr
150 {
151 unsigned int size;
152 unsigned short reserved1;
153 unsigned short reserved2;
154 unsigned int offset;
155 };
156
157 struct dib_hdr
158 {
159 unsigned int hdr_size;
160 int width;
161 int height;
162 unsigned short nplanes;
163 unsigned short bpp;
164 unsigned int compress_type;
165 unsigned int image_size;
166 int hres;
167 int vres;
168 unsigned int ncolors;
169 unsigned int nimpcolors;
170 };
171
172 /******************************************************************************/
173 static int
load_bmp_file(int in_fd,char ** data,int * width,int * height)174 load_bmp_file(int in_fd, char **data, int *width, int *height)
175 {
176 struct bmp_magic bmpm;
177 struct bmp_hdr bmph;
178 struct dib_hdr dibh;
179 int awidth;
180 int aheight;
181 int line_bytes;
182 int index;
183 int jndex;
184 int red;
185 int gre;
186 int blu;
187 int *dst32;
188 char *line;
189 char *line_ptr;
190
191 if (read(in_fd, &bmpm, sizeof(struct bmp_magic)) != sizeof(struct bmp_magic))
192 {
193 return 1;
194 }
195 if (read(in_fd, &bmph, sizeof(struct bmp_hdr)) != sizeof(struct bmp_hdr))
196 {
197 return 1;
198 }
199 if (read(in_fd, &dibh, sizeof(struct dib_hdr)) != sizeof(struct dib_hdr))
200 {
201 return 1;
202 }
203 if (dibh.bpp != 24)
204 {
205 printf("only support 24 bpp bmp file now\n");
206 return 1;
207 }
208 printf("bpp %d\n", dibh.bpp);
209 *width = dibh.width;
210 *height = dibh.height;
211 awidth = (dibh.width + 63) & ~63;
212 aheight = (dibh.height + 63) & ~63;
213 *data = (char *) malloc(awidth * aheight * 4);
214
215 line_bytes = dibh.width * 3;
216 line_bytes = (line_bytes + 3) & ~3;
217 line = (char *) malloc(line_bytes);
218
219 memset(*data, 0, awidth * aheight);
220 for (index = 0; index < dibh.height; index++)
221 {
222 dst32 = (int *) (*data);
223 dst32 += index * awidth;
224
225 line_ptr = line;
226 if (read(in_fd, line, line_bytes) != line_bytes)
227 {
228 return 1;
229 }
230 for (jndex = 0; jndex < dibh.width; jndex++)
231 {
232 red = *(line_ptr++);
233 gre = *(line_ptr++);
234 blu = *(line_ptr++);
235 *(dst32++) = (red << 16) | (gre << 8) | blu;
236 }
237 }
238
239 free(line);
240
241 return 0;
242 }
243
244 /******************************************************************************/
245 static int
encode_file(char * data,int width,int height,char * cdata,int * cdata_bytes,const char * quants,int num_quants)246 encode_file(char *data, int width, int height, char *cdata, int *cdata_bytes,
247 const char *quants, int num_quants)
248 {
249 int awidth;
250 int aheight;
251 int num_tiles;
252 int index;
253 int jndex;
254 int error;
255 int num_regions;
256 struct rfx_tile *tiles;
257 struct rfx_tile *tiles_ptr;
258 void *han;
259 struct rfx_rect regions[1];
260
261 error = rfxcodec_encode_create_ex(1920, 1024, RFX_FORMAT_BGRA, RFX_FLAGS_RLGR1, &han);
262 if (error != 0)
263 {
264 printf("encode_file: rfxcodec_encode_create_ex failed\n");
265 return 1;
266 }
267
268 awidth = (width + 63) & ~63;
269 aheight = (height + 63) & ~63;
270
271 num_tiles = (awidth / 64) * (aheight / 64);
272 tiles = (struct rfx_tile *) malloc(num_tiles * sizeof(struct rfx_tile));
273 tiles_ptr = tiles;
274 for (index = 0; index < aheight; index += 64)
275 {
276 for (jndex = 0; jndex < awidth; jndex += 64)
277 {
278 tiles_ptr[0].x = jndex;
279 tiles_ptr[0].y = index;
280 tiles_ptr[0].cx = 64;
281 tiles_ptr[0].cy = 64;
282 tiles_ptr[0].quant_y = 0;
283 tiles_ptr[0].quant_cb = num_quants - 1;
284 tiles_ptr[0].quant_cr = num_quants - 1;
285 tiles_ptr++;
286 }
287 }
288
289 regions[0].x = 0;
290 regions[0].y = 0;
291 regions[0].cx = width;
292 regions[0].cy = height;
293 num_regions = 1;
294
295 error = rfxcodec_encode_ex(han, cdata, cdata_bytes, data, width, height, width * 4,
296 regions, num_regions, tiles, num_tiles,
297 quants, num_quants, 0);
298 if (error != 0)
299 {
300 printf("encode_file: rfxcodec_encode failed error %d\n", error);
301 return 1;
302 }
303
304 rfxcodec_encode_destroy(han);
305
306
307 free(tiles);
308 return 0;
309 }
310
311 /******************************************************************************/
312 static int
read_file(int count,const char * quants,int num_quants,const char * in_file,const char * out_file)313 read_file(int count, const char *quants, int num_quants,
314 const char *in_file, const char *out_file)
315 {
316 int in_fd;
317 int out_fd;
318 int width;
319 int height;
320 int cdata_bytes;
321 char *data;
322 char *cdata;
323
324 in_fd = open(in_file, O_RDONLY);
325 if (in_fd == -1)
326 {
327 printf("error opening %s\n", in_file);
328 return 1;
329 }
330 out_fd = -1;
331 if (out_file[0] != 0)
332 {
333 if (access(out_file, F_OK) == 0)
334 {
335 printf("out files exists\n");
336 return 1;
337 }
338 out_fd = open(out_file, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
339 if (out_fd == -1)
340 {
341 printf("error opening %s\n", out_file);
342 return 1;
343 }
344 }
345
346 data = 0;
347 width = 0;
348 height = 0;
349 if (load_bmp_file(in_fd, &data, &width, &height) != 0)
350 {
351 printf("load_bmp_file failed\n");
352 return 1;
353 }
354 printf("loaded file ok width %d height %d\n", width, height);
355 cdata_bytes = (width + 64) * (height + 64);
356 cdata = (char *) malloc(cdata_bytes);
357 if (encode_file(data, width, height, cdata, &cdata_bytes, quants, num_quants) != 0)
358 {
359 printf("encode_file failed\n");
360 return 1;
361 }
362 printf("encode data ok bytes %d\n", cdata_bytes);
363
364 if (out_fd != -1)
365 {
366 if (write(out_fd, cdata, cdata_bytes) != cdata_bytes)
367 {
368 printf("write failed\n");
369 }
370 }
371
372 free(data);
373 free(cdata);
374 close(in_fd);
375 if (out_fd != -1)
376 {
377 close(out_fd);
378 }
379 return 0;
380 }
381
382 /******************************************************************************/
383 static int
out_usage(void)384 out_usage(void)
385 {
386 printf("rfxdectest usage\n");
387 printf("this program is used for testing the rfx encoder for both speed "
388 "and integrity\n");
389 printf("examples\n");
390 printf(" ./rfxcodectest --speed --count 1000\n");
391 printf(" ./rfxcodectest -i infile.bmp -o outfile.rfx\n");
392 printf("\n");
393 return 0;
394 }
395
396 /******************************************************************************/
397 int
main(int argc,char ** argv)398 main(int argc, char **argv)
399 {
400 int index;
401 int do_speed;
402 int do_read;
403 int count;
404 char in_file[256];
405 char out_file[256];
406 const char *quants = (const char *) g_rfx_default_quantization_values;
407
408 do_speed = 0;
409 do_read = 0;
410 in_file[0] = 0;
411 out_file[0] = 0;
412 count = 1;
413 if (argc < 2)
414 {
415 return out_usage();
416 }
417 for (index = 1; index < argc; index++)
418 {
419 if (strcmp("--speed", argv[index]) == 0)
420 {
421 do_speed = 1;
422 }
423 else if (strcmp("--count", argv[index]) == 0)
424 {
425 index++;
426 count = atoi(argv[index]);
427 }
428 else if (strcmp("-i", argv[index]) == 0)
429 {
430 index++;
431 snprintf(in_file, 255, "%s", argv[index]);
432 do_read = 1;
433 }
434 else if (strcmp("-o", argv[index]) == 0)
435 {
436 index++;
437 snprintf(out_file, 255, "%s", argv[index]);
438 }
439 else
440 {
441 return out_usage();
442 }
443 }
444 if (do_speed)
445 {
446 speed_random(count, quants);
447 }
448 if (do_read)
449 {
450 read_file(count, quants, 2, in_file, out_file);
451 }
452 return 0;
453 }
454