Index: configure
===================================================================
--- configure	(revision 9856)
+++ configure	(working copy)
@@ -54,6 +54,7 @@
 lirc="yes"
 joystick_menu="yes"
 firewire_cable_box="yes"
+freebox_box="yes"
 dbox2_dvb_box="yes"
 hdhomerun_box="yes"
 x11_include_path="/usr/X11R6/include"
@@ -175,6 +176,9 @@
 echo "  --disable-lirc           disable lirc support (Infrared Remotes)"
 echo "  --disable-joystick-menu  disable joystick menu"
 echo "  --disable-firewire       disable support for FireWire cable boxes"
+echo "  --disable-freebox        disable support for Freebox"
+echo "  --livelibdir=DIR         location of Live streaming library"
+echo "  --liveincludedir=DIR     location of Live streaming include files"
 echo "  --disable-dbox2          disable support for Nokia DBOX2 DVB boxes (or compatibles)"
 echo "  --disable-hdhomerun      disable support for HDHomeRun boxes"
 echo "  --disable-v4l            disable Video4Linux support"
@@ -813,6 +817,14 @@
   ;;
   --disable-dbox2) dbox2_dvb_box="no"
   ;;
+  --enable-freebox) freebox_box="yes"
+  ;;
+  --disable-freebox) freebox_box="no"
+  ;;
+  --livelibdir=*) live_lib_dir=`echo $opt | cut -d '=' -f 2`
+  ;;
+  --liveincludedir=*) live_include_dir=`echo $opt | cut -d '=' -f 2`
+  ;;
   --enable-hdhomerun) hdhomerun_box="yes"
   ;;
   --disable-hdhomerun) hdhomerun_box="no"
@@ -2105,6 +2117,15 @@
     fi
 fi
 
+if test x"$dvd" = x"yes" ; then
+    if has_library libdvdnav ; then
+        if has_header dvdnav/dvdnav.h ; then
+            dvd="yes"
+        fi
+    fi
+fi
+
+
 VENDOR_XVMC_LIBS=""
 if test x"$xvmc" = x"yes"; then
     xvmc="no"
@@ -2271,6 +2292,7 @@
   echo "FireWire support $firewire_cable_box"
   echo "DVB support      $dvb [$dvb_path]"
   echo "DBox2 support    $dbox2_dvb_box"
+  echo "freebox support  $freebox_box"
   echo "HDHomeRun sup.   $hdhomerun_box"
 fi
 
@@ -2917,6 +2939,46 @@
   CCONFIG="$CCONFIG using_dbox2"
 fi
 
+if test x"$freebox_box" = x"yes" ; then
+  if test "x$live_lib_dir" = "x"; then
+    if has_library libliveMedia; then
+	  CONFIG_LIVE_LIBS="-lliveMedia -lgroupsock -lBasicUsageEnvironment -lUsageEnvironment"
+	else
+	  echo "Unable to find Live Media library."
+	  exit 1;
+	fi
+  else
+    if test ! -f "$live_lib_dir/liveMedia/libliveMedia.a"; then
+	  echo "Unable to find Live Media library."
+	  exit 1;
+	fi
+	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"
+  fi
+  if test "x$live_include_dir" = "x"; then
+    if has_header liveMedia.hh; then
+	  true
+	else
+	  echo "Unable to find Live Media headers."
+	  exit 1;
+	fi
+  else
+    if test -f "$live_include_dir/liveMedia/include/liveMedia.hh"; then
+	  LIVE_INCLUDES="$live_include_dir/liveMedia/include $live_include_dir/UsageEnvironment/include $live_include_dir/BasicUsageEnvironment/include $live_include_dir/groupsock/include"
+	else
+	  if test -f "$live_include_dir/liveMedia/liveMedia.hh"; then
+	    LIVE_INCLUDES="$live_include_dir/liveMedia $live_include_dir/UsageEnvironment $live_include_dir/BasicUsageEnvironment $live_include_dir/groupsock"
+	  else
+	    echo "Unable to find Live Media headers."
+		exit 1;
+	  fi
+	fi
+  fi
+  CCONFIG="$CCONFIG using_freebox"
+  CONFIG_DEFINES="$CONFIG_DEFINES USING_FREEBOX"
+  echo "CONFIG_LIVE_LIBS=$CONFIG_LIVE_LIBS" >> $MYTH_CONFIG_MAK
+  CONFIG_INCLUDEPATH="$CONFIG_INCLUDEPATH $LIVE_INCLUDES"
+fi
+
 if test x"$hdhomerun_box" = x"yes" ; then
   CCONFIG="$CCONFIG using_hdhr"
 fi
Index: libs/libmythtv/freeboxchannel.h
===================================================================
--- libs/libmythtv/freeboxchannel.h	(revision 0)
+++ libs/libmythtv/freeboxchannel.h	(revision 0)
@@ -0,0 +1,79 @@
+#ifndef FREEBOXCHANNEL_H
+#define FREEBOXCHANNEL_H
+
+#include "channelbase.h"
+
+class FreeboxDBOptions;
+class QHttp;
+
+
+
+class FreeboxChannel : public QObject, public ChannelBase
+{
+    Q_OBJECT
+  public:
+    FreeboxChannel(TVRec *parent, FreeboxDBOptions *freebox_options, int cardid);
+    ~FreeboxChannel(void)
+    {
+    }
+
+    bool Open();
+    void Close();
+    bool SwitchToInput(const QString &inputname, const QString &chan);
+    bool SetChannelByString(const QString &chan);
+    bool IsOpen(void) const;
+
+    QString GetCurrentChannelUrl();
+
+    bool SwitchToInput(int newcapchannel, bool setstarting)
+    {
+        (void)newcapchannel;
+        (void)setstarting;
+        return false;
+    }
+
+    QString GetChannelUrlFromNumber(const QString& channelnumber);
+    QString GetDefaultChannel();
+
+  signals:
+    void ChannelChanged();
+
+  public slots:
+    void HttpRequestDone(bool error);
+
+  private:
+    void LoadChannels();
+    QString normalize(QString channelName);
+
+    void Log(QString string);
+
+    QHttp                *http;
+    FreeboxDBOptions     *m_freeboxoptions;
+
+    bool                  m_channelListReady;
+    QString               m_requestChannel;
+    QString               m_lastChannel;
+    int                   m_cardid;
+
+    // the rtsp url for the current channel
+    QString               m_currenturl;
+
+    // number of channel support by freebox
+    int                   m_freeboxchannelcount;
+
+    // map channelNum to channel index in table
+    QMap<int,int>         m_freeboxchannelIds;
+
+    // map channel index to channel url
+    QMap<int,QString>     m_freeboxchannelUrl;
+
+    // map channel index to channel name
+    QMap<int,QString>     m_freeboxchannelNames;
+
+    // map channel index to channel normalize name
+    QMap<int,QString>     m_freeboxchannelNamesN;
+};
+
+#endif//FREEBOXCHANNEL_H
+
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
Index: libs/libmythtv/libmythtv.pro
===================================================================
--- libs/libmythtv/libmythtv.pro	(revision 9856)
+++ libs/libmythtv/libmythtv.pro	(working copy)
@@ -348,6 +348,11 @@
     using_dbox2:SOURCES += dbox2recorder.cpp dbox2channel.cpp dbox2epg.cpp
     using_dbox2:HEADERS += dbox2recorder.h dbox2channel.h dbox2epg.h
     using_dbox2:DEFINES += USING_DBOX2
+    
+    # Support for freebox (http://adsl.free.fr/)
+    using_freebox:SOURCES += freeboxrecorder.cpp freeboxchannel.cpp freeboxmediasink.cpp
+    using_freebox:HEADERS += freeboxrecorder.h freeboxchannel.h freeboxmediasink.h
+    using_freebox:DEFINES += USING_FREEBOX
 
     # Support for HDHomeRun box
     using_hdhr {
Index: libs/libmythtv/freeboxchannel.cpp
===================================================================
--- libs/libmythtv/freeboxchannel.cpp	(revision 0)
+++ libs/libmythtv/freeboxchannel.cpp	(revision 0)
@@ -0,0 +1,324 @@
+/**
+ *  FreeboxChannel
+ *  Copyright (c) 2005 by Levent Gündogdu
+ *  Distributed as part of MythTV under GPL v2 and later.
+ */
+
+#include "freeboxchannel.h"
+
+#include <qhttp.h>
+#include <qurl.h>
+
+
+
+FreeboxChannel::FreeboxChannel(TVRec *parent, FreeboxDBOptions *freebox_options, int cardid):
+                               QObject(NULL, "FreeboxChannel"),
+                               ChannelBase(parent),
+                               http(new QHttp()),
+                               m_freeboxoptions(freebox_options),
+                               m_channelListReady(false),
+                               m_requestChannel(""),
+                               m_lastChannel("1"),
+                               m_cardid(cardid),
+                               m_freeboxchannelcount(0)
+{
+    connect(http, SIGNAL(done(bool)),
+            this, SLOT(HttpRequestDone(bool)));
+
+    LoadChannels();
+}
+
+bool FreeboxChannel::SwitchToInput(const QString &inputname, const QString &chan)
+{
+    int inputNum = GetInputByName(inputname);
+    if (inputNum < 0)
+        return false;
+
+    return SetChannelByString(chan);
+}
+
+bool FreeboxChannel::SetChannelByString(const QString &newChan)
+{
+    // Delay set channel when list has not yet been retrieved
+    if (!m_channelListReady)
+    {
+        VERBOSE(VB_IMPORTANT,QString("Freebox # Channel list not received yet. Will switch to channel %1 later...").arg(newChan));
+        m_requestChannel = newChan;
+        return true;
+    }
+
+    QString chan = newChan;
+    // If chan is empty, use DefautChannel
+    if (chan == "")
+    {
+        VERBOSE(VB_IMPORTANT,QString("Freebox # Empty channel name has been provided. Getting default name."));
+        chan = GetDefaultChannel();
+    }
+
+    // update current chanel
+    if (m_lastChannel != curchannelname)
+        m_lastChannel = curchannelname;
+
+    curchannelname = chan;
+    m_currenturl = GetChannelUrlFromNumber(curchannelname);
+
+    // emit signal to recorder
+    emit ChannelChanged();
+
+    return true;
+}
+
+QString FreeboxChannel::GetCurrentChannelUrl()
+{
+    return m_currenturl;
+}
+
+bool FreeboxChannel::IsOpen(void) const
+{
+    return true;
+}
+
+bool FreeboxChannel::Open(void)
+{
+    if (!InitializeInputs())
+        return false;
+
+    return true;
+}
+
+void FreeboxChannel::Close(void)
+{
+}
+
+
+// =====================================================================================
+//
+//  C H A N N E L     L O A D I N G
+// =====================================================================================
+
+
+void FreeboxChannel::LoadChannels()
+{
+    // Request Channel list via http. Signal will be emmitted when list is ready.
+    QUrl url( m_freeboxoptions->mrl );
+    QHttpRequestHeader header("GET", url.path());
+    header.setValue("Host", url.host());
+    int port = url.hasPort() ? url.port() : 80;
+    http->setHost(url.host(), port);
+    http->request(header);
+}
+
+
+QString FreeboxChannel::normalize(QString channelName)
+{
+    // Normalize Channel name so we can try to automap channel return by freebox to channel coming from tv_grab_fr
+    QString res;
+    for (unsigned int i=0;i<channelName.length();i++)
+    {
+        QChar c = channelName[i];
+        if (c.isSpace()) continue;
+        c = c.lower();
+        if (c=='é' || c=='ê' || c=='ê') c='e';
+        if (c=='à') c='a';
+        if (c=='i' || c=='î') c=='i';
+        if (c=='ô') c=='o';
+
+        res += c;
+    }
+
+    return res;
+}
+
+// ==========================================================================================
+// HttpRequestDone : Receive response to channel list request
+//
+// ==========================================================================================
+void FreeboxChannel::HttpRequestDone(bool error)
+{
+    if (error)
+    {
+        VERBOSE(VB_IMPORTANT,QString("Freebox # Reading channel list failed! (%1)").arg(http->errorString()));
+        return;
+    }
+
+    QString buffer=http->readAll();
+    m_freeboxchannelcount = 0;
+
+    int sepCount = 0;
+
+    QString header = buffer.section("\n", sepCount, sepCount);
+    sepCount++;
+
+    // Verify header is ok
+    if (header != "#EXTM3U")
+    {
+        VERBOSE(VB_IMPORTANT,QString("Freebox # Invalid header while retrieve channel list.!"));
+        return;
+    }
+
+    while (true)
+    {
+        QString line1 = buffer.section("\n", sepCount, sepCount);
+        if (line1 == "")
+            break;
+
+        sepCount++;
+
+        QString line2 = buffer.section("\n", sepCount, sepCount);
+        if (line2 == "")
+            break;
+
+        sepCount++;
+
+        // each line contains ://
+        // header:extension,channelNum - channelName rtsp://channelUrl
+        //#EXTINF:0,2 - France 2 rtsp://mafreebox.freebox.fr/freeboxtv/201
+
+        QString lineHead;
+        QString extension;
+        QString channelNum;
+        QString channelName;
+
+        int pos = 0;
+        int oldPos = 0;
+
+        pos = line1.find(":", oldPos);
+        if (pos<0)
+        {
+            VERBOSE(VB_IMPORTANT,QString("Freebox # Invalid header while retrieve channel list.!"));
+            return;
+        }
+        lineHead = line1.mid(0, pos);
+
+        if (lineHead != "#EXTINF")
+        {
+            VERBOSE(VB_IMPORTANT,QString("Freebox # Invalid header while retrieve channel list.!"));
+            return;
+        }
+
+        oldPos = pos + 1;
+        pos = line1.find(",", oldPos);
+        if (pos<0)
+        {
+            VERBOSE(VB_IMPORTANT,QString("Freebox # Invalid header while retrieve channel list.!"));
+            return;
+        }
+        extension = line1.mid(oldPos, pos - oldPos);
+
+        oldPos = pos + 1;
+        pos = line1.find(" ", oldPos);
+        if (pos<0)
+        {
+            VERBOSE(VB_IMPORTANT,QString("Freebox # Invalid header while retrieve channel list.!"));
+            return;
+        }
+        channelNum = line1.mid(oldPos, pos - oldPos);
+
+        oldPos = pos + 1;
+        pos = line1.find("- ", oldPos);
+        if (pos<0)
+        {
+            VERBOSE(VB_IMPORTANT,QString("Freebox # Invalid header while retrieve channel list.!"));
+            return;
+        }
+        channelName = line1.mid(pos + 2, line1.length());
+
+        QString channelUrl = line2;
+
+        // save all this information in map for quick access
+        bool ok;
+        int channelNumI = channelNum.toInt( &ok, 10 );
+
+        QString channelNameN = normalize(channelName);
+
+        m_freeboxchannelIds[channelNumI] = m_freeboxchannelcount;
+        m_freeboxchannelUrl[m_freeboxchannelcount] = channelUrl;
+        m_freeboxchannelNames[m_freeboxchannelcount] = channelName;
+        m_freeboxchannelNamesN[m_freeboxchannelcount] = channelNameN;
+
+        m_freeboxchannelcount++;
+    }
+
+    // Channel list is ready.
+    m_channelListReady = true;
+
+    // Change channel if delayed request is available
+    if (m_requestChannel != "")
+    {
+        SetChannelByString(m_requestChannel);
+        m_requestChannel = "";
+    }
+}
+
+
+// ==========================================================================================
+// GetChannelUrlFromNumber : Map a channel number to the corresponding rtsp URL
+//
+// ==========================================================================================
+QString FreeboxChannel::GetChannelUrlFromNumber(const QString& channelnumber)
+{
+    MSqlQuery query(MSqlQuery::InitCon());
+
+    query.prepare("SELECT name,freqid "
+          "FROM channel,cardinput "
+                  "WHERE "
+          "channel.sourceid = cardinput.sourceid AND "
+          "cardinput.cardid = :CARDID AND "
+                  "channel.channum = :CHANNUM");
+
+    query.bindValue(":CARDID", m_cardid);
+    query.bindValue(":CHANNUM", channelnumber);
+
+    if (query.exec() && query.isActive() && query.size() > 0)
+    {
+        query.next();
+        QString chanName = query.value(0).toString();
+
+        // if we have a FreqID in the table, use this as the real freebox channel number
+        int mFreqId = query.value(1).toInt();
+        if (mFreqId!=0)
+        {
+            int channelI = m_freeboxchannelIds[mFreqId];
+            return m_freeboxchannelUrl[channelI];
+        }
+
+        // if no freqID, try to map the chanName to an existing channel name
+        for (int i=0;i<m_freeboxchannelcount;i++)
+        {
+            if (m_freeboxchannelNamesN[i] == chanName)
+            {
+                return m_freeboxchannelUrl[i];
+            }
+        }
+
+        return "";
+    }
+    return "";
+}
+
+// ==========================================================================================
+// GetDefaultChannel : Search for default channel
+//
+// ==========================================================================================
+
+QString FreeboxChannel::GetDefaultChannel()
+{
+    MSqlQuery query(MSqlQuery::InitCon());   
+    query.prepare("SELECT channum "
+          "FROM channel,cardinput "
+                  "WHERE "
+          "channel.sourceid = cardinput.sourceid AND "
+          "cardinput.cardid = :CARDID "
+          "ORDER BY channum limit 1");
+
+    query.bindValue(":CARDID", m_cardid);
+
+    if (query.exec() && query.isActive() && query.size() > 0)
+    {
+        query.next();
+        return query.value(0).toString();
+    } 
+    return "";
+}
+
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
Index: libs/libmythtv/freeboxmediasink.cpp
===================================================================
--- libs/libmythtv/freeboxmediasink.cpp	(revision 0)
+++ libs/libmythtv/freeboxmediasink.cpp	(revision 0)
@@ -0,0 +1,57 @@
+#include "freeboxmediasink.h"
+
+#include "freeboxrecorder.h"
+
+
+
+FreeboxMediaSink::FreeboxMediaSink(UsageEnvironment& pEnv, FreeboxRecorder &pRecorder) :
+    MediaSink(pEnv),
+    env(pEnv),
+    recorder(pRecorder)
+{
+    // Setup the data buffer
+    fBufferSize = 20000;
+    fBuffer = new unsigned char[fBufferSize];
+}
+
+FreeboxMediaSink::~FreeboxMediaSink()
+{
+    // free the data buffer
+    delete[] fBuffer;
+}
+
+FreeboxMediaSink* FreeboxMediaSink::createNew(UsageEnvironment& env, FreeboxRecorder &pRecorder)
+{
+    FreeboxMediaSink* newSink = new FreeboxMediaSink(env, pRecorder);
+    return newSink;
+}
+
+Boolean FreeboxMediaSink::continuePlaying()
+{
+    if (fSource == NULL) return False;
+
+    fSource->getNextFrame(fBuffer, fBufferSize, afterGettingFrame, this, onSourceClosure, this);
+
+    return True;
+}
+
+void FreeboxMediaSink::afterGettingFrame(void*          clientData,
+                                    unsigned       frameSize,
+                                    unsigned       /*numTruncatedBytes*/,
+                                    struct timeval presentationTime,
+                                    unsigned       /*durationInMicroseconds*/)
+{
+    FreeboxMediaSink* sink = (FreeboxMediaSink*)clientData;
+    sink->afterGettingFrame1(frameSize, presentationTime);
+}
+
+void FreeboxMediaSink::afterGettingFrame1(unsigned frameSize, struct timeval presentationTime)
+{
+    addData(fBuffer, frameSize, presentationTime);
+    continuePlaying();
+}
+
+void FreeboxMediaSink::addData(unsigned char* data, unsigned dataSize, struct timeval presentationTime)
+{
+    recorder.addData(data, dataSize, presentationTime);
+}
Index: libs/libmythtv/dbcheck.cpp
===================================================================
--- libs/libmythtv/dbcheck.cpp	(revision 9856)
+++ libs/libmythtv/dbcheck.cpp	(working copy)
@@ -10,7 +10,7 @@
 #include "mythdbcon.h"
 
 /// This is the DB schema version expected by the running MythTV instance.
-const QString currentDatabaseVersion = "1137";
+const QString currentDatabaseVersion = "1138";
 
 static bool UpdateDBVersionNumber(const QString &newnumber);
 static bool performActualUpdate(const QString updates[], QString version,
@@ -2206,6 +2206,19 @@
 //"ALTER TABLE capturecard DROP COLUMN dvb_hw_decoder;" in 0.21
 //"ALTER TABLE cardinput DROP COLUMN  preference;" in 0.22
 
+  if (dbver == "1137")
+    {
+        const QString updates[] = {
+"INSERT INTO profilegroups SET name = 'Freebox Input', cardtype = 'Freebox', is_default = 1;",
+"ALTER TABLE capturecard ADD COLUMN freebox_mrl varchar(64) DEFAULT 'http://mafreebox.freebox.fr/freeboxtv/playlist.m3u';",
+""
+};
+
+        if (!performActualUpdate(updates, "1138", dbver))
+            return false;
+    }
+
+
     return true;
 }
 
@@ -2266,6 +2279,7 @@
 "  dbox2_port int(10) unsigned NOT NULL default '31338',"
 "  dbox2_httpport int(10) unsigned NOT NULL default '80',"
 "  dbox2_host varchar(32) default NULL,"
+"  freebox_mrl varchar(64) DEFAULT 'http://mafreebox.freebox.fr/freeboxtv/playlist.m3u',"
 "  signal_timeout int(11) NOT NULL default '1000',"
 "  channel_timeout int(11) NOT NULL default '3000',"
 "  PRIMARY KEY  (cardid)"
@@ -2832,6 +2846,7 @@
 "INSERT INTO profilegroups VALUES (8,"
 " 'USB Mpeg-4 Encoder (Plextor ConvertX, etc)','GO7007',1,NULL);",
 "INSERT INTO profilegroups VALUES (9,'DBOX2 Input','DBOX2',1,NULL);",
+"INSERT INTO `profilegroups` VALUES (10,'Freebox Input','Freebox',1,NULL);",
 "INSERT INTO recordingprofiles VALUES (1,'Default',NULL,NULL,1);",
 "INSERT INTO recordingprofiles VALUES (2,'Live TV',NULL,NULL,1);",
 "INSERT INTO recordingprofiles VALUES (3,'High Quality',NULL,NULL,1);",
Index: libs/libmythtv/freeboxrecorder.cpp
===================================================================
--- libs/libmythtv/freeboxrecorder.cpp	(revision 0)
+++ libs/libmythtv/freeboxrecorder.cpp	(revision 0)
@@ -0,0 +1,368 @@
+/**
+ *  FreeboxRecorder
+ *  Copyright (c) 2005 by Levent G?u (mythtv@feature-it.com)
+ *  Distributed as part of MythTV under GPL v2 and later.
+ */
+
+#include "freeboxrecorder.h"
+
+#include <BasicUsageEnvironment.hh>
+#include <MediaSession.hh>
+#include <RTSPClient.hh>
+
+#include "mpeg/tspacket.h"
+#include "freeboxchannel.h"
+#include "freeboxmediasink.h"
+
+
+
+// ============================================================================
+// FreeboxData : Helper class use for static Callback handler
+// ============================================================================
+class FreeboxData
+{
+  public:
+    FreeboxData(FreeboxRecorder *pFreeboxRecorder, MediaSubsession *pMediaSubSession)
+    {
+        freeboxRecorder = pFreeboxRecorder;
+        mediaSubSession = pMediaSubSession;
+    }
+
+    FreeboxRecorder *freeboxRecorder;
+    MediaSubsession *mediaSubSession;
+};
+
+
+
+FreeboxRecorder::FreeboxRecorder(TVRec *rec, FreeboxChannel *channel) :
+    DTVRecorder(rec),
+    env(NULL),
+    rtspClient(NULL),
+    session(NULL),
+    _abort_rtsp(0),
+    _abort_recording(false),
+    m_channel(channel)
+{
+    connect(m_channel, SIGNAL(ChannelChanged()),
+            this,      SLOT(  ChannelChanged()));
+}
+
+
+
+FreeboxRecorder::~FreeboxRecorder()
+{
+}
+
+
+
+bool FreeboxRecorder::Open()
+{
+    return StartRtsp();
+}
+
+
+
+void FreeboxRecorder::Close()
+{
+    if (session == NULL) return;
+
+    // Ensure RTSP cleanup, remove old RTSP session
+    MediaSubsessionIterator iter(*session);
+    MediaSubsession* subsession;
+    while ((subsession = iter.next()) != NULL)
+    {
+        Medium::close(subsession->sink);
+        subsession->sink = NULL;
+    }
+
+    if (session == NULL) return;
+
+    rtspClient->teardownMediaSession(*session);
+
+    // Close all RTSP descriptor
+    Medium::close(session);
+    Medium::close(rtspClient);
+}
+
+
+
+void FreeboxRecorder::ChannelChanged()
+{
+    // Channel change, we need to close current RTSP flow, and open a new one
+    ResetEventLoop();
+}
+
+
+
+void FreeboxRecorder::SetOptionsFromProfile(RecordingProfile *profile,
+                                            const QString    &videodev,
+                                            const QString    &audiodev,
+                                            const QString    &vbidev)
+{
+    (void)videodev;
+    (void)audiodev;
+    (void)vbidev;
+    (void)profile;
+}
+
+
+
+void FreeboxRecorder::StartRecording()
+{
+    while(!_abort_recording && Open())
+    {
+        _abort_rtsp = 0;
+        _recording = true;
+        // Go into main RTSP loop, feeding data to mythtv
+        env->taskScheduler().doEventLoop(&_abort_rtsp); // does not return
+
+        // Event loop exists, the recording finish
+        FinishRecording();
+        _recording = false;
+        Close();
+    }
+}
+
+void FreeboxRecorder::StopRecording(void)
+{
+    _abort_recording = true;
+    ResetEventLoop();
+}
+
+void FreeboxRecorder::ResetEventLoop()
+{
+    _abort_rtsp = ~0;
+    while( _recording ) usleep(10000);
+}
+
+// ======================================================================
+// StartRtsp : start a new RTSP session for the current channel
+// ======================================================================
+bool FreeboxRecorder::StartRtsp()
+{
+    // Retrieve the RTSP channel URL
+    QString url = m_channel->GetCurrentChannelUrl();
+
+    // Begin by setting up our usage environment:
+    TaskScheduler* scheduler = BasicTaskScheduler::createNew();
+    env = BasicUsageEnvironment::createNew(*scheduler);
+
+
+    // Create our client object:
+    rtspClient = RTSPClient::createNew(*env, 0, "myRTSP", 0);
+    if (rtspClient == NULL)
+    {
+        VERBOSE(VB_IMPORTANT, QString("Freebox # Failed to create RTSP client: %1").arg(env->getResultMsg()));
+        return false;
+    }
+
+    // Setup URL for the current session
+    char* sdpDescription = rtspClient->describeURL(url);
+    rtspClient->describeStatus();
+
+    if (sdpDescription == NULL)
+    {
+        VERBOSE(VB_IMPORTANT, QString("Freebox # Failed to get a SDP description from URL: %1 %2").arg(url).arg(env->getResultMsg()));
+        return false;
+    }
+
+    // Create a media session object from this SDP description:
+    session = MediaSession::createNew(*env, sdpDescription);
+    delete[] sdpDescription;
+    if (session == NULL)
+    {
+        VERBOSE(VB_IMPORTANT, QString("Freebox # Failed to create a MediaSession object from the SDP description: %1").arg(env->getResultMsg()));
+        return false;
+    }
+    else if (!session->hasSubsessions())
+    {
+        VERBOSE(VB_IMPORTANT, QString("Freebox # This session has no media subsessions"));
+        return false;
+    }
+
+    // Then, setup the "RTPSource"s for the session:
+    MediaSubsessionIterator iter(*session);
+    MediaSubsession *subsession;
+    Boolean madeProgress = False;
+    while ((subsession = iter.next()) != NULL)
+    {
+        if (!subsession->initiate(-1))
+        {
+            VERBOSE(VB_IMPORTANT, QString("Freebox # Unable to create receiver for: %1 / %2 subsession: %3")
+                    .arg(subsession->mediumName())
+                    .arg(subsession->codecName())
+                    .arg(env->getResultMsg()));
+        }
+        else
+        {
+            madeProgress = True;
+
+            if (subsession->rtpSource() != NULL)
+            {
+                  unsigned const thresh = 1000000; // 1 second
+                  subsession->rtpSource()->setPacketReorderingThresholdTime(thresh);
+            }
+        }
+    }
+
+    if (!madeProgress) return false;
+
+    // Perform additional 'setup' on each subsession, before playing them:
+    madeProgress = false;
+    iter.reset();
+    while ((subsession = iter.next()) != NULL)
+    {
+        if (subsession->clientPortNum() == 0) continue; // port # was not set
+
+        if (rtspClient->setupMediaSubsession(*subsession, False, false))
+        {
+            madeProgress = True;
+        }
+        else
+        {
+            VERBOSE(VB_IMPORTANT, QString("Freebox # Failed to setup: %1 %2 : %3").arg(subsession->mediumName()).arg(subsession->codecName()).arg(env->getResultMsg()));
+        }
+    }
+
+    if (!madeProgress) return false;
+
+   // Create and start "FileSink"s for each subsession:
+   // FileSink while receive Mpeg2 TS Data & will feed them to mythtv
+    madeProgress = False;
+    iter.reset();
+    while ((subsession = iter.next()) != NULL)
+    {
+        if (subsession->readSource() == NULL) continue; // was not initiated
+
+        FreeboxMediaSink* freeboxMediaSink = FreeboxMediaSink::createNew(*env, *this);
+
+        subsession->sink = freeboxMediaSink;
+        if (subsession->sink == NULL)
+        {
+            VERBOSE(VB_IMPORTANT, QString("Freebox # Failed to create sink: %1").arg(env->getResultMsg()));
+        }
+
+        subsession->sink->startPlaying(*(subsession->readSource()),
+                                       subsessionAfterPlayingCallback,
+                                       new FreeboxData(this, subsession));
+
+        if (subsession->rtcpInstance() != NULL)
+        {
+            subsession->rtcpInstance()->setByeHandler(subsessionByeHandlerCallback,
+                                                      new FreeboxData(this, subsession));
+        }
+
+        madeProgress = True;
+    }
+
+    if (!madeProgress) return false;
+
+    // Setup player
+    if (!(rtspClient->playMediaSession(*session)))
+    {
+        VERBOSE(VB_IMPORTANT, QString("Freebox # Failed to start playing session: %1").arg(env->getResultMsg()));
+        return false;
+    }
+
+    return true;
+}
+
+// ===================================================
+// findTSHeader : find a TS Header in flow
+// ===================================================
+static int FreeboxRecorder_findTSHeader(const unsigned char *data, unsigned dataSize)
+{
+    unsigned int pos = 0;
+    while (pos < dataSize)
+    {
+        if (data[pos] == 0x47)
+            return pos;
+        pos++;
+    }
+    return -1;
+}
+
+// ===================================================
+// addData : feed date from RTSP flow to mythtv
+// ===================================================
+void FreeboxRecorder::addData(unsigned char* data, unsigned dataSize, struct timeval)
+{
+    unsigned int readIndex = 0;
+
+    // data may be compose from more than one packet, loop to consume all data
+    while (readIndex < dataSize)
+    {
+        // If recorder is pause, stop there
+        if (PauseAndWait())
+        {
+            return;
+        }
+
+        // Find the next TS Header in data
+        int tsPos = FreeboxRecorder_findTSHeader(data + readIndex, dataSize);
+
+        // if no TS, something bad happens
+        if (tsPos == -1)
+        {
+            VERBOSE(VB_IMPORTANT, QString("FREEBOX: No TS header."));
+            break;
+        }
+
+        // if TS Header not at start of data, we receive out of sync data
+        if (tsPos > 0)
+        {
+            VERBOSE(VB_IMPORTANT, QString("FREEBOX: TS header at %1, not in sync.").arg(tsPos));
+        }
+
+        // Check if the next packet in buffer is complete : packet size is 188 bytes long
+        if ((dataSize - tsPos) < 188)
+        {
+            VERBOSE(VB_IMPORTANT, QString("FREEBOX: TS header at %1 but packet not yet complete.").arg(tsPos));
+            break;
+        }
+
+        // Cast current found TS Packet to TSPacket structure
+        const void *newData = data + tsPos + readIndex;
+        const TSPacket *tspacket = reinterpret_cast<const TSPacket*>(newData);
+
+        // Feed current packet to myth
+        _buffer_packets = !FindKeyframes(tspacket);
+        BufferedWrite(*tspacket);
+
+        // follow to next packet
+        readIndex += tsPos + TSPacket::SIZE;
+    }
+}
+
+void FreeboxRecorder::subsessionAfterPlayingCallback(void *clientData)
+{
+    FreeboxData *myData = (FreeboxData*)clientData;
+    myData->freeboxRecorder->SubsessionAfterPlaying(myData->mediaSubSession);
+}
+
+void FreeboxRecorder::subsessionByeHandlerCallback(void *clientData)
+{
+    FreeboxData *myData = (FreeboxData*)clientData;
+    myData->freeboxRecorder->SubsessionByeHandler(myData->mediaSubSession);
+}
+
+void FreeboxRecorder::SubsessionAfterPlaying(MediaSubsession* subsession)
+{
+    Medium::close(subsession->sink);
+    subsession->sink = NULL;
+
+    MediaSession& session = subsession->parentSession();
+    MediaSubsessionIterator iter(session);
+    while ((subsession = iter.next()) != NULL)
+    {
+        if (subsession->sink != NULL) return;
+    }
+}
+
+
+void FreeboxRecorder::SubsessionByeHandler(MediaSubsession* subsession)
+{
+    SubsessionAfterPlaying(subsession);
+}
+
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
Index: libs/libmythtv/cardutil.cpp
===================================================================
--- libs/libmythtv/cardutil.cpp	(revision 9856)
+++ libs/libmythtv/cardutil.cpp	(working copy)
@@ -517,6 +517,7 @@
 
     if (("FIREWIRE"  == cardtype) ||
         ("DBOX2"     == cardtype) ||
+        ("FREEBOX"   == cardtype) ||
         ("HDHOMERUN" == cardtype))
     {
         ret += "MPEG2TS";
@@ -709,6 +710,21 @@
                 .arg(query.value(1).toString())
                 .arg(query.value(2).toString());
     }
+    else if (cardtype == "FREEBOX")
+    {
+        MSqlQuery query(MSqlQuery::InitCon());
+        query.prepare(
+            "SELECT freebox_mrl "
+            "FROM capturecard "
+            "WHERE cardid = :CARDID");
+        query.bindValue(":CARDID", cardid);
+
+        if (!query.exec() || !query.isActive() || !query.next())
+            label = "[ DB ERROR ]";
+        else
+            label = QString("[ FREEBOX : MRL %1 ]")
+                .arg(query.value(0).toString());
+    }
     else if (cardtype == "HDHOMERUN")
     {
         MSqlQuery query(MSqlQuery::InitCon());
@@ -745,6 +761,7 @@
 
     if (("FIREWIRE"  == cardtype) ||
         ("DBOX2"     == cardtype) ||
+        ("FREEBOX"   == cardtype) ||
         ("HDHOMERUN" == cardtype))
     {
         inputs += "MPEG2TS";
Index: libs/libmythtv/freeboxmediasink.h
===================================================================
--- libs/libmythtv/freeboxmediasink.h	(revision 0)
+++ libs/libmythtv/freeboxmediasink.h	(revision 0)
@@ -0,0 +1,42 @@
+#ifndef _FREEBOXMEDIASINK_H_
+#define _FREEBOXMEDIASINK_H_
+
+#include <MediaSink.hh>
+
+class FreeboxRecorder;
+
+
+
+// ============================================================================
+// FreeboxMediaSink : Helper class use to receive RTSP data from socket.
+// ============================================================================
+class FreeboxMediaSink: public MediaSink
+{
+  public:
+    static FreeboxMediaSink* createNew(UsageEnvironment& env, FreeboxRecorder &pRecorder);
+
+    // Callback function when rtsp data are ready
+    void addData(unsigned char* data, unsigned dataSize, struct timeval presentationTime);
+
+  protected:
+    FreeboxMediaSink(UsageEnvironment& env, FreeboxRecorder &pRecorder);
+    virtual ~FreeboxMediaSink();
+
+    static void afterGettingFrame(void*          clientData,
+                                  unsigned       frameSize,
+                                  unsigned       numTruncatedBytes,
+                                  struct timeval presentationTime,
+                                  unsigned       durationInMicroseconds);
+    virtual void afterGettingFrame1(unsigned frameSize, struct timeval presentationTime);
+
+  private:
+    virtual Boolean continuePlaying();
+
+    unsigned char* fBuffer;
+    unsigned fBufferSize;
+    UsageEnvironment &env;
+    FreeboxRecorder &recorder;
+    int bufferIndex;
+};
+
+#endif//_FREEBOXMEDIASINK_H_
Index: libs/libmythtv/videosource.cpp
===================================================================
--- libs/libmythtv/videosource.cpp	(revision 9856)
+++ libs/libmythtv/videosource.cpp	(working copy)
@@ -927,6 +927,17 @@
     }
 };
 
+class FreeboxHost : public LineEditSetting, public CCSetting {
+  public:
+    FreeboxHost(const CaptureCard &parent):
+        CCSetting(parent, "freebox_mrl")
+    {
+        setValue("http://mafreebox.freebox.fr/freeboxtv/playlist.m3u");
+        setLabel(QObject::tr("Freebox MRL"));
+        setHelpText(QObject::tr("The freebox Media Resource Locator (MRL)."));
+    }
+};
+
 class HDHomeRunTunerIndex: public ComboBoxSetting, public CCSetting
 {
   public:
@@ -939,6 +950,20 @@
     }
 };
 
+class FreeboxConfigurationGroup: public VerticalConfigurationGroup {
+  public:
+    FreeboxConfigurationGroup(CaptureCard& a_parent):
+       ConfigurationGroup(false, true, false, false),
+       VerticalConfigurationGroup(false, true, false, false),
+       parent(a_parent)
+    {
+       setUseLabel(false);
+       addChild(new FreeboxHost(parent));
+    };
+  private:
+    CaptureCard& parent;
+};
+
 void HDHRCardInput::fillSelections(const QString&)
 {
     clearSelections();
@@ -1073,6 +1098,10 @@
     addTarget("DBOX2",     new DBOX2ConfigurationGroup(parent));
 #endif // USING_DBOX2
 
+#ifdef USING_FREEBOX
+    addTarget("FREEBOX",   new FreeboxConfigurationGroup(parent));
+#endif // USING_FREEBOX
+
 #ifdef USING_HDHOMERUN
     addTarget("HDHOMERUN", new HDHomeRunConfigurationGroup(parent));
 #endif // USING_HDHOMERUN
@@ -1190,6 +1219,11 @@
         QObject::tr("DBox2 TCP/IP cable box"), "DBOX2");
 #endif // USING_DBOX2
 
+#ifdef USING_FREEBOX
+    setting->addSelection(
+        QObject::tr("Freebox"), "FREEBOX");
+#endif // USING_FREEBOX
+
 #ifdef USING_HDHOMERUN
     setting->addSelection(
         QObject::tr("HDHomeRun DTV tuner box"), "HDHOMERUN");
Index: libs/libmythtv/freeboxrecorder.h
===================================================================
--- libs/libmythtv/freeboxrecorder.h	(revision 0)
+++ libs/libmythtv/freeboxrecorder.h	(revision 0)
@@ -0,0 +1,80 @@
+/**
+ *  FreeboxRecorder
+ *  Copyright (c) 2005 by Levent Gündogdu
+ *  Distributed as part of MythTV under GPL v2 and later.
+ */
+
+#ifndef FREEBOXRECORDER_H_
+#define FREEBOXRECORDER_H_
+
+#include "dtvrecorder.h"
+
+class FreeboxChannel;
+class MediaSession;
+class MediaSubsession;
+class RTSPClient;
+class UsageEnvironment;
+
+
+
+/**
+ *
+ *  Constructs a FreeboxRecorder
+ *
+ */
+class FreeboxRecorder :
+    public QObject, //FIXME see changeset #9743 for details
+    public DTVRecorder
+{
+    Q_OBJECT
+  public:
+    FreeboxRecorder(TVRec *rec, FreeboxChannel *channel);
+    ~FreeboxRecorder();
+    
+    void StartRecording(void);  //< RecorderBase
+    void StopRecording(void);   //< DTVRecorder
+
+    // RecorderBase
+    void SetOptionsFromProfile(RecordingProfile *profile,
+                               const QString    &videodev,
+                               const QString    &audiodev,
+                               const QString    &vbidev);
+
+  public slots:
+    void ChannelChanged();
+
+  private:
+    friend class FreeboxMediaSink;
+
+    bool Open(); //< RecorderBase
+    void Close();
+
+    static void subsessionAfterPlayingCallback(void *clientData);
+    static void subsessionByeHandlerCallback(void *clientData);
+    void SubsessionAfterPlaying(MediaSubsession *subsession);
+    void SubsessionByeHandler(MediaSubsession *subsession);
+
+    // Callback function to add MPEG2 TS data
+    void addData(unsigned char* data, unsigned dataSize, struct timeval presentationTime);
+
+    bool StartRtsp();
+    void ResetEventLoop();
+
+  private:
+    UsageEnvironment* env;
+    RTSPClient* rtspClient;
+    MediaSession* session;
+
+    // var to check if we need to abort current rtsp session
+    char _abort_rtsp;
+
+    // request abort for StartRecording method
+    bool _abort_recording;
+
+    // Current channel
+    FreeboxChannel *m_channel;
+};
+
+#endif//FREEBOXRECORDER_H_
+
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
Index: libs/libmythtv/tv_rec.cpp
===================================================================
--- libs/libmythtv/tv_rec.cpp	(revision 9856)
+++ libs/libmythtv/tv_rec.cpp	(working copy)
@@ -72,6 +72,11 @@
 #include "dbox2channel.h"
 #endif
 
+#ifdef USING_FREEBOX
+#include "freeboxrecorder.h"
+#include "freeboxchannel.h"
+#endif // USING_FREEBOX
+
 #ifdef USING_HDHOMERUN
 #include "hdhrrecorder.h"
 #include "hdhrchannel.h"
@@ -187,6 +192,17 @@
         init_run = true;
 #endif
     }
+    else if (genOpt.cardtype == "FREEBOX")
+    {
+#ifdef USING_FREEBOX
+    	VERBOSE(VB_IMPORTANT,QString("trye to alloc chan"));
+        channel = new FreeboxChannel(this, &freeboxOpt, cardid);
+        channel->Open();
+        InitChannel(genOpt.defaultinput, startchannel);
+        init_run = true;
+		VERBOSE(VB_IMPORTANT,QString("end trye to alloc chan"));
+#endif
+    }    
     else if (genOpt.cardtype == "HDHOMERUN")
     {
 #ifdef USING_HDHOMERUN
@@ -243,7 +259,7 @@
 {
     QMutexLocker lock(&stateChangeLock);
 
-    if (!GetDevices(cardid, genOpt, dvbOpt, fwOpt, dboxOpt))
+    if (!GetDevices(cardid, genOpt, dvbOpt, fwOpt, dboxOpt, freeboxOpt))
         return false;
 
     QString startchannel = GetStartChannel(cardid, genOpt.defaultinput);
@@ -299,6 +315,11 @@
         scanner = NULL;
     }
 
+#ifdef USING_FREEBOX
+    if (GetFreeboxChannel())
+        GetFreeboxChannel()->deleteLater();
+    else
+#endif // USING_FREEBOX
     if (channel)
     {
         delete channel;
@@ -855,6 +876,13 @@
         recorder->SetOption("httpport", dboxOpt.httpport);
 #endif // USING_DBOX2
     }
+    else if (genOpt.cardtype == "FREEBOX")
+    {
+#ifdef USING_FREEBOX
+        recorder = new FreeboxRecorder(this, GetFreeboxChannel());
+        recorder->SetOption("mrl", freeboxOpt.mrl);
+#endif // USING_FREEBOX
+    }
     else if (genOpt.cardtype == "HDHOMERUN")
     {
 #ifdef USING_HDHOMERUN
@@ -1098,6 +1126,15 @@
 #endif // USING_DBOX2
 }
 
+FreeboxChannel *TVRec::GetFreeboxChannel(void)
+{
+#ifdef USING_FREEBOX
+    return dynamic_cast<FreeboxChannel*>(channel);
+#else
+    return NULL;
+#endif // USING_FREEBOX
+}
+ 
 HDHRChannel *TVRec::GetHDHRChannel(void)
 {
 #ifdef USING_HDHOMERUN
@@ -1428,11 +1465,12 @@
     return ok;
 }
 
-bool TVRec::GetDevices(int cardid,
-                       GeneralDBOptions   &gen_opts,
-                       DVBDBOptions       &dvb_opts,
-                       FireWireDBOptions  &firewire_opts,
-                       DBox2DBOptions     &dbox2_opts)
+bool TVRec::GetDevices(int               cardid,
+                       GeneralDBOptions  &gen_opts,
+                       DVBDBOptions      &dvb_opts,
+                       FireWireDBOptions &firewire_opts,
+                       DBox2DBOptions    &dbox2_opts,
+                       FreeboxDBOptions  &freebox_opts)
 {
     int testnum = 0;
     QString test;
@@ -1449,7 +1487,8 @@
         "       firewire_port,    firewire_node,       firewire_speed,  "
         "       firewire_model,   firewire_connection,                  "
         ""
-        "       dbox2_port,       dbox2_host,          dbox2_httpport   "
+        "       dbox2_port,       dbox2_host,          dbox2_httpport,  "
+        "       freebox_mrl "
         ""
         "FROM capturecard "
         "WHERE cardid = :CARDID");
@@ -1527,6 +1566,12 @@
 
     dbox2_opts.httpport = query.value(dbox2off + 2).toUInt();
 
+    // Freebox options
+    uint freeboxoff = dbox2off + 3;
+    test = query.value(freeboxoff).toString();
+    if (test != QString::null)
+        freebox_opts.mrl = QString::fromUtf8(test); 
+
     return true;
 }
 
@@ -3586,7 +3631,7 @@
         delete channel;
         channel = NULL;
 
-        GetDevices(newCardID, genOpt, dvbOpt, fwOpt, dboxOpt);
+        GetDevices(newCardID, genOpt, dvbOpt, fwOpt, dboxOpt, freeboxOpt);
         genOpt.defaultinput = inputname;
         CreateChannel(channum);
         if (!(request.flags & kFlagNoRec))
Index: libs/libmythtv/tv_rec.h
===================================================================
--- libs/libmythtv/tv_rec.h	(revision 9856)
+++ libs/libmythtv/tv_rec.h	(working copy)
@@ -39,6 +39,9 @@
 class DVBChannel;
 class Channel;
 
+class FreeboxChannel;
+
+
 class MPEGStreamData;
 class ProgramMapTable;
 
@@ -130,6 +133,16 @@
     QString host;
 };
 
+ 
+class FreeboxDBOptions
+{
+  public:
+    FreeboxDBOptions() : mrl("http://mafreebox.freebox.fr/freeboxtv/playlist.m3u") {}
+
+	QString mrl;
+};
+
+
 class TuningRequest
 {
   public:
@@ -268,11 +281,12 @@
     void SetPseudoLiveTVRecording(ProgramInfo*);
     void TeardownAll(void);
 
-    static bool GetDevices(int cardid,
+    static bool GetDevices(int                cardid,
                            GeneralDBOptions   &general_opts,
                            DVBDBOptions       &dvb_opts,
                            FireWireDBOptions  &firewire_opts,
-                           DBox2DBOptions     &dbox2_opts);
+                           DBox2DBOptions     &dbox2_opts,
+                           FreeboxDBOptions   &free_opts);
 
 
     static QString GetStartChannel(int cardid, const QString &defaultinput);
@@ -286,11 +300,13 @@
     bool CreateChannel(const QString &startChanNum);
     void InitChannel(const QString &inputname, const QString &startchannel);
     void CloseChannel(void);
-    DBox2Channel *GetDBox2Channel(void);
-    HDHRChannel  *GetHDHRChannel(void);
-    DVBChannel   *GetDVBChannel(void);
-    Channel      *GetV4LChannel(void);
 
+    DBox2Channel   *GetDBox2Channel(void);
+    HDHRChannel    *GetHDHRChannel(void);
+    DVBChannel     *GetDVBChannel(void);
+    FreeboxChannel *GetFreeboxChannel(void);
+    Channel        *GetV4LChannel(void);
+
     void SetupSignalMonitor(bool enable_table_monitoring, bool notify);
     bool SetupDTVSignalMonitor(void);
     void TeardownSignalMonitor(void);
@@ -366,6 +382,7 @@
     DVBDBOptions       dvbOpt;
     FireWireDBOptions  fwOpt;
     DBox2DBOptions     dboxOpt;
+    FreeboxDBOptions   freeboxOpt;
 
     // State variables
     QMutex         stateChangeLock;
Index: settings.pro
===================================================================
--- settings.pro	(revision 9856)
+++ settings.pro	(working copy)
@@ -20,6 +20,10 @@
 
 INCLUDEPATH += $${PREFIX}/include
 INCLUDEPATH += $$CONFIG_INCLUDEPATH
+INCLUDEPATH += /usr/include/liveMedia 
+INCLUDEPATH += /usr/include/UsageEnvironment 
+INCLUDEPATH += /usr/include/BasicUsageEnvironment 
+INCLUDEPATH += /usr/include/groupsock 
 
 # figure out compile flags based on qmake info
 
@@ -79,6 +83,7 @@
 EXTRA_LIBS += $$CONFIG_AUDIO_JACK_LIBS
 EXTRA_LIBS += $$CONFIG_FIREWIRE_LIBS
 EXTRA_LIBS += $$CONFIG_DIRECTFB_LIBS
+EXTRA_LIBS += $$CONFIG_LIVE_LIBS
 
 EXTRA_LIBS += $$LOCAL_LIBDIR_OGL
 EXTRA_LIBS += $$LOCAL_LIBDIR_X11
