00001
00008 #include "mythcontext.h"
00009 #include "tv_rec.h"
00010 #include "linuxfirewiredevice.h"
00011 #include "darwinfirewiredevice.h"
00012 #include "firewirechannel.h"
00013
00014 #define LOC QString("FireChan(%1): ").arg(GetDevice())
00015 #define LOC_WARN QString("FireChan(%1), Warning: ").arg(GetDevice())
00016 #define LOC_ERR QString("FireChan(%1), Error: ").arg(GetDevice())
00017
00018 FirewireChannel::FirewireChannel(TVRec *parent, const QString &_videodevice,
00019 const FireWireDBOptions &firewire_opts) :
00020 DTVChannel(parent),
00021 videodevice(_videodevice),
00022 fw_opts(firewire_opts),
00023 device(NULL),
00024 current_channel(0),
00025 isopen(false)
00026 {
00027 uint64_t guid = string_to_guid(videodevice);
00028 uint subunitid = 0;
00029
00030 #ifdef USING_LINUX_FIREWIRE
00031 device = new LinuxFirewireDevice(
00032 guid, subunitid, fw_opts.speed,
00033 LinuxFirewireDevice::kConnectionP2P == (uint) fw_opts.connection);
00034 #endif // USING_LINUX_FIREWIRE
00035
00036 #ifdef USING_OSX_FIREWIRE
00037 device = new DarwinFirewireDevice(guid, subunitid, fw_opts.speed);
00038 #endif // USING_OSX_FIREWIRE
00039
00040 InitializeInputs();
00041 }
00042
00043 bool FirewireChannel::SetChannelByString(const QString &channum)
00044 {
00045 QString loc = LOC + QString("SetChannelByString(%1)").arg(channum);
00046 VERBOSE(VB_CHANNEL, loc);
00047
00048 InputMap::const_iterator it = inputs.find(currentInputID);
00049 if (it == inputs.end())
00050 return false;
00051
00052 uint mplexid_restriction;
00053 if (!IsInputAvailable(currentInputID, mplexid_restriction))
00054 {
00055 VERBOSE(VB_IMPORTANT, loc + " " + QString(
00056 "Requested channel '%1' is on input '%2' "
00057 "which is in a busy input group")
00058 .arg(channum).arg(currentInputID));
00059
00060 return false;
00061 }
00062
00063
00064 QString tvformat, modulation, freqtable, freqid, dtv_si_std;
00065 int finetune;
00066 uint64_t frequency;
00067 int mpeg_prog_num;
00068 uint atsc_major, atsc_minor, mplexid, tsid, netid;
00069
00070 if (!ChannelUtil::GetChannelData(
00071 (*it)->sourceid, channum,
00072 tvformat, modulation, freqtable, freqid,
00073 finetune, frequency,
00074 dtv_si_std, mpeg_prog_num, atsc_major, atsc_minor, tsid, netid,
00075 mplexid, commfree))
00076 {
00077 VERBOSE(VB_IMPORTANT, loc + " " + QString(
00078 "Requested channel '%1' is on input '%2' "
00079 "which is in a busy input group")
00080 .arg(channum).arg(currentInputID));
00081
00082 return false;
00083 }
00084
00085 if (mplexid_restriction && (mplexid != mplexid_restriction))
00086 {
00087 VERBOSE(VB_IMPORTANT, loc + " " + QString(
00088 "Requested channel '%1' is not available because "
00089 "the tuner is currently in use on another transport.")
00090 .arg(channum));
00091
00092 return false;
00093 }
00094
00095 bool ok = false;
00096 if (!(*it)->externalChanger.isEmpty())
00097 {
00098 ok = ChangeExternalChannel(freqid);
00099 SetSIStandard("mpeg");
00100 SetDTVInfo(0,0,0,0,1);
00101 }
00102 else
00103 {
00104 uint ichan = freqid.toUInt(&ok);
00105 ok = ok && isopen && SetChannelByNumber(ichan);
00106 }
00107
00108 if (ok)
00109 {
00110
00111 curchannelname = QDeepCopy<QString>(channum);
00112 (*it)->startChanNum = QDeepCopy<QString>(channum);
00113 }
00114
00115 VERBOSE(VB_CHANNEL, loc + " " + ((ok) ? "success" : "failure"));
00116
00117 return ok;
00118 }
00119
00120 bool FirewireChannel::Open(void)
00121 {
00122 VERBOSE(VB_CHANNEL, LOC + "Open()");
00123
00124 if (inputs.find(currentInputID) == inputs.end())
00125 return false;
00126
00127 if (!device)
00128 return false;
00129
00130 if (isopen)
00131 return true;
00132
00133 InputMap::const_iterator it = inputs.find(currentInputID);
00134 if (!FirewireDevice::IsSTBSupported(fw_opts.model) &&
00135 (*it)->externalChanger.isEmpty())
00136 {
00137 VERBOSE(VB_IMPORTANT, LOC_ERR +
00138 QString("Model: '%1' is not supported.").arg(fw_opts.model));
00139
00140 return false;
00141 }
00142
00143 if (!device->OpenPort())
00144 return false;
00145
00146 isopen = true;
00147
00148 return true;
00149 }
00150
00151 void FirewireChannel::Close(void)
00152 {
00153 VERBOSE(VB_CHANNEL, LOC + "Close()");
00154 if (isopen)
00155 {
00156 device->ClosePort();
00157 isopen = false;
00158 }
00159 }
00160
00161 QString FirewireChannel::GetDevice(void) const
00162 {
00163 return videodevice;
00164 }
00165
00166 bool FirewireChannel::SetPowerState(bool on)
00167 {
00168 if (!isopen)
00169 {
00170 VERBOSE(VB_IMPORTANT, LOC_ERR +
00171 "SetPowerState() called on closed FirewireChannel.");
00172
00173 return false;
00174 }
00175
00176 return device->SetPowerState(on);
00177 }
00178
00179 FirewireDevice::PowerState FirewireChannel::GetPowerState(void) const
00180 {
00181 if (!isopen)
00182 {
00183 VERBOSE(VB_IMPORTANT, LOC_ERR +
00184 "GetPowerState() called on closed FirewireChannel.");
00185
00186 return FirewireDevice::kAVCPowerQueryFailed;
00187 }
00188
00189 return device->GetPowerState();
00190 }
00191
00192 bool FirewireChannel::Retune(void)
00193 {
00194 VERBOSE(VB_CHANNEL, LOC + "Retune()");
00195
00196 if (FirewireDevice::kAVCPowerOff == GetPowerState())
00197 {
00198 VERBOSE(VB_IMPORTANT, LOC_ERR +
00199 "STB is turned off, must be on to retune.");
00200
00201 return false;
00202 }
00203
00204 if (current_channel)
00205 return SetChannelByNumber(current_channel);
00206
00207 return false;
00208 }
00209
00210 bool FirewireChannel::SetChannelByNumber(int channel)
00211 {
00212 VERBOSE(VB_CHANNEL, QString("SetChannelByNumber(%1)").arg(channel));
00213 current_channel = channel;
00214
00215 if (FirewireDevice::kAVCPowerOff == GetPowerState())
00216 {
00217 VERBOSE(VB_IMPORTANT, LOC_WARN +
00218 "STB is turned off, must be on to set channel.");
00219
00220 SetSIStandard("mpeg");
00221 SetDTVInfo(0,0,0,0,1);
00222
00223 return true;
00224 }
00225
00226 if (!device->SetChannel(fw_opts.model, 0, channel))
00227 return false;
00228
00229 SetSIStandard("mpeg");
00230 SetDTVInfo(0,0,0,0,1);
00231
00232 return true;
00233 }