Ticket #1530: fwupdate2.diff

File fwupdate2.diff, 31.5 KB (added by jwestfall@…, 20 years ago)
  • libs/libmythtv/firewirechannel.cpp

     
    4444
    4545FirewireChannel::FirewireChannel(FireWireDBOptions firewire_opts,
    4646                                 TVRec *parent)
    47     : ChannelBase(parent), fw_opts(firewire_opts),
    48       fwhandle(NULL),      isopen(false)
     47    : FirewireChannelBase(parent), fw_opts(firewire_opts),
     48      fwhandle(NULL)
    4949{
    5050}
    5151
     
    5454    Close();
    5555}
    5656
    57 bool FirewireChannel::SetChannelByString(const QString &chan)
     57bool FirewireChannel::SetChannelByNumber(int channel)
    5858{
    59     inputs[currentInputID]->startChanNum = chan;
    60     curchannelname = chan;
    61 
    62     InputMap::const_iterator it = inputs.find(currentInputID);
    63 
    64     if (!(*it)->externalChanger.isEmpty())
    65         return ChangeExternalChannel(chan);
    66 
    6759    // Change channel using internal changer
    6860
    6961    if (!is_supported(fw_opts.model))
     
    7466        return false;
    7567    }
    7668
    77     if (!isopen)
    78         return false;
    79 
    80     int channel = chan.toInt();
    8169    int dig[3];
    8270    dig[0] = (channel % 1000) / 100;
    8371    dig[1] = (channel % 100)  / 10;
     
    138126    return true;
    139127}
    140128
    141 bool FirewireChannel::Open(void)
     129bool FirewireChannel::OpenFirewire(void)
    142130{
    143     if (!InitializeInputs())
    144         return false;
    145 
    146     InputMap::const_iterator it = inputs.find(currentInputID);
    147     if (!(*it)->externalChanger.isEmpty())
    148         return true;
    149 
    150131    if (!is_supported(fw_opts.model))
    151132    {
    152133        VERBOSE(VB_IMPORTANT, LOC_ERR +
     
    167148    VERBOSE(VB_CHANNEL, LOC + "Allocated raw1394 handle " +
    168149            QString("for port %1").arg(fw_opts.port));
    169150
    170     isopen = true;
    171151    return true;
    172152}
    173153
    174 void FirewireChannel::Close(void)
     154void FirewireChannel::CloseFirewire(void)
    175155{
    176     // Close channel
    177     if (isopen)
    178     {
    179         VERBOSE(VB_CHANNEL, LOC + "Releasing raw1394 handle");
    180         raw1394_destroy_handle(fwhandle);
    181         isopen = false;
    182     }
     156    VERBOSE(VB_CHANNEL, LOC + "Releasing raw1394 handle");
     157    raw1394_destroy_handle(fwhandle);
    183158}
    184 
    185 bool FirewireChannel::SwitchToInput(const QString &input, const QString &chan)
    186 {
    187     int inputNum = GetInputByName(input);
    188     if (inputNum < 0)
    189         return false;
    190 
    191     // input switching code would go here
    192 
    193     return SetChannelByString(chan);
    194 }
  • libs/libmythtv/firewirerecorderbase.h

     
    88#define FIREWIRERECORDERBASE_H_
    99
    1010#include "dtvrecorder.h"
     11#include "tsstats.h"
    1112#include "mpeg/tspacket.h"
    12 #include <time.h>
    1313
    14 #define FIREWIRE_TIMEOUT 15
     14class MPEGStreamData;
     15class ProgramAssociationTable;
     16class ProgramMapTable;
    1517
    1618/** \class FirewireRecorderBase
    1719 *  \brief This is a specialization of DTVRecorder used to
     
    2123 */
    2224class FirewireRecorderBase : public DTVRecorder
    2325{
     26  Q_OBJECT
     27    friend class MPEGStreamData;
     28    friend class TSPacketProcessor;
     29
    2430  public:
    25     FirewireRecorderBase(TVRec *rec, char const* name) :
    26         DTVRecorder(rec, name),
    27         lastpacket(0)
    28     {;}
    29        
     31    FirewireRecorderBase(TVRec *rec, char const* name);
     32   ~FirewireRecorderBase();
     33
     34    // Commands
    3035    void StartRecording(void);
    3136    void ProcessTSPacket(const TSPacket &tspacket);
     37    bool PauseAndWait(int timeout = 100);
     38
     39    // Sets
    3240    void SetOptionsFromProfile(RecordingProfile *profile,
    3341                               const QString &videodev,
    3442                               const QString &audiodev,
    3543                               const QString &vbidev);
     44    void SetStreamData(MPEGStreamData*);
    3645
    37     bool PauseAndWait(int timeout = 100);
     46    // Gets
     47    MPEGStreamData* StreamData(void) { return _mpeg_stream_data; }
    3848
    3949  public slots:
    4050    void deleteLater(void);
     51    void WritePAT(ProgramAssociationTable*);
     52    void WritePMT(ProgramMapTable*);
    4153
    42  protected:
    43     static int read_tspacket (
    44         unsigned char *tspacket, int len, uint dropped, void *callback_data);
     54  private:
    4555
    46  private:
    4756    virtual void Close() = 0;
    48 
    4957    virtual void start() = 0;
    5058    virtual void stop() = 0;
    5159    virtual bool grab_frames() = 0;
    52     virtual void no_data() = 0;
    5360
    54   private:
    55     time_t lastpacket;
     61    MPEGStreamData  *_mpeg_stream_data;
     62    TSStats          _ts_stats; 
     63
     64  protected:
     65    static const int  kTimeoutInSeconds;
     66
    5667};
    5768
    5869#endif
  • libs/libmythtv/firewirechannelbase.h

     
    2323class FirewireChannelBase : public ChannelBase
    2424{
    2525  public:
    26     FirewireChannelBase(TVRec *parent);
    27     ~FirewireChannelBase();
     26    FirewireChannelBase(TVRec *parent) 
     27        : ChannelBase(parent), isopen(false) { }
     28    ~FirewireChannelBase() { Close(); }
    2829
    2930    bool Open(void);
    3031    void Close(void);
    3132
    3233    // Sets
    3334    bool SetChannelByString(const QString &chan);
    34     void SetExternalChanger(void);   
    3535    virtual bool SetChannelByNumber(int channel) = 0;
    3636
    3737    // Gets
    3838    bool IsOpen(void) const { return isopen; }
    39 //    QString GetDevice(void) const;
    4039
    4140    // Commands
    4241    bool SwitchToInput(const QString &inputname, const QString &chan);
     
    4847    virtual void CloseFirewire() = 0;
    4948
    5049  protected:
    51     bool UseExternalChanger();
    5250    bool isopen;
    5351};
    5452
  • libs/libmythtv/libmythtv.pro

     
    6161        QMAKE_EXT_CPP += .mm
    6262    }
    6363
     64    using_firewire {
     65        QMAKE_CXXFLAGS += -F$${CONFIG_MAC_AVC}
     66        LIBS += -F$${CONFIG_MAC_AVC} -framework AVCVideoServices
     67    }
     68
    6469    # There is a dependence on some stuff in libmythui.
    6570    # It isn't built yet, so we have to ignore these for now:
    6671    QMAKE_LFLAGS_SHLIB += -flat_namespace -undefined warning
     
    290295        DEFINES += USING_V4L
    291296    }
    292297
    293     # Support for cable boxes that provide Firewire out on Linux
    294     using_firewire:HEADERS += firewirerecorder.h   firewirechannel.h
    295     using_firewire:SOURCES += firewirerecorder.cpp firewirechannel.cpp
    296     using_firewire:DEFINES += USING_FIREWIRE
     298    # Support for cable boxes that provide Firewire out
     299    using_firewire {
     300        HEADERS += firewirerecorderbase.h       firewirechannelbase.h
     301        SOURCES += firewirerecorderbase.cpp     firewirechannelbase.cpp
    297302
     303        macx {
     304           HEADERS += darwinfirewirechannel.h   darwinfirewirerecorder.h
     305           SOURCES += darwinfirewirechannel.cpp darwinfirewirerecorder.cpp
     306           HEADERS += selectavcdevice.h
     307           SOURCES += selectavcdevice.cpp
     308        }
     309
     310        linux {
     311            HEADERS += firewirechannel.h        firewirerecorder.h
     312            SOURCES += firewirechannel.cpp      firewirerecorder.cpp
     313        }
     314
     315        DEFINES += USING_FIREWIRE
     316    }
     317
    298318    # Support for set top boxes (Nokia DBox2 etc.)
    299319    using_dbox2:SOURCES += dbox2recorder.cpp dbox2channel.cpp dbox2epg.cpp
    300320    using_dbox2:HEADERS += dbox2recorder.h dbox2channel.h dbox2epg.h
  • libs/libmythtv/darwinfirewirerecorder.cpp

     
    3939{
    4040    VERBOSE(
    4141        VB_IMPORTANT,
    42         QString("Firewire: No Input in %1 seconds").arg(FIREWIRE_TIMEOUT));
     42        QString("Firewire: No Input in %1 seconds").arg(kTimeoutInSeconds));
    4343}
    4444
    4545namespace
     
    111111
    112112IOReturn DarwinFirewireRecorder::tspacket_callback(UInt32 tsPacketCount, UInt32 **ppBuf,void *pRefCon)
    113113{
     114    DarwinFirewireRecorder* self = static_cast<DarwinFirewireRecorder*>(pRefCon);
     115    if (!self)
     116        return kIOReturnBadArgument;
     117
    114118    for (UInt32 i = 0; i < tsPacketCount; ++i)
    115119    {
    116         void* packet = ppBuf[i];
    117         int ok = FirewireRecorderBase::read_tspacket(
    118             static_cast<unsigned char *>(packet),
    119               AVS::kMPEG2TSPacketSize,
    120               0, // dropped
    121               pRefCon);
    122 
    123         // This is based on knowledge of what read_tspacket does --
    124         // the only way it fails is with a NULL callback_data
    125         // argument.
    126         if (!ok)
    127             return kIOReturnBadArgument;
     120        self->ProcessTSPacket(*(reinterpret_cast<TSPacket*>(ppBuf[i])));
    128121    }
    129122   
    130123    return 0;
     
    181174
    182175        // Register a no-data notification callback
    183176        video_stream->pMPEGReceiver->registerNoDataNotificationCallback(
    184         MPEGNoData, this, FIREWIRE_TIMEOUT * 1000);
     177        MPEGNoData, this, kTimeoutInSeconds * 1000);
    185178       
    186179     return true;
    187180}
  • libs/libmythtv/firewirerecorderbase.cpp

     
    77// MythTV includes
    88#include "firewirerecorderbase.h"
    99#include "mythcontext.h"
    10 #include "tspacket.h"
     10#include "mpegtables.h"
     11#include "mpegstreamdata.h"
    1112#include "tv_rec.h"
    1213
    13 // callback function for libiec61883
    14 int FirewireRecorderBase::read_tspacket (unsigned char *tspacket, int /*len*/,
    15                    uint dropped, void *callback_data)
    16 {
    17     FirewireRecorderBase *fw = (FirewireRecorderBase*) callback_data;
     14#define LOC QString("FireRecBase: ")
     15#define LOC_ERR QString("FireRecBase, Error: ")
    1816
    19     if (!fw)
    20         return 0;
     17const int FirewireRecorderBase::kTimeoutInSeconds = 15;
    2118
    22     if (dropped)
    23     {
    24         VERBOSE(VB_RECORD,
    25                 QString("Firewire: %1 packet(s) dropped.").arg(dropped));
    26     }
     19FirewireRecorderBase::FirewireRecorderBase(TVRec *rec, char const* name)
     20    : DTVRecorder(rec, name),
     21      _mpeg_stream_data(NULL)
     22{
     23    _mpeg_stream_data = new MPEGStreamData(1, true);
     24    connect(_mpeg_stream_data,
     25            SIGNAL(UpdatePATSingleProgram(ProgramAssociationTable*)),
     26            this, SLOT(WritePAT(ProgramAssociationTable*)));
     27    connect(_mpeg_stream_data,
     28            SIGNAL(UpdatePMTSingleProgram(ProgramMapTable*)),
     29            this, SLOT(WritePMT(ProgramMapTable*)));
     30}
    2731
    28     if (SYNC_BYTE != tspacket[0])
    29     {
    30         VERBOSE(VB_IMPORTANT, "Firewire: Got out of sync TS Packet");
    31         return 1;
    32     }
     32FirewireRecorderBase::~FirewireRecorderBase()
     33{
     34   if (_mpeg_stream_data)
     35   {
     36       delete _mpeg_stream_data;
     37       _mpeg_stream_data = NULL;
     38   }
     39}
    3340
    34     fw->ProcessTSPacket(*(reinterpret_cast<TSPacket*>(tspacket)));
    35 
    36     return 1;
    37 }
    38  
    3941void FirewireRecorderBase::deleteLater(void)
    4042{
    4143    Close();
     
    4446
    4547void FirewireRecorderBase::StartRecording(void) {
    4648 
    47     VERBOSE(VB_RECORD, QString("StartRecording"));
     49    VERBOSE(VB_RECORD, LOC + "StartRecording");
    4850
    4951    if (!Open()) {
    5052        _error = true;       
     
    5456    _request_recording = true;
    5557    _recording = true;
    5658   
    57     this->start();
     59    start();
    5860
    59     lastpacket = time(NULL);
    6061    while(_request_recording) {
    6162       if (PauseAndWait())
    6263           continue;
    6364
    64        if (time(NULL) - lastpacket > FIREWIRE_TIMEOUT) {
    65            this->no_data();
    66            this->stop();
    67            _error = true;
    68            return;
    69        }
    70 
    71        if (!this->grab_frames())
     65       if (!grab_frames())
    7266       {
    7367           _error = true;
    7468           return;
    7569       }
    7670    }       
    7771   
    78     this->stop();
     72    stop();
    7973    FinishRecording();
    8074
    8175    _recording = false;
     
    8377
    8478void FirewireRecorderBase::ProcessTSPacket(const TSPacket &tspacket)
    8579{
    86     lastpacket = time(NULL);
    87     _buffer_packets = !FindKeyframes(&tspacket);
    88     BufferedWrite(tspacket);
     80   if (tspacket.TransportError())
     81        return;
     82
     83    if (tspacket.ScramplingControl())
     84        return;
     85
     86    if (tspacket.HasAdaptationField())
     87        StreamData()->HandleAdaptationFieldControl(&tspacket);
     88
     89    if (tspacket.HasPayload())
     90    {
     91        const unsigned int lpid = tspacket.PID();
     92
     93        // Pass or reject packets based on PID, and parse info from them
     94        if (lpid == StreamData()->VideoPIDSingleProgram())
     95        {
     96            _buffer_packets = !FindKeyframes(&tspacket);
     97            BufferedWrite(tspacket);
     98        }
     99        else if (StreamData()->IsAudioPID(lpid))
     100            BufferedWrite(tspacket);
     101        else if (StreamData()->IsListeningPID(lpid))
     102            StreamData()->HandleTSTables(&tspacket);
     103        else if (StreamData()->IsWritingPID(lpid))
     104            BufferedWrite(tspacket);
     105    }
     106
     107    _ts_stats.IncrTSPacketCount();
     108    if (0 == _ts_stats.TSPacketCount()%1000000)
     109        VERBOSE(VB_RECORD, _ts_stats.toString());
    89110}
    90111
    91112void FirewireRecorderBase::SetOptionsFromProfile(RecordingProfile *profile,
     
    106127    {
    107128        if (!paused)
    108129        {
    109             this->stop();
     130            stop();
    110131            paused = true;
    111132            pauseWait.wakeAll();
    112133            if (tvrec)
     
    116137    }
    117138    if (!request_pause && paused)
    118139    {
    119         this->start();
     140        start();
    120141        paused = false;
    121142    }
    122143    return paused;
    123144}
     145
     146void FirewireRecorderBase::SetStreamData(MPEGStreamData *stream_data)
     147{
     148    if (stream_data == _mpeg_stream_data)
     149        return;
     150
     151    MPEGStreamData *old_data = _mpeg_stream_data;
     152    _mpeg_stream_data = stream_data;
     153    if (old_data)
     154        delete old_data;
     155}
     156
     157void FirewireRecorderBase::WritePAT(ProgramAssociationTable *pat)
     158{
     159    if (!pat)
     160        return;
     161
     162    int next = (pat->tsheader()->ContinuityCounter()+1)&0xf;
     163    pat->tsheader()->SetContinuityCounter(next);
     164    BufferedWrite(*(reinterpret_cast<const TSPacket*>(pat->tsheader())));
     165}
     166
     167void FirewireRecorderBase::WritePMT(ProgramMapTable *pmt)
     168{
     169    if (!pmt)
     170        return;
     171
     172    int next = (pmt->tsheader()->ContinuityCounter()+1)&0xf;
     173    pmt->tsheader()->SetContinuityCounter(next);
     174    BufferedWrite(*(reinterpret_cast<const TSPacket*>(pmt->tsheader())));
     175}
  • libs/libmythtv/firewirerecorder.cpp

     
    2222#define LOC QString("FireRec: ")
    2323#define LOC_ERR QString("FireRec, Error: ")
    2424
    25 const int FirewireRecorder::kBroadcastChannel    = 63;
    26 const int FirewireRecorder::kTimeoutInSeconds    = 15;
    27 const int FirewireRecorder::kConnectionP2P       = 0;
    28 const int FirewireRecorder::kConnectionBroadcast = 1;
     25const int  FirewireRecorder::kBroadcastChannel    = 63;
     26const int  FirewireRecorder::kConnectionP2P       = 0;
     27const int  FirewireRecorder::kConnectionBroadcast = 1;
     28const uint FirewireRecorder::kMaxBufferedPackets  = 8000;
    2929
    3030// callback function for libiec61883
    3131int fw_tspacket_handler(unsigned char *tspacket, int /*len*/,
     
    5959    return QString("%1Mbps").arg(speeds[speed]);
    6060}
    6161
    62 FirewireRecorder::FirewireRecorder(TVRec *rec)
    63     : DTVRecorder(rec, "FirewireRecorder"),
    64       fwport(-1),     fwchannel(-1), fwspeed(-1),   fwbandwidth(-1),
    65       fwfd(-1),       fwconnection(kConnectionP2P),
    66       fwoplug(-1),    fwiplug(-1),   fwmodel(""),   fwnode(0),
    67       fwhandle(NULL), fwmpeg(NULL),  isopen(false), lastpacket(0),
    68       _mpeg_stream_data(NULL)
    69 {
    70     _mpeg_stream_data = new MPEGStreamData(1, true);
    71     connect(_mpeg_stream_data,
    72             SIGNAL(UpdatePATSingleProgram(ProgramAssociationTable*)),
    73             this, SLOT(WritePAT(ProgramAssociationTable*)));
    74     connect(_mpeg_stream_data,
    75             SIGNAL(UpdatePMTSingleProgram(ProgramMapTable*)),
    76             this, SLOT(WritePMT(ProgramMapTable*)));
    77 }
    78 
    79 FirewireRecorder::~FirewireRecorder()
    80 {
    81    Close();
    82    if (_mpeg_stream_data)
    83    {
    84        delete _mpeg_stream_data;
    85        _mpeg_stream_data = NULL;
    86    }
    87 }
    88 
    89 void FirewireRecorder::deleteLater(void)
    90 {
    91     Close();
    92     DTVRecorder::deleteLater();
    93 }
    94 
    9562bool FirewireRecorder::Open(void)
    9663{
    9764     if (isopen)
    9865         return true;
    9966
    100      if (!_mpeg_stream_data)
    101          return false;
    102 
    10367     VERBOSE(VB_RECORD, LOC +
    10468             QString("Initializing Port: %1, Node: %2, Speed: %3")
    10569             .arg(fwport).arg(fwnode).arg(speed_to_string(fwspeed)));
     
    157121         return false;
    158122     }
    159123
    160      // Set buffer size
     124     // Set buffered packets size
    161125     size_t buffer_size = gContext->GetNumSetting("HDRingbufferSize",
    162126                                                  50 * TSPacket::SIZE);
    163      iec61883_mpeg2_set_buffers(fwmpeg, buffer_size / 2);
     127     size_t buffered_packets = min(buffer_size / 4, kMaxBufferedPackets);
     128     iec61883_mpeg2_set_buffers(fwmpeg, buffered_packets);
    164129     VERBOSE(VB_IMPORTANT, LOC +
    165              QString("Buffer size %1 KB").arg(buffer_size));
     130             QString("Buffered packets %1 (%2 KB)").
     131             arg(buffered_packets).arg(buffered_packets * 4));
    166132
    167133     // Set speed if needed.
    168134     // Probably shouldn't even allow user to set,
     
    188154     return isopen = true;
    189155}
    190156
    191 void FirewireRecorder::SetStreamData(MPEGStreamData *stream_data)
    192 {
    193     if (stream_data == _mpeg_stream_data)
    194         return;
    195 
    196     MPEGStreamData *old_data = _mpeg_stream_data;
    197     _mpeg_stream_data = stream_data;
    198     if (old_data)
    199         delete old_data;
    200 }
    201 
    202157void FirewireRecorder::Close(void)
    203158{
    204159    if (!isopen)
     
    223178    raw1394_destroy_handle(fwhandle);
    224179}
    225180
    226 void FirewireRecorder::StartRecording(void)
     181bool FirewireRecorder::grab_frames()
    227182{
    228183    struct timeval tv;
    229184    fd_set rfds;
    230185
    231     VERBOSE(VB_RECORD, LOC + "StartRecording");
     186    FD_ZERO(&rfds);
     187    FD_SET(fwfd, &rfds);
     188    tv.tv_sec = kTimeoutInSeconds;
     189    tv.tv_usec = 0;
    232190
    233     if (!Open())
     191    if (select(fwfd + 1, &rfds, NULL, NULL, &tv)  <= 0)
    234192    {
    235         _error = true;
    236         return;
     193        VERBOSE(VB_IMPORTANT, LOC +
     194                QString("No Input in %1 seconds [P:%2 N:%3] (select)")
     195                .arg(kTimeoutInSeconds).arg(fwport).arg(fwnode));
     196        return false;
    237197    }
    238198
    239     _request_recording = true;
    240     _recording = true;
    241 
    242     iec61883_mpeg2_recv_start(fwmpeg,fwchannel);
    243     lastpacket = time(NULL);
    244     while (_request_recording)
     199    int ret = raw1394_loop_iterate(fwhandle);
     200    if (ret)
    245201    {
    246        if (PauseAndWait())
    247            continue;
    248 
    249        if (time(NULL) - lastpacket > kTimeoutInSeconds)
    250        {
    251             VERBOSE(VB_IMPORTANT, LOC +
    252                     QString("No Input in %1 seconds [P:%2 N:%3] (time)")
    253                     .arg(kTimeoutInSeconds).arg(fwport).arg(fwnode));
    254 
    255             iec61883_mpeg2_recv_stop(fwmpeg);
    256             _error = true;
    257             return;
    258        }
    259 
    260        FD_ZERO(&rfds);
    261        FD_SET(fwfd, &rfds);
    262        tv.tv_sec = kTimeoutInSeconds;
    263        tv.tv_usec = 0;
    264 
    265        if (select(fwfd + 1, &rfds, NULL, NULL, &tv) > 0)
    266        {
    267            int ret = raw1394_loop_iterate(fwhandle);
    268            if (ret)
    269            {
    270                VERBOSE(VB_IMPORTANT, LOC_ERR + "libraw1394_loop_iterate() " +
    271                        QString("returned %1").arg(ret));
    272 
    273                iec61883_mpeg2_recv_stop(fwmpeg);
    274                _error = true;
    275                return; 
    276            }
    277        }
    278        else
    279        {
    280            VERBOSE(VB_IMPORTANT, LOC +
    281                    QString("No Input in %1 seconds [P:%2 N:%3] (select)")
    282                    .arg(kTimeoutInSeconds).arg(fwport).arg(fwnode));
    283 
    284            iec61883_mpeg2_recv_stop(fwmpeg);
    285            // to bad setting _error does nothing once recording has started..
    286            _error = true;
    287            return;
    288        }
     202        VERBOSE(VB_IMPORTANT, LOC_ERR + "libraw1394_loop_iterate() " +
     203                QString("returned %1").arg(ret));
     204        return false;
    289205    }
    290 
    291     iec61883_mpeg2_recv_stop(fwmpeg);
    292 
    293     VERBOSE(VB_IMPORTANT, QString("Firewire: Total dropped packets %1")
    294             .arg(iec61883_mpeg2_get_dropped(fwmpeg)));
    295 
    296     FinishRecording();
    297     _recording = false;
     206 
     207    return true;
    298208}
    299209
    300 void FirewireRecorder::WritePAT(ProgramAssociationTable *pat)
    301 {
    302     if (!pat)
    303         return;
    304 
    305     int next = (pat->tsheader()->ContinuityCounter()+1)&0xf;
    306     pat->tsheader()->SetContinuityCounter(next);
    307     BufferedWrite(*(reinterpret_cast<const TSPacket*>(pat->tsheader())));
    308 }
    309 
    310 void FirewireRecorder::WritePMT(ProgramMapTable *pmt)
    311 {
    312     if (!pmt)
    313         return;
    314 
    315     int next = (pmt->tsheader()->ContinuityCounter()+1)&0xf;
    316     pmt->tsheader()->SetContinuityCounter(next);
    317     BufferedWrite(*(reinterpret_cast<const TSPacket*>(pmt->tsheader())));
    318 }
    319 
    320 void FirewireRecorder::ProcessTSPacket(const TSPacket &tspacket)
    321 {
    322     if (tspacket.TransportError())
    323         return;
    324 
    325     if (tspacket.ScramplingControl())
    326         return;
    327 
    328     if (tspacket.HasAdaptationField())
    329         StreamData()->HandleAdaptationFieldControl(&tspacket);
    330 
    331     if (tspacket.HasPayload())
    332     {
    333         const unsigned int lpid = tspacket.PID();
    334 
    335         // Pass or reject packets based on PID, and parse info from them
    336         if (lpid == StreamData()->VideoPIDSingleProgram())
    337         {
    338             _buffer_packets = !FindKeyframes(&tspacket);
    339             BufferedWrite(tspacket);
    340         }
    341         else if (StreamData()->IsAudioPID(lpid))
    342             BufferedWrite(tspacket);
    343         else if (StreamData()->IsListeningPID(lpid))
    344             StreamData()->HandleTSTables(&tspacket);
    345         else if (StreamData()->IsWritingPID(lpid))
    346             BufferedWrite(tspacket);
    347     }
    348 
    349     lastpacket = time(NULL);
    350     _ts_stats.IncrTSPacketCount();
    351     if (0 == _ts_stats.TSPacketCount()%1000000)
    352         VERBOSE(VB_RECORD, _ts_stats.toString());
    353 }
    354 
    355 void FirewireRecorder::SetOptionsFromProfile(RecordingProfile *profile,
    356                                              const QString &videodev,
    357                                              const QString &audiodev,
    358                                              const QString &vbidev)
    359 {
    360     (void)videodev;
    361     (void)audiodev;
    362     (void)vbidev;
    363     (void)profile;
    364 }
    365 
    366210void FirewireRecorder::SetOption(const QString &name, const QString &value)
    367211{
    368212    if (name == "model")
     
    403247        fwconnection = value;
    404248    }
    405249}
    406 
    407 // documented in recorderbase.cpp
    408 bool FirewireRecorder::PauseAndWait(int timeout)
    409 {
    410     if (request_pause)
    411     {
    412         if (!paused)
    413         {
    414             iec61883_mpeg2_recv_stop(fwmpeg);
    415             paused = true;
    416             pauseWait.wakeAll();
    417             if (tvrec)
    418                 tvrec->RecorderPaused();
    419         }
    420         unpauseWait.wait(timeout);
    421     }
    422 
    423     if (!request_pause && paused)
    424     {
    425         iec61883_mpeg2_recv_start(fwmpeg, fwchannel);
    426         paused = false;
    427     }
    428 
    429     return paused;
    430 }
  • libs/libmythtv/firewirerecorder.h

     
    77#ifndef FIREWIRERECORDER_H_
    88#define FIREWIRERECORDER_H_
    99
    10 #include "dtvrecorder.h"
     10#include "firewirerecorderbase.h"
    1111#include "tsstats.h"
    1212#include <libraw1394/raw1394.h>
    1313#include <libiec61883/iec61883.h>
    14 #include <time.h>
    1514
    16 class MPEGStreamData;
    17 class ProgramAssociationTable;
    18 class ProgramMapTable;
    19 
    2015/** \class FirewireRecorder
    21  *  \brief This is a specialization of DTVRecorder used to
    22  *         handle DVB and ATSC streams from a firewire input.
     16 *  \brief Linux FirewireRecorder
    2317 *
    24  *  \sa DTVRecorder
     18 *  \sa FirewireRecorderBase
    2519 */
    26 class FirewireRecorder : public DTVRecorder
     20class FirewireRecorder : public FirewireRecorderBase
    2721{
    28   Q_OBJECT
    29     friend class MPEGStreamData;
    30     friend class TSPacketProcessor;
    3122    friend int fw_tspacket_handler(unsigned char*,int,uint,void*);
    3223
    3324  public:
    34     FirewireRecorder(TVRec *rec);
    35    ~FirewireRecorder();
     25    FirewireRecorder(TVRec *rec)
     26        : FirewireRecorderBase(rec, "FirewireRecorder"),
     27        fwport(-1),     fwchannel(-1), fwspeed(-1),   fwbandwidth(-1),
     28        fwfd(-1),       fwconnection(kConnectionP2P),
     29        fwoplug(-1),    fwiplug(-1),   fwmodel(""),   fwnode(0),
     30        fwhandle(NULL), fwmpeg(NULL),  isopen(false) { }
     31   ~FirewireRecorder() { Close(); }
    3632
    3733    // Commands
    38     void StartRecording(void);
    3934    bool Open(void);
    40     bool PauseAndWait(int timeout = 100);
    4135
    4236    // Sets
    43     void SetOptionsFromProfile(RecordingProfile *profile,
    44                                const QString &videodev,
    45                                const QString &audiodev,
    46                                const QString &vbidev);
    4737    void SetOption(const QString &name, const QString &value);
    4838    void SetOption(const QString &name, int value);
    49     void SetStreamData(MPEGStreamData*);
    5039
    51     // Gets
    52     MPEGStreamData* StreamData(void) { return _mpeg_stream_data; }
    53 
    54   public slots:
    55     void deleteLater(void);
    56     void WritePAT(ProgramAssociationTable*);
    57     void WritePMT(ProgramMapTable*);
    58        
    5940  private:
    6041    void Close(void);
    61     void ProcessTSPacket(const TSPacket &tspacket);
     42    void start() { iec61883_mpeg2_recv_start(fwmpeg, fwchannel); }
     43    void stop() { iec61883_mpeg2_recv_stop(fwmpeg); }
     44    bool grab_frames();
    6245
    6346  private:
    6447    int              fwport;
     
    7457    raw1394handle_t  fwhandle;
    7558    iec61883_mpeg2_t fwmpeg;
    7659    bool             isopen;
    77     time_t           lastpacket;
    78     MPEGStreamData  *_mpeg_stream_data;
    79     TSStats          _ts_stats; 
    8060
    81     static const int kBroadcastChannel;
    82     static const int kTimeoutInSeconds;
    83     static const int kConnectionP2P;
    84     static const int kConnectionBroadcast;
     61    static const int  kBroadcastChannel;
     62    static const int  kConnectionP2P;
     63    static const int  kConnectionBroadcast;
     64    static const uint kMaxBufferedPackets;
    8565};
    8666
    8767#endif
  • libs/libmythtv/darwinfirewirerecorder.h

     
    3737    ~DarwinFirewireRecorder();
    3838
    3939    bool Open(void);
    40     void ProcessTSPacket(const TSPacket &tspacket);
    4140
    4241    void SetOption(const QString &name, const QString &value);
    4342    void SetOption(const QString &name, int value);
  • libs/libmythtv/firewirechannel.h

     
    1111
    1212#include <qstring.h>
    1313#include "tv_rec.h"
    14 #include "channelbase.h"
     14#include "firewirechannelbase.h"
    1515#include <libavc1394/avc1394.h>
    1616
    1717using namespace std;
    1818
    19 class FirewireChannel : public ChannelBase
     19class FirewireChannel : public FirewireChannelBase
    2020{
    2121  public:
    2222    FirewireChannel(FireWireDBOptions firewire_opts, TVRec *parent);
    2323    ~FirewireChannel(void);
    2424
    25     bool Open(void);
    26     void Close(void);
     25    bool OpenFirewire(void);
     26    void CloseFirewire(void);
    2727
    2828    // Sets
    29     bool SetChannelByString(const QString &chan);
    30     void SetExternalChanger(void);   
     29    void SetExternalChanger(void);
     30    bool SetChannelByNumber(int channel);
    3131
    3232    // Gets
    3333    bool IsOpen(void) const { return isopen; }
    3434    QString GetDevice(void) const
    3535        { return QString("%1:%2").arg(fw_opts.port).arg(fw_opts.node); }
    3636
    37     // Commands
    38     bool SwitchToInput(const QString &inputname, const QString &chan);
    39     bool SwitchToInput(int newcapchannel, bool setstarting)
    40         { (void)newcapchannel; (void)setstarting; return false; }
    4137
    4238  private:
    4339    FireWireDBOptions  fw_opts;
    4440    nodeid_t           fwnode;
    4541    raw1394handle_t    fwhandle;
    46     bool               isopen;
    4742};
    4843
    4944#endif
  • libs/libmythtv/firewirechannelbase.cpp

     
    99#include "mythcontext.h"
    1010#include "firewirechannelbase.h"
    1111
    12 bool FirewireChannelBase::UseExternalChanger()
    13 {
    14     return !externalChanger[currentcapchannel].isEmpty();
    15 }
    16 
    17 FirewireChannelBase::FirewireChannelBase(TVRec *parent)
    18   : ChannelBase(parent), isopen(false)
     12bool FirewireChannelBase::SetChannelByString(const QString &chan)
    1913{
    20        
    21     isopen = false;
    22     channelnames[0] = "MPEG2TS";
    23 }
     14    inputs[currentInputID]->startChanNum = chan;
     15    curchannelname = chan;
    2416
    25 FirewireChannelBase::~FirewireChannelBase(void)
    26 {
    27     this->Close();
    28 }
     17    InputMap::const_iterator it = inputs.find(currentInputID);   
    2918
    30 bool FirewireChannelBase::SetChannelByString(const QString &chan)
    31 {
    32      inputChannel[currentcapchannel] = chan;
    33      curchannelname = chan;
     19    if (!(*it)->externalChanger.isEmpty())
     20        return ChangeExternalChannel(chan);
    3421
    35      if (this->UseExternalChanger())
    36          return ChangeExternalChannel(chan);
    37      else
    38          return isopen && SetChannelByNumber(chan.toInt());
     22    return isopen && SetChannelByNumber(chan.toInt());
    3923}
    4024
    4125bool FirewireChannelBase::Open()
    4226{
    43     if (this->UseExternalChanger())
    44     {
    45         this->SetExternalChanger();
     27    if (!InitializeInputs())
     28        return false;
     29
     30    InputMap::const_iterator it = inputs.find(currentInputID);
     31    if (!(*it)->externalChanger.isEmpty())
    4632        return true;
    47     }
    48     else
     33
     34    if (!isopen)
    4935    {
    50         if (!this->isopen)
    51             this->isopen = this->OpenFirewire();
    52         return this->isopen;
     36        isopen = OpenFirewire();
     37        return isopen;
    5338    }
     39    return true;
    5440}
    5541
    5642void FirewireChannelBase::Close()
    5743{
    58     if (this->isopen)
     44    if (isopen)
    5945        CloseFirewire();
    60     this->isopen = false;
     46    isopen = false;
    6147}
    6248   
    6349bool FirewireChannelBase::SwitchToInput(const QString &input, const QString &chan)
    6450{
    65     currentcapchannel = 0;
    66     if (channelnames.empty())
    67        channelnames[currentcapchannel] = input;
     51    int inputNum = GetInputByName(input);
     52    if (inputNum < 0)
     53        return false;
    6854
    6955    return SetChannelByString(chan);
    7056}
    71 
    72 void FirewireChannelBase::SetExternalChanger(void)
    73 {       
    74     RetrieveInputChannels(inputChannel, inputTuneTo,
    75                           externalChanger, sourceid);
    76 }
  • libs/libmythtv/tv_rec.cpp

     
    5959#endif
    6060
    6161#ifdef USING_FIREWIRE
    62 #include "firewirerecorder.h"
    63 #include "firewirechannel.h"
     62# ifdef CONFIG_DARWIN
     63#  include "darwinfirewirerecorder.h"
     64#  include "darwinfirewirechannel.h"
     65# else
     66#  include "firewirerecorder.h"
     67#  include "firewirechannel.h"
     68# endif
    6469#endif
    6570
    6671#ifdef USING_DBOX2
     
    156161    else if (genOpt.cardtype == "FIREWIRE")
    157162    {
    158163#ifdef USING_FIREWIRE
     164# ifdef CONFIG_DARWIN
     165        channel = new DarwinFirewireChannel(fwOpt, this);
     166# else
     167
    159168        channel = new FirewireChannel(fwOpt, this);
     169# endif
    160170        if (!channel->Open())
    161171            return false;
    162172        InitChannel(genOpt.defaultinput, startchannel);
     
    827837    else if (genOpt.cardtype == "FIREWIRE")
    828838    {
    829839#ifdef USING_FIREWIRE
     840# ifdef CONFIG_DARWIN
     841        recorder = new DarwinFirewireRecorder(this, this->channel);
     842# else
    830843        recorder = new FirewireRecorder(this);
    831844        recorder->SetOption("port",       fwOpt.port);
    832845        recorder->SetOption("node",       fwOpt.node);
    833846        recorder->SetOption("speed",      fwOpt.speed);
    834847        recorder->SetOption("model",      fwOpt.model);
    835848        recorder->SetOption("connection", fwOpt.connection);
     849# endif
    836850#endif // USING_FIREWIRE
    837851    }
    838852    else if (genOpt.cardtype == "DBOX2")