From 90dd6749511c3c29aba780521c1abf813fd8fc9b Mon Sep 17 00:00:00 2001 From: Hongguang Date: Tue, 23 Nov 2021 13:24:00 -0800 Subject: [PATCH] Add some new features to tuner. *) Add DTS info to DemuxFilterMediaEvent. *) Allow to ignore download Id in DemuxFilterDownloadSettings and put download id into DemuxFilterDownloadEvent. *) Change section data size 64 bits. *) Support DvrPlayback seek. *) Support FrontendStatus streamIdList. Bug: 183583908 Bug: 183024067 Bug: 203181023 Bug: 198195793 Bug: 171540818 Test: atest android.media.tv.tuner.cts on AIDL and HILD HALs Change-Id: I5872e5f042f5803c367cf7624dbefc31292fd7e9 --- core/api/system-current.txt | 11 +- .../media/tv/tuner/dvr/DvrPlayback.java | 28 +++-- .../media/tv/tuner/dvr/DvrRecorder.java | 13 +-- .../media/tv/tuner/filter/DownloadEvent.java | 14 ++- .../tv/tuner/filter/DownloadSettings.java | 35 +++++- .../media/tv/tuner/filter/MediaEvent.java | 30 ++++- .../media/tv/tuner/filter/SectionEvent.java | 11 +- .../tv/tuner/frontend/FrontendStatus.java | 29 ++++- media/jni/android_media_tv_Tuner.cpp | 109 +++++++++++------- media/jni/tuner/DvrClient.cpp | 10 ++ media/jni/tuner/DvrClient.h | 5 + 11 files changed, 224 insertions(+), 71 deletions(-) diff --git a/core/api/system-current.txt b/core/api/system-current.txt index dd1760c510978..4bc2b0ff629db 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -6250,6 +6250,7 @@ package android.media.tv.tuner.dvr { method public int flush(); method public long read(long); method public long read(@NonNull byte[], long, long); + method public long seek(long); method public void setFileDescriptor(@NonNull android.os.ParcelFileDescriptor); method public int start(); method public int stop(); @@ -6385,6 +6386,7 @@ package android.media.tv.tuner.filter { public class DownloadEvent extends android.media.tv.tuner.filter.FilterEvent { method public int getDataLength(); + method public int getDownloadId(); method public int getItemFragmentIndex(); method public int getItemId(); method public int getLastItemFragmentIndex(); @@ -6394,11 +6396,13 @@ package android.media.tv.tuner.filter { public class DownloadSettings extends android.media.tv.tuner.filter.Settings { method @NonNull public static android.media.tv.tuner.filter.DownloadSettings.Builder builder(int); method public int getDownloadId(); + method public boolean useDownloadId(); } public static class DownloadSettings.Builder { method @NonNull public android.media.tv.tuner.filter.DownloadSettings build(); method @NonNull public android.media.tv.tuner.filter.DownloadSettings.Builder setDownloadId(int); + method @NonNull public android.media.tv.tuner.filter.DownloadSettings.Builder setUseDownloadId(boolean); } public class Filter implements java.lang.AutoCloseable { @@ -6497,12 +6501,14 @@ package android.media.tv.tuner.filter { method public long getAudioHandle(); method public long getAvDataId(); method public long getDataLength(); + method public long getDts(); method @Nullable public android.media.tv.tuner.filter.AudioDescriptor getExtraMetaData(); method @Nullable public android.media.MediaCodec.LinearBlock getLinearBlock(); method @IntRange(from=0) public int getMpuSequenceNumber(); method public long getOffset(); method public long getPts(); method public int getStreamId(); + method public boolean isDtsPresent(); method public boolean isPrivateData(); method public boolean isPtsPresent(); method public boolean isSecureMemory(); @@ -6612,7 +6618,8 @@ package android.media.tv.tuner.filter { } public class SectionEvent extends android.media.tv.tuner.filter.FilterEvent { - method public int getDataLength(); + method @Deprecated public int getDataLength(); + method public long getDataLengthLong(); method public int getSectionNumber(); method public int getTableId(); method public int getVersion(); @@ -7344,6 +7351,7 @@ package android.media.tv.tuner.frontend { method public int getSignalStrength(); method public int getSnr(); method public int getSpectralInversion(); + method @NonNull public int[] getStreamIdList(); method public int getSymbolRate(); method @IntRange(from=0, to=65535) public int getSystemId(); method public int getTransmissionMode(); @@ -7390,6 +7398,7 @@ package android.media.tv.tuner.frontend { field public static final int FRONTEND_STATUS_TYPE_SIGNAL_STRENGTH = 6; // 0x6 field public static final int FRONTEND_STATUS_TYPE_SNR = 1; // 0x1 field public static final int FRONTEND_STATUS_TYPE_SPECTRAL = 10; // 0xa + field public static final int FRONTEND_STATUS_TYPE_STREAM_ID_LIST = 39; // 0x27 field public static final int FRONTEND_STATUS_TYPE_SYMBOL_RATE = 7; // 0x7 field public static final int FRONTEND_STATUS_TYPE_T2_SYSTEM_ID = 29; // 0x1d field public static final int FRONTEND_STATUS_TYPE_TRANSMISSION_MODE = 27; // 0x1b diff --git a/media/java/android/media/tv/tuner/dvr/DvrPlayback.java b/media/java/android/media/tv/tuner/dvr/DvrPlayback.java index cfd85834048c2..6f3ab032a75c4 100644 --- a/media/java/android/media/tv/tuner/dvr/DvrPlayback.java +++ b/media/java/android/media/tv/tuner/dvr/DvrPlayback.java @@ -98,6 +98,7 @@ public class DvrPlayback implements AutoCloseable { private native void nativeSetFileDescriptor(int fd); private native long nativeRead(long size); private native long nativeRead(byte[] bytes, long offset, long size); + private native long nativeSeek(long pos); private DvrPlayback() { mUserId = Process.myUid(); @@ -243,7 +244,7 @@ public class DvrPlayback implements AutoCloseable { * * @param fd the file descriptor to read data. * @see #read(long) - * @see #read(byte[], long, long) + * @see #seek(long) */ public void setFileDescriptor(@NonNull ParcelFileDescriptor fd) { nativeSetFileDescriptor(fd.getFd()); @@ -261,19 +262,30 @@ public class DvrPlayback implements AutoCloseable { } /** - * Reads data from the buffer for DVR playback and copies to the given byte array. + * Reads data from the buffer for DVR playback. * - * @param bytes the byte array to store the data. - * @param offset the index of the first byte in {@code bytes} to copy to. + * @param buffer the byte array where DVR reads data from. + * @param offset the index of the first byte in {@code buffer} to read. * @param size the maximum number of bytes to read. * @return the number of bytes read. */ @BytesLong - public long read(@NonNull byte[] bytes, @BytesLong long offset, @BytesLong long size) { - if (size + offset > bytes.length) { + public long read(@NonNull byte[] buffer, @BytesLong long offset, @BytesLong long size) { + if (size + offset > buffer.length) { throw new ArrayIndexOutOfBoundsException( - "Array length=" + bytes.length + ", offset=" + offset + ", size=" + size); + "Array length=" + buffer.length + ", offset=" + offset + ", size=" + size); } - return nativeRead(bytes, offset, size); + return nativeRead(buffer, offset, size); + } + + /** + * Sets the file pointer offset of the file descriptor. + * + * @param pos the offset position, measured in bytes from the beginning of the file. + * @return the new offset position. + */ + @BytesLong + public long seek(@BytesLong long pos) { + return nativeSeek(pos); } } diff --git a/media/java/android/media/tv/tuner/dvr/DvrRecorder.java b/media/java/android/media/tv/tuner/dvr/DvrRecorder.java index 212a71343a49d..e72026aab992d 100644 --- a/media/java/android/media/tv/tuner/dvr/DvrRecorder.java +++ b/media/java/android/media/tv/tuner/dvr/DvrRecorder.java @@ -216,7 +216,6 @@ public class DvrRecorder implements AutoCloseable { * * @param fd the file descriptor to write data. * @see #write(long) - * @see #write(byte[], long, long) */ public void setFileDescriptor(@NonNull ParcelFileDescriptor fd) { nativeSetFileDescriptor(fd.getFd()); @@ -236,17 +235,17 @@ public class DvrRecorder implements AutoCloseable { /** * Writes recording data to buffer. * - * @param bytes the byte array stores the data to be written to DVR. - * @param offset the index of the first byte in {@code bytes} to be written to DVR. + * @param buffer the byte array stores the data from DVR. + * @param offset the index of the first byte in {@code buffer} to write the data from DVR. * @param size the maximum number of bytes to write. * @return the number of bytes written. */ @BytesLong - public long write(@NonNull byte[] bytes, @BytesLong long offset, @BytesLong long size) { - if (size + offset > bytes.length) { + public long write(@NonNull byte[] buffer, @BytesLong long offset, @BytesLong long size) { + if (size + offset > buffer.length) { throw new ArrayIndexOutOfBoundsException( - "Array length=" + bytes.length + ", offset=" + offset + ", size=" + size); + "Array length=" + buffer.length + ", offset=" + offset + ", size=" + size); } - return nativeWrite(bytes, offset, size); + return nativeWrite(buffer, offset, size); } } diff --git a/media/java/android/media/tv/tuner/filter/DownloadEvent.java b/media/java/android/media/tv/tuner/filter/DownloadEvent.java index 394211be646b3..25989db2fb973 100644 --- a/media/java/android/media/tv/tuner/filter/DownloadEvent.java +++ b/media/java/android/media/tv/tuner/filter/DownloadEvent.java @@ -27,15 +27,17 @@ import android.annotation.SystemApi; @SystemApi public class DownloadEvent extends FilterEvent { private final int mItemId; + private final int mDownloadId; private final int mMpuSequenceNumber; private final int mItemFragmentIndex; private final int mLastItemFragmentIndex; private final int mDataLength; // This constructor is used by JNI code only - private DownloadEvent(int itemId, int mpuSequenceNumber, int itemFragmentIndex, + private DownloadEvent(int itemId, int downloadId, int mpuSequenceNumber, int itemFragmentIndex, int lastItemFragmentIndex, int dataLength) { mItemId = itemId; + mDownloadId = downloadId; mMpuSequenceNumber = mpuSequenceNumber; mItemFragmentIndex = itemFragmentIndex; mLastItemFragmentIndex = lastItemFragmentIndex; @@ -49,6 +51,15 @@ public class DownloadEvent extends FilterEvent { return mItemId; } + /** + * Gets download ID. + * + *

This query is only supported in Tuner 2.0 or higher version. Unsupported version will + * return {@code -1}. + * Use {@link TunerVersionChecker#getTunerVersion()} to get the version information. + */ + public int getDownloadId() { return mDownloadId; } + /** * Gets MPU sequence number of filtered data. */ @@ -80,4 +91,3 @@ public class DownloadEvent extends FilterEvent { return mDataLength; } } - diff --git a/media/java/android/media/tv/tuner/filter/DownloadSettings.java b/media/java/android/media/tv/tuner/filter/DownloadSettings.java index 7ba923e23c701..e2cfd7c173a2e 100644 --- a/media/java/android/media/tv/tuner/filter/DownloadSettings.java +++ b/media/java/android/media/tv/tuner/filter/DownloadSettings.java @@ -19,6 +19,7 @@ package android.media.tv.tuner.filter; import android.annotation.NonNull; import android.annotation.SystemApi; import android.media.tv.tuner.TunerUtils; +import android.media.tv.tuner.TunerVersionChecker; /** * Filter Settings for a Download. @@ -27,10 +28,12 @@ import android.media.tv.tuner.TunerUtils; */ @SystemApi public class DownloadSettings extends Settings { + private final boolean mUseDownloadId; private final int mDownloadId; - private DownloadSettings(int mainType, int downloadId) { + private DownloadSettings(int mainType, boolean useDownloadId, int downloadId) { super(TunerUtils.getFilterSubtype(mainType, Filter.SUBTYPE_DOWNLOAD)); + mUseDownloadId = useDownloadId; mDownloadId = downloadId; } @@ -41,6 +44,15 @@ public class DownloadSettings extends Settings { return mDownloadId; } + /** + * Gets whether download ID is used. + * + *

This query is only supported in Tuner 2.0 or higher version. Unsupported version will + * return {@code false}. + * Use {@link TunerVersionChecker#getTunerVersion()} to get the version information. + */ + public boolean useDownloadId() { return mUseDownloadId; } + /** * Creates a builder for {@link DownloadSettings}. * @@ -56,12 +68,31 @@ public class DownloadSettings extends Settings { */ public static class Builder { private final int mMainType; + private boolean mUseDownloadId = false; private int mDownloadId; private Builder(int mainType) { mMainType = mainType; } + /** + * Sets whether download ID is used or not. + * + *

This configuration is only supported in Tuner 2.0 or higher version. Unsupported + * version will cause no-op. Use {@link TunerVersionChecker#getTunerVersion()} to get the + * version information. + * + *

Default value is {@code false}. + */ + @NonNull + public Builder setUseDownloadId(boolean useDownloadId) { + if (TunerVersionChecker.checkHigherOrEqualVersionTo( + TunerVersionChecker.TUNER_VERSION_2_0, "setUseDownloadId")) { + mUseDownloadId = useDownloadId; + } + return this; + } + /** * Sets download ID. */ @@ -76,7 +107,7 @@ public class DownloadSettings extends Settings { */ @NonNull public DownloadSettings build() { - return new DownloadSettings(mMainType, mDownloadId); + return new DownloadSettings(mMainType, mUseDownloadId, mDownloadId); } } } diff --git a/media/java/android/media/tv/tuner/filter/MediaEvent.java b/media/java/android/media/tv/tuner/filter/MediaEvent.java index dbd85e9997d82..79d4062cfbbfa 100644 --- a/media/java/android/media/tv/tuner/filter/MediaEvent.java +++ b/media/java/android/media/tv/tuner/filter/MediaEvent.java @@ -40,6 +40,8 @@ public class MediaEvent extends FilterEvent { private final int mStreamId; private final boolean mIsPtsPresent; private final long mPts; + private final boolean mIsDtsPresent; + private final long mDts; private final long mDataLength; private final long mOffset; private LinearBlock mLinearBlock; @@ -50,12 +52,14 @@ public class MediaEvent extends FilterEvent { private final AudioDescriptor mExtraMetaData; // This constructor is used by JNI code only - private MediaEvent(int streamId, boolean isPtsPresent, long pts, long dataLength, long offset, - LinearBlock buffer, boolean isSecureMemory, long dataId, int mpuSequenceNumber, - boolean isPrivateData, AudioDescriptor extraMetaData) { + private MediaEvent(int streamId, boolean isPtsPresent, long pts, boolean isDtsPresent, long dts, + long dataLength, long offset, LinearBlock buffer, boolean isSecureMemory, long dataId, + int mpuSequenceNumber, boolean isPrivateData, AudioDescriptor extraMetaData) { mStreamId = streamId; mIsPtsPresent = isPtsPresent; mPts = pts; + mIsDtsPresent = isDtsPresent; + mDts = dts; mDataLength = dataLength; mOffset = offset; mLinearBlock = buffer; @@ -89,6 +93,26 @@ public class MediaEvent extends FilterEvent { return mPts; } + /** + * Returns whether DTS (Decode Time Stamp) is present. + * + *

This query is only supported in Tuner 2.0 or higher version. Unsupported version will + * return {@code false}. + * Use {@link TunerVersionChecker#getTunerVersion()} to get the version information. + * + * @return {@code true} if DTS is present in PES header; {@code false} otherwise. + */ + public boolean isDtsPresent() { return mIsDtsPresent; } + + /** + * Gets DTS (Decode Time Stamp) for audio or video frame. + * + * *

This query is only supported in Tuner 2.0 or higher version. Unsupported version will + * return {@code -1}. + * Use {@link TunerVersionChecker#getTunerVersion()} to get the version information. + */ + public long getDts() { return mDts; } + /** * Gets data size in bytes of audio or video frame. */ diff --git a/media/java/android/media/tv/tuner/filter/SectionEvent.java b/media/java/android/media/tv/tuner/filter/SectionEvent.java index ff1249296efd4..182bb9463bd6e 100644 --- a/media/java/android/media/tv/tuner/filter/SectionEvent.java +++ b/media/java/android/media/tv/tuner/filter/SectionEvent.java @@ -28,10 +28,10 @@ public class SectionEvent extends FilterEvent { private final int mTableId; private final int mVersion; private final int mSectionNum; - private final int mDataLength; + private final long mDataLength; // This constructor is used by JNI code only - private SectionEvent(int tableId, int version, int sectionNum, int dataLength) { + private SectionEvent(int tableId, int version, int sectionNum, long dataLength) { mTableId = tableId; mVersion = version; mSectionNum = sectionNum; @@ -61,8 +61,13 @@ public class SectionEvent extends FilterEvent { /** * Gets data size in bytes of filtered data. + * + * @deprecated Use {@link #getDataLengthLong()} */ + @Deprecated public int getDataLength() { - return mDataLength; + return (int) getDataLengthLong(); } + + public long getDataLengthLong() { return mDataLength; } } diff --git a/media/java/android/media/tv/tuner/frontend/FrontendStatus.java b/media/java/android/media/tv/tuner/frontend/FrontendStatus.java index 31f1a63e12ba6..582e4f54e2c38 100644 --- a/media/java/android/media/tv/tuner/frontend/FrontendStatus.java +++ b/media/java/android/media/tv/tuner/frontend/FrontendStatus.java @@ -19,10 +19,10 @@ package android.media.tv.tuner.frontend; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; +import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.media.tv.tuner.Lnb; import android.media.tv.tuner.TunerVersionChecker; - import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -53,7 +53,7 @@ public class FrontendStatus { FRONTEND_STATUS_TYPE_MODULATIONS_EXT, FRONTEND_STATUS_TYPE_ROLL_OFF, FRONTEND_STATUS_TYPE_IS_MISO_ENABLED, FRONTEND_STATUS_TYPE_IS_LINEAR, FRONTEND_STATUS_TYPE_IS_SHORT_FRAMES_ENABLED, FRONTEND_STATUS_TYPE_ISDBT_MODE, - FRONTEND_STATUS_TYPE_ISDBT_PARTIAL_RECEPTION_FLAG}) + FRONTEND_STATUS_TYPE_ISDBT_PARTIAL_RECEPTION_FLAG, FRONTEND_STATUS_TYPE_STREAM_ID_LIST}) @Retention(RetentionPolicy.SOURCE) public @interface FrontendStatusType {} @@ -254,6 +254,12 @@ public class FrontendStatus { public static final int FRONTEND_STATUS_TYPE_ISDBT_PARTIAL_RECEPTION_FLAG = android.hardware.tv.tuner.FrontendStatusType.ISDBT_PARTIAL_RECEPTION_FLAG; + /** + * Stream ID list included in a transponder. + */ + public static final int FRONTEND_STATUS_TYPE_STREAM_ID_LIST = + android.hardware.tv.tuner.FrontendStatusType.STREAM_ID_LIST; + /** @hide */ @IntDef(value = { AtscFrontendSettings.MODULATION_UNDEFINED, @@ -493,6 +499,7 @@ public class FrontendStatus { private Boolean mIsShortFrames; private Integer mIsdbtMode; private Integer mIsdbtPartialReceptionFlag; + private int[] mStreamIds; // Constructed and fields set by JNI code. private FrontendStatus() { @@ -1000,6 +1007,24 @@ public class FrontendStatus { return mIsdbtPartialReceptionFlag; } + /** + * Gets stream id list included in a transponder. + * + *

This query is only supported by Tuner HAL 2.0 or higher. Unsupported version or if HAL + * doesn't return stream id list status will throw IllegalStateException. Use + * {@link TunerVersionChecker#getTunerVersion()} to check the version. + */ + @SuppressLint("ArrayReturn") + @NonNull + public int[] getStreamIdList() { + TunerVersionChecker.checkHigherOrEqualVersionTo( + TunerVersionChecker.TUNER_VERSION_2_0, "stream id list status"); + if (mStreamIds == null) { + throw new IllegalStateException("stream id list status is empty"); + } + return mStreamIds; + } + /** * Information of each tuning Physical Layer Pipes. */ diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp index 4c1ed45c5f3d7..b4a3c647991f0 100644 --- a/media/jni/android_media_tv_Tuner.cpp +++ b/media/jni/android_media_tv_Tuner.cpp @@ -588,13 +588,13 @@ void FilterClientCallbackImpl::getSectionEvent(jobjectArray &arr, const int size const DemuxFilterEvent &event) { JNIEnv *env = AndroidRuntime::getJNIEnv(); jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/SectionEvent"); - jmethodID eventInit = env->GetMethodID(eventClazz, "", "(IIII)V"); + jmethodID eventInit = env->GetMethodID(eventClazz, "", "(IIIJ)V"); const DemuxFilterSectionEvent §ionEvent = event.get(); jint tableId = sectionEvent.tableId; jint version = sectionEvent.version; jint sectionNum = sectionEvent.sectionNum; - jint dataLength = sectionEvent.dataLength; + jlong dataLength = sectionEvent.dataLength; jobject obj = env->NewObject(eventClazz, eventInit, tableId, version, sectionNum, dataLength); env->SetObjectArrayElement(arr, size, obj); @@ -604,10 +604,9 @@ void FilterClientCallbackImpl::getMediaEvent(jobjectArray &arr, const int size, const DemuxFilterEvent &event) { JNIEnv *env = AndroidRuntime::getJNIEnv(); jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/MediaEvent"); - jmethodID eventInit = env->GetMethodID(eventClazz, - "", - "(IZJJJLandroid/media/MediaCodec$LinearBlock;" - "ZJIZLandroid/media/tv/tuner/filter/AudioDescriptor;)V"); + jmethodID eventInit = env->GetMethodID(eventClazz, "", + "(IZJZJJJLandroid/media/MediaCodec$LinearBlock;" + "ZJIZLandroid/media/tv/tuner/filter/AudioDescriptor;)V"); jfieldID eventContext = env->GetFieldID(eventClazz, "mNativeContext", "J"); const DemuxFilterMediaEvent &mediaEvent = event.get(); @@ -633,15 +632,17 @@ void FilterClientCallbackImpl::getMediaEvent(jobjectArray &arr, const int size, jint streamId = mediaEvent.streamId; jboolean isPtsPresent = mediaEvent.isPtsPresent; jlong pts = mediaEvent.pts; + jboolean isDtsPresent = mediaEvent.isDtsPresent; + jlong dts = mediaEvent.dts; jlong offset = mediaEvent.offset; jboolean isSecureMemory = mediaEvent.isSecureMemory; jlong avDataId = mediaEvent.avDataId; jint mpuSequenceNumber = mediaEvent.mpuSequenceNumber; jboolean isPesPrivateData = mediaEvent.isPesPrivateData; - jobject obj = env->NewObject(eventClazz, eventInit, streamId, isPtsPresent, pts, dataLength, - offset, nullptr, isSecureMemory, avDataId, mpuSequenceNumber, - isPesPrivateData, audioDescriptor); + jobject obj = env->NewObject(eventClazz, eventInit, streamId, isPtsPresent, pts, isDtsPresent, + dts, dataLength, offset, nullptr, isSecureMemory, avDataId, + mpuSequenceNumber, isPesPrivateData, audioDescriptor); uint64_t avSharedMemSize = mFilterClient->getAvSharedHandleInfo().size; if (mediaEvent.avMemory.fds.size() > 0 || mediaEvent.avDataId != 0 || @@ -733,16 +734,17 @@ void FilterClientCallbackImpl::getDownloadEvent(jobjectArray &arr, const int siz const DemuxFilterEvent &event) { JNIEnv *env = AndroidRuntime::getJNIEnv(); jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/DownloadEvent"); - jmethodID eventInit = env->GetMethodID(eventClazz, "", "(IIIII)V"); + jmethodID eventInit = env->GetMethodID(eventClazz, "", "(IIIIII)V"); const DemuxFilterDownloadEvent &downloadEvent = event.get(); jint itemId = downloadEvent.itemId; + jint downloadId = downloadEvent.downloadId; jint mpuSequenceNumber = downloadEvent.mpuSequenceNumber; jint itemFragmentIndex = downloadEvent.itemFragmentIndex; jint lastItemFragmentIndex = downloadEvent.lastItemFragmentIndex; jint dataLength = downloadEvent.dataLength; - jobject obj = env->NewObject(eventClazz, eventInit, itemId, mpuSequenceNumber, + jobject obj = env->NewObject(eventClazz, eventInit, itemId, downloadId, mpuSequenceNumber, itemFragmentIndex, lastItemFragmentIndex, dataLength); env->SetObjectArrayElement(arr, size, obj); } @@ -2450,7 +2452,14 @@ jobject JTuner::getFrontendStatus(jintArray types) { env->SetObjectField(statusObj, field, newIntegerObj); break; } - default: { + case FrontendStatus::Tag::streamIdList: { + jfieldID field = env->GetFieldID(clazz, "mStreamIds", "[I"); + std::vector ids = s.get(); + + jintArray valObj = env->NewIntArray(v.size()); + env->SetIntArrayRegion(valObj, 0, v.size(), reinterpret_cast(&ids[0])); + + env->SetObjectField(statusObj, field, valObj); break; } } @@ -3469,10 +3478,13 @@ static DemuxFilterRecordSettings getFilterRecordSettings(JNIEnv *env, const jobj static DemuxFilterDownloadSettings getFilterDownloadSettings(JNIEnv *env, const jobject& settings) { jclass clazz = env->FindClass("android/media/tv/tuner/filter/DownloadSettings"); + bool useDownloadId = + env->GetBooleanField(settings, env->GetFieldID(clazz, "mUseDownloadId", "Z")); int32_t downloadId = env->GetIntField(settings, env->GetFieldID(clazz, "mDownloadId", "I")); - DemuxFilterDownloadSettings filterDownloadSettings { - .downloadId = downloadId, + DemuxFilterDownloadSettings filterDownloadSettings{ + .useDownloadId = useDownloadId, + .downloadId = downloadId, }; return filterDownloadSettings; } @@ -4253,6 +4265,17 @@ static jlong android_media_tv_Tuner_read_dvr(JNIEnv *env, jobject dvr, jlong siz return (jlong)dvrClient->readFromFile(size); } +static jlong android_media_tv_Tuner_seek_dvr(JNIEnv *env, jobject dvr, jlong pos) { + sp dvrClient = getDvrClient(env, dvr); + if (dvrClient == nullptr) { + jniThrowException(env, "java/lang/IllegalStateException", + "Failed to seek dvr: dvr client not found"); + return -1; + } + + return (jlong)dvrClient->seekFile(pos); +} + static jlong android_media_tv_Tuner_read_dvr_from_array( JNIEnv* env, jobject dvr, jbyteArray buffer, jlong offset, jlong size) { sp dvrClient = getDvrClient(env, dvr); @@ -4403,38 +4426,37 @@ static const JNINativeMethod gTunerMethods[] = { { "nativeClose", "()I", (void *)android_media_tv_Tuner_close_tuner }, { "nativeCloseFrontend", "(I)I", (void *)android_media_tv_Tuner_close_frontend }, { "nativeCloseDemux", "(I)I", (void *)android_media_tv_Tuner_close_demux }, - {"nativeOpenSharedFilter", + { "nativeOpenSharedFilter", "(Ljava/lang/String;)Landroid/media/tv/tuner/filter/SharedFilter;", (void *)android_media_tv_Tuner_open_shared_filter}, }; static const JNINativeMethod gFilterMethods[] = { { "nativeConfigureFilter", "(IILandroid/media/tv/tuner/filter/FilterConfiguration;)I", - (void *)android_media_tv_Tuner_configure_filter }, - { "nativeGetId", "()I", (void *)android_media_tv_Tuner_get_filter_id }, - { "nativeGetId64Bit", "()J", - (void *)android_media_tv_Tuner_get_filter_64bit_id }, + (void *)android_media_tv_Tuner_configure_filter}, + { "nativeGetId", "()I", (void *)android_media_tv_Tuner_get_filter_id}, + { "nativeGetId64Bit", "()J", (void *)android_media_tv_Tuner_get_filter_64bit_id}, { "nativeConfigureMonitorEvent", "(I)I", - (void *)android_media_tv_Tuner_configure_monitor_event }, + (void *)android_media_tv_Tuner_configure_monitor_event}, { "nativeSetDataSource", "(Landroid/media/tv/tuner/filter/Filter;)I", - (void *)android_media_tv_Tuner_set_filter_data_source }, - { "nativeStartFilter", "()I", (void *)android_media_tv_Tuner_start_filter }, - { "nativeStopFilter", "()I", (void *)android_media_tv_Tuner_stop_filter }, - { "nativeFlushFilter", "()I", (void *)android_media_tv_Tuner_flush_filter }, - { "nativeRead", "([BJJ)I", (void *)android_media_tv_Tuner_read_filter_fmq }, - { "nativeClose", "()I", (void *)android_media_tv_Tuner_close_filter }, - {"nativeAcquireSharedFilterToken", "()Ljava/lang/String;", + (void *)android_media_tv_Tuner_set_filter_data_source}, + { "nativeStartFilter", "()I", (void *)android_media_tv_Tuner_start_filter}, + { "nativeStopFilter", "()I", (void *)android_media_tv_Tuner_stop_filter}, + { "nativeFlushFilter", "()I", (void *)android_media_tv_Tuner_flush_filter}, + { "nativeRead", "([BJJ)I", (void *)android_media_tv_Tuner_read_filter_fmq}, + { "nativeClose", "()I", (void *)android_media_tv_Tuner_close_filter}, + { "nativeAcquireSharedFilterToken", "()Ljava/lang/String;", (void *)android_media_tv_Tuner_acquire_shared_filter_token}, - {"nativeFreeSharedFilterToken", "(Ljava/lang/String;)V", + { "nativeFreeSharedFilterToken", "(Ljava/lang/String;)V", (void *)android_media_tv_Tuner_free_shared_filter_token}, }; static const JNINativeMethod gSharedFilterMethods[] = { - {"nativeStartSharedFilter", "()I", (void *)android_media_tv_Tuner_start_filter}, - {"nativeStopSharedFilter", "()I", (void *)android_media_tv_Tuner_stop_filter}, - {"nativeFlushSharedFilter", "()I", (void *)android_media_tv_Tuner_flush_filter}, - {"nativeSharedRead", "([BJJ)I", (void *)android_media_tv_Tuner_read_filter_fmq}, - {"nativeSharedClose", "()I", (void *)android_media_tv_Tuner_close_filter}, + { "nativeStartSharedFilter", "()I", (void *)android_media_tv_Tuner_start_filter}, + { "nativeStopSharedFilter", "()I", (void *)android_media_tv_Tuner_stop_filter}, + { "nativeFlushSharedFilter", "()I", (void *)android_media_tv_Tuner_flush_filter}, + { "nativeSharedRead", "([BJJ)I", (void *)android_media_tv_Tuner_read_filter_fmq}, + { "nativeSharedClose", "()I", (void *)android_media_tv_Tuner_close_filter}, }; static const JNINativeMethod gTimeFilterMethods[] = { @@ -4474,18 +4496,19 @@ static const JNINativeMethod gDvrRecorderMethods[] = { static const JNINativeMethod gDvrPlaybackMethods[] = { { "nativeAttachFilter", "(Landroid/media/tv/tuner/filter/Filter;)I", - (void *)android_media_tv_Tuner_attach_filter }, + (void *)android_media_tv_Tuner_attach_filter}, { "nativeDetachFilter", "(Landroid/media/tv/tuner/filter/Filter;)I", - (void *)android_media_tv_Tuner_detach_filter }, + (void *)android_media_tv_Tuner_detach_filter}, { "nativeConfigureDvr", "(Landroid/media/tv/tuner/dvr/DvrSettings;)I", - (void *)android_media_tv_Tuner_configure_dvr }, - { "nativeStartDvr", "()I", (void *)android_media_tv_Tuner_start_dvr }, - { "nativeStopDvr", "()I", (void *)android_media_tv_Tuner_stop_dvr }, - { "nativeFlushDvr", "()I", (void *)android_media_tv_Tuner_flush_dvr }, - { "nativeClose", "()I", (void *)android_media_tv_Tuner_close_dvr }, - { "nativeSetFileDescriptor", "(I)V", (void *)android_media_tv_Tuner_dvr_set_fd }, - { "nativeRead", "(J)J", (void *)android_media_tv_Tuner_read_dvr }, - { "nativeRead", "([BJJ)J", (void *)android_media_tv_Tuner_read_dvr_from_array }, + (void *)android_media_tv_Tuner_configure_dvr}, + { "nativeStartDvr", "()I", (void *)android_media_tv_Tuner_start_dvr}, + { "nativeStopDvr", "()I", (void *)android_media_tv_Tuner_stop_dvr}, + { "nativeFlushDvr", "()I", (void *)android_media_tv_Tuner_flush_dvr}, + { "nativeClose", "()I", (void *)android_media_tv_Tuner_close_dvr}, + { "nativeSetFileDescriptor", "(I)V", (void *)android_media_tv_Tuner_dvr_set_fd}, + { "nativeRead", "(J)J", (void *)android_media_tv_Tuner_read_dvr}, + { "nativeRead", "([BJJ)J", (void *)android_media_tv_Tuner_read_dvr_from_array}, + { "nativeSeek", "(J)J", (void *)android_media_tv_Tuner_seek_dvr}, }; static const JNINativeMethod gLnbMethods[] = { diff --git a/media/jni/tuner/DvrClient.cpp b/media/jni/tuner/DvrClient.cpp index 30278382c8ecf..05683b661716f 100644 --- a/media/jni/tuner/DvrClient.cpp +++ b/media/jni/tuner/DvrClient.cpp @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include #include "ClientHelper.h" @@ -200,6 +202,14 @@ int64_t DvrClient::writeToBuffer(int8_t* buffer, int64_t size) { return size; } +int64_t DvrClient::seekFile(int64_t pos) { + if (mFd < 0) { + ALOGE("Failed to seekFile. File is not configured"); + return -1; + } + return lseek64(mFd, pos, SEEK_SET); +} + Result DvrClient::configure(DvrSettings settings) { if (mTunerDvr != nullptr) { Status s = mTunerDvr->configure(settings); diff --git a/media/jni/tuner/DvrClient.h b/media/jni/tuner/DvrClient.h index 9080c7288f767..61c0325813a4c 100644 --- a/media/jni/tuner/DvrClient.h +++ b/media/jni/tuner/DvrClient.h @@ -81,6 +81,11 @@ public: */ int64_t writeToFile(int64_t size); + /** + * Seeks the Dvr file descriptor from the beginning of the file. + */ + int64_t seekFile(int64_t pos); + /** * Write data to the given buffer with given size. Return the actual write size. */