450 lines
16 KiB
C++
450 lines
16 KiB
C++
/*
|
|||
|
|
* Copyright (C) 2014-2025 Amlogic, Inc. All rights reserved.
|
||
|
|
*
|
||
|
|
* All information contained herein is Amlogic confidential.
|
||
|
|
*
|
||
|
|
* This software is provided to you pursuant to Software License Agreement
|
||
|
|
* (SLA) with Amlogic Inc ("Amlogic"). This software may be used
|
||
|
|
* only in accordance with the terms of this agreement.
|
||
|
|
*
|
||
|
|
* Redistribution and use in source and binary forms, with or without
|
||
|
|
* modification is strictly prohibited without prior written permission from
|
||
|
|
* Amlogic.
|
||
|
|
*
|
||
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
|
*/
|
||
|
|
|
||
|
|
#define LOG_TAG "SubtitleServer"
|
||
|
|
#include "AndroidCallbackMessageQueue.h"
|
||
|
|
|
||
|
|
#include <Parser.h>
|
||
|
|
#include <RemoteData.h>
|
||
|
|
#include <sys/ipc.h>
|
||
|
|
#include <sys/shm.h>
|
||
|
|
|
||
|
|
#include <algorithm>
|
||
|
|
#include <iterator>
|
||
|
|
#include <memory>
|
||
|
|
#include <thread>
|
||
|
|
#include <vector>
|
||
|
|
|
||
|
|
#include "SubtitleLog.h"
|
||
|
|
|
||
|
|
#define EVENT_ON_SUBTITLEDATA_CALLBACK 0xA00000
|
||
|
|
#define EVENT_ON_SUBTITLEAVAILABLE_CALLBACK 0xA00001
|
||
|
|
#define EVENT_ON_VIDEOAFDCHANGE_CALLBACK 0xA00002
|
||
|
|
#define EVENT_ON_MIXVIDEOEVENT_CALLBACK 0xA00003
|
||
|
|
#define EVENT_ON_SUBTITLE_DIMENSION_CALLBACK 0xA00004
|
||
|
|
#define EVENT_ON_SUBTITLE_LANGUAGE_CALLBACK 0xA00005
|
||
|
|
#define EVENT_ON_SUBTITLE_INFO_CALLBACK 0xA00006
|
||
|
|
#define SHMEMORY_ID 0x9FE7
|
||
|
|
|
||
|
|
namespace amlogic {
|
||
|
|
|
||
|
|
static const int MSG_CHECK_SUBDATA = 0;
|
||
|
|
|
||
|
|
// This hal never recreate
|
||
|
|
sp<AndroidCallbackMessageQueue> AndroidCallbackMessageQueue::sInstance = nullptr;
|
||
|
|
sp<AndroidCallbackMessageQueue> AndroidCallbackMessageQueue::Instance() {
|
||
|
|
return sInstance;
|
||
|
|
}
|
||
|
|
|
||
|
|
AndroidCallbackMessageQueue::AndroidCallbackMessageQueue(sp<AndroidCallbackHandler> proxy) {
|
||
|
|
android::AutoMutex _l(mLock);
|
||
|
|
mStopped = false;
|
||
|
|
mProxyHandler = proxy;
|
||
|
|
sInstance = this;
|
||
|
|
initSender();
|
||
|
|
mCallbackLooperThread = std::thread(&AndroidCallbackMessageQueue::looperLoop, this);
|
||
|
|
}
|
||
|
|
|
||
|
|
AndroidCallbackMessageQueue::~AndroidCallbackMessageQueue() {
|
||
|
|
deInitSender();
|
||
|
|
mStopped = true;
|
||
|
|
if (mLooper != nullptr) {
|
||
|
|
mLooper->wake();
|
||
|
|
}
|
||
|
|
// post a message to wakeup and exit.
|
||
|
|
if (mLooper != nullptr) {
|
||
|
|
mLooper->sendMessage(this, Message(MSG_CHECK_SUBDATA));
|
||
|
|
}
|
||
|
|
mCallbackLooperThread.join();
|
||
|
|
sInstance = nullptr;
|
||
|
|
}
|
||
|
|
|
||
|
|
void AndroidCallbackMessageQueue::looperLoop() {
|
||
|
|
mLooper = new Looper(false);
|
||
|
|
mLooper->sendMessageDelayed(100LL, this, Message(MSG_CHECK_SUBDATA));
|
||
|
|
// never exited
|
||
|
|
while (!mStopped && mLooper != nullptr) {
|
||
|
|
mLooper->pollAll(-1);
|
||
|
|
// If mLooper is set to nullptr at some point within the loop, ensure proper handling and
|
||
|
|
// exit the loop
|
||
|
|
if (mLooper == nullptr) {
|
||
|
|
SUBTITLE_LOGE("looperLoop mLooper is Null.");
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
mLooper = nullptr;
|
||
|
|
}
|
||
|
|
|
||
|
|
void AndroidCallbackMessageQueue::handleMessage(const Message &message) {
|
||
|
|
std::unique_ptr<SubtitleData> data(nullptr);
|
||
|
|
|
||
|
|
mLock.lock();
|
||
|
|
if (mSubtitleData.size() > 0) {
|
||
|
|
auto iter = mSubtitleData.begin();
|
||
|
|
std::unique_ptr<SubtitleData> items = std::move(*iter);
|
||
|
|
data.swap(items);
|
||
|
|
mSubtitleData.erase(iter);
|
||
|
|
}
|
||
|
|
if (mSubtitleData.size() > 0) {
|
||
|
|
mLooper->removeMessages(this, MSG_CHECK_SUBDATA);
|
||
|
|
mLooper->sendMessage(this, Message(MSG_CHECK_SUBDATA));
|
||
|
|
} else {
|
||
|
|
mLooper->removeMessages(this, MSG_CHECK_SUBDATA);
|
||
|
|
mLooper->sendMessageDelayed(s2ns(2), this, Message(MSG_CHECK_SUBDATA));
|
||
|
|
}
|
||
|
|
mLock.unlock();
|
||
|
|
|
||
|
|
// processing, outside lock.
|
||
|
|
if (mProxyHandler == nullptr || data == nullptr) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
auto remoteData = std::make_shared<RemoteData>();
|
||
|
|
if (remoteData == nullptr) {
|
||
|
|
SUBTITLE_LOGE("Failed to allocate memory for RemoteData");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
remoteData->callbackType = data->type;
|
||
|
|
switch (remoteData->callbackType) {
|
||
|
|
case EVENT_ON_SUBTITLEDATA_CALLBACK: {
|
||
|
|
remoteData->event = data->x;
|
||
|
|
remoteData->channelId = data->y;
|
||
|
|
SUBTITLE_LOGI("onSubtitleDataEvent EVENT_ON_SUBTITLEDATA_CALLBACK: event:%d, id:%d",
|
||
|
|
data->x, data->y);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case EVENT_ON_SUBTITLEAVAILABLE_CALLBACK: {
|
||
|
|
remoteData->available = data->x;
|
||
|
|
SUBTITLE_LOGI("onSubtitleDataEvent EVENT_ON_SUBTITLEAVAILABLE_CALLBACK: available:%d",
|
||
|
|
data->x);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case EVENT_ON_VIDEOAFDCHANGE_CALLBACK: {
|
||
|
|
remoteData->afd = data->x;
|
||
|
|
remoteData->playerid = data->y;
|
||
|
|
SUBTITLE_LOGI(
|
||
|
|
"onSubtitleDataEvent EVENT_ON_VIDEOAFDCHANGE_CALLBACK:afd:%d, playerid = %d",
|
||
|
|
data->x, data->y);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case EVENT_ON_SUBTITLE_DIMENSION_CALLBACK: {
|
||
|
|
remoteData->width = data->x;
|
||
|
|
remoteData->height = data->y;
|
||
|
|
SUBTITLE_LOGI(
|
||
|
|
"onSubtitleDataEvent EVENT_ON_SUBTITLE_DIMENSION_CALLBACK: width:%d, height:%d",
|
||
|
|
data->x, data->y);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case EVENT_ON_MIXVIDEOEVENT_CALLBACK: {
|
||
|
|
// middleware api do not need this
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
case EVENT_ON_SUBTITLE_LANGUAGE_CALLBACK: {
|
||
|
|
if (data->lang != nullptr) {
|
||
|
|
strncpy(remoteData->lang, data->lang, sizeof(remoteData->lang) - 1);
|
||
|
|
remoteData->lang[sizeof(remoteData->lang) - 1] = '\0';
|
||
|
|
}
|
||
|
|
SUBTITLE_LOGI("onSubtitleDataEvent EVENT_ONSUBTITLE_LANGUAGE_CALLBACK:lang:%s",
|
||
|
|
remoteData->lang);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case EVENT_ON_SUBTITLE_INFO_CALLBACK: {
|
||
|
|
remoteData->what = data->x;
|
||
|
|
remoteData->extra = data->y;
|
||
|
|
SUBTITLE_LOGI("onSubtitleDataEvent EVENT_ONSUBTITLE_INFO_CALLBACK:what:%d, extra:%d",
|
||
|
|
data->x, data->y);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
default: {
|
||
|
|
remoteData->type = data->type;
|
||
|
|
remoteData->width = data->width;
|
||
|
|
remoteData->height = data->height;
|
||
|
|
remoteData->size = data->size;
|
||
|
|
remoteData->isShow = data->isShow;
|
||
|
|
remoteData->x = data->x;
|
||
|
|
remoteData->y = data->y;
|
||
|
|
remoteData->videoWidth = data->videoWidth;
|
||
|
|
remoteData->videoHeight = data->videoHeight;
|
||
|
|
remoteData->shimId = data->shmid;
|
||
|
|
remoteData->objectSegmentId = data->objectSegmentId;
|
||
|
|
|
||
|
|
remoteData->isText = [](int type) -> bool {
|
||
|
|
return type == SubtitleType::TYPE_SUBTITLE_CLOSED_CAPTION ||
|
||
|
|
type == SubtitleType::TYPE_SUBTITLE_SCTE27 ||
|
||
|
|
type == SubtitleType::TYPE_SUBTITLE_SMPTE_TTML ||
|
||
|
|
type == SubtitleType::TYPE_SUBTITLE_DVB_TTML;
|
||
|
|
}(data->type);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
sendData(remoteData);
|
||
|
|
}
|
||
|
|
|
||
|
|
void AndroidCallbackMessageQueue::deInitSender() {
|
||
|
|
if (mDataSender != nullptr) {
|
||
|
|
mDataSender->stop();
|
||
|
|
mDataSender->join();
|
||
|
|
mDataSender = nullptr;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void AndroidCallbackMessageQueue::sendData(std::shared_ptr<RemoteData> remoteData) {
|
||
|
|
if (mDataSender == nullptr && !mStopped) {
|
||
|
|
SUBTITLE_LOGE("mDataSender is nullptr");
|
||
|
|
initSender();
|
||
|
|
if (mDataSender == nullptr) return;
|
||
|
|
}
|
||
|
|
for (auto it : mSendFds) {
|
||
|
|
if (mDataSender != nullptr) {
|
||
|
|
std::string resultStr = mDataSender->sendForResult(
|
||
|
|
it, reinterpret_cast<char *>(remoteData.get()), sizeof(RemoteData));
|
||
|
|
if (resultStr == "-1") {
|
||
|
|
SUBTITLE_LOGE("postData Server is broken, stop!!!");
|
||
|
|
deInitSender();
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
SUBTITLE_LOGE("mDataSender is nullptr");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (remoteData->shimId) {
|
||
|
|
int shmId = shmget(remoteData->shimId, remoteData->size, 0);
|
||
|
|
if (shmctl(shmId, IPC_RMID, NULL) == -1) {
|
||
|
|
SUBTITLE_LOGE("Error removing shm ipc_id=%d, error=%m", shmId);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void AndroidCallbackMessageQueue::initSender() {
|
||
|
|
deInitSender();
|
||
|
|
|
||
|
|
mDataSender = std::make_shared<IpcSocket>(true);
|
||
|
|
mDataSender->start(6666, this);
|
||
|
|
if (!mDataSender->isvalid()) {
|
||
|
|
SUBTITLE_LOGI("Client: initRemoteLocked failed");
|
||
|
|
deInitSender();
|
||
|
|
SUBTITLE_LOGI("mDataSender stop success");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
mDataSender->setEventListener(
|
||
|
|
[&](int fd, void *data) -> int { return handleReceivedReadyData(fd); });
|
||
|
|
}
|
||
|
|
|
||
|
|
int AndroidCallbackMessageQueue::handleReceivedReadyData(int fd) {
|
||
|
|
char retBuf[128];
|
||
|
|
memset(retBuf, 0, sizeof(retBuf));
|
||
|
|
|
||
|
|
if (!IpcSocket::receive(fd, retBuf, sizeof(retBuf))) {
|
||
|
|
SUBTITLE_LOGE("Client broken, fd= %d, remove it.", fd);
|
||
|
|
auto it = std::find(mSendFds.begin(), mSendFds.end(), fd);
|
||
|
|
if (it != mSendFds.end()) {
|
||
|
|
mSendFds.erase(it);
|
||
|
|
}
|
||
|
|
return EventsTracker::RET_REMOVE;
|
||
|
|
}
|
||
|
|
|
||
|
|
SUBTITLE_LOGI("Receive data: %s", retBuf);
|
||
|
|
|
||
|
|
auto reply = [](int fd, const char *ret) {
|
||
|
|
std::string retStr = ret;
|
||
|
|
bool sendStatus = IpcSocket::send(fd, retStr.c_str(), retStr.size());
|
||
|
|
SUBTITLE_LOGI("Reply %s", (sendStatus ? "OK" : "NG"));
|
||
|
|
};
|
||
|
|
|
||
|
|
if (strncmp(retBuf, "recv-ready", 10) == 0) {
|
||
|
|
SUBTITLE_LOGI("New client connected, fd = %d", fd);
|
||
|
|
if (fd != -1) {
|
||
|
|
mSendFds.push_back(fd);
|
||
|
|
reply(fd, "1");
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
reply(fd, "0");
|
||
|
|
}
|
||
|
|
|
||
|
|
return EventsTracker::RET_CONTINUE;
|
||
|
|
}
|
||
|
|
|
||
|
|
void AndroidCallbackMessageQueue::onSubtitleDataEvent(int event, int channelId) {
|
||
|
|
android::AutoMutex _l(mLock);
|
||
|
|
std::unique_ptr<SubtitleData> subtitleData(new SubtitleData);
|
||
|
|
|
||
|
|
subtitleData->type = EVENT_ON_SUBTITLEDATA_CALLBACK;
|
||
|
|
subtitleData->x = event;
|
||
|
|
subtitleData->y = channelId;
|
||
|
|
mSubtitleData.push_back(std::move(subtitleData));
|
||
|
|
mLooper->sendMessage(this, Message(MSG_CHECK_SUBDATA));
|
||
|
|
}
|
||
|
|
void AndroidCallbackMessageQueue::onSubtitleDimension(int width, int height) {
|
||
|
|
android::AutoMutex _l(mLock);
|
||
|
|
// std::unique_ptr<SubtitleData> subtitleData = std::make_unique<SubtitleData>();
|
||
|
|
std::unique_ptr<SubtitleData> subtitleData(new SubtitleData);
|
||
|
|
subtitleData->type = EVENT_ON_SUBTITLE_DIMENSION_CALLBACK;
|
||
|
|
subtitleData->x = width;
|
||
|
|
subtitleData->y = height;
|
||
|
|
mSubtitleData.push_back(std::move(subtitleData));
|
||
|
|
mLooper->sendMessage(this, Message(MSG_CHECK_SUBDATA));
|
||
|
|
}
|
||
|
|
|
||
|
|
void AndroidCallbackMessageQueue::onSubtitleAvailable(int available) {
|
||
|
|
android::AutoMutex _l(mLock);
|
||
|
|
std::unique_ptr<SubtitleData> subtitleData(new SubtitleData);
|
||
|
|
subtitleData->type = EVENT_ON_SUBTITLEAVAILABLE_CALLBACK;
|
||
|
|
subtitleData->x = available;
|
||
|
|
mSubtitleData.push_back(std::move(subtitleData));
|
||
|
|
mLooper->sendMessage(this, Message(MSG_CHECK_SUBDATA));
|
||
|
|
}
|
||
|
|
|
||
|
|
void AndroidCallbackMessageQueue::onVideoAfdChange(int afd, int playerid) {
|
||
|
|
android::AutoMutex _l(mLock);
|
||
|
|
std::unique_ptr<SubtitleData> subtitleData(new SubtitleData);
|
||
|
|
subtitleData->type = EVENT_ON_VIDEOAFDCHANGE_CALLBACK;
|
||
|
|
subtitleData->x = afd;
|
||
|
|
subtitleData->y = playerid;
|
||
|
|
mSubtitleData.push_back(std::move(subtitleData));
|
||
|
|
mLooper->sendMessage(this, Message(MSG_CHECK_SUBDATA));
|
||
|
|
}
|
||
|
|
|
||
|
|
void AndroidCallbackMessageQueue::onMixVideoEvent(int val) {
|
||
|
|
android::AutoMutex _l(mLock);
|
||
|
|
std::unique_ptr<SubtitleData> subtitleData(new SubtitleData);
|
||
|
|
subtitleData->type = EVENT_ON_MIXVIDEOEVENT_CALLBACK;
|
||
|
|
subtitleData->x = val;
|
||
|
|
mSubtitleData.push_back(std::move(subtitleData));
|
||
|
|
mLooper->sendMessage(this, Message(MSG_CHECK_SUBDATA));
|
||
|
|
}
|
||
|
|
|
||
|
|
void AndroidCallbackMessageQueue::onSubtitleLanguage(char *lang) {
|
||
|
|
android::AutoMutex _l(mLock);
|
||
|
|
std::unique_ptr<SubtitleData> subtitleData(new SubtitleData);
|
||
|
|
subtitleData->type = EVENT_ON_SUBTITLE_LANGUAGE_CALLBACK;
|
||
|
|
subtitleData->lang = lang;
|
||
|
|
mSubtitleData.push_back(std::move(subtitleData));
|
||
|
|
mLooper->sendMessage(this, Message(MSG_CHECK_SUBDATA));
|
||
|
|
}
|
||
|
|
|
||
|
|
void AndroidCallbackMessageQueue::onSubtitleInfo(int what, int extra) {
|
||
|
|
android::AutoMutex _l(mLock);
|
||
|
|
std::unique_ptr<SubtitleData> subtitleData(new SubtitleData);
|
||
|
|
subtitleData->type = EVENT_ON_SUBTITLE_INFO_CALLBACK;
|
||
|
|
subtitleData->x = what;
|
||
|
|
subtitleData->y = extra;
|
||
|
|
mSubtitleData.push_back(std::move(subtitleData));
|
||
|
|
mLooper->sendMessage(this, Message(MSG_CHECK_SUBDATA));
|
||
|
|
}
|
||
|
|
|
||
|
|
int AndroidCallbackMessageQueue::copyShareMemory(const char *data, int size) {
|
||
|
|
int shmid;
|
||
|
|
char *shmaddr = nullptr;
|
||
|
|
if ((0 == size) || (data == nullptr)) {
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
// key_t key = ftok("/tmp/subtitle",0x03);
|
||
|
|
// shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|IPC_EXCL|0666 ) ;
|
||
|
|
shmid = shmget(MIPC_SUBTITLE_PORTID, size, IPC_CREAT | IPC_EXCL | 0666);
|
||
|
|
if (shmid < 0) {
|
||
|
|
SUBTITLE_LOGE("get shm ipc_id error size=%d,shmid=%d, error=%s", size, shmid,
|
||
|
|
strerror(errno));
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
SUBTITLE_LOGI("AndroidCallbackMessageQueue shmid=%d", shmid);
|
||
|
|
shmaddr = (char *)shmat(shmid, NULL, 0);
|
||
|
|
if (shmaddr == nullptr) {
|
||
|
|
SUBTITLE_LOGE("AndroidCallbackMessageQueue Error: shmat addr error");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
memcpy(shmaddr, data, size);
|
||
|
|
shmdt(shmaddr);
|
||
|
|
return MIPC_SUBTITLE_PORTID;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool AndroidCallbackMessageQueue::postDisplayData(const char *data, int type, int x, int y,
|
||
|
|
int width, int height, int videoWidth,
|
||
|
|
int videoHeight, int size, int cmd,
|
||
|
|
int objectSegmentId) {
|
||
|
|
SUBTITLE_LOGE(
|
||
|
|
" AndroidCallbackMessageQueue::postDisplayData x=%d,y=%d,width=%d,height=%d,size=%d\n", x,
|
||
|
|
y, width, height, size);
|
||
|
|
|
||
|
|
/*sp<HidlMemory> mem;
|
||
|
|
sp<IAllocator> ashmemAllocator = IAllocator::getService("ashmem");
|
||
|
|
|
||
|
|
bool allocRes = false;
|
||
|
|
|
||
|
|
Return<void> r = ashmemAllocator->allocate(size+1024, [&](bool success, const hidl_memory& _mem)
|
||
|
|
{ if (success) { mem = HidlMemory::getInstance(_mem); sp<IMemory> memory = mapMemory(_mem); if
|
||
|
|
(memory == nullptr) { SUBTITLE_LOGE("map Memory Failed!!"); return; // we may need status!
|
||
|
|
}
|
||
|
|
|
||
|
|
memory->update();
|
||
|
|
if (data != nullptr) memcpy(memory->getPointer(), data, size);
|
||
|
|
memory->commit();
|
||
|
|
allocRes = true;
|
||
|
|
} else {
|
||
|
|
SUBTITLE_LOGE("alloc memory Fail");
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
IMemoryHeap mMemHeap = new MemoryHeapBase(size+1024, 0, "Heap Name");
|
||
|
|
if (mMemHeap->getHeapID() < 0) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
IMemory* mMemBase = new MemoryBase(mMemHeap, 0, size+1024);
|
||
|
|
//void * addr = mMemHeap ->base();
|
||
|
|
if (mMemBase != nullptr) {
|
||
|
|
memcpy(mMemBase->base(), data, size);
|
||
|
|
}*/
|
||
|
|
// if (r.isOk() && allocRes) {
|
||
|
|
// int shmid = 1234;///copyShareMemory(data, size);
|
||
|
|
int shmid = copyShareMemory(data, size);
|
||
|
|
if (shmid < 0) {
|
||
|
|
SUBTITLE_LOGE("Fail to process share memory!!");
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
android::AutoMutex _l(mLock);
|
||
|
|
std::unique_ptr<SubtitleData> subtitleData(new SubtitleData);
|
||
|
|
subtitleData->type = type;
|
||
|
|
subtitleData->x = x;
|
||
|
|
subtitleData->y = y;
|
||
|
|
subtitleData->width = width;
|
||
|
|
subtitleData->height = height;
|
||
|
|
subtitleData->videoWidth = videoWidth;
|
||
|
|
subtitleData->videoHeight = videoHeight;
|
||
|
|
subtitleData->size = size;
|
||
|
|
subtitleData->isShow = cmd;
|
||
|
|
// subtitleData->mem = mMemBase;
|
||
|
|
subtitleData->objectSegmentId =
|
||
|
|
objectSegmentId; // objectSegmentId: the current number object segment object.
|
||
|
|
subtitleData->shmid = shmid;
|
||
|
|
mSubtitleData.push_back(std::move(subtitleData));
|
||
|
|
mLooper->sendMessage(this, Message(MSG_CHECK_SUBDATA));
|
||
|
|
|
||
|
|
SUBTITLE_LOGI("in postDisplayData: type:%d, width=%d, height=%d size=%d objectSegmentId=%d",
|
||
|
|
type, width, height, size, objectSegmentId);
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
} // namespace amlogic
|