xref: /rockchip-linux_mpp/test/mpi_dec_test.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2*437bfbebSnyanmisaka /*
3*437bfbebSnyanmisaka  * Copyright (c) 2015 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_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_simple(MpiDecLoopData * data)51*437bfbebSnyanmisaka static int dec_simple(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     mpp_packet_set_data(packet, slot->data);
84*437bfbebSnyanmisaka     mpp_packet_set_size(packet, slot->size);
85*437bfbebSnyanmisaka     mpp_packet_set_pos(packet, slot->data);
86*437bfbebSnyanmisaka     mpp_packet_set_length(packet, slot->size);
87*437bfbebSnyanmisaka     // setup eos flag
88*437bfbebSnyanmisaka     if (pkt_eos)
89*437bfbebSnyanmisaka         mpp_packet_set_eos(packet);
90*437bfbebSnyanmisaka 
91*437bfbebSnyanmisaka     do {
92*437bfbebSnyanmisaka         RK_U32 frm_eos = 0;
93*437bfbebSnyanmisaka         RK_S32 times = 30;
94*437bfbebSnyanmisaka 
95*437bfbebSnyanmisaka         // send the packet first if packet is not done
96*437bfbebSnyanmisaka         if (!pkt_done) {
97*437bfbebSnyanmisaka             ret = mpi->decode_put_packet(ctx, packet);
98*437bfbebSnyanmisaka             if (MPP_OK == ret) {
99*437bfbebSnyanmisaka                 pkt_done = 1;
100*437bfbebSnyanmisaka                 if (!data->first_pkt)
101*437bfbebSnyanmisaka                     data->first_pkt = mpp_time();
102*437bfbebSnyanmisaka             }
103*437bfbebSnyanmisaka         }
104*437bfbebSnyanmisaka 
105*437bfbebSnyanmisaka         // then get all available frame and release
106*437bfbebSnyanmisaka         do {
107*437bfbebSnyanmisaka             RK_S32 get_frm = 0;
108*437bfbebSnyanmisaka             MppFrame frame = NULL;
109*437bfbebSnyanmisaka 
110*437bfbebSnyanmisaka         try_again:
111*437bfbebSnyanmisaka             ret = mpi->decode_get_frame(ctx, &frame);
112*437bfbebSnyanmisaka             if (MPP_ERR_TIMEOUT == ret) {
113*437bfbebSnyanmisaka                 if (times > 0) {
114*437bfbebSnyanmisaka                     times--;
115*437bfbebSnyanmisaka                     msleep(1);
116*437bfbebSnyanmisaka                     goto try_again;
117*437bfbebSnyanmisaka                 }
118*437bfbebSnyanmisaka                 mpp_err("%p decode_get_frame failed too much time\n", ctx);
119*437bfbebSnyanmisaka             }
120*437bfbebSnyanmisaka             if (ret) {
121*437bfbebSnyanmisaka                 mpp_err("%p decode_get_frame failed ret %d\n", ret, ctx);
122*437bfbebSnyanmisaka                 break;
123*437bfbebSnyanmisaka             }
124*437bfbebSnyanmisaka 
125*437bfbebSnyanmisaka             if (frame) {
126*437bfbebSnyanmisaka                 if (mpp_frame_get_info_change(frame)) {
127*437bfbebSnyanmisaka                     RK_U32 width = mpp_frame_get_width(frame);
128*437bfbebSnyanmisaka                     RK_U32 height = mpp_frame_get_height(frame);
129*437bfbebSnyanmisaka                     RK_U32 hor_stride = mpp_frame_get_hor_stride(frame);
130*437bfbebSnyanmisaka                     RK_U32 ver_stride = mpp_frame_get_ver_stride(frame);
131*437bfbebSnyanmisaka                     RK_U32 buf_size = mpp_frame_get_buf_size(frame);
132*437bfbebSnyanmisaka                     MppBufferGroup grp = NULL;
133*437bfbebSnyanmisaka 
134*437bfbebSnyanmisaka                     mpp_log_q(quiet, "%p decode_get_frame get info changed found\n", ctx);
135*437bfbebSnyanmisaka                     mpp_log_q(quiet, "%p decoder require buffer w:h [%d:%d] stride [%d:%d] buf_size %d",
136*437bfbebSnyanmisaka                               ctx, width, height, hor_stride, ver_stride, buf_size);
137*437bfbebSnyanmisaka 
138*437bfbebSnyanmisaka                     if (MPP_FRAME_FMT_IS_FBC(cmd->format)) {
139*437bfbebSnyanmisaka                         MppFrame frm = NULL;
140*437bfbebSnyanmisaka 
141*437bfbebSnyanmisaka                         mpp_frame_init(&frm);
142*437bfbebSnyanmisaka                         mpp_frame_set_width(frm, width);
143*437bfbebSnyanmisaka                         mpp_frame_set_height(frm, height);
144*437bfbebSnyanmisaka                         mpp_frame_set_fmt(frm, cmd->format);
145*437bfbebSnyanmisaka 
146*437bfbebSnyanmisaka                         ret = mpi->control(ctx, MPP_DEC_SET_FRAME_INFO, frm);
147*437bfbebSnyanmisaka                         mpp_frame_deinit(&frm);
148*437bfbebSnyanmisaka 
149*437bfbebSnyanmisaka                         if (ret) {
150*437bfbebSnyanmisaka                             mpp_err("set fbc frame info failed\n");
151*437bfbebSnyanmisaka                             break;
152*437bfbebSnyanmisaka                         }
153*437bfbebSnyanmisaka                     }
154*437bfbebSnyanmisaka 
155*437bfbebSnyanmisaka                     grp = dec_buf_mgr_setup(data->buf_mgr, buf_size, 24, cmd->buf_mode);
156*437bfbebSnyanmisaka                     /* Set buffer to mpp decoder */
157*437bfbebSnyanmisaka                     ret = mpi->control(ctx, MPP_DEC_SET_EXT_BUF_GROUP, grp);
158*437bfbebSnyanmisaka                     if (ret) {
159*437bfbebSnyanmisaka                         mpp_err("%p set buffer group failed ret %d\n", ctx, ret);
160*437bfbebSnyanmisaka                         break;
161*437bfbebSnyanmisaka                     }
162*437bfbebSnyanmisaka                     data->frm_grp = grp;
163*437bfbebSnyanmisaka 
164*437bfbebSnyanmisaka                     /*
165*437bfbebSnyanmisaka                      * All buffer group config done. Set info change ready to let
166*437bfbebSnyanmisaka                      * decoder continue decoding
167*437bfbebSnyanmisaka                      */
168*437bfbebSnyanmisaka                     ret = mpi->control(ctx, MPP_DEC_SET_INFO_CHANGE_READY, NULL);
169*437bfbebSnyanmisaka                     if (ret) {
170*437bfbebSnyanmisaka                         mpp_err("%p info change ready failed ret %d\n", ctx, ret);
171*437bfbebSnyanmisaka                         break;
172*437bfbebSnyanmisaka                     }
173*437bfbebSnyanmisaka                 } else {
174*437bfbebSnyanmisaka                     char log_buf[256];
175*437bfbebSnyanmisaka                     RK_S32 log_size = sizeof(log_buf) - 1;
176*437bfbebSnyanmisaka                     RK_S32 log_len = 0;
177*437bfbebSnyanmisaka                     RK_U32 err_info = mpp_frame_get_errinfo(frame);
178*437bfbebSnyanmisaka                     RK_U32 discard = mpp_frame_get_discard(frame);
179*437bfbebSnyanmisaka 
180*437bfbebSnyanmisaka                     if (!data->first_frm)
181*437bfbebSnyanmisaka                         data->first_frm = mpp_time();
182*437bfbebSnyanmisaka 
183*437bfbebSnyanmisaka                     log_len += snprintf(log_buf + log_len, log_size - log_len,
184*437bfbebSnyanmisaka                                         "decode get frame %d", data->frame_count);
185*437bfbebSnyanmisaka 
186*437bfbebSnyanmisaka                     if (mpp_frame_has_meta(frame)) {
187*437bfbebSnyanmisaka                         MppMeta meta = mpp_frame_get_meta(frame);
188*437bfbebSnyanmisaka                         RK_S32 temporal_id = 0;
189*437bfbebSnyanmisaka 
190*437bfbebSnyanmisaka                         mpp_meta_get_s32(meta, KEY_TEMPORAL_ID, &temporal_id);
191*437bfbebSnyanmisaka 
192*437bfbebSnyanmisaka                         log_len += snprintf(log_buf + log_len, log_size - log_len,
193*437bfbebSnyanmisaka                                             " tid %d", temporal_id);
194*437bfbebSnyanmisaka                     }
195*437bfbebSnyanmisaka 
196*437bfbebSnyanmisaka                     if (err_info || discard) {
197*437bfbebSnyanmisaka                         log_len += snprintf(log_buf + log_len, log_size - log_len,
198*437bfbebSnyanmisaka                                             " err %x discard %x", err_info, discard);
199*437bfbebSnyanmisaka                     }
200*437bfbebSnyanmisaka                     mpp_log_q(quiet, "%p %s\n", ctx, log_buf);
201*437bfbebSnyanmisaka 
202*437bfbebSnyanmisaka                     data->frame_count++;
203*437bfbebSnyanmisaka                     if (data->fp_output && !err_info)
204*437bfbebSnyanmisaka                         dump_mpp_frame_to_file(frame, data->fp_output);
205*437bfbebSnyanmisaka 
206*437bfbebSnyanmisaka                     if (data->fp_verify) {
207*437bfbebSnyanmisaka                         calc_frm_crc(frame, checkcrc);
208*437bfbebSnyanmisaka                         write_frm_crc(data->fp_verify, checkcrc);
209*437bfbebSnyanmisaka                     }
210*437bfbebSnyanmisaka 
211*437bfbebSnyanmisaka                     fps_calc_inc(cmd->fps);
212*437bfbebSnyanmisaka                 }
213*437bfbebSnyanmisaka                 frm_eos = mpp_frame_get_eos(frame);
214*437bfbebSnyanmisaka                 mpp_frame_deinit(&frame);
215*437bfbebSnyanmisaka                 get_frm = 1;
216*437bfbebSnyanmisaka             }
217*437bfbebSnyanmisaka 
218*437bfbebSnyanmisaka             // try get runtime frame memory usage
219*437bfbebSnyanmisaka             if (data->frm_grp) {
220*437bfbebSnyanmisaka                 size_t usage = mpp_buffer_group_usage(data->frm_grp);
221*437bfbebSnyanmisaka                 if (usage > data->max_usage)
222*437bfbebSnyanmisaka                     data->max_usage = usage;
223*437bfbebSnyanmisaka             }
224*437bfbebSnyanmisaka 
225*437bfbebSnyanmisaka             // if last packet is send but last frame is not found continue
226*437bfbebSnyanmisaka             if (pkt_eos && pkt_done && !frm_eos) {
227*437bfbebSnyanmisaka                 msleep(1);
228*437bfbebSnyanmisaka                 continue;
229*437bfbebSnyanmisaka             }
230*437bfbebSnyanmisaka 
231*437bfbebSnyanmisaka             if (frm_eos) {
232*437bfbebSnyanmisaka                 mpp_log_q(quiet, "%p found last packet\n", ctx);
233*437bfbebSnyanmisaka                 break;
234*437bfbebSnyanmisaka             }
235*437bfbebSnyanmisaka 
236*437bfbebSnyanmisaka             if ((data->frame_num > 0 && (data->frame_count >= data->frame_num)) ||
237*437bfbebSnyanmisaka                 ((data->frame_num == 0) && frm_eos))
238*437bfbebSnyanmisaka                 break;
239*437bfbebSnyanmisaka 
240*437bfbebSnyanmisaka             if (get_frm)
241*437bfbebSnyanmisaka                 continue;
242*437bfbebSnyanmisaka             break;
243*437bfbebSnyanmisaka         } while (1);
244*437bfbebSnyanmisaka 
245*437bfbebSnyanmisaka         if ((data->frame_num > 0 && (data->frame_count >= data->frame_num)) ||
246*437bfbebSnyanmisaka             ((data->frame_num == 0) && frm_eos)) {
247*437bfbebSnyanmisaka             data->loop_end = 1;
248*437bfbebSnyanmisaka             break;
249*437bfbebSnyanmisaka         }
250*437bfbebSnyanmisaka 
251*437bfbebSnyanmisaka         if (pkt_done)
252*437bfbebSnyanmisaka             break;
253*437bfbebSnyanmisaka 
254*437bfbebSnyanmisaka         /*
255*437bfbebSnyanmisaka          * why sleep here:
256*437bfbebSnyanmisaka          * mpi->decode_put_packet will failed when packet in internal queue is
257*437bfbebSnyanmisaka          * full,waiting the package is consumed .Usually hardware decode one
258*437bfbebSnyanmisaka          * frame which resolution is 1080p needs 2 ms,so here we sleep 1ms
259*437bfbebSnyanmisaka          * * is enough.
260*437bfbebSnyanmisaka          */
261*437bfbebSnyanmisaka         msleep(1);
262*437bfbebSnyanmisaka     } while (1);
263*437bfbebSnyanmisaka 
264*437bfbebSnyanmisaka     return ret;
265*437bfbebSnyanmisaka }
266*437bfbebSnyanmisaka 
dec_advanced(MpiDecLoopData * data)267*437bfbebSnyanmisaka static int dec_advanced(MpiDecLoopData *data)
268*437bfbebSnyanmisaka {
269*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
270*437bfbebSnyanmisaka     MpiDecTestCmd *cmd = data->cmd;
271*437bfbebSnyanmisaka     MppCtx ctx  = data->ctx;
272*437bfbebSnyanmisaka     MppApi *mpi = data->mpi;
273*437bfbebSnyanmisaka     MppPacket packet = NULL;
274*437bfbebSnyanmisaka     MppPacket packet_ret = NULL;
275*437bfbebSnyanmisaka     MppFrame frame = data->frame;
276*437bfbebSnyanmisaka     MppFrame frame_ret = NULL;
277*437bfbebSnyanmisaka     MppMeta meta = NULL;
278*437bfbebSnyanmisaka     RK_U32 quiet = data->quiet;
279*437bfbebSnyanmisaka     FileBufSlot *slot = NULL;
280*437bfbebSnyanmisaka     FrmCrc *checkcrc = &data->checkcrc;
281*437bfbebSnyanmisaka 
282*437bfbebSnyanmisaka     ret = reader_index_read(cmd->reader, 0, &slot);
283*437bfbebSnyanmisaka     mpp_assert(ret == MPP_OK);
284*437bfbebSnyanmisaka     mpp_assert(slot);
285*437bfbebSnyanmisaka 
286*437bfbebSnyanmisaka     mpp_packet_init_with_buffer(&packet, slot->buf);
287*437bfbebSnyanmisaka 
288*437bfbebSnyanmisaka     // setup eos flag
289*437bfbebSnyanmisaka     if (slot->eos)
290*437bfbebSnyanmisaka         mpp_packet_set_eos(packet);
291*437bfbebSnyanmisaka 
292*437bfbebSnyanmisaka     /* use the MppFrame with prealloced buffer and do not release */
293*437bfbebSnyanmisaka     meta = mpp_packet_get_meta(packet);
294*437bfbebSnyanmisaka     if (meta)
295*437bfbebSnyanmisaka         mpp_meta_set_frame(meta, KEY_OUTPUT_FRAME, frame);
296*437bfbebSnyanmisaka 
297*437bfbebSnyanmisaka     ret = mpi->decode_put_packet(ctx, packet);
298*437bfbebSnyanmisaka     if (ret) {
299*437bfbebSnyanmisaka         mpp_err("%p mpp decode put packet failed ret %d\n", ctx, ret);
300*437bfbebSnyanmisaka         data->loop_end = 1;
301*437bfbebSnyanmisaka         goto DONE;
302*437bfbebSnyanmisaka     }
303*437bfbebSnyanmisaka 
304*437bfbebSnyanmisaka     if (!data->first_pkt)
305*437bfbebSnyanmisaka         data->first_pkt = mpp_time();
306*437bfbebSnyanmisaka 
307*437bfbebSnyanmisaka     ret = mpi->decode_get_frame(ctx, &frame_ret);
308*437bfbebSnyanmisaka     if (ret || !frame_ret) {
309*437bfbebSnyanmisaka         mpp_err("%p mpp decode get frame failed ret %d frame %p\n", ctx, ret, frame_ret);
310*437bfbebSnyanmisaka         data->loop_end = 1;
311*437bfbebSnyanmisaka         goto DONE;
312*437bfbebSnyanmisaka     }
313*437bfbebSnyanmisaka 
314*437bfbebSnyanmisaka     if (!data->first_frm)
315*437bfbebSnyanmisaka         data->first_frm = mpp_time();
316*437bfbebSnyanmisaka 
317*437bfbebSnyanmisaka     if (frame_ret != frame)
318*437bfbebSnyanmisaka         mpp_err_f("mismatch frame %p -> %p\n", frame_ret, frame);
319*437bfbebSnyanmisaka 
320*437bfbebSnyanmisaka     /* write frame to file here */
321*437bfbebSnyanmisaka     if (data->fp_output)
322*437bfbebSnyanmisaka         dump_mpp_frame_to_file(frame_ret, data->fp_output);
323*437bfbebSnyanmisaka 
324*437bfbebSnyanmisaka     if (data->fp_verify) {
325*437bfbebSnyanmisaka         calc_frm_crc(frame_ret, checkcrc);
326*437bfbebSnyanmisaka         write_frm_crc(data->fp_verify, checkcrc);
327*437bfbebSnyanmisaka     }
328*437bfbebSnyanmisaka 
329*437bfbebSnyanmisaka     mpp_log_q(quiet, "%p decoded frame %d\n", ctx, data->frame_count);
330*437bfbebSnyanmisaka     data->frame_count++;
331*437bfbebSnyanmisaka 
332*437bfbebSnyanmisaka     if (mpp_frame_get_eos(frame_ret))
333*437bfbebSnyanmisaka         mpp_log_q(quiet, "%p found eos frame\n", ctx);
334*437bfbebSnyanmisaka 
335*437bfbebSnyanmisaka     fps_calc_inc(cmd->fps);
336*437bfbebSnyanmisaka 
337*437bfbebSnyanmisaka     meta = mpp_frame_get_meta(frame);
338*437bfbebSnyanmisaka     if (meta) {
339*437bfbebSnyanmisaka         ret = mpp_meta_get_packet(meta, KEY_INPUT_PACKET, &packet_ret);
340*437bfbebSnyanmisaka         if (ret || !packet_ret) {
341*437bfbebSnyanmisaka             mpp_err("%p mpp meta get packet failed ret %d\n", ctx, ret);
342*437bfbebSnyanmisaka             goto DONE;
343*437bfbebSnyanmisaka         }
344*437bfbebSnyanmisaka 
345*437bfbebSnyanmisaka         if (packet_ret != packet)
346*437bfbebSnyanmisaka             mpp_err_f("mismatch packet %p -> %p\n", packet, packet_ret);
347*437bfbebSnyanmisaka     }
348*437bfbebSnyanmisaka 
349*437bfbebSnyanmisaka     if (data->frame_num > 0) {
350*437bfbebSnyanmisaka         if (data->frame_count >= data->frame_num)
351*437bfbebSnyanmisaka             data->loop_end = 1;
352*437bfbebSnyanmisaka     } else if (data->frame_num == 0) {
353*437bfbebSnyanmisaka         if (slot->eos)
354*437bfbebSnyanmisaka             data->loop_end = 1;
355*437bfbebSnyanmisaka     }
356*437bfbebSnyanmisaka 
357*437bfbebSnyanmisaka DONE:
358*437bfbebSnyanmisaka     mpp_packet_deinit(&packet);
359*437bfbebSnyanmisaka 
360*437bfbebSnyanmisaka     return ret;
361*437bfbebSnyanmisaka }
362*437bfbebSnyanmisaka 
thread_decode(void * arg)363*437bfbebSnyanmisaka void *thread_decode(void *arg)
364*437bfbebSnyanmisaka {
365*437bfbebSnyanmisaka     MpiDecLoopData *data = (MpiDecLoopData *)arg;
366*437bfbebSnyanmisaka     MpiDecTestCmd *cmd = data->cmd;
367*437bfbebSnyanmisaka     MppCtx ctx  = data->ctx;
368*437bfbebSnyanmisaka     MppApi *mpi = data->mpi;
369*437bfbebSnyanmisaka     RK_S64 t_s, t_e;
370*437bfbebSnyanmisaka 
371*437bfbebSnyanmisaka     memset(&data->checkcrc, 0, sizeof(data->checkcrc));
372*437bfbebSnyanmisaka     data->checkcrc.luma.sum = mpp_malloc(RK_ULONG, 512);
373*437bfbebSnyanmisaka     data->checkcrc.chroma.sum = mpp_malloc(RK_ULONG, 512);
374*437bfbebSnyanmisaka 
375*437bfbebSnyanmisaka     t_s = mpp_time();
376*437bfbebSnyanmisaka 
377*437bfbebSnyanmisaka     if (cmd->simple) {
378*437bfbebSnyanmisaka         while (!data->loop_end)
379*437bfbebSnyanmisaka             dec_simple(data);
380*437bfbebSnyanmisaka     } else {
381*437bfbebSnyanmisaka         /* NOTE: change output format before jpeg decoding */
382*437bfbebSnyanmisaka         if (MPP_FRAME_FMT_IS_YUV(cmd->format) || MPP_FRAME_FMT_IS_RGB(cmd->format)) {
383*437bfbebSnyanmisaka             MPP_RET ret = mpi->control(ctx, MPP_DEC_SET_OUTPUT_FORMAT, &cmd->format);
384*437bfbebSnyanmisaka             if (ret) {
385*437bfbebSnyanmisaka                 mpp_err("Failed to set output format 0x%x\n", cmd->format);
386*437bfbebSnyanmisaka                 return NULL;
387*437bfbebSnyanmisaka             }
388*437bfbebSnyanmisaka         }
389*437bfbebSnyanmisaka 
390*437bfbebSnyanmisaka         while (!data->loop_end)
391*437bfbebSnyanmisaka             dec_advanced(data);
392*437bfbebSnyanmisaka     }
393*437bfbebSnyanmisaka 
394*437bfbebSnyanmisaka     t_e = mpp_time();
395*437bfbebSnyanmisaka     data->elapsed_time = t_e - t_s;
396*437bfbebSnyanmisaka     data->frame_rate = (float)data->frame_count * 1000000 / data->elapsed_time;
397*437bfbebSnyanmisaka     data->delay = data->first_frm - data->first_pkt;
398*437bfbebSnyanmisaka 
399*437bfbebSnyanmisaka     mpp_log("decode %d frames time %lld ms delay %3d ms fps %3.2f\n",
400*437bfbebSnyanmisaka             data->frame_count, (RK_S64)(data->elapsed_time / 1000),
401*437bfbebSnyanmisaka             (RK_S32)(data->delay / 1000), data->frame_rate);
402*437bfbebSnyanmisaka 
403*437bfbebSnyanmisaka     MPP_FREE(data->checkcrc.luma.sum);
404*437bfbebSnyanmisaka     MPP_FREE(data->checkcrc.chroma.sum);
405*437bfbebSnyanmisaka 
406*437bfbebSnyanmisaka     return NULL;
407*437bfbebSnyanmisaka }
408*437bfbebSnyanmisaka 
dec_decode(MpiDecTestCmd * cmd)409*437bfbebSnyanmisaka int dec_decode(MpiDecTestCmd *cmd)
410*437bfbebSnyanmisaka {
411*437bfbebSnyanmisaka     // base flow context
412*437bfbebSnyanmisaka     MppCtx ctx          = NULL;
413*437bfbebSnyanmisaka     MppApi *mpi         = NULL;
414*437bfbebSnyanmisaka 
415*437bfbebSnyanmisaka     // input / output
416*437bfbebSnyanmisaka     MppPacket packet    = NULL;
417*437bfbebSnyanmisaka     MppFrame  frame     = NULL;
418*437bfbebSnyanmisaka 
419*437bfbebSnyanmisaka     // paramter for resource malloc
420*437bfbebSnyanmisaka     RK_U32 width        = cmd->width;
421*437bfbebSnyanmisaka     RK_U32 height       = cmd->height;
422*437bfbebSnyanmisaka     MppCodingType type  = cmd->type;
423*437bfbebSnyanmisaka 
424*437bfbebSnyanmisaka     // config for runtime mode
425*437bfbebSnyanmisaka     MppDecCfg cfg       = NULL;
426*437bfbebSnyanmisaka     RK_U32 need_split   = 1;
427*437bfbebSnyanmisaka 
428*437bfbebSnyanmisaka     // resources
429*437bfbebSnyanmisaka     MppBuffer frm_buf   = NULL;
430*437bfbebSnyanmisaka     pthread_t thd;
431*437bfbebSnyanmisaka     pthread_attr_t attr;
432*437bfbebSnyanmisaka     MpiDecLoopData data;
433*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
434*437bfbebSnyanmisaka 
435*437bfbebSnyanmisaka     mpp_log("mpi_dec_test start\n");
436*437bfbebSnyanmisaka     memset(&data, 0, sizeof(data));
437*437bfbebSnyanmisaka     pthread_attr_init(&attr);
438*437bfbebSnyanmisaka 
439*437bfbebSnyanmisaka     cmd->simple = (cmd->type != MPP_VIDEO_CodingMJPEG) ? (1) : (0);
440*437bfbebSnyanmisaka 
441*437bfbebSnyanmisaka     if (cmd->have_output) {
442*437bfbebSnyanmisaka         data.fp_output = fopen(cmd->file_output, "w+b");
443*437bfbebSnyanmisaka         if (NULL == data.fp_output) {
444*437bfbebSnyanmisaka             mpp_err("failed to open output file %s\n", cmd->file_output);
445*437bfbebSnyanmisaka             goto MPP_TEST_OUT;
446*437bfbebSnyanmisaka         }
447*437bfbebSnyanmisaka     }
448*437bfbebSnyanmisaka 
449*437bfbebSnyanmisaka     if (cmd->file_slt) {
450*437bfbebSnyanmisaka         data.fp_verify = fopen(cmd->file_slt, "wt");
451*437bfbebSnyanmisaka         if (!data.fp_verify)
452*437bfbebSnyanmisaka             mpp_err("failed to open verify file %s\n", cmd->file_slt);
453*437bfbebSnyanmisaka     }
454*437bfbebSnyanmisaka 
455*437bfbebSnyanmisaka     ret = dec_buf_mgr_init(&data.buf_mgr);
456*437bfbebSnyanmisaka     if (ret) {
457*437bfbebSnyanmisaka         mpp_err("dec_buf_mgr_init failed\n");
458*437bfbebSnyanmisaka         goto MPP_TEST_OUT;
459*437bfbebSnyanmisaka     }
460*437bfbebSnyanmisaka 
461*437bfbebSnyanmisaka     if (cmd->simple) {
462*437bfbebSnyanmisaka         ret = mpp_packet_init(&packet, NULL, 0);
463*437bfbebSnyanmisaka         if (ret) {
464*437bfbebSnyanmisaka             mpp_err("mpp_packet_init failed\n");
465*437bfbebSnyanmisaka             goto MPP_TEST_OUT;
466*437bfbebSnyanmisaka         }
467*437bfbebSnyanmisaka     } else {
468*437bfbebSnyanmisaka         RK_U32 hor_stride = MPP_ALIGN(width, 16);
469*437bfbebSnyanmisaka         RK_U32 ver_stride = MPP_ALIGN(height, 16);
470*437bfbebSnyanmisaka 
471*437bfbebSnyanmisaka         ret = mpp_frame_init(&frame); /* output frame */
472*437bfbebSnyanmisaka         if (ret) {
473*437bfbebSnyanmisaka             mpp_err("mpp_frame_init failed\n");
474*437bfbebSnyanmisaka             goto MPP_TEST_OUT;
475*437bfbebSnyanmisaka         }
476*437bfbebSnyanmisaka 
477*437bfbebSnyanmisaka         data.frm_grp = dec_buf_mgr_setup(data.buf_mgr, hor_stride * ver_stride * 4, 4, cmd->buf_mode);
478*437bfbebSnyanmisaka         if (!data.frm_grp) {
479*437bfbebSnyanmisaka             mpp_err("failed to get buffer group for input frame ret %d\n", ret);
480*437bfbebSnyanmisaka             ret = MPP_NOK;
481*437bfbebSnyanmisaka             goto MPP_TEST_OUT;
482*437bfbebSnyanmisaka         }
483*437bfbebSnyanmisaka 
484*437bfbebSnyanmisaka         /*
485*437bfbebSnyanmisaka          * NOTE: For jpeg could have YUV420 and YUV422 the buffer should be
486*437bfbebSnyanmisaka          * larger for output. And the buffer dimension should align to 16.
487*437bfbebSnyanmisaka          * YUV420 buffer is 3/2 times of w*h.
488*437bfbebSnyanmisaka          * YUV422 buffer is 2 times of w*h.
489*437bfbebSnyanmisaka          * So create larger buffer with 2 times w*h.
490*437bfbebSnyanmisaka          */
491*437bfbebSnyanmisaka         ret = mpp_buffer_get(data.frm_grp, &frm_buf, hor_stride * ver_stride * 4);
492*437bfbebSnyanmisaka         if (ret) {
493*437bfbebSnyanmisaka             mpp_err("failed to get buffer for input frame ret %d\n", ret);
494*437bfbebSnyanmisaka             goto MPP_TEST_OUT;
495*437bfbebSnyanmisaka         }
496*437bfbebSnyanmisaka 
497*437bfbebSnyanmisaka         mpp_frame_set_buffer(frame, frm_buf);
498*437bfbebSnyanmisaka     }
499*437bfbebSnyanmisaka 
500*437bfbebSnyanmisaka     // decoder demo
501*437bfbebSnyanmisaka     ret = mpp_create(&ctx, &mpi);
502*437bfbebSnyanmisaka     if (ret) {
503*437bfbebSnyanmisaka         mpp_err("mpp_create failed\n");
504*437bfbebSnyanmisaka         goto MPP_TEST_OUT;
505*437bfbebSnyanmisaka     }
506*437bfbebSnyanmisaka 
507*437bfbebSnyanmisaka     mpp_log("%p mpi_dec_test decoder test start w %d h %d type %d\n",
508*437bfbebSnyanmisaka             ctx, width, height, type);
509*437bfbebSnyanmisaka 
510*437bfbebSnyanmisaka     ret = mpp_init(ctx, MPP_CTX_DEC, type);
511*437bfbebSnyanmisaka     if (ret) {
512*437bfbebSnyanmisaka         mpp_err("%p mpp_init failed\n", ctx);
513*437bfbebSnyanmisaka         goto MPP_TEST_OUT;
514*437bfbebSnyanmisaka     }
515*437bfbebSnyanmisaka 
516*437bfbebSnyanmisaka     mpp_dec_cfg_init(&cfg);
517*437bfbebSnyanmisaka 
518*437bfbebSnyanmisaka     /* get default config from decoder context */
519*437bfbebSnyanmisaka     ret = mpi->control(ctx, MPP_DEC_GET_CFG, cfg);
520*437bfbebSnyanmisaka     if (ret) {
521*437bfbebSnyanmisaka         mpp_err("%p failed to get decoder cfg ret %d\n", ctx, ret);
522*437bfbebSnyanmisaka         goto MPP_TEST_OUT;
523*437bfbebSnyanmisaka     }
524*437bfbebSnyanmisaka 
525*437bfbebSnyanmisaka     /*
526*437bfbebSnyanmisaka      * split_parse is to enable mpp internal frame spliter when the input
527*437bfbebSnyanmisaka      * packet is not aplited into frames.
528*437bfbebSnyanmisaka      */
529*437bfbebSnyanmisaka     ret = mpp_dec_cfg_set_u32(cfg, "base:split_parse", need_split);
530*437bfbebSnyanmisaka     if (ret) {
531*437bfbebSnyanmisaka         mpp_err("%p failed to set split_parse ret %d\n", ctx, ret);
532*437bfbebSnyanmisaka         goto MPP_TEST_OUT;
533*437bfbebSnyanmisaka     }
534*437bfbebSnyanmisaka 
535*437bfbebSnyanmisaka     ret = mpi->control(ctx, MPP_DEC_SET_CFG, cfg);
536*437bfbebSnyanmisaka     if (ret) {
537*437bfbebSnyanmisaka         mpp_err("%p failed to set cfg %p ret %d\n", ctx, cfg, ret);
538*437bfbebSnyanmisaka         goto MPP_TEST_OUT;
539*437bfbebSnyanmisaka     }
540*437bfbebSnyanmisaka 
541*437bfbebSnyanmisaka     data.cmd            = cmd;
542*437bfbebSnyanmisaka     data.ctx            = ctx;
543*437bfbebSnyanmisaka     data.mpi            = mpi;
544*437bfbebSnyanmisaka     data.loop_end       = 0;
545*437bfbebSnyanmisaka     data.packet         = packet;
546*437bfbebSnyanmisaka     data.frame          = frame;
547*437bfbebSnyanmisaka     data.frame_count    = 0;
548*437bfbebSnyanmisaka     data.frame_num      = cmd->frame_num;
549*437bfbebSnyanmisaka     data.quiet          = cmd->quiet;
550*437bfbebSnyanmisaka 
551*437bfbebSnyanmisaka     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
552*437bfbebSnyanmisaka 
553*437bfbebSnyanmisaka     ret = pthread_create(&thd, &attr, thread_decode, &data);
554*437bfbebSnyanmisaka     if (ret) {
555*437bfbebSnyanmisaka         mpp_err("failed to create thread for input ret %d\n", ret);
556*437bfbebSnyanmisaka         goto MPP_TEST_OUT;
557*437bfbebSnyanmisaka     }
558*437bfbebSnyanmisaka 
559*437bfbebSnyanmisaka     if (cmd->frame_num < 0) {
560*437bfbebSnyanmisaka         // wait for input then quit decoding
561*437bfbebSnyanmisaka         mpp_log("*******************************************\n");
562*437bfbebSnyanmisaka         mpp_log("**** Press Enter to stop loop decoding ****\n");
563*437bfbebSnyanmisaka         mpp_log("*******************************************\n");
564*437bfbebSnyanmisaka 
565*437bfbebSnyanmisaka         getc(stdin);
566*437bfbebSnyanmisaka         data.loop_end = 1;
567*437bfbebSnyanmisaka     }
568*437bfbebSnyanmisaka 
569*437bfbebSnyanmisaka     pthread_join(thd, NULL);
570*437bfbebSnyanmisaka 
571*437bfbebSnyanmisaka     cmd->max_usage = data.max_usage;
572*437bfbebSnyanmisaka 
573*437bfbebSnyanmisaka     ret = mpi->reset(ctx);
574*437bfbebSnyanmisaka     if (ret) {
575*437bfbebSnyanmisaka         mpp_err("%p mpi->reset failed\n", ctx);
576*437bfbebSnyanmisaka         goto MPP_TEST_OUT;
577*437bfbebSnyanmisaka     }
578*437bfbebSnyanmisaka 
579*437bfbebSnyanmisaka MPP_TEST_OUT:
580*437bfbebSnyanmisaka     if (data.packet) {
581*437bfbebSnyanmisaka         mpp_packet_deinit(&data.packet);
582*437bfbebSnyanmisaka         data.packet = NULL;
583*437bfbebSnyanmisaka     }
584*437bfbebSnyanmisaka 
585*437bfbebSnyanmisaka     if (frame) {
586*437bfbebSnyanmisaka         mpp_frame_deinit(&frame);
587*437bfbebSnyanmisaka         frame = NULL;
588*437bfbebSnyanmisaka     }
589*437bfbebSnyanmisaka 
590*437bfbebSnyanmisaka     if (ctx) {
591*437bfbebSnyanmisaka         mpp_destroy(ctx);
592*437bfbebSnyanmisaka         ctx = NULL;
593*437bfbebSnyanmisaka     }
594*437bfbebSnyanmisaka 
595*437bfbebSnyanmisaka     if (!cmd->simple) {
596*437bfbebSnyanmisaka         if (frm_buf) {
597*437bfbebSnyanmisaka             mpp_buffer_put(frm_buf);
598*437bfbebSnyanmisaka             frm_buf = NULL;
599*437bfbebSnyanmisaka         }
600*437bfbebSnyanmisaka     }
601*437bfbebSnyanmisaka 
602*437bfbebSnyanmisaka     data.frm_grp = NULL;
603*437bfbebSnyanmisaka     if (data.buf_mgr) {
604*437bfbebSnyanmisaka         dec_buf_mgr_deinit(data.buf_mgr);
605*437bfbebSnyanmisaka         data.buf_mgr = NULL;
606*437bfbebSnyanmisaka     }
607*437bfbebSnyanmisaka 
608*437bfbebSnyanmisaka     if (data.fp_output) {
609*437bfbebSnyanmisaka         fclose(data.fp_output);
610*437bfbebSnyanmisaka         data.fp_output = NULL;
611*437bfbebSnyanmisaka     }
612*437bfbebSnyanmisaka 
613*437bfbebSnyanmisaka     if (data.fp_verify) {
614*437bfbebSnyanmisaka         fclose(data.fp_verify);
615*437bfbebSnyanmisaka         data.fp_verify = NULL;
616*437bfbebSnyanmisaka     }
617*437bfbebSnyanmisaka 
618*437bfbebSnyanmisaka     if (cfg) {
619*437bfbebSnyanmisaka         mpp_dec_cfg_deinit(cfg);
620*437bfbebSnyanmisaka         cfg = NULL;
621*437bfbebSnyanmisaka     }
622*437bfbebSnyanmisaka 
623*437bfbebSnyanmisaka     pthread_attr_destroy(&attr);
624*437bfbebSnyanmisaka 
625*437bfbebSnyanmisaka     return ret;
626*437bfbebSnyanmisaka }
627*437bfbebSnyanmisaka 
main(int argc,char ** argv)628*437bfbebSnyanmisaka int main(int argc, char **argv)
629*437bfbebSnyanmisaka {
630*437bfbebSnyanmisaka     RK_S32 ret = 0;
631*437bfbebSnyanmisaka     MpiDecTestCmd  cmd_ctx;
632*437bfbebSnyanmisaka     MpiDecTestCmd* cmd = &cmd_ctx;
633*437bfbebSnyanmisaka 
634*437bfbebSnyanmisaka     memset((void*)cmd, 0, sizeof(*cmd));
635*437bfbebSnyanmisaka     cmd->format = MPP_FMT_BUTT;
636*437bfbebSnyanmisaka     cmd->pkt_size = MPI_DEC_STREAM_SIZE;
637*437bfbebSnyanmisaka 
638*437bfbebSnyanmisaka     // parse the cmd option
639*437bfbebSnyanmisaka     ret = mpi_dec_test_cmd_init(cmd, argc, argv);
640*437bfbebSnyanmisaka     if (ret)
641*437bfbebSnyanmisaka         goto RET;
642*437bfbebSnyanmisaka 
643*437bfbebSnyanmisaka     mpi_dec_test_cmd_options(cmd);
644*437bfbebSnyanmisaka 
645*437bfbebSnyanmisaka     ret = dec_decode(cmd);
646*437bfbebSnyanmisaka     if (MPP_OK == ret)
647*437bfbebSnyanmisaka         mpp_log("test success max memory %.2f MB\n", cmd->max_usage / (float)(1 << 20));
648*437bfbebSnyanmisaka     else
649*437bfbebSnyanmisaka         mpp_err("test failed ret %d\n", ret);
650*437bfbebSnyanmisaka 
651*437bfbebSnyanmisaka RET:
652*437bfbebSnyanmisaka     mpi_dec_test_cmd_deinit(cmd);
653*437bfbebSnyanmisaka 
654*437bfbebSnyanmisaka     return ret;
655*437bfbebSnyanmisaka }
656*437bfbebSnyanmisaka 
657