diff options
| author | 2020-03-10 22:29:16 +0000 | |
|---|---|---|
| committer | 2020-03-10 22:29:16 +0000 | |
| commit | f4d115b1c5ca02a3f5ff50a89f21f41be099042e (patch) | |
| tree | f7d1409f464c595c0afc9233d7a2251f7c0108bd | |
| parent | 6111751922bfb9e02b3aaf17b4a7a20a21e0f09f (diff) | |
| parent | 3e0c37b525ccb1da97113bd2247ebeae5ba6e908 (diff) | |
Merge "Tuner JNI: FilterCallback" into rvc-dev
| -rw-r--r-- | media/java/android/media/tv/tuner/filter/Filter.java | 1 | ||||
| -rw-r--r-- | media/jni/android_media_tv_Tuner.cpp | 295 | ||||
| -rw-r--r-- | media/jni/android_media_tv_Tuner.h | 19 |
3 files changed, 295 insertions, 20 deletions
diff --git a/media/java/android/media/tv/tuner/filter/Filter.java b/media/java/android/media/tv/tuner/filter/Filter.java index 52bdb595050e..4777fe861420 100644 --- a/media/java/android/media/tv/tuner/filter/Filter.java +++ b/media/java/android/media/tv/tuner/filter/Filter.java @@ -225,6 +225,7 @@ public class Filter implements AutoCloseable { mCallback = cb; mExecutor = executor; } + /** @hide */ public FilterCallback getCallback() { return mCallback; diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp index 273c77684635..01f068a05fc3 100644 --- a/media/jni/android_media_tv_Tuner.cpp +++ b/media/jni/android_media_tv_Tuner.cpp @@ -34,19 +34,28 @@ using ::android::hardware::Void; using ::android::hardware::hidl_bitfield; using ::android::hardware::hidl_vec; +using ::android::hardware::tv::tuner::V1_0::AudioExtraMetaData; +using ::android::hardware::tv::tuner::V1_0::Constant; using ::android::hardware::tv::tuner::V1_0::DataFormat; using ::android::hardware::tv::tuner::V1_0::DemuxAlpFilterSettings; using ::android::hardware::tv::tuner::V1_0::DemuxAlpFilterType; using ::android::hardware::tv::tuner::V1_0::DemuxAlpLengthType; using ::android::hardware::tv::tuner::V1_0::DemuxFilterAvSettings; +using ::android::hardware::tv::tuner::V1_0::DemuxFilterDownloadEvent; using ::android::hardware::tv::tuner::V1_0::DemuxFilterDownloadSettings; +using ::android::hardware::tv::tuner::V1_0::DemuxFilterIpPayloadEvent; using ::android::hardware::tv::tuner::V1_0::DemuxFilterMainType; using ::android::hardware::tv::tuner::V1_0::DemuxFilterMediaEvent; +using ::android::hardware::tv::tuner::V1_0::DemuxFilterMmtpRecordEvent; using ::android::hardware::tv::tuner::V1_0::DemuxFilterPesDataSettings; +using ::android::hardware::tv::tuner::V1_0::DemuxFilterPesEvent; using ::android::hardware::tv::tuner::V1_0::DemuxFilterRecordSettings; using ::android::hardware::tv::tuner::V1_0::DemuxFilterSectionBits; +using ::android::hardware::tv::tuner::V1_0::DemuxFilterSectionEvent; using ::android::hardware::tv::tuner::V1_0::DemuxFilterSectionSettings; using ::android::hardware::tv::tuner::V1_0::DemuxFilterSettings; +using ::android::hardware::tv::tuner::V1_0::DemuxFilterTemiEvent; +using ::android::hardware::tv::tuner::V1_0::DemuxFilterTsRecordEvent; using ::android::hardware::tv::tuner::V1_0::DemuxIpAddress; using ::android::hardware::tv::tuner::V1_0::DemuxIpFilterSettings; using ::android::hardware::tv::tuner::V1_0::DemuxIpFilterType; @@ -136,6 +145,7 @@ struct fields_t { jmethodID dvrInitID; jmethodID onFrontendEventID; jmethodID onFilterStatusID; + jmethodID onFilterEventID; jmethodID lnbInitID; jmethodID onLnbEventID; jmethodID descramblerInitID; @@ -248,48 +258,287 @@ jobject FilterCallback::handleToLinearBlock(const native_handle_t* handle, uint3 return linearBlock; } -jobject FilterCallback::getMediaEvent(const DemuxFilterEvent::Event& event) { +jobjectArray FilterCallback::getSectionEvent( + jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) { JNIEnv *env = AndroidRuntime::getJNIEnv(); - jclass clazz = env->FindClass("android/media/tv/tuner/filter/MediaEvent"); - jmethodID eventInit = env->GetMethodID(clazz, + jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/SectionEvent"); + jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(IIII)V"); + + for (int i = 0; i < events.size(); i++) { + auto event = events[i]; + DemuxFilterSectionEvent sectionEvent = event.section(); + + jint tableId = static_cast<jint>(sectionEvent.tableId); + jint version = static_cast<jint>(sectionEvent.version); + jint sectionNum = static_cast<jint>(sectionEvent.sectionNum); + jint dataLength = static_cast<jint>(sectionEvent.dataLength); + + jobject obj = + env->NewObject(eventClazz, eventInit, tableId, version, sectionNum, dataLength); + env->SetObjectArrayElement(arr, i, obj); + } + return arr; +} + +jobjectArray FilterCallback::getMediaEvent( + jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) { + JNIEnv *env = AndroidRuntime::getJNIEnv(); + jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/MediaEvent"); + jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(IZJJJLandroid/media/MediaCodec$LinearBlock;" "ZJIZLandroid/media/tv/tuner/filter/AudioDescriptor;)V"); - DemuxFilterMediaEvent mediaEvent = event.media(); - uint32_t dataLength = mediaEvent.dataLength; - const native_handle_t* h = mediaEvent.avMemory.getNativeHandle(); - jobject block = handleToLinearBlock(h, dataLength); - // TODO: handle other fields + for (int i = 0; i < events.size(); i++) { + auto event = events[i]; + DemuxFilterMediaEvent mediaEvent = event.media(); + + jobject audioDescriptor = NULL; + if (mediaEvent.extraMetaData.getDiscriminator() + == DemuxFilterMediaEvent::ExtraMetaData::hidl_discriminator::audio) { + jclass adClazz = env->FindClass("android/media/tv/tuner/filter/AudioDescriptor"); + jmethodID adInit = env->GetMethodID(adClazz, "<init>", "(BBCBBB)V"); + + AudioExtraMetaData ad = mediaEvent.extraMetaData.audio(); + jbyte adFade = static_cast<jbyte>(ad.adFade); + jbyte adPan = static_cast<jbyte>(ad.adPan); + jchar versionTextTag = static_cast<jchar>(ad.versionTextTag); + jbyte adGainCenter = static_cast<jbyte>(ad.adGainCenter); + jbyte adGainFront = static_cast<jbyte>(ad.adGainFront); + jbyte adGainSurround = static_cast<jbyte>(ad.adGainSurround); + + audioDescriptor = + env->NewObject(adClazz, adInit, adFade, adPan, versionTextTag, adGainCenter, + adGainFront, adGainSurround); + } + + jlong dataLength = static_cast<jlong>(mediaEvent.dataLength); + const native_handle_t* h = NULL; + jobject block = NULL; + if (mediaEvent.avMemory != NULL) { + h = mediaEvent.avMemory.getNativeHandle(); + block = handleToLinearBlock(h, dataLength); + } + + jint streamId = static_cast<jint>(mediaEvent.streamId); + jboolean isPtsPresent = static_cast<jboolean>(mediaEvent.isPtsPresent); + jlong pts = static_cast<jlong>(mediaEvent.pts); + jlong offset = static_cast<jlong>(mediaEvent.offset); + jboolean isSecureMemory = static_cast<jboolean>(mediaEvent.isSecureMemory); + jlong avDataId = static_cast<jlong>(mediaEvent.avDataId); + jint mpuSequenceNumber = static_cast<jint>(mediaEvent.mpuSequenceNumber); + jboolean isPesPrivateData = static_cast<jboolean>(mediaEvent.isPesPrivateData); + + jobject obj = + env->NewObject(eventClazz, eventInit, streamId, isPtsPresent, pts, dataLength, + offset, block, isSecureMemory, avDataId, mpuSequenceNumber, isPesPrivateData, + audioDescriptor); + env->SetObjectArrayElement(arr, i, obj); + } + return arr; +} + +jobjectArray FilterCallback::getPesEvent( + jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) { + JNIEnv *env = AndroidRuntime::getJNIEnv(); + jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/PesEvent"); + jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(III)V"); + + for (int i = 0; i < events.size(); i++) { + auto event = events[i]; + DemuxFilterPesEvent pesEvent = event.pes(); + + jint streamId = static_cast<jint>(pesEvent.streamId); + jint dataLength = static_cast<jint>(pesEvent.dataLength); + jint mpuSequenceNumber = static_cast<jint>(pesEvent.mpuSequenceNumber); - return env->NewObject(clazz, eventInit, (jint) 0, (jboolean) 0, (jlong) 0, (jlong) 0, (jlong) 0, - block, (jboolean) 0, (jlong) 0, (jint) 0, (jboolean) 0, NULL); + jobject obj = + env->NewObject(eventClazz, eventInit, streamId, dataLength, mpuSequenceNumber); + env->SetObjectArrayElement(arr, i, obj); + } + return arr; +} + +jobjectArray FilterCallback::getTsRecordEvent( + jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) { + JNIEnv *env = AndroidRuntime::getJNIEnv(); + jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/TsRecordEvent"); + jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(IIIJ)V"); + + for (int i = 0; i < events.size(); i++) { + auto event = events[i]; + DemuxFilterTsRecordEvent tsRecordEvent = event.tsRecord(); + DemuxPid pid = tsRecordEvent.pid; + + jint jpid = static_cast<jint>(Constant::INVALID_TS_PID); + + if (pid.getDiscriminator() == DemuxPid::hidl_discriminator::tPid) { + jpid = static_cast<jint>(pid.tPid()); + } else if (pid.getDiscriminator() == DemuxPid::hidl_discriminator::mmtpPid) { + jpid = static_cast<jint>(pid.mmtpPid()); + } + + jint sc = 0; + + if (tsRecordEvent.scIndexMask.getDiscriminator() + == DemuxFilterTsRecordEvent::ScIndexMask::hidl_discriminator::sc) { + sc = static_cast<jint>(tsRecordEvent.scIndexMask.sc()); + } else if (tsRecordEvent.scIndexMask.getDiscriminator() + == DemuxFilterTsRecordEvent::ScIndexMask::hidl_discriminator::scHevc) { + sc = static_cast<jint>(tsRecordEvent.scIndexMask.scHevc()); + } + + jint ts = static_cast<jint>(tsRecordEvent.tsIndexMask); + + jlong byteNumber = static_cast<jlong>(tsRecordEvent.byteNumber); + + jobject obj = + env->NewObject(eventClazz, eventInit, jpid, ts, sc, byteNumber); + env->SetObjectArrayElement(arr, i, obj); + } + return arr; +} + +jobjectArray FilterCallback::getMmtpRecordEvent( + jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) { + JNIEnv *env = AndroidRuntime::getJNIEnv(); + jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/MmtpRecordEvent"); + jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(IJ)V"); + + for (int i = 0; i < events.size(); i++) { + auto event = events[i]; + DemuxFilterMmtpRecordEvent mmtpRecordEvent = event.mmtpRecord(); + + jint scHevcIndexMask = static_cast<jint>(mmtpRecordEvent.scHevcIndexMask); + jlong byteNumber = static_cast<jlong>(mmtpRecordEvent.byteNumber); + + jobject obj = + env->NewObject(eventClazz, eventInit, scHevcIndexMask, byteNumber); + env->SetObjectArrayElement(arr, i, obj); + } + return arr; +} + +jobjectArray FilterCallback::getDownloadEvent( + jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) { + JNIEnv *env = AndroidRuntime::getJNIEnv(); + jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/DownloadEvent"); + jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(IIIII)V"); + + for (int i = 0; i < events.size(); i++) { + auto event = events[i]; + DemuxFilterDownloadEvent downloadEvent = event.download(); + + jint itemId = static_cast<jint>(downloadEvent.itemId); + jint mpuSequenceNumber = static_cast<jint>(downloadEvent.mpuSequenceNumber); + jint itemFragmentIndex = static_cast<jint>(downloadEvent.itemFragmentIndex); + jint lastItemFragmentIndex = static_cast<jint>(downloadEvent.lastItemFragmentIndex); + jint dataLength = static_cast<jint>(downloadEvent.dataLength); + + jobject obj = + env->NewObject(eventClazz, eventInit, itemId, mpuSequenceNumber, itemFragmentIndex, + lastItemFragmentIndex, dataLength); + env->SetObjectArrayElement(arr, i, obj); + } + return arr; +} + +jobjectArray FilterCallback::getIpPayloadEvent( + jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) { + JNIEnv *env = AndroidRuntime::getJNIEnv(); + jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/IpPayloadEvent"); + jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(I)V"); + + for (int i = 0; i < events.size(); i++) { + auto event = events[i]; + DemuxFilterIpPayloadEvent ipPayloadEvent = event.ipPayload(); + jint dataLength = static_cast<jint>(ipPayloadEvent.dataLength); + jobject obj = env->NewObject(eventClazz, eventInit, dataLength); + env->SetObjectArrayElement(arr, i, obj); + } + return arr; +} + +jobjectArray FilterCallback::getTemiEvent( + jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) { + JNIEnv *env = AndroidRuntime::getJNIEnv(); + jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/TemiEvent"); + jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(JB[B)V"); + + for (int i = 0; i < events.size(); i++) { + auto event = events[i]; + DemuxFilterTemiEvent temiEvent = event.temi(); + jlong pts = static_cast<jlong>(temiEvent.pts); + jbyte descrTag = static_cast<jbyte>(temiEvent.descrTag); + std::vector<uint8_t> descrData = temiEvent.descrData; + + jbyteArray array = env->NewByteArray(descrData.size()); + env->SetByteArrayRegion( + array, 0, descrData.size(), reinterpret_cast<jbyte*>(&descrData[0])); + + jobject obj = env->NewObject(eventClazz, eventInit, pts, descrTag, array); + env->SetObjectArrayElement(arr, i, obj); + } + return arr; } Return<void> FilterCallback::onFilterEvent(const DemuxFilterEvent& filterEvent) { ALOGD("FilterCallback::onFilterEvent"); JNIEnv *env = AndroidRuntime::getJNIEnv(); - jclass clazz = env->FindClass("android/media/tv/tuner/filter/Filter"); std::vector<DemuxFilterEvent::Event> events = filterEvent.events; jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/FilterEvent"); jobjectArray array = env->NewObjectArray(events.size(), eventClazz, NULL); - for (int i = 0; i < events.size(); i++) { - auto event = events[i]; - if (event.getDiscriminator() == DemuxFilterEvent::Event::hidl_discriminator::media) { - env->SetObjectArrayElement(array, i, getMediaEvent(event)); + if (!events.empty()) { + auto event = events[0]; + switch (event.getDiscriminator()) { + case DemuxFilterEvent::Event::hidl_discriminator::media: { + array = getMediaEvent(array, events); + break; + } + case DemuxFilterEvent::Event::hidl_discriminator::section: { + array = getSectionEvent(array, events); + break; + } + case DemuxFilterEvent::Event::hidl_discriminator::pes: { + array = getPesEvent(array, events); + break; + } + case DemuxFilterEvent::Event::hidl_discriminator::tsRecord: { + array = getTsRecordEvent(array, events); + break; + } + case DemuxFilterEvent::Event::hidl_discriminator::mmtpRecord: { + array = getMmtpRecordEvent(array, events); + break; + } + case DemuxFilterEvent::Event::hidl_discriminator::download: { + array = getDownloadEvent(array, events); + break; + } + case DemuxFilterEvent::Event::hidl_discriminator::ipPayload: { + array = getIpPayloadEvent(array, events); + break; + } + case DemuxFilterEvent::Event::hidl_discriminator::temi: { + array = getTemiEvent(array, events); + break; + } + default: { + break; + } } } env->CallVoidMethod( mFilter, - env->GetMethodID(clazz, "onFilterEvent", - "([Landroid/media/tv/tuner/filter/FilterEvent;)V"), + gFields.onFilterEventID, array); return Void(); } + Return<void> FilterCallback::onFilterStatus(const DemuxFilterStatus status) { ALOGD("FilterCallback::onFilterStatus"); JNIEnv *env = AndroidRuntime::getJNIEnv(); @@ -308,9 +557,16 @@ void FilterCallback::setFilter(const jobject filter) { /////////////// Filter /////////////////////// -Filter::Filter(sp<IFilter> sp, jweak obj) : mFilterSp(sp), mFilterObj(obj) {} +Filter::Filter(sp<IFilter> 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); } @@ -1625,6 +1881,9 @@ static void android_media_tv_Tuner_native_init(JNIEnv *env) { env->GetMethodID(filterClazz, "<init>", "(I)V"); gFields.onFilterStatusID = env->GetMethodID(filterClazz, "onFilterStatus", "(I)V"); + gFields.onFilterEventID = + env->GetMethodID(filterClazz, "onFilterEvent", + "([Landroid/media/tv/tuner/filter/FilterEvent;)V"); jclass timeFilterClazz = env->FindClass("android/media/tv/tuner/filter/TimeFilter"); gFields.timeFilterContext = env->GetFieldID(timeFilterClazz, "mNativeContext", "J"); diff --git a/media/jni/android_media_tv_Tuner.h b/media/jni/android_media_tv_Tuner.h index fec4cd8d5002..d3298a851fdd 100644 --- a/media/jni/android_media_tv_Tuner.h +++ b/media/jni/android_media_tv_Tuner.h @@ -114,7 +114,22 @@ struct FilterCallback : public IFilterCallback { jobject handleToLinearBlock(const native_handle_t* handle, uint32_t size); private: jweak mFilter; - jobject getMediaEvent(const DemuxFilterEvent::Event& event); + jobjectArray getSectionEvent( + jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events); + jobjectArray getMediaEvent( + jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events); + jobjectArray getPesEvent( + jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events); + jobjectArray getTsRecordEvent( + jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events); + jobjectArray getMmtpRecordEvent( + jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events); + jobjectArray getDownloadEvent( + jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events); + jobjectArray getIpPayloadEvent( + jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events); + jobjectArray getTemiEvent( + jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events); }; struct FrontendCallback : public IFrontendCallback { @@ -129,7 +144,7 @@ struct FrontendCallback : public IFrontendCallback { }; struct Filter : public RefBase { - Filter(sp<IFilter> sp, jweak obj); + Filter(sp<IFilter> sp, jobject obj); ~Filter(); int close(); sp<IFilter> getIFilter(); |