MythTV  0.26-pre
hdhrchannel.cpp
Go to the documentation of this file.
00001 
00007 // C includes
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 // C++ includes
00020 #include <algorithm>
00021 using namespace std;
00022 
00023 // MythTV includes
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; // this caller didn't have it open in the first place..
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 /*finetune*/)
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"; // uses bandwidth from channel map
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"; // uses bandwidth from channel map
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         // old atsc firmware does no recognize "auto"
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 /*inputname*/)
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     // HACK HACK HACK -- BEGIN
00186     // if the DTVTunerType were specified in tuning we wouldn't
00187     // need to try alternative tuning...
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     // HACK HACK HACK -- END
00210 
00211     return ok;
00212 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends