Ticket #1704: patch.freebox.v1.23.9974.diff
File patch.freebox.v1.23.9974.diff, 48.0 KB (added by , 18 years ago) |
---|
-
configure
54 54 lirc="yes" 55 55 joystick_menu="yes" 56 56 firewire_cable_box="yes" 57 freebox_box="yes" 57 58 dbox2_dvb_box="yes" 58 59 ip_network_recorder="yes" 59 60 hdhomerun_box="yes" … … 178 179 echo " --disable-lirc disable lirc support (Infrared Remotes)" 179 180 echo " --disable-joystick-menu disable joystick menu" 180 181 echo " --disable-firewire disable support for FireWire cable boxes" 182 echo " --disable-freebox disable support for Freebox" 183 echo " --livelibdir=DIR location of Live streaming library" 184 echo " --liveincludedir=DIR location of Live streaming include files" 181 185 echo " --disable-dbox2 disable support for Nokia DBOX2 DVB boxes (or compatibles)" 182 186 echo " --disable-hdhomerun disable support for HDHomeRun boxes" 183 187 echo " --disable-iprec disable support for Network Recorder" … … 819 823 ;; 820 824 --disable-dbox2) dbox2_dvb_box="no" 821 825 ;; 826 --enable-freebox) freebox_box="yes" 827 ;; 828 --disable-freebox) freebox_box="no" 829 ;; 830 --livelibdir=*) live_lib_dir=`echo $opt | cut -d '=' -f 2` 831 ;; 832 --liveincludedir=*) live_include_dir=`echo $opt | cut -d '=' -f 2` 833 ;; 822 834 --enable-hdhomerun) hdhomerun_box="yes" 823 835 ;; 824 836 --disable-hdhomerun) hdhomerun_box="no" … … 2119 2131 fi 2120 2132 fi 2121 2133 2134 if test x"$dvd" = x"yes" ; then 2135 if has_library libdvdnav ; then 2136 if has_header dvdnav/dvdnav.h ; then 2137 dvd="yes" 2138 fi 2139 fi 2140 fi 2141 2142 2122 2143 VENDOR_XVMC_LIBS="" 2123 2144 if test x"$xvmc" = x"yes"; then 2124 2145 xvmc="no" … … 2306 2327 echo "FireWire support $firewire_cable_box" 2307 2328 echo "DVB support $dvb [$dvb_path]" 2308 2329 echo "DBox2 support $dbox2_dvb_box" 2330 echo "freebox support $freebox_box" 2309 2331 echo "HDHomeRun sup. $hdhomerun_box" 2310 2332 echo "CRC Ip Rec sup. $ip_network_recorder" 2311 2333 fi … … 2960 2982 CCONFIG="$CCONFIG using_dbox2" 2961 2983 fi 2962 2984 2985 if test x"$freebox_box" = x"yes" ; then 2986 if test "x$live_lib_dir" = "x"; then 2987 if has_library libliveMedia; then 2988 CONFIG_LIVE_LIBS="-lliveMedia -lgroupsock -lBasicUsageEnvironment -lUsageEnvironment" 2989 else 2990 echo "Unable to find Live Media library." 2991 exit 1; 2992 fi 2993 else 2994 if test ! -f "$live_lib_dir/liveMedia/libliveMedia.a"; then 2995 echo "Unable to find Live Media library." 2996 exit 1; 2997 fi 2998 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" 2999 fi 3000 if test "x$live_include_dir" = "x"; then 3001 if has_header liveMedia.hh; then 3002 true 3003 else 3004 echo "Unable to find Live Media headers." 3005 exit 1; 3006 fi 3007 else 3008 if test -f "$live_include_dir/liveMedia/include/liveMedia.hh"; then 3009 LIVE_INCLUDES="$live_include_dir/liveMedia/include $live_include_dir/UsageEnvironment/include $live_include_dir/BasicUsageEnvironment/include $live_include_dir/groupsock/include" 3010 else 3011 if test -f "$live_include_dir/liveMedia/liveMedia.hh"; then 3012 LIVE_INCLUDES="$live_include_dir/liveMedia $live_include_dir/UsageEnvironment $live_include_dir/BasicUsageEnvironment $live_include_dir/groupsock" 3013 else 3014 echo "Unable to find Live Media headers." 3015 exit 1; 3016 fi 3017 fi 3018 fi 3019 CCONFIG="$CCONFIG using_freebox" 3020 CONFIG_DEFINES="$CONFIG_DEFINES USING_FREEBOX" 3021 echo "CONFIG_LIVE_LIBS=$CONFIG_LIVE_LIBS" >> $MYTH_CONFIG_MAK 3022 CONFIG_INCLUDEPATH="$CONFIG_INCLUDEPATH $LIVE_INCLUDES" 3023 fi 3024 2963 3025 if test x"$hdhomerun_box" = x"yes" ; then 2964 3026 CCONFIG="$CCONFIG using_hdhr" 2965 3027 fi -
libs/libmythtv/freeboxchannel.h
1 /** 2 * FreeboxChannel 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 FREEBOXCHANNEL_H 8 #define FREEBOXCHANNEL_H 9 10 #include "channelbase.h" 11 12 class FreeboxDBOptions; 13 class QHttp; 14 15 16 17 class FreeboxChannel : public QObject, public ChannelBase 18 { 19 Q_OBJECT 20 public: 21 FreeboxChannel(TVRec *parent, FreeboxDBOptions *freebox_options, int cardid); 22 ~FreeboxChannel(void) 23 { 24 } 25 26 bool Open(); 27 void Close(); 28 bool SwitchToInput(const QString &inputname, const QString &chan); 29 bool SetChannelByString(const QString &chan); 30 bool IsOpen(void) const; 31 32 QString GetCurrentChannelUrl(); 33 34 bool SwitchToInput(int newcapchannel, bool setstarting) 35 { 36 (void)newcapchannel; 37 (void)setstarting; 38 return false; 39 } 40 41 QString GetChannelUrlFromNumber(const QString& channelnumber); 42 QString GetDefaultChannel(); 43 44 signals: 45 void ChannelChanged(); 46 47 public slots: 48 void HttpRequestDone(bool error); 49 50 private: 51 void LoadChannels(); 52 QString normalize(QString channelName); 53 54 void Log(QString string); 55 56 QHttp *http; 57 FreeboxDBOptions *m_freeboxoptions; 58 59 bool m_channelListReady; 60 QString m_requestChannel; 61 QString m_lastChannel; 62 int m_cardid; 63 64 // the rtsp url for the current channel 65 QString m_currenturl; 66 67 // number of channel support by freebox 68 int m_freeboxchannelcount; 69 70 // map channelNum to channel index in table 71 QMap<int,int> m_freeboxchannelIds; 72 73 // map channel index to channel url 74 QMap<int,QString> m_freeboxchannelUrl; 75 76 // map channel index to channel name 77 QMap<int,QString> m_freeboxchannelNames; 78 79 // map channel index to channel normalize name 80 QMap<int,QString> m_freeboxchannelNamesN; 81 }; 82 83 #endif//FREEBOXCHANNEL_H 84 85 /* vim: set expandtab tabstop=4 shiftwidth=4: */ -
libs/libmythtv/libmythtv.pro
369 369 using_dbox2:SOURCES += dbox2recorder.cpp dbox2channel.cpp dbox2epg.cpp 370 370 using_dbox2:HEADERS += dbox2recorder.h dbox2channel.h dbox2epg.h 371 371 using_dbox2:DEFINES += USING_DBOX2 372 373 # Support for freebox (http://adsl.free.fr/) 374 using_freebox:SOURCES += freeboxrecorder.cpp freeboxchannel.cpp freeboxmediasink.cpp 375 using_freebox:HEADERS += freeboxrecorder.h freeboxchannel.h freeboxmediasink.h 376 using_freebox:DEFINES += USING_FREEBOX 372 377 373 378 # Support for HDHomeRun box 374 379 using_hdhr { -
libs/libmythtv/freeboxchannel.cpp
1 /** 2 * FreeboxChannel 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 "freeboxchannel.h" 8 9 #include <qhttp.h> 10 #include <qurl.h> 11 12 #include "libmythtv/tv_rec.h" 13 14 15 16 FreeboxChannel::FreeboxChannel(TVRec *parent, FreeboxDBOptions *freebox_options, int cardid): 17 QObject(NULL, "FreeboxChannel"), 18 ChannelBase(parent), 19 http(new QHttp()), 20 m_freeboxoptions(freebox_options), 21 m_channelListReady(false), 22 m_requestChannel(""), 23 m_lastChannel("1"), 24 m_cardid(cardid), 25 m_freeboxchannelcount(0) 26 { 27 connect(http, SIGNAL(done(bool)), 28 this, SLOT(HttpRequestDone(bool))); 29 30 LoadChannels(); 31 } 32 33 bool FreeboxChannel::SwitchToInput(const QString &inputname, const QString &chan) 34 { 35 int inputNum = GetInputByName(inputname); 36 if (inputNum < 0) 37 return false; 38 39 return SetChannelByString(chan); 40 } 41 42 bool FreeboxChannel::SetChannelByString(const QString &newChan) 43 { 44 // Delay set channel when list has not yet been retrieved 45 if (!m_channelListReady) 46 { 47 VERBOSE(VB_IMPORTANT,QString("Freebox # Channel list not received yet. Will switch to channel %1 later...").arg(newChan)); 48 m_requestChannel = newChan; 49 return true; 50 } 51 52 QString chan = newChan; 53 // If chan is empty, use DefautChannel 54 if (chan == "") 55 { 56 VERBOSE(VB_IMPORTANT,QString("Freebox # Empty channel name has been provided. Getting default name.")); 57 chan = GetDefaultChannel(); 58 } 59 60 // update current chanel 61 if (m_lastChannel != curchannelname) 62 m_lastChannel = curchannelname; 63 64 curchannelname = chan; 65 m_currenturl = GetChannelUrlFromNumber(curchannelname); 66 67 // emit signal to recorder 68 emit ChannelChanged(); 69 70 return true; 71 } 72 73 QString FreeboxChannel::GetCurrentChannelUrl() 74 { 75 return m_currenturl; 76 } 77 78 bool FreeboxChannel::IsOpen(void) const 79 { 80 return true; 81 } 82 83 bool FreeboxChannel::Open(void) 84 { 85 if (!InitializeInputs()) 86 return false; 87 88 return true; 89 } 90 91 void FreeboxChannel::Close(void) 92 { 93 } 94 95 96 // ===================================================================================== 97 // 98 // C H A N N E L L O A D I N G 99 // ===================================================================================== 100 101 102 void FreeboxChannel::LoadChannels() 103 { 104 // Request Channel list via http. Signal will be emmitted when list is ready. 105 QUrl url( m_freeboxoptions->mrl ); 106 QHttpRequestHeader header("GET", url.path()); 107 header.setValue("Host", url.host()); 108 int port = url.hasPort() ? url.port() : 80; 109 http->setHost(url.host(), port); 110 http->request(header); 111 } 112 113 114 QString FreeboxChannel::normalize(QString channelName) 115 { 116 // Normalize Channel name so we can try to automap channel return by freebox to channel coming from tv_grab_fr 117 static const QString map1 = QString::fromUtf8("áâÀà ãåçéêëÚÃîïìñóÎöòõúûÌùÜÿ"); 118 static const QString map2 = QString::fromUtf8("aaaaaaceeeeiiiinooooouuuuyy"); 119 QString res; 120 for (unsigned int i=0;i<channelName.length();i++) 121 { 122 QChar c = channelName[i].lower(); 123 if (c.isSpace()) continue; 124 int pos = map1.find(c); 125 if (pos>=0) 126 { 127 res += map2[pos]; 128 } 129 else 130 { 131 res += c; 132 } 133 } 134 135 return res; 136 } 137 138 // ========================================================================================== 139 // HttpRequestDone : Receive response to channel list request 140 // 141 // ========================================================================================== 142 void FreeboxChannel::HttpRequestDone(bool error) 143 { 144 if (error) 145 { 146 VERBOSE(VB_IMPORTANT,QString("Freebox # Reading channel list failed! (%1)").arg(http->errorString())); 147 return; 148 } 149 150 QString buffer = QString::fromUtf8(http->readAll()); 151 m_freeboxchannelcount = 0; 152 153 int sepCount = 0; 154 155 QString header = buffer.section("\n", sepCount, sepCount); 156 sepCount++; 157 158 // Verify header is ok 159 if (header != "#EXTM3U") 160 { 161 VERBOSE(VB_IMPORTANT,QString("Freebox # Invalid header while retrieve channel list.!")); 162 return; 163 } 164 165 while (true) 166 { 167 QString line1 = buffer.section("\n", sepCount, sepCount); 168 if (line1 == "") 169 break; 170 171 sepCount++; 172 173 QString line2 = buffer.section("\n", sepCount, sepCount); 174 if (line2 == "") 175 break; 176 177 sepCount++; 178 179 // each line contains :// 180 // header:extension,channelNum - channelName rtsp://channelUrl 181 //#EXTINF:0,2 - France 2 rtsp://mafreebox.freebox.fr/freeboxtv/201 182 183 QString lineHead; 184 QString extension; 185 QString channelNum; 186 QString channelName; 187 188 int pos = 0; 189 int oldPos = 0; 190 191 pos = line1.find(":", oldPos); 192 if (pos<0) 193 { 194 VERBOSE(VB_IMPORTANT,QString("Freebox # Invalid header while retrieve channel list.!")); 195 return; 196 } 197 lineHead = line1.mid(0, pos); 198 199 if (lineHead != "#EXTINF") 200 { 201 VERBOSE(VB_IMPORTANT,QString("Freebox # Invalid header while retrieve channel list.!")); 202 return; 203 } 204 205 oldPos = pos + 1; 206 pos = line1.find(",", oldPos); 207 if (pos<0) 208 { 209 VERBOSE(VB_IMPORTANT,QString("Freebox # Invalid header while retrieve channel list.!")); 210 return; 211 } 212 extension = line1.mid(oldPos, pos - oldPos); 213 214 oldPos = pos + 1; 215 pos = line1.find(" ", oldPos); 216 if (pos<0) 217 { 218 VERBOSE(VB_IMPORTANT,QString("Freebox # Invalid header while retrieve channel list.!")); 219 return; 220 } 221 channelNum = line1.mid(oldPos, pos - oldPos); 222 223 oldPos = pos + 1; 224 pos = line1.find("- ", oldPos); 225 if (pos<0) 226 { 227 VERBOSE(VB_IMPORTANT,QString("Freebox # Invalid header while retrieve channel list.!")); 228 return; 229 } 230 channelName = line1.mid(pos + 2, line1.length()); 231 232 QString channelUrl = line2; 233 234 // save all this information in map for quick access 235 bool ok; 236 int channelNumI = channelNum.toInt( &ok, 10 ); 237 238 QString channelNameN = normalize(channelName); 239 240 m_freeboxchannelIds[channelNumI] = m_freeboxchannelcount; 241 m_freeboxchannelUrl[m_freeboxchannelcount] = channelUrl; 242 m_freeboxchannelNames[m_freeboxchannelcount] = channelName; 243 m_freeboxchannelNamesN[m_freeboxchannelcount] = channelNameN; 244 245 m_freeboxchannelcount++; 246 } 247 248 // Channel list is ready. 249 m_channelListReady = true; 250 251 // Change channel if delayed request is available 252 if (m_requestChannel != "") 253 { 254 SetChannelByString(m_requestChannel); 255 m_requestChannel = ""; 256 } 257 } 258 259 260 // ========================================================================================== 261 // GetChannelUrlFromNumber : Map a channel number to the corresponding rtsp URL 262 // 263 // ========================================================================================== 264 QString FreeboxChannel::GetChannelUrlFromNumber(const QString& channelnumber) 265 { 266 MSqlQuery query(MSqlQuery::InitCon()); 267 268 query.prepare("SELECT name,freqid " 269 "FROM channel,cardinput " 270 "WHERE " 271 "channel.sourceid = cardinput.sourceid AND " 272 "cardinput.cardid = :CARDID AND " 273 "channel.channum = :CHANNUM"); 274 275 query.bindValue(":CARDID", m_cardid); 276 query.bindValue(":CHANNUM", channelnumber); 277 278 if (query.exec() && query.isActive() && query.size() > 0) 279 { 280 query.next(); 281 QString chanName = query.value(0).toString(); 282 283 // if we have a FreqID in the table, use this as the real freebox channel number 284 int mFreqId = query.value(1).toInt(); 285 if (mFreqId!=0) 286 { 287 int channelI = m_freeboxchannelIds[mFreqId]; 288 return m_freeboxchannelUrl[channelI]; 289 } 290 291 // if no freqID, try to map the chanName to an existing channel name 292 for (int i=0;i<m_freeboxchannelcount;i++) 293 { 294 if (m_freeboxchannelNamesN[i] == chanName) 295 { 296 return m_freeboxchannelUrl[i]; 297 } 298 } 299 300 VERBOSE(VB_IMPORTANT,QString("Freebox # GetChannelUrlFromNumber(num=%1,name=%2) failed") 301 .arg(channelnumber) 302 .arg(chanName)); 303 return ""; 304 } 305 VERBOSE(VB_IMPORTANT,QString("Freebox # GetChannelUrlFromNumber(num=%1) failed") 306 .arg(channelnumber)); 307 return ""; 308 } 309 310 // ========================================================================================== 311 // GetDefaultChannel : Search for default channel 312 // 313 // ========================================================================================== 314 315 QString FreeboxChannel::GetDefaultChannel() 316 { 317 MSqlQuery query(MSqlQuery::InitCon()); 318 query.prepare("SELECT channum " 319 "FROM channel,cardinput " 320 "WHERE " 321 "channel.sourceid = cardinput.sourceid AND " 322 "cardinput.cardid = :CARDID " 323 "ORDER BY channum limit 1"); 324 325 query.bindValue(":CARDID", m_cardid); 326 327 if (query.exec() && query.isActive() && query.size() > 0) 328 { 329 query.next(); 330 return query.value(0).toString(); 331 } 332 return ""; 333 } 334 335 /* vim: set expandtab tabstop=4 shiftwidth=4: */ -
libs/libmythtv/freeboxmediasink.cpp
1 /** 2 * FreeboxMediaSink 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 "freeboxmediasink.h" 8 9 #include "freeboxrecorder.h" 10 11 12 13 FreeboxMediaSink::FreeboxMediaSink(UsageEnvironment& pEnv, 14 FreeboxRecorder& pRecorder, 15 unsigned bufferSize) : 16 MediaSink(pEnv), 17 fBufferSize(bufferSize), 18 env(pEnv), 19 recorder(pRecorder) 20 { 21 // Setup the data buffer 22 fBuffer = new unsigned char[fBufferSize]; 23 } 24 25 FreeboxMediaSink::~FreeboxMediaSink() 26 { 27 // free the data buffer 28 delete[] fBuffer; 29 } 30 31 FreeboxMediaSink* FreeboxMediaSink::createNew(UsageEnvironment& env, 32 FreeboxRecorder& pRecorder, 33 unsigned bufferSize) 34 { 35 return new FreeboxMediaSink(env, pRecorder, bufferSize); 36 } 37 38 Boolean FreeboxMediaSink::continuePlaying() 39 { 40 if (fSource == NULL) return False; 41 42 fSource->getNextFrame(fBuffer, fBufferSize, 43 afterGettingFrame, this, 44 onSourceClosure, this); 45 return True; 46 } 47 48 void FreeboxMediaSink::afterGettingFrame(void* clientData, 49 unsigned frameSize, 50 unsigned /*numTruncatedBytes*/, 51 struct timeval presentationTime, 52 unsigned /*durationInMicroseconds*/) 53 { 54 FreeboxMediaSink* sink = (FreeboxMediaSink*)clientData; 55 sink->afterGettingFrame1(frameSize, presentationTime); 56 } 57 58 void FreeboxMediaSink::afterGettingFrame1(unsigned frameSize, 59 struct timeval presentationTime) 60 { 61 addData(fBuffer, frameSize, presentationTime); 62 continuePlaying(); 63 } 64 65 void FreeboxMediaSink::addData(unsigned char* data, 66 unsigned dataSize, 67 struct timeval presentationTime) 68 { 69 recorder.addData(data, dataSize, presentationTime); 70 } -
libs/libmythtv/dbcheck.cpp
10 10 #include "mythdbcon.h" 11 11 12 12 /// This is the DB schema version expected by the running MythTV instance. 13 const QString currentDatabaseVersion = "11 39";13 const QString currentDatabaseVersion = "1140"; 14 14 15 15 static bool UpdateDBVersionNumber(const QString &newnumber); 16 16 static bool performActualUpdate(const QString updates[], QString version, … … 2231 2231 //"ALTER TABLE capturecard DROP COLUMN dvb_hw_decoder;" in 0.21 2232 2232 //"ALTER TABLE cardinput DROP COLUMN preference;" in 0.22 2233 2233 2234 if (dbver == "1139") 2235 { 2236 const QString updates[] = { 2237 "INSERT INTO profilegroups SET name = 'Freebox Input', cardtype = 'Freebox', is_default = 1;", 2238 "ALTER TABLE capturecard ADD COLUMN freebox_mrl varchar(64) DEFAULT 'http://mafreebox.freebox.fr/freeboxtv/playlist.m3u';", 2239 "" 2240 }; 2241 2242 if (!performActualUpdate(updates, "1140", dbver)) 2243 return false; 2244 } 2245 2246 2234 2247 return true; 2235 2248 } 2236 2249 … … 2291 2304 " dbox2_port int(10) unsigned NOT NULL default '31338'," 2292 2305 " dbox2_httpport int(10) unsigned NOT NULL default '80'," 2293 2306 " dbox2_host varchar(32) default NULL," 2307 " freebox_mrl varchar(64) DEFAULT 'http://mafreebox.freebox.fr/freeboxtv/playlist.m3u'," 2294 2308 " signal_timeout int(11) NOT NULL default '1000'," 2295 2309 " channel_timeout int(11) NOT NULL default '3000'," 2296 2310 " PRIMARY KEY (cardid)" … … 2857 2871 "INSERT INTO profilegroups VALUES (8," 2858 2872 " 'USB Mpeg-4 Encoder (Plextor ConvertX, etc)','GO7007',1,NULL);", 2859 2873 "INSERT INTO profilegroups VALUES (9,'DBOX2 Input','DBOX2',1,NULL);", 2874 "INSERT INTO `profilegroups` VALUES (10,'Freebox Input','Freebox',1,NULL);", 2860 2875 "INSERT INTO recordingprofiles VALUES (1,'Default',NULL,NULL,1);", 2861 2876 "INSERT INTO recordingprofiles VALUES (2,'Live TV',NULL,NULL,1);", 2862 2877 "INSERT INTO recordingprofiles VALUES (3,'High Quality',NULL,NULL,1);", -
libs/libmythtv/freeboxrecorder.cpp
1 /** 2 * FreeboxRecorder 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 "freeboxrecorder.h" 8 9 #include <BasicUsageEnvironment.hh> 10 #include <MediaSession.hh> 11 #include <RTSPClient.hh> 12 #include <qwaitcondition.h> 13 #include <qmutex.h> 14 15 #include "mpeg/tspacket.h" 16 #include "freeboxchannel.h" 17 #include "freeboxmediasink.h" 18 19 20 21 // ============================================================================ 22 // FreeboxData : Helper class use for static Callback handler 23 // ============================================================================ 24 class FreeboxData 25 { 26 public: 27 FreeboxData(FreeboxRecorder *pFreeboxRecorder, MediaSubsession *pMediaSubSession) : 28 freeboxRecorder(pFreeboxRecorder), 29 mediaSubSession(pMediaSubSession) 30 { 31 } 32 33 static void subsessionAfterPlayingCallback(void *clientData); 34 static void subsessionByeHandlerCallback(void *clientData); 35 void SubsessionAfterPlaying(); 36 void SubsessionByeHandler(); 37 38 private: 39 FreeboxRecorder *freeboxRecorder; 40 MediaSubsession *mediaSubSession; 41 }; 42 43 void FreeboxData::subsessionAfterPlayingCallback(void *clientData) 44 { 45 ((FreeboxData*)clientData)->SubsessionAfterPlaying(); 46 } 47 48 void FreeboxData::subsessionByeHandlerCallback(void *clientData) 49 { 50 ((FreeboxData*)clientData)->SubsessionByeHandler(); 51 } 52 53 void FreeboxData::SubsessionAfterPlaying() 54 { 55 MediaSubsession* subsession = mediaSubSession; 56 Medium::close(subsession->sink); 57 subsession->sink = NULL; 58 59 MediaSession& session = subsession->parentSession(); 60 MediaSubsessionIterator iter(session); 61 while ((subsession = iter.next()) != NULL) 62 { 63 if (subsession->sink != NULL) return; 64 } 65 } 66 67 void FreeboxData::SubsessionByeHandler() 68 { 69 SubsessionAfterPlaying(); 70 } 71 72 73 74 class FreeboxRecorderImpl 75 { 76 public: 77 FreeboxRecorderImpl(FreeboxChannel& channel) : 78 env(NULL), 79 rtspClient(NULL), 80 session(NULL), 81 _channel(channel), 82 _abort_rtsp(0), 83 _abort_recording(false) 84 { 85 } 86 87 // livemedia 88 UsageEnvironment* env; 89 RTSPClient* rtspClient; 90 MediaSession* session; 91 92 // Current channel 93 FreeboxChannel& _channel; 94 95 // condition used to coordinate threads 96 QWaitCondition _cond; 97 98 // lock used to coordinate threads 99 QMutex _lock; 100 101 // var to check if we need to abort current rtsp session 102 char _abort_rtsp; 103 104 // request abort for StartRecording method 105 bool _abort_recording; 106 }; 107 108 109 110 FreeboxRecorder::FreeboxRecorder(TVRec *rec, FreeboxChannel *channel) : 111 DTVRecorder(rec), 112 _impl(new FreeboxRecorderImpl(*channel)) 113 { 114 connect(channel, SIGNAL(ChannelChanged()), 115 this, SLOT( ChannelChanged())); 116 } 117 118 119 120 FreeboxRecorder::~FreeboxRecorder() 121 { 122 delete _impl; 123 } 124 125 126 127 bool FreeboxRecorder::Open() 128 { 129 bool result = StartRtsp(); 130 _error = !result; 131 return result; 132 } 133 134 135 136 void FreeboxRecorder::Close() 137 { 138 if (_impl->session == NULL) return; 139 140 // Ensure RTSP cleanup, remove old RTSP session 141 MediaSubsessionIterator iter(*_impl->session); 142 MediaSubsession* subsession; 143 while ((subsession = iter.next()) != NULL) 144 { 145 Medium::close(subsession->sink); 146 subsession->sink = NULL; 147 } 148 149 if (_impl->session == NULL) return; 150 151 _impl->rtspClient->teardownMediaSession(*_impl->session); 152 153 // Close all RTSP descriptor 154 Medium::close(_impl->session); 155 Medium::close(_impl->rtspClient); 156 } 157 158 159 160 void FreeboxRecorder::ChannelChanged() 161 { 162 // Channel change, we need to close current RTSP flow, and open a new one 163 ResetEventLoop(); 164 } 165 166 167 168 void FreeboxRecorder::SetOptionsFromProfile(RecordingProfile *profile, 169 const QString &videodev, 170 const QString &audiodev, 171 const QString &vbidev) 172 { 173 (void)videodev; 174 (void)audiodev; 175 (void)vbidev; 176 (void)profile; 177 } 178 179 180 181 void FreeboxRecorder::StartRecording() 182 { 183 _impl->_lock.lock(); 184 _recording = true; 185 while(!_impl->_abort_recording && Open()) 186 { 187 _impl->_lock.unlock(); 188 // Go into main RTSP loop, feeding data to mythtv 189 _impl->env->taskScheduler().doEventLoop(&_impl->_abort_rtsp); 190 191 _impl->_lock.lock(); 192 FinishRecording(); 193 Close(); 194 195 // Reset _abort_rtsp before unlocking ResetEventLoop() to avoid race condition 196 _impl->_abort_rtsp = 0; 197 _impl->_cond.wakeAll(); 198 } 199 _recording = false; 200 _impl->_lock.unlock(); 201 } 202 203 void FreeboxRecorder::StopRecording(void) 204 { 205 _impl->_abort_recording = true; // No lock needed 206 ResetEventLoop(); 207 } 208 209 void FreeboxRecorder::ResetEventLoop() 210 { 211 _impl->_lock.lock(); 212 _impl->_abort_rtsp = ~0; 213 while(_recording && _impl->_abort_rtsp) 214 _impl->_cond.wait(&_impl->_lock, 1000); 215 _impl->_lock.unlock(); 216 } 217 218 // ====================================================================== 219 // StartRtsp : start a new RTSP session for the current channel 220 // ====================================================================== 221 bool FreeboxRecorder::StartRtsp() 222 { 223 // Retrieve the RTSP channel URL 224 QString url = _impl->_channel.GetCurrentChannelUrl(); 225 226 // Begin by setting up our usage environment: 227 TaskScheduler* scheduler = BasicTaskScheduler::createNew(); 228 _impl->env = BasicUsageEnvironment::createNew(*scheduler); 229 230 231 // Create our client object: 232 _impl->rtspClient = RTSPClient::createNew(*_impl->env, 0, "myRTSP", 0); 233 if (_impl->rtspClient == NULL) 234 { 235 VERBOSE(VB_IMPORTANT, QString("Freebox # Failed to create RTSP client: %1") 236 .arg(_impl->env->getResultMsg())); 237 return false; 238 } 239 240 // Setup URL for the current session 241 char* sdpDescription = _impl->rtspClient->describeURL(url); 242 _impl->rtspClient->describeStatus(); 243 if (sdpDescription == NULL) 244 { 245 VERBOSE(VB_IMPORTANT, QString("Freebox # Failed to get a SDP description from URL: %1 %2") 246 .arg(url) 247 .arg(_impl->env->getResultMsg())); 248 return false; 249 } 250 251 // Create a media session object from this SDP description: 252 _impl->session = MediaSession::createNew(*_impl->env, sdpDescription); 253 delete[] sdpDescription; 254 if (_impl->session == NULL) 255 { 256 VERBOSE(VB_IMPORTANT, QString("Freebox # Failed to create MediaSession: %1") 257 .arg(_impl->env->getResultMsg())); 258 return false; 259 } 260 else if (!_impl->session->hasSubsessions()) 261 { 262 VERBOSE(VB_IMPORTANT, QString("Freebox # This session has no media subsessions")); 263 return false; 264 } 265 266 // Then, setup the "RTPSource"s for the session: 267 MediaSubsessionIterator iter(*_impl->session); 268 MediaSubsession *subsession; 269 Boolean madeProgress = False; 270 while ((subsession = iter.next()) != NULL) 271 { 272 if (!subsession->initiate(-1)) 273 { 274 VERBOSE(VB_IMPORTANT, QString("Freebox # Unable to create receiver for: %1 / %2 subsession: %3") 275 .arg(subsession->mediumName()) 276 .arg(subsession->codecName()) 277 .arg(_impl->env->getResultMsg())); 278 } 279 else 280 { 281 madeProgress = True; 282 283 if (subsession->rtpSource() != NULL) 284 { 285 unsigned const thresh = 1000000; // 1 second 286 subsession->rtpSource()->setPacketReorderingThresholdTime(thresh); 287 } 288 } 289 } 290 291 if (!madeProgress) return false; 292 293 // Perform additional 'setup' on each subsession, before playing them: 294 madeProgress = false; 295 iter.reset(); 296 while ((subsession = iter.next()) != NULL) 297 { 298 if (subsession->clientPortNum() == 0) continue; // port # was not set 299 300 if (_impl->rtspClient->setupMediaSubsession(*subsession, False, false)) 301 { 302 madeProgress = True; 303 } 304 else 305 { 306 VERBOSE(VB_IMPORTANT, QString("Freebox # Failed to setup: %1 %2 : %3") 307 .arg(subsession->mediumName()) 308 .arg(subsession->codecName()) 309 .arg(_impl->env->getResultMsg())); 310 } 311 } 312 313 if (!madeProgress) return false; 314 315 // Create and start "FileSink"s for each subsession: 316 // FileSink while receive Mpeg2 TS Data & will feed them to mythtv 317 madeProgress = False; 318 iter.reset(); 319 while ((subsession = iter.next()) != NULL) 320 { 321 if (subsession->readSource() == NULL) continue; // was not initiated 322 323 FreeboxMediaSink* freeboxMediaSink = 324 FreeboxMediaSink::createNew(*_impl->env, *this, TSPacket::SIZE*128); 325 326 subsession->sink = freeboxMediaSink; 327 if (subsession->sink == NULL) 328 { 329 VERBOSE(VB_IMPORTANT, QString("Freebox # Failed to create sink: %1") 330 .arg(_impl->env->getResultMsg())); 331 } 332 333 subsession->sink->startPlaying( 334 *(subsession->readSource()), 335 FreeboxData::subsessionAfterPlayingCallback, 336 new FreeboxData(this, subsession)); 337 338 if (subsession->rtcpInstance() != NULL) 339 { 340 subsession->rtcpInstance()->setByeHandler( 341 FreeboxData::subsessionByeHandlerCallback, 342 new FreeboxData(this, subsession)); 343 } 344 345 madeProgress = True; 346 } 347 348 if (!madeProgress) return false; 349 350 // Setup player 351 if (!(_impl->rtspClient->playMediaSession(*_impl->session))) 352 { 353 VERBOSE(VB_IMPORTANT, QString("Freebox # Failed to start playing session: %1") 354 .arg(_impl->env->getResultMsg())); 355 return false; 356 } 357 358 return true; 359 } 360 361 // =================================================== 362 // findTSHeader : find a TS Header in flow 363 // =================================================== 364 static int FreeboxRecorder_findTSHeader(const unsigned char *data, unsigned dataSize) 365 { 366 unsigned int pos = 0; 367 while (pos < dataSize) 368 { 369 if (data[pos] == 0x47) 370 return pos; 371 pos++; 372 } 373 return -1; 374 } 375 376 // =================================================== 377 // addData : feed date from RTSP flow to mythtv 378 // =================================================== 379 void FreeboxRecorder::addData(unsigned char* data, unsigned dataSize, struct timeval) 380 { 381 unsigned int readIndex = 0; 382 383 // data may be compose from more than one packet, loop to consume all data 384 while (readIndex < dataSize) 385 { 386 // If recorder is pause, stop there 387 if (PauseAndWait()) 388 { 389 return; 390 } 391 392 // Find the next TS Header in data 393 int tsPos = FreeboxRecorder_findTSHeader(data + readIndex, dataSize); 394 395 // if no TS, something bad happens 396 if (tsPos == -1) 397 { 398 VERBOSE(VB_IMPORTANT, QString("FREEBOX: No TS header.")); 399 break; 400 } 401 402 // if TS Header not at start of data, we receive out of sync data 403 if (tsPos > 0) 404 { 405 VERBOSE(VB_IMPORTANT, QString("FREEBOX: TS header at %1, not in sync.").arg(tsPos)); 406 } 407 408 // Check if the next packet in buffer is complete : packet size is 188 bytes long 409 if ((dataSize - tsPos) < TSPacket::SIZE) 410 { 411 VERBOSE(VB_IMPORTANT, QString("FREEBOX: TS header at %1 but packet not yet complete.").arg(tsPos)); 412 break; 413 } 414 415 // Cast current found TS Packet to TSPacket structure 416 const void *newData = data + tsPos + readIndex; 417 const TSPacket *tspacket = reinterpret_cast<const TSPacket*>(newData); 418 419 // Feed current packet to myth 420 _buffer_packets = !FindMPEG2Keyframes(tspacket); 421 BufferedWrite(*tspacket); 422 423 // follow to next packet 424 readIndex += tsPos + TSPacket::SIZE; 425 } 426 } 427 428 /* vim: set expandtab tabstop=4 shiftwidth=4: */ -
libs/libmythtv/cardutil.cpp
571 571 572 572 if (("FIREWIRE" == cardtype) || 573 573 ("DBOX2" == cardtype) || 574 ("FREEBOX" == cardtype) || 574 575 ("HDHOMERUN" == cardtype) || 575 576 ("CRC_IP" == cardtype)) 576 577 { … … 768 769 .arg(query.value(1).toString()) 769 770 .arg(query.value(2).toString()); 770 771 } 772 else if (cardtype == "FREEBOX") 773 { 774 MSqlQuery query(MSqlQuery::InitCon()); 775 query.prepare( 776 "SELECT freebox_mrl " 777 "FROM capturecard " 778 "WHERE cardid = :CARDID"); 779 query.bindValue(":CARDID", cardid); 780 781 if (!query.exec() || !query.isActive() || !query.next()) 782 label = "[ DB ERROR ]"; 783 else 784 label = QString("[ FREEBOX : MRL %1 ]") 785 .arg(query.value(0).toString()); 786 } 771 787 else if (cardtype == "HDHOMERUN") 772 788 { 773 789 MSqlQuery query(MSqlQuery::InitCon()); … … 804 820 805 821 if (("FIREWIRE" == cardtype) || 806 822 ("DBOX2" == cardtype) || 823 ("FREEBOX" == cardtype) || 807 824 ("HDHOMERUN" == cardtype) || 808 825 ("CRC_IP" == cardtype)) 809 826 { -
libs/libmythtv/freeboxmediasink.h
1 /** 2 * FreeboxMediaSink 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 _FREEBOXMEDIASINK_H_ 8 #define _FREEBOXMEDIASINK_H_ 9 10 #include <MediaSink.hh> 11 12 class FreeboxRecorder; 13 14 15 16 // ============================================================================ 17 // FreeboxMediaSink : Helper class use to receive RTSP data from socket. 18 // ============================================================================ 19 class FreeboxMediaSink: public MediaSink 20 { 21 public: 22 static FreeboxMediaSink* createNew(UsageEnvironment& env, 23 FreeboxRecorder& pRecorder, 24 unsigned bufferSize); 25 26 // Callback function when rtsp data are ready 27 void addData(unsigned char* data, unsigned dataSize, struct timeval presentationTime); 28 29 protected: 30 FreeboxMediaSink(UsageEnvironment& env, 31 FreeboxRecorder& pRecorder, 32 unsigned bufferSize); 33 virtual ~FreeboxMediaSink(); 34 35 static void afterGettingFrame(void* clientData, 36 unsigned frameSize, 37 unsigned numTruncatedBytes, 38 struct timeval presentationTime, 39 unsigned durationInMicroseconds); 40 virtual void afterGettingFrame1(unsigned frameSize, struct timeval presentationTime); 41 42 private: 43 virtual Boolean continuePlaying(); 44 45 private: 46 unsigned char* fBuffer; 47 unsigned fBufferSize; 48 UsageEnvironment& env; 49 FreeboxRecorder& recorder; 50 51 private: 52 // avoid default contructors & operator= 53 FreeboxMediaSink(); 54 FreeboxMediaSink(const FreeboxMediaSink&); 55 FreeboxMediaSink& operator=(const FreeboxMediaSink&); 56 }; 57 58 #endif//_FREEBOXMEDIASINK_H_ -
libs/libmythtv/videosource.cpp
993 993 } 994 994 }; 995 995 996 class FreeboxHost : public LineEditSetting, public CCSetting { 997 public: 998 FreeboxHost(const CaptureCard &parent): 999 CCSetting(parent, "freebox_mrl") 1000 { 1001 setValue("http://mafreebox.freebox.fr/freeboxtv/playlist.m3u"); 1002 setLabel(QObject::tr("Freebox MRL")); 1003 setHelpText(QObject::tr("The freebox Media Resource Locator (MRL).")); 1004 } 1005 }; 1006 996 1007 class HDHomeRunTunerIndex: public ComboBoxSetting, public CCSetting 997 1008 { 998 1009 public: … … 1005 1016 } 1006 1017 }; 1007 1018 1019 class FreeboxConfigurationGroup: public VerticalConfigurationGroup { 1020 public: 1021 FreeboxConfigurationGroup(CaptureCard& a_parent): 1022 ConfigurationGroup(false, true, false, false), 1023 VerticalConfigurationGroup(false, true, false, false), 1024 parent(a_parent) 1025 { 1026 setUseLabel(false); 1027 addChild(new FreeboxHost(parent)); 1028 }; 1029 private: 1030 CaptureCard& parent; 1031 }; 1032 1008 1033 void HDHRCardInput::fillSelections(const QString&) 1009 1034 { 1010 1035 clearSelections(); … … 1229 1254 addTarget("DBOX2", new DBOX2ConfigurationGroup(parent)); 1230 1255 #endif // USING_DBOX2 1231 1256 1257 #ifdef USING_FREEBOX 1258 addTarget("FREEBOX", new FreeboxConfigurationGroup(parent)); 1259 #endif // USING_FREEBOX 1260 1232 1261 #ifdef USING_HDHOMERUN 1233 1262 addTarget("HDHOMERUN", new HDHomeRunConfigurationGroup(parent)); 1234 1263 #endif // USING_HDHOMERUN … … 1350 1379 QObject::tr("DBox2 TCP/IP cable box"), "DBOX2"); 1351 1380 #endif // USING_DBOX2 1352 1381 1382 #ifdef USING_FREEBOX 1383 setting->addSelection( 1384 QObject::tr("Freebox"), "FREEBOX"); 1385 #endif // USING_FREEBOX 1386 1353 1387 #ifdef USING_HDHOMERUN 1354 1388 setting->addSelection( 1355 1389 QObject::tr("HDHomeRun DTV tuner box"), "HDHOMERUN"); -
libs/libmythtv/freeboxrecorder.h
1 /** 2 * FreeboxRecorder 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 FREEBOXRECORDER_H_ 8 #define FREEBOXRECORDER_H_ 9 10 #include "dtvrecorder.h" 11 12 class FreeboxChannel; 13 class FreeboxRecorderImpl; 14 15 16 17 /** 18 * Constructs a FreeboxRecorder 19 */ 20 class FreeboxRecorder : 21 public QObject, //FIXME see changeset #9743 for details 22 public DTVRecorder 23 { 24 Q_OBJECT 25 public: 26 FreeboxRecorder(TVRec *rec, FreeboxChannel *channel); 27 ~FreeboxRecorder(); 28 29 void StartRecording(void); //< RecorderBase 30 void StopRecording(void); //< DTVRecorder 31 32 // RecorderBase 33 void SetOptionsFromProfile(RecordingProfile *profile, 34 const QString &videodev, 35 const QString &audiodev, 36 const QString &vbidev); 37 38 public slots: 39 void ChannelChanged(); 40 41 private: 42 friend class FreeboxMediaSink; 43 44 bool Open(); //< RecorderBase 45 void Close(); 46 47 // Callback function to add MPEG2 TS data 48 void addData(unsigned char* data, unsigned dataSize, struct timeval presentationTime); 49 50 bool StartRtsp(); 51 void ResetEventLoop(); 52 53 private: 54 FreeboxRecorderImpl* _impl; 55 }; 56 57 #endif//FREEBOXRECORDER_H_ 58 59 /* vim: set expandtab tabstop=4 shiftwidth=4: */ -
libs/libmythtv/tv_rec.cpp
54 54 #include "dbox2recorder.h" 55 55 #include "hdhrrecorder.h" 56 56 57 #ifdef USING_FREEBOX 58 #include "freeboxrecorder.h" 59 #include "freeboxchannel.h" 60 #endif // USING_FREEBOX 61 57 62 #ifdef USING_CRC_IP_NETWORK_REC 58 63 #include "crcipnetworkrecorder.h" 59 64 #endif … … 183 188 init_run = true; 184 189 #endif 185 190 } 191 else if (genOpt.cardtype == "FREEBOX") 192 { 193 #ifdef USING_FREEBOX 194 channel = new FreeboxChannel(this, &freeboxOpt, cardid); 195 if (!channel->Open()) 196 return false; 197 InitChannel(genOpt.defaultinput, startchannel); 198 init_run = true; 199 #endif 200 } 186 201 else if (genOpt.cardtype == "HDHOMERUN") 187 202 { 188 203 #ifdef USING_HDHOMERUN … … 249 264 { 250 265 QMutexLocker lock(&stateChangeLock); 251 266 252 if (!GetDevices(cardid, genOpt, dvbOpt, fwOpt, dboxOpt ))267 if (!GetDevices(cardid, genOpt, dvbOpt, fwOpt, dboxOpt, freeboxOpt)) 253 268 return false; 254 269 255 270 // configure the Channel instance … … 308 323 scanner = NULL; 309 324 } 310 325 326 #ifdef USING_FREEBOX 327 if (GetFreeboxChannel()) 328 GetFreeboxChannel()->deleteLater(); 329 else 330 #endif // USING_FREEBOX 311 331 if (channel) 312 332 { 313 333 delete channel; … … 871 891 recorder->SetOption("httpport", dboxOpt.httpport); 872 892 #endif // USING_DBOX2 873 893 } 894 else if (genOpt.cardtype == "FREEBOX") 895 { 896 #ifdef USING_FREEBOX 897 recorder = new FreeboxRecorder(this, GetFreeboxChannel()); 898 recorder->SetOption("mrl", freeboxOpt.mrl); 899 #endif // USING_FREEBOX 900 } 874 901 else if (genOpt.cardtype == "HDHOMERUN") 875 902 { 876 903 #ifdef USING_HDHOMERUN … … 1081 1108 #endif // USING_DBOX2 1082 1109 } 1083 1110 1111 FreeboxChannel *TVRec::GetFreeboxChannel(void) 1112 { 1113 #ifdef USING_FREEBOX 1114 return dynamic_cast<FreeboxChannel*>(channel); 1115 #else 1116 return NULL; 1117 #endif // USING_FREEBOX 1118 } 1119 1084 1120 HDHRChannel *TVRec::GetHDHRChannel(void) 1085 1121 { 1086 1122 #ifdef USING_HDHOMERUN … … 1366 1402 return ok; 1367 1403 } 1368 1404 1369 bool TVRec::GetDevices(int cardid, 1370 GeneralDBOptions &gen_opts, 1371 DVBDBOptions &dvb_opts, 1372 FireWireDBOptions &firewire_opts, 1373 DBox2DBOptions &dbox2_opts) 1405 bool TVRec::GetDevices(int cardid, 1406 GeneralDBOptions &gen_opts, 1407 DVBDBOptions &dvb_opts, 1408 FireWireDBOptions &firewire_opts, 1409 DBox2DBOptions &dbox2_opts, 1410 FreeboxDBOptions &freebox_opts) 1374 1411 { 1375 1412 int testnum = 0; 1376 1413 QString test; … … 1387 1424 " firewire_port, firewire_node, firewire_speed, " 1388 1425 " firewire_model, firewire_connection, " 1389 1426 "" 1390 " dbox2_port, dbox2_host, dbox2_httpport " 1427 " dbox2_port, dbox2_host, dbox2_httpport, " 1428 " freebox_mrl " 1391 1429 "" 1392 1430 "FROM capturecard " 1393 1431 "WHERE cardid = :CARDID"); … … 1465 1503 1466 1504 dbox2_opts.httpport = query.value(dbox2off + 2).toUInt(); 1467 1505 1506 // Freebox options 1507 uint freeboxoff = dbox2off + 3; 1508 test = query.value(freeboxoff).toString(); 1509 if (test != QString::null) 1510 freebox_opts.mrl = QString::fromUtf8(test); 1511 1468 1512 return true; 1469 1513 } 1470 1514 … … 3291 3335 delete channel; 3292 3336 channel = NULL; 3293 3337 3294 GetDevices(newCardID, genOpt, dvbOpt, fwOpt, dboxOpt );3338 GetDevices(newCardID, genOpt, dvbOpt, fwOpt, dboxOpt, freeboxOpt); 3295 3339 genOpt.defaultinput = inputname; 3296 3340 CreateChannel(channum); 3297 3341 if (!(request.flags & kFlagNoRec)) -
libs/libmythtv/tv_rec.h
39 39 class DVBChannel; 40 40 class Channel; 41 41 42 class FreeboxChannel; 43 44 42 45 class MPEGStreamData; 43 46 class ProgramMapTable; 44 47 … … 130 133 QString host; 131 134 }; 132 135 136 137 class FreeboxDBOptions 138 { 139 public: 140 FreeboxDBOptions() : mrl("http://mafreebox.freebox.fr/freeboxtv/playlist.m3u") {} 141 142 QString mrl; 143 }; 144 145 133 146 class TuningRequest 134 147 { 135 148 public: … … 262 275 void SetPseudoLiveTVRecording(ProgramInfo*); 263 276 void TeardownAll(void); 264 277 265 static bool GetDevices(int cardid,278 static bool GetDevices(int cardid, 266 279 GeneralDBOptions &general_opts, 267 280 DVBDBOptions &dvb_opts, 268 281 FireWireDBOptions &firewire_opts, 269 DBox2DBOptions &dbox2_opts); 282 DBox2DBOptions &dbox2_opts, 283 FreeboxDBOptions &free_opts); 270 284 271 285 272 286 static QString GetStartChannel(int cardid, const QString &defaultinput); … … 280 294 bool CreateChannel(const QString &startChanNum); 281 295 void InitChannel(const QString &inputname, const QString &startchannel); 282 296 void CloseChannel(void); 283 DBox2Channel *GetDBox2Channel(void);284 HDHRChannel *GetHDHRChannel(void);285 DVBChannel *GetDVBChannel(void);286 Channel *GetV4LChannel(void);287 297 298 DBox2Channel *GetDBox2Channel(void); 299 HDHRChannel *GetHDHRChannel(void); 300 DVBChannel *GetDVBChannel(void); 301 FreeboxChannel *GetFreeboxChannel(void); 302 Channel *GetV4LChannel(void); 303 288 304 void SetupSignalMonitor(bool enable_table_monitoring, bool notify); 289 305 bool SetupDTVSignalMonitor(void); 290 306 void TeardownSignalMonitor(void); … … 361 377 DVBDBOptions dvbOpt; 362 378 FireWireDBOptions fwOpt; 363 379 DBox2DBOptions dboxOpt; 380 FreeboxDBOptions freeboxOpt; 364 381 365 382 // State variables 366 383 QMutex stateChangeLock; -
settings.pro
79 79 EXTRA_LIBS += $$CONFIG_AUDIO_JACK_LIBS 80 80 EXTRA_LIBS += $$CONFIG_FIREWIRE_LIBS 81 81 EXTRA_LIBS += $$CONFIG_DIRECTFB_LIBS 82 EXTRA_LIBS += $$CONFIG_LIVE_LIBS 82 83 83 84 EXTRA_LIBS += $$LOCAL_LIBDIR_OGL 84 85 EXTRA_LIBS += $$LOCAL_LIBDIR_X11