From 9b5831b0a1bc951c14c527b2a64513c9f1fe8665 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Wed, 9 Dec 2020 21:13:58 -0800 Subject: [PATCH] [PARTIAL] Migrate Tuner JNI to use Client interfaces Test: atest android.media.tv.tuner.cts Test: local test on SampleTIS Cuttlefish Bug: 174095851 Change-Id: I69e28132d6b5da34f99da4611b4fbc72e96913f8 --- media/jni/android_media_tv_Tuner.cpp | 615 ++++++++++++--------------- media/jni/android_media_tv_Tuner.h | 65 +-- media/jni/tuner/DemuxClient.cpp | 6 +- media/jni/tuner/FilterClient.cpp | 59 ++- media/jni/tuner/FilterClient.h | 19 +- 5 files changed, 385 insertions(+), 379 deletions(-) diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp index 440d5bc2f1670..6fa94f1b7a7b5 100644 --- a/media/jni/android_media_tv_Tuner.cpp +++ b/media/jni/android_media_tv_Tuner.cpp @@ -337,8 +337,8 @@ C2DataIdInfo::C2DataIdInfo(uint32_t index, uint64_t value) : C2Param(kParamSize, /////////////// MediaEvent /////////////////////// -MediaEvent::MediaEvent(sp filter, hidl_handle avHandle, - uint64_t dataId, uint64_t dataSize, jobject obj) : mFilter(filter), +MediaEvent::MediaEvent(sp filterClient, hidl_handle avHandle, + uint64_t dataId, uint64_t dataSize, jobject obj) : mFilterClient(filterClient), mDataId(dataId), mDataSize(dataSize), mBuffer(nullptr), mDataIdRefCnt(0), mAvHandleRefCnt(0), mIonHandle(nullptr) { JNIEnv *env = AndroidRuntime::getJNIEnv(); @@ -359,12 +359,13 @@ MediaEvent::~MediaEvent() { if (pC2Buffer != NULL) { pC2Buffer->unregisterOnDestroyNotify(&DestroyCallback, this); } + mFilterClient = NULL; } void MediaEvent::finalize() { - if (mAvHandleRefCnt == 0) { - mFilter->mFilterSp->releaseAvHandle( - hidl_handle(mAvHandle), mDataIdRefCnt == 0 ? mDataId : 0); + if (mAvHandleRefCnt == 0 && mFilterClient != NULL) { + mFilterClient->releaseAvHandle( + mAvHandle, mDataIdRefCnt == 0 ? mDataId : 0); native_handle_close(mAvHandle); } } @@ -382,21 +383,25 @@ jobject MediaEvent::getLinearBlock() { int numInts = 0; int memIndex; int dataSize; + SharedHandleInfo info = mFilterClient->getAvSharedHandleInfo(); + native_handle_t* avSharedHandle = info.sharedHandle; + uint64_t avSharedMemSize = info.size; + if (mAvHandle->numFds == 0) { - if (mFilter->mAvSharedHandle == NULL) { + if (avSharedHandle == NULL) { ALOGE("Shared AV memory handle is not initialized."); return NULL; } - if (mFilter->mAvSharedHandle->numFds == 0) { + if (avSharedHandle->numFds == 0) { ALOGE("Shared AV memory handle is empty."); return NULL; } - fd = mFilter->mAvSharedHandle->data[0]; - dataSize = mFilter->mAvSharedMemSize; - numInts = mFilter->mAvSharedHandle->numInts; + fd = avSharedHandle->data[0]; + dataSize = avSharedMemSize; + numInts = avSharedHandle->numInts; if (numInts > 0) { // If the first int in the shared native handle has value, use it as the index - memIndex = mFilter->mAvSharedHandle->data[mFilter->mAvSharedHandle->numFds]; + memIndex = avSharedHandle->data[avSharedHandle->numFds]; } } else { fd = mAvHandle->data[0]; @@ -407,11 +412,11 @@ jobject MediaEvent::getLinearBlock() { // event has value, use it as the index memIndex = mAvHandle->data[mAvHandle->numFds]; } else { - if (mFilter->mAvSharedHandle != NULL) { - numInts = mFilter->mAvSharedHandle->numInts; + if (avSharedHandle != NULL) { + numInts = avSharedHandle->numInts; if (numInts > 0) { // If the first int in the shared native handle has value, use it as the index - memIndex = mFilter->mAvSharedHandle->data[mFilter->mAvSharedHandle->numFds]; + memIndex = avSharedHandle->data[avSharedHandle->numFds]; } } } @@ -462,9 +467,9 @@ uint64_t MediaEvent::getAudioHandle() { return mDataId; } -/////////////// FilterCallback /////////////////////// +/////////////// FilterClientCallbackImpl /////////////////////// -jobjectArray FilterCallback::getSectionEvent( +jobjectArray FilterClientCallbackImpl::getSectionEvent( jobjectArray& arr, const std::vector& events) { JNIEnv *env = AndroidRuntime::getJNIEnv(); jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/SectionEvent"); @@ -486,7 +491,7 @@ jobjectArray FilterCallback::getSectionEvent( return arr; } -jobjectArray FilterCallback::getMediaEvent( +jobjectArray FilterClientCallbackImpl::getMediaEvent( jobjectArray& arr, const std::vector& events) { JNIEnv *env = AndroidRuntime::getJNIEnv(); jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/MediaEvent"); @@ -537,7 +542,7 @@ jobjectArray FilterCallback::getMediaEvent( if (mediaEvent.avMemory.getNativeHandle() != NULL || mediaEvent.avDataId != 0) { sp mediaEventSp = - new MediaEvent(mFilter, mediaEvent.avMemory, + new MediaEvent(mFilterClient, mediaEvent.avMemory, mediaEvent.avDataId, dataLength + offset, obj); mediaEventSp->mAvHandleRefCnt++; env->SetLongField(obj, eventContext, (jlong) mediaEventSp.get()); @@ -549,7 +554,7 @@ jobjectArray FilterCallback::getMediaEvent( return arr; } -jobjectArray FilterCallback::getPesEvent( +jobjectArray FilterClientCallbackImpl::getPesEvent( jobjectArray& arr, const std::vector& events) { JNIEnv *env = AndroidRuntime::getJNIEnv(); jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/PesEvent"); @@ -570,7 +575,7 @@ jobjectArray FilterCallback::getPesEvent( return arr; } -jobjectArray FilterCallback::getTsRecordEvent( +jobjectArray FilterClientCallbackImpl::getTsRecordEvent( jobjectArray& arr, const std::vector& events, const std::vector& eventsExt) { JNIEnv *env = AndroidRuntime::getJNIEnv(); @@ -623,7 +628,7 @@ jobjectArray FilterCallback::getTsRecordEvent( return arr; } -jobjectArray FilterCallback::getMmtpRecordEvent( +jobjectArray FilterClientCallbackImpl::getMmtpRecordEvent( jobjectArray& arr, const std::vector& events, const std::vector& eventsExt) { JNIEnv *env = AndroidRuntime::getJNIEnv(); @@ -665,7 +670,7 @@ jobjectArray FilterCallback::getMmtpRecordEvent( return arr; } -jobjectArray FilterCallback::getDownloadEvent( +jobjectArray FilterClientCallbackImpl::getDownloadEvent( jobjectArray& arr, const std::vector& events) { JNIEnv *env = AndroidRuntime::getJNIEnv(); jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/DownloadEvent"); @@ -689,7 +694,7 @@ jobjectArray FilterCallback::getDownloadEvent( return arr; } -jobjectArray FilterCallback::getIpPayloadEvent( +jobjectArray FilterClientCallbackImpl::getIpPayloadEvent( jobjectArray& arr, const std::vector& events) { JNIEnv *env = AndroidRuntime::getJNIEnv(); jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/IpPayloadEvent"); @@ -705,7 +710,7 @@ jobjectArray FilterCallback::getIpPayloadEvent( return arr; } -jobjectArray FilterCallback::getTemiEvent( +jobjectArray FilterClientCallbackImpl::getTemiEvent( jobjectArray& arr, const std::vector& events) { JNIEnv *env = AndroidRuntime::getJNIEnv(); jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/TemiEvent"); @@ -728,7 +733,7 @@ jobjectArray FilterCallback::getTemiEvent( return arr; } -jobjectArray FilterCallback::getScramblingStatusEvent( +jobjectArray FilterClientCallbackImpl::getScramblingStatusEvent( jobjectArray& arr, const std::vector& eventsExt) { JNIEnv *env = AndroidRuntime::getJNIEnv(); jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/ScramblingStatusEvent"); @@ -740,7 +745,7 @@ jobjectArray FilterCallback::getScramblingStatusEvent( return arr; } -jobjectArray FilterCallback::getIpCidChangeEvent( +jobjectArray FilterClientCallbackImpl::getIpCidChangeEvent( jobjectArray& arr, const std::vector& eventsExt) { JNIEnv *env = AndroidRuntime::getJNIEnv(); jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/IpCidChangeEvent"); @@ -752,7 +757,7 @@ jobjectArray FilterCallback::getIpCidChangeEvent( return arr; } -jobjectArray FilterCallback::getRestartEvent( +jobjectArray FilterClientCallbackImpl::getRestartEvent( jobjectArray& arr, const std::vector& eventsExt) { JNIEnv *env = AndroidRuntime::getJNIEnv(); jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/RestartEvent"); @@ -764,9 +769,9 @@ jobjectArray FilterCallback::getRestartEvent( return arr; } -Return FilterCallback::onFilterEvent_1_1(const DemuxFilterEvent& filterEvent, +void FilterClientCallbackImpl::onFilterEvent_1_1(const DemuxFilterEvent& filterEvent, const DemuxFilterEventExt& filterEventExt) { - ALOGD("FilterCallback::onFilterEvent_1_1"); + ALOGD("FilterClientCallbackImpl::onFilterEvent_1_1"); JNIEnv *env = AndroidRuntime::getJNIEnv(); jobjectArray array; @@ -848,14 +853,13 @@ Return FilterCallback::onFilterEvent_1_1(const DemuxFilterEvent& filterEve } } env->CallVoidMethod( - mFilter->mFilterObj, + mFilterObj, gFields.onFilterEventID, array); - return Void(); } -Return FilterCallback::onFilterEvent(const DemuxFilterEvent& filterEvent) { - ALOGD("FilterCallback::onFilterEvent"); +void FilterClientCallbackImpl::onFilterEvent(const DemuxFilterEvent& filterEvent) { + ALOGD("FilterClientCallbackImpl::onFilterEvent"); std::vector emptyEventsExt; DemuxFilterEventExt emptyFilterEventExt { .events = emptyEventsExt, @@ -863,49 +867,20 @@ Return FilterCallback::onFilterEvent(const DemuxFilterEvent& filterEvent) return onFilterEvent_1_1(filterEvent, emptyFilterEventExt); } -Return FilterCallback::onFilterStatus(const DemuxFilterStatus status) { - ALOGD("FilterCallback::onFilterStatus"); +void FilterClientCallbackImpl::onFilterStatus(const DemuxFilterStatus status) { + ALOGD("FilterClientCallbackImpl::onFilterStatus"); JNIEnv *env = AndroidRuntime::getJNIEnv(); env->CallVoidMethod( - mFilter->mFilterObj, + mFilterObj, gFields.onFilterStatusID, (jint)status); - return Void(); } -void FilterCallback::setFilter(const sp filter) { - ALOGD("FilterCallback::setFilter"); - // JNI Object - mFilter = filter; -} - -FilterCallback::~FilterCallback() {} - -/////////////// Filter /////////////////////// - -Filter::Filter(sp sp, jobject obj) : mFilterSp(sp) { - JNIEnv *env = AndroidRuntime::getJNIEnv(); - mFilterObj = env->NewWeakGlobalRef(obj); -} - -Filter::~Filter() { - JNIEnv *env = AndroidRuntime::getJNIEnv(); - - env->DeleteWeakGlobalRef(mFilterObj); - mFilterObj = NULL; - EventFlag::deleteEventFlag(&mFilterMQEventFlag); -} - -int Filter::close() { - Result r = mFilterSp->close(); - if (r == Result::SUCCESS) { - EventFlag::deleteEventFlag(&mFilterMQEventFlag); - } - return (int)r; -} - -sp Filter::getIFilter() { - return mFilterSp; +void FilterClientCallbackImpl::setFilter(jweak filterObj, sp filterClient) { + ALOGD("FilterClientCallbackImpl::setFilter"); + // Java Object + mFilterObj = filterObj; + mFilterClient = filterClient; } /////////////// TimeFilter /////////////////////// @@ -927,22 +902,23 @@ sp TimeFilter::getITimeFilter() { return mTimeFilterSp; } -/////////////// FrontendCallback /////////////////////// +/////////////// FrontendClientCallbackImpl /////////////////////// -FrontendCallback::FrontendCallback(jweak tunerObj, FrontendId id) : mObject(tunerObj), mId(id) {} +FrontendClientCallbackImpl::FrontendClientCallbackImpl( + jweak tunerObj, FrontendId id) : mObject(tunerObj), mId(id) {} -Return FrontendCallback::onEvent(FrontendEventType frontendEventType) { - ALOGD("FrontendCallback::onEvent, type=%d", frontendEventType); +void FrontendClientCallbackImpl::onEvent(FrontendEventType frontendEventType) { + ALOGD("FrontendClientCallbackImpl::onEvent, type=%d", frontendEventType); JNIEnv *env = AndroidRuntime::getJNIEnv(); env->CallVoidMethod( mObject, gFields.onFrontendEventID, (jint)frontendEventType); - return Void(); } -Return FrontendCallback::onScanMessage(FrontendScanMessageType type, const FrontendScanMessage& message) { - ALOGD("FrontendCallback::onScanMessage, type=%d", type); +void FrontendClientCallbackImpl::onScanMessage( + FrontendScanMessageType type, const FrontendScanMessage& message) { + ALOGD("FrontendClientCallbackImpl::onScanMessage, type=%d", type); JNIEnv *env = AndroidRuntime::getJNIEnv(); jclass clazz = env->FindClass("android/media/tv/tuner/Tuner"); switch(type) { @@ -1050,13 +1026,15 @@ Return FrontendCallback::onScanMessage(FrontendScanMessageType type, const mObject, env->GetMethodID(clazz, "onDvbsStandard", "(I)V"), standard); - } else if (std.getDiscriminator() == FrontendScanMessage::Standard::hidl_discriminator::tStd) { + } else if (std.getDiscriminator() == + FrontendScanMessage::Standard::hidl_discriminator::tStd) { standard = (jint) std.tStd(); env->CallVoidMethod( mObject, env->GetMethodID(clazz, "onDvbtStandard", "(I)V"), standard); - } else if (std.getDiscriminator() == FrontendScanMessage::Standard::hidl_discriminator::sifStd) { + } else if (std.getDiscriminator() == + FrontendScanMessage::Standard::hidl_discriminator::sifStd) { standard = (jint) std.sifStd(); env->CallVoidMethod( mObject, @@ -1081,17 +1059,17 @@ Return FrontendCallback::onScanMessage(FrontendScanMessageType type, const } env->CallVoidMethod( mObject, - env->GetMethodID(clazz, "onAtsc3PlpInfos", "([Landroid/media/tv/tuner/frontend/Atsc3PlpInfo;)V"), + env->GetMethodID(clazz, "onAtsc3PlpInfos", + "([Landroid/media/tv/tuner/frontend/Atsc3PlpInfo;)V"), array); break; } } - return Void(); } -Return FrontendCallback::onScanMessageExt1_1(FrontendScanMessageTypeExt1_1 type, +void FrontendClientCallbackImpl::onScanMessageExt1_1(FrontendScanMessageTypeExt1_1 type, const FrontendScanMessageExt1_1& message) { - ALOGD("FrontendCallback::onScanMessageExt1_1, type=%d", type); + ALOGD("FrontendClientCallbackImpl::onScanMessageExt1_1, type=%d", type); JNIEnv *env = AndroidRuntime::getJNIEnv(); jclass clazz = env->FindClass("android/media/tv/tuner/Tuner"); switch(type) { @@ -1165,7 +1143,6 @@ Return FrontendCallback::onScanMessageExt1_1(FrontendScanMessageTypeExt1_1 default: break; } - return Void(); } /////////////// Tuner /////////////////////// @@ -1202,7 +1179,11 @@ JTuner::~JTuner() { env->DeleteWeakGlobalRef(mObject); env->DeleteGlobalRef(mClass); mTuner = NULL; + mFe = NULL; + mDemux = NULL; mTunerClient = NULL; + mFeClient = NULL; + mDemuxClient = NULL; mClass = NULL; mObject = NULL; } @@ -1252,9 +1233,11 @@ jobject JTuner::getFrontendIds() { return obj; } -jobject JTuner::openFrontendById(int id) { +jobject JTuner::openFrontendByHandle(int feHandle) { sp fe; Result res; + uint32_t id = getResourceIdFromHandle(feHandle); + mTuner->openFrontendById(id, [&](Result r, const sp& frontend) { fe = frontend; res = r; @@ -1269,11 +1252,25 @@ jobject JTuner::openFrontendById(int id) { if (mDemux != NULL) { mDemux->setFrontendDataSource(mFeId); } - sp feCb = new FrontendCallback(mObject, id); - fe->setCallback(feCb); jint jId = (jint) id; + // TODO: Handle reopening frontend with different handle + sp feClient = mTunerClient->openFrontend(feHandle); + if (feClient == NULL) { + ALOGE("Failed to open frontend"); + return NULL; + } + mFeClient = feClient; + + mFeId = mFeClient->getId(); + jId = (jint) id; + if (mDemuxClient != NULL) { + mDemuxClient->setFrontendDataSource(mFeClient); + } + sp feClientCb = new FrontendClientCallbackImpl(mObject, id); + mFeClient->setCallback(feClientCb); + JNIEnv *env = AndroidRuntime::getJNIEnv(); // TODO: add more fields to frontend return env->NewObject( @@ -1589,30 +1586,19 @@ jobject JTuner::openLnbByName(jstring name) { } int JTuner::tune(const FrontendSettings& settings, const FrontendSettingsExt1_1& settingsExt1_1) { - if (mFe == NULL) { + if (mFeClient == nullptr) { ALOGE("frontend is not initialized"); return (int)Result::INVALID_STATE; } - Result result; - sp<::android::hardware::tv::tuner::V1_1::IFrontend> fe_1_1 = - ::android::hardware::tv::tuner::V1_1::IFrontend::castFrom(mFe); - if (fe_1_1 == NULL) { - ALOGD("1.1 frontend is not found. Using 1.0 instead."); - result = mFe->tune(settings); - return (int)result; - } - - result = fe_1_1->tune_1_1(settings, settingsExt1_1); - return (int)result; + return (int) mFeClient->tune(settings,settingsExt1_1); } int JTuner::stopTune() { - if (mFe == NULL) { + if (mFeClient == nullptr) { ALOGE("frontend is not initialized"); return (int)Result::INVALID_STATE; } - Result result = mFe->stopTune(); - return (int)result; + return (int) mFeClient->stopTune(); } int JTuner::scan(const FrontendSettings& settings, FrontendScanType scanType, @@ -1662,28 +1648,47 @@ int JTuner::setLna(bool enable) { } Result JTuner::openDemux() { - if (mTuner == nullptr) { + if (mTuner == nullptr || mTunerClient == nullptr) { return Result::NOT_INITIALIZED; } - if (mDemux != nullptr) { - return Result::SUCCESS; - } - Result res; - uint32_t id; - sp demuxSp; - mTuner->openDemux([&](Result r, uint32_t demuxId, const sp& demux) { - demuxSp = demux; - id = demuxId; - res = r; - ALOGD("open demux, id = %d", demuxId); - }); - if (res == Result::SUCCESS) { - mDemux = demuxSp; - mDemuxId = id; - if (mFe != NULL) { - mDemux->setFrontendDataSource(mFeId); + + Result res = Result::SUCCESS; + + if (mDemux == nullptr) { + uint32_t id; + sp demuxSp; + mTuner->openDemux([&](Result r, uint32_t demuxId, const sp& demux) { + demuxSp = demux; + id = demuxId; + res = r; + ALOGD("open demux, id = %d", demuxId); + }); + if (res == Result::SUCCESS) { + mDemux = demuxSp; + mDemuxId = id; + if (mFe != NULL) { + mDemux->setFrontendDataSource(mFeId); + } + } else { + return res; } } + + // TODO: replace demux opening with mTunerClient->openDemux(handle) + // when DemuxClient is fully ready + if (mDemuxClient == nullptr) { + sp demuxClient = new DemuxClient(); + if (demuxClient == NULL) { + ALOGE("Failed to open demux"); + return Result::UNKNOWN_ERROR; + } + mDemuxClient = demuxClient; + mDemuxClient->setHidlDemux(mDemux); + if (mFeClient != NULL) { + mDemuxClient->setFrontendDataSource(mFeClient); + } + } + return res; } @@ -1701,23 +1706,31 @@ jint JTuner::close() { return (jint) res; } } + + if (mFeClient != NULL) { + res = mFeClient->close(); + if (res != Result::SUCCESS) { + return (jint) res; + } + mFeClient = NULL; + } + if (mDemuxClient != NULL) { + res = mDemuxClient->close(); + if (res != Result::SUCCESS) { + return (jint) res; + } + mDemuxClient = NULL; + } return (jint) res; } -jobject JTuner::getAvSyncHwId(sp filter) { - if (mDemux == NULL) { +jobject JTuner::getAvSyncHwId(sp filterClient) { + if (mDemuxClient == NULL) { return NULL; } - uint32_t avSyncHwId; - Result res; - sp iFilterSp = filter->getIFilter(); - mDemux->getAvSyncHwId(iFilterSp, - [&](Result r, uint32_t id) { - res = r; - avSyncHwId = id; - }); - if (res == Result::SUCCESS) { + int avSyncHwId = mDemuxClient->getAvSyncHwId(filterClient); + if (avSyncHwId >= 0) { JNIEnv *env = AndroidRuntime::getJNIEnv(); jclass integerClazz = env->FindClass("java/lang/Integer"); jmethodID intInit = env->GetMethodID(integerClazz, "", "(I)V"); @@ -1727,17 +1740,11 @@ jobject JTuner::getAvSyncHwId(sp filter) { } jobject JTuner::getAvSyncTime(jint id) { - if (mDemux == NULL) { + if (mDemuxClient == NULL) { return NULL; } - uint64_t time; - Result res; - mDemux->getAvSyncTime(static_cast(id), - [&](Result r, uint64_t ts) { - res = r; - time = ts; - }); - if (res == Result::SUCCESS) { + long time = mDemuxClient->getAvSyncTime((int)id); + if (time >= 0) { JNIEnv *env = AndroidRuntime::getJNIEnv(); jclass longClazz = env->FindClass("java/lang/Long"); jmethodID longInit = env->GetMethodID(longClazz, "", "(J)V"); @@ -1747,13 +1754,13 @@ jobject JTuner::getAvSyncTime(jint id) { } int JTuner::connectCiCam(jint id) { - if (mDemux == NULL) { + if (mDemuxClient == NULL) { Result r = openDemux(); if (r != Result::SUCCESS) { return (int) r; } } - Result r = mDemux->connectCiCam(static_cast(id)); + Result r = mDemuxClient->connectCiCam((int)id); return (int) r; } @@ -1779,13 +1786,13 @@ int JTuner::linkCiCam(int id) { } int JTuner::disconnectCiCam() { - if (mDemux == NULL) { + if (mDemuxClient == NULL) { Result r = openDemux(); if (r != Result::SUCCESS) { return (int) r; } } - Result r = mDemux->disconnectCiCam(); + Result r = mDemuxClient->disconnectCiCam(); return (int) r; } @@ -1832,34 +1839,25 @@ jobject JTuner::openDescrambler() { } jobject JTuner::openFilter(DemuxFilterType type, int bufferSize) { - if (mDemux == NULL) { + if (mDemux == NULL || mDemuxClient == NULL) { if (openDemux() != Result::SUCCESS) { return NULL; } } - sp iFilterSp; - sp<::android::hardware::tv::tuner::V1_1::IFilter> iFilterSp_1_1; - sp callback = new FilterCallback(); - Result res; - mDemux->openFilter(type, bufferSize, callback, - [&](Result r, const sp& filter) { - iFilterSp = filter; - res = r; - }); - if (res != Result::SUCCESS || iFilterSp == NULL) { + sp filterClient; + sp callback = new FilterClientCallbackImpl(); + filterClient = mDemuxClient->openFilter(type, bufferSize, callback); + if (filterClient == NULL) { ALOGD("Failed to open filter, type = %d", type.mainType); return NULL; } uint64_t fId; - iFilterSp->getId([&](Result, uint32_t filterId) { - fId = filterId; - }); - iFilterSp_1_1 = ::android::hardware::tv::tuner::V1_1::IFilter::castFrom(iFilterSp); - if (iFilterSp_1_1 != NULL) { - iFilterSp_1_1->getId64Bit([&](Result, uint64_t filterId64Bit) { - fId = filterId64Bit; - }); + Result res = filterClient->getId64Bit(fId); + if (res != Result::SUCCESS) { + uint32_t id; + filterClient->getId(id); + fId = static_cast(id); } JNIEnv *env = AndroidRuntime::getJNIEnv(); @@ -1869,35 +1867,9 @@ jobject JTuner::openFilter(DemuxFilterType type, int bufferSize) { gFields.filterInitID, (jlong) fId); - sp filterSp = new Filter(iFilterSp, filterObj); - filterSp->incStrong(filterObj); - env->SetLongField(filterObj, gFields.filterContext, (jlong)filterSp.get()); - filterSp->mIsMediaFilter = false; - filterSp->mAvSharedHandle = NULL; - callback->setFilter(filterSp); - - if (type.mainType == DemuxFilterMainType::MMTP) { - if (type.subType.mmtpFilterType() == DemuxMmtpFilterType::AUDIO || - type.subType.mmtpFilterType() == DemuxMmtpFilterType::VIDEO) { - filterSp->mIsMediaFilter = true; - } - } - - if (type.mainType == DemuxFilterMainType::TS) { - if (type.subType.tsFilterType() == DemuxTsFilterType::AUDIO || - type.subType.tsFilterType() == DemuxTsFilterType::VIDEO) { - filterSp->mIsMediaFilter = true; - } - } - - if (iFilterSp_1_1 != NULL && filterSp->mIsMediaFilter) { - iFilterSp_1_1->getAvSharedHandle([&](Result r, hidl_handle avMemory, uint64_t avMemSize) { - if (r == Result::SUCCESS) { - filterSp->mAvSharedHandle = native_handle_clone(avMemory.getNativeHandle()); - filterSp->mAvSharedMemSize = avMemSize; - } - }); - } + filterClient->incStrong(filterObj); + env->SetLongField(filterObj, gFields.filterContext, (jlong)filterClient.get()); + callback->setFilter(env->NewWeakGlobalRef(filterObj), filterClient); return filterObj; } @@ -2616,6 +2588,15 @@ jint JTuner::closeFrontend() { if (r == Result::SUCCESS) { mFe = NULL; mFe_1_1 = NULL; + } else { + return (jint) r; + } + + if (mFeClient != NULL) { + r = mFeClient->close(); + } + if (r == Result::SUCCESS) { + mFeClient = NULL; } return (jint) r; } @@ -2627,10 +2608,18 @@ jint JTuner::closeDemux() { } if (r == Result::SUCCESS) { mDemux = NULL; + } else { + return (jint) r; + } + + if (mDemuxClient != NULL) { + r = mDemuxClient->close(); + } + if (r == Result::SUCCESS) { + mDemuxClient = NULL; } return (jint) r; } - } // namespace android //////////////////////////////////////////////////////////////////////////////// @@ -3271,8 +3260,8 @@ static FrontendSettingsExt1_1 getFrontendSettingsExt1_1(JNIEnv *env, int type, j return settingsExt1_1; } -static sp getFilter(JNIEnv *env, jobject filter) { - return (Filter *)env->GetLongField(filter, gFields.filterContext); +static sp getFilterClient(JNIEnv *env, jobject filter) { + return (FilterClient *)env->GetLongField(filter, gFields.filterContext); } static DvrSettings getDvrSettings(JNIEnv *env, jobject settings, bool isRecorder) { @@ -3383,7 +3372,7 @@ static void android_media_tv_Tuner_native_init(JNIEnv *env) { static void android_media_tv_Tuner_native_setup(JNIEnv *env, jobject thiz) { sp tuner = new JTuner(env, thiz); - setTuner(env,thiz, tuner); + setTuner(env, thiz, tuner); } static jint android_media_tv_Tuner_native_get_tuner_version(JNIEnv *env, jobject thiz) { @@ -3399,8 +3388,7 @@ static jobject android_media_tv_Tuner_get_frontend_ids(JNIEnv *env, jobject thiz static jobject android_media_tv_Tuner_open_frontend_by_handle( JNIEnv *env, jobject thiz, jint handle) { sp tuner = getTuner(env, thiz); - uint32_t id = getResourceIdFromHandle(handle); - return tuner->openFrontendById(id); + return tuner->openFrontendByHandle(handle); } static int android_media_tv_Tuner_tune(JNIEnv *env, jobject thiz, jint type, jobject settings) { @@ -3446,13 +3434,13 @@ static jobject android_media_tv_Tuner_get_frontend_status( static jobject android_media_tv_Tuner_get_av_sync_hw_id( JNIEnv *env, jobject thiz, jobject filter) { - sp filterSp = getFilter(env, filter); - if (filterSp == NULL) { - ALOGD("Failed to get sync ID. Filter not found"); + sp filterClient = getFilterClient(env, filter); + if (filterClient == NULL) { + ALOGD("Failed to get sync ID. Filter client not found"); return NULL; } sp tuner = getTuner(env, thiz); - return tuner->getAvSyncHwId(filterSp); + return tuner->getAvSyncHwId(filterClient); } static jobject android_media_tv_Tuner_get_av_sync_time(JNIEnv *env, jobject thiz, jint id) { @@ -3913,26 +3901,13 @@ static DemuxFilterSettings getFilterConfiguration( } static Result configureIpFilterContextId( - JNIEnv *env, sp iFilterSp, jobject ipFilterConfigObj) { + JNIEnv *env, sp filterClient, jobject ipFilterConfigObj) { jclass clazz = env->FindClass( "android/media/tv/tuner/filter/IpFilterConfiguration"); uint32_t cid = env->GetIntField(ipFilterConfigObj, env->GetFieldID( clazz, "mIpFilterContextId", "I")); - Result res = Result::SUCCESS; - if (cid != static_cast(Constant::INVALID_IP_FILTER_CONTEXT_ID)) { - sp<::android::hardware::tv::tuner::V1_1::IFilter> iFilterSp_1_1; - iFilterSp_1_1 = ::android::hardware::tv::tuner::V1_1::IFilter::castFrom(iFilterSp); - if (iFilterSp_1_1 != NULL) { - res = iFilterSp_1_1->configureIpCid(cid); - if (res != Result::SUCCESS) { - return res; - } - } else { - ALOGW("configureIpCid is not supported with the current HAL implementation."); - } - } - return res; + return filterClient->configureIpFilterContextId(cid); } static jint copyData(JNIEnv *env, std::unique_ptr& mq, EventFlag* flag, jbyteArray buffer, @@ -3975,21 +3950,20 @@ static bool isAvFilterSettings(DemuxFilterSettings filterSettings) { static jint android_media_tv_Tuner_configure_filter( JNIEnv *env, jobject filter, int type, int subtype, jobject settings) { ALOGD("configure filter type=%d, subtype=%d", type, subtype); - sp filterSp = getFilter(env, filter); - sp iFilterSp = filterSp->getIFilter(); - if (iFilterSp == NULL) { + sp filterClient = getFilterClient(env, filter); + if (filterClient == NULL) { ALOGD("Failed to configure filter: filter not found"); return (jint) Result::NOT_INITIALIZED; } DemuxFilterSettings filterSettings = getFilterConfiguration(env, type, subtype, settings); - Result res = iFilterSp->configure(filterSettings); + Result res = filterClient->configure(filterSettings); if (res != Result::SUCCESS) { return (jint) res; } if (static_cast(type) == DemuxFilterMainType::IP) { - res = configureIpFilterContextId(env, iFilterSp, settings); + res = configureIpFilterContextId(env, filterClient, settings); if (res != Result::SUCCESS) { return (jint) res; } @@ -3997,49 +3971,19 @@ static jint android_media_tv_Tuner_configure_filter( AvStreamType streamType; if (isAvFilterSettings(filterSettings) && getAvStreamType(env, settings, streamType)) { - sp<::android::hardware::tv::tuner::V1_1::IFilter> iFilterSp_1_1; - iFilterSp_1_1 = ::android::hardware::tv::tuner::V1_1::IFilter::castFrom(iFilterSp); - if (iFilterSp_1_1 != NULL) { - res = iFilterSp_1_1->configureAvStreamType(streamType); - } else { - ALOGW("configureAvStreamType is not supported with the current HAL implementation."); - } - if (res != Result::SUCCESS) { - return (jint) res; - } + res = filterClient->configureAvStreamType(streamType); } - - MQDescriptorSync filterMQDesc; - Result getQueueDescResult = Result::UNKNOWN_ERROR; - if (filterSp->mFilterMQ == NULL) { - iFilterSp->getQueueDesc( - [&](Result r, const MQDescriptorSync& desc) { - filterMQDesc = desc; - getQueueDescResult = r; - ALOGD("getFilterQueueDesc"); - }); - if (getQueueDescResult == Result::SUCCESS) { - filterSp->mFilterMQ = std::make_unique(filterMQDesc, true); - EventFlag::createEventFlag( - filterSp->mFilterMQ->getEventFlagWord(), &(filterSp->mFilterMQEventFlag)); - } - } - return (jint) getQueueDescResult; + return (jint) res; } static jint android_media_tv_Tuner_get_filter_id(JNIEnv* env, jobject filter) { - sp iFilterSp = getFilter(env, filter)->getIFilter(); - if (iFilterSp == NULL) { - ALOGD("Failed to get filter ID: filter not found"); + sp filterClient = getFilterClient(env, filter); + if (filterClient == NULL) { + ALOGD("Failed to get filter ID: filter client not found"); return (int) Result::NOT_INITIALIZED; } - Result res; uint32_t id; - iFilterSp->getId( - [&](Result r, uint32_t filterId) { - res = r; - id = filterId; - }); + Result res = filterClient->getId(id); if (res != Result::SUCCESS) { return (jint) Constant::INVALID_FILTER_ID; } @@ -4047,30 +3991,13 @@ static jint android_media_tv_Tuner_get_filter_id(JNIEnv* env, jobject filter) { } static jlong android_media_tv_Tuner_get_filter_64bit_id(JNIEnv* env, jobject filter) { - sp iFilterSp = getFilter(env, filter)->getIFilter(); - if (iFilterSp == NULL) { - ALOGD("Failed to get filter ID: filter not found"); - return static_cast( - ::android::hardware::tv::tuner::V1_1::Constant64Bit::INVALID_FILTER_ID_64BIT); + sp filterClient = getFilterClient(env, filter); + if (filterClient == NULL) { + ALOGD("Failed to get filter ID 64 bit: filter client not found"); + return (int) Result::NOT_INITIALIZED; } - - sp<::android::hardware::tv::tuner::V1_1::IFilter> iFilterSp_1_1; - iFilterSp_1_1 = ::android::hardware::tv::tuner::V1_1::IFilter::castFrom(iFilterSp); - Result res; uint64_t id; - - if (iFilterSp_1_1 != NULL) { - iFilterSp_1_1->getId64Bit( - [&](Result r, uint64_t filterId64Bit) { - res = r; - id = filterId64Bit; - }); - } else { - ALOGW("getId64Bit is not supported with the current HAL implementation."); - return static_cast( - ::android::hardware::tv::tuner::V1_1::Constant64Bit::INVALID_FILTER_ID_64BIT); - } - + Result res = filterClient->getId64Bit(id); return (res == Result::SUCCESS) ? static_cast(id) : static_cast( ::android::hardware::tv::tuner::V1_1::Constant64Bit::INVALID_FILTER_ID_64BIT); @@ -4078,96 +4005,96 @@ static jlong android_media_tv_Tuner_get_filter_64bit_id(JNIEnv* env, jobject fil static jint android_media_tv_Tuner_configure_monitor_event( JNIEnv* env, jobject filter, int monitorEventType) { - sp iFilterSp = getFilter(env, filter)->getIFilter(); - if (iFilterSp == NULL) { - ALOGD("Failed to configure scrambling event: filter not found"); - return (jint) Result::NOT_INITIALIZED; + sp filterClient = getFilterClient(env, filter); + if (filterClient == NULL) { + ALOGD("Failed to configure scrambling event: filter client not found"); + return (int) Result::NOT_INITIALIZED; } - - sp<::android::hardware::tv::tuner::V1_1::IFilter> iFilterSp_1_1; - iFilterSp_1_1 = ::android::hardware::tv::tuner::V1_1::IFilter::castFrom(iFilterSp); - Result res; - - if (iFilterSp_1_1 != NULL) { - res = iFilterSp_1_1->configureMonitorEvent(monitorEventType); - } else { - ALOGW("configureScramblingEvent is not supported with the current HAL implementation."); - return (jint) Result::INVALID_STATE; - } - + Result res = filterClient->configureMonitorEvent(monitorEventType); return (jint) res; } static jint android_media_tv_Tuner_set_filter_data_source( JNIEnv* env, jobject filter, jobject srcFilter) { - sp iFilterSp = getFilter(env, filter)->getIFilter(); - if (iFilterSp == NULL) { - ALOGD("Failed to set filter data source: filter not found"); - return (jint) Result::NOT_INITIALIZED; + sp filterClient = getFilterClient(env, filter); + if (filterClient == NULL) { + ALOGD("Failed to set filter data source: filter client not found"); + return (int) Result::NOT_INITIALIZED; } - Result r; + Result res; if (srcFilter == NULL) { - r = iFilterSp->setDataSource(NULL); + res = filterClient->setDataSource(NULL); } else { - sp srcSp = getFilter(env, srcFilter)->getIFilter(); - if (iFilterSp == NULL) { + sp srcClient = getFilterClient(env, srcFilter); + if (srcClient == NULL) { ALOGD("Failed to set filter data source: src filter not found"); return (jint) Result::INVALID_ARGUMENT; } - r = iFilterSp->setDataSource(srcSp); + res = filterClient->setDataSource(srcClient); } - return (jint) r; + return (jint) res; } static jint android_media_tv_Tuner_start_filter(JNIEnv *env, jobject filter) { - sp iFilterSp = getFilter(env, filter)->getIFilter(); - if (iFilterSp == NULL) { - ALOGD("Failed to start filter: filter not found"); - return (jint) Result::NOT_INITIALIZED; + sp filterClient = getFilterClient(env, filter); + if (filterClient == NULL) { + ALOGD("Failed to start filter: filter client not found"); + return (int) Result::NOT_INITIALIZED; } - Result r = iFilterSp->start(); - return (jint) r; + return (jint) filterClient->start(); } static jint android_media_tv_Tuner_stop_filter(JNIEnv *env, jobject filter) { - sp iFilterSp = getFilter(env, filter)->getIFilter(); - if (iFilterSp == NULL) { - ALOGD("Failed to stop filter: filter not found"); - return (jint) Result::NOT_INITIALIZED; + sp filterClient = getFilterClient(env, filter); + if (filterClient == NULL) { + ALOGD("Failed to stop filter: filter client not found"); + return (int) Result::NOT_INITIALIZED; } - Result r = iFilterSp->stop(); - return (jint) r; + return (jint) filterClient->stop(); } static jint android_media_tv_Tuner_flush_filter(JNIEnv *env, jobject filter) { - sp iFilterSp = getFilter(env, filter)->getIFilter(); - if (iFilterSp == NULL) { - ALOGD("Failed to flush filter: filter not found"); - return (jint) Result::NOT_INITIALIZED; + sp filterClient = getFilterClient(env, filter); + if (filterClient == NULL) { + ALOGD("Failed to flush filter: filter client not found"); + return (int) Result::NOT_INITIALIZED; } - Result r = iFilterSp->flush(); - return (jint) r; + return (jint) filterClient->flush(); } static jint android_media_tv_Tuner_read_filter_fmq( JNIEnv *env, jobject filter, jbyteArray buffer, jlong offset, jlong size) { - sp filterSp = getFilter(env, filter); - if (filterSp == NULL) { + sp filterClient = getFilterClient(env, filter); + if (filterClient == NULL) { jniThrowException(env, "java/lang/IllegalStateException", - "Failed to read filter FMQ: filter not found"); + "Failed to read filter FMQ: filter client not found"); return 0; } - return copyData(env, filterSp->mFilterMQ, filterSp->mFilterMQEventFlag, buffer, offset, size); + + jboolean isCopy; + jbyte *dst = env->GetByteArrayElements(buffer, &isCopy); + ALOGD("copyData, isCopy=%d", isCopy); + if (dst == nullptr) { + jniThrowRuntimeException(env, "Failed to GetByteArrayElements"); + return 0; + } + int realReadSize = filterClient->read(reinterpret_cast(dst) + offset, size); + env->ReleaseByteArrayElements(buffer, dst, 0); + if (realReadSize < 0) { + return (jint) Result::UNKNOWN_ERROR; + } + return (jint) Result::SUCCESS; } static jint android_media_tv_Tuner_close_filter(JNIEnv *env, jobject filter) { - sp iFilterSp = getFilter(env, filter)->getIFilter(); - if (iFilterSp == NULL) { - ALOGD("Failed to close filter: filter not found"); - return (jint) Result::NOT_INITIALIZED; + sp filterClient = getFilterClient(env, filter); + if (filterClient == NULL) { + jniThrowException(env, "java/lang/IllegalStateException", + "Failed to close filter: filter client not found"); + return 0; } - Result r = iFilterSp->close(); - return (jint) r; + + return (jint) filterClient->close(); } static sp getTimeFilter(JNIEnv *env, jobject filter) { @@ -4275,7 +4202,8 @@ static jint android_media_tv_Tuner_descrambler_add_pid( if (descramblerSp == NULL) { return (jint) Result::NOT_INITIALIZED; } - sp iFilterSp = getFilter(env, filter)->getIFilter(); + // TODO: use filter client once descramblerClient is ready + sp iFilterSp = getFilterClient(env, filter)->getHalFilter(); Result result = descramblerSp->addPid(getDemuxPid((int)pidType, (int)pid), iFilterSp); return (jint) result; } @@ -4286,7 +4214,8 @@ static jint android_media_tv_Tuner_descrambler_remove_pid( if (descramblerSp == NULL) { return (jint) Result::NOT_INITIALIZED; } - sp iFilterSp = getFilter(env, filter)->getIFilter(); + // TODO: use filter client once descramblerClient is ready + sp iFilterSp = getFilterClient(env, filter)->getHalFilter(); Result result = descramblerSp->removePid(getDemuxPid((int)pidType, (int)pid), iFilterSp); return (jint) result; } @@ -4358,12 +4287,13 @@ static jint android_media_tv_Tuner_attach_filter(JNIEnv *env, jobject dvr, jobje if (dvrSp == NULL) { return (jint) Result::NOT_INITIALIZED; } - sp filterSp = getFilter(env, filter); - if (filterSp == NULL) { + sp filterClient = getFilterClient(env, filter); + if (filterClient == NULL) { return (jint) Result::INVALID_ARGUMENT; } sp iDvrSp = dvrSp->getIDvr(); - sp iFilterSp = filterSp->getIFilter(); + // TODO: use filter client once dvrClient is ready + sp iFilterSp = filterClient->getHalFilter(); Result result = iDvrSp->attachFilter(iFilterSp); return (jint) result; } @@ -4373,12 +4303,13 @@ static jint android_media_tv_Tuner_detach_filter(JNIEnv *env, jobject dvr, jobje if (dvrSp == NULL) { return (jint) Result::NOT_INITIALIZED; } - sp filterSp = getFilter(env, filter); - if (filterSp == NULL) { + sp filterClient = getFilterClient(env, filter); + if (filterClient == NULL) { return (jint) Result::INVALID_ARGUMENT; } sp iDvrSp = dvrSp->getIDvr(); - sp iFilterSp = filterSp->getIFilter(); + // TODO: use filter client once dvrClient is ready + sp iFilterSp = filterClient->getHalFilter(); Result result = iDvrSp->detachFilter(iFilterSp); return (jint) result; } diff --git a/media/jni/android_media_tv_Tuner.h b/media/jni/android_media_tv_Tuner.h index bec834cac2381..4149228523778 100644 --- a/media/jni/android_media_tv_Tuner.h +++ b/media/jni/android_media_tv_Tuner.h @@ -34,6 +34,11 @@ #include #include +#include "tuner/DemuxClient.h" +#include "tuner/FilterClient.h" +#include "tuner/FilterClientCallback.h" +#include "tuner/FrontendClient.h" +#include "tuner/FrontendClientCallback.h" #include "tuner/TunerClient.h" #include "jni.h" @@ -95,6 +100,7 @@ struct Lnb : public RefBase { Lnb(sp sp, jobject obj); ~Lnb(); sp getILnb(); + // TODO: remove after migrate to client lib sp mLnbSp; jweak mLnbObj; }; @@ -115,6 +121,7 @@ struct Dvr : public RefBase { jint close(); MQ& getDvrMQ(); sp getIDvr(); + // TODO: remove after migrate to client lib sp mDvrSp; jweak mDvrObj; std::unique_ptr mDvrMQ; @@ -123,29 +130,15 @@ struct Dvr : public RefBase { int mFd; }; -struct Filter : public RefBase { - Filter(sp sp, jobject obj); - ~Filter(); - int close(); - sp getIFilter(); - sp mFilterSp; - std::unique_ptr mFilterMQ; - EventFlag* mFilterMQEventFlag; - jweak mFilterObj; - native_handle_t* mAvSharedHandle; - uint64_t mAvSharedMemSize; - bool mIsMediaFilter; -}; - struct MediaEvent : public RefBase { - MediaEvent(sp filter, hidl_handle avHandle, uint64_t dataId, + MediaEvent(sp filterClient, hidl_handle avHandle, uint64_t dataId, uint64_t dataSize, jobject obj); ~MediaEvent(); jobject getLinearBlock(); uint64_t getAudioHandle(); void finalize(); - sp mFilter; + sp mFilterClient; native_handle_t* mAvHandle; uint64_t mDataId; uint64_t mDataSize; @@ -159,16 +152,16 @@ struct MediaEvent : public RefBase { std::weak_ptr mC2Buffer; }; -struct FilterCallback : public IFilterCallback { - ~FilterCallback(); - virtual Return onFilterEvent_1_1(const DemuxFilterEvent& filterEvent, +struct FilterClientCallbackImpl : public FilterClientCallback { + virtual void onFilterEvent_1_1(const DemuxFilterEvent& filterEvent, const DemuxFilterEventExt& filterEventExt); - virtual Return onFilterEvent(const DemuxFilterEvent& filterEvent); - virtual Return onFilterStatus(const DemuxFilterStatus status); + virtual void onFilterEvent(const DemuxFilterEvent& filterEvent); + virtual void onFilterStatus(const DemuxFilterStatus status); - void setFilter(const sp filter); + void setFilter(jweak filterObj, sp filterClient); private: - sp mFilter; + jweak mFilterObj; + sp mFilterClient; jobjectArray getSectionEvent( jobjectArray& arr, const std::vector& events); jobjectArray getMediaEvent( @@ -195,13 +188,13 @@ private: jobjectArray& arr, const std::vector& eventsExt); }; -struct FrontendCallback : public IFrontendCallback { - FrontendCallback(jweak tunerObj, FrontendId id); +struct FrontendClientCallbackImpl : public FrontendClientCallback { + FrontendClientCallbackImpl(jweak tunerObj, FrontendId id); - virtual Return onEvent(FrontendEventType frontendEventType); - virtual Return onScanMessage( + virtual void onEvent(FrontendEventType frontendEventType); + virtual void onScanMessage( FrontendScanMessageType type, const FrontendScanMessage& message); - virtual Return onScanMessageExt1_1( + virtual void onScanMessageExt1_1( FrontendScanMessageTypeExt1_1 type, const FrontendScanMessageExt1_1& messageExt); jweak mObject; @@ -212,22 +205,24 @@ struct TimeFilter : public RefBase { TimeFilter(sp sp, jweak obj); ~TimeFilter(); sp getITimeFilter(); + // TODO: remove after migrate to client lib sp mTimeFilterSp; jweak mTimeFilterObj; }; struct JTuner : public RefBase { JTuner(JNIEnv *env, jobject thiz); + // TODO: modify after migrate to client lib sp getTunerService(); int getTunerVersion(); - jobject getAvSyncHwId(sp filter); + jobject getAvSyncHwId(sp filter); jobject getAvSyncTime(jint id); int connectCiCam(jint id); int linkCiCam(jint id); int disconnectCiCam(); int unlinkCiCam(jint id); jobject getFrontendIds(); - jobject openFrontendById(int id); + jobject openFrontendByHandle(int feHandle); jint closeFrontendById(int id); jobject getFrontendInfo(int id); int tune(const FrontendSettings& settings, const FrontendSettingsExt1_1& settingsExt1_1); @@ -257,15 +252,22 @@ protected: private: jclass mClass; jweak mObject; + // TODO: remove after migrate to client lib static sp mTuner; static sp<::android::hardware::tv::tuner::V1_1::ITuner> mTuner_1_1; static sp mTunerClient; + // TODO: remove after migrate to client lib sp mFe; + // TODO: remove after migrate to client lib sp<::android::hardware::tv::tuner::V1_1::IFrontend> mFe_1_1; + sp mFeClient; int mFeId; hidl_vec mLnbIds; + // TODO: remove after migrate to client lib sp mLnb; + // TODO: remove after migrate to client lib sp mDemux; + sp mDemuxClient; uint32_t mDemuxId; static jobject getAnalogFrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps); static jobject getAtsc3FrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps); @@ -279,6 +281,9 @@ private: static jobject getDtmbFrontendCaps(JNIEnv *env, int id); bool isV1_1ExtendedStatusType(jint type); + static uint32_t getResourceIdFromHandle(jint handle) { + return (handle & 0x00ff0000) >> 16; + } }; class C2DataIdInfo : public C2Param { diff --git a/media/jni/tuner/DemuxClient.cpp b/media/jni/tuner/DemuxClient.cpp index 11acb5ebf52e4..b237a242d03e3 100644 --- a/media/jni/tuner/DemuxClient.cpp +++ b/media/jni/tuner/DemuxClient.cpp @@ -68,14 +68,12 @@ sp DemuxClient::openFilter(DemuxFilterType type, int bufferSize, sp callback = new HidlFilterCallback(cb); sp hidlFilter = openHidlFilter(type, bufferSize, callback); if (hidlFilter != NULL) { - sp filterClient = new FilterClient(); + sp filterClient = new FilterClient(type); filterClient->setHidlFilter(hidlFilter); return filterClient; } } - // TODO: handle share av memory handle - return NULL; } @@ -141,7 +139,7 @@ Result DemuxClient::disconnectCiCam() { } Result DemuxClient::close() { - // pending aidl interface + // TODO: pending aidl interface if (mDemux != NULL) { Result res = mDemux->close(); diff --git a/media/jni/tuner/FilterClient.cpp b/media/jni/tuner/FilterClient.cpp index a71cae60e464e..0aab5fe7de862 100644 --- a/media/jni/tuner/FilterClient.cpp +++ b/media/jni/tuner/FilterClient.cpp @@ -22,6 +22,9 @@ #include "FilterClient.h" using ::android::hardware::tv::tuner::V1_0::DemuxQueueNotifyBits; +using ::android::hardware::tv::tuner::V1_0::DemuxFilterMainType; +using ::android::hardware::tv::tuner::V1_0::DemuxMmtpFilterType; +using ::android::hardware::tv::tuner::V1_0::DemuxTsFilterType; namespace android { @@ -29,20 +32,25 @@ namespace android { // TODO: pending aidl interface // TODO: add filter callback -FilterClient::FilterClient() { +FilterClient::FilterClient(DemuxFilterType type) { //mTunerFilter = tunerFilter; + mAvSharedHandle = NULL; + checkIsMediaFilter(type); } FilterClient::~FilterClient() { //mTunerFilter = NULL; mFilter = NULL; mFilter_1_1 = NULL; + mAvSharedHandle = NULL; + mAvSharedMemSize = 0; } // TODO: remove after migration to Tuner Service is done. void FilterClient::setHidlFilter(sp filter) { mFilter = filter; mFilter_1_1 = ::android::hardware::tv::tuner::V1_1::IFilter::castFrom(mFilter); + handleAvShareMemory(); } int FilterClient::read(uint8_t* buffer, int size) { @@ -59,6 +67,22 @@ int FilterClient::read(uint8_t* buffer, int size) { return -1; } +SharedHandleInfo FilterClient::getAvSharedHandleInfo() { + SharedHandleInfo info{ + .sharedHandle = NULL, + .size = 0, + }; + + // TODO: pending aidl interface + + if (mFilter_1_1 != NULL) { + info.sharedHandle = mAvSharedHandle; + info.size = mAvSharedMemSize; + } + + return info; +} + Result FilterClient::configure(DemuxFilterSettings configure) { // TODO: pending aidl interface @@ -187,7 +211,11 @@ Result FilterClient::close() { // TODO: pending aidl interface if (mFilter != NULL) { - return mFilter->close(); + Result res = mFilter->close(); + if (res == Result::SUCCESS) { + mFilter = NULL; + } + return res; } return Result::INVALID_STATE; @@ -261,4 +289,31 @@ int FilterClient::copyData(uint8_t* buffer, int size) { return size; } + +void FilterClient::checkIsMediaFilter(DemuxFilterType type) { + if (type.mainType == DemuxFilterMainType::MMTP) { + if (type.subType.mmtpFilterType() == DemuxMmtpFilterType::AUDIO || + type.subType.mmtpFilterType() == DemuxMmtpFilterType::VIDEO) { + mIsMediaFilter = true; + } + } + + if (type.mainType == DemuxFilterMainType::TS) { + if (type.subType.tsFilterType() == DemuxTsFilterType::AUDIO || + type.subType.tsFilterType() == DemuxTsFilterType::VIDEO) { + mIsMediaFilter = true; + } + } +} + +void FilterClient::handleAvShareMemory() { + if (mFilter_1_1 != NULL && mIsMediaFilter) { + mFilter_1_1->getAvSharedHandle([&](Result r, hidl_handle avMemory, uint64_t avMemSize) { + if (r == Result::SUCCESS) { + mAvSharedHandle = native_handle_clone(avMemory.getNativeHandle()); + mAvSharedMemSize = avMemSize; + } + }); + } +} } // namespace android diff --git a/media/jni/tuner/FilterClient.h b/media/jni/tuner/FilterClient.h index 4af74b06d00b0..976b2f5a107de 100644 --- a/media/jni/tuner/FilterClient.h +++ b/media/jni/tuner/FilterClient.h @@ -34,6 +34,7 @@ using ::android::hardware::Return; using ::android::hardware::Void; using ::android::hardware::hidl_handle; using ::android::hardware::tv::tuner::V1_0::DemuxFilterSettings; +using ::android::hardware::tv::tuner::V1_0::DemuxFilterType; using ::android::hardware::tv::tuner::V1_0::IFilter; using ::android::hardware::tv::tuner::V1_0::Result; using ::android::hardware::tv::tuner::V1_1::AvStreamType; @@ -45,6 +46,11 @@ using MQ = MessageQueue; namespace android { +struct SharedHandleInfo { + native_handle_t* sharedHandle; + uint64_t size; +}; + // TODO: pending aidl interface /*class TunerFilterCallback : public BnTunerFilterCallback { @@ -75,7 +81,7 @@ struct FilterClient : public RefBase { public: // TODO: pending aidl interface - FilterClient(); + FilterClient(DemuxFilterType type); ~FilterClient(); // TODO: remove after migration to Tuner Service is done. @@ -88,6 +94,11 @@ public: */ int read(uint8_t* buffer, int size); + /** + * Get the a/v shared memory handle information + */ + SharedHandleInfo getAvSharedHandleInfo(); + /** * Configure the filter. */ @@ -161,6 +172,8 @@ public: private: Result getFilterMq(); int copyData(uint8_t* buffer, int size); + void checkIsMediaFilter(DemuxFilterType type); + void handleAvShareMemory(); /** * An AIDL Tuner Filter Singleton assigned at the first time when the Tuner Client @@ -189,6 +202,10 @@ private: sp mCallback; //shared_ptr mAidlCallback; sp mHidlCallback; + + native_handle_t* mAvSharedHandle; + uint64_t mAvSharedMemSize; + bool mIsMediaFilter; }; } // namespace android