| 1 | diff -u -r -N mythtv-SVN.orig/configure mythtv-SVN/configure
|
|---|
| 2 | --- mythtv-SVN.orig/configure 2006-04-18 09:06:57.000000000 +0200
|
|---|
| 3 | +++ mythtv-SVN/configure 2006-04-18 09:08:41.000000000 +0200
|
|---|
| 4 | @@ -54,6 +54,7 @@
|
|---|
| 5 | lirc="yes"
|
|---|
| 6 | joystick_menu="yes"
|
|---|
| 7 | firewire_cable_box="yes"
|
|---|
| 8 | +freebox_box="no"
|
|---|
| 9 | dbox2_dvb_box="yes"
|
|---|
| 10 | hdhomerun_box="yes"
|
|---|
| 11 | x11_include_path="/usr/X11R6/include"
|
|---|
| 12 | @@ -173,6 +174,9 @@
|
|---|
| 13 | echo " --disable-lirc disable lirc support (Infrared Remotes)"
|
|---|
| 14 | echo " --disable-joystick-menu disable joystick menu"
|
|---|
| 15 | echo " --disable-firewire disable support for FireWire cable boxes"
|
|---|
| 16 | +echo " --enable-freebox enable support for Freebox"
|
|---|
| 17 | +echo " --livelibdir=DIR location of Live streaming library"
|
|---|
| 18 | +echo " --liveincludedir=DIR location of Live streaming include files"
|
|---|
| 19 | echo " --disable-dbox2 disable support for Nokia DBOX2 DVB boxes (or compatibles)"
|
|---|
| 20 | echo " --disable-hdhomerun disable support for HDHomeRun boxes"
|
|---|
| 21 | echo " --disable-v4l disable Video4Linux support"
|
|---|
| 22 | @@ -810,6 +814,14 @@
|
|---|
| 23 | ;;
|
|---|
| 24 | --disable-dbox2) dbox2_dvb_box="no"
|
|---|
| 25 | ;;
|
|---|
| 26 | + --enable-freebox) freebox_box="yes"
|
|---|
| 27 | + ;;
|
|---|
| 28 | + --disable-freebox) freebox_box="no"
|
|---|
| 29 | + ;;
|
|---|
| 30 | + --livelibdir=*) live_lib_dir=`echo $opt | cut -d '=' -f 2`
|
|---|
| 31 | + ;;
|
|---|
| 32 | + --liveincludedir=*) live_include_dir=`echo $opt | cut -d '=' -f 2`
|
|---|
| 33 | + ;;
|
|---|
| 34 | --enable-hdhomerun) hdhomerun_box="yes"
|
|---|
| 35 | ;;
|
|---|
| 36 | --disable-hdhomerun) hdhomerun_box="no"
|
|---|
| 37 | @@ -2243,6 +2255,7 @@
|
|---|
| 38 | echo "FireWire support $firewire_cable_box"
|
|---|
| 39 | echo "DVB support $dvb [$dvb_path]"
|
|---|
| 40 | echo "DBox2 support $dbox2_dvb_box"
|
|---|
| 41 | + echo "freebox support $freebox_box"
|
|---|
| 42 | echo "HDHomeRun sup. $hdhomerun_box"
|
|---|
| 43 | fi
|
|---|
| 44 |
|
|---|
| 45 | @@ -2885,6 +2898,46 @@
|
|---|
| 46 | CCONFIG="$CCONFIG using_dbox2"
|
|---|
| 47 | fi
|
|---|
| 48 |
|
|---|
| 49 | +if test x"$freebox_box" = x"yes" ; then
|
|---|
| 50 | + if test "x$live_lib_dir" = "x"; then
|
|---|
| 51 | + if has_library libliveMedia; then
|
|---|
| 52 | + CONFIG_LIVE_LIBS="-lliveMedia -lgroupsock -lBasicUsageEnvironment -lUsageEnvironment"
|
|---|
| 53 | + else
|
|---|
| 54 | + echo "Unable to find Live Media library."
|
|---|
| 55 | + exit 1;
|
|---|
| 56 | + fi
|
|---|
| 57 | + else
|
|---|
| 58 | + if test ! -f "$live_lib_dir/liveMedia/libliveMedia.a"; then
|
|---|
| 59 | + echo "Unable to find Live Media library."
|
|---|
| 60 | + exit 1;
|
|---|
| 61 | + fi
|
|---|
| 62 | + 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"
|
|---|
| 63 | + fi
|
|---|
| 64 | + if test "x$live_include_dir" = "x"; then
|
|---|
| 65 | + if has_header liveMedia.hh; then
|
|---|
| 66 | + true
|
|---|
| 67 | + else
|
|---|
| 68 | + echo "Unable to find Live Media headers."
|
|---|
| 69 | + exit 1;
|
|---|
| 70 | + fi
|
|---|
| 71 | + else
|
|---|
| 72 | + if test -f "$live_include_dir/liveMedia/include/liveMedia.hh"; then
|
|---|
| 73 | + LIVE_INCLUDES="$live_include_dir/liveMedia/include $live_include_dir/UsageEnvironment/include $live_include_dir/BasicUsageEnvironment/include $live_include_dir/groupsock/include"
|
|---|
| 74 | + else
|
|---|
| 75 | + if test -f "$live_include_dir/liveMedia/liveMedia.hh"; then
|
|---|
| 76 | + LIVE_INCLUDES="$live_include_dir/liveMedia $live_include_dir/UsageEnvironment $live_include_dir/BasicUsageEnvironment $live_include_dir/groupsock"
|
|---|
| 77 | + else
|
|---|
| 78 | + echo "Unable to find Live Media headers."
|
|---|
| 79 | + exit 1;
|
|---|
| 80 | + fi
|
|---|
| 81 | + fi
|
|---|
| 82 | + fi
|
|---|
| 83 | + CCONFIG="$CCONFIG using_freebox"
|
|---|
| 84 | + CONFIG_DEFINES="$CONFIG_DEFINES USING_FREEBOX"
|
|---|
| 85 | + echo "CONFIG_LIVE_LIBS=$CONFIG_LIVE_LIBS" >> $MYTH_CONFIG_MAK
|
|---|
| 86 | + CONFIG_INCLUDEPATH="$CONFIG_INCLUDEPATH $LIVE_INCLUDES"
|
|---|
| 87 | +fi
|
|---|
| 88 | +
|
|---|
| 89 | if test x"$hdhomerun_box" = x"yes" ; then
|
|---|
| 90 | CCONFIG="$CCONFIG using_hdhr"
|
|---|
| 91 | fi
|
|---|
| 92 | diff -u -r -N mythtv-SVN.orig/libs/libmythtv/cardutil.cpp mythtv-SVN/libs/libmythtv/cardutil.cpp
|
|---|
| 93 | --- mythtv-SVN.orig/libs/libmythtv/cardutil.cpp 2006-04-18 09:07:01.000000000 +0200
|
|---|
| 94 | +++ mythtv-SVN/libs/libmythtv/cardutil.cpp 2006-04-18 09:11:04.000000000 +0200
|
|---|
| 95 | @@ -517,6 +517,7 @@
|
|---|
| 96 |
|
|---|
| 97 | if (("FIREWIRE" == cardtype) ||
|
|---|
| 98 | ("DBOX2" == cardtype) ||
|
|---|
| 99 | + ("FREEBOX" == cardtype) ||
|
|---|
| 100 | ("HDHOMERUN" == cardtype))
|
|---|
| 101 | {
|
|---|
| 102 | ret += "MPEG2TS";
|
|---|
| 103 | @@ -709,6 +710,10 @@
|
|---|
| 104 | .arg(query.value(1).toString())
|
|---|
| 105 | .arg(query.value(2).toString());
|
|---|
| 106 | }
|
|---|
| 107 | + else if (cardtype == "FREEBOX")
|
|---|
| 108 | + {
|
|---|
| 109 | + label = QString("[ FREEBOX : HOST mafreebox.freebox.fr ]");
|
|---|
| 110 | + }
|
|---|
| 111 | else if (cardtype == "HDHOMERUN")
|
|---|
| 112 | {
|
|---|
| 113 | MSqlQuery query(MSqlQuery::InitCon());
|
|---|
| 114 | @@ -745,6 +750,7 @@
|
|---|
| 115 |
|
|---|
| 116 | if (("FIREWIRE" == cardtype) ||
|
|---|
| 117 | ("DBOX2" == cardtype) ||
|
|---|
| 118 | + ("FREEBOX" == cardtype) ||
|
|---|
| 119 | ("HDHOMERUN" == cardtype))
|
|---|
| 120 | {
|
|---|
| 121 | inputs += "MPEG2TS";
|
|---|
| 122 | diff -u -r -N mythtv-SVN.orig/libs/libmythtv/dbcheck.cpp mythtv-SVN/libs/libmythtv/dbcheck.cpp
|
|---|
| 123 | --- mythtv-SVN.orig/libs/libmythtv/dbcheck.cpp 2006-04-18 09:07:00.000000000 +0200
|
|---|
| 124 | +++ mythtv-SVN/libs/libmythtv/dbcheck.cpp 2006-04-18 09:20:03.000000000 +0200
|
|---|
| 125 | @@ -10,7 +10,7 @@
|
|---|
| 126 | #include "mythdbcon.h"
|
|---|
| 127 |
|
|---|
| 128 | /// This is the DB schema version expected by the running MythTV instance.
|
|---|
| 129 | -const QString currentDatabaseVersion = "1137";
|
|---|
| 130 | +const QString currentDatabaseVersion = "1138";
|
|---|
| 131 |
|
|---|
| 132 | static bool UpdateDBVersionNumber(const QString &newnumber);
|
|---|
| 133 | static bool performActualUpdate(const QString updates[], QString version,
|
|---|
| 134 | @@ -2176,7 +2176,7 @@
|
|---|
| 135 | ""
|
|---|
| 136 | };
|
|---|
| 137 |
|
|---|
| 138 | - if (!performActualUpdate(updates, "1135", dbver))
|
|---|
| 139 | + if (!performActualUpdate(updates, "1135", dbver))
|
|---|
| 140 | return false;
|
|---|
| 141 | }
|
|---|
| 142 |
|
|---|
| 143 | @@ -2187,7 +2187,7 @@
|
|---|
| 144 | "",
|
|---|
| 145 | };
|
|---|
| 146 |
|
|---|
| 147 | - if (!performActualUpdate(updates, "1136", dbver))
|
|---|
| 148 | + if (!performActualUpdate(updates, "1136", dbver))
|
|---|
| 149 | return false;
|
|---|
| 150 | }
|
|---|
| 151 |
|
|---|
| 152 | @@ -2198,7 +2198,7 @@
|
|---|
| 153 | "",
|
|---|
| 154 | };
|
|---|
| 155 |
|
|---|
| 156 | - if (!performActualUpdate(updates, "1137", dbver))
|
|---|
| 157 | + if (!performActualUpdate(updates, "1137", dbver))
|
|---|
| 158 | return false;
|
|---|
| 159 | }
|
|---|
| 160 |
|
|---|
| 161 | @@ -2206,6 +2206,18 @@
|
|---|
| 162 | //"ALTER TABLE capturecard DROP COLUMN dvb_hw_decoder;" in 0.21
|
|---|
| 163 | //"ALTER TABLE cardinput DROP COLUMN preference;" in 0.22
|
|---|
| 164 |
|
|---|
| 165 | + if (dbver == "1137")
|
|---|
| 166 | + {
|
|---|
| 167 | + const QString updates[] = {
|
|---|
| 168 | +"INSERT INTO profilegroups (name, cardtype, is_default) "
|
|---|
| 169 | +" VALUES('Freebox Input', 'Freebox', 1);",
|
|---|
| 170 | +""
|
|---|
| 171 | +};
|
|---|
| 172 | +
|
|---|
| 173 | + if (!performActualUpdate(updates, "1138", dbver))
|
|---|
| 174 | + return false;
|
|---|
| 175 | + }
|
|---|
| 176 | +
|
|---|
| 177 | return true;
|
|---|
| 178 | }
|
|---|
| 179 |
|
|---|
| 180 | @@ -2832,6 +2844,7 @@
|
|---|
| 181 | "INSERT INTO profilegroups VALUES (8,"
|
|---|
| 182 | " 'USB Mpeg-4 Encoder (Plextor ConvertX, etc)','GO7007',1,NULL);",
|
|---|
| 183 | "INSERT INTO profilegroups VALUES (9,'DBOX2 Input','DBOX2',1,NULL);",
|
|---|
| 184 | +"INSERT INTO profilegroups VALUES (10,'Freebox Input','Freebox',1,NULL);",
|
|---|
| 185 | "INSERT INTO recordingprofiles VALUES (1,'Default',NULL,NULL,1);",
|
|---|
| 186 | "INSERT INTO recordingprofiles VALUES (2,'Live TV',NULL,NULL,1);",
|
|---|
| 187 | "INSERT INTO recordingprofiles VALUES (3,'High Quality',NULL,NULL,1);",
|
|---|
| 188 | diff -u -r -N mythtv-SVN.orig/libs/libmythtv/freeboxchannel.cpp mythtv-SVN/libs/libmythtv/freeboxchannel.cpp
|
|---|
| 189 | --- mythtv-SVN.orig/libs/libmythtv/freeboxchannel.cpp 1970-01-01 01:00:00.000000000 +0100
|
|---|
| 190 | +++ mythtv-SVN/libs/libmythtv/freeboxchannel.cpp 2006-04-17 19:34:09.000000000 +0200
|
|---|
| 191 | @@ -0,0 +1,327 @@
|
|---|
| 192 | +/**
|
|---|
| 193 | + * FreeboxChannel
|
|---|
| 194 | + * Copyright (c) 2005 by Levent Gündogdu
|
|---|
| 195 | + * Distributed as part of MythTV under GPL v2 and later.
|
|---|
| 196 | + */
|
|---|
| 197 | +
|
|---|
| 198 | +#include <iostream>
|
|---|
| 199 | +#include <qsqldatabase.h>
|
|---|
| 200 | +#include "mythdbcon.h"
|
|---|
| 201 | +#include "mythcontext.h"
|
|---|
| 202 | +#include "freeboxchannel.h"
|
|---|
| 203 | +
|
|---|
| 204 | +FreeboxChannel::FreeboxChannel(TVRec *parent,
|
|---|
| 205 | + int cardid)
|
|---|
| 206 | + : QObject(NULL, "FreeboxChannel"),
|
|---|
| 207 | + ChannelBase(parent),
|
|---|
| 208 | + http(new QHttp()),
|
|---|
| 209 | + m_freeboxchannelcount(0),
|
|---|
| 210 | + m_channelListReady(false),
|
|---|
| 211 | + m_requestChannel(""),
|
|---|
| 212 | + m_lastChannel("1"),
|
|---|
| 213 | + m_cardid(cardid)
|
|---|
| 214 | +{
|
|---|
| 215 | + connect(http, SIGNAL(done(bool)),
|
|---|
| 216 | + this, SLOT (HttpRequestDone(bool)));
|
|---|
| 217 | +
|
|---|
| 218 | + LoadChannels();
|
|---|
| 219 | +}
|
|---|
| 220 | +
|
|---|
| 221 | +
|
|---|
| 222 | +bool FreeboxChannel::SwitchToInput(const QString &inputname,
|
|---|
| 223 | + const QString &chan)
|
|---|
| 224 | +{
|
|---|
| 225 | + int inputNum = GetInputByName(inputname);
|
|---|
| 226 | + if (inputNum < 0)
|
|---|
| 227 | + return false;
|
|---|
| 228 | +
|
|---|
| 229 | + return SetChannelByString(chan);
|
|---|
| 230 | +}
|
|---|
| 231 | +
|
|---|
| 232 | +
|
|---|
| 233 | +bool FreeboxChannel::SetChannelByString(const QString &newChan)
|
|---|
| 234 | +{
|
|---|
| 235 | + // Delay set channel when list has not yet been retrieved
|
|---|
| 236 | + if (!m_channelListReady)
|
|---|
| 237 | + {
|
|---|
| 238 | + VERBOSE(VB_IMPORTANT,QString("Freebox # Channel list not received yet. Will switch to channel %1 later...").arg(newChan));
|
|---|
| 239 | + m_requestChannel = newChan;
|
|---|
| 240 | + return true;
|
|---|
| 241 | + }
|
|---|
| 242 | +
|
|---|
| 243 | + QString chan = newChan;
|
|---|
| 244 | + // If chan is empty, use DefautChannel
|
|---|
| 245 | + if (chan == "")
|
|---|
| 246 | + {
|
|---|
| 247 | + VERBOSE(VB_IMPORTANT,QString("Freebox # Empty channel name has been provided. Getting default name."));
|
|---|
| 248 | + chan = GetDefaultChannel();
|
|---|
| 249 | + }
|
|---|
| 250 | +
|
|---|
| 251 | + // update current chanel
|
|---|
| 252 | + if (m_lastChannel != curchannelname)
|
|---|
| 253 | + m_lastChannel = curchannelname;
|
|---|
| 254 | +
|
|---|
| 255 | + curchannelname = chan;
|
|---|
| 256 | + m_currenturl = GetChannelUrlFromNumber(curchannelname);
|
|---|
| 257 | +
|
|---|
| 258 | + // emit signal to recorder
|
|---|
| 259 | + emit ChannelChanged();
|
|---|
| 260 | +
|
|---|
| 261 | + return true;
|
|---|
| 262 | +}
|
|---|
| 263 | +
|
|---|
| 264 | +
|
|---|
| 265 | +QString FreeboxChannel::GetCurrentChannelUrl()
|
|---|
| 266 | +{
|
|---|
| 267 | + if(m_currenturl == "")
|
|---|
| 268 | + m_currenturl = QString("rtsp://mafreebox.freebox.fr/freeboxtv/201");
|
|---|
| 269 | + return m_currenturl;
|
|---|
| 270 | +}
|
|---|
| 271 | +
|
|---|
| 272 | +
|
|---|
| 273 | +bool FreeboxChannel::IsOpen(void) const
|
|---|
| 274 | +{
|
|---|
| 275 | + return true;
|
|---|
| 276 | +}
|
|---|
| 277 | +
|
|---|
| 278 | +
|
|---|
| 279 | +bool FreeboxChannel::Open(void)
|
|---|
| 280 | +{
|
|---|
| 281 | + if (!InitializeInputs())
|
|---|
| 282 | + return false;
|
|---|
| 283 | +
|
|---|
| 284 | + return true;
|
|---|
| 285 | +}
|
|---|
| 286 | +
|
|---|
| 287 | +
|
|---|
| 288 | +void FreeboxChannel::Close(void)
|
|---|
| 289 | +{
|
|---|
| 290 | +}
|
|---|
| 291 | +
|
|---|
| 292 | +
|
|---|
| 293 | +/*
|
|---|
| 294 | + * Channel loading
|
|---|
| 295 | + */
|
|---|
| 296 | +
|
|---|
| 297 | +void FreeboxChannel::LoadChannels()
|
|---|
| 298 | +{
|
|---|
| 299 | + // Request Channel list via http. Signal will be emmitted when list is ready.
|
|---|
| 300 | + QHttpRequestHeader header("GET", "/freeboxtv/playlist.m3u");
|
|---|
| 301 | + header.setValue("Host", "mafreebox.freebox.fr");
|
|---|
| 302 | + http->setHost("mafreebox.freebox.fr", 80);
|
|---|
| 303 | + http->request(header);
|
|---|
| 304 | +}
|
|---|
| 305 | +
|
|---|
| 306 | +
|
|---|
| 307 | +QString FreeboxChannel::normalize(QString channelName)
|
|---|
| 308 | +{
|
|---|
| 309 | + // Normalize Channel name so we can try to automap channel return by freebox to channel coming from tv_grab_fr
|
|---|
| 310 | + QString res;
|
|---|
| 311 | + for (unsigned int i=0;i<channelName.length();i++)
|
|---|
| 312 | + {
|
|---|
| 313 | + QChar c = channelName[i];
|
|---|
| 314 | + if (c.isSpace()) continue;
|
|---|
| 315 | + c=c.lower();
|
|---|
| 316 | + if (c=='é' || c=='ê' || c=='ê') c='e';
|
|---|
| 317 | + if (c=='à') c='a';
|
|---|
| 318 | + if (c=='i' || c=='î') c=='i';
|
|---|
| 319 | + if (c=='ô') c=='o';
|
|---|
| 320 | +
|
|---|
| 321 | + res += c;
|
|---|
| 322 | + }
|
|---|
| 323 | +
|
|---|
| 324 | + return res;
|
|---|
| 325 | +}
|
|---|
| 326 | +
|
|---|
| 327 | +
|
|---|
| 328 | +/*
|
|---|
| 329 | + * Receive response to channel list request
|
|---|
| 330 | + */
|
|---|
| 331 | +
|
|---|
| 332 | +void FreeboxChannel::HttpRequestDone(bool error)
|
|---|
| 333 | +{
|
|---|
| 334 | + if (error)
|
|---|
| 335 | + {
|
|---|
| 336 | + VERBOSE(VB_IMPORTANT,QString("Freebox # Reading channel list failed!"));
|
|---|
| 337 | + return;
|
|---|
| 338 | + }
|
|---|
| 339 | +
|
|---|
| 340 | + QString buffer=http->readAll();
|
|---|
| 341 | + m_freeboxchannelcount = 0;
|
|---|
| 342 | +
|
|---|
| 343 | + int sepCount = 0;
|
|---|
| 344 | +
|
|---|
| 345 | + QString header = buffer.section("\n", sepCount, sepCount);
|
|---|
| 346 | + sepCount++;
|
|---|
| 347 | +
|
|---|
| 348 | + // Verify header is ok
|
|---|
| 349 | + if (header != "#EXTM3U")
|
|---|
| 350 | + {
|
|---|
| 351 | + VERBOSE(VB_IMPORTANT,QString("Freebox # Invalid header while retrieve channel list.!"));
|
|---|
| 352 | + return;
|
|---|
| 353 | + }
|
|---|
| 354 | +
|
|---|
| 355 | + while (true)
|
|---|
| 356 | + {
|
|---|
| 357 | + QString line1 = buffer.section("\n", sepCount, sepCount);
|
|---|
| 358 | + if (line1 == "")
|
|---|
| 359 | + break;
|
|---|
| 360 | +
|
|---|
| 361 | + sepCount++;
|
|---|
| 362 | +
|
|---|
| 363 | + QString line2 = buffer.section("\n", sepCount, sepCount);
|
|---|
| 364 | + if (line2 == "")
|
|---|
| 365 | + break;
|
|---|
| 366 | +
|
|---|
| 367 | + sepCount++;
|
|---|
| 368 | +
|
|---|
| 369 | + // each line contains ://
|
|---|
| 370 | + // header:extension,channelNum - channelName rtsp://channelUrl
|
|---|
| 371 | + //#EXTINF:0,2 - France 2 rtsp://mafreebox.freebox.fr/freeboxtv/201
|
|---|
| 372 | +
|
|---|
| 373 | + QString lineHead;
|
|---|
| 374 | + QString extension;
|
|---|
| 375 | + QString channelNum;
|
|---|
| 376 | + QString channelName;
|
|---|
| 377 | +
|
|---|
| 378 | + int pos = 0;
|
|---|
| 379 | + int oldPos = 0;
|
|---|
| 380 | +
|
|---|
| 381 | + pos = line1.find(":", oldPos);
|
|---|
| 382 | + if (pos<0)
|
|---|
| 383 | + {
|
|---|
| 384 | + VERBOSE(VB_IMPORTANT,QString("Freebox # Invalid header while retrieve channel list.!"));
|
|---|
| 385 | + return;
|
|---|
| 386 | + }
|
|---|
| 387 | + lineHead = line1.mid(0, pos);
|
|---|
| 388 | +
|
|---|
| 389 | + if (lineHead != "#EXTINF")
|
|---|
| 390 | + {
|
|---|
| 391 | + VERBOSE(VB_IMPORTANT,QString("Freebox # Invalid header while retrieve channel list.!"));
|
|---|
| 392 | + return;
|
|---|
| 393 | + }
|
|---|
| 394 | +
|
|---|
| 395 | + oldPos = pos + 1;
|
|---|
| 396 | + pos = line1.find(",", oldPos);
|
|---|
| 397 | + if (pos<0)
|
|---|
| 398 | + {
|
|---|
| 399 | + VERBOSE(VB_IMPORTANT,QString("Freebox # Invalid header while retrieve channel list.!"));
|
|---|
| 400 | + return;
|
|---|
| 401 | + }
|
|---|
| 402 | + extension = line1.mid(oldPos, pos - oldPos);
|
|---|
| 403 | +
|
|---|
| 404 | + oldPos = pos + 1;
|
|---|
| 405 | + pos = line1.find(" ", oldPos);
|
|---|
| 406 | + if (pos<0)
|
|---|
| 407 | + {
|
|---|
| 408 | + VERBOSE(VB_IMPORTANT,QString("Freebox # Invalid header while retrieve channel list.!"));
|
|---|
| 409 | + return;
|
|---|
| 410 | + }
|
|---|
| 411 | + channelNum = line1.mid(oldPos, pos - oldPos);
|
|---|
| 412 | +
|
|---|
| 413 | + oldPos = pos + 1;
|
|---|
| 414 | + pos = line1.find("- ", oldPos);
|
|---|
| 415 | + if (pos<0)
|
|---|
| 416 | + {
|
|---|
| 417 | + VERBOSE(VB_IMPORTANT,QString("Freebox # Invalid header while retrieve channel list.!"));
|
|---|
| 418 | + return;
|
|---|
| 419 | + }
|
|---|
| 420 | + channelName = line1.mid(pos + 2, line1.length());
|
|---|
| 421 | +
|
|---|
| 422 | + QString channelUrl = line2;
|
|---|
| 423 | +
|
|---|
| 424 | + // save all this information in map for quick access
|
|---|
| 425 | + bool ok;
|
|---|
| 426 | + int channelNumI = channelNum.toInt( &ok, 10 );
|
|---|
| 427 | +
|
|---|
| 428 | + QString channelNameN = normalize(channelName);
|
|---|
| 429 | +
|
|---|
| 430 | + m_freeboxchannelIds[channelNumI] = m_freeboxchannelcount;
|
|---|
| 431 | + m_freeboxchannelUrl[m_freeboxchannelcount] = channelUrl;
|
|---|
| 432 | + m_freeboxchannelNames[m_freeboxchannelcount] = channelName;
|
|---|
| 433 | + m_freeboxchannelNamesN[m_freeboxchannelcount] = channelNameN;
|
|---|
| 434 | +
|
|---|
| 435 | + m_freeboxchannelcount++;
|
|---|
| 436 | + }
|
|---|
| 437 | +
|
|---|
| 438 | + // Channel list is ready.
|
|---|
| 439 | + m_channelListReady = true;
|
|---|
| 440 | +
|
|---|
| 441 | + // Change channel if delayed request is available
|
|---|
| 442 | + if (m_requestChannel != "")
|
|---|
| 443 | + {
|
|---|
| 444 | + SetChannelByString(m_requestChannel);
|
|---|
| 445 | + m_requestChannel = "";
|
|---|
| 446 | + }
|
|---|
| 447 | +}
|
|---|
| 448 | +
|
|---|
| 449 | +
|
|---|
| 450 | +/*
|
|---|
| 451 | + * Map a channel number to the corresponding rtsp URL
|
|---|
| 452 | + */
|
|---|
| 453 | +
|
|---|
| 454 | +QString FreeboxChannel::GetChannelUrlFromNumber(const QString& channelnumber)
|
|---|
| 455 | +{
|
|---|
| 456 | + MSqlQuery query(MSqlQuery::InitCon());
|
|---|
| 457 | +
|
|---|
| 458 | + query.prepare("SELECT name,freqid "
|
|---|
| 459 | + "FROM channel,cardinput "
|
|---|
| 460 | + "WHERE "
|
|---|
| 461 | + "channel.sourceid = cardinput.sourceid AND "
|
|---|
| 462 | + "cardinput.cardid = :CARDID AND "
|
|---|
| 463 | + "channel.channum = :CHANNUM");
|
|---|
| 464 | +
|
|---|
| 465 | + query.bindValue(":CARDID", m_cardid);
|
|---|
| 466 | + query.bindValue(":CHANNUM", channelnumber);
|
|---|
| 467 | +
|
|---|
| 468 | + if (query.exec() && query.isActive() && query.size() > 0)
|
|---|
| 469 | + {
|
|---|
| 470 | + query.next();
|
|---|
| 471 | + QString chanName = query.value(0).toString();
|
|---|
| 472 | +
|
|---|
| 473 | + // if we have a FreqID in the table, use this as the real freebox channel number
|
|---|
| 474 | + int mFreqId = query.value(1).toInt();
|
|---|
| 475 | + if (mFreqId!=0)
|
|---|
| 476 | + {
|
|---|
| 477 | + int channelI = m_freeboxchannelIds[mFreqId];
|
|---|
| 478 | + return m_freeboxchannelUrl[channelI];
|
|---|
| 479 | + }
|
|---|
| 480 | +
|
|---|
| 481 | + // if no freqID, try to map the chanName to an existing channel name
|
|---|
| 482 | + for (int i=0;i<m_freeboxchannelcount;i++)
|
|---|
| 483 | + {
|
|---|
| 484 | + if (m_freeboxchannelNamesN[i] == chanName)
|
|---|
| 485 | + {
|
|---|
| 486 | + return m_freeboxchannelUrl[i];
|
|---|
| 487 | + }
|
|---|
| 488 | + }
|
|---|
| 489 | +
|
|---|
| 490 | + return "";
|
|---|
| 491 | + }
|
|---|
| 492 | + return "";
|
|---|
| 493 | +}
|
|---|
| 494 | +
|
|---|
| 495 | +
|
|---|
| 496 | +/*
|
|---|
| 497 | + * Search for default channel
|
|---|
| 498 | + */
|
|---|
| 499 | +
|
|---|
| 500 | +QString FreeboxChannel::GetDefaultChannel()
|
|---|
| 501 | +{
|
|---|
| 502 | + MSqlQuery query(MSqlQuery::InitCon());
|
|---|
| 503 | + query.prepare("SELECT channum "
|
|---|
| 504 | + "FROM channel,cardinput "
|
|---|
| 505 | + "WHERE "
|
|---|
| 506 | + "channel.sourceid = cardinput.sourceid AND "
|
|---|
| 507 | + "cardinput.cardid = :CARDID "
|
|---|
| 508 | + "ORDER BY channum limit 1");
|
|---|
| 509 | +
|
|---|
| 510 | + query.bindValue(":CARDID", m_cardid);
|
|---|
| 511 | +
|
|---|
| 512 | + if (query.exec() && query.isActive() && query.size() > 0)
|
|---|
| 513 | + {
|
|---|
| 514 | + query.next();
|
|---|
| 515 | + return query.value(0).toString();
|
|---|
| 516 | + }
|
|---|
| 517 | + return "";
|
|---|
| 518 | +}
|
|---|
| 519 | diff -u -r -N mythtv-SVN.orig/libs/libmythtv/freeboxchannel.h mythtv-SVN/libs/libmythtv/freeboxchannel.h
|
|---|
| 520 | --- mythtv-SVN.orig/libs/libmythtv/freeboxchannel.h 1970-01-01 01:00:00.000000000 +0100
|
|---|
| 521 | +++ mythtv-SVN/libs/libmythtv/freeboxchannel.h 2006-04-16 19:04:23.000000000 +0200
|
|---|
| 522 | @@ -0,0 +1,85 @@
|
|---|
| 523 | +#ifndef FREEBOXCHANNEL_H
|
|---|
| 524 | +#define FREEBOXCHANNEL_H
|
|---|
| 525 | +
|
|---|
| 526 | +#include <qstring.h>
|
|---|
| 527 | +#include <qmap.h>
|
|---|
| 528 | +#include <qhttp.h>
|
|---|
| 529 | +#include <qobject.h>
|
|---|
| 530 | +#include <qthread.h>
|
|---|
| 531 | +
|
|---|
| 532 | +#ifdef HAVE_STDINT_H
|
|---|
| 533 | +#include <stdint.h>
|
|---|
| 534 | +#endif
|
|---|
| 535 | +
|
|---|
| 536 | +#include "tv_rec.h"
|
|---|
| 537 | +#include "channelbase.h"
|
|---|
| 538 | +#include "sitypes.h"
|
|---|
| 539 | +
|
|---|
| 540 | +
|
|---|
| 541 | +class FreeboxChannel:public QObject, public ChannelBase
|
|---|
| 542 | +{
|
|---|
| 543 | + Q_OBJECT public:
|
|---|
| 544 | + FreeboxChannel (TVRec * parent, int cardid);
|
|---|
| 545 | + ~FreeboxChannel (void)
|
|---|
| 546 | + {
|
|---|
| 547 | + }
|
|---|
| 548 | +
|
|---|
| 549 | +
|
|---|
| 550 | + bool Open ();
|
|---|
| 551 | + void Close ();
|
|---|
| 552 | + bool SwitchToInput (const QString & inputname, const QString & chan);
|
|---|
| 553 | + bool SetChannelByString (const QString & chan);
|
|---|
| 554 | + bool IsOpen (void) const;
|
|---|
| 555 | +
|
|---|
| 556 | +
|
|---|
| 557 | + QString GetCurrentChannelUrl ();
|
|---|
| 558 | +
|
|---|
| 559 | +
|
|---|
| 560 | + bool SwitchToInput (int newcapchannel, bool setstarting)
|
|---|
| 561 | + {
|
|---|
| 562 | + (void) newcapchannel;
|
|---|
| 563 | + (void) setstarting;
|
|---|
| 564 | + return false;
|
|---|
| 565 | + }
|
|---|
| 566 | +
|
|---|
| 567 | + QString GetChannelUrlFromNumber (const QString & channelnumber);
|
|---|
| 568 | + QString GetDefaultChannel ();
|
|---|
| 569 | +
|
|---|
| 570 | + signals:
|
|---|
| 571 | + void ChannelChanged ();
|
|---|
| 572 | +
|
|---|
| 573 | + public slots:void HttpRequestDone (bool error);
|
|---|
| 574 | +
|
|---|
| 575 | + private:
|
|---|
| 576 | + void LoadChannels ();
|
|---|
| 577 | + QString normalize (QString channelName);
|
|---|
| 578 | +
|
|---|
| 579 | + void Log (QString string);
|
|---|
| 580 | +
|
|---|
| 581 | + QHttp *http;
|
|---|
| 582 | +
|
|---|
| 583 | + bool m_channelListReady;
|
|---|
| 584 | + QString m_requestChannel;
|
|---|
| 585 | + QString m_lastChannel;
|
|---|
| 586 | + int m_cardid;
|
|---|
| 587 | +
|
|---|
| 588 | + // the rtsp url for the current channel
|
|---|
| 589 | + QString m_currenturl;
|
|---|
| 590 | +
|
|---|
| 591 | + // number of channel support by freebox
|
|---|
| 592 | + int m_freeboxchannelcount;
|
|---|
| 593 | +
|
|---|
| 594 | + // map channelNum to channel index in table
|
|---|
| 595 | + QMap < int, int >m_freeboxchannelIds;
|
|---|
| 596 | +
|
|---|
| 597 | + // map channel index to channel url
|
|---|
| 598 | + QMap < int, QString > m_freeboxchannelUrl;
|
|---|
| 599 | +
|
|---|
| 600 | + // map channel index to channel name
|
|---|
| 601 | + QMap < int, QString > m_freeboxchannelNames;
|
|---|
| 602 | +
|
|---|
| 603 | + // map channel index to channel normalize name
|
|---|
| 604 | + QMap < int, QString > m_freeboxchannelNamesN;
|
|---|
| 605 | +};
|
|---|
| 606 | +
|
|---|
| 607 | +#endif
|
|---|
| 608 | diff -u -r -N mythtv-SVN.orig/libs/libmythtv/freeboxrecorder.cpp mythtv-SVN/libs/libmythtv/freeboxrecorder.cpp
|
|---|
| 609 | --- mythtv-SVN.orig/libs/libmythtv/freeboxrecorder.cpp 1970-01-01 01:00:00.000000000 +0100
|
|---|
| 610 | +++ mythtv-SVN/libs/libmythtv/freeboxrecorder.cpp 2006-04-16 19:04:23.000000000 +0200
|
|---|
| 611 | @@ -0,0 +1,448 @@
|
|---|
| 612 | +/**
|
|---|
| 613 | + * FreeboxRecorder
|
|---|
| 614 | + * Copyright (c) 2005 by Levent G?u (mythtv@feature-it.com)
|
|---|
| 615 | + * Distributed as part of MythTV under GPL v2 and later.
|
|---|
| 616 | + */
|
|---|
| 617 | +
|
|---|
| 618 | +#include <iostream>
|
|---|
| 619 | +using namespace std;
|
|---|
| 620 | +
|
|---|
| 621 | +#include <pthread.h>
|
|---|
| 622 | +#include "RingBuffer.h"
|
|---|
| 623 | +#include "mythcontext.h"
|
|---|
| 624 | +#include "freeboxrecorder.h"
|
|---|
| 625 | +#include "freeboxchannel.h"
|
|---|
| 626 | +#include <qhttp.h>
|
|---|
| 627 | +#include <qobject.h>
|
|---|
| 628 | +#include <sys/select.h>
|
|---|
| 629 | +#include <sys/types.h>
|
|---|
| 630 | +#include <sys/socket.h>
|
|---|
| 631 | +#include <netdb.h>
|
|---|
| 632 | +#include <fcntl.h>
|
|---|
| 633 | +#include <unistd.h>
|
|---|
| 634 | +#include <netinet/in.h> // For sockaddr_in on OS X
|
|---|
| 635 | +
|
|---|
| 636 | +void subsessionAfterPlaying(void *clientData);
|
|---|
| 637 | +void subsessionByeHandler(void *clientData);
|
|---|
| 638 | +
|
|---|
| 639 | +FreeboxRecorder::FreeboxRecorder(TVRec *rec, FreeboxChannel *channel)
|
|---|
| 640 | + : DTVRecorder(rec, "FreeboxRecorder"),
|
|---|
| 641 | + m_channel(channel)
|
|---|
| 642 | +{
|
|---|
| 643 | + // the var will be use to abort current rtsp session
|
|---|
| 644 | + _abort_rtsp = new char();
|
|---|
| 645 | +
|
|---|
| 646 | + connect (m_channel, SIGNAL(ChannelChanged()),
|
|---|
| 647 | + this, SLOT( ChannelChanged()));
|
|---|
| 648 | +}
|
|---|
| 649 | +
|
|---|
| 650 | +
|
|---|
| 651 | +bool FreeboxRecorder::Open()
|
|---|
| 652 | +{
|
|---|
| 653 | + // Start a new RTSP flow with current channel
|
|---|
| 654 | + pthread_create(&start_thread, NULL, FreeboxRecorder::StartRtspS, this);
|
|---|
| 655 | + return true;
|
|---|
| 656 | +}
|
|---|
| 657 | +
|
|---|
| 658 | +
|
|---|
| 659 | +void FreeboxRecorder::Close()
|
|---|
| 660 | +{
|
|---|
| 661 | + // ask for RTSP shutdown setting abort_rstp=1, and wait effective shutdown on mutex
|
|---|
| 662 | + waitShutdown = new QWaitCondition();
|
|---|
| 663 | + *_abort_rtsp = 1;
|
|---|
| 664 | + _request_recording = false;
|
|---|
| 665 | + waitShutdown->wait();
|
|---|
| 666 | +
|
|---|
| 667 | + if (session == NULL) return;
|
|---|
| 668 | +
|
|---|
| 669 | + // Ensure RTSP cleanup, remove old RTSP session
|
|---|
| 670 | + MediaSubsessionIterator iter(*session);
|
|---|
| 671 | + MediaSubsession* subsession;
|
|---|
| 672 | + while ((subsession = iter.next()) != NULL)
|
|---|
| 673 | + {
|
|---|
| 674 | + Medium::close(subsession->sink);
|
|---|
| 675 | + subsession->sink = NULL;
|
|---|
| 676 | + }
|
|---|
| 677 | +
|
|---|
| 678 | + if (session == NULL) return;
|
|---|
| 679 | +
|
|---|
| 680 | + rtspClient->teardownMediaSession(*session);
|
|---|
| 681 | +
|
|---|
| 682 | + // Close all RTSP descriptor
|
|---|
| 683 | + Medium::close(session);
|
|---|
| 684 | + Medium::close(rtspClient);
|
|---|
| 685 | +}
|
|---|
| 686 | +
|
|---|
| 687 | +
|
|---|
| 688 | +void FreeboxRecorder::ChannelChanged()
|
|---|
| 689 | +{
|
|---|
| 690 | + // Channel change, we need to close current RTSP flow, and open a new one
|
|---|
| 691 | + Close();
|
|---|
| 692 | + Open();
|
|---|
| 693 | +}
|
|---|
| 694 | +
|
|---|
| 695 | +
|
|---|
| 696 | +void FreeboxRecorder::SetOptionsFromProfile(RecordingProfile *profile,
|
|---|
| 697 | + const QString &videodev,
|
|---|
| 698 | + const QString &audiodev,
|
|---|
| 699 | + const QString &vbidev)
|
|---|
| 700 | +{
|
|---|
| 701 | + (void)videodev;
|
|---|
| 702 | + (void)audiodev;
|
|---|
| 703 | + (void)vbidev;
|
|---|
| 704 | + (void)profile;
|
|---|
| 705 | +}
|
|---|
| 706 | +
|
|---|
| 707 | +
|
|---|
| 708 | +void FreeboxRecorder::StartRecording()
|
|---|
| 709 | +{
|
|---|
| 710 | + // Open RTSP flow for current channel
|
|---|
| 711 | + Open();
|
|---|
| 712 | +
|
|---|
| 713 | + _request_recording = true;
|
|---|
| 714 | + _recording = true;
|
|---|
| 715 | + _request_abort = false;
|
|---|
| 716 | +
|
|---|
| 717 | + // wait until recorder abot
|
|---|
| 718 | + while(_request_recording)
|
|---|
| 719 | + {
|
|---|
| 720 | + if (_request_abort)
|
|---|
| 721 | + break;
|
|---|
| 722 | +
|
|---|
| 723 | + usleep(1000);
|
|---|
| 724 | + }
|
|---|
| 725 | +}
|
|---|
| 726 | +
|
|---|
| 727 | +
|
|---|
| 728 | +void FreeboxRecorder::StopRecording(void)
|
|---|
| 729 | +{
|
|---|
| 730 | + // Close the current RTSP flow
|
|---|
| 731 | + Close();
|
|---|
| 732 | +}
|
|---|
| 733 | +
|
|---|
| 734 | +
|
|---|
| 735 | +void *FreeboxRecorder::StartRtspS(void *param)
|
|---|
| 736 | +{
|
|---|
| 737 | + FreeboxRecorder *recorder = (FreeboxRecorder*)param;
|
|---|
| 738 | + recorder->StartRtsp();
|
|---|
| 739 | + return NULL;
|
|---|
| 740 | +}
|
|---|
| 741 | +
|
|---|
| 742 | +
|
|---|
| 743 | +/*
|
|---|
| 744 | + * Start a new RTSP session for the current channel
|
|---|
| 745 | + */
|
|---|
| 746 | +
|
|---|
| 747 | +void FreeboxRecorder::StartRtsp()
|
|---|
| 748 | +{
|
|---|
| 749 | + // Retrieve the RTSP channel URL
|
|---|
| 750 | + QString url = m_channel->GetCurrentChannelUrl();
|
|---|
| 751 | +
|
|---|
| 752 | + VERBOSE(VB_IMPORTANT, QString("Freebox # URL: %1").arg(url));
|
|---|
| 753 | + //
|
|---|
| 754 | + // Begin by setting up our usage environment:
|
|---|
| 755 | + TaskScheduler* scheduler = BasicTaskScheduler::createNew();
|
|---|
| 756 | + env = BasicUsageEnvironment::createNew(*scheduler);
|
|---|
| 757 | +
|
|---|
| 758 | + // Create our client object:
|
|---|
| 759 | + rtspClient = RTSPClient::createNew(*env, 0, "myRTSP", 0);
|
|---|
| 760 | + if (rtspClient == NULL)
|
|---|
| 761 | + {
|
|---|
| 762 | + VERBOSE(VB_IMPORTANT, QString("Freebox # Failed to create RTSP client: %1").arg(env->getResultMsg()));
|
|---|
| 763 | + shutdown();
|
|---|
| 764 | + }
|
|---|
| 765 | +
|
|---|
| 766 | + // Setup URL for the current session
|
|---|
| 767 | + char* sdpDescription = rtspClient->describeURL(url);
|
|---|
| 768 | + rtspClient->describeStatus();
|
|---|
| 769 | +
|
|---|
| 770 | + if (sdpDescription == NULL)
|
|---|
| 771 | + {
|
|---|
| 772 | + VERBOSE(VB_IMPORTANT, QString("Freebox # Failed to get a SDP description from URL: %1 %2").arg(url).arg(env->getResultMsg()));
|
|---|
| 773 | + shutdown();
|
|---|
| 774 | + }
|
|---|
| 775 | +
|
|---|
| 776 | + // Create a media session object from this SDP description:
|
|---|
| 777 | + session = MediaSession::createNew(*env, sdpDescription);
|
|---|
| 778 | + delete[] sdpDescription;
|
|---|
| 779 | + if (session == NULL)
|
|---|
| 780 | + {
|
|---|
| 781 | + VERBOSE(VB_IMPORTANT, QString("Freebox # Failed to create a MediaSession object from the SDP description: %1").arg(env->getResultMsg()));
|
|---|
| 782 | + shutdown();
|
|---|
| 783 | + }
|
|---|
| 784 | + else if (!session->hasSubsessions())
|
|---|
| 785 | + {
|
|---|
| 786 | + VERBOSE(VB_IMPORTANT, QString("Freebox # This session has no media subsessions"));
|
|---|
| 787 | + shutdown();
|
|---|
| 788 | + }
|
|---|
| 789 | +
|
|---|
| 790 | + // Then, setup the "RTPSource"s for the session:
|
|---|
| 791 | + MediaSubsessionIterator iter(*session);
|
|---|
| 792 | + MediaSubsession *subsession;
|
|---|
| 793 | + Boolean madeProgress = False;
|
|---|
| 794 | + while ((subsession = iter.next()) != NULL)
|
|---|
| 795 | + {
|
|---|
| 796 | + if (!subsession->initiate(-1))
|
|---|
| 797 | + {
|
|---|
| 798 | + VERBOSE(VB_IMPORTANT, QString("Freebox # Unable to create receiver for: %1 / %2 subsession: %3").arg(subsession->mediumName()).arg(subsession->codecName()).arg(env->getResultMsg()));
|
|---|
| 799 | + }
|
|---|
| 800 | + else
|
|---|
| 801 | + {
|
|---|
| 802 | + madeProgress = True;
|
|---|
| 803 | +
|
|---|
| 804 | + if (subsession->rtpSource() != NULL)
|
|---|
| 805 | + {
|
|---|
| 806 | + // 1 second
|
|---|
| 807 | + unsigned const thresh = 1000000;
|
|---|
| 808 | + subsession->rtpSource()->setPacketReorderingThresholdTime(thresh);
|
|---|
| 809 | + }
|
|---|
| 810 | + }
|
|---|
| 811 | + }
|
|---|
| 812 | +
|
|---|
| 813 | + if (!madeProgress) shutdown();
|
|---|
| 814 | +
|
|---|
| 815 | + // Perform additional 'setup' on each subsession, before playing them:
|
|---|
| 816 | + madeProgress = false;
|
|---|
| 817 | + iter.reset();
|
|---|
| 818 | + while ((subsession = iter.next()) != NULL)
|
|---|
| 819 | + {
|
|---|
| 820 | + // port # was not set
|
|---|
| 821 | + if (subsession->clientPortNum() == 0) continue;
|
|---|
| 822 | +
|
|---|
| 823 | + if (rtspClient->setupMediaSubsession(*subsession, False, false))
|
|---|
| 824 | + {
|
|---|
| 825 | + madeProgress = True;
|
|---|
| 826 | + }
|
|---|
| 827 | + else
|
|---|
| 828 | + {
|
|---|
| 829 | + VERBOSE(VB_IMPORTANT, QString("Freebox # Failed to setup: %1 %2 : %3").arg(subsession->mediumName()).arg(subsession->codecName()).arg(env->getResultMsg()));
|
|---|
| 830 | + }
|
|---|
| 831 | + }
|
|---|
| 832 | +
|
|---|
| 833 | + if (!madeProgress) shutdown();
|
|---|
| 834 | +
|
|---|
| 835 | + // Create and start "FileSink"s for each subsession:
|
|---|
| 836 | + // FileSink while receive Mpeg2 TS Data & will feed them to mythtv
|
|---|
| 837 | + madeProgress = False;
|
|---|
| 838 | + iter.reset();
|
|---|
| 839 | + while ((subsession = iter.next()) != NULL)
|
|---|
| 840 | + {
|
|---|
| 841 | + // was not initiated
|
|---|
| 842 | + if (subsession->readSource() == NULL) continue;
|
|---|
| 843 | +
|
|---|
| 844 | + FreeboxSink* FreeboxSink = FreeboxSink::createNew(*env, this);
|
|---|
| 845 | +
|
|---|
| 846 | + subsession->sink = FreeboxSink;
|
|---|
| 847 | + if (subsession->sink == NULL)
|
|---|
| 848 | + {
|
|---|
| 849 | + VERBOSE(VB_IMPORTANT, QString("Freebox # Failed to create sink: %1").arg(env->getResultMsg()));
|
|---|
| 850 | + }
|
|---|
| 851 | +
|
|---|
| 852 | + subsession->sink->startPlaying(*(subsession->readSource()), subsessionAfterPlaying, new FreeboxData(this, subsession));
|
|---|
| 853 | +
|
|---|
| 854 | + if (subsession->rtcpInstance() != NULL)
|
|---|
| 855 | + {
|
|---|
| 856 | + subsession->rtcpInstance()->setByeHandler(subsessionByeHandler, new FreeboxData(this, subsession));
|
|---|
| 857 | + }
|
|---|
| 858 | +
|
|---|
| 859 | + madeProgress = True;
|
|---|
| 860 | + }
|
|---|
| 861 | +
|
|---|
| 862 | + if (!madeProgress) shutdown();
|
|---|
| 863 | +
|
|---|
| 864 | + // Setup player
|
|---|
| 865 | + if (!(rtspClient->playMediaSession(*session)))
|
|---|
| 866 | + {
|
|---|
| 867 | + VERBOSE(VB_IMPORTANT, QString("Freebox # Failed to start playing session: %1").arg(env->getResultMsg()));
|
|---|
| 868 | + shutdown();
|
|---|
| 869 | + }
|
|---|
| 870 | +
|
|---|
| 871 | + request_pause = false;
|
|---|
| 872 | + paused = false;
|
|---|
| 873 | + _request_recording = true;
|
|---|
| 874 | + _recording = true;
|
|---|
| 875 | + *_abort_rtsp=0;
|
|---|
| 876 | +
|
|---|
| 877 | + // Go into main RTSP loop, feeding data to mythtv
|
|---|
| 878 | + // does not return
|
|---|
| 879 | + env->taskScheduler().doEventLoop(_abort_rtsp);
|
|---|
| 880 | +
|
|---|
| 881 | + // Event loop exists, the recording finish
|
|---|
| 882 | + FinishRecording();
|
|---|
| 883 | + _recording = false;
|
|---|
| 884 | +
|
|---|
| 885 | + // wakeUp everibody
|
|---|
| 886 | + waitShutdown->wakeAll();
|
|---|
| 887 | +}
|
|---|
| 888 | +
|
|---|
| 889 | +
|
|---|
| 890 | +/*
|
|---|
| 891 | + * Find a TS Header in flow
|
|---|
| 892 | + */
|
|---|
| 893 | +int FreeboxRecorder::findTSHeader(unsigned char *data, unsigned dataSize)
|
|---|
| 894 | +{
|
|---|
| 895 | + unsigned int pos = 0;
|
|---|
| 896 | +
|
|---|
| 897 | + while (pos < dataSize)
|
|---|
| 898 | + {
|
|---|
| 899 | + if (data[pos] == 0x47)
|
|---|
| 900 | + return pos;
|
|---|
| 901 | + pos++;
|
|---|
| 902 | + }
|
|---|
| 903 | + return -1;
|
|---|
| 904 | +}
|
|---|
| 905 | +
|
|---|
| 906 | +
|
|---|
| 907 | +/*
|
|---|
| 908 | + * Feed date from RTSP flow to mythtv
|
|---|
| 909 | + */
|
|---|
| 910 | +void FreeboxRecorder::addData(unsigned char* data, unsigned dataSize, struct timeval )
|
|---|
| 911 | +{
|
|---|
| 912 | + unsigned int readIndex = 0;
|
|---|
| 913 | +
|
|---|
| 914 | + // data may be compose from more than one packet, loop to consume all data
|
|---|
| 915 | + while (readIndex < dataSize)
|
|---|
| 916 | + {
|
|---|
| 917 | + // If recorder is pause, stop there
|
|---|
| 918 | + if (PauseAndWait())
|
|---|
| 919 | + {
|
|---|
| 920 | + return;
|
|---|
| 921 | + }
|
|---|
| 922 | +
|
|---|
| 923 | + // Find the next TS Header in data
|
|---|
| 924 | + int tsPos = findTSHeader(data + readIndex, dataSize);
|
|---|
| 925 | +
|
|---|
| 926 | + // if no TS, something bad happens
|
|---|
| 927 | + if (tsPos == -1)
|
|---|
| 928 | + {
|
|---|
| 929 | + VERBOSE(VB_IMPORTANT, QString("FREEBOX: No TS header."));
|
|---|
| 930 | + break;
|
|---|
| 931 | + }
|
|---|
| 932 | +
|
|---|
| 933 | + // if TS Header not at start of data, we receive out of sync data
|
|---|
| 934 | + if (tsPos > 0)
|
|---|
| 935 | + {
|
|---|
| 936 | + VERBOSE(VB_IMPORTANT, QString("FREEBOX: TS header at %1, not in sync.").arg(tsPos));
|
|---|
| 937 | + }
|
|---|
| 938 | +
|
|---|
| 939 | + // Check if the next packet in buffer is complete : packet size is 188 bytes long
|
|---|
| 940 | + if ((dataSize - tsPos) < 188)
|
|---|
| 941 | + {
|
|---|
| 942 | + VERBOSE(VB_IMPORTANT, QString("FREEBOX: TS header at %1 but packet not yet complete.").arg(tsPos));
|
|---|
| 943 | + break;
|
|---|
| 944 | + }
|
|---|
| 945 | +
|
|---|
| 946 | + // Cast current found TS Packet to TSPacket structure
|
|---|
| 947 | + const void *newData = data + tsPos + readIndex;
|
|---|
| 948 | + const TSPacket *tspacket = reinterpret_cast<const TSPacket*>(newData);
|
|---|
| 949 | +
|
|---|
| 950 | + // Feed current packet to myth
|
|---|
| 951 | + _buffer_packets = !FindKeyframes(tspacket);
|
|---|
| 952 | + BufferedWrite(*tspacket);
|
|---|
| 953 | +
|
|---|
| 954 | + // follow to next packet
|
|---|
| 955 | + readIndex += tsPos + TSPacket::SIZE;
|
|---|
| 956 | +
|
|---|
| 957 | + }
|
|---|
| 958 | +}
|
|---|
| 959 | +
|
|---|
| 960 | +
|
|---|
| 961 | +void FreeboxRecorder::shutdown(int )
|
|---|
| 962 | +{
|
|---|
| 963 | +}
|
|---|
| 964 | +
|
|---|
| 965 | +
|
|---|
| 966 | +void subsessionAfterPlaying(void *clientData)
|
|---|
| 967 | +{
|
|---|
| 968 | + FreeboxData *myData = (FreeboxData*)clientData;
|
|---|
| 969 | + myData->freeboxRecorder->SubsessionAfterPlaying(myData->mediaSubSession);
|
|---|
| 970 | +}
|
|---|
| 971 | +
|
|---|
| 972 | +
|
|---|
| 973 | +void subsessionByeHandler(void *clientData)
|
|---|
| 974 | +{
|
|---|
| 975 | + FreeboxData *myData = (FreeboxData*)clientData;
|
|---|
| 976 | + myData->freeboxRecorder->SubsessionByeHandler(myData->mediaSubSession);
|
|---|
| 977 | +}
|
|---|
| 978 | +
|
|---|
| 979 | +
|
|---|
| 980 | +void FreeboxRecorder::SubsessionAfterPlaying(MediaSubsession* subsession)
|
|---|
| 981 | +{
|
|---|
| 982 | + Medium::close(subsession->sink);
|
|---|
| 983 | + subsession->sink = NULL;
|
|---|
| 984 | +
|
|---|
| 985 | + MediaSession& session = subsession->parentSession();
|
|---|
| 986 | + MediaSubsessionIterator iter(session);
|
|---|
| 987 | + while ((subsession = iter.next()) != NULL)
|
|---|
| 988 | + {
|
|---|
| 989 | + if (subsession->sink != NULL) return;
|
|---|
| 990 | + }
|
|---|
| 991 | +
|
|---|
| 992 | + shutdown(0);
|
|---|
| 993 | +
|
|---|
| 994 | +}
|
|---|
| 995 | +
|
|---|
| 996 | +
|
|---|
| 997 | +void FreeboxRecorder::SubsessionByeHandler(MediaSubsession* subsession)
|
|---|
| 998 | +{
|
|---|
| 999 | + subsessionAfterPlaying(subsession);
|
|---|
| 1000 | +}
|
|---|
| 1001 | +
|
|---|
| 1002 | +/*
|
|---|
| 1003 | + * Helper class use to receive RTSP data from socket.
|
|---|
| 1004 | + */
|
|---|
| 1005 | +
|
|---|
| 1006 | +FreeboxSink::FreeboxSink(UsageEnvironment& pEnv, FreeboxRecorder *pRecorder) : MediaSink(pEnv)
|
|---|
| 1007 | +{
|
|---|
| 1008 | + recorder = pRecorder;
|
|---|
| 1009 | + env = &pEnv;
|
|---|
| 1010 | +
|
|---|
| 1011 | + // Setup the data buffer
|
|---|
| 1012 | + fBufferSize = 20000;
|
|---|
| 1013 | + fBuffer = new unsigned char[fBufferSize];
|
|---|
| 1014 | +}
|
|---|
| 1015 | +
|
|---|
| 1016 | +
|
|---|
| 1017 | +FreeboxSink::~FreeboxSink()
|
|---|
| 1018 | +{
|
|---|
| 1019 | + // free the data buffer
|
|---|
| 1020 | + delete[] fBuffer;
|
|---|
| 1021 | +}
|
|---|
| 1022 | +
|
|---|
| 1023 | +
|
|---|
| 1024 | +FreeboxSink* FreeboxSink::createNew(UsageEnvironment& env, FreeboxRecorder *pRecorder)
|
|---|
| 1025 | +{
|
|---|
| 1026 | + FreeboxSink* newSink = new FreeboxSink(env, pRecorder);
|
|---|
| 1027 | + return newSink;
|
|---|
| 1028 | +}
|
|---|
| 1029 | +
|
|---|
| 1030 | +
|
|---|
| 1031 | +Boolean FreeboxSink::continuePlaying()
|
|---|
| 1032 | +{
|
|---|
| 1033 | + if (fSource == NULL) return False;
|
|---|
| 1034 | +
|
|---|
| 1035 | + fSource->getNextFrame(fBuffer, fBufferSize, afterGettingFrame, this, onSourceClosure, this);
|
|---|
| 1036 | +
|
|---|
| 1037 | + return True;
|
|---|
| 1038 | +}
|
|---|
| 1039 | +
|
|---|
| 1040 | +
|
|---|
| 1041 | +void FreeboxSink::afterGettingFrame(void* clientData, unsigned frameSize, unsigned /*numTruncatedBytes*/,struct timeval presentationTime, unsigned /*durationInMicroseconds*/)
|
|---|
| 1042 | +{
|
|---|
| 1043 | +
|
|---|
| 1044 | + FreeboxSink* sink = (FreeboxSink*)clientData;
|
|---|
| 1045 | + sink->afterGettingFrame1(frameSize, presentationTime);
|
|---|
| 1046 | +}
|
|---|
| 1047 | +
|
|---|
| 1048 | +
|
|---|
| 1049 | +void FreeboxSink::afterGettingFrame1(unsigned frameSize, struct timeval presentationTime)
|
|---|
| 1050 | +{
|
|---|
| 1051 | + addData(fBuffer, frameSize, presentationTime);
|
|---|
| 1052 | + continuePlaying();
|
|---|
| 1053 | +}
|
|---|
| 1054 | +
|
|---|
| 1055 | +
|
|---|
| 1056 | +void FreeboxSink::addData(unsigned char* data, unsigned dataSize, struct timeval presentationTime)
|
|---|
| 1057 | +{
|
|---|
| 1058 | + recorder->addData(data, dataSize, presentationTime);
|
|---|
| 1059 | +}
|
|---|
| 1060 | diff -u -r -N mythtv-SVN.orig/libs/libmythtv/freeboxrecorder.h mythtv-SVN/libs/libmythtv/freeboxrecorder.h
|
|---|
| 1061 | --- mythtv-SVN.orig/libs/libmythtv/freeboxrecorder.h 1970-01-01 01:00:00.000000000 +0100
|
|---|
| 1062 | +++ mythtv-SVN/libs/libmythtv/freeboxrecorder.h 2006-04-16 19:04:23.000000000 +0200
|
|---|
| 1063 | @@ -0,0 +1,148 @@
|
|---|
| 1064 | +/**
|
|---|
| 1065 | + * DBOX2Recorder
|
|---|
| 1066 | + * Copyright (c) 2005 by Levent Gündogdu
|
|---|
| 1067 | + * Distributed as part of MythTV under GPL v2 and later.
|
|---|
| 1068 | + */
|
|---|
| 1069 | +
|
|---|
| 1070 | +#ifndef FREEBOXRECORDER_H_
|
|---|
| 1071 | +#define FREEBOXRECORDER_H_
|
|---|
| 1072 | +
|
|---|
| 1073 | +#include "dtvrecorder.h"
|
|---|
| 1074 | +#include <time.h>
|
|---|
| 1075 | +#include "freeboxchannel.h"
|
|---|
| 1076 | +#include "sitypes.h"
|
|---|
| 1077 | +#include "qhttp.h"
|
|---|
| 1078 | +#include "mpeg/tspacket.h"
|
|---|
| 1079 | +
|
|---|
| 1080 | +
|
|---|
| 1081 | +#include "BasicUsageEnvironment.hh"
|
|---|
| 1082 | +#include "GroupsockHelper.hh"
|
|---|
| 1083 | +#include "liveMedia.hh"
|
|---|
| 1084 | +
|
|---|
| 1085 | +/**
|
|---|
| 1086 | + * Constructs a FreeboxRecorder
|
|---|
| 1087 | + */
|
|---|
| 1088 | +
|
|---|
| 1089 | +#if defined(__WIN32__) || defined(_WIN32)
|
|---|
| 1090 | +#define snprintf _snprintf
|
|---|
| 1091 | +#else
|
|---|
| 1092 | +#include <signal.h>
|
|---|
| 1093 | +#define USE_SIGNALS 1
|
|---|
| 1094 | +#endif
|
|---|
| 1095 | +
|
|---|
| 1096 | +
|
|---|
| 1097 | +
|
|---|
| 1098 | +class FreeboxRecorder:public DTVRecorder
|
|---|
| 1099 | +{
|
|---|
| 1100 | + Q_OBJECT public:
|
|---|
| 1101 | + FreeboxRecorder (TVRec * rec, FreeboxChannel * channel);
|
|---|
| 1102 | + ~FreeboxRecorder ()
|
|---|
| 1103 | + {
|
|---|
| 1104 | + }
|
|---|
| 1105 | +
|
|---|
| 1106 | +
|
|---|
| 1107 | + void StartRecording (void);
|
|---|
| 1108 | + void StopRecording (void);
|
|---|
| 1109 | + bool Open (void);
|
|---|
| 1110 | + void Close ();
|
|---|
| 1111 | +
|
|---|
| 1112 | + void SetOptionsFromProfile (RecordingProfile * profile,
|
|---|
| 1113 | + const QString & videodev,
|
|---|
| 1114 | + const QString & audiodev,
|
|---|
| 1115 | + const QString & vbidev);
|
|---|
| 1116 | +
|
|---|
| 1117 | + void SubsessionAfterPlaying (MediaSubsession * subsession);
|
|---|
| 1118 | + void SubsessionByeHandler (MediaSubsession * subsession);
|
|---|
| 1119 | +
|
|---|
| 1120 | + // Callback function to add MPEG2 TS data
|
|---|
| 1121 | + void addData (unsigned char *data, unsigned dataSize,
|
|---|
| 1122 | + struct timeval presentationTime);
|
|---|
| 1123 | +
|
|---|
| 1124 | + // Look for TS Header in data
|
|---|
| 1125 | + int findTSHeader (unsigned char *data, unsigned dataSize);
|
|---|
| 1126 | +
|
|---|
| 1127 | +
|
|---|
| 1128 | + public slots:void ChannelChanged ();
|
|---|
| 1129 | +
|
|---|
| 1130 | +
|
|---|
| 1131 | + private:
|
|---|
| 1132 | + UsageEnvironment * env;
|
|---|
| 1133 | + RTSPClient *rtspClient;
|
|---|
| 1134 | + MediaSession *session;
|
|---|
| 1135 | +
|
|---|
| 1136 | + // var to check if we need to abort current rtsp session
|
|---|
| 1137 | + char *_abort_rtsp;
|
|---|
| 1138 | +
|
|---|
| 1139 | + // request abort for StartRecording Thread
|
|---|
| 1140 | + bool _request_abort;
|
|---|
| 1141 | +
|
|---|
| 1142 | + // Call back function to start RTSP Flow
|
|---|
| 1143 | + static void *StartRtspS (void *param);
|
|---|
| 1144 | + void StartRtsp ();
|
|---|
| 1145 | +
|
|---|
| 1146 | + void shutdown (int exitCode = 1);
|
|---|
| 1147 | +
|
|---|
| 1148 | + // Current channel
|
|---|
| 1149 | + FreeboxChannel *m_channel;
|
|---|
| 1150 | +
|
|---|
| 1151 | + // Mutex : use to make sure that current RTSP thread as stop
|
|---|
| 1152 | + QWaitCondition *waitShutdown;
|
|---|
| 1153 | +
|
|---|
| 1154 | + // The current RTSP thread
|
|---|
| 1155 | + pthread_t start_thread;
|
|---|
| 1156 | +};
|
|---|
| 1157 | +
|
|---|
| 1158 | +
|
|---|
| 1159 | +/*
|
|---|
| 1160 | + * Helper class use for static Callback handler
|
|---|
| 1161 | + */
|
|---|
| 1162 | +class FreeboxData
|
|---|
| 1163 | +{
|
|---|
| 1164 | + public:
|
|---|
| 1165 | + FreeboxData (FreeboxRecorder * pFreeboxRecorder,
|
|---|
| 1166 | + MediaSubsession * pMediaSubSession)
|
|---|
| 1167 | + {
|
|---|
| 1168 | + freeboxRecorder = pFreeboxRecorder;
|
|---|
| 1169 | + mediaSubSession = pMediaSubSession;
|
|---|
| 1170 | + }
|
|---|
| 1171 | +
|
|---|
| 1172 | + FreeboxRecorder *freeboxRecorder;
|
|---|
| 1173 | + MediaSubsession *mediaSubSession;
|
|---|
| 1174 | +};
|
|---|
| 1175 | +
|
|---|
| 1176 | +
|
|---|
| 1177 | +/*
|
|---|
| 1178 | + * Helper class use to receive RTSP data from socket.
|
|---|
| 1179 | + */
|
|---|
| 1180 | +class FreeboxSink:public MediaSink
|
|---|
| 1181 | +{
|
|---|
| 1182 | + public:
|
|---|
| 1183 | + static FreeboxSink *createNew (UsageEnvironment & env,
|
|---|
| 1184 | + FreeboxRecorder * pRecorder);
|
|---|
| 1185 | +
|
|---|
| 1186 | + // Callback function when rtsp data are ready
|
|---|
| 1187 | + void addData (unsigned char *data, unsigned dataSize,
|
|---|
| 1188 | + struct timeval presentationTime);
|
|---|
| 1189 | +
|
|---|
| 1190 | + protected:
|
|---|
| 1191 | + FreeboxSink (UsageEnvironment & env, FreeboxRecorder * pRecorder);
|
|---|
| 1192 | + virtual ~ FreeboxSink ();
|
|---|
| 1193 | +
|
|---|
| 1194 | + static void afterGettingFrame (void *clientData, unsigned frameSize,
|
|---|
| 1195 | + unsigned numTruncatedBytes,
|
|---|
| 1196 | + struct timeval presentationTime,
|
|---|
| 1197 | + unsigned durationInMicroseconds);
|
|---|
| 1198 | + virtual void afterGettingFrame1 (unsigned frameSize,
|
|---|
| 1199 | + struct timeval presentationTime);
|
|---|
| 1200 | +
|
|---|
| 1201 | + private:
|
|---|
| 1202 | + virtual Boolean continuePlaying ();
|
|---|
| 1203 | +
|
|---|
| 1204 | + unsigned char *fBuffer;
|
|---|
| 1205 | + unsigned fBufferSize;
|
|---|
| 1206 | + UsageEnvironment *env;
|
|---|
| 1207 | + FreeboxRecorder *recorder;
|
|---|
| 1208 | + int bufferIndex;
|
|---|
| 1209 | +
|
|---|
| 1210 | +};
|
|---|
| 1211 | +#endif
|
|---|
| 1212 | diff -u -r -N mythtv-SVN.orig/libs/libmythtv/libmythtv.pro mythtv-SVN/libs/libmythtv/libmythtv.pro
|
|---|
| 1213 | --- mythtv-SVN.orig/libs/libmythtv/libmythtv.pro 2006-04-18 09:06:59.000000000 +0200
|
|---|
| 1214 | +++ mythtv-SVN/libs/libmythtv/libmythtv.pro 2006-04-18 09:09:38.000000000 +0200
|
|---|
| 1215 | @@ -347,6 +347,10 @@
|
|---|
| 1216 | using_dbox2:SOURCES += dbox2recorder.cpp dbox2channel.cpp dbox2epg.cpp
|
|---|
| 1217 | using_dbox2:HEADERS += dbox2recorder.h dbox2channel.h dbox2epg.h
|
|---|
| 1218 | using_dbox2:DEFINES += USING_DBOX2
|
|---|
| 1219 | +
|
|---|
| 1220 | + # Support for FreeBox
|
|---|
| 1221 | + using_freebox:SOURCES += freeboxrecorder.cpp freeboxchannel.cpp
|
|---|
| 1222 | + using_freebox:HEADERS += freeboxrecorder.h freeboxchannel.h
|
|---|
| 1223 |
|
|---|
| 1224 | # Support for HDHomeRun box
|
|---|
| 1225 | using_hdhr {
|
|---|
| 1226 | diff -u -r -N mythtv-SVN.orig/libs/libmythtv/tv_rec.cpp mythtv-SVN/libs/libmythtv/tv_rec.cpp
|
|---|
| 1227 | --- mythtv-SVN.orig/libs/libmythtv/tv_rec.cpp 2006-04-18 09:07:02.000000000 +0200
|
|---|
| 1228 | +++ mythtv-SVN/libs/libmythtv/tv_rec.cpp 2006-04-18 09:36:41.000000000 +0200
|
|---|
| 1229 | @@ -73,6 +73,11 @@
|
|---|
| 1230 | #include "dbox2channel.h"
|
|---|
| 1231 | #endif
|
|---|
| 1232 |
|
|---|
| 1233 | +#ifdef USING_FREEBOX
|
|---|
| 1234 | +#include "freeboxrecorder.h"
|
|---|
| 1235 | +#include "freeboxchannel.h"
|
|---|
| 1236 | +#endif
|
|---|
| 1237 | +
|
|---|
| 1238 | #ifdef USING_HDHOMERUN
|
|---|
| 1239 | #include "hdhrrecorder.h"
|
|---|
| 1240 | #include "hdhrchannel.h"
|
|---|
| 1241 | @@ -188,6 +193,16 @@
|
|---|
| 1242 | init_run = true;
|
|---|
| 1243 | #endif
|
|---|
| 1244 | }
|
|---|
| 1245 | + else if (genOpt.cardtype == "FREEBOX")
|
|---|
| 1246 | + {
|
|---|
| 1247 | +#ifdef USING_FREEBOX
|
|---|
| 1248 | + channel = new FreeboxChannel(this, cardid);
|
|---|
| 1249 | + if(!channel->Open())
|
|---|
| 1250 | + return false;
|
|---|
| 1251 | + InitChannel(genOpt.defaultinput, startchannel);
|
|---|
| 1252 | + init_run = true;
|
|---|
| 1253 | +#endif
|
|---|
| 1254 | + }
|
|---|
| 1255 | else if (genOpt.cardtype == "HDHOMERUN")
|
|---|
| 1256 | {
|
|---|
| 1257 | #ifdef USING_HDHOMERUN
|
|---|
| 1258 | @@ -310,6 +325,11 @@
|
|---|
| 1259 | GetDBox2Channel()->deleteLater();
|
|---|
| 1260 | else
|
|---|
| 1261 | #endif // USING_DBOX2
|
|---|
| 1262 | +#ifdef USING_FREEBOX
|
|---|
| 1263 | + if (GetFreeboxChannel())
|
|---|
| 1264 | + GetFreeboxChannel()->deleteLater();
|
|---|
| 1265 | + else
|
|---|
| 1266 | +#endif // USING_FREEBOX
|
|---|
| 1267 | if (channel)
|
|---|
| 1268 | delete channel;
|
|---|
| 1269 | channel = NULL;
|
|---|
| 1270 | @@ -870,6 +890,12 @@
|
|---|
| 1271 | recorder->SetOption("httpport", dboxOpt.httpport);
|
|---|
| 1272 | #endif // USING_DBOX2
|
|---|
| 1273 | }
|
|---|
| 1274 | + else if (genOpt.cardtype == "FREEBOX")
|
|---|
| 1275 | + {
|
|---|
| 1276 | +#ifdef USING_FREEBOX
|
|---|
| 1277 | + recorder = new FreeboxRecorder(this, GetFreeboxChannel());
|
|---|
| 1278 | +#endif // USING_FREEBOX
|
|---|
| 1279 | + }
|
|---|
| 1280 | else if (genOpt.cardtype == "HDHOMERUN")
|
|---|
| 1281 | {
|
|---|
| 1282 | #ifdef USING_HDHOMERUN
|
|---|
| 1283 | @@ -1094,6 +1120,15 @@
|
|---|
| 1284 | #endif // USING_DBOX2
|
|---|
| 1285 | }
|
|---|
| 1286 |
|
|---|
| 1287 | +FreeboxChannel *TVRec::GetFreeboxChannel(void)
|
|---|
| 1288 | +{
|
|---|
| 1289 | +#ifdef USING_FREEBOX
|
|---|
| 1290 | + return dynamic_cast<FreeboxChannel*>(channel);
|
|---|
| 1291 | +#else
|
|---|
| 1292 | + return NULL;
|
|---|
| 1293 | +#endif // USING_FREEBOX
|
|---|
| 1294 | +}
|
|---|
| 1295 | +
|
|---|
| 1296 | HDHRChannel *TVRec::GetHDHRChannel(void)
|
|---|
| 1297 | {
|
|---|
| 1298 | #ifdef USING_HDHOMERUN
|
|---|
| 1299 | diff -u -r -N mythtv-SVN.orig/libs/libmythtv/tv_rec.h mythtv-SVN/libs/libmythtv/tv_rec.h
|
|---|
| 1300 | --- mythtv-SVN.orig/libs/libmythtv/tv_rec.h 2006-04-18 09:07:02.000000000 +0200
|
|---|
| 1301 | +++ mythtv-SVN/libs/libmythtv/tv_rec.h 2006-04-18 09:15:58.000000000 +0200
|
|---|
| 1302 | @@ -36,6 +36,7 @@
|
|---|
| 1303 |
|
|---|
| 1304 | class ChannelBase;
|
|---|
| 1305 | class DBox2Channel;
|
|---|
| 1306 | +class FreeboxChannel;
|
|---|
| 1307 | class HDHRChannel;
|
|---|
| 1308 | class DVBChannel;
|
|---|
| 1309 | class Channel;
|
|---|
| 1310 | @@ -287,10 +288,11 @@
|
|---|
| 1311 | bool CreateChannel(const QString &startChanNum);
|
|---|
| 1312 | void InitChannel(const QString &inputname, const QString &startchannel);
|
|---|
| 1313 | void CloseChannel(void);
|
|---|
| 1314 | - DBox2Channel *GetDBox2Channel(void);
|
|---|
| 1315 | - HDHRChannel *GetHDHRChannel(void);
|
|---|
| 1316 | - DVBChannel *GetDVBChannel(void);
|
|---|
| 1317 | - Channel *GetV4LChannel(void);
|
|---|
| 1318 | + DBox2Channel *GetDBox2Channel(void);
|
|---|
| 1319 | + HDHRChannel *GetHDHRChannel(void);
|
|---|
| 1320 | + DVBChannel *GetDVBChannel(void);
|
|---|
| 1321 | + FreeboxChannel *GetFreeboxChannel(void);
|
|---|
| 1322 | + Channel *GetV4LChannel(void);
|
|---|
| 1323 |
|
|---|
| 1324 | void SetupSignalMonitor(bool enable_table_monitoring, bool notify);
|
|---|
| 1325 | bool SetupDTVSignalMonitor(void);
|
|---|
| 1326 | diff -u -r -N mythtv-SVN.orig/libs/libmythtv/videosource.cpp mythtv-SVN/libs/libmythtv/videosource.cpp
|
|---|
| 1327 | --- mythtv-SVN.orig/libs/libmythtv/videosource.cpp 2006-04-18 09:07:01.000000000 +0200
|
|---|
| 1328 | +++ mythtv-SVN/libs/libmythtv/videosource.cpp 2006-04-18 09:36:02.000000000 +0200
|
|---|
| 1329 | @@ -914,6 +914,19 @@
|
|---|
| 1330 | CaptureCard &parent;
|
|---|
| 1331 | };
|
|---|
| 1332 |
|
|---|
| 1333 | +class FreeboxConfigurationGroup: public VerticalConfigurationGroup {
|
|---|
| 1334 | + public:
|
|---|
| 1335 | + FreeboxConfigurationGroup(CaptureCard& a_parent):
|
|---|
| 1336 | + ConfigurationGroup(false, true, false, false),
|
|---|
| 1337 | + VerticalConfigurationGroup(false, true, false, false),
|
|---|
| 1338 | + parent(a_parent)
|
|---|
| 1339 | + {
|
|---|
| 1340 | + setUseLabel(false);
|
|---|
| 1341 | + };
|
|---|
| 1342 | + private:
|
|---|
| 1343 | + CaptureCard& parent;
|
|---|
| 1344 | +};
|
|---|
| 1345 | +
|
|---|
| 1346 | class HDHomeRunDeviceID: public LineEditSetting, public CCSetting
|
|---|
| 1347 | {
|
|---|
| 1348 | public:
|
|---|
| 1349 | @@ -927,6 +940,7 @@
|
|---|
| 1350 | }
|
|---|
| 1351 | };
|
|---|
| 1352 |
|
|---|
| 1353 | +
|
|---|
| 1354 | class HDHomeRunTunerIndex: public ComboBoxSetting, public CCSetting
|
|---|
| 1355 | {
|
|---|
| 1356 | public:
|
|---|
| 1357 | @@ -1076,6 +1090,10 @@
|
|---|
| 1358 | #ifdef USING_HDHOMERUN
|
|---|
| 1359 | addTarget("HDHOMERUN", new HDHomeRunConfigurationGroup(parent));
|
|---|
| 1360 | #endif // USING_HDHOMERUN
|
|---|
| 1361 | +
|
|---|
| 1362 | +#ifdef USING_FREEBOX
|
|---|
| 1363 | + addTarget("FREEBOX", new FreeboxConfigurationGroup(parent));
|
|---|
| 1364 | +#endif // USING_FREEBOX
|
|---|
| 1365 | }
|
|---|
| 1366 |
|
|---|
| 1367 | void CaptureCardGroup::triggerChanged(const QString& value)
|
|---|
| 1368 | @@ -1190,6 +1208,11 @@
|
|---|
| 1369 | QObject::tr("DBox2 TCP/IP cable box"), "DBOX2");
|
|---|
| 1370 | #endif // USING_DBOX2
|
|---|
| 1371 |
|
|---|
| 1372 | +#ifdef USING_FREEBOX
|
|---|
| 1373 | + setting->addSelection(
|
|---|
| 1374 | + QObject::tr("Freebox"), "FREEBOX");
|
|---|
| 1375 | +#endif // USING_FREEBOX
|
|---|
| 1376 | +
|
|---|
| 1377 | #ifdef USING_HDHOMERUN
|
|---|
| 1378 | setting->addSelection(
|
|---|
| 1379 | QObject::tr("HDHomeRun DTV tuner box"), "HDHOMERUN");
|
|---|
| 1380 | diff -u -r -N mythtv-SVN.orig/settings.pro mythtv-SVN/settings.pro
|
|---|
| 1381 | --- mythtv-SVN.orig/settings.pro 2006-04-18 09:07:07.000000000 +0200
|
|---|
| 1382 | +++ mythtv-SVN/settings.pro 2006-04-16 19:05:43.000000000 +0200
|
|---|
| 1383 | @@ -79,6 +79,7 @@
|
|---|
| 1384 | EXTRA_LIBS += $$CONFIG_AUDIO_JACK_LIBS
|
|---|
| 1385 | EXTRA_LIBS += $$CONFIG_FIREWIRE_LIBS
|
|---|
| 1386 | EXTRA_LIBS += $$CONFIG_DIRECTFB_LIBS
|
|---|
| 1387 | +EXTRA_LIBS += $$CONFIG_LIVE_LIBS
|
|---|
| 1388 |
|
|---|
| 1389 | EXTRA_LIBS += $$LOCAL_LIBDIR_OGL
|
|---|
| 1390 | EXTRA_LIBS += $$LOCAL_LIBDIR_X11
|
|---|