Merge "Tuner JNI: use linearblock for media event"
This commit is contained in:
committed by
Android (Google) Code Review
commit
0526d43236
@@ -652,7 +652,7 @@ public class Tuner implements AutoCloseable {
|
||||
if (filter != null) {
|
||||
filter.setMainType(mainType);
|
||||
filter.setSubtype(subType);
|
||||
filter.setCallback(cb);
|
||||
filter.setCallback(cb, executor);
|
||||
if (mHandler == null) {
|
||||
mHandler = createEventHandler();
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.media.tv.tuner.TunerUtils;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* Tuner data filter.
|
||||
@@ -177,6 +178,7 @@ public class Filter implements AutoCloseable {
|
||||
|
||||
private long mNativeContext;
|
||||
private FilterCallback mCallback;
|
||||
private Executor mExecutor;
|
||||
private final int mId;
|
||||
private int mMainType;
|
||||
private int mSubtype;
|
||||
@@ -199,6 +201,12 @@ public class Filter implements AutoCloseable {
|
||||
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 @@ public class Filter implements AutoCloseable {
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public void setCallback(FilterCallback cb) {
|
||||
public void setCallback(FilterCallback cb, Executor executor) {
|
||||
mCallback = cb;
|
||||
mExecutor = executor;
|
||||
}
|
||||
/** @hide */
|
||||
public FilterCallback getCallback() {
|
||||
|
||||
@@ -136,17 +136,23 @@ cc_library_shared {
|
||||
],
|
||||
|
||||
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",
|
||||
],
|
||||
|
||||
|
||||
@@ -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 @@ struct fields_t {
|
||||
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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
68
media/jni/android_media_MediaCodecLinearBlock.h
Normal file
68
media/jni/android_media_MediaCodecLinearBlock.h
Normal file
@@ -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_
|
||||
@@ -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::DemuxAlpLengthType;
|
||||
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 @@ struct fields_t {
|
||||
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 @@ DvrMQ& Dvr::getDvrMQ() {
|
||||
|
||||
/////////////// 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 @@ static void android_media_tv_Tuner_native_init(JNIEnv *env) {
|
||||
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) {
|
||||
|
||||
@@ -102,8 +102,10 @@ struct FilterCallback : public IFilterCallback {
|
||||
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 @@ private:
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user