Home | History | Annotate | Download | only in jni
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "tunertvinput_jni.h"
     18 #include <map>
     19 
     20 #include "DvbManager.h"
     21 #define LOG_TAG "tunertvinput_jni"
     22 #include "logging.h"
     23 
     24 //-------------------------------------------------------------------------------
     25 // JNI native method implementation
     26 //-------------------------------------------------------------------------------
     27 
     28 #define TS_PACKET_SIZE 188
     29 #define TS_PAYLOAD_SIZE (TS_PACKET_SIZE * 7) // Fit Ethernet MTU (1500)
     30 #define READ_TIMEOUT_MS 100
     31 
     32 static int sTotalBytesFetched = 0;
     33 static std::map<jlong, DvbManager *> sDvbManagers;
     34 
     35 /*
     36  * Class:     com_android_usbtuner_TunerHal
     37  * Method:    nativeFinalize
     38  * Signature: (J)V
     39  */
     40 JNIEXPORT void JNICALL
     41 Java_com_android_usbtuner_TunerHal_nativeFinalize
     42 (JNIEnv *, jobject, jlong deviceId) {
     43     std::map<jlong, DvbManager *>::iterator it = sDvbManagers.find(deviceId);
     44     if (it != sDvbManagers.end()) {
     45         delete it->second;
     46         sDvbManagers.erase(it);
     47     }
     48 }
     49 
     50 /*
     51  * Class:     com_android_usbtuner_TunerHal
     52  * Method:    nativeTune
     53  * Signature: (JILjava/lang/String;)Z
     54  */
     55 JNIEXPORT jboolean JNICALL
     56 Java_com_android_usbtuner_TunerHal_nativeTune
     57 (JNIEnv *env, jobject thiz, jlong deviceId, jint frequency, jstring modulation, jint timeout_ms) {
     58     std::map<jlong, DvbManager *>::iterator it = sDvbManagers.find(deviceId);
     59     DvbManager *dvbManager;
     60     if (it == sDvbManagers.end()) {
     61         dvbManager = new DvbManager(env, thiz);
     62         sDvbManagers.insert(std::pair<jlong, DvbManager *>(deviceId, dvbManager));
     63     } else {
     64         dvbManager = it->second;
     65     }
     66     int res = dvbManager->tune(env, thiz,
     67             frequency, env->GetStringUTFChars(modulation, 0), timeout_ms);
     68     return (res == 0);
     69 }
     70 
     71 /*
     72  * Class:     com_android_usbtuner_TunerHal
     73  * Method:    nativeCloseAllPidFilters
     74  * Signature: (J)V
     75  */
     76 JNIEXPORT void JNICALL Java_com_android_usbtuner_TunerHal_nativeCloseAllPidFilters
     77   (JNIEnv *, jobject, jlong deviceId) {
     78     std::map<jlong, DvbManager *>::iterator it = sDvbManagers.find(deviceId);
     79     if (it != sDvbManagers.end()) {
     80         it->second->closeAllDvbPidFilter();
     81     }
     82 }
     83 
     84 /*
     85  * Class:     com_android_usbtuner_TunerHal
     86  * Method:    nativeStopTune
     87  * Signature: (J)V
     88  */
     89 JNIEXPORT void JNICALL
     90 Java_com_android_usbtuner_TunerHal_nativeStopTune
     91 (JNIEnv *, jobject, jlong deviceId) {
     92     std::map<jlong, DvbManager *>::iterator it = sDvbManagers.find(deviceId);
     93     if (it != sDvbManagers.end()) {
     94         it->second->stopTune();
     95     }
     96 }
     97 
     98 /*
     99  * Class:     com_android_usbtuner_TunerHal
    100  * Method:    nativeAddPidFilter
    101  * Signature: (JII)V
    102  */
    103 JNIEXPORT void JNICALL
    104 Java_com_android_usbtuner_TunerHal_nativeAddPidFilter
    105 (JNIEnv *env, jobject thiz, jlong deviceId, jint pid, jint filterType) {
    106     std::map<jlong, DvbManager *>::iterator it = sDvbManagers.find(deviceId);
    107     if (it != sDvbManagers.end()) {
    108         it->second->startTsPidFilter(env, thiz, pid, filterType);
    109     }
    110 }
    111 
    112 /*
    113  * Class:     com_android_usbtuner_TunerHal
    114  * Method:    nativeWriteInBuffer
    115  * Signature: (J[BI)I
    116  */
    117 JNIEXPORT jint JNICALL
    118 Java_com_android_usbtuner_TunerHal_nativeWriteInBuffer
    119 (JNIEnv *env, jobject thiz, jlong deviceId, jbyteArray javaBuffer, jint javaBufferSize) {
    120     uint8_t tsBuffer[TS_PAYLOAD_SIZE];
    121     std::map<jlong, DvbManager *>::iterator it = sDvbManagers.find(deviceId);
    122     if (it == sDvbManagers.end()) {
    123         return -1;
    124     }
    125     DvbManager *dvbManager = it->second;
    126 
    127     // Always read multiple of TS_PACKET_SIZE
    128     javaBufferSize = (javaBufferSize / TS_PACKET_SIZE) * TS_PACKET_SIZE;
    129     int readBufferSize = (javaBufferSize < TS_PAYLOAD_SIZE) ? javaBufferSize : TS_PAYLOAD_SIZE;
    130 
    131     int dataSize = dvbManager->readTsStream(env, thiz, tsBuffer, readBufferSize, READ_TIMEOUT_MS);
    132     if (dataSize == 0) {
    133         ALOGD("No data to read DVR");
    134         return 0;
    135     } else if (dataSize < 0) {
    136         return -1;
    137     }
    138 
    139     sTotalBytesFetched += dataSize;
    140 
    141     env->SetByteArrayRegion(javaBuffer, 0, dataSize, (jbyte *) tsBuffer);
    142     return dataSize;
    143 }
    144