Ticket #1704: patch.freebox.v1.17.9856.diff

File patch.freebox.v1.17.9856.diff, 44.2 KB (added by mythtv@…, 14 years ago)

The patch

  • configure

     
    5454lirc="yes"
    5555joystick_menu="yes"
    5656firewire_cable_box="yes"
     57freebox_box="yes"
    5758dbox2_dvb_box="yes"
    5859hdhomerun_box="yes"
    5960x11_include_path="/usr/X11R6/include"
     
    175176echo "  --disable-lirc           disable lirc support (Infrared Remotes)"
    176177echo "  --disable-joystick-menu  disable joystick menu"
    177178echo "  --disable-firewire       disable support for FireWire cable boxes"
     179echo "  --disable-freebox        disable support for Freebox"
     180echo "  --livelibdir=DIR         location of Live streaming library"
     181echo "  --liveincludedir=DIR     location of Live streaming include files"
    178182echo "  --disable-dbox2          disable support for Nokia DBOX2 DVB boxes (or compatibles)"
    179183echo "  --disable-hdhomerun      disable support for HDHomeRun boxes"
    180184echo "  --disable-v4l            disable Video4Linux support"
     
    813817  ;;
    814818  --disable-dbox2) dbox2_dvb_box="no"
    815819  ;;
     820  --enable-freebox) freebox_box="yes"
     821  ;;
     822  --disable-freebox) freebox_box="no"
     823  ;;
     824  --livelibdir=*) live_lib_dir=`echo $opt | cut -d '=' -f 2`
     825  ;;
     826  --liveincludedir=*) live_include_dir=`echo $opt | cut -d '=' -f 2`
     827  ;;
    816828  --enable-hdhomerun) hdhomerun_box="yes"
    817829  ;;
    818830  --disable-hdhomerun) hdhomerun_box="no"
     
    21052117    fi
    21062118fi
    21072119
     2120if test x"$dvd" = x"yes" ; then
     2121    if has_library libdvdnav ; then
     2122        if has_header dvdnav/dvdnav.h ; then
     2123            dvd="yes"
     2124        fi
     2125    fi
     2126fi
     2127
     2128
    21082129VENDOR_XVMC_LIBS=""
    21092130if test x"$xvmc" = x"yes"; then
    21102131    xvmc="no"
     
    22712292  echo "FireWire support $firewire_cable_box"
    22722293  echo "DVB support      $dvb [$dvb_path]"
    22732294  echo "DBox2 support    $dbox2_dvb_box"
     2295  echo "freebox support  $freebox_box"
    22742296  echo "HDHomeRun sup.   $hdhomerun_box"
    22752297fi
    22762298
     
    29172939  CCONFIG="$CCONFIG using_dbox2"
    29182940fi
    29192941
     2942if test x"$freebox_box" = x"yes" ; then
     2943  if test "x$live_lib_dir" = "x"; then
     2944    if has_library libliveMedia; then
     2945          CONFIG_LIVE_LIBS="-lliveMedia -lgroupsock -lBasicUsageEnvironment -lUsageEnvironment"
     2946        else
     2947          echo "Unable to find Live Media library."
     2948          exit 1;
     2949        fi
     2950  else
     2951    if test ! -f "$live_lib_dir/liveMedia/libliveMedia.a"; then
     2952          echo "Unable to find Live Media library."
     2953          exit 1;
     2954        fi
     2955        CONFIG_LIVE_LIBS="-L$live_lib_dir/liveMedia -L$live_lib_dir/UsageEnvironment -L$live_lib_dir/BasicUsageEnvironment -L$live_lib_dir/groupsock -lliveMedia -lgroupsock -lBasicUsageEnvironment -lUsageEnvironment"
     2956  fi
     2957  if test "x$live_include_dir" = "x"; then
     2958    if has_header liveMedia.hh; then
     2959          true
     2960        else
     2961          echo "Unable to find Live Media headers."
     2962          exit 1;
     2963        fi
     2964  else
     2965    if test -f "$live_include_dir/liveMedia/include/liveMedia.hh"; then
     2966          LIVE_INCLUDES="$live_include_dir/liveMedia/include $live_include_dir/UsageEnvironment/include $live_include_dir/BasicUsageEnvironment/include $live_include_dir/groupsock/include"
     2967        else
     2968          if test -f "$live_include_dir/liveMedia/liveMedia.hh"; then
     2969            LIVE_INCLUDES="$live_include_dir/liveMedia $live_include_dir/UsageEnvironment $live_include_dir/BasicUsageEnvironment $live_include_dir/groupsock"
     2970          else
     2971            echo "Unable to find Live Media headers."
     2972                exit 1;
     2973          fi
     2974        fi
     2975  fi
     2976  CCONFIG="$CCONFIG using_freebox"
     2977  CONFIG_DEFINES="$CONFIG_DEFINES USING_FREEBOX"
     2978  echo "CONFIG_LIVE_LIBS=$CONFIG_LIVE_LIBS" >> $MYTH_CONFIG_MAK
     2979  CONFIG_INCLUDEPATH="$CONFIG_INCLUDEPATH $LIVE_INCLUDES"
     2980fi
     2981
    29202982if test x"$hdhomerun_box" = x"yes" ; then
    29212983  CCONFIG="$CCONFIG using_hdhr"
    29222984fi
  • libs/libmythtv/freeboxchannel.h

     
     1#ifndef FREEBOXCHANNEL_H
     2#define FREEBOXCHANNEL_H
     3
     4#include "channelbase.h"
     5
     6class FreeboxDBOptions;
     7class QHttp;
     8
     9
     10
     11class FreeboxChannel : public QObject, public ChannelBase
     12{
     13    Q_OBJECT
     14  public:
     15    FreeboxChannel(TVRec *parent, FreeboxDBOptions *freebox_options, int cardid);
     16    ~FreeboxChannel(void)
     17    {
     18    }
     19
     20    bool Open();
     21    void Close();
     22    bool SwitchToInput(const QString &inputname, const QString &chan);
     23    bool SetChannelByString(const QString &chan);
     24    bool IsOpen(void) const;
     25
     26    QString GetCurrentChannelUrl();
     27
     28    bool SwitchToInput(int newcapchannel, bool setstarting)
     29    {
     30        (void)newcapchannel;
     31        (void)setstarting;
     32        return false;
     33    }
     34
     35    QString GetChannelUrlFromNumber(const QString& channelnumber);
     36    QString GetDefaultChannel();
     37
     38  signals:
     39    void ChannelChanged();
     40
     41  public slots:
     42    void HttpRequestDone(bool error);
     43
     44  private:
     45    void LoadChannels();
     46    QString normalize(QString channelName);
     47
     48    void Log(QString string);
     49
     50    QHttp                *http;
     51    FreeboxDBOptions     *m_freeboxoptions;
     52
     53    bool                  m_channelListReady;
     54    QString               m_requestChannel;
     55    QString               m_lastChannel;
     56    int                   m_cardid;
     57
     58    // the rtsp url for the current channel
     59    QString               m_currenturl;
     60
     61    // number of channel support by freebox
     62    int                   m_freeboxchannelcount;
     63
     64    // map channelNum to channel index in table
     65    QMap<int,int>         m_freeboxchannelIds;
     66
     67    // map channel index to channel url
     68    QMap<int,QString>     m_freeboxchannelUrl;
     69
     70    // map channel index to channel name
     71    QMap<int,QString>     m_freeboxchannelNames;
     72
     73    // map channel index to channel normalize name
     74    QMap<int,QString>     m_freeboxchannelNamesN;
     75};
     76
     77#endif//FREEBOXCHANNEL_H
     78
     79/* vim: set expandtab tabstop=4 shiftwidth=4: */
  • libs/libmythtv/libmythtv.pro

     
    348348    using_dbox2:SOURCES += dbox2recorder.cpp dbox2channel.cpp dbox2epg.cpp
    349349    using_dbox2:HEADERS += dbox2recorder.h dbox2channel.h dbox2epg.h
    350350    using_dbox2:DEFINES += USING_DBOX2
     351   
     352    # Support for freebox (http://adsl.free.fr/)
     353    using_freebox:SOURCES += freeboxrecorder.cpp freeboxchannel.cpp freeboxmediasink.cpp
     354    using_freebox:HEADERS += freeboxrecorder.h freeboxchannel.h freeboxmediasink.h
     355    using_freebox:DEFINES += USING_FREEBOX
    351356
    352357    # Support for HDHomeRun box
    353358    using_hdhr {
  • libs/libmythtv/freeboxchannel.cpp

     
     1/**
     2 *  FreeboxChannel
     3 *  Copyright (c) 2005 by Levent Gündogdu
     4 *  Distributed as part of MythTV under GPL v2 and later.
     5 */
     6
     7#include "freeboxchannel.h"
     8
     9#include <qhttp.h>
     10#include <qurl.h>
     11
     12
     13
     14FreeboxChannel::FreeboxChannel(TVRec *parent, FreeboxDBOptions *freebox_options, int cardid):
     15                               QObject(NULL, "FreeboxChannel"),
     16                               ChannelBase(parent),
     17                               http(new QHttp()),
     18                               m_freeboxoptions(freebox_options),
     19                               m_channelListReady(false),
     20                               m_requestChannel(""),
     21                               m_lastChannel("1"),
     22                               m_cardid(cardid),
     23                               m_freeboxchannelcount(0)
     24{
     25    connect(http, SIGNAL(done(bool)),
     26            this, SLOT(HttpRequestDone(bool)));
     27
     28    LoadChannels();
     29}
     30
     31bool FreeboxChannel::SwitchToInput(const QString &inputname, const QString &chan)
     32{
     33    int inputNum = GetInputByName(inputname);
     34    if (inputNum < 0)
     35        return false;
     36
     37    return SetChannelByString(chan);
     38}
     39
     40bool FreeboxChannel::SetChannelByString(const QString &newChan)
     41{
     42    // Delay set channel when list has not yet been retrieved
     43    if (!m_channelListReady)
     44    {
     45        VERBOSE(VB_IMPORTANT,QString("Freebox # Channel list not received yet. Will switch to channel %1 later...").arg(newChan));
     46        m_requestChannel = newChan;
     47        return true;
     48    }
     49
     50    QString chan = newChan;
     51    // If chan is empty, use DefautChannel
     52    if (chan == "")
     53    {
     54        VERBOSE(VB_IMPORTANT,QString("Freebox # Empty channel name has been provided. Getting default name."));
     55        chan = GetDefaultChannel();
     56    }
     57
     58    // update current chanel
     59    if (m_lastChannel != curchannelname)
     60        m_lastChannel = curchannelname;
     61
     62    curchannelname = chan;
     63    m_currenturl = GetChannelUrlFromNumber(curchannelname);
     64
     65    // emit signal to recorder
     66    emit ChannelChanged();
     67
     68    return true;
     69}
     70
     71QString FreeboxChannel::GetCurrentChannelUrl()
     72{
     73    return m_currenturl;
     74}
     75
     76bool FreeboxChannel::IsOpen(void) const
     77{
     78    return true;
     79}
     80
     81bool FreeboxChannel::Open(void)
     82{
     83    if (!InitializeInputs())
     84        return false;
     85
     86    return true;
     87}
     88
     89void FreeboxChannel::Close(void)
     90{
     91}
     92
     93
     94// =====================================================================================
     95//
     96//  C H A N N E L     L O A D I N G
     97// =====================================================================================
     98
     99
     100void FreeboxChannel::LoadChannels()
     101{
     102    // Request Channel list via http. Signal will be emmitted when list is ready.
     103    QUrl url( m_freeboxoptions->mrl );
     104    QHttpRequestHeader header("GET", url.path());
     105    header.setValue("Host", url.host());
     106    int port = url.hasPort() ? url.port() : 80;
     107    http->setHost(url.host(), port);
     108    http->request(header);
     109}
     110
     111
     112QString FreeboxChannel::normalize(QString channelName)
     113{
     114    // Normalize Channel name so we can try to automap channel return by freebox to channel coming from tv_grab_fr
     115    QString res;
     116    for (unsigned int i=0;i<channelName.length();i++)
     117    {
     118        QChar c = channelName[i];
     119        if (c.isSpace()) continue;
     120        c = c.lower();
     121        if (c=='é' || c=='ê' || c=='ê') c='e';
     122        if (c=='à') c='a';
     123        if (c=='i' || c=='î') c=='i';
     124        if (c=='ô') c=='o';
     125
     126        res += c;
     127    }
     128
     129    return res;
     130}
     131
     132// ==========================================================================================
     133// HttpRequestDone : Receive response to channel list request
     134//
     135// ==========================================================================================
     136void FreeboxChannel::HttpRequestDone(bool error)
     137{
     138    if (error)
     139    {
     140        VERBOSE(VB_IMPORTANT,QString("Freebox # Reading channel list failed! (%1)").arg(http->errorString()));
     141        return;
     142    }
     143
     144    QString buffer=http->readAll();
     145    m_freeboxchannelcount = 0;
     146
     147    int sepCount = 0;
     148
     149    QString header = buffer.section("\n", sepCount, sepCount);
     150    sepCount++;
     151
     152    // Verify header is ok
     153    if (header != "#EXTM3U")
     154    {
     155        VERBOSE(VB_IMPORTANT,QString("Freebox # Invalid header while retrieve channel list.!"));
     156        return;
     157    }
     158
     159    while (true)
     160    {
     161        QString line1 = buffer.section("\n", sepCount, sepCount);
     162        if (line1 == "")
     163            break;
     164
     165        sepCount++;
     166
     167        QString line2 = buffer.section("\n", sepCount, sepCount);
     168        if (line2 == "")
     169            break;
     170
     171        sepCount++;
     172
     173        // each line contains ://
     174        // header:extension,channelNum - channelName rtsp://channelUrl
     175        //#EXTINF:0,2 - France 2 rtsp://mafreebox.freebox.fr/freeboxtv/201
     176
     177        QString lineHead;
     178        QString extension;
     179        QString channelNum;
     180        QString channelName;
     181
     182        int pos = 0;
     183        int oldPos = 0;
     184
     185        pos = line1.find(":", oldPos);
     186        if (pos<0)
     187        {
     188            VERBOSE(VB_IMPORTANT,QString("Freebox # Invalid header while retrieve channel list.!"));
     189            return;
     190        }
     191        lineHead = line1.mid(0, pos);
     192
     193        if (lineHead != "#EXTINF")
     194        {
     195            VERBOSE(VB_IMPORTANT,QString("Freebox # Invalid header while retrieve channel list.!"));
     196            return;
     197        }
     198
     199        oldPos = pos + 1;
     200        pos = line1.find(",", oldPos);
     201        if (pos<0)
     202        {
     203            VERBOSE(VB_IMPORTANT,QString("Freebox # Invalid header while retrieve channel list.!"));
     204            return;
     205        }
     206        extension = line1.mid(oldPos, pos - oldPos);
     207
     208        oldPos = pos + 1;
     209        pos = line1.find(" ", oldPos);
     210        if (pos<0)
     211        {
     212            VERBOSE(VB_IMPORTANT,QString("Freebox # Invalid header while retrieve channel list.!"));
     213            return;
     214        }
     215        channelNum = line1.mid(oldPos, pos - oldPos);
     216
     217        oldPos = pos + 1;
     218        pos = line1.find("- ", oldPos);
     219        if (pos<0)
     220        {
     221            VERBOSE(VB_IMPORTANT,QString("Freebox # Invalid header while retrieve channel list.!"));
     222            return;
     223        }
     224        channelName = line1.mid(pos + 2, line1.length());
     225
     226        QString channelUrl = line2;
     227
     228        // save all this information in map for quick access
     229        bool ok;
     230        int channelNumI = channelNum.toInt( &ok, 10 );
     231
     232        QString channelNameN = normalize(channelName);
     233
     234        m_freeboxchannelIds[channelNumI] = m_freeboxchannelcount;
     235        m_freeboxchannelUrl[m_freeboxchannelcount] = channelUrl;
     236        m_freeboxchannelNames[m_freeboxchannelcount] = channelName;
     237        m_freeboxchannelNamesN[m_freeboxchannelcount] = channelNameN;
     238
     239        m_freeboxchannelcount++;
     240    }
     241
     242    // Channel list is ready.
     243    m_channelListReady = true;
     244
     245    // Change channel if delayed request is available
     246    if (m_requestChannel != "")
     247    {
     248        SetChannelByString(m_requestChannel);
     249        m_requestChannel = "";
     250    }
     251}
     252
     253
     254// ==========================================================================================
     255// GetChannelUrlFromNumber : Map a channel number to the corresponding rtsp URL
     256//
     257// ==========================================================================================
     258QString FreeboxChannel::GetChannelUrlFromNumber(const QString& channelnumber)
     259{
     260    MSqlQuery query(MSqlQuery::InitCon());
     261
     262    query.prepare("SELECT name,freqid "
     263          "FROM channel,cardinput "
     264                  "WHERE "
     265          "channel.sourceid = cardinput.sourceid AND "
     266          "cardinput.cardid = :CARDID AND "
     267                  "channel.channum = :CHANNUM");
     268
     269    query.bindValue(":CARDID", m_cardid);
     270    query.bindValue(":CHANNUM", channelnumber);
     271
     272    if (query.exec() && query.isActive() && query.size() > 0)
     273    {
     274        query.next();
     275        QString chanName = query.value(0).toString();
     276
     277        // if we have a FreqID in the table, use this as the real freebox channel number
     278        int mFreqId = query.value(1).toInt();
     279        if (mFreqId!=0)
     280        {
     281            int channelI = m_freeboxchannelIds[mFreqId];
     282            return m_freeboxchannelUrl[channelI];
     283        }
     284
     285        // if no freqID, try to map the chanName to an existing channel name
     286        for (int i=0;i<m_freeboxchannelcount;i++)
     287        {
     288            if (m_freeboxchannelNamesN[i] == chanName)
     289            {
     290                return m_freeboxchannelUrl[i];
     291            }
     292        }
     293
     294        return "";
     295    }
     296    return "";
     297}
     298
     299// ==========================================================================================
     300// GetDefaultChannel : Search for default channel
     301//
     302// ==========================================================================================
     303
     304QString FreeboxChannel::GetDefaultChannel()
     305{
     306    MSqlQuery query(MSqlQuery::InitCon());   
     307    query.prepare("SELECT channum "
     308          "FROM channel,cardinput "
     309                  "WHERE "
     310          "channel.sourceid = cardinput.sourceid AND "
     311          "cardinput.cardid = :CARDID "
     312          "ORDER BY channum limit 1");
     313
     314    query.bindValue(":CARDID", m_cardid);
     315
     316    if (query.exec() && query.isActive() && query.size() > 0)
     317    {
     318        query.next();
     319        return query.value(0).toString();
     320    }
     321    return "";
     322}
     323
     324/* vim: set expandtab tabstop=4 shiftwidth=4: */
  • libs/libmythtv/freeboxmediasink.cpp

     
     1#include "freeboxmediasink.h"
     2
     3#include "freeboxrecorder.h"
     4
     5
     6
     7FreeboxMediaSink::FreeboxMediaSink(UsageEnvironment& pEnv, FreeboxRecorder &pRecorder) :
     8    MediaSink(pEnv),
     9    env(pEnv),
     10    recorder(pRecorder)
     11{
     12    // Setup the data buffer
     13    fBufferSize = 20000;
     14    fBuffer = new unsigned char[fBufferSize];
     15}
     16
     17FreeboxMediaSink::~FreeboxMediaSink()
     18{
     19    // free the data buffer
     20    delete[] fBuffer;
     21}
     22
     23FreeboxMediaSink* FreeboxMediaSink::createNew(UsageEnvironment& env, FreeboxRecorder &pRecorder)
     24{
     25    FreeboxMediaSink* newSink = new FreeboxMediaSink(env, pRecorder);
     26    return newSink;
     27}
     28
     29Boolean FreeboxMediaSink::continuePlaying()
     30{
     31    if (fSource == NULL) return False;
     32
     33    fSource->getNextFrame(fBuffer, fBufferSize, afterGettingFrame, this, onSourceClosure, this);
     34
     35    return True;
     36}
     37
     38void FreeboxMediaSink::afterGettingFrame(void*          clientData,
     39                                    unsigned       frameSize,
     40                                    unsigned       /*numTruncatedBytes*/,
     41                                    struct timeval presentationTime,
     42                                    unsigned       /*durationInMicroseconds*/)
     43{
     44    FreeboxMediaSink* sink = (FreeboxMediaSink*)clientData;
     45    sink->afterGettingFrame1(frameSize, presentationTime);
     46}
     47
     48void FreeboxMediaSink::afterGettingFrame1(unsigned frameSize, struct timeval presentationTime)
     49{
     50    addData(fBuffer, frameSize, presentationTime);
     51    continuePlaying();
     52}
     53
     54void FreeboxMediaSink::addData(unsigned char* data, unsigned dataSize, struct timeval presentationTime)
     55{
     56    recorder.addData(data, dataSize, presentationTime);
     57}
  • libs/libmythtv/dbcheck.cpp

     
    1010#include "mythdbcon.h"
    1111
    1212/// This is the DB schema version expected by the running MythTV instance.
    13 const QString currentDatabaseVersion = "1137";
     13const QString currentDatabaseVersion = "1138";
    1414
    1515static bool UpdateDBVersionNumber(const QString &newnumber);
    1616static bool performActualUpdate(const QString updates[], QString version,
     
    22062206//"ALTER TABLE capturecard DROP COLUMN dvb_hw_decoder;" in 0.21
    22072207//"ALTER TABLE cardinput DROP COLUMN  preference;" in 0.22
    22082208
     2209  if (dbver == "1137")
     2210    {
     2211        const QString updates[] = {
     2212"INSERT INTO profilegroups SET name = 'Freebox Input', cardtype = 'Freebox', is_default = 1;",
     2213"ALTER TABLE capturecard ADD COLUMN freebox_mrl varchar(64) DEFAULT 'http://mafreebox.freebox.fr/freeboxtv/playlist.m3u';",
     2214""
     2215};
     2216
     2217        if (!performActualUpdate(updates, "1138", dbver))
     2218            return false;
     2219    }
     2220
     2221
    22092222    return true;
    22102223}
    22112224
     
    22662279"  dbox2_port int(10) unsigned NOT NULL default '31338',"
    22672280"  dbox2_httpport int(10) unsigned NOT NULL default '80',"
    22682281"  dbox2_host varchar(32) default NULL,"
     2282"  freebox_mrl varchar(64) DEFAULT 'http://mafreebox.freebox.fr/freeboxtv/playlist.m3u',"
    22692283"  signal_timeout int(11) NOT NULL default '1000',"
    22702284"  channel_timeout int(11) NOT NULL default '3000',"
    22712285"  PRIMARY KEY  (cardid)"
     
    28322846"INSERT INTO profilegroups VALUES (8,"
    28332847" 'USB Mpeg-4 Encoder (Plextor ConvertX, etc)','GO7007',1,NULL);",
    28342848"INSERT INTO profilegroups VALUES (9,'DBOX2 Input','DBOX2',1,NULL);",
     2849"INSERT INTO `profilegroups` VALUES (10,'Freebox Input','Freebox',1,NULL);",
    28352850"INSERT INTO recordingprofiles VALUES (1,'Default',NULL,NULL,1);",
    28362851"INSERT INTO recordingprofiles VALUES (2,'Live TV',NULL,NULL,1);",
    28372852"INSERT INTO recordingprofiles VALUES (3,'High Quality',NULL,NULL,1);",
  • libs/libmythtv/freeboxrecorder.cpp

     
     1/**
     2 *  FreeboxRecorder
     3 *  Copyright (c) 2005 by Levent G?u (mythtv@feature-it.com)
     4 *  Distributed as part of MythTV under GPL v2 and later.
     5 */
     6
     7#include "freeboxrecorder.h"
     8
     9#include <BasicUsageEnvironment.hh>
     10#include <MediaSession.hh>
     11#include <RTSPClient.hh>
     12
     13#include "mpeg/tspacket.h"
     14#include "freeboxchannel.h"
     15#include "freeboxmediasink.h"
     16
     17
     18
     19// ============================================================================
     20// FreeboxData : Helper class use for static Callback handler
     21// ============================================================================
     22class FreeboxData
     23{
     24  public:
     25    FreeboxData(FreeboxRecorder *pFreeboxRecorder, MediaSubsession *pMediaSubSession)
     26    {
     27        freeboxRecorder = pFreeboxRecorder;
     28        mediaSubSession = pMediaSubSession;
     29    }
     30
     31    FreeboxRecorder *freeboxRecorder;
     32    MediaSubsession *mediaSubSession;
     33};
     34
     35
     36
     37FreeboxRecorder::FreeboxRecorder(TVRec *rec, FreeboxChannel *channel) :
     38    DTVRecorder(rec),
     39    env(NULL),
     40    rtspClient(NULL),
     41    session(NULL),
     42    _abort_rtsp(0),
     43    _abort_recording(false),
     44    m_channel(channel)
     45{
     46    connect(m_channel, SIGNAL(ChannelChanged()),
     47            this,      SLOT(  ChannelChanged()));
     48}
     49
     50
     51
     52FreeboxRecorder::~FreeboxRecorder()
     53{
     54}
     55
     56
     57
     58bool FreeboxRecorder::Open()
     59{
     60    return StartRtsp();
     61}
     62
     63
     64
     65void FreeboxRecorder::Close()
     66{
     67    if (session == NULL) return;
     68
     69    // Ensure RTSP cleanup, remove old RTSP session
     70    MediaSubsessionIterator iter(*session);
     71    MediaSubsession* subsession;
     72    while ((subsession = iter.next()) != NULL)
     73    {
     74        Medium::close(subsession->sink);
     75        subsession->sink = NULL;
     76    }
     77
     78    if (session == NULL) return;
     79
     80    rtspClient->teardownMediaSession(*session);
     81
     82    // Close all RTSP descriptor
     83    Medium::close(session);
     84    Medium::close(rtspClient);
     85}
     86
     87
     88
     89void FreeboxRecorder::ChannelChanged()
     90{
     91    // Channel change, we need to close current RTSP flow, and open a new one
     92    ResetEventLoop();
     93}
     94
     95
     96
     97void FreeboxRecorder::SetOptionsFromProfile(RecordingProfile *profile,
     98                                            const QString    &videodev,
     99                                            const QString    &audiodev,
     100                                            const QString    &vbidev)
     101{
     102    (void)videodev;
     103    (void)audiodev;
     104    (void)vbidev;
     105    (void)profile;
     106}
     107
     108
     109
     110void FreeboxRecorder::StartRecording()
     111{
     112    while(!_abort_recording && Open())
     113    {
     114        _abort_rtsp = 0;
     115        _recording = true;
     116        // Go into main RTSP loop, feeding data to mythtv
     117        env->taskScheduler().doEventLoop(&_abort_rtsp); // does not return
     118
     119        // Event loop exists, the recording finish
     120        FinishRecording();
     121        _recording = false;
     122        Close();
     123    }
     124}
     125
     126void FreeboxRecorder::StopRecording(void)
     127{
     128    _abort_recording = true;
     129    ResetEventLoop();
     130}
     131
     132void FreeboxRecorder::ResetEventLoop()
     133{
     134    _abort_rtsp = ~0;
     135    while( _recording ) usleep(10000);
     136}
     137
     138// ======================================================================
     139// StartRtsp : start a new RTSP session for the current channel
     140// ======================================================================
     141bool FreeboxRecorder::StartRtsp()
     142{
     143    // Retrieve the RTSP channel URL
     144    QString url = m_channel->GetCurrentChannelUrl();
     145
     146    // Begin by setting up our usage environment:
     147    TaskScheduler* scheduler = BasicTaskScheduler::createNew();
     148    env = BasicUsageEnvironment::createNew(*scheduler);
     149
     150
     151    // Create our client object:
     152    rtspClient = RTSPClient::createNew(*env, 0, "myRTSP", 0);
     153    if (rtspClient == NULL)
     154    {
     155        VERBOSE(VB_IMPORTANT, QString("Freebox # Failed to create RTSP client: %1").arg(env->getResultMsg()));
     156        return false;
     157    }
     158
     159    // Setup URL for the current session
     160    char* sdpDescription = rtspClient->describeURL(url);
     161    rtspClient->describeStatus();
     162
     163    if (sdpDescription == NULL)
     164    {
     165        VERBOSE(VB_IMPORTANT, QString("Freebox # Failed to get a SDP description from URL: %1 %2").arg(url).arg(env->getResultMsg()));
     166        return false;
     167    }
     168
     169    // Create a media session object from this SDP description:
     170    session = MediaSession::createNew(*env, sdpDescription);
     171    delete[] sdpDescription;
     172    if (session == NULL)
     173    {
     174        VERBOSE(VB_IMPORTANT, QString("Freebox # Failed to create a MediaSession object from the SDP description: %1").arg(env->getResultMsg()));
     175        return false;
     176    }
     177    else if (!session->hasSubsessions())
     178    {
     179        VERBOSE(VB_IMPORTANT, QString("Freebox # This session has no media subsessions"));
     180        return false;
     181    }
     182
     183    // Then, setup the "RTPSource"s for the session:
     184    MediaSubsessionIterator iter(*session);
     185    MediaSubsession *subsession;
     186    Boolean madeProgress = False;
     187    while ((subsession = iter.next()) != NULL)
     188    {
     189        if (!subsession->initiate(-1))
     190        {
     191            VERBOSE(VB_IMPORTANT, QString("Freebox # Unable to create receiver for: %1 / %2 subsession: %3")
     192                    .arg(subsession->mediumName())
     193                    .arg(subsession->codecName())
     194                    .arg(env->getResultMsg()));
     195        }
     196        else
     197        {
     198            madeProgress = True;
     199
     200            if (subsession->rtpSource() != NULL)
     201            {
     202                  unsigned const thresh = 1000000; // 1 second
     203                  subsession->rtpSource()->setPacketReorderingThresholdTime(thresh);
     204            }
     205        }
     206    }
     207
     208    if (!madeProgress) return false;
     209
     210    // Perform additional 'setup' on each subsession, before playing them:
     211    madeProgress = false;
     212    iter.reset();
     213    while ((subsession = iter.next()) != NULL)
     214    {
     215        if (subsession->clientPortNum() == 0) continue; // port # was not set
     216
     217        if (rtspClient->setupMediaSubsession(*subsession, False, false))
     218        {
     219            madeProgress = True;
     220        }
     221        else
     222        {
     223            VERBOSE(VB_IMPORTANT, QString("Freebox # Failed to setup: %1 %2 : %3").arg(subsession->mediumName()).arg(subsession->codecName()).arg(env->getResultMsg()));
     224        }
     225    }
     226
     227    if (!madeProgress) return false;
     228
     229   // Create and start "FileSink"s for each subsession:
     230   // FileSink while receive Mpeg2 TS Data & will feed them to mythtv
     231    madeProgress = False;
     232    iter.reset();
     233    while ((subsession = iter.next()) != NULL)
     234    {
     235        if (subsession->readSource() == NULL) continue; // was not initiated
     236
     237        FreeboxMediaSink* freeboxMediaSink = FreeboxMediaSink::createNew(*env, *this);
     238
     239        subsession->sink = freeboxMediaSink;
     240        if (subsession->sink == NULL)
     241        {
     242            VERBOSE(VB_IMPORTANT, QString("Freebox # Failed to create sink: %1").arg(env->getResultMsg()));
     243        }
     244
     245        subsession->sink->startPlaying(*(subsession->readSource()),
     246                                       subsessionAfterPlayingCallback,
     247                                       new FreeboxData(this, subsession));
     248
     249        if (subsession->rtcpInstance() != NULL)
     250        {
     251            subsession->rtcpInstance()->setByeHandler(subsessionByeHandlerCallback,
     252                                                      new FreeboxData(this, subsession));
     253        }
     254
     255        madeProgress = True;
     256    }
     257
     258    if (!madeProgress) return false;
     259
     260    // Setup player
     261    if (!(rtspClient->playMediaSession(*session)))
     262    {
     263        VERBOSE(VB_IMPORTANT, QString("Freebox # Failed to start playing session: %1").arg(env->getResultMsg()));
     264        return false;
     265    }
     266
     267    return true;
     268}
     269
     270// ===================================================
     271// findTSHeader : find a TS Header in flow
     272// ===================================================
     273static int FreeboxRecorder_findTSHeader(const unsigned char *data, unsigned dataSize)
     274{
     275    unsigned int pos = 0;
     276    while (pos < dataSize)
     277    {
     278        if (data[pos] == 0x47)
     279            return pos;
     280        pos++;
     281    }
     282    return -1;
     283}
     284
     285// ===================================================
     286// addData : feed date from RTSP flow to mythtv
     287// ===================================================
     288void FreeboxRecorder::addData(unsigned char* data, unsigned dataSize, struct timeval)
     289{
     290    unsigned int readIndex = 0;
     291
     292    // data may be compose from more than one packet, loop to consume all data
     293    while (readIndex < dataSize)
     294    {
     295        // If recorder is pause, stop there
     296        if (PauseAndWait())
     297        {
     298            return;
     299        }
     300
     301        // Find the next TS Header in data
     302        int tsPos = FreeboxRecorder_findTSHeader(data + readIndex, dataSize);
     303
     304        // if no TS, something bad happens
     305        if (tsPos == -1)
     306        {
     307            VERBOSE(VB_IMPORTANT, QString("FREEBOX: No TS header."));
     308            break;
     309        }
     310
     311        // if TS Header not at start of data, we receive out of sync data
     312        if (tsPos > 0)
     313        {
     314            VERBOSE(VB_IMPORTANT, QString("FREEBOX: TS header at %1, not in sync.").arg(tsPos));
     315        }
     316
     317        // Check if the next packet in buffer is complete : packet size is 188 bytes long
     318        if ((dataSize - tsPos) < 188)
     319        {
     320            VERBOSE(VB_IMPORTANT, QString("FREEBOX: TS header at %1 but packet not yet complete.").arg(tsPos));
     321            break;
     322        }
     323
     324        // Cast current found TS Packet to TSPacket structure
     325        const void *newData = data + tsPos + readIndex;
     326        const TSPacket *tspacket = reinterpret_cast<const TSPacket*>(newData);
     327
     328        // Feed current packet to myth
     329        _buffer_packets = !FindKeyframes(tspacket);
     330        BufferedWrite(*tspacket);
     331
     332        // follow to next packet
     333        readIndex += tsPos + TSPacket::SIZE;
     334    }
     335}
     336
     337void FreeboxRecorder::subsessionAfterPlayingCallback(void *clientData)
     338{
     339    FreeboxData *myData = (FreeboxData*)clientData;
     340    myData->freeboxRecorder->SubsessionAfterPlaying(myData->mediaSubSession);
     341}
     342
     343void FreeboxRecorder::subsessionByeHandlerCallback(void *clientData)
     344{
     345    FreeboxData *myData = (FreeboxData*)clientData;
     346    myData->freeboxRecorder->SubsessionByeHandler(myData->mediaSubSession);
     347}
     348
     349void FreeboxRecorder::SubsessionAfterPlaying(MediaSubsession* subsession)
     350{
     351    Medium::close(subsession->sink);
     352    subsession->sink = NULL;
     353
     354    MediaSession& session = subsession->parentSession();
     355    MediaSubsessionIterator iter(session);
     356    while ((subsession = iter.next()) != NULL)
     357    {
     358        if (subsession->sink != NULL) return;
     359    }
     360}
     361
     362
     363void FreeboxRecorder::SubsessionByeHandler(MediaSubsession* subsession)
     364{
     365    SubsessionAfterPlaying(subsession);
     366}
     367
     368/* vim: set expandtab tabstop=4 shiftwidth=4: */
  • libs/libmythtv/cardutil.cpp

     
    517517
    518518    if (("FIREWIRE"  == cardtype) ||
    519519        ("DBOX2"     == cardtype) ||
     520        ("FREEBOX"   == cardtype) ||
    520521        ("HDHOMERUN" == cardtype))
    521522    {
    522523        ret += "MPEG2TS";
     
    709710                .arg(query.value(1).toString())
    710711                .arg(query.value(2).toString());
    711712    }
     713    else if (cardtype == "FREEBOX")
     714    {
     715        MSqlQuery query(MSqlQuery::InitCon());
     716        query.prepare(
     717            "SELECT freebox_mrl "
     718            "FROM capturecard "
     719            "WHERE cardid = :CARDID");
     720        query.bindValue(":CARDID", cardid);
     721
     722        if (!query.exec() || !query.isActive() || !query.next())
     723            label = "[ DB ERROR ]";
     724        else
     725            label = QString("[ FREEBOX : MRL %1 ]")
     726                .arg(query.value(0).toString());
     727    }
    712728    else if (cardtype == "HDHOMERUN")
    713729    {
    714730        MSqlQuery query(MSqlQuery::InitCon());
     
    745761
    746762    if (("FIREWIRE"  == cardtype) ||
    747763        ("DBOX2"     == cardtype) ||
     764        ("FREEBOX"   == cardtype) ||
    748765        ("HDHOMERUN" == cardtype))
    749766    {
    750767        inputs += "MPEG2TS";
  • libs/libmythtv/freeboxmediasink.h

     
     1#ifndef _FREEBOXMEDIASINK_H_
     2#define _FREEBOXMEDIASINK_H_
     3
     4#include <MediaSink.hh>
     5
     6class FreeboxRecorder;
     7
     8
     9
     10// ============================================================================
     11// FreeboxMediaSink : Helper class use to receive RTSP data from socket.
     12// ============================================================================
     13class FreeboxMediaSink: public MediaSink
     14{
     15  public:
     16    static FreeboxMediaSink* createNew(UsageEnvironment& env, FreeboxRecorder &pRecorder);
     17
     18    // Callback function when rtsp data are ready
     19    void addData(unsigned char* data, unsigned dataSize, struct timeval presentationTime);
     20
     21  protected:
     22    FreeboxMediaSink(UsageEnvironment& env, FreeboxRecorder &pRecorder);
     23    virtual ~FreeboxMediaSink();
     24
     25    static void afterGettingFrame(void*          clientData,
     26                                  unsigned       frameSize,
     27                                  unsigned       numTruncatedBytes,
     28                                  struct timeval presentationTime,
     29                                  unsigned       durationInMicroseconds);
     30    virtual void afterGettingFrame1(unsigned frameSize, struct timeval presentationTime);
     31
     32  private:
     33    virtual Boolean continuePlaying();
     34
     35    unsigned char* fBuffer;
     36    unsigned fBufferSize;
     37    UsageEnvironment &env;
     38    FreeboxRecorder &recorder;
     39    int bufferIndex;
     40};
     41
     42#endif//_FREEBOXMEDIASINK_H_
  • libs/libmythtv/videosource.cpp

     
    927927    }
    928928};
    929929
     930class FreeboxHost : public LineEditSetting, public CCSetting {
     931  public:
     932    FreeboxHost(const CaptureCard &parent):
     933        CCSetting(parent, "freebox_mrl")
     934    {
     935        setValue("http://mafreebox.freebox.fr/freeboxtv/playlist.m3u");
     936        setLabel(QObject::tr("Freebox MRL"));
     937        setHelpText(QObject::tr("The freebox Media Resource Locator (MRL)."));
     938    }
     939};
     940
    930941class HDHomeRunTunerIndex: public ComboBoxSetting, public CCSetting
    931942{
    932943  public:
     
    939950    }
    940951};
    941952
     953class FreeboxConfigurationGroup: public VerticalConfigurationGroup {
     954  public:
     955    FreeboxConfigurationGroup(CaptureCard& a_parent):
     956       ConfigurationGroup(false, true, false, false),
     957       VerticalConfigurationGroup(false, true, false, false),
     958       parent(a_parent)
     959    {
     960       setUseLabel(false);
     961       addChild(new FreeboxHost(parent));
     962    };
     963  private:
     964    CaptureCard& parent;
     965};
     966
    942967void HDHRCardInput::fillSelections(const QString&)
    943968{
    944969    clearSelections();
     
    10731098    addTarget("DBOX2",     new DBOX2ConfigurationGroup(parent));
    10741099#endif // USING_DBOX2
    10751100
     1101#ifdef USING_FREEBOX
     1102    addTarget("FREEBOX",   new FreeboxConfigurationGroup(parent));
     1103#endif // USING_FREEBOX
     1104
    10761105#ifdef USING_HDHOMERUN
    10771106    addTarget("HDHOMERUN", new HDHomeRunConfigurationGroup(parent));
    10781107#endif // USING_HDHOMERUN
     
    11901219        QObject::tr("DBox2 TCP/IP cable box"), "DBOX2");
    11911220#endif // USING_DBOX2
    11921221
     1222#ifdef USING_FREEBOX
     1223    setting->addSelection(
     1224        QObject::tr("Freebox"), "FREEBOX");
     1225#endif // USING_FREEBOX
     1226
    11931227#ifdef USING_HDHOMERUN
    11941228    setting->addSelection(
    11951229        QObject::tr("HDHomeRun DTV tuner box"), "HDHOMERUN");
  • libs/libmythtv/freeboxrecorder.h

     
     1/**
     2 *  FreeboxRecorder
     3 *  Copyright (c) 2005 by Levent Gündogdu
     4 *  Distributed as part of MythTV under GPL v2 and later.
     5 */
     6
     7#ifndef FREEBOXRECORDER_H_
     8#define FREEBOXRECORDER_H_
     9
     10#include "dtvrecorder.h"
     11
     12class FreeboxChannel;
     13class MediaSession;
     14class MediaSubsession;
     15class RTSPClient;
     16class UsageEnvironment;
     17
     18
     19
     20/**
     21 *
     22 *  Constructs a FreeboxRecorder
     23 *
     24 */
     25class FreeboxRecorder :
     26    public QObject, //FIXME see changeset #9743 for details
     27    public DTVRecorder
     28{
     29    Q_OBJECT
     30  public:
     31    FreeboxRecorder(TVRec *rec, FreeboxChannel *channel);
     32    ~FreeboxRecorder();
     33   
     34    void StartRecording(void);  //< RecorderBase
     35    void StopRecording(void);   //< DTVRecorder
     36
     37    // RecorderBase
     38    void SetOptionsFromProfile(RecordingProfile *profile,
     39                               const QString    &videodev,
     40                               const QString    &audiodev,
     41                               const QString    &vbidev);
     42
     43  public slots:
     44    void ChannelChanged();
     45
     46  private:
     47    friend class FreeboxMediaSink;
     48
     49    bool Open(); //< RecorderBase
     50    void Close();
     51
     52    static void subsessionAfterPlayingCallback(void *clientData);
     53    static void subsessionByeHandlerCallback(void *clientData);
     54    void SubsessionAfterPlaying(MediaSubsession *subsession);
     55    void SubsessionByeHandler(MediaSubsession *subsession);
     56
     57    // Callback function to add MPEG2 TS data
     58    void addData(unsigned char* data, unsigned dataSize, struct timeval presentationTime);
     59
     60    bool StartRtsp();
     61    void ResetEventLoop();
     62
     63  private:
     64    UsageEnvironment* env;
     65    RTSPClient* rtspClient;
     66    MediaSession* session;
     67
     68    // var to check if we need to abort current rtsp session
     69    char _abort_rtsp;
     70
     71    // request abort for StartRecording method
     72    bool _abort_recording;
     73
     74    // Current channel
     75    FreeboxChannel *m_channel;
     76};
     77
     78#endif//FREEBOXRECORDER_H_
     79
     80/* vim: set expandtab tabstop=4 shiftwidth=4: */
  • libs/libmythtv/tv_rec.cpp

     
    7272#include "dbox2channel.h"
    7373#endif
    7474
     75#ifdef USING_FREEBOX
     76#include "freeboxrecorder.h"
     77#include "freeboxchannel.h"
     78#endif // USING_FREEBOX
     79
    7580#ifdef USING_HDHOMERUN
    7681#include "hdhrrecorder.h"
    7782#include "hdhrchannel.h"
     
    187192        init_run = true;
    188193#endif
    189194    }
     195    else if (genOpt.cardtype == "FREEBOX")
     196    {
     197#ifdef USING_FREEBOX
     198        VERBOSE(VB_IMPORTANT,QString("trye to alloc chan"));
     199        channel = new FreeboxChannel(this, &freeboxOpt, cardid);
     200        channel->Open();
     201        InitChannel(genOpt.defaultinput, startchannel);
     202        init_run = true;
     203                VERBOSE(VB_IMPORTANT,QString("end trye to alloc chan"));
     204#endif
     205    }   
    190206    else if (genOpt.cardtype == "HDHOMERUN")
    191207    {
    192208#ifdef USING_HDHOMERUN
     
    243259{
    244260    QMutexLocker lock(&stateChangeLock);
    245261
    246     if (!GetDevices(cardid, genOpt, dvbOpt, fwOpt, dboxOpt))
     262    if (!GetDevices(cardid, genOpt, dvbOpt, fwOpt, dboxOpt, freeboxOpt))
    247263        return false;
    248264
    249265    QString startchannel = GetStartChannel(cardid, genOpt.defaultinput);
     
    299315        scanner = NULL;
    300316    }
    301317
     318#ifdef USING_FREEBOX
     319    if (GetFreeboxChannel())
     320        GetFreeboxChannel()->deleteLater();
     321    else
     322#endif // USING_FREEBOX
    302323    if (channel)
    303324    {
    304325        delete channel;
     
    855876        recorder->SetOption("httpport", dboxOpt.httpport);
    856877#endif // USING_DBOX2
    857878    }
     879    else if (genOpt.cardtype == "FREEBOX")
     880    {
     881#ifdef USING_FREEBOX
     882        recorder = new FreeboxRecorder(this, GetFreeboxChannel());
     883        recorder->SetOption("mrl", freeboxOpt.mrl);
     884#endif // USING_FREEBOX
     885    }
    858886    else if (genOpt.cardtype == "HDHOMERUN")
    859887    {
    860888#ifdef USING_HDHOMERUN
     
    10981126#endif // USING_DBOX2
    10991127}
    11001128
     1129FreeboxChannel *TVRec::GetFreeboxChannel(void)
     1130{
     1131#ifdef USING_FREEBOX
     1132    return dynamic_cast<FreeboxChannel*>(channel);
     1133#else
     1134    return NULL;
     1135#endif // USING_FREEBOX
     1136}
     1137 
    11011138HDHRChannel *TVRec::GetHDHRChannel(void)
    11021139{
    11031140#ifdef USING_HDHOMERUN
     
    14281465    return ok;
    14291466}
    14301467
    1431 bool TVRec::GetDevices(int cardid,
    1432                        GeneralDBOptions   &gen_opts,
    1433                        DVBDBOptions       &dvb_opts,
    1434                        FireWireDBOptions  &firewire_opts,
    1435                        DBox2DBOptions     &dbox2_opts)
     1468bool TVRec::GetDevices(int               cardid,
     1469                       GeneralDBOptions  &gen_opts,
     1470                       DVBDBOptions      &dvb_opts,
     1471                       FireWireDBOptions &firewire_opts,
     1472                       DBox2DBOptions    &dbox2_opts,
     1473                       FreeboxDBOptions  &freebox_opts)
    14361474{
    14371475    int testnum = 0;
    14381476    QString test;
     
    14491487        "       firewire_port,    firewire_node,       firewire_speed,  "
    14501488        "       firewire_model,   firewire_connection,                  "
    14511489        ""
    1452         "       dbox2_port,       dbox2_host,          dbox2_httpport   "
     1490        "       dbox2_port,       dbox2_host,          dbox2_httpport,  "
     1491        "       freebox_mrl "
    14531492        ""
    14541493        "FROM capturecard "
    14551494        "WHERE cardid = :CARDID");
     
    15271566
    15281567    dbox2_opts.httpport = query.value(dbox2off + 2).toUInt();
    15291568
     1569    // Freebox options
     1570    uint freeboxoff = dbox2off + 3;
     1571    test = query.value(freeboxoff).toString();
     1572    if (test != QString::null)
     1573        freebox_opts.mrl = QString::fromUtf8(test);
     1574
    15301575    return true;
    15311576}
    15321577
     
    35863631        delete channel;
    35873632        channel = NULL;
    35883633
    3589         GetDevices(newCardID, genOpt, dvbOpt, fwOpt, dboxOpt);
     3634        GetDevices(newCardID, genOpt, dvbOpt, fwOpt, dboxOpt, freeboxOpt);
    35903635        genOpt.defaultinput = inputname;
    35913636        CreateChannel(channum);
    35923637        if (!(request.flags & kFlagNoRec))
  • libs/libmythtv/tv_rec.h

     
    3939class DVBChannel;
    4040class Channel;
    4141
     42class FreeboxChannel;
     43
     44
    4245class MPEGStreamData;
    4346class ProgramMapTable;
    4447
     
    130133    QString host;
    131134};
    132135
     136 
     137class FreeboxDBOptions
     138{
     139  public:
     140    FreeboxDBOptions() : mrl("http://mafreebox.freebox.fr/freeboxtv/playlist.m3u") {}
     141
     142        QString mrl;
     143};
     144
     145
    133146class TuningRequest
    134147{
    135148  public:
     
    268281    void SetPseudoLiveTVRecording(ProgramInfo*);
    269282    void TeardownAll(void);
    270283
    271     static bool GetDevices(int cardid,
     284    static bool GetDevices(int                cardid,
    272285                           GeneralDBOptions   &general_opts,
    273286                           DVBDBOptions       &dvb_opts,
    274287                           FireWireDBOptions  &firewire_opts,
    275                            DBox2DBOptions     &dbox2_opts);
     288                           DBox2DBOptions     &dbox2_opts,
     289                           FreeboxDBOptions   &free_opts);
    276290
    277291
    278292    static QString GetStartChannel(int cardid, const QString &defaultinput);
     
    286300    bool CreateChannel(const QString &startChanNum);
    287301    void InitChannel(const QString &inputname, const QString &startchannel);
    288302    void CloseChannel(void);
    289     DBox2Channel *GetDBox2Channel(void);
    290     HDHRChannel  *GetHDHRChannel(void);
    291     DVBChannel   *GetDVBChannel(void);
    292     Channel      *GetV4LChannel(void);
    293303
     304    DBox2Channel   *GetDBox2Channel(void);
     305    HDHRChannel    *GetHDHRChannel(void);
     306    DVBChannel     *GetDVBChannel(void);
     307    FreeboxChannel *GetFreeboxChannel(void);
     308    Channel        *GetV4LChannel(void);
     309
    294310    void SetupSignalMonitor(bool enable_table_monitoring, bool notify);
    295311    bool SetupDTVSignalMonitor(void);
    296312    void TeardownSignalMonitor(void);
     
    366382    DVBDBOptions       dvbOpt;
    367383    FireWireDBOptions  fwOpt;
    368384    DBox2DBOptions     dboxOpt;
     385    FreeboxDBOptions   freeboxOpt;
    369386
    370387    // State variables
    371388    QMutex         stateChangeLock;
  • settings.pro

     
    2020
    2121INCLUDEPATH += $${PREFIX}/include
    2222INCLUDEPATH += $$CONFIG_INCLUDEPATH
     23INCLUDEPATH += /usr/include/liveMedia
     24INCLUDEPATH += /usr/include/UsageEnvironment
     25INCLUDEPATH += /usr/include/BasicUsageEnvironment
     26INCLUDEPATH += /usr/include/groupsock
    2327
    2428# figure out compile flags based on qmake info
    2529
     
    7983EXTRA_LIBS += $$CONFIG_AUDIO_JACK_LIBS
    8084EXTRA_LIBS += $$CONFIG_FIREWIRE_LIBS
    8185EXTRA_LIBS += $$CONFIG_DIRECTFB_LIBS
     86EXTRA_LIBS += $$CONFIG_LIVE_LIBS
    8287
    8388EXTRA_LIBS += $$LOCAL_LIBDIR_OGL
    8489EXTRA_LIBS += $$LOCAL_LIBDIR_X11