Index: libs/libmythtv/libmythtv.pro
===================================================================
--- libs/libmythtv/libmythtv.pro	(revision 11660)
+++ libs/libmythtv/libmythtv.pro	(working copy)
@@ -402,7 +402,9 @@
         HEADERS += iptv/iptvchannelfetcher.h  iptv/iptvchannelinfo.h
         HEADERS += iptv/iptvmediasink.h       iptv/iptvlistener.h
         HEADERS += iptv/iptvfeeder.h          iptv/iptvfeederwrapper.h
-        HEADERS += iptv/iptvfeederrtsp.h      iptv/iptvfeederlive.h
+        HEADERS += iptv/iptvfeederrtsp.h      iptv/iptvfeederudp.h
+        HEADERS += iptv/iptvfeederfile.h      iptv/iptvfeederlive.h
+        HEADERS += iptv/iptvfeederrtp.h
         HEADERS += iptv/urlfetcher.h          iptv/timeoutedtaskscheduler.h
 
         SOURCES += iptvchannel.cpp            iptvrecorder.cpp
@@ -410,7 +412,9 @@
         SOURCES += iptv/iptvchannelfetcher.cpp
         SOURCES += iptv/iptvmediasink.cpp
         SOURCES += iptv/iptvfeeder.cpp        iptv/iptvfeederwrapper.cpp
-        SOURCES += iptv/iptvfeederrtsp.cpp    iptv/iptvfeederlive.cpp
+        SOURCES += iptv/iptvfeederrtsp.cpp    iptv/iptvfeederudp.cpp
+        SOURCES += iptv/iptvfeederfile.cpp    iptv/iptvfeederlive.cpp
+        SOURCES += iptv/iptvfeederrtp.cpp
         SOURCES += iptv/urlfetcher.cpp        iptv/timeoutedtaskscheduler.cpp
 
         DEFINES += USING_IPTV
Index: libs/libmythtv/iptv/iptvfeederwrapper.cpp
===================================================================
--- libs/libmythtv/iptv/iptvfeederwrapper.cpp	(revision 11660)
+++ libs/libmythtv/iptv/iptvfeederwrapper.cpp	(working copy)
@@ -8,6 +8,9 @@
 
 #include "iptvfeeder.h"
 #include "iptvfeederrtsp.h"
+#include "iptvfeederudp.h"
+#include "iptvfeederrtp.h"
+#include "iptvfeederfile.h"
 #include "mythcontext.h"
 
 #define LOC QString("IPTVFeed: ")
@@ -48,6 +51,18 @@
     {
         tmp_feeder = new IPTVFeederRTSP();
     }
+    else if (IPTVFeederUDP::IsUDP(url))
+    {
+        tmp_feeder = new IPTVFeederUDP();
+    }
+    else if (IPTVFeederRTP::IsRTP(url))
+    {
+        tmp_feeder = new IPTVFeederRTP();
+    }
+    else if (IPTVFeederFile::IsFile(url))
+    {
+        tmp_feeder = new IPTVFeederFile();
+    }
     else
     {
         VERBOSE(VB_RECORD, LOC_ERR +
Index: libs/libmythtv/iptv/iptvfeederfile.h
===================================================================
--- libs/libmythtv/iptv/iptvfeederfile.h	(revision 0)
+++ libs/libmythtv/iptv/iptvfeederfile.h	(revision 0)
@@ -0,0 +1,44 @@
+/** -*- Mode: c++ -*-
+ *  IPTVFeederFile
+ *  Copyright (c) 2006 by Mike Mironov & Mickaël Remars
+ *  Distributed as part of MythTV under GPL v2 and later.
+ */
+
+#ifndef _IPTV_FEEDER_FILE_H_
+#define _IPTV_FEEDER_FILE_H_
+
+// MythTV headers
+#include "iptvfeederlive.h"
+
+class IPTVListener;
+class ByteStreamFileSource;
+class IPTVMediaSink;
+
+
+class IPTVFeederFile : public IPTVFeederLive
+{
+  public:
+    IPTVFeederFile();
+    virtual ~IPTVFeederFile();
+
+    bool CanHandle(const QString &url) const { return IsFile(url); }
+    bool IsOpen(void) const { return _source; }
+
+    bool Open(const QString &url);
+    void Close(void);
+
+    void AddListener(IPTVListener*);
+    void RemoveListener(IPTVListener*);
+
+    static bool IsFile(const QString &url);
+
+  private:
+    IPTVFeederFile &operator=(const IPTVFeederFile&);
+    IPTVFeederFile(const IPTVFeederFile&);
+
+  private:
+    ByteStreamFileSource *_source;
+    IPTVMediaSink        *_sink;
+};
+
+#endif //_IPTV_FEEDER_FILE_H_
Index: libs/libmythtv/iptv/iptvfeederudp.cpp
===================================================================
--- libs/libmythtv/iptv/iptvfeederudp.cpp	(revision 0)
+++ libs/libmythtv/iptv/iptvfeederudp.cpp	(revision 0)
@@ -0,0 +1,187 @@
+/** -*- Mode: c++ -*-
+ *  IPTVFeederUdp
+ *  Copyright (c) 2006 by Mike Mironov & Mickaël Remars
+ *  Distributed as part of MythTV under GPL v2 and later.
+ */
+
+#include "iptvfeederudp.h"
+
+// Qt headers
+#include <qurl.h>
+
+// Live555 headers
+#include <BasicUsageEnvironment.hh>
+#include <Groupsock.hh>
+#include <GroupsockHelper.hh>
+#include <BasicUDPSource.hh>
+#include <TunnelEncaps.hh>
+
+// MythTV headers
+#include "iptvmediasink.h"
+#include "mythcontext.h"
+#include "tspacket.h"
+
+#define LOC QString("IPTVFeedUDP: ")
+#define LOC_ERR QString("IPTVFeedUDP, Error: ")
+
+IPTVFeederUDP::IPTVFeederUDP() :
+    _source(NULL),
+    _sink(NULL)
+{
+    VERBOSE(VB_RECORD, LOC + "ctor -- success");
+}
+
+IPTVFeederUDP::~IPTVFeederUDP()
+{
+    VERBOSE(VB_RECORD, LOC + "dtor -- begin");
+    Close();
+    VERBOSE(VB_RECORD, LOC + "dtor -- end");
+}
+
+bool IPTVFeederUDP::IsUDP(const QString &url)
+{
+    return url.startsWith("udp://", false);
+}
+
+bool IPTVFeederUDP::Open(const QString &url)
+{
+    VERBOSE(VB_RECORD, LOC + QString("Open(%1) -- begin").arg(url));
+
+    QMutexLocker locker(&_lock);
+
+    if (_source)
+    {
+        VERBOSE(VB_RECORD, LOC + "Open() -- end 1");
+        return true;
+    }
+        
+    QUrl parse(url);
+    if (!parse.isValid() || !parse.hasHost() || !parse.hasPort())
+    {
+        VERBOSE(VB_RECORD, LOC + "Open() -- end 2");
+        return false;
+    }
+        
+    struct in_addr addr;
+    addr.s_addr = our_inet_addr(parse.host().latin1());
+
+    // Begin by setting up our usage environment:
+    if (!InitEnv())
+        return false;
+    
+    Groupsock *socket = new Groupsock(*_live_env, addr, parse.port(), 0);
+    if (!socket)
+    {
+        VERBOSE(VB_IMPORTANT, LOC + "Failed to create Live UDP Socket.");
+        FreeEnv();
+        return false;
+    }
+    _source = BasicUDPSource::createNew(*_live_env, socket);
+    if (!_source)
+    {
+        VERBOSE(VB_IMPORTANT, LOC + "Failed to create Live UDP Source.");
+
+        if (socket)
+            delete socket;
+
+        FreeEnv();
+        return false;
+    }
+
+    _sink = IPTVMediaSink::CreateNew(*_live_env, TSPacket::SIZE * 128*1024);
+    if (!_sink)
+    {
+        VERBOSE(VB_IMPORTANT,
+                QString("IPTV # Failed to create sink: %1")
+                .arg(_live_env->getResultMsg()));
+
+        Medium::close(_source);
+        _source = NULL;
+        if (socket)
+            delete socket;
+        FreeEnv();
+
+        return false;
+    }
+
+    _sink->startPlaying(*_source, NULL, NULL);
+    vector<IPTVListener*>::iterator it = _listeners.begin();
+    for (; it != _listeners.end(); ++it)
+        _sink->AddListener(*it);
+        
+    VERBOSE(VB_RECORD, LOC + "Open() -- end");
+
+    return true;
+}
+
+void IPTVFeederUDP::Close(void)
+{
+    VERBOSE(VB_RECORD, LOC + "Close() -- begin");
+    Stop();
+
+    QMutexLocker locker(&_lock);
+
+    if (_sink)
+    {
+        Medium::close(_sink);
+        _sink = NULL;
+    }
+
+    if (_source)
+    {
+        Groupsock *socket = _source->gs();
+        Medium::close(_source);
+        _source = NULL;
+        if (socket)
+            delete socket;
+    }
+
+    FreeEnv();
+
+    VERBOSE(VB_RECORD, LOC + "Close() -- end");
+}
+
+void IPTVFeederUDP::AddListener(IPTVListener *item)
+{
+    VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- begin");
+    if (!item)
+    {
+        VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- end");
+        return;
+    }
+
+    // avoid duplicates
+    RemoveListener(item);
+
+    // add to local list
+    QMutexLocker locker(&_lock);
+    _listeners.push_back(item);
+    
+    if (_sink)
+        _sink->AddListener(item);
+
+    VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- end");
+}
+
+void IPTVFeederUDP::RemoveListener(IPTVListener *item)
+{
+    VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- begin");
+    QMutexLocker locker(&_lock);
+    vector<IPTVListener*>::iterator it =
+        find(_listeners.begin(), _listeners.end(), item);
+
+    if (it == _listeners.end())
+    {
+        VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- end 1");
+        return;
+    }
+
+    // remove from local list..
+    *it = *_listeners.rbegin();
+    _listeners.resize(_listeners.size() - 1);
+
+    if (_sink)
+        _sink->RemoveListener(item);
+
+    VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- end 2");
+}
Index: libs/libmythtv/iptv/iptvfeederudp.h
===================================================================
--- libs/libmythtv/iptv/iptvfeederudp.h	(revision 0)
+++ libs/libmythtv/iptv/iptvfeederudp.h	(revision 0)
@@ -0,0 +1,39 @@
+/** -*- Mode: c++ -*-
+ *  IPTVFeederUDP
+ *  Copyright (c) 2006 by Mike Mironov & Mickaël Remars
+ *  Distributed as part of MythTV under GPL v2 and later.
+ */
+
+#ifndef _IPTV_FEEDER_UDP_H_
+#define _IPTV_FEEDER_UDP_H_
+
+// MythTV headers
+#include "iptvfeederlive.h"
+
+class BasicUDPSource;
+class IPTVMediaSink;
+
+
+class IPTVFeederUDP : public IPTVFeederLive
+{
+  public:
+    IPTVFeederUDP();
+    virtual ~IPTVFeederUDP();
+
+    bool CanHandle(const QString &url) const { return IsUDP(url); }
+    bool IsOpen(void) const { return _source; }
+
+    bool Open(const QString &url);
+    void Close(void);
+
+    void AddListener(IPTVListener*);
+    void RemoveListener(IPTVListener*);
+
+    static bool IsUDP(const QString &url);
+
+  private:
+    BasicUDPSource *_source;
+    IPTVMediaSink  *_sink;
+};
+
+#endif // _IPTV_FEEDER_UDP_H_
Index: libs/libmythtv/iptv/iptvfeederrtp.cpp
===================================================================
--- libs/libmythtv/iptv/iptvfeederrtp.cpp	(revision 0)
+++ libs/libmythtv/iptv/iptvfeederrtp.cpp	(revision 0)
@@ -0,0 +1,189 @@
+/** -*- Mode: c++ -*-
+ *  IPTVFeederRtp
+ *  Copyright (c) 2006 by Mike Mironov & Mickaël Remars
+ *  Distributed as part of MythTV under GPL v2 and later.
+ */
+
+#include "iptvfeederrtp.h"
+
+// Qt headers
+#include <qurl.h>
+
+// Live555 headers
+#include <BasicUsageEnvironment.hh>
+#include <Groupsock.hh>
+#include <GroupsockHelper.hh>
+#include <SimpleRTPSource.hh>
+#include <TunnelEncaps.hh>
+
+// MythTV headers
+#include "iptvmediasink.h"
+#include "mythcontext.h"
+#include "tspacket.h"
+
+#define LOC QString("IPTVFeedRTP: ")
+#define LOC_ERR QString("IPTVFeedRTP, Error: ")
+
+IPTVFeederRTP::IPTVFeederRTP() :
+    _source(NULL),
+    _sink(NULL)
+{
+    VERBOSE(VB_RECORD, LOC + "ctor -- success");
+}
+
+IPTVFeederRTP::~IPTVFeederRTP()
+{
+    VERBOSE(VB_RECORD, LOC + "dtor -- begin");
+    Close();
+    VERBOSE(VB_RECORD, LOC + "dtor -- end");
+}
+
+bool IPTVFeederRTP::IsRTP(const QString &url)
+{
+    return url.startsWith("rtp://", false);
+}
+
+bool IPTVFeederRTP::Open(const QString &url)
+{
+    VERBOSE(VB_RECORD, LOC + QString("Open(%1) -- begin").arg(url));
+
+    QMutexLocker locker(&_lock);
+
+    if (_source)
+    {
+        VERBOSE(VB_RECORD, LOC + "Open() -- end 1");
+        return true;
+    }
+        
+    QUrl parse(url);
+    if (!parse.isValid() || !parse.hasHost() || !parse.hasPort())
+    {
+        VERBOSE(VB_RECORD, LOC + "Open() -- end 2");
+        return false;
+    }
+        
+    struct in_addr addr;
+    addr.s_addr = our_inet_addr(parse.host().latin1());
+
+    // Begin by setting up our usage environment:
+    if (!InitEnv())
+        return false;
+    
+    Groupsock *socket = new Groupsock(*_live_env, addr, parse.port(), 0);
+    if (!socket)
+    {
+        VERBOSE(VB_IMPORTANT, LOC + "Failed to create Live RTP Socket.");
+        FreeEnv();
+        return false;
+    }
+    
+    _source = SimpleRTPSource::createNew(*_live_env, socket, 33, 90000,
+                                         "video/MP2T", 0, False);
+    if (!_source)
+    {
+        VERBOSE(VB_IMPORTANT, LOC + "Failed to create Live RTP Source.");
+
+        if (socket)
+            delete socket;
+
+        FreeEnv();
+        return false;
+    }
+
+    _sink = IPTVMediaSink::CreateNew(*_live_env, TSPacket::SIZE * 128*1024);
+    if (!_sink)
+    {
+        VERBOSE(VB_IMPORTANT,
+                QString("IPTV # Failed to create sink: %1")
+                .arg(_live_env->getResultMsg()));
+
+        Medium::close(_source);
+        _source = NULL;
+        if (socket)
+            delete socket;
+        FreeEnv();
+
+        return false;
+    }
+
+    _sink->startPlaying(*_source, NULL, NULL);
+    vector<IPTVListener*>::iterator it = _listeners.begin();
+    for (; it != _listeners.end(); ++it)
+        _sink->AddListener(*it);
+        
+    VERBOSE(VB_RECORD, LOC + "Open() -- end");
+
+    return true;
+}
+
+void IPTVFeederRTP::Close(void)
+{
+    VERBOSE(VB_RECORD, LOC + "Close() -- begin");
+    Stop();
+
+    QMutexLocker locker(&_lock);
+
+    if (_sink)
+    {
+        Medium::close(_sink);
+        _sink = NULL;
+    }
+
+    if (_source)
+    {
+        Groupsock *socket = _source->RTPgs();
+        Medium::close(_source);
+        _source = NULL;
+        if (socket)
+            delete socket;
+    }
+
+    FreeEnv();
+    
+    VERBOSE(VB_RECORD, LOC + "Close() -- end");
+}
+
+void IPTVFeederRTP::AddListener(IPTVListener *item)
+{
+    VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- begin");
+    if (!item)
+    {
+        VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- end");
+        return;
+    }
+
+    // avoid duplicates
+    RemoveListener(item);
+
+    // add to local list
+    QMutexLocker locker(&_lock);
+    _listeners.push_back(item);
+    
+    if (_sink)
+        _sink->AddListener(item);
+
+    VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- end");
+}
+
+void IPTVFeederRTP::RemoveListener(IPTVListener *item)
+{
+    VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- begin");
+    QMutexLocker locker(&_lock);
+    vector<IPTVListener*>::iterator it =
+        find(_listeners.begin(), _listeners.end(), item);
+
+    if (it == _listeners.end())
+    {
+        VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- end 1");
+        return;
+    }
+
+    // remove from local list..
+    *it = *_listeners.rbegin();
+    _listeners.resize(_listeners.size() - 1);
+
+    if (_sink)
+        _sink->RemoveListener(item);
+
+    VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- end 2");
+}
Index: libs/libmythtv/iptv/iptvfeederrtp.h
===================================================================
--- libs/libmythtv/iptv/iptvfeederrtp.h	(revision 0)
+++ libs/libmythtv/iptv/iptvfeederrtp.h	(revision 0)
@@ -0,0 +1,43 @@
+/** -*- Mode: c++ -*-
+ *  IPTVFeederRTP
+ *  Copyright (c) 2006 by Mike Mironov & Mickaël Remars
+ *  Distributed as part of MythTV under GPL v2 and later.
+ */
+
+#ifndef _IPTV_FEEDER_RTP_H_
+#define _IPTV_FEEDER_RTP_H_
+
+// MythTV headers
+#include "iptvfeederlive.h"
+
+class SimpleRTPSource;
+class IPTVMediaSink;
+
+
+class IPTVFeederRTP : public IPTVFeederLive
+{
+  public:
+    IPTVFeederRTP();
+    virtual ~IPTVFeederRTP();
+
+    bool CanHandle(const QString &url) const { return IsRTP(url); }
+    bool IsOpen(void) const { return _source; }
+
+    bool Open(const QString &url);
+    void Close(void);
+
+    void AddListener(IPTVListener*);
+    void RemoveListener(IPTVListener*);
+
+    static bool IsRTP(const QString &url);
+
+  private:
+    IPTVFeederRTP &operator=(const IPTVFeederRTP&);
+    IPTVFeederRTP(const IPTVFeederRTP&);
+
+  private:
+    SimpleRTPSource *_source;
+    IPTVMediaSink   *_sink;
+};
+
+#endif // _IPTV_FEEDER_RTP_H_
Index: libs/libmythtv/iptv/iptvfeederfile.cpp
===================================================================
--- libs/libmythtv/iptv/iptvfeederfile.cpp	(revision 0)
+++ libs/libmythtv/iptv/iptvfeederfile.cpp	(revision 0)
@@ -0,0 +1,171 @@
+/** -*- Mode: c++ -*-
+ *  IPTVFeederFile
+ *
+ *  Please, don't submit bug reports if it
+ *  can't read your file. Just use MythVideo!
+ *
+ *  Copyright (c) 2006 by Mike Mironov & Mickaël Remars
+ *  Distributed as part of MythTV under GPL v2 and later.
+ */
+
+#include "iptvfeederfile.h"
+
+// Qt headers
+#include <qurl.h>
+
+// Live555 headers
+#include <BasicUsageEnvironment.hh>
+#include <Groupsock.hh>
+#include <GroupsockHelper.hh>
+#include <ByteStreamFileSource.hh>
+#include <TunnelEncaps.hh>
+
+// MythTV headers
+#include "iptvmediasink.h"
+#include "mythcontext.h"
+#include "tspacket.h"
+
+#define LOC QString("FbFeedFile: ")
+#define LOC_ERR QString("FbFeedFile, Error: ")
+
+
+IPTVFeederFile::IPTVFeederFile() :
+    _source(NULL),
+    _sink(NULL)
+{
+}
+
+IPTVFeederFile::~IPTVFeederFile()
+{
+    Close();
+}
+
+bool IPTVFeederFile::IsFile(const QString &url)
+{
+    return url.startsWith("file:", false);
+}
+
+bool IPTVFeederFile::Open(const QString &url)
+{
+    VERBOSE(VB_RECORD, LOC + QString("Open(%1) -- begin").arg(url));
+
+    QMutexLocker locker(&_lock);
+
+    if (_source)
+    {
+        VERBOSE(VB_RECORD, LOC + "Open() -- end 1");
+        return true;
+    }
+        
+    QUrl parse(url);
+    if (!parse.hasPath() || !parse.isLocalFile())
+    {
+        VERBOSE(VB_RECORD, LOC + "Open() -- end 2");
+        return false;
+    }
+        
+    // Begin by setting up our usage environment:
+    if (!InitEnv())
+        return false;
+    
+    _source = ByteStreamFileSource::createNew(
+        *_live_env, parse.path().local8Bit());
+    if (!_source)
+    {
+        VERBOSE(VB_IMPORTANT, LOC + "Failed to create Live File Source.");
+        FreeEnv();
+        return false;
+    }
+
+    _sink = IPTVMediaSink::CreateNew(*_live_env, TSPacket::SIZE * 128*1024);
+    if (!_sink)
+    {
+        VERBOSE(VB_IMPORTANT,
+                QString("IPTV # Failed to create sink: %1")
+                .arg(_live_env->getResultMsg()));
+
+        Medium::close(_source);
+        _source = NULL;
+        FreeEnv();
+
+        return false;
+    }
+
+    _sink->startPlaying(*_source, NULL, NULL);
+    vector<IPTVListener*>::iterator it = _listeners.begin();
+    for (; it != _listeners.end(); ++it)
+        _sink->AddListener(*it);
+        
+    VERBOSE(VB_RECORD, LOC + "Open() -- end");
+
+    return true;
+}
+
+void IPTVFeederFile::Close(void)
+{
+    VERBOSE(VB_RECORD, LOC + "Close() -- begin");
+    Stop();
+
+    QMutexLocker locker(&_lock);
+
+    if (_sink)
+    {
+        Medium::close(_sink);
+        _sink = NULL;
+    }
+
+    if (_source)
+    {
+        Medium::close(_source);
+        _source = NULL;
+    }
+
+    FreeEnv();
+
+    VERBOSE(VB_RECORD, LOC + "Close() -- end");
+}
+
+void IPTVFeederFile::AddListener(IPTVListener *item)
+{
+    VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- begin");
+    if (!item)
+    {
+        VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- end");
+        return;
+    }
+
+    // avoid duplicates
+    RemoveListener(item);
+
+    // add to local list
+    QMutexLocker locker(&_lock);
+    _listeners.push_back(item);
+    
+    if (_sink)
+        _sink->AddListener(item);
+
+    VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- end");
+}
+
+void IPTVFeederFile::RemoveListener(IPTVListener *item)
+{
+    VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- begin");
+    QMutexLocker locker(&_lock);
+    vector<IPTVListener*>::iterator it =
+        find(_listeners.begin(), _listeners.end(), item);
+
+    if (it == _listeners.end())
+    {
+        VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- end 1");
+        return;
+    }
+
+    // remove from local list..
+    *it = *_listeners.rbegin();
+    _listeners.resize(_listeners.size() - 1);
+
+    if (_sink)
+        _sink->RemoveListener(item);
+
+    VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- end 2");
+}
