1551 lines
50 KiB
C++
1551 lines
50 KiB
C++
/*
|
|
* Copyright (c) 2026 Amlogic, Inc. All rights reserved.
|
|
*
|
|
* This source code is subject to the terms and conditions defined in the
|
|
* file 'LICENSE' which is part of this source code package.
|
|
*
|
|
* Description: Amlogic MP SDK Player Client Implementation
|
|
*/
|
|
#ifdef CONFIG_AMP_SERVER
|
|
#define LOG_TAG "Aml_MP_PlayerClient"
|
|
|
|
#include "Aml_MP/Aml_MP.h"
|
|
#include "Aml_MP_PlayerClient.h"
|
|
#include "utils/AmlMpUtils.h"
|
|
#include "utils/AmlMpLog.h"
|
|
#include "cas/AmlDvbCasHal.h"
|
|
#include "cas/AmlCasBase.h"
|
|
#include "AmlTsParser.h"
|
|
#include "AmlMpAidlConvert.h"
|
|
#include "Amlsysfsutils.h"
|
|
|
|
#include <vector>
|
|
#include <ctime>
|
|
|
|
#include <cutils/properties.h>
|
|
#include <binder/IServiceManager.h>
|
|
#include <binder/IBinder.h>
|
|
#include <binder/IInterface.h>
|
|
#include <utils/String16.h>
|
|
#include <android/binder_manager.h>
|
|
#include <android/binder_interface_utils.h>
|
|
#include <aidl/com/amlogic/aml_mp/player/IAmlMpPlayer.h>
|
|
|
|
#define TEMP_BUFFER_SIZE (188 * 100)
|
|
|
|
using android::sp;
|
|
using android::IBinder;
|
|
using android::IServiceManager;
|
|
using android::defaultServiceManager;
|
|
using android::String16;
|
|
using namespace com::amlogic::aml_mp::player;
|
|
|
|
void AmpMpPlayerDumpFile(const char *name, const uint8_t* data, int32_t len)
|
|
{
|
|
if (!property_get_bool("vendor.media.aml_mp.client.dump", false)) {
|
|
return;
|
|
}
|
|
|
|
char saveName[100] = { 0 };
|
|
snprintf(saveName, sizeof(saveName), "/data/%s_client.ts", name);
|
|
FILE *dumpFile = fopen(saveName, "ab");
|
|
if (dumpFile == nullptr) {
|
|
ALOGE("%s open dump ts failed:%s", name, strerror(errno));
|
|
return;
|
|
}
|
|
|
|
fwrite(data, 1, len, dumpFile);
|
|
fflush(dumpFile);
|
|
fclose(dumpFile);
|
|
}
|
|
|
|
Aml_MP_PlayerClient::Aml_MP_PlayerClient(const Aml_MP_PlayerCreateParams* createParams)
|
|
: mCreateParams(*createParams),
|
|
mServiceConnected(false) {
|
|
snprintf(mName, sizeof(mName), "%s", LOG_TAG);
|
|
MLOGI("enter %s", __FUNCTION__);
|
|
int32_t result = -1;
|
|
|
|
if (mCreateParams.drmMode != AML_MP_INPUT_STREAM_SECURE_MEMORY) {
|
|
InitBufPool();
|
|
}
|
|
connectToService();
|
|
if (!mServiceConnected) {
|
|
MLOGE("connect server fail");
|
|
return;
|
|
}
|
|
|
|
mWriteBuffer = new aml_mp::AmlMpBuffer(TEMP_BUFFER_SIZE);
|
|
mWriteBuffer->setRange(0, 0);
|
|
|
|
mTsBuffer.init(aml_mp::AmlMpConfig::instance().mWriteBufferSize * 1024 * 1024); // 2M
|
|
|
|
AmlMpPlayerCreateParams aidlParams{};
|
|
convertToAidl(aidlParams, &mCreateParams);
|
|
auto status = mPlayerService->createPlayer(aidlParams, &result);
|
|
if (status.isOk()) {
|
|
player_id = result;
|
|
snprintf(mName, sizeof(mName), "%s_%p_%d", LOG_TAG, this, player_id);
|
|
} else {
|
|
MLOGE("server create player fail");
|
|
}
|
|
|
|
if (mBufPoolHasInit && !setBufPool2Servier()) {
|
|
MLOGI("set buf pool to server success.");
|
|
} else {
|
|
MLOGE("set buf pool to server fail.");
|
|
}
|
|
|
|
mWaitingEcmMode = (aml_mp::WaitingEcmMode)aml_mp::AmlMpConfig::instance().mWaitingEcmMode;
|
|
mWaitingEcmAtServer = property_get_bool("vendor.media.waitEcmServer.enable", mWaitingEcmAtServer);
|
|
MLOGI("ecmMode:%d, waitEcm from %s", mWaitingEcmMode, mWaitingEcmAtServer ? "server" : "client");
|
|
if (mWaitingEcmAtServer) {
|
|
if (makeCallbackToServer() != 0) {
|
|
MLOGE("why make callback fail");
|
|
}
|
|
}
|
|
|
|
MLOGI("exit %s, ", __FUNCTION__);
|
|
}
|
|
|
|
Aml_MP_PlayerClient::~Aml_MP_PlayerClient() {
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
MLOGI("call ~Aml_MP_PlayerClient");
|
|
int32_t result = -1;
|
|
if (mServiceConnected && mPlayerService && player_id > 0) {
|
|
MLOGI("[%s] destroy player %d", mName, player_id);
|
|
auto status = mPlayerService->destroyPlayer(player_id, &result);
|
|
}
|
|
|
|
if (mRawBinder && mRecipient) {
|
|
AIBinder_unlinkToDeath(mRawBinder, mRecipient, this);
|
|
}
|
|
|
|
if (mRecipient) {
|
|
AIBinder_DeathRecipient_delete(mRecipient);
|
|
}
|
|
|
|
mRawBinder = nullptr;
|
|
mRecipient = nullptr;
|
|
|
|
FreeBufPool();
|
|
clearTunnelId();
|
|
|
|
stopDescrambling_l();
|
|
|
|
mIsStandaloneCas = false;
|
|
mCasHandle.clear();
|
|
}
|
|
|
|
bool Aml_MP_PlayerClient::connectToService() {
|
|
if (!mBufPoolHasInit) {
|
|
MLOGE("not alloc buf pool, please check it.");
|
|
return false;
|
|
}
|
|
|
|
if (mServiceDead) {
|
|
return false;
|
|
}
|
|
|
|
if (mServiceConnected) {
|
|
return true;
|
|
}
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
const std::string serverName = std::string(IAmlMpPlayer::descriptor) + "/default";
|
|
MLOGI("connect to the service:%s", serverName.c_str());
|
|
mRawBinder = AServiceManager_waitForService(serverName.c_str());
|
|
if (!mRawBinder) {
|
|
MLOGE("service not found");
|
|
return false;
|
|
}
|
|
|
|
ndk::SpAIBinder binder(mRawBinder);
|
|
mPlayerService = IAmlMpPlayer::fromBinder(binder);
|
|
if (mPlayerService == nullptr) {
|
|
MLOGE("[%s] failed to obtain IAmlMpPlayer", mName);
|
|
return false;
|
|
}
|
|
|
|
if (!mRecipient) {
|
|
mRecipient = AIBinder_DeathRecipient_new(Aml_MP_PlayerClient::onBinderDied);
|
|
int ret = AIBinder_linkToDeath(mRawBinder, mRecipient, this);
|
|
if (ret != STATUS_OK) {
|
|
MLOGE("linkToDeath failed: %d", ret);
|
|
}
|
|
}
|
|
|
|
mServiceConnected = true;
|
|
MLOGI("connect to the service:%s successful", serverName.c_str());
|
|
return true;
|
|
}
|
|
|
|
void Aml_MP_PlayerClient::onBinderDied(void *cookie) {
|
|
ALOGE("IAmlMpPlayerService died!");
|
|
auto* self = static_cast<Aml_MP_PlayerClient*>(cookie);
|
|
|
|
std::lock_guard<std::mutex> _l(self->mutex);
|
|
|
|
self->mServiceDead = true;
|
|
|
|
self->mRawBinder = nullptr;
|
|
self->mServiceConnected = false;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::start() {
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
MLOG();
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
startDescrambling_l();
|
|
|
|
int32_t result = -1;
|
|
auto status = mPlayerService->start(player_id, &result);
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::stop() {
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
MLOG();
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
int32_t result = -1;
|
|
auto status = mPlayerService->stop(player_id, &result);
|
|
stopDescrambling_l();
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::pause() {
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
MLOG();
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
int32_t result = -1;
|
|
|
|
auto status = mPlayerService->pause(player_id, &result);
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::resume() {
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
MLOG();
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
int32_t result = -1;
|
|
|
|
auto status = mPlayerService->resume(player_id, &result);
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::setVideoParams(const Aml_MP_VideoParams* params) {
|
|
MLOG();
|
|
RETURN_IF(-1, params == nullptr);
|
|
|
|
AmlMpVideoParams aidlParams{};
|
|
convertToAidl(aidlParams, params);
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
int32_t result = -1;
|
|
|
|
auto status = mPlayerService->setVideoParams(player_id, aidlParams, &result);
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::setAudioParams(const Aml_MP_AudioParams* params) {
|
|
MLOG();
|
|
RETURN_IF(-1, params == nullptr);
|
|
|
|
AmlMpAudioParams aidlParams{};
|
|
convertToAidl(aidlParams, params);
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
int32_t result = -1;
|
|
|
|
auto status = mPlayerService->setAudioParams(player_id, aidlParams, &result);
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::setSubtitleParams(const Aml_MP_SubtitleParams* params) {
|
|
MLOG();
|
|
RETURN_IF(-1, params == nullptr);
|
|
|
|
AmlMpSubtitleParams aidlParams{};
|
|
convertToAidl(aidlParams, params);
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
int32_t result = -1;
|
|
|
|
auto status = mPlayerService->setSubtitleParams(player_id, aidlParams, &result);
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
void Aml_MP_PlayerClient::setEcmPidToServer() {
|
|
if (mServiceDead || !mServiceConnected) {
|
|
MLOGE("sever not connect");
|
|
return;
|
|
}
|
|
|
|
if (!mWaitingEcmAtServer) {
|
|
return;
|
|
}
|
|
|
|
if (mEcmPids.empty()) {
|
|
MLOGE("why ecm pids is empty?");
|
|
return;
|
|
}
|
|
|
|
std::string dump;
|
|
for (auto pid : mEcmPids) {
|
|
dump += std::to_string(pid) + " ";
|
|
}
|
|
MLOGI("client will ecm pids:%s", dump.c_str());
|
|
AmlMpPlayerInvokeParams inParams{};
|
|
AmlMpPlayerInvokeParams outParams{};
|
|
inParams.invokeId = AML_MP_SERVER_PLAYER_ID_SET_ECM_PIDS;
|
|
|
|
inParams.intPayload = mEcmPids;
|
|
|
|
auto status = mPlayerService->invoke(player_id, inParams, &outParams);
|
|
if (!status.isOk()) {
|
|
MLOGE("invoke set ecm pids fail");
|
|
}
|
|
}
|
|
|
|
void Aml_MP_PlayerClient::startDescrambling_l()
|
|
{
|
|
if (mHasStartCas) {
|
|
return;
|
|
}
|
|
|
|
if (mIsStandaloneCas) {
|
|
return;
|
|
}
|
|
|
|
MLOG();
|
|
if (mCasServiceType == AML_MP_CAS_SERVICE_TYPE_INVALID) {
|
|
MLOGE("unknown cas type!");
|
|
return;
|
|
}
|
|
|
|
#ifndef __ANDROID_RECOVERY__
|
|
if (mCasHandle == nullptr) {
|
|
mCasHandle = AmlCasBase::create(mCasServiceType);
|
|
}
|
|
#endif
|
|
|
|
if (mCasHandle == nullptr) {
|
|
MLOGE("create CAS handle failed!");
|
|
return;
|
|
}
|
|
|
|
int ret = mCasHandle->startDescrambling(&mIptvCasParams);
|
|
if (ret == 0) {
|
|
mHasStartCas = true;
|
|
MLOGI("start cas success.");
|
|
}
|
|
#ifndef __ANDROID_RECOVERY__
|
|
mCasHandle->getEcmPids(mEcmPids);
|
|
setEcmPidToServer();
|
|
#endif
|
|
}
|
|
|
|
void Aml_MP_PlayerClient::stopDescrambling_l()
|
|
{
|
|
resetEcmVariables();
|
|
|
|
if (!mHasStartCas) {
|
|
return;
|
|
}
|
|
|
|
if (mIsStandaloneCas) {
|
|
return;
|
|
}
|
|
|
|
MLOG();
|
|
if (mCasHandle) {
|
|
mCasHandle->stopDescrambling();
|
|
mCasHandle.clear();
|
|
}
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::setCasSession(AML_MP_CASSESSION casSession) {
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
MLOG();
|
|
|
|
sptr<AmlCasBase> casBase = aml_handle_cast<aml_mp::AmlCasBase>(casSession);
|
|
RETURN_IF(-1, casBase == nullptr);
|
|
|
|
if (casBase->serviceType() < AML_MP_CAS_SERVICE_TYPE_IPTV) {
|
|
MLOGE("do not support bind DVB caseSession!");
|
|
} else if (casBase->serviceType() == AML_MP_CAS_SERVICE_VERIMATRIX_WEB) {
|
|
MLOGW("verimatrix web casSession don't need bind!");
|
|
} else if (casBase->serviceType() == AML_MP_CAS_SERVICE_NAGRA_WEB) {
|
|
MLOGW("nagra web casSession don't need bind!");
|
|
}
|
|
|
|
mCasHandle = casBase;
|
|
#ifndef __ANDROID_RECOVERY__
|
|
casBase->getEcmPids(mEcmPids);
|
|
setEcmPidToServer();
|
|
#endif
|
|
mIsStandaloneCas = true;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::setIptvCASParams(Aml_MP_CASServiceType serviceType, const Aml_MP_IptvCASParams* params) {
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
MLOG();
|
|
mCasServiceType = serviceType;
|
|
mIptvCasParams = *params;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::flush() {
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
int32_t result = -1;
|
|
|
|
auto status = mPlayerService->flush(player_id, &result);
|
|
resetEcmVariables();
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::setPlaybackRate(float rate) {
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
MLOG();
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
int32_t result = -1;
|
|
|
|
auto status =
|
|
mPlayerService->setPlaybackRate(player_id, rate, &result);
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::setPlaybackRate2(float rate, Aml_MP_VideoDecodeMode decodeMode) {
|
|
int aidlDecodeMode = static_cast<Aml_MP_VideoDecodeMode>(decodeMode);
|
|
MLOG();
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
int32_t result = -1;
|
|
|
|
auto status = mPlayerService->setPlaybackRate2(player_id, rate, aidlDecodeMode, &result);
|
|
return status.isOk() ? result : -1;
|
|
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::getPlaybackRate(float* rate) {
|
|
RETURN_IF(-1, rate == nullptr);
|
|
MLOG();
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
auto status =
|
|
mPlayerService->getPlaybackRate(player_id, rate);
|
|
return status.isOk() ? 0 : -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::switchAudioTrack(const Aml_MP_AudioParams* params) {
|
|
RETURN_IF(-1, params == nullptr);
|
|
MLOG();
|
|
|
|
AmlMpAudioParams aidlParams{};
|
|
convertToAidl(aidlParams, params);
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
int32_t result = -1;
|
|
|
|
auto status =
|
|
mPlayerService->switchAudioTrack(
|
|
player_id, aidlParams, &result);
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::switchSubtitleTrack(const Aml_MP_SubtitleParams* params) {
|
|
RETURN_IF(-1, params == nullptr);
|
|
MLOG();
|
|
|
|
AmlMpSubtitleParams aidlParams{};
|
|
convertToAidl(aidlParams, params);
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
int32_t result = -1;
|
|
|
|
auto status =
|
|
mPlayerService->switchSubtitleTrack(
|
|
player_id, aidlParams, &result);
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
void Aml_MP_PlayerClient::FreeBufPool() {
|
|
if (!mBufPoolHasInit) {
|
|
return;
|
|
}
|
|
|
|
MLOGI("enter %s", __FUNCTION__);
|
|
if (mBufPoolBufs != nullptr) {
|
|
free(mBufPoolBufs);
|
|
mBufPoolBufs = nullptr;
|
|
}
|
|
|
|
if (mBufPoolPtr != nullptr) {
|
|
munmap(mBufPoolPtr, mBufPoolBufCnt * mBufPoolBufOne);
|
|
mBufPoolPtr = nullptr;
|
|
}
|
|
|
|
if (mBufPoolFd >= 0) {
|
|
close(mBufPoolFd);
|
|
mBufPoolFd = -1;
|
|
}
|
|
MLOGI("exit %s", __FUNCTION__);
|
|
}
|
|
|
|
void Aml_MP_PlayerClient::InitBufPool() {
|
|
if (mBufPoolHasInit) {
|
|
return;
|
|
}
|
|
|
|
MLOGI("enter %s", __FUNCTION__);
|
|
mBufPoolHasInit = false;
|
|
mBufPoolBufCnt = property_get_int32("vendor.media.buf_pool.cnt", 16);
|
|
mBufPoolBufOne = property_get_int32("vendor.media.buf_pool.once", 1 * 1024 * 1024);
|
|
if (mBufPoolBufCnt <= 0 || mBufPoolBufOne <= 0) {
|
|
return;
|
|
}
|
|
BufPoolNode *bufs = (BufPoolNode *)malloc(sizeof(BufPoolNode) * mBufPoolBufCnt);
|
|
if (bufs == nullptr) {
|
|
MLOGE("malloc fail");
|
|
return;
|
|
}
|
|
|
|
std::unique_ptr<DataQueueMQ> bufPoolDataMq = std::make_unique<DataQueueMQ>(mBufPoolBufCnt, /*configureEventFlagWord=*/true);
|
|
std::unique_ptr<FreeQueueMQ> bufPoolFreeMq = std::make_unique<FreeQueueMQ>(mBufPoolBufCnt, /*configureEventFlagWord=*/true);
|
|
|
|
char bufPoolName[100] = { 0 };
|
|
snprintf(bufPoolName, sizeof(bufPoolName) - 1, "aml_mp_sdk_buf_pool_%p", this);
|
|
int fd = ashmem_create_region(bufPoolName, mBufPoolBufCnt * mBufPoolBufOne);
|
|
if (fd < 0) {
|
|
free(bufs);
|
|
MLOGE("alloc buf pool fail");
|
|
return;
|
|
}
|
|
|
|
void* base = (uint8_t *)mmap(nullptr, mBufPoolBufCnt * mBufPoolBufOne, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
|
if (base == MAP_FAILED) {
|
|
free(bufs);
|
|
MLOGE("mmap fail");
|
|
close(fd);
|
|
return;
|
|
}
|
|
|
|
mBufPoolBufs = bufs;
|
|
for (int i = 0; i < mBufPoolBufCnt; i++) {
|
|
mBufPoolBufs[i].ptr = (uint8_t *)base + i * mBufPoolBufOne;
|
|
mBufPoolBufs[i].size = mBufPoolBufOne;
|
|
}
|
|
|
|
mBufPoolDataMq = std::move(bufPoolDataMq);
|
|
mBufPoolFreeMq = std::move(bufPoolFreeMq);
|
|
mBufPoolFd = fd;
|
|
mBufPoolPtr = base;
|
|
mBufPoolHasInit = true;
|
|
MLOGI("init buf pool success, name:%s, fd:%d, ptr:%p", bufPoolName, fd, base);
|
|
}
|
|
|
|
int32_t Aml_MP_PlayerClient::setBufPool2Servier() {
|
|
MLOGI("enter %s", __FUNCTION__);
|
|
int32_t result = -1;
|
|
ndk::ScopedFileDescriptor fd(dup(mBufPoolFd));
|
|
auto dataDesc = mBufPoolDataMq->dupeDesc();
|
|
auto freeDesc = mBufPoolFreeMq->dupeDesc();
|
|
auto status = mPlayerService->setBuffs(player_id, fd, mBufPoolBufCnt, mBufPoolBufOne,
|
|
dataDesc, freeDesc, &result);
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
void Aml_MP_PlayerClient::resetEcmVariables()
|
|
{
|
|
mFirstEcmWritten = false;
|
|
mTsBuffer.reset();
|
|
mWriteBuffer->setRange(0, 0);
|
|
mCacheEcmSize = 0;
|
|
}
|
|
|
|
/*
|
|
* > 0: cache data
|
|
* == 0: send cache to player
|
|
* < 0: cache send all, so continue send buffer to player
|
|
*/
|
|
int Aml_MP_PlayerClient::processEcmBeforeWrite(const uint8_t* buffer, size_t size) {
|
|
if (mCasHandle == nullptr || mWaitingEcmAtServer) {
|
|
return -1;
|
|
}
|
|
|
|
if (mCasHandle && mCreateParams.drmMode == AML_MP_INPUT_STREAM_ENCRYPTED && !mFirstEcmWritten) {
|
|
size_t ecmOffset = size;
|
|
size_t ecmSize = 188;
|
|
ecmOffset = aml_mp::findEcmPacket(buffer, size, mEcmPids, &ecmSize);
|
|
if (ecmSize > 0) {
|
|
mCasHandle->processEcm(false, 0, buffer + ecmOffset, ecmSize);
|
|
mFirstEcmWritten = true;
|
|
MLOGI("first ECM written, offset:%zu", mTsBuffer.size() + ecmOffset);
|
|
}
|
|
|
|
if (mTsBuffer.empty()) {
|
|
MLOGI("encrypted stream, not find ecm, will cache.");
|
|
}
|
|
|
|
if (mTsBuffer.space() < size) {
|
|
MLOGE("mTsBuffer full!, why not find ecm data?");
|
|
mTsBuffer.reset();
|
|
}
|
|
|
|
return mTsBuffer.put(buffer, size);
|
|
}
|
|
|
|
if (mTsBuffer.empty() || mWriteBuffer->size() == 0) {
|
|
return -1;
|
|
}
|
|
|
|
|
|
int written = 0;
|
|
int retry = 0;
|
|
MLOGI("encrypted stream, find ecm, stop cache. will send data %d - %d", mTsBuffer.size(), mWriteBuffer->size());
|
|
while (!mTsBuffer.empty() || mWriteBuffer->size() != 0) {
|
|
if (mWriteBuffer->size() == 0) {
|
|
size_t readSize = mTsBuffer.get(mWriteBuffer->base(), mWriteBuffer->capacity());
|
|
mWriteBuffer->setRange(0, readSize);
|
|
}
|
|
|
|
written = doWriteTsData(mWriteBuffer->data(), mWriteBuffer->size());
|
|
|
|
if (written > 0) {
|
|
//coverity[overflow_const]
|
|
mWriteBuffer->setRange(mWriteBuffer->offset()+written, mWriteBuffer->size()-written);
|
|
mCacheEcmSize += written;
|
|
} else {
|
|
if (retry >= 5) {
|
|
break;
|
|
}
|
|
retry++;
|
|
usleep(10 * 1000);
|
|
}
|
|
}
|
|
|
|
if ((mWriteBuffer->size() != 0) || (!mTsBuffer.empty())) {
|
|
MLOGI("encrypted stream, find ecm, stop cache. has send:%d, still send data %d - %d",
|
|
mCacheEcmSize, mTsBuffer.size(), mWriteBuffer->size());
|
|
return 0;
|
|
}
|
|
|
|
MLOGI("encrypted stream, find ecm, stop cache. all has send data:%d", mCacheEcmSize);
|
|
return -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::doWriteTsData(const uint8_t* buffer, size_t size) {
|
|
int ecmCount = 0;
|
|
size_t leftSize = size;
|
|
while (leftSize > 0) {
|
|
int32_t index = -1;
|
|
if (!mBufPoolFreeMq->read(&index)) {
|
|
usleep(10 * 1000);
|
|
break;
|
|
}
|
|
|
|
if (index < 0 || index >= mBufPoolBufCnt) {
|
|
MLOGE("why here?????");
|
|
break;
|
|
}
|
|
|
|
const uint8_t *curBuf = buffer + (size - leftSize);
|
|
|
|
size_t ecmSize = 0;
|
|
size_t ecmOffset = leftSize;
|
|
if (!mWaitingEcmAtServer &&
|
|
mCreateParams.drmMode == AML_MP_INPUT_STREAM_ENCRYPTED && mCasHandle != nullptr) {
|
|
ecmOffset = aml_mp::findEcmPacket(curBuf, leftSize, mEcmPids, &ecmSize);
|
|
}
|
|
|
|
uint8_t *data = mBufPoolBufs[index].ptr;
|
|
size_t maxSize = mBufPoolBufs[index].size;
|
|
size_t cpySize = std::min(leftSize, maxSize);
|
|
if (ecmOffset > 0) {
|
|
cpySize = std::min(ecmOffset, cpySize);
|
|
}
|
|
if (ecmSize > 0) {
|
|
cpySize += ecmSize;
|
|
}
|
|
memcpy(data, curBuf, cpySize);
|
|
|
|
AmlMpBufPoolDataPacket pkt; //BufPoolDataPacket
|
|
pkt.isTsData = true;
|
|
pkt.index = index;
|
|
pkt.size = cpySize;
|
|
if (!mBufPoolDataMq->write(&pkt)) {
|
|
MLOGE("why client write fail, data and free MQ is same");
|
|
}
|
|
//MLOGI("client write idx:%d, size:%d", index, cpySize);
|
|
|
|
leftSize -= cpySize;
|
|
|
|
if (ecmSize > 0) {
|
|
ecmCount++;
|
|
mCasHandle->processEcm(false, 0, curBuf + ecmOffset, ecmSize);
|
|
}
|
|
}
|
|
|
|
//MLOGI("client write ret:%d", size - leftSize);
|
|
return size - leftSize;
|
|
}
|
|
|
|
/*
|
|
* -1: not write data
|
|
* 0: write all data
|
|
* > 0 : write ret data;
|
|
*/
|
|
int Aml_MP_PlayerClient::writeData(const uint8_t* buffer, size_t size) {
|
|
RETURN_IF(-1, buffer == nullptr || size == 0);
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
if (mCreateParams.drmMode == AML_MP_INPUT_STREAM_SECURE_MEMORY) {
|
|
int32_t result = -1;
|
|
AmlMpWriteBuffer aidlBuf;
|
|
aidlBuf.isSecBuf = true;
|
|
aidlBuf.isTs = true;
|
|
aidlBuf.secData = static_cast<int64_t>(reinterpret_cast<intptr_t>(buffer));
|
|
aidlBuf.size = size;
|
|
auto status = mPlayerService->writeData(player_id, aidlBuf, &result);
|
|
int32_t ret = status.isOk() ? result : -1;
|
|
return ret <= 0 ? -1 : ret;
|
|
};
|
|
|
|
int32_t ret = processEcmBeforeWrite(buffer, size);
|
|
if (ret < 0) {
|
|
ret = doWriteTsData(buffer, size);
|
|
}
|
|
|
|
if (ret > 0) {
|
|
// AmpMpPlayerDumpFile(mName, buffer, ret);
|
|
}
|
|
|
|
return ret <= 0 ? -1 : ret;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::writeEsData(Aml_MP_StreamType streamType, const uint8_t* buffer, size_t size, int64_t pts) {
|
|
RETURN_IF(-1, buffer == nullptr || size == 0);
|
|
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
|
|
if (mCreateParams.drmMode == AML_MP_INPUT_STREAM_SECURE_MEMORY) {
|
|
int32_t result = -1;
|
|
AmlMpWriteBuffer aidlBuf;
|
|
aidlBuf.isSecBuf = true;
|
|
aidlBuf.isTs = false;
|
|
aidlBuf.secData = static_cast<int64_t>(reinterpret_cast<intptr_t>(buffer));
|
|
aidlBuf.size = size;
|
|
aidlBuf.streamType = streamType;
|
|
aidlBuf.pts = pts;
|
|
auto status = mPlayerService->writeData(player_id, aidlBuf, &result);
|
|
int32_t ret = status.isOk() ? result : -1;
|
|
return ret <= 0 ? -1 : ret;
|
|
};
|
|
|
|
int32_t index = -1;
|
|
if (!mBufPoolFreeMq->read(&index)) {
|
|
usleep(10 * 1000);
|
|
return -1;
|
|
}
|
|
|
|
if (index < 0 || index >= mBufPoolBufCnt) {
|
|
MLOGE("why here?????");
|
|
return -1;
|
|
}
|
|
|
|
uint8_t *data = mBufPoolBufs[index].ptr;
|
|
size_t maxSize = mBufPoolBufs[index].size;
|
|
if (size > maxSize) {
|
|
MLOGE("cur es size:%d > bufpool node:%d", size, maxSize);
|
|
return -1;
|
|
}
|
|
size_t cpySize = std::min(size, maxSize);
|
|
memcpy(data, buffer, cpySize);
|
|
|
|
AmlMpBufPoolDataPacket pkt; //BufPoolDataPacket
|
|
pkt.isTsData = false;
|
|
pkt.index = index;
|
|
pkt.size = cpySize;
|
|
pkt.pts = pts;
|
|
pkt.streamType = streamType;
|
|
mBufPoolDataMq->write(&pkt);
|
|
|
|
return size;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::getCurrentPts(Aml_MP_StreamType streamType, int64_t* pts) {
|
|
RETURN_IF(-1, pts == nullptr);
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
int64_t result = -1;
|
|
|
|
auto status = mPlayerService->getCurrentPts(player_id, static_cast<int32_t>(streamType), &result);
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::getFirstPts(Aml_MP_StreamType streamType, int64_t* pts) {
|
|
RETURN_IF(-1, pts == nullptr);
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
int64_t result = -1;
|
|
|
|
auto status = mPlayerService->getCurrentPts(player_id, static_cast<int32_t>(streamType), &result);
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::getBufferStat(Aml_MP_BufferStat* bufferStat) {
|
|
RETURN_IF(-1, bufferStat == nullptr);
|
|
|
|
AmlMpBufferStat aidlStat{};
|
|
int32_t result = -1;
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
auto status = mPlayerService->getBufferStat(player_id, &aidlStat, &result);
|
|
|
|
if (status.isOk()) {
|
|
convertFromAidl(*bufferStat, aidlStat);
|
|
return result;
|
|
}
|
|
return -1;
|
|
|
|
}
|
|
|
|
void Aml_MP_PlayerClient::clearTunnelId() {
|
|
if (mMesonVtFd >= 0) {
|
|
if (mTunnelId >= 0) {
|
|
MLOGI("%s: free Id:%d", __FUNCTION__, mTunnelId);
|
|
meson_vt_free_id(mMesonVtFd, mTunnelId);
|
|
}
|
|
meson_vt_close(mMesonVtFd);
|
|
mTunnelId = -1;
|
|
mMesonVtFd = -1;
|
|
}
|
|
}
|
|
|
|
int32_t Aml_MP_PlayerClient::allocTunnelId() {
|
|
int type = AM_FIXED_TUNNEL;
|
|
if (mMesonVtFd < 0) {
|
|
mMesonVtFd = meson_vt_open();
|
|
if (mMesonVtFd < 0) {
|
|
MLOGE("meson_vt_open failed!");
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
if (mTunnelId >= 0) {
|
|
return mTunnelId;
|
|
}
|
|
|
|
if (mTunnelId < 0) {
|
|
int tunnelId = -1;
|
|
if (meson_vt_alloc_id(mMesonVtFd, &tunnelId) < 0) {
|
|
MLOGE("meson_vt_alloc_id failed!");
|
|
meson_vt_close(mMesonVtFd);
|
|
mMesonVtFd = -1;
|
|
return -1;
|
|
}
|
|
|
|
MLOGI("allocTunnelId: %d", tunnelId);
|
|
mTunnelId = tunnelId;
|
|
}
|
|
|
|
if (mSidebandHandle == nullptr) {
|
|
native_handle_t *sidebandHandle = am_gralloc_create_sideband_handle(type, mTunnelId);
|
|
mSidebandHandle = android::NativeHandle::create(sidebandHandle, true);
|
|
}
|
|
|
|
return mTunnelId;
|
|
}
|
|
|
|
|
|
|
|
int Aml_MP_PlayerClient::setANativeWindow(ANativeWindow* nativeWindow) {
|
|
RETURN_IF(-1, nativeWindow == nullptr);
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
if (mNativeWindow == nativeWindow) {
|
|
return 0;
|
|
}
|
|
|
|
if (allocTunnelId() < 0) {
|
|
MLOGE("alloc tunnel id fail");
|
|
return -1;
|
|
}
|
|
|
|
MLOGI("setAnativeWindow:%p, sidebandHandle:%p, videoTunnelId: %d",
|
|
nativeWindow, (native_handle_t*)mSidebandHandle->handle(), mTunnelId);
|
|
int32_t ret = native_window_set_sideband_stream(nativeWindow, (native_handle_t*)mSidebandHandle->handle());
|
|
if (ret < 0) {
|
|
MLOGE("set sideband stream failed!");
|
|
return ret;
|
|
}
|
|
|
|
mNativeWindow = nativeWindow;
|
|
|
|
AmlMpPlayerParam param{};
|
|
param.key = static_cast<int32_t>(AML_MP_PLAYER_PARAMETER_VIDEO_TUNNEL_ID);
|
|
param.intValue = mTunnelId;
|
|
auto status = mPlayerService->setParameter(player_id, param);
|
|
return status.isOk() ? 0 : -EIO;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::setVideoWindow(int32_t x, int32_t y, int32_t width, int32_t height) {
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
int32_t result = -1;
|
|
|
|
auto status = mPlayerService->setVideoWindow(player_id, x, y, width, height, &result);
|
|
return status.isOk() ? result : -1;
|
|
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::setVolume(float volume) {
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
int32_t result = -1;
|
|
|
|
auto status = mPlayerService->setVolume(player_id, volume, &result);
|
|
return status.isOk() ? result : -1;
|
|
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::getVolume(float* volume) {
|
|
RETURN_IF(-1, volume == nullptr);
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
int32_t result = -1;
|
|
|
|
auto status = mPlayerService->getVolume(player_id, volume);
|
|
return status.isOk() ? 0 : -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::showVideo() {
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
int32_t result = -1;
|
|
|
|
auto status = mPlayerService->showVideo(player_id, &result);
|
|
return status.isOk() ? result : -1;
|
|
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::hideVideo() {
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
int32_t result = -1;
|
|
|
|
auto status = mPlayerService->hideVideo(player_id, &result);
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::showSubtitle() {
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
int32_t result = -1;
|
|
|
|
auto status = mPlayerService->showSubtitle(player_id, &result);
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::hideSubtitle() {
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
int32_t result = -1;
|
|
|
|
auto status = mPlayerService->hideSubtitle(player_id, &result);
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::setParameter(
|
|
Aml_MP_PlayerParameterKey key,
|
|
void* parameter) {
|
|
RETURN_IF(-EINVAL, parameter == nullptr);
|
|
|
|
AmlMpPlayerParam param{};
|
|
param.key = static_cast<int32_t>(key);
|
|
{
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-ENODEV, (mServiceDead || !mServiceConnected)); // Binder init MUST be outside lock
|
|
}
|
|
|
|
switch (key) {
|
|
case AML_MP_PLAYER_PARAMETER_VIDEO_PTS_OFFSET:
|
|
case AML_MP_PLAYER_PARAMETER_AUDIO_PTS_OFFSET:
|
|
case AML_MP_PLAYER_PARAMETER_NETWORK_JITTER:
|
|
case AML_MP_PLAYER_PARAMETER_VIDEO_WINDOW_ZORDER:
|
|
case AML_MP_PLAYER_PARAMETER_VENDOR_ID:
|
|
case AML_MP_PLAYER_PARAMETER_VIDEO_TUNNEL_ID:
|
|
case AML_MP_PLAYER_PARAMETER_AUDIO_PRESENTATION_ID:
|
|
case AML_MP_PLAYER_PARAMETER_LIBDVR_FAKE_PID:
|
|
case AML_MP_PLAYER_PARAMETER_AUDIO_BLOCK_ALIGN:
|
|
case AML_MP_PLAYER_PARAMETER_AUDIO_PATCH_ADDRESS:
|
|
case AML_MP_PLAYER_PARAMETER_VIDEO_DISPLAY_MODE:
|
|
case AML_MP_PLAYER_PARAMETER_VIDEO_DECODE_MODE:
|
|
case AML_MP_PLAYER_PARAMETER_AUDIO_OUTPUT_MODE:
|
|
case AML_MP_PLAYER_PARAMETER_AUDIO_OUTPUT_DEVICE:
|
|
case AML_MP_PLAYER_PARAMETER_AUDIO_BALANCE:
|
|
case AML_MP_PLAYER_PARAMETER_AD_STATE:
|
|
case AML_MP_PLAYER_PARAMETER_WORK_MODE:
|
|
case AML_MP_PLAYER_PARAMETER_SPDIF_PROTECTION:
|
|
case AML_MP_PLAYER_PARAMETER_VIDEO_ERROR_RECOVERY_MODE:
|
|
case AML_MP_PLAYER_PARAMETER_VIDEO_AFD_ASPECT_MODE:
|
|
param.intValue = *static_cast<const int32_t*>(parameter);
|
|
break;
|
|
case AML_MP_PLAYER_PARAMETER_BLACK_OUT:
|
|
case AML_MP_PLAYER_PARAMETER_AUDIO_MUTE:
|
|
case AML_MP_PLAYER_PARAMETER_USE_TIF:
|
|
param.boolValue = *static_cast<const bool*>(parameter);
|
|
break;
|
|
case AML_MP_PLAYER_PARAMETER_AD_MIX_LEVEL:
|
|
setToHolder<AmlMpADVolume>(param, parameter);
|
|
break;
|
|
case AML_MP_PLAYER_PARAMETER_TELETEXT_CONTROL:
|
|
setToHolder<AmlMpTeletextCtrl>(param, parameter);
|
|
break;
|
|
case AML_MP_PLAYER_PARAMETER_VIDEO_CROP:
|
|
setToHolder<AmlMpRect>(param, parameter);
|
|
break;
|
|
case AML_MP_PLAYER_PARAMETER_AUDIO_LANGUAGE:
|
|
setToHolder<AmlMpAudioLanguage>(param, parameter);
|
|
break;
|
|
case AML_MP_PLAYER_PARAMETER_CREATE_PARAMS:
|
|
setToHolder<AmlMpPlayerCreateParams>(param, parameter);
|
|
break;
|
|
case AML_MP_PLAYER_PARAMETER_SURFACE_HANDLE:
|
|
// not impl
|
|
break;
|
|
default:
|
|
MLOGE("SetParameter: unsupported key %d", key);
|
|
return -EINVAL;
|
|
}
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
auto status = mPlayerService->setParameter(player_id, param);
|
|
return status.isOk() ? 0 : -EIO;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::getParameter( Aml_MP_PlayerParameterKey key, void* parameter) {
|
|
RETURN_IF(-EINVAL, parameter == nullptr);
|
|
{
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-ENODEV, (mServiceDead || !mServiceConnected)); // Binder init MUST be outside lock
|
|
}
|
|
|
|
AmlMpPlayerParam inParam{};
|
|
inParam.key = static_cast<int32_t>(key);
|
|
|
|
AmlMpPlayerParam param{};
|
|
{
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
if (key == AML_MP_PLAYER_PARAMETER_AV_INFO_JSON) { // Aml_MP_AvInfo
|
|
setToHolder<AmlMpAvInfo>(inParam, parameter);
|
|
} else if (key == AML_MP_PLAYER_PARAMETER_AV_STAT_JSON) { // Aml_MP_AvStat Aml_MP_AvInfo
|
|
setToHolder<AmlMpAvInfo>(inParam, parameter);
|
|
}
|
|
auto status = mPlayerService->getParameter(player_id, inParam, ¶m);
|
|
if (!status.isOk()) {
|
|
MLOGE("GetParameter: binder call failed for key %d", key);
|
|
return -EIO;
|
|
}
|
|
}
|
|
|
|
switch (key) {
|
|
case AML_MP_PLAYER_PARAMETER_VIDEO_PTS_OFFSET:
|
|
case AML_MP_PLAYER_PARAMETER_AUDIO_PTS_OFFSET:
|
|
case AML_MP_PLAYER_PARAMETER_NETWORK_JITTER:
|
|
case AML_MP_PLAYER_PARAMETER_VIDEO_WINDOW_ZORDER:
|
|
case AML_MP_PLAYER_PARAMETER_VENDOR_ID:
|
|
case AML_MP_PLAYER_PARAMETER_VIDEO_TUNNEL_ID:
|
|
case AML_MP_PLAYER_PARAMETER_AUDIO_PRESENTATION_ID:
|
|
case AML_MP_PLAYER_PARAMETER_LIBDVR_FAKE_PID:
|
|
case AML_MP_PLAYER_PARAMETER_AUDIO_BLOCK_ALIGN:
|
|
case AML_MP_PLAYER_PARAMETER_AUDIO_PATCH_ADDRESS:
|
|
case AML_MP_PLAYER_PARAMETER_VIDEO_DISPLAY_MODE:
|
|
case AML_MP_PLAYER_PARAMETER_VIDEO_DECODE_MODE:
|
|
case AML_MP_PLAYER_PARAMETER_AUDIO_OUTPUT_MODE:
|
|
case AML_MP_PLAYER_PARAMETER_AUDIO_OUTPUT_DEVICE:
|
|
case AML_MP_PLAYER_PARAMETER_AUDIO_BALANCE:
|
|
case AML_MP_PLAYER_PARAMETER_AD_STATE:
|
|
case AML_MP_PLAYER_PARAMETER_WORK_MODE:
|
|
case AML_MP_PLAYER_PARAMETER_SPDIF_PROTECTION:
|
|
case AML_MP_PLAYER_PARAMETER_VIDEO_ERROR_RECOVERY_MODE:
|
|
case AML_MP_PLAYER_PARAMETER_VIDEO_AFD_ASPECT_MODE:
|
|
case AML_MP_PLAYER_PARAMETER_INSTANCE_ID:
|
|
case AML_MP_PLAYER_PARAMETER_SYNC_ID:
|
|
*(int32_t*)(parameter) = param.intValue;
|
|
break;
|
|
case AML_MP_PLAYER_PARAMETER_BLACK_OUT:
|
|
case AML_MP_PLAYER_PARAMETER_AUDIO_MUTE:
|
|
case AML_MP_PLAYER_PARAMETER_USE_TIF:
|
|
case AML_MP_PLAYER_PARAMETER_VIDEO_SHOW_STATE:
|
|
*(bool*)(parameter) = param.boolValue;
|
|
break;
|
|
case AML_MP_PLAYER_PARAMETER_CREATE_PARAMS:
|
|
getFromHolder<AmlMpPlayerCreateParams>(player_id, param.holder, *(Aml_MP_PlayerCreateParams *)parameter, key);
|
|
break;
|
|
case AML_MP_PLAYER_PARAMETER_AD_MIX_LEVEL:
|
|
getFromHolder<AmlMpADVolume>(player_id, param.holder, *(Aml_MP_ADVolume *)parameter, key);
|
|
break;
|
|
case AML_MP_PLAYER_PARAMETER_TELETEXT_CONTROL:
|
|
getFromHolder<AmlMpTeletextCtrl>(player_id, param.holder, *(AML_MP_TeletextCtrlParam *)parameter, key);
|
|
break;
|
|
case AML_MP_PLAYER_PARAMETER_VIDEO_CROP:
|
|
getFromHolder<AmlMpRect>(player_id, param.holder, *(Aml_MP_Rect *)parameter, key);
|
|
break;
|
|
case AML_MP_PLAYER_PARAMETER_AUDIO_LANGUAGE:
|
|
getFromHolder<AmlMpAudioLanguage>(player_id, param.holder, *(Aml_MP_AudioLanguage *)parameter, key);
|
|
break;
|
|
case AML_MP_PLAYER_PARAMETER_VIDEO_INFO:
|
|
getFromHolder<AmlMpVideoInfo>(player_id, param.holder, *(Aml_MP_VideoInfo *)parameter, key);
|
|
break;
|
|
case AML_MP_PLAYER_PARAMETER_VIDEO_DECODE_STAT:
|
|
getFromHolder<AmlMpVdecStat>(player_id, param.holder, *(Aml_MP_VdecStat *)parameter, key);
|
|
break;
|
|
case AML_MP_PLAYER_PARAMETER_AUDIO_INFO:
|
|
getFromHolder<AmlMpAudioInfo>(player_id, param.holder, *(Aml_MP_AudioInfo *)parameter, key);
|
|
break;
|
|
case AML_MP_PLAYER_PARAMETER_AUDIO_DECODE_STAT:
|
|
getFromHolder<AmlMpAdecStat>(player_id, param.holder, *(Aml_MP_AdecStat *)parameter, key);
|
|
break;
|
|
case AML_MP_PLAYER_PARAMETER_SUBTITLE_INFO:
|
|
getFromHolder<AmlMpSubtitleInfo>(player_id, param.holder, *(Aml_MP_SubtitleInfo *)parameter, key);
|
|
break;
|
|
case AML_MP_PLAYER_PARAMETER_SUBTITLE_DECODE_STAT:
|
|
getFromHolder<AmlMpSubDecStat>(player_id, param.holder, *(Aml_MP_SubDecStat *)parameter, key);
|
|
break;
|
|
case AML_MP_PLAYER_PARAMETER_AD_INFO:
|
|
getFromHolder<AmlMpAudioInfo>(player_id, param.holder, *(Aml_MP_AudioInfo *)parameter, key);
|
|
break;
|
|
case AML_MP_PLAYER_PARAMETER_AD_DECODE_STAT:
|
|
getFromHolder<AmlMpAdecStat>(player_id, param.holder, *(Aml_MP_AdecStat *)parameter, key);
|
|
break;
|
|
case AML_MP_PLAYER_PARAMETER_AV_INFO_JSON: { // Aml_MP_AvInfo
|
|
getFromHolder<AmlMpAvInfo>(player_id, param.holder, *(Aml_MP_AvInfo *)parameter, key);
|
|
break;
|
|
}
|
|
case AML_MP_PLAYER_PARAMETER_AV_STAT_JSON: { // Aml_MP_AvStat
|
|
getFromHolder<AmlMpAvInfo>(player_id, param.holder, *(Aml_MP_AvStat *)parameter, key);
|
|
break;
|
|
}
|
|
case AML_MP_PLAYER_PARAMETER_TSPLAYER_HANDLE: //getTsPlayerHandle(am_tsplayer_handle*)
|
|
// not impl
|
|
break;
|
|
case AML_MP_PLAYER_PARAMETER_SURFACE_HANDLE:
|
|
// not impl
|
|
break;
|
|
default:
|
|
MLOGE("GetParameter: unsupported key %d", key);
|
|
return -EINVAL;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::setSubtitleWindow(int x, int y, int width, int height) {
|
|
RETURN_IF(-1, width <= 0 || height <= 0);
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
int32_t result = -1;
|
|
|
|
auto status = mPlayerService->setSubtitleWindow(player_id, x, y, width, height, &result);
|
|
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::setAVSyncSource(Aml_MP_AVSyncSource syncSource) {
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
int32_t result = -1;
|
|
|
|
auto status = mPlayerService->setAVSyncSource(
|
|
player_id, static_cast<int32_t>(syncSource), &result);
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::setPcrPid(int pid) {
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
int32_t result = -1;
|
|
|
|
auto status = mPlayerService->setPcrPid(player_id, pid, &result);
|
|
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::startVideoDecoding() {
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
MLOG();
|
|
startDescrambling_l();
|
|
int32_t result = -1;
|
|
auto status = mPlayerService->startVideoDecoding(player_id, &result);
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::stopVideoDecoding() {
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
int32_t result = -1;
|
|
MLOG();
|
|
|
|
auto status = mPlayerService->stopVideoDecoding(player_id, &result);
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::startAudioDecoding() {
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
MLOG();
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
startDescrambling_l();
|
|
int32_t result = -1;
|
|
auto status = mPlayerService->startAudioDecoding(player_id, &result);
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::stopAudioDecoding() {
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
MLOG();
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
int32_t result = -1;
|
|
|
|
auto status = mPlayerService->stopAudioDecoding(player_id, &result);
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::startSubtitleDecoding() {
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
MLOG();
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
|
|
int32_t result = -1;
|
|
auto status = mPlayerService->startSubtitleDecoding(player_id, &result);
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::stopSubtitleDecoding() {
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
MLOG();
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
int32_t result = -1;
|
|
|
|
auto status = mPlayerService->stopSubtitleDecoding(player_id, &result);
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::setADParams(Aml_MP_AudioParams* params) {
|
|
RETURN_IF(-1, params == nullptr);
|
|
|
|
AmlMpAudioParams aidlParams{};
|
|
convertToAidl(aidlParams, params);
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
int32_t result = -1;
|
|
|
|
auto status = mPlayerService->setADParams(player_id, aidlParams, &result);
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::startADDecoding() {
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
MLOG();
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
startDescrambling_l();
|
|
|
|
int32_t result = -1;
|
|
auto status = mPlayerService->startADDecoding(player_id, &result);
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::stopADDecoding() {
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
MLOG();
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
int32_t result = -1;
|
|
|
|
auto status = mPlayerService->stopADDecoding(player_id, &result);
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::getDecodingState(Aml_MP_StreamType streamType, AML_MP_DecodingState* decodingState) {
|
|
RETURN_IF(-1, decodingState == nullptr);
|
|
|
|
int32_t aidlState = 0;
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
auto status = mPlayerService->getDecodingState(
|
|
player_id, static_cast<int32_t>(streamType), &aidlState);
|
|
if (status.isOk()) {
|
|
*decodingState = static_cast<AML_MP_DecodingState>(aidlState);
|
|
return 0;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::setADVolume(float volume) {
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
int32_t result = -1;
|
|
|
|
auto status = mPlayerService->setADVolume(player_id, volume, &result);
|
|
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::getADVolume(float* volume) {
|
|
RETURN_IF(-1, volume == nullptr);
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
int32_t result = -1;
|
|
|
|
auto status = mPlayerService->getADVolume(player_id, volume);
|
|
return status.isOk() ? result : -1;
|
|
}
|
|
|
|
Aml_MP_PlayerClient::ClientEventCallBack::ClientEventCallBack(aml_mp::wptr<Aml_MP_PlayerClient>& weakThis,
|
|
int32_t playerId, Aml_MP_PlayerEventCallback cb, void* userData) {
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
mCb = cb;
|
|
mUserData = userData;
|
|
mClient = weakThis;
|
|
snprintf(mName, sizeof(mName), "%s_%p_%d", "Aml_MP_PlayerClientEventCallBack", this, playerId);
|
|
}
|
|
|
|
int32_t Aml_MP_PlayerClient::ClientEventCallBack::setCallBack(Aml_MP_PlayerEventCallback cb, void *userData) {
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
if (mCb != nullptr) {
|
|
MLOGE("why register call again.");
|
|
return -1;
|
|
}
|
|
|
|
mCb = cb;
|
|
mUserData = userData;
|
|
MLOGI("register callback:%p - %p success", cb, userData);
|
|
|
|
return 0;
|
|
}
|
|
|
|
Aml_MP_PlayerClient::status Aml_MP_PlayerClient::ClientEventCallBack::onPlayerEvent(const AmlMpPlayerEvent& event) {
|
|
sptr<Aml_MP_PlayerClient> clientRemote = mClient.promote();
|
|
if (clientRemote == nullptr) {
|
|
// client already dec
|
|
return status::ok();
|
|
}
|
|
|
|
Aml_MP_PlayerClient* client = clientRemote.get();
|
|
Aml_MP_PlayerEventCallback cb = nullptr;
|
|
aml_mp::sptr<aml_mp::AmlCasBase> casHandle = nullptr;
|
|
void* userData = nullptr;
|
|
{
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
cb = mCb;
|
|
userData = mUserData;
|
|
casHandle = client->mCasHandle;
|
|
}
|
|
|
|
Aml_MP_PlayerEventType eventType = (Aml_MP_PlayerEventType)event.eventType;
|
|
if (eventType == AML_MP_PLAYER_EVENT_ECM_NOTIFY) {
|
|
if (casHandle != nullptr) {
|
|
bool async = event.boolValue;
|
|
int32_t pid = event.intValue;
|
|
const uint8_t *data = event.payload.data();
|
|
int32_t size = event.payload.size();
|
|
|
|
std::string ecmDataStr;
|
|
char hex[3];
|
|
for (int i = 0; i < size; i++) {
|
|
snprintf(hex, sizeof(hex), "%02X", data[i]);
|
|
ecmDataStr.append(hex);
|
|
ecmDataStr.append(" ");
|
|
}
|
|
MLOGI("programEventCallback: ecmPid: %d, ecmData: size:%d, hexStr:%s", pid, size, ecmDataStr.c_str());
|
|
casHandle->processEcm(event.boolValue, event.intValue, event.payload.data(), event.payload.size());
|
|
}
|
|
return status::ok();
|
|
}
|
|
|
|
if (cb == nullptr) {
|
|
return status::ok();
|
|
}
|
|
|
|
void *value = nullptr;
|
|
int32_t cpySize = 0;
|
|
Aml_MP_PlayerEventScrambling scrambling{};
|
|
Aml_MP_PlayerEventPidChangeInfo pidChanged{};
|
|
Aml_MP_PlayerEventVideoFormat videoFormat{};
|
|
Aml_MP_PlayerEventAudioFormat audioFormat{};
|
|
Aml_MP_SubtitleInfo subInfo{};
|
|
Aml_MP_SubtitleDimension subDimension{};
|
|
Aml_MP_SubtitleChannelUpdate subChannelUpdate{};
|
|
std::string subLang;
|
|
Aml_MP_PlayerEventMpegUserData mpegUserData{};
|
|
Aml_MP_SubtitleData subData{};
|
|
switch (eventType) {
|
|
case AML_MP_PLAYER_EVENT_FIRST_FRAME: // only event, no param.
|
|
case AML_MP_PLAYER_EVENT_AV_SYNC_DONE:
|
|
case AML_MP_PLAYER_EVENT_DATA_LOSS:
|
|
case AML_MP_PLAYER_EVENT_DATA_RESUME:
|
|
case AML_MP_PLAYER_EVENT_DECODER_DATA_LOSS:
|
|
case AML_MP_PLAYER_EVENT_DECODER_DATA_RESUME:
|
|
case AML_MP_PLAYER_EVENT_VIDEO_DECODE_FIRST_FRAME:
|
|
case AML_MP_PLAYER_EVENT_VIDEO_INVALID_TIMESTAMP:
|
|
case AML_MP_PLAYER_EVENT_VIDEO_INVALID_DATA:
|
|
case AML_MP_PLAYER_EVENT_VIDEO_ERROR_FRAME_COUNT:
|
|
case AML_MP_PLAYER_EVENT_AUDIO_INVALID_TIMESTAMP:
|
|
case AML_MP_PLAYER_EVENT_AUDIO_INVALID_DATA:
|
|
case AML_MP_PLAYER_EVENT_VIDEO_UNSUPPORT:
|
|
case AML_MP_PLAYER_EVENT_AUDIO_DECODE_FIRST_FRAME:
|
|
break;
|
|
|
|
case AML_MP_PLAYER_EVENT_SUBTITLE_AVAIL: // int32_t
|
|
case AML_MP_PLAYER_EVENT_SUBTITLE_LOSEDATA:
|
|
case AML_MP_PLAYER_EVENT_SUBTITLE_TIMEOUT:
|
|
case AML_MP_PLAYER_EVENT_SUBTITLE_INVALID_TIMESTAMP:
|
|
case AML_MP_PLAYER_EVENT_SUBTITLE_INVALID_DATA:
|
|
case AML_MP_PLAYER_EVENT_SUBTITLE_AFD_EVENT:
|
|
value = (void *)&event.intValue;
|
|
break;
|
|
|
|
case AML_MP_PLAYER_EVENT_VIDEO_OVERFLOW: // uint32_t
|
|
case AML_MP_PLAYER_EVENT_VIDEO_UNDERFLOW:
|
|
case AML_MP_PLAYER_EVENT_AUDIO_OVERFLOW:
|
|
case AML_MP_PLAYER_EVENT_AUDIO_UNDERFLOW:
|
|
value = (void *)&event.longValue;
|
|
break;
|
|
|
|
case AML_MP_PLAYER_EVENT_VIDEO_INPUT_BUFFER_DONE: // free handle from drive
|
|
case AML_MP_PLAYER_EVENT_AUDIO_INPUT_BUFFER_DONE:
|
|
value = (void *)event.longValue;
|
|
break;
|
|
|
|
case AML_MP_PLAYER_EVENT_SCRAMBLING: // Aml_MP_PlayerEventScrambling
|
|
value = getFromHolder<AmlMpPlayerEventScrambling>(client->player_id, event.holder, scrambling, eventType);
|
|
break;
|
|
case AML_MP_PLAYER_EVENT_PID_CHANGED: //Aml_MP_PlayerEventPidChangeInfo
|
|
value = getFromHolder<AmlMpPlayerEventPidChanged>(client->player_id, event.holder, pidChanged, eventType);
|
|
break;
|
|
case AML_MP_PLAYER_EVENT_VIDEO_CHANGED: // Aml_MP_PlayerEventVideoFormat
|
|
value = getFromHolder<AmlMpPlayerEventVideoFormat>(client->player_id, event.holder, videoFormat, eventType);
|
|
break;
|
|
case AML_MP_PLAYER_EVENT_AUDIO_CHANGED: // Aml_MP_PlayerEventAudioFormat
|
|
value = getFromHolder<AmlMpPlayerEventAudioFormat>(client->player_id, event.holder, audioFormat, eventType);
|
|
break;
|
|
case AML_MP_PLAYER_EVENT_SUBTITLE_DIMENSION: // Aml_MP_SubtitleDimension
|
|
value = getFromHolder<AmlMpSubtitleDimension>(client->player_id, event.holder, subDimension, eventType);
|
|
break;
|
|
case AML_MP_PLAYER_EVENT_SUBTITLE_CHANNEL_UPDATE: // Aml_MP_SubtitleChannelUpdate
|
|
value = getFromHolder<AmlMpSubtitleChannelUpdate>(client->player_id, event.holder, subChannelUpdate, eventType);
|
|
break;
|
|
case AML_MP_PLAYER_EVENT_SUBTITLE_LANGUAGE: // char[4]
|
|
getFromHolder<AmlMpSubtitleLanguage>(client->player_id, event.holder, subLang, eventType);
|
|
value = (void *)subLang.c_str();
|
|
break;
|
|
case AML_MP_PLAYER_EVENT_SUBTITLE_INFO: // Aml_MP_SubtitleInfo
|
|
value = getFromHolder<AmlMpSubtitleInfo>(client->player_id, event.holder, subInfo, eventType);
|
|
break;
|
|
case AML_MP_PLAYER_EVENT_USERDATA_AFD:
|
|
case AML_MP_PLAYER_EVENT_USERDATA_CC: // Aml_MP_PlayerEventMpegUserData
|
|
value = getFromHolder<AmlMpPlayerEventMpegUserData>(client->player_id, event.holder, mpegUserData, eventType);
|
|
break;
|
|
case AML_MP_PLAYER_EVENT_SUBTITLE_DATA: // Aml_MP_SubtitleData
|
|
value = getFromHolder<AmlMpSubtitleData>(client->player_id, event.holder, subData, eventType);
|
|
break;
|
|
case AML_MP_MEDIAPLAYER_EVENT_PLAYBACK_COMPLETE: // mediaplayer
|
|
case AML_MP_MEDIAPLAYER_EVENT_PLAYBACK_SOF:
|
|
case AML_MP_MEDIAPLAYER_EVENT_PREPARED:
|
|
case AML_MP_MEDIAPLAYER_EVENT_STOPPED:
|
|
case AML_MP_MEDIAPLAYER_EVENT_MEDIA_ERROR:
|
|
case AML_MP_MEDIAPLAYER_EVENT_FIRST_FRAME_TOGGLED:
|
|
case AML_MP_MEDIAPLAYER_EVENT_BUFFERING_START:
|
|
case AML_MP_MEDIAPLAYER_EVENT_BUFFERING_END:
|
|
case AML_MP_MEDIAPLAYER_EVENT_VIDEO_UNSUPPORT:
|
|
case AML_MP_MEDIAPLAYER_EVENT_AUDIO_UNSUPPORT:
|
|
|
|
case AML_MP_DVRPLAYER_EVENT_ERROR: // drvpalyer will impl on client
|
|
case AML_MP_DVRPLAYER_EVENT_TRANSITION_OK:
|
|
case AML_MP_DVRPLAYER_EVENT_TRANSITION_FAILED:
|
|
case AML_MP_DVRPLAYER_EVENT_KEY_FAILURE:
|
|
case AML_MP_DVRPLAYER_EVENT_NO_KEY:
|
|
case AML_MP_DVRPLAYER_EVENT_REACHED_BEGIN:
|
|
case AML_MP_DVRPLAYER_EVENT_REACHED_END:
|
|
case AML_MP_DVRPLAYER_EVENT_NOTIFY_PLAYTIME:
|
|
case AML_MP_DVRPLAYER_EVENT_TIMESHIFT_FR_REACHED_BEGIN:
|
|
case AML_MP_DVRPLAYER_EVENT_TIMESHIFT_FF_REACHED_END:
|
|
case AML_MP_DVRPLAYER_EVENT_AUTO_RESUMED:
|
|
break;
|
|
default:
|
|
MLOGE("not support the event:%d", eventType);
|
|
return status::ok();;
|
|
}
|
|
|
|
cb(userData, eventType, (int64_t)value);
|
|
|
|
return status::ok();
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::makeCallbackToServer(Aml_MP_PlayerEventCallback cb, void* userData) {
|
|
if (mCallback != nullptr) {
|
|
return -1;
|
|
}
|
|
|
|
MLOG();
|
|
aml_mp::wptr<Aml_MP_PlayerClient> weakThis = this;
|
|
mCallback = ::ndk::SharedRefBase::make<ClientEventCallBack>(weakThis, player_id, cb, userData);
|
|
if (mCallback == nullptr) {
|
|
MLOGE("make event callback fail");
|
|
return -1;
|
|
}
|
|
|
|
if (mPlayerService == nullptr) {
|
|
MLOGE("mPlayerService is null");
|
|
return -1;
|
|
}
|
|
|
|
auto status = mPlayerService->registerPlayerCallback(player_id, mCallback);
|
|
if (!status.isOk()) {
|
|
mCallback = nullptr;
|
|
MLOGE("register event callback to server fail");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int Aml_MP_PlayerClient::registerEventCallback(Aml_MP_PlayerEventCallback cb, void* userData) {
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
MLOGI("enter %s", __FUNCTION__);
|
|
RETURN_IF(-1, (mServiceDead || !mServiceConnected));
|
|
RETURN_IF(-1, (cb == nullptr));
|
|
|
|
if (mCallback != nullptr) {
|
|
MLOGI("set callback:%p - %p", cb, userData);
|
|
return mCallback->setCallBack(cb, userData);
|
|
}
|
|
|
|
int32_t ret = makeCallbackToServer(cb, userData);
|
|
|
|
MLOGI("exit %s, ret:%d", __FUNCTION__, ret);
|
|
return ret;
|
|
}
|
|
#endif
|