Ticket #2152: patch-freebox-unified-udp-v6.diff

File patch-freebox-unified-udp-v6.diff, 64.1 KB (added by mythtv@…, 18 years ago)

The unified patch

  • libs/libmythtv/freeboxsignalmonitor.cpp

     
    22
    33// MythTV headers
    44#include "mpegstreamdata.h"
     5#include "freeboxchannel.h"
     6#include "freeboxfeederwrapper.h"
    57#include "freeboxsignalmonitor.h"
    6 #include "rtspcomms.h"
    78
    89#undef DBG_SM
    910#define DBG_SM(FUNC, MSG) VERBOSE(VB_CHANNEL, \
     
    3435      dtvMonitorRunning(false)
    3536{
    3637    bool isLocked = false;
    37     if (GetChannel()->GetRTSP()->Init())
     38    FreeboxChannelInfo chaninfo = GetChannel()->GetCurrentChanInfo();
     39    if (chaninfo.isValid())
    3840    {
    39         FreeboxChannelInfo chaninfo = GetChannel()->GetCurrentChanInfo();
    40         isLocked = (chaninfo.isValid() &&
    41                     GetChannel()->GetRTSP()->Open(chaninfo.m_url));
     41        isLocked = GetChannel()->GetFeeder()->Open(chaninfo.m_url);
    4242    }
    4343
    4444    QMutexLocker locker(&statusLock);
     
    5151 */
    5252FreeboxSignalMonitor::~FreeboxSignalMonitor()
    5353{
    54     GetChannel()->GetRTSP()->RemoveListener(this);
     54    GetChannel()->GetFeeder()->RemoveListener(this);
    5555    Stop();
    5656}
    5757
     
    6363void FreeboxSignalMonitor::deleteLater(void)
    6464{
    6565    disconnect(); // disconnect signals we may be sending...
    66     GetChannel()->GetRTSP()->RemoveListener(this);
     66    GetChannel()->GetFeeder()->RemoveListener(this);
    6767    Stop();
    6868    DTVSignalMonitor::deleteLater();
    6969}
     
    7474void FreeboxSignalMonitor::Stop(void)
    7575{
    7676    DBG_SM("Stop", "begin");
    77     GetChannel()->GetRTSP()->RemoveListener(this);
     77    GetChannel()->GetFeeder()->RemoveListener(this);
    7878    SignalMonitor::Stop();
    7979    if (dtvMonitorRunning)
    8080    {
    81         GetChannel()->GetRTSP()->Stop();
     81        GetChannel()->GetFeeder()->Stop();
    8282        dtvMonitorRunning = false;
    8383        pthread_join(table_monitor_thread, NULL);
    8484    }
     
    101101
    102102    GetStreamData()->AddListeningPID(0);
    103103
    104     GetChannel()->GetRTSP()->AddListener(this);
    105     GetChannel()->GetRTSP()->Run();
    106     GetChannel()->GetRTSP()->RemoveListener(this);
     104    GetChannel()->GetFeeder()->AddListener(this);
     105    GetChannel()->GetFeeder()->Run();
     106    GetChannel()->GetFeeder()->RemoveListener(this);
    107107
    108108    dtvMonitorRunning = false;
    109109    DBG_SM("Run", "end");
    110110}
    111111
    112112void FreeboxSignalMonitor::AddData(
    113     unsigned char *data, unsigned dataSize, struct timeval)
     113    unsigned char *data, unsigned dataSize)
    114114{
    115115    GetStreamData()->ProcessData(data, dataSize);
    116116}
  • libs/libmythtv/freeboxfeederudp.cpp

     
     1/** -*- Mode: c++ -*-
     2 *  FreeboxFeederUdp
     3 *  Copyright (c) 2006 by Mike Mironov & Mickaël Remars
     4 *  Distributed as part of MythTV under GPL v2 and later.
     5 */
     6
     7#include "freeboxfeederudp.h"
     8
     9// Qt headers
     10#include <qurl.h>
     11
     12// Live555 headers
     13#include <BasicUsageEnvironment.hh>
     14#include <Groupsock.hh>
     15#include <GroupsockHelper.hh>
     16#include <BasicUDPSource.hh>
     17#include <TunnelEncaps.hh>
     18
     19// MythTV headers
     20#include "freeboxmediasink.h"
     21#include "mythcontext.h"
     22#include "tspacket.h"
     23
     24#define LOC QString("FbFeedUdp(%1):").arg(pthread_self())
     25
     26
     27FreeboxFeederUdp::FreeboxFeederUdp(StreamDataListener &listener) :
     28    FreeboxFeederLive(listener),
     29    _source(NULL),
     30    _sink(NULL)
     31{
     32    VERBOSE(VB_RECORD, LOC + "ctor -- success");
     33}
     34
     35FreeboxFeederUdp::~FreeboxFeederUdp()
     36{
     37    VERBOSE(VB_RECORD, LOC + "dtor -- begin");
     38    Close();
     39    VERBOSE(VB_RECORD, LOC + "dtor -- end");
     40}
     41
     42bool FreeboxFeederUdp::CanHandle(const QString &url) const
     43{
     44    return url.startsWith("udp://", false);
     45}
     46
     47bool FreeboxFeederUdp::Open(const QString &url)
     48{
     49    VERBOSE(VB_RECORD, LOC + "Open(\""<<url<<"\") -- begin");
     50
     51    QMutexLocker locker(&GetLock());
     52
     53    if (_source)
     54    {
     55        VERBOSE(VB_RECORD, LOC + "Open() -- end 1");
     56        return true;
     57    }
     58       
     59    QUrl parse(url);
     60    if (!parse.isValid() || !parse.hasHost() || !parse.hasPort())
     61    {
     62        VERBOSE(VB_RECORD, LOC + "Open() -- end 2");
     63        return false;
     64    }
     65       
     66    struct in_addr addr;
     67    addr.s_addr = our_inet_addr(parse.host().latin1());
     68
     69    // Begin by setting up our usage environment:
     70    if (!InitEnv())
     71        return false;
     72   
     73    Groupsock *socket = new Groupsock(GetLiveEnv(), addr, parse.port(), 0);
     74    if (!socket)
     75    {
     76        VERBOSE(VB_IMPORTANT, LOC + "Failed to create Live UDP Socket.");
     77        FreeEnv();
     78        return false;
     79    }
     80    _source = BasicUDPSource::createNew(GetLiveEnv(), socket);
     81    if (!_source)
     82    {
     83        VERBOSE(VB_IMPORTANT, LOC + "Failed to create Live UDP Source.");
     84        delete socket;
     85        FreeEnv();
     86        return false;
     87    }
     88
     89    _sink = FreeboxMediaSink::CreateNew(
     90        GetLiveEnv(), GetListener(), TSPacket::SIZE * 128*1024);
     91    if (!_sink)
     92    {
     93        VERBOSE(VB_IMPORTANT,
     94                QString("Freebox # Failed to create sink: %1")
     95                .arg(GetLiveEnv().getResultMsg()));
     96        Medium::close(_source);
     97        _source = NULL;
     98        delete socket;
     99        FreeEnv();
     100        return false;
     101    }
     102    _sink->startPlaying(*_source, NULL, NULL);
     103       
     104    VERBOSE(VB_RECORD, LOC + "Open() -- end");
     105    return true;
     106}
     107
     108void FreeboxFeederUdp::Close(void)
     109{
     110    VERBOSE(VB_RECORD, LOC + "Close() -- begin");
     111    Stop();
     112
     113    QMutexLocker locker(&GetLock());
     114
     115    if (_sink)
     116    {
     117        Medium::close(_sink);
     118        _sink = NULL;
     119    }
     120
     121    if (_source)
     122    {
     123        Groupsock *socket=_source->gs();
     124        Medium::close(_source);
     125        _source=NULL;
     126        delete socket;
     127    }
     128
     129    FreeEnv();
     130
     131    VERBOSE(VB_RECORD, LOC + "Close() -- end");
     132}
  • libs/libmythtv/streamdatalistener.h

     
     1/** -*- Mode: c++ -*-
     2 *  StreamDataListener
     3 *  Copyright (c) 2006 by Laurent Arnal, Benjamin Lerman & Mickaël Remars
     4 *  Distributed as part of MythTV under GPL v2 and later.
     5 */
     6 
     7#ifndef _STREAMDATALISTENER_H_
     8#define _STREAMDATALISTENER_H_
     9
     10
     11class StreamDataListener
     12{
     13  public:
     14    /// Callback function to add MPEG2 TS data
     15    virtual void AddData(unsigned char *data,
     16                         unsigned int   dataSize) = 0;
     17  protected:
     18    virtual ~StreamDataListener() {}
     19};
     20
     21#endif//_STREAMDATALISTENER_H_
  • libs/libmythtv/freeboxchannel.h

     
    1212
    1313#include <qmutex.h>
    1414
    15 class RTSPComms;
     15class FreeboxFeederWrapper;
    1616
    1717class FreeboxChannel : public ChannelBase
    1818{
     
    3232    FreeboxChannelInfo GetCurrentChanInfo(void) const
    3333        { return GetChanInfo(curchannelname); }
    3434
    35     RTSPComms       *GetRTSP(void)       { return m_rtsp; }
    36     const RTSPComms *GetRTSP(void) const { return m_rtsp; }
     35    FreeboxFeederWrapper       *GetFeeder(void)       { return m_feeder; }
     36    const FreeboxFeederWrapper *GetFeeder(void) const { return m_feeder; }
    3737   
    3838  private:
    3939    FreeboxChannelInfo GetChanInfo(const QString& channum,
     
    4141
    4242    QString               m_videodev;
    4343    fbox_chan_map_t       m_freeboxchannels;
    44     RTSPComms            *m_rtsp;
     44    FreeboxFeederWrapper *m_feeder;
    4545    mutable QMutex        m_lock;
    4646
    4747  private:
  • libs/libmythtv/freeboxchannelfetcher.h

     
    77// Qt headers
    88#include <qobject.h>
    99#include <qmutex.h>
     10#include <qurloperator.h>
    1011
    1112// MythTV headers
    1213#include "freeboxchannelinfo.h"
    1314
     15class FreeboxUrlFetch : public QObject
     16{
     17    Q_OBJECT
     18
     19  private:
     20    FreeboxUrlFetch(const QString& url);
     21    ~FreeboxUrlFetch();
     22
     23    QUrlOperator *op;
     24    QNetworkProtocol::State state;
     25    QString str;
     26
     27  private slots:
     28    void finished(QNetworkOperation *op);
     29    void data(const QByteArray &data,QNetworkOperation *op);
     30
     31  public:
     32    static QString fetchData(const QString &url,bool inQtThread);
     33};
     34
    1435class FreeboxChannelFetcher : public QObject
    1536{
    1637    Q_OBJECT
  • libs/libmythtv/libmythtv.pro

     
    396396    using_freebox {
    397397        HEADERS += freeboxrecorder.h           freeboxmediasink.h
    398398        HEADERS += freeboxchannel.h            freeboxchannelfetcher.h
    399         HEADERS += freeboxsignalmonitor.h      rtspcomms.h
     399        HEADERS += freeboxsignalmonitor.h
    400400        HEADERS += freeboxchannelinfo.h
     401        HEADERS += freeboxfeeder.h
     402        HEADERS += freeboxfeederlive.h
     403        HEADERS += freeboxfeederrtsp.h
     404        HEADERS += freeboxfeederudp.h
     405        HEADERS += freeboxfeederwrapper.h
     406        HEADERS += streamdatalistener.h
     407        HEADERS += timeoutedtaskscheduler.h
    401408
    402409        SOURCES += freeboxrecorder.cpp         freeboxmediasink.cpp
    403410        SOURCES += freeboxchannel.cpp          freeboxchannelfetcher.cpp
    404         SOURCES += freeboxsignalmonitor.cpp    rtspcomms.cpp
     411        SOURCES += freeboxsignalmonitor.cpp
     412        SOURCES += freeboxfeederlive.cpp
     413        SOURCES += freeboxfeederrtsp.cpp
     414        SOURCES += freeboxfeederudp.cpp
     415        SOURCES += freeboxfeederwrapper.cpp
     416        SOURCES += timeoutedtaskscheduler.cpp
    405417
    406418        DEFINES += USING_FREEBOX
    407419    }
  • libs/libmythtv/freeboxchannel.cpp

     
    1111#include "libmyth/mythcontext.h"
    1212#include "libmyth/mythdbcon.h"
    1313#include "libmythtv/freeboxchannelfetcher.h"
    14 #include "libmythtv/rtspcomms.h"
     14#include "libmythtv/freeboxfeederwrapper.h"
    1515
    1616#define LOC QString("FBChan(%1): ").arg(GetCardID())
    1717#define LOC_ERR QString("FBChan(%1), Error: ").arg(GetCardID())
     
    2020                               const QString &videodev)
    2121    : ChannelBase(parent),
    2222      m_videodev(QDeepCopy<QString>(videodev)),
    23       m_rtsp(new RTSPComms()),
     23      m_feeder(new FreeboxFeederWrapper()),
    2424      m_lock(true)
    2525{
    2626    VERBOSE(VB_CHANNEL, LOC + "ctor");
     
    2929FreeboxChannel::~FreeboxChannel()
    3030{
    3131    VERBOSE(VB_CHANNEL, LOC + "dtor -- begin");
    32     if (m_rtsp)
     32    if (m_feeder)
    3333    {
    34         delete m_rtsp;
    35         m_rtsp = NULL;
     34        delete m_feeder;
     35        m_feeder = NULL;
    3636    }
    3737    VERBOSE(VB_CHANNEL, LOC + "dtor -- end");
    3838}
     
    193193        }
    194194
    195195        // Try to map name to a channel in the map
    196         const QString name    = query.value(1).toString();
     196        const QString name = QString::fromUtf8(query.value(1).toString());
    197197        for (it = m_freeboxchannels.begin();
    198198             it != m_freeboxchannels.end(); ++it)
    199199        {
  • libs/libmythtv/freeboxfeederlive.cpp

     
     1/** -*- Mode: c++ -*-
     2 *  FreeboxFeederLive -- base class for livemedia based FreeboxFeeders
     3 *  Copyright (c) 2006 by Laurent Arnal, Benjamin Lerman & Mickaël Remars
     4 *  Distributed as part of MythTV under GPL v2 and later.
     5 */
     6
     7#include "freeboxfeederlive.h"
     8
     9#include <cassert>
     10
     11// MythTV headers
     12#include "mythcontext.h"
     13#include "timeoutedtaskscheduler.h"
     14
     15#define LOC QString("FbFeedLive(%1):").arg(pthread_self())
     16#define LOC_ERR QString("FbFeedLive(%1), Error:").arg(pthread_self())
     17
     18
     19FreeboxFeederLive::FreeboxFeederLive(StreamDataListener &listener) :
     20    _abort(0),
     21    _running(false),
     22    _live_env(NULL),
     23    _lock(false),
     24    _listener(listener)
     25{
     26}
     27
     28FreeboxFeederLive::~FreeboxFeederLive()
     29{
     30}
     31
     32bool FreeboxFeederLive::InitEnv(void)
     33{
     34    TaskScheduler *scheduler = new TimeoutedTaskScheduler(500);
     35    if (!scheduler)
     36    {
     37        VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to create Live Scheduler.");
     38        return false;
     39    }
     40
     41    assert(_live_env==NULL);
     42    _live_env = BasicUsageEnvironment::createNew(*scheduler);
     43    if (!_live_env)
     44    {
     45        VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to create Live Environment.");
     46        delete scheduler;
     47        return false;
     48    }
     49   
     50    return true;
     51}
     52
     53void FreeboxFeederLive::FreeEnv(void)
     54{
     55    if (_live_env)
     56    {
     57        TaskScheduler *scheduler = &_live_env->taskScheduler();
     58        _live_env->reclaim();
     59        _live_env = NULL;
     60        delete scheduler;
     61    }
     62}
     63
     64void FreeboxFeederLive::Run(void)
     65{
     66    VERBOSE(VB_RECORD, LOC + "Run() -- begin");
     67    _lock.lock();
     68    _running = true;
     69    _abort   = 0;
     70    _lock.unlock();
     71
     72    VERBOSE(VB_RECORD, LOC + "Run() -- loop begin");
     73    if (_live_env)
     74        _live_env->taskScheduler().doEventLoop(&_abort);
     75    VERBOSE(VB_RECORD, LOC + "Run() -- loop end");
     76
     77    _lock.lock();
     78    _running = false;
     79    _cond.wakeAll();
     80    _lock.unlock();
     81    VERBOSE(VB_RECORD, LOC + "Run() -- end");
     82}
     83
     84void FreeboxFeederLive::Stop(void)
     85{
     86    VERBOSE(VB_RECORD, LOC + "Stop() -- begin");
     87    QMutexLocker locker(&_lock);
     88    _abort = 0xFF;
     89
     90    while (_running)
     91        _cond.wait(&_lock, 500);
     92    VERBOSE(VB_RECORD, LOC + "Stop() -- end");
     93}
  • libs/libmythtv/freeboxmediasink.cpp

     
    44 *  Distributed as part of MythTV under GPL v2 and later.
    55 */
    66
    7 #include <algorithm>
    8 using namespace std;
    9 
    10 #include "mythcontext.h"
    117#include "freeboxmediasink.h"
    12 #include "rtspcomms.h"
     8#include "mythcontext.h"
     9#include "streamdatalistener.h"
    1310
    14 #define LOC QString("RTSPSink:")
    15 #define LOC_ERR QString("RTSPSink, Error:")
     11#define LOC QString("FbxSink:")
     12#define LOC_ERR QString("FbxSink, Error:")
    1613
    17 FreeboxMediaSink::FreeboxMediaSink(UsageEnvironment &pEnv,
    18                                    unsigned int      bufferSize) :
    19     MediaSink(pEnv),    fBufferSize(bufferSize),
    20     env(pEnv),          lock(true)
     14FreeboxMediaSink::FreeboxMediaSink(UsageEnvironment   &pEnv,
     15                                   StreamDataListener &listener,
     16                                   unsigned int        bufferSize) :
     17    MediaSink(pEnv),
     18    fBufferSize(bufferSize),
     19    env(pEnv),
     20    _listener(listener),
     21    lock(true)
    2122{
    2223    fBuffer = new unsigned char[fBufferSize];
    2324}
     
    3132    }
    3233}
    3334
    34 FreeboxMediaSink *FreeboxMediaSink::CreateNew(UsageEnvironment &env,
    35                                               unsigned int      bufferSize)
     35FreeboxMediaSink *FreeboxMediaSink::CreateNew(UsageEnvironment   &env,
     36                                              StreamDataListener &listener,
     37                                              unsigned int        bufferSize)
    3638{
    37     return new FreeboxMediaSink(env, bufferSize);
     39    return new FreeboxMediaSink(env, listener, bufferSize);
    3840}
    3941
    4042Boolean FreeboxMediaSink::continuePlaying(void)
     
    6163}
    6264
    6365void FreeboxMediaSink::afterGettingFrame1(unsigned int   frameSize,
    64                                           struct timeval presentationTime)
     66                                          struct timeval)
    6567{
    66     lock.lock();
    67     vector<RTSPListener*>::iterator it = listeners.begin();
    68     for (; it != listeners.end(); ++it)
    69         (*it)->AddData(fBuffer, frameSize, presentationTime);
    70     lock.unlock();
    71 
     68    _listener.AddData(fBuffer, frameSize);
    7269    continuePlaying();
    7370}
    7471
    75 void FreeboxMediaSink::AddListener(RTSPListener *item)
    76 {
    77     VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- begin");
    78     if (item)
    79     {
    80         RemoveListener(item);
    81         QMutexLocker locker(&lock);
    82         listeners.push_back(item);
    83     }
    84     VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- end");
    85 }
    86 
    87 void FreeboxMediaSink::RemoveListener(RTSPListener *item)
    88 {
    89     VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- begin 1");
    90     QMutexLocker locker(&lock);
    91     vector<RTSPListener*>::iterator it =
    92         find(listeners.begin(), listeners.end(), item);
    93     if (it != listeners.end())
    94     {
    95         *it = *listeners.rbegin();
    96         listeners.resize(listeners.size() - 1);
    97     }
    98     VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- end 6");
    99 }
    100 
    10172/* vim: set expandtab tabstop=4 shiftwidth=4: */
  • libs/libmythtv/freeboxsignalmonitor.h

     
    44#define _FREEBOXSIGNALMONITOR_H_
    55
    66#include "dtvsignalmonitor.h"
    7 #include "freeboxmediasink.h"
     7#include "streamdatalistener.h"
    88
    9 class RTSPComms;
    109class FreeboxChannel;
    1110
    12 class FreeboxSignalMonitor : public DTVSignalMonitor, public RTSPListener
     11
     12class FreeboxSignalMonitor : public DTVSignalMonitor, public StreamDataListener
    1313{
    1414    Q_OBJECT
    1515
     
    2121
    2222    void Stop(void);
    2323
    24     // implements RTSPListener
     24    // implements StreamDataListener
    2525    void AddData(unsigned char *data,
    26                  unsigned       dataSize,
    27                  struct timeval);
     26                 unsigned       dataSize);
    2827
    2928  public slots:
    3029    void deleteLater(void);
  • libs/libmythtv/freeboxfeederwrapper.cpp

     
     1/** -*- Mode: c++ -*-
     2 *  FreeboxFeederWrapper
     3 *  Copyright (c) 2006 by Mickaël Remars
     4 *  Distributed as part of MythTV under GPL v2 and later.
     5 */
     6
     7#include "freeboxfeederwrapper.h"
     8
     9#include "freeboxfeeder.h"
     10#include "freeboxfeederrtsp.h"
     11#include "freeboxfeederudp.h"
     12#include "mythcontext.h"
     13
     14#define LOC QString("FBFeed: ")
     15#define LOC_ERR QString("FBFeed, Error: ")
     16
     17
     18FreeboxFeederWrapper::FreeboxFeederWrapper() :
     19    _feeder(NULL)
     20{
     21}
     22
     23FreeboxFeederWrapper::~FreeboxFeederWrapper()
     24{
     25    if (_feeder)
     26    {
     27        _feeder->Stop();
     28        _feeder->Close();
     29        delete _feeder;
     30    }
     31}
     32
     33FreeboxFeeder* FreeboxFeederWrapper::NewFeeder(const QString      &url,
     34                                               StreamDataListener &listener)
     35{
     36    if (url.startsWith("rtsp://", false))
     37    {
     38        return new FreeboxFeederRtsp(listener);
     39    }
     40    else if (url.startsWith("udp://", false))
     41    {
     42        return new FreeboxFeederUdp(listener);
     43    }
     44       
     45    VERBOSE(VB_RECORD, LOC_ERR + QString("InitFeeder() -- unhandled url (%1)")
     46        .arg(url));
     47    return NULL;
     48}
     49
     50bool FreeboxFeederWrapper::InitFeeder(const QString &url)
     51{
     52    VERBOSE(VB_RECORD, LOC + "Init() -- begin");
     53    QMutexLocker locker(&_lock);
     54    if (_feeder && _feeder->CanHandle(url))
     55    {
     56        VERBOSE(VB_RECORD, LOC + "Init() -- end 0");
     57        return true;
     58    }
     59
     60    delete _feeder;
     61    _feeder = NewFeeder(url, *this);
     62
     63    VERBOSE(VB_RECORD, LOC + "Init() -- end 1");
     64    return _feeder != NULL;
     65}
     66
     67bool FreeboxFeederWrapper::Open(const QString& url)
     68{
     69    VERBOSE(VB_RECORD, LOC + "Open() -- begin");
     70    bool result = InitFeeder(url) && _feeder->Open(url);
     71    VERBOSE(VB_RECORD, LOC + "Open() -- end");
     72    return result;
     73}
     74
     75bool FreeboxFeederWrapper::IsOpen(void) const
     76{
     77    VERBOSE(VB_RECORD, LOC + "IsOpen() -- begin");
     78    bool result = _feeder && _feeder->IsOpen();
     79    VERBOSE(VB_RECORD, LOC + "IsOpen() -- end");
     80    return result;
     81}
     82
     83void FreeboxFeederWrapper::Close(void)
     84{
     85    VERBOSE(VB_RECORD, LOC + "Close() -- begin");
     86    if (_feeder) _feeder->Close();
     87    VERBOSE(VB_RECORD, LOC + "Close() -- end");
     88}
     89
     90void FreeboxFeederWrapper::Run(void)
     91{
     92    VERBOSE(VB_RECORD, LOC + "Run() -- begin");
     93    if (_feeder) _feeder->Run();
     94    VERBOSE(VB_RECORD, LOC + "Run() -- end");
     95}
     96
     97void FreeboxFeederWrapper::Stop(void)
     98{
     99    VERBOSE(VB_RECORD, LOC + "Stop() -- begin");
     100    if (_feeder) _feeder->Stop();
     101    VERBOSE(VB_RECORD, LOC + "Stop() -- end");
     102}
     103
     104void FreeboxFeederWrapper::AddListener(StreamDataListener *item)
     105{
     106    VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- begin");
     107    if (!item)
     108    {
     109        VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- end 0");
     110        return;
     111    }
     112
     113    QMutexLocker locker(&_lock);
     114    std::vector<StreamDataListener*>::iterator it =
     115        find(_listeners.begin(), _listeners.end(), item);
     116    if (it == _listeners.end()) // avoid duplicates
     117        _listeners.push_back(item);
     118
     119    VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- end 1");
     120}
     121
     122void FreeboxFeederWrapper::RemoveListener(StreamDataListener *item)
     123{
     124    VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- begin");
     125    QMutexLocker locker(&_lock);
     126    std::vector<StreamDataListener*>::iterator it =
     127        find(_listeners.begin(), _listeners.end(), item);
     128
     129    if (it == _listeners.end())
     130    {
     131        VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- end (not found)");
     132        return;
     133    }
     134
     135    // remove from local list..
     136    *it = *_listeners.rbegin();
     137    _listeners.resize(_listeners.size() - 1);
     138    VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- end (ok, removed)");
     139}
     140
     141void FreeboxFeederWrapper::AddData(unsigned char *data, unsigned int dataSize)
     142{
     143    QMutexLocker locker(&_lock);
     144    std::vector<StreamDataListener*>::iterator it = _listeners.begin();
     145    std::vector<StreamDataListener*>::iterator end = _listeners.end();
     146    for( ; it!=end ; ++it )
     147        (*it)->AddData(data, dataSize);
     148}
  • libs/libmythtv/freeboxchannelfetcher.cpp

     
    44#include <cmath>
    55#include <unistd.h>
    66
     7// Qt headers
     8#include <qnetwork.h>
     9#include <qapplication.h>
     10
    711// MythTV headers
    812#include "mythcontext.h"
    913#include "httpcomms.h"
     
    2125static bool parse_extinf(const QString &data,
    2226                         QString &channum, QString &name);
    2327
     28FreeboxUrlFetch::FreeboxUrlFetch(const QString& url)
     29    :   op(new QUrlOperator(url)),
     30    state(QNetworkProtocol::StInProgress),
     31    str("")
     32{
     33    connect(op,   SIGNAL( finished(QNetworkOperation *)),
     34            this, SLOT(   finished(QNetworkOperation *)));
     35    connect(op,   SIGNAL( data(const QByteArray &,QNetworkOperation *)),
     36            this, SLOT(   data(const QByteArray &,QNetworkOperation *)));
     37    op->get();
     38}
     39
     40FreeboxUrlFetch::~FreeboxUrlFetch()
     41{
     42    disconnect();
     43    delete op;
     44    op=NULL;
     45}
     46
     47void FreeboxUrlFetch::finished(QNetworkOperation *op)
     48{
     49    state = op->state();
     50}
     51
     52void FreeboxUrlFetch::data(const QByteArray &data,QNetworkOperation *op)
     53{
     54    if (!data.isNull())
     55        str += QString::fromUtf8(data.data(),data.size());
     56    state = op->state();
     57}
     58
     59QString FreeboxUrlFetch::fetchData(const QString &url,bool inQtThread)
     60{
     61    FreeboxUrlFetch obj(url);
     62    while(obj.state==QNetworkProtocol::StWaiting ||
     63            obj.state==QNetworkProtocol::StInProgress)
     64    {
     65        if (inQtThread)
     66            qApp->processEvents();
     67        usleep(1000);
     68    }
     69    if (obj.state==QNetworkProtocol::StDone)
     70        return obj.str;
     71    else // QNetworkProtocol::StFailed || QNetworkProtocol::StStopped
     72        return QString::null;
     73}
     74
     75
    2476FreeboxChannelFetcher::FreeboxChannelFetcher(unsigned _sourceid,
    2577                                             unsigned _cardid) :
    2678    sourceid(_sourceid),    cardid(_cardid),
     
    177229QString FreeboxChannelFetcher::DownloadPlaylist(const QString &url,
    178230                                                bool inQtThread)
    179231{
    180     QString redirected_url = url;
     232    if (url.startsWith("http:")) {
     233        // Use Myth HttpComms for http URLs
     234        QString redirected_url = url;
    181235
    182     QString tmp = HttpComms::getHttp(
    183         redirected_url,
    184         10000 /* ms        */, 3     /* retries      */,
    185         3     /* redirects */, true  /* allow gzip   */,
    186         NULL  /* login     */, inQtThread);
     236        QString tmp = HttpComms::getHttp(
     237            redirected_url,
     238            10000 /* ms        */, 3     /* retries      */,
     239            3     /* redirects */, true  /* allow gzip   */,
     240            NULL  /* login     */, inQtThread);
    187241
    188     if (redirected_url != url)
    189     {
    190         VERBOSE(VB_CHANNEL, QString("Channel URL redirected to %1")
    191                 .arg(redirected_url));
    192     }
     242        if (redirected_url != url)
     243        {
     244            VERBOSE(VB_CHANNEL, QString("Channel URL redirected to %1")
     245                    .arg(redirected_url));
     246        }
    193247
    194     return QString::fromUtf8(tmp);
     248        return QString::fromUtf8(tmp);
     249    } else
     250        return FreeboxUrlFetch::fetchData(url,inQtThread);
    195251}
    196252
    197253static uint estimate_number_of_channels(const QString &rawdata)
  • libs/libmythtv/freeboxfeederrtsp.h

     
     1/** -*- Mode: c++ -*-
     2 *  FreeboxFeederRtsp
     3 *  Copyright (c) 2006 by Laurent Arnal, Benjamin Lerman & Mickaël Remars
     4 *  Distributed as part of MythTV under GPL v2 and later.
     5 */
     6
     7#ifndef FREEBOXFEEDERRTSP_H
     8#define FREEBOXFEEDERRTSP_H
     9
     10// MythTV headers
     11#include "freeboxfeederlive.h"
     12
     13class RTSPClient;
     14class MediaSession;
     15
     16
     17class FreeboxFeederRtsp : public FreeboxFeederLive
     18{
     19  public:
     20    explicit FreeboxFeederRtsp(StreamDataListener &listener);
     21    virtual ~FreeboxFeederRtsp();
     22
     23    bool CanHandle(const QString &url) const;
     24    bool Open(const QString &url);
     25    bool IsOpen(void) const { return _session; }
     26    void Close(void);
     27
     28  private:
     29    RTSPClient         *_rtsp_client;
     30    MediaSession       *_session;
     31
     32  private:
     33    /// avoid default copy operator
     34    FreeboxFeederRtsp& operator=(const FreeboxFeederRtsp&);
     35    /// avoid default copy constructor
     36    FreeboxFeederRtsp(const FreeboxFeederRtsp&);
     37    /// avoid default constructor
     38    FreeboxFeederRtsp();
     39};
     40
     41#endif//FREEBOXFEEDERRTSP_H
  • libs/libmythtv/freeboxrecorder.cpp

     
    88#include "mpegstreamdata.h"
    99#include "tspacket.h"
    1010#include "freeboxchannel.h"
     11#include "freeboxfeederwrapper.h"
    1112#include "freeboxrecorder.h"
    12 #include "rtspcomms.h"
    1313
    1414#define LOC QString("FBRec: ")
    1515#define LOC_ERR QString("FBRec, Error: ")
     
    2323    _channel(channel),
    2424    _stream_data(NULL)
    2525{
    26     _channel->GetRTSP()->AddListener(this);
     26    _channel->GetFeeder()->AddListener(this);
    2727}
    2828
    2929FreeboxRecorder::~FreeboxRecorder()
    3030{
    3131    StopRecording();
    32     _channel->GetRTSP()->RemoveListener(this);
     32    _channel->GetFeeder()->RemoveListener(this);
    3333}
    3434
    3535bool FreeboxRecorder::Open(void)
    3636{
    3737    VERBOSE(VB_RECORD, LOC + "Open() -- begin");
    3838
    39     if (_channel->GetRTSP()->IsOpen())
    40         _channel->GetRTSP()->Close();
     39    if (_channel->GetFeeder()->IsOpen())
     40        _channel->GetFeeder()->Close();
    4141
    4242    FreeboxChannelInfo chaninfo = _channel->GetCurrentChanInfo();
    43     if (!chaninfo.isValid())
    44     {
    45         _error = true;
    46     }
    47     else
    48     {
    49         _error = !(_channel->GetRTSP()->Init());
    50         if (!_error)
    51             _error = !(_channel->GetRTSP()->Open(chaninfo.m_url));
    52     }
     43    _error = !chaninfo.isValid()
     44          || !_channel->GetFeeder()->Open(chaninfo.m_url);
    5345
    5446    VERBOSE(VB_RECORD, LOC + "Open() -- end err("<<_error<<")");
    5547    return !_error;
     
    5850void FreeboxRecorder::Close(void)
    5951{
    6052    VERBOSE(VB_RECORD, LOC + "Close() -- begin");
    61     _channel->GetRTSP()->Stop();
    62     _channel->GetRTSP()->Close();
     53    _channel->GetFeeder()->Stop();
     54    _channel->GetFeeder()->Close();
    6355    VERBOSE(VB_RECORD, LOC + "Close() -- end");
    6456}
    6557
     
    6759{
    6860    VERBOSE(VB_RECORD, LOC + "Pause() -- begin");
    6961    DTVRecorder::Pause(clear);
    70     _channel->GetRTSP()->Stop();
    71     _channel->GetRTSP()->Close();
     62    _channel->GetFeeder()->Stop();
     63    _channel->GetFeeder()->Close();
    7264    VERBOSE(VB_RECORD, LOC + "Pause() -- end");
    7365}
    7466
    7567void FreeboxRecorder::Unpause(void)
    7668{
    7769    VERBOSE(VB_RECORD, LOC + "Unpause() -- begin");
    78     if (_recording && !_channel->GetRTSP()->IsOpen())
     70    if (_recording && !_channel->GetFeeder()->IsOpen())
    7971        Open();
     72    if (_stream_data)
     73        _stream_data->Reset(_stream_data->DesiredProgram());
    8074    DTVRecorder::Unpause();
    8175    VERBOSE(VB_RECORD, LOC + "Unpause() -- end");
    8276}
     
    9993        if (PauseAndWait())
    10094            continue;
    10195
    102         if (!_channel->GetRTSP()->IsOpen())
     96        if (!_channel->GetFeeder()->IsOpen())
    10397        {
    10498            usleep(5000);
    10599            continue;
    106100        }
    107101
    108102        // Go into main RTSP loop, feeding data to AddData
    109         _channel->GetRTSP()->Run();
     103        _channel->GetFeeder()->Run();
    110104    }
    111105
    112106    // Finish up...
     
    122116{
    123117    VERBOSE(VB_RECORD, LOC + "StopRecording() -- begin");
    124118    Pause();
    125     _channel->GetRTSP()->Close();
     119    _channel->GetFeeder()->Close();
    126120
    127121    _request_recording = false;
    128122    while (_recording)
     
    153147// AddData : feed data from RTSP flow to mythtv
    154148// ===================================================
    155149void FreeboxRecorder::AddData(unsigned char *data,
    156                               unsigned       dataSize,
    157                               struct timeval)
     150                              unsigned       dataSize)
    158151{
    159152    unsigned int readIndex = 0;
    160153
     
    166159            return;
    167160
    168161        // Find the next TS Header in data
    169         int tsPos = FreeboxRecorder_findTSHeader(data + readIndex, dataSize);
     162        int tsPos = FreeboxRecorder_findTSHeader(data + readIndex, dataSize - readIndex);
    170163
    171164        // if no TS, something bad happens
    172165        if (tsPos == -1)
     
    184177
    185178        // Check if the next packet in buffer is complete :
    186179        // packet size is 188 bytes long
    187         if ((dataSize - tsPos) < TSPacket::SIZE)
     180        if ((dataSize - tsPos - readIndex) < TSPacket::SIZE)
    188181        {
    189182            VERBOSE(VB_IMPORTANT, LOC_ERR +
    190183                    "TS packet at stradles end of buffer.");
     
    232225
    233226void FreeboxRecorder::SetStreamData(MPEGStreamData *data)
    234227{
    235     VERBOSE(VB_RECORD, LOC + "SetStreamData()");
     228    VERBOSE(VB_RECORD, LOC + "SetStreamData("<<data<<") -- begin");
    236229    if (data == _stream_data)
     230    {
     231        VERBOSE(VB_RECORD, LOC + "SetStreamData("<<data<<") -- end 0");
    237232        return;
     233    }
    238234
    239235    MPEGStreamData *old_data = _stream_data;
    240236    _stream_data = data;
     
    243239
    244240    if (data)
    245241        data->AddMPEGSPListener(this);
     242    VERBOSE(VB_RECORD, LOC + "SetStreamData("<<data<<") -- end 1");
    246243}
    247244
    248245void FreeboxRecorder::HandleSingleProgramPAT(ProgramAssociationTable *pat)
  • libs/libmythtv/rtspcomms.cpp

     
    1 /** -*- Mode: c++ -*-
    2  *  RTSPComms
    3  *  Copyright (c) 2006 by Laurent Arnal, Benjamin Lerman & Mickaël Remars
    4  *  Distributed as part of MythTV under GPL v2 and later.
    5  */
    6 
    7 #include "rtspcomms.h"
    8 
    9 // Live555 headers
    10 #include <RTSPClient.hh>
    11 #include <BasicUsageEnvironment.hh>
    12 #include <MediaSession.hh>
    13 
    14 // MythTV headers
    15 #include "freeboxmediasink.h"
    16 #include "mythcontext.h"
    17 #include "tspacket.h"
    18 
    19 #define LOC QString("RTSPData:")
    20 #define LOC_ERR QString("RTSPData, Error:")
    21 
    22 // ============================================================================
    23 // RTSPData : Helper class use for static Callback handler
    24 // ============================================================================
    25 class RTSPData
    26 {
    27   public:
    28     RTSPData(MediaSubsession *pMediaSubSession) :
    29         mediaSubSession(pMediaSubSession)
    30     {
    31     }
    32 
    33     void SubsessionAfterPlayingCB(void);
    34     void SubsessionByeHandlerCB(void);
    35 
    36   private:
    37     MediaSubsession *mediaSubSession;
    38 };
    39 
    40 void RTSPData::SubsessionAfterPlayingCB(void)
    41 {
    42     MediaSubsession *subsession = mediaSubSession;
    43     Medium::close(subsession->sink);
    44     subsession->sink = NULL;
    45 
    46     MediaSession &session = subsession->parentSession();
    47     MediaSubsessionIterator iter(session);
    48 
    49     while ((subsession = iter.next())) /* <- extra braces for pedantic gcc */
    50     {
    51         if (subsession->sink)
    52             return;
    53     }
    54 }
    55 
    56 static void sub_after_playing_cb(void *clientData)
    57 {
    58     ((RTSPData*)clientData)->SubsessionAfterPlayingCB();
    59 }
    60 
    61 void RTSPData::SubsessionByeHandlerCB(void)
    62 {
    63     SubsessionAfterPlayingCB();
    64 }
    65 
    66 static void sub_bye_handler_cb(void *clientData)
    67 {
    68     ((RTSPData*)clientData)->SubsessionByeHandlerCB();
    69 }
    70 
    71 RTSPComms::RTSPComms() :
    72     _abort(0),          _running(false),
    73     _live_env(NULL),    _rtsp_client(NULL),
    74     _session(NULL),     _lock(false)
    75 {
    76     //Init();
    77 }
    78 
    79 RTSPComms::~RTSPComms()
    80 {
    81     VERBOSE(VB_RECORD, LOC + "dtor -- begin");
    82     //Stop();
    83     Close();
    84     //Deinit();
    85     VERBOSE(VB_RECORD, LOC + "dtor -- end");
    86 }
    87 
    88 bool RTSPComms::Init(void)
    89 {
    90     VERBOSE(VB_RECORD, LOC + "Init() -- begin");
    91     QMutexLocker locker(&_lock);
    92 
    93     if (_rtsp_client)
    94         return true;
    95 
    96     // Begin by setting up our usage environment:
    97     TaskScheduler *scheduler = BasicTaskScheduler::createNew();
    98     if (!scheduler)
    99     {
    100         VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to create Live Scheduler.");
    101         return false;
    102     }
    103 
    104     _live_env = BasicUsageEnvironment::createNew(*scheduler);
    105     if (!_live_env)
    106     {
    107         VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to create Live Environment.");
    108         delete scheduler;
    109         return false;
    110     }
    111 
    112     // Create our client object:
    113     _rtsp_client = RTSPClient::createNew(*_live_env, 0, "myRTSP", 0);
    114 
    115     if (!_rtsp_client)
    116     {
    117         VERBOSE(VB_IMPORTANT, LOC_ERR +
    118                 QString("Failed to create RTSP client: %1")
    119                 .arg(_live_env->getResultMsg()));
    120 
    121         _live_env->reclaim();
    122         _live_env = NULL;
    123         delete scheduler;
    124     }
    125 
    126     VERBOSE(VB_RECORD, LOC + "Init() -- end");
    127     return _rtsp_client;
    128 }
    129 
    130 void RTSPComms::Deinit(void)
    131 {
    132     VERBOSE(VB_RECORD, LOC + "Deinit() -- begin");
    133 
    134     if (_session)
    135         Close();
    136 
    137     if (_rtsp_client)
    138     {
    139         Medium::close(_rtsp_client);
    140         _rtsp_client = NULL;
    141     }
    142 
    143     if (_live_env)
    144     {
    145         TaskScheduler *scheduler = &_live_env->taskScheduler();
    146         _live_env->reclaim();
    147         _live_env = NULL;
    148         delete scheduler;
    149     }
    150     VERBOSE(VB_RECORD, LOC + "Deinit() -- end");
    151 }
    152 
    153 bool RTSPComms::Open(const QString &url)
    154 {
    155     VERBOSE(VB_RECORD, LOC + "Open() -- begin");
    156 
    157     if (!Init())
    158         return false;
    159 
    160     QMutexLocker locker(&_lock);
    161 
    162     // Setup URL for the current session
    163     char *sdpDescription = _rtsp_client->describeURL(url);
    164     _rtsp_client->describeStatus();
    165 
    166     if (!sdpDescription)
    167     {
    168         VERBOSE(VB_IMPORTANT, LOC + QString(
    169                     "Failed to get a SDP "
    170                     "description from URL: %1 %2")
    171                 .arg(url).arg(_live_env->getResultMsg()));
    172         return false;
    173     }
    174 
    175     // Create a media session object from this SDP description:
    176     _session = MediaSession::createNew(*_live_env, sdpDescription);
    177 
    178     delete[] sdpDescription;
    179 
    180     if (!_session)
    181     {
    182         VERBOSE(VB_IMPORTANT, LOC +
    183                 QString("Failed to create MediaSession: %1")
    184                 .arg(_live_env->getResultMsg()));
    185         return false;
    186     }
    187     else if (!_session->hasSubsessions())
    188     {
    189         VERBOSE(VB_IMPORTANT, LOC +
    190                 "This session has no media subsessions");
    191         Close();
    192         return false;
    193     }
    194 
    195     // Then, setup the "RTPSource"s for the session:
    196     MediaSubsessionIterator iter(*_session);
    197     MediaSubsession *subsession;
    198     bool madeProgress = false;
    199 
    200     while ((subsession = iter.next())) /* <- extra braces for pedantic gcc */
    201     {
    202         if (!subsession->initiate(-1))
    203         {
    204             VERBOSE(VB_IMPORTANT, LOC +
    205                     QString("Can't create receiver for: "
    206                             "%1 / %2 subsession: %3")
    207                     .arg(subsession->mediumName())
    208                     .arg(subsession->codecName())
    209                     .arg(_live_env->getResultMsg()));
    210         }
    211         else
    212         {
    213             madeProgress = true;
    214 
    215             if (subsession->rtpSource() != NULL)
    216             {
    217                 unsigned const thresh = 1000000; // 1 second
    218                 subsession->rtpSource()->
    219                     setPacketReorderingThresholdTime(thresh);
    220             }
    221         }
    222     }
    223 
    224     if (!madeProgress)
    225         return false;
    226 
    227     // Perform additional 'setup' on each subsession, before playing them:
    228     madeProgress = false;
    229     iter.reset();
    230     while ((subsession = iter.next()) != NULL)
    231     {
    232         if (subsession->clientPortNum() == 0)
    233             continue; // port # was not set
    234 
    235         if (_rtsp_client->setupMediaSubsession(*subsession, false, false))
    236         {
    237             madeProgress = true;
    238         }
    239         else
    240         {
    241             VERBOSE(VB_IMPORTANT, LOC +
    242                     QString("Failed to setup: %1 %2 : %3")
    243                     .arg(subsession->mediumName())
    244                     .arg(subsession->codecName())
    245                     .arg(_live_env->getResultMsg()));
    246         }
    247     }
    248 
    249     if (!madeProgress)
    250         return false;
    251 
    252     // Create and start "FileSink"s for each subsession:
    253     // FileSink while receive Mpeg2 TS Data & will feed them to mythtv
    254     madeProgress = false;
    255     iter.reset();
    256 
    257     while ((subsession = iter.next())) /* <- extra braces for pedantic gcc */
    258     {
    259         if (!subsession->readSource())
    260             continue; // was not initiated
    261 
    262         FreeboxMediaSink *freeboxMediaSink = FreeboxMediaSink::CreateNew(
    263             *_live_env, TSPacket::SIZE * 128*1024);
    264 
    265         subsession->sink = freeboxMediaSink;
    266         if (!subsession->sink)
    267         {
    268             VERBOSE(VB_IMPORTANT,
    269                     QString("Freebox # Failed to create sink: %1")
    270                     .arg(_live_env->getResultMsg()));
    271         }
    272 
    273         vector<RTSPListener*>::iterator it = _listeners.begin();
    274         for (; it != _listeners.end(); ++it)
    275             freeboxMediaSink->AddListener(*it);
    276 
    277         subsession->sink->startPlaying(*(subsession->readSource()),
    278                                        sub_after_playing_cb,
    279                                        new RTSPData(subsession));
    280 
    281         if (subsession->rtcpInstance())
    282         {
    283             subsession->rtcpInstance()->setByeHandler(
    284                 sub_bye_handler_cb, new RTSPData(subsession));
    285         }
    286 
    287         madeProgress = true;
    288     }
    289 
    290     if (!madeProgress)
    291         return false;
    292 
    293     // Setup player
    294     if (!(_rtsp_client->playMediaSession(*_session)))
    295     {
    296         VERBOSE(VB_IMPORTANT, LOC +
    297                 QString("Failed to start playing session: %1")
    298                 .arg(_live_env->getResultMsg()));
    299         return false;
    300     }
    301 
    302     VERBOSE(VB_RECORD, LOC + "Open() -- end");
    303     return true;
    304 }
    305 
    306 void RTSPComms::Close(void)
    307 {
    308     VERBOSE(VB_RECORD, LOC + "Close() -- begin");
    309     Stop();
    310 
    311     VERBOSE(VB_RECORD, LOC + "Close() -- middle 1");
    312 
    313     _lock.lock();
    314     if (_session)
    315     {
    316         // Ensure RTSP cleanup, remove old RTSP session
    317         MediaSubsessionIterator iter(*_session);
    318         MediaSubsession *subsession;
    319         while ((subsession = iter.next())) /*<-extra braces for pedantic gcc*/
    320         {
    321             Medium::close(subsession->sink);
    322             subsession->sink = NULL;
    323         }
    324 
    325         _rtsp_client->teardownMediaSession(*_session);
    326 
    327         // Close all RTSP descriptor
    328         Medium::close(_session);
    329         _session = NULL;
    330     }
    331     _lock.unlock();
    332 
    333     VERBOSE(VB_RECORD, LOC + "Close() -- middle 2");
    334 
    335     Deinit();
    336     VERBOSE(VB_RECORD, LOC + "Close() -- end");
    337 }
    338 
    339 void RTSPComms::Run(void)
    340 {
    341     VERBOSE(VB_RECORD, LOC + "Run() -- begin");
    342     _lock.lock();
    343     _running = true;
    344     _abort   = 0;
    345     _lock.unlock();
    346 
    347     VERBOSE(VB_RECORD, LOC + "Run() -- loop begin");
    348     if (_live_env)
    349         _live_env->taskScheduler().doEventLoop(&_abort);
    350     VERBOSE(VB_RECORD, LOC + "Run() -- loop end");
    351 
    352     _lock.lock();
    353     _running = false;
    354     _cond.wakeAll();
    355     _lock.unlock();
    356     VERBOSE(VB_RECORD, LOC + "Run() -- end");
    357 }
    358 
    359 void RTSPComms::Stop(void)
    360 {
    361     VERBOSE(VB_RECORD, LOC + "Stop() -- begin");
    362     QMutexLocker locker(&_lock);
    363     _abort = 0xFF;
    364 
    365     while (_running)
    366         _cond.wait(&_lock, 500);
    367     VERBOSE(VB_RECORD, LOC + "Stop() -- end");
    368 }
    369 
    370 void RTSPComms::AddListener(RTSPListener *item)
    371 {
    372     VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- begin");
    373     if (!item)
    374     {
    375         VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- end 0");
    376         return;
    377     }
    378 
    379     // avoid duplicates
    380     RemoveListener(item);
    381 
    382     // add to local list
    383     QMutexLocker locker(&_lock);
    384     _listeners.push_back(item);
    385 
    386     // if there is a session, add to each subsession->sink
    387     if (!_session)
    388     {
    389         VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- end 1");
    390         return;
    391     }
    392 
    393     MediaSubsessionIterator mit(*_session);
    394     MediaSubsession *subsession;
    395     while ((subsession = mit.next())) /* <- extra braces for pedantic gcc */
    396     {
    397         FreeboxMediaSink *sink = NULL;
    398         if ((sink = dynamic_cast<FreeboxMediaSink*>(subsession->sink)))
    399             sink->AddListener(item);
    400     }
    401     VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- end 2");
    402 }
    403 
    404 void RTSPComms::RemoveListener(RTSPListener *item)
    405 {
    406     VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- begin");
    407     QMutexLocker locker(&_lock);
    408     vector<RTSPListener*>::iterator it =
    409         find(_listeners.begin(), _listeners.end(), item);
    410 
    411     if (it == _listeners.end())
    412     {
    413         VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- end 1");
    414         return;
    415     }
    416 
    417     // remove from local list..
    418     *it = *_listeners.rbegin();
    419     _listeners.resize(_listeners.size() - 1);
    420 
    421     // if there is a session, remove from each subsession->sink
    422     if (!_session)
    423     {
    424         VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- end 2");
    425         return;
    426     }
    427 
    428     MediaSubsessionIterator mit(*_session);
    429     MediaSubsession *subsession;
    430     while ((subsession = mit.next())) /* <- extra braces for pedantic gcc */
    431     {
    432         FreeboxMediaSink *sink = NULL;
    433         if ((sink = dynamic_cast<FreeboxMediaSink*>(subsession->sink)))
    434             sink->RemoveListener(item);
    435     }
    436     VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- end 3");
    437 }
  • libs/libmythtv/timeoutedtaskscheduler.cpp

     
     1/** -*- Mode: c++ -*-
     2 *  TimeoutedTaskScheduler
     3 *  Copyright (c) 2006 by Mike Mironov
     4 *  Distributed as part of MythTV under GPL v2 and later.
     5 */
     6
     7#include "timeoutedtaskscheduler.h"
     8
     9
     10TimeoutedTaskScheduler::TimeoutedTaskScheduler(unsigned maxDelayTimeMS) :
     11    _maxDelayTimeUS(maxDelayTimeMS*1000)
     12{
     13}
     14
     15void TimeoutedTaskScheduler::doEventLoop(char* watchVariable)
     16{
     17    // Repeatedly loop, handling readble sockets and timed events:
     18    while (1)
     19    {
     20        if (watchVariable != NULL && *watchVariable != 0)
     21            break;
     22        SingleStep(_maxDelayTimeUS);
     23    }
     24}
  • libs/libmythtv/freeboxfeederudp.h

     
     1/** -*- Mode: c++ -*-
     2 *  FreeboxFeederUdp
     3 *  Copyright (c) 2006 by Mike Mironov & Mickaël Remars
     4 *  Distributed as part of MythTV under GPL v2 and later.
     5 */
     6
     7#ifndef FREEBOXFEEDERUDP_H
     8#define FREEBOXFEEDERUDP_H
     9
     10// MythTV headers
     11#include "freeboxfeederlive.h"
     12
     13class BasicUDPSource;
     14class FreeboxMediaSink;
     15
     16
     17class FreeboxFeederUdp : public FreeboxFeederLive
     18{
     19  public:
     20    explicit FreeboxFeederUdp(StreamDataListener &listener);
     21    virtual ~FreeboxFeederUdp();
     22
     23    bool CanHandle(const QString &url) const;
     24    bool Open(const QString &url);
     25    bool IsOpen(void) const { return _source; }
     26    void Close(void);
     27
     28  private:
     29    BasicUDPSource     *_source;
     30    FreeboxMediaSink   *_sink;
     31
     32  private:
     33    /// avoid default copy operator
     34    FreeboxFeederUdp& operator=(const FreeboxFeederUdp&);
     35    /// avoid default copy constructor
     36    FreeboxFeederUdp(const FreeboxFeederUdp&);
     37    /// avoid default constructor
     38    FreeboxFeederUdp();
     39};
     40
     41#endif//FREEBOXFEEDERUDP_H
  • libs/libmythtv/freeboxmediasink.h

     
    77#ifndef _FREEBOXMEDIASINK_H_
    88#define _FREEBOXMEDIASINK_H_
    99
    10 #include <vector>
    11 using namespace std;
    12 
    1310#include <qmutex.h>
    1411
    1512#include <MediaSink.hh>
    1613
    17 class RTSPListener
    18 {
    19   public:
    20     /// Callback function to add MPEG2 TS data
    21     virtual void AddData(unsigned char *data,
    22                          unsigned int   dataSize,
    23                          struct timeval presentationTime) = 0;
    24   protected:
    25     virtual ~RTSPListener() {}
    26 };
     14class StreamDataListener;
    2715
     16
    2817// ============================================================================
    2918// FreeboxMediaSink : Helper class use to receive RTSP data from socket.
    3019// ============================================================================
    3120class FreeboxMediaSink : public MediaSink
    3221{
    3322  public:
    34     static FreeboxMediaSink *CreateNew(UsageEnvironment &env,
    35                                        unsigned          bufferSize);
     23    static FreeboxMediaSink *CreateNew(UsageEnvironment   &env,
     24                                       StreamDataListener &listener,
     25                                       unsigned            bufferSize);
    3626
    37     void AddListener(RTSPListener*);
    38     void RemoveListener(RTSPListener*);
    39 
    4027  protected:
    41     FreeboxMediaSink(UsageEnvironment &env,
    42                      unsigned int      bufferSize);
     28    FreeboxMediaSink(UsageEnvironment   &env,
     29                     StreamDataListener &listener,
     30                     unsigned int        bufferSize);
    4331    virtual ~FreeboxMediaSink();
    4432
    4533    virtual void afterGettingFrame1(unsigned       frameSize,
     
    5846    unsigned char         *fBuffer;
    5947    unsigned int           fBufferSize;
    6048    UsageEnvironment      &env;
    61     vector<RTSPListener*>  listeners;
     49    StreamDataListener    &_listener;
    6250    mutable QMutex         lock;
    6351
    6452  private:
  • libs/libmythtv/freeboxrecorder.h

     
    1010#include <qwaitcondition.h>
    1111
    1212#include "dtvrecorder.h"
    13 #include "freeboxmediasink.h"
     13#include "streamdatalistener.h"
    1414#include "streamlisteners.h"
    1515
    1616class FreeboxChannel;
    1717
    18 /** \brief Processes data from RTSPComms and writes it to disk.
     18/** \brief Processes data from StreamDataListener and writes it to disk.
    1919 */
    20 class FreeboxRecorder : public DTVRecorder, public RTSPListener,
     20class FreeboxRecorder : public DTVRecorder,
     21                        public StreamDataListener,
    2122                        public MPEGSingleProgramStreamListener
    2223{
    2324    friend class FreeboxMediaSink;
    24     friend class RTSPComms;
    2525
    2626  public:
    2727    FreeboxRecorder(TVRec *rec, FreeboxChannel *channel);
     
    4747
    4848    // implements RTSPListener
    4949    void AddData(unsigned char *data,
    50                  unsigned int   dataSize,
    51                  struct timeval presentationTime);
     50                 unsigned int   dataSize);
    5251
    5352    // implements MPEGSingleProgramStreamListener
    5453    void HandleSingleProgramPAT(ProgramAssociationTable *pat);
     
    5958    MPEGStreamData *_stream_data;
    6059    QWaitCondition  _cond_recording;
    6160
    62 
    6361  private:
    6462    FreeboxRecorder& operator=(const FreeboxRecorder&); //< avoid default impl
    6563    FreeboxRecorder(const FreeboxRecorder&);            //< avoid default impl
  • libs/libmythtv/timeoutedtaskscheduler.h

     
     1/** -*- Mode: c++ -*-
     2 *  TimeoutedTaskScheduler
     3 *  Copyright (c) 2006 by Mike Mironov
     4 *  Distributed as part of MythTV under GPL v2 and later.
     5 */
     6
     7#ifndef _TIMEOUTEDTASKSCHEDULER_H_
     8#define _TIMEOUTEDTASKSCHEDULER_H_
     9
     10// Live555 headers
     11#include <BasicUsageEnvironment.hh>
     12
     13
     14class TimeoutedTaskScheduler : public BasicTaskScheduler
     15{
     16  public:
     17    TimeoutedTaskScheduler(unsigned maxDelayTimeMS);
     18
     19  public:
     20    virtual void doEventLoop(char* watchVariable);
     21
     22  private:
     23    unsigned _maxDelayTimeUS;
     24};
     25
     26#endif//_TIMEOUTEDTASKSCHEDULER_H_
  • libs/libmythtv/freeboxfeeder.h

     
     1/** -*- Mode: c++ -*-
     2 *  FreeboxFeeder
     3 *  Copyright (c) 2006 by Mickaël Remars
     4 *  Distributed as part of MythTV under GPL v2 and later.
     5 */
     6
     7#ifndef FREEBOXFEEDER_H
     8#define FREEBOXFEEDER_H
     9
     10#include <qstring.h>
     11
     12class StreamDataListener;
     13
     14
     15/** \interface FreeboxFeeder
     16**  \brief This is the interface that need to be implemented to support new
     17**         protocols in the FreeboxRecorder.
     18**
     19**  To register a new implementation, it must be instanciated in
     20**  FreeboxFeederWrapper::NewFeeder().
     21**
     22**  \sa FreeboxFeederWrapper
     23*/
     24class FreeboxFeeder
     25{
     26  public:
     27    virtual ~FreeboxFeeder() {}
     28
     29    /// \brief Returns true if the feeder can handle url
     30    virtual bool CanHandle(const QString &url) const = 0;
     31
     32    /// \brief Inits the feeder and opens the stream identified by url
     33    virtual bool Open(const QString &url) = 0;
     34
     35    /// \brief Returns true if the feeder is currently open
     36    virtual bool IsOpen(void) const = 0;
     37
     38    /// \brief Closes the stream and frees resources allocated in Open()
     39    virtual void Close(void) = 0;
     40
     41    /** \brief Reads the stream and sends data to its StreamDataListener. This
     42    **         is a blocking call : it should not exit until Stop() is called.
     43    **  \sa Stop()
     44    */
     45    virtual void Run(void) = 0;
     46
     47    /** \brief Signals to the Run() function that it should stop and exit
     48    **         cleanly.
     49    **
     50    **  This function should block until Run() has finished up.
     51    **  \sa Run()
     52    */
     53    virtual void Stop(void) = 0;
     54};
     55
     56#endif//FREEBOXFEEDER_H
     57
  • libs/libmythtv/freeboxfeederrtsp.cpp

     
     1/** -*- Mode: c++ -*-
     2 *  FreeboxFeederRtsp
     3 *  Copyright (c) 2006 by Laurent Arnal, Benjamin Lerman & Mickaël Remars
     4 *  Distributed as part of MythTV under GPL v2 and later.
     5 */
     6
     7#include "freeboxfeederrtsp.h"
     8
     9// Live555 headers
     10#include <RTSPClient.hh>
     11#include <BasicUsageEnvironment.hh>
     12#include <MediaSession.hh>
     13
     14// MythTV headers
     15#include "freeboxmediasink.h"
     16#include "mythcontext.h"
     17#include "tspacket.h"
     18
     19#define LOC QString("FbFeedRtsp(%1):").arg(pthread_self())
     20#define LOC_ERR QString("FbFeedRtsp(%1), Error:").arg(pthread_self())
     21
     22// ============================================================================
     23// RTSPData : Helper class use for static Callback handler
     24// ============================================================================
     25class RTSPData
     26{
     27  public:
     28    RTSPData(MediaSubsession *pMediaSubSession) :
     29        mediaSubSession(pMediaSubSession)
     30    {
     31    }
     32
     33    void SubsessionAfterPlayingCB(void);
     34    void SubsessionByeHandlerCB(void);
     35
     36  private:
     37    MediaSubsession *mediaSubSession;
     38};
     39
     40void RTSPData::SubsessionAfterPlayingCB(void)
     41{
     42    MediaSubsession *subsession = mediaSubSession;
     43    Medium::close(subsession->sink);
     44    subsession->sink = NULL;
     45}
     46
     47static void sub_after_playing_cb(void *clientData)
     48{
     49    ((RTSPData*)clientData)->SubsessionAfterPlayingCB();
     50}
     51
     52void RTSPData::SubsessionByeHandlerCB(void)
     53{
     54    SubsessionAfterPlayingCB();
     55}
     56
     57static void sub_bye_handler_cb(void *clientData)
     58{
     59    ((RTSPData*)clientData)->SubsessionByeHandlerCB();
     60}
     61
     62
     63
     64FreeboxFeederRtsp::FreeboxFeederRtsp(StreamDataListener &listener) :
     65    FreeboxFeederLive(listener),
     66    _rtsp_client(NULL),
     67    _session(NULL)
     68{
     69    VERBOSE(VB_RECORD, LOC + "ctor -- success");
     70}
     71
     72FreeboxFeederRtsp::~FreeboxFeederRtsp()
     73{
     74    VERBOSE(VB_RECORD, LOC + "dtor -- begin");
     75    Close();
     76    VERBOSE(VB_RECORD, LOC + "dtor -- end");
     77}
     78
     79bool FreeboxFeederRtsp::CanHandle(const QString &url) const
     80{
     81    return url.startsWith("rtsp://", false);
     82}
     83
     84bool FreeboxFeederRtsp::Open(const QString &url)
     85{
     86    VERBOSE(VB_RECORD, LOC + "Open(\""<<url<<"\") -- begin");
     87
     88    QMutexLocker locker(&GetLock());
     89
     90    if (_rtsp_client)
     91    {
     92        VERBOSE(VB_RECORD, LOC + "Open() -- end 1");
     93        return true;
     94    }
     95
     96    // Begin by setting up our usage environment:
     97    if (!InitEnv())
     98        return false;
     99
     100    // Create our client object:
     101    _rtsp_client = RTSPClient::createNew(GetLiveEnv(), 0, "myRTSP", 0);
     102    if (!_rtsp_client)
     103    {
     104        VERBOSE(VB_IMPORTANT, LOC_ERR +
     105                QString("Failed to create RTSP client: %1")
     106                .arg(GetLiveEnv().getResultMsg()));
     107        FreeEnv();
     108    }
     109
     110    // Setup URL for the current session
     111    char *sdpDescription = _rtsp_client->describeURL(url);
     112    _rtsp_client->describeStatus();
     113
     114    if (!sdpDescription)
     115    {
     116        VERBOSE(VB_IMPORTANT, LOC + QString(
     117                    "Failed to get a SDP "
     118                    "description from URL: %1 %2")
     119                .arg(url).arg(GetLiveEnv().getResultMsg()));
     120        return false;
     121    }
     122
     123    // Create a media session object from this SDP description:
     124    _session = MediaSession::createNew(GetLiveEnv(), sdpDescription);
     125
     126    delete[] sdpDescription;
     127
     128    if (!_session)
     129    {
     130        VERBOSE(VB_IMPORTANT, LOC +
     131                QString("Failed to create MediaSession: %1")
     132                .arg(GetLiveEnv().getResultMsg()));
     133        return false;
     134    }
     135    else if (!_session->hasSubsessions())
     136    {
     137        VERBOSE(VB_IMPORTANT, LOC +
     138                "This session has no media subsessions");
     139        Close();
     140        return false;
     141    }
     142
     143    // Then, setup the "RTPSource"s for the session:
     144    MediaSubsessionIterator iter(*_session);
     145    MediaSubsession *subsession;
     146    bool madeProgress = false;
     147
     148    while ((subsession = iter.next())) /* <- extra braces for pedantic gcc */
     149    {
     150        if (!subsession->initiate(-1))
     151        {
     152            VERBOSE(VB_IMPORTANT, LOC +
     153                    QString("Can't create receiver for: "
     154                            "%1 / %2 subsession: %3")
     155                    .arg(subsession->mediumName())
     156                    .arg(subsession->codecName())
     157                    .arg(GetLiveEnv().getResultMsg()));
     158        }
     159        else
     160        {
     161            madeProgress = true;
     162
     163            if (subsession->rtpSource() != NULL)
     164            {
     165                unsigned const thresh = 1000000; // 1 second
     166                subsession->rtpSource()->
     167                    setPacketReorderingThresholdTime(thresh);
     168            }
     169        }
     170    }
     171
     172    if (!madeProgress)
     173        return false;
     174
     175    // Perform additional 'setup' on each subsession, before playing them:
     176    madeProgress = false;
     177    iter.reset();
     178    while ((subsession = iter.next()) != NULL)
     179    {
     180        if (subsession->clientPortNum() == 0)
     181            continue; // port # was not set
     182
     183        if (_rtsp_client->setupMediaSubsession(*subsession, false, false))
     184        {
     185            madeProgress = true;
     186        }
     187        else
     188        {
     189            VERBOSE(VB_IMPORTANT, LOC +
     190                    QString("Failed to setup: %1 %2 : %3")
     191                    .arg(subsession->mediumName())
     192                    .arg(subsession->codecName())
     193                    .arg(GetLiveEnv().getResultMsg()));
     194        }
     195    }
     196
     197    if (!madeProgress)
     198        return false;
     199
     200    // Create and start "FileSink"s for each subsession:
     201    // FileSink while receive Mpeg2 TS Data & will feed them to mythtv
     202    madeProgress = false;
     203    iter.reset();
     204
     205    while ((subsession = iter.next())) /* <- extra braces for pedantic gcc */
     206    {
     207        if (!subsession->readSource())
     208            continue; // was not initiated
     209
     210        FreeboxMediaSink *freeboxMediaSink = FreeboxMediaSink::CreateNew(
     211            GetLiveEnv(), GetListener(), TSPacket::SIZE * 128*1024);
     212
     213        subsession->sink = freeboxMediaSink;
     214        if (!subsession->sink)
     215        {
     216            VERBOSE(VB_IMPORTANT,
     217                    QString("Freebox # Failed to create sink: %1")
     218                    .arg(GetLiveEnv().getResultMsg()));
     219        }
     220
     221        subsession->sink->startPlaying(*(subsession->readSource()),
     222                                       sub_after_playing_cb,
     223                                       new RTSPData(subsession));
     224
     225        if (subsession->rtcpInstance())
     226        {
     227            subsession->rtcpInstance()->setByeHandler(
     228                sub_bye_handler_cb, new RTSPData(subsession));
     229        }
     230
     231        madeProgress = true;
     232    }
     233
     234    if (!madeProgress)
     235        return false;
     236
     237    // Setup player
     238    if (!(_rtsp_client->playMediaSession(*_session)))
     239    {
     240        VERBOSE(VB_IMPORTANT, LOC +
     241                QString("Failed to start playing session: %1")
     242                .arg(GetLiveEnv().getResultMsg()));
     243        return false;
     244    }
     245
     246    VERBOSE(VB_RECORD, LOC + "Open() -- end");
     247    return true;
     248}
     249
     250void FreeboxFeederRtsp::Close(void)
     251{
     252    VERBOSE(VB_RECORD, LOC + "Close() -- begin");
     253    Stop();
     254
     255    QMutexLocker locker(&GetLock());
     256
     257    if (_session)
     258    {
     259        // Ensure RTSP cleanup, remove old RTSP session
     260        MediaSubsessionIterator iter(*_session);
     261        MediaSubsession *subsession;
     262        while ((subsession = iter.next())) /*<-extra braces for pedantic gcc*/
     263        {
     264            Medium::close(subsession->sink);
     265            subsession->sink = NULL;
     266        }
     267
     268        _rtsp_client->teardownMediaSession(*_session);
     269
     270        // Close all RTSP descriptor
     271        Medium::close(_session);
     272        _session = NULL;
     273    }
     274
     275    if (_rtsp_client)
     276    {
     277        Medium::close(_rtsp_client);
     278        _rtsp_client = NULL;
     279    }
     280
     281    FreeEnv();
     282
     283    VERBOSE(VB_RECORD, LOC + "Close() -- end");
     284}
  • libs/libmythtv/freeboxfeederwrapper.h

     
     1/** -*- Mode: c++ -*-
     2 *  FreeboxFeederWrapper
     3 *  Copyright (c) 2006 by Mickaël Remars
     4 *  Distributed as part of MythTV under GPL v2 and later.
     5 */
     6
     7#ifndef FREEBOXFEEDERWRAPPER_H
     8#define FREEBOXFEEDERWRAPPER_H
     9
     10#include <qmutex.h>
     11#include <qstring.h>
     12#include <vector>
     13
     14#include "streamdatalistener.h"
     15
     16class FreeboxFeeder;
     17
     18
     19/** \class FreeboxFeederWrapper
     20**  \brief Handles the various implementations of FeederRecorder.
     21*/
     22class FreeboxFeederWrapper : private StreamDataListener
     23{
     24  public:
     25    FreeboxFeederWrapper();
     26    ~FreeboxFeederWrapper();
     27
     28  public:
     29    bool Open(const QString &url);
     30    bool IsOpen(void) const;
     31    void Close(void);
     32
     33    void Run(void);
     34    void Stop(void);
     35
     36    void AddListener(StreamDataListener*);
     37    void RemoveListener(StreamDataListener*);
     38   
     39  private:
     40    static FreeboxFeeder* NewFeeder(const QString      &url,
     41                                    StreamDataListener &listener);
     42    bool InitFeeder(const QString &url);
     43
     44  private: // implements StreamDataListener
     45    void AddData(unsigned char *data, unsigned int dataSize);
     46
     47  private:
     48    FreeboxFeeder *_feeder;
     49    mutable QMutex _lock; ///< Lock  used to coordinate threads
     50    std::vector<StreamDataListener*> _listeners;
     51
     52  private:
     53    /// avoid default copy operator
     54    FreeboxFeederWrapper& operator=(const FreeboxFeederWrapper&);
     55    /// avoid default copy constructor
     56    FreeboxFeederWrapper(const FreeboxFeederWrapper&);
     57};
     58
     59#endif//FREEBOXFEEDERWRAPPER_H
  • libs/libmythtv/freeboxfeederlive.h

     
     1/** -*- Mode: c++ -*-
     2 *  FreeboxFeederLive -- base class for livemedia based FreeboxFeeders
     3 *  Copyright (c) 2006 by Laurent Arnal, Benjamin Lerman & Mickaël Remars
     4 *  Distributed as part of MythTV under GPL v2 and later.
     5 */
     6
     7#ifndef _FREEBOXFEEDERLIVE_H_
     8#define _FREEBOXFEEDERLIVE_H_
     9
     10// C++ headers
     11#include <vector>
     12
     13// Qt headers
     14#include <qwaitcondition.h>
     15#include <qmutex.h>
     16
     17// Mythtv headers
     18#include "freeboxfeeder.h"
     19
     20class QString;
     21class StreamDataListener;
     22class UsageEnvironment;
     23
     24
     25class FreeboxFeederLive : public FreeboxFeeder
     26{
     27  public:
     28    explicit FreeboxFeederLive(StreamDataListener &listener);
     29
     30    void Run(void);
     31    void Stop(void);
     32   
     33  protected:
     34    virtual ~FreeboxFeederLive();
     35    bool InitEnv(void);
     36    void FreeEnv(void);
     37
     38    UsageEnvironment&   GetLiveEnv()  { return *_live_env; }
     39    QMutex&             GetLock()     { return _lock;      }
     40    StreamDataListener& GetListener() { return _listener;  }
     41
     42  private:
     43    char                _abort;
     44    bool                _running;
     45    UsageEnvironment   *_live_env;
     46    QWaitCondition      _cond;       ///< Condition  used to coordinate threads
     47    mutable QMutex      _lock;       ///< Lock  used to coordinate threads
     48    StreamDataListener &_listener;
     49
     50  private:
     51    /// avoid default copy operator
     52    FreeboxFeederLive& operator=(const FreeboxFeederLive&);
     53    /// avoid default copy constructor
     54    FreeboxFeederLive(const FreeboxFeederLive&);
     55    /// avoid default constructor
     56    FreeboxFeederLive();
     57};
     58
     59#endif//_FREEBOXFEEDERLIVE_H_
  • libs/libmythtv/rtspcomms.h

     
    1 /** -*- Mode: c++ -*-
    2  *  RTSPComms
    3  *  Copyright (c) 2006 by Laurent Arnal, Benjamin Lerman & Mickaël Remars
    4  *  Distributed as part of MythTV under GPL v2 and later.
    5  */
    6 
    7 // C++ headers
    8 #include <vector>
    9 using namespace std;
    10 
    11 // Qt headers
    12 #include <qwaitcondition.h>
    13 #include <qmutex.h>
    14 
    15 // MythTV headers
    16 #include "freeboxchannel.h"
    17 
    18 class UsageEnvironment;
    19 class RTSPClient;
    20 class MediaSession;
    21 class RTSPListener;
    22 
    23 class RTSPComms
    24 {
    25   public:
    26     RTSPComms();
    27     virtual ~RTSPComms();
    28 
    29     bool Init(void);
    30     void Deinit(void);
    31 
    32     bool Open(const QString &url);
    33     bool IsOpen(void) const { return _session; }
    34     void Close(void);
    35 
    36     void Run(void);
    37     void Stop(void);
    38 
    39     void AddListener(RTSPListener*);
    40     void RemoveListener(RTSPListener*);
    41 
    42   private:
    43 
    44     char                _abort;
    45     bool                _running;
    46     UsageEnvironment   *_live_env;
    47     RTSPClient         *_rtsp_client;
    48     MediaSession       *_session;
    49     vector<RTSPListener*> _listeners;
    50     QWaitCondition      _cond;       ///< Condition  used to coordinate threads
    51     mutable QMutex      _lock;       ///< Lock  used to coordinate threads
    52 };