Ticket #1458: patch.freebox.v1.10.diff

File patch.freebox.v1.10.diff, 45.1 KB (added by anonymous, 13 years ago)
  • mythtv/configure

    diff -ru --new-file --exclude=.svn myth-org/mythtv/configure myth-patch/mythtv/configure
    old new  
    22#
    33# ffmpeg configure script (c) 2000, 2001, 2002 Fabrice Bellard
    44#
    5 
     5 
    66x86_mmx_cpus="pentium-mmx,pentium2,pentium3,pentium3m,pentium-m"
    77x86_mmx_cpus="$x86_mmx_cpus,pentium4,pentium4m,prescott"
    88x86_mmx_cpus="$x86_mmx_cpus,athlon,athlon-xp,athlon-tbird,athlon-4,athlon-mp,"
     
    5555lirc="yes"
    5656joystick_menu="yes"
    5757firewire_cable_box="yes"
     58freebox_box="yes"
    5859dbox2_dvb_box="yes"
    5960x11_include_path="/usr/X11R6/include"
    6061x11="yes"
     
    173174echo "  --disable-lirc           disable lirc support (Infrared Remotes)"
    174175echo "  --disable-joystick-menu  disable joystick menu"
    175176echo "  --disable-firewire       disable support for FireWire cable boxes"
     177echo "  --disable-freebox        disable support for Freebox"
    176178echo "  --disable-dbox2          disable support for Nokia DBOX2 DVB boxes (or compatibles)"
    177179echo "  --disable-v4l            disable Video4Linux support"
    178180echo "  --disable-ivtv           disable ivtv support (PVR-x50) req. v4l support"
     
    809811  ;;
    810812  --disable-dbox2) dbox2_dvb_box="no"
    811813  ;;
     814  --enable-freebox) freebox_box="yes"
     815  ;;
     816  --disable-freebox) freebox_box="no"
     817  ;;
    812818  --enable-dvb) dvb="yes"
    813819  ;;
    814820  --disable-dvb) dvb="no"
     
    21002106    fi
    21012107fi
    21022108
     2109if test x"$dvd" = x"yes" ; then
     2110    if has_library libdvdnav ; then
     2111        if has_header dvdnav/dvdnav.h ; then
     2112            dvd="yes"
     2113        fi
     2114    fi
     2115fi
     2116
     2117
    21032118VENDOR_XVMC_LIBS=""
    21042119if test x"$xvmc" = x"yes"; then
    21052120    xvmc="no"
     
    22492264  echo "FireWire support $firewire_cable_box"
    22502265  echo "DVB support      $dvb [$dvb_path]"
    22512266  echo "DBox2 support    $dbox2_dvb_box"
     2267  echo "freebox support    $freebox_box"
     2268
    22522269fi
    22532270
    22542271if test x"$frontend" = x"yes" ; then
     
    28912908  CONFIG_DEFINES="$CONFIG_DEFINES USING_DBOX2"
    28922909fi
    28932910
     2911if test x"$freebox_box" = x"yes" ; then
     2912  CCONFIG="$CCONFIG using_freebox"
     2913  CONFIG_DEFINES="$CONFIG_DEFINES USING_FREEBOX"
     2914fi
     2915
     2916
    28942917if test x"$lirc" = x"yes" ; then
    28952918  CCONFIG="$CCONFIG using_lirc"
    28962919  echo "CONFIG_LIRC_LIBS=-llirc_client" >> $MYTH_CONFIG_MAK
  • mythtv/libs/libmythtv/cardutil.cpp

    diff -ru --new-file --exclude=.svn myth-org/mythtv/libs/libmythtv/cardutil.cpp myth-patch/mythtv/libs/libmythtv/cardutil.cpp
    old new  
    515515{
    516516    QStringList ret;
    517517
    518     if (("FIREWIRE" == cardtype) || ("DBOX2" == cardtype))
     518    if (("FIREWIRE" == cardtype) || ("DBOX2" == cardtype) || ("FREEBOX" == cardtype))
    519519        ret += "MPEG2TS";
    520520    else if ("DVB" == cardtype)
    521521        ret += probeDVBInputs(device, diseqctype);
     
    705705                .arg(query.value(1).toString())
    706706                .arg(query.value(2).toString());
    707707    }
     708    else if (cardtype == "FREEBOX")
     709    {
     710        MSqlQuery query(MSqlQuery::InitCon());
     711        query.prepare(
     712            "SELECT freebox_host "
     713            "FROM capturecard "
     714            "WHERE cardid = :CARDID");
     715        query.bindValue(":CARDID", cardid);
     716
     717        if (!query.exec() || !query.isActive() || !query.size())
     718            label = "[ DB ERROR ]";
     719        else
     720            label = QString("[ FREEBOX : HOST %1  ]")
     721                .arg(query.value(0).toString());
     722    }
    708723    else
    709724    {
    710725        label = QString("[ %1 : %2 ]").arg(cardtype).arg(videodevice);
     
    724739    int rcardid = (parentid) ? parentid : cardid;
    725740    QStringList inputs;
    726741
    727     if (("FIREWIRE" == cardtype) || ("DBOX2" == cardtype))
     742    if (("FIREWIRE" == cardtype) || ("DBOX2" == cardtype) || ("FREEBOX" == cardtype))
    728743        inputs += "MPEG2TS";
    729744    else if ("DVB" != cardtype)
    730745        inputs += probeV4LInputs(device);
  • mythtv/libs/libmythtv/dbcheck.cpp

    diff -ru --new-file --exclude=.svn myth-org/mythtv/libs/libmythtv/dbcheck.cpp myth-patch/mythtv/libs/libmythtv/dbcheck.cpp
    old new  
    20102010            return false;
    20112011    }
    20122012
     2013
    20132014    if (dbver == "1123")
    20142015    {
    20152016        const QString updates[] = {
     
    21842185//"ALTER TABLE capturecard DROP COLUMN dvb_hw_decoder;" in 0.21
    21852186//"ALTER TABLE cardinput DROP COLUMN  preference;" in 0.22
    21862187
     2188  if (dbver == "1134")
     2189    {
     2190        const QString updates[] = {
     2191"INSERT INTO profilegroups SET name = 'Freebox Input', cardtype = 'Freebox', is_default = 1;",
     2192"ALTER TABLE capturecard ADD COLUMN freebox_host varchar(64) DEFAULT 'mafreebox.freebox.fr';",
     2193""
     2194};
     2195
     2196        if (!performActualUpdate(updates, "1135", dbver))
     2197            return false;
     2198    }
     2199
     2200
    21872201    return true;
    21882202}
    21892203
     
    22442258"  dbox2_port int(10) unsigned NOT NULL default '31338',"
    22452259"  dbox2_httpport int(10) unsigned NOT NULL default '80',"
    22462260"  dbox2_host varchar(32) default NULL,"
     2261"  freebox_host varchar(64) DEFAULT 'mafreebox.freebox.fr',"
    22472262"  signal_timeout int(11) NOT NULL default '1000',"
    22482263"  channel_timeout int(11) NOT NULL default '3000',"
    22492264"  PRIMARY KEY  (cardid)"
     
    28102825"INSERT INTO profilegroups VALUES (8,"
    28112826" 'USB Mpeg-4 Encoder (Plextor ConvertX, etc)','GO7007',1,NULL);",
    28122827"INSERT INTO profilegroups VALUES (9,'DBOX2 Input','DBOX2',1,NULL);",
     2828"INSERT INTO `profilegroups` VALUES (10,'Freebox Input','Freebox',1,NULL);",
    28132829"INSERT INTO recordingprofiles VALUES (1,'Default',NULL,NULL,1);",
    28142830"INSERT INTO recordingprofiles VALUES (2,'Live TV',NULL,NULL,1);",
    28152831"INSERT INTO recordingprofiles VALUES (3,'High Quality',NULL,NULL,1);",
  • mythtv/libs/libmythtv/freeboxchannel.cpp

    diff -ru --new-file --exclude=.svn myth-org/mythtv/libs/libmythtv/freeboxchannel.cpp myth-patch/mythtv/libs/libmythtv/freeboxchannel.cpp
    old new  
     1/**
     2 *  FreeboxChannel
     3 *  Copyright (c) 2005 by Levent Gündogdu
     4 *  Distributed as part of MythTV under GPL v2 and later.
     5 */
     6
     7
     8
     9#include <iostream>
     10#include <qsqldatabase.h>
     11#include "mythdbcon.h"
     12#include "mythcontext.h"
     13#include "freeboxchannel.h"
     14
     15
     16FreeboxChannel::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_freeboxchannelcount(0),
     22                                m_channelListReady(false),
     23                                m_requestChannel(""),
     24                                m_lastChannel("1"),
     25                                m_cardid(cardid)
     26
     27{
     28        connect(http,        SIGNAL(           done(bool)),
     29            this,        SLOT(  HttpRequestDone(bool)));
     30 
     31        LoadChannels();
     32}
     33
     34bool FreeboxChannel::SwitchToInput(const QString &inputname, const QString &chan)
     35{
     36        int inputNum = GetInputByName(inputname);
     37        if (inputNum < 0)
     38         return false;
     39               
     40   return SetChannelByString(chan);
     41}
     42
     43bool FreeboxChannel::SetChannelByString(const QString &newChan)
     44{
     45         // Delay set channel when list has not yet been retrieved
     46    if (!m_channelListReady)
     47    {
     48        VERBOSE(VB_IMPORTANT,QString("Freebox # Channel list not received yet. Will switch to channel %1 later...").arg(newChan));
     49                m_requestChannel = newChan;
     50                return true;
     51    }
     52   
     53    QString chan = newChan;
     54    // If chan is empty, use DefautChannel
     55    if (chan == "")
     56    {
     57        VERBOSE(VB_IMPORTANT,QString("Freebox # Empty channel name has been provided. Getting default name."));
     58                chan = GetDefaultChannel();
     59    }
     60   
     61    // update current chanel
     62    if (m_lastChannel != curchannelname)
     63        m_lastChannel = curchannelname;
     64
     65    curchannelname = chan;
     66    m_currenturl = GetChannelUrlFromNumber(curchannelname);
     67       
     68
     69        // emit signal to recorder
     70        emit ChannelChanged();
     71
     72    return true;
     73}
     74
     75QString FreeboxChannel::GetCurrentChannelUrl()
     76{
     77        return m_currenturl;
     78}
     79
     80bool FreeboxChannel::IsOpen(void) const
     81{
     82        return true;
     83}
     84
     85bool FreeboxChannel::Open(void)
     86{
     87    if (!InitializeInputs())
     88        return false;
     89       
     90        return true;
     91}
     92
     93void FreeboxChannel::Close(void)
     94{
     95}
     96
     97
     98// =====================================================================================
     99//
     100//      C H A N N E L     L O A D I N G
     101// =====================================================================================
     102
     103
     104void FreeboxChannel::LoadChannels()
     105{
     106    // Request Channel list via http. Signal will be emmitted when list is ready.
     107    QHttpRequestHeader header("GET", "/freeboxtv/playlist.m3u");
     108    header.setValue("Host", m_freeboxoptions->host);
     109    http->setHost(m_freeboxoptions->host, 80);
     110    http->request(header);
     111}
     112
     113
     114QString 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        QString res;
     118        for (unsigned int i=0;i<channelName.length();i++)
     119        {
     120                QChar c = channelName[i];
     121                if (c.isSpace()) continue;
     122                c=c.lower();
     123                if (c=='é' || c=='ê' || c=='ê') c='e';
     124                if (c=='à') c='a';
     125                if (c=='i' || c=='î') c=='i';
     126                if (c=='ô') c=='o';
     127               
     128                res += c;
     129        }
     130       
     131        return res;
     132}
     133
     134// ==========================================================================================
     135// HttpRequestDone : Receive response to channel list request
     136//
     137// ==========================================================================================
     138void FreeboxChannel::HttpRequestDone(bool error)
     139{
     140    if (error)
     141    {
     142        VERBOSE(VB_IMPORTANT,QString("Freebox # Reading channel list failed!"));
     143        return;
     144    }
     145
     146    QString buffer=http->readAll();
     147    m_freeboxchannelcount = 0;
     148
     149    int sepCount = 0;
     150   
     151    QString header = buffer.section("\n", sepCount, sepCount);
     152    sepCount++;
     153
     154        // Verify header is ok
     155        if (header != "#EXTM3U")
     156        {
     157                VERBOSE(VB_IMPORTANT,QString("Freebox # Invalid header while retrieve channel list.!"));
     158                return;
     159        }
     160   
     161    while (true)
     162    {
     163        QString line1 = buffer.section("\n", sepCount, sepCount);
     164                if (line1 == "")
     165                break;
     166           
     167            sepCount++;
     168
     169        QString line2 = buffer.section("\n", sepCount, sepCount);
     170                if (line2 == "")
     171                break;
     172
     173            sepCount++;
     174
     175                // each line contains ://
     176                // header:extension,channelNum - channelName rtsp://channelUrl
     177                //#EXTINF:0,2 - France 2 rtsp://mafreebox.freebox.fr/freeboxtv/201
     178
     179                QString lineHead;
     180                QString extension;
     181                QString channelNum;
     182                QString channelName;
     183       
     184                int pos = 0;
     185                int oldPos = 0;
     186               
     187                pos = line1.find(":", oldPos);
     188                if (pos<0)
     189                {
     190                        VERBOSE(VB_IMPORTANT,QString("Freebox # Invalid header while retrieve channel list.!"));
     191                        return;
     192                }
     193                lineHead = line1.mid(0, pos);
     194               
     195                if (lineHead != "#EXTINF")
     196                {
     197                        VERBOSE(VB_IMPORTANT,QString("Freebox # Invalid header while retrieve channel list.!"));
     198                        return;
     199                }
     200               
     201                oldPos = pos + 1;
     202                pos = line1.find(",", oldPos);
     203                if (pos<0)
     204                {
     205                        VERBOSE(VB_IMPORTANT,QString("Freebox # Invalid header while retrieve channel list.!"));
     206                        return;
     207                }
     208                extension = line1.mid(oldPos, pos - oldPos);
     209               
     210
     211                oldPos = pos + 1;
     212                pos = line1.find(" ", oldPos);
     213                if (pos<0)
     214                {
     215                        VERBOSE(VB_IMPORTANT,QString("Freebox # Invalid header while retrieve channel list.!"));
     216                        return;
     217                }
     218                channelNum = line1.mid(oldPos, pos - oldPos);
     219               
     220               
     221                oldPos = pos + 1;
     222                pos = line1.find("- ", oldPos);
     223                if (pos<0)
     224                {
     225                        VERBOSE(VB_IMPORTANT,QString("Freebox # Invalid header while retrieve channel list.!"));
     226                        return;
     227                }
     228                channelName = line1.mid(pos + 2, line1.length());
     229               
     230               
     231
     232                QString channelUrl = line2;
     233               
     234               
     235                // save all this information in map for quick access
     236                bool ok;
     237                int channelNumI = channelNum.toInt( &ok, 10 );     
     238   
     239        QString channelNameN = normalize(channelName);
     240               
     241                m_freeboxchannelIds[channelNumI] = m_freeboxchannelcount;
     242                m_freeboxchannelUrl[m_freeboxchannelcount] = channelUrl;
     243                m_freeboxchannelNames[m_freeboxchannelcount] = channelName;
     244                m_freeboxchannelNamesN[m_freeboxchannelcount] = channelNameN;
     245               
     246                m_freeboxchannelcount++;
     247    }
     248   
     249 
     250    // Channel list is ready.
     251    m_channelListReady = true;
     252   
     253    // Change channel if delayed request is available
     254    if (m_requestChannel != "")
     255    {
     256                SetChannelByString(m_requestChannel);
     257                m_requestChannel = "";
     258    }
     259}
     260
     261
     262// ==========================================================================================
     263// GetChannelUrlFromNumber : Map a channel number to the corresponding rtsp URL
     264//
     265// ==========================================================================================
     266QString FreeboxChannel::GetChannelUrlFromNumber(const QString& channelnumber)
     267{
     268    MSqlQuery query(MSqlQuery::InitCon());   
     269   
     270    query.prepare("SELECT name,freqid "
     271                  "FROM channel,cardinput "
     272                  "WHERE "
     273                  "channel.sourceid = cardinput.sourceid AND "
     274                  "cardinput.cardid = :CARDID AND "
     275                  "channel.channum = :CHANNUM");
     276                 
     277    query.bindValue(":CARDID", m_cardid);
     278    query.bindValue(":CHANNUM", channelnumber);
     279
     280    if (query.exec() && query.isActive() && query.size() > 0)
     281    {
     282        query.next();
     283        QString chanName = query.value(0).toString();
     284
     285                // if we have a FreqID in the table, use this as the real freebox channel number
     286        int mFreqId = query.value(1).toInt();
     287        if (mFreqId!=0)
     288        {
     289                int channelI = m_freeboxchannelIds[mFreqId];
     290                return m_freeboxchannelUrl[channelI];
     291        }
     292       
     293        // if no freqID, try to map the chanName to an existing channel name
     294        for (int i=0;i<m_freeboxchannelcount;i++)
     295        {
     296                if (m_freeboxchannelNamesN[i] == chanName)
     297                {
     298                        return m_freeboxchannelUrl[i];
     299                }
     300        }
     301
     302                return "";       
     303    }
     304    return "";
     305}
     306
     307// ==========================================================================================
     308// GetDefaultChannel : Search for default channel
     309//
     310// ==========================================================================================
     311
     312QString FreeboxChannel::GetDefaultChannel()
     313{
     314    MSqlQuery query(MSqlQuery::InitCon());   
     315    query.prepare("SELECT channum "
     316                  "FROM channel,cardinput "
     317                  "WHERE "
     318                  "channel.sourceid = cardinput.sourceid AND "
     319                  "cardinput.cardid = :CARDID "
     320                  "ORDER BY channum limit 1");
     321                 
     322    query.bindValue(":CARDID", m_cardid);
     323
     324    if (query.exec() && query.isActive() && query.size() > 0)
     325    {
     326        query.next();
     327        return query.value(0).toString();
     328    }
     329    return "";
     330}
     331 Pas de fin de ligne à la fin du fichier.
  • mythtv/libs/libmythtv/freeboxchannel.h

    diff -ru --new-file --exclude=.svn myth-org/mythtv/libs/libmythtv/freeboxchannel.h myth-patch/mythtv/libs/libmythtv/freeboxchannel.h
    old new  
     1#ifndef FREEBOXCHANNEL_H
     2#define FREEBOXCHANNEL_H
     3
     4#include <qstring.h>
     5#include <qmap.h>
     6#include <qhttp.h>
     7#include <qobject.h>
     8#include <qthread.h>
     9
     10#ifdef HAVE_STDINT_H
     11#include <stdint.h>
     12#endif
     13
     14#include "tv_rec.h"
     15#include "channelbase.h"
     16#include "sitypes.h"
     17
     18
     19class FreeboxChannel : public QObject, public ChannelBase
     20{
     21    Q_OBJECT
     22        public:
     23        FreeboxChannel(TVRec *parent, FreeboxDBOptions *freebox_options, int cardid);
     24        ~FreeboxChannel(void)
     25        { 
     26                }
     27
     28
     29        bool Open();
     30        void Close();
     31        bool SwitchToInput(const QString &inputname, const QString &chan);
     32        bool SetChannelByString(const QString &chan);
     33        bool IsOpen(void) const;
     34 
     35               
     36                QString GetCurrentChannelUrl();
     37               
     38               
     39            bool SwitchToInput(int newcapchannel, bool setstarting)
     40        {
     41                (void)newcapchannel;
     42                (void)setstarting;
     43                return false;
     44        }
     45       
     46        QString GetChannelUrlFromNumber(const QString& channelnumber);
     47                QString GetDefaultChannel();
     48               
     49  signals:
     50        void ChannelChanged();
     51   
     52        public slots:
     53        void HttpRequestDone(bool error);
     54   
     55        private:
     56        void LoadChannels();
     57                QString normalize(QString channelName);
     58
     59                void Log(QString string);
     60 
     61                QHttp                   *http;
     62                FreeboxDBOptions        *m_freeboxoptions;
     63               
     64
     65                bool                    m_channelListReady;
     66                QString                 m_requestChannel;
     67                QString                 m_lastChannel;
     68            int                 m_cardid;
     69           
     70            // the rtsp url for the current channel
     71            QString             m_currenturl;
     72               
     73                // number of channel support by freebox
     74                int                     m_freeboxchannelcount;
     75       
     76        // map channelNum to channel index in table
     77        QMap<int,int>           m_freeboxchannelIds;
     78
     79        // map channel index to channel url
     80        QMap<int,QString>       m_freeboxchannelUrl;
     81
     82        // map channel index to channel name
     83        QMap<int,QString>       m_freeboxchannelNames;
     84
     85        // map channel index to channel normalize name
     86        QMap<int,QString>       m_freeboxchannelNamesN;
     87};
     88
     89#endif
  • mythtv/libs/libmythtv/freeboxrecorder.cpp

    diff -ru --new-file --exclude=.svn myth-org/mythtv/libs/libmythtv/freeboxrecorder.cpp myth-patch/mythtv/libs/libmythtv/freeboxrecorder.cpp
    old new  
     1/**
     2 *  FreeboxRecorder
     3 *  Copyright (c) 2005 by Levent G?u (mythtv@feature-it.com)
     4 *  Distributed as part of MythTV under GPL v2 and later.
     5 */
     6
     7#include <iostream>
     8using namespace std;
     9
     10
     11
     12#include <pthread.h>
     13#include "RingBuffer.h"
     14#include "mythcontext.h"
     15#include "freeboxrecorder.h"
     16#include "freeboxchannel.h"
     17#include <qhttp.h>
     18#include <qobject.h>
     19#include <sys/select.h>
     20#include <sys/types.h>
     21#include <sys/socket.h>
     22#include <netdb.h>
     23#include <fcntl.h>
     24#include <unistd.h>
     25#include <netinet/in.h>    // For sockaddr_in on OS X
     26
     27void subsessionAfterPlaying(void *clientData);
     28void subsessionByeHandler(void *clientData);
     29
     30
     31
     32
     33
     34FreeboxRecorder::FreeboxRecorder(TVRec *rec, FreeboxChannel *channel):DTVRecorder(rec, "FreeboxRecorder"),
     35      // ptr to FreeboxChannel
     36      m_channel(channel)
     37                                       
     38{
     39        // the var will be use to abort current rtsp session
     40        _abort_rtsp = new char();
     41       
     42        connect (m_channel, SIGNAL(ChannelChanged()),
     43                        this,      SLOT(  ChannelChanged()));
     44}
     45
     46
     47bool FreeboxRecorder::Open()
     48{
     49        // Start a new RTSP flow with current channel
     50        pthread_create(&start_thread, NULL, FreeboxRecorder::StartRtspS, this);
     51        return true;
     52}       
     53
     54
     55void FreeboxRecorder::Close()
     56{
     57        // ask for RTSP shutdown setting abort_rstp=1, and wait effective shutdown on mutex
     58        waitShutdown = new QWaitCondition();
     59        *_abort_rtsp = 1;
     60        _request_recording = false;
     61        waitShutdown->wait();
     62       
     63        if (session == NULL) return;
     64
     65        // Ensure RTSP cleanup, remove old RTSP session         
     66        MediaSubsessionIterator iter(*session);
     67        MediaSubsession* subsession;
     68        while ((subsession = iter.next()) != NULL)
     69        {
     70            Medium::close(subsession->sink);
     71        subsession->sink = NULL;
     72        }
     73 
     74        if (session == NULL) return;
     75 
     76        rtspClient->teardownMediaSession(*session);
     77 
     78        // Close all RTSP descriptor
     79        Medium::close(session);
     80        Medium::close(rtspClient);     
     81}
     82
     83void FreeboxRecorder::ChannelChanged()
     84{
     85                // Channel change, we need to close current RTSP flow, and open a new one
     86        Close();
     87        Open();
     88}
     89
     90
     91
     92void FreeboxRecorder::SetOptionsFromProfile(RecordingProfile *profile,
     93                                                                                           const QString &videodev,
     94                                                                                           const QString &audiodev,
     95                                                                                           const QString &vbidev)
     96{
     97        (void)videodev;
     98        (void)audiodev;
     99        (void)vbidev;
     100        (void)profile;
     101}
     102
     103
     104
     105void FreeboxRecorder::StartRecording()
     106{
     107        // Open RTSP flow for current channel
     108        Open();
     109
     110    _request_recording = true;
     111    _recording = true;
     112    _request_abort = false;
     113   
     114        // wait until recorder abot
     115    while(_request_recording)
     116    {
     117        if (_request_abort)
     118            break;
     119           
     120            usleep(1000);
     121    }
     122}
     123
     124void FreeboxRecorder::StopRecording(void)
     125{
     126        // Close the current RTSP flow
     127        Close();       
     128}
     129
     130
     131void *FreeboxRecorder::StartRtspS(void *param)
     132{
     133        FreeboxRecorder *recorder = (FreeboxRecorder*)param;
     134        recorder->StartRtsp();
     135        return NULL;
     136}
     137
     138// ======================================================================
     139// StartRtsp : start a new RTSP session for the current channel
     140// ======================================================================
     141void FreeboxRecorder::StartRtsp()
     142{
     143        // Retrieve the RTSP channel URL
     144        QString url = m_channel->GetCurrentChannelUrl();
     145       
     146       
     147        // Begin by setting up our usage environment:
     148        TaskScheduler* scheduler = BasicTaskScheduler::createNew();
     149        env = BasicUsageEnvironment::createNew(*scheduler);
     150
     151 
     152        // Create our client object:
     153        rtspClient = RTSPClient::createNew(*env, 0, "myRTSP", 0);
     154        if (rtspClient == NULL)
     155        {
     156                VERBOSE(VB_IMPORTANT, QString("Freebox # Failed to create RTSP client: %1").arg(env->getResultMsg()));
     157        shutdown();
     158        }
     159       
     160        // Setup URL for the current session
     161        char* sdpDescription = rtspClient->describeURL(url);
     162        rtspClient->describeStatus();
     163
     164        if (sdpDescription == NULL)
     165        {
     166                VERBOSE(VB_IMPORTANT, QString("Freebox # Failed to get a SDP description from URL: %1 %2").arg(url).arg(env->getResultMsg()));
     167        shutdown();
     168        }
     169 
     170
     171        // Create a media session object from this SDP description:
     172        session = MediaSession::createNew(*env, sdpDescription);
     173        delete[] sdpDescription;
     174        if (session == NULL)
     175        {
     176                VERBOSE(VB_IMPORTANT, QString("Freebox # Failed to create a MediaSession object from the SDP description: %1").arg(env->getResultMsg()));
     177            shutdown();
     178        }
     179        else if (!session->hasSubsessions())
     180        {
     181                VERBOSE(VB_IMPORTANT, QString("Freebox # This session has no media subsessions"));
     182        shutdown();
     183        }
     184 
     185        // Then, setup the "RTPSource"s for the session:
     186        MediaSubsessionIterator iter(*session);
     187        MediaSubsession *subsession;
     188        Boolean madeProgress = False;
     189        while ((subsession = iter.next()) != NULL)
     190        {
     191        if (!subsession->initiate(-1))
     192        {
     193                        VERBOSE(VB_IMPORTANT, QString("Freebox # Unable to create receiver for: %1 / %2 subsession: %3").arg(subsession->mediumName()).arg(subsession->codecName()).arg(env->getResultMsg()));
     194        }
     195        else
     196        {
     197                        madeProgress = True;
     198
     199                        if (subsession->rtpSource() != NULL)
     200                        {
     201                                unsigned const thresh = 1000000; // 1 second
     202                                subsession->rtpSource()->setPacketReorderingThresholdTime(thresh);
     203                        }
     204        }
     205        }
     206
     207
     208        if (!madeProgress) shutdown();
     209
     210
     211        // Perform additional 'setup' on each subsession, before playing them:
     212        madeProgress = false;
     213        iter.reset();
     214        while ((subsession = iter.next()) != NULL)
     215        {
     216        if (subsession->clientPortNum() == 0) continue; // port # was not set
     217
     218
     219            if (rtspClient->setupMediaSubsession(*subsession, False, false))
     220        {
     221                madeProgress = True;
     222                }
     223                else
     224                {       
     225                        VERBOSE(VB_IMPORTANT, QString("Freebox # Failed to setup: %1 %2 : %3").arg(subsession->mediumName()).arg(subsession->codecName()).arg(env->getResultMsg()));
     226        }
     227        }
     228 
     229 
     230        if (!madeProgress) shutdown();
     231 
     232 
     233        // Create and start "FileSink"s for each subsession:
     234        // FileSink while receive Mpeg2 TS Data & will feed them to mythtv
     235        madeProgress = False;
     236        iter.reset();
     237        while ((subsession = iter.next()) != NULL)
     238        {
     239                if (subsession->readSource() == NULL) continue; // was not initiated
     240
     241                FreeboxSink* FreeboxSink = FreeboxSink::createNew(*env, this);
     242           
     243        subsession->sink = FreeboxSink;
     244                if (subsession->sink == NULL)
     245                {
     246                        VERBOSE(VB_IMPORTANT, QString("Freebox # Failed to create sink: %1").arg(env->getResultMsg()));
     247                }
     248               
     249            subsession->sink->startPlaying(*(subsession->readSource()),  subsessionAfterPlaying, new FreeboxData(this, subsession));
     250           
     251            if (subsession->rtcpInstance() != NULL) {
     252                        subsession->rtcpInstance()->setByeHandler(subsessionByeHandler, new FreeboxData(this, subsession));
     253                }
     254
     255            madeProgress = True;
     256        }
     257
     258        if (!madeProgress) shutdown();
     259
     260        // Setup player
     261        if (!(rtspClient->playMediaSession(*session)))
     262        {
     263                VERBOSE(VB_IMPORTANT, QString("Freebox # Failed to start playing session: %1").arg(env->getResultMsg()));
     264                shutdown();
     265        }
     266
     267
     268        request_pause = false;
     269        paused = false;
     270        _request_recording = true;
     271        _recording = true;
     272        *_abort_rtsp=0;
     273
     274        // Go into main RTSP loop, feeding data to mythtv 
     275        env->taskScheduler().doEventLoop(_abort_rtsp); // does not return
     276
     277        // Event loop exists, the recording finish
     278        FinishRecording();
     279        _recording = false;
     280
     281
     282        // wakeUp everibody
     283        waitShutdown->wakeAll();
     284}
     285
     286
     287// ===================================================
     288// FindTSHeader : find a TS Header in flow
     289// ===================================================
     290int FreeboxRecorder::findTSHeader(unsigned char *data, unsigned dataSize)
     291{
     292    unsigned int pos = 0;
     293   
     294    while (pos < dataSize)
     295    {
     296        if (data[pos] == 0x47)
     297                return pos;
     298                pos++;
     299    }
     300    return -1;
     301}
     302
     303// ===================================================
     304// addData : feed date from RTSP flow to mythtv
     305// ===================================================
     306void FreeboxRecorder::addData(unsigned char* data, unsigned dataSize, struct timeval )
     307
     308        unsigned int readIndex = 0;
     309       
     310        // data may be compose from more than one packet, loop to consume all data
     311    while (readIndex < dataSize)
     312    {
     313        // If recorder is pause, stop there
     314        if (PauseAndWait())
     315        {
     316                return;
     317        }
     318
     319               
     320        // Find the next TS Header in data
     321        int tsPos = findTSHeader(data + readIndex, dataSize);
     322       
     323        // if no TS, something bad happens
     324        if (tsPos == -1)
     325        {
     326                VERBOSE(VB_IMPORTANT, QString("FREEBOX: No TS header."));
     327                break;
     328                }
     329     
     330        // if TS Header not at start of data, we receive out of sync data
     331                if (tsPos > 0)
     332                {
     333                VERBOSE(VB_IMPORTANT, QString("FREEBOX: TS header at %1, not in sync.").arg(tsPos));
     334            }
     335
     336                // Check if the next packet in buffer is complete : packet size is 188 bytes long
     337                if ((dataSize - tsPos) < 188)
     338                {
     339                VERBOSE(VB_IMPORTANT, QString("FREEBOX: TS header at %1 but packet not yet complete.").arg(tsPos));
     340                        break;
     341            }
     342       
     343                // Cast current found TS Packet to TSPacket structure
     344            const void     *newData     = data + tsPos + readIndex;
     345            const TSPacket *tspacket = reinterpret_cast<const TSPacket*>(newData);
     346
     347                // Feed current packet to myth
     348                _buffer_packets = !FindKeyframes(tspacket);
     349                BufferedWrite(*tspacket);
     350               
     351                // follow to next packet
     352                readIndex += tsPos + TSPacket::SIZE;
     353               
     354        }
     355}
     356
     357
     358void FreeboxRecorder::shutdown(int )
     359{
     360}
     361
     362
     363void subsessionAfterPlaying(void *clientData)
     364{
     365        FreeboxData *myData = (FreeboxData*)clientData;
     366        myData->freeboxRecorder->SubsessionAfterPlaying(myData->mediaSubSession);
     367}
     368
     369void subsessionByeHandler(void *clientData)
     370{
     371        FreeboxData *myData = (FreeboxData*)clientData;
     372        myData->freeboxRecorder->SubsessionByeHandler(myData->mediaSubSession);
     373}
     374
     375void FreeboxRecorder::SubsessionAfterPlaying(MediaSubsession* subsession)
     376{
     377        Medium::close(subsession->sink);
     378        subsession->sink = NULL;
     379
     380        MediaSession& session = subsession->parentSession();
     381        MediaSubsessionIterator iter(session);
     382        while ((subsession = iter.next()) != NULL)
     383        {
     384            if (subsession->sink != NULL) return;
     385        }
     386
     387        shutdown(0);
     388
     389}
     390
     391
     392void FreeboxRecorder::SubsessionByeHandler(MediaSubsession* subsession)
     393{
     394        subsessionAfterPlaying(subsession);
     395}
     396
     397
     398// ==================================================================================================
     399// FreeboxSink : Helper class use to receive RTSP data from socket.
     400// ==================================================================================================
     401
     402FreeboxSink::FreeboxSink(UsageEnvironment& pEnv, FreeboxRecorder *pRecorder) : MediaSink(pEnv)
     403{
     404        recorder = pRecorder;
     405        env = &pEnv;
     406       
     407        // Setup the data buffer
     408        fBufferSize = 20000;
     409        fBuffer = new unsigned char[fBufferSize];
     410}
     411
     412FreeboxSink::~FreeboxSink()
     413{
     414        // free the data buffer
     415        delete[] fBuffer;
     416}
     417
     418FreeboxSink* FreeboxSink::createNew(UsageEnvironment& env, FreeboxRecorder *pRecorder)
     419{
     420  FreeboxSink* newSink = new FreeboxSink(env, pRecorder);
     421  return newSink;
     422}
     423
     424Boolean FreeboxSink::continuePlaying()
     425{
     426  if (fSource == NULL) return False;
     427
     428  fSource->getNextFrame(fBuffer, fBufferSize, afterGettingFrame, this, onSourceClosure, this);
     429
     430  return True;
     431}
     432
     433void FreeboxSink::afterGettingFrame(void* clientData, unsigned frameSize, unsigned /*numTruncatedBytes*/,struct timeval presentationTime, unsigned /*durationInMicroseconds*/)
     434{
     435
     436  FreeboxSink* sink = (FreeboxSink*)clientData;
     437  sink->afterGettingFrame1(frameSize, presentationTime);
     438
     439
     440void FreeboxSink::afterGettingFrame1(unsigned frameSize, struct timeval presentationTime)
     441{
     442        addData(fBuffer, frameSize, presentationTime);
     443    continuePlaying();
     444}
     445
     446void FreeboxSink::addData(unsigned char* data, unsigned dataSize, struct timeval presentationTime)
     447
     448        recorder->addData(data, dataSize, presentationTime);
     449}
     450
     451
     452
     453
     454
     455
     456
     457
  • mythtv/libs/libmythtv/freeboxrecorder.h

    diff -ru --new-file --exclude=.svn myth-org/mythtv/libs/libmythtv/freeboxrecorder.h myth-patch/mythtv/libs/libmythtv/freeboxrecorder.h
    old new  
     1/**
     2 *  DBOX2Recorder
     3 *  Copyright (c) 2005 by Levent Gündogdu
     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#include <time.h>
     12#include "freeboxchannel.h"
     13#include "sitypes.h"
     14#include "qhttp.h"
     15#include "mpeg/tspacket.h"
     16
     17
     18#include "BasicUsageEnvironment.hh"
     19#include "GroupsockHelper.hh"
     20#include "liveMedia.hh"
     21
     22/**
     23
     24 *
     25 *  Constructs a FreeboxRecorder
     26 *
     27 */
     28
     29#if defined(__WIN32__) || defined(_WIN32)
     30#define snprintf _snprintf
     31#else
     32#include <signal.h>
     33#define USE_SIGNALS 1
     34#endif
     35
     36
     37
     38class FreeboxRecorder : public DTVRecorder
     39{
     40    Q_OBJECT
     41    public:
     42        FreeboxRecorder(TVRec *rec, FreeboxChannel *channel);
     43        ~FreeboxRecorder() {  }
     44
     45
     46                void StartRecording(void);
     47                void StopRecording(void);
     48                bool Open(void);
     49                void Close();
     50       
     51                void SetOptionsFromProfile(RecordingProfile *profile,
     52                                   const QString &videodev,
     53                                   const QString &audiodev,
     54                                   const QString &vbidev);
     55
     56                void SubsessionAfterPlaying(MediaSubsession* subsession);
     57                void SubsessionByeHandler(MediaSubsession* subsession);
     58
     59                // Callback function to add MPEG2 TS data
     60                void addData(unsigned char* data, unsigned dataSize, struct timeval presentationTime);
     61               
     62                // Look for TS Header in data
     63                int findTSHeader(unsigned char *data, unsigned dataSize);
     64
     65       
     66    public slots:
     67        void ChannelChanged();
     68               
     69 
     70        private:
     71                UsageEnvironment* env;
     72                RTSPClient* rtspClient;
     73                MediaSession* session;
     74
     75                // var to check if we need to abort current rtsp session
     76                char* _abort_rtsp;
     77
     78                // request abort for StartRecording Thread         
     79                bool _request_abort;
     80               
     81                // Call back function to start RTSP Flow
     82                static void *StartRtspS(void *param);
     83                void StartRtsp();
     84
     85                void shutdown(int exitCode = 1);
     86
     87                // Current channel         
     88                FreeboxChannel *m_channel;
     89               
     90                // Mutex : use to make sure that current RTSP thread as stop
     91                QWaitCondition *waitShutdown;
     92         
     93                // The current RTSP thread
     94                pthread_t start_thread;
     95};
     96
     97
     98// ==================================================================================================
     99// FreeboxData : Helper class use for static Callback handler
     100// ==================================================================================================
     101class FreeboxData
     102{
     103        public:
     104                FreeboxData(FreeboxRecorder *pFreeboxRecorder, MediaSubsession *pMediaSubSession)
     105                {
     106                        freeboxRecorder = pFreeboxRecorder;
     107                        mediaSubSession = pMediaSubSession;
     108                }
     109       
     110        FreeboxRecorder *freeboxRecorder;
     111        MediaSubsession *mediaSubSession;
     112};
     113
     114
     115// ==================================================================================================
     116// FreeboxSink : Helper class use to receive RTSP data from socket.
     117// ==================================================================================================
     118class FreeboxSink: public MediaSink {
     119        public:
     120                static FreeboxSink* createNew(UsageEnvironment& env, FreeboxRecorder *pRecorder);
     121       
     122                // Callback function when rtsp data are ready
     123                void addData(unsigned char* data, unsigned dataSize, struct timeval presentationTime);
     124       
     125        protected:
     126                FreeboxSink(UsageEnvironment& env, FreeboxRecorder *pRecorder);
     127                virtual ~FreeboxSink();
     128       
     129                static void afterGettingFrame(void* clientData, unsigned frameSize, unsigned numTruncatedBytes, struct timeval presentationTime, unsigned durationInMicroseconds);
     130                virtual void afterGettingFrame1(unsigned frameSize, struct timeval presentationTime);
     131       
     132        private:
     133                virtual Boolean continuePlaying();
     134         
     135                  unsigned char* fBuffer;
     136                  unsigned fBufferSize;
     137                UsageEnvironment *env;
     138                FreeboxRecorder *recorder;
     139                int bufferIndex;
     140         
     141};
     142#endif
  • mythtv/libs/libmythtv/libmythtv.pro

    diff -ru --new-file --exclude=.svn myth-org/mythtv/libs/libmythtv/libmythtv.pro myth-patch/mythtv/libs/libmythtv/libmythtv.pro
    old new  
    332332    # Support for set top boxes (Nokia DBox2 etc.)
    333333    using_dbox2:SOURCES += dbox2recorder.cpp dbox2channel.cpp dbox2epg.cpp
    334334    using_dbox2:HEADERS += dbox2recorder.h dbox2channel.h dbox2epg.h
     335   
     336    using_freebox:SOURCES += freeboxrecorder.cpp freeboxchannel.cpp
     337    using_freebox:HEADERS += freeboxrecorder.h freeboxchannel.h
    335338
    336339    # Support for PVR-150/250/350/500, etc. on Linux
    337340    using_ivtv:HEADERS += mpegrecorder.h
  • mythtv/libs/libmythtv/tv_rec.cpp

    diff -ru --new-file --exclude=.svn myth-org/mythtv/libs/libmythtv/tv_rec.cpp myth-patch/mythtv/libs/libmythtv/tv_rec.cpp
    old new  
    7373#include "dbox2channel.h"
    7474#endif
    7575
     76#ifdef USING_FREEBOX
     77#include "freeboxrecorder.h"
     78#include "freeboxchannel.h"
     79#endif
     80
     81
    7682#define DEBUG_CHANNEL_PREFIX 0 /**< set to 1 to channel prefixing */
    7783
    7884#define LOC QString("TVRec(%1): ").arg(cardid)
     
    185191        init_run = true;
    186192#endif
    187193    }
     194else if (genOpt.cardtype == "FREEBOX")
     195    {
     196        VERBOSE(VB_IMPORTANT,QString("trye to alloc chan"));
     197#ifdef USING_FREEBOX
     198        channel = new FreeboxChannel(this, &freeboxOpt, cardid);
     199        channel->Open();
     200        InitChannel(genOpt.defaultinput, startchannel);
     201        init_run = true;
     202        VERBOSE(VB_IMPORTANT,QString("end trye to alloc chan"));
     203#endif
     204    }   
    188205    else if (genOpt.cardtype == "MPEG" &&
    189206             genOpt.videodev.lower().left(5) == "file:")
    190207    {
     
    232249{
    233250    QMutexLocker lock(&stateChangeLock);
    234251
    235     if (!GetDevices(cardid, genOpt, dvbOpt, fwOpt, dboxOpt))
     252    if (!GetDevices(cardid, genOpt, dvbOpt, fwOpt, dboxOpt, freeboxOpt))
    236253        return false;
    237254
    238255    QString startchannel = GetStartChannel(cardid, genOpt.defaultinput);
     
    299316        GetDBox2Channel()->deleteLater();
    300317    else
    301318#endif // USING_DBOX2
     319#ifdef USING_FREEBOX
     320        if (GetFreeboxChannel())
     321        GetFreeboxChannel()->deleteLater();
     322        else
     323#endif // USING_FREEBOX
    302324    if (channel)
    303325        delete channel;
    304326    channel = NULL;
     
    861883        recorder->SetOption("httpport", dboxOpt.httpport);
    862884#endif // USING_DBOX2
    863885    }
     886    else if (genOpt.cardtype == "FREEBOX")
     887    {
     888#ifdef USING_FREEBOX
     889        recorder = new FreeboxRecorder(this, GetFreeboxChannel());
     890        recorder->SetOption("host",     freeboxOpt.host);
     891#endif // USING_FREEBOX
     892    }
    864893    else if (genOpt.cardtype == "DVB")
    865894    {
    866895#ifdef USING_DVB
     
    10671096    return NULL;
    10681097#endif // USING_DBOX2
    10691098}
     1099FreeboxChannel *TVRec::GetFreeboxChannel(void)
     1100{
     1101#ifdef USING_FREEBOX
     1102    return dynamic_cast<FreeboxChannel*>(channel);
     1103#else
     1104    return NULL;
     1105#endif // USING_FREEBOX
     1106}
     1107
    10701108
     1109 
     1110 
    10711111DVBChannel *TVRec::GetDVBChannel(void)
    10721112{
    10731113#ifdef USING_DVB
     
    14041444                       GeneralDBOptions  &gen_opts,
    14051445                       DVBDBOptions      &dvb_opts,
    14061446                       FireWireDBOptions &firewire_opts,
    1407                        DBox2DBOptions    &dbox2_opts)
     1447                       DBox2DBOptions    &dbox2_opts,
     1448                       FreeboxDBOptions  &freebox_opts)
    14081449{
    14091450    int testnum = 0;
    14101451    QString test;
     
    14211462        "       firewire_port,    firewire_node,       firewire_speed,  "
    14221463        "       firewire_model,   firewire_connection,                  "
    14231464        ""
    1424         "       dbox2_port,       dbox2_host,          dbox2_httpport   "
     1465        "       dbox2_port,       dbox2_host,          dbox2_httpport,  "
     1466        "               freebox_host "
    14251467        ""
    14261468        "FROM capturecard "
    14271469        "WHERE cardid = :CARDID");
     
    14991541
    15001542    dbox2_opts.httpport = query.value(dbox2off + 2).toUInt();
    15011543
     1544    // Freebox options
     1545    uint freeboxoff = dbox2off + 3;
     1546    test = query.value(freeboxoff).toString();
     1547    if (test != QString::null)
     1548           freebox_opts.host = QString::fromUtf8(test);
     1549
     1550
    15021551    return true;
    15031552}
    15041553
     
    35493598        delete channel;
    35503599        channel = NULL;
    35513600
    3552         GetDevices(newCardID, genOpt, dvbOpt, fwOpt, dboxOpt);
     3601        GetDevices(newCardID, genOpt, dvbOpt, fwOpt, dboxOpt, freeboxOpt);
    35533602        genOpt.defaultinput = inputname;
    35543603        CreateChannel(channum);
    35553604        if (!(request.flags & kFlagNoRec))
  • mythtv/libs/libmythtv/tv_rec.h

    diff -ru --new-file --exclude=.svn myth-org/mythtv/libs/libmythtv/tv_rec.h myth-patch/mythtv/libs/libmythtv/tv_rec.h
    old new  
    3838class DVBChannel;
    3939class Channel;
    4040
     41class FreeboxChannel;
     42
     43
    4144class MPEGStreamData;
    4245class ProgramMapTable;
    4346
     
    129132    QString host;
    130133};
    131134
     135 
     136class FreeboxDBOptions
     137{
     138        public:
     139            FreeboxDBOptions() : host("mafreebox.freebox.fr") {;}
     140
     141        QString host;
     142};
     143
     144
     145
    132146class TuningRequest
    133147{
    134148  public:
     
    271285                           GeneralDBOptions   &general_opts,
    272286                           DVBDBOptions       &dvb_opts,
    273287                           FireWireDBOptions  &firewire_opts,
    274                            DBox2DBOptions     &dbox2_opts);
     288                           DBox2DBOptions     &dbox2_opts,
     289                           FreeboxDBOptions       &free_opts);
    275290
    276291
    277292    static QString GetStartChannel(int cardid, const QString &defaultinput);
     
    284299    bool CreateChannel(const QString &startChanNum);
    285300    void InitChannel(const QString &inputname, const QString &startchannel);
    286301    void CloseChannel(void);
     302   
     303   
    287304    DBox2Channel *GetDBox2Channel(void);
    288305    DVBChannel   *GetDVBChannel(void);
     306    FreeboxChannel *GetFreeboxChannel(void);
    289307    Channel      *GetV4LChannel(void);
    290308
    291309    void SetupSignalMonitor(bool enable_table_monitoring, bool notify);
     
    368386    DVBDBOptions      dvbOpt;
    369387    FireWireDBOptions fwOpt;
    370388    DBox2DBOptions    dboxOpt;
     389    FreeboxDBOptions  freeboxOpt;
    371390
    372391    // State variables
    373392    QMutex         stateChangeLock;
  • mythtv/libs/libmythtv/videosource.cpp

    diff -ru --new-file --exclude=.svn myth-org/mythtv/libs/libmythtv/videosource.cpp myth-patch/mythtv/libs/libmythtv/videosource.cpp
    old new  
    928928 };
    929929
    930930
     931class FreeboxHost : public LineEditSetting, public CCSetting {
     932        public:
     933           FreeboxHost(const CaptureCard &parent):
     934           CCSetting(parent, "freebox_host") {
     935                        setValue("mafreebox.freebox.fr");
     936                        setLabel(QObject::tr("Freebox Host"));
     937            setHelpText(QObject::tr("The freebox host."));
     938        }
     939};
     940
     941class FreeboxConfigurationGroup: public VerticalConfigurationGroup {
     942public:
     943   FreeboxConfigurationGroup(CaptureCard& a_parent):
     944           ConfigurationGroup(false, true, false, false),
     945       VerticalConfigurationGroup(false, true, false, false),
     946       parent(a_parent) {
     947       setUseLabel(false);
     948       addChild(new FreeboxHost(parent));
     949   };
     950  private:
     951     CaptureCard& parent;
     952 };
     953                     
    931954
    932955
    933956class V4LConfigurationGroup: public VerticalConfigurationGroup
     
    10251048    addTarget("MPEG", new MPEGConfigurationGroup(parent));
    10261049    addTarget("FIREWIRE", new FirewireConfigurationGroup(parent));
    10271050    addTarget("DBOX2", new DBOX2ConfigurationGroup(parent));
     1051    addTarget("FREEBOX", new FreeboxConfigurationGroup(parent));
    10281052}
    10291053
    10301054void CaptureCardGroup::triggerChanged(const QString& value)
     
    10591083    QString qstr =
    10601084        "SELECT cardtype, videodevice, cardid, "
    10611085        "       firewire_port, firewire_node, "
    1062         "       dbox2_port, dbox2_host, dbox2_httpport "
     1086        "       dbox2_port, dbox2_host, dbox2_httpport, freebox_host "
    10631087        "FROM capturecard "
    10641088        "WHERE hostname = :HOSTNAME";
    10651089    if (no_children)
     
    10891113                    "Streaming-Port: " + query.value(5).toString() + ", " +
    10901114                    "Http-Port: " + query.value(7).toString() +
    10911115                    "] ", query.value(2).toString());
    1092             }
     1116        }
     1117            else if (query.value(0).toString() == "FREEBOX")
     1118            {
     1119                setting->addSelection(
     1120                    "[ " + query.value(0).toString() + " " +
     1121                    "HOST: " + query.value(8).toString() +  " " +
     1122                    "] ", query.value(2).toString());
     1123          }
    10931124            else
    10941125            {
    10951126                setting->addSelection(
     
    11351166        "GO7007");
    11361167    setting->addSelection(
    11371168        QObject::tr("DBox2 TCP/IP cable box"), "DBOX2");
     1169    setting->addSelection(
     1170        QObject::tr("Freebox"), "FREEBOX");
    11381171}
    11391172
    11401173class CardID: public SelectLabelSetting, public CISetting {
     
    19431976    // SelectSetting provided a facility to edit the labels, we
    19441977    // could use CaptureCard::fillSelections
    19451978
     1979
    19461980    MSqlQuery query(MSqlQuery::InitCon());
    19471981    query.prepare(
    19481982        "SELECT cardid, videodevice, cardtype "
  • mythtv/programs/mythbackend/version.cpp

    diff -ru --new-file --exclude=.svn myth-org/mythtv/programs/mythbackend/version.cpp myth-patch/mythtv/programs/mythbackend/version.cpp
    old new  
     1const char *myth_source_version = "9647M";
  • mythtv/programs/mythfrontend/version.cpp

    diff -ru --new-file --exclude=.svn myth-org/mythtv/programs/mythfrontend/version.cpp myth-patch/mythtv/programs/mythfrontend/version.cpp
    old new  
     1const char *myth_source_version = "9647M";
  • mythtv/settings.pro

    diff -ru --new-file --exclude=.svn myth-org/mythtv/settings.pro myth-patch/mythtv/settings.pro
    old new  
    2020
    2121INCLUDEPATH += $${PREFIX}/include
    2222INCLUDEPATH += $$CONFIG_INCLUDEPATH
     23INCLUDEPATH += /usr/lib/live/liveMedia/include
     24INCLUDEPATH += /usr/lib/live/UsageEnvironment/include
     25INCLUDEPATH += /usr/lib/live/BasicUsageEnvironment/include
     26INCLUDEPATH += /usr/lib/live/groupsock/include
    2327
    2428# figure out compile flags based on qmake info
    2529
     
    7276}
    7377QMAKE_LIBDIR_OPENGL =
    7478
    75 EXTRA_LIBS = -lfreetype -lmp3lame
     79EXTRA_LIBS = -lfreetype -lmp3lame -L /usr/lib/live/liveMedia -lliveMedia -L/usr/lib/live/UsageEnvironment -lUsageEnvironment -L/usr/lib/live/groupsock -lgroupsock -L/usr/lib/live/BasicUsageEnvironment -lBasicUsageEnvironment
    7680EXTRA_LIBS += $$CONFIG_AUDIO_OSS_LIBS
    7781EXTRA_LIBS += $$CONFIG_AUDIO_ALSA_LIBS
    7882EXTRA_LIBS += $$CONFIG_AUDIO_ARTS_LIBS