1ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko/* 2ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * Copyright (C) 2015 The Android Open Source Project 3ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * 4ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * Licensed under the Apache License, Version 2.0 (the "License"); 5ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * you may not use this file except in compliance with the License. 6ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * You may obtain a copy of the License at 7ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * 8ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * http://www.apache.org/licenses/LICENSE-2.0 9ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * 10ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * Unless required by applicable law or agreed to in writing, software 11ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * distributed under the License is distributed on an "AS IS" BASIS, 12ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * See the License for the specific language governing permissions and 14ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * limitations under the License. 15ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko */ 16ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 1765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkopackage com.android.tv.tuner; 18ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 19ba5845f23b8fbc985890f892961abc8b39886611Nick Chalkoimport android.content.Context; 20ba5845f23b8fbc985890f892961abc8b39886611Nick Chalkoimport android.support.annotation.IntDef; 21ba5845f23b8fbc985890f892961abc8b39886611Nick Chalkoimport android.support.annotation.StringDef; 226ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkoimport android.support.annotation.WorkerThread; 23ba5845f23b8fbc985890f892961abc8b39886611Nick Chalkoimport android.util.Log; 246ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkoimport android.util.Pair; 256ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko 266ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkoimport com.android.tv.Features; 276ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkoimport com.android.tv.customization.TvCustomizationManager; 28ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 29ba5845f23b8fbc985890f892961abc8b39886611Nick Chalkoimport java.lang.annotation.Retention; 30ba5845f23b8fbc985890f892961abc8b39886611Nick Chalkoimport java.lang.annotation.RetentionPolicy; 31ba5845f23b8fbc985890f892961abc8b39886611Nick Chalkoimport java.util.Objects; 32ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 33ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko/** 34ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * A base class to handle a hardware tuner device. 35ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko */ 36ba5845f23b8fbc985890f892961abc8b39886611Nick Chalkopublic abstract class TunerHal implements AutoCloseable { 37ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko protected static final String TAG = "TunerHal"; 38ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko protected static final boolean DEBUG = false; 39ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 40ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko @IntDef({ FILTER_TYPE_OTHER, FILTER_TYPE_AUDIO, FILTER_TYPE_VIDEO, FILTER_TYPE_PCR }) 41ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko @Retention(RetentionPolicy.SOURCE) 42ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko public @interface FilterType {} 43ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko public static final int FILTER_TYPE_OTHER = 0; 44ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko public static final int FILTER_TYPE_AUDIO = 1; 45ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko public static final int FILTER_TYPE_VIDEO = 2; 46ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko public static final int FILTER_TYPE_PCR = 3; 47ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 48ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko @StringDef({ MODULATION_8VSB, MODULATION_QAM256 }) 49ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko @Retention(RetentionPolicy.SOURCE) 50ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko public @interface ModulationType {} 51ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko public static final String MODULATION_8VSB = "8VSB"; 52ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko public static final String MODULATION_QAM256 = "QAM256"; 53ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 546ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko @IntDef({ DELIVERY_SYSTEM_UNDEFINED, DELIVERY_SYSTEM_ATSC, DELIVERY_SYSTEM_DVBC, 556ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko DELIVERY_SYSTEM_DVBS, DELIVERY_SYSTEM_DVBS2, DELIVERY_SYSTEM_DVBT, 566ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko DELIVERY_SYSTEM_DVBT2 }) 576ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko @Retention(RetentionPolicy.SOURCE) 586ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko public @interface DeliverySystemType {} 596ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko public static final int DELIVERY_SYSTEM_UNDEFINED = 0; 606ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko public static final int DELIVERY_SYSTEM_ATSC = 1; 616ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko public static final int DELIVERY_SYSTEM_DVBC = 2; 626ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko public static final int DELIVERY_SYSTEM_DVBS = 3; 636ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko public static final int DELIVERY_SYSTEM_DVBS2 = 4; 646ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko public static final int DELIVERY_SYSTEM_DVBT = 5; 656ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko public static final int DELIVERY_SYSTEM_DVBT2 = 6; 666ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko 676ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko @IntDef({ TUNER_TYPE_BUILT_IN, TUNER_TYPE_USB, TUNER_TYPE_NETWORK }) 686ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko @Retention(RetentionPolicy.SOURCE) 696ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko public @interface TunerType {} 7065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public static final int TUNER_TYPE_BUILT_IN = 1; 7165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public static final int TUNER_TYPE_USB = 2; 726ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko public static final int TUNER_TYPE_NETWORK = 3; 7365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 74ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko protected static final int PID_PAT = 0; 75ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko protected static final int PID_ATSC_SI_BASE = 0x1ffb; 766ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko protected static final int PID_DVB_SDT = 0x0011; 776ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko protected static final int PID_DVB_EIT = 0x0012; 78ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko protected static final int DEFAULT_VSB_TUNE_TIMEOUT_MS = 2000; 79ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko protected static final int DEFAULT_QAM_TUNE_TIMEOUT_MS = 4000; // Some device takes time for 80ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko // QAM256 tuning. 816ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko @IntDef({ 826ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko BUILT_IN_TUNER_TYPE_LINUX_DVB 836ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko }) 846ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko @Retention(RetentionPolicy.SOURCE) 856ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko private @interface BuiltInTunerType {} 866ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko private static final int BUILT_IN_TUNER_TYPE_LINUX_DVB = 1; 876ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko 886ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko private static Integer sBuiltInTunerType; 896ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko 906ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko protected @DeliverySystemType int mDeliverySystemType; 91ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko private boolean mIsStreaming; 92ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko private int mFrequency; 93ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko private String mModulation; 94ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 95ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko static { 96ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko System.loadLibrary("tunertvinput_jni"); 97ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko } 98ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 992e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko /** 1002e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko * Creates a TunerHal instance. 1012e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko * @param context context for creating the TunerHal instance 1022e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko * @return the TunerHal instance 1032e1279b8bbe0603fb4399b25b73121bed5953c46Nick Chalko */ 1046ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko @WorkerThread 10565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public synchronized static TunerHal createInstance(Context context) { 10665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko TunerHal tunerHal = null; 1076ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko if (DvbTunerHal.getNumberOfDevices(context) > 0) { 1086ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko if (DEBUG) Log.d(TAG, "Use DvbTunerHal"); 1096ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko tunerHal = new DvbTunerHal(context); 110721bd0da688cd552737fbb753a00597f95103b95Adrian Roos } 1116ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko return tunerHal != null && tunerHal.openFirstAvailable() ? tunerHal : null; 112ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko } 113ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 11465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 11565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Gets the number of tuner devices currently present. 11665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 1176ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko @WorkerThread 1186ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko public static Pair<Integer, Integer> getTunerTypeAndCount(Context context) { 1196ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko if (useBuiltInTuner(context)) { 1206ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko if (getBuiltInTunerType(context) == BUILT_IN_TUNER_TYPE_LINUX_DVB) { 1216ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko return new Pair<>(TUNER_TYPE_BUILT_IN, DvbTunerHal.getNumberOfDevices(context)); 1226ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko } 1236ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko } else { 1246ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko int usbTunerCount = DvbTunerHal.getNumberOfDevices(context); 1256ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko if (usbTunerCount > 0) { 1266ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko return new Pair<>(TUNER_TYPE_USB, usbTunerCount); 1276ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko } 12865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 1296ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko return new Pair<>(null, 0); 1306ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko } 1316ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko 1326ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko /** 1336ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko * Check a delivery system is for DVB or not. 1346ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko */ 1356ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko public static boolean isDvbDeliverySystem(@DeliverySystemType int deliverySystemType) { 1366ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko return deliverySystemType == DELIVERY_SYSTEM_DVBC 1376ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko || deliverySystemType == DELIVERY_SYSTEM_DVBS 1386ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko || deliverySystemType == DELIVERY_SYSTEM_DVBS2 1396ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko || deliverySystemType == DELIVERY_SYSTEM_DVBT 1406ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko || deliverySystemType == DELIVERY_SYSTEM_DVBT2; 14165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 14265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 14365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko /** 1446ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko * Returns if tuner input service would use built-in tuners instead of USB tuners or network 1456ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko * tuners. 14665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */ 1476ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko static boolean useBuiltInTuner(Context context) { 1486ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko return getBuiltInTunerType(context) != 0; 1496ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko } 1506ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko 1516ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko private static @BuiltInTunerType int getBuiltInTunerType(Context context) { 1526ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko if (sBuiltInTunerType == null) { 1536ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko sBuiltInTunerType = 0; 1546ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko if (TvCustomizationManager.hasLinuxDvbBuiltInTuner(context) 1556ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko && DvbTunerHal.getNumberOfDevices(context) > 0) { 1566ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko sBuiltInTunerType = BUILT_IN_TUNER_TYPE_LINUX_DVB; 1576ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko } 1586ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko } 1596ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko return sBuiltInTunerType; 16065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 16165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 162ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko protected TunerHal(Context context) { 163ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko mIsStreaming = false; 164ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko mFrequency = -1; 165ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko mModulation = null; 166ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko } 167ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 168ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko protected boolean isStreaming() { 169ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko return mIsStreaming; 170ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko } 171ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 1726ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko protected void getDeliverySystemTypeFromDevice() { 1736ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko if (mDeliverySystemType == DELIVERY_SYSTEM_UNDEFINED) { 1746ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko mDeliverySystemType = nativeGetDeliverySystemType(getDeviceId()); 1756ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko } 1766ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko } 1776ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko 1786ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko /** 1796ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko * Returns {@code true} if this tuner HAL can be reused to save tuning time between channels 1806ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko * of the same frequency. 1816ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko */ 1826ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko public boolean isReusable() { 1836ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko return true; 1846ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko } 1856ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko 186ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko @Override 187ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko protected void finalize() throws Throwable { 188ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko super.finalize(); 189ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko close(); 190ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko } 191ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 192ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko protected native void nativeFinalize(long deviceId); 193ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 194ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko /** 195ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * Acquires the first available tuner device. If there is a tuner device that is available, the 196ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * tuner device will be locked to the current instance. 197ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * 198ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * @return {@code true} if the operation was successful, {@code false} otherwise 199ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko */ 200ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko protected abstract boolean openFirstAvailable(); 201ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 202ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko protected abstract boolean isDeviceOpen(); 203ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 204ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko protected abstract long getDeviceId(); 205ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 206ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko /** 207ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * Sets the tuner channel. This should be called after acquiring a tuner device. 208ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * 209ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * @param frequency a frequency of the channel to tune to 210ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * @param modulation a modulation method of the channel to tune to 2116ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko * @param channelNumber channel number when channel number is already known. Some tuner HAL 2126ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko * may use channelNumber instead of frequency for tune. 213ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * @return {@code true} if the operation was successful, {@code false} otherwise 214ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko */ 2156ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko public synchronized boolean tune(int frequency, @ModulationType String modulation, 2166ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko String channelNumber) { 217ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko if (!isDeviceOpen()) { 218ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko Log.e(TAG, "There's no available device"); 219ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko return false; 220ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko } 221ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko if (mIsStreaming) { 222ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko nativeCloseAllPidFilters(getDeviceId()); 223ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko mIsStreaming = false; 224ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko } 225ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 226ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko // When tuning to a new channel in the same frequency, there's no need to stop current tuner 227ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko // device completely and the only thing necessary for tuning is reopening pid filters. 228ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko if (mFrequency == frequency && Objects.equals(mModulation, modulation)) { 229ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko addPidFilter(PID_PAT, FILTER_TYPE_OTHER); 230ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko addPidFilter(PID_ATSC_SI_BASE, FILTER_TYPE_OTHER); 2316ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko if (isDvbDeliverySystem(mDeliverySystemType)) { 2326ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko addPidFilter(PID_DVB_SDT, FILTER_TYPE_OTHER); 2336ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko addPidFilter(PID_DVB_EIT, FILTER_TYPE_OTHER); 2346ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko } 235ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko mIsStreaming = true; 236ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko return true; 237ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko } 238ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko int timeout_ms = modulation.equals(MODULATION_8VSB) ? DEFAULT_VSB_TUNE_TIMEOUT_MS 239ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko : DEFAULT_QAM_TUNE_TIMEOUT_MS; 240ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko if (nativeTune(getDeviceId(), frequency, modulation, timeout_ms)) { 241ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko addPidFilter(PID_PAT, FILTER_TYPE_OTHER); 242ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko addPidFilter(PID_ATSC_SI_BASE, FILTER_TYPE_OTHER); 2436ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko if (isDvbDeliverySystem(mDeliverySystemType)) { 2446ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko addPidFilter(PID_DVB_SDT, FILTER_TYPE_OTHER); 2456ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko addPidFilter(PID_DVB_EIT, FILTER_TYPE_OTHER); 2466ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko } 247ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko mFrequency = frequency; 248ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko mModulation = modulation; 249ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko mIsStreaming = true; 250ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko return true; 251ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko } 252ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko return false; 253ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko } 254ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 255ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko protected native boolean nativeTune(long deviceId, int frequency, 256ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko @ModulationType String modulation, int timeout_ms); 257ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 258ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko /** 259ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * Sets a pid filter. This should be set after setting a channel. 260ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * 261ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * @param pid a pid number to be added to filter list 262ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * @param filterType a type of pid. Must be one of (FILTER_TYPE_XXX) 263ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * @return {@code true} if the operation was successful, {@code false} otherwise 264ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko */ 26565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public synchronized boolean addPidFilter(int pid, @FilterType int filterType) { 266ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko if (!isDeviceOpen()) { 267ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko Log.e(TAG, "There's no available device"); 268ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko return false; 269ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko } 270ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko if (pid >= 0 && pid <= 0x1fff) { 271ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko nativeAddPidFilter(getDeviceId(), pid, filterType); 272ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko return true; 273ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko } 274ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko return false; 275ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko } 276ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 277ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko protected native void nativeAddPidFilter(long deviceId, int pid, @FilterType int filterType); 278ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko protected native void nativeCloseAllPidFilters(long deviceId); 27965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko protected native void nativeSetHasPendingTune(long deviceId, boolean hasPendingTune); 2806ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko protected native int nativeGetDeliverySystemType(long deviceId); 281ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 282ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko /** 283ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * Stops current tuning. The tuner device and pid filters will be reset by this call and make 284ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * the tuner ready to accept another tune request. 285ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko */ 28665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public synchronized void stopTune() { 287ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko if (isDeviceOpen()) { 288ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko if (mIsStreaming) { 289ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko nativeCloseAllPidFilters(getDeviceId()); 290ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko } 291ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko nativeStopTune(getDeviceId()); 292ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko } 293ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko mIsStreaming = false; 294ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko mFrequency = -1; 295ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko mModulation = null; 296ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko } 297ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 29865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public void setHasPendingTune(boolean hasPendingTune) { 29965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko nativeSetHasPendingTune(getDeviceId(), hasPendingTune); 30065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko } 30165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko 3026ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko public int getDeliverySystemType() { 3036ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko return mDeliverySystemType; 3046ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko } 3056ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko 306ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko protected native void nativeStopTune(long deviceId); 307ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 308ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko /** 309ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * This method must be called after {@link TunerHal#tune} and before 31065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * {@link TunerHal#stopTune}. Writes at most maxSize TS frames in a buffer 311ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * provided by the user. The frames employ MPEG encoding. 312ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * 313ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * @param javaBuffer a buffer to write the video data in 314ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * @param javaBufferSize the max amount of bytes to write in this buffer. Usually this number 315ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * should be equal to the length of the buffer. 316ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * @return the amount of bytes written in the buffer. Note that this value could be 0 if no new 317ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * frames have been obtained since the last call. 318ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko */ 31965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko public synchronized int readTsStream(byte[] javaBuffer, int javaBufferSize) { 320ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko if (isDeviceOpen()) { 321ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko return nativeWriteInBuffer(getDeviceId(), javaBuffer, javaBufferSize); 322ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko } else { 323ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko return 0; 324ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko } 325ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko } 326ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 327ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko protected native int nativeWriteInBuffer(long deviceId, byte[] javaBuffer, int javaBufferSize); 328ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 329ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko /** 330ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * Opens Linux DVB frontend device. This method is called from native JNI and used only for 3316ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko * DvbTunerHal. 332ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko */ 333ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko protected int openDvbFrontEndFd() { 334ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko return -1; 335ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko } 336ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 337ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko /** 338ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * Opens Linux DVB demux device. This method is called from native JNI and used only for 3396ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko * DvbTunerHal. 340ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko */ 341ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko protected int openDvbDemuxFd() { 342ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko return -1; 343ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko } 344ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko 345ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko /** 346ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko * Opens Linux DVB dvr device. This method is called from native JNI and used only for 3476ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko * DvbTunerHal. 348ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko */ 349ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko protected int openDvbDvrFd() { 350ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko return -1; 351ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko } 352ba5845f23b8fbc985890f892961abc8b39886611Nick Chalko} 353