diff options
Diffstat (limited to 'jni')
-rw-r--r-- | jni/Android.mk | 12 | ||||
-rw-r--r-- | jni/DvbManager.cpp | 339 | ||||
-rw-r--r-- | jni/DvbManager.h | 84 | ||||
-rwxr-xr-x | jni/gen_jni.sh | 3 | ||||
-rw-r--r-- | jni/logging.h | 32 | ||||
-rw-r--r-- | jni/mutex.h | 61 | ||||
-rw-r--r-- | jni/tunertvinput_jni.cpp | 157 | ||||
-rw-r--r-- | jni/tunertvinput_jni.h | 98 |
8 files changed, 786 insertions, 0 deletions
diff --git a/jni/Android.mk b/jni/Android.mk new file mode 100644 index 00000000..684830c9 --- /dev/null +++ b/jni/Android.mk @@ -0,0 +1,12 @@ +LOCAL_PATH := $(call my-dir) + +# -------------------------------------------------------------- +include $(CLEAR_VARS) + +LOCAL_MODULE := libtunertvinput_jni +LOCAL_SRC_FILES += tunertvinput_jni.cpp DvbManager.cpp +LOCAL_SDK_VERSION := 21 +LOCAL_NDK_STL_VARIANT := stlport_static +LOCAL_LDLIBS := -llog + +include $(BUILD_SHARED_LIBRARY) diff --git a/jni/DvbManager.cpp b/jni/DvbManager.cpp new file mode 100644 index 00000000..aa4ed530 --- /dev/null +++ b/jni/DvbManager.cpp @@ -0,0 +1,339 @@ +/* + * Copyright (C) 2015 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. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <unistd.h> +#include <limits.h> +#include <string.h> +#include <fcntl.h> +#include <sys/poll.h> +#include <sys/ioctl.h> +#include <linux/dvb/dmx.h> +#include <linux/dvb/frontend.h> + +#define LOG_TAG "DvbManager" +#include "logging.h" + +#include "DvbManager.h" + +static double currentTimeMillis() { + struct timeval tv; + gettimeofday(&tv, (struct timezone *) NULL); + return tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0; +} + +DvbManager::DvbManager(JNIEnv *env, jobject) + : mFeFd(-1), + mDemuxFd(-1), + mDvrFd(-1), + mPatFilterFd(-1), + mFeHasLock(false), + mHasPendingTune(false) { + jclass clazz = env->FindClass( + "com/android/tv/tuner/TunerHal"); + mOpenDvbFrontEndMethodID = env->GetMethodID( + clazz, "openDvbFrontEndFd", "()I"); + mOpenDvbDemuxMethodID = env->GetMethodID( + clazz, "openDvbDemuxFd", "()I"); + mOpenDvbDvrMethodID = env->GetMethodID( + clazz, "openDvbDvrFd", "()I"); +} + +DvbManager::~DvbManager() { + reset(); +} + +bool DvbManager::isFeLocked() { + struct pollfd pollFd; + pollFd.fd = mFeFd; + pollFd.events = POLLIN; + pollFd.revents = 0; + int poll_result = poll(&pollFd, NUM_POLLFDS, FE_POLL_TIMEOUT_MS); + if (poll_result > 0 && (pollFd.revents & POLLIN)) { + struct dvb_frontend_event kevent; + memset(&kevent, 0, sizeof(kevent)); + if (ioctl(mFeFd, FE_GET_EVENT, &kevent) == 0) { + return (kevent.status & FE_HAS_LOCK); + } + } + return false; +} + +int DvbManager::tune(JNIEnv *env, jobject thiz, + const int frequency, const char *modulationStr, int timeout_ms) { + resetExceptFe(); + + struct dvb_frontend_parameters feParams; + memset(&feParams, 0, sizeof(struct dvb_frontend_parameters)); + feParams.frequency = frequency; + if (strcmp(modulationStr, "8VSB") == 0) { + feParams.u.vsb.modulation = VSB_8; + } else if (strcmp(modulationStr, "QAM256") == 0) { + feParams.u.vsb.modulation = QAM_256; + } else { + ALOGE("Unrecognized modulation mode : %s", modulationStr); + return -1; + } + + if (mHasPendingTune) { + return -1; + } + if (openDvbFe(env, thiz) != 0) { + return -1; + } + + feParams.inversion = INVERSION_AUTO; + /* Check frontend capability */ + struct dvb_frontend_info feInfo; + if (ioctl(mFeFd, FE_GET_INFO, &feInfo) != -1) { + if (!(feInfo.caps & FE_CAN_INVERSION_AUTO)) { + // FE can't do INVERSION_AUTO, trying INVERSION_OFF instead + feParams.inversion = INVERSION_OFF; + } + } + + if (ioctl(mFeFd, FE_SET_FRONTEND, &feParams) != 0) { + ALOGD("Can't set Frontend : %s", strerror(errno)); + return -1; + } + + int lockSuccessCount = 0; + double tuneClock = currentTimeMillis(); + while (currentTimeMillis() - tuneClock < timeout_ms) { + if (mHasPendingTune) { + // Return 0 here since we already call FE_SET_FRONTEND, and return due to having pending + // tune request. And the frontend setting could be successful. + mFeHasLock = true; + return 0; + } + bool lockStatus = isFeLocked(); + if (lockStatus) { + lockSuccessCount++; + } else { + lockSuccessCount = 0; + } + ALOGI("Lock status : %s", lockStatus ? "true" : "false"); + if (lockSuccessCount >= FE_CONSECUTIVE_LOCK_SUCCESS_COUNT) { + mFeHasLock = true; + openDvbDvr(env, thiz); + return 0; + } + } + + return -1; +} + +int DvbManager::stopTune() { + reset(); + usleep(DVB_TUNE_STOP_DELAY_MS); + return 0; +} + +int DvbManager::openDvbFeFromSystemApi(JNIEnv *env, jobject thiz) { + int fd = (int) env->CallIntMethod(thiz, mOpenDvbFrontEndMethodID); + fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); + return fd; +} + +int DvbManager::openDvbDemuxFromSystemApi(JNIEnv *env, jobject thiz) { + int fd = (int) env->CallIntMethod(thiz, mOpenDvbDemuxMethodID); + fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); + return fd; +} + +int DvbManager::openDvbDvrFromSystemApi(JNIEnv *env, jobject thiz) { + int fd = (int) env->CallIntMethod(thiz, mOpenDvbDvrMethodID); + fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); + return fd; +} + +int DvbManager::openDvbFe(JNIEnv *env, jobject thiz) { + if (mFeFd == -1) { + if ((mFeFd = openDvbFeFromSystemApi(env, thiz)) < 0) { + ALOGD("Can't open FE file : %s", strerror(errno)); + return -1; + } + } + + struct dvb_frontend_info info; + if (ioctl(mFeFd, FE_GET_INFO, &info) == 0) { + const char *types; + switch (info.type) { + case FE_QPSK: + types = "DVB-S"; + break; + case FE_QAM: + types = "DVB-C"; + break; + case FE_OFDM: + types = "DVB-T"; + break; + case FE_ATSC: + types = "ATSC"; + break; + default: + types = "Unknown"; + } + ALOGI("Using frontend \"%s\", type %s", info.name, types); + } + return 0; +} + +int DvbManager::startTsPidFilter(JNIEnv *env, jobject thiz, int pid, int filterType) { + Mutex::Autolock autoLock(mFilterLock); + + if (mPidFilters.find(pid) != mPidFilters.end() || (mPatFilterFd != -1 && pid == PAT_PID)) { + return 0; + } + + if (mHasPendingTune) { + return -1; + } + + int demuxFd; + if ((demuxFd = openDvbDemuxFromSystemApi(env, thiz)) < 0) { + ALOGD("Can't open DEMUX file : %s", strerror(errno)); + return -1; + } + + struct dmx_pes_filter_params filter; + memset(&filter, 0, sizeof(filter)); + filter.pid = pid; + filter.input = DMX_IN_FRONTEND; + switch (filterType) { + case FILTER_TYPE_AUDIO: + filter.pes_type = DMX_PES_AUDIO; + break; + case FILTER_TYPE_VIDEO: + filter.pes_type = DMX_PES_VIDEO; + break; + case FILTER_TYPE_PCR: + filter.pes_type = DMX_PES_PCR; + break; + default: + filter.pes_type = DMX_PES_OTHER; + break; + } + filter.output = DMX_OUT_TS_TAP; + filter.flags |= (DMX_CHECK_CRC | DMX_IMMEDIATE_START); + + // create a pes filter + if (ioctl(demuxFd, DMX_SET_PES_FILTER, &filter)) { + close(demuxFd); + return -1; + } + + if (pid != PAT_PID) { + mPidFilters.insert(std::pair<int, int>(pid, demuxFd)); + } else { + mPatFilterFd = demuxFd; + } + + return 0; +} + +void DvbManager::closeAllDvbPidFilter() { + // Close all dvb pid filters except PAT filter to maintain the opening status of the device. + Mutex::Autolock autoLock(mFilterLock); + + for (std::map<int, int>::iterator it(mPidFilters.begin()); + it != mPidFilters.end(); it++) { + close(it->second); + } + mPidFilters.clear(); + // Close mDvrFd to make sure there is not buffer from previous channel left. + closeDvbDvr(); +} + +void DvbManager::closePatFilter() { + Mutex::Autolock autoLock(mFilterLock); + + if (mPatFilterFd != -1) { + close(mPatFilterFd); + mPatFilterFd = -1; + } +} + +int DvbManager::openDvbDvr(JNIEnv *env, jobject thiz) { + if ((mDvrFd = openDvbDvrFromSystemApi(env, thiz)) < 0) { + ALOGD("Can't open DVR file : %s", strerror(errno)); + return -1; + } + return 0; +} + +void DvbManager::closeDvbFe() { + if (mFeFd != -1) { + close(mFeFd); + mFeFd = -1; + } +} + +void DvbManager::closeDvbDvr() { + if (mDvrFd != -1) { + close(mDvrFd); + mDvrFd = -1; + } +} + +void DvbManager::reset() { + mFeHasLock = false; + closeDvbDvr(); + closeAllDvbPidFilter(); + closePatFilter(); + closeDvbFe(); +} + +void DvbManager::resetExceptFe() { + mFeHasLock = false; + closeDvbDvr(); + closeAllDvbPidFilter(); + closePatFilter(); +} + +int DvbManager::readTsStream(JNIEnv *env, jobject thiz, + uint8_t *tsBuffer, int tsBufferSize, int timeout_ms) { + if (!mFeHasLock) { + usleep(DVB_ERROR_RETRY_INTERVAL_MS); + return -1; + } + + if (mDvrFd == -1) { + openDvbDvr(env, thiz); + } + + struct pollfd pollFd; + pollFd.fd = mDvrFd; + pollFd.events = POLLIN|POLLPRI|POLLERR; + pollFd.revents = 0; + int poll_result = poll(&pollFd, NUM_POLLFDS, timeout_ms); + if (poll_result == 0) { + return 0; + } else if (poll_result == -1 || pollFd.revents & POLLERR) { + ALOGD("Can't read DVR : %s", strerror(errno)); + // TODO: Find how to recover this situation correctly. + closeDvbDvr(); + usleep(DVB_ERROR_RETRY_INTERVAL_MS); + return -1; + } + return read(mDvrFd, tsBuffer, tsBufferSize); +} + +void DvbManager::setHasPendingTune(bool hasPendingTune) { + mHasPendingTune = hasPendingTune; +} diff --git a/jni/DvbManager.h b/jni/DvbManager.h new file mode 100644 index 00000000..7475bd41 --- /dev/null +++ b/jni/DvbManager.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2015 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 DVB_MANAGER_H_ +#define DVB_MANAGER_H_ + +#include <jni.h> +#include <map> + +#include "mutex.h" +#include "tunertvinput_jni.h" + +class DvbManager { + static const int NUM_POLLFDS = 1; + static const int FE_LOCK_CHECK_INTERNAL_US = 100 * 1000; + static const int FE_CONSECUTIVE_LOCK_SUCCESS_COUNT = 1; + static const int DVB_ERROR_RETRY_INTERVAL_MS = 100 * 1000; + static const int DVB_TUNE_STOP_DELAY_MS = 100 * 1000; + static const int FE_POLL_TIMEOUT_MS = 100; + static const int PAT_PID = 0; + + static const int FILTER_TYPE_OTHER = + com_android_tv_tuner_TunerHal_FILTER_TYPE_OTHER; + static const int FILTER_TYPE_AUDIO = + com_android_tv_tuner_TunerHal_FILTER_TYPE_AUDIO; + static const int FILTER_TYPE_VIDEO = + com_android_tv_tuner_TunerHal_FILTER_TYPE_VIDEO; + static const int FILTER_TYPE_PCR = + com_android_tv_tuner_TunerHal_FILTER_TYPE_PCR; + + int mFeFd; + int mDemuxFd; + int mDvrFd; + int mPatFilterFd; + bool mFeHasLock; + // Flag for pending tune request. Used for canceling the current tune operation. + bool volatile mHasPendingTune; + std::map<int, int> mPidFilters; + Mutex mFilterLock; + jmethodID mOpenDvbFrontEndMethodID; + jmethodID mOpenDvbDemuxMethodID; + jmethodID mOpenDvbDvrMethodID; + +public: + DvbManager(JNIEnv *env, jobject thiz); + ~DvbManager(); + int tune(JNIEnv *env, jobject thiz, + const int frequency, const char *modulationStr, int timeout_ms); + int stopTune(); + int readTsStream(JNIEnv *env, jobject thiz, + uint8_t *tsBuffer, int tsBufferSize, int timeout_ms); + int startTsPidFilter(JNIEnv *env, jobject thiz, int pid, int filterType); + void closeAllDvbPidFilter(); + void setHasPendingTune(bool hasPendingTune); + +private: + int openDvbFe(JNIEnv *env, jobject thiz); + int openDvbDvr(JNIEnv *env, jobject thiz); + void closePatFilter(); + void closeDvbFe(); + void closeDvbDvr(); + void reset(); + void resetExceptFe(); + bool isFeLocked(); + // Call to java method + int openDvbFeFromSystemApi(JNIEnv *env, jobject thiz); + int openDvbDemuxFromSystemApi(JNIEnv *env, jobject thiz); + int openDvbDvrFromSystemApi(JNIEnv *env, jobject thiz); +}; + +#endif // DVB_MANAGER_H_ diff --git a/jni/gen_jni.sh b/jni/gen_jni.sh new file mode 100755 index 00000000..aa52b248 --- /dev/null +++ b/jni/gen_jni.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +javah -jni -classpath ../../bin/classes:../../../../../../prebuilts/sdk/current/android.jar -o tunertvinput_jni.h com.android.tv.tuner.TunerHal diff --git a/jni/logging.h b/jni/logging.h new file mode 100644 index 00000000..af90961c --- /dev/null +++ b/jni/logging.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2015 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 LOGGING_H_ +#define LOGGING_H_ + +#include <android/log.h> + +#ifndef LOG_TAG +#define LOG_TAG "usbtuner" +#endif + +#define ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__) +#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG , LOG_TAG, __VA_ARGS__) +#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO , LOG_TAG, __VA_ARGS__) +#define ALOGW(...) __android_log_print(ANDROID_LOG_WARN , LOG_TAG, __VA_ARGS__) +#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR , LOG_TAG, __VA_ARGS__) + +#endif // LOGGING_H_ diff --git a/jni/mutex.h b/jni/mutex.h new file mode 100644 index 00000000..90527ae4 --- /dev/null +++ b/jni/mutex.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2015 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 MUTEX_H_ +#define MUTEX_H_ + +#include "pthread.h" + +// Based on utils/threads.h, but tailored to build with the NDK and used unbundled. +// This is a simple wrapper over the pthread_mutex_t type. +class Mutex { +public: + Mutex() { + pthread_mutex_init(&mMutex, NULL); + } + int lock() { + return -pthread_mutex_lock(&mMutex); + } + void unlock() { + pthread_mutex_unlock(&mMutex); + } + ~Mutex() { + pthread_mutex_destroy(&mMutex); + } + + // A simple class that locks a given mutex on construction + // and unlocks it when it goes out of scope. + class Autolock { + public: + Autolock(Mutex &mutex) : lock(&mutex) { + lock->lock(); + } + ~Autolock() { + lock->unlock(); + } + private: + Mutex *lock; + }; + +private: + pthread_mutex_t mMutex; + + // Disallow copy and assign. + Mutex(const Mutex&); + Mutex& operator=(const Mutex&); +}; + +#endif // MUTEX_H_ diff --git a/jni/tunertvinput_jni.cpp b/jni/tunertvinput_jni.cpp new file mode 100644 index 00000000..bcbc4c29 --- /dev/null +++ b/jni/tunertvinput_jni.cpp @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2015 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. + */ + +#include "tunertvinput_jni.h" +#include <map> + +#include "DvbManager.h" +#define LOG_TAG "tunertvinput_jni" +#include "logging.h" + +//------------------------------------------------------------------------------- +// JNI native method implementation +//------------------------------------------------------------------------------- + +#define TS_PACKET_SIZE 188 +#define TS_PAYLOAD_SIZE (TS_PACKET_SIZE * 7) // Fit Ethernet MTU (1500) +#define READ_TIMEOUT_MS 100 + +static int sTotalBytesFetched = 0; +static std::map<jlong, DvbManager *> sDvbManagers; + +/* + * Class: com_android_tv_tuner_TunerHal + * Method: nativeFinalize + * Signature: (J)V + */ +JNIEXPORT void JNICALL +Java_com_android_tv_tuner_TunerHal_nativeFinalize +(JNIEnv *, jobject, jlong deviceId) { + std::map<jlong, DvbManager *>::iterator it = sDvbManagers.find(deviceId); + if (it != sDvbManagers.end()) { + delete it->second; + sDvbManagers.erase(it); + } +} + +/* + * Class: com_android_tv_tuner_TunerHal + * Method: nativeTune + * Signature: (JILjava/lang/String;)Z + */ +JNIEXPORT jboolean JNICALL +Java_com_android_tv_tuner_TunerHal_nativeTune +(JNIEnv *env, jobject thiz, jlong deviceId, jint frequency, jstring modulation, jint timeout_ms) { + std::map<jlong, DvbManager *>::iterator it = sDvbManagers.find(deviceId); + DvbManager *dvbManager; + if (it == sDvbManagers.end()) { + dvbManager = new DvbManager(env, thiz); + sDvbManagers.insert(std::pair<jlong, DvbManager *>(deviceId, dvbManager)); + } else { + dvbManager = it->second; + } + int res = dvbManager->tune(env, thiz, + frequency, env->GetStringUTFChars(modulation, 0), timeout_ms); + return (res == 0); +} + +/* + * Class: com_android_tv_tuner_TunerHal + * Method: nativeCloseAllPidFilters + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_android_tv_tuner_TunerHal_nativeCloseAllPidFilters + (JNIEnv *, jobject, jlong deviceId) { + std::map<jlong, DvbManager *>::iterator it = sDvbManagers.find(deviceId); + if (it != sDvbManagers.end()) { + it->second->closeAllDvbPidFilter(); + } +} + +/* + * Class: com_android_tv_tuner_TunerHal + * Method: nativeStopTune + * Signature: (J)V + */ +JNIEXPORT void JNICALL +Java_com_android_tv_tuner_TunerHal_nativeStopTune +(JNIEnv *, jobject, jlong deviceId) { + std::map<jlong, DvbManager *>::iterator it = sDvbManagers.find(deviceId); + if (it != sDvbManagers.end()) { + it->second->stopTune(); + } +} + +/* + * Class: com_android_tv_tuner_TunerHal + * Method: nativeAddPidFilter + * Signature: (JII)V + */ +JNIEXPORT void JNICALL +Java_com_android_tv_tuner_TunerHal_nativeAddPidFilter +(JNIEnv *env, jobject thiz, jlong deviceId, jint pid, jint filterType) { + std::map<jlong, DvbManager *>::iterator it = sDvbManagers.find(deviceId); + if (it != sDvbManagers.end()) { + it->second->startTsPidFilter(env, thiz, pid, filterType); + } +} + +/* + * Class: com_android_tv_tuner_TunerHal + * Method: nativeWriteInBuffer + * Signature: (J[BI)I + */ +JNIEXPORT jint JNICALL +Java_com_android_tv_tuner_TunerHal_nativeWriteInBuffer +(JNIEnv *env, jobject thiz, jlong deviceId, jbyteArray javaBuffer, jint javaBufferSize) { + uint8_t tsBuffer[TS_PAYLOAD_SIZE]; + std::map<jlong, DvbManager *>::iterator it = sDvbManagers.find(deviceId); + if (it == sDvbManagers.end()) { + return -1; + } + DvbManager *dvbManager = it->second; + + // Always read multiple of TS_PACKET_SIZE + javaBufferSize = (javaBufferSize / TS_PACKET_SIZE) * TS_PACKET_SIZE; + int readBufferSize = (javaBufferSize < TS_PAYLOAD_SIZE) ? javaBufferSize : TS_PAYLOAD_SIZE; + + int dataSize = dvbManager->readTsStream(env, thiz, tsBuffer, readBufferSize, READ_TIMEOUT_MS); + if (dataSize == 0) { + ALOGD("No data to read DVR"); + return 0; + } else if (dataSize < 0) { + return -1; + } + + sTotalBytesFetched += dataSize; + + env->SetByteArrayRegion(javaBuffer, 0, dataSize, (jbyte *) tsBuffer); + return dataSize; +} + +/* + * Class: com_android_tv_tuner_TunerHal + * Method: nativeSetHasPendingTune + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL +Java_com_android_tv_tuner_TunerHal_nativeSetHasPendingTune +(JNIEnv *env, jobject thiz, jlong deviceId, jboolean hasPendingTune) { + std::map<jlong, DvbManager *>::iterator it = sDvbManagers.find(deviceId); + if (it != sDvbManagers.end()) { + it->second->setHasPendingTune(hasPendingTune); + } +} diff --git a/jni/tunertvinput_jni.h b/jni/tunertvinput_jni.h new file mode 100644 index 00000000..4ade29e4 --- /dev/null +++ b/jni/tunertvinput_jni.h @@ -0,0 +1,98 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include <jni.h> +/* Header for class com_android_tv_tuner_TunerHal */ + +#ifndef _Included_com_android_tv_tuner_TunerHal +#define _Included_com_android_tv_tuner_TunerHal +#ifdef __cplusplus +extern "C" { +#endif +#undef com_android_tv_tuner_TunerHal_DEBUG +#define com_android_tv_tuner_TunerHal_DEBUG 0L +#undef com_android_tv_tuner_TunerHal_FILTER_TYPE_OTHER +#define com_android_tv_tuner_TunerHal_FILTER_TYPE_OTHER 0L +#undef com_android_tv_tuner_TunerHal_FILTER_TYPE_AUDIO +#define com_android_tv_tuner_TunerHal_FILTER_TYPE_AUDIO 1L +#undef com_android_tv_tuner_TunerHal_FILTER_TYPE_VIDEO +#define com_android_tv_tuner_TunerHal_FILTER_TYPE_VIDEO 2L +#undef com_android_tv_tuner_TunerHal_FILTER_TYPE_PCR +#define com_android_tv_tuner_TunerHal_FILTER_TYPE_PCR 3L +#undef com_android_tv_tuner_TunerHal_PID_PAT +#define com_android_tv_tuner_TunerHal_PID_PAT 0L +#undef com_android_tv_tuner_TunerHal_PID_ATSC_SI_BASE +#define com_android_tv_tuner_TunerHal_PID_ATSC_SI_BASE 8187L +#undef com_android_tv_tuner_TunerHal_DEFAULT_VSB_TUNE_TIMEOUT_MS +#define com_android_tv_tuner_TunerHal_DEFAULT_VSB_TUNE_TIMEOUT_MS 2000L +#undef com_android_tv_tuner_TunerHal_DEFAULT_QAM_TUNE_TIMEOUT_MS +#define com_android_tv_tuner_TunerHal_DEFAULT_QAM_TUNE_TIMEOUT_MS 4000L +/* + * Class: com_android_tv_tuner_TunerHal + * Method: nativeFinalize + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_android_tv_tuner_TunerHal_nativeFinalize + (JNIEnv *, jobject, jlong); + +/* + * Class: com_android_tv_tuner_TunerHal + * Method: nativeTune + * Signature: (JILjava/lang/String;I)Z + */ +JNIEXPORT jboolean JNICALL Java_com_android_tv_tuner_TunerHal_nativeTune + (JNIEnv *, jobject, jlong, jint, jstring, jint); + +/* + * Class: com_android_tv_tuner_TunerHal + * Method: nativeAddPidFilter + * Signature: (JII)V + */ +JNIEXPORT void JNICALL Java_com_android_tv_tuner_TunerHal_nativeAddPidFilter + (JNIEnv *, jobject, jlong, jint, jint); + +/* + * Class: com_android_tv_tuner_TunerHal + * Method: nativeCloseAllPidFilters + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_android_tv_tuner_TunerHal_nativeCloseAllPidFilters + (JNIEnv *, jobject, jlong); + +/* + * Class: com_android_tv_tuner_TunerHal + * Method: nativeStopTune + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_android_tv_tuner_TunerHal_nativeStopTune + (JNIEnv *, jobject, jlong); + +/* + * Class: com_android_tv_tuner_TunerHal + * Method: nativeWriteInBuffer + * Signature: (J[BI)I + */ +JNIEXPORT jint JNICALL Java_com_android_tv_tuner_TunerHal_nativeWriteInBuffer + (JNIEnv *, jobject, jlong, jbyteArray, jint); + +/* + * Class: com_android_tv_tuner_TunerHal + * Method: nativeSetHasPendingTune + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_android_tv_tuner_TunerHal_nativeSetHasPendingTune + (JNIEnv *, jobject, jlong, jboolean); + +#ifdef __cplusplus +} +#endif +#endif +/* Header for class com_android_tv_tuner_TunerHal_FilterType */ + +#ifndef _Included_com_android_tv_tuner_TunerHal_FilterType +#define _Included_com_android_tv_tuner_TunerHal_FilterType +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif +#endif |