Loading media/java/android/media/tv/tuner/filter/Filter.java +1 −0 Original line number Diff line number Diff line Loading @@ -225,6 +225,7 @@ public class Filter implements AutoCloseable { mCallback = cb; mExecutor = executor; } /** @hide */ public FilterCallback getCallback() { return mCallback; Loading media/jni/android_media_tv_Tuner.cpp +277 −18 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -136,6 +145,7 @@ struct fields_t { jmethodID dvrInitID; jmethodID onFrontendEventID; jmethodID onFilterStatusID; jmethodID onFilterEventID; jmethodID lnbInitID; jmethodID onLnbEventID; jmethodID descramblerInitID; Loading Loading @@ -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"); for (int i = 0; i < events.size(); i++) { auto event = events[i]; 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 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 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); 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(); Loading @@ -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); } Loading Loading @@ -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"); Loading media/jni/android_media_tv_Tuner.h +17 −2 Original line number Diff line number Diff line Loading @@ -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 { Loading @@ -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(); Loading Loading
media/java/android/media/tv/tuner/filter/Filter.java +1 −0 Original line number Diff line number Diff line Loading @@ -225,6 +225,7 @@ public class Filter implements AutoCloseable { mCallback = cb; mExecutor = executor; } /** @hide */ public FilterCallback getCallback() { return mCallback; Loading
media/jni/android_media_tv_Tuner.cpp +277 −18 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -136,6 +145,7 @@ struct fields_t { jmethodID dvrInitID; jmethodID onFrontendEventID; jmethodID onFilterStatusID; jmethodID onFilterEventID; jmethodID lnbInitID; jmethodID onLnbEventID; jmethodID descramblerInitID; Loading Loading @@ -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"); for (int i = 0; i < events.size(); i++) { auto event = events[i]; 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 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 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); 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(); Loading @@ -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); } Loading Loading @@ -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"); Loading
media/jni/android_media_tv_Tuner.h +17 −2 Original line number Diff line number Diff line Loading @@ -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 { Loading @@ -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(); Loading