Merge "Tuner JNI: FilterCallback" into rvc-dev am: f4d115b1c5 am: ed9493af67 am: 4dd8b6d903 am: 656c860a95

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

View File

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

View File

@@ -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();
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();
@@ -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");

View File

@@ -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();