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
394 #ifdef MM_JPEG_USE_PIPELINE
395 rc = mm_jpeg_test_alloc(&p_obj->output[i], 1);
396 #else
397 rc = mm_jpeg_test_alloc(&p_obj->output[i], 0);
398 #endif
399
400 if (rc) {
401 LOGE("Error");
402 return -1;
403 }
404 /* dest buffer config */
405 p_params->dest_buf[i].buf_size = p_obj->output[i].size;
406 p_params->dest_buf[i].buf_vaddr = p_obj->output[i].addr;
407 p_params->dest_buf[i].fd = p_obj->output[i].p_pmem_fd;
408 p_params->dest_buf[i].index = i;
409 }
410
411
412 p_params->num_src_bufs = p_obj->num_bufs;
413 p_params->num_tmb_bufs = 0;
414 g_count = p_params->num_src_bufs;
415
416 p_params->encode_thumbnail = p_input->encode_thumbnail;
417 if (p_params->encode_thumbnail) {
418 p_params->num_tmb_bufs = p_obj->num_bufs;
419 }
420 p_params->quality = (uint32_t)p_input->main_quality;
421 p_params->thumb_quality = (uint32_t)p_input->thumb_quality;
422
423 p_job_params->dst_index = 0;
424 p_job_params->src_index = 0;
425 p_job_params->rotation = 0;
426
427 /* main dimension */
428 p_job_params->main_dim.src_dim.width = p_obj->width;
429 p_job_params->main_dim.src_dim.height = p_obj->height;
430 p_job_params->main_dim.dst_dim.width = p_obj->width;
431 p_job_params->main_dim.dst_dim.height = p_obj->height;
432 p_job_params->main_dim.crop.top = 0;
433 p_job_params->main_dim.crop.left = 0;
434 p_job_params->main_dim.crop.width = p_obj->width;
435 p_job_params->main_dim.crop.height = p_obj->height;
436
437 p_params->main_dim = p_job_params->main_dim;
438
439 /* thumb dimension */
440 p_job_params->thumb_dim.src_dim.width = p_obj->width;
441 p_job_params->thumb_dim.src_dim.height = p_obj->height;
442 p_job_params->thumb_dim.dst_dim.width = p_input->tmb_width;
443 p_job_params->thumb_dim.dst_dim.height = p_input->tmb_height;
444 p_job_params->thumb_dim.crop.top = 0;
445 p_job_params->thumb_dim.crop.left = 0;
446 p_job_params->thumb_dim.crop.width = 0;
447 p_job_params->thumb_dim.crop.height = 0;
448
449 p_params->thumb_dim = p_job_params->thumb_dim;
450
451 p_job_params->exif_info.numOfEntries = 0;
452 p_params->burst_mode = burst_mode;
453
454 /* Qtable */
455 p_job_params->qtable[0].eQuantizationTable =
456 OMX_IMAGE_QuantizationTableLuma;
457 p_job_params->qtable[1].eQuantizationTable =
458 OMX_IMAGE_QuantizationTableChroma;
459 p_job_params->qtable_set[0] = 1;
460 p_job_params->qtable_set[1] = 1;
461
462 for (i = 0; i < QUANT_SIZE; i++) {
463 p_job_params->qtable[0].nQuantizationMatrix[i] = DEFAULT_QTABLE_0[i];
464 p_job_params->qtable[1].nQuantizationMatrix[i] = DEFAULT_QTABLE_1[i];
465 }
466
467 p_obj->pic_size.w = (uint32_t)p_input->width;
468 p_obj->pic_size.h = (uint32_t)p_input->height;
469
470 p_obj->clinet_id = client_id;
471
472 return 0;
473 }
474
encode_test(void * data)475 static void *encode_test(void *data)
476 {
477 int rc = 0;
478 mm_jpeg_intf_test_t *jpeg_obj = (mm_jpeg_intf_test_t *)data;
479 char file_name[64];
480
481 uint32_t i = 0;
482 jpeg_obj->handle = jpeg_open(&jpeg_obj->ops, NULL, jpeg_obj->pic_size, NULL);
483 if (jpeg_obj->handle == 0) {
484 LOGE("Error");
485 jpeg_obj->ret = -1;
486 goto end;
487 }
488
489 rc = jpeg_obj->ops.create_session(jpeg_obj->handle, &jpeg_obj->params,
490 &jpeg_obj->job.encode_job.session_id);
491 if (jpeg_obj->job.encode_job.session_id == 0) {
492 LOGE("Error");
493 jpeg_obj->ret = -1;
494 goto end;
495 }
496
497 for (i = 0; i < jpeg_obj->num_bufs; i++) {
498 jpeg_obj->job.job_type = JPEG_JOB_TYPE_ENCODE;
499 jpeg_obj->job.encode_job.src_index = (int32_t) i;
500 jpeg_obj->job.encode_job.dst_index = (int32_t) i;
501 jpeg_obj->job.encode_job.thumb_index = (uint32_t) i;
502
503 if (jpeg_obj->params.burst_mode && jpeg_obj->min_out_bufs) {
504 jpeg_obj->job.encode_job.dst_index = -1;
505 }
506
507 rc = jpeg_obj->ops.start_job(&jpeg_obj->job, &jpeg_obj->job_id[i]);
508 if (rc) {
509 LOGE("Error");
510 jpeg_obj->ret = rc;
511 goto end;
512 }
513 }
514 jpeg_obj->job_id[i] = 0;
515
516 /*
517 usleep(5);
518 jpeg_obj->ops.abort_job(jpeg_obj->job_id[0]);
519 */
520 pthread_mutex_lock(&jpeg_obj->lock);
521 pthread_cond_wait(&jpeg_obj->cond, &jpeg_obj->lock);
522 pthread_mutex_unlock(&jpeg_obj->lock);
523
524 jpeg_obj->ops.destroy_session(jpeg_obj->job.encode_job.session_id);
525 jpeg_obj->ops.close(jpeg_obj->handle);
526
527 end:
528 for (i = 0; i < jpeg_obj->num_bufs; i++) {
529 if (!jpeg_obj->min_out_bufs) {
530 // Save output files
531 LOGE("Saving file%s addr %p len %zu",
532 jpeg_obj->out_filename[i],
533 jpeg_obj->output[i].addr, jpeg_obj->buf_filled_len[i]);
534
535 snprintf(file_name, sizeof(file_name), "%s_%d.jpg",
536 jpeg_obj->out_filename[i], jpeg_obj->clinet_id);
537 fprintf(stderr, "Output file for client %d = %s\n",
538 jpeg_obj->clinet_id, file_name);
539
540 DUMP_TO_FILE(file_name, jpeg_obj->output[i].addr,
541 jpeg_obj->buf_filled_len[i]);
542 }
543 mm_jpeg_test_free(&jpeg_obj->input[i]);
544 mm_jpeg_test_free(&jpeg_obj->output[i]);
545 }
546 return NULL;
547 }
548
549 #define MAX_FILE_CNT (20)
mm_jpeg_test_get_input(int argc,char * argv[],jpeg_test_input_t * p_test)550 static int mm_jpeg_test_get_input(int argc, char *argv[],
551 jpeg_test_input_t *p_test)
552 {
553 int c;
554 size_t in_file_cnt = 0, out_file_cnt = 0, i;
555 int idx = 0;
556 jpeg_test_input_t *p_test_base = p_test;
557
558 char *in_files[MAX_FILE_CNT];
559 char *out_files[MAX_FILE_CNT];
560
561 while ((c = getopt(argc, argv, "-I:O:W:H:F:BTx:y:Q:J:K:C:q:")) != -1) {
562 switch (c) {
563 case 'B':
564 fprintf(stderr, "%-25s\n", "Using burst mode");
565 p_test->burst_mode = 1;
566 break;
567 case 'I':
568 for (idx = optind - 1; idx < argc; idx++) {
569 if (argv[idx][0] == '-') {
570 break;
571 }
572 in_files[in_file_cnt++] = argv[idx];
573 }
574 optind = idx -1;
575
576 break;
577 case 'O':
578 for (idx = optind - 1; idx < argc; idx++) {
579 if (argv[idx][0] == '-') {
580 break;
581 }
582 out_files[out_file_cnt++] = argv[idx];
583 }
584 optind = idx -1;
585
586 break;
587 case 'W':
588 p_test->width = atoi(optarg);
589 fprintf(stderr, "%-25s%d\n", "Width: ", p_test->width);
590 break;
591 case 'H':
592 p_test->height = atoi(optarg);
593 fprintf(stderr, "%-25s%d\n", "Height: ", p_test->height);
594 break;
595 case 'F':
596 p_test->col_fmt = color_formats[atoi(optarg)];
597 fprintf(stderr, "%-25s%s\n", "Format: ", p_test->col_fmt.str);
598 break;
599 case 'M':
600 p_test->min_out_bufs = 1;
601 fprintf(stderr, "%-25s\n", "Using minimum number of output buffers");
602 break;
603 case 'T':
604 p_test->encode_thumbnail = 1;
605 fprintf(stderr, "%-25s\n", "Encode thumbnail");
606 break;
607 case 'x':
608 p_test->tmb_width = atoi(optarg);
609 fprintf(stderr, "%-25s%d\n", "Tmb Width: ", p_test->tmb_width);
610 break;
611 case 'y':
612 p_test->tmb_height = atoi(optarg);
613 fprintf(stderr, "%-25s%d\n", "Tmb Height: ", p_test->tmb_height);
614 break;
615 case 'Q':
616 p_test->main_quality = atoi(optarg);
617 fprintf(stderr, "%-25s%d\n", "Main quality: ", p_test->main_quality);
618 break;
619 case 'q':
620 p_test->thumb_quality = atoi(optarg);
621 fprintf(stderr, "%-25s%d\n", "Thumb quality: ", p_test->thumb_quality);
622 break;
623 case 'J':
624 p_test->qtable_luma_file = optarg;
625 fprintf(stderr, "%-25s%s\n", "Qtable luma path",
626 p_test->qtable_luma_file);
627 break;
628 case 'K':
629 p_test->qtable_chroma_file = optarg;
630 fprintf(stderr, "%-25s%s\n", "Qtable chroma path",
631 p_test->qtable_chroma_file);
632 break;
633 case 'C':
634 p_test->client_cnt = atoi(optarg);
635 fprintf(stderr, "%-25s%d\n", "Number of clients ",
636 p_test->client_cnt);
637 default:;
638 }
639 }
640 fprintf(stderr, "Infiles: %zu Outfiles: %zu\n", in_file_cnt, out_file_cnt);
641
642 if (p_test->client_cnt > MAX_NUM_CLIENT) {
643 fprintf(stderr, "Clients requested exceeds max limit %d\n",
644 MAX_NUM_CLIENT);
645 return 1;
646 }
647 if (in_file_cnt > out_file_cnt) {
648 fprintf(stderr, "%-25s\n", "Insufficient number of output files!");
649 return 1;
650 }
651
652 // Discard the extra out files
653 out_file_cnt = in_file_cnt;
654
655 p_test = realloc(p_test, (in_file_cnt + 1) * sizeof(*p_test));
656 if (!p_test) {
657 LOGE("Error");
658 return 1;
659 }
660 memset(p_test+1, 0, (in_file_cnt) * sizeof(*p_test));
661
662 for (i = 0; i < in_file_cnt; i++, p_test++) {
663 memcpy(p_test, p_test_base, sizeof(*p_test));
664 p_test->filename = in_files[i];
665 p_test->out_filename = out_files[i];
666 fprintf(stderr, "Inf: %s Outf: %s\n", in_files[i], out_files[i]);
667 }
668
669 return 0;
670 }
671
mm_jpeg_test_print_usage()672 static void mm_jpeg_test_print_usage()
673 {
674 fprintf(stderr, "Usage: program_name [options]\n");
675 fprintf(stderr, "Mandatory options:\n");
676 fprintf(stderr, " -I FILE1 [FILE2] [FILEN]\tList of input files\n");
677 fprintf(stderr, " -O FILE1 [FILE2] [FILEN]\tList of output files\n");
678 fprintf(stderr, " -W WIDTH\t\tOutput image width\n");
679 fprintf(stderr, " -H HEIGHT\t\tOutput image height\n");
680 fprintf(stderr, " -F \t\tColor format: \n");
681 fprintf(stderr, "\t\t\t\t%s (0), %s (1), %s (2) %s (3)\n"
682 "\t\t\t\t%s (4), %s (5), %s (6) %s (7)\n ",
683 color_formats[0].str, color_formats[1].str,
684 color_formats[2].str, color_formats[3].str,
685 color_formats[4].str, color_formats[5].str,
686 color_formats[6].str, color_formats[7].str);
687 fprintf(stderr, "Optional:\n");
688 fprintf(stderr, " -T \t\Encode thumbnail\n");
689 fprintf(stderr, " -x TMB_WIDTH\t\tThumbnail width\n");
690 fprintf(stderr, " -y TMB_HEIGHT\t\tThumbnail height\n");
691 fprintf(stderr, " -Q MAIN_QUALITY\t\tMain image quality\n");
692 fprintf(stderr, " -q TMB_QUALITY\t\tThumbnail image quality\n");
693 fprintf(stderr, " -B \t\tBurst mode. Utilize both encoder engines on"
694 "supported targets\n");
695 fprintf(stderr, " -M \t\tUse minimum number of output buffers \n");
696 fprintf(stderr, " -J \t\tLuma QTable filename. Comma separated 8x8"
697 " matrix\n");
698 fprintf(stderr, " -K \t\tChroma QTable filename. Comma separated"
699 " 8x8 matrix\n");
700 fprintf(stderr, " -C \t\tNumber of clients to run in parllel\n");
701 fprintf(stderr, "\n");
702 }
703
704 /** main:
705 *
706 * Arguments:
707 * @argc
708 * @argv
709 *
710 * Return:
711 * 0 or -ve values
712 *
713 * Description:
714 * main function
715 *
716 **/
main(int argc,char * argv[])717 int main(int argc, char* argv[])
718 {
719 jpeg_test_input_t *p_test_input;
720 mm_jpeg_intf_test_t client[MAX_NUM_CLIENT];
721 int ret = 0;
722 int i = 0;
723 int thread_cnt = 0;
724
725 if (argc > 1) {
726 p_test_input = calloc(2, sizeof(*p_test_input));
727 if (!p_test_input) {
728 LOGE("Error");
729 goto exit;
730 }
731 memcpy(p_test_input, &jpeg_input[0], sizeof(*p_test_input));
732 ret = mm_jpeg_test_get_input(argc, argv, p_test_input);
733 if (ret) {
734 LOGE("Error");
735 goto exit;
736 }
737 } else {
738 mm_jpeg_test_print_usage();
739 return 1;
740 }
741
742 for (i = 0; i < p_test_input->client_cnt; i++) {
743 memset(&client[i], 0x0, sizeof(mm_jpeg_intf_test_t));
744 ret = encode_init(p_test_input, &client[i], i);
745 if (ret) {
746 LOGE("Error");
747 return -1;
748 }
749
750 ret = pthread_create(&client[i].thread_id, NULL, encode_test,
751 &client[i]);
752 if (ret != 0) {
753 fprintf(stderr, "Error in thread creation\n");
754 break;
755 }
756 }
757
758 thread_cnt = i;
759 for (i = 0; i < thread_cnt; i++) {
760 pthread_join(client[i].thread_id, NULL);
761 }
762
763 exit:
764 for (i = 0; i < thread_cnt; i++) {
765 if (!client[i].ret) {
766 fprintf(stderr, "%-25s %d %s\n", "Client", i, "Success!");
767 } else {
768 fprintf(stderr, "%-25s %d %s\n", "Client", i, "Fail!");
769 }
770 }
771
772 if (argc > 1) {
773 if (p_test_input) {
774 free(p_test_input);
775 p_test_input = NULL;
776 }
777 }
778
779 return ret;
780 }
781
782
783