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 #define MODULE_TAG "mpp"
7*437bfbebSnyanmisaka
8*437bfbebSnyanmisaka #include <errno.h>
9*437bfbebSnyanmisaka #include <string.h>
10*437bfbebSnyanmisaka
11*437bfbebSnyanmisaka #include "rk_mpi.h"
12*437bfbebSnyanmisaka
13*437bfbebSnyanmisaka #include "mpp_mem.h"
14*437bfbebSnyanmisaka #include "mpp_env.h"
15*437bfbebSnyanmisaka #include "mpp_time.h"
16*437bfbebSnyanmisaka #include "mpp_impl.h"
17*437bfbebSnyanmisaka #include "mpp_2str.h"
18*437bfbebSnyanmisaka #include "mpp_debug.h"
19*437bfbebSnyanmisaka
20*437bfbebSnyanmisaka #include "mpp.h"
21*437bfbebSnyanmisaka #include "mpp_hal.h"
22*437bfbebSnyanmisaka
23*437bfbebSnyanmisaka #include "mpp_task_impl.h"
24*437bfbebSnyanmisaka #include "mpp_buffer_impl.h"
25*437bfbebSnyanmisaka #include "mpp_frame_impl.h"
26*437bfbebSnyanmisaka #include "mpp_packet_impl.h"
27*437bfbebSnyanmisaka
28*437bfbebSnyanmisaka #include "kmpp.h"
29*437bfbebSnyanmisaka
30*437bfbebSnyanmisaka #define MPP_TEST_FRAME_SIZE SZ_1M
31*437bfbebSnyanmisaka #define MPP_TEST_PACKET_SIZE SZ_512K
32*437bfbebSnyanmisaka
mpp_notify_by_buffer_group(void * arg,void * group)33*437bfbebSnyanmisaka static void mpp_notify_by_buffer_group(void *arg, void *group)
34*437bfbebSnyanmisaka {
35*437bfbebSnyanmisaka Mpp *mpp = (Mpp *)arg;
36*437bfbebSnyanmisaka mpp_notify_group(mpp, (MppBufferGroup)group);
37*437bfbebSnyanmisaka }
38*437bfbebSnyanmisaka
list_wraper_packet(void * arg)39*437bfbebSnyanmisaka static void *list_wraper_packet(void *arg)
40*437bfbebSnyanmisaka {
41*437bfbebSnyanmisaka MppPacket packet = *(MppPacket*)arg;
42*437bfbebSnyanmisaka
43*437bfbebSnyanmisaka if (mpp_packet_has_meta(packet)) {
44*437bfbebSnyanmisaka MppMeta meta = mpp_packet_get_meta(packet);
45*437bfbebSnyanmisaka MppFrame frm = NULL;
46*437bfbebSnyanmisaka
47*437bfbebSnyanmisaka if (MPP_OK == mpp_meta_get_frame(meta, KEY_INPUT_FRAME, &frm)) {
48*437bfbebSnyanmisaka mpp_assert(frm);
49*437bfbebSnyanmisaka mpp_frame_deinit(&frm);
50*437bfbebSnyanmisaka }
51*437bfbebSnyanmisaka }
52*437bfbebSnyanmisaka
53*437bfbebSnyanmisaka mpp_packet_deinit((MppPacket *)arg);
54*437bfbebSnyanmisaka return NULL;
55*437bfbebSnyanmisaka }
56*437bfbebSnyanmisaka
list_wraper_frame(void * arg)57*437bfbebSnyanmisaka static void *list_wraper_frame(void *arg)
58*437bfbebSnyanmisaka {
59*437bfbebSnyanmisaka mpp_frame_deinit((MppFrame *)arg);
60*437bfbebSnyanmisaka return NULL;
61*437bfbebSnyanmisaka }
62*437bfbebSnyanmisaka
check_frm_task_cnt_cap(MppCodingType coding)63*437bfbebSnyanmisaka static RK_S32 check_frm_task_cnt_cap(MppCodingType coding)
64*437bfbebSnyanmisaka {
65*437bfbebSnyanmisaka RockchipSocType soc_type = mpp_get_soc_type();
66*437bfbebSnyanmisaka
67*437bfbebSnyanmisaka if (soc_type == ROCKCHIP_SOC_RK3588 || soc_type == ROCKCHIP_SOC_RK3576) {
68*437bfbebSnyanmisaka if (coding == MPP_VIDEO_CodingAVC || coding == MPP_VIDEO_CodingHEVC)
69*437bfbebSnyanmisaka return 2;
70*437bfbebSnyanmisaka if (coding == MPP_VIDEO_CodingMJPEG && soc_type == ROCKCHIP_SOC_RK3588)
71*437bfbebSnyanmisaka return 4;
72*437bfbebSnyanmisaka }
73*437bfbebSnyanmisaka
74*437bfbebSnyanmisaka mpp_log("Only rk3588's h264/265/jpeg and rk3576's h264/265 encoder can use frame parallel\n");
75*437bfbebSnyanmisaka
76*437bfbebSnyanmisaka return 1;
77*437bfbebSnyanmisaka }
78*437bfbebSnyanmisaka
mpp_ctx_create(Mpp ** mpp,MppCtx ctx)79*437bfbebSnyanmisaka MPP_RET mpp_ctx_create(Mpp **mpp, MppCtx ctx)
80*437bfbebSnyanmisaka {
81*437bfbebSnyanmisaka if (!mpp) {
82*437bfbebSnyanmisaka mpp_err_f("invalid input mpp pointer\n");
83*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
84*437bfbebSnyanmisaka }
85*437bfbebSnyanmisaka
86*437bfbebSnyanmisaka Mpp *p = mpp_calloc(Mpp, 1);
87*437bfbebSnyanmisaka if (!p) {
88*437bfbebSnyanmisaka mpp_err_f("failed to allocate mpp context\n");
89*437bfbebSnyanmisaka return MPP_ERR_MALLOC;
90*437bfbebSnyanmisaka }
91*437bfbebSnyanmisaka
92*437bfbebSnyanmisaka /* Initialize all members to default values */
93*437bfbebSnyanmisaka p->mPktIn = NULL;
94*437bfbebSnyanmisaka p->mPktOut = NULL;
95*437bfbebSnyanmisaka p->mFrmIn = NULL;
96*437bfbebSnyanmisaka p->mFrmOut = NULL;
97*437bfbebSnyanmisaka p->mPacketPutCount = 0;
98*437bfbebSnyanmisaka p->mPacketGetCount = 0;
99*437bfbebSnyanmisaka p->mFramePutCount = 0;
100*437bfbebSnyanmisaka p->mFrameGetCount = 0;
101*437bfbebSnyanmisaka p->mTaskPutCount = 0;
102*437bfbebSnyanmisaka p->mTaskGetCount = 0;
103*437bfbebSnyanmisaka p->mPacketGroup = NULL;
104*437bfbebSnyanmisaka p->mFrameGroup = NULL;
105*437bfbebSnyanmisaka p->mExternalBufferMode = 0;
106*437bfbebSnyanmisaka p->mUsrInPort = NULL;
107*437bfbebSnyanmisaka p->mUsrOutPort = NULL;
108*437bfbebSnyanmisaka p->mMppInPort = NULL;
109*437bfbebSnyanmisaka p->mMppOutPort = NULL;
110*437bfbebSnyanmisaka p->mInputTaskQueue = NULL;
111*437bfbebSnyanmisaka p->mOutputTaskQueue = NULL;
112*437bfbebSnyanmisaka p->mInputTaskCount = 1;
113*437bfbebSnyanmisaka p->mOutputTaskCount = 1;
114*437bfbebSnyanmisaka p->mInputTimeout = MPP_POLL_BUTT;
115*437bfbebSnyanmisaka p->mOutputTimeout = MPP_POLL_BUTT;
116*437bfbebSnyanmisaka p->mInputTask = NULL;
117*437bfbebSnyanmisaka p->mEosTask = NULL;
118*437bfbebSnyanmisaka p->mCtx = ctx;
119*437bfbebSnyanmisaka p->mDec = NULL;
120*437bfbebSnyanmisaka p->mEnc = NULL;
121*437bfbebSnyanmisaka p->mEncAyncIo = 0;
122*437bfbebSnyanmisaka p->mEncAyncProc = 0;
123*437bfbebSnyanmisaka p->mIoMode = MPP_IO_MODE_DEFAULT;
124*437bfbebSnyanmisaka p->mDisableThread = 0;
125*437bfbebSnyanmisaka p->mDump = NULL;
126*437bfbebSnyanmisaka p->mKmpp = NULL;
127*437bfbebSnyanmisaka p->mVencInitKcfg = NULL;
128*437bfbebSnyanmisaka p->mType = MPP_CTX_BUTT;
129*437bfbebSnyanmisaka p->mCoding = MPP_VIDEO_CodingUnused;
130*437bfbebSnyanmisaka p->mInitDone = 0;
131*437bfbebSnyanmisaka p->mStatus = 0;
132*437bfbebSnyanmisaka p->mDecCfg = NULL;
133*437bfbebSnyanmisaka p->mParserFastMode = 0;
134*437bfbebSnyanmisaka p->mParserNeedSplit = 0;
135*437bfbebSnyanmisaka p->mParserInternalPts = 0;
136*437bfbebSnyanmisaka p->mImmediateOut = 0;
137*437bfbebSnyanmisaka p->mExtraPacket = NULL;
138*437bfbebSnyanmisaka
139*437bfbebSnyanmisaka mpp_env_get_u32("mpp_debug", &mpp_debug, 0);
140*437bfbebSnyanmisaka
141*437bfbebSnyanmisaka mpp_dec_cfg_init(&p->mDecCfg);
142*437bfbebSnyanmisaka mpp_dec_cfg_set_u32(p->mDecCfg, "base:enable_vproc", MPP_VPROC_MODE_DEINTELACE);
143*437bfbebSnyanmisaka
144*437bfbebSnyanmisaka mpp_dump_init(&p->mDump);
145*437bfbebSnyanmisaka
146*437bfbebSnyanmisaka *mpp = p;
147*437bfbebSnyanmisaka return MPP_OK;
148*437bfbebSnyanmisaka }
149*437bfbebSnyanmisaka
mpp_ctx_init(Mpp * mpp,MppCtxType type,MppCodingType coding)150*437bfbebSnyanmisaka MPP_RET mpp_ctx_init(Mpp *mpp, MppCtxType type, MppCodingType coding)
151*437bfbebSnyanmisaka {
152*437bfbebSnyanmisaka MPP_RET ret = MPP_NOK;
153*437bfbebSnyanmisaka
154*437bfbebSnyanmisaka if (!mpp) {
155*437bfbebSnyanmisaka mpp_err_f("invalid input mpp pointer\n");
156*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
157*437bfbebSnyanmisaka }
158*437bfbebSnyanmisaka
159*437bfbebSnyanmisaka if (!mpp_check_soc_cap(type, coding)) {
160*437bfbebSnyanmisaka mpp_err("unable to create %s %s for soc %s unsupported\n",
161*437bfbebSnyanmisaka strof_ctx_type(type), strof_coding_type(coding),
162*437bfbebSnyanmisaka mpp_get_soc_info()->compatible);
163*437bfbebSnyanmisaka return MPP_NOK;
164*437bfbebSnyanmisaka }
165*437bfbebSnyanmisaka
166*437bfbebSnyanmisaka if (mpp_check_support_format(type, coding)) {
167*437bfbebSnyanmisaka mpp_err("unable to create %s %s for mpp unsupported\n",
168*437bfbebSnyanmisaka strof_ctx_type(type), strof_coding_type(coding));
169*437bfbebSnyanmisaka return MPP_NOK;
170*437bfbebSnyanmisaka }
171*437bfbebSnyanmisaka
172*437bfbebSnyanmisaka mpp_ops_init(mpp->mDump, type, coding);
173*437bfbebSnyanmisaka
174*437bfbebSnyanmisaka mpp->mType = type;
175*437bfbebSnyanmisaka mpp->mCoding = coding;
176*437bfbebSnyanmisaka
177*437bfbebSnyanmisaka /* init kmpp venc */
178*437bfbebSnyanmisaka if (mpp->mVencInitKcfg) {
179*437bfbebSnyanmisaka mpp->mKmpp = mpp_calloc(Kmpp, 1);
180*437bfbebSnyanmisaka if (!mpp->mKmpp) {
181*437bfbebSnyanmisaka mpp_err("failed to alloc kmpp context\n");
182*437bfbebSnyanmisaka return MPP_NOK;
183*437bfbebSnyanmisaka }
184*437bfbebSnyanmisaka mpp->mKmpp->mClientFd = -1;
185*437bfbebSnyanmisaka mpp_get_api(mpp->mKmpp);
186*437bfbebSnyanmisaka mpp->mKmpp->mVencInitKcfg = mpp->mVencInitKcfg;
187*437bfbebSnyanmisaka ret = mpp->mKmpp->mApi->init(mpp->mKmpp, type, coding);
188*437bfbebSnyanmisaka if (ret) {
189*437bfbebSnyanmisaka mpp_err("failed to init kmpp ret %d\n", ret);
190*437bfbebSnyanmisaka return ret;
191*437bfbebSnyanmisaka }
192*437bfbebSnyanmisaka mpp->mInitDone = 1;
193*437bfbebSnyanmisaka return ret;
194*437bfbebSnyanmisaka }
195*437bfbebSnyanmisaka
196*437bfbebSnyanmisaka mpp_task_queue_init(&mpp->mInputTaskQueue, mpp, "input");
197*437bfbebSnyanmisaka mpp_task_queue_init(&mpp->mOutputTaskQueue, mpp, "output");
198*437bfbebSnyanmisaka
199*437bfbebSnyanmisaka switch (mpp->mType) {
200*437bfbebSnyanmisaka case MPP_CTX_DEC : {
201*437bfbebSnyanmisaka mpp->mPktIn = mpp_list_create(list_wraper_packet);
202*437bfbebSnyanmisaka mpp->mFrmOut = mpp_list_create(list_wraper_frame);
203*437bfbebSnyanmisaka
204*437bfbebSnyanmisaka if (mpp->mInputTimeout == MPP_POLL_BUTT)
205*437bfbebSnyanmisaka mpp->mInputTimeout = MPP_POLL_NON_BLOCK;
206*437bfbebSnyanmisaka
207*437bfbebSnyanmisaka if (mpp->mOutputTimeout == MPP_POLL_BUTT)
208*437bfbebSnyanmisaka mpp->mOutputTimeout = MPP_POLL_NON_BLOCK;
209*437bfbebSnyanmisaka
210*437bfbebSnyanmisaka if (mpp->mCoding != MPP_VIDEO_CodingMJPEG) {
211*437bfbebSnyanmisaka mpp_buffer_group_get_internal(&mpp->mPacketGroup, MPP_BUFFER_TYPE_ION | MPP_BUFFER_FLAGS_CACHABLE);
212*437bfbebSnyanmisaka mpp_buffer_group_limit_config(mpp->mPacketGroup, 0, 3);
213*437bfbebSnyanmisaka
214*437bfbebSnyanmisaka mpp->mInputTaskCount = 4;
215*437bfbebSnyanmisaka mpp->mOutputTaskCount = 4;
216*437bfbebSnyanmisaka }
217*437bfbebSnyanmisaka
218*437bfbebSnyanmisaka mpp_task_queue_setup(mpp->mInputTaskQueue, mpp->mInputTaskCount);
219*437bfbebSnyanmisaka mpp_task_queue_setup(mpp->mOutputTaskQueue, mpp->mOutputTaskCount);
220*437bfbebSnyanmisaka
221*437bfbebSnyanmisaka mpp->mUsrInPort = mpp_task_queue_get_port(mpp->mInputTaskQueue, MPP_PORT_INPUT);
222*437bfbebSnyanmisaka mpp->mUsrOutPort = mpp_task_queue_get_port(mpp->mOutputTaskQueue, MPP_PORT_OUTPUT);
223*437bfbebSnyanmisaka mpp->mMppInPort = mpp_task_queue_get_port(mpp->mInputTaskQueue, MPP_PORT_OUTPUT);
224*437bfbebSnyanmisaka mpp->mMppOutPort = mpp_task_queue_get_port(mpp->mOutputTaskQueue, MPP_PORT_INPUT);
225*437bfbebSnyanmisaka
226*437bfbebSnyanmisaka mpp_dec_cfg_set_u32(mpp->mDecCfg, "base:disable_thread", mpp->mDisableThread);
227*437bfbebSnyanmisaka
228*437bfbebSnyanmisaka MppDecInitCfg cfg = {
229*437bfbebSnyanmisaka coding,
230*437bfbebSnyanmisaka mpp,
231*437bfbebSnyanmisaka mpp->mDecCfg,
232*437bfbebSnyanmisaka };
233*437bfbebSnyanmisaka
234*437bfbebSnyanmisaka ret = mpp_dec_init(&mpp->mDec, &cfg);
235*437bfbebSnyanmisaka if (ret)
236*437bfbebSnyanmisaka break;
237*437bfbebSnyanmisaka ret = mpp_dec_start(mpp->mDec);
238*437bfbebSnyanmisaka if (ret)
239*437bfbebSnyanmisaka break;
240*437bfbebSnyanmisaka mpp->mInitDone = 1;
241*437bfbebSnyanmisaka } break;
242*437bfbebSnyanmisaka case MPP_CTX_ENC : {
243*437bfbebSnyanmisaka mpp->mPktOut = mpp_list_create(list_wraper_packet);
244*437bfbebSnyanmisaka mpp->mFrmIn = mpp_list_create(list_wraper_frame);
245*437bfbebSnyanmisaka
246*437bfbebSnyanmisaka if (mpp->mInputTimeout == MPP_POLL_BUTT)
247*437bfbebSnyanmisaka mpp->mInputTimeout = MPP_POLL_BLOCK;
248*437bfbebSnyanmisaka
249*437bfbebSnyanmisaka if (mpp->mOutputTimeout == MPP_POLL_BUTT)
250*437bfbebSnyanmisaka mpp->mOutputTimeout = MPP_POLL_NON_BLOCK;
251*437bfbebSnyanmisaka
252*437bfbebSnyanmisaka mpp_buffer_group_get_internal(&mpp->mPacketGroup, MPP_BUFFER_TYPE_ION);
253*437bfbebSnyanmisaka mpp_buffer_group_get_internal(&mpp->mFrameGroup, MPP_BUFFER_TYPE_ION);
254*437bfbebSnyanmisaka
255*437bfbebSnyanmisaka if (mpp->mInputTimeout == MPP_POLL_NON_BLOCK) {
256*437bfbebSnyanmisaka mpp->mEncAyncIo = 1;
257*437bfbebSnyanmisaka
258*437bfbebSnyanmisaka mpp->mInputTaskCount = check_frm_task_cnt_cap(coding);
259*437bfbebSnyanmisaka if (mpp->mInputTaskCount == 1)
260*437bfbebSnyanmisaka mpp->mInputTimeout = MPP_POLL_BLOCK;
261*437bfbebSnyanmisaka }
262*437bfbebSnyanmisaka mpp->mOutputTaskCount = 8;
263*437bfbebSnyanmisaka
264*437bfbebSnyanmisaka mpp_task_queue_setup(mpp->mInputTaskQueue, mpp->mInputTaskCount);
265*437bfbebSnyanmisaka mpp_task_queue_setup(mpp->mOutputTaskQueue, mpp->mOutputTaskCount);
266*437bfbebSnyanmisaka
267*437bfbebSnyanmisaka mpp->mUsrInPort = mpp_task_queue_get_port(mpp->mInputTaskQueue, MPP_PORT_INPUT);
268*437bfbebSnyanmisaka mpp->mUsrOutPort = mpp_task_queue_get_port(mpp->mOutputTaskQueue, MPP_PORT_OUTPUT);
269*437bfbebSnyanmisaka mpp->mMppInPort = mpp_task_queue_get_port(mpp->mInputTaskQueue, MPP_PORT_OUTPUT);
270*437bfbebSnyanmisaka mpp->mMppOutPort = mpp_task_queue_get_port(mpp->mOutputTaskQueue, MPP_PORT_INPUT);
271*437bfbebSnyanmisaka
272*437bfbebSnyanmisaka MppEncInitCfg cfg = {
273*437bfbebSnyanmisaka coding,
274*437bfbebSnyanmisaka mpp->mInputTaskCount,
275*437bfbebSnyanmisaka mpp,
276*437bfbebSnyanmisaka };
277*437bfbebSnyanmisaka
278*437bfbebSnyanmisaka ret = mpp_enc_init_v2(&mpp->mEnc, &cfg);
279*437bfbebSnyanmisaka if (ret)
280*437bfbebSnyanmisaka break;
281*437bfbebSnyanmisaka
282*437bfbebSnyanmisaka if (mpp->mInputTimeout == MPP_POLL_NON_BLOCK) {
283*437bfbebSnyanmisaka mpp->mEncAyncProc = 1;
284*437bfbebSnyanmisaka ret = mpp_enc_start_async(mpp->mEnc);
285*437bfbebSnyanmisaka } else {
286*437bfbebSnyanmisaka ret = mpp_enc_start_v2(mpp->mEnc);
287*437bfbebSnyanmisaka }
288*437bfbebSnyanmisaka
289*437bfbebSnyanmisaka if (ret)
290*437bfbebSnyanmisaka break;
291*437bfbebSnyanmisaka mpp->mInitDone = 1;
292*437bfbebSnyanmisaka } break;
293*437bfbebSnyanmisaka default : {
294*437bfbebSnyanmisaka mpp_err("Mpp error type %d\n", mpp->mType);
295*437bfbebSnyanmisaka } break;
296*437bfbebSnyanmisaka }
297*437bfbebSnyanmisaka
298*437bfbebSnyanmisaka if (!mpp->mInitDone) {
299*437bfbebSnyanmisaka mpp_err("error found on mpp initialization\n");
300*437bfbebSnyanmisaka mpp_clear(mpp);
301*437bfbebSnyanmisaka }
302*437bfbebSnyanmisaka
303*437bfbebSnyanmisaka return ret;
304*437bfbebSnyanmisaka }
305*437bfbebSnyanmisaka
mpp_clear(Mpp * mpp)306*437bfbebSnyanmisaka void mpp_clear(Mpp *mpp)
307*437bfbebSnyanmisaka {
308*437bfbebSnyanmisaka if (!mpp)
309*437bfbebSnyanmisaka return;
310*437bfbebSnyanmisaka
311*437bfbebSnyanmisaka /* MUST: release listener here */
312*437bfbebSnyanmisaka if (mpp->mFrameGroup)
313*437bfbebSnyanmisaka mpp_buffer_group_set_callback((MppBufferGroupImpl *)mpp->mFrameGroup,
314*437bfbebSnyanmisaka NULL, NULL);
315*437bfbebSnyanmisaka
316*437bfbebSnyanmisaka if (mpp->mType == MPP_CTX_DEC) {
317*437bfbebSnyanmisaka if (mpp->mDec) {
318*437bfbebSnyanmisaka mpp_dec_stop(mpp->mDec);
319*437bfbebSnyanmisaka mpp_dec_deinit(mpp->mDec);
320*437bfbebSnyanmisaka mpp->mDec = NULL;
321*437bfbebSnyanmisaka }
322*437bfbebSnyanmisaka } else {
323*437bfbebSnyanmisaka if (mpp->mEnc) {
324*437bfbebSnyanmisaka mpp_enc_stop_v2(mpp->mEnc);
325*437bfbebSnyanmisaka mpp_enc_deinit_v2(mpp->mEnc);
326*437bfbebSnyanmisaka mpp->mEnc = NULL;
327*437bfbebSnyanmisaka }
328*437bfbebSnyanmisaka }
329*437bfbebSnyanmisaka
330*437bfbebSnyanmisaka if (mpp->mInputTaskQueue) {
331*437bfbebSnyanmisaka mpp_task_queue_deinit(mpp->mInputTaskQueue);
332*437bfbebSnyanmisaka mpp->mInputTaskQueue = NULL;
333*437bfbebSnyanmisaka }
334*437bfbebSnyanmisaka if (mpp->mOutputTaskQueue) {
335*437bfbebSnyanmisaka mpp_task_queue_deinit(mpp->mOutputTaskQueue);
336*437bfbebSnyanmisaka mpp->mOutputTaskQueue = NULL;
337*437bfbebSnyanmisaka }
338*437bfbebSnyanmisaka
339*437bfbebSnyanmisaka mpp->mUsrInPort = NULL;
340*437bfbebSnyanmisaka mpp->mUsrOutPort = NULL;
341*437bfbebSnyanmisaka mpp->mMppInPort = NULL;
342*437bfbebSnyanmisaka mpp->mMppOutPort = NULL;
343*437bfbebSnyanmisaka
344*437bfbebSnyanmisaka if (mpp->mExtraPacket) {
345*437bfbebSnyanmisaka mpp_packet_deinit(&mpp->mExtraPacket);
346*437bfbebSnyanmisaka mpp->mExtraPacket = NULL;
347*437bfbebSnyanmisaka }
348*437bfbebSnyanmisaka
349*437bfbebSnyanmisaka if (mpp->mPktIn) {
350*437bfbebSnyanmisaka mpp_list_destroy(mpp->mPktIn);
351*437bfbebSnyanmisaka mpp->mPktIn = NULL;
352*437bfbebSnyanmisaka }
353*437bfbebSnyanmisaka if (mpp->mPktOut) {
354*437bfbebSnyanmisaka mpp_list_destroy(mpp->mPktOut);
355*437bfbebSnyanmisaka mpp->mPktOut = NULL;
356*437bfbebSnyanmisaka }
357*437bfbebSnyanmisaka if (mpp->mFrmIn) {
358*437bfbebSnyanmisaka mpp_list_destroy(mpp->mFrmIn);
359*437bfbebSnyanmisaka mpp->mFrmIn = NULL;
360*437bfbebSnyanmisaka }
361*437bfbebSnyanmisaka if (mpp->mFrmOut) {
362*437bfbebSnyanmisaka mpp_list_destroy(mpp->mFrmOut);
363*437bfbebSnyanmisaka mpp->mFrmOut = NULL;
364*437bfbebSnyanmisaka }
365*437bfbebSnyanmisaka
366*437bfbebSnyanmisaka if (mpp->mPacketGroup) {
367*437bfbebSnyanmisaka mpp_buffer_group_put(mpp->mPacketGroup);
368*437bfbebSnyanmisaka mpp->mPacketGroup = NULL;
369*437bfbebSnyanmisaka }
370*437bfbebSnyanmisaka
371*437bfbebSnyanmisaka if (mpp->mFrameGroup && !mpp->mExternalBufferMode) {
372*437bfbebSnyanmisaka mpp_buffer_group_put(mpp->mFrameGroup);
373*437bfbebSnyanmisaka mpp->mFrameGroup = NULL;
374*437bfbebSnyanmisaka }
375*437bfbebSnyanmisaka
376*437bfbebSnyanmisaka if (mpp->mKmpp) {
377*437bfbebSnyanmisaka if (mpp->mKmpp->mApi && mpp->mKmpp->mApi->clear)
378*437bfbebSnyanmisaka mpp->mKmpp->mApi->clear(mpp->mKmpp);
379*437bfbebSnyanmisaka
380*437bfbebSnyanmisaka MPP_FREE(mpp->mKmpp);
381*437bfbebSnyanmisaka }
382*437bfbebSnyanmisaka
383*437bfbebSnyanmisaka if (mpp->mDecCfg) {
384*437bfbebSnyanmisaka mpp_dec_cfg_deinit(mpp->mDecCfg);
385*437bfbebSnyanmisaka mpp->mDecCfg = NULL;
386*437bfbebSnyanmisaka }
387*437bfbebSnyanmisaka
388*437bfbebSnyanmisaka mpp_dump_deinit(&mpp->mDump);
389*437bfbebSnyanmisaka }
390*437bfbebSnyanmisaka
mpp_ctx_destroy(Mpp * mpp)391*437bfbebSnyanmisaka MPP_RET mpp_ctx_destroy(Mpp *mpp)
392*437bfbebSnyanmisaka {
393*437bfbebSnyanmisaka if (!mpp)
394*437bfbebSnyanmisaka return MPP_OK;
395*437bfbebSnyanmisaka
396*437bfbebSnyanmisaka mpp_clear(mpp);
397*437bfbebSnyanmisaka mpp_free(mpp);
398*437bfbebSnyanmisaka
399*437bfbebSnyanmisaka return MPP_OK;
400*437bfbebSnyanmisaka }
401*437bfbebSnyanmisaka
mpp_start(Mpp * mpp)402*437bfbebSnyanmisaka MPP_RET mpp_start(Mpp *mpp)
403*437bfbebSnyanmisaka {
404*437bfbebSnyanmisaka if (!mpp) {
405*437bfbebSnyanmisaka mpp_err_f("invalid input mpp pointer\n");
406*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
407*437bfbebSnyanmisaka }
408*437bfbebSnyanmisaka return MPP_OK;
409*437bfbebSnyanmisaka }
410*437bfbebSnyanmisaka
mpp_stop(Mpp * mpp)411*437bfbebSnyanmisaka MPP_RET mpp_stop(Mpp *mpp)
412*437bfbebSnyanmisaka {
413*437bfbebSnyanmisaka if (!mpp) {
414*437bfbebSnyanmisaka mpp_err_f("invalid input mpp pointer\n");
415*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
416*437bfbebSnyanmisaka }
417*437bfbebSnyanmisaka return MPP_OK;
418*437bfbebSnyanmisaka }
419*437bfbebSnyanmisaka
mpp_pause(Mpp * mpp)420*437bfbebSnyanmisaka MPP_RET mpp_pause(Mpp *mpp)
421*437bfbebSnyanmisaka {
422*437bfbebSnyanmisaka if (!mpp) {
423*437bfbebSnyanmisaka mpp_err_f("invalid input mpp pointer\n");
424*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
425*437bfbebSnyanmisaka }
426*437bfbebSnyanmisaka return MPP_OK;
427*437bfbebSnyanmisaka }
428*437bfbebSnyanmisaka
mpp_resume(Mpp * mpp)429*437bfbebSnyanmisaka MPP_RET mpp_resume(Mpp *mpp)
430*437bfbebSnyanmisaka {
431*437bfbebSnyanmisaka if (!mpp) {
432*437bfbebSnyanmisaka mpp_err_f("invalid input mpp pointer\n");
433*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
434*437bfbebSnyanmisaka }
435*437bfbebSnyanmisaka return MPP_OK;
436*437bfbebSnyanmisaka }
437*437bfbebSnyanmisaka
mpp_put_packet(Mpp * mpp,MppPacket packet)438*437bfbebSnyanmisaka MPP_RET mpp_put_packet(Mpp *mpp, MppPacket packet)
439*437bfbebSnyanmisaka {
440*437bfbebSnyanmisaka if (!mpp) {
441*437bfbebSnyanmisaka mpp_err_f("invalid input mpp pointer\n");
442*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
443*437bfbebSnyanmisaka }
444*437bfbebSnyanmisaka
445*437bfbebSnyanmisaka if (!mpp->mInitDone)
446*437bfbebSnyanmisaka return MPP_ERR_INIT;
447*437bfbebSnyanmisaka
448*437bfbebSnyanmisaka MPP_RET ret = MPP_NOK;
449*437bfbebSnyanmisaka MppPollType timeout = mpp->mInputTimeout;
450*437bfbebSnyanmisaka MppTask task_dequeue = NULL;
451*437bfbebSnyanmisaka RK_U32 pkt_copy = 0;
452*437bfbebSnyanmisaka
453*437bfbebSnyanmisaka if (mpp->mDisableThread) {
454*437bfbebSnyanmisaka mpp_err_f("no thread decoding case MUST use mpi_decode interface\n");
455*437bfbebSnyanmisaka return ret;
456*437bfbebSnyanmisaka }
457*437bfbebSnyanmisaka
458*437bfbebSnyanmisaka if (mpp->mExtraPacket) {
459*437bfbebSnyanmisaka MppPacket extra = mpp->mExtraPacket;
460*437bfbebSnyanmisaka
461*437bfbebSnyanmisaka mpp->mExtraPacket = NULL;
462*437bfbebSnyanmisaka mpp_put_packet(mpp, extra);
463*437bfbebSnyanmisaka }
464*437bfbebSnyanmisaka
465*437bfbebSnyanmisaka /* non-jpeg mode - reserve extra task for incoming eos packet */
466*437bfbebSnyanmisaka if (mpp->mInputTaskCount > 1) {
467*437bfbebSnyanmisaka if (!mpp->mEosTask) {
468*437bfbebSnyanmisaka /* handle eos packet on block mode */
469*437bfbebSnyanmisaka ret = mpp_poll(mpp, MPP_PORT_INPUT, MPP_POLL_BLOCK);
470*437bfbebSnyanmisaka if (ret < 0)
471*437bfbebSnyanmisaka goto RET;
472*437bfbebSnyanmisaka
473*437bfbebSnyanmisaka mpp_dequeue(mpp, MPP_PORT_INPUT, &mpp->mEosTask);
474*437bfbebSnyanmisaka if (NULL == mpp->mEosTask) {
475*437bfbebSnyanmisaka mpp_err_f("fail to reserve eos task\n");
476*437bfbebSnyanmisaka ret = MPP_NOK;
477*437bfbebSnyanmisaka goto RET;
478*437bfbebSnyanmisaka }
479*437bfbebSnyanmisaka }
480*437bfbebSnyanmisaka
481*437bfbebSnyanmisaka if (mpp_packet_get_eos(packet)) {
482*437bfbebSnyanmisaka mpp_assert(mpp->mEosTask);
483*437bfbebSnyanmisaka task_dequeue = mpp->mEosTask;
484*437bfbebSnyanmisaka mpp->mEosTask = NULL;
485*437bfbebSnyanmisaka }
486*437bfbebSnyanmisaka }
487*437bfbebSnyanmisaka
488*437bfbebSnyanmisaka /* Use reserved task to send eos packet */
489*437bfbebSnyanmisaka if (mpp->mInputTask && !task_dequeue) {
490*437bfbebSnyanmisaka task_dequeue = mpp->mInputTask;
491*437bfbebSnyanmisaka mpp->mInputTask = NULL;
492*437bfbebSnyanmisaka }
493*437bfbebSnyanmisaka
494*437bfbebSnyanmisaka if (NULL == task_dequeue) {
495*437bfbebSnyanmisaka ret = mpp_poll(mpp, MPP_PORT_INPUT, timeout);
496*437bfbebSnyanmisaka if (ret < 0) {
497*437bfbebSnyanmisaka ret = MPP_ERR_BUFFER_FULL;
498*437bfbebSnyanmisaka goto RET;
499*437bfbebSnyanmisaka }
500*437bfbebSnyanmisaka
501*437bfbebSnyanmisaka /* do not pull here to avoid block wait */
502*437bfbebSnyanmisaka mpp_dequeue(mpp, MPP_PORT_INPUT, &task_dequeue);
503*437bfbebSnyanmisaka if (NULL == task_dequeue) {
504*437bfbebSnyanmisaka mpp_err_f("fail to get task on poll ret %d\n", ret);
505*437bfbebSnyanmisaka ret = MPP_NOK;
506*437bfbebSnyanmisaka goto RET;
507*437bfbebSnyanmisaka }
508*437bfbebSnyanmisaka }
509*437bfbebSnyanmisaka
510*437bfbebSnyanmisaka if (NULL == mpp_packet_get_buffer(packet)) {
511*437bfbebSnyanmisaka /* packet copy path */
512*437bfbebSnyanmisaka MppPacket pkt_in = NULL;
513*437bfbebSnyanmisaka
514*437bfbebSnyanmisaka mpp_packet_copy_init(&pkt_in, packet);
515*437bfbebSnyanmisaka mpp_packet_set_length(packet, 0);
516*437bfbebSnyanmisaka pkt_copy = 1;
517*437bfbebSnyanmisaka packet = pkt_in;
518*437bfbebSnyanmisaka ret = MPP_OK;
519*437bfbebSnyanmisaka } else {
520*437bfbebSnyanmisaka /* packet zero copy path */
521*437bfbebSnyanmisaka timeout = MPP_POLL_BLOCK;
522*437bfbebSnyanmisaka ret = MPP_OK;
523*437bfbebSnyanmisaka }
524*437bfbebSnyanmisaka
525*437bfbebSnyanmisaka /* setup task */
526*437bfbebSnyanmisaka ret = mpp_task_meta_set_packet(task_dequeue, KEY_INPUT_PACKET, packet);
527*437bfbebSnyanmisaka if (ret) {
528*437bfbebSnyanmisaka mpp_err_f("set input frame to task ret %d\n", ret);
529*437bfbebSnyanmisaka /* keep current task for next */
530*437bfbebSnyanmisaka mpp->mInputTask = task_dequeue;
531*437bfbebSnyanmisaka goto RET;
532*437bfbebSnyanmisaka }
533*437bfbebSnyanmisaka
534*437bfbebSnyanmisaka mpp_ops_dec_put_pkt(mpp->mDump, packet);
535*437bfbebSnyanmisaka
536*437bfbebSnyanmisaka /* enqueue valid task to decoder */
537*437bfbebSnyanmisaka ret = mpp_enqueue(mpp, MPP_PORT_INPUT, task_dequeue);
538*437bfbebSnyanmisaka if (ret) {
539*437bfbebSnyanmisaka mpp_err_f("enqueue ret %d\n", ret);
540*437bfbebSnyanmisaka goto RET;
541*437bfbebSnyanmisaka }
542*437bfbebSnyanmisaka
543*437bfbebSnyanmisaka mpp->mPacketPutCount++;
544*437bfbebSnyanmisaka
545*437bfbebSnyanmisaka if (timeout && !pkt_copy)
546*437bfbebSnyanmisaka mpp_poll(mpp, MPP_PORT_INPUT, timeout);
547*437bfbebSnyanmisaka
548*437bfbebSnyanmisaka RET:
549*437bfbebSnyanmisaka /* wait enqueued task finished */
550*437bfbebSnyanmisaka if (NULL == mpp->mInputTask) {
551*437bfbebSnyanmisaka MPP_RET cnt = mpp_poll(mpp, MPP_PORT_INPUT, MPP_POLL_NON_BLOCK);
552*437bfbebSnyanmisaka /* reserve one task for eos block mode */
553*437bfbebSnyanmisaka if (cnt >= 0) {
554*437bfbebSnyanmisaka mpp_dequeue(mpp, MPP_PORT_INPUT, &mpp->mInputTask);
555*437bfbebSnyanmisaka mpp_assert(mpp->mInputTask);
556*437bfbebSnyanmisaka }
557*437bfbebSnyanmisaka }
558*437bfbebSnyanmisaka
559*437bfbebSnyanmisaka return ret;
560*437bfbebSnyanmisaka }
561*437bfbebSnyanmisaka
mpp_get_frame(Mpp * mpp,MppFrame * frame)562*437bfbebSnyanmisaka MPP_RET mpp_get_frame(Mpp *mpp, MppFrame *frame)
563*437bfbebSnyanmisaka {
564*437bfbebSnyanmisaka MppFrame frm = NULL;
565*437bfbebSnyanmisaka
566*437bfbebSnyanmisaka if (!mpp) {
567*437bfbebSnyanmisaka mpp_err_f("invalid input mpp pointer\n");
568*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
569*437bfbebSnyanmisaka }
570*437bfbebSnyanmisaka
571*437bfbebSnyanmisaka if (!mpp->mInitDone)
572*437bfbebSnyanmisaka return MPP_ERR_INIT;
573*437bfbebSnyanmisaka
574*437bfbebSnyanmisaka mpp_mutex_cond_lock(&mpp->mFrmOut->cond_lock);
575*437bfbebSnyanmisaka
576*437bfbebSnyanmisaka if (0 == mpp_list_size(mpp->mFrmOut)) {
577*437bfbebSnyanmisaka if (mpp->mOutputTimeout) {
578*437bfbebSnyanmisaka if (mpp->mOutputTimeout < 0) {
579*437bfbebSnyanmisaka /* block wait */
580*437bfbebSnyanmisaka mpp_list_wait(mpp->mFrmOut);
581*437bfbebSnyanmisaka } else {
582*437bfbebSnyanmisaka RK_S32 ret = mpp_list_wait_timed(mpp->mFrmOut, mpp->mOutputTimeout);
583*437bfbebSnyanmisaka if (ret) {
584*437bfbebSnyanmisaka if (ret == ETIMEDOUT) {
585*437bfbebSnyanmisaka mpp_mutex_cond_unlock(&mpp->mFrmOut->cond_lock);
586*437bfbebSnyanmisaka return MPP_ERR_TIMEOUT;
587*437bfbebSnyanmisaka } else {
588*437bfbebSnyanmisaka mpp_mutex_cond_unlock(&mpp->mFrmOut->cond_lock);
589*437bfbebSnyanmisaka return MPP_NOK;
590*437bfbebSnyanmisaka }
591*437bfbebSnyanmisaka }
592*437bfbebSnyanmisaka }
593*437bfbebSnyanmisaka }
594*437bfbebSnyanmisaka }
595*437bfbebSnyanmisaka
596*437bfbebSnyanmisaka if (mpp_list_size(mpp->mFrmOut)) {
597*437bfbebSnyanmisaka MppBuffer buffer;
598*437bfbebSnyanmisaka
599*437bfbebSnyanmisaka mpp_list_del_at_head(mpp->mFrmOut, &frm, sizeof(frm));
600*437bfbebSnyanmisaka mpp->mFrameGetCount++;
601*437bfbebSnyanmisaka mpp_notify_flag(mpp, MPP_OUTPUT_DEQUEUE);
602*437bfbebSnyanmisaka
603*437bfbebSnyanmisaka buffer = mpp_frame_get_buffer(frm);
604*437bfbebSnyanmisaka if (buffer)
605*437bfbebSnyanmisaka mpp_buffer_sync_ro_begin(buffer);
606*437bfbebSnyanmisaka } else {
607*437bfbebSnyanmisaka // NOTE: Add signal here is not efficient
608*437bfbebSnyanmisaka // This is for fix bug of stucking on decoder parser thread
609*437bfbebSnyanmisaka // When decoder parser thread is block by info change and enter waiting.
610*437bfbebSnyanmisaka // There is no way to wake up parser thread to continue decoding.
611*437bfbebSnyanmisaka // The put_packet only signal sem on may be it better to use sem on info
612*437bfbebSnyanmisaka // change too.
613*437bfbebSnyanmisaka mpp_mutex_cond_lock(&mpp->mPktIn->cond_lock);
614*437bfbebSnyanmisaka if (mpp_list_size(mpp->mPktIn))
615*437bfbebSnyanmisaka mpp_notify_flag(mpp, MPP_INPUT_ENQUEUE);
616*437bfbebSnyanmisaka mpp_mutex_cond_unlock(&mpp->mPktIn->cond_lock);
617*437bfbebSnyanmisaka }
618*437bfbebSnyanmisaka
619*437bfbebSnyanmisaka *frame = frm;
620*437bfbebSnyanmisaka
621*437bfbebSnyanmisaka // dump output
622*437bfbebSnyanmisaka mpp_ops_dec_get_frm(mpp->mDump, frm);
623*437bfbebSnyanmisaka mpp_mutex_cond_unlock(&mpp->mFrmOut->cond_lock);
624*437bfbebSnyanmisaka
625*437bfbebSnyanmisaka return MPP_OK;
626*437bfbebSnyanmisaka }
627*437bfbebSnyanmisaka
mpp_get_frame_noblock(Mpp * mpp,MppFrame * frame)628*437bfbebSnyanmisaka MPP_RET mpp_get_frame_noblock(Mpp *mpp, MppFrame *frame)
629*437bfbebSnyanmisaka {
630*437bfbebSnyanmisaka MppFrame first = NULL;
631*437bfbebSnyanmisaka
632*437bfbebSnyanmisaka if (!mpp) {
633*437bfbebSnyanmisaka mpp_err_f("invalid input mpp pointer\n");
634*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
635*437bfbebSnyanmisaka }
636*437bfbebSnyanmisaka
637*437bfbebSnyanmisaka if (!mpp->mInitDone)
638*437bfbebSnyanmisaka return MPP_ERR_INIT;
639*437bfbebSnyanmisaka
640*437bfbebSnyanmisaka mpp_mutex_cond_lock(&mpp->mFrmOut->cond_lock);
641*437bfbebSnyanmisaka if (mpp_list_size(mpp->mFrmOut)) {
642*437bfbebSnyanmisaka mpp_list_del_at_head(mpp->mFrmOut, &first, sizeof(first));
643*437bfbebSnyanmisaka mpp_buffer_sync_ro_begin(mpp_frame_get_buffer(first));
644*437bfbebSnyanmisaka mpp->mFrameGetCount++;
645*437bfbebSnyanmisaka }
646*437bfbebSnyanmisaka mpp_mutex_cond_unlock(&mpp->mFrmOut->cond_lock);
647*437bfbebSnyanmisaka *frame = first;
648*437bfbebSnyanmisaka
649*437bfbebSnyanmisaka return MPP_OK;
650*437bfbebSnyanmisaka }
651*437bfbebSnyanmisaka
mpp_decode(Mpp * mpp,MppPacket packet,MppFrame * frame)652*437bfbebSnyanmisaka MPP_RET mpp_decode(Mpp *mpp, MppPacket packet, MppFrame *frame)
653*437bfbebSnyanmisaka {
654*437bfbebSnyanmisaka RK_U32 pkt_done = 0;
655*437bfbebSnyanmisaka RK_S32 frm_rdy = 0;
656*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
657*437bfbebSnyanmisaka
658*437bfbebSnyanmisaka if (!mpp) {
659*437bfbebSnyanmisaka mpp_err_f("invalid input mpp pointer\n");
660*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
661*437bfbebSnyanmisaka }
662*437bfbebSnyanmisaka
663*437bfbebSnyanmisaka if (!mpp->mDec)
664*437bfbebSnyanmisaka return MPP_NOK;
665*437bfbebSnyanmisaka
666*437bfbebSnyanmisaka if (!mpp->mInitDone)
667*437bfbebSnyanmisaka return MPP_ERR_INIT;
668*437bfbebSnyanmisaka
669*437bfbebSnyanmisaka /*
670*437bfbebSnyanmisaka * If there is frame to return get the frame first
671*437bfbebSnyanmisaka * But if the output mode is block then we need to send packet first
672*437bfbebSnyanmisaka */
673*437bfbebSnyanmisaka if (!mpp->mOutputTimeout) {
674*437bfbebSnyanmisaka mpp_mutex_cond_lock(&mpp->mFrmOut->cond_lock);
675*437bfbebSnyanmisaka if (mpp_list_size(mpp->mFrmOut)) {
676*437bfbebSnyanmisaka MppBuffer buffer;
677*437bfbebSnyanmisaka
678*437bfbebSnyanmisaka mpp_list_del_at_head(mpp->mFrmOut, frame, sizeof(*frame));
679*437bfbebSnyanmisaka buffer = mpp_frame_get_buffer(*frame);
680*437bfbebSnyanmisaka if (buffer)
681*437bfbebSnyanmisaka mpp_buffer_sync_ro_begin(buffer);
682*437bfbebSnyanmisaka mpp->mFrameGetCount++;
683*437bfbebSnyanmisaka mpp_mutex_cond_unlock(&mpp->mFrmOut->cond_lock);
684*437bfbebSnyanmisaka return MPP_OK;
685*437bfbebSnyanmisaka }
686*437bfbebSnyanmisaka mpp_mutex_cond_unlock(&mpp->mFrmOut->cond_lock);
687*437bfbebSnyanmisaka }
688*437bfbebSnyanmisaka
689*437bfbebSnyanmisaka do {
690*437bfbebSnyanmisaka if (!pkt_done)
691*437bfbebSnyanmisaka ret = mpp_dec_decode(mpp->mDec, packet);
692*437bfbebSnyanmisaka
693*437bfbebSnyanmisaka /* check input packet finished or not */
694*437bfbebSnyanmisaka if (!packet || !mpp_packet_get_length(packet))
695*437bfbebSnyanmisaka pkt_done = 1;
696*437bfbebSnyanmisaka
697*437bfbebSnyanmisaka /* always try getting frame */
698*437bfbebSnyanmisaka mpp_mutex_cond_lock(&mpp->mFrmOut->cond_lock);
699*437bfbebSnyanmisaka if (mpp_list_size(mpp->mFrmOut)) {
700*437bfbebSnyanmisaka MppBuffer buffer;
701*437bfbebSnyanmisaka
702*437bfbebSnyanmisaka mpp_list_del_at_head(mpp->mFrmOut, frame, sizeof(*frame));
703*437bfbebSnyanmisaka buffer = mpp_frame_get_buffer(*frame);
704*437bfbebSnyanmisaka if (buffer)
705*437bfbebSnyanmisaka mpp_buffer_sync_ro_begin(buffer);
706*437bfbebSnyanmisaka mpp->mFrameGetCount++;
707*437bfbebSnyanmisaka frm_rdy = 1;
708*437bfbebSnyanmisaka }
709*437bfbebSnyanmisaka mpp_mutex_cond_unlock(&mpp->mFrmOut->cond_lock);
710*437bfbebSnyanmisaka
711*437bfbebSnyanmisaka /* return on flow error */
712*437bfbebSnyanmisaka if (ret < 0)
713*437bfbebSnyanmisaka break;
714*437bfbebSnyanmisaka
715*437bfbebSnyanmisaka /* return on output frame is ready */
716*437bfbebSnyanmisaka if (frm_rdy) {
717*437bfbebSnyanmisaka mpp_assert(ret > 0);
718*437bfbebSnyanmisaka ret = MPP_OK;
719*437bfbebSnyanmisaka break;
720*437bfbebSnyanmisaka }
721*437bfbebSnyanmisaka
722*437bfbebSnyanmisaka /* return when packet is send and it is a non-block call */
723*437bfbebSnyanmisaka if (pkt_done) {
724*437bfbebSnyanmisaka ret = MPP_OK;
725*437bfbebSnyanmisaka break;
726*437bfbebSnyanmisaka }
727*437bfbebSnyanmisaka
728*437bfbebSnyanmisaka /* otherwise continue decoding and getting frame */
729*437bfbebSnyanmisaka } while (1);
730*437bfbebSnyanmisaka
731*437bfbebSnyanmisaka return ret;
732*437bfbebSnyanmisaka }
733*437bfbebSnyanmisaka
mpp_put_frame(Mpp * mpp,MppFrame frame)734*437bfbebSnyanmisaka MPP_RET mpp_put_frame(Mpp *mpp, MppFrame frame)
735*437bfbebSnyanmisaka {
736*437bfbebSnyanmisaka if (!mpp) {
737*437bfbebSnyanmisaka mpp_err_f("invalid input mpp pointer\n");
738*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
739*437bfbebSnyanmisaka }
740*437bfbebSnyanmisaka
741*437bfbebSnyanmisaka if (!mpp->mInitDone)
742*437bfbebSnyanmisaka return MPP_ERR_INIT;
743*437bfbebSnyanmisaka
744*437bfbebSnyanmisaka mpp_dbg_pts("%p input frame pts %lld\n", mpp, mpp_frame_get_pts(frame));
745*437bfbebSnyanmisaka
746*437bfbebSnyanmisaka if (mpp->mKmpp && mpp->mKmpp->mApi && mpp->mKmpp->mApi->put_frame)
747*437bfbebSnyanmisaka return mpp->mKmpp->mApi->put_frame(mpp->mKmpp, frame);
748*437bfbebSnyanmisaka
749*437bfbebSnyanmisaka if (mpp->mInputTimeout == MPP_POLL_NON_BLOCK) {
750*437bfbebSnyanmisaka mpp_set_io_mode(mpp, MPP_IO_MODE_NORMAL);
751*437bfbebSnyanmisaka return mpp_put_frame_async(mpp, frame);
752*437bfbebSnyanmisaka }
753*437bfbebSnyanmisaka
754*437bfbebSnyanmisaka MPP_RET ret = MPP_NOK;
755*437bfbebSnyanmisaka MppStopwatch stopwatch = NULL;
756*437bfbebSnyanmisaka
757*437bfbebSnyanmisaka if (mpp_debug & MPP_DBG_TIMING) {
758*437bfbebSnyanmisaka mpp_frame_set_stopwatch_enable(frame, 1);
759*437bfbebSnyanmisaka stopwatch = mpp_frame_get_stopwatch(frame);
760*437bfbebSnyanmisaka }
761*437bfbebSnyanmisaka
762*437bfbebSnyanmisaka mpp_stopwatch_record(stopwatch, NULL);
763*437bfbebSnyanmisaka mpp_stopwatch_record(stopwatch, "put frame start");
764*437bfbebSnyanmisaka
765*437bfbebSnyanmisaka if (mpp->mInputTask == NULL) {
766*437bfbebSnyanmisaka mpp_stopwatch_record(stopwatch, "input port user poll");
767*437bfbebSnyanmisaka /* poll input port for valid task */
768*437bfbebSnyanmisaka ret = mpp_poll(mpp, MPP_PORT_INPUT, mpp->mInputTimeout);
769*437bfbebSnyanmisaka if (ret < 0) {
770*437bfbebSnyanmisaka if (mpp->mInputTimeout)
771*437bfbebSnyanmisaka mpp_log_f("poll on set timeout %d ret %d\n", mpp->mInputTimeout, ret);
772*437bfbebSnyanmisaka goto RET;
773*437bfbebSnyanmisaka }
774*437bfbebSnyanmisaka
775*437bfbebSnyanmisaka /* dequeue task for setup */
776*437bfbebSnyanmisaka mpp_stopwatch_record(stopwatch, "input port user dequeue");
777*437bfbebSnyanmisaka ret = mpp_dequeue(mpp, MPP_PORT_INPUT, &mpp->mInputTask);
778*437bfbebSnyanmisaka if (ret || NULL == mpp->mInputTask) {
779*437bfbebSnyanmisaka mpp_log_f("dequeue on set ret %d task %p\n", ret, mpp->mInputTask);
780*437bfbebSnyanmisaka goto RET;
781*437bfbebSnyanmisaka }
782*437bfbebSnyanmisaka }
783*437bfbebSnyanmisaka
784*437bfbebSnyanmisaka mpp_assert(mpp->mInputTask);
785*437bfbebSnyanmisaka
786*437bfbebSnyanmisaka /* setup task */
787*437bfbebSnyanmisaka ret = mpp_task_meta_set_frame(mpp->mInputTask, KEY_INPUT_FRAME, frame);
788*437bfbebSnyanmisaka if (ret) {
789*437bfbebSnyanmisaka mpp_log_f("set input frame to task ret %d\n", ret);
790*437bfbebSnyanmisaka goto RET;
791*437bfbebSnyanmisaka }
792*437bfbebSnyanmisaka
793*437bfbebSnyanmisaka if (mpp_frame_has_meta(frame)) {
794*437bfbebSnyanmisaka MppMeta meta = mpp_frame_get_meta(frame);
795*437bfbebSnyanmisaka MppPacket packet = NULL;
796*437bfbebSnyanmisaka MppBuffer md_info_buf = NULL;
797*437bfbebSnyanmisaka
798*437bfbebSnyanmisaka mpp_meta_get_packet(meta, KEY_OUTPUT_PACKET, &packet);
799*437bfbebSnyanmisaka if (packet) {
800*437bfbebSnyanmisaka ret = mpp_task_meta_set_packet(mpp->mInputTask, KEY_OUTPUT_PACKET, packet);
801*437bfbebSnyanmisaka if (ret) {
802*437bfbebSnyanmisaka mpp_log_f("set output packet to task ret %d\n", ret);
803*437bfbebSnyanmisaka goto RET;
804*437bfbebSnyanmisaka }
805*437bfbebSnyanmisaka }
806*437bfbebSnyanmisaka
807*437bfbebSnyanmisaka mpp_meta_get_buffer(meta, KEY_MOTION_INFO, &md_info_buf);
808*437bfbebSnyanmisaka if (md_info_buf) {
809*437bfbebSnyanmisaka ret = mpp_task_meta_set_buffer(mpp->mInputTask, KEY_MOTION_INFO, md_info_buf);
810*437bfbebSnyanmisaka if (ret) {
811*437bfbebSnyanmisaka mpp_log_f("set output motion dection info ret %d\n", ret);
812*437bfbebSnyanmisaka goto RET;
813*437bfbebSnyanmisaka }
814*437bfbebSnyanmisaka }
815*437bfbebSnyanmisaka }
816*437bfbebSnyanmisaka
817*437bfbebSnyanmisaka // dump input
818*437bfbebSnyanmisaka mpp_ops_enc_put_frm(mpp->mDump, frame);
819*437bfbebSnyanmisaka
820*437bfbebSnyanmisaka /* enqueue valid task to encoder */
821*437bfbebSnyanmisaka mpp_stopwatch_record(stopwatch, "input port user enqueue");
822*437bfbebSnyanmisaka ret = mpp_enqueue(mpp, MPP_PORT_INPUT, mpp->mInputTask);
823*437bfbebSnyanmisaka if (ret) {
824*437bfbebSnyanmisaka mpp_log_f("enqueue ret %d\n", ret);
825*437bfbebSnyanmisaka goto RET;
826*437bfbebSnyanmisaka }
827*437bfbebSnyanmisaka
828*437bfbebSnyanmisaka mpp->mInputTask = NULL;
829*437bfbebSnyanmisaka /* wait enqueued task finished */
830*437bfbebSnyanmisaka mpp_stopwatch_record(stopwatch, "input port user poll");
831*437bfbebSnyanmisaka ret = mpp_poll(mpp, MPP_PORT_INPUT, mpp->mInputTimeout);
832*437bfbebSnyanmisaka if (ret < 0) {
833*437bfbebSnyanmisaka if (mpp->mInputTimeout)
834*437bfbebSnyanmisaka mpp_log_f("poll on get timeout %d ret %d\n", mpp->mInputTimeout, ret);
835*437bfbebSnyanmisaka goto RET;
836*437bfbebSnyanmisaka }
837*437bfbebSnyanmisaka
838*437bfbebSnyanmisaka /* get previous enqueued task back */
839*437bfbebSnyanmisaka mpp_stopwatch_record(stopwatch, "input port user dequeue");
840*437bfbebSnyanmisaka ret = mpp_dequeue(mpp, MPP_PORT_INPUT, &mpp->mInputTask);
841*437bfbebSnyanmisaka if (ret) {
842*437bfbebSnyanmisaka mpp_log_f("dequeue on get ret %d\n", ret);
843*437bfbebSnyanmisaka goto RET;
844*437bfbebSnyanmisaka }
845*437bfbebSnyanmisaka
846*437bfbebSnyanmisaka mpp_assert(mpp->mInputTask);
847*437bfbebSnyanmisaka if (mpp->mInputTask) {
848*437bfbebSnyanmisaka MppFrame frm_out = NULL;
849*437bfbebSnyanmisaka
850*437bfbebSnyanmisaka mpp_task_meta_get_frame(mpp->mInputTask, KEY_INPUT_FRAME, &frm_out);
851*437bfbebSnyanmisaka mpp_assert(frm_out == frame);
852*437bfbebSnyanmisaka }
853*437bfbebSnyanmisaka
854*437bfbebSnyanmisaka RET:
855*437bfbebSnyanmisaka mpp_stopwatch_record(stopwatch, "put_frame finish");
856*437bfbebSnyanmisaka mpp_frame_set_stopwatch_enable(frame, 0);
857*437bfbebSnyanmisaka return ret;
858*437bfbebSnyanmisaka }
859*437bfbebSnyanmisaka
mpp_get_packet(Mpp * mpp,MppPacket * packet)860*437bfbebSnyanmisaka MPP_RET mpp_get_packet(Mpp *mpp, MppPacket *packet)
861*437bfbebSnyanmisaka {
862*437bfbebSnyanmisaka MppPacket pkt = NULL;
863*437bfbebSnyanmisaka
864*437bfbebSnyanmisaka if (!mpp) {
865*437bfbebSnyanmisaka mpp_err_f("invalid input mpp pointer\n");
866*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
867*437bfbebSnyanmisaka }
868*437bfbebSnyanmisaka
869*437bfbebSnyanmisaka if (!mpp->mInitDone)
870*437bfbebSnyanmisaka return MPP_ERR_INIT;
871*437bfbebSnyanmisaka
872*437bfbebSnyanmisaka if (mpp->mKmpp && mpp->mKmpp->mApi && mpp->mKmpp->mApi->get_packet)
873*437bfbebSnyanmisaka return mpp->mKmpp->mApi->get_packet(mpp->mKmpp, packet);
874*437bfbebSnyanmisaka
875*437bfbebSnyanmisaka if (mpp->mInputTimeout == MPP_POLL_NON_BLOCK) {
876*437bfbebSnyanmisaka mpp_set_io_mode(mpp, MPP_IO_MODE_NORMAL);
877*437bfbebSnyanmisaka return mpp_get_packet_async(mpp, packet);
878*437bfbebSnyanmisaka }
879*437bfbebSnyanmisaka
880*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
881*437bfbebSnyanmisaka MppTask task = NULL;
882*437bfbebSnyanmisaka
883*437bfbebSnyanmisaka ret = mpp_poll(mpp, MPP_PORT_OUTPUT, mpp->mOutputTimeout);
884*437bfbebSnyanmisaka if (ret < 0) {
885*437bfbebSnyanmisaka // NOTE: Do not treat poll failure as error. Just clear output
886*437bfbebSnyanmisaka ret = MPP_OK;
887*437bfbebSnyanmisaka *packet = NULL;
888*437bfbebSnyanmisaka goto RET;
889*437bfbebSnyanmisaka }
890*437bfbebSnyanmisaka
891*437bfbebSnyanmisaka ret = mpp_dequeue(mpp, MPP_PORT_OUTPUT, &task);
892*437bfbebSnyanmisaka if (ret || NULL == task) {
893*437bfbebSnyanmisaka mpp_log_f("dequeue on get ret %d task %p\n", ret, task);
894*437bfbebSnyanmisaka goto RET;
895*437bfbebSnyanmisaka }
896*437bfbebSnyanmisaka
897*437bfbebSnyanmisaka mpp_assert(task);
898*437bfbebSnyanmisaka
899*437bfbebSnyanmisaka ret = mpp_task_meta_get_packet(task, KEY_OUTPUT_PACKET, packet);
900*437bfbebSnyanmisaka if (ret) {
901*437bfbebSnyanmisaka mpp_log_f("get output packet from task ret %d\n", ret);
902*437bfbebSnyanmisaka goto RET;
903*437bfbebSnyanmisaka }
904*437bfbebSnyanmisaka
905*437bfbebSnyanmisaka pkt = *packet;
906*437bfbebSnyanmisaka if (!pkt) {
907*437bfbebSnyanmisaka mpp_log_f("get invalid task without output packet\n");
908*437bfbebSnyanmisaka } else {
909*437bfbebSnyanmisaka MppPacketImpl *impl = (MppPacketImpl *)pkt;
910*437bfbebSnyanmisaka MppBuffer buf = impl->buffer;
911*437bfbebSnyanmisaka
912*437bfbebSnyanmisaka if (buf) {
913*437bfbebSnyanmisaka RK_U32 offset = (RK_U32)((char *)impl->pos - (char *)impl->data);
914*437bfbebSnyanmisaka
915*437bfbebSnyanmisaka mpp_buffer_sync_ro_partial_begin(buf, offset, impl->length);
916*437bfbebSnyanmisaka }
917*437bfbebSnyanmisaka
918*437bfbebSnyanmisaka mpp_dbg_pts("%p output packet pts %lld\n", mpp, impl->pts);
919*437bfbebSnyanmisaka }
920*437bfbebSnyanmisaka
921*437bfbebSnyanmisaka // dump output
922*437bfbebSnyanmisaka mpp_ops_enc_get_pkt(mpp->mDump, pkt);
923*437bfbebSnyanmisaka
924*437bfbebSnyanmisaka ret = mpp_enqueue(mpp, MPP_PORT_OUTPUT, task);
925*437bfbebSnyanmisaka if (ret)
926*437bfbebSnyanmisaka mpp_log_f("enqueue on set ret %d\n", ret);
927*437bfbebSnyanmisaka RET:
928*437bfbebSnyanmisaka
929*437bfbebSnyanmisaka return ret;
930*437bfbebSnyanmisaka }
931*437bfbebSnyanmisaka
mpp_put_frame_async(Mpp * mpp,MppFrame frame)932*437bfbebSnyanmisaka MPP_RET mpp_put_frame_async(Mpp *mpp, MppFrame frame)
933*437bfbebSnyanmisaka {
934*437bfbebSnyanmisaka if (!mpp) {
935*437bfbebSnyanmisaka mpp_err_f("invalid input mpp pointer\n");
936*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
937*437bfbebSnyanmisaka }
938*437bfbebSnyanmisaka
939*437bfbebSnyanmisaka if (NULL == mpp->mFrmIn)
940*437bfbebSnyanmisaka return MPP_NOK;
941*437bfbebSnyanmisaka
942*437bfbebSnyanmisaka if (mpp_mutex_cond_trylock(&mpp->mFrmIn->cond_lock))
943*437bfbebSnyanmisaka return MPP_NOK;
944*437bfbebSnyanmisaka
945*437bfbebSnyanmisaka /* NOTE: the max input queue length is 2 */
946*437bfbebSnyanmisaka if (mpp_list_wait_le(mpp->mFrmIn, 10, 1)) {
947*437bfbebSnyanmisaka mpp_mutex_cond_unlock(&mpp->mFrmIn->cond_lock);
948*437bfbebSnyanmisaka return MPP_NOK;
949*437bfbebSnyanmisaka }
950*437bfbebSnyanmisaka
951*437bfbebSnyanmisaka mpp_list_add_at_tail(mpp->mFrmIn, &frame, sizeof(frame));
952*437bfbebSnyanmisaka mpp->mFramePutCount++;
953*437bfbebSnyanmisaka
954*437bfbebSnyanmisaka mpp_notify_flag(mpp, MPP_INPUT_ENQUEUE);
955*437bfbebSnyanmisaka mpp_mutex_cond_unlock(&mpp->mFrmIn->cond_lock);
956*437bfbebSnyanmisaka
957*437bfbebSnyanmisaka return MPP_OK;
958*437bfbebSnyanmisaka }
959*437bfbebSnyanmisaka
mpp_get_packet_async(Mpp * mpp,MppPacket * packet)960*437bfbebSnyanmisaka MPP_RET mpp_get_packet_async(Mpp *mpp, MppPacket *packet)
961*437bfbebSnyanmisaka {
962*437bfbebSnyanmisaka if (!mpp) {
963*437bfbebSnyanmisaka mpp_err_f("invalid input mpp pointer\n");
964*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
965*437bfbebSnyanmisaka }
966*437bfbebSnyanmisaka
967*437bfbebSnyanmisaka mpp_mutex_cond_lock(&mpp->mPktOut->cond_lock);
968*437bfbebSnyanmisaka *packet = NULL;
969*437bfbebSnyanmisaka if (0 == mpp_list_size(mpp->mPktOut)) {
970*437bfbebSnyanmisaka if (mpp->mOutputTimeout) {
971*437bfbebSnyanmisaka if (mpp->mOutputTimeout < 0) {
972*437bfbebSnyanmisaka /* block wait */
973*437bfbebSnyanmisaka mpp_list_wait(mpp->mPktOut);
974*437bfbebSnyanmisaka } else {
975*437bfbebSnyanmisaka RK_S32 ret = mpp_list_wait_timed(mpp->mPktOut, mpp->mOutputTimeout);
976*437bfbebSnyanmisaka
977*437bfbebSnyanmisaka if (ret) {
978*437bfbebSnyanmisaka if (ret == ETIMEDOUT) {
979*437bfbebSnyanmisaka mpp_mutex_cond_unlock(&mpp->mPktOut->cond_lock);
980*437bfbebSnyanmisaka return MPP_ERR_TIMEOUT;
981*437bfbebSnyanmisaka } else {
982*437bfbebSnyanmisaka mpp_mutex_cond_unlock(&mpp->mPktOut->cond_lock);
983*437bfbebSnyanmisaka return MPP_NOK;
984*437bfbebSnyanmisaka }
985*437bfbebSnyanmisaka }
986*437bfbebSnyanmisaka }
987*437bfbebSnyanmisaka } else {
988*437bfbebSnyanmisaka /* NOTE: in non-block mode the sleep is to avoid user's dead loop */
989*437bfbebSnyanmisaka msleep(1);
990*437bfbebSnyanmisaka }
991*437bfbebSnyanmisaka }
992*437bfbebSnyanmisaka
993*437bfbebSnyanmisaka if (mpp_list_size(mpp->mPktOut)) {
994*437bfbebSnyanmisaka MppPacket pkt = NULL;
995*437bfbebSnyanmisaka MppPacketImpl *impl = NULL;
996*437bfbebSnyanmisaka RK_U32 offset;
997*437bfbebSnyanmisaka
998*437bfbebSnyanmisaka mpp_list_del_at_head(mpp->mPktOut, &pkt, sizeof(pkt));
999*437bfbebSnyanmisaka mpp->mPacketGetCount++;
1000*437bfbebSnyanmisaka mpp_notify_flag(mpp, MPP_OUTPUT_DEQUEUE);
1001*437bfbebSnyanmisaka
1002*437bfbebSnyanmisaka *packet = pkt;
1003*437bfbebSnyanmisaka
1004*437bfbebSnyanmisaka impl = (MppPacketImpl *)pkt;
1005*437bfbebSnyanmisaka if (impl->buffer) {
1006*437bfbebSnyanmisaka offset = (RK_U32)((char *)impl->pos - (char *)impl->data);
1007*437bfbebSnyanmisaka mpp_buffer_sync_ro_partial_begin(impl->buffer, offset, impl->length);
1008*437bfbebSnyanmisaka }
1009*437bfbebSnyanmisaka } else {
1010*437bfbebSnyanmisaka mpp_mutex_cond_lock(&mpp->mFrmIn->cond_lock);
1011*437bfbebSnyanmisaka if (mpp_list_size(mpp->mFrmIn))
1012*437bfbebSnyanmisaka mpp_notify_flag(mpp, MPP_INPUT_ENQUEUE);
1013*437bfbebSnyanmisaka mpp_mutex_cond_unlock(&mpp->mFrmIn->cond_lock);
1014*437bfbebSnyanmisaka mpp_mutex_cond_unlock(&mpp->mPktOut->cond_lock);
1015*437bfbebSnyanmisaka
1016*437bfbebSnyanmisaka return MPP_NOK;
1017*437bfbebSnyanmisaka }
1018*437bfbebSnyanmisaka mpp_mutex_cond_unlock(&mpp->mPktOut->cond_lock);
1019*437bfbebSnyanmisaka
1020*437bfbebSnyanmisaka return MPP_OK;
1021*437bfbebSnyanmisaka }
1022*437bfbebSnyanmisaka
mpp_poll(Mpp * mpp,MppPortType type,MppPollType timeout)1023*437bfbebSnyanmisaka MPP_RET mpp_poll(Mpp *mpp, MppPortType type, MppPollType timeout)
1024*437bfbebSnyanmisaka {
1025*437bfbebSnyanmisaka MppTaskQueue port = NULL;
1026*437bfbebSnyanmisaka MPP_RET ret = MPP_NOK;
1027*437bfbebSnyanmisaka
1028*437bfbebSnyanmisaka if (!mpp) {
1029*437bfbebSnyanmisaka mpp_err_f("invalid input mpp pointer\n");
1030*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
1031*437bfbebSnyanmisaka }
1032*437bfbebSnyanmisaka
1033*437bfbebSnyanmisaka if (!mpp->mInitDone)
1034*437bfbebSnyanmisaka return MPP_ERR_INIT;
1035*437bfbebSnyanmisaka
1036*437bfbebSnyanmisaka mpp_set_io_mode(mpp, MPP_IO_MODE_TASK);
1037*437bfbebSnyanmisaka
1038*437bfbebSnyanmisaka switch (type) {
1039*437bfbebSnyanmisaka case MPP_PORT_INPUT : {
1040*437bfbebSnyanmisaka port = mpp->mUsrInPort;
1041*437bfbebSnyanmisaka } break;
1042*437bfbebSnyanmisaka case MPP_PORT_OUTPUT : {
1043*437bfbebSnyanmisaka port = mpp->mUsrOutPort;
1044*437bfbebSnyanmisaka } break;
1045*437bfbebSnyanmisaka default : {
1046*437bfbebSnyanmisaka } break;
1047*437bfbebSnyanmisaka }
1048*437bfbebSnyanmisaka
1049*437bfbebSnyanmisaka if (port)
1050*437bfbebSnyanmisaka ret = mpp_port_poll(port, timeout);
1051*437bfbebSnyanmisaka
1052*437bfbebSnyanmisaka return ret;
1053*437bfbebSnyanmisaka }
1054*437bfbebSnyanmisaka
mpp_dequeue(Mpp * mpp,MppPortType type,MppTask * task)1055*437bfbebSnyanmisaka MPP_RET mpp_dequeue(Mpp *mpp, MppPortType type, MppTask *task)
1056*437bfbebSnyanmisaka {
1057*437bfbebSnyanmisaka MppTaskQueue port = NULL;
1058*437bfbebSnyanmisaka RK_U32 notify_flag = 0;
1059*437bfbebSnyanmisaka MPP_RET ret = MPP_NOK;
1060*437bfbebSnyanmisaka
1061*437bfbebSnyanmisaka if (!mpp) {
1062*437bfbebSnyanmisaka mpp_err_f("invalid input mpp pointer\n");
1063*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
1064*437bfbebSnyanmisaka }
1065*437bfbebSnyanmisaka
1066*437bfbebSnyanmisaka if (!mpp->mInitDone)
1067*437bfbebSnyanmisaka return MPP_ERR_INIT;
1068*437bfbebSnyanmisaka
1069*437bfbebSnyanmisaka mpp_set_io_mode(mpp, MPP_IO_MODE_TASK);
1070*437bfbebSnyanmisaka
1071*437bfbebSnyanmisaka switch (type) {
1072*437bfbebSnyanmisaka case MPP_PORT_INPUT : {
1073*437bfbebSnyanmisaka port = mpp->mUsrInPort;
1074*437bfbebSnyanmisaka notify_flag = MPP_INPUT_DEQUEUE;
1075*437bfbebSnyanmisaka } break;
1076*437bfbebSnyanmisaka case MPP_PORT_OUTPUT : {
1077*437bfbebSnyanmisaka port = mpp->mUsrOutPort;
1078*437bfbebSnyanmisaka notify_flag = MPP_OUTPUT_DEQUEUE;
1079*437bfbebSnyanmisaka } break;
1080*437bfbebSnyanmisaka default : {
1081*437bfbebSnyanmisaka } break;
1082*437bfbebSnyanmisaka }
1083*437bfbebSnyanmisaka
1084*437bfbebSnyanmisaka if (port) {
1085*437bfbebSnyanmisaka ret = mpp_port_dequeue(port, task);
1086*437bfbebSnyanmisaka if (MPP_OK == ret)
1087*437bfbebSnyanmisaka mpp_notify_flag(mpp, notify_flag);
1088*437bfbebSnyanmisaka }
1089*437bfbebSnyanmisaka
1090*437bfbebSnyanmisaka return ret;
1091*437bfbebSnyanmisaka }
1092*437bfbebSnyanmisaka
mpp_enqueue(Mpp * mpp,MppPortType type,MppTask task)1093*437bfbebSnyanmisaka MPP_RET mpp_enqueue(Mpp *mpp, MppPortType type, MppTask task)
1094*437bfbebSnyanmisaka {
1095*437bfbebSnyanmisaka MppTaskQueue port = NULL;
1096*437bfbebSnyanmisaka RK_U32 notify_flag = 0;
1097*437bfbebSnyanmisaka MPP_RET ret = MPP_NOK;
1098*437bfbebSnyanmisaka
1099*437bfbebSnyanmisaka if (!mpp) {
1100*437bfbebSnyanmisaka mpp_err_f("invalid input mpp pointer\n");
1101*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
1102*437bfbebSnyanmisaka }
1103*437bfbebSnyanmisaka
1104*437bfbebSnyanmisaka if (!mpp->mInitDone)
1105*437bfbebSnyanmisaka return MPP_ERR_INIT;
1106*437bfbebSnyanmisaka
1107*437bfbebSnyanmisaka mpp_set_io_mode(mpp, MPP_IO_MODE_TASK);
1108*437bfbebSnyanmisaka
1109*437bfbebSnyanmisaka switch (type) {
1110*437bfbebSnyanmisaka case MPP_PORT_INPUT : {
1111*437bfbebSnyanmisaka port = mpp->mUsrInPort;
1112*437bfbebSnyanmisaka notify_flag = MPP_INPUT_ENQUEUE;
1113*437bfbebSnyanmisaka } break;
1114*437bfbebSnyanmisaka case MPP_PORT_OUTPUT : {
1115*437bfbebSnyanmisaka port = mpp->mUsrOutPort;
1116*437bfbebSnyanmisaka notify_flag = MPP_OUTPUT_ENQUEUE;
1117*437bfbebSnyanmisaka } break;
1118*437bfbebSnyanmisaka default : {
1119*437bfbebSnyanmisaka } break;
1120*437bfbebSnyanmisaka }
1121*437bfbebSnyanmisaka
1122*437bfbebSnyanmisaka if (port) {
1123*437bfbebSnyanmisaka ret = mpp_port_enqueue(port, task);
1124*437bfbebSnyanmisaka // if enqueue success wait up thread
1125*437bfbebSnyanmisaka if (MPP_OK == ret)
1126*437bfbebSnyanmisaka mpp_notify_flag(mpp, notify_flag);
1127*437bfbebSnyanmisaka }
1128*437bfbebSnyanmisaka
1129*437bfbebSnyanmisaka return ret;
1130*437bfbebSnyanmisaka }
1131*437bfbebSnyanmisaka
mpp_set_io_mode(Mpp * mpp,MppIoMode mode)1132*437bfbebSnyanmisaka void mpp_set_io_mode(Mpp *mpp, MppIoMode mode)
1133*437bfbebSnyanmisaka {
1134*437bfbebSnyanmisaka if (!mpp) {
1135*437bfbebSnyanmisaka mpp_err_f("invalid input mpp pointer\n");
1136*437bfbebSnyanmisaka return;
1137*437bfbebSnyanmisaka }
1138*437bfbebSnyanmisaka
1139*437bfbebSnyanmisaka mpp_assert(mode == MPP_IO_MODE_NORMAL || mode == MPP_IO_MODE_TASK);
1140*437bfbebSnyanmisaka
1141*437bfbebSnyanmisaka if (mpp->mIoMode == MPP_IO_MODE_DEFAULT)
1142*437bfbebSnyanmisaka mpp->mIoMode = mode;
1143*437bfbebSnyanmisaka else if (mpp->mIoMode != mode) {
1144*437bfbebSnyanmisaka static const char *iomode_2str[] = {
1145*437bfbebSnyanmisaka "normal",
1146*437bfbebSnyanmisaka "task queue",
1147*437bfbebSnyanmisaka };
1148*437bfbebSnyanmisaka
1149*437bfbebSnyanmisaka mpp_assert(mpp->mIoMode < MPP_IO_MODE_BUTT);
1150*437bfbebSnyanmisaka mpp_assert(mode < MPP_IO_MODE_BUTT);
1151*437bfbebSnyanmisaka mpp_err("can not reset io mode from %s to %s\n",
1152*437bfbebSnyanmisaka iomode_2str[!!mpp->mIoMode], iomode_2str[!!mode]);
1153*437bfbebSnyanmisaka }
1154*437bfbebSnyanmisaka }
1155*437bfbebSnyanmisaka
mpp_control(Mpp * mpp,MpiCmd cmd,MppParam param)1156*437bfbebSnyanmisaka MPP_RET mpp_control(Mpp *mpp, MpiCmd cmd, MppParam param)
1157*437bfbebSnyanmisaka {
1158*437bfbebSnyanmisaka MPP_RET ret = MPP_NOK;
1159*437bfbebSnyanmisaka
1160*437bfbebSnyanmisaka if (!mpp) {
1161*437bfbebSnyanmisaka mpp_err_f("invalid input mpp pointer\n");
1162*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
1163*437bfbebSnyanmisaka }
1164*437bfbebSnyanmisaka
1165*437bfbebSnyanmisaka mpp_ops_ctrl(mpp->mDump, cmd);
1166*437bfbebSnyanmisaka
1167*437bfbebSnyanmisaka if (mpp->mKmpp && mpp->mKmpp->mApi && mpp->mKmpp->mApi->control)
1168*437bfbebSnyanmisaka return mpp->mKmpp->mApi->control(mpp->mKmpp, cmd, param);
1169*437bfbebSnyanmisaka
1170*437bfbebSnyanmisaka switch (cmd & CMD_MODULE_ID_MASK) {
1171*437bfbebSnyanmisaka case CMD_MODULE_OSAL : {
1172*437bfbebSnyanmisaka ret = mpp_control_osal(mpp, cmd, param);
1173*437bfbebSnyanmisaka } break;
1174*437bfbebSnyanmisaka case CMD_MODULE_MPP : {
1175*437bfbebSnyanmisaka mpp_assert(cmd > MPP_CMD_BASE);
1176*437bfbebSnyanmisaka mpp_assert(cmd < MPP_CMD_END);
1177*437bfbebSnyanmisaka
1178*437bfbebSnyanmisaka ret = mpp_control_mpp(mpp, cmd, param);
1179*437bfbebSnyanmisaka } break;
1180*437bfbebSnyanmisaka case CMD_MODULE_CODEC : {
1181*437bfbebSnyanmisaka switch (cmd & CMD_CTX_ID_MASK) {
1182*437bfbebSnyanmisaka case CMD_CTX_ID_DEC : {
1183*437bfbebSnyanmisaka mpp_assert(mpp->mType == MPP_CTX_DEC || mpp->mType == MPP_CTX_BUTT);
1184*437bfbebSnyanmisaka mpp_assert(cmd > MPP_DEC_CMD_BASE);
1185*437bfbebSnyanmisaka mpp_assert(cmd < MPP_DEC_CMD_END);
1186*437bfbebSnyanmisaka
1187*437bfbebSnyanmisaka ret = mpp_control_dec(mpp, cmd, param);
1188*437bfbebSnyanmisaka } break;
1189*437bfbebSnyanmisaka case CMD_CTX_ID_ENC : {
1190*437bfbebSnyanmisaka mpp_assert(mpp->mType == MPP_CTX_ENC);
1191*437bfbebSnyanmisaka mpp_assert(cmd > MPP_ENC_CMD_BASE);
1192*437bfbebSnyanmisaka mpp_assert(cmd < MPP_ENC_CMD_END);
1193*437bfbebSnyanmisaka
1194*437bfbebSnyanmisaka ret = mpp_control_enc(mpp, cmd, param);
1195*437bfbebSnyanmisaka } break;
1196*437bfbebSnyanmisaka case CMD_CTX_ID_ISP : {
1197*437bfbebSnyanmisaka mpp_assert(mpp->mType == MPP_CTX_ISP);
1198*437bfbebSnyanmisaka ret = mpp_control_isp(mpp, cmd, param);
1199*437bfbebSnyanmisaka } break;
1200*437bfbebSnyanmisaka default : {
1201*437bfbebSnyanmisaka mpp_assert(cmd > MPP_CODEC_CMD_BASE);
1202*437bfbebSnyanmisaka mpp_assert(cmd < MPP_CODEC_CMD_END);
1203*437bfbebSnyanmisaka
1204*437bfbebSnyanmisaka ret = mpp_control_codec(mpp, cmd, param);
1205*437bfbebSnyanmisaka } break;
1206*437bfbebSnyanmisaka }
1207*437bfbebSnyanmisaka } break;
1208*437bfbebSnyanmisaka default : {
1209*437bfbebSnyanmisaka } break;
1210*437bfbebSnyanmisaka }
1211*437bfbebSnyanmisaka
1212*437bfbebSnyanmisaka if (ret)
1213*437bfbebSnyanmisaka mpp_err("command %x param %p ret %d\n", cmd, param, ret);
1214*437bfbebSnyanmisaka
1215*437bfbebSnyanmisaka return ret;
1216*437bfbebSnyanmisaka }
1217*437bfbebSnyanmisaka
mpp_reset(Mpp * mpp)1218*437bfbebSnyanmisaka MPP_RET mpp_reset(Mpp *mpp)
1219*437bfbebSnyanmisaka {
1220*437bfbebSnyanmisaka if (!mpp) {
1221*437bfbebSnyanmisaka mpp_err_f("invalid input mpp pointer\n");
1222*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
1223*437bfbebSnyanmisaka }
1224*437bfbebSnyanmisaka
1225*437bfbebSnyanmisaka if (!mpp->mInitDone)
1226*437bfbebSnyanmisaka return MPP_ERR_INIT;
1227*437bfbebSnyanmisaka
1228*437bfbebSnyanmisaka if (mpp->mKmpp && mpp->mKmpp->mApi && mpp->mKmpp->mApi->reset)
1229*437bfbebSnyanmisaka return mpp->mKmpp->mApi->reset(mpp->mKmpp);
1230*437bfbebSnyanmisaka
1231*437bfbebSnyanmisaka mpp_ops_reset(mpp->mDump);
1232*437bfbebSnyanmisaka
1233*437bfbebSnyanmisaka if (mpp->mType == MPP_CTX_DEC) {
1234*437bfbebSnyanmisaka /*
1235*437bfbebSnyanmisaka * On mp4 case extra data of sps/pps will be put at the beginning
1236*437bfbebSnyanmisaka * If these packet was reset before they are send to decoder then
1237*437bfbebSnyanmisaka * decoder can not get these important information to continue decoding
1238*437bfbebSnyanmisaka * To avoid this case happen we need to save it on reset beginning
1239*437bfbebSnyanmisaka * then restore it on reset end.
1240*437bfbebSnyanmisaka */
1241*437bfbebSnyanmisaka mpp_mutex_cond_lock(&mpp->mPktIn->cond_lock);
1242*437bfbebSnyanmisaka while (mpp_list_size(mpp->mPktIn)) {
1243*437bfbebSnyanmisaka MppPacket pkt = NULL;
1244*437bfbebSnyanmisaka
1245*437bfbebSnyanmisaka mpp_list_del_at_head(mpp->mPktIn, &pkt, sizeof(pkt));
1246*437bfbebSnyanmisaka mpp->mPacketGetCount++;
1247*437bfbebSnyanmisaka
1248*437bfbebSnyanmisaka RK_U32 flags = mpp_packet_get_flag(pkt);
1249*437bfbebSnyanmisaka if (flags & MPP_PACKET_FLAG_EXTRA_DATA) {
1250*437bfbebSnyanmisaka if (mpp->mExtraPacket) {
1251*437bfbebSnyanmisaka mpp_packet_deinit(&mpp->mExtraPacket);
1252*437bfbebSnyanmisaka }
1253*437bfbebSnyanmisaka mpp->mExtraPacket = pkt;
1254*437bfbebSnyanmisaka } else {
1255*437bfbebSnyanmisaka mpp_packet_deinit(&pkt);
1256*437bfbebSnyanmisaka }
1257*437bfbebSnyanmisaka }
1258*437bfbebSnyanmisaka mpp_list_flush(mpp->mPktIn);
1259*437bfbebSnyanmisaka mpp_mutex_cond_unlock(&mpp->mPktIn->cond_lock);
1260*437bfbebSnyanmisaka
1261*437bfbebSnyanmisaka mpp_dec_reset(mpp->mDec);
1262*437bfbebSnyanmisaka
1263*437bfbebSnyanmisaka mpp_mutex_cond_lock(&mpp->mFrmOut->cond_lock);
1264*437bfbebSnyanmisaka mpp_list_flush(mpp->mFrmOut);
1265*437bfbebSnyanmisaka mpp_mutex_cond_unlock(&mpp->mFrmOut->cond_lock);
1266*437bfbebSnyanmisaka
1267*437bfbebSnyanmisaka mpp_port_awake(mpp->mUsrInPort);
1268*437bfbebSnyanmisaka mpp_port_awake(mpp->mUsrOutPort);
1269*437bfbebSnyanmisaka } else {
1270*437bfbebSnyanmisaka mpp_enc_reset_v2(mpp->mEnc);
1271*437bfbebSnyanmisaka }
1272*437bfbebSnyanmisaka
1273*437bfbebSnyanmisaka return MPP_OK;
1274*437bfbebSnyanmisaka }
1275*437bfbebSnyanmisaka
mpp_control_mpp(Mpp * mpp,MpiCmd cmd,MppParam param)1276*437bfbebSnyanmisaka MPP_RET mpp_control_mpp(Mpp *mpp, MpiCmd cmd, MppParam param)
1277*437bfbebSnyanmisaka {
1278*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
1279*437bfbebSnyanmisaka
1280*437bfbebSnyanmisaka if (!mpp) {
1281*437bfbebSnyanmisaka mpp_err_f("invalid input mpp pointer\n");
1282*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
1283*437bfbebSnyanmisaka }
1284*437bfbebSnyanmisaka
1285*437bfbebSnyanmisaka switch (cmd) {
1286*437bfbebSnyanmisaka case MPP_SET_INPUT_BLOCK :
1287*437bfbebSnyanmisaka case MPP_SET_OUTPUT_BLOCK :
1288*437bfbebSnyanmisaka case MPP_SET_INTPUT_BLOCK_TIMEOUT :
1289*437bfbebSnyanmisaka case MPP_SET_OUTPUT_BLOCK_TIMEOUT : {
1290*437bfbebSnyanmisaka MppPollType block = (param) ? *((MppPollType *)param) : MPP_POLL_NON_BLOCK;
1291*437bfbebSnyanmisaka
1292*437bfbebSnyanmisaka if (block <= MPP_POLL_BUTT || block > MPP_POLL_MAX) {
1293*437bfbebSnyanmisaka mpp_err("invalid output timeout type %d should be in range [%d, %d]\n",
1294*437bfbebSnyanmisaka block, MPP_POLL_BUTT, MPP_POLL_MAX);
1295*437bfbebSnyanmisaka ret = MPP_ERR_VALUE;
1296*437bfbebSnyanmisaka break;
1297*437bfbebSnyanmisaka }
1298*437bfbebSnyanmisaka if (cmd == MPP_SET_INPUT_BLOCK || cmd == MPP_SET_INTPUT_BLOCK_TIMEOUT)
1299*437bfbebSnyanmisaka mpp->mInputTimeout = block;
1300*437bfbebSnyanmisaka else
1301*437bfbebSnyanmisaka mpp->mOutputTimeout = block;
1302*437bfbebSnyanmisaka
1303*437bfbebSnyanmisaka mpp_log("deprecated block control, use timeout control instead\n");
1304*437bfbebSnyanmisaka } break;
1305*437bfbebSnyanmisaka
1306*437bfbebSnyanmisaka case MPP_SET_DISABLE_THREAD: {
1307*437bfbebSnyanmisaka mpp->mDisableThread = 1;
1308*437bfbebSnyanmisaka } break;
1309*437bfbebSnyanmisaka
1310*437bfbebSnyanmisaka case MPP_SET_INPUT_TIMEOUT:
1311*437bfbebSnyanmisaka case MPP_SET_OUTPUT_TIMEOUT: {
1312*437bfbebSnyanmisaka MppPollType timeout = (param) ? *((MppPollType *)param) : MPP_POLL_NON_BLOCK;
1313*437bfbebSnyanmisaka
1314*437bfbebSnyanmisaka if (timeout <= MPP_POLL_BUTT || timeout > MPP_POLL_MAX) {
1315*437bfbebSnyanmisaka mpp_err("invalid output timeout type %d should be in range [%d, %d]\n",
1316*437bfbebSnyanmisaka timeout, MPP_POLL_BUTT, MPP_POLL_MAX);
1317*437bfbebSnyanmisaka ret = MPP_ERR_VALUE;
1318*437bfbebSnyanmisaka break;
1319*437bfbebSnyanmisaka }
1320*437bfbebSnyanmisaka
1321*437bfbebSnyanmisaka if (cmd == MPP_SET_INPUT_TIMEOUT)
1322*437bfbebSnyanmisaka mpp->mInputTimeout = timeout;
1323*437bfbebSnyanmisaka else
1324*437bfbebSnyanmisaka mpp->mOutputTimeout = timeout;
1325*437bfbebSnyanmisaka } break;
1326*437bfbebSnyanmisaka case MPP_SET_VENC_INIT_KCFG: {
1327*437bfbebSnyanmisaka KmppObj obj = param;
1328*437bfbebSnyanmisaka
1329*437bfbebSnyanmisaka if (!obj) {
1330*437bfbebSnyanmisaka mpp_err_f("ctrl %d invalid param %p\n", cmd, param);
1331*437bfbebSnyanmisaka return MPP_ERR_VALUE;
1332*437bfbebSnyanmisaka }
1333*437bfbebSnyanmisaka mpp->mVencInitKcfg = obj;
1334*437bfbebSnyanmisaka } break;
1335*437bfbebSnyanmisaka case MPP_START : {
1336*437bfbebSnyanmisaka mpp_start(mpp);
1337*437bfbebSnyanmisaka } break;
1338*437bfbebSnyanmisaka case MPP_STOP : {
1339*437bfbebSnyanmisaka mpp_stop(mpp);
1340*437bfbebSnyanmisaka } break;
1341*437bfbebSnyanmisaka
1342*437bfbebSnyanmisaka case MPP_PAUSE : {
1343*437bfbebSnyanmisaka mpp_pause(mpp);
1344*437bfbebSnyanmisaka } break;
1345*437bfbebSnyanmisaka case MPP_RESUME : {
1346*437bfbebSnyanmisaka mpp_resume(mpp);
1347*437bfbebSnyanmisaka } break;
1348*437bfbebSnyanmisaka
1349*437bfbebSnyanmisaka default : {
1350*437bfbebSnyanmisaka ret = MPP_NOK;
1351*437bfbebSnyanmisaka } break;
1352*437bfbebSnyanmisaka }
1353*437bfbebSnyanmisaka return ret;
1354*437bfbebSnyanmisaka }
1355*437bfbebSnyanmisaka
mpp_control_osal(Mpp * mpp,MpiCmd cmd,MppParam param)1356*437bfbebSnyanmisaka MPP_RET mpp_control_osal(Mpp *mpp, MpiCmd cmd, MppParam param)
1357*437bfbebSnyanmisaka {
1358*437bfbebSnyanmisaka MPP_RET ret = MPP_NOK;
1359*437bfbebSnyanmisaka
1360*437bfbebSnyanmisaka if (!mpp) {
1361*437bfbebSnyanmisaka mpp_err_f("invalid input mpp pointer\n");
1362*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
1363*437bfbebSnyanmisaka }
1364*437bfbebSnyanmisaka
1365*437bfbebSnyanmisaka mpp_assert(cmd > MPP_OSAL_CMD_BASE);
1366*437bfbebSnyanmisaka mpp_assert(cmd < MPP_OSAL_CMD_END);
1367*437bfbebSnyanmisaka
1368*437bfbebSnyanmisaka (void)cmd;
1369*437bfbebSnyanmisaka (void)param;
1370*437bfbebSnyanmisaka return ret;
1371*437bfbebSnyanmisaka }
1372*437bfbebSnyanmisaka
mpp_control_codec(Mpp * mpp,MpiCmd cmd,MppParam param)1373*437bfbebSnyanmisaka MPP_RET mpp_control_codec(Mpp *mpp, MpiCmd cmd, MppParam param)
1374*437bfbebSnyanmisaka {
1375*437bfbebSnyanmisaka MPP_RET ret = MPP_NOK;
1376*437bfbebSnyanmisaka
1377*437bfbebSnyanmisaka if (!mpp) {
1378*437bfbebSnyanmisaka mpp_err_f("invalid input mpp pointer\n");
1379*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
1380*437bfbebSnyanmisaka }
1381*437bfbebSnyanmisaka
1382*437bfbebSnyanmisaka (void)cmd;
1383*437bfbebSnyanmisaka (void)param;
1384*437bfbebSnyanmisaka return ret;
1385*437bfbebSnyanmisaka }
1386*437bfbebSnyanmisaka
mpp_control_dec(Mpp * mpp,MpiCmd cmd,MppParam param)1387*437bfbebSnyanmisaka MPP_RET mpp_control_dec(Mpp *mpp, MpiCmd cmd, MppParam param)
1388*437bfbebSnyanmisaka {
1389*437bfbebSnyanmisaka MPP_RET ret = MPP_NOK;
1390*437bfbebSnyanmisaka
1391*437bfbebSnyanmisaka if (!mpp) {
1392*437bfbebSnyanmisaka mpp_err_f("invalid input mpp pointer\n");
1393*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
1394*437bfbebSnyanmisaka }
1395*437bfbebSnyanmisaka
1396*437bfbebSnyanmisaka switch (cmd) {
1397*437bfbebSnyanmisaka case MPP_DEC_GET_THUMBNAIL_FRAME_INFO:
1398*437bfbebSnyanmisaka case MPP_DEC_SET_FRAME_INFO: {
1399*437bfbebSnyanmisaka ret = mpp_dec_control(mpp->mDec, cmd, param);
1400*437bfbebSnyanmisaka } break;
1401*437bfbebSnyanmisaka case MPP_DEC_SET_EXT_BUF_GROUP: {
1402*437bfbebSnyanmisaka /*
1403*437bfbebSnyanmisaka * NOTE: If frame buffer group is configured before decoder init
1404*437bfbebSnyanmisaka * then the buffer limitation maybe not be correctly setup
1405*437bfbebSnyanmisaka * without infomation from InfoChange frame.
1406*437bfbebSnyanmisaka * And the thread signal connection may not be setup here. It
1407*437bfbebSnyanmisaka * may have a bad effect on MPP efficiency.
1408*437bfbebSnyanmisaka */
1409*437bfbebSnyanmisaka if (!mpp->mInitDone) {
1410*437bfbebSnyanmisaka mpp_err("WARNING: setup buffer group before decoder init\n");
1411*437bfbebSnyanmisaka break;
1412*437bfbebSnyanmisaka }
1413*437bfbebSnyanmisaka
1414*437bfbebSnyanmisaka ret = MPP_OK;
1415*437bfbebSnyanmisaka if (!param) {
1416*437bfbebSnyanmisaka /* set to internal mode */
1417*437bfbebSnyanmisaka if (mpp->mExternalBufferMode) {
1418*437bfbebSnyanmisaka /* switch from external mode to internal mode */
1419*437bfbebSnyanmisaka mpp_assert(mpp->mFrameGroup);
1420*437bfbebSnyanmisaka mpp_buffer_group_set_callback((MppBufferGroupImpl *)mpp->mFrameGroup,
1421*437bfbebSnyanmisaka NULL, NULL);
1422*437bfbebSnyanmisaka mpp->mFrameGroup = NULL;
1423*437bfbebSnyanmisaka } else {
1424*437bfbebSnyanmisaka /* keep internal buffer mode cleanup old buffers */
1425*437bfbebSnyanmisaka if (mpp->mFrameGroup)
1426*437bfbebSnyanmisaka mpp_buffer_group_clear(mpp->mFrameGroup);
1427*437bfbebSnyanmisaka }
1428*437bfbebSnyanmisaka
1429*437bfbebSnyanmisaka mpp_dbg_info("using internal buffer group %p\n", mpp->mFrameGroup);
1430*437bfbebSnyanmisaka mpp->mExternalBufferMode = 0;
1431*437bfbebSnyanmisaka } else {
1432*437bfbebSnyanmisaka /* set to external mode */
1433*437bfbebSnyanmisaka if (mpp->mExternalBufferMode) {
1434*437bfbebSnyanmisaka /* keep external buffer mode */
1435*437bfbebSnyanmisaka if (mpp->mFrameGroup != param) {
1436*437bfbebSnyanmisaka /* switch to new buffer group */
1437*437bfbebSnyanmisaka mpp_assert(mpp->mFrameGroup);
1438*437bfbebSnyanmisaka mpp_buffer_group_set_callback((MppBufferGroupImpl *)mpp->mFrameGroup,
1439*437bfbebSnyanmisaka NULL, NULL);
1440*437bfbebSnyanmisaka } else {
1441*437bfbebSnyanmisaka /* keep old group the external group user should cleanup its old buffers */
1442*437bfbebSnyanmisaka }
1443*437bfbebSnyanmisaka } else {
1444*437bfbebSnyanmisaka /* switch from intenal mode to external mode */
1445*437bfbebSnyanmisaka if (mpp->mFrameGroup)
1446*437bfbebSnyanmisaka mpp_buffer_group_put(mpp->mFrameGroup);
1447*437bfbebSnyanmisaka }
1448*437bfbebSnyanmisaka
1449*437bfbebSnyanmisaka mpp_dbg_info("using external buffer group %p\n", mpp->mFrameGroup);
1450*437bfbebSnyanmisaka
1451*437bfbebSnyanmisaka mpp->mFrameGroup = (MppBufferGroup)param;
1452*437bfbebSnyanmisaka mpp_buffer_group_set_callback((MppBufferGroupImpl *)mpp->mFrameGroup,
1453*437bfbebSnyanmisaka mpp_notify_by_buffer_group, (void *)mpp);
1454*437bfbebSnyanmisaka mpp->mExternalBufferMode = 1;
1455*437bfbebSnyanmisaka mpp_notify_flag(mpp, MPP_DEC_NOTIFY_EXT_BUF_GRP_READY);
1456*437bfbebSnyanmisaka }
1457*437bfbebSnyanmisaka } break;
1458*437bfbebSnyanmisaka case MPP_DEC_SET_INFO_CHANGE_READY: {
1459*437bfbebSnyanmisaka mpp_dbg_info("set info change ready\n");
1460*437bfbebSnyanmisaka
1461*437bfbebSnyanmisaka ret = mpp_dec_control(mpp->mDec, cmd, param);
1462*437bfbebSnyanmisaka mpp_notify_flag(mpp, MPP_DEC_NOTIFY_INFO_CHG_DONE | MPP_DEC_NOTIFY_BUFFER_MATCH);
1463*437bfbebSnyanmisaka } break;
1464*437bfbebSnyanmisaka case MPP_DEC_SET_PRESENT_TIME_ORDER :
1465*437bfbebSnyanmisaka case MPP_DEC_SET_PARSER_SPLIT_MODE :
1466*437bfbebSnyanmisaka case MPP_DEC_SET_PARSER_FAST_MODE :
1467*437bfbebSnyanmisaka case MPP_DEC_SET_IMMEDIATE_OUT :
1468*437bfbebSnyanmisaka case MPP_DEC_SET_DISABLE_ERROR :
1469*437bfbebSnyanmisaka case MPP_DEC_SET_DIS_ERR_CLR_MARK :
1470*437bfbebSnyanmisaka case MPP_DEC_SET_ENABLE_DEINTERLACE :
1471*437bfbebSnyanmisaka case MPP_DEC_SET_ENABLE_FAST_PLAY :
1472*437bfbebSnyanmisaka case MPP_DEC_SET_ENABLE_MVC :
1473*437bfbebSnyanmisaka case MPP_DEC_SET_DISABLE_DPB_CHECK :
1474*437bfbebSnyanmisaka case MPP_DEC_SET_CODEC_MODE : {
1475*437bfbebSnyanmisaka /*
1476*437bfbebSnyanmisaka * These control may be set before mpp_init
1477*437bfbebSnyanmisaka * When this case happen record the config and wait for decoder init
1478*437bfbebSnyanmisaka */
1479*437bfbebSnyanmisaka if (mpp->mDec) {
1480*437bfbebSnyanmisaka ret = mpp_dec_control(mpp->mDec, cmd, param);
1481*437bfbebSnyanmisaka return ret;
1482*437bfbebSnyanmisaka }
1483*437bfbebSnyanmisaka
1484*437bfbebSnyanmisaka ret = mpp_dec_set_cfg_by_cmd(mpp->mDecCfg, cmd, param);
1485*437bfbebSnyanmisaka } break;
1486*437bfbebSnyanmisaka case MPP_DEC_GET_STREAM_COUNT: {
1487*437bfbebSnyanmisaka mpp_mutex_cond_lock(&mpp->mPktIn->cond_lock);
1488*437bfbebSnyanmisaka *((RK_S32 *)param) = mpp_list_size(mpp->mPktIn);
1489*437bfbebSnyanmisaka ret = MPP_OK;
1490*437bfbebSnyanmisaka mpp_mutex_cond_unlock(&mpp->mPktIn->cond_lock);
1491*437bfbebSnyanmisaka } break;
1492*437bfbebSnyanmisaka case MPP_DEC_GET_VPUMEM_USED_COUNT :
1493*437bfbebSnyanmisaka case MPP_DEC_SET_OUTPUT_FORMAT :
1494*437bfbebSnyanmisaka case MPP_DEC_QUERY :
1495*437bfbebSnyanmisaka case MPP_DEC_SET_MAX_USE_BUFFER_SIZE: {
1496*437bfbebSnyanmisaka ret = mpp_dec_control(mpp->mDec, cmd, param);
1497*437bfbebSnyanmisaka } break;
1498*437bfbebSnyanmisaka case MPP_DEC_SET_CFG : {
1499*437bfbebSnyanmisaka if (mpp->mDec)
1500*437bfbebSnyanmisaka ret = mpp_dec_control(mpp->mDec, cmd, param);
1501*437bfbebSnyanmisaka else if (param) {
1502*437bfbebSnyanmisaka ret = (MPP_RET)kmpp_obj_update(mpp->mDecCfg, param);
1503*437bfbebSnyanmisaka }
1504*437bfbebSnyanmisaka } break;
1505*437bfbebSnyanmisaka case MPP_DEC_GET_CFG : {
1506*437bfbebSnyanmisaka if (mpp->mDec)
1507*437bfbebSnyanmisaka ret = mpp_dec_control(mpp->mDec, cmd, param);
1508*437bfbebSnyanmisaka else if (param) {
1509*437bfbebSnyanmisaka ret = (MPP_RET)kmpp_obj_copy_entry(param, mpp->mDecCfg);
1510*437bfbebSnyanmisaka }
1511*437bfbebSnyanmisaka } break;
1512*437bfbebSnyanmisaka default : {
1513*437bfbebSnyanmisaka } break;
1514*437bfbebSnyanmisaka }
1515*437bfbebSnyanmisaka return ret;
1516*437bfbebSnyanmisaka }
1517*437bfbebSnyanmisaka
mpp_control_enc(Mpp * mpp,MpiCmd cmd,MppParam param)1518*437bfbebSnyanmisaka MPP_RET mpp_control_enc(Mpp *mpp, MpiCmd cmd, MppParam param)
1519*437bfbebSnyanmisaka {
1520*437bfbebSnyanmisaka if (!mpp) {
1521*437bfbebSnyanmisaka mpp_err_f("invalid input mpp pointer\n");
1522*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
1523*437bfbebSnyanmisaka }
1524*437bfbebSnyanmisaka
1525*437bfbebSnyanmisaka mpp_assert(mpp->mEnc);
1526*437bfbebSnyanmisaka return mpp_enc_control_v2(mpp->mEnc, cmd, param);
1527*437bfbebSnyanmisaka }
1528*437bfbebSnyanmisaka
mpp_control_isp(Mpp * mpp,MpiCmd cmd,MppParam param)1529*437bfbebSnyanmisaka MPP_RET mpp_control_isp(Mpp *mpp, MpiCmd cmd, MppParam param)
1530*437bfbebSnyanmisaka {
1531*437bfbebSnyanmisaka MPP_RET ret = MPP_NOK;
1532*437bfbebSnyanmisaka
1533*437bfbebSnyanmisaka if (!mpp) {
1534*437bfbebSnyanmisaka mpp_err_f("invalid input mpp pointer\n");
1535*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
1536*437bfbebSnyanmisaka }
1537*437bfbebSnyanmisaka
1538*437bfbebSnyanmisaka mpp_assert(cmd > MPP_ISP_CMD_BASE);
1539*437bfbebSnyanmisaka mpp_assert(cmd < MPP_ISP_CMD_END);
1540*437bfbebSnyanmisaka
1541*437bfbebSnyanmisaka (void)cmd;
1542*437bfbebSnyanmisaka (void)param;
1543*437bfbebSnyanmisaka return ret;
1544*437bfbebSnyanmisaka }
1545*437bfbebSnyanmisaka
mpp_notify_flag(Mpp * mpp,RK_U32 flag)1546*437bfbebSnyanmisaka MPP_RET mpp_notify_flag(Mpp *mpp, RK_U32 flag)
1547*437bfbebSnyanmisaka {
1548*437bfbebSnyanmisaka if (!mpp) {
1549*437bfbebSnyanmisaka mpp_err_f("invalid input mpp pointer\n");
1550*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
1551*437bfbebSnyanmisaka }
1552*437bfbebSnyanmisaka
1553*437bfbebSnyanmisaka switch (mpp->mType) {
1554*437bfbebSnyanmisaka case MPP_CTX_DEC : {
1555*437bfbebSnyanmisaka return mpp_dec_notify(mpp->mDec, flag);
1556*437bfbebSnyanmisaka } break;
1557*437bfbebSnyanmisaka case MPP_CTX_ENC : {
1558*437bfbebSnyanmisaka return mpp_enc_notify_v2(mpp->mEnc, flag);
1559*437bfbebSnyanmisaka } break;
1560*437bfbebSnyanmisaka default : {
1561*437bfbebSnyanmisaka mpp_err("unsupport context type %d\n", mpp->mType);
1562*437bfbebSnyanmisaka } break;
1563*437bfbebSnyanmisaka }
1564*437bfbebSnyanmisaka return MPP_NOK;
1565*437bfbebSnyanmisaka }
1566*437bfbebSnyanmisaka
mpp_notify_group(Mpp * mpp,MppBufferGroup group)1567*437bfbebSnyanmisaka MPP_RET mpp_notify_group(Mpp *mpp, MppBufferGroup group)
1568*437bfbebSnyanmisaka {
1569*437bfbebSnyanmisaka MPP_RET ret = MPP_NOK;
1570*437bfbebSnyanmisaka
1571*437bfbebSnyanmisaka if (!mpp) {
1572*437bfbebSnyanmisaka mpp_err_f("invalid input mpp pointer\n");
1573*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
1574*437bfbebSnyanmisaka }
1575*437bfbebSnyanmisaka
1576*437bfbebSnyanmisaka switch (mpp->mType) {
1577*437bfbebSnyanmisaka case MPP_CTX_DEC : {
1578*437bfbebSnyanmisaka if (group == mpp->mFrameGroup)
1579*437bfbebSnyanmisaka ret = mpp_notify_flag(mpp, MPP_DEC_NOTIFY_BUFFER_VALID | MPP_DEC_NOTIFY_BUFFER_MATCH);
1580*437bfbebSnyanmisaka } break;
1581*437bfbebSnyanmisaka default : {
1582*437bfbebSnyanmisaka } break;
1583*437bfbebSnyanmisaka }
1584*437bfbebSnyanmisaka
1585*437bfbebSnyanmisaka return ret;
1586*437bfbebSnyanmisaka }
1587