Permalink
Browse files

Support Internal Firewire channel change with analog capture.

Allows one to specify "Internal" (minus quotes) as the channel change command.  Will then use MythTV's internal firewire device control to change the channels.

Adds two new DB fields in cardinput, one for changer device (The GUID for the box, exactly as specified when one sets up a firewire tuner (no 0x)) and the changer model, also exactly as specified for a firewire capture device (I use "MOTO GENERIC" without quotes).

I am not committing a UI for the GUID and model portions of this.  I have one, but figuring out how to get the dropdown for GUID and Model to appear only when an internal channel change is configured has so far escaped me.

I've been using this for a few weeks with perfect function.  This should be a nice way for new users of HD-PVRs, ivtv, framegrabbers, etc. to configure channel change without having to bother with a script.
  • Loading branch information...
1 parent bececaa commit d49f3f22dbf7aae97478875e2a46b176eea70407 Robert McNamara committed Sep 17, 2011
@@ -114,7 +114,7 @@ package MythTV;
# schema version supported in the main code. We need to check that the schema
# version in the database is as expected by the bindings, which are expected
# to be kept in sync with the main code.
- our $SCHEMA_VERSION = "1281";
+ our $SCHEMA_VERSION = "1282";
# NUMPROGRAMLINES is defined in mythtv/libs/libmythtv/programinfo.h and is
# the number of items in a ProgramInfo QStringList group used by
@@ -5,7 +5,7 @@
"""
OWN_VERSION = (0,25,-1,2)
-SCHEMA_VERSION = 1281
+SCHEMA_VERSION = 1282
NVSCHEMA_VERSION = 1007
MUSICSCHEMA_VERSION = 1018
PROTO_VERSION = '69'
@@ -51,7 +51,7 @@
* MythTV Python Bindings
* mythtv/bindings/python/MythTV/static.py
*/
-#define MYTH_DATABASE_VERSION "1281"
+#define MYTH_DATABASE_VERSION "1282"
MBASE_PUBLIC const char *GetMythSourceVersion();
@@ -890,6 +890,40 @@ vector<uint> CardUtil::GetCloneCardIDs(uint cardid)
return list;
}
+QString CardUtil::GetFirewireChangerNode(uint inputid)
+{
+ QString fwnode;
+
+ MSqlQuery query(MSqlQuery::InitCon());
+ query.prepare("SELECT changer_device "
+ "FROM cardinput WHERE cardinputid = :INPUTID ");
+ query.bindValue(":CARDID", inputid);
+
+ if (query.exec() && query.next())
+ {
+ fwnode = query.value(0).toString();
+ }
+
+ return fwnode;
+}
+
+QString CardUtil::GetFirewireChangerModel(uint inputid)
+{
+ QString fwnode;
+
+ MSqlQuery query(MSqlQuery::InitCon());
+ query.prepare("SELECT changer_model "
+ "FROM cardinput WHERE cardinputid = :INPUTID ");
+ query.bindValue(":CARDID", inputid);
+
+ if (query.exec() && query.next())
+ {
+ fwnode = query.value(0).toString();
+ }
+
+ return fwnode;
+}
+
vector<uint> CardUtil::GetCardIDs(uint sourceid)
{
MSqlQuery query(MSqlQuery::InitCon());
@@ -278,6 +278,8 @@ class MTV_PUBLIC CardUtil
// Other
static bool CloneCard(uint src_cardid, uint dst_cardid);
static vector<uint> GetCloneCardIDs(uint cardid);
+ static QString GetFirewireChangerNode(uint inputid);
+ static QString GetFirewireChangerModel(uint inputid);
// DTV info
static bool GetTimeouts(uint cardid,
@@ -17,6 +17,12 @@ using namespace std;
#include <QCoreApplication>
// MythTV headers
+#ifdef USING_OSX_FIREWIRE
+#include "darwinfirewiredevice.h"
+#endif
+#ifdef USING_LINUX_FIREWIRE
+#include "linuxfirewiredevice.h"
+#endif
#include "firewirechannel.h"
#include "mythcorecontext.h"
#include "dummychannel.h"
@@ -694,14 +700,75 @@ void ChannelBase::HandleScript(const QString &freqid)
}
else
{
- ok = ChangeExternalChannel((*it)->externalChanger, freqid);
- if (!ok)
+ if ((*it)->externalChanger.toLower() == "internal")
{
- LOG(VB_GENERAL, LOG_ERR, LOC + "Can not execute channel changer.");
- m_system_status = 2; // failed
+ ok = ChangeInternalChannel(freqid, (*it)->inputid);
+ if (!ok)
+ {
+ LOG(VB_GENERAL, LOG_ERR, LOC + "Can not execute internal channel "
+ "changer.");
+ m_system_status = 2; // failed
+ }
+ else
+ m_system_status = 3; // success
+
HandleScriptEnd(ok);
}
+ else
+ {
+ ok = ChangeExternalChannel((*it)->externalChanger, freqid);
+ if (!ok)
+ {
+ LOG(VB_GENERAL, LOG_ERR, LOC + "Can not execute channel changer.");
+ m_system_status = 2; // failed
+ HandleScriptEnd(ok);
+ }
+ }
+ }
+}
+
+bool ChannelBase::ChangeInternalChannel(const QString &freqid,
+ uint inputid)
+{
+#ifdef USING_FIREWIRE
+ FirewireDevice *device = NULL;
+ QString fwnode = CardUtil::GetFirewireChangerNode(inputid);
+ uint64_t guid = string_to_guid(fwnode);
+ QString fwmodel = CardUtil::GetFirewireChangerModel(inputid);
+
+ LOG(VB_GENERAL, LOG_ERR, LOC + QString("Internal channel change to %1 "
+ "on inputid %2, GUID %3 (%4)").arg(freqid).arg(inputid)
+ .arg(fwnode).arg(fwmodel));
+
+#ifdef USING_LINUX_FIREWIRE
+ device = new LinuxFirewireDevice(
+ guid, 0, 100, 1);
+#endif // USING_LINUX_FIREWIRE
+
+#ifdef USING_OSX_FIREWIRE
+ device = new DarwinFirewireDevice(guid, 0, 100);
+#endif // USING_OSX_FIREWIRE
+
+ if (!device)
+ return false;
+
+ if (!device->OpenPort())
+ return false;
+
+ if (!device->SetChannel(fwmodel, 0, freqid.toUInt()))
+ {
+ device->ClosePort();
+ delete device;
+ device = NULL;
+ return false;
}
+
+ device->ClosePort();
+ delete device;
+ device = NULL;
+ return true;
+#endif
+ return false;
}
/// \note m_system_lock must be held when this is called
@@ -153,6 +153,8 @@ class ChannelBase
bool ChangeExternalChannel(const QString &changer,
const QString &newchan);
+ bool ChangeInternalChannel(const QString &newchan,
+ uint cardinputid);
TVRec *m_pParent;
QString m_curchannelname;
@@ -5866,6 +5866,19 @@ NULL
return false;
}
+ if (dbver == "1281")
+ {
+ const char *updates[] = {
+"ALTER TABLE cardinput ADD changer_device VARCHAR(128) "
+"AFTER externalcommand;",
+"ALTER TABLE cardinput ADD changer_model VARCHAR(128) "
+"AFTER changer_device;",
+NULL
+};
+ if (!performActualUpdate(updates, "1282", dbver))
+ return false;
+ }
+
return true;
}

0 comments on commit d49f3f2

Please sign in to comment.