00001
00007
00008 #include <unistd.h>
00009 #include <sys/types.h>
00010 #ifndef USING_MINGW
00011 #include <sys/socket.h>
00012 #include <netinet/in.h>
00013 #include <arpa/inet.h>
00014 #include <netdb.h>
00015 #endif
00016 #include <sys/time.h>
00017 #include <fcntl.h>
00018
00019
00020 #include <algorithm>
00021 using namespace std;
00022
00023
00024 #include "mythdbcon.h"
00025 #include "mythlogging.h"
00026 #include "hdhrchannel.h"
00027 #include "videosource.h"
00028 #include "channelutil.h"
00029 #include "hdhrstreamhandler.h"
00030
00031 #define LOC QString("HDHRChan(%1): ").arg(GetDevice())
00032
00033 HDHRChannel::HDHRChannel(TVRec *parent, const QString &device)
00034 : DTVChannel(parent),
00035 _device_id(device),
00036 _stream_handler(NULL)
00037 {
00038 RegisterForMaster(_device_id);
00039 }
00040
00041 HDHRChannel::~HDHRChannel(void)
00042 {
00043 Close();
00044 DeregisterForMaster(_device_id);
00045 }
00046
00047 bool HDHRChannel::IsMaster(void) const
00048 {
00049 DTVChannel *master = DTVChannel::GetMasterLock(_device_id);
00050 bool is_master = (master == static_cast<const DTVChannel*>(this));
00051 DTVChannel::ReturnMasterLock(master);
00052 return is_master;
00053 }
00054
00055 bool HDHRChannel::Open(void)
00056 {
00057 LOG(VB_CHANNEL, LOG_INFO, LOC + "Opening HDHR channel");
00058
00059 if (IsOpen())
00060 return true;
00061
00062 _stream_handler = HDHRStreamHandler::Get(_device_id);
00063
00064 _tuner_types = _stream_handler->GetTunerTypes();
00065 tunerType = (_tuner_types.empty()) ?
00066 DTVTunerType::kTunerTypeUnknown : (int) _tuner_types[0];
00067
00068 if (!InitializeInputs())
00069 {
00070 Close();
00071 return false;
00072 }
00073
00074 return _stream_handler->IsConnected();
00075 }
00076
00077 void HDHRChannel::Close(void)
00078 {
00079 LOG(VB_CHANNEL, LOG_INFO, LOC + "Closing HDHR channel");
00080
00081 if (!IsOpen())
00082 return;
00083
00084 HDHRStreamHandler::Return(_stream_handler);
00085 }
00086
00087 bool HDHRChannel::EnterPowerSavingMode(void)
00088 {
00089 if (IsOpen())
00090 return _stream_handler->EnterPowerSavingMode();
00091 else
00092 return true;
00093 }
00094
00095 bool HDHRChannel::IsOpen(void) const
00096 {
00097 return _stream_handler;
00098 }
00099
00101 bool HDHRChannel::Tune(const QString &freqid, int )
00102 {
00103 return _stream_handler->TuneVChannel(freqid);
00104 }
00105
00106 static QString format_modulation(const DTVMultiplex &tuning)
00107 {
00108 if (DTVModulation::kModulationQAM256 == tuning.modulation)
00109 return "qam256";
00110 else if (DTVModulation::kModulationQAM128 == tuning.modulation)
00111 return "qam128";
00112 else if (DTVModulation::kModulationQAM64 == tuning.modulation)
00113 return "qam64";
00114 else if (DTVModulation::kModulationQAM16 == tuning.modulation)
00115 return "qam16";
00116 else if (DTVModulation::kModulationDQPSK == tuning.modulation)
00117 return "qpsk";
00118 else if (DTVModulation::kModulation8VSB == tuning.modulation)
00119 return "8vsb";
00120
00121 return "auto";
00122 }
00123
00124 static QString format_dvbt(const DTVMultiplex &tuning, const QString &mod)
00125 {
00126 const QChar b = tuning.bandwidth.toChar();
00127
00128 if ((QChar('a') == b) || (mod == "auto"))
00129 return "auto";
00130 else if (QChar('a') != b)
00131 return QString("t%1%2").arg(b).arg(mod);
00132
00133 return QString("auto%1t").arg(b);
00134 }
00135
00136 static QString format_dvbc(const DTVMultiplex &tuning, const QString &mod)
00137 {
00138 const QChar b = tuning.bandwidth.toChar();
00139
00140 if ((QChar('a') == b) || (mod == "auto"))
00141 return "auto";
00142 else if ((QChar('a') != b) && (tuning.symbolrate > 0))
00143 return QString("a%1%2-%3")
00144 .arg(b).arg(mod).arg(tuning.symbolrate/1000);
00145
00146 return QString("auto%1c").arg(b);
00147 }
00148
00149 static QString get_tune_spec(
00150 const DTVTunerType &tunerType, const DTVMultiplex &tuning)
00151 {
00152 const QString mod = format_modulation(tuning);
00153
00154 if (DTVTunerType::kTunerTypeATSC == tunerType)
00155
00156 return (mod == "auto") ? "qam" : mod;
00157 else if (DTVTunerType::kTunerTypeDVBC == tunerType)
00158 return format_dvbc(tuning, mod);
00159 else if (DTVTunerType::kTunerTypeDVBT == tunerType)
00160 return format_dvbt(tuning, mod);
00161
00162 return "auto";
00163 }
00164
00165 bool HDHRChannel::Tune(const DTVMultiplex &tuning, QString )
00166 {
00167 QString spec = get_tune_spec(tunerType, tuning);
00168 QString chan = QString("%1:%2").arg(spec).arg(tuning.frequency);
00169
00170 LOG(VB_CHANNEL, LOG_INFO, LOC + "Tuning to " + chan);
00171
00172 if (_stream_handler->TuneChannel(chan))
00173 {
00174 SetSIStandard(tuning.sistandard);
00175 return true;
00176 }
00177
00178 return false;
00179 }
00180
00181 bool HDHRChannel::SetChannelByString(const QString &channum)
00182 {
00183 bool ok = DTVChannel::SetChannelByString(channum);
00184
00185
00186
00187
00188 if (!ok && DTVTunerType::kTunerTypeDVBT == tunerType)
00189 {
00190 bool has_dvbc = false, has_dvbt = false;
00191 vector<DTVTunerType>::const_iterator it = _tuner_types.begin();
00192 for (; it != _tuner_types.end(); ++it)
00193 {
00194 has_dvbt |= (DTVTunerType::kTunerTypeDVBT == *it);
00195 has_dvbc |= (DTVTunerType::kTunerTypeDVBC == *it);
00196 }
00197
00198 if (has_dvbt && has_dvbc)
00199 {
00200 tunerType = DTVTunerType::kTunerTypeDVBC;
00201 ok = DTVChannel::SetChannelByString(channum);
00202 if (!ok)
00203 {
00204 tunerType = DTVTunerType::kTunerTypeDVBT;
00205 return false;
00206 }
00207 }
00208 }
00209
00210
00211 return ok;
00212 }