1*437bfbebSnyanmisaka /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2*437bfbebSnyanmisaka /*
3*437bfbebSnyanmisaka * Copyright (c) 2022 Rockchip Electronics Co., Ltd.
4*437bfbebSnyanmisaka */
5*437bfbebSnyanmisaka
6*437bfbebSnyanmisaka #if defined(_WIN32)
7*437bfbebSnyanmisaka #include "vld.h"
8*437bfbebSnyanmisaka #endif
9*437bfbebSnyanmisaka
10*437bfbebSnyanmisaka #define MODULE_TAG "mpi_dec_nt_test"
11*437bfbebSnyanmisaka
12*437bfbebSnyanmisaka #include <string.h>
13*437bfbebSnyanmisaka #include "rk_mpi.h"
14*437bfbebSnyanmisaka
15*437bfbebSnyanmisaka #include "mpp_mem.h"
16*437bfbebSnyanmisaka #include "mpp_env.h"
17*437bfbebSnyanmisaka #include "mpp_time.h"
18*437bfbebSnyanmisaka #include "mpp_common.h"
19*437bfbebSnyanmisaka #include "mpi_dec_utils.h"
20*437bfbebSnyanmisaka
21*437bfbebSnyanmisaka typedef struct {
22*437bfbebSnyanmisaka MpiDecTestCmd *cmd;
23*437bfbebSnyanmisaka MppCtx ctx;
24*437bfbebSnyanmisaka MppApi *mpi;
25*437bfbebSnyanmisaka RK_U32 quiet;
26*437bfbebSnyanmisaka
27*437bfbebSnyanmisaka /* end of stream flag when set quit the loop */
28*437bfbebSnyanmisaka RK_U32 loop_end;
29*437bfbebSnyanmisaka
30*437bfbebSnyanmisaka /* input and output */
31*437bfbebSnyanmisaka DecBufMgr buf_mgr;
32*437bfbebSnyanmisaka MppBufferGroup frm_grp;
33*437bfbebSnyanmisaka MppPacket packet;
34*437bfbebSnyanmisaka MppFrame frame;
35*437bfbebSnyanmisaka
36*437bfbebSnyanmisaka FILE *fp_output;
37*437bfbebSnyanmisaka RK_S32 frame_count;
38*437bfbebSnyanmisaka RK_S32 frame_num;
39*437bfbebSnyanmisaka
40*437bfbebSnyanmisaka RK_S64 first_pkt;
41*437bfbebSnyanmisaka RK_S64 first_frm;
42*437bfbebSnyanmisaka
43*437bfbebSnyanmisaka size_t max_usage;
44*437bfbebSnyanmisaka float frame_rate;
45*437bfbebSnyanmisaka RK_S64 elapsed_time;
46*437bfbebSnyanmisaka RK_S64 delay;
47*437bfbebSnyanmisaka FILE *fp_verify;
48*437bfbebSnyanmisaka FrmCrc checkcrc;
49*437bfbebSnyanmisaka } MpiDecLoopData;
50*437bfbebSnyanmisaka
dec_loop(MpiDecLoopData * data)51*437bfbebSnyanmisaka static int dec_loop(MpiDecLoopData *data)
52*437bfbebSnyanmisaka {
53*437bfbebSnyanmisaka RK_U32 pkt_done = 0;
54*437bfbebSnyanmisaka RK_U32 pkt_eos = 0;
55*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
56*437bfbebSnyanmisaka MpiDecTestCmd *cmd = data->cmd;
57*437bfbebSnyanmisaka MppCtx ctx = data->ctx;
58*437bfbebSnyanmisaka MppApi *mpi = data->mpi;
59*437bfbebSnyanmisaka MppPacket packet = data->packet;
60*437bfbebSnyanmisaka FileBufSlot *slot = NULL;
61*437bfbebSnyanmisaka RK_U32 quiet = data->quiet;
62*437bfbebSnyanmisaka FrmCrc *checkcrc = &data->checkcrc;
63*437bfbebSnyanmisaka
64*437bfbebSnyanmisaka // when packet size is valid read the input binary file
65*437bfbebSnyanmisaka ret = reader_read(cmd->reader, &slot);
66*437bfbebSnyanmisaka
67*437bfbebSnyanmisaka mpp_assert(ret == MPP_OK);
68*437bfbebSnyanmisaka mpp_assert(slot);
69*437bfbebSnyanmisaka
70*437bfbebSnyanmisaka pkt_eos = slot->eos;
71*437bfbebSnyanmisaka
72*437bfbebSnyanmisaka if (pkt_eos) {
73*437bfbebSnyanmisaka if (data->frame_num < 0 || data->frame_num > data->frame_count) {
74*437bfbebSnyanmisaka mpp_log_q(quiet, "%p loop again\n", ctx);
75*437bfbebSnyanmisaka reader_rewind(cmd->reader);
76*437bfbebSnyanmisaka pkt_eos = 0;
77*437bfbebSnyanmisaka } else {
78*437bfbebSnyanmisaka mpp_log_q(quiet, "%p found last packet\n", ctx);
79*437bfbebSnyanmisaka data->loop_end = 1;
80*437bfbebSnyanmisaka }
81*437bfbebSnyanmisaka }
82*437bfbebSnyanmisaka
83*437bfbebSnyanmisaka if (!slot->buf) {
84*437bfbebSnyanmisaka /* non-jpeg decoding */
85*437bfbebSnyanmisaka mpp_packet_set_data(packet, slot->data);
86*437bfbebSnyanmisaka mpp_packet_set_size(packet, slot->size);
87*437bfbebSnyanmisaka mpp_packet_set_pos(packet, slot->data);
88*437bfbebSnyanmisaka mpp_packet_set_length(packet, slot->size);
89*437bfbebSnyanmisaka } else {
90*437bfbebSnyanmisaka /* jpeg decoding */
91*437bfbebSnyanmisaka void *buf = mpp_buffer_get_ptr(slot->buf);
92*437bfbebSnyanmisaka size_t size = mpp_buffer_get_size(slot->buf);
93*437bfbebSnyanmisaka
94*437bfbebSnyanmisaka mpp_packet_set_data(packet, buf);
95*437bfbebSnyanmisaka mpp_packet_set_size(packet, size);
96*437bfbebSnyanmisaka mpp_packet_set_pos(packet, buf);
97*437bfbebSnyanmisaka mpp_packet_set_length(packet, size);
98*437bfbebSnyanmisaka mpp_packet_set_buffer(packet, slot->buf);
99*437bfbebSnyanmisaka }
100*437bfbebSnyanmisaka
101*437bfbebSnyanmisaka // setup eos flag
102*437bfbebSnyanmisaka if (pkt_eos)
103*437bfbebSnyanmisaka mpp_packet_set_eos(packet);
104*437bfbebSnyanmisaka
105*437bfbebSnyanmisaka do {
106*437bfbebSnyanmisaka RK_U32 frm_eos = 0;
107*437bfbebSnyanmisaka RK_S32 get_frm = 0;
108*437bfbebSnyanmisaka MppFrame frame = NULL;
109*437bfbebSnyanmisaka
110*437bfbebSnyanmisaka // send the packet first if packet is not done
111*437bfbebSnyanmisaka ret = mpi->decode(ctx, packet, &frame);
112*437bfbebSnyanmisaka if (ret)
113*437bfbebSnyanmisaka mpp_err("decode failed ret %d\n", ret);
114*437bfbebSnyanmisaka
115*437bfbebSnyanmisaka // then get all available frame and release
116*437bfbebSnyanmisaka if (frame) {
117*437bfbebSnyanmisaka if (mpp_frame_get_info_change(frame)) {
118*437bfbebSnyanmisaka RK_U32 width = mpp_frame_get_width(frame);
119*437bfbebSnyanmisaka RK_U32 height = mpp_frame_get_height(frame);
120*437bfbebSnyanmisaka RK_U32 hor_stride = mpp_frame_get_hor_stride(frame);
121*437bfbebSnyanmisaka RK_U32 ver_stride = mpp_frame_get_ver_stride(frame);
122*437bfbebSnyanmisaka RK_U32 buf_size = mpp_frame_get_buf_size(frame);
123*437bfbebSnyanmisaka MppBufferGroup grp = NULL;
124*437bfbebSnyanmisaka
125*437bfbebSnyanmisaka mpp_log_q(quiet, "%p decode_get_frame get info changed found\n", ctx);
126*437bfbebSnyanmisaka mpp_log_q(quiet, "%p decoder require buffer w:h [%d:%d] stride [%d:%d] buf_size %d",
127*437bfbebSnyanmisaka ctx, width, height, hor_stride, ver_stride, buf_size);
128*437bfbebSnyanmisaka
129*437bfbebSnyanmisaka if (MPP_FRAME_FMT_IS_FBC(cmd->format)) {
130*437bfbebSnyanmisaka MppFrame frm = NULL;
131*437bfbebSnyanmisaka
132*437bfbebSnyanmisaka mpp_frame_init(&frm);
133*437bfbebSnyanmisaka mpp_frame_set_width(frm, width);
134*437bfbebSnyanmisaka mpp_frame_set_height(frm, height);
135*437bfbebSnyanmisaka mpp_frame_set_fmt(frm, cmd->format);
136*437bfbebSnyanmisaka
137*437bfbebSnyanmisaka ret = mpi->control(ctx, MPP_DEC_SET_FRAME_INFO, frm);
138*437bfbebSnyanmisaka mpp_frame_deinit(&frm);
139*437bfbebSnyanmisaka
140*437bfbebSnyanmisaka if (ret) {
141*437bfbebSnyanmisaka mpp_err("set fbc frame info failed\n");
142*437bfbebSnyanmisaka break;
143*437bfbebSnyanmisaka }
144*437bfbebSnyanmisaka }
145*437bfbebSnyanmisaka
146*437bfbebSnyanmisaka grp = dec_buf_mgr_setup(data->buf_mgr, buf_size, 24, cmd->buf_mode);
147*437bfbebSnyanmisaka /* Set buffer to mpp decoder */
148*437bfbebSnyanmisaka ret = mpi->control(ctx, MPP_DEC_SET_EXT_BUF_GROUP, grp);
149*437bfbebSnyanmisaka if (ret) {
150*437bfbebSnyanmisaka mpp_err("%p set buffer group failed ret %d\n", ctx, ret);
151*437bfbebSnyanmisaka break;
152*437bfbebSnyanmisaka }
153*437bfbebSnyanmisaka
154*437bfbebSnyanmisaka data->frm_grp = grp;
155*437bfbebSnyanmisaka
156*437bfbebSnyanmisaka /*
157*437bfbebSnyanmisaka * All buffer group config done. Set info change ready to let
158*437bfbebSnyanmisaka * decoder continue decoding
159*437bfbebSnyanmisaka */
160*437bfbebSnyanmisaka ret = mpi->control(ctx, MPP_DEC_SET_INFO_CHANGE_READY, NULL);
161*437bfbebSnyanmisaka if (ret) {
162*437bfbebSnyanmisaka mpp_err("%p info change ready failed ret %d\n", ctx, ret);
163*437bfbebSnyanmisaka break;
164*437bfbebSnyanmisaka }
165*437bfbebSnyanmisaka
166*437bfbebSnyanmisaka mpp_frame_deinit(&frame);
167*437bfbebSnyanmisaka continue;
168*437bfbebSnyanmisaka } else {
169*437bfbebSnyanmisaka char log_buf[256];
170*437bfbebSnyanmisaka RK_S32 log_size = sizeof(log_buf) - 1;
171*437bfbebSnyanmisaka RK_S32 log_len = 0;
172*437bfbebSnyanmisaka RK_U32 err_info = mpp_frame_get_errinfo(frame);
173*437bfbebSnyanmisaka RK_U32 discard = mpp_frame_get_discard(frame);
174*437bfbebSnyanmisaka
175*437bfbebSnyanmisaka if (!data->first_frm)
176*437bfbebSnyanmisaka data->first_frm = mpp_time();
177*437bfbebSnyanmisaka
178*437bfbebSnyanmisaka log_len += snprintf(log_buf + log_len, log_size - log_len,
179*437bfbebSnyanmisaka "decode get frame %d", data->frame_count);
180*437bfbebSnyanmisaka
181*437bfbebSnyanmisaka if (mpp_frame_has_meta(frame)) {
182*437bfbebSnyanmisaka MppMeta meta = mpp_frame_get_meta(frame);
183*437bfbebSnyanmisaka RK_S32 temporal_id = 0;
184*437bfbebSnyanmisaka
185*437bfbebSnyanmisaka mpp_meta_get_s32(meta, KEY_TEMPORAL_ID, &temporal_id);
186*437bfbebSnyanmisaka
187*437bfbebSnyanmisaka log_len += snprintf(log_buf + log_len, log_size - log_len,
188*437bfbebSnyanmisaka " tid %d", temporal_id);
189*437bfbebSnyanmisaka }
190*437bfbebSnyanmisaka
191*437bfbebSnyanmisaka if (err_info || discard) {
192*437bfbebSnyanmisaka log_len += snprintf(log_buf + log_len, log_size - log_len,
193*437bfbebSnyanmisaka " err %x discard %x", err_info, discard);
194*437bfbebSnyanmisaka }
195*437bfbebSnyanmisaka mpp_log_q(quiet, "%p %s\n", ctx, log_buf);
196*437bfbebSnyanmisaka
197*437bfbebSnyanmisaka data->frame_count++;
198*437bfbebSnyanmisaka if (data->fp_output && !err_info)
199*437bfbebSnyanmisaka dump_mpp_frame_to_file(frame, data->fp_output);
200*437bfbebSnyanmisaka
201*437bfbebSnyanmisaka if (data->fp_verify) {
202*437bfbebSnyanmisaka calc_frm_crc(frame, checkcrc);
203*437bfbebSnyanmisaka write_frm_crc(data->fp_verify, checkcrc);
204*437bfbebSnyanmisaka }
205*437bfbebSnyanmisaka
206*437bfbebSnyanmisaka fps_calc_inc(cmd->fps);
207*437bfbebSnyanmisaka }
208*437bfbebSnyanmisaka frm_eos = mpp_frame_get_eos(frame);
209*437bfbebSnyanmisaka mpp_frame_deinit(&frame);
210*437bfbebSnyanmisaka get_frm = 1;
211*437bfbebSnyanmisaka }
212*437bfbebSnyanmisaka
213*437bfbebSnyanmisaka // try get runtime frame memory usage
214*437bfbebSnyanmisaka if (data->frm_grp) {
215*437bfbebSnyanmisaka size_t usage = mpp_buffer_group_usage(data->frm_grp);
216*437bfbebSnyanmisaka if (usage > data->max_usage)
217*437bfbebSnyanmisaka data->max_usage = usage;
218*437bfbebSnyanmisaka }
219*437bfbebSnyanmisaka
220*437bfbebSnyanmisaka // when get one output frame check the output frame count limit
221*437bfbebSnyanmisaka if (get_frm) {
222*437bfbebSnyanmisaka if (data->frame_num > 0) {
223*437bfbebSnyanmisaka // when get enough frame quit
224*437bfbebSnyanmisaka if (data->frame_count >= data->frame_num) {
225*437bfbebSnyanmisaka data->loop_end = 1;
226*437bfbebSnyanmisaka break;
227*437bfbebSnyanmisaka }
228*437bfbebSnyanmisaka } else {
229*437bfbebSnyanmisaka // when get last frame quit
230*437bfbebSnyanmisaka if (frm_eos) {
231*437bfbebSnyanmisaka mpp_log_q(quiet, "%p found last packet\n", ctx);
232*437bfbebSnyanmisaka data->loop_end = 1;
233*437bfbebSnyanmisaka break;
234*437bfbebSnyanmisaka }
235*437bfbebSnyanmisaka }
236*437bfbebSnyanmisaka }
237*437bfbebSnyanmisaka
238*437bfbebSnyanmisaka if (packet) {
239*437bfbebSnyanmisaka if (mpp_packet_get_length(packet)) {
240*437bfbebSnyanmisaka msleep(1);
241*437bfbebSnyanmisaka continue;
242*437bfbebSnyanmisaka }
243*437bfbebSnyanmisaka
244*437bfbebSnyanmisaka if (!data->first_pkt)
245*437bfbebSnyanmisaka data->first_pkt = mpp_time();
246*437bfbebSnyanmisaka
247*437bfbebSnyanmisaka packet = NULL;
248*437bfbebSnyanmisaka pkt_done = 1;
249*437bfbebSnyanmisaka }
250*437bfbebSnyanmisaka
251*437bfbebSnyanmisaka mpp_assert(pkt_done);
252*437bfbebSnyanmisaka
253*437bfbebSnyanmisaka // if last packet is send but last frame is not found continue
254*437bfbebSnyanmisaka if (pkt_eos && !frm_eos) {
255*437bfbebSnyanmisaka msleep(1);
256*437bfbebSnyanmisaka continue;
257*437bfbebSnyanmisaka }
258*437bfbebSnyanmisaka
259*437bfbebSnyanmisaka if (pkt_done)
260*437bfbebSnyanmisaka break;
261*437bfbebSnyanmisaka
262*437bfbebSnyanmisaka /*
263*437bfbebSnyanmisaka * why sleep here:
264*437bfbebSnyanmisaka * mpi->decode_put_packet will failed when packet in internal queue is
265*437bfbebSnyanmisaka * full,waiting the package is consumed .Usually hardware decode one
266*437bfbebSnyanmisaka * frame which resolution is 1080p needs 2 ms,so here we sleep 1ms
267*437bfbebSnyanmisaka * * is enough.
268*437bfbebSnyanmisaka */
269*437bfbebSnyanmisaka msleep(1);
270*437bfbebSnyanmisaka } while (1);
271*437bfbebSnyanmisaka
272*437bfbebSnyanmisaka return ret;
273*437bfbebSnyanmisaka }
274*437bfbebSnyanmisaka
thread_decode(void * arg)275*437bfbebSnyanmisaka void *thread_decode(void *arg)
276*437bfbebSnyanmisaka {
277*437bfbebSnyanmisaka MpiDecLoopData *data = (MpiDecLoopData *)arg;
278*437bfbebSnyanmisaka RK_S64 t_s, t_e;
279*437bfbebSnyanmisaka
280*437bfbebSnyanmisaka memset(&data->checkcrc, 0, sizeof(data->checkcrc));
281*437bfbebSnyanmisaka data->checkcrc.luma.sum = mpp_malloc(RK_ULONG, 512);
282*437bfbebSnyanmisaka data->checkcrc.chroma.sum = mpp_malloc(RK_ULONG, 512);
283*437bfbebSnyanmisaka
284*437bfbebSnyanmisaka t_s = mpp_time();
285*437bfbebSnyanmisaka
286*437bfbebSnyanmisaka while (!data->loop_end)
287*437bfbebSnyanmisaka dec_loop(data);
288*437bfbebSnyanmisaka
289*437bfbebSnyanmisaka t_e = mpp_time();
290*437bfbebSnyanmisaka data->elapsed_time = t_e - t_s;
291*437bfbebSnyanmisaka data->frame_rate = (float)data->frame_count * 1000000 / data->elapsed_time;
292*437bfbebSnyanmisaka data->delay = data->first_frm - data->first_pkt;
293*437bfbebSnyanmisaka
294*437bfbebSnyanmisaka mpp_log("decode %d frames time %lld ms delay %3d ms fps %3.2f\n",
295*437bfbebSnyanmisaka data->frame_count, (RK_S64)(data->elapsed_time / 1000),
296*437bfbebSnyanmisaka (RK_S32)(data->delay / 1000), data->frame_rate);
297*437bfbebSnyanmisaka
298*437bfbebSnyanmisaka MPP_FREE(data->checkcrc.luma.sum);
299*437bfbebSnyanmisaka MPP_FREE(data->checkcrc.chroma.sum);
300*437bfbebSnyanmisaka
301*437bfbebSnyanmisaka return NULL;
302*437bfbebSnyanmisaka }
303*437bfbebSnyanmisaka
dec_nt_decode(MpiDecTestCmd * cmd)304*437bfbebSnyanmisaka int dec_nt_decode(MpiDecTestCmd *cmd)
305*437bfbebSnyanmisaka {
306*437bfbebSnyanmisaka // base flow context
307*437bfbebSnyanmisaka MppCtx ctx = NULL;
308*437bfbebSnyanmisaka MppApi *mpi = NULL;
309*437bfbebSnyanmisaka
310*437bfbebSnyanmisaka // input / output
311*437bfbebSnyanmisaka MppPacket packet = NULL;
312*437bfbebSnyanmisaka MppFrame frame = NULL;
313*437bfbebSnyanmisaka
314*437bfbebSnyanmisaka // paramter for resource malloc
315*437bfbebSnyanmisaka RK_U32 width = cmd->width;
316*437bfbebSnyanmisaka RK_U32 height = cmd->height;
317*437bfbebSnyanmisaka MppCodingType type = cmd->type;
318*437bfbebSnyanmisaka
319*437bfbebSnyanmisaka // config for runtime mode
320*437bfbebSnyanmisaka MppDecCfg cfg = NULL;
321*437bfbebSnyanmisaka RK_U32 need_split = 1;
322*437bfbebSnyanmisaka
323*437bfbebSnyanmisaka // resources
324*437bfbebSnyanmisaka MppBuffer frm_buf = NULL;
325*437bfbebSnyanmisaka pthread_t thd;
326*437bfbebSnyanmisaka pthread_attr_t attr;
327*437bfbebSnyanmisaka MpiDecLoopData data;
328*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
329*437bfbebSnyanmisaka
330*437bfbebSnyanmisaka mpp_log("mpi_dec_test start\n");
331*437bfbebSnyanmisaka memset(&data, 0, sizeof(data));
332*437bfbebSnyanmisaka pthread_attr_init(&attr);
333*437bfbebSnyanmisaka
334*437bfbebSnyanmisaka cmd->simple = (cmd->type != MPP_VIDEO_CodingMJPEG) ? (1) : (0);
335*437bfbebSnyanmisaka
336*437bfbebSnyanmisaka if (cmd->have_output) {
337*437bfbebSnyanmisaka data.fp_output = fopen(cmd->file_output, "w+b");
338*437bfbebSnyanmisaka if (NULL == data.fp_output) {
339*437bfbebSnyanmisaka mpp_err("failed to open output file %s\n", cmd->file_output);
340*437bfbebSnyanmisaka goto MPP_TEST_OUT;
341*437bfbebSnyanmisaka }
342*437bfbebSnyanmisaka }
343*437bfbebSnyanmisaka
344*437bfbebSnyanmisaka if (cmd->file_slt) {
345*437bfbebSnyanmisaka data.fp_verify = fopen(cmd->file_slt, "wt");
346*437bfbebSnyanmisaka if (!data.fp_verify)
347*437bfbebSnyanmisaka mpp_err("failed to open verify file %s\n", cmd->file_slt);
348*437bfbebSnyanmisaka }
349*437bfbebSnyanmisaka
350*437bfbebSnyanmisaka ret = dec_buf_mgr_init(&data.buf_mgr);
351*437bfbebSnyanmisaka if (ret) {
352*437bfbebSnyanmisaka mpp_err("dec_buf_mgr_init failed\n");
353*437bfbebSnyanmisaka goto MPP_TEST_OUT;
354*437bfbebSnyanmisaka }
355*437bfbebSnyanmisaka
356*437bfbebSnyanmisaka ret = mpp_packet_init(&packet, NULL, 0);
357*437bfbebSnyanmisaka mpp_err_f("mpp_packet_init get %p\n", packet);
358*437bfbebSnyanmisaka if (ret) {
359*437bfbebSnyanmisaka mpp_err("mpp_packet_init failed\n");
360*437bfbebSnyanmisaka goto MPP_TEST_OUT;
361*437bfbebSnyanmisaka }
362*437bfbebSnyanmisaka
363*437bfbebSnyanmisaka // decoder demo
364*437bfbebSnyanmisaka ret = mpp_create(&ctx, &mpi);
365*437bfbebSnyanmisaka if (ret) {
366*437bfbebSnyanmisaka mpp_err("mpp_create failed\n");
367*437bfbebSnyanmisaka goto MPP_TEST_OUT;
368*437bfbebSnyanmisaka }
369*437bfbebSnyanmisaka
370*437bfbebSnyanmisaka mpp_log("%p mpi_dec_test decoder test start w %d h %d type %d\n",
371*437bfbebSnyanmisaka ctx, width, height, type);
372*437bfbebSnyanmisaka
373*437bfbebSnyanmisaka ret = mpi->control(ctx, MPP_SET_DISABLE_THREAD, NULL);
374*437bfbebSnyanmisaka
375*437bfbebSnyanmisaka ret = mpp_init(ctx, MPP_CTX_DEC, type);
376*437bfbebSnyanmisaka if (ret) {
377*437bfbebSnyanmisaka mpp_err("%p mpp_init failed\n", ctx);
378*437bfbebSnyanmisaka goto MPP_TEST_OUT;
379*437bfbebSnyanmisaka }
380*437bfbebSnyanmisaka
381*437bfbebSnyanmisaka mpp_dec_cfg_init(&cfg);
382*437bfbebSnyanmisaka
383*437bfbebSnyanmisaka /* get default config from decoder context */
384*437bfbebSnyanmisaka ret = mpi->control(ctx, MPP_DEC_GET_CFG, cfg);
385*437bfbebSnyanmisaka if (ret) {
386*437bfbebSnyanmisaka mpp_err("%p failed to get decoder cfg ret %d\n", ctx, ret);
387*437bfbebSnyanmisaka goto MPP_TEST_OUT;
388*437bfbebSnyanmisaka }
389*437bfbebSnyanmisaka
390*437bfbebSnyanmisaka /*
391*437bfbebSnyanmisaka * split_parse is to enable mpp internal frame spliter when the input
392*437bfbebSnyanmisaka * packet is not aplited into frames.
393*437bfbebSnyanmisaka */
394*437bfbebSnyanmisaka ret = mpp_dec_cfg_set_u32(cfg, "base:split_parse", need_split);
395*437bfbebSnyanmisaka if (ret) {
396*437bfbebSnyanmisaka mpp_err("%p failed to set split_parse ret %d\n", ctx, ret);
397*437bfbebSnyanmisaka goto MPP_TEST_OUT;
398*437bfbebSnyanmisaka }
399*437bfbebSnyanmisaka
400*437bfbebSnyanmisaka ret = mpi->control(ctx, MPP_DEC_SET_CFG, cfg);
401*437bfbebSnyanmisaka if (ret) {
402*437bfbebSnyanmisaka mpp_err("%p failed to set cfg %p ret %d\n", ctx, cfg, ret);
403*437bfbebSnyanmisaka goto MPP_TEST_OUT;
404*437bfbebSnyanmisaka }
405*437bfbebSnyanmisaka
406*437bfbebSnyanmisaka data.cmd = cmd;
407*437bfbebSnyanmisaka data.ctx = ctx;
408*437bfbebSnyanmisaka data.mpi = mpi;
409*437bfbebSnyanmisaka data.loop_end = 0;
410*437bfbebSnyanmisaka data.packet = packet;
411*437bfbebSnyanmisaka data.frame = frame;
412*437bfbebSnyanmisaka data.frame_count = 0;
413*437bfbebSnyanmisaka data.frame_num = cmd->frame_num;
414*437bfbebSnyanmisaka data.quiet = cmd->quiet;
415*437bfbebSnyanmisaka
416*437bfbebSnyanmisaka pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
417*437bfbebSnyanmisaka
418*437bfbebSnyanmisaka ret = pthread_create(&thd, &attr, thread_decode, &data);
419*437bfbebSnyanmisaka if (ret) {
420*437bfbebSnyanmisaka mpp_err("failed to create thread for input ret %d\n", ret);
421*437bfbebSnyanmisaka goto MPP_TEST_OUT;
422*437bfbebSnyanmisaka }
423*437bfbebSnyanmisaka
424*437bfbebSnyanmisaka if (cmd->frame_num < 0) {
425*437bfbebSnyanmisaka // wait for input then quit decoding
426*437bfbebSnyanmisaka mpp_log("*******************************************\n");
427*437bfbebSnyanmisaka mpp_log("**** Press Enter to stop loop decoding ****\n");
428*437bfbebSnyanmisaka mpp_log("*******************************************\n");
429*437bfbebSnyanmisaka
430*437bfbebSnyanmisaka getc(stdin);
431*437bfbebSnyanmisaka data.loop_end = 1;
432*437bfbebSnyanmisaka }
433*437bfbebSnyanmisaka
434*437bfbebSnyanmisaka pthread_join(thd, NULL);
435*437bfbebSnyanmisaka
436*437bfbebSnyanmisaka cmd->max_usage = data.max_usage;
437*437bfbebSnyanmisaka
438*437bfbebSnyanmisaka ret = mpi->reset(ctx);
439*437bfbebSnyanmisaka if (ret) {
440*437bfbebSnyanmisaka mpp_err("%p mpi->reset failed\n", ctx);
441*437bfbebSnyanmisaka goto MPP_TEST_OUT;
442*437bfbebSnyanmisaka }
443*437bfbebSnyanmisaka
444*437bfbebSnyanmisaka MPP_TEST_OUT:
445*437bfbebSnyanmisaka if (data.packet) {
446*437bfbebSnyanmisaka mpp_packet_deinit(&data.packet);
447*437bfbebSnyanmisaka data.packet = NULL;
448*437bfbebSnyanmisaka }
449*437bfbebSnyanmisaka
450*437bfbebSnyanmisaka if (frame) {
451*437bfbebSnyanmisaka mpp_frame_deinit(&frame);
452*437bfbebSnyanmisaka frame = NULL;
453*437bfbebSnyanmisaka }
454*437bfbebSnyanmisaka
455*437bfbebSnyanmisaka if (ctx) {
456*437bfbebSnyanmisaka mpp_destroy(ctx);
457*437bfbebSnyanmisaka ctx = NULL;
458*437bfbebSnyanmisaka }
459*437bfbebSnyanmisaka
460*437bfbebSnyanmisaka if (!cmd->simple) {
461*437bfbebSnyanmisaka if (frm_buf) {
462*437bfbebSnyanmisaka mpp_buffer_put(frm_buf);
463*437bfbebSnyanmisaka frm_buf = NULL;
464*437bfbebSnyanmisaka }
465*437bfbebSnyanmisaka }
466*437bfbebSnyanmisaka
467*437bfbebSnyanmisaka data.frm_grp = NULL;
468*437bfbebSnyanmisaka if (data.buf_mgr) {
469*437bfbebSnyanmisaka dec_buf_mgr_deinit(data.buf_mgr);
470*437bfbebSnyanmisaka data.buf_mgr = NULL;
471*437bfbebSnyanmisaka }
472*437bfbebSnyanmisaka
473*437bfbebSnyanmisaka if (data.fp_output) {
474*437bfbebSnyanmisaka fclose(data.fp_output);
475*437bfbebSnyanmisaka data.fp_output = NULL;
476*437bfbebSnyanmisaka }
477*437bfbebSnyanmisaka
478*437bfbebSnyanmisaka if (data.fp_verify) {
479*437bfbebSnyanmisaka fclose(data.fp_verify);
480*437bfbebSnyanmisaka data.fp_verify = NULL;
481*437bfbebSnyanmisaka }
482*437bfbebSnyanmisaka
483*437bfbebSnyanmisaka if (cfg) {
484*437bfbebSnyanmisaka mpp_dec_cfg_deinit(cfg);
485*437bfbebSnyanmisaka cfg = NULL;
486*437bfbebSnyanmisaka }
487*437bfbebSnyanmisaka
488*437bfbebSnyanmisaka pthread_attr_destroy(&attr);
489*437bfbebSnyanmisaka
490*437bfbebSnyanmisaka return ret;
491*437bfbebSnyanmisaka }
492*437bfbebSnyanmisaka
main(int argc,char ** argv)493*437bfbebSnyanmisaka int main(int argc, char **argv)
494*437bfbebSnyanmisaka {
495*437bfbebSnyanmisaka RK_S32 ret = 0;
496*437bfbebSnyanmisaka MpiDecTestCmd cmd_ctx;
497*437bfbebSnyanmisaka MpiDecTestCmd* cmd = &cmd_ctx;
498*437bfbebSnyanmisaka
499*437bfbebSnyanmisaka memset((void*)cmd, 0, sizeof(*cmd));
500*437bfbebSnyanmisaka cmd->format = MPP_FMT_BUTT;
501*437bfbebSnyanmisaka cmd->pkt_size = MPI_DEC_STREAM_SIZE;
502*437bfbebSnyanmisaka
503*437bfbebSnyanmisaka // parse the cmd option
504*437bfbebSnyanmisaka ret = mpi_dec_test_cmd_init(cmd, argc, argv);
505*437bfbebSnyanmisaka if (ret)
506*437bfbebSnyanmisaka goto RET;
507*437bfbebSnyanmisaka
508*437bfbebSnyanmisaka mpi_dec_test_cmd_options(cmd);
509*437bfbebSnyanmisaka
510*437bfbebSnyanmisaka ret = dec_nt_decode(cmd);
511*437bfbebSnyanmisaka if (MPP_OK == ret)
512*437bfbebSnyanmisaka mpp_log("test success max memory %.2f MB\n", cmd->max_usage / (float)(1 << 20));
513*437bfbebSnyanmisaka else
514*437bfbebSnyanmisaka mpp_err("test failed ret %d\n", ret);
515*437bfbebSnyanmisaka
516*437bfbebSnyanmisaka RET:
517*437bfbebSnyanmisaka mpi_dec_test_cmd_deinit(cmd);
518*437bfbebSnyanmisaka
519*437bfbebSnyanmisaka return ret;
520*437bfbebSnyanmisaka }
521*437bfbebSnyanmisaka
522