/* * 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 #include #include #include #include #include #include #include #include #include #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 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 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(cookie); std::lock_guard _l(self->mutex); self->mServiceDead = true; self->mRawBinder = nullptr; self->mServiceConnected = false; } int Aml_MP_PlayerClient::start() { std::lock_guard 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 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 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 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 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 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 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 lock(mutex); MLOG(); sptr casBase = aml_handle_cast(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 lock(mutex); MLOG(); mCasServiceType = serviceType; mIptvCasParams = *params; return 0; } int Aml_MP_PlayerClient::flush() { std::lock_guard 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 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(decodeMode); MLOG(); std::lock_guard 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 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 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 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 bufPoolDataMq = std::make_unique(mBufPoolBufCnt, /*configureEventFlagWord=*/true); std::unique_ptr bufPoolFreeMq = std::make_unique(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 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(reinterpret_cast(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 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(reinterpret_cast(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 lock(mutex); RETURN_IF(-1, (mServiceDead || !mServiceConnected)); int64_t result = -1; auto status = mPlayerService->getCurrentPts(player_id, static_cast(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 lock(mutex); RETURN_IF(-1, (mServiceDead || !mServiceConnected)); int64_t result = -1; auto status = mPlayerService->getCurrentPts(player_id, static_cast(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 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 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(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 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 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 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 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 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 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 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(key); { std::lock_guard 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(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(parameter); break; case AML_MP_PLAYER_PARAMETER_AD_MIX_LEVEL: setToHolder(param, parameter); break; case AML_MP_PLAYER_PARAMETER_TELETEXT_CONTROL: setToHolder(param, parameter); break; case AML_MP_PLAYER_PARAMETER_VIDEO_CROP: setToHolder(param, parameter); break; case AML_MP_PLAYER_PARAMETER_AUDIO_LANGUAGE: setToHolder(param, parameter); break; case AML_MP_PLAYER_PARAMETER_CREATE_PARAMS: setToHolder(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 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 lock(mutex); RETURN_IF(-ENODEV, (mServiceDead || !mServiceConnected)); // Binder init MUST be outside lock } AmlMpPlayerParam inParam{}; inParam.key = static_cast(key); AmlMpPlayerParam param{}; { std::lock_guard lock(mutex); if (key == AML_MP_PLAYER_PARAMETER_AV_INFO_JSON) { // Aml_MP_AvInfo setToHolder(inParam, parameter); } else if (key == AML_MP_PLAYER_PARAMETER_AV_STAT_JSON) { // Aml_MP_AvStat Aml_MP_AvInfo setToHolder(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(player_id, param.holder, *(Aml_MP_PlayerCreateParams *)parameter, key); break; case AML_MP_PLAYER_PARAMETER_AD_MIX_LEVEL: getFromHolder(player_id, param.holder, *(Aml_MP_ADVolume *)parameter, key); break; case AML_MP_PLAYER_PARAMETER_TELETEXT_CONTROL: getFromHolder(player_id, param.holder, *(AML_MP_TeletextCtrlParam *)parameter, key); break; case AML_MP_PLAYER_PARAMETER_VIDEO_CROP: getFromHolder(player_id, param.holder, *(Aml_MP_Rect *)parameter, key); break; case AML_MP_PLAYER_PARAMETER_AUDIO_LANGUAGE: getFromHolder(player_id, param.holder, *(Aml_MP_AudioLanguage *)parameter, key); break; case AML_MP_PLAYER_PARAMETER_VIDEO_INFO: getFromHolder(player_id, param.holder, *(Aml_MP_VideoInfo *)parameter, key); break; case AML_MP_PLAYER_PARAMETER_VIDEO_DECODE_STAT: getFromHolder(player_id, param.holder, *(Aml_MP_VdecStat *)parameter, key); break; case AML_MP_PLAYER_PARAMETER_AUDIO_INFO: getFromHolder(player_id, param.holder, *(Aml_MP_AudioInfo *)parameter, key); break; case AML_MP_PLAYER_PARAMETER_AUDIO_DECODE_STAT: getFromHolder(player_id, param.holder, *(Aml_MP_AdecStat *)parameter, key); break; case AML_MP_PLAYER_PARAMETER_SUBTITLE_INFO: getFromHolder(player_id, param.holder, *(Aml_MP_SubtitleInfo *)parameter, key); break; case AML_MP_PLAYER_PARAMETER_SUBTITLE_DECODE_STAT: getFromHolder(player_id, param.holder, *(Aml_MP_SubDecStat *)parameter, key); break; case AML_MP_PLAYER_PARAMETER_AD_INFO: getFromHolder(player_id, param.holder, *(Aml_MP_AudioInfo *)parameter, key); break; case AML_MP_PLAYER_PARAMETER_AD_DECODE_STAT: getFromHolder(player_id, param.holder, *(Aml_MP_AdecStat *)parameter, key); break; case AML_MP_PLAYER_PARAMETER_AV_INFO_JSON: { // Aml_MP_AvInfo getFromHolder(player_id, param.holder, *(Aml_MP_AvInfo *)parameter, key); break; } case AML_MP_PLAYER_PARAMETER_AV_STAT_JSON: { // Aml_MP_AvStat getFromHolder(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 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 lock(mutex); RETURN_IF(-1, (mServiceDead || !mServiceConnected)); int32_t result = -1; auto status = mPlayerService->setAVSyncSource( player_id, static_cast(syncSource), &result); return status.isOk() ? result : -1; } int Aml_MP_PlayerClient::setPcrPid(int pid) { std::lock_guard 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 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 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 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 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 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 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 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 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 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 lock(mutex); RETURN_IF(-1, (mServiceDead || !mServiceConnected)); auto status = mPlayerService->getDecodingState( player_id, static_cast(streamType), &aidlState); if (status.isOk()) { *decodingState = static_cast(aidlState); return 0; } return -1; } int Aml_MP_PlayerClient::setADVolume(float volume) { std::lock_guard 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 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& weakThis, int32_t playerId, Aml_MP_PlayerEventCallback cb, void* userData) { std::lock_guard 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 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 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 casHandle = nullptr; void* userData = nullptr; { std::lock_guard 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(client->player_id, event.holder, scrambling, eventType); break; case AML_MP_PLAYER_EVENT_PID_CHANGED: //Aml_MP_PlayerEventPidChangeInfo value = getFromHolder(client->player_id, event.holder, pidChanged, eventType); break; case AML_MP_PLAYER_EVENT_VIDEO_CHANGED: // Aml_MP_PlayerEventVideoFormat value = getFromHolder(client->player_id, event.holder, videoFormat, eventType); break; case AML_MP_PLAYER_EVENT_AUDIO_CHANGED: // Aml_MP_PlayerEventAudioFormat value = getFromHolder(client->player_id, event.holder, audioFormat, eventType); break; case AML_MP_PLAYER_EVENT_SUBTITLE_DIMENSION: // Aml_MP_SubtitleDimension value = getFromHolder(client->player_id, event.holder, subDimension, eventType); break; case AML_MP_PLAYER_EVENT_SUBTITLE_CHANNEL_UPDATE: // Aml_MP_SubtitleChannelUpdate value = getFromHolder(client->player_id, event.holder, subChannelUpdate, eventType); break; case AML_MP_PLAYER_EVENT_SUBTITLE_LANGUAGE: // char[4] getFromHolder(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(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(client->player_id, event.holder, mpegUserData, eventType); break; case AML_MP_PLAYER_EVENT_SUBTITLE_DATA: // Aml_MP_SubtitleData value = getFromHolder(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 weakThis = this; mCallback = ::ndk::SharedRefBase::make(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 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