[mythtv] [patch] firewire mpeg2ts input

Jim Westfall jwestfall at surrealistic.net
Wed Feb 2 01:16:03 UTC 2005


Attached is a patch that enables firewire mpeg2ts as a valid input in 
linux (x86/ppc).  Its been tested on set top models DCT-6200 and SA 3250 
thus far.  I would appreciate additional testers and any feed back.

following libs and versions are required to use the patch:

libraw1394 version 1.1.0+ (www.linux1394.org)
libiec61883 svn revision 49+ (svn://svn.linux1394.org/libiec61883)

The patch is against cvs from last night, so it should apply 
without much trouble.  Once applied edit settings.pro to enable 
firewire support.

The patch only supports external channel changing at this point, but most 
everything (livetv/recording/ff/etc) else should be working.

thanks
Jim Westfall

-------------- next part --------------
diff -urN --exclude='config.*' --exclude='Makefile*' --exclude='*.o' --exclude='*.so' --exclude='moc*' mythtv.orig/libs/libmythtv/dbcheck.cpp mythtv/libs/libmythtv/dbcheck.cpp
--- mythtv.orig/libs/libmythtv/dbcheck.cpp	2005-01-30 15:25:12.000000000 -0800
+++ mythtv/libs/libmythtv/dbcheck.cpp	2005-01-31 12:28:18.000000000 -0800
@@ -8,7 +8,7 @@
 
 #include "mythcontext.h"
 
-const QString currentDatabaseVersion = "1065";
+const QString currentDatabaseVersion = "1066";
 
 void UpdateDBVersionNumber(const QString &newnumber)
 {
@@ -1218,8 +1218,25 @@
 ""
 };
         performActualUpdate(updates, "1065", dbver);
+
     }
 
+ 
+  
+    if (dbver == "1065") {
+        const QString updates[] = {
+"INSERT INTO profilegroups SET name = 'FireWire Input', cardtype = 'FIREWIRE', is_default = 1;",
+"ALTER TABLE capturecard ADD COLUMN firewire_port INT UNSIGNED NOT NULL DEFAULT 0;",
+"ALTER TABLE capturecard ADD COLUMN firewire_node INT UNSIGNED NOT NULL DEFAULT 2;",
+"ALTER TABLE capturecard ADD COLUMN firewire_speed INT UNSIGNED NOT NULL DEFAULT 0;",
+"ALTER TABLE capturecard ADD COLUMN firewire_model varchar(32) default NULL;",
+""
+};
+        performActualUpdate(updates, "1066", dbver);
+    } 
+ 
+
+
 }
 
 void InitializeDatabase(void)
diff -urN --exclude='config.*' --exclude='Makefile*' --exclude='*.o' --exclude='*.so' --exclude='moc*' mythtv.orig/libs/libmythtv/firewirechannel.cpp mythtv/libs/libmythtv/firewirechannel.cpp
--- mythtv.orig/libs/libmythtv/firewirechannel.cpp	1969-12-31 16:00:00.000000000 -0800
+++ mythtv/libs/libmythtv/firewirechannel.cpp	2005-01-31 12:26:29.000000000 -0800
@@ -0,0 +1,59 @@
+/**
+ *  FirewireChannel
+ *  Copyright (c) 2005 by Jim Westfall
+ *  Distributed as part of MythTV under GPL v2 and later.
+ */
+
+
+#include <iostream>
+#include "mythcontext.h"
+#include "firewirechannel.h"
+
+class TVRec;
+
+
+FirewireChannel::FirewireChannel(TVRec *parent): ChannelBase(parent) {
+    capchannels = 1;
+    channelnames[0] = "MPEG2TS";
+}
+
+FirewireChannel::~FirewireChannel(void)
+{   
+}
+
+bool FirewireChannel::SetChannelByString(const QString &chan) {
+
+
+     inputChannel[currentcapchannel] = chan;
+     curchannelname = chan;
+
+     if (externalChanger[currentcapchannel].isEmpty()) {
+         VERBOSE(VB_IMPORTANT,QString("FireWire: external channel changer only supported at this time.")); 
+     } else if(!ChangeExternalChannel(chan)) {
+         return false;
+     }
+     return true;
+}
+
+bool FirewireChannel::Open() {
+    SetExternalChanger();
+    return true;
+}
+void FirewireChannel::Close() {
+
+}
+    
+void FirewireChannel::SwitchToInput(const QString &input, const QString &chan)
+{
+    currentcapchannel = 0;
+    if (channelnames.empty())
+       channelnames[currentcapchannel] = input;
+
+    SetChannelByString(chan);
+}
+
+void FirewireChannel::SetExternalChanger(void) {
+	
+     pParent->RetrieveInputChannels(inputChannel, inputTuneTo,
+                                       externalChanger, sourceid);
+}
diff -urN --exclude='config.*' --exclude='Makefile*' --exclude='*.o' --exclude='*.so' --exclude='moc*' mythtv.orig/libs/libmythtv/firewirechannel.h mythtv/libs/libmythtv/firewirechannel.h
--- mythtv.orig/libs/libmythtv/firewirechannel.h	1969-12-31 16:00:00.000000000 -0800
+++ mythtv/libs/libmythtv/firewirechannel.h	2005-01-31 12:26:29.000000000 -0800
@@ -0,0 +1,33 @@
+/**
+ *  FirewireChannel
+ *  Copyright (c) 2005 by Jim Westfall
+ *  Distributed as part of MythTV under GPL v2 and later.
+ */
+
+
+#ifndef FIREWIRECHANNEL_H
+#define FIREWIRECHANNEL_H
+
+#include <qstring.h>
+#include "tv_rec.h"
+#include "channelbase.h"
+
+using namespace std;
+
+class FirewireChannel : public ChannelBase
+{
+ public:
+    FirewireChannel(TVRec *parent);
+    ~FirewireChannel(void);
+
+    bool SetChannelByString(const QString &chan);
+    bool Open();
+    void Close();
+    void SwitchToInput(const QString &inputname, const QString &chan);
+    void SwitchToInput(int newcapchannel, bool setstarting)
+                      { (void)newcapchannel; (void)setstarting; }
+    void SetExternalChanger(void);
+
+};
+
+#endif
diff -urN --exclude='config.*' --exclude='Makefile*' --exclude='*.o' --exclude='*.so' --exclude='moc*' mythtv.orig/libs/libmythtv/firewirerecorder.cpp mythtv/libs/libmythtv/firewirerecorder.cpp
--- mythtv.orig/libs/libmythtv/firewirerecorder.cpp	1969-12-31 16:00:00.000000000 -0800
+++ mythtv/libs/libmythtv/firewirerecorder.cpp	2005-01-31 13:12:38.000000000 -0800
@@ -0,0 +1,230 @@
+/**
+ *  FirewireRecorder
+ *  Copyright (c) 2005 by Jim Westfall
+ *  Distributed as part of MythTV under GPL v2 and later.
+ */
+
+#include <iostream>
+using namespace std;
+
+#include <pthread.h>
+#include "RingBuffer.h"
+#include "mythcontext.h"
+#include "firewirerecorder.h"
+#include "mpeg/tspacket.h"
+#include <sys/select.h>
+
+// callback function for libiec61883
+int read_tspacket (unsigned char *tspacket, int len, unsigned int dropped, void *callback_data) {
+
+     FirewireRecorder *fw = (FirewireRecorder*)callback_data;
+     if(!fw) return 0;
+
+     if(dropped) {
+         VERBOSE(VB_GENERAL,QString("FireWire: %1 packet(s) dropped.").arg(dropped));
+     }
+     fw->ProcessTSPacket(tspacket,len);
+     return 1;
+}
+
+
+FirewireRecorder::FirewireRecorder() {
+
+    isopen = false;
+    fwchannel = -1;
+    fwbandwidth = -1;
+    fwport = -1;
+    fwnode = 0;
+    fwspeed = -1;
+    fwhandle = NULL;
+    fwmpeg = NULL;
+    fwfd = -1;
+           
+}
+
+FirewireRecorder::~FirewireRecorder() {
+
+    if(isopen) {
+        VERBOSE(VB_GENERAL,QString("FireWire: releasing iec61883_mpeg2 object"));
+        iec61883_mpeg2_close(fwmpeg);
+        if(fwchannel > -1) {
+              VERBOSE(VB_GENERAL,QString("FireWire: disconnecting channel %1").arg(fwchannel));
+	      iec61883_cmp_disconnect (fwhandle, fwnode | 0xffc0,
+                   raw1394_get_local_id (fwhandle), fwchannel, fwbandwidth);
+        }
+        VERBOSE(VB_GENERAL,QString("FireWire: releasing raw1394 handle"));
+        raw1394_destroy_handle(fwhandle);
+    }    
+    isopen = false;
+}
+
+bool FirewireRecorder::Open() {
+
+     if(isopen)
+         return true;
+    
+     VERBOSE(VB_GENERAL,QString("FireWire: Initializing Port: %1, Node: %2, Speed: %3")
+                               .arg(fwport)
+                               .arg(fwnode)
+                               .arg(FirewireSpeedString(fwspeed)));
+
+     if((fwhandle = raw1394_new_handle_on_port(fwport)) == NULL) {
+         VERBOSE(VB_IMPORTANT, QString("Firewire: unable to get handle for port: %1, bailing").arg(fwport));
+         perror("firewire port");
+         return false;
+     }
+
+     fwchannel = iec61883_cmp_connect (fwhandle, fwnode | 0xffc0,
+                        raw1394_get_local_id (fwhandle), &fwbandwidth);
+
+     if(fwchannel > -1) {
+	VERBOSE(VB_GENERAL,QString("FireWire: Created Channel: %1, Bandwidth Allocation: %2").arg(fwchannel).arg(fwbandwidth));
+     }
+
+     if((fwmpeg = iec61883_mpeg2_recv_init (fwhandle, read_tspacket, this)) == NULL) {
+         VERBOSE(VB_IMPORTANT, QString("Firewire: unable to init iec61883_mpeg2 object, bailing"));
+         perror("iec61883_mpeg2 object");
+ 
+         // release raw1394 object;
+	 raw1394_destroy_handle(fwhandle);
+         return false;
+     }
+     
+     // set speed if needed
+     // probably shouldnt even allow user to set, 100Mbps should be more the enough
+     int curspeed = iec61883_mpeg2_get_speed(fwmpeg);
+     if(curspeed != fwspeed) {
+         VERBOSE(VB_GENERAL,QString("FireWire: Changing Speed %1 -> %2")
+                                    .arg(FirewireSpeedString(curspeed))
+                                    .arg(FirewireSpeedString(fwspeed)));
+         iec61883_mpeg2_set_speed(fwmpeg, fwspeed);
+         if(fwspeed != iec61883_mpeg2_get_speed(fwmpeg)) {
+              VERBOSE(VB_IMPORTANT, QString("Firewire: unable to set firewire speed, continuing"));
+         }
+     }
+     
+     isopen = true;
+     fwfd = raw1394_get_fd(fwhandle); 
+     return true;
+}
+
+void FirewireRecorder::StartRecording(void) {
+
+    struct timeval tv;
+    fd_set rfds;
+  
+    VERBOSE(VB_RECORD, QString("StartRecording"));
+
+    if (!Open()) {
+        _error = true;        
+        return;
+    }
+
+    _request_recording = true;
+    _recording = true;
+   
+    iec61883_mpeg2_recv_start(fwmpeg,fwchannel);
+    lastpacket = time(NULL);
+    while(_request_recording) {
+       if(_request_pause) {
+            if(!_paused) {
+                 // stop mpeg
+                 iec61883_mpeg2_recv_stop(fwmpeg);
+                  _paused = true;
+            }
+            pauseWait.wakeAll();
+
+            usleep(1000);
+            continue;
+
+       } else if(!_request_pause && _paused) {
+            _paused = false;
+            iec61883_mpeg2_recv_start(fwmpeg,fwchannel);
+            lastpacket = time(NULL);
+       }
+
+       if(time(NULL) - lastpacket > FIREWIRE_TIMEOUT) {
+            VERBOSE(VB_IMPORTANT, QString("Firewire: No Input in %1 seconds [P:%2 N:%3] (time)").arg(FIREWIRE_TIMEOUT).arg(fwport).arg(fwnode));
+            iec61883_mpeg2_recv_stop(fwmpeg);
+            _error = true;
+            return;
+       }
+
+       FD_ZERO (&rfds);
+       FD_SET (fwfd, &rfds);
+       tv.tv_sec = FIREWIRE_TIMEOUT;
+
+       if(select (fwfd + 1, &rfds, NULL, NULL, &tv) > 0) {
+            if(raw1394_loop_iterate(fwhandle) != 0) {
+                 VERBOSE(VB_IMPORTANT, "Firewire: libraw1394_loop_iterate() returned error.");
+                 iec61883_mpeg2_recv_stop(fwmpeg);
+                 _error = true;
+	         return;	
+            }
+       } else { 
+            VERBOSE(VB_IMPORTANT, QString("Firewire: No Input in %1 seconds [P:%2 N:%3] (select)").arg(FIREWIRE_TIMEOUT).arg(fwport).arg(fwnode));
+            iec61883_mpeg2_recv_stop(fwmpeg);
+            // to bad setting _error does nothing once recording has started..
+            _error = true;
+            return;
+       }
+    }        
+
+    iec61883_mpeg2_recv_stop(fwmpeg);
+    FinishRecording();
+    _recording = false;
+}  
+
+void FirewireRecorder::ProcessTSPacket(unsigned char *tspacket, int len) {
+    tpkt.InitHeader(tspacket);
+    tpkt.InitPayload(tspacket+4);
+    FindKeyframes(&tpkt);
+    lastpacket = time(NULL);
+    ringBuffer->Write(tspacket,len);
+}
+
+void FirewireRecorder::SetOptionsFromProfile(RecordingProfile *profile,
+                                         const QString &videodev,
+                                         const QString &audiodev,
+                                         const QString &vbidev, int ispip) {
+    (void)videodev;
+    (void)audiodev;
+    (void)vbidev;
+    (void)profile;
+    (void)ispip;
+}
+
+void FirewireRecorder::SetOption(const QString &name, const QString &value) {
+
+    if(name == "model") {
+        fwmodel = value;
+    }
+}
+
+void FirewireRecorder::SetOption(const QString &name, int value) {
+
+    if(name == "port") {
+	fwport = value;
+    } else if(name == "node") {
+        fwnode = value;
+    } else if(name == "speed") {
+        fwspeed = value;
+        if(fwspeed != RAW1394_ISO_SPEED_100 && fwspeed != RAW1394_ISO_SPEED_200 && fwspeed != RAW1394_ISO_SPEED_400) {
+            VERBOSE(VB_IMPORTANT, QString("Firewire: Invalid speed '%1', assuming 0 (100Mbps)").arg(fwspeed));
+            fwspeed = 0;
+        }
+    }
+}
+
+QString FirewireRecorder::FirewireSpeedString (int speed) {
+    switch(speed) {
+        case RAW1394_ISO_SPEED_100:
+               return("100Mbps");
+        case RAW1394_ISO_SPEED_200: 
+               return("200Mbps");
+        case RAW1394_ISO_SPEED_400:
+               return("400Mbps");
+        default:
+               return(QString("Invalid (%1)").arg(speed));
+     }
+}
diff -urN --exclude='config.*' --exclude='Makefile*' --exclude='*.o' --exclude='*.so' --exclude='moc*' mythtv.orig/libs/libmythtv/firewirerecorder.h mythtv/libs/libmythtv/firewirerecorder.h
--- mythtv.orig/libs/libmythtv/firewirerecorder.h	1969-12-31 16:00:00.000000000 -0800
+++ mythtv/libs/libmythtv/firewirerecorder.h	2005-01-31 12:26:29.000000000 -0800
@@ -0,0 +1,49 @@
+/**
+ *  FirewireRecorder
+ *  Copyright (c) 2005 by Jim Westfall
+ *  Distributed as part of MythTV under GPL v2 and later.
+ */
+
+#ifndef FIREWIRERECORDER_H_
+#define FIREWIRERECORDER_H_
+
+#include "dtvrecorder.h"
+#include "mpeg/tspacket.h"
+#include <libraw1394/raw1394.h>
+#include <libiec61883/iec61883.h>
+
+#include <time.h>
+
+#define FIREWIRE_TIMEOUT 15
+
+class FirewireRecorder : public DTVRecorder
+{
+  public:
+
+    FirewireRecorder();
+    ~FirewireRecorder();
+
+    void StartRecording(void);
+    bool Open(void); 
+    void ProcessTSPacket(unsigned char *tspacket, int len);
+    void FirewireRecorder::SetOptionsFromProfile(RecordingProfile *profile,
+                                         const QString &videodev,
+                                         const QString &audiodev,
+                                         const QString &vbidev, int ispip);
+
+    void SetOption(const QString &name, const QString &value);
+    void SetOption(const QString &name, int value);
+    QString FirewireSpeedString(int speed);
+
+  private:
+    int fwport, fwchannel, fwspeed, fwbandwidth, fwfd;
+    QString fwmodel;
+    nodeid_t fwnode;
+    raw1394handle_t fwhandle;
+    iec61883_mpeg2_t fwmpeg;
+    bool isopen;
+    time_t lastpacket;
+    TSPacket tpkt;
+};
+
+#endif
diff -urN --exclude='config.*' --exclude='Makefile*' --exclude='*.o' --exclude='*.so' --exclude='moc*' mythtv.orig/libs/libmythtv/libmythtv.pro mythtv/libs/libmythtv/libmythtv.pro
--- mythtv.orig/libs/libmythtv/libmythtv.pro	2005-01-28 21:21:36.000000000 -0800
+++ mythtv/libs/libmythtv/libmythtv.pro	2005-01-31 12:26:29.000000000 -0800
@@ -132,6 +132,11 @@
     HEADERS += dvbdev/dvbci.h
 }
 
+using_firewire {
+    SOURCES += firewirerecorder.cpp firewirechannel.cpp
+    HEADERS += firewirerecorder.h firewirechannel.h
+}
+
 using_directfb {
     SOURCES += videoout_directfb.cpp
     HEADERS += videoout_directfb.h
diff -urN --exclude='config.*' --exclude='Makefile*' --exclude='*.o' --exclude='*.so' --exclude='moc*' mythtv.orig/libs/libmythtv/tv_rec.cpp mythtv/libs/libmythtv/tv_rec.cpp
--- mythtv.orig/libs/libmythtv/tv_rec.cpp	2005-01-23 14:45:30.000000000 -0800
+++ mythtv/libs/libmythtv/tv_rec.cpp	2005-01-31 12:26:29.000000000 -0800
@@ -37,6 +37,11 @@
 #include "siscan.h"
 #endif
 
+#ifdef USING_FIREWIRE
+#include "firewirerecorder.h"
+#include "firewirechannel.h"
+#endif
+
 void *SpawnEncode(void *param)
 {
     RecorderBase *nvr = (RecorderBase *)param;
@@ -86,7 +91,7 @@
     QString inputname, startchannel;
 
     GetDevices(capturecardnum, videodev, vbidev, audiodev, audiosamplerate,
-               inputname, startchannel, cardtype, dvb_options, skip_btaudio);
+               inputname, startchannel, cardtype, dvb_options, firewire_options, skip_btaudio);
 
     if (cardtype == "DVB")
     {
@@ -114,6 +119,24 @@
         exit(-20);
 #endif
     }
+    if (cardtype == "FIREWIRE")
+    {
+#ifdef USING_FIREWIRE
+        channel = new FirewireChannel(this);
+        channel->Open();
+        if (inputname.isEmpty())
+            channel->SetChannelByString(startchannel);
+        else
+            channel->SwitchToInput(inputname, startchannel);
+        channel->SetChannelOrdering(chanorder);
+#else
+        VERBOSE(VB_IMPORTANT, "ERROR: FireWire Input configured, "
+                              "but no FireWire support compiled in!");
+        VERBOSE(VB_IMPORTANT, "Remove the card from configuration, "
+                              "or recompile MythTV.");
+        exit(-20);
+#endif
+    }
     else if ((cardtype == "MPEG") && (videodev.lower().left(5) == "file:"))
     {
         channel = NULL;
@@ -645,6 +668,20 @@
         nvr->Initialize();
         return;
     }
+    else if (cardtype == "FIREWIRE")
+    {
+#ifdef USING_FIREWIRE
+        nvr = new FirewireRecorder();
+        nvr->SetRingBuffer(rbuffer);
+        nvr->SetOptionsFromProfile(&profile, videodev, audiodev, vbidev, ispip);
+        nvr->SetOption("port", firewire_options.port);
+        nvr->SetOption("node", firewire_options.node);
+        nvr->SetOption("speed", firewire_options.speed);
+        nvr->SetOption("model", firewire_options.model);
+        nvr->Initialize();
+#endif
+        return;
+    }
     else if (cardtype == "DVB")
     {
 #ifdef USING_DVB
@@ -1096,7 +1133,8 @@
 void TVRec::GetDevices(int cardnum, QString &video, QString &vbi, 
                        QString &audio, int &rate, QString &defaultinput,
                        QString &startchan, QString &type, 
-                       dvb_options_t &dvb_opts, bool &skip_bt)
+                       dvb_options_t &dvb_opts, firewire_options_t &firewire_opts, 
+                       bool &skip_bt)
 {
     video = "";
     vbi = "";
@@ -1113,7 +1151,9 @@
                                "audioratelimit,defaultinput,cardtype,"
                                "dvb_swfilter, dvb_recordts,"
                                "dvb_wait_for_seqstart,dvb_dmx_buf_size,"
-                               "dvb_pkt_buf_size, skipbtaudio, dvb_on_demand "
+                               "dvb_pkt_buf_size, skipbtaudio, dvb_on_demand,"
+                               "firewire_port, firewire_node, firewire_speed,"
+                               "firewire_model "
                                "FROM capturecard WHERE cardid = %1;")
                               .arg(cardnum);
 
@@ -1158,6 +1198,12 @@
 
         skip_bt = query.value(11).toInt();
         dvb_opts.dvb_on_demand = query.value(12).toInt();
+        firewire_opts.port = query.value(13).toInt();
+        firewire_opts.node = query.value(14).toInt(); 
+        firewire_opts.speed = query.value(15).toInt();
+        test = query.value(16).toString();
+        if (test != QString::null)
+	   firewire_opts.model = QString::fromUtf8(test);
     }
 
     thequery = QString("SELECT if(startchan!='', startchan, '3') "
diff -urN --exclude='config.*' --exclude='Makefile*' --exclude='*.o' --exclude='*.so' --exclude='moc*' mythtv.orig/libs/libmythtv/tv_rec.h mythtv/libs/libmythtv/tv_rec.h
--- mythtv.orig/libs/libmythtv/tv_rec.h	2005-01-23 14:45:30.000000000 -0800
+++ mythtv/libs/libmythtv/tv_rec.h	2005-01-31 12:26:29.000000000 -0800
@@ -41,6 +41,14 @@
     bool dvb_on_demand;
 } dvb_options_t;
 
+typedef struct _firewire_options_t
+{
+    int port;
+    int node;
+    int speed;
+    QString model;
+} firewire_options_t;
+
 class TVRec
 {
  public:
@@ -156,7 +164,8 @@
 
     void GetDevices(int cardnum, QString &video, QString &vbi, QString &audio,
                     int &rate, QString &defaultinput, QString &startchannel,
-                    QString &type, dvb_options_t &dvb_opts, bool &skip_bt);
+                    QString &type, dvb_options_t &dvb_opts, firewire_options_t &firewire_opts,
+                    bool &skip_bt);
 
     void ConnectDB(int cardnum);
     void DisconnectDB(void);
@@ -232,6 +241,7 @@
     int autoTranscode;
 
     dvb_options_t dvb_options;
+    firewire_options_t firewire_options;
 
     char requestBuffer[256001];
 
diff -urN --exclude='config.*' --exclude='Makefile*' --exclude='*.o' --exclude='*.so' --exclude='moc*' mythtv.orig/libs/libmythtv/videosource.cpp mythtv/libs/libmythtv/videosource.cpp
--- mythtv.orig/libs/libmythtv/videosource.cpp	2005-01-30 08:10:05.000000000 -0800
+++ mythtv/libs/libmythtv/videosource.cpp	2005-01-31 12:26:29.000000000 -0800
@@ -783,6 +783,74 @@
     };
 };
 
+class FirewireModel: public ComboBoxSetting, public CCSetting {
+    public:
+	FirewireModel(const CaptureCard& parent):
+ 	CCSetting(parent, "firewire_model") {
+            setLabel(QObject::tr("Firewire Model"));
+            addSelection(QObject::tr("Other"));
+            setHelpText(QObject::tr("Firewire Model is for future use incase there " 
+                                     "is a need to model specific work arounds.")); 
+
+        }
+};
+
+class FirewirePort: public LineEditSetting, public CCSetting {
+    public:
+	FirewirePort(const CaptureCard& parent):
+ 	CCSetting(parent, "firewire_port") {
+            setValue("0");
+            setLabel(QObject::tr("Firewire Port"));
+            setHelpText(QObject::tr("Firewire port on your firewire card."));
+        }
+};
+
+class FirewireNode: public LineEditSetting, public CCSetting {
+    public:
+        FirewireNode(const CaptureCard& parent):
+        CCSetting(parent, "firewire_node") {
+            setValue("2");
+            setLabel(QObject::tr("Firewire Node"));
+            setHelpText(QObject::tr("Firewire node is the remote device."));
+        }
+};
+
+class FirewireSpeed: public ComboBoxSetting, public CCSetting {
+    public:
+	FirewireSpeed(const CaptureCard& parent):
+ 	CCSetting(parent, "firewire_speed") {
+            setLabel(QObject::tr("Firewire Speed"));
+            addSelection(QObject::tr("100Mbps"),"0");
+            addSelection(QObject::tr("200Mbps"),"1");
+            addSelection(QObject::tr("400Mbps"),"2");
+        }
+};
+
+class FirewireInput: public ComboBoxSetting, public CCSetting {
+    public:
+	FirewireInput(const CaptureCard& parent):
+ 	CCSetting(parent, "defaultinput") {
+            setLabel(QObject::tr("Default Input"));
+            addSelection("MPEG2TS");
+            setHelpText(QObject::tr("Only MPEG2TS is supported at this time."));
+        }
+};
+
+class FirewireConfigurationGroup: public VerticalConfigurationGroup {
+public:
+    FirewireConfigurationGroup(CaptureCard& a_parent):
+        parent(a_parent) {
+        setUseLabel(false);
+        addChild(new FirewireModel(parent));
+        addChild(new FirewirePort(parent));
+        addChild(new FirewireNode(parent));
+        addChild(new FirewireSpeed(parent));
+   	addChild(new FirewireInput(parent));
+    };
+private:
+    CaptureCard& parent;
+};
+
 class V4LConfigurationGroup: public VerticalConfigurationGroup {
 public:
     V4LConfigurationGroup(CaptureCard& a_parent):
@@ -823,6 +891,7 @@
 
     addTarget("V4L", new V4LConfigurationGroup(parent));
     addTarget("DVB", new DVBConfigurationGroup(parent));
+    addTarget("FIREWIRE", new FirewireConfigurationGroup(parent));
 }
 
 void CaptureCardGroup::triggerChanged(const QString& value) 
@@ -846,16 +915,24 @@
 
 void CaptureCard::fillSelections(QSqlDatabase* db,
                                  SelectSetting* setting) {
-    QString query = QString("SELECT cardtype, videodevice, cardid "
+    QString query = QString("SELECT cardtype, videodevice, cardid, firewire_port, firewire_node "
                             "FROM capturecard WHERE hostname = \"%1\";")
                             .arg(gContext->GetHostName());
     QSqlQuery result = db->exec(query);
 
     if (result.isActive() && result.numRowsAffected() > 0)
         while (result.next())
-            setting->addSelection("[ " + result.value(0).toString() + " : " +
+            // dont like doing this..
+            if(result.value(0).toString() == "FIREWIRE") {
+                     setting->addSelection("[ " + result.value(0).toString() + " Port: " +
+                                  result.value(3).toString() + ", Node: " +
+                                  result.value(4).toString() + "]",
+                                  result.value(2).toString());
+            } else {
+                     setting->addSelection("[ " + result.value(0).toString() + " : " +
                                   result.value(1).toString() + " ]",
                                   result.value(2).toString());
+            }
 }
 
 void CaptureCard::loadByID(QSqlDatabase* db, int cardid) {
@@ -883,6 +960,8 @@
                           "HDTV");
     setting->addSelection(QObject::tr("Digital Video Broadcast card (DVB)"), 
                           "DVB");
+    setting->addSelection(QObject::tr("FireWire Input"),
+                          "FIREWIRE");
 }
 
 class CardID: public SelectLabelSetting, public CISetting {
@@ -1391,7 +1470,8 @@
     // SelectSetting provided a facility to edit the labels, we
     // could use CaptureCard::fillSelections
 
-    QString thequery = QString("SELECT cardid, videodevice, cardtype, dvb_diseqc_type "
+    QString thequery = QString("SELECT cardid, videodevice, cardtype, dvb_diseqc_type, "
+                               "firewire_port, firewire_node "
                                "FROM capturecard WHERE hostname = \"%1\";")
                               .arg(gContext->GetHostName());
 
@@ -1402,14 +1482,20 @@
             QString videodevice(capturecards.value(1).toString());
 
             QStringList inputs;
-            if (capturecards.value(2).toString() != "DVB")
+            if (capturecards.value(2).toString() == "DVB")
             {
-                inputs = VideoDevice::probeInputs(videodevice);
-                for (QStringList::iterator i = inputs.begin(); 
-                     i != inputs.end(); ++i)
+                QValueList<DVBDiseqcInputList> dvbinput;
+                dvbinput = VideoDevice::fillDVBInputsDiseqc(capturecards.value(3).toInt());
+
+                QValueList<DVBDiseqcInputList>::iterator it;
+                for (it = dvbinput.begin(); it != dvbinput.end(); ++it)
                 {
-                    CardInput* cardinput = new CardInput();
-                    cardinput->loadByInput(db, cardid, *i);
+                    // IS DVB Check for CardInput class
+                    CardInput* cardinput = new CardInput(1);
+                    cardinput->loadByInput(db, cardid, (*it).input);
+
+                    cardinput->fillDiseqcSettingsInput((*it).position,(*it).port);
+
                     cardinputs.push_back(cardinput);
                     QString index = QString::number(cardinputs.size()-1);
 
@@ -1417,6 +1503,28 @@
                         .arg("[ " + capturecards.value(2).toString() +
                              " : " + capturecards.value(1).toString() +
                              " ]")
+                        .arg((*it).input)
+                        .arg(cardinput->getSourceName());
+                    addSelection(label, index);
+                }
+            }
+            else if(capturecards.value(2).toString() == "FIREWIRE")
+            {
+                inputs = QStringList("MPEG2TS");
+                for (QStringList::iterator i = inputs.begin();
+                     i != inputs.end(); ++i)
+                { 
+                    CardInput* cardinput = new CardInput();
+                    cardinput->loadByInput(db, cardid, *i);   
+                    cardinputs.push_back(cardinput);
+                    QString index = QString::number(cardinputs.size()-1);
+
+                    QString label;
+                    label = QString("%1 (%2) -> %3")
+                        .arg("[ " + capturecards.value(2).toString() +
+                             " Port: " + capturecards.value(3).toString() +
+                             ", Node: " + capturecards.value(4).toString() +
+                             " ]")
                         .arg(*i)
                         .arg(cardinput->getSourceName());
                     addSelection(label, index);
@@ -1424,18 +1532,12 @@
             }
             else
             {
-                QValueList<DVBDiseqcInputList> dvbinput;
-                dvbinput = VideoDevice::fillDVBInputsDiseqc(capturecards.value(3).toInt());
-
-                QValueList<DVBDiseqcInputList>::iterator it;
-                for (it = dvbinput.begin(); it != dvbinput.end(); ++it)
+                inputs = VideoDevice::probeInputs(videodevice);
+                for (QStringList::iterator i = inputs.begin(); 
+                     i != inputs.end(); ++i)
                 {
-                    // IS DVB Check for CardInput class
-                    CardInput* cardinput = new CardInput(1);
-                    cardinput->loadByInput(db, cardid, (*it).input);
-
-                    cardinput->fillDiseqcSettingsInput((*it).position,(*it).port);
-
+                    CardInput* cardinput = new CardInput();
+                    cardinput->loadByInput(db, cardid, *i);
                     cardinputs.push_back(cardinput);
                     QString index = QString::number(cardinputs.size()-1);
 
@@ -1443,7 +1545,7 @@
                         .arg("[ " + capturecards.value(2).toString() +
                              " : " + capturecards.value(1).toString() +
                              " ]")
-                        .arg((*it).input)
+                        .arg(*i)
                         .arg(cardinput->getSourceName());
                     addSelection(label, index);
                 }
@@ -1627,6 +1729,7 @@
 
     for(QStringList::iterator i = inputs.begin(); i != inputs.end(); ++i)
         addSelection(*i);
+
 }
 
 void TunerCardInput::fillSelections(const QString& device) {
diff -urN --exclude='config.*' --exclude='Makefile*' --exclude='*.o' --exclude='*.so' --exclude='moc*' mythtv.orig/settings.pro mythtv/settings.pro
--- mythtv.orig/settings.pro	2005-01-30 13:47:59.000000000 -0800
+++ mythtv/settings.pro	2005-01-31 13:37:20.000000000 -0800
@@ -83,6 +83,12 @@
 #define the following if you want On Air Guide information
 #DEFINES += USING_DVB_EIT
 
+# Firewire support
+#CONFIG += using_firewire
+#DEFINES += USING_FIREWIRE
+#EXTRA_LIBS += -lraw1394 -liec61883
+
+
 # Joystick menu support
 CONFIG += using_joystick_menu
 


More information about the mythtv-dev mailing list