1 /*
2 * Copyright 2020 Rockchip Electronics Co. LTD
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define MODULE_TAG "mpi_dec_utils"
18
19 #include <string.h>
20 #include <pthread.h>
21
22 #include "rk_mpi.h"
23
24 #include "mpp_env.h"
25 #include "mpp_mem.h"
26 #include "mpp_lock.h"
27 #include "mpp_time.h"
28 #include "mpp_common.h"
29 #include "mpp_buffer.h"
30
31 #include "mpp_opt.h"
32 #include "mpi_dec_utils.h"
33
34 #define IVF_HEADER_LENGTH 32
35 #define IVF_FRAME_HEADER_LENGTH 12
36
37 #define DEFAULT_PACKET_SIZE SZ_4K
38
39 typedef enum {
40 FILE_NORMAL_TYPE,
41 FILE_JPEG_TYPE,
42 FILE_IVF_TYPE,
43 FILE_BUTT,
44 } FileType;
45
46 typedef FileBufSlot *(*ReaderFunc)(FileReader data);
47
48 typedef struct FileReader_t {
49 FILE *fp_input;
50 size_t file_size;
51
52 MppCodingType type;
53 FileType file_type;
54 char *buf;
55 size_t buf_size;
56 size_t stuff_size;
57 RK_S32 seek_base;
58 ReaderFunc read_func;
59
60 /* return value for each read */
61 size_t read_total;
62 size_t read_size;
63 MppBufferGroup group;
64
65 pthread_t thd;
66 volatile RK_U32 thd_stop;
67
68 RK_U32 slot_max;
69 RK_U32 slot_cnt;
70 RK_U32 slot_rd_idx;
71 FileBufSlot **slots;
72 } FileReaderImpl;
73
74 #define READ_ONCE(var) (*((volatile typeof(var) *)(&(var))))
75
76 OptionInfo mpi_dec_cmd[] = {
77 {"i", "input_file", "input bitstream file"},
78 {"o", "output_file", "output bitstream file, "},
79 {"c", "ops_file", "input operation config file"},
80 {"w", "width", "the width of input bitstream"},
81 {"h", "height", "the height of input bitstream"},
82 {"t", "type", "input stream coding type"},
83 {"f", "format", "output frame format type"},
84 {"x", "timeout", "output timeout interval"},
85 {"n", "frame_number", "max output frame number"},
86 {"s", "instance_nb", "number of instances"},
87 {"v", "trace", "q - quiet f - show fps"},
88 {"c", "verify_file", "verify file for slt check"},
89 {NULL, NULL, NULL},
90 };
91
add_new_slot(FileReaderImpl * impl,FileBufSlot * slot)92 static MPP_RET add_new_slot(FileReaderImpl* impl, FileBufSlot *slot)
93 {
94 mpp_assert(impl);
95
96 slot->index = impl->slot_cnt;
97 impl->slots[impl->slot_cnt] = slot;
98 impl->slot_cnt++;
99
100 if (impl->slot_cnt >= impl->slot_max) {
101 impl->slots = mpp_realloc(impl->slots, FileBufSlot*, impl->slot_max * 2);
102 if (!impl->slots)
103 return MPP_NOK;
104
105 impl->slot_max *= 2;
106 }
107
108 mpp_assert(impl->slots);
109 mpp_assert(impl->slot_cnt < impl->slot_max);
110
111 return MPP_OK;
112 }
113
read_ivf_file(FileReader data)114 static FileBufSlot *read_ivf_file(FileReader data)
115 {
116 FileReaderImpl *impl = (FileReaderImpl*)data;
117 RK_U8 ivf_data[IVF_FRAME_HEADER_LENGTH] = {0};
118 size_t ivf_data_size = IVF_FRAME_HEADER_LENGTH;
119 FILE *fp = impl->fp_input;
120 FileBufSlot *slot = NULL;
121 size_t data_size = 0;
122 size_t read_size = 0;
123 RK_U32 eos = 0;
124
125 if (fread(ivf_data, 1, ivf_data_size, fp) != ivf_data_size) {
126 /* end of frame queue */
127 slot = mpp_calloc(FileBufSlot, 1);
128 slot->eos = 1;
129
130 return slot;
131 }
132
133 impl->read_total += ivf_data_size;
134 data_size = ivf_data[0] | (ivf_data[1] << 8) | (ivf_data[2] << 16) | (ivf_data[3] << 24);
135 slot = mpp_malloc_size(FileBufSlot, MPP_ALIGN(sizeof(FileBufSlot) + data_size, SZ_4K));
136 slot->data = (char *)(slot + 1);
137 read_size = fread(slot->data, 1, data_size, fp);
138 impl->read_total += read_size;
139 impl->read_size = read_size;
140
141 if (!data_size)
142 mpp_err("data_size is zero! ftell size %d\n", ftell(fp));
143 /* check reach eos whether or not */
144 if (!data_size || read_size != data_size || feof(fp) || impl->read_total >= impl->file_size)
145 eos = 1;
146
147 slot->buf = NULL;
148 slot->size = read_size;
149 slot->eos = eos;
150
151 return slot;
152 }
153
read_jpeg_file(FileReader data)154 static FileBufSlot *read_jpeg_file(FileReader data)
155 {
156 FileReaderImpl *impl = (FileReaderImpl*)data;
157 FILE *fp = impl->fp_input;
158 size_t read_size = 0;
159 size_t buf_size = impl->file_size;
160 MppBuffer hw_buf = NULL;
161 FileBufSlot *slot = mpp_calloc(FileBufSlot, 1);
162
163 mpp_buffer_get(impl->group, &hw_buf, impl->file_size);
164 mpp_assert(hw_buf);
165
166 slot->data = mpp_buffer_get_ptr(hw_buf);
167 mpp_assert(slot->data);
168 read_size = fread(slot->data, 1, buf_size, fp);
169
170 mpp_assert(read_size == buf_size);
171
172 impl->read_total += read_size;
173 impl->read_size = read_size;
174
175 slot->buf = hw_buf;
176 slot->size = read_size;
177 slot->eos = 1;
178
179 return slot;
180 }
181
read_normal_file(FileReader data)182 static FileBufSlot *read_normal_file(FileReader data)
183 {
184 FileReaderImpl *impl = (FileReaderImpl*)data;
185 FILE *fp = impl->fp_input;
186 size_t read_size = 0;
187 size_t buf_size = impl->buf_size;
188 size_t size = sizeof(FileBufSlot) + buf_size + impl->stuff_size;
189 FileBufSlot *slot = mpp_malloc_size(FileBufSlot, size);
190 RK_U32 eos = 0;
191
192 slot->data = (char *)(slot + 1);
193 read_size = fread(slot->data, 1, buf_size, fp);
194 impl->read_total += read_size;
195 impl->read_size = read_size;
196
197 /* check reach eos whether or not */
198 if (read_size != buf_size || feof(fp) || impl->read_total >= impl->file_size)
199 eos = 1;
200
201 slot->buf = NULL;
202 slot->size = read_size;
203 slot->eos = eos;
204
205 return slot;
206 }
207
check_file_type(FileReader data,char * file_in,MppCodingType type)208 static void check_file_type(FileReader data, char *file_in, MppCodingType type)
209 {
210 FileReaderImpl *impl = (FileReaderImpl*)data;
211
212 if (strstr(file_in, ".ivf")) {
213 impl->file_type = FILE_IVF_TYPE;
214 impl->buf_size = 0;
215 impl->stuff_size = 0;
216 impl->seek_base = IVF_HEADER_LENGTH;
217 impl->read_func = read_ivf_file;
218 impl->slot_max = 1024; /* preset 1024 file slots */
219
220 fseek(impl->fp_input, impl->seek_base, SEEK_SET);
221 impl->read_total = impl->seek_base;
222 } else if (strstr(file_in, ".jpg") ||
223 strstr(file_in, ".jpeg") ||
224 strstr(file_in, ".mjpeg") ||
225 type == MPP_VIDEO_CodingMJPEG) {
226 impl->file_type = FILE_JPEG_TYPE;
227 impl->buf_size = impl->file_size;
228 impl->stuff_size = 0;
229 impl->seek_base = 0;
230 impl->read_func = read_jpeg_file;
231 impl->slot_max = 1;
232 mpp_buffer_group_get_internal(&impl->group, MPP_BUFFER_TYPE_ION);
233 mpp_assert(impl->group);
234 } else {
235 RK_U32 buf_size = 0;
236
237 mpp_env_get_u32("reader_buf_size", &buf_size, DEFAULT_PACKET_SIZE);
238
239 buf_size = MPP_MAX(buf_size, SZ_4K);
240 buf_size = MPP_ALIGN(buf_size, SZ_4K);
241
242 impl->file_type = FILE_NORMAL_TYPE;
243 impl->buf_size = buf_size;
244 impl->stuff_size = 256;
245 impl->seek_base = 0;
246 impl->read_func = read_normal_file;
247 impl->slot_max = 1024; /* preset 1024 file slots */
248 }
249 }
250
reader_size(FileReader reader)251 size_t reader_size(FileReader reader)
252 {
253 FileReaderImpl *impl = (FileReaderImpl*)reader;
254 size_t size = 0;
255
256 if (impl)
257 size = impl->file_size;
258
259 return size;
260 }
261
reader_read(FileReader reader,FileBufSlot ** buf)262 MPP_RET reader_read(FileReader reader, FileBufSlot **buf)
263 {
264 FileReaderImpl *impl = (FileReaderImpl*)reader;
265 FileBufSlot *slot = NULL;
266
267 if (NULL == impl || NULL == impl->slots) {
268 mpp_log_f("invalid reader %p\n", reader);
269 return MPP_NOK;
270 }
271
272 if (impl->slot_rd_idx >= impl->slot_max) {
273 mpp_log_f("invalid read index % max %d\n", impl->slot_rd_idx, impl->slot_max);
274 return MPP_NOK;
275 }
276
277 do {
278 slot = impl->slots[impl->slot_rd_idx];
279 if (slot == NULL || (impl->slot_rd_idx > impl->slot_cnt))
280 msleep(1);
281 } while (slot == NULL);
282
283 mpp_assert(slot);
284
285 *buf = slot;
286 impl->slot_rd_idx++;
287
288 return MPP_OK;
289 }
290
reader_index_read(FileReader reader,RK_S32 index,FileBufSlot ** buf)291 MPP_RET reader_index_read(FileReader reader, RK_S32 index, FileBufSlot **buf)
292 {
293 FileReaderImpl *impl = (FileReaderImpl*)reader;
294 FileBufSlot *slot = NULL;
295
296 if (NULL == impl || NULL == impl->slots) {
297 mpp_log_f("invalid reader %p\n", reader);
298 return MPP_NOK;
299 }
300
301 if (index >= (RK_S32)impl->slot_max) {
302 mpp_log_f("invalid read index % max %d\n", index, impl->slot_max);
303 return MPP_NOK;
304 }
305
306 do {
307 slot = impl->slots[index];
308 if (slot == NULL)
309 msleep(1);
310 } while (slot == NULL);
311
312 mpp_assert(slot);
313
314 *buf = slot;
315
316 return MPP_OK;
317 }
318
reader_rewind(FileReader reader)319 void reader_rewind(FileReader reader)
320 {
321 FileReaderImpl *impl = (FileReaderImpl*)reader;
322
323 impl->slot_rd_idx = 0;
324 }
325
reader_init(FileReader * reader,char * file_in,MppCodingType type)326 void reader_init(FileReader* reader, char* file_in, MppCodingType type)
327 {
328 FILE *fp_input = fopen(file_in, "rb");
329 FileReaderImpl *impl = NULL;
330
331 if (!fp_input) {
332 mpp_err("failed to open input file %s\n", file_in);
333 *reader = NULL;
334 return;
335 }
336
337 impl = mpp_calloc(FileReaderImpl, 1);
338 mpp_assert(impl);
339
340 impl->fp_input = fp_input;
341 fseek(fp_input, 0L, SEEK_END);
342 impl->file_size = ftell(fp_input);
343 fseek(fp_input, 0L, SEEK_SET);
344
345 check_file_type(impl, file_in, type);
346
347 impl->slots = mpp_calloc(FileBufSlot*, impl->slot_max);
348
349 reader_start(impl);
350
351 *reader = impl;
352 }
353
reader_deinit(FileReader reader)354 void reader_deinit(FileReader reader)
355 {
356 FileReaderImpl *impl = (FileReaderImpl*)(reader);
357 RK_U32 i;
358
359 mpp_assert(impl);
360 reader_stop(impl);
361
362 if (impl->fp_input) {
363 fclose(impl->fp_input);
364 impl->fp_input = NULL;
365 }
366
367 for (i = 0; i < impl->slot_cnt; i++) {
368 FileBufSlot *slot = impl->slots[i];
369 if (!slot)
370 continue;
371
372 if (slot->buf) {
373 mpp_buffer_put(slot->buf);
374 slot->buf = NULL;
375 }
376 MPP_FREE(impl->slots[i]);
377 }
378
379 if (impl->group) {
380 mpp_buffer_group_put(impl->group);
381 impl->group = NULL;
382 }
383
384 MPP_FREE(impl->slots);
385 MPP_FREE(impl);
386 }
387
reader_worker(void * param)388 static void* reader_worker(void *param)
389 {
390 FileReaderImpl *impl = (FileReaderImpl*)param;
391 RK_U32 eos = 0;
392
393 while (!impl->thd_stop && !eos) {
394 FileBufSlot *slot = impl->read_func(impl);
395
396 if (NULL == slot)
397 break;
398
399 add_new_slot(impl, slot);
400 eos = slot->eos;
401 }
402
403 return NULL;
404 }
405
reader_start(FileReader reader)406 void reader_start(FileReader reader)
407 {
408 FileReaderImpl *impl = (FileReaderImpl*)reader;
409
410 impl->thd_stop = 0;
411 pthread_create(&impl->thd, NULL, reader_worker, impl);
412 }
413
reader_sync(FileReader reader)414 void reader_sync(FileReader reader)
415 {
416 FileReaderImpl *impl = (FileReaderImpl*)reader;
417
418 pthread_join(impl->thd, NULL);
419 impl->thd_stop = 1;
420 }
421
reader_stop(FileReader reader)422 void reader_stop(FileReader reader)
423 {
424 FileReaderImpl *impl = (FileReaderImpl*)reader;
425
426 if (MPP_BOOL_CAS(&impl->thd_stop, 0, 1))
427 pthread_join(impl->thd, NULL);
428 }
429
show_dec_fps(RK_S64 total_time,RK_S64 total_count,RK_S64 last_time,RK_S64 last_count)430 void show_dec_fps(RK_S64 total_time, RK_S64 total_count, RK_S64 last_time, RK_S64 last_count)
431 {
432 float avg_fps = (float)total_count * 1000000 / total_time;
433 float ins_fps = (float)last_count * 1000000 / last_time;
434
435 mpp_log("decoded %10lld frame fps avg %7.2f ins %7.2f\n",
436 total_count, avg_fps, ins_fps);
437 }
438
mpi_dec_opt_i(void * ctx,const char * next)439 RK_S32 mpi_dec_opt_i(void *ctx, const char *next)
440 {
441 MpiDecTestCmd *cmd = (MpiDecTestCmd *)ctx;
442
443 if (next) {
444 strncpy(cmd->file_input, next, MAX_FILE_NAME_LENGTH - 1);
445 cmd->have_input = 1;
446 if (!cmd->type)
447 name_to_coding_type(cmd->file_input, &cmd->type);
448 return 1;
449 }
450
451 mpp_err("input file is invalid\n");
452 return 0;
453 }
454
mpi_dec_opt_o(void * ctx,const char * next)455 RK_S32 mpi_dec_opt_o(void *ctx, const char *next)
456 {
457 MpiDecTestCmd *cmd = (MpiDecTestCmd *)ctx;
458
459 if (next) {
460 strncpy(cmd->file_output, next, MAX_FILE_NAME_LENGTH - 1);
461 cmd->have_output = 1;
462 return 1;
463 }
464
465 mpp_log("output file is invalid\n");
466 return 0;
467 }
468
mpi_dec_opt_w(void * ctx,const char * next)469 RK_S32 mpi_dec_opt_w(void *ctx, const char *next)
470 {
471 MpiDecTestCmd *cmd = (MpiDecTestCmd *)ctx;
472
473 if (next) {
474 cmd->width = atoi(next);
475 return 1;
476 }
477
478 mpp_err("invalid input width\n");
479 return 0;
480 }
481
mpi_dec_opt_h(void * ctx,const char * next)482 RK_S32 mpi_dec_opt_h(void *ctx, const char *next)
483 {
484 MpiDecTestCmd *cmd = (MpiDecTestCmd *)ctx;
485
486 if (next) {
487 cmd->height = atoi(next);
488 return 1;
489 }
490
491 mpp_err("invalid input height\n");
492 return 0;
493 }
494
mpi_dec_opt_t(void * ctx,const char * next)495 RK_S32 mpi_dec_opt_t(void *ctx, const char *next)
496 {
497 MpiDecTestCmd *cmd = (MpiDecTestCmd *)ctx;
498
499 if (next) {
500 MPP_RET ret;
501
502 cmd->type = (MppCodingType)atoi(next);
503 ret = mpp_check_support_format(MPP_CTX_DEC, cmd->type);
504 if (!ret)
505 return 1;
506 }
507
508 mpp_err("invalid input coding type\n");
509 return 0;
510 }
511
mpi_dec_opt_f(void * ctx,const char * next)512 RK_S32 mpi_dec_opt_f(void *ctx, const char *next)
513 {
514 MpiDecTestCmd *cmd = (MpiDecTestCmd *)ctx;
515
516 if (next) {
517 cmd->format = (MppFrameFormat)atoi(next);
518
519 if (MPP_FRAME_FMT_IS_YUV(cmd->format) ||
520 MPP_FRAME_FMT_IS_RGB(cmd->format))
521 return 1;
522 }
523
524 mpp_err("invalid output format\n");
525 cmd->format = MPP_FMT_BUTT;
526 return 0;
527 }
528
mpi_dec_opt_n(void * ctx,const char * next)529 RK_S32 mpi_dec_opt_n(void *ctx, const char *next)
530 {
531 MpiDecTestCmd *cmd = (MpiDecTestCmd *)ctx;
532
533 if (next) {
534 cmd->frame_num = atoi(next);
535
536 if (cmd->frame_num < 0)
537 mpp_log("infinite loop decoding mode\n");
538
539 return 1;
540 }
541
542 mpp_err("invalid frame number\n");
543 return 0;
544 }
545
mpi_dec_opt_s(void * ctx,const char * next)546 RK_S32 mpi_dec_opt_s(void *ctx, const char *next)
547 {
548 MpiDecTestCmd *cmd = (MpiDecTestCmd *)ctx;
549
550 cmd->nthreads = -1;
551 if (next) {
552 cmd->nthreads = atoi(next);
553 if (cmd->nthreads >= 1)
554 return 1;
555 }
556
557 mpp_err("invalid nthreads %d\n", cmd->nthreads);
558 cmd->nthreads = 1;
559 return 0;
560 }
561
mpi_dec_opt_v(void * ctx,const char * next)562 RK_S32 mpi_dec_opt_v(void *ctx, const char *next)
563 {
564 MpiDecTestCmd *cmd = (MpiDecTestCmd *)ctx;
565
566 if (next) {
567 if (strstr(next, "q"))
568 cmd->quiet = 1;
569 if (strstr(next, "f"))
570 cmd->trace_fps = 1;
571
572 return 1;
573 }
574
575 return 0;
576 }
577
mpi_dec_opt_slt(void * ctx,const char * next)578 RK_S32 mpi_dec_opt_slt(void *ctx, const char *next)
579 {
580 MpiDecTestCmd *cmd = (MpiDecTestCmd *)ctx;
581
582 if (next) {
583 size_t len = strnlen(next, MAX_FILE_NAME_LENGTH);
584 if (len) {
585 cmd->file_slt = mpp_calloc(char, len + 1);
586 strncpy(cmd->file_slt, next, len);
587
588 return 1;
589 }
590 }
591
592 mpp_err("input slt verify file is invalid\n");
593 return 0;
594 }
595
mpi_dec_opt_help(void * ctx,const char * next)596 RK_S32 mpi_dec_opt_help(void *ctx, const char *next)
597 {
598 (void)ctx;
599 (void)next;
600 /* return invalid option to print help */
601 return -1;
602 }
603
604 static MppOptInfo dec_opts[] = {
605 {"i", "input_file", "input bitstream file", mpi_dec_opt_i},
606 {"o", "output_file", "output decoded frame file", mpi_dec_opt_o},
607 {"w", "width", "the width of input bitstream", mpi_dec_opt_w},
608 {"h", "height", "the height of input bitstream", mpi_dec_opt_h},
609 {"t", "type", "input stream coding type", mpi_dec_opt_t},
610 {"f", "format", "output frame format type", mpi_dec_opt_f},
611 {"n", "frame_number", "max output frame number", mpi_dec_opt_n},
612 {"s", "instance_nb", "number of instances", mpi_dec_opt_s},
613 {"v", "trace option", "q - quiet f - show fps", mpi_dec_opt_v},
614 {"slt", "slt file", "slt verify data file", mpi_dec_opt_slt},
615 {"help", "help", "show help", mpi_dec_opt_help},
616 };
617
618 static RK_U32 dec_opt_cnt = MPP_ARRAY_ELEMS(dec_opts);
619
mpi_dec_show_help(const char * name)620 RK_S32 mpi_dec_show_help(const char *name)
621 {
622 RK_U32 max_name = 1;
623 RK_U32 max_full_name = 1;
624 RK_U32 max_help = 1;
625 char logs[256];
626 RK_U32 len;
627 RK_U32 i;
628
629 mpp_log("usage: %s [options]\n", name);
630
631 for (i = 0; i < dec_opt_cnt; i++) {
632 MppOptInfo *opt = &dec_opts[i];
633
634 if (opt->name) {
635 len = strlen(opt->name);
636 if (len > max_name)
637 max_name = len;
638 }
639
640 if (opt->full_name) {
641 len = strlen(opt->full_name);
642 if (len > max_full_name)
643 max_full_name = len;
644 }
645
646 if (opt->help) {
647 len = strlen(opt->help);
648 if (len > max_help)
649 max_help = len;
650 }
651 }
652
653 snprintf(logs, sizeof(logs) - 1, "-%%-%ds %%-%ds %%-%ds\n", max_name, max_full_name, max_help);
654
655 for (i = 0; i < dec_opt_cnt; i++) {
656 MppOptInfo *opt = &dec_opts[i];
657
658 mpp_log(logs, opt->name, opt->full_name, opt->help);
659 }
660 mpp_show_support_format();
661
662 return -1;
663 }
664
mpi_dec_test_cmd_init(MpiDecTestCmd * cmd,int argc,char ** argv)665 RK_S32 mpi_dec_test_cmd_init(MpiDecTestCmd* cmd, int argc, char **argv)
666 {
667 MppOpt opts = NULL;
668 RK_S32 ret = -1;
669 RK_U32 i;
670
671 if ((argc < 2) || (cmd == NULL))
672 goto done;
673
674 mpp_opt_init(&opts);
675 /* should change node count when option increases */
676 mpp_opt_setup(opts, cmd, 22, dec_opt_cnt);
677
678 for (i = 0; i < dec_opt_cnt; i++)
679 mpp_opt_add(opts, &dec_opts[i]);
680
681 /* mark option end */
682 mpp_opt_add(opts, NULL);
683
684 ret = mpp_opt_parse(opts, argc, argv);
685
686 if (cmd->have_input) {
687 reader_init(&cmd->reader, cmd->file_input, cmd->type);
688 if (cmd->reader)
689 mpp_log("input file %s size %ld\n", cmd->file_input, reader_size(cmd->reader));
690 }
691 if (cmd->trace_fps) {
692 fps_calc_init(&cmd->fps);
693 mpp_assert(cmd->fps);
694 fps_calc_set_cb(cmd->fps, show_dec_fps);
695 }
696
697 done:
698 if (opts) {
699 mpp_opt_deinit(opts);
700 opts = NULL;
701 }
702
703 if (ret)
704 mpi_dec_show_help(argv[0]);
705
706 return ret;
707 }
708
mpi_dec_test_cmd_deinit(MpiDecTestCmd * cmd)709 RK_S32 mpi_dec_test_cmd_deinit(MpiDecTestCmd* cmd)
710 {
711 if (!cmd)
712 return 0;
713
714 if (cmd->reader) {
715 reader_deinit(cmd->reader);
716 cmd->reader = NULL;
717 }
718
719 MPP_FREE(cmd->file_slt);
720
721 if (cmd->fps) {
722 fps_calc_deinit(cmd->fps);
723 cmd->fps = NULL;
724 }
725
726 return 0;
727 }
728
mpi_dec_test_cmd_options(MpiDecTestCmd * cmd)729 void mpi_dec_test_cmd_options(MpiDecTestCmd* cmd)
730 {
731 if (cmd->quiet)
732 return;
733
734 mpp_log("cmd parse result:\n");
735 mpp_log("input file name: %s\n", cmd->file_input);
736 mpp_log("output file name: %s\n", cmd->file_output);
737 mpp_log("width : %4d\n", cmd->width);
738 mpp_log("height : %4d\n", cmd->height);
739 mpp_log("type : %4d\n", cmd->type);
740 mpp_log("max frames : %4d\n", cmd->frame_num);
741 if (cmd->file_slt)
742 mpp_log("verify : %s\n", cmd->file_slt);
743 }
744