/* * 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 &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 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 &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); } } };