00001
00010 #include <algorithm>
00011
00012 #include "iptvfeederfile.h"
00013
00014
00015 #include <qurl.h>
00016
00017
00018 #include <BasicUsageEnvironment.hh>
00019 #include <Groupsock.hh>
00020 #include <GroupsockHelper.hh>
00021 #include <ByteStreamFileSource.hh>
00022 #include <TunnelEncaps.hh>
00023
00024
00025 #include "iptvmediasink.h"
00026 #include "mythcontext.h"
00027 #include "tspacket.h"
00028
00029 #define LOC QString("FbFeedFile: ")
00030 #define LOC_ERR QString("FbFeedFile, Error: ")
00031
00032
00033 IPTVFeederFile::IPTVFeederFile() :
00034 _source(NULL),
00035 _sink(NULL)
00036 {
00037 }
00038
00039 IPTVFeederFile::~IPTVFeederFile()
00040 {
00041 Close();
00042 }
00043
00044 bool IPTVFeederFile::IsFile(const QString &url)
00045 {
00046 return url.startsWith("file:", false);
00047 }
00048
00049 bool IPTVFeederFile::Open(const QString &url)
00050 {
00051 VERBOSE(VB_RECORD, LOC + QString("Open(%1) -- begin").arg(url));
00052
00053 QMutexLocker locker(&_lock);
00054
00055 if (_source)
00056 {
00057 VERBOSE(VB_RECORD, LOC + "Open() -- end 1");
00058 return true;
00059 }
00060
00061 QUrl parse(url);
00062 if (!parse.hasPath() || !parse.isLocalFile())
00063 {
00064 VERBOSE(VB_RECORD, LOC + "Open() -- end 2");
00065 return false;
00066 }
00067
00068
00069 if (!InitEnv())
00070 return false;
00071
00072 _source = ByteStreamFileSource::createNew(
00073 *_live_env, parse.path().local8Bit());
00074 if (!_source)
00075 {
00076 VERBOSE(VB_IMPORTANT, LOC + "Failed to create Live File Source.");
00077 FreeEnv();
00078 return false;
00079 }
00080
00081 _sink = IPTVMediaSink::CreateNew(*_live_env, TSPacket::SIZE * 128*1024);
00082 if (!_sink)
00083 {
00084 VERBOSE(VB_IMPORTANT,
00085 QString("IPTV # Failed to create sink: %1")
00086 .arg(_live_env->getResultMsg()));
00087
00088 Medium::close(_source);
00089 _source = NULL;
00090 FreeEnv();
00091
00092 return false;
00093 }
00094
00095 _sink->startPlaying(*_source, NULL, NULL);
00096 vector<TSDataListener*>::iterator it = _listeners.begin();
00097 for (; it != _listeners.end(); ++it)
00098 _sink->AddListener(*it);
00099
00100 VERBOSE(VB_RECORD, LOC + "Open() -- end");
00101
00102 return true;
00103 }
00104
00105 void IPTVFeederFile::Close(void)
00106 {
00107 VERBOSE(VB_RECORD, LOC + "Close() -- begin");
00108 Stop();
00109
00110 QMutexLocker locker(&_lock);
00111
00112 if (_sink)
00113 {
00114 Medium::close(_sink);
00115 _sink = NULL;
00116 }
00117
00118 if (_source)
00119 {
00120 Medium::close(_source);
00121 _source = NULL;
00122 }
00123
00124 FreeEnv();
00125
00126 VERBOSE(VB_RECORD, LOC + "Close() -- end");
00127 }
00128
00129 void IPTVFeederFile::AddListener(TSDataListener *item)
00130 {
00131 VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- begin");
00132 if (!item)
00133 {
00134 VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- end");
00135 return;
00136 }
00137
00138
00139 RemoveListener(item);
00140
00141
00142 QMutexLocker locker(&_lock);
00143 _listeners.push_back(item);
00144
00145 if (_sink)
00146 _sink->AddListener(item);
00147
00148 VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- end");
00149 }
00150
00151 void IPTVFeederFile::RemoveListener(TSDataListener *item)
00152 {
00153 VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- begin");
00154 QMutexLocker locker(&_lock);
00155 vector<TSDataListener*>::iterator it =
00156 find(_listeners.begin(), _listeners.end(), item);
00157
00158 if (it == _listeners.end())
00159 {
00160 VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- end 1");
00161 return;
00162 }
00163
00164
00165 *it = *_listeners.rbegin();
00166 _listeners.resize(_listeners.size() - 1);
00167
00168 if (_sink)
00169 _sink->RemoveListener(item);
00170
00171 VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- end 2");
00172 }