Merge "Tuner JNI: use linearblock for media event"
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index 012b8d6..73769be 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -652,7 +652,7 @@
if (filter != null) {
filter.setMainType(mainType);
filter.setSubtype(subType);
- filter.setCallback(cb);
+ filter.setCallback(cb, executor);
if (mHandler == null) {
mHandler = createEventHandler();
}
diff --git a/media/java/android/media/tv/tuner/filter/Filter.java b/media/java/android/media/tv/tuner/filter/Filter.java
index a98183b..cfb943b 100644
--- a/media/java/android/media/tv/tuner/filter/Filter.java
+++ b/media/java/android/media/tv/tuner/filter/Filter.java
@@ -27,6 +27,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.concurrent.Executor;
/**
* Tuner data filter.
@@ -177,6 +178,7 @@
private long mNativeContext;
private FilterCallback mCallback;
+ private Executor mExecutor;
private final int mId;
private int mMainType;
private int mSubtype;
@@ -199,6 +201,12 @@
private void onFilterStatus(int status) {
}
+ private void onFilterEvent(FilterEvent[] events) {
+ if (mCallback != null && mExecutor != null) {
+ mExecutor.execute(() -> mCallback.onFilterEvent(this, events));
+ }
+ }
+
/** @hide */
public void setMainType(@Type int mainType) {
mMainType = mainType;
@@ -209,8 +217,9 @@
}
/** @hide */
- public void setCallback(FilterCallback cb) {
+ public void setCallback(FilterCallback cb, Executor executor) {
mCallback = cb;
+ mExecutor = executor;
}
/** @hide */
public FilterCallback getCallback() {
diff --git a/media/jni/Android.bp b/media/jni/Android.bp
index 47ec7e6..d2294b3 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -136,17 +136,23 @@
],
shared_libs: [
+ "android.hardware.graphics.bufferqueue@2.0",
"android.hardware.tv.tuner@1.0",
"libandroid_runtime",
"libcutils",
"libfmq",
"libhidlbase",
"liblog",
+ "libmedia",
"libnativehelper",
"libutils",
],
+ defaults: [
+ "libcodec2-impl-defaults",
+ ],
header_libs: [
+ "libcodec2_internal",
"libstagefright_foundation_headers",
],
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index 71ba59c..893e516 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -22,6 +22,7 @@
#include "android_media_MediaCodec.h"
+#include "android_media_MediaCodecLinearBlock.h"
#include "android_media_MediaCrypto.h"
#include "android_media_MediaDescrambler.h"
#include "android_media_MediaMetricsJNI.h"
@@ -174,44 +175,6 @@
static fields_t gFields;
static const void *sRefBaseOwner;
-struct JMediaCodecLinearBlock {
- std::shared_ptr<C2Buffer> mBuffer;
- std::shared_ptr<C2ReadView> mReadonlyMapping;
-
- std::shared_ptr<C2LinearBlock> mBlock;
- std::shared_ptr<C2WriteView> mReadWriteMapping;
-
- sp<IMemoryHeap> mHeap;
- sp<hardware::HidlMemory> mMemory;
-
- sp<MediaCodecBuffer> mLegacyBuffer;
-
- std::once_flag mCopyWarningFlag;
-
- std::shared_ptr<C2Buffer> toC2Buffer(size_t offset, size_t size) {
- if (mBuffer) {
- if (mBuffer->data().type() != C2BufferData::LINEAR) {
- return nullptr;
- }
- C2ConstLinearBlock block = mBuffer->data().linearBlocks().front();
- if (offset == 0 && size == block.capacity()) {
- return mBuffer;
- }
- return C2Buffer::CreateLinearBuffer(block.subBlock(offset, size));
- }
- if (mBlock) {
- return C2Buffer::CreateLinearBuffer(mBlock->share(offset, size, C2Fence{}));
- }
- return nullptr;
- }
-
- sp<hardware::HidlMemory> toHidlMemory() {
- if (mMemory) {
- return mMemory;
- }
- return nullptr;
- }
-};
struct JMediaCodecGraphicBlock {
std::shared_ptr<C2Buffer> mBuffer;
diff --git a/media/jni/android_media_MediaCodec.h b/media/jni/android_media_MediaCodec.h
index 1d12e77..8899fee 100644
--- a/media/jni/android_media_MediaCodec.h
+++ b/media/jni/android_media_MediaCodec.h
@@ -21,6 +21,9 @@
#include "jni.h"
+#include <C2Buffer.h>
+#include <binder/MemoryHeapBase.h>
+#include <media/MediaCodecBuffer.h>
#include <media/MediaMetricsItem.h>
#include <media/hardware/CryptoAPI.h>
#include <media/stagefright/foundation/ABase.h>
diff --git a/media/jni/android_media_MediaCodecLinearBlock.h b/media/jni/android_media_MediaCodecLinearBlock.h
new file mode 100644
index 0000000..0843834
--- /dev/null
+++ b/media/jni/android_media_MediaCodecLinearBlock.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ANDROID_MEDIA_MEDIACODECLINEARBLOCK_H_
+#define _ANDROID_MEDIA_MEDIACODECLINEARBLOCK_H_
+
+#include <C2Buffer.h>
+#include <binder/MemoryHeapBase.h>
+#include <hidl/HidlSupport.h>
+#include <media/MediaCodecBuffer.h>
+
+namespace android {
+
+struct JMediaCodecLinearBlock {
+ std::shared_ptr<C2Buffer> mBuffer;
+ std::shared_ptr<C2ReadView> mReadonlyMapping;
+
+ std::shared_ptr<C2LinearBlock> mBlock;
+ std::shared_ptr<C2WriteView> mReadWriteMapping;
+
+ sp<IMemoryHeap> mHeap;
+ sp<hardware::HidlMemory> mMemory;
+
+ sp<MediaCodecBuffer> mLegacyBuffer;
+
+ std::once_flag mCopyWarningFlag;
+
+ std::shared_ptr<C2Buffer> toC2Buffer(size_t offset, size_t size) {
+ if (mBuffer) {
+ if (mBuffer->data().type() != C2BufferData::LINEAR) {
+ return nullptr;
+ }
+ C2ConstLinearBlock block = mBuffer->data().linearBlocks().front();
+ if (offset == 0 && size == block.capacity()) {
+ return mBuffer;
+ }
+ return C2Buffer::CreateLinearBuffer(block.subBlock(offset, size));
+ }
+ if (mBlock) {
+ return C2Buffer::CreateLinearBuffer(mBlock->share(offset, size, C2Fence{}));
+ }
+ return nullptr;
+ }
+
+ sp<hardware::HidlMemory> toHidlMemory() {
+ if (mMemory) {
+ return mMemory;
+ }
+ return nullptr;
+ }
+};
+
+} // namespace android
+
+#endif // _ANDROID_MEDIA_MEDIACODECLINEARBLOCK_H_
\ No newline at end of file
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index 4f31f6c..5c39f29 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -17,12 +17,17 @@
#define LOG_TAG "TvTuner-JNI"
#include <utils/Log.h>
+#include "android_media_MediaCodecLinearBlock.h"
#include "android_media_tv_Tuner.h"
#include "android_runtime/AndroidRuntime.h"
+#include <C2BlockInternal.h>
+#include <C2HandleIonInternal.h>
#include <android/hardware/tv/tuner/1.0/ITuner.h>
#include <media/stagefright/foundation/ADebug.h>
#include <nativehelper/JNIHelp.h>
+#include <nativehelper/ScopedLocalRef.h>
+#include <utils/NativeHandle.h>
#pragma GCC diagnostic ignored "-Wunused-function"
@@ -36,6 +41,7 @@
using ::android::hardware::tv::tuner::V1_0::DemuxFilterAvSettings;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterDownloadSettings;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
+using ::android::hardware::tv::tuner::V1_0::DemuxFilterMediaEvent;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterPesDataSettings;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterRecordSettings;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterSectionBits;
@@ -130,10 +136,13 @@
jmethodID lnbInitID;
jmethodID onLnbEventID;
jmethodID descramblerInitID;
+ jmethodID linearBlockInitID;
+ jmethodID linearBlockSetInternalStateID;
};
static fields_t gFields;
+
static int IP_V4_LENGTH = 4;
static int IP_V6_LENGTH = 16;
@@ -198,8 +207,66 @@
/////////////// FilterCallback ///////////////////////
//TODO: implement filter callback
-Return<void> FilterCallback::onFilterEvent(const DemuxFilterEvent& /*filterEvent*/) {
+jobject FilterCallback::handleToLinearBlock(const native_handle_t* handle, uint32_t size) {
+ ALOGD("FilterCallback::handleToLinearBlock");
+ C2HandleIon* ion = new C2HandleIon(handle->data[0], size);
+ std::shared_ptr<C2LinearBlock> block = _C2BlockFactory::CreateLinearBlock(ion);
+
+ JNIEnv *env = AndroidRuntime::getJNIEnv();
+ std::unique_ptr<JMediaCodecLinearBlock> context{new JMediaCodecLinearBlock};
+ context->mBlock = block;
+
+ jobject linearBlock =
+ env->NewObject(
+ env->FindClass("android/media/MediaCodec$LinearBlock"),
+ gFields.linearBlockInitID);
+ env->CallVoidMethod(
+ linearBlock,
+ gFields.linearBlockSetInternalStateID,
+ (jlong)context.release(),
+ true);
+ return linearBlock;
+}
+
+jobject FilterCallback::getMediaEvent(const DemuxFilterEvent::Event& event) {
+ JNIEnv *env = AndroidRuntime::getJNIEnv();
+ jclass clazz = env->FindClass("android/media/tv/tuner/filter/MediaEvent");
+ jmethodID eventInit = env->GetMethodID(clazz,
+ "<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
+
+ 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);
+}
+
+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));
+ }
+ }
+ env->CallVoidMethod(
+ mFilter,
+ env->GetMethodID(clazz, "onFilterEvent",
+ "([Landroid/media/tv/tuner/filter/FilterEvent;)V"),
+ array);
return Void();
}
@@ -1483,6 +1550,11 @@
jclass dvrClazz = env->FindClass("android/media/tv/tuner/dvr/Dvr");
gFields.dvrContext = env->GetFieldID(dvrClazz, "mNativeContext", "J");
gFields.dvrInitID = env->GetMethodID(dvrClazz, "<init>", "()V");
+
+ jclass linearBlockClazz = env->FindClass("android/media/MediaCodec$LinearBlock");
+ gFields.linearBlockInitID = env->GetMethodID(linearBlockClazz, "<init>", "()V");
+ gFields.linearBlockSetInternalStateID =
+ env->GetMethodID(linearBlockClazz, "setInternalStateLocked", "(JZ)V");
}
static void android_media_tv_Tuner_native_setup(JNIEnv *env, jobject thiz) {
diff --git a/media/jni/android_media_tv_Tuner.h b/media/jni/android_media_tv_Tuner.h
index c5590b9..32d4899 100644
--- a/media/jni/android_media_tv_Tuner.h
+++ b/media/jni/android_media_tv_Tuner.h
@@ -102,8 +102,10 @@
virtual Return<void> onFilterStatus(const DemuxFilterStatus status);
void setFilter(const jobject filter);
+ jobject handleToLinearBlock(const native_handle_t* handle, uint32_t size);
private:
jweak mFilter;
+ jobject getMediaEvent(const DemuxFilterEvent::Event& event);
};
struct FrontendCallback : public IFrontendCallback {
@@ -168,7 +170,7 @@
hidl_vec<LnbId> mLnbIds;
sp<ILnb> mLnb;
sp<IDemux> mDemux;
- int mDemuxId;
+ uint32_t mDemuxId;
static jobject getAnalogFrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities caps);
static jobject getAtsc3FrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities caps);
static jobject getAtscFrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities caps);