summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--media/java/android/media/tv/tuner/filter/Filter.java23
-rw-r--r--media/jni/android_media_tv_Tuner.cpp131
2 files changed, 107 insertions, 47 deletions
diff --git a/media/java/android/media/tv/tuner/filter/Filter.java b/media/java/android/media/tv/tuner/filter/Filter.java
index b943fe589270..d654b45da092 100644
--- a/media/java/android/media/tv/tuner/filter/Filter.java
+++ b/media/java/android/media/tv/tuner/filter/Filter.java
@@ -22,7 +22,9 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.hardware.tv.tuner.V1_0.Constants;
+import android.media.tv.tuner.Tuner;
import android.media.tv.tuner.Tuner.Result;
+import android.media.tv.tuner.TunerUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -178,13 +180,14 @@ public class Filter implements AutoCloseable {
*/
public static final int STATUS_OVERFLOW = Constants.DemuxFilterStatus.OVERFLOW;
-
private long mNativeContext;
private FilterCallback mCallback;
private Executor mExecutor;
private final int mId;
private int mMainType;
private int mSubtype;
+ private Filter mSource;
+ private boolean mStarted;
private native int nativeConfigureFilter(
int type, int subType, FilterConfiguration settings);
@@ -202,6 +205,9 @@ public class Filter implements AutoCloseable {
}
private void onFilterStatus(int status) {
+ if (mCallback != null && mExecutor != null) {
+ mExecutor.execute(() -> mCallback.onFilterStatusChanged(this, status));
+ }
}
private void onFilterEvent(FilterEvent[] events) {
@@ -266,10 +272,18 @@ public class Filter implements AutoCloseable {
* @param source the filter instance which provides data input. Switch to
* use demux as data source if the filter instance is NULL.
* @return result status of the operation.
+ * @throws IllegalStateException if the data source has been set.
*/
@Result
public int setDataSource(@Nullable Filter source) {
- return nativeSetDataSource(source);
+ if (mSource != null) {
+ throw new IllegalStateException("Data source is existing");
+ }
+ int res = nativeSetDataSource(source);
+ if (res == Tuner.RESULT_SUCCESS) {
+ mSource = source;
+ }
+ return res;
}
/**
@@ -328,6 +342,9 @@ public class Filter implements AutoCloseable {
*/
@Override
public void close() {
- nativeClose();
+ int res = nativeClose();
+ if (res != Tuner.RESULT_SUCCESS) {
+ TunerUtils.throwExceptionForResult(res, "Failed to close filter.");
+ }
}
}
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index 95ce07d3c55e..29dfd730a84c 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -2448,11 +2448,11 @@ static DemuxFilterSettings getFilterConfiguration(
return filterSettings;
}
-static int copyData(JNIEnv *env, sp<Filter> filter, jbyteArray buffer, jint offset, int size) {
- ALOGD("copyData, size=%d, offset=%d", size, offset);
+static jint copyData(JNIEnv *env, sp<Filter> filter, jbyteArray buffer, jlong offset, jlong size) {
+ ALOGD("copyData, size=%ld, offset=%ld", (long) size, (long) offset);
- int available = filter->mFilterMQ->availableToRead();
- ALOGD("copyData, available=%d", available);
+ jlong available = filter->mFilterMQ->availableToRead();
+ ALOGD("copyData, available=%ld", (long) available);
size = std::min(size, available);
jboolean isCopy;
@@ -2474,7 +2474,7 @@ static int copyData(JNIEnv *env, sp<Filter> filter, jbyteArray buffer, jint offs
return size;
}
-static int android_media_tv_Tuner_configure_filter(
+static jint android_media_tv_Tuner_configure_filter(
JNIEnv *env, jobject filter, int type, int subtype, jobject settings) {
ALOGD("configure filter type=%d, subtype=%d", type, subtype);
sp<Filter> filterSp = getFilter(env, filter);
@@ -2485,9 +2485,14 @@ static int android_media_tv_Tuner_configure_filter(
}
DemuxFilterSettings filterSettings = getFilterConfiguration(env, type, subtype, settings);
Result res = iFilterSp->configure(filterSettings);
+
+ if (res != Result::SUCCESS) {
+ return (jint) res;
+ }
+
MQDescriptorSync<uint8_t> filterMQDesc;
- if (res == Result::SUCCESS && filterSp->mFilterMQ == NULL) {
- Result getQueueDescResult = Result::UNKNOWN_ERROR;
+ Result getQueueDescResult = Result::UNKNOWN_ERROR;
+ if (filterSp->mFilterMQ == NULL) {
iFilterSp->getQueueDesc(
[&](Result r, const MQDescriptorSync<uint8_t>& desc) {
filterMQDesc = desc;
@@ -2500,59 +2505,97 @@ static int android_media_tv_Tuner_configure_filter(
filterSp->mFilterMQ->getEventFlagWord(), &(filterSp->mFilterMQEventFlag));
}
}
- return (int)res;
+ return (jint) getQueueDescResult;
}
-static int android_media_tv_Tuner_get_filter_id(JNIEnv*, jobject) {
- return 0;
+static jint android_media_tv_Tuner_get_filter_id(JNIEnv* env, jobject filter) {
+ sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
+ if (iFilterSp == NULL) {
+ ALOGD("Failed to get filter ID: filter not found");
+ return (int) Result::INVALID_STATE;
+ }
+ Result res;
+ uint32_t id;
+ iFilterSp->getId(
+ [&](Result r, uint32_t filterId) {
+ res = r;
+ id = filterId;
+ });
+ if (res != Result::SUCCESS) {
+ return (jint) Constant::INVALID_FILTER_ID;
+ }
+ return (jint) id;
}
-static int android_media_tv_Tuner_set_filter_data_source(JNIEnv*, jobject, jobject) {
- return 0;
+static jint android_media_tv_Tuner_set_filter_data_source(
+ JNIEnv* env, jobject filter, jobject srcFilter) {
+ sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
+ if (iFilterSp == NULL) {
+ ALOGD("Failed to set filter data source: filter not found");
+ return (jint) Result::INVALID_STATE;
+ }
+ Result r;
+ if (srcFilter == NULL) {
+ r = iFilterSp->setDataSource(NULL);
+ } else {
+ sp<IFilter> srcSp = getFilter(env, srcFilter)->getIFilter();
+ if (iFilterSp == NULL) {
+ ALOGD("Failed to set filter data source: src filter not found");
+ return (jint) Result::INVALID_STATE;
+ }
+ r = iFilterSp->setDataSource(srcSp);
+ }
+ return (jint) r;
}
-static int android_media_tv_Tuner_start_filter(JNIEnv *env, jobject filter) {
- sp<IFilter> filterSp = getFilter(env, filter)->getIFilter();
- if (filterSp == NULL) {
+static jint android_media_tv_Tuner_start_filter(JNIEnv *env, jobject filter) {
+ sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
+ if (iFilterSp == NULL) {
ALOGD("Failed to start filter: filter not found");
- return false;
+ return (jint) Result::INVALID_STATE;
}
- Result r = filterSp->start();
- return (int) r;
+ Result r = iFilterSp->start();
+ return (jint) r;
}
-static int android_media_tv_Tuner_stop_filter(JNIEnv *env, jobject filter) {
- sp<IFilter> filterSp = getFilter(env, filter)->getIFilter();
- if (filterSp == NULL) {
+static jint android_media_tv_Tuner_stop_filter(JNIEnv *env, jobject filter) {
+ sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
+ if (iFilterSp == NULL) {
ALOGD("Failed to stop filter: filter not found");
- return false;
+ return (jint) Result::INVALID_STATE;
}
- Result r = filterSp->stop();
- return (int) r;
+ Result r = iFilterSp->stop();
+ return (jint) r;
}
-static int android_media_tv_Tuner_flush_filter(JNIEnv *env, jobject filter) {
- sp<IFilter> filterSp = getFilter(env, filter)->getIFilter();
- if (filterSp == NULL) {
+static jint android_media_tv_Tuner_flush_filter(JNIEnv *env, jobject filter) {
+ sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
+ if (iFilterSp == NULL) {
ALOGD("Failed to flush filter: filter not found");
- return false;
+ return (jint) Result::INVALID_STATE;
}
- Result r = filterSp->flush();
- return (int) r;
+ Result r = iFilterSp->flush();
+ return (jint) r;
}
-static int android_media_tv_Tuner_read_filter_fmq(
+static jint android_media_tv_Tuner_read_filter_fmq(
JNIEnv *env, jobject filter, jbyteArray buffer, jlong offset, jlong size) {
sp<Filter> filterSp = getFilter(env, filter);
if (filterSp == NULL) {
ALOGD("Failed to read filter FMQ: filter not found");
- return 0;
+ return (jint) Result::INVALID_STATE;
}
return copyData(env, filterSp, buffer, offset, size);
}
-static int android_media_tv_Tuner_close_filter(JNIEnv*, jobject) {
- return 0;
+static jint android_media_tv_Tuner_close_filter(JNIEnv *env, jobject filter) {
+ sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
+ if (iFilterSp == NULL) {
+ ALOGD("Failed to close filter: filter not found");
+ return (jint) Result::INVALID_STATE;
+ }
+ Result r = iFilterSp->close();
+ return (jint) r;
}
static sp<TimeFilter> getTimeFilter(JNIEnv *env, jobject filter) {
@@ -2660,8 +2703,8 @@ static int android_media_tv_Tuner_add_pid(
if (descramblerSp == NULL) {
return false;
}
- sp<IFilter> filterSp = getFilter(env, filter)->getIFilter();
- Result result = descramblerSp->addPid(getDemuxPid((int)pidType, (int)pid), filterSp);
+ sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
+ Result result = descramblerSp->addPid(getDemuxPid((int)pidType, (int)pid), iFilterSp);
return (int)result;
}
@@ -2671,8 +2714,8 @@ static int android_media_tv_Tuner_remove_pid(
if (descramblerSp == NULL) {
return false;
}
- sp<IFilter> filterSp = getFilter(env, filter)->getIFilter();
- Result result = descramblerSp->removePid(getDemuxPid((int)pidType, (int)pid), filterSp);
+ sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
+ Result result = descramblerSp->removePid(getDemuxPid((int)pidType, (int)pid), iFilterSp);
return (int)result;
}
@@ -2702,21 +2745,21 @@ static jobject android_media_tv_Tuner_get_demux_caps(JNIEnv*, jobject) {
static int android_media_tv_Tuner_attach_filter(JNIEnv *env, jobject dvr, jobject filter) {
sp<IDvr> dvrSp = getDvr(env, dvr)->getIDvr();
- sp<IFilter> filterSp = getFilter(env, filter)->getIFilter();
- if (dvrSp == NULL || filterSp == NULL) {
+ sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
+ if (dvrSp == NULL || iFilterSp == NULL) {
return false;
}
- Result result = dvrSp->attachFilter(filterSp);
+ Result result = dvrSp->attachFilter(iFilterSp);
return (int) result;
}
static int android_media_tv_Tuner_detach_filter(JNIEnv *env, jobject dvr, jobject filter) {
sp<IDvr> dvrSp = getDvr(env, dvr)->getIDvr();
- sp<IFilter> filterSp = getFilter(env, filter)->getIFilter();
- if (dvrSp == NULL || filterSp == NULL) {
+ sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
+ if (dvrSp == NULL || iFilterSp == NULL) {
return false;
}
- Result result = dvrSp->detachFilter(filterSp);
+ Result result = dvrSp->detachFilter(iFilterSp);
return (int) result;
}