From 07352a511c49ee6360df494c73bdf3d3ea29f810 Mon Sep 17 00:00:00 2001 From: ChenHengming Date: Fri, 22 Jul 2016 01:05:39 +0000 Subject: [PATCH] [mpp_enc]: fix memory leak and flow error in Android recording flow git-svn-id: https://10.10.10.66:8443/svn/MediaProcessPlatform/trunk/mpp@1068 6e48237b-75ef-9749-8fc9-41990f28c85a --- mpp/base/mpp_meta.cpp | 1 + mpp/base/mpp_task_impl.cpp | 3 ++- mpp/codec/mpp_enc.cpp | 22 +++++++++++++++------- mpp/mpp.cpp | 25 +++++++++++++++++-------- mpp/mpp.h | 3 +++ 5 files changed, 38 insertions(+), 16 deletions(-) diff --git a/mpp/base/mpp_meta.cpp b/mpp/base/mpp_meta.cpp index 446ae73c..40b12eee 100644 --- a/mpp/base/mpp_meta.cpp +++ b/mpp/base/mpp_meta.cpp @@ -316,6 +316,7 @@ static MPP_RET get_val_by_key(MppMetaImpl *meta, MppMetaKey key, MppMetaType typ MppMetaNode *node = service->find_node(meta, index); if (node) { *val = node->val; + service->put_node(node); ret = MPP_OK; } return ret; diff --git a/mpp/base/mpp_task_impl.cpp b/mpp/base/mpp_task_impl.cpp index 08aafaa1..70b61171 100644 --- a/mpp/base/mpp_task_impl.cpp +++ b/mpp/base/mpp_task_impl.cpp @@ -282,7 +282,8 @@ MPP_RET mpp_task_queue_deinit(MppTaskQueue queue) if (p->tasks) { for (RK_S32 i = 0; i < p->task_count; i++) { /* we must ensure that all task return to init status */ - mpp_assert(p->tasks[i].status == MPP_INPUT_PORT); + mpp_assert(p->tasks[i].status == MPP_INPUT_PORT || + p->tasks[i].status == MPP_INPUT_HOLD); mpp_meta_put(p->tasks[i].meta); } mpp_free(p->tasks); diff --git a/mpp/codec/mpp_enc.cpp b/mpp/codec/mpp_enc.cpp index 86e4b695..eaab5f50 100644 --- a/mpp/codec/mpp_enc.cpp +++ b/mpp/codec/mpp_enc.cpp @@ -28,7 +28,7 @@ #include "mpp_packet_impl.h" #include "hal_h264e_api.h" -static MPP_RET release_task_in_port(MppPort output) +static MPP_RET release_task_in_port(MppPort port) { MPP_RET ret = MPP_OK; MppPacket packet = NULL; @@ -36,23 +36,26 @@ static MPP_RET release_task_in_port(MppPort output) MppTask mpp_task; do { - ret = mpp_port_dequeue(output, &mpp_task); + ret = mpp_port_dequeue(port, &mpp_task); if (ret) break; if (mpp_task) { packet = NULL; frame = NULL; - mpp_task_meta_get_frame (mpp_task, MPP_META_KEY_INPUT_FRM, &frame); + ret = mpp_task_meta_get_frame(mpp_task, MPP_META_KEY_INPUT_FRM, &frame); if (frame) { mpp_frame_deinit(&frame); frame = NULL; } - mpp_task_meta_get_packet(mpp_task, MPP_META_KEY_OUTPUT_PKT, &packet); + ret = mpp_task_meta_get_packet(mpp_task, MPP_META_KEY_OUTPUT_PKT, &packet); if (packet) { - mpp_frame_deinit(&packet); + mpp_packet_deinit(&packet); packet = NULL; } + + mpp_port_enqueue(port, mpp_task); + mpp_task = NULL; } else break; } while (1); @@ -134,13 +137,17 @@ void *mpp_enc_control_thread(void *data) if (mpp_frame_get_eos(frame)) mpp_packet_set_eos(packet); - // enqueue task back to input input + /* + * first clear output packet + * then enqueue task back to input port + * final user will release the mpp_frame they had input + */ + mpp_task_meta_set_frame(mpp_task, MPP_META_KEY_INPUT_FRM, frame); mpp_port_enqueue(input, mpp_task); mpp_task = NULL; // send finished task to output port mpp_port_dequeue(output, &mpp_task); - mpp_task_meta_set_frame(mpp_task, MPP_META_KEY_INPUT_FRM, frame); mpp_task_meta_set_packet(mpp_task, MPP_META_KEY_OUTPUT_PKT, packet); { @@ -162,6 +169,7 @@ void *mpp_enc_control_thread(void *data) } // clear remain task in output port + release_task_in_port(mpp->mInputPort); release_task_in_port(input); release_task_in_port(mpp->mOutputPort); diff --git a/mpp/mpp.cpp b/mpp/mpp.cpp index 67cc4bc8..ebabdba1 100644 --- a/mpp/mpp.cpp +++ b/mpp/mpp.cpp @@ -60,6 +60,7 @@ Mpp::Mpp() mInputBlock(0), mOutputBlock(0), mMultiFrame(0), + mInputTask(NULL), mStatus(0), mParserFastMode(0), mParserNeedSplit(0), @@ -282,7 +283,7 @@ MPP_RET Mpp::put_frame(MppFrame frame) return MPP_NOK; MPP_RET ret = MPP_NOK; - MppTask task = NULL; + MppTask task = mInputTask; do { if (NULL == task) { @@ -317,11 +318,26 @@ MPP_RET Mpp::put_frame(MppFrame frame) while (MPP_NOK == mpp_port_can_dequeue(mInputPort)) { msleep(2); } + + ret = dequeue(MPP_PORT_INPUT, &task); + if (ret) { + mpp_log_f("failed to dequeue from input port ret %d\n", ret); + break; + } + + mpp_assert(task); + ret = mpp_task_meta_get_frame(task, MPP_META_KEY_INPUT_FRM, &frame); + if (frame) { + mpp_frame_deinit(&frame); + frame = NULL; + } } break; } while (1); + mInputTask = task; + return ret; } @@ -332,7 +348,6 @@ MPP_RET Mpp::get_packet(MppPacket *packet) MPP_RET ret = MPP_OK; MppTask task = NULL; - MppFrame frame = NULL; do { if (NULL == task) { @@ -355,12 +370,6 @@ MPP_RET Mpp::get_packet(MppPacket *packet) mpp_assert(task); - mpp_task_meta_get_frame(task, MPP_META_KEY_INPUT_FRM, &frame); - if (frame) { - mpp_frame_deinit(&frame); - frame = NULL; - } - ret = mpp_task_meta_get_packet(task, MPP_META_KEY_OUTPUT_PKT, packet); if (ret) { mpp_log_f("failed to get output packet from task ret %d\n", ret); diff --git a/mpp/mpp.h b/mpp/mpp.h index 5ebe6f2a..cc97d212 100644 --- a/mpp/mpp.h +++ b/mpp/mpp.h @@ -136,6 +136,9 @@ private: RK_U32 mOutputBlock; RK_U32 mMultiFrame; + // task for put_frame / put_packet + MppTask mInputTask; + RK_U32 mStatus; /* decoder paramter before init */