From 027f647eb8bd400175c40a015e61583904e29d17 Mon Sep 17 00:00:00 2001 From: ChenHengming Date: Wed, 26 Aug 2015 03:19:32 +0000 Subject: [PATCH] [mpp]: add mpp_thread.cpp, add mutex_destroy to mpp_allocator, add codec thread and hal thread prototype git-svn-id: https://10.10.10.66:8443/svn/MediaProcessPlatform/trunk/mpp@163 6e48237b-75ef-9749-8fc9-41990f28c85a --- mpp/mpp.cpp | 93 ++++++++++++++++++++++++++++++++++++------ mpp/mpp.h | 11 +++-- osal/CMakeLists.txt | 1 + osal/inc/mpp_thread.h | 35 ++++++++++++++++ osal/mpp_allocator.cpp | 1 + osal/mpp_thread.cpp | 81 ++++++++++++++++++++++++++++++++++++ 6 files changed, 204 insertions(+), 18 deletions(-) create mode 100644 osal/mpp_thread.cpp diff --git a/mpp/mpp.cpp b/mpp/mpp.cpp index f3d0e8e1..acd10137 100644 --- a/mpp/mpp.cpp +++ b/mpp/mpp.cpp @@ -26,6 +26,41 @@ #include "mpp_packet.h" #include "mpp_packet_impl.h" +#if 0 +static void *thread_hal(void *data) +{ + Mpp *mpp = (Mpp*)data; + mpp_list *frames = mpp->frames; + MppPacketImpl packet; + MppFrame frame; + + while () { + /* + * hal thread wait for dxva interface intput firt + */ + // get_config + // register genertation + + /* + * wait previous register set done + */ + // hal->get_regs; + + /* + * send current register set to hardware + */ + // hal->put_regs; + + /* + * mark previous buffer is complete + */ + // signal() + // mark frame in output queue + // wait up output thread to get a output frame + } +} +#endif + static void *thread_dec(void *data) { Mpp *mpp = (Mpp*)data; @@ -34,7 +69,7 @@ static void *thread_dec(void *data) MppPacketImpl packet; MppFrame frame; - while (mpp->thread_running) { + while (mpp->thread_codec_running) { if (packets->list_size()) { /* * packet will be destroyed outside, here just copy the content @@ -42,8 +77,42 @@ static void *thread_dec(void *data) packets->del_at_head(&packet, sizeof(packet)); /* - * generate a new frame, copy the pointer to list + * 1. send packet data to parser + * + * parser functioin input / output + * input: packet data + * dxva output slot + * output: dxva output slot + * buffer usage informatioin */ + + // decoder->parser->parse; + + /* + * 2. do buffer operation according to usage information + * + * possible case: + * a. normal case + * - wait and alloc a normal frame buffer + * b. field mode case + * - two field may reuse a same buffer, no need to alloc + * c. info change case + * - need buffer in different side, need to send a info change + * frame to hal loop. + */ + + // mpp->get_buffer + + /* + * 3. send dxva output information and buffer information to hal thread + * combinate video codec dxva output and buffer information + */ + + // hal->wait_prev_done; + // hal->send_config; + + + // for test mpp_frame_init(&frame); frames->add_at_tail(&frame, sizeof(frame)); } @@ -62,7 +131,7 @@ static void *thread_enc(void *data) size_t size = SZ_1M; char *buf = mpp_malloc(char, size); - while (mpp->thread_running) { + while (mpp->thread_codec_running) { if (frames->list_size()) { frames->del_at_head(&frame, sizeof(frame)); @@ -77,8 +146,8 @@ static void *thread_enc(void *data) Mpp::Mpp(MppCtxType type) : packets(NULL), frames(NULL), - thread_running(0), - thread_reset(0), + thread_codec_running(0), + thread_codec_reset(0), status(0) { switch (type) { @@ -100,7 +169,7 @@ Mpp::Mpp(MppCtxType type) Mpp::~Mpp () { - if (thread_running) + if (thread_codec_running) thread_stop(); if (packets) delete packets; @@ -108,25 +177,25 @@ Mpp::~Mpp () delete frames; } -void Mpp::thread_start(MppThread func) +void Mpp::thread_start(MppThreadFunc func) { - if (!thread_running) { + if (!thread_codec_running) { pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - if (pthread_create(&thread, &attr, func, (void*)this)) + if (pthread_create(&thread_codec, &attr, func, (void*)this)) status = MPP_ERR_FATAL_THREAD; else - thread_running = 1; + thread_codec_running = 1; pthread_attr_destroy(&attr); } } void Mpp::thread_stop() { - thread_running = 0; + thread_codec_running = 0; void *dummy; - pthread_join(thread, &dummy); + pthread_join(thread_codec, &dummy); } MPP_RET Mpp::put_packet(MppPacket packet) diff --git a/mpp/mpp.h b/mpp/mpp.h index 0032857e..12e53dd5 100644 --- a/mpp/mpp.h +++ b/mpp/mpp.h @@ -21,8 +21,6 @@ #include "mpp_list.h" #include "mpp_thread.h" -typedef void *(*MppThread)(void *); - class Mpp { public: Mpp(MppCtxType type); @@ -31,9 +29,10 @@ public: mpp_list *packets; mpp_list *frames; - pthread_t thread; - RK_S32 thread_running; - RK_S32 thread_reset; + pthread_t thread_codec; + pthread_t thread_hal; + RK_S32 thread_codec_running; + RK_S32 thread_codec_reset; RK_U32 status; @@ -44,7 +43,7 @@ public: MPP_RET get_packet(MppPacket *packet); private: - void thread_start(MppThread func); + void thread_start(MppThreadFunc func); void thread_stop(); Mpp(); diff --git a/osal/CMakeLists.txt b/osal/CMakeLists.txt index ad57c17b..9f78b7d2 100644 --- a/osal/CMakeLists.txt +++ b/osal/CMakeLists.txt @@ -13,6 +13,7 @@ include_directories(.) add_library(osal STATIC mpp_allocator.cpp + mpp_thread.cpp mpp_common.cpp mpp_time.cpp mpp_list.cpp diff --git a/osal/inc/mpp_thread.h b/osal/inc/mpp_thread.h index 6661aa20..cc81bab5 100644 --- a/osal/inc/mpp_thread.h +++ b/osal/inc/mpp_thread.h @@ -46,4 +46,39 @@ #endif +typedef void *(*MppThreadFunc)(void *); + +typedef enum { + MPP_THREAD_UNINITED, + MPP_THREAD_RUNNING, + MPP_THREAD_WAITING, + MPP_THREAD_STOPPING, +} MppThreadStatus; + +#ifdef __cplusplus +class MppThread { +public: + MppThread(MppThreadFunc func, void *ctx); + ~MppThread(); + + void lock(); + void unlock(); + void wait(); + void signal(); + +private: + pthread_t thread; + pthread_mutex_t thread_lock; + pthread_cond_t condition; + + MppThreadStatus status; + MppThreadFunc function; + void *context; + + MppThread(); + MppThread(const MppThread &); + MppThread &operator=(const MppThread &); +}; +#endif + #endif /*__MPP_THREAD_H__*/ diff --git a/osal/mpp_allocator.cpp b/osal/mpp_allocator.cpp index f121d217..90a2db0e 100644 --- a/osal/mpp_allocator.cpp +++ b/osal/mpp_allocator.cpp @@ -120,6 +120,7 @@ MPP_RET mpp_alloctor_put(MppAllocator *allocator) *allocator = NULL; if (p->os_api.close) p->os_api.close(p->ctx); + pthread_mutex_destroy(&p->lock); if (p) mpp_free(p); diff --git a/osal/mpp_thread.cpp b/osal/mpp_thread.cpp new file mode 100644 index 00000000..83bb3900 --- /dev/null +++ b/osal/mpp_thread.cpp @@ -0,0 +1,81 @@ +/* + * 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. + */ + +#define MODULE_TAG "mpp_thread" + +#include "mpp_log.h" +#include "mpp_thread.h" + +#define MPP_THREAD_DBG_FUNCTION (0x00000001) + +static RK_U32 thread_debug = 0; + +#define thread_dbg(flag, fmt, ...) mpp_dbg(thread_debug, flag, fmt, ## __VA_ARGS__) + +MppThread::MppThread(MppThreadFunc func, void *ctx) + : status(MPP_THREAD_UNINITED) +{ + pthread_mutexattr_t mutex; + pthread_mutexattr_init(&mutex); + pthread_mutexattr_settype(&mutex, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&thread_lock, &mutex); + pthread_mutexattr_destroy(&mutex); + + pthread_cond_init(&condition, NULL); + + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + + if (0 == pthread_create(&thread, &attr, func, ctx)) { + status = MPP_THREAD_RUNNING; + thread_dbg(MPP_THREAD_DBG_FUNCTION, "thread %p context %p create success\n", + func, ctx); + } + + pthread_attr_destroy(&attr); + +} + +MppThread::~MppThread() +{ + status = MPP_THREAD_STOPPING; + void *dummy; + pthread_join(thread, &dummy); + thread_dbg(MPP_THREAD_DBG_FUNCTION, "thread %p context %p destroy success\n", + function, context); +} + +void MppThread::lock() +{ + pthread_mutex_lock(&thread_lock); +} + +void MppThread::unlock() +{ + pthread_mutex_unlock(&thread_lock); +} + +void MppThread::wait() +{ + pthread_cond_wait(&condition, &thread_lock); +} + +void MppThread::signal() +{ + pthread_cond_signal(&condition); +} +