Index: libs/libmythtv/freeboxsignalmonitor.cpp
===================================================================
--- libs/libmythtv/freeboxsignalmonitor.cpp	(revision 10736)
+++ libs/libmythtv/freeboxsignalmonitor.cpp	(working copy)
@@ -2,6 +2,7 @@
 
 // MythTV headers
 #include "mpegstreamdata.h"
+#include "freeboxfeederwrapper.h"
 #include "freeboxsignalmonitor.h"
 #include "rtspcomms.h"
 
@@ -34,11 +35,12 @@
       dtvMonitorRunning(false)
 {
     bool isLocked = false;
-    if (GetChannel()->GetRTSP()->Init())
+    FreeboxChannelInfo chaninfo = GetChannel()->GetCurrentChanInfo();
+    if (chaninfo.isValid())
     {
-        FreeboxChannelInfo chaninfo = GetChannel()->GetCurrentChanInfo();
-        isLocked = (chaninfo.isValid() && 
-                    GetChannel()->GetRTSP()->Open(chaninfo.m_url));
+        isLocked = GetChannel()->GetFeeder()->Init(chaninfo.m_url);
+        if (isLocked)
+            isLocked = GetChannel()->GetFeeder()->Open();
     }
 
     QMutexLocker locker(&statusLock);
@@ -51,7 +53,7 @@
  */
 FreeboxSignalMonitor::~FreeboxSignalMonitor()
 {
-    GetChannel()->GetRTSP()->RemoveListener(this);
+    GetChannel()->GetFeeder()->RemoveListener(this);
     Stop();
 }
 
@@ -63,7 +65,7 @@
 void FreeboxSignalMonitor::deleteLater(void)
 {
     disconnect(); // disconnect signals we may be sending...
-    GetChannel()->GetRTSP()->RemoveListener(this);
+    GetChannel()->GetFeeder()->RemoveListener(this);
     Stop();
     DTVSignalMonitor::deleteLater();
 }
@@ -74,11 +76,11 @@
 void FreeboxSignalMonitor::Stop(void)
 {
     DBG_SM("Stop", "begin");
-    GetChannel()->GetRTSP()->RemoveListener(this);
+    GetChannel()->GetFeeder()->RemoveListener(this);
     SignalMonitor::Stop();
     if (dtvMonitorRunning)
     {
-        GetChannel()->GetRTSP()->Stop();
+        GetChannel()->GetFeeder()->Stop();
         dtvMonitorRunning = false;
         pthread_join(table_monitor_thread, NULL);
     }
@@ -101,16 +103,16 @@
 
     GetStreamData()->AddListeningPID(0);
 
-    GetChannel()->GetRTSP()->AddListener(this);
-    GetChannel()->GetRTSP()->Run();
-    GetChannel()->GetRTSP()->RemoveListener(this);
+    GetChannel()->GetFeeder()->AddListener(this);
+    GetChannel()->GetFeeder()->Run();
+    GetChannel()->GetFeeder()->RemoveListener(this);
 
     dtvMonitorRunning = false;
     DBG_SM("Run", "end");
 }
 
 void FreeboxSignalMonitor::AddData(
-    unsigned char *data, unsigned dataSize, struct timeval)
+    unsigned char *data, unsigned dataSize)
 {
     GetStreamData()->ProcessData(data, dataSize);
 }
Index: libs/libmythtv/freeboxfeederudp.cpp
===================================================================
--- libs/libmythtv/freeboxfeederudp.cpp	(revision 0)
+++ libs/libmythtv/freeboxfeederudp.cpp	(revision 0)
@@ -0,0 +1,227 @@
+/** -*- Mode: c++ -*-
+ *  FreeboxFeederUdp
+ *  Copyright (c) 2006 by Mickaël Remars
+ *  Distributed as part of MythTV under GPL v2 and later.
+ */
+
+#include "freeboxfeederudp.h"
+
+#include "../libavformat/avformat.h"
+#include "freeboxmediasink.h"
+#include "mythcontext.h"
+#include "tspacket.h"
+
+#define LOC QString("FBFeedUdp:")
+#define LOC_ERR QString("FBFeedUdp, Error:")
+
+
+FreeboxFeederUdp::FreeboxFeederUdp() :
+    url_context(0),
+    network_buffer(0),
+    _stream_fd(-1),
+    _lock(false),
+    _abort(0),
+    _running(false)
+{
+    QMutexLocker locker(&avcodeclock);
+    av_register_all();
+}
+
+FreeboxFeederUdp::~FreeboxFeederUdp()
+{
+}
+
+bool FreeboxFeederUdp::CanHandle(const QString &url) const
+{
+    return url.startsWith("udp://", false);
+}
+
+bool FreeboxFeederUdp::Init(void)
+{
+    // Nothing to init
+    return true;
+}
+
+void FreeboxFeederUdp::Deinit(void)
+{
+    // Nothing to deinit
+}
+
+bool FreeboxFeederUdp::Open(const QString &url)
+{
+    VERBOSE(VB_RECORD, LOC << "Open(" << url << ")");
+
+    avcodeclock.lock();
+    assert(url_context==NULL);
+    int err = url_open(&url_context, url, URL_RDONLY);
+    avcodeclock.unlock();
+
+    if (err < 0)
+    {
+        VERBOSE(VB_IMPORTANT, LOC_ERR +
+                "failed to open the avformat URLContext" + ENO);
+        return false;
+    }
+
+    assert(_stream_fd<0);
+    _stream_fd = udp_get_file_handle(url_context);
+    if (_stream_fd < 0)
+    {
+        VERBOSE(VB_IMPORTANT, LOC_ERR +
+                "failed to get the URLContext's file descriptor" + ENO);
+        return false;
+    }
+    
+    return true;
+}
+
+bool FreeboxFeederUdp::IsOpen(void) const
+{
+    return _stream_fd>=0;
+}
+
+void FreeboxFeederUdp::Close(void)
+{
+    if (url_context)
+    {
+        url_close(url_context);
+        url_context = 0;
+        _stream_fd = -1;
+    }
+}
+
+void FreeboxFeederUdp::Run(void)
+{
+    VERBOSE(VB_RECORD, LOC + "Run() -- begin");
+    _lock.lock();
+    _running = true;
+    _abort   = 0;
+    _lock.unlock();
+
+    VERBOSE(VB_RECORD, LOC + "Run() -- loop begin");
+    DoEventLoop();
+    VERBOSE(VB_RECORD, LOC + "Run() -- loop end");
+
+    _lock.lock();
+    _running = false;
+    _cond.wakeAll();
+    _lock.unlock();
+    VERBOSE(VB_RECORD, LOC + "Run() -- end");
+}
+
+void FreeboxFeederUdp::DoEventLoop(void)
+{
+    struct timeval tv;
+    fd_set rdset;
+    ssize_t bytes_read;
+    ssize_t unprocessed_bytes = 0;
+    unsigned char _buffer[TSPacket::SIZE * 50];
+    int _buffer_size = TSPacket::SIZE * 50;
+    bzero(_buffer, _buffer_size);
+
+    while (!_abort)
+    {
+        tv.tv_sec = 5;
+        tv.tv_usec = 0;
+        FD_ZERO(&rdset);
+        FD_SET(_stream_fd, &rdset);
+
+        // wait until we can read something
+        switch (select(_stream_fd + 1, &rdset, NULL, NULL, &tv))
+        {
+            case -1:
+                if (errno == EINTR)
+                    continue;
+
+                VERBOSE(VB_IMPORTANT, LOC_ERR + "select error" + ENO);
+                continue;
+
+            case 0:
+                VERBOSE(VB_RECORD, LOC_ERR + "select timeout");
+                continue;
+
+            default: break;
+        }
+
+        bytes_read = url_read(url_context, _buffer + unprocessed_bytes,
+                              _buffer_size - unprocessed_bytes);
+
+        if (bytes_read < 0 && errno != EAGAIN)
+        {
+            VERBOSE(VB_IMPORTANT, LOC_ERR +
+                    "failed to read from the URLContext" + ENO);
+            continue;
+        }
+        else if (bytes_read == 0)
+            continue;
+
+        bytes_read += unprocessed_bytes;
+        unprocessed_bytes = ProcessData(_buffer, bytes_read);
+        if (unprocessed_bytes > 0)
+        {
+            ssize_t ts_remainder = unprocessed_bytes % TSPacket::SIZE;
+            if (ts_remainder > 0)
+                unprocessed_bytes += ts_remainder;
+
+            memmove(_buffer, &(_buffer[_buffer_size - unprocessed_bytes]),
+                    unprocessed_bytes);
+        }
+    }
+}
+
+ssize_t FreeboxFeederUdp::ProcessData(unsigned char *buf, ssize_t len)
+{
+    QMutexLocker locker(&_lock);
+    std::vector<RTSPListener*>::iterator it = _listeners.begin();
+    for (; it != _listeners.end(); ++it)
+        (*it)->AddData(buf, len);
+    return 0;
+}
+
+void FreeboxFeederUdp::Stop(void)
+{
+    VERBOSE(VB_RECORD, LOC + "Stop() -- begin");
+    QMutexLocker locker(&_lock);
+    _abort = 0xFF;
+
+    while (_running)
+        _cond.wait(&_lock, 500);
+    VERBOSE(VB_RECORD, LOC + "Stop() -- end");
+}
+
+void FreeboxFeederUdp::AddListener(RTSPListener *item)
+{
+    VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- begin");
+    if (!item)
+    {
+        VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- end 0");
+        return;
+    }
+
+    QMutexLocker locker(&_lock);
+    std::vector<RTSPListener*>::iterator it =
+        find(_listeners.begin(), _listeners.end(), item);
+    if (it == _listeners.end()) // avoid duplicates
+        _listeners.push_back(item);
+
+    VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- end 1");
+}
+
+void FreeboxFeederUdp::RemoveListener(RTSPListener *item)
+{
+    VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- begin");
+    QMutexLocker locker(&_lock);
+    std::vector<RTSPListener*>::iterator it =
+        find(_listeners.begin(), _listeners.end(), item);
+
+    if (it == _listeners.end())
+    {
+        VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- end (not found)");
+        return;
+    }
+
+    // remove from local list..
+    *it = *_listeners.rbegin();
+    _listeners.resize(_listeners.size() - 1);
+    VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- end (ok, removed)");
+}
Index: libs/libmythtv/freeboxchannel.h
===================================================================
--- libs/libmythtv/freeboxchannel.h	(revision 10736)
+++ libs/libmythtv/freeboxchannel.h	(working copy)
@@ -12,7 +12,7 @@
 
 #include <qmutex.h>
 
-class RTSPComms;
+class FreeboxFeederWrapper;
 
 class FreeboxChannel : public ChannelBase
 {
@@ -32,8 +32,8 @@
     FreeboxChannelInfo GetCurrentChanInfo(void) const
         { return GetChanInfo(curchannelname); }
 
-    RTSPComms       *GetRTSP(void)       { return m_rtsp; }
-    const RTSPComms *GetRTSP(void) const { return m_rtsp; }
+    FreeboxFeederWrapper       *GetFeeder(void)       { return m_feeder; }
+    const FreeboxFeederWrapper *GetFeeder(void) const { return m_feeder; }
     
   private:
     FreeboxChannelInfo GetChanInfo(const QString& channum,
@@ -41,7 +41,7 @@
 
     QString               m_videodev;
     fbox_chan_map_t       m_freeboxchannels;
-    RTSPComms            *m_rtsp;
+    FreeboxFeederWrapper *m_feeder;
     mutable QMutex        m_lock;
 
   private:
Index: libs/libmythtv/libmythtv.pro
===================================================================
--- libs/libmythtv/libmythtv.pro	(revision 10736)
+++ libs/libmythtv/libmythtv.pro	(working copy)
@@ -398,10 +398,17 @@
         HEADERS += freeboxchannel.h            freeboxchannelfetcher.h
         HEADERS += freeboxsignalmonitor.h      rtspcomms.h
         HEADERS += freeboxchannelinfo.h
+        HEADERS += freeboxfeeder.h
+        HEADERS += freeboxfeederrtsp.h
+        HEADERS += freeboxfeederudp.h
+        HEADERS += freeboxfeederwrapper.h
 
         SOURCES += freeboxrecorder.cpp         freeboxmediasink.cpp
         SOURCES += freeboxchannel.cpp          freeboxchannelfetcher.cpp
         SOURCES += freeboxsignalmonitor.cpp    rtspcomms.cpp
+        SOURCES += freeboxfeederrtsp.cpp
+        SOURCES += freeboxfeederudp.cpp
+        SOURCES += freeboxfeederwrapper.cpp
 
         DEFINES += USING_FREEBOX
     }
Index: libs/libmythtv/freeboxchannel.cpp
===================================================================
--- libs/libmythtv/freeboxchannel.cpp	(revision 10736)
+++ libs/libmythtv/freeboxchannel.cpp	(working copy)
@@ -11,7 +11,7 @@
 #include "libmyth/mythcontext.h"
 #include "libmyth/mythdbcon.h"
 #include "libmythtv/freeboxchannelfetcher.h"
-#include "libmythtv/rtspcomms.h"
+#include "libmythtv/freeboxfeederwrapper.h"
 
 #define LOC QString("FBChan(%1): ").arg(GetCardID())
 #define LOC_ERR QString("FBChan(%1), Error: ").arg(GetCardID())
@@ -20,7 +20,7 @@
                                const QString &videodev)
     : ChannelBase(parent),
       m_videodev(QDeepCopy<QString>(videodev)),
-      m_rtsp(new RTSPComms()),
+      m_feeder(new FreeboxFeederWrapper()),
       m_lock(true)
 {
     VERBOSE(VB_CHANNEL, LOC + "ctor");
@@ -29,10 +29,10 @@
 FreeboxChannel::~FreeboxChannel()
 {
     VERBOSE(VB_CHANNEL, LOC + "dtor -- begin");
-    if (m_rtsp)
+    if (m_feeder)
     {
-        delete m_rtsp;
-        m_rtsp = NULL;
+        delete m_feeder;
+        m_feeder = NULL;
     }
     VERBOSE(VB_CHANNEL, LOC + "dtor -- end");
 }
Index: libs/libmythtv/freeboxmediasink.cpp
===================================================================
--- libs/libmythtv/freeboxmediasink.cpp	(revision 10736)
+++ libs/libmythtv/freeboxmediasink.cpp	(working copy)
@@ -61,12 +61,12 @@
 }
 
 void FreeboxMediaSink::afterGettingFrame1(unsigned int   frameSize,
-                                          struct timeval presentationTime)
+                                          struct timeval)
 {
     lock.lock();
     vector<RTSPListener*>::iterator it = listeners.begin();
     for (; it != listeners.end(); ++it)
-        (*it)->AddData(fBuffer, frameSize, presentationTime);
+        (*it)->AddData(fBuffer, frameSize);
     lock.unlock();
 
     continuePlaying();
Index: libs/libmythtv/freeboxsignalmonitor.h
===================================================================
--- libs/libmythtv/freeboxsignalmonitor.h	(revision 10736)
+++ libs/libmythtv/freeboxsignalmonitor.h	(working copy)
@@ -6,9 +6,9 @@
 #include "dtvsignalmonitor.h"
 #include "freeboxmediasink.h"
 
-class RTSPComms;
 class FreeboxChannel;
 
+
 class FreeboxSignalMonitor : public DTVSignalMonitor, public RTSPListener
 {
     Q_OBJECT
@@ -23,8 +23,7 @@
 
     // implements RTSPListener
     void AddData(unsigned char *data,
-                 unsigned       dataSize,
-                 struct timeval);
+                 unsigned       dataSize);
 
   public slots:
     void deleteLater(void);
Index: libs/libmythtv/freeboxfeederwrapper.cpp
===================================================================
--- libs/libmythtv/freeboxfeederwrapper.cpp	(revision 0)
+++ libs/libmythtv/freeboxfeederwrapper.cpp	(revision 0)
@@ -0,0 +1,160 @@
+/** -*- Mode: c++ -*-
+ *  FreeboxFeederWrapper
+ *  Copyright (c) 2006 by Mickaël Remars
+ *  Distributed as part of MythTV under GPL v2 and later.
+ */
+
+#include "freeboxfeederwrapper.h"
+
+#include "freeboxfeeder.h"
+#include "freeboxfeederrtsp.h"
+#include "freeboxfeederudp.h"
+#include "mythcontext.h"
+
+#define LOC QString("FBFeed: ")
+#define LOC_ERR QString("FBFeed, Error: ")
+
+
+FreeboxFeederWrapper::FreeboxFeederWrapper() :
+    _feeder(NULL)
+{
+}
+
+FreeboxFeederWrapper::~FreeboxFeederWrapper()
+{
+    delete _feeder;
+}
+
+bool FreeboxFeederWrapper::Init(const QString &url)
+{
+    VERBOSE(VB_RECORD, LOC + "Init() -- begin");
+    QMutexLocker locker(&_lock);
+    if (_feeder && _feeder->CanHandle(url))
+    {
+        _url = url;
+        VERBOSE(VB_RECORD, LOC + "Init() -- end 0");
+        return true;
+    }
+
+    FreeboxFeeder *feeder = NULL;
+    if (url.startsWith("rtsp://", false))
+    {
+        feeder = new FreeboxFeederRtsp();
+    }
+    else if (url.startsWith("udp://", false))
+    {
+        feeder = new FreeboxFeederUdp();
+    }
+    else
+    {
+        VERBOSE(VB_RECORD, LOC_ERR + QString("Init() -- unhandled url (%1)")
+            .arg(url));
+    }
+    bool result = feeder && feeder->Init();
+    delete _feeder;
+    _url = url;
+    _feeder = feeder;
+    
+    VERBOSE(VB_RECORD, LOC + "Init() -- adding listeners");
+    std::vector<RTSPListener*>::iterator it = _listeners.begin();
+    for (; it != _listeners.end(); ++it)
+        _feeder->AddListener(*it);
+    
+    VERBOSE(VB_RECORD, LOC + "Init() -- end 1");
+    return result;
+}
+
+void FreeboxFeederWrapper::Deinit(void)
+{
+    VERBOSE(VB_RECORD, LOC + "Deinit() -- begin");
+    QMutexLocker locker(&_lock);
+    assert(_feeder!=NULL);
+    _feeder->Deinit();
+    delete _feeder;
+    _feeder = NULL;
+    _url = QString();
+    VERBOSE(VB_RECORD, LOC + "Deinit() -- end");
+}
+
+bool FreeboxFeederWrapper::Open()
+{
+    VERBOSE(VB_RECORD, LOC + "Open() -- begin");
+    assert(_feeder!=NULL);
+    bool result = _feeder->Open(_url);
+    VERBOSE(VB_RECORD, LOC + "Open() -- end");
+    return result;
+}
+
+bool FreeboxFeederWrapper::IsOpen(void) const
+{
+    VERBOSE(VB_RECORD, LOC + "IsOpen() -- begin");
+    assert(_feeder!=NULL);
+    bool result = _feeder->IsOpen();
+    VERBOSE(VB_RECORD, LOC + "IsOpen() -- end");
+    return result;
+}
+
+void FreeboxFeederWrapper::Close(void)
+{
+    VERBOSE(VB_RECORD, LOC + "Close() -- begin");
+    assert(_feeder!=NULL);
+    _feeder->Close();
+    VERBOSE(VB_RECORD, LOC + "Close() -- end");
+}
+
+void FreeboxFeederWrapper::Run(void)
+{
+    VERBOSE(VB_RECORD, LOC + "Run() -- begin");
+    assert(_feeder!=NULL);
+    _feeder->Run();
+    VERBOSE(VB_RECORD, LOC + "Run() -- end");
+}
+
+void FreeboxFeederWrapper::Stop(void)
+{
+    VERBOSE(VB_RECORD, LOC + "Stop() -- begin");
+    assert(_feeder!=NULL);
+    _feeder->Stop();
+    VERBOSE(VB_RECORD, LOC + "Stop() -- end");
+}
+
+void FreeboxFeederWrapper::AddListener(RTSPListener *item)
+{
+    VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- begin");
+    if (!item)
+    {
+        VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- end 0");
+        return;
+    }
+
+    QMutexLocker locker(&_lock);
+    std::vector<RTSPListener*>::iterator it =
+        find(_listeners.begin(), _listeners.end(), item);
+    if (it == _listeners.end()) // avoid duplicates
+    {
+        _listeners.push_back(item);
+        if(_feeder) _feeder->AddListener(item);
+    }
+
+    VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- end 1");
+}
+
+void FreeboxFeederWrapper::RemoveListener(RTSPListener *item)
+{
+    VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- begin");
+    QMutexLocker locker(&_lock);
+    std::vector<RTSPListener*>::iterator it =
+        find(_listeners.begin(), _listeners.end(), item);
+
+    if (it == _listeners.end())
+    {
+        VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- end (not found)");
+        return;
+    }
+
+    // remove from local list..
+    *it = *_listeners.rbegin();
+    _listeners.resize(_listeners.size() - 1);
+    if(_feeder) _feeder->RemoveListener(item);
+    VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- end (ok, removed)");
+}
Index: libs/libmythtv/freeboxfeederrtsp.h
===================================================================
--- libs/libmythtv/freeboxfeederrtsp.h	(revision 0)
+++ libs/libmythtv/freeboxfeederrtsp.h	(revision 0)
@@ -0,0 +1,45 @@
+/** -*- Mode: c++ -*-
+ *  FreeboxFeederRtsp
+ *  Copyright (c) 2006 by Mickaël Remars
+ *  Distributed as part of MythTV under GPL v2 and later.
+ */
+
+#ifndef FREEBOXFEEDERRTSP_H
+#define FREEBOXFEEDERRTSP_H
+
+#include "freeboxfeeder.h"
+#include "rtspcomms.h"
+
+
+class FreeboxFeederRtsp : public FreeboxFeeder
+{
+  public:
+    FreeboxFeederRtsp();
+    virtual ~FreeboxFeederRtsp();
+
+  public:
+    bool CanHandle(const QString &url) const;
+    bool Init(void);
+    void Deinit(void);
+
+    bool Open(const QString &url);
+    bool IsOpen(void) const;
+    void Close(void);
+
+    void Run(void);
+    void Stop(void);
+
+    void AddListener(RTSPListener*);
+    void RemoveListener(RTSPListener*);
+
+  private:
+    RTSPComms m_rtsp;
+
+  private:
+    /// avoid default copy operator
+    FreeboxFeederRtsp& operator=(const FreeboxFeederRtsp&);
+    /// avoid default copy constructor
+    FreeboxFeederRtsp(const FreeboxFeederRtsp&);
+};
+
+#endif // FREEBOXFEEDERRTSP_H
Index: libs/libmythtv/freeboxrecorder.cpp
===================================================================
--- libs/libmythtv/freeboxrecorder.cpp	(revision 10736)
+++ libs/libmythtv/freeboxrecorder.cpp	(working copy)
@@ -8,8 +8,8 @@
 #include "mpegstreamdata.h"
 #include "tspacket.h"
 #include "freeboxchannel.h"
+#include "freeboxfeederwrapper.h"
 #include "freeboxrecorder.h"
-#include "rtspcomms.h"
 
 #define LOC QString("FBRec: ")
 #define LOC_ERR QString("FBRec, Error: ")
@@ -23,21 +23,21 @@
     _channel(channel),
     _stream_data(NULL)
 {
-    _channel->GetRTSP()->AddListener(this);
+    _channel->GetFeeder()->AddListener(this);
 }
 
 FreeboxRecorder::~FreeboxRecorder()
 {
     StopRecording();
-    _channel->GetRTSP()->RemoveListener(this);
+    _channel->GetFeeder()->RemoveListener(this);
 }
 
 bool FreeboxRecorder::Open(void)
 {
     VERBOSE(VB_RECORD, LOC + "Open() -- begin");
 
-    if (_channel->GetRTSP()->IsOpen())
-        _channel->GetRTSP()->Close();
+    if (_channel->GetFeeder()->IsOpen())
+        _channel->GetFeeder()->Close();
 
     FreeboxChannelInfo chaninfo = _channel->GetCurrentChanInfo();
     if (!chaninfo.isValid())
@@ -46,9 +46,9 @@
     }
     else
     {
-        _error = !(_channel->GetRTSP()->Init()); 
+        _error = !(_channel->GetFeeder()->Init(chaninfo.m_url)); 
         if (!_error)
-            _error = !(_channel->GetRTSP()->Open(chaninfo.m_url));
+            _error = !(_channel->GetFeeder()->Open());
     }
 
     VERBOSE(VB_RECORD, LOC + "Open() -- end err("<<_error<<")");
@@ -58,8 +58,8 @@
 void FreeboxRecorder::Close(void)
 {
     VERBOSE(VB_RECORD, LOC + "Close() -- begin");
-    _channel->GetRTSP()->Stop();
-    _channel->GetRTSP()->Close();
+    _channel->GetFeeder()->Stop();
+    _channel->GetFeeder()->Close();
     VERBOSE(VB_RECORD, LOC + "Close() -- end");
 }
 
@@ -67,15 +67,15 @@
 {
     VERBOSE(VB_RECORD, LOC + "Pause() -- begin");
     DTVRecorder::Pause(clear);
-    _channel->GetRTSP()->Stop();
-    _channel->GetRTSP()->Close();
+    _channel->GetFeeder()->Stop();
+    _channel->GetFeeder()->Close();
     VERBOSE(VB_RECORD, LOC + "Pause() -- end");
 }
 
 void FreeboxRecorder::Unpause(void)
 {
     VERBOSE(VB_RECORD, LOC + "Unpause() -- begin");
-    if (_recording && !_channel->GetRTSP()->IsOpen())
+    if (_recording && !_channel->GetFeeder()->IsOpen())
         Open();
     DTVRecorder::Unpause();
     VERBOSE(VB_RECORD, LOC + "Unpause() -- end");
@@ -99,14 +99,14 @@
         if (PauseAndWait())
             continue;
 
-        if (!_channel->GetRTSP()->IsOpen())
+        if (!_channel->GetFeeder()->IsOpen())
         {
             usleep(5000);
             continue;
         }
 
         // Go into main RTSP loop, feeding data to AddData
-        _channel->GetRTSP()->Run();
+        _channel->GetFeeder()->Run();
     }
 
     // Finish up...
@@ -122,7 +122,7 @@
 {
     VERBOSE(VB_RECORD, LOC + "StopRecording() -- begin");
     Pause();
-    _channel->GetRTSP()->Close();
+    _channel->GetFeeder()->Close();
 
     _request_recording = false;
     while (_recording)
@@ -153,8 +153,7 @@
 // AddData : feed data from RTSP flow to mythtv
 // ===================================================
 void FreeboxRecorder::AddData(unsigned char *data,
-                              unsigned       dataSize,
-                              struct timeval)
+                              unsigned       dataSize)
 {
     unsigned int readIndex = 0;
 
Index: libs/libmythtv/freeboxfeederudp.h
===================================================================
--- libs/libmythtv/freeboxfeederudp.h	(revision 0)
+++ libs/libmythtv/freeboxfeederudp.h	(revision 0)
@@ -0,0 +1,67 @@
+/** -*- Mode: c++ -*-
+ *  FreeboxFeederUdp
+ *  Copyright (c) 2006 by Mickaël Remars
+ *  Distributed as part of MythTV under GPL v2 and later.
+ */
+
+#ifndef FREEBOXFEEDERUDP_H
+#define FREEBOXFEEDERUDP_H
+
+// C++ headers
+#include <vector>
+
+// Qt headers
+#include <qwaitcondition.h>
+#include <qmutex.h>
+
+// MythTV headers
+#include "freeboxfeeder.h"
+
+struct URLContext;
+
+
+class FreeboxFeederUdp : public FreeboxFeeder
+{
+  public:
+    FreeboxFeederUdp();
+    virtual ~FreeboxFeederUdp();
+
+  public:
+    bool CanHandle(const QString& url) const;
+    bool Init(void);
+    void Deinit(void);
+
+    bool Open(const QString &url);
+    bool IsOpen(void) const;
+    void Close(void);
+
+    void Run(void);
+    void Stop(void);
+
+    void AddListener(RTSPListener*);
+    void RemoveListener(RTSPListener*);
+
+  private:
+    void DoEventLoop();
+    ssize_t ProcessData(unsigned char *buf, ssize_t len);
+
+  private:
+    // UDP support (using libavformat)
+    URLContext     *url_context;
+    unsigned char  *network_buffer;
+    int             _stream_fd;
+    
+    std::vector<RTSPListener*> _listeners;
+    QWaitCondition  _cond;       ///< Condition  used to coordinate threads
+    mutable QMutex  _lock;       ///< Lock  used to coordinate threads
+    char            _abort;
+    bool            _running;
+
+  private:
+    /// avoid default copy operator
+    FreeboxFeederUdp& operator=(const FreeboxFeederUdp&);
+    /// avoid default copy constructor
+    FreeboxFeederUdp(const FreeboxFeederUdp&);
+};
+
+#endif // FREEBOXFEEDERUDP_H
Index: libs/libmythtv/freeboxmediasink.h
===================================================================
--- libs/libmythtv/freeboxmediasink.h	(revision 10736)
+++ libs/libmythtv/freeboxmediasink.h	(working copy)
@@ -19,8 +19,7 @@
   public:
     /// Callback function to add MPEG2 TS data
     virtual void AddData(unsigned char *data,
-                         unsigned int   dataSize,
-                         struct timeval presentationTime) = 0;
+                         unsigned int   dataSize) = 0;
   protected:
     virtual ~RTSPListener() {}
 };
Index: libs/libmythtv/freeboxrecorder.h
===================================================================
--- libs/libmythtv/freeboxrecorder.h	(revision 10736)
+++ libs/libmythtv/freeboxrecorder.h	(working copy)
@@ -47,8 +47,7 @@
 
     // implements RTSPListener
     void AddData(unsigned char *data,
-                 unsigned int   dataSize,
-                 struct timeval presentationTime);
+                 unsigned int   dataSize);
 
     // implements MPEGSingleProgramStreamListener
     void HandleSingleProgramPAT(ProgramAssociationTable *pat);
Index: libs/libmythtv/freeboxfeeder.h
===================================================================
--- libs/libmythtv/freeboxfeeder.h	(revision 0)
+++ libs/libmythtv/freeboxfeeder.h	(revision 0)
@@ -0,0 +1,36 @@
+/** -*- Mode: c++ -*-
+ *  FreeboxFeeder
+ *  Copyright (c) 2006 by Mickaël Remars
+ *  Distributed as part of MythTV under GPL v2 and later.
+ */
+
+#ifndef FREEBOXFEEDER_H
+#define FREEBOXFEEDER_H
+
+#include <qstring.h>
+
+class RTSPListener;
+
+
+class FreeboxFeeder
+{
+  public:
+    virtual ~FreeboxFeeder() {}
+    
+    virtual bool CanHandle(const QString &url) const = 0;
+    virtual bool Init(void) = 0;
+    virtual void Deinit(void) = 0;
+
+    virtual bool Open(const QString &url) = 0;
+    virtual bool IsOpen(void) const = 0;
+    virtual void Close(void) = 0;
+
+    virtual void Run(void) = 0;
+    virtual void Stop(void) = 0;
+
+    virtual void AddListener(RTSPListener*) = 0;
+    virtual void RemoveListener(RTSPListener*) = 0;
+};
+
+#endif//FREEBOXFEEDER_H
+
Index: libs/libmythtv/freeboxfeederrtsp.cpp
===================================================================
--- libs/libmythtv/freeboxfeederrtsp.cpp	(revision 0)
+++ libs/libmythtv/freeboxfeederrtsp.cpp	(revision 0)
@@ -0,0 +1,65 @@
+/** -*- Mode: c++ -*-
+ *  FreeboxFeederRtsp
+ *  Copyright (c) 2006 by Mickaël Remars
+ *  Distributed as part of MythTV under GPL v2 and later.
+ */
+
+#include "freeboxfeederrtsp.h"
+
+FreeboxFeederRtsp::FreeboxFeederRtsp()
+{
+}
+
+FreeboxFeederRtsp::~FreeboxFeederRtsp()
+{
+}
+
+bool FreeboxFeederRtsp::CanHandle(const QString &url) const
+{
+    return url.startsWith("rtsp://", false);
+}
+
+bool FreeboxFeederRtsp::Init(void)
+{
+    return m_rtsp.Init();
+}
+
+void FreeboxFeederRtsp::Deinit(void)
+{
+    m_rtsp.Deinit();
+}
+
+bool FreeboxFeederRtsp::Open(const QString &url)
+{
+    return m_rtsp.Open(url);
+}
+
+bool FreeboxFeederRtsp::IsOpen(void) const
+{
+    return m_rtsp.IsOpen();
+}
+
+void FreeboxFeederRtsp::Close(void)
+{
+    m_rtsp.Close();
+}
+
+void FreeboxFeederRtsp::Run(void)
+{
+    m_rtsp.Run();
+}
+
+void FreeboxFeederRtsp::Stop(void)
+{
+    m_rtsp.Stop();
+}
+
+void FreeboxFeederRtsp::AddListener(RTSPListener *listener)
+{
+    m_rtsp.AddListener(listener);
+}
+
+void FreeboxFeederRtsp::RemoveListener(RTSPListener *listener)
+{
+    m_rtsp.RemoveListener(listener);
+}
Index: libs/libmythtv/freeboxfeederwrapper.h
===================================================================
--- libs/libmythtv/freeboxfeederwrapper.h	(revision 0)
+++ libs/libmythtv/freeboxfeederwrapper.h	(revision 0)
@@ -0,0 +1,51 @@
+/** -*- Mode: c++ -*-
+ *  FreeboxFeederWrapper
+ *  Copyright (c) 2006 by Mickaël Remars
+ *  Distributed as part of MythTV under GPL v2 and later.
+ */
+
+#ifndef FREEBOXFEEDERWRAPPER_H
+#define FREEBOXFEEDERWRAPPER_H
+
+#include <qmutex.h>
+#include <qstring.h>
+#include <vector>
+
+class FreeboxFeeder;
+class RTSPListener;
+
+
+class FreeboxFeederWrapper
+{
+  public:
+    FreeboxFeederWrapper();
+    ~FreeboxFeederWrapper();
+
+  public:
+    bool Init(const QString &url);
+    void Deinit(void);
+
+    bool Open(void);
+    bool IsOpen(void) const;
+    void Close(void);
+
+    void Run(void);
+    void Stop(void);
+
+    void AddListener(RTSPListener*);
+    void RemoveListener(RTSPListener*);
+    
+  private:
+    FreeboxFeeder *_feeder;
+    QString        _url;
+    mutable QMutex  _lock; ///< Lock  used to coordinate threads
+    std::vector<RTSPListener*> _listeners;
+
+  private:
+    /// avoid default copy operator
+    FreeboxFeederWrapper& operator=(const FreeboxFeederWrapper&);
+    /// avoid default copy constructor
+    FreeboxFeederWrapper(const FreeboxFeederWrapper&);
+};
+
+#endif//FREEBOXFEEDERWRAPPER_H
