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