diff --git a/mpp/CMakeLists.txt b/mpp/CMakeLists.txt index ccbbc0ec..4b43588a 100644 --- a/mpp/CMakeLists.txt +++ b/mpp/CMakeLists.txt @@ -40,10 +40,10 @@ add_subdirectory(hal) # add mpp implement # ---------------------------------------------------------------------------- set (MPP_SRC - mpp_info.cpp - mpp.cpp - mpp_impl.cpp - mpi.cpp + mpp_info.c + mpp.c + mpp_impl.c + mpi.c ) set(MPP_VERSION "0") @@ -63,7 +63,7 @@ endif() set_target_properties(${MPP_SHARED} PROPERTIES FOLDER "mpp") set_target_properties(${MPP_SHARED} PROPERTIES CLEAN_DIRECT_OUTPUT 1) target_link_libraries(${MPP_SHARED} mpp_codec mpp_hal mpp_vproc kmpp - ${BEGIN_WHOLE_ARCHIVE} mpp_base kmpp_base osal ${END_WHOLE_ARCHIVE}) + ${BEGIN_WHOLE_ARCHIVE} mpp_base kmpp_base osal ${END_WHOLE_ARCHIVE} m) # build static library add_library(${MPP_STATIC} STATIC ${MPP_SRC}) diff --git a/mpp/codec/CMakeLists.txt b/mpp/codec/CMakeLists.txt index 70d4a078..3768a242 100644 --- a/mpp/codec/CMakeLists.txt +++ b/mpp/codec/CMakeLists.txt @@ -4,12 +4,12 @@ # add mpp_dec implement # ---------------------------------------------------------------------------- add_library(mpp_codec OBJECT - mpp_enc_impl.cpp - mpp_enc_v2.cpp - enc_impl.cpp - mpp_dec_no_thread.cpp - mpp_dec_normal.cpp - mpp_dec.cpp + mpp_enc_impl.c + mpp_enc_v2.c + enc_impl.c + mpp_dec_no_thread.c + mpp_dec_normal.c + mpp_dec.c mpp_parser.c ) diff --git a/mpp/codec/enc_impl.cpp b/mpp/codec/enc_impl.c similarity index 88% rename from mpp/codec/enc_impl.cpp rename to mpp/codec/enc_impl.c index f9eb9464..d9d4b370 100644 --- a/mpp/codec/enc_impl.cpp +++ b/mpp/codec/enc_impl.c @@ -1,17 +1,6 @@ +/* SPDX-License-Identifier: Apache-2.0 OR MIT */ /* - * Copyright 2010 Rockchip Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright (c) 2010 Rockchip Electronics Co., Ltd. */ #define MODULE_TAG "enc_impl" diff --git a/mpp/codec/mpp_dec.cpp b/mpp/codec/mpp_dec.c similarity index 97% rename from mpp/codec/mpp_dec.cpp rename to mpp/codec/mpp_dec.c index df7a41b9..7955a417 100644 --- a/mpp/codec/mpp_dec.cpp +++ b/mpp/codec/mpp_dec.c @@ -1,17 +1,6 @@ +/* SPDX-License-Identifier: Apache-2.0 OR MIT */ /* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright (c) 2015 Rockchip Electronics Co., Ltd. */ #define MODULE_TAG "mpp_dec" diff --git a/mpp/codec/mpp_dec_no_thread.cpp b/mpp/codec/mpp_dec_no_thread.c similarity index 96% rename from mpp/codec/mpp_dec_no_thread.cpp rename to mpp/codec/mpp_dec_no_thread.c index a9c57884..475c5d8d 100644 --- a/mpp/codec/mpp_dec_no_thread.cpp +++ b/mpp/codec/mpp_dec_no_thread.c @@ -1,17 +1,6 @@ +/* SPDX-License-Identifier: Apache-2.0 OR MIT */ /* - * Copyright 2022 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright (c) 2022 Rockchip Electronics Co., Ltd. */ #define MODULE_TAG "mpp_dec_nt" diff --git a/mpp/codec/mpp_dec_normal.cpp b/mpp/codec/mpp_dec_normal.c similarity index 98% rename from mpp/codec/mpp_dec_normal.cpp rename to mpp/codec/mpp_dec_normal.c index 03a270fb..1289fdb6 100644 --- a/mpp/codec/mpp_dec_normal.cpp +++ b/mpp/codec/mpp_dec_normal.c @@ -1,17 +1,6 @@ +/* SPDX-License-Identifier: Apache-2.0 OR MIT */ /* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright (c) 2015 Rockchip Electronics Co., Ltd. */ #define MODULE_TAG "mpp_dec" diff --git a/mpp/codec/mpp_enc_impl.cpp b/mpp/codec/mpp_enc_impl.c similarity index 99% rename from mpp/codec/mpp_enc_impl.cpp rename to mpp/codec/mpp_enc_impl.c index 8198a6c4..1a12d3ef 100644 --- a/mpp/codec/mpp_enc_impl.cpp +++ b/mpp/codec/mpp_enc_impl.c @@ -1,17 +1,6 @@ +/* SPDX-License-Identifier: Apache-2.0 OR MIT */ /* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright (c) 2015 Rockchip Electronics Co., Ltd. */ #define MODULE_TAG "mpp_enc" diff --git a/mpp/codec/mpp_enc_v2.cpp b/mpp/codec/mpp_enc_v2.c similarity index 94% rename from mpp/codec/mpp_enc_v2.cpp rename to mpp/codec/mpp_enc_v2.c index 765dfc53..f1619b6c 100644 --- a/mpp/codec/mpp_enc_v2.cpp +++ b/mpp/codec/mpp_enc_v2.c @@ -1,17 +1,6 @@ +/* SPDX-License-Identifier: Apache-2.0 OR MIT */ /* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright (c) 2015 Rockchip Electronics Co., Ltd. */ #define MODULE_TAG "mpp_enc" diff --git a/mpp/inc/mpp.h b/mpp/inc/mpp.h index 6a35004f..7c587d82 100644 --- a/mpp/inc/mpp.h +++ b/mpp/inc/mpp.h @@ -1,17 +1,6 @@ +/* SPDX-License-Identifier: Apache-2.0 OR MIT */ /* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright (c) 2015 Rockchip Electronics Co., Ltd. */ #ifndef __MPP_H__ @@ -26,6 +15,10 @@ #include "kmpp_obj.h" #include "kmpp.h" +#ifdef __cplusplus +extern "C" { +#endif + #define MPP_DBG_FUNCTION (0x00000001) #define MPP_DBG_PACKET (0x00000002) #define MPP_DBG_FRAME (0x00000004) @@ -101,40 +94,8 @@ typedef enum MppIOMode_e { * +--------------+ +-----------+ +-----------+ +--------------+ */ -#ifdef __cplusplus - -class Mpp -{ -public: - Mpp(MppCtx ctx = NULL); - ~Mpp(); - MPP_RET init(MppCtxType type, MppCodingType coding); - - MPP_RET start(); - MPP_RET stop(); - - MPP_RET pause(); - MPP_RET resume(); - - MPP_RET put_packet(MppPacket packet); - MPP_RET get_frame(MppFrame *frame); - MPP_RET get_frame_noblock(MppFrame *frame); - - MPP_RET put_frame(MppFrame frame); - MPP_RET get_packet(MppPacket *packet); - - MPP_RET poll(MppPortType type, MppPollType timeout); - MPP_RET dequeue(MppPortType type, MppTask *task); - MPP_RET enqueue(MppPortType type, MppTask task); - - MPP_RET decode(MppPacket packet, MppFrame *frame); - - MPP_RET reset(); - MPP_RET control(MpiCmd cmd, MppParam param); - - MPP_RET notify(RK_U32 flag); - MPP_RET notify(MppBufferGroup group); - +typedef struct Mpp { + /* Public members that were previously public in C++ class */ MppList *mPktIn; MppList *mPktOut; MppList *mFrmIn; @@ -204,8 +165,6 @@ public: /* kmpp infos */ Kmpp *mKmpp; KmppObj mVencInitKcfg; -private: - void clear(); MppCtxType mType; MppCodingType mCoding; @@ -222,26 +181,57 @@ private: RK_U32 mImmediateOut; /* backup extra packet for seek */ MppPacket mExtraPacket; +} Mpp; - MPP_RET control_mpp(MpiCmd cmd, MppParam param); - MPP_RET control_osal(MpiCmd cmd, MppParam param); - MPP_RET control_codec(MpiCmd cmd, MppParam param); - MPP_RET control_dec(MpiCmd cmd, MppParam param); - MPP_RET control_enc(MpiCmd cmd, MppParam param); - MPP_RET control_isp(MpiCmd cmd, MppParam param); +MPP_RET mpp_ctx_create(Mpp **mpp, MppCtx ctx); +MPP_RET mpp_ctx_destroy(Mpp *mpp); +MPP_RET mpp_ctx_init(Mpp *mpp, MppCtxType type, MppCodingType coding); +void mpp_clear(Mpp *mpp); - /* for special encoder async io mode */ - MPP_RET put_frame_async(MppFrame frame); - MPP_RET get_packet_async(MppPacket *packet); +/* Control functions */ +MPP_RET mpp_start(Mpp *mpp); +MPP_RET mpp_stop(Mpp *mpp); +MPP_RET mpp_pause(Mpp *mpp); +MPP_RET mpp_resume(Mpp *mpp); - void set_io_mode(MppIoMode mode); +/* Data processing functions */ +MPP_RET mpp_put_packet(Mpp *mpp, MppPacket packet); +MPP_RET mpp_get_frame(Mpp *mpp, MppFrame *frame); +MPP_RET mpp_get_frame_noblock(Mpp *mpp, MppFrame *frame); - Mpp(const Mpp &); - Mpp &operator=(const Mpp &); -}; +MPP_RET mpp_put_frame(Mpp *mpp, MppFrame frame); +MPP_RET mpp_get_packet(Mpp *mpp, MppPacket *packet); +/* Task queue functions */ +MPP_RET mpp_poll(Mpp *mpp, MppPortType type, MppPollType timeout); +MPP_RET mpp_dequeue(Mpp *mpp, MppPortType type, MppTask *task); +MPP_RET mpp_enqueue(Mpp *mpp, MppPortType type, MppTask task); -extern "C" { +/* Decode function */ +MPP_RET mpp_decode(Mpp *mpp, MppPacket packet, MppFrame *frame); + +/* System functions */ +MPP_RET mpp_reset(Mpp *mpp); +MPP_RET mpp_control(Mpp *mpp, MpiCmd cmd, MppParam param); + +/* Notification functions */ +MPP_RET mpp_notify_flag(Mpp *mpp, RK_U32 flag); +MPP_RET mpp_notify_group(Mpp *mpp, MppBufferGroup group); + +MPP_RET mpp_control_mpp(Mpp *mpp, MpiCmd cmd, MppParam param); +MPP_RET mpp_control_osal(Mpp *mpp, MpiCmd cmd, MppParam param); +MPP_RET mpp_control_codec(Mpp *mpp, MpiCmd cmd, MppParam param); +MPP_RET mpp_control_dec(Mpp *mpp, MpiCmd cmd, MppParam param); +MPP_RET mpp_control_enc(Mpp *mpp, MpiCmd cmd, MppParam param); +MPP_RET mpp_control_isp(Mpp *mpp, MpiCmd cmd, MppParam param); + +/* for special encoder async io mode */ +MPP_RET mpp_put_frame_async(Mpp *mpp, MppFrame frame); +MPP_RET mpp_get_packet_async(Mpp *mpp, MppPacket *packet); + +void mpp_set_io_mode(Mpp *mpp, MppIoMode mode); + +#ifdef __cplusplus } #endif diff --git a/mpp/legacy/CMakeLists.txt b/mpp/legacy/CMakeLists.txt index 7ec7815d..a88065ad 100644 --- a/mpp/legacy/CMakeLists.txt +++ b/mpp/legacy/CMakeLists.txt @@ -12,7 +12,7 @@ set (MPP_LEGACY_SRC vpu_mem_legacy.c rk_list.cpp ppOp.cpp - ../mpp_info.cpp + ../mpp_info.c ) set(VPU_VERSION "0") diff --git a/mpp/mpi.cpp b/mpp/mpi.c similarity index 91% rename from mpp/mpi.cpp rename to mpp/mpi.c index f341c20e..9cc79f37 100644 --- a/mpp/mpi.cpp +++ b/mpp/mpi.c @@ -1,17 +1,6 @@ +/* SPDX-License-Identifier: Apache-2.0 OR MIT */ /* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright (c) 2015 Rockchip Electronics Co., Ltd. */ #define MODULE_TAG "mpi" @@ -117,7 +106,7 @@ static MPP_RET mpi_decode(MppCtx ctx, MppPacket packet, MppFrame *frame) if (frame) *frame = NULL; - ret = p->ctx->decode(packet, frame); + ret = mpp_decode(p->ctx, packet, frame); } while (0); mpi_dbg_func("leave ctx %p ret %d\n", ctx, ret); @@ -141,7 +130,7 @@ static MPP_RET mpi_decode_put_packet(MppCtx ctx, MppPacket packet) break; } - ret = p->ctx->put_packet(packet); + ret = mpp_put_packet(p->ctx, packet); } while (0); mpi_dbg_func("leave ctx %p ret %d\n", ctx, ret); @@ -165,7 +154,7 @@ static MPP_RET mpi_decode_get_frame(MppCtx ctx, MppFrame *frame) break; } - ret = p->ctx->get_frame(frame); + ret = mpp_get_frame(p->ctx, frame); } while (0); mpi_dbg_func("leave ctx %p ret %d\n", ctx, ret); @@ -213,7 +202,7 @@ static MPP_RET mpi_encode_put_frame(MppCtx ctx, MppFrame frame) break; } - ret = p->ctx->put_frame(frame); + ret = mpp_put_frame(p->ctx, frame); } while (0); mpi_dbg_func("leave ctx %p ret %d\n", ctx, ret); @@ -237,7 +226,7 @@ static MPP_RET mpi_encode_get_packet(MppCtx ctx, MppPacket *packet) break; } - ret = p->ctx->get_packet(packet); + ret = mpp_get_packet(p->ctx, packet); } while (0); mpi_dbg_func("leave ctx %p ret %d\n", ctx, ret); @@ -296,7 +285,7 @@ static MPP_RET mpi_poll(MppCtx ctx, MppPortType type, MppPollType timeout) break; } - ret = p->ctx->poll(type, timeout); + ret = mpp_poll(p->ctx, type, timeout); if (ret > 0) ret = MPP_OK; } while (0); @@ -322,7 +311,7 @@ static MPP_RET mpi_dequeue(MppCtx ctx, MppPortType type, MppTask *task) break; } - ret = p->ctx->dequeue(type, task); + ret = mpp_dequeue(p->ctx, type, task); } while (0); mpi_dbg_func("leave ctx %p ret %d\n", ctx, ret); @@ -346,7 +335,7 @@ static MPP_RET mpi_enqueue(MppCtx ctx, MppPortType type, MppTask task) break; } - ret = p->ctx->enqueue(type, task); + ret = mpp_enqueue(p->ctx, type, task); } while (0); mpi_dbg_func("leave ctx %p ret %d\n", ctx, ret); @@ -364,7 +353,7 @@ static MPP_RET mpi_reset(MppCtx ctx) if (ret) break;; - ret = p->ctx->reset(); + ret = mpp_reset(p->ctx); } while (0); mpi_dbg_func("leave ctx %p ret %d\n", ctx, ret); @@ -382,7 +371,7 @@ static MPP_RET mpi_control(MppCtx ctx, MpiCmd cmd, MppParam param) if (ret) break;; - ret = p->ctx->control(cmd, param); + ret = mpp_control(p->ctx, cmd, param); } while (0); mpi_dbg_func("leave ctx %p ret %d\n", ctx, ret); @@ -433,10 +422,10 @@ MPP_RET mpp_create(MppCtx *ctx, MppApi **mpi) } memset(p, 0, sizeof(*p)); - p->ctx = new Mpp(p); - if (NULL == p->ctx) { + ret = mpp_ctx_create(&p->ctx, p); + if (ret || NULL == p->ctx) { mpp_free(p); - mpp_err_f("failed to new Mpp\n"); + mpp_err_f("failed to create Mpp context ret %d\n", ret); ret = MPP_ERR_MALLOC; break; } @@ -472,7 +461,7 @@ MPP_RET mpp_init(MppCtx ctx, MppCtxType type, MppCodingType coding) break; } - ret = p->ctx->init(type, coding); + ret = mpp_ctx_init(p->ctx, type, coding); p->type = type; p->coding = coding; } while (0); @@ -494,7 +483,7 @@ MPP_RET mpp_destroy(MppCtx ctx) return ret; if (p->ctx) - delete p->ctx; + mpp_ctx_destroy(p->ctx); mpp_free(p); } while (0); @@ -519,7 +508,7 @@ MPP_RET mpp_check_support_format(MppCtxType type, MppCodingType coding) return ret; } -void mpp_show_support_format() +void mpp_show_support_format(void) { RK_U32 i = 0; @@ -566,7 +555,7 @@ static MppFrameFormatInfo color_list[] = { { MPP_FMT_RGBA8888, "RGBA8888" }, }; -void mpp_show_color_format() +void mpp_show_color_format(void) { RK_U32 i = 0; diff --git a/mpp/mpp.c b/mpp/mpp.c new file mode 100644 index 00000000..bba1fb3e --- /dev/null +++ b/mpp/mpp.c @@ -0,0 +1,1587 @@ +/* SPDX-License-Identifier: Apache-2.0 OR MIT */ +/* + * Copyright (c) 2015 Rockchip Electronics Co., Ltd. + */ + +#define MODULE_TAG "mpp" + +#include +#include + +#include "rk_mpi.h" + +#include "mpp_mem.h" +#include "mpp_env.h" +#include "mpp_time.h" +#include "mpp_impl.h" +#include "mpp_2str.h" +#include "mpp_debug.h" + +#include "mpp.h" +#include "mpp_hal.h" + +#include "mpp_task_impl.h" +#include "mpp_buffer_impl.h" +#include "mpp_frame_impl.h" +#include "mpp_packet_impl.h" + +#include "kmpp.h" + +#define MPP_TEST_FRAME_SIZE SZ_1M +#define MPP_TEST_PACKET_SIZE SZ_512K + +static void mpp_notify_by_buffer_group(void *arg, void *group) +{ + Mpp *mpp = (Mpp *)arg; + mpp_notify_group(mpp, (MppBufferGroup)group); +} + +static void *list_wraper_packet(void *arg) +{ + MppPacket packet = *(MppPacket*)arg; + + if (mpp_packet_has_meta(packet)) { + MppMeta meta = mpp_packet_get_meta(packet); + MppFrame frm = NULL; + + if (MPP_OK == mpp_meta_get_frame(meta, KEY_INPUT_FRAME, &frm)) { + mpp_assert(frm); + mpp_frame_deinit(&frm); + } + } + + mpp_packet_deinit((MppPacket *)arg); + return NULL; +} + +static void *list_wraper_frame(void *arg) +{ + mpp_frame_deinit((MppFrame *)arg); + return NULL; +} + +static RK_S32 check_frm_task_cnt_cap(MppCodingType coding) +{ + RockchipSocType soc_type = mpp_get_soc_type(); + + if (soc_type == ROCKCHIP_SOC_RK3588 || soc_type == ROCKCHIP_SOC_RK3576) { + if (coding == MPP_VIDEO_CodingAVC || coding == MPP_VIDEO_CodingHEVC) + return 2; + if (coding == MPP_VIDEO_CodingMJPEG && soc_type == ROCKCHIP_SOC_RK3588) + return 4; + } + + mpp_log("Only rk3588's h264/265/jpeg and rk3576's h264/265 encoder can use frame parallel\n"); + + return 1; +} + +MPP_RET mpp_ctx_create(Mpp **mpp, MppCtx ctx) +{ + if (!mpp) { + mpp_err_f("invalid input mpp pointer\n"); + return MPP_ERR_NULL_PTR; + } + + Mpp *p = mpp_calloc(Mpp, 1); + if (!p) { + mpp_err_f("failed to allocate mpp context\n"); + return MPP_ERR_MALLOC; + } + + /* Initialize all members to default values */ + p->mPktIn = NULL; + p->mPktOut = NULL; + p->mFrmIn = NULL; + p->mFrmOut = NULL; + p->mPacketPutCount = 0; + p->mPacketGetCount = 0; + p->mFramePutCount = 0; + p->mFrameGetCount = 0; + p->mTaskPutCount = 0; + p->mTaskGetCount = 0; + p->mPacketGroup = NULL; + p->mFrameGroup = NULL; + p->mExternalBufferMode = 0; + p->mUsrInPort = NULL; + p->mUsrOutPort = NULL; + p->mMppInPort = NULL; + p->mMppOutPort = NULL; + p->mInputTaskQueue = NULL; + p->mOutputTaskQueue = NULL; + p->mInputTaskCount = 1; + p->mOutputTaskCount = 1; + p->mInputTimeout = MPP_POLL_BUTT; + p->mOutputTimeout = MPP_POLL_BUTT; + p->mInputTask = NULL; + p->mEosTask = NULL; + p->mCtx = ctx; + p->mDec = NULL; + p->mEnc = NULL; + p->mEncAyncIo = 0; + p->mEncAyncProc = 0; + p->mIoMode = MPP_IO_MODE_DEFAULT; + p->mDisableThread = 0; + p->mDump = NULL; + p->mKmpp = NULL; + p->mVencInitKcfg = NULL; + p->mType = MPP_CTX_BUTT; + p->mCoding = MPP_VIDEO_CodingUnused; + p->mInitDone = 0; + p->mStatus = 0; + p->mDecCfg = NULL; + p->mParserFastMode = 0; + p->mParserNeedSplit = 0; + p->mParserInternalPts = 0; + p->mImmediateOut = 0; + p->mExtraPacket = NULL; + + mpp_env_get_u32("mpp_debug", &mpp_debug, 0); + + mpp_dec_cfg_init(&p->mDecCfg); + mpp_dec_cfg_set_u32(p->mDecCfg, "base:enable_vproc", MPP_VPROC_MODE_DEINTELACE); + + mpp_dump_init(&p->mDump); + + *mpp = p; + return MPP_OK; +} + +MPP_RET mpp_ctx_init(Mpp *mpp, MppCtxType type, MppCodingType coding) +{ + MPP_RET ret = MPP_NOK; + + if (!mpp) { + mpp_err_f("invalid input mpp pointer\n"); + return MPP_ERR_NULL_PTR; + } + + if (!mpp_check_soc_cap(type, coding)) { + mpp_err("unable to create %s %s for soc %s unsupported\n", + strof_ctx_type(type), strof_coding_type(coding), + mpp_get_soc_info()->compatible); + return MPP_NOK; + } + + if (mpp_check_support_format(type, coding)) { + mpp_err("unable to create %s %s for mpp unsupported\n", + strof_ctx_type(type), strof_coding_type(coding)); + return MPP_NOK; + } + + mpp_ops_init(mpp->mDump, type, coding); + + mpp->mType = type; + mpp->mCoding = coding; + + /* init kmpp venc */ + if (mpp->mVencInitKcfg) { + mpp->mKmpp = mpp_calloc(Kmpp, 1); + if (!mpp->mKmpp) { + mpp_err("failed to alloc kmpp context\n"); + return MPP_NOK; + } + mpp->mKmpp->mClientFd = -1; + mpp_get_api(mpp->mKmpp); + mpp->mKmpp->mVencInitKcfg = mpp->mVencInitKcfg; + ret = mpp->mKmpp->mApi->init(mpp->mKmpp, type, coding); + if (ret) { + mpp_err("failed to init kmpp ret %d\n", ret); + return ret; + } + mpp->mInitDone = 1; + return ret; + } + + mpp_task_queue_init(&mpp->mInputTaskQueue, mpp, "input"); + mpp_task_queue_init(&mpp->mOutputTaskQueue, mpp, "output"); + + switch (mpp->mType) { + case MPP_CTX_DEC : { + mpp->mPktIn = mpp_list_create(list_wraper_packet); + mpp->mFrmOut = mpp_list_create(list_wraper_frame); + + if (mpp->mInputTimeout == MPP_POLL_BUTT) + mpp->mInputTimeout = MPP_POLL_NON_BLOCK; + + if (mpp->mOutputTimeout == MPP_POLL_BUTT) + mpp->mOutputTimeout = MPP_POLL_NON_BLOCK; + + if (mpp->mCoding != MPP_VIDEO_CodingMJPEG) { + mpp_buffer_group_get_internal(&mpp->mPacketGroup, MPP_BUFFER_TYPE_ION | MPP_BUFFER_FLAGS_CACHABLE); + mpp_buffer_group_limit_config(mpp->mPacketGroup, 0, 3); + + mpp->mInputTaskCount = 4; + mpp->mOutputTaskCount = 4; + } + + mpp_task_queue_setup(mpp->mInputTaskQueue, mpp->mInputTaskCount); + mpp_task_queue_setup(mpp->mOutputTaskQueue, mpp->mOutputTaskCount); + + mpp->mUsrInPort = mpp_task_queue_get_port(mpp->mInputTaskQueue, MPP_PORT_INPUT); + mpp->mUsrOutPort = mpp_task_queue_get_port(mpp->mOutputTaskQueue, MPP_PORT_OUTPUT); + mpp->mMppInPort = mpp_task_queue_get_port(mpp->mInputTaskQueue, MPP_PORT_OUTPUT); + mpp->mMppOutPort = mpp_task_queue_get_port(mpp->mOutputTaskQueue, MPP_PORT_INPUT); + + mpp_dec_cfg_set_u32(mpp->mDecCfg, "base:disable_thread", mpp->mDisableThread); + + MppDecInitCfg cfg = { + coding, + mpp, + mpp->mDecCfg, + }; + + ret = mpp_dec_init(&mpp->mDec, &cfg); + if (ret) + break; + ret = mpp_dec_start(mpp->mDec); + if (ret) + break; + mpp->mInitDone = 1; + } break; + case MPP_CTX_ENC : { + mpp->mPktOut = mpp_list_create(list_wraper_packet); + mpp->mFrmIn = mpp_list_create(list_wraper_frame); + + if (mpp->mInputTimeout == MPP_POLL_BUTT) + mpp->mInputTimeout = MPP_POLL_BLOCK; + + if (mpp->mOutputTimeout == MPP_POLL_BUTT) + mpp->mOutputTimeout = MPP_POLL_NON_BLOCK; + + mpp_buffer_group_get_internal(&mpp->mPacketGroup, MPP_BUFFER_TYPE_ION); + mpp_buffer_group_get_internal(&mpp->mFrameGroup, MPP_BUFFER_TYPE_ION); + + if (mpp->mInputTimeout == MPP_POLL_NON_BLOCK) { + mpp->mEncAyncIo = 1; + + mpp->mInputTaskCount = check_frm_task_cnt_cap(coding); + if (mpp->mInputTaskCount == 1) + mpp->mInputTimeout = MPP_POLL_BLOCK; + } + mpp->mOutputTaskCount = 8; + + mpp_task_queue_setup(mpp->mInputTaskQueue, mpp->mInputTaskCount); + mpp_task_queue_setup(mpp->mOutputTaskQueue, mpp->mOutputTaskCount); + + mpp->mUsrInPort = mpp_task_queue_get_port(mpp->mInputTaskQueue, MPP_PORT_INPUT); + mpp->mUsrOutPort = mpp_task_queue_get_port(mpp->mOutputTaskQueue, MPP_PORT_OUTPUT); + mpp->mMppInPort = mpp_task_queue_get_port(mpp->mInputTaskQueue, MPP_PORT_OUTPUT); + mpp->mMppOutPort = mpp_task_queue_get_port(mpp->mOutputTaskQueue, MPP_PORT_INPUT); + + MppEncInitCfg cfg = { + coding, + mpp->mInputTaskCount, + mpp, + }; + + ret = mpp_enc_init_v2(&mpp->mEnc, &cfg); + if (ret) + break; + + if (mpp->mInputTimeout == MPP_POLL_NON_BLOCK) { + mpp->mEncAyncProc = 1; + ret = mpp_enc_start_async(mpp->mEnc); + } else { + ret = mpp_enc_start_v2(mpp->mEnc); + } + + if (ret) + break; + mpp->mInitDone = 1; + } break; + default : { + mpp_err("Mpp error type %d\n", mpp->mType); + } break; + } + + if (!mpp->mInitDone) { + mpp_err("error found on mpp initialization\n"); + mpp_clear(mpp); + } + + return ret; +} + +void mpp_clear(Mpp *mpp) +{ + if (!mpp) + return; + + /* MUST: release listener here */ + if (mpp->mFrameGroup) + mpp_buffer_group_set_callback((MppBufferGroupImpl *)mpp->mFrameGroup, + NULL, NULL); + + if (mpp->mType == MPP_CTX_DEC) { + if (mpp->mDec) { + mpp_dec_stop(mpp->mDec); + mpp_dec_deinit(mpp->mDec); + mpp->mDec = NULL; + } + } else { + if (mpp->mEnc) { + mpp_enc_stop_v2(mpp->mEnc); + mpp_enc_deinit_v2(mpp->mEnc); + mpp->mEnc = NULL; + } + } + + if (mpp->mInputTaskQueue) { + mpp_task_queue_deinit(mpp->mInputTaskQueue); + mpp->mInputTaskQueue = NULL; + } + if (mpp->mOutputTaskQueue) { + mpp_task_queue_deinit(mpp->mOutputTaskQueue); + mpp->mOutputTaskQueue = NULL; + } + + mpp->mUsrInPort = NULL; + mpp->mUsrOutPort = NULL; + mpp->mMppInPort = NULL; + mpp->mMppOutPort = NULL; + + if (mpp->mExtraPacket) { + mpp_packet_deinit(&mpp->mExtraPacket); + mpp->mExtraPacket = NULL; + } + + if (mpp->mPktIn) { + mpp_list_destroy(mpp->mPktIn); + mpp->mPktIn = NULL; + } + if (mpp->mPktOut) { + mpp_list_destroy(mpp->mPktOut); + mpp->mPktOut = NULL; + } + if (mpp->mFrmIn) { + mpp_list_destroy(mpp->mFrmIn); + mpp->mFrmIn = NULL; + } + if (mpp->mFrmOut) { + mpp_list_destroy(mpp->mFrmOut); + mpp->mFrmOut = NULL; + } + + if (mpp->mPacketGroup) { + mpp_buffer_group_put(mpp->mPacketGroup); + mpp->mPacketGroup = NULL; + } + + if (mpp->mFrameGroup && !mpp->mExternalBufferMode) { + mpp_buffer_group_put(mpp->mFrameGroup); + mpp->mFrameGroup = NULL; + } + + if (mpp->mKmpp) { + if (mpp->mKmpp->mApi && mpp->mKmpp->mApi->clear) + mpp->mKmpp->mApi->clear(mpp->mKmpp); + + MPP_FREE(mpp->mKmpp); + } + + if (mpp->mDecCfg) { + mpp_dec_cfg_deinit(mpp->mDecCfg); + mpp->mDecCfg = NULL; + } + + mpp_dump_deinit(&mpp->mDump); +} + +MPP_RET mpp_ctx_destroy(Mpp *mpp) +{ + if (!mpp) + return MPP_OK; + + mpp_clear(mpp); + mpp_free(mpp); + + return MPP_OK; +} + +MPP_RET mpp_start(Mpp *mpp) +{ + if (!mpp) { + mpp_err_f("invalid input mpp pointer\n"); + return MPP_ERR_NULL_PTR; + } + return MPP_OK; +} + +MPP_RET mpp_stop(Mpp *mpp) +{ + if (!mpp) { + mpp_err_f("invalid input mpp pointer\n"); + return MPP_ERR_NULL_PTR; + } + return MPP_OK; +} + +MPP_RET mpp_pause(Mpp *mpp) +{ + if (!mpp) { + mpp_err_f("invalid input mpp pointer\n"); + return MPP_ERR_NULL_PTR; + } + return MPP_OK; +} + +MPP_RET mpp_resume(Mpp *mpp) +{ + if (!mpp) { + mpp_err_f("invalid input mpp pointer\n"); + return MPP_ERR_NULL_PTR; + } + return MPP_OK; +} + +MPP_RET mpp_put_packet(Mpp *mpp, MppPacket packet) +{ + if (!mpp) { + mpp_err_f("invalid input mpp pointer\n"); + return MPP_ERR_NULL_PTR; + } + + if (!mpp->mInitDone) + return MPP_ERR_INIT; + + MPP_RET ret = MPP_NOK; + MppPollType timeout = mpp->mInputTimeout; + MppTask task_dequeue = NULL; + RK_U32 pkt_copy = 0; + + if (mpp->mDisableThread) { + mpp_err_f("no thread decoding case MUST use mpi_decode interface\n"); + return ret; + } + + if (mpp->mExtraPacket) { + MppPacket extra = mpp->mExtraPacket; + + mpp->mExtraPacket = NULL; + mpp_put_packet(mpp, extra); + } + + /* non-jpeg mode - reserve extra task for incoming eos packet */ + if (mpp->mInputTaskCount > 1) { + if (!mpp->mEosTask) { + /* handle eos packet on block mode */ + ret = mpp_poll(mpp, MPP_PORT_INPUT, MPP_POLL_BLOCK); + if (ret < 0) + goto RET; + + mpp_dequeue(mpp, MPP_PORT_INPUT, &mpp->mEosTask); + if (NULL == mpp->mEosTask) { + mpp_err_f("fail to reserve eos task\n"); + ret = MPP_NOK; + goto RET; + } + } + + if (mpp_packet_get_eos(packet)) { + mpp_assert(mpp->mEosTask); + task_dequeue = mpp->mEosTask; + mpp->mEosTask = NULL; + } + } + + /* Use reserved task to send eos packet */ + if (mpp->mInputTask && !task_dequeue) { + task_dequeue = mpp->mInputTask; + mpp->mInputTask = NULL; + } + + if (NULL == task_dequeue) { + ret = mpp_poll(mpp, MPP_PORT_INPUT, timeout); + if (ret < 0) { + ret = MPP_ERR_BUFFER_FULL; + goto RET; + } + + /* do not pull here to avoid block wait */ + mpp_dequeue(mpp, MPP_PORT_INPUT, &task_dequeue); + if (NULL == task_dequeue) { + mpp_err_f("fail to get task on poll ret %d\n", ret); + ret = MPP_NOK; + goto RET; + } + } + + if (NULL == mpp_packet_get_buffer(packet)) { + /* packet copy path */ + MppPacket pkt_in = NULL; + + mpp_packet_copy_init(&pkt_in, packet); + mpp_packet_set_length(packet, 0); + pkt_copy = 1; + packet = pkt_in; + ret = MPP_OK; + } else { + /* packet zero copy path */ + timeout = MPP_POLL_BLOCK; + ret = MPP_OK; + } + + /* setup task */ + ret = mpp_task_meta_set_packet(task_dequeue, KEY_INPUT_PACKET, packet); + if (ret) { + mpp_err_f("set input frame to task ret %d\n", ret); + /* keep current task for next */ + mpp->mInputTask = task_dequeue; + goto RET; + } + + mpp_ops_dec_put_pkt(mpp->mDump, packet); + + /* enqueue valid task to decoder */ + ret = mpp_enqueue(mpp, MPP_PORT_INPUT, task_dequeue); + if (ret) { + mpp_err_f("enqueue ret %d\n", ret); + goto RET; + } + + mpp->mPacketPutCount++; + + if (timeout && !pkt_copy) + mpp_poll(mpp, MPP_PORT_INPUT, timeout); + +RET: + /* wait enqueued task finished */ + if (NULL == mpp->mInputTask) { + MPP_RET cnt = mpp_poll(mpp, MPP_PORT_INPUT, MPP_POLL_NON_BLOCK); + /* reserve one task for eos block mode */ + if (cnt >= 0) { + mpp_dequeue(mpp, MPP_PORT_INPUT, &mpp->mInputTask); + mpp_assert(mpp->mInputTask); + } + } + + return ret; +} + +MPP_RET mpp_get_frame(Mpp *mpp, MppFrame *frame) +{ + MppFrame frm = NULL; + + if (!mpp) { + mpp_err_f("invalid input mpp pointer\n"); + return MPP_ERR_NULL_PTR; + } + + if (!mpp->mInitDone) + return MPP_ERR_INIT; + + mpp_mutex_cond_lock(&mpp->mFrmOut->cond_lock); + + if (0 == mpp_list_size(mpp->mFrmOut)) { + if (mpp->mOutputTimeout) { + if (mpp->mOutputTimeout < 0) { + /* block wait */ + mpp_list_wait(mpp->mFrmOut); + } else { + RK_S32 ret = mpp_list_wait_timed(mpp->mFrmOut, mpp->mOutputTimeout); + if (ret) { + if (ret == ETIMEDOUT) { + mpp_mutex_cond_unlock(&mpp->mFrmOut->cond_lock); + return MPP_ERR_TIMEOUT; + } else { + mpp_mutex_cond_unlock(&mpp->mFrmOut->cond_lock); + return MPP_NOK; + } + } + } + } + } + + if (mpp_list_size(mpp->mFrmOut)) { + MppBuffer buffer; + + mpp_list_del_at_head(mpp->mFrmOut, &frm, sizeof(frm)); + mpp->mFrameGetCount++; + mpp_notify_flag(mpp, MPP_OUTPUT_DEQUEUE); + + buffer = mpp_frame_get_buffer(frm); + if (buffer) + mpp_buffer_sync_ro_begin(buffer); + } else { + // NOTE: Add signal here is not efficient + // This is for fix bug of stucking on decoder parser thread + // When decoder parser thread is block by info change and enter waiting. + // There is no way to wake up parser thread to continue decoding. + // The put_packet only signal sem on may be it better to use sem on info + // change too. + mpp_mutex_cond_lock(&mpp->mPktIn->cond_lock); + if (mpp_list_size(mpp->mPktIn)) + mpp_notify_flag(mpp, MPP_INPUT_ENQUEUE); + mpp_mutex_cond_unlock(&mpp->mPktIn->cond_lock); + } + + *frame = frm; + + // dump output + mpp_ops_dec_get_frm(mpp->mDump, frm); + mpp_mutex_cond_unlock(&mpp->mFrmOut->cond_lock); + + return MPP_OK; +} + +MPP_RET mpp_get_frame_noblock(Mpp *mpp, MppFrame *frame) +{ + MppFrame first = NULL; + + if (!mpp) { + mpp_err_f("invalid input mpp pointer\n"); + return MPP_ERR_NULL_PTR; + } + + if (!mpp->mInitDone) + return MPP_ERR_INIT; + + mpp_mutex_cond_lock(&mpp->mFrmOut->cond_lock); + if (mpp_list_size(mpp->mFrmOut)) { + mpp_list_del_at_head(mpp->mFrmOut, &first, sizeof(first)); + mpp_buffer_sync_ro_begin(mpp_frame_get_buffer(first)); + mpp->mFrameGetCount++; + } + mpp_mutex_cond_unlock(&mpp->mFrmOut->cond_lock); + *frame = first; + + return MPP_OK; +} + +MPP_RET mpp_decode(Mpp *mpp, MppPacket packet, MppFrame *frame) +{ + RK_U32 pkt_done = 0; + RK_S32 frm_rdy = 0; + MPP_RET ret = MPP_OK; + + if (!mpp) { + mpp_err_f("invalid input mpp pointer\n"); + return MPP_ERR_NULL_PTR; + } + + if (!mpp->mDec) + return MPP_NOK; + + if (!mpp->mInitDone) + return MPP_ERR_INIT; + + /* + * If there is frame to return get the frame first + * But if the output mode is block then we need to send packet first + */ + if (!mpp->mOutputTimeout) { + mpp_mutex_cond_lock(&mpp->mFrmOut->cond_lock); + if (mpp_list_size(mpp->mFrmOut)) { + MppBuffer buffer; + + mpp_list_del_at_head(mpp->mFrmOut, frame, sizeof(*frame)); + buffer = mpp_frame_get_buffer(*frame); + if (buffer) + mpp_buffer_sync_ro_begin(buffer); + mpp->mFrameGetCount++; + mpp_mutex_cond_unlock(&mpp->mFrmOut->cond_lock); + return MPP_OK; + } + mpp_mutex_cond_unlock(&mpp->mFrmOut->cond_lock); + } + + do { + if (!pkt_done) + ret = mpp_dec_decode(mpp->mDec, packet); + + /* check input packet finished or not */ + if (!packet || !mpp_packet_get_length(packet)) + pkt_done = 1; + + /* always try getting frame */ + mpp_mutex_cond_lock(&mpp->mFrmOut->cond_lock); + if (mpp_list_size(mpp->mFrmOut)) { + MppBuffer buffer; + + mpp_list_del_at_head(mpp->mFrmOut, frame, sizeof(*frame)); + buffer = mpp_frame_get_buffer(*frame); + if (buffer) + mpp_buffer_sync_ro_begin(buffer); + mpp->mFrameGetCount++; + frm_rdy = 1; + } + mpp_mutex_cond_unlock(&mpp->mFrmOut->cond_lock); + + /* return on flow error */ + if (ret < 0) + break; + + /* return on output frame is ready */ + if (frm_rdy) { + mpp_assert(ret > 0); + ret = MPP_OK; + break; + } + + /* return when packet is send and it is a non-block call */ + if (pkt_done) { + ret = MPP_OK; + break; + } + + /* otherwise continue decoding and getting frame */ + } while (1); + + return ret; +} + +MPP_RET mpp_put_frame(Mpp *mpp, MppFrame frame) +{ + if (!mpp) { + mpp_err_f("invalid input mpp pointer\n"); + return MPP_ERR_NULL_PTR; + } + + if (!mpp->mInitDone) + return MPP_ERR_INIT; + + mpp_dbg_pts("%p input frame pts %lld\n", mpp, mpp_frame_get_pts(frame)); + + if (mpp->mKmpp && mpp->mKmpp->mApi && mpp->mKmpp->mApi->put_frame) + return mpp->mKmpp->mApi->put_frame(mpp->mKmpp, frame); + + if (mpp->mInputTimeout == MPP_POLL_NON_BLOCK) { + mpp_set_io_mode(mpp, MPP_IO_MODE_NORMAL); + return mpp_put_frame_async(mpp, frame); + } + + MPP_RET ret = MPP_NOK; + MppStopwatch stopwatch = NULL; + + if (mpp_debug & MPP_DBG_TIMING) { + mpp_frame_set_stopwatch_enable(frame, 1); + stopwatch = mpp_frame_get_stopwatch(frame); + } + + mpp_stopwatch_record(stopwatch, NULL); + mpp_stopwatch_record(stopwatch, "put frame start"); + + if (mpp->mInputTask == NULL) { + mpp_stopwatch_record(stopwatch, "input port user poll"); + /* poll input port for valid task */ + ret = mpp_poll(mpp, MPP_PORT_INPUT, mpp->mInputTimeout); + if (ret < 0) { + if (mpp->mInputTimeout) + mpp_log_f("poll on set timeout %d ret %d\n", mpp->mInputTimeout, ret); + goto RET; + } + + /* dequeue task for setup */ + mpp_stopwatch_record(stopwatch, "input port user dequeue"); + ret = mpp_dequeue(mpp, MPP_PORT_INPUT, &mpp->mInputTask); + if (ret || NULL == mpp->mInputTask) { + mpp_log_f("dequeue on set ret %d task %p\n", ret, mpp->mInputTask); + goto RET; + } + } + + mpp_assert(mpp->mInputTask); + + /* setup task */ + ret = mpp_task_meta_set_frame(mpp->mInputTask, KEY_INPUT_FRAME, frame); + if (ret) { + mpp_log_f("set input frame to task ret %d\n", ret); + goto RET; + } + + if (mpp_frame_has_meta(frame)) { + MppMeta meta = mpp_frame_get_meta(frame); + MppPacket packet = NULL; + MppBuffer md_info_buf = NULL; + + mpp_meta_get_packet(meta, KEY_OUTPUT_PACKET, &packet); + if (packet) { + ret = mpp_task_meta_set_packet(mpp->mInputTask, KEY_OUTPUT_PACKET, packet); + if (ret) { + mpp_log_f("set output packet to task ret %d\n", ret); + goto RET; + } + } + + mpp_meta_get_buffer(meta, KEY_MOTION_INFO, &md_info_buf); + if (md_info_buf) { + ret = mpp_task_meta_set_buffer(mpp->mInputTask, KEY_MOTION_INFO, md_info_buf); + if (ret) { + mpp_log_f("set output motion dection info ret %d\n", ret); + goto RET; + } + } + } + + // dump input + mpp_ops_enc_put_frm(mpp->mDump, frame); + + /* enqueue valid task to encoder */ + mpp_stopwatch_record(stopwatch, "input port user enqueue"); + ret = mpp_enqueue(mpp, MPP_PORT_INPUT, mpp->mInputTask); + if (ret) { + mpp_log_f("enqueue ret %d\n", ret); + goto RET; + } + + mpp->mInputTask = NULL; + /* wait enqueued task finished */ + mpp_stopwatch_record(stopwatch, "input port user poll"); + ret = mpp_poll(mpp, MPP_PORT_INPUT, mpp->mInputTimeout); + if (ret < 0) { + if (mpp->mInputTimeout) + mpp_log_f("poll on get timeout %d ret %d\n", mpp->mInputTimeout, ret); + goto RET; + } + + /* get previous enqueued task back */ + mpp_stopwatch_record(stopwatch, "input port user dequeue"); + ret = mpp_dequeue(mpp, MPP_PORT_INPUT, &mpp->mInputTask); + if (ret) { + mpp_log_f("dequeue on get ret %d\n", ret); + goto RET; + } + + mpp_assert(mpp->mInputTask); + if (mpp->mInputTask) { + MppFrame frm_out = NULL; + + mpp_task_meta_get_frame(mpp->mInputTask, KEY_INPUT_FRAME, &frm_out); + mpp_assert(frm_out == frame); + } + +RET: + mpp_stopwatch_record(stopwatch, "put_frame finish"); + mpp_frame_set_stopwatch_enable(frame, 0); + return ret; +} + +MPP_RET mpp_get_packet(Mpp *mpp, MppPacket *packet) +{ + MppPacket pkt = NULL; + + if (!mpp) { + mpp_err_f("invalid input mpp pointer\n"); + return MPP_ERR_NULL_PTR; + } + + if (!mpp->mInitDone) + return MPP_ERR_INIT; + + if (mpp->mKmpp && mpp->mKmpp->mApi && mpp->mKmpp->mApi->get_packet) + return mpp->mKmpp->mApi->get_packet(mpp->mKmpp, packet); + + if (mpp->mInputTimeout == MPP_POLL_NON_BLOCK) { + mpp_set_io_mode(mpp, MPP_IO_MODE_NORMAL); + return mpp_get_packet_async(mpp, packet); + } + + MPP_RET ret = MPP_OK; + MppTask task = NULL; + + ret = mpp_poll(mpp, MPP_PORT_OUTPUT, mpp->mOutputTimeout); + if (ret < 0) { + // NOTE: Do not treat poll failure as error. Just clear output + ret = MPP_OK; + *packet = NULL; + goto RET; + } + + ret = mpp_dequeue(mpp, MPP_PORT_OUTPUT, &task); + if (ret || NULL == task) { + mpp_log_f("dequeue on get ret %d task %p\n", ret, task); + goto RET; + } + + mpp_assert(task); + + ret = mpp_task_meta_get_packet(task, KEY_OUTPUT_PACKET, packet); + if (ret) { + mpp_log_f("get output packet from task ret %d\n", ret); + goto RET; + } + + pkt = *packet; + if (!pkt) { + mpp_log_f("get invalid task without output packet\n"); + } else { + MppPacketImpl *impl = (MppPacketImpl *)pkt; + MppBuffer buf = impl->buffer; + + if (buf) { + RK_U32 offset = (RK_U32)((char *)impl->pos - (char *)impl->data); + + mpp_buffer_sync_ro_partial_begin(buf, offset, impl->length); + } + + mpp_dbg_pts("%p output packet pts %lld\n", mpp, impl->pts); + } + + // dump output + mpp_ops_enc_get_pkt(mpp->mDump, pkt); + + ret = mpp_enqueue(mpp, MPP_PORT_OUTPUT, task); + if (ret) + mpp_log_f("enqueue on set ret %d\n", ret); +RET: + + return ret; +} + +MPP_RET mpp_put_frame_async(Mpp *mpp, MppFrame frame) +{ + if (!mpp) { + mpp_err_f("invalid input mpp pointer\n"); + return MPP_ERR_NULL_PTR; + } + + if (NULL == mpp->mFrmIn) + return MPP_NOK; + + if (mpp_mutex_cond_trylock(&mpp->mFrmIn->cond_lock)) + return MPP_NOK; + + /* NOTE: the max input queue length is 2 */ + if (mpp_list_wait_le(mpp->mFrmIn, 10, 1)) { + mpp_mutex_cond_unlock(&mpp->mFrmIn->cond_lock); + return MPP_NOK; + } + + mpp_list_add_at_tail(mpp->mFrmIn, &frame, sizeof(frame)); + mpp->mFramePutCount++; + + mpp_notify_flag(mpp, MPP_INPUT_ENQUEUE); + mpp_mutex_cond_unlock(&mpp->mFrmIn->cond_lock); + + return MPP_OK; +} + +MPP_RET mpp_get_packet_async(Mpp *mpp, MppPacket *packet) +{ + if (!mpp) { + mpp_err_f("invalid input mpp pointer\n"); + return MPP_ERR_NULL_PTR; + } + + mpp_mutex_cond_lock(&mpp->mPktOut->cond_lock); + *packet = NULL; + if (0 == mpp_list_size(mpp->mPktOut)) { + if (mpp->mOutputTimeout) { + if (mpp->mOutputTimeout < 0) { + /* block wait */ + mpp_list_wait(mpp->mPktOut); + } else { + RK_S32 ret = mpp_list_wait_timed(mpp->mPktOut, mpp->mOutputTimeout); + + if (ret) { + if (ret == ETIMEDOUT) { + mpp_mutex_cond_unlock(&mpp->mPktOut->cond_lock); + return MPP_ERR_TIMEOUT; + } else { + mpp_mutex_cond_unlock(&mpp->mPktOut->cond_lock); + return MPP_NOK; + } + } + } + } else { + /* NOTE: in non-block mode the sleep is to avoid user's dead loop */ + msleep(1); + } + } + + if (mpp_list_size(mpp->mPktOut)) { + MppPacket pkt = NULL; + MppPacketImpl *impl = NULL; + RK_U32 offset; + + mpp_list_del_at_head(mpp->mPktOut, &pkt, sizeof(pkt)); + mpp->mPacketGetCount++; + mpp_notify_flag(mpp, MPP_OUTPUT_DEQUEUE); + + *packet = pkt; + + impl = (MppPacketImpl *)pkt; + if (impl->buffer) { + offset = (RK_U32)((char *)impl->pos - (char *)impl->data); + mpp_buffer_sync_ro_partial_begin(impl->buffer, offset, impl->length); + } + } else { + mpp_mutex_cond_lock(&mpp->mFrmIn->cond_lock); + if (mpp_list_size(mpp->mFrmIn)) + mpp_notify_flag(mpp, MPP_INPUT_ENQUEUE); + mpp_mutex_cond_unlock(&mpp->mFrmIn->cond_lock); + mpp_mutex_cond_unlock(&mpp->mPktOut->cond_lock); + + return MPP_NOK; + } + mpp_mutex_cond_unlock(&mpp->mPktOut->cond_lock); + + return MPP_OK; +} + +MPP_RET mpp_poll(Mpp *mpp, MppPortType type, MppPollType timeout) +{ + MppTaskQueue port = NULL; + MPP_RET ret = MPP_NOK; + + if (!mpp) { + mpp_err_f("invalid input mpp pointer\n"); + return MPP_ERR_NULL_PTR; + } + + if (!mpp->mInitDone) + return MPP_ERR_INIT; + + mpp_set_io_mode(mpp, MPP_IO_MODE_TASK); + + switch (type) { + case MPP_PORT_INPUT : { + port = mpp->mUsrInPort; + } break; + case MPP_PORT_OUTPUT : { + port = mpp->mUsrOutPort; + } break; + default : { + } break; + } + + if (port) + ret = mpp_port_poll(port, timeout); + + return ret; +} + +MPP_RET mpp_dequeue(Mpp *mpp, MppPortType type, MppTask *task) +{ + MppTaskQueue port = NULL; + RK_U32 notify_flag = 0; + MPP_RET ret = MPP_NOK; + + if (!mpp) { + mpp_err_f("invalid input mpp pointer\n"); + return MPP_ERR_NULL_PTR; + } + + if (!mpp->mInitDone) + return MPP_ERR_INIT; + + mpp_set_io_mode(mpp, MPP_IO_MODE_TASK); + + switch (type) { + case MPP_PORT_INPUT : { + port = mpp->mUsrInPort; + notify_flag = MPP_INPUT_DEQUEUE; + } break; + case MPP_PORT_OUTPUT : { + port = mpp->mUsrOutPort; + notify_flag = MPP_OUTPUT_DEQUEUE; + } break; + default : { + } break; + } + + if (port) { + ret = mpp_port_dequeue(port, task); + if (MPP_OK == ret) + mpp_notify_flag(mpp, notify_flag); + } + + return ret; +} + +MPP_RET mpp_enqueue(Mpp *mpp, MppPortType type, MppTask task) +{ + MppTaskQueue port = NULL; + RK_U32 notify_flag = 0; + MPP_RET ret = MPP_NOK; + + if (!mpp) { + mpp_err_f("invalid input mpp pointer\n"); + return MPP_ERR_NULL_PTR; + } + + if (!mpp->mInitDone) + return MPP_ERR_INIT; + + mpp_set_io_mode(mpp, MPP_IO_MODE_TASK); + + switch (type) { + case MPP_PORT_INPUT : { + port = mpp->mUsrInPort; + notify_flag = MPP_INPUT_ENQUEUE; + } break; + case MPP_PORT_OUTPUT : { + port = mpp->mUsrOutPort; + notify_flag = MPP_OUTPUT_ENQUEUE; + } break; + default : { + } break; + } + + if (port) { + ret = mpp_port_enqueue(port, task); + // if enqueue success wait up thread + if (MPP_OK == ret) + mpp_notify_flag(mpp, notify_flag); + } + + return ret; +} + +void mpp_set_io_mode(Mpp *mpp, MppIoMode mode) +{ + if (!mpp) { + mpp_err_f("invalid input mpp pointer\n"); + return; + } + + mpp_assert(mode == MPP_IO_MODE_NORMAL || mode == MPP_IO_MODE_TASK); + + if (mpp->mIoMode == MPP_IO_MODE_DEFAULT) + mpp->mIoMode = mode; + else if (mpp->mIoMode != mode) { + static const char *iomode_2str[] = { + "normal", + "task queue", + }; + + mpp_assert(mpp->mIoMode < MPP_IO_MODE_BUTT); + mpp_assert(mode < MPP_IO_MODE_BUTT); + mpp_err("can not reset io mode from %s to %s\n", + iomode_2str[!!mpp->mIoMode], iomode_2str[!!mode]); + } +} + +MPP_RET mpp_control(Mpp *mpp, MpiCmd cmd, MppParam param) +{ + MPP_RET ret = MPP_NOK; + + if (!mpp) { + mpp_err_f("invalid input mpp pointer\n"); + return MPP_ERR_NULL_PTR; + } + + mpp_ops_ctrl(mpp->mDump, cmd); + + if (mpp->mKmpp && mpp->mKmpp->mApi && mpp->mKmpp->mApi->control) + return mpp->mKmpp->mApi->control(mpp->mKmpp, cmd, param); + + switch (cmd & CMD_MODULE_ID_MASK) { + case CMD_MODULE_OSAL : { + ret = mpp_control_osal(mpp, cmd, param); + } break; + case CMD_MODULE_MPP : { + mpp_assert(cmd > MPP_CMD_BASE); + mpp_assert(cmd < MPP_CMD_END); + + ret = mpp_control_mpp(mpp, cmd, param); + } break; + case CMD_MODULE_CODEC : { + switch (cmd & CMD_CTX_ID_MASK) { + case CMD_CTX_ID_DEC : { + mpp_assert(mpp->mType == MPP_CTX_DEC || mpp->mType == MPP_CTX_BUTT); + mpp_assert(cmd > MPP_DEC_CMD_BASE); + mpp_assert(cmd < MPP_DEC_CMD_END); + + ret = mpp_control_dec(mpp, cmd, param); + } break; + case CMD_CTX_ID_ENC : { + mpp_assert(mpp->mType == MPP_CTX_ENC); + mpp_assert(cmd > MPP_ENC_CMD_BASE); + mpp_assert(cmd < MPP_ENC_CMD_END); + + ret = mpp_control_enc(mpp, cmd, param); + } break; + case CMD_CTX_ID_ISP : { + mpp_assert(mpp->mType == MPP_CTX_ISP); + ret = mpp_control_isp(mpp, cmd, param); + } break; + default : { + mpp_assert(cmd > MPP_CODEC_CMD_BASE); + mpp_assert(cmd < MPP_CODEC_CMD_END); + + ret = mpp_control_codec(mpp, cmd, param); + } break; + } + } break; + default : { + } break; + } + + if (ret) + mpp_err("command %x param %p ret %d\n", cmd, param, ret); + + return ret; +} + +MPP_RET mpp_reset(Mpp *mpp) +{ + if (!mpp) { + mpp_err_f("invalid input mpp pointer\n"); + return MPP_ERR_NULL_PTR; + } + + if (!mpp->mInitDone) + return MPP_ERR_INIT; + + if (mpp->mKmpp && mpp->mKmpp->mApi && mpp->mKmpp->mApi->reset) + return mpp->mKmpp->mApi->reset(mpp->mKmpp); + + mpp_ops_reset(mpp->mDump); + + if (mpp->mType == MPP_CTX_DEC) { + /* + * On mp4 case extra data of sps/pps will be put at the beginning + * If these packet was reset before they are send to decoder then + * decoder can not get these important information to continue decoding + * To avoid this case happen we need to save it on reset beginning + * then restore it on reset end. + */ + mpp_mutex_cond_lock(&mpp->mPktIn->cond_lock); + while (mpp_list_size(mpp->mPktIn)) { + MppPacket pkt = NULL; + + mpp_list_del_at_head(mpp->mPktIn, &pkt, sizeof(pkt)); + mpp->mPacketGetCount++; + + RK_U32 flags = mpp_packet_get_flag(pkt); + if (flags & MPP_PACKET_FLAG_EXTRA_DATA) { + if (mpp->mExtraPacket) { + mpp_packet_deinit(&mpp->mExtraPacket); + } + mpp->mExtraPacket = pkt; + } else { + mpp_packet_deinit(&pkt); + } + } + mpp_list_flush(mpp->mPktIn); + mpp_mutex_cond_unlock(&mpp->mPktIn->cond_lock); + + mpp_dec_reset(mpp->mDec); + + mpp_mutex_cond_lock(&mpp->mFrmOut->cond_lock); + mpp_list_flush(mpp->mFrmOut); + mpp_mutex_cond_unlock(&mpp->mFrmOut->cond_lock); + + mpp_port_awake(mpp->mUsrInPort); + mpp_port_awake(mpp->mUsrOutPort); + } else { + mpp_enc_reset_v2(mpp->mEnc); + } + + return MPP_OK; +} + +MPP_RET mpp_control_mpp(Mpp *mpp, MpiCmd cmd, MppParam param) +{ + MPP_RET ret = MPP_OK; + + if (!mpp) { + mpp_err_f("invalid input mpp pointer\n"); + return MPP_ERR_NULL_PTR; + } + + switch (cmd) { + case MPP_SET_INPUT_BLOCK : + case MPP_SET_OUTPUT_BLOCK : + case MPP_SET_INTPUT_BLOCK_TIMEOUT : + case MPP_SET_OUTPUT_BLOCK_TIMEOUT : { + MppPollType block = (param) ? *((MppPollType *)param) : MPP_POLL_NON_BLOCK; + + if (block <= MPP_POLL_BUTT || block > MPP_POLL_MAX) { + mpp_err("invalid output timeout type %d should be in range [%d, %d]\n", + block, MPP_POLL_BUTT, MPP_POLL_MAX); + ret = MPP_ERR_VALUE; + break; + } + if (cmd == MPP_SET_INPUT_BLOCK || cmd == MPP_SET_INTPUT_BLOCK_TIMEOUT) + mpp->mInputTimeout = block; + else + mpp->mOutputTimeout = block; + + mpp_log("deprecated block control, use timeout control instead\n"); + } break; + + case MPP_SET_DISABLE_THREAD: { + mpp->mDisableThread = 1; + } break; + + case MPP_SET_INPUT_TIMEOUT: + case MPP_SET_OUTPUT_TIMEOUT: { + MppPollType timeout = (param) ? *((MppPollType *)param) : MPP_POLL_NON_BLOCK; + + if (timeout <= MPP_POLL_BUTT || timeout > MPP_POLL_MAX) { + mpp_err("invalid output timeout type %d should be in range [%d, %d]\n", + timeout, MPP_POLL_BUTT, MPP_POLL_MAX); + ret = MPP_ERR_VALUE; + break; + } + + if (cmd == MPP_SET_INPUT_TIMEOUT) + mpp->mInputTimeout = timeout; + else + mpp->mOutputTimeout = timeout; + } break; + case MPP_SET_VENC_INIT_KCFG: { + KmppObj obj = param; + + if (!obj) { + mpp_err_f("ctrl %d invalid param %p\n", cmd, param); + return MPP_ERR_VALUE; + } + mpp->mVencInitKcfg = obj; + } break; + case MPP_START : { + mpp_start(mpp); + } break; + case MPP_STOP : { + mpp_stop(mpp); + } break; + + case MPP_PAUSE : { + mpp_pause(mpp); + } break; + case MPP_RESUME : { + mpp_resume(mpp); + } break; + + default : { + ret = MPP_NOK; + } break; + } + return ret; +} + +MPP_RET mpp_control_osal(Mpp *mpp, MpiCmd cmd, MppParam param) +{ + MPP_RET ret = MPP_NOK; + + if (!mpp) { + mpp_err_f("invalid input mpp pointer\n"); + return MPP_ERR_NULL_PTR; + } + + mpp_assert(cmd > MPP_OSAL_CMD_BASE); + mpp_assert(cmd < MPP_OSAL_CMD_END); + + (void)cmd; + (void)param; + return ret; +} + +MPP_RET mpp_control_codec(Mpp *mpp, MpiCmd cmd, MppParam param) +{ + MPP_RET ret = MPP_NOK; + + if (!mpp) { + mpp_err_f("invalid input mpp pointer\n"); + return MPP_ERR_NULL_PTR; + } + + (void)cmd; + (void)param; + return ret; +} + +MPP_RET mpp_control_dec(Mpp *mpp, MpiCmd cmd, MppParam param) +{ + MPP_RET ret = MPP_NOK; + + if (!mpp) { + mpp_err_f("invalid input mpp pointer\n"); + return MPP_ERR_NULL_PTR; + } + + switch (cmd) { + case MPP_DEC_GET_THUMBNAIL_FRAME_INFO: + case MPP_DEC_SET_FRAME_INFO: { + ret = mpp_dec_control(mpp->mDec, cmd, param); + } break; + case MPP_DEC_SET_EXT_BUF_GROUP: { + /* + * NOTE: If frame buffer group is configured before decoder init + * then the buffer limitation maybe not be correctly setup + * without infomation from InfoChange frame. + * And the thread signal connection may not be setup here. It + * may have a bad effect on MPP efficiency. + */ + if (!mpp->mInitDone) { + mpp_err("WARNING: setup buffer group before decoder init\n"); + break; + } + + ret = MPP_OK; + if (!param) { + /* set to internal mode */ + if (mpp->mExternalBufferMode) { + /* switch from external mode to internal mode */ + mpp_assert(mpp->mFrameGroup); + mpp_buffer_group_set_callback((MppBufferGroupImpl *)mpp->mFrameGroup, + NULL, NULL); + mpp->mFrameGroup = NULL; + } else { + /* keep internal buffer mode cleanup old buffers */ + if (mpp->mFrameGroup) + mpp_buffer_group_clear(mpp->mFrameGroup); + } + + mpp_dbg_info("using internal buffer group %p\n", mpp->mFrameGroup); + mpp->mExternalBufferMode = 0; + } else { + /* set to external mode */ + if (mpp->mExternalBufferMode) { + /* keep external buffer mode */ + if (mpp->mFrameGroup != param) { + /* switch to new buffer group */ + mpp_assert(mpp->mFrameGroup); + mpp_buffer_group_set_callback((MppBufferGroupImpl *)mpp->mFrameGroup, + NULL, NULL); + } else { + /* keep old group the external group user should cleanup its old buffers */ + } + } else { + /* switch from intenal mode to external mode */ + if (mpp->mFrameGroup) + mpp_buffer_group_put(mpp->mFrameGroup); + } + + mpp_dbg_info("using external buffer group %p\n", mpp->mFrameGroup); + + mpp->mFrameGroup = (MppBufferGroup)param; + mpp_buffer_group_set_callback((MppBufferGroupImpl *)mpp->mFrameGroup, + mpp_notify_by_buffer_group, (void *)mpp); + mpp->mExternalBufferMode = 1; + mpp_notify_flag(mpp, MPP_DEC_NOTIFY_EXT_BUF_GRP_READY); + } + } break; + case MPP_DEC_SET_INFO_CHANGE_READY: { + mpp_dbg_info("set info change ready\n"); + + ret = mpp_dec_control(mpp->mDec, cmd, param); + mpp_notify_flag(mpp, MPP_DEC_NOTIFY_INFO_CHG_DONE | MPP_DEC_NOTIFY_BUFFER_MATCH); + } break; + case MPP_DEC_SET_PRESENT_TIME_ORDER : + case MPP_DEC_SET_PARSER_SPLIT_MODE : + case MPP_DEC_SET_PARSER_FAST_MODE : + case MPP_DEC_SET_IMMEDIATE_OUT : + case MPP_DEC_SET_DISABLE_ERROR : + case MPP_DEC_SET_DIS_ERR_CLR_MARK : + case MPP_DEC_SET_ENABLE_DEINTERLACE : + case MPP_DEC_SET_ENABLE_FAST_PLAY : + case MPP_DEC_SET_ENABLE_MVC : + case MPP_DEC_SET_DISABLE_DPB_CHECK : + case MPP_DEC_SET_CODEC_MODE : { + /* + * These control may be set before mpp_init + * When this case happen record the config and wait for decoder init + */ + if (mpp->mDec) { + ret = mpp_dec_control(mpp->mDec, cmd, param); + return ret; + } + + ret = mpp_dec_set_cfg_by_cmd(mpp->mDecCfg, cmd, param); + } break; + case MPP_DEC_GET_STREAM_COUNT: { + mpp_mutex_cond_lock(&mpp->mPktIn->cond_lock); + *((RK_S32 *)param) = mpp_list_size(mpp->mPktIn); + ret = MPP_OK; + mpp_mutex_cond_unlock(&mpp->mPktIn->cond_lock); + } break; + case MPP_DEC_GET_VPUMEM_USED_COUNT : + case MPP_DEC_SET_OUTPUT_FORMAT : + case MPP_DEC_QUERY : + case MPP_DEC_SET_MAX_USE_BUFFER_SIZE: { + ret = mpp_dec_control(mpp->mDec, cmd, param); + } break; + case MPP_DEC_SET_CFG : { + if (mpp->mDec) + ret = mpp_dec_control(mpp->mDec, cmd, param); + else if (param) { + ret = (MPP_RET)kmpp_obj_update(mpp->mDecCfg, param); + } + } break; + case MPP_DEC_GET_CFG : { + if (mpp->mDec) + ret = mpp_dec_control(mpp->mDec, cmd, param); + else if (param) { + ret = (MPP_RET)kmpp_obj_copy_entry(param, mpp->mDecCfg); + } + } break; + default : { + } break; + } + return ret; +} + +MPP_RET mpp_control_enc(Mpp *mpp, MpiCmd cmd, MppParam param) +{ + if (!mpp) { + mpp_err_f("invalid input mpp pointer\n"); + return MPP_ERR_NULL_PTR; + } + + mpp_assert(mpp->mEnc); + return mpp_enc_control_v2(mpp->mEnc, cmd, param); +} + +MPP_RET mpp_control_isp(Mpp *mpp, MpiCmd cmd, MppParam param) +{ + MPP_RET ret = MPP_NOK; + + if (!mpp) { + mpp_err_f("invalid input mpp pointer\n"); + return MPP_ERR_NULL_PTR; + } + + mpp_assert(cmd > MPP_ISP_CMD_BASE); + mpp_assert(cmd < MPP_ISP_CMD_END); + + (void)cmd; + (void)param; + return ret; +} + +MPP_RET mpp_notify_flag(Mpp *mpp, RK_U32 flag) +{ + if (!mpp) { + mpp_err_f("invalid input mpp pointer\n"); + return MPP_ERR_NULL_PTR; + } + + switch (mpp->mType) { + case MPP_CTX_DEC : { + return mpp_dec_notify(mpp->mDec, flag); + } break; + case MPP_CTX_ENC : { + return mpp_enc_notify_v2(mpp->mEnc, flag); + } break; + default : { + mpp_err("unsupport context type %d\n", mpp->mType); + } break; + } + return MPP_NOK; +} + +MPP_RET mpp_notify_group(Mpp *mpp, MppBufferGroup group) +{ + MPP_RET ret = MPP_NOK; + + if (!mpp) { + mpp_err_f("invalid input mpp pointer\n"); + return MPP_ERR_NULL_PTR; + } + + switch (mpp->mType) { + case MPP_CTX_DEC : { + if (group == mpp->mFrameGroup) + ret = mpp_notify_flag(mpp, MPP_DEC_NOTIFY_BUFFER_VALID | + MPP_DEC_NOTIFY_BUFFER_MATCH); + } break; + default : { + } break; + } + + return ret; +} diff --git a/mpp/mpp.cpp b/mpp/mpp.cpp deleted file mode 100644 index 1c91d349..00000000 --- a/mpp/mpp.cpp +++ /dev/null @@ -1,1439 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "mpp" - -#include -#include - -#include "rk_mpi.h" - -#include "mpp_mem.h" -#include "mpp_env.h" -#include "mpp_time.h" -#include "mpp_impl.h" -#include "mpp_2str.h" -#include "mpp_debug.h" - -#include "mpp.h" -#include "mpp_hal.h" - -#include "mpp_task_impl.h" -#include "mpp_buffer_impl.h" -#include "mpp_frame_impl.h" -#include "mpp_packet_impl.h" - -#include "kmpp.h" - -#define MPP_TEST_FRAME_SIZE SZ_1M -#define MPP_TEST_PACKET_SIZE SZ_512K - -static void mpp_notify_by_buffer_group(void *arg, void *group) -{ - Mpp *mpp = (Mpp *)arg; - - mpp->notify((MppBufferGroup) group); -} - -static void *list_wraper_packet(void *arg) -{ - MppPacket packet = *(MppPacket*)arg; - - if (mpp_packet_has_meta(packet)) { - MppMeta meta = mpp_packet_get_meta(packet); - MppFrame frm = NULL; - - if (MPP_OK == mpp_meta_get_frame(meta, KEY_INPUT_FRAME, &frm)) { - mpp_assert(frm); - mpp_frame_deinit(&frm); - } - } - - mpp_packet_deinit((MppPacket *)arg); - return NULL; -} - -static void *list_wraper_frame(void *arg) -{ - mpp_frame_deinit((MppFrame *)arg); - return NULL; -} - -static RK_S32 check_frm_task_cnt_cap(MppCodingType coding) -{ - RockchipSocType soc_type = mpp_get_soc_type(); - - if (soc_type == ROCKCHIP_SOC_RK3588 || soc_type == ROCKCHIP_SOC_RK3576) { - if (coding == MPP_VIDEO_CodingAVC || coding == MPP_VIDEO_CodingHEVC) - return 2; - if (coding == MPP_VIDEO_CodingMJPEG && soc_type == ROCKCHIP_SOC_RK3588) - return 4; - } - - mpp_log("Only rk3588's h264/265/jpeg and rk3576's h264/265 encoder can use frame parallel\n"); - - return 1; -} - -Mpp::Mpp(MppCtx ctx) - : mPktIn(NULL), - mPktOut(NULL), - mFrmIn(NULL), - mFrmOut(NULL), - mPacketPutCount(0), - mPacketGetCount(0), - mFramePutCount(0), - mFrameGetCount(0), - mTaskPutCount(0), - mTaskGetCount(0), - mPacketGroup(NULL), - mFrameGroup(NULL), - mExternalBufferMode(0), - mUsrInPort(NULL), - mUsrOutPort(NULL), - mMppInPort(NULL), - mMppOutPort(NULL), - mInputTaskQueue(NULL), - mOutputTaskQueue(NULL), - mInputTaskCount(1), - mOutputTaskCount(1), - mInputTimeout(MPP_POLL_BUTT), - mOutputTimeout(MPP_POLL_BUTT), - mInputTask(NULL), - mEosTask(NULL), - mCtx(ctx), - mDec(NULL), - mEnc(NULL), - mEncAyncIo(0), - mEncAyncProc(0), - mIoMode(MPP_IO_MODE_DEFAULT), - mDisableThread(0), - mDump(NULL), - mType(MPP_CTX_BUTT), - mCoding(MPP_VIDEO_CodingUnused), - mInitDone(0), - mStatus(0), - mExtraPacket(NULL) -{ - mpp_env_get_u32("mpp_debug", &mpp_debug, 0); - - mpp_dec_cfg_init(&mDecCfg); - mpp_dec_cfg_set_u32(mDecCfg, "base:enable_vproc", MPP_VPROC_MODE_DEINTELACE); - - mKmpp = NULL; - mVencInitKcfg = NULL; - mpp_dump_init(&mDump); -} - -MPP_RET Mpp::init(MppCtxType type, MppCodingType coding) -{ - MPP_RET ret = MPP_NOK; - - if (!mpp_check_soc_cap(type, coding)) { - mpp_err("unable to create %s %s for soc %s unsupported\n", - strof_ctx_type(type), strof_coding_type(coding), - mpp_get_soc_info()->compatible); - return MPP_NOK; - } - - if (mpp_check_support_format(type, coding)) { - mpp_err("unable to create %s %s for mpp unsupported\n", - strof_ctx_type(type), strof_coding_type(coding)); - return MPP_NOK; - } - - mpp_ops_init(mDump, type, coding); - - mType = type; - mCoding = coding; - - /* init kmpp venc */ - if (mVencInitKcfg) { - mKmpp = mpp_calloc(Kmpp, 1); - if (!mKmpp) { - mpp_err("failed to alloc kmpp context\n"); - return MPP_NOK; - } - mKmpp->mClientFd = -1; - mpp_get_api(mKmpp); - mKmpp->mVencInitKcfg = mVencInitKcfg; - ret = mKmpp->mApi->init(mKmpp, type, coding); - if (ret) { - mpp_err("failed to init kmpp ret %d\n", ret); - return ret; - } - mInitDone = 1; - - return ret; - } - - mpp_task_queue_init(&mInputTaskQueue, this, "input"); - mpp_task_queue_init(&mOutputTaskQueue, this, "output"); - - switch (mType) { - case MPP_CTX_DEC : { - mPktIn = mpp_list_create(list_wraper_packet); - mFrmOut = mpp_list_create(list_wraper_frame); - - if (mInputTimeout == MPP_POLL_BUTT) - mInputTimeout = MPP_POLL_NON_BLOCK; - - if (mOutputTimeout == MPP_POLL_BUTT) - mOutputTimeout = MPP_POLL_NON_BLOCK; - - if (mCoding != MPP_VIDEO_CodingMJPEG) { - mpp_buffer_group_get_internal(&mPacketGroup, MPP_BUFFER_TYPE_ION | MPP_BUFFER_FLAGS_CACHABLE); - mpp_buffer_group_limit_config(mPacketGroup, 0, 3); - - mInputTaskCount = 4; - mOutputTaskCount = 4; - } - - mpp_task_queue_setup(mInputTaskQueue, mInputTaskCount); - mpp_task_queue_setup(mOutputTaskQueue, mOutputTaskCount); - - mUsrInPort = mpp_task_queue_get_port(mInputTaskQueue, MPP_PORT_INPUT); - mUsrOutPort = mpp_task_queue_get_port(mOutputTaskQueue, MPP_PORT_OUTPUT); - mMppInPort = mpp_task_queue_get_port(mInputTaskQueue, MPP_PORT_OUTPUT); - mMppOutPort = mpp_task_queue_get_port(mOutputTaskQueue, MPP_PORT_INPUT); - - mpp_dec_cfg_set_u32(mDecCfg, "base:disable_thread", mDisableThread); - - MppDecInitCfg cfg = { - coding, - this, - mDecCfg, - }; - - ret = mpp_dec_init(&mDec, &cfg); - if (ret) - break; - ret = mpp_dec_start(mDec); - if (ret) - break; - mInitDone = 1; - } break; - case MPP_CTX_ENC : { - mPktOut = mpp_list_create(list_wraper_packet); - mFrmIn = mpp_list_create(list_wraper_frame); - - if (mInputTimeout == MPP_POLL_BUTT) - mInputTimeout = MPP_POLL_BLOCK; - - if (mOutputTimeout == MPP_POLL_BUTT) - mOutputTimeout = MPP_POLL_NON_BLOCK; - - mpp_buffer_group_get_internal(&mPacketGroup, MPP_BUFFER_TYPE_ION); - mpp_buffer_group_get_internal(&mFrameGroup, MPP_BUFFER_TYPE_ION); - - if (mInputTimeout == MPP_POLL_NON_BLOCK) { - mEncAyncIo = 1; - - mInputTaskCount = check_frm_task_cnt_cap(coding); - if (mInputTaskCount == 1) - mInputTimeout = MPP_POLL_BLOCK; - } - mOutputTaskCount = 8; - - mpp_task_queue_setup(mInputTaskQueue, mInputTaskCount); - mpp_task_queue_setup(mOutputTaskQueue, mOutputTaskCount); - - mUsrInPort = mpp_task_queue_get_port(mInputTaskQueue, MPP_PORT_INPUT); - mUsrOutPort = mpp_task_queue_get_port(mOutputTaskQueue, MPP_PORT_OUTPUT); - mMppInPort = mpp_task_queue_get_port(mInputTaskQueue, MPP_PORT_OUTPUT); - mMppOutPort = mpp_task_queue_get_port(mOutputTaskQueue, MPP_PORT_INPUT); - - MppEncInitCfg cfg = { - coding, - mInputTaskCount, - this, - }; - - ret = mpp_enc_init_v2(&mEnc, &cfg); - if (ret) - break; - - if (mInputTimeout == MPP_POLL_NON_BLOCK) { - mEncAyncProc = 1; - ret = mpp_enc_start_async(mEnc); - } else { - ret = mpp_enc_start_v2(mEnc); - } - - if (ret) - break; - mInitDone = 1; - } break; - default : { - mpp_err("Mpp error type %d\n", mType); - } break; - } - - - if (!mInitDone) { - mpp_err("error found on mpp initialization\n"); - clear(); - } - - return ret; -} - -Mpp::~Mpp () -{ - clear(); -} - -void Mpp::clear() -{ - // MUST: release listener here - if (mFrameGroup) - mpp_buffer_group_set_callback((MppBufferGroupImpl *)mFrameGroup, - NULL, NULL); - - if (mType == MPP_CTX_DEC) { - if (mDec) { - mpp_dec_stop(mDec); - mpp_dec_deinit(mDec); - mDec = NULL; - } - } else { - if (mEnc) { - mpp_enc_stop_v2(mEnc); - mpp_enc_deinit_v2(mEnc); - mEnc = NULL; - } - } - - if (mInputTaskQueue) { - mpp_task_queue_deinit(mInputTaskQueue); - mInputTaskQueue = NULL; - } - if (mOutputTaskQueue) { - mpp_task_queue_deinit(mOutputTaskQueue); - mOutputTaskQueue = NULL; - } - - mUsrInPort = NULL; - mUsrOutPort = NULL; - mMppInPort = NULL; - mMppOutPort = NULL; - - if (mExtraPacket) { - mpp_packet_deinit(&mExtraPacket); - mExtraPacket = NULL; - } - - if (mPktIn) { - mpp_list_destroy(mPktIn); - mPktIn = NULL; - } - if (mPktOut) { - mpp_list_destroy(mPktOut); - mPktOut = NULL; - } - if (mFrmIn) { - mpp_list_destroy(mFrmIn); - mFrmIn = NULL; - } - if (mFrmOut) { - mpp_list_destroy(mFrmOut); - mFrmOut = NULL; - } - - if (mPacketGroup) { - mpp_buffer_group_put(mPacketGroup); - mPacketGroup = NULL; - } - - if (mFrameGroup && !mExternalBufferMode) { - mpp_buffer_group_put(mFrameGroup); - mFrameGroup = NULL; - } - - if (mKmpp) { - if (mKmpp->mApi && mKmpp->mApi->clear) - mKmpp->mApi->clear(mKmpp); - - MPP_FREE(mKmpp); - } - - if (mDecCfg) { - mpp_dec_cfg_deinit(mDecCfg); - mDecCfg = NULL; - } - - mpp_dump_deinit(&mDump); -} - -MPP_RET Mpp::start() -{ - return MPP_OK; -} - -MPP_RET Mpp::stop() -{ - return MPP_OK; -} - -MPP_RET Mpp::pause() -{ - return MPP_OK; -} - -MPP_RET Mpp::resume() -{ - return MPP_OK; -} - -MPP_RET Mpp::put_packet(MppPacket packet) -{ - if (!mInitDone) - return MPP_ERR_INIT; - - MPP_RET ret = MPP_NOK; - MppPollType timeout = mInputTimeout; - MppTask task_dequeue = NULL; - RK_U32 pkt_copy = 0; - - if (mDisableThread) { - mpp_err_f("no thread decoding case MUST use mpi_decode interface\n"); - return ret; - } - - if (mExtraPacket) { - MppPacket extra = mExtraPacket; - - mExtraPacket = NULL; - put_packet(extra); - } - - /* non-jpeg mode - reserve extra task for incoming eos packet */ - if (mInputTaskCount > 1) { - if (!mEosTask) { - /* handle eos packet on block mode */ - ret = poll(MPP_PORT_INPUT, MPP_POLL_BLOCK); - if (ret < 0) - goto RET; - - dequeue(MPP_PORT_INPUT, &mEosTask); - if (NULL == mEosTask) { - mpp_err_f("fail to reserve eos task\n", ret); - ret = MPP_NOK; - goto RET; - } - } - - if (mpp_packet_get_eos(packet)) { - mpp_assert(mEosTask); - task_dequeue = mEosTask; - mEosTask = NULL; - } - } - - /* Use reserved task to send eos packet */ - if (mInputTask && !task_dequeue) { - task_dequeue = mInputTask; - mInputTask = NULL; - } - - if (NULL == task_dequeue) { - ret = poll(MPP_PORT_INPUT, timeout); - if (ret < 0) { - ret = MPP_ERR_BUFFER_FULL; - goto RET; - } - - /* do not pull here to avoid block wait */ - dequeue(MPP_PORT_INPUT, &task_dequeue); - if (NULL == task_dequeue) { - mpp_err_f("fail to get task on poll ret %d\n", ret); - ret = MPP_NOK; - goto RET; - } - } - - if (NULL == mpp_packet_get_buffer(packet)) { - /* packet copy path */ - MppPacket pkt_in = NULL; - - mpp_packet_copy_init(&pkt_in, packet); - mpp_packet_set_length(packet, 0); - pkt_copy = 1; - packet = pkt_in; - ret = MPP_OK; - } else { - /* packet zero copy path */ - timeout = MPP_POLL_BLOCK; - ret = MPP_OK; - } - - /* setup task */ - ret = mpp_task_meta_set_packet(task_dequeue, KEY_INPUT_PACKET, packet); - if (ret) { - mpp_err_f("set input frame to task ret %d\n", ret); - /* keep current task for next */ - mInputTask = task_dequeue; - goto RET; - } - - mpp_ops_dec_put_pkt(mDump, packet); - - /* enqueue valid task to decoder */ - ret = enqueue(MPP_PORT_INPUT, task_dequeue); - if (ret) { - mpp_err_f("enqueue ret %d\n", ret); - goto RET; - } - - mPacketPutCount++; - - if (timeout && !pkt_copy) - poll(MPP_PORT_INPUT, timeout); - -RET: - /* wait enqueued task finished */ - if (NULL == mInputTask) { - MPP_RET cnt = poll(MPP_PORT_INPUT, MPP_POLL_NON_BLOCK); - /* reserve one task for eos block mode */ - if (cnt >= 0) { - dequeue(MPP_PORT_INPUT, &mInputTask); - mpp_assert(mInputTask); - } - } - - return ret; -} - -MPP_RET Mpp::get_frame(MppFrame *frame) -{ - MppFrame frm = NULL; - - if (!mInitDone) - return MPP_ERR_INIT; - - mpp_mutex_cond_lock(&mFrmOut->cond_lock); - - if (0 == mpp_list_size(mFrmOut)) { - if (mOutputTimeout) { - if (mOutputTimeout < 0) { - /* block wait */ - mpp_list_wait(mFrmOut); - } else { - RK_S32 ret = mpp_list_wait_timed(mFrmOut, mOutputTimeout); - if (ret) { - if (ret == ETIMEDOUT) { - mpp_mutex_cond_unlock(&mFrmOut->cond_lock); - return MPP_ERR_TIMEOUT; - } else { - mpp_mutex_cond_unlock(&mFrmOut->cond_lock); - return MPP_NOK; - } - } - } - } - } - - if (mpp_list_size(mFrmOut)) { - MppBuffer buffer; - - mpp_list_del_at_head(mFrmOut, &frm, sizeof(frame)); - mFrameGetCount++; - notify(MPP_OUTPUT_DEQUEUE); - - buffer = mpp_frame_get_buffer(frm); - if (buffer) - mpp_buffer_sync_ro_begin(buffer); - } else { - // NOTE: Add signal here is not efficient - // This is for fix bug of stucking on decoder parser thread - // When decoder parser thread is block by info change and enter waiting. - // There is no way to wake up parser thread to continue decoding. - // The put_packet only signal sem on may be it better to use sem on info - // change too. - mpp_mutex_cond_lock(&mPktIn->cond_lock); - if (mpp_list_size(mPktIn)) - notify(MPP_INPUT_ENQUEUE); - mpp_mutex_cond_unlock(&mPktIn->cond_lock); - } - - *frame = frm; - - // dump output - mpp_ops_dec_get_frm(mDump, frm); - mpp_mutex_cond_unlock(&mFrmOut->cond_lock); - - return MPP_OK; -} - -MPP_RET Mpp::get_frame_noblock(MppFrame *frame) -{ - MppFrame first = NULL; - - if (!mInitDone) - return MPP_ERR_INIT; - - mpp_mutex_cond_lock(&mFrmOut->cond_lock); - if (mpp_list_size(mFrmOut)) { - mpp_list_del_at_head(mFrmOut, &first, sizeof(frame)); - mpp_buffer_sync_ro_begin(mpp_frame_get_buffer(first)); - mFrameGetCount++; - } - mpp_mutex_cond_unlock(&mFrmOut->cond_lock); - *frame = first; - - return MPP_OK; -} - -MPP_RET Mpp::decode(MppPacket packet, MppFrame *frame) -{ - RK_U32 pkt_done = 0; - RK_S32 frm_rdy = 0; - MPP_RET ret = MPP_OK; - - if (!mDec) - return MPP_NOK; - - if (!mInitDone) - return MPP_ERR_INIT; - - /* - * If there is frame to return get the frame first - * But if the output mode is block then we need to send packet first - */ - if (!mOutputTimeout) { - mpp_mutex_cond_lock(&mFrmOut->cond_lock); - if (mpp_list_size(mFrmOut)) { - MppBuffer buffer; - - mpp_list_del_at_head(mFrmOut, frame, sizeof(*frame)); - buffer = mpp_frame_get_buffer(*frame); - if (buffer) - mpp_buffer_sync_ro_begin(buffer); - mFrameGetCount++; - mpp_mutex_cond_unlock(&mFrmOut->cond_lock); - return MPP_OK; - } - mpp_mutex_cond_unlock(&mFrmOut->cond_lock); - } - - do { - if (!pkt_done) - ret = mpp_dec_decode(mDec, packet); - - /* check input packet finished or not */ - if (!packet || !mpp_packet_get_length(packet)) - pkt_done = 1; - - /* always try getting frame */ - mpp_mutex_cond_lock(&mFrmOut->cond_lock); - if (mpp_list_size(mFrmOut)) { - MppBuffer buffer; - - mpp_list_del_at_head(mFrmOut, frame, sizeof(*frame)); - buffer = mpp_frame_get_buffer(*frame); - if (buffer) - mpp_buffer_sync_ro_begin(buffer); - mFrameGetCount++; - frm_rdy = 1; - } - mpp_mutex_cond_unlock(&mFrmOut->cond_lock); - - /* return on flow error */ - if (ret < 0) - break; - - /* return on output frame is ready */ - if (frm_rdy) { - mpp_assert(ret > 0); - ret = MPP_OK; - break; - } - - /* return when packet is send and it is a non-block call */ - if (pkt_done) { - ret = MPP_OK; - break; - } - - /* otherwise continue decoding and getting frame */ - } while (1); - - return ret; -} - -MPP_RET Mpp::put_frame(MppFrame frame) -{ - if (!mInitDone) - return MPP_ERR_INIT; - - mpp_dbg_pts("%p input frame pts %lld\n", this, mpp_frame_get_pts(frame)); - - if (mKmpp && mKmpp->mApi && mKmpp->mApi->put_frame) - return mKmpp->mApi->put_frame(mKmpp, frame); - - if (mInputTimeout == MPP_POLL_NON_BLOCK) { - set_io_mode(MPP_IO_MODE_NORMAL); - return put_frame_async(frame); - } - - MPP_RET ret = MPP_NOK; - MppStopwatch stopwatch = NULL; - - if (mpp_debug & MPP_DBG_TIMING) { - mpp_frame_set_stopwatch_enable(frame, 1); - stopwatch = mpp_frame_get_stopwatch(frame); - } - - mpp_stopwatch_record(stopwatch, NULL); - mpp_stopwatch_record(stopwatch, "put frame start"); - - if (mInputTask == NULL) { - mpp_stopwatch_record(stopwatch, "input port user poll"); - /* poll input port for valid task */ - ret = poll(MPP_PORT_INPUT, mInputTimeout); - if (ret < 0) { - if (mInputTimeout) - mpp_log_f("poll on set timeout %d ret %d\n", mInputTimeout, ret); - goto RET; - } - - /* dequeue task for setup */ - mpp_stopwatch_record(stopwatch, "input port user dequeue"); - ret = dequeue(MPP_PORT_INPUT, &mInputTask); - if (ret || NULL == mInputTask) { - mpp_log_f("dequeue on set ret %d task %p\n", ret, mInputTask); - goto RET; - } - } - - mpp_assert(mInputTask); - - /* setup task */ - ret = mpp_task_meta_set_frame(mInputTask, KEY_INPUT_FRAME, frame); - if (ret) { - mpp_log_f("set input frame to task ret %d\n", ret); - goto RET; - } - - if (mpp_frame_has_meta(frame)) { - MppMeta meta = mpp_frame_get_meta(frame); - MppPacket packet = NULL; - MppBuffer md_info_buf = NULL; - - mpp_meta_get_packet(meta, KEY_OUTPUT_PACKET, &packet); - if (packet) { - ret = mpp_task_meta_set_packet(mInputTask, KEY_OUTPUT_PACKET, packet); - if (ret) { - mpp_log_f("set output packet to task ret %d\n", ret); - goto RET; - } - } - - mpp_meta_get_buffer(meta, KEY_MOTION_INFO, &md_info_buf); - if (md_info_buf) { - ret = mpp_task_meta_set_buffer(mInputTask, KEY_MOTION_INFO, md_info_buf); - if (ret) { - mpp_log_f("set output motion dection info ret %d\n", ret); - goto RET; - } - } - } - - // dump input - mpp_ops_enc_put_frm(mDump, frame); - - /* enqueue valid task to encoder */ - mpp_stopwatch_record(stopwatch, "input port user enqueue"); - ret = enqueue(MPP_PORT_INPUT, mInputTask); - if (ret) { - mpp_log_f("enqueue ret %d\n", ret); - goto RET; - } - - mInputTask = NULL; - /* wait enqueued task finished */ - mpp_stopwatch_record(stopwatch, "input port user poll"); - ret = poll(MPP_PORT_INPUT, mInputTimeout); - if (ret < 0) { - if (mInputTimeout) - mpp_log_f("poll on get timeout %d ret %d\n", mInputTimeout, ret); - goto RET; - } - - /* get previous enqueued task back */ - mpp_stopwatch_record(stopwatch, "input port user dequeue"); - ret = dequeue(MPP_PORT_INPUT, &mInputTask); - if (ret) { - mpp_log_f("dequeue on get ret %d\n", ret); - goto RET; - } - - mpp_assert(mInputTask); - if (mInputTask) { - MppFrame frm_out = NULL; - - mpp_task_meta_get_frame(mInputTask, KEY_INPUT_FRAME, &frm_out); - mpp_assert(frm_out == frame); - } - -RET: - mpp_stopwatch_record(stopwatch, "put_frame finish"); - mpp_frame_set_stopwatch_enable(frame, 0); - return ret; -} - -MPP_RET Mpp::get_packet(MppPacket *packet) -{ - MppPacket pkt = NULL; - - if (!mInitDone) - return MPP_ERR_INIT; - - if (mKmpp && mKmpp->mApi && mKmpp->mApi->get_packet) - return mKmpp->mApi->get_packet(mKmpp, packet); - - if (mInputTimeout == MPP_POLL_NON_BLOCK) { - set_io_mode(MPP_IO_MODE_NORMAL); - return get_packet_async(packet); - } - - MPP_RET ret = MPP_OK; - MppTask task = NULL; - - ret = poll(MPP_PORT_OUTPUT, mOutputTimeout); - if (ret < 0) { - // NOTE: Do not treat poll failure as error. Just clear output - ret = MPP_OK; - *packet = NULL; - goto RET; - } - - ret = dequeue(MPP_PORT_OUTPUT, &task); - if (ret || NULL == task) { - mpp_log_f("dequeue on get ret %d task %p\n", ret, task); - goto RET; - } - - mpp_assert(task); - - ret = mpp_task_meta_get_packet(task, KEY_OUTPUT_PACKET, packet); - if (ret) { - mpp_log_f("get output packet from task ret %d\n", ret); - goto RET; - } - - pkt = *packet; - if (!pkt) { - mpp_log_f("get invalid task without output packet\n"); - } else { - MppPacketImpl *impl = (MppPacketImpl *)pkt; - MppBuffer buf = impl->buffer; - - if (buf) { - RK_U32 offset = (RK_U32)((char *)impl->pos - (char *)impl->data); - - mpp_buffer_sync_ro_partial_begin(buf, offset, impl->length); - } - - mpp_dbg_pts("%p output packet pts %lld\n", this, impl->pts); - } - - // dump output - mpp_ops_enc_get_pkt(mDump, pkt); - - ret = enqueue(MPP_PORT_OUTPUT, task); - if (ret) - mpp_log_f("enqueue on set ret %d\n", ret); -RET: - - return ret; -} - -MPP_RET Mpp::put_frame_async(MppFrame frame) -{ - if (NULL == mFrmIn) - return MPP_NOK; - - if (mpp_mutex_cond_trylock(&mFrmIn->cond_lock)) - return MPP_NOK; - - /* NOTE: the max input queue length is 2 */ - if (mpp_list_wait_le(mFrmIn, 10, 1)) { - mpp_mutex_cond_unlock(&mFrmIn->cond_lock); - return MPP_NOK; - } - - mpp_list_add_at_tail(mFrmIn, &frame, sizeof(frame)); - mFramePutCount++; - - notify(MPP_INPUT_ENQUEUE); - mpp_mutex_cond_unlock(&mFrmIn->cond_lock); - - return MPP_OK; -} - -MPP_RET Mpp::get_packet_async(MppPacket *packet) -{ - mpp_mutex_cond_lock(&mPktOut->cond_lock); - *packet = NULL; - if (0 == mpp_list_size(mPktOut)) { - if (mOutputTimeout) { - if (mOutputTimeout < 0) { - /* block wait */ - mpp_list_wait(mPktOut); - } else { - RK_S32 ret = mpp_list_wait_timed(mPktOut, mOutputTimeout); - - if (ret) { - if (ret == ETIMEDOUT) { - mpp_mutex_cond_unlock(&mPktOut->cond_lock); - return MPP_ERR_TIMEOUT; - } else { - mpp_mutex_cond_unlock(&mPktOut->cond_lock); - return MPP_NOK; - } - } - } - } else { - /* NOTE: in non-block mode the sleep is to avoid user's dead loop */ - msleep(1); - } - } - - if (mpp_list_size(mPktOut)) { - MppPacket pkt = NULL; - MppPacketImpl *impl = NULL; - RK_U32 offset; - - mpp_list_del_at_head(mPktOut, &pkt, sizeof(pkt)); - mPacketGetCount++; - notify(MPP_OUTPUT_DEQUEUE); - - *packet = pkt; - - impl = (MppPacketImpl *)pkt; - if (impl->buffer) { - offset = (RK_U32)((char *)impl->pos - (char *)impl->data); - mpp_buffer_sync_ro_partial_begin(impl->buffer, offset, impl->length); - } - } else { - mpp_mutex_cond_lock(&mFrmIn->cond_lock); - if (mpp_list_size(mFrmIn)) - notify(MPP_INPUT_ENQUEUE); - mpp_mutex_cond_unlock(&mFrmIn->cond_lock); - - mpp_mutex_cond_unlock(&mPktOut->cond_lock); - return MPP_NOK; - } - mpp_mutex_cond_unlock(&mPktOut->cond_lock); - return MPP_OK; -} - -MPP_RET Mpp::poll(MppPortType type, MppPollType timeout) -{ - MppTaskQueue port = NULL; - MPP_RET ret = MPP_NOK; - - if (!mInitDone) - return MPP_ERR_INIT; - - set_io_mode(MPP_IO_MODE_TASK); - - switch (type) { - case MPP_PORT_INPUT : { - port = mUsrInPort; - } break; - case MPP_PORT_OUTPUT : { - port = mUsrOutPort; - } break; - default : { - } break; - } - - if (port) - ret = mpp_port_poll(port, timeout); - - return ret; -} - -MPP_RET Mpp::dequeue(MppPortType type, MppTask *task) -{ - MppTaskQueue port = NULL; - RK_U32 notify_flag = 0; - MPP_RET ret = MPP_NOK; - - if (!mInitDone) - return MPP_ERR_INIT; - - set_io_mode(MPP_IO_MODE_TASK); - - switch (type) { - case MPP_PORT_INPUT : { - port = mUsrInPort; - notify_flag = MPP_INPUT_DEQUEUE; - } break; - case MPP_PORT_OUTPUT : { - port = mUsrOutPort; - notify_flag = MPP_OUTPUT_DEQUEUE; - } break; - default : { - } break; - } - - if (port) { - ret = mpp_port_dequeue(port, task); - if (MPP_OK == ret) - notify(notify_flag); - } - - return ret; -} - -MPP_RET Mpp::enqueue(MppPortType type, MppTask task) -{ - MppTaskQueue port = NULL; - RK_U32 notify_flag = 0; - MPP_RET ret = MPP_NOK; - - if (!mInitDone) - return MPP_ERR_INIT; - - set_io_mode(MPP_IO_MODE_TASK); - - switch (type) { - case MPP_PORT_INPUT : { - port = mUsrInPort; - notify_flag = MPP_INPUT_ENQUEUE; - } break; - case MPP_PORT_OUTPUT : { - port = mUsrOutPort; - notify_flag = MPP_OUTPUT_ENQUEUE; - } break; - default : { - } break; - } - - if (port) { - ret = mpp_port_enqueue(port, task); - // if enqueue success wait up thread - if (MPP_OK == ret) - notify(notify_flag); - } - - return ret; -} - -void Mpp::set_io_mode(MppIoMode mode) -{ - mpp_assert(mode == MPP_IO_MODE_NORMAL || mode == MPP_IO_MODE_TASK); - - if (mIoMode == MPP_IO_MODE_DEFAULT) - mIoMode = mode; - else if (mIoMode != mode) { - static const char *iomode_2str[] = { - "normal", - "task queue", - }; - - mpp_assert(mIoMode < MPP_IO_MODE_BUTT); - mpp_assert(mode < MPP_IO_MODE_BUTT); - mpp_err("can not reset io mode from %s to %s\n", - iomode_2str[!!mIoMode], iomode_2str[!!mode]); - } -} - -MPP_RET Mpp::control(MpiCmd cmd, MppParam param) -{ - MPP_RET ret = MPP_NOK; - - mpp_ops_ctrl(mDump, cmd); - - if (mKmpp && mKmpp->mApi && mKmpp->mApi->control) - return mKmpp->mApi->control(mKmpp, cmd, param); - - switch (cmd & CMD_MODULE_ID_MASK) { - case CMD_MODULE_OSAL : { - ret = control_osal(cmd, param); - } break; - case CMD_MODULE_MPP : { - mpp_assert(cmd > MPP_CMD_BASE); - mpp_assert(cmd < MPP_CMD_END); - - ret = control_mpp(cmd, param); - } break; - case CMD_MODULE_CODEC : { - switch (cmd & CMD_CTX_ID_MASK) { - case CMD_CTX_ID_DEC : { - mpp_assert(mType == MPP_CTX_DEC || mType == MPP_CTX_BUTT); - mpp_assert(cmd > MPP_DEC_CMD_BASE); - mpp_assert(cmd < MPP_DEC_CMD_END); - - ret = control_dec(cmd, param); - } break; - case CMD_CTX_ID_ENC : { - mpp_assert(mType == MPP_CTX_ENC); - mpp_assert(cmd > MPP_ENC_CMD_BASE); - mpp_assert(cmd < MPP_ENC_CMD_END); - - ret = control_enc(cmd, param); - } break; - case CMD_CTX_ID_ISP : { - mpp_assert(mType == MPP_CTX_ISP); - ret = control_isp(cmd, param); - } break; - default : { - mpp_assert(cmd > MPP_CODEC_CMD_BASE); - mpp_assert(cmd < MPP_CODEC_CMD_END); - - ret = control_codec(cmd, param); - } break; - } - } break; - default : { - } break; - } - - if (ret) - mpp_err("command %x param %p ret %d\n", cmd, param, ret); - - return ret; -} - -MPP_RET Mpp::reset() -{ - if (!mInitDone) - return MPP_ERR_INIT; - - if (mKmpp && mKmpp->mApi && mKmpp->mApi->reset) - return mKmpp->mApi->reset(mKmpp); - - mpp_ops_reset(mDump); - - if (mType == MPP_CTX_DEC) { - /* - * On mp4 case extra data of sps/pps will be put at the beginning - * If these packet was reset before they are send to decoder then - * decoder can not get these important information to continue decoding - * To avoid this case happen we need to save it on reset beginning - * then restore it on reset end. - */ - mpp_mutex_cond_lock(&mPktIn->cond_lock); - while (mpp_list_size(mPktIn)) { - MppPacket pkt = NULL; - - mpp_list_del_at_head(mPktIn, &pkt, sizeof(pkt)); - mPacketGetCount++; - - RK_U32 flags = mpp_packet_get_flag(pkt); - if (flags & MPP_PACKET_FLAG_EXTRA_DATA) { - if (mExtraPacket) { - mpp_packet_deinit(&mExtraPacket); - } - mExtraPacket = pkt; - } else { - mpp_packet_deinit(&pkt); - } - } - mpp_list_flush(mPktIn); - mpp_mutex_cond_unlock(&mPktIn->cond_lock); - - mpp_dec_reset(mDec); - - mpp_mutex_cond_lock(&mFrmOut->cond_lock); - mpp_list_flush(mFrmOut); - mpp_mutex_cond_unlock(&mFrmOut->cond_lock); - - mpp_port_awake(mUsrInPort); - mpp_port_awake(mUsrOutPort); - } else { - mpp_enc_reset_v2(mEnc); - } - - return MPP_OK; -} - -MPP_RET Mpp::control_mpp(MpiCmd cmd, MppParam param) -{ - MPP_RET ret = MPP_OK; - - switch (cmd) { - case MPP_SET_INPUT_BLOCK : - case MPP_SET_OUTPUT_BLOCK : - case MPP_SET_INTPUT_BLOCK_TIMEOUT : - case MPP_SET_OUTPUT_BLOCK_TIMEOUT : { - MppPollType block = (param) ? *((MppPollType *)param) : MPP_POLL_NON_BLOCK; - - if (block <= MPP_POLL_BUTT || block > MPP_POLL_MAX) { - mpp_err("invalid output timeout type %d should be in range [%d, %d]\n", - block, MPP_POLL_BUTT, MPP_POLL_MAX); - ret = MPP_ERR_VALUE; - break; - } - if (cmd == MPP_SET_INPUT_BLOCK || cmd == MPP_SET_INTPUT_BLOCK_TIMEOUT) - mInputTimeout = block; - else - mOutputTimeout = block; - - mpp_log("deprecated block control, use timeout control instead\n"); - } break; - - case MPP_SET_DISABLE_THREAD: { - mDisableThread = 1; - } break; - - case MPP_SET_INPUT_TIMEOUT: - case MPP_SET_OUTPUT_TIMEOUT: { - MppPollType timeout = (param) ? *((MppPollType *)param) : MPP_POLL_NON_BLOCK; - - if (timeout <= MPP_POLL_BUTT || timeout > MPP_POLL_MAX) { - mpp_err("invalid output timeout type %d should be in range [%d, %d]\n", - timeout, MPP_POLL_BUTT, MPP_POLL_MAX); - ret = MPP_ERR_VALUE; - break; - } - - if (cmd == MPP_SET_INPUT_TIMEOUT) - mInputTimeout = timeout; - else - mOutputTimeout = timeout; - } break; - case MPP_SET_VENC_INIT_KCFG: { - KmppObj obj = param; - - if (!obj) { - mpp_err_f("ctrl %d invalid param %p\n", cmd, param); - return MPP_ERR_VALUE; - } - mVencInitKcfg = obj; - } break; - case MPP_START : { - start(); - } break; - case MPP_STOP : { - stop(); - } break; - - case MPP_PAUSE : { - pause(); - } break; - case MPP_RESUME : { - resume(); - } break; - - default : { - ret = MPP_NOK; - } break; - } - return ret; -} - -MPP_RET Mpp::control_osal(MpiCmd cmd, MppParam param) -{ - MPP_RET ret = MPP_NOK; - - mpp_assert(cmd > MPP_OSAL_CMD_BASE); - mpp_assert(cmd < MPP_OSAL_CMD_END); - - (void)cmd; - (void)param; - return ret; -} - -MPP_RET Mpp::control_codec(MpiCmd cmd, MppParam param) -{ - MPP_RET ret = MPP_NOK; - - (void)cmd; - (void)param; - return ret; -} - -MPP_RET Mpp::control_dec(MpiCmd cmd, MppParam param) -{ - MPP_RET ret = MPP_NOK; - - switch (cmd) { - case MPP_DEC_GET_THUMBNAIL_FRAME_INFO: - case MPP_DEC_SET_FRAME_INFO: { - ret = mpp_dec_control(mDec, cmd, param); - } break; - case MPP_DEC_SET_EXT_BUF_GROUP: { - /* - * NOTE: If frame buffer group is configured before decoder init - * then the buffer limitation maybe not be correctly setup - * without infomation from InfoChange frame. - * And the thread signal connection may not be setup here. It - * may have a bad effect on MPP efficiency. - */ - if (!mInitDone) { - mpp_err("WARNING: setup buffer group before decoder init\n"); - break; - } - - ret = MPP_OK; - if (!param) { - /* set to internal mode */ - if (mExternalBufferMode) { - /* switch from external mode to internal mode */ - mpp_assert(mFrameGroup); - mpp_buffer_group_set_callback((MppBufferGroupImpl *)mFrameGroup, - NULL, NULL); - mFrameGroup = NULL; - } else { - /* keep internal buffer mode cleanup old buffers */ - if (mFrameGroup) - mpp_buffer_group_clear(mFrameGroup); - } - - mpp_dbg_info("using internal buffer group %p\n", mFrameGroup); - mExternalBufferMode = 0; - } else { - /* set to external mode */ - if (mExternalBufferMode) { - /* keep external buffer mode */ - if (mFrameGroup != param) { - /* switch to new buffer group */ - mpp_assert(mFrameGroup); - mpp_buffer_group_set_callback((MppBufferGroupImpl *)mFrameGroup, - NULL, NULL); - } else { - /* keep old group the external group user should cleanup its old buffers */ - } - } else { - /* switch from intenal mode to external mode */ - if (mFrameGroup) - mpp_buffer_group_put(mFrameGroup); - } - - mpp_dbg_info("using external buffer group %p\n", mFrameGroup); - - mFrameGroup = (MppBufferGroup)param; - mpp_buffer_group_set_callback((MppBufferGroupImpl *)mFrameGroup, - mpp_notify_by_buffer_group, (void *)this); - mExternalBufferMode = 1; - notify(MPP_DEC_NOTIFY_EXT_BUF_GRP_READY); - } - } break; - case MPP_DEC_SET_INFO_CHANGE_READY: { - mpp_dbg_info("set info change ready\n"); - - ret = mpp_dec_control(mDec, cmd, param); - notify(MPP_DEC_NOTIFY_INFO_CHG_DONE | MPP_DEC_NOTIFY_BUFFER_MATCH); - } break; - case MPP_DEC_SET_PRESENT_TIME_ORDER : - case MPP_DEC_SET_PARSER_SPLIT_MODE : - case MPP_DEC_SET_PARSER_FAST_MODE : - case MPP_DEC_SET_IMMEDIATE_OUT : - case MPP_DEC_SET_DISABLE_ERROR : - case MPP_DEC_SET_DIS_ERR_CLR_MARK : - case MPP_DEC_SET_ENABLE_DEINTERLACE : - case MPP_DEC_SET_ENABLE_FAST_PLAY : - case MPP_DEC_SET_ENABLE_MVC : - case MPP_DEC_SET_DISABLE_DPB_CHECK : - case MPP_DEC_SET_CODEC_MODE : { - /* - * These control may be set before mpp_init - * When this case happen record the config and wait for decoder init - */ - if (mDec) { - ret = mpp_dec_control(mDec, cmd, param); - return ret; - } - - ret = mpp_dec_set_cfg_by_cmd(mDecCfg, cmd, param); - } break; - case MPP_DEC_GET_STREAM_COUNT: { - mpp_mutex_cond_lock(&mPktIn->cond_lock); - *((RK_S32 *)param) = mpp_list_size(mPktIn); - ret = MPP_OK; - mpp_mutex_cond_unlock(&mPktIn->cond_lock); - } break; - case MPP_DEC_GET_VPUMEM_USED_COUNT : - case MPP_DEC_SET_OUTPUT_FORMAT : - case MPP_DEC_QUERY : - case MPP_DEC_SET_MAX_USE_BUFFER_SIZE: { - ret = mpp_dec_control(mDec, cmd, param); - } break; - case MPP_DEC_SET_CFG : { - if (mDec) - ret = mpp_dec_control(mDec, cmd, param); - else if (param) { - ret = (MPP_RET)kmpp_obj_update(mDecCfg, param); - } - } break; - case MPP_DEC_GET_CFG : { - if (mDec) - ret = mpp_dec_control(mDec, cmd, param); - else if (param) { - ret = (MPP_RET)kmpp_obj_copy_entry(param, mDecCfg); - } - } break; - default : { - } break; - } - return ret; -} - -MPP_RET Mpp::control_enc(MpiCmd cmd, MppParam param) -{ - mpp_assert(mEnc); - return mpp_enc_control_v2(mEnc, cmd, param); -} - -MPP_RET Mpp::control_isp(MpiCmd cmd, MppParam param) -{ - MPP_RET ret = MPP_NOK; - - mpp_assert(cmd > MPP_ISP_CMD_BASE); - mpp_assert(cmd < MPP_ISP_CMD_END); - - (void)cmd; - (void)param; - return ret; -} - -MPP_RET Mpp::notify(RK_U32 flag) -{ - switch (mType) { - case MPP_CTX_DEC : { - return mpp_dec_notify(mDec, flag); - } break; - case MPP_CTX_ENC : { - return mpp_enc_notify_v2(mEnc, flag); - } break; - default : { - mpp_err("unsupport context type %d\n", mType); - } break; - } - return MPP_NOK; -} - -MPP_RET Mpp::notify(MppBufferGroup group) -{ - MPP_RET ret = MPP_NOK; - - switch (mType) { - case MPP_CTX_DEC : { - if (group == mFrameGroup) - ret = notify(MPP_DEC_NOTIFY_BUFFER_VALID | - MPP_DEC_NOTIFY_BUFFER_MATCH); - } break; - default : { - } break; - } - - return ret; -} diff --git a/mpp/mpp_impl.cpp b/mpp/mpp_impl.c similarity index 90% rename from mpp/mpp_impl.cpp rename to mpp/mpp_impl.c index c0c4c1e2..c8db0c6e 100644 --- a/mpp/mpp_impl.cpp +++ b/mpp/mpp_impl.c @@ -1,18 +1,6 @@ +/* SPDX-License-Identifier: Apache-2.0 OR MIT */ /* - * - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright (c) 2015 Rockchip Electronics Co., Ltd. */ #define MODULE_TAG "mpp_impl" @@ -69,35 +57,36 @@ typedef struct MppDumpImpl_t { RK_U32 idx; } MppDumpImpl; +typedef union OpsArgs_u { + struct MppOpsInitArg_t { + MppCtxType type; + MppCodingType coding; + } init_arg; + + struct MppOpsPktArg_t { + RK_U32 offset; // offset in packet file + RK_U32 length; // pakcet length + RK_S64 pts; + } pkt_arg; + + struct MppOpsFrmArg_t { + RK_U32 fd; + RK_U32 info_change; + RK_U32 error; + RK_U32 discard; + RK_S64 pts; + } frm_arg; + + struct MppOpCtrlArg_t { + MpiCmd cmd; + } ctrl_arg; +} OpsArgs; + typedef struct MppOpsInfo_t { - RK_U32 idx; - RK_U32 id; - RK_S64 time; - - union OpsArgs_u { - struct MppOpsInitArg_t { - MppCtxType type; - MppCodingType coding; - }; - - struct MppOpsPktArg_t { - RK_U32 offset; // offset in packet file - RK_U32 length; // pakcet length - RK_S64 pts; - }; - - struct MppOpsFrmArg_t { - RK_U32 fd; - RK_U32 info_change; - RK_U32 error; - RK_U32 discard; - RK_S64 pts; - }; - - struct MppOpCtrlArg_t { - MpiCmd cmd; - }; - }; + RK_U32 idx; + RK_U32 id; + RK_S64 time; + OpsArgs args; } MppOpsInfo; /* @@ -147,7 +136,7 @@ static RK_U8 fetch_data(RK_U32 fmt, RK_U8 *line, RK_U32 num) value = line[num]; } - return RK_U8(value); + return (RK_U8)value; } static void rearrange_pix(RK_U8 *tmp_line, RK_U8 *base, RK_U32 n) diff --git a/mpp/mpp_info.cpp b/mpp/mpp_info.c similarity index 63% rename from mpp/mpp_info.cpp rename to mpp/mpp_info.c index addb9248..79cb0206 100644 --- a/mpp/mpp_info.cpp +++ b/mpp/mpp_info.c @@ -1,17 +1,6 @@ +/* SPDX-License-Identifier: Apache-2.0 OR MIT */ /* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright (c) 2015 Rockchip Electronics Co., Ltd. */ #define MODULE_TAG "mpp_info" diff --git a/mpp/vproc/CMakeLists.txt b/mpp/vproc/CMakeLists.txt index 81a39b6d..fb18bd6a 100644 --- a/mpp/vproc/CMakeLists.txt +++ b/mpp/vproc/CMakeLists.txt @@ -3,7 +3,7 @@ # ---------------------------------------------------------------------------- # add mpp video process implement # ---------------------------------------------------------------------------- -add_library(mpp_vproc STATIC mpp_dec_vproc.cpp mpp_vproc_dev.c) +add_library(mpp_vproc STATIC mpp_dec_vproc.c mpp_vproc_dev.c) target_link_libraries(mpp_vproc vproc_rga vproc_iep vproc_iep2 ${VPROC_VDPP} mpp_base) add_subdirectory(rga) diff --git a/mpp/vproc/mpp_dec_vproc.cpp b/mpp/vproc/mpp_dec_vproc.c similarity index 98% rename from mpp/vproc/mpp_dec_vproc.cpp rename to mpp/vproc/mpp_dec_vproc.c index 39d256b2..13ecd6ac 100644 --- a/mpp/vproc/mpp_dec_vproc.cpp +++ b/mpp/vproc/mpp_dec_vproc.c @@ -1,17 +1,6 @@ +/* SPDX-License-Identifier: Apache-2.0 OR MIT */ /* - * Copyright 2020 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright (c) 2020 Rockchip Electronics Co., Ltd. */ #define MODULE_TAG "mpp_dec_vproc" @@ -90,7 +79,7 @@ typedef struct MppDecVprocCtxImpl_t { IepCtx iep_ctx; iep_com_ctx *com_ctx; IepCmdParamDeiCfg dei_cfg; - iep2_api_info dei_info; + struct iep2_api_info dei_info; VprocTaskStatus task_status; VprocTaskWait task_wait; @@ -278,7 +267,7 @@ static MPP_RET dec_vproc_set_dei_v1(MppDecVprocCtx *vproc_ctx, MppFrame frm) if (ret) mpp_log_f("IEP_CMD_INIT failed %d\n", ret); - IepCap_t *cap = NULL; + struct IepCap_t *cap = NULL; ret = ctx->com_ctx->ops->control(ctx->iep_ctx, IEP_CMD_QUERY_CAP, &cap); if (ret) mpp_log_f("IEP_CMD_QUERY_CAP failed %d\n", ret); diff --git a/mpp/vproc/vdpp/CMakeLists.txt b/mpp/vproc/vdpp/CMakeLists.txt index 7ecde43c..536e6aa1 100644 --- a/mpp/vproc/vdpp/CMakeLists.txt +++ b/mpp/vproc/vdpp/CMakeLists.txt @@ -12,7 +12,7 @@ set_target_properties(vproc_vdpp PROPERTIES FOLDER "mpp/vproc/vdpp") add_subdirectory(test) # libvdpp.so for hwpq -add_library(vdpp SHARED hwpq_vdpp_proc.c ../../mpp_info.cpp) +add_library(vdpp SHARED hwpq_vdpp_proc.c ../../mpp_info.c) set_target_properties(vdpp PROPERTIES FOLDER "mpp/vproc/vdpp") set_target_properties(vdpp PROPERTIES CLEAN_DIRECT_OUTPUT 1) target_link_libraries(vdpp osal mpp_base kmpp_base vproc_vdpp m)