1 /* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30 // System dependencies
31 #include <pthread.h>
32 #include <stdlib.h>
33 #define TIME_H <SYSTEM_HEADER_PREFIX/time.h>
34 #include TIME_H
35
36 // JPEG dependencies
37 #include "mm_jpeg_interface.h"
38 #include "mm_jpeg_ionbuf.h"
39
40 // Camera dependencies
41 #include "mm_camera_dbg.h"
42
43 #define MAX_NUM_BUFS (12)
44 #define MAX_NUM_CLIENT (8)
45
46 /** DUMP_TO_FILE:
47 * @filename: file name
48 * @p_addr: address of the buffer
49 * @len: buffer length
50 *
51 * dump the image to the file
52 **/
53 #define DUMP_TO_FILE(filename, p_addr, len) ({ \
54 FILE *fp = fopen(filename, "w+"); \
55 if (fp) { \
56 fwrite(p_addr, 1, len, fp); \
57 fclose(fp); \
58 } else { \
59 LOGE("cannot dump image"); \
60 } \
61 })
62
63 static uint32_t g_count = 1U, g_i;
64
65 typedef struct {
66 mm_jpeg_color_format fmt;
67 cam_rational_type_t mult;
68 const char *str;
69 } mm_jpeg_intf_test_colfmt_t;
70
71 typedef struct {
72 char *filename;
73 int width;
74 int height;
75 char *out_filename;
76 uint32_t burst_mode;
77 uint32_t min_out_bufs;
78 mm_jpeg_intf_test_colfmt_t col_fmt;
79 uint32_t encode_thumbnail;
80 int tmb_width;
81 int tmb_height;
82 int main_quality;
83 int thumb_quality;
84 char *qtable_luma_file;
85 char *qtable_chroma_file;
86 int client_cnt;
87 } jpeg_test_input_t;
88
89 /* Static constants */
90 /* default Luma Qtable */
91 uint8_t DEFAULT_QTABLE_0[QUANT_SIZE] = {
92 16, 11, 10, 16, 24, 40, 51, 61,
93 12, 12, 14, 19, 26, 58, 60, 55,
94 14, 13, 16, 24, 40, 57, 69, 56,
95 14, 17, 22, 29, 51, 87, 80, 62,
96 18, 22, 37, 56, 68, 109, 103, 77,
97 24, 35, 55, 64, 81, 104, 113, 92,
98 49, 64, 78, 87, 103, 121, 120, 101,
99 72, 92, 95, 98, 112, 100, 103, 99
100 };
101
102 /* default Chroma Qtable */
103 uint8_t DEFAULT_QTABLE_1[QUANT_SIZE] = {
104 17, 18, 24, 47, 99, 99, 99, 99,
105 18, 21, 26, 66, 99, 99, 99, 99,
106 24, 26, 56, 99, 99, 99, 99, 99,
107 47, 66, 99, 99, 99, 99, 99, 99,
108 99, 99, 99, 99, 99, 99, 99, 99,
109 99, 99, 99, 99, 99, 99, 99, 99,
110 99, 99, 99, 99, 99, 99, 99, 99,
111 99, 99, 99, 99, 99, 99, 99, 99
112 };
113
114 typedef struct {
115 char *filename[MAX_NUM_BUFS];
116 int width;
117 int height;
118 char *out_filename[MAX_NUM_BUFS];
119 pthread_mutex_t lock;
120 pthread_cond_t cond;
121 pthread_t thread_id;
122 buffer_t input[MAX_NUM_BUFS];
123 buffer_t output[MAX_NUM_BUFS];
124 int use_ion;
125 uint32_t handle;
126 mm_jpeg_ops_t ops;
127 uint32_t job_id[MAX_NUM_BUFS];
128 mm_jpeg_encode_params_t params;
129 mm_jpeg_job_t job;
130 uint32_t session_id;
131 uint32_t num_bufs;
132 uint32_t min_out_bufs;
133 size_t buf_filled_len[MAX_NUM_BUFS];
134 mm_dimension pic_size;
135 int ret;
136 int clinet_id;
137 } mm_jpeg_intf_test_t;
138
139
140
141 static const mm_jpeg_intf_test_colfmt_t color_formats[] =
142 {
143 { MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V2, {3, 2}, "YCRCBLP_H2V2" },
144 { MM_JPEG_COLOR_FORMAT_YCBCRLP_H2V2, {3, 2}, "YCBCRLP_H2V2" },
145 { MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V1, {2, 1}, "YCRCBLP_H2V1" },
146 { MM_JPEG_COLOR_FORMAT_YCBCRLP_H2V1, {2, 1}, "YCBCRLP_H2V1" },
147 { MM_JPEG_COLOR_FORMAT_YCRCBLP_H1V2, {2, 1}, "YCRCBLP_H1V2" },
148 { MM_JPEG_COLOR_FORMAT_YCBCRLP_H1V2, {2, 1}, "YCBCRLP_H1V2" },
149 { MM_JPEG_COLOR_FORMAT_YCRCBLP_H1V1, {3, 1}, "YCRCBLP_H1V1" },
150 { MM_JPEG_COLOR_FORMAT_YCBCRLP_H1V1, {3, 1}, "YCBCRLP_H1V1" }
151 };
152
153 static jpeg_test_input_t jpeg_input[] = {
154 { QCAMERA_DUMP_FRM_LOCATION"test_1.yuv", 4000, 3008, QCAMERA_DUMP_FRM_LOCATION"test_1.jpg", 0, 0,
155 { MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V2, {3, 2}, "YCRCBLP_H2V2" },
156 0, 320, 240, 80, 80, NULL, NULL, 1}
157 };
158
mm_jpeg_encode_callback(jpeg_job_status_t status,uint32_t client_hdl,uint32_t jobId,mm_jpeg_output_t * p_output,void * userData)159 static void mm_jpeg_encode_callback(jpeg_job_status_t status,
160 uint32_t client_hdl,
161 uint32_t jobId,
162 mm_jpeg_output_t *p_output,
163 void *userData)
164 {
165 mm_jpeg_intf_test_t *p_obj = (mm_jpeg_intf_test_t *)userData;
166
167 pthread_mutex_lock(&p_obj->lock);
168
169 if (status == JPEG_JOB_STATUS_ERROR) {
170 LOGE("Encode error");
171 } else {
172 int i = 0;
173 for (i = 0; p_obj->job_id[i] && (jobId != p_obj->job_id[i]); i++)
174 ;
175 if (!p_obj->job_id[i]) {
176 LOGE("Cannot find job ID!!!");
177 goto error;
178 }
179 LOGE("Encode success addr %p len %zu idx %d",
180 p_output->buf_vaddr, p_output->buf_filled_len, i);
181
182 p_obj->buf_filled_len[i] = p_output->buf_filled_len;
183 if (p_obj->min_out_bufs) {
184 LOGE("Saving file%s addr %p len %zu",
185 p_obj->out_filename[i],
186 p_output->buf_vaddr, p_output->buf_filled_len);
187 DUMP_TO_FILE(p_obj->out_filename[i], p_output->buf_vaddr,
188 p_output->buf_filled_len);
189 }
190 }
191 g_i++;
192
193 error:
194
195 if (g_i >= g_count) {
196 LOGE("Signal the thread");
197 pthread_cond_signal(&p_obj->cond);
198 }
199 pthread_mutex_unlock(&p_obj->lock);
200 }
201
mm_jpeg_test_alloc(buffer_t * p_buffer,int use_pmem)202 int mm_jpeg_test_alloc(buffer_t *p_buffer, int use_pmem)
203 {
204 int ret = 0;
205 /*Allocate buffers*/
206 if (use_pmem) {
207 p_buffer->addr = (uint8_t *)buffer_allocate(p_buffer, 0);
208 if (NULL == p_buffer->addr) {
209 LOGE("Error");
210 return -1;
211 }
212 } else {
213 /* Allocate heap memory */
214 p_buffer->addr = (uint8_t *)malloc(p_buffer->size);
215 if (NULL == p_buffer->addr) {
216 LOGE("Error");
217 return -1;
218 }
219 }
220 return ret;
221 }
222
mm_jpeg_test_free(buffer_t * p_buffer)223 void mm_jpeg_test_free(buffer_t *p_buffer)
224 {
225 if (p_buffer->addr == NULL)
226 return;
227
228 if (p_buffer->p_pmem_fd >= 0)
229 buffer_deallocate(p_buffer);
230 else
231 free(p_buffer->addr);
232
233 memset(p_buffer, 0x0, sizeof(buffer_t));
234 }
235
mm_jpeg_test_read(mm_jpeg_intf_test_t * p_obj,uint32_t idx)236 int mm_jpeg_test_read(mm_jpeg_intf_test_t *p_obj, uint32_t idx)
237 {
238 FILE *fp = NULL;
239 size_t file_size = 0;
240 fp = fopen(p_obj->filename[idx], "rb");
241 if (!fp) {
242 LOGE("error");
243 return -1;
244 }
245 fseek(fp, 0, SEEK_END);
246 file_size = (size_t)ftell(fp);
247 fseek(fp, 0, SEEK_SET);
248 LOGE("input file size is %zu buf_size %zu",
249 file_size, p_obj->input[idx].size);
250
251 if (p_obj->input[idx].size > file_size) {
252 LOGE("error");
253 fclose(fp);
254 return -1;
255 }
256 fread(p_obj->input[idx].addr, 1, p_obj->input[idx].size, fp);
257 fclose(fp);
258 return 0;
259 }
260
261 /** mm_jpeg_test_read_qtable:
262 *
263 * Arguments:
264 * @filename: Qtable filename
265 * @chroma_flag: Flag indicating chroma qtable
266 *
267 * Return:
268 * 0 success, failure otherwise
269 *
270 * Description:
271 * Reads qtable from file and sets it in appropriate qtable
272 * based on flag.
273 **/
mm_jpeg_test_read_qtable(const char * filename,bool chroma_flag)274 int mm_jpeg_test_read_qtable(const char *filename, bool chroma_flag)
275 {
276 FILE *fp = NULL;
277 int i;
278
279 if (filename == NULL)
280 return 0;
281
282 fp = fopen(filename, "r");
283 if (!fp) {
284 LOGE("error cannot open file");
285 return -1;
286 }
287
288 if (chroma_flag) {
289 for (i = 0; i < QUANT_SIZE; i++)
290 fscanf(fp, "%hhu,", &DEFAULT_QTABLE_1[i]);
291 } else {
292 for (i = 0; i < QUANT_SIZE; i++)
293 fscanf(fp, "%hhu,", &DEFAULT_QTABLE_0[i]);
294 }
295
296 fclose(fp);
297 return 0;
298 }
299
encode_init(jpeg_test_input_t * p_input,mm_jpeg_intf_test_t * p_obj,int client_id)300 static int encode_init(jpeg_test_input_t *p_input, mm_jpeg_intf_test_t *p_obj,
301 int client_id)
302 {
303 int rc = -1;
304 size_t size = (size_t)(p_input->width * p_input->height);
305 mm_jpeg_encode_params_t *p_params = &p_obj->params;
306 mm_jpeg_encode_job_t *p_job_params = &p_obj->job.encode_job;
307 uint32_t i = 0;
308 uint32_t burst_mode = p_input->burst_mode;
309 jpeg_test_input_t *p_in = p_input;
310
311 do {
312 p_obj->filename[i] = p_in->filename;
313 p_obj->width = p_input->width;
314 p_obj->height = p_input->height;
315 p_obj->out_filename[i] = p_in->out_filename;
316 p_obj->use_ion = 1;
317 p_obj->min_out_bufs = p_input->min_out_bufs;
318
319 /* allocate buffers */
320 p_obj->input[i].size = size * (size_t)p_input->col_fmt.mult.numerator /
321 (size_t)p_input->col_fmt.mult.denominator;
322 rc = mm_jpeg_test_alloc(&p_obj->input[i], p_obj->use_ion);
323 if (rc) {
324 LOGE("Error");
325 return -1;
326 }
327
328
329 rc = mm_jpeg_test_read(p_obj, i);
330 if (rc) {
331 LOGE("Error, unable to read input image");
332 return -1;
333 }
334
335 mm_jpeg_test_read_qtable(p_input->qtable_luma_file, false);
336 if (rc) {
337 LOGE("Error, unable to read luma qtable");
338 return -1;
339 }
340
341 mm_jpeg_test_read_qtable(p_input->qtable_chroma_file, true);
342 if (rc) {
343 LOGE("Error, unable to read chrome qtable");
344 return -1;
345 }
346
347 /* src buffer config*/
348 p_params->src_main_buf[i].buf_size = p_obj->input[i].size;
349 p_params->src_main_buf[i].buf_vaddr = p_obj->input[i].addr;
350 p_params->src_main_buf[i].fd = p_obj->input[i].p_pmem_fd;
351 p_params->src_main_buf[i].index = i;
352 p_params->src_main_buf[i].format = MM_JPEG_FMT_YUV;
353 p_params->src_main_buf[i].offset.mp[0].len = (uint32_t)size;
354 p_params->src_main_buf[i].offset.mp[0].stride = p_input->width;
355 p_params->src_main_buf[i].offset.mp[0].scanline = p_input->height;
356 p_params->src_main_buf[i].offset.mp[1].len = (uint32_t)(size >> 1);
357
358 /* src buffer config*/
359 p_params->src_thumb_buf[i].buf_size = p_obj->input[i].size;
360 p_params->src_thumb_buf[i].buf_vaddr = p_obj->input[i].addr;
361 p_params->src_thumb_buf[i].fd = p_obj->input[i].p_pmem_fd;
362 p_params->src_thumb_buf[i].index = i;
363 p_params->src_thumb_buf[i].format = MM_JPEG_FMT_YUV;
364 p_params->src_thumb_buf[i].offset.mp[0].len = (uint32_t)size;
365 p_params->src_thumb_buf[i].offset.mp[0].stride = p_input->width;
366 p_params->src_thumb_buf[i].offset.mp[0].scanline = p_input->height;
367 p_params->src_thumb_buf[i].offset.mp[1].len = (uint32_t)(size >> 1);
368
369
370 i++;
371 } while((++p_in)->filename);
372
373 p_obj->num_bufs = i;
374
375 pthread_mutex_init(&p_obj->lock, NULL);
376 pthread_cond_init(&p_obj->cond, NULL);
377
378
379 /* set encode parameters */
380 p_params->jpeg_cb = mm_jpeg_encode_callback;
381 p_params->userdata = p_obj;
382 p_params->color_format = p_input->col_fmt.fmt;
383 p_params->thumb_color_format = p_input->col_fmt.fmt;
384
385 if (p_obj->min_out_bufs) {
386 p_params->num_dst_bufs = 2;
387 } else {
388 p_params->num_dst_bufs = p_obj->num_bufs;
389 }
390
391 for (i = 0; i < (uint32_t)p_params->num_dst_bufs; i++) {
392 p_obj->output[i].size = size * 3/2;
393 rc = mm_jpeg_test_alloc(&p_obj->output[i], 0);
394 if (rc) {
395 LOGE("Error");
396 return -1;
397 }
398 /* dest buffer config */
399 p_params->dest_buf[i].buf_size = p_obj->output[i].size;
400 p_params->dest_buf[i].buf_vaddr = p_obj->output[i].addr;
401 p_params->dest_buf[i].fd = p_obj->output[i].p_pmem_fd;
402 p_params->dest_buf[i].index = i;
403 }
404
405
406 p_params->num_src_bufs = p_obj->num_bufs;
407 p_params->num_tmb_bufs = 0;
408 g_count = p_params->num_src_bufs;
409
410 p_params->encode_thumbnail = p_input->encode_thumbnail;
411 if (p_params->encode_thumbnail) {
412 p_params->num_tmb_bufs = p_obj->num_bufs;
413 }
414 p_params->quality = (uint32_t)p_input->main_quality;
415 p_params->thumb_quality = (uint32_t)p_input->thumb_quality;
416
417 p_job_params->dst_index = 0;
418 p_job_params->src_index = 0;
419 p_job_params->rotation = 0;
420
421 /* main dimension */
422 p_job_params->main_dim.src_dim.width = p_obj->width;
423 p_job_params->main_dim.src_dim.height = p_obj->height;
424 p_job_params->main_dim.dst_dim.width = p_obj->width;
425 p_job_params->main_dim.dst_dim.height = p_obj->height;
426 p_job_params->main_dim.crop.top = 0;
427 p_job_params->main_dim.crop.left = 0;
428 p_job_params->main_dim.crop.width = p_obj->width;
429 p_job_params->main_dim.crop.height = p_obj->height;
430
431 p_params->main_dim = p_job_params->main_dim;
432
433 /* thumb dimension */
434 p_job_params->thumb_dim.src_dim.width = p_obj->width;
435 p_job_params->thumb_dim.src_dim.height = p_obj->height;
436 p_job_params->thumb_dim.dst_dim.width = p_input->tmb_width;
437 p_job_params->thumb_dim.dst_dim.height = p_input->tmb_height;
438 p_job_params->thumb_dim.crop.top = 0;
439 p_job_params->thumb_dim.crop.left = 0;
440 p_job_params->thumb_dim.crop.width = 0;
441 p_job_params->thumb_dim.crop.height = 0;
442
443 p_params->thumb_dim = p_job_params->thumb_dim;
444
445 p_job_params->exif_info.numOfEntries = 0;
446 p_params->burst_mode = burst_mode;
447
448 /* Qtable */
449 p_job_params->qtable[0].eQuantizationTable =
450 OMX_IMAGE_QuantizationTableLuma;
451 p_job_params->qtable[1].eQuantizationTable =
452 OMX_IMAGE_QuantizationTableChroma;
453 p_job_params->qtable_set[0] = 1;
454 p_job_params->qtable_set[1] = 1;
455
456 for (i = 0; i < QUANT_SIZE; i++) {
457 p_job_params->qtable[0].nQuantizationMatrix[i] = DEFAULT_QTABLE_0[i];
458 p_job_params->qtable[1].nQuantizationMatrix[i] = DEFAULT_QTABLE_1[i];
459 }
460
461 p_obj->pic_size.w = (uint32_t)p_input->width;
462 p_obj->pic_size.h = (uint32_t)p_input->height;
463
464 p_obj->clinet_id = client_id;
465
466 return 0;
467 }
468
encode_test(void * data)469 static void *encode_test(void *data)
470 {
471 int rc = 0;
472 mm_jpeg_intf_test_t *jpeg_obj = (mm_jpeg_intf_test_t *)data;
473 char file_name[64];
474
475 uint32_t i = 0;
476 jpeg_obj->handle = jpeg_open(&jpeg_obj->ops, NULL, jpeg_obj->pic_size, NULL);
477 if (jpeg_obj->handle == 0) {
478 LOGE("Error");
479 jpeg_obj->ret = -1;
480 goto end;
481 }
482
483 rc = jpeg_obj->ops.create_session(jpeg_obj->handle, &jpeg_obj->params,
484 &jpeg_obj->job.encode_job.session_id);
485 if (jpeg_obj->job.encode_job.session_id == 0) {
486 LOGE("Error");
487 jpeg_obj->ret = -1;
488 goto end;
489 }
490
491 for (i = 0; i < jpeg_obj->num_bufs; i++) {
492 jpeg_obj->job.job_type = JPEG_JOB_TYPE_ENCODE;
493 jpeg_obj->job.encode_job.src_index = (int32_t) i;
494 jpeg_obj->job.encode_job.dst_index = (int32_t) i;
495 jpeg_obj->job.encode_job.thumb_index = (uint32_t) i;
496
497 if (jpeg_obj->params.burst_mode && jpeg_obj->min_out_bufs) {
498 jpeg_obj->job.encode_job.dst_index = -1;
499 }
500
501 rc = jpeg_obj->ops.start_job(&jpeg_obj->job, &jpeg_obj->job_id[i]);
502 if (rc) {
503 LOGE("Error");
504 jpeg_obj->ret = rc;
505 goto end;
506 }
507 }
508 jpeg_obj->job_id[i] = 0;
509
510 /*
511 usleep(5);
512 jpeg_obj->ops.abort_job(jpeg_obj->job_id[0]);
513 */
514 pthread_mutex_lock(&jpeg_obj->lock);
515 pthread_cond_wait(&jpeg_obj->cond, &jpeg_obj->lock);
516 pthread_mutex_unlock(&jpeg_obj->lock);
517
518 jpeg_obj->ops.destroy_session(jpeg_obj->job.encode_job.session_id);
519 jpeg_obj->ops.close(jpeg_obj->handle);
520
521 end:
522 for (i = 0; i < jpeg_obj->num_bufs; i++) {
523 if (!jpeg_obj->min_out_bufs) {
524 // Save output files
525 LOGE("Saving file%s addr %p len %zu",
526 jpeg_obj->out_filename[i],
527 jpeg_obj->output[i].addr, jpeg_obj->buf_filled_len[i]);
528
529 snprintf(file_name, sizeof(file_name), "%s_%d.jpg",
530 jpeg_obj->out_filename[i], jpeg_obj->clinet_id);
531 fprintf(stderr, "Output file for client %d = %s\n",
532 jpeg_obj->clinet_id, file_name);
533
534 DUMP_TO_FILE(file_name, jpeg_obj->output[i].addr,
535 jpeg_obj->buf_filled_len[i]);
536 }
537 mm_jpeg_test_free(&jpeg_obj->input[i]);
538 mm_jpeg_test_free(&jpeg_obj->output[i]);
539 }
540 return NULL;
541 }
542
543 #define MAX_FILE_CNT (20)
mm_jpeg_test_get_input(int argc,char * argv[],jpeg_test_input_t * p_test)544 static int mm_jpeg_test_get_input(int argc, char *argv[],
545 jpeg_test_input_t *p_test)
546 {
547 int c;
548 size_t in_file_cnt = 0, out_file_cnt = 0, i;
549 int idx = 0;
550 jpeg_test_input_t *p_test_base = p_test;
551
552 char *in_files[MAX_FILE_CNT];
553 char *out_files[MAX_FILE_CNT];
554
555 while ((c = getopt(argc, argv, "-I:O:W:H:F:BTx:y:Q:J:K:C:q:")) != -1) {
556 switch (c) {
557 case 'B':
558 fprintf(stderr, "%-25s\n", "Using burst mode");
559 p_test->burst_mode = 1;
560 break;
561 case 'I':
562 for (idx = optind - 1; idx < argc; idx++) {
563 if (argv[idx][0] == '-') {
564 break;
565 }
566 in_files[in_file_cnt++] = argv[idx];
567 }
568 optind = idx -1;
569
570 break;
571 case 'O':
572 for (idx = optind - 1; idx < argc; idx++) {
573 if (argv[idx][0] == '-') {
574 break;
575 }
576 out_files[out_file_cnt++] = argv[idx];
577 }
578 optind = idx -1;
579
580 break;
581 case 'W':
582 p_test->width = atoi(optarg);
583 fprintf(stderr, "%-25s%d\n", "Width: ", p_test->width);
584 break;
585 case 'H':
586 p_test->height = atoi(optarg);
587 fprintf(stderr, "%-25s%d\n", "Height: ", p_test->height);
588 break;
589 case 'F':
590 p_test->col_fmt = color_formats[atoi(optarg)];
591 fprintf(stderr, "%-25s%s\n", "Format: ", p_test->col_fmt.str);
592 break;
593 case 'M':
594 p_test->min_out_bufs = 1;
595 fprintf(stderr, "%-25s\n", "Using minimum number of output buffers");
596 break;
597 case 'T':
598 p_test->encode_thumbnail = 1;
599 fprintf(stderr, "%-25s\n", "Encode thumbnail");
600 break;
601 case 'x':
602 p_test->tmb_width = atoi(optarg);
603 fprintf(stderr, "%-25s%d\n", "Tmb Width: ", p_test->tmb_width);
604 break;
605 case 'y':
606 p_test->tmb_height = atoi(optarg);
607 fprintf(stderr, "%-25s%d\n", "Tmb Height: ", p_test->tmb_height);
608 break;
609 case 'Q':
610 p_test->main_quality = atoi(optarg);
611 fprintf(stderr, "%-25s%d\n", "Main quality: ", p_test->main_quality);
612 break;
613 case 'q':
614 p_test->thumb_quality = atoi(optarg);
615 fprintf(stderr, "%-25s%d\n", "Thumb quality: ", p_test->thumb_quality);
616 break;
617 case 'J':
618 p_test->qtable_luma_file = optarg;
619 fprintf(stderr, "%-25s%s\n", "Qtable luma path",
620 p_test->qtable_luma_file);
621 break;
622 case 'K':
623 p_test->qtable_chroma_file = optarg;
624 fprintf(stderr, "%-25s%s\n", "Qtable chroma path",
625 p_test->qtable_chroma_file);
626 break;
627 case 'C':
628 p_test->client_cnt = atoi(optarg);
629 fprintf(stderr, "%-25s%d\n", "Number of clients ",
630 p_test->client_cnt);
631 default:;
632 }
633 }
634 fprintf(stderr, "Infiles: %zu Outfiles: %zu\n", in_file_cnt, out_file_cnt);
635
636 if (p_test->client_cnt > MAX_NUM_CLIENT) {
637 fprintf(stderr, "Clients requested exceeds max limit %d\n",
638 MAX_NUM_CLIENT);
639 return 1;
640 }
641 if (in_file_cnt > out_file_cnt) {
642 fprintf(stderr, "%-25s\n", "Insufficient number of output files!");
643 return 1;
644 }
645
646 // Discard the extra out files
647 out_file_cnt = in_file_cnt;
648
649 p_test = realloc(p_test, (in_file_cnt + 1) * sizeof(*p_test));
650 if (!p_test) {
651 LOGE("Error");
652 return 1;
653 }
654 memset(p_test+1, 0, (in_file_cnt) * sizeof(*p_test));
655
656 for (i = 0; i < in_file_cnt; i++, p_test++) {
657 memcpy(p_test, p_test_base, sizeof(*p_test));
658 p_test->filename = in_files[i];
659 p_test->out_filename = out_files[i];
660 fprintf(stderr, "Inf: %s Outf: %s\n", in_files[i], out_files[i]);
661 }
662
663 return 0;
664 }
665
mm_jpeg_test_print_usage()666 static void mm_jpeg_test_print_usage()
667 {
668 fprintf(stderr, "Usage: program_name [options]\n");
669 fprintf(stderr, "Mandatory options:\n");
670 fprintf(stderr, " -I FILE1 [FILE2] [FILEN]\tList of input files\n");
671 fprintf(stderr, " -O FILE1 [FILE2] [FILEN]\tList of output files\n");
672 fprintf(stderr, " -W WIDTH\t\tOutput image width\n");
673 fprintf(stderr, " -H HEIGHT\t\tOutput image height\n");
674 fprintf(stderr, " -F \t\tColor format: \n");
675 fprintf(stderr, "\t\t\t\t%s (0), %s (1), %s (2) %s (3)\n"
676 "\t\t\t\t%s (4), %s (5), %s (6) %s (7)\n ",
677 color_formats[0].str, color_formats[1].str,
678 color_formats[2].str, color_formats[3].str,
679 color_formats[4].str, color_formats[5].str,
680 color_formats[6].str, color_formats[7].str);
681 fprintf(stderr, "Optional:\n");
682 fprintf(stderr, " -T \t\Encode thumbnail\n");
683 fprintf(stderr, " -x TMB_WIDTH\t\tThumbnail width\n");
684 fprintf(stderr, " -y TMB_HEIGHT\t\tThumbnail height\n");
685 fprintf(stderr, " -Q MAIN_QUALITY\t\tMain image quality\n");
686 fprintf(stderr, " -q TMB_QUALITY\t\tThumbnail image quality\n");
687 fprintf(stderr, " -B \t\tBurst mode. Utilize both encoder engines on"
688 "supported targets\n");
689 fprintf(stderr, " -M \t\tUse minimum number of output buffers \n");
690 fprintf(stderr, " -J \t\tLuma QTable filename. Comma separated 8x8"
691 " matrix\n");
692 fprintf(stderr, " -K \t\tChroma QTable filename. Comma separated"
693 " 8x8 matrix\n");
694 fprintf(stderr, " -C \t\tNumber of clients to run in parllel\n");
695 fprintf(stderr, "\n");
696 }
697
698 /** main:
699 *
700 * Arguments:
701 * @argc
702 * @argv
703 *
704 * Return:
705 * 0 or -ve values
706 *
707 * Description:
708 * main function
709 *
710 **/
main(int argc,char * argv[])711 int main(int argc, char* argv[])
712 {
713 jpeg_test_input_t *p_test_input;
714 mm_jpeg_intf_test_t client[MAX_NUM_CLIENT];
715 int ret = 0;
716 int i = 0;
717 int thread_cnt = 0;
718
719 if (argc > 1) {
720 p_test_input = calloc(2, sizeof(*p_test_input));
721 if (!p_test_input) {
722 LOGE("Error");
723 goto exit;
724 }
725 memcpy(p_test_input, &jpeg_input[0], sizeof(*p_test_input));
726 ret = mm_jpeg_test_get_input(argc, argv, p_test_input);
727 if (ret) {
728 LOGE("Error");
729 goto exit;
730 }
731 } else {
732 mm_jpeg_test_print_usage();
733 return 1;
734 }
735
736 for (i = 0; i < p_test_input->client_cnt; i++) {
737 memset(&client[i], 0x0, sizeof(mm_jpeg_intf_test_t));
738 ret = encode_init(p_test_input, &client[i], i);
739 if (ret) {
740 LOGE("Error");
741 return -1;
742 }
743
744 ret = pthread_create(&client[i].thread_id, NULL, encode_test,
745 &client[i]);
746 if (ret != 0) {
747 fprintf(stderr, "Error in thread creation\n");
748 break;
749 }
750 }
751
752 thread_cnt = i;
753 for (i = 0; i < thread_cnt; i++) {
754 pthread_join(client[i].thread_id, NULL);
755 }
756
757 exit:
758 for (i = 0; i < thread_cnt; i++) {
759 if (!client[i].ret) {
760 fprintf(stderr, "%-25s %d %s\n", "Client", i, "Success!");
761 } else {
762 fprintf(stderr, "%-25s %d %s\n", "Client", i, "Fail!");
763 }
764 }
765
766 if (argc > 1) {
767 if (p_test_input) {
768 free(p_test_input);
769 p_test_input = NULL;
770 }
771 }
772
773 return ret;
774 }
775
776
777