You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

212 lines
5.3 KiB

/*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2020. All rights reserved.
* Description: NxMediaMsg class
* Author: NxPlayer software group
* Create: 2019-07-15
*/
#define LOG_NDEBUG 0
#define LOG_TAG "NP_SysMsg"
#include "NxMediaMsg.h"
#include "NxMediaDefine.h"
#include "NxMediaPlayerManage.h"
namespace android {
NxMediaMsg::NxMediaMsg(int idx)
: m_looper(nullptr),
m_isExit(0),
m_enableNxMediaMsg(true),
m_instIdx(idx)
{
Init();
HLOGI("new NxMediaMsg");
}
NxMediaMsg::~NxMediaMsg()
{
HLOGI("delete NxMediaMsg");
}
void NxMediaMsg::Init()
{
m_looper = new (std::nothrow) NxLooper(m_instIdx);
if (m_looper == nullptr) {
HLOGE("init NxMediaMsg failure");
return;
}
m_looper->Init();
status_t ret = run("NxMediaPlayer_NxMsg", PRIORITY_BACKGROUND);
if (ret != NO_ERROR) {
HLOGW("init NxMediaMsg success");
}
}
status_t NxMediaMsg::PostMessage(const sp<NxMessageHandler> &handler, NxMessage &msg)
{
AutoMutex autoMutex(m_lock);
if (m_isExit != 0) {
HLOGE("NxMediaMsg is exit, cannot PostMessage");
if (msg.mBuffer && msg.mDataLen > 0) {
delete[] msg.mBuffer;
msg.mBuffer = nullptr;
}
return OK;
}
if (m_looper == nullptr) {
return OK;
}
size_t count = mMsgPackages.size();
NxMessagePackage msgPackage(handler, msg);
mMsgPackages.insertAt(msgPackage, count, 1);
m_looper->WakeUp();
return OK;
}
int NxMediaMsg::ReadMsg(int timeoutMs)
{
int ret = POLL_WAKE;
if (m_looper == nullptr) {
return ret;
}
m_looper->Wait(timeoutMs);
ret = ProcessMessagePackages(ret);
return ret;
}
status_t NxMediaMsg::EnableNxMediaMsg(bool enable)
{
AutoMutex autoMutex(m_lock);
m_enableNxMediaMsg = enable;
HLOGI("m_enableNxMediaMsg=%d", m_enableNxMediaMsg);
return OK;
}
int NxMediaMsg::Flush(int timeoutMs)
{
for (;;) {
int ret = ReadMsg(timeoutMs);
if (ret != POLL_CALLBACK) {
return ret;
}
}
}
int NxMediaMsg::ProcessMessagePackages(int result)
{
int ret = result;
while (1) {
m_lock.lock();
if (mMsgPackages.size() == 0) {
m_lock.unlock();
break;
}
const NxMessagePackage &messagePackage = mMsgPackages.itemAt(0);
sp<NxMessageHandler> handler = messagePackage.handler;
NxMessage message = messagePackage.message;
mMsgPackages.removeAt(0);
m_lock.unlock();
if (handler.get() != nullptr && (m_enableNxMediaMsg || message.mMsg == NX_MSG_EXIT)) {
handler->HandleMessage(message);
} else {
HLOGW("flush msg(%d, %d, %d)", message.mMsg, message.mPara1, message.mPara2);
if (message.mBuffer && message.mDataLen > 0) {
delete[] message.mBuffer;
message.mBuffer = nullptr;
}
}
ret = POLL_CALLBACK;
}
return ret;
}
void NxMediaMsg::MessageProcess()
{
const int pollTimeOut = 50; /* ms */
const int dumpLogThreshold = 40; /* wait 40 times and every wait about 50 ms to dump heart beat */
unsigned int poolWakeNum = 0;
while (m_isExit == 0) {
int32_t ret = ReadMsg(pollTimeOut);
switch (ret) {
case POLL_WAKE:
if (poolWakeNum++ % dumpLogThreshold == 0) {
HLOGD("POLL_WAKE heart beat");
} else if (poolWakeNum > UINT_MAX - 1) {
poolWakeNum = 0;
}
continue;
case POLL_CALLBACK:
continue;
default:
HLOGW("unknown status %d", ret);
break;
}
}
HLOGI("thread exit loop, flush");
Flush(pollTimeOut);
}
bool NxMediaMsg::threadLoop()
{
HLOGD("threadLoop in");
MessageProcess();
HLOGD("threadLoop out");
return OK;
}
NxMessageHandler::~NxMessageHandler()
{
}
NxMediaMsgHandle::NxMediaMsgHandle(sp<NxMediaMsg> &msg, NxMediaPlayerManage *player, int idx)
: m_nxMsg(msg), m_hmplayer(player), m_instIdx(idx)
{
HLOGD("new NxMediaMsgHandle");
}
NxMediaMsgHandle::~NxMediaMsgHandle()
{
HLOGD("delete NxMediaMsgHandle");
}
void NxMediaMsgHandle::SetCbPlayer(NxMediaPlayerManage *player)
{
HLOGD("SetCbPlayer player");
Mutex::Autolock l(m_cbLock);
m_hmplayer = player;
}
void NxMediaMsgHandle::HandleMessage(NxMessage &message)
{
Mutex::Autolock l(m_cbLock);
if (message.mMsg == NX_MSG_EXIT) {
HLOGI("handle send event MSG_EXIT");
m_nxMsg->m_isExit = true;
}
if (message.mBuffer && message.mDataLen > 0) {
if (m_nxMsg->m_isExit != true && m_hmplayer != nullptr) {
Parcel parcelObj;
parcelObj.setData(message.mBuffer, message.mDataLen);
m_hmplayer->notifyFunc(message.mMsg, message.mPara1, message.mPara2, &parcelObj);
} else {
HLOGW("cannot notify msg, m_isExit=%d", m_nxMsg->m_isExit);
}
delete[] message.mBuffer;
message.mBuffer = nullptr;
} else if (m_nxMsg->m_isExit != true && m_hmplayer != nullptr) {
m_hmplayer->notifyFunc(message.mMsg, message.mPara1, message.mPara2);
} else {
HLOGW("cannot notify msg(%d, %d, %d), m_isExit=%d",
message.mMsg, message.mPara1, message.mPara1, m_nxMsg->m_isExit);
}
}
};