143 lines
4.5 KiB
C++
143 lines
4.5 KiB
C++
/*
|
|
* 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_usbtuner_TunerHal
|
|
* Method: nativeFinalize
|
|
* Signature: (J)V
|
|
*/
|
|
JNIEXPORT void JNICALL
|
|
Java_com_android_usbtuner_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_usbtuner_TunerHal
|
|
* Method: nativeTune
|
|
* Signature: (JILjava/lang/String;)Z
|
|
*/
|
|
JNIEXPORT jboolean JNICALL
|
|
Java_com_android_usbtuner_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_usbtuner_TunerHal
|
|
* Method: nativeCloseAllPidFilters
|
|
* Signature: (J)V
|
|
*/
|
|
JNIEXPORT void JNICALL Java_com_android_usbtuner_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_usbtuner_TunerHal
|
|
* Method: nativeStopTune
|
|
* Signature: (J)V
|
|
*/
|
|
JNIEXPORT void JNICALL
|
|
Java_com_android_usbtuner_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_usbtuner_TunerHal
|
|
* Method: nativeAddPidFilter
|
|
* Signature: (JII)V
|
|
*/
|
|
JNIEXPORT void JNICALL
|
|
Java_com_android_usbtuner_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_usbtuner_TunerHal
|
|
* Method: nativeWriteInBuffer
|
|
* Signature: (J[BI)I
|
|
*/
|
|
JNIEXPORT jint JNICALL
|
|
Java_com_android_usbtuner_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;
|
|
}
|