Ticket #2152: udp.patch
File udp.patch, 34.7 KB (added by , 19 years ago) |
---|
-
libs/libmythtv/freeboxsignalmonitor.cpp
2 2 3 3 // MythTV headers 4 4 #include "mpegstreamdata.h" 5 #include "freeboxchannel.h" 5 6 #include "freeboxsignalmonitor.h" 6 7 #include "rtspcomms.h" 7 8 … … 33 34 : DTVSignalMonitor(db_cardnum, _channel, _flags, _name), 34 35 dtvMonitorRunning(false) 35 36 { 36 bool isLocked = false; 37 if (GetChannel()->GetRTSP()->Init()) 38 { 39 FreeboxChannelInfo chaninfo = GetChannel()->GetCurrentChanInfo(); 40 isLocked = (chaninfo.isValid() && 41 GetChannel()->GetRTSP()->Open(chaninfo.m_url)); 42 } 37 FreeboxChannelInfo chaninfo = GetChannel()->GetCurrentChanInfo(); 38 bool isLocked = (chaninfo.isValid() && 39 GetChannel()->StreamOpen(chaninfo.m_url)); 43 40 44 41 QMutexLocker locker(&statusLock); 45 42 signalLock.SetValue((isLocked) ? 1 : 0); … … 51 48 */ 52 49 FreeboxSignalMonitor::~FreeboxSignalMonitor() 53 50 { 54 GetChannel()-> GetRTSP()->RemoveListener(this);51 GetChannel()->RemoveListener(this); 55 52 Stop(); 56 53 } 57 54 … … 63 60 void FreeboxSignalMonitor::deleteLater(void) 64 61 { 65 62 disconnect(); // disconnect signals we may be sending... 66 GetChannel()-> GetRTSP()->RemoveListener(this);63 GetChannel()->RemoveListener(this); 67 64 Stop(); 68 65 DTVSignalMonitor::deleteLater(); 69 66 } … … 74 71 void FreeboxSignalMonitor::Stop(void) 75 72 { 76 73 DBG_SM("Stop", "begin"); 77 GetChannel()-> GetRTSP()->RemoveListener(this);74 GetChannel()->RemoveListener(this); 78 75 SignalMonitor::Stop(); 79 76 if (dtvMonitorRunning) 80 77 { 81 GetChannel()-> GetRTSP()->Stop();78 GetChannel()->StreamStop(); 82 79 dtvMonitorRunning = false; 83 80 pthread_join(table_monitor_thread, NULL); 84 81 } … … 101 98 102 99 GetStreamData()->AddListeningPID(0); 103 100 104 GetChannel()-> GetRTSP()->AddListener(this);105 GetChannel()-> GetRTSP()->Run();106 GetChannel()-> GetRTSP()->RemoveListener(this);101 GetChannel()->AddListener(this); 102 GetChannel()->StreamRun(); 103 GetChannel()->RemoveListener(this); 107 104 108 105 dtvMonitorRunning = false; 109 106 DBG_SM("Run", "end"); 110 107 } 111 108 112 109 void FreeboxSignalMonitor::AddData( 113 unsigned char *data, unsigned dataSize , struct timeval)110 unsigned char *data, unsigned dataSize) 114 111 { 115 112 GetStreamData()->ProcessData(data, dataSize); 116 113 } -
libs/libmythtv/udpcomms.cpp
1 /** -*- Mode: c++ -*- 2 * UDPComms 3 * Copyright (c) 2006 by Laurent Arnal, Benjamin Lerman & Mickaël Remars 4 * Distributed as part of MythTV under GPL v2 and later. 5 */ 6 7 #include "udpcomms.h" 8 9 // Qt headers 10 #include <qurl.h> 11 12 // Live555 headers 13 #include <BasicUsageEnvironment.hh> 14 #include <Groupsock.hh> 15 #include <GroupsockHelper.hh> 16 #include <BasicUDPSource.hh> 17 #include <TunnelEncaps.hh> 18 19 // MythTV headers 20 #include "mythcontext.h" 21 #include "tspacket.h" 22 #include "freeboxmediasink.h" 23 24 #define LOC QString("UDPComms(%1):").arg(pthread_self()) 25 26 class TimeoutedTaskScheduler : public BasicTaskScheduler 27 { 28 public: 29 TimeoutedTaskScheduler(unsigned maxDelayTime) 30 : BasicTaskScheduler(), _maxDelayTime(maxDelayTime) {}; 31 32 virtual void doEventLoop(char* watchVariable); 33 34 private: 35 unsigned _maxDelayTime; 36 }; 37 38 void TimeoutedTaskScheduler::doEventLoop(char* watchVariable) 39 { 40 // Repeatedly loop, handling readble sockets and timed events: 41 while (1) 42 { 43 if (watchVariable != NULL && *watchVariable != 0) 44 break; 45 SingleStep(_maxDelayTime); 46 } 47 } 48 49 UDPComms::UDPComms() : 50 _abort(0), _running(false), 51 _live_env(NULL), _source(NULL), 52 _sink(NULL), _lock(false) 53 { 54 VERBOSE(VB_RECORD, LOC + "ctor -- success"); 55 } 56 57 UDPComms::~UDPComms() 58 { 59 VERBOSE(VB_RECORD, LOC + "dtor -- begin"); 60 Close(); 61 VERBOSE(VB_RECORD, LOC + "dtor -- end"); 62 } 63 64 bool UDPComms::Open(const QString &url) 65 { 66 VERBOSE(VB_RECORD, LOC + "Open(\""<<url<<"\") -- begin"); 67 68 QMutexLocker locker(&_lock); 69 70 if (_source) 71 { 72 VERBOSE(VB_RECORD, LOC + "Open() -- end 1"); 73 return true; 74 } 75 76 QUrl parse(url); 77 if (!parse.isValid() || !parse.hasHost() || !parse.hasPort()) 78 { 79 VERBOSE(VB_RECORD, LOC + "Open() -- end 2"); 80 return false; 81 } 82 83 struct in_addr addr; 84 addr.s_addr = our_inet_addr(parse.host().latin1()); 85 86 // Begin by setting up our usage environment: 87 TaskScheduler *scheduler = new TimeoutedTaskScheduler(3000); 88 89 _live_env = BasicUsageEnvironment::createNew(*scheduler); 90 if (!_live_env) 91 { 92 VERBOSE(VB_IMPORTANT, LOC + "Failed to create Live Environment."); 93 delete scheduler; 94 return false; 95 } 96 97 Groupsock *socket = new Groupsock(*_live_env, addr, parse.port(), 0); 98 _source = BasicUDPSource::createNew(*_live_env, socket); 99 if (!_source) 100 { 101 VERBOSE(VB_IMPORTANT, LOC + "Failed to create Live UDP Source."); 102 delete socket; 103 _live_env->reclaim(); 104 _live_env = NULL; 105 delete scheduler; 106 return false; 107 } 108 109 _sink = FreeboxMediaSink::CreateNew(*_live_env, TSPacket::SIZE * 128*1024); 110 if (!_sink) 111 { 112 VERBOSE(VB_IMPORTANT, 113 QString("Freebox # Failed to create sink: %1") 114 .arg(_live_env->getResultMsg())); 115 Medium::close(_source); 116 _source=NULL; 117 delete socket; 118 _live_env->reclaim(); 119 _live_env = NULL; 120 delete scheduler; 121 return false; 122 } 123 _sink->startPlaying(*_source,NULL,NULL); 124 vector<StreamDataListener*>::iterator it = _listeners.begin(); 125 for (; it != _listeners.end(); ++it) 126 _sink->AddListener(*it); 127 128 VERBOSE(VB_RECORD, LOC + "Open() -- end"); 129 return true; 130 } 131 132 void UDPComms::Close(void) 133 { 134 VERBOSE(VB_RECORD, LOC + "Close() -- begin"); 135 Stop(); 136 137 QMutexLocker locker(&_lock); 138 139 if (_sink) 140 { 141 Medium::close(_sink); 142 _sink = NULL; 143 } 144 145 if (_source) 146 { 147 Groupsock *socket=_source->gs(); 148 Medium::close(_source); 149 _source=NULL; 150 delete socket; 151 } 152 153 if (_live_env) 154 { 155 TaskScheduler *scheduler = &_live_env->taskScheduler(); 156 _live_env->reclaim(); 157 _live_env = NULL; 158 delete scheduler; 159 } 160 161 VERBOSE(VB_RECORD, LOC + "Close() -- end"); 162 } 163 164 void UDPComms::Run(void) 165 { 166 VERBOSE(VB_RECORD, LOC + "Run() -- begin"); 167 { 168 QMutexLocker locker(&_lock); 169 _running = true; 170 _abort = 0; 171 } 172 173 VERBOSE(VB_RECORD, LOC + "Run() -- loop begin"); 174 if (_live_env) 175 _live_env->taskScheduler().doEventLoop(&_abort); 176 VERBOSE(VB_RECORD, LOC + "Run() -- loop end"); 177 178 { 179 QMutexLocker locker(&_lock); 180 _running = false; 181 _cond.wakeAll(); 182 } 183 VERBOSE(VB_RECORD, LOC + "Run() -- end"); 184 } 185 186 void UDPComms::Stop(void) 187 { 188 VERBOSE(VB_RECORD, LOC + "Stop() -- begin"); 189 QMutexLocker locker(&_lock); 190 _abort = 0xFF; 191 192 while (_running) 193 _cond.wait(&_lock, 500); 194 VERBOSE(VB_RECORD, LOC + "Stop() -- end"); 195 } 196 197 void UDPComms::AddListener(StreamDataListener *item) 198 { 199 VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- begin"); 200 if (!item) 201 { 202 VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- end"); 203 return; 204 } 205 206 // avoid duplicates 207 RemoveListener(item); 208 209 // add to local list 210 QMutexLocker locker(&_lock); 211 _listeners.push_back(item); 212 213 if (_sink) 214 _sink->AddListener(item); 215 VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- end"); 216 } 217 218 void UDPComms::RemoveListener(StreamDataListener *item) 219 { 220 VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- begin"); 221 QMutexLocker locker(&_lock); 222 vector<StreamDataListener*>::iterator it = 223 find(_listeners.begin(), _listeners.end(), item); 224 225 if (it == _listeners.end()) 226 { 227 VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- end 1"); 228 return; 229 } 230 231 // remove from local list.. 232 *it = *_listeners.rbegin(); 233 _listeners.resize(_listeners.size() - 1); 234 if (_sink) 235 _sink->RemoveListener(item); 236 VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- end 2"); 237 } -
libs/libmythtv/freeboxchannel.h
7 7 #ifndef FREEBOXCHANNEL_H 8 8 #define FREEBOXCHANNEL_H 9 9 10 // C++ headers 11 #include <vector> 12 10 13 #include "channelbase.h" 11 14 #include "freeboxchannelinfo.h" 12 15 13 16 #include <qmutex.h> 14 17 15 class RTSPComms; 18 class StreamComms; 19 class StreamDataListener; 16 20 17 21 class FreeboxChannel : public ChannelBase 18 22 { … … 32 36 FreeboxChannelInfo GetCurrentChanInfo(void) const 33 37 { return GetChanInfo(curchannelname); } 34 38 35 RTSPComms *GetRTSP(void) { return m_rtsp; } 36 const RTSPComms *GetRTSP(void) const { return m_rtsp; } 37 39 bool StreamOpen(const QString &url); 40 bool StreamIsOpen(void) const; 41 void StreamClose(void); 42 43 void StreamRun(void); 44 void StreamStop(void); 45 46 void AddListener(StreamDataListener*); 47 void RemoveListener(StreamDataListener*); 48 38 49 private: 39 50 FreeboxChannelInfo GetChanInfo(const QString& channum, 40 51 uint sourceid = 0) const; 41 52 53 std::vector<StreamDataListener*> _listeners; 54 42 55 QString m_videodev; 43 56 fbox_chan_map_t m_freeboxchannels; 44 RTSPComms *m_rtsp;57 StreamComms *m_stream; 45 58 mutable QMutex m_lock; 59 mutable QMutex m_list_lock; 46 60 47 61 private: 48 62 FreeboxChannel& operator=(const FreeboxChannel&); //< avoid default impl -
libs/libmythtv/freeboxchannelfetcher.h
7 7 // Qt headers 8 8 #include <qobject.h> 9 9 #include <qmutex.h> 10 #include <qurloperator.h> 10 11 11 12 // MythTV headers 12 13 #include "freeboxchannelinfo.h" 13 14 15 class FreeboxUrlFetch : public QObject 16 { 17 Q_OBJECT 18 19 private: 20 FreeboxUrlFetch(const QString& url); 21 ~FreeboxUrlFetch(); 22 23 QUrlOperator *op; 24 QNetworkProtocol::State state; 25 QString str; 26 27 private slots: 28 void finished(QNetworkOperation *op); 29 void data(const QByteArray &data,QNetworkOperation *op); 30 31 public: 32 static QString fetchData(const QString &url,bool inQtThread); 33 }; 34 14 35 class FreeboxChannelFetcher : public QObject 15 36 { 16 37 Q_OBJECT -
libs/libmythtv/libmythtv.pro
396 396 using_freebox { 397 397 HEADERS += freeboxrecorder.h freeboxmediasink.h 398 398 HEADERS += freeboxchannel.h freeboxchannelfetcher.h 399 HEADERS += freeboxsignalmonitor.h rtspcomms.h 400 HEADERS += freeboxchannelinfo.h 399 HEADERS += freeboxsignalmonitor.h freeboxchannelinfo.h 400 HEADERS += rtspcomms.h udpcomms.h 401 HEADERS += streamcomms.h 401 402 402 403 SOURCES += freeboxrecorder.cpp freeboxmediasink.cpp 403 404 SOURCES += freeboxchannel.cpp freeboxchannelfetcher.cpp 404 405 SOURCES += freeboxsignalmonitor.cpp rtspcomms.cpp 406 SOURCES += udpcomms.cpp 405 407 406 408 DEFINES += USING_FREEBOX 407 409 } -
libs/libmythtv/freeboxchannel.cpp
5 5 */ 6 6 7 7 #include "freeboxchannel.h" 8 using namespace std; 8 9 9 10 #include <qdeepcopy.h> 10 11 11 12 #include "libmyth/mythcontext.h" 12 13 #include "libmyth/mythdbcon.h" 13 14 #include "libmythtv/freeboxchannelfetcher.h" 15 #include "libmythtv/streamcomms.h" 14 16 #include "libmythtv/rtspcomms.h" 17 #include "libmythtv/udpcomms.h" 15 18 16 19 #define LOC QString("FBChan(%1): ").arg(GetCardID()) 17 20 #define LOC_ERR QString("FBChan(%1), Error: ").arg(GetCardID()) … … 20 23 const QString &videodev) 21 24 : ChannelBase(parent), 22 25 m_videodev(QDeepCopy<QString>(videodev)), 23 m_rtsp(new RTSPComms()), 24 m_lock(true) 26 m_stream(NULL), 27 m_lock(true), 28 m_list_lock(true) 25 29 { 26 30 VERBOSE(VB_CHANNEL, LOC + "ctor"); 27 31 } … … 29 33 FreeboxChannel::~FreeboxChannel() 30 34 { 31 35 VERBOSE(VB_CHANNEL, LOC + "dtor -- begin"); 32 if (m_ rtsp)36 if (m_stream) 33 37 { 34 delete m_ rtsp;35 m_ rtsp= NULL;38 delete m_stream; 39 m_stream = NULL; 36 40 } 37 41 VERBOSE(VB_CHANNEL, LOC + "dtor -- end"); 38 42 } … … 206 210 return dummy; 207 211 } 208 212 213 bool FreeboxChannel::StreamOpen(const QString &url) 214 { 215 VERBOSE(VB_CHANNEL, LOC + "StreamOpen() -- begin"); 216 217 if (url.startsWith("rtsp:")) 218 { 219 if (!dynamic_cast<RTSPComms *>(m_stream)) 220 { 221 if (m_stream) 222 { 223 m_stream->Stop(); 224 m_stream->Close(); 225 delete m_stream; 226 m_stream=NULL; 227 } 228 m_stream=new RTSPComms(); 229 230 QMutexLocker locker(&m_list_lock); 231 232 vector<StreamDataListener*>::iterator it = _listeners.begin(); 233 for (; it != _listeners.end(); ++it) 234 m_stream->AddListener(*it); 235 } 236 } 237 else if (url.startsWith("udp:")) 238 { 239 if (!dynamic_cast<UDPComms *>(m_stream)) 240 { 241 if (m_stream) 242 { 243 m_stream->Stop(); 244 m_stream->Close(); 245 delete m_stream; 246 m_stream=NULL; 247 } 248 m_stream=new UDPComms(); 249 250 QMutexLocker locker(&m_list_lock); 251 252 vector<StreamDataListener*>::iterator it = _listeners.begin(); 253 for (; it != _listeners.end(); ++it) 254 m_stream->AddListener(*it); 255 } 256 } 257 VERBOSE(VB_CHANNEL, LOC + "StreamOpen() -- at the end"); 258 if (m_stream) 259 return m_stream->Open(url); 260 else 261 return false; 262 } 263 264 bool FreeboxChannel::StreamIsOpen(void) const 265 { 266 if (m_stream) 267 return m_stream->IsOpen(); 268 else 269 return false; 270 } 271 272 void FreeboxChannel::StreamClose(void) 273 { 274 if (m_stream) 275 m_stream->Close(); 276 } 277 278 void FreeboxChannel::StreamRun(void) 279 { 280 if (m_stream) 281 m_stream->Run(); 282 } 283 284 void FreeboxChannel::StreamStop(void) 285 { 286 if (m_stream) 287 m_stream->Stop(); 288 } 289 290 void FreeboxChannel::AddListener(StreamDataListener *item) 291 { 292 VERBOSE(VB_CHANNEL, LOC + "AddListener() -- begin"); 293 294 if (!item) 295 return; 296 297 RemoveListener(item); 298 299 // add to local list 300 QMutexLocker locker(&m_list_lock); 301 _listeners.push_back(item); 302 303 if (m_stream) 304 m_stream->AddListener(item); 305 VERBOSE(VB_CHANNEL, LOC + "AddListener() -- end"); 306 } 307 308 void FreeboxChannel::RemoveListener(StreamDataListener *item) 309 { 310 VERBOSE(VB_CHANNEL, LOC + "RemoveListener() -- begin"); 311 312 QMutexLocker locker(&m_list_lock); 313 vector<StreamDataListener*>::iterator it = 314 find(_listeners.begin(), _listeners.end(), item); 315 316 if (it == _listeners.end()) 317 { 318 VERBOSE(VB_CHANNEL, LOC + "RemoveListener() -- end 1"); 319 return; 320 } 321 322 // remove from local list.. 323 *it = *_listeners.rbegin(); 324 _listeners.resize(_listeners.size() - 1); 325 326 if (m_stream) 327 m_stream->RemoveListener(item); 328 VERBOSE(VB_CHANNEL, LOC + "RemoveListener() -- end 2"); 329 } 330 209 331 /* vim: set expandtab tabstop=4 shiftwidth=4: */ -
libs/libmythtv/freeboxmediasink.cpp
9 9 10 10 #include "mythcontext.h" 11 11 #include "freeboxmediasink.h" 12 #include " rtspcomms.h"12 #include "tspacket.h" 13 13 14 #define LOC QString(" RTSPSink:")15 #define LOC_ERR QString(" RTSPSink, Error:")14 #define LOC QString("FBSink:") 15 #define LOC_ERR QString("FBSink, Error:") 16 16 17 17 FreeboxMediaSink::FreeboxMediaSink(UsageEnvironment &pEnv, 18 18 unsigned int bufferSize) : … … 61 61 } 62 62 63 63 void FreeboxMediaSink::afterGettingFrame1(unsigned int frameSize, 64 struct timeval presentationTime)64 struct timeval /*presentationTime*/) 65 65 { 66 66 lock.lock(); 67 vector< RTSPListener*>::iterator it = listeners.begin();67 vector<StreamDataListener*>::iterator it = listeners.begin(); 68 68 for (; it != listeners.end(); ++it) 69 (*it)->AddData(fBuffer, frameSize , presentationTime);69 (*it)->AddData(fBuffer, frameSize); 70 70 lock.unlock(); 71 71 72 72 continuePlaying(); 73 73 } 74 74 75 void FreeboxMediaSink::AddListener( RTSPListener *item)75 void FreeboxMediaSink::AddListener(StreamDataListener *item) 76 76 { 77 77 VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- begin"); 78 78 if (item) … … 84 84 VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- end"); 85 85 } 86 86 87 void FreeboxMediaSink::RemoveListener( RTSPListener *item)87 void FreeboxMediaSink::RemoveListener(StreamDataListener *item) 88 88 { 89 89 VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- begin 1"); 90 90 QMutexLocker locker(&lock); 91 vector< RTSPListener*>::iterator it =91 vector<StreamDataListener*>::iterator it = 92 92 find(listeners.begin(), listeners.end(), item); 93 93 if (it != listeners.end()) 94 94 { -
libs/libmythtv/freeboxsignalmonitor.h
4 4 #define _FREEBOXSIGNALMONITOR_H_ 5 5 6 6 #include "dtvsignalmonitor.h" 7 #include " freeboxmediasink.h"7 #include "streamcomms.h" 8 8 9 class RTSPComms;10 9 class FreeboxChannel; 11 10 12 class FreeboxSignalMonitor : public DTVSignalMonitor, public RTSPListener11 class FreeboxSignalMonitor : public DTVSignalMonitor, public StreamDataListener 13 12 { 14 13 Q_OBJECT 15 14 … … 21 20 22 21 void Stop(void); 23 22 24 // implements RTSPListener23 // implements StreamDataListener 25 24 void AddData(unsigned char *data, 26 unsigned dataSize, 27 struct timeval); 25 unsigned dataSize); 28 26 29 27 public slots: 30 28 void deleteLater(void); -
libs/libmythtv/freeboxchannelfetcher.cpp
4 4 #include <cmath> 5 5 #include <unistd.h> 6 6 7 // Qt headers 8 #include <qnetwork.h> 9 #include <qapplication.h> 10 7 11 // MythTV headers 8 12 #include "mythcontext.h" 9 13 #include "httpcomms.h" … … 21 25 static bool parse_extinf(const QString &data, 22 26 QString &channum, QString &name); 23 27 28 FreeboxUrlFetch::FreeboxUrlFetch(const QString& url) 29 : op(new QUrlOperator(url)), 30 state(QNetworkProtocol::StInProgress), 31 str("") 32 { 33 connect(op, SIGNAL( finished(QNetworkOperation *)), 34 this, SLOT( finished(QNetworkOperation *))); 35 connect(op, SIGNAL( data(const QByteArray &,QNetworkOperation *)), 36 this, SLOT( data(const QByteArray &,QNetworkOperation *))); 37 op->get(); 38 } 39 40 FreeboxUrlFetch::~FreeboxUrlFetch() 41 { 42 disconnect(); 43 delete op; 44 op=NULL; 45 } 46 47 void FreeboxUrlFetch::finished(QNetworkOperation *op) 48 { 49 state = op->state(); 50 } 51 52 void FreeboxUrlFetch::data(const QByteArray &data,QNetworkOperation *op) 53 { 54 if (!data.isNull()) 55 str += QString::fromUtf8(data.data(),data.size()); 56 state = op->state(); 57 } 58 59 QString FreeboxUrlFetch::fetchData(const QString &url,bool inQtThread) 60 { 61 FreeboxUrlFetch obj(url); 62 while(obj.state==QNetworkProtocol::StWaiting || 63 obj.state==QNetworkProtocol::StInProgress) 64 { 65 if (inQtThread) 66 qApp->processEvents(); 67 usleep(1000); 68 } 69 if (obj.state==QNetworkProtocol::StDone) 70 return obj.str; 71 else // QNetworkProtocol::StFailed || QNetworkProtocol::StStopped 72 return QString::null; 73 } 74 75 24 76 FreeboxChannelFetcher::FreeboxChannelFetcher(unsigned _sourceid, 25 77 unsigned _cardid) : 26 78 sourceid(_sourceid), cardid(_cardid), … … 177 229 QString FreeboxChannelFetcher::DownloadPlaylist(const QString &url, 178 230 bool inQtThread) 179 231 { 180 QString redirected_url = url; 232 if (url.startsWith("http:")) { 233 // Use Myth HttpComms for http URLs 234 QString redirected_url = url; 181 235 182 QString tmp = HttpComms::getHttp(183 redirected_url,184 10000 /* ms */, 3 /* retries */,185 3 /* redirects */, true /* allow gzip */,186 NULL /* login */, inQtThread);236 QString tmp = HttpComms::getHttp( 237 redirected_url, 238 10000 /* ms */, 3 /* retries */, 239 3 /* redirects */, true /* allow gzip */, 240 NULL /* login */, inQtThread); 187 241 188 if (redirected_url != url)189 {190 VERBOSE(VB_CHANNEL, QString("Channel URL redirected to %1")191 .arg(redirected_url));192 }242 if (redirected_url != url) 243 { 244 VERBOSE(VB_CHANNEL, QString("Channel URL redirected to %1") 245 .arg(redirected_url)); 246 } 193 247 194 return QString::fromUtf8(tmp); 248 return QString::fromUtf8(tmp); 249 } else 250 return FreeboxUrlFetch::fetchData(url,inQtThread); 195 251 } 196 252 197 253 static uint estimate_number_of_channels(const QString &rawdata) -
libs/libmythtv/freeboxrecorder.cpp
15 15 #define LOC_ERR QString("FBRec, Error: ") 16 16 17 17 // ============================================================================ 18 // FreeboxRecorder : Processes data from RTSPComms and writes it to disk18 // FreeboxRecorder : Processes data from StreamDataComms and writes it to disk 19 19 // ============================================================================ 20 20 21 21 FreeboxRecorder::FreeboxRecorder(TVRec *rec, FreeboxChannel *channel) : … … 23 23 _channel(channel), 24 24 _stream_data(NULL) 25 25 { 26 _channel-> GetRTSP()->AddListener(this);26 _channel->AddListener(this); 27 27 } 28 28 29 29 FreeboxRecorder::~FreeboxRecorder() 30 30 { 31 31 StopRecording(); 32 _channel-> GetRTSP()->RemoveListener(this);32 _channel->RemoveListener(this); 33 33 } 34 34 35 35 bool FreeboxRecorder::Open(void) 36 36 { 37 37 VERBOSE(VB_RECORD, LOC + "Open() -- begin"); 38 38 39 if (_channel-> GetRTSP()->IsOpen())40 _channel-> GetRTSP()->Close();39 if (_channel->StreamIsOpen()) 40 _channel->StreamClose(); 41 41 42 42 FreeboxChannelInfo chaninfo = _channel->GetCurrentChanInfo(); 43 43 if (!chaninfo.isValid()) … … 46 46 } 47 47 else 48 48 { 49 _error = !(_channel->GetRTSP()->Init()); 50 if (!_error) 51 _error = !(_channel->GetRTSP()->Open(chaninfo.m_url)); 49 _error = !(_channel->StreamOpen(chaninfo.m_url)); 52 50 } 53 51 54 52 VERBOSE(VB_RECORD, LOC + "Open() -- end err("<<_error<<")"); … … 58 56 void FreeboxRecorder::Close(void) 59 57 { 60 58 VERBOSE(VB_RECORD, LOC + "Close() -- begin"); 61 _channel-> GetRTSP()->Stop();62 _channel-> GetRTSP()->Close();59 _channel->StreamStop(); 60 _channel->StreamClose(); 63 61 VERBOSE(VB_RECORD, LOC + "Close() -- end"); 64 62 } 65 63 64 void FreeboxRecorder::Reset(void) 65 { 66 VERBOSE(VB_RECORD, LOC + "Reset() -- begin"); 67 DTVRecorder::Reset(); 68 _channel->StreamStop(); 69 _channel->StreamClose(); 70 if (_stream_data) 71 _stream_data->Reset(_channel->GetProgramNumber()); 72 VERBOSE(VB_RECORD, LOC + "Reset() -- end"); 73 } 74 66 75 void FreeboxRecorder::Pause(bool clear) 67 76 { 68 77 VERBOSE(VB_RECORD, LOC + "Pause() -- begin"); 69 78 DTVRecorder::Pause(clear); 70 _channel-> GetRTSP()->Stop();71 _channel-> GetRTSP()->Close();79 _channel->StreamStop(); 80 _channel->StreamClose(); 72 81 VERBOSE(VB_RECORD, LOC + "Pause() -- end"); 73 82 } 74 83 75 84 void FreeboxRecorder::Unpause(void) 76 85 { 77 86 VERBOSE(VB_RECORD, LOC + "Unpause() -- begin"); 78 if (_recording && !_channel-> GetRTSP()->IsOpen())87 if (_recording && !_channel->StreamIsOpen()) 79 88 Open(); 80 89 DTVRecorder::Unpause(); 81 90 VERBOSE(VB_RECORD, LOC + "Unpause() -- end"); … … 99 108 if (PauseAndWait()) 100 109 continue; 101 110 102 if (!_channel-> GetRTSP()->IsOpen())111 if (!_channel->StreamIsOpen()) 103 112 { 104 113 usleep(5000); 105 114 continue; 106 115 } 107 108 // Go into main RTSPloop, feeding data to AddData109 _channel-> GetRTSP()->Run();116 117 // Go into main loop, feeding data to AddData 118 _channel->StreamRun(); 110 119 } 111 120 112 121 // Finish up... … … 122 131 { 123 132 VERBOSE(VB_RECORD, LOC + "StopRecording() -- begin"); 124 133 Pause(); 125 _channel-> GetRTSP()->Close();134 _channel->StreamClose(); 126 135 127 136 _request_recording = false; 128 137 while (_recording) 129 138 _cond_recording.wait(500); 130 139 DTVRecorder::StopRecording(); 131 140 VERBOSE(VB_RECORD, LOC + "StopRecording() -- end"); 132 141 } 133 142 … … 150 159 } 151 160 152 161 // =================================================== 153 // AddData : feed data from RTSPflow to mythtv162 // AddData : feed data from flow to mythtv 154 163 // =================================================== 155 164 void FreeboxRecorder::AddData(unsigned char *data, 156 unsigned dataSize, 157 struct timeval) 165 unsigned dataSize) 158 166 { 159 167 unsigned int readIndex = 0; 160 168 … … 166 174 return; 167 175 168 176 // Find the next TS Header in data 169 int tsPos = FreeboxRecorder_findTSHeader(data + readIndex, dataSize );170 177 int tsPos = FreeboxRecorder_findTSHeader(data + readIndex, dataSize - readIndex); 178 171 179 // if no TS, something bad happens 172 180 if (tsPos == -1) 173 181 { … … 184 192 185 193 // Check if the next packet in buffer is complete : 186 194 // packet size is 188 bytes long 187 if ((dataSize - tsPos ) < TSPacket::SIZE)195 if ((dataSize - tsPos - readIndex) < TSPacket::SIZE) 188 196 { 189 197 VERBOSE(VB_IMPORTANT, LOC_ERR + 190 198 "TS packet at stradles end of buffer."); -
libs/libmythtv/rtspcomms.cpp
270 270 .arg(_live_env->getResultMsg())); 271 271 } 272 272 273 vector< RTSPListener*>::iterator it = _listeners.begin();273 vector<StreamDataListener*>::iterator it = _listeners.begin(); 274 274 for (; it != _listeners.end(); ++it) 275 275 freeboxMediaSink->AddListener(*it); 276 276 … … 367 367 VERBOSE(VB_RECORD, LOC + "Stop() -- end"); 368 368 } 369 369 370 void RTSPComms::AddListener( RTSPListener *item)370 void RTSPComms::AddListener(StreamDataListener *item) 371 371 { 372 372 VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- begin"); 373 373 if (!item) … … 401 401 VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- end 2"); 402 402 } 403 403 404 void RTSPComms::RemoveListener( RTSPListener *item)404 void RTSPComms::RemoveListener(StreamDataListener *item) 405 405 { 406 406 VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- begin"); 407 407 QMutexLocker locker(&_lock); 408 vector< RTSPListener*>::iterator it =408 vector<StreamDataListener*>::iterator it = 409 409 find(_listeners.begin(), _listeners.end(), item); 410 410 411 411 if (it == _listeners.end()) -
libs/libmythtv/udpcomms.h
1 /** -*- Mode: c++ -*- 2 * RTSPComms 3 * Copyright (c) 2006 by Laurent Arnal, Benjamin Lerman & Mickaël Remars 4 * Distributed as part of MythTV under GPL v2 and later. 5 */ 6 7 #ifndef UDPCOMMS_H 8 #define UDPCOMMS_H 9 10 // C++ headers 11 #include <vector> 12 using namespace std; 13 14 // Qt headers 15 #include <qwaitcondition.h> 16 #include <qmutex.h> 17 18 // MythTV headers 19 #include "streamcomms.h" 20 21 class UsageEnvironment; 22 class BasicUDPSource; 23 class FreeboxMediaSink; 24 class StreamDataListener; 25 26 class UDPComms : public StreamComms 27 { 28 public: 29 UDPComms(); 30 virtual ~UDPComms(); 31 32 bool Open(const QString &url); 33 bool IsOpen(void) const { return _source; } 34 void Close(void); 35 36 void Run(void); 37 void Stop(void); 38 39 void AddListener(StreamDataListener*); 40 void RemoveListener(StreamDataListener*); 41 42 private: 43 44 char _abort; 45 bool _running; 46 UsageEnvironment *_live_env; 47 BasicUDPSource *_source; 48 FreeboxMediaSink *_sink; 49 vector<StreamDataListener*> _listeners; 50 QWaitCondition _cond; ///< Condition used to coordinate threads 51 mutable QMutex _lock; ///< Lock used to coordinate threads 52 }; 53 54 #endif -
libs/libmythtv/streamcomms.h
1 /** -*- Mode: c++ -*- 2 * StreamComms 3 * Copyright (c) 2006 by Laurent Arnal, Benjamin Lerman & Mickaël Remars 4 * Distributed as part of MythTV under GPL v2 and later. 5 */ 6 7 #ifndef _STREAMCOMMS_H_ 8 #define _STREAMCOMMS_H_ 9 10 class StreamDataListener 11 { 12 public: 13 /// Callback function to add MPEG2 TS data 14 virtual void AddData(unsigned char *data, 15 unsigned int dataSize) = 0; 16 protected: 17 virtual ~StreamDataListener() {} 18 }; 19 20 class QString; 21 22 class StreamComms 23 { 24 public: 25 StreamComms(){}; 26 virtual ~StreamComms(){}; 27 28 virtual bool Open(const QString &url) = 0; 29 virtual bool IsOpen(void) const = 0; 30 virtual void Close(void) = 0; 31 32 virtual void Run(void) = 0; 33 virtual void Stop(void) = 0; 34 35 virtual void AddListener(StreamDataListener*) = 0; 36 virtual void RemoveListener(StreamDataListener*) = 0; 37 }; 38 39 #endif -
libs/libmythtv/freeboxmediasink.h
14 14 15 15 #include <MediaSink.hh> 16 16 17 class RTSPListener 18 { 19 public: 20 /// Callback function to add MPEG2 TS data 21 virtual void AddData(unsigned char *data, 22 unsigned int dataSize, 23 struct timeval presentationTime) = 0; 24 protected: 25 virtual ~RTSPListener() {} 26 }; 17 #include "streamcomms.h" 27 18 28 19 // ============================================================================ 29 20 // FreeboxMediaSink : Helper class use to receive RTSP data from socket. … … 34 25 static FreeboxMediaSink *CreateNew(UsageEnvironment &env, 35 26 unsigned bufferSize); 36 27 37 void AddListener( RTSPListener*);38 void RemoveListener( RTSPListener*);28 void AddListener(StreamDataListener*); 29 void RemoveListener(StreamDataListener*); 39 30 40 31 protected: 41 32 FreeboxMediaSink(UsageEnvironment &env, … … 58 49 unsigned char *fBuffer; 59 50 unsigned int fBufferSize; 60 51 UsageEnvironment &env; 61 vector< RTSPListener*> listeners;52 vector<StreamDataListener*> listeners; 62 53 mutable QMutex lock; 63 54 64 55 private: -
libs/libmythtv/freeboxrecorder.h
10 10 #include <qwaitcondition.h> 11 11 12 12 #include "dtvrecorder.h" 13 #include "freeboxmediasink.h" 14 #include "streamlisteners.h" 13 #include "streamcomms.h" 15 14 16 15 class FreeboxChannel; 17 16 18 /** \brief Processes data from RTSPComms and writes it to disk.17 /** \brief Processes data from StreamComms and writes it to disk. 19 18 */ 20 class FreeboxRecorder : public DTVRecorder, public RTSPListener,19 class FreeboxRecorder : public DTVRecorder, public StreamDataListener, 21 20 public MPEGSingleProgramStreamListener 22 21 { 23 friend class FreeboxMediaSink;24 friend class RTSPComms;25 26 22 public: 27 23 FreeboxRecorder(TVRec *rec, FreeboxChannel *channel); 28 24 ~FreeboxRecorder(); 29 25 30 26 bool Open(void); 31 27 void Close(void); 28 void Reset(void); 32 29 33 30 virtual void Pause(bool clear = true); 34 31 virtual void Unpause(void); … … 45 42 private: 46 43 void ProcessTSPacket(const TSPacket& tspacket); 47 44 48 // implements RTSPListener45 // implements StreamDataListener 49 46 void AddData(unsigned char *data, 50 unsigned int dataSize, 51 struct timeval presentationTime); 47 unsigned int dataSize); 52 48 53 49 // implements MPEGSingleProgramStreamListener 54 50 void HandleSingleProgramPAT(ProgramAssociationTable *pat); -
libs/libmythtv/rtspcomms.h
4 4 * Distributed as part of MythTV under GPL v2 and later. 5 5 */ 6 6 7 #ifndef RTSPCOMMS_H 8 #define RTSPCOMMS_H 9 7 10 // C++ headers 8 11 #include <vector> 9 12 using namespace std; … … 13 16 #include <qmutex.h> 14 17 15 18 // MythTV headers 16 #include " freeboxchannel.h"19 #include "streamcomms.h" 17 20 18 21 class UsageEnvironment; 19 22 class RTSPClient; 20 23 class MediaSession; 21 class RTSPListener;24 class StreamDataListener; 22 25 23 class RTSPComms 26 class RTSPComms : public StreamComms 24 27 { 25 28 public: 26 29 RTSPComms(); … … 36 39 void Run(void); 37 40 void Stop(void); 38 41 39 void AddListener( RTSPListener*);40 void RemoveListener( RTSPListener*);42 void AddListener(StreamDataListener*); 43 void RemoveListener(StreamDataListener*); 41 44 42 45 private: 43 46 … … 46 49 UsageEnvironment *_live_env; 47 50 RTSPClient *_rtsp_client; 48 51 MediaSession *_session; 49 vector< RTSPListener*> _listeners;52 vector<StreamDataListener*> _listeners; 50 53 QWaitCondition _cond; ///< Condition used to coordinate threads 51 54 mutable QMutex _lock; ///< Lock used to coordinate threads 52 55 }; 56 57 #endif