Merge "Tuner JNI: FilterCallback" into rvc-dev am: f4d115b1c5 am: ed9493af67

Change-Id: Icba0c3653619f3466f6d3091380f37d6637f4342
This commit is contained in:
Automerger Merge Worker
2020-03-10 23:04:03 +00:00
3 changed files with 295 additions and 20 deletions

View File

@@ -225,6 +225,7 @@ public class Filter implements AutoCloseable {
mCallback = cb; mCallback = cb;
mExecutor = executor; mExecutor = executor;
} }
/** @hide */ /** @hide */
public FilterCallback getCallback() { public FilterCallback getCallback() {
return mCallback; return mCallback;

View File

@@ -34,19 +34,28 @@
using ::android::hardware::Void; using ::android::hardware::Void;
using ::android::hardware::hidl_bitfield; using ::android::hardware::hidl_bitfield;
using ::android::hardware::hidl_vec; 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::DataFormat;
using ::android::hardware::tv::tuner::V1_0::DemuxAlpFilterSettings; using ::android::hardware::tv::tuner::V1_0::DemuxAlpFilterSettings;
using ::android::hardware::tv::tuner::V1_0::DemuxAlpFilterType; using ::android::hardware::tv::tuner::V1_0::DemuxAlpFilterType;
using ::android::hardware::tv::tuner::V1_0::DemuxAlpLengthType; using ::android::hardware::tv::tuner::V1_0::DemuxAlpLengthType;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterAvSettings; 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::DemuxFilterDownloadSettings;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterIpPayloadEvent;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterMainType; using ::android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterMediaEvent; 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::DemuxFilterPesDataSettings;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterPesEvent;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterRecordSettings; using ::android::hardware::tv::tuner::V1_0::DemuxFilterRecordSettings;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterSectionBits; 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::DemuxFilterSectionSettings;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterSettings; 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::DemuxIpAddress;
using ::android::hardware::tv::tuner::V1_0::DemuxIpFilterSettings; using ::android::hardware::tv::tuner::V1_0::DemuxIpFilterSettings;
using ::android::hardware::tv::tuner::V1_0::DemuxIpFilterType; using ::android::hardware::tv::tuner::V1_0::DemuxIpFilterType;
@@ -136,6 +145,7 @@ struct fields_t {
jmethodID dvrInitID; jmethodID dvrInitID;
jmethodID onFrontendEventID; jmethodID onFrontendEventID;
jmethodID onFilterStatusID; jmethodID onFilterStatusID;
jmethodID onFilterEventID;
jmethodID lnbInitID; jmethodID lnbInitID;
jmethodID onLnbEventID; jmethodID onLnbEventID;
jmethodID descramblerInitID; jmethodID descramblerInitID;
@@ -248,48 +258,287 @@ jobject FilterCallback::handleToLinearBlock(const native_handle_t* handle, uint3
return linearBlock; return linearBlock;
} }
jobject FilterCallback::getMediaEvent(const DemuxFilterEvent::Event& event) { jobjectArray FilterCallback::getSectionEvent(
jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) {
JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = AndroidRuntime::getJNIEnv();
jclass clazz = env->FindClass("android/media/tv/tuner/filter/MediaEvent"); jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/SectionEvent");
jmethodID eventInit = env->GetMethodID(clazz, 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>", "<init>",
"(IZJJJLandroid/media/MediaCodec$LinearBlock;" "(IZJJJLandroid/media/MediaCodec$LinearBlock;"
"ZJIZLandroid/media/tv/tuner/filter/AudioDescriptor;)V"); "ZJIZLandroid/media/tv/tuner/filter/AudioDescriptor;)V");
DemuxFilterMediaEvent mediaEvent = event.media(); for (int i = 0; i < events.size(); i++) {
uint32_t dataLength = mediaEvent.dataLength; auto event = events[i];
const native_handle_t* h = mediaEvent.avMemory.getNativeHandle(); DemuxFilterMediaEvent mediaEvent = event.media();
jobject block = handleToLinearBlock(h, dataLength);
// TODO: handle other fields
return env->NewObject(clazz, eventInit, (jint) 0, (jboolean) 0, (jlong) 0, (jlong) 0, (jlong) 0, jobject audioDescriptor = NULL;
block, (jboolean) 0, (jlong) 0, (jint) 0, (jboolean) 0, 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) { Return<void> FilterCallback::onFilterEvent(const DemuxFilterEvent& filterEvent) {
ALOGD("FilterCallback::onFilterEvent"); ALOGD("FilterCallback::onFilterEvent");
JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = AndroidRuntime::getJNIEnv();
jclass clazz = env->FindClass("android/media/tv/tuner/filter/Filter");
std::vector<DemuxFilterEvent::Event> events = filterEvent.events; std::vector<DemuxFilterEvent::Event> events = filterEvent.events;
jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/FilterEvent"); jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/FilterEvent");
jobjectArray array = env->NewObjectArray(events.size(), eventClazz, NULL); jobjectArray array = env->NewObjectArray(events.size(), eventClazz, NULL);
for (int i = 0; i < events.size(); i++) { if (!events.empty()) {
auto event = events[i]; auto event = events[0];
if (event.getDiscriminator() == DemuxFilterEvent::Event::hidl_discriminator::media) { switch (event.getDiscriminator()) {
env->SetObjectArrayElement(array, i, getMediaEvent(event)); 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( env->CallVoidMethod(
mFilter, mFilter,
env->GetMethodID(clazz, "onFilterEvent", gFields.onFilterEventID,
"([Landroid/media/tv/tuner/filter/FilterEvent;)V"),
array); array);
return Void(); return Void();
} }
Return<void> FilterCallback::onFilterStatus(const DemuxFilterStatus status) { Return<void> FilterCallback::onFilterStatus(const DemuxFilterStatus status) {
ALOGD("FilterCallback::onFilterStatus"); ALOGD("FilterCallback::onFilterStatus");
JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = AndroidRuntime::getJNIEnv();
@@ -308,9 +557,16 @@ void FilterCallback::setFilter(const jobject filter) {
/////////////// 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() { Filter::~Filter() {
JNIEnv *env = AndroidRuntime::getJNIEnv();
env->DeleteWeakGlobalRef(mFilterObj);
mFilterObj = NULL;
EventFlag::deleteEventFlag(&mFilterMQEventFlag); EventFlag::deleteEventFlag(&mFilterMQEventFlag);
} }
@@ -1625,6 +1881,9 @@ static void android_media_tv_Tuner_native_init(JNIEnv *env) {
env->GetMethodID(filterClazz, "<init>", "(I)V"); env->GetMethodID(filterClazz, "<init>", "(I)V");
gFields.onFilterStatusID = gFields.onFilterStatusID =
env->GetMethodID(filterClazz, "onFilterStatus", "(I)V"); 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"); jclass timeFilterClazz = env->FindClass("android/media/tv/tuner/filter/TimeFilter");
gFields.timeFilterContext = env->GetFieldID(timeFilterClazz, "mNativeContext", "J"); gFields.timeFilterContext = env->GetFieldID(timeFilterClazz, "mNativeContext", "J");

View File

@@ -114,7 +114,22 @@ struct FilterCallback : public IFilterCallback {
jobject handleToLinearBlock(const native_handle_t* handle, uint32_t size); jobject handleToLinearBlock(const native_handle_t* handle, uint32_t size);
private: private:
jweak mFilter; 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 { struct FrontendCallback : public IFrontendCallback {
@@ -129,7 +144,7 @@ struct FrontendCallback : public IFrontendCallback {
}; };
struct Filter : public RefBase { struct Filter : public RefBase {
Filter(sp<IFilter> sp, jweak obj); Filter(sp<IFilter> sp, jobject obj);
~Filter(); ~Filter();
int close(); int close();
sp<IFilter> getIFilter(); sp<IFilter> getIFilter();