Ticket #1704: patch.freebox.v1.28.10247.diff

File patch.freebox.v1.28.10247.diff, 48.0 KB (added by mythtv@…, 14 years ago)
  • configure

     
    5454lirc="yes"
    5555joystick_menu="yes"
    5656firewire_cable_box="yes"
     57freebox_box="yes"
    5758dbox2_dvb_box="yes"
    5859ip_network_recorder="yes"
    5960hdhomerun_box="yes"
     
    178179echo "  --disable-lirc           disable lirc support (Infrared Remotes)"
    179180echo "  --disable-joystick-menu  disable joystick menu"
    180181echo "  --disable-firewire       disable support for FireWire cable boxes"
     182echo "  --disable-freebox        disable support for Freebox"
     183echo "  --livelibdir=DIR         location of Live streaming library"
     184echo "  --liveincludedir=DIR     location of Live streaming include files"
    181185echo "  --disable-dbox2          disable support for Nokia DBOX2 DVB boxes (or compatibles)"
    182186echo "  --disable-hdhomerun      disable support for HDHomeRun boxes"
    183187echo "  --disable-crciprec       disable support for Network Recorder"
     
    819823  ;;
    820824  --disable-dbox2) dbox2_dvb_box="no"
    821825  ;;
     826  --enable-freebox) freebox_box="yes"
     827  ;;
     828  --disable-freebox) freebox_box="no"
     829  ;;
     830  --livelibdir=*) live_lib_dir=`echo $opt | cut -d '=' -f 2`
     831  ;;
     832  --liveincludedir=*) live_include_dir=`echo $opt | cut -d '=' -f 2`
     833  ;;
    822834  --enable-hdhomerun) hdhomerun_box="yes"
    823835  ;;
    824836  --disable-hdhomerun) hdhomerun_box="no"
     
    20412053    fi
    20422054fi
    20432055
     2056if test x"$freebox_box" = x"yes" ; then
     2057    if test x"$live_lib_dir" = x""; then
     2058        if has_library libliveMedia; then
     2059            CONFIG_LIVE_LIBS="-lliveMedia -lgroupsock -lBasicUsageEnvironment -lUsageEnvironment"
     2060        else
     2061            echo "Unable to find Live Media library."
     2062            freebox_box="no"
     2063        fi
     2064    else
     2065        if test ! -f "$live_lib_dir/liveMedia/libliveMedia.a"; then
     2066            echo "Unable to find Live Media library."
     2067            freebox_box="no"
     2068        fi
     2069        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"
     2070    fi
     2071    if test "x$live_include_dir" = "x"; then
     2072        if has_header liveMedia.hh; then
     2073            true
     2074        else
     2075            echo "Unable to find Live Media headers."
     2076            freebox_box="no"
     2077        fi
     2078    else
     2079        if test -f "$live_include_dir/liveMedia/include/liveMedia.hh"; then
     2080            LIVE_INCLUDES="$live_include_dir/liveMedia/include $live_include_dir/UsageEnvironment/include $live_include_dir/BasicUsageEnvironment/include $live_include_dir/groupsock/include"
     2081        else
     2082            if test -f "$live_include_dir/liveMedia/liveMedia.hh"; then
     2083                LIVE_INCLUDES="$live_include_dir/liveMedia $live_include_dir/UsageEnvironment $live_include_dir/BasicUsageEnvironment $live_include_dir/groupsock"
     2084            else
     2085                echo "Unable to find Live Media headers."
     2086                freebox_box="no"
     2087            fi
     2088        fi
     2089    fi
     2090fi
     2091
    20442092lamemp3="no"
    20452093if has_library libmp3lame ; then
    20462094    if has_header lame/lame.h ; then
     
    23272375  echo "FireWire support $firewire_cable_box"
    23282376  echo "DVB support      $dvb [$dvb_path]"
    23292377  echo "DBox2 support    $dbox2_dvb_box"
     2378  echo "freebox support  $freebox_box"
    23302379  echo "HDHomeRun sup.   $hdhomerun_box"
    23312380  echo "CRC Ip Rec sup.  $ip_network_recorder"
    23322381fi
     
    29903039  CCONFIG="$CCONFIG using_ip_rec"
    29913040fi
    29923041
     3042if test x"$freebox_box" = x"yes" ; then
     3043    CCONFIG="$CCONFIG using_freebox"
     3044    CONFIG_DEFINES="$CONFIG_DEFINES USING_FREEBOX"
     3045    echo "CONFIG_LIVE_LIBS=$CONFIG_LIVE_LIBS" >> $MYTH_CONFIG_MAK
     3046    CONFIG_INCLUDEPATH="$CONFIG_INCLUDEPATH $LIVE_INCLUDES"
     3047fi
     3048
    29933049if test x"$lirc" = x"yes" ; then
    29943050  CCONFIG="$CCONFIG using_lirc"
    29953051  echo "CONFIG_LIRC_LIBS=-llirc_client" >> $MYTH_CONFIG_MAK
  • libs/libmythtv/freeboxchannel.h

     
     1/** -*- Mode: c++ -*-
     2 *  FreeboxChannel
     3 *  Copyright (c) 2006 by Laurent Arnal, Benjamin Lerman & Mickaël Remars
     4 *  Distributed as part of MythTV under GPL v2 and later.
     5 */
     6
     7#ifndef FREEBOXCHANNEL_H
     8#define FREEBOXCHANNEL_H
     9
     10#include "channelbase.h"
     11#include "freeboxchannelinfo.h"
     12
     13#include <qmutex.h>
     14
     15class FreeboxRecorder;
     16
     17class FreeboxChannel : public ChannelBase
     18{
     19    friend class FreeboxRecorderImpl;
     20  public:
     21    FreeboxChannel(TVRec *parent, const QString &videodev, int cardid);
     22    ~FreeboxChannel(void) { }
     23
     24    bool Open(void);
     25    void Close(void);
     26
     27    bool IsOpen(void) const;
     28
     29    bool SwitchToInput(const QString &inputname, const QString &channum);
     30    bool SwitchToInput(int inputNum, bool setstarting);
     31    bool SetChannelByString(const QString &channum);
     32
     33    void SetRecorder(FreeboxRecorder *rec);
     34
     35  private:
     36    FreeboxChannelInfo GetChanInfo(const QString& channum,
     37                                   uint           sourceid = 0) const;
     38    FreeboxChannelInfo GetCurrentChanInfo(void) const
     39        { return GetChanInfo(curchannelname); }
     40
     41    QString               m_videodev;
     42    FreeboxRecorder      *m_recorder;
     43    fbox_chan_map_t       m_freeboxchannels;
     44    mutable QMutex        m_lock;
     45    int                   m_cardid;
     46
     47  private:
     48    FreeboxChannel& operator=(const FreeboxChannel&); //< avoid default impl
     49    FreeboxChannel(const FreeboxChannel&);            //< avoid default impl
     50    FreeboxChannel();                                 //< avoid default impl
     51};
     52
     53#endif // FREEBOXCHANNEL_H
     54
     55/* vim: set expandtab tabstop=4 shiftwidth=4: */
  • libs/libmythtv/freeboxchannelfetcher.h

     
     1#ifndef _FREEBOXCHANNELFETCHER_H_
     2#define _FREEBOXCHANNELFETCHER_H_
     3
     4#include "freeboxchannelinfo.h"
     5
     6class FreeboxChannelFetcher
     7{
     8  private:
     9    FreeboxChannelFetcher();
     10    ~FreeboxChannelFetcher();
     11
     12  public:
     13    static QString DownloadPlaylist(const QString& url);
     14    static fbox_chan_map_t ParsePlaylist(const QString& rawdata);
     15};
     16
     17#endif//_FREEBOXCHANNELFETCHER_H_
     18
     19/* vim: set expandtab tabstop=4 shiftwidth=4: */
  • libs/libmythtv/libmythtv.pro

     
    374374    using_dbox2:SOURCES += dbox2recorder.cpp dbox2channel.cpp dbox2epg.cpp
    375375    using_dbox2:HEADERS += dbox2recorder.h dbox2channel.h dbox2epg.h
    376376    using_dbox2:DEFINES += USING_DBOX2
     377   
     378    # Support for freebox (http://adsl.free.fr/)
     379    using_freebox:SOURCES += freeboxrecorder.cpp
     380    using_freebox:SOURCES += freeboxchannel.cpp
     381    using_freebox:SOURCES += freeboxchannelfetcher.cpp
     382    using_freebox:SOURCES += freeboxmediasink.cpp
     383    using_freebox:HEADERS += freeboxrecorder.h
     384    using_freebox:HEADERS += freeboxchannel.h
     385    using_freebox:HEADERS += freeboxchannelfetcher.h
     386    using_freebox:HEADERS += freeboxchannelinfo.h
     387    using_freebox:HEADERS += freeboxmediasink.h
     388    using_freebox:DEFINES += USING_FREEBOX
    377389
    378390    # Support for HDHomeRun box
    379391    using_hdhr {
  • libs/libmythtv/freeboxchannel.cpp

     
     1/** -*- Mode: c++ -*-
     2 *  FreeboxChannel
     3 *  Copyright (c) 2006 by Laurent Arnal, Benjamin Lerman & Mickaël Remars
     4 *  Distributed as part of MythTV under GPL v2 and later.
     5 */
     6
     7#include "freeboxchannel.h"
     8
     9#include "libmythtv/freeboxchannelfetcher.h"
     10#include "libmythtv/freeboxrecorder.h"
     11#include "libmythtv/tv_rec.h"
     12
     13#define LOC QString("FBChan(%1): ").arg(GetCardID())
     14#define LOC_ERR QString("FBChan(%1), Error: ").arg(GetCardID())
     15
     16FreeboxChannel::FreeboxChannel(TVRec*         parent,
     17                               const QString& videodev,
     18                               int            cardid)
     19    : ChannelBase(parent),
     20      m_videodev(videodev),
     21      m_recorder(NULL),
     22      m_lock(TRUE),
     23      m_cardid(cardid)
     24{
     25}
     26
     27bool FreeboxChannel::Open(void)
     28{
     29    QMutexLocker locker(&m_lock);
     30
     31    if (!InitializeInputs())
     32    {
     33        VERBOSE(VB_IMPORTANT, LOC_ERR +
     34            QString("InitializeInputs() failed"));
     35        return false;
     36    }
     37   
     38    if (m_freeboxchannels.size() == 0)
     39    {
     40        QString content = FreeboxChannelFetcher::DownloadPlaylist(m_videodev);
     41        m_freeboxchannels = FreeboxChannelFetcher::ParsePlaylist(content);
     42        VERBOSE(VB_IMPORTANT, LOC + QString("Loaded %1 channels from %2")
     43            .arg(m_freeboxchannels.size())
     44            .arg(m_videodev));
     45    }
     46
     47    return IsOpen();
     48}
     49
     50void FreeboxChannel::Close(void)
     51{
     52    QMutexLocker locker(&m_lock);
     53    m_freeboxchannels.clear();
     54}
     55
     56bool FreeboxChannel::IsOpen(void) const
     57{
     58    QMutexLocker locker(&m_lock);
     59    return m_freeboxchannels.size() > 0;
     60}
     61
     62bool FreeboxChannel::SwitchToInput(const QString &inputname,
     63                                   const QString &channum)
     64{
     65    QMutexLocker locker(&m_lock);
     66
     67    int inputNum = GetInputByName(inputname);
     68    if (inputNum < 0)
     69        return false;
     70
     71    return SetChannelByString(channum);
     72}
     73
     74bool FreeboxChannel::SwitchToInput(int inputNum, bool setstarting)
     75{
     76    QMutexLocker locker(&m_lock);
     77
     78    InputMap::const_iterator it = inputs.find(inputNum);
     79    if (it == inputs.end())
     80        return false;
     81
     82    QString channum = (*it)->startChanNum;
     83
     84    if (setstarting)
     85        return SetChannelByString(channum);
     86
     87    return true;
     88}
     89
     90bool FreeboxChannel::SetChannelByString(const QString &channum)
     91{
     92    QMutexLocker locker(&m_lock);
     93
     94    // Verify that channel exists
     95    if (!GetChanInfo(channum).isValid())
     96    {
     97        VERBOSE(VB_IMPORTANT, LOC_ERR +
     98                QString("SetChannelByString(%1)").arg(channum) +
     99                " Invalid channel");
     100        return false;
     101    }
     102
     103    // Set the channel..
     104    curchannelname = channum;
     105
     106    // Send signal to recorder that channel has changed.
     107    if (m_recorder)
     108    {
     109        FreeboxChannelInfo chaninfo(GetCurrentChanInfo());
     110        m_recorder->ChannelChanged(chaninfo);
     111    }
     112
     113    return true;
     114}
     115
     116FreeboxChannelInfo FreeboxChannel::GetChanInfo(const QString& channum,
     117                                               uint           sourceid) const
     118{
     119    QMutexLocker locker(&m_lock);
     120
     121    FreeboxChannelInfo dummy;
     122    QString msg = LOC_ERR + QString("GetChanInfo(%1) failed").arg(channum);
     123
     124    if (channum.isEmpty())
     125    {
     126        VERBOSE(VB_IMPORTANT, msg);
     127        return dummy;
     128    }
     129
     130    if (!sourceid)
     131    {
     132        InputMap::const_iterator it = inputs.find(currentInputID);
     133        if (it == inputs.end())
     134        {
     135            VERBOSE(VB_IMPORTANT, msg);
     136            return dummy;
     137        }
     138        sourceid = (*it)->sourceid;
     139    }
     140
     141    MSqlQuery query(MSqlQuery::InitCon());
     142    query.prepare(
     143        "SELECT freqid, name "
     144        "FROM channel "
     145        "WHERE channum  = :CHANNUM AND "
     146        "      sourceid = :SOURCEID");
     147
     148    query.bindValue(":CHANNUM",  channum);
     149    query.bindValue(":SOURCEID", sourceid);
     150
     151    if (!query.exec() || !query.isActive())
     152    {
     153        MythContext::DBError("fetching chaninfo", query);
     154        VERBOSE(VB_IMPORTANT, msg);
     155        return dummy;
     156    }
     157
     158    while (query.next())
     159    {
     160        // Try to map freqid or name to a channel in the map
     161        const QString freqid = query.value(0).toString();
     162        fbox_chan_map_t::const_iterator it;
     163        if (!freqid.isEmpty())
     164        {
     165            it = m_freeboxchannels.find(freqid);
     166            if (it != m_freeboxchannels.end())
     167                return *it;
     168        }
     169
     170        // Try to map name to a channel in the map
     171        const QString name    = query.value(1).toString();
     172        for (it = m_freeboxchannels.begin();
     173             it != m_freeboxchannels.end(); ++it)
     174        {
     175            if ((*it).m_name == name)
     176                return *it;
     177        }
     178    }
     179
     180    VERBOSE(VB_IMPORTANT, msg);
     181    return dummy;
     182}
     183
     184void FreeboxChannel::SetRecorder(FreeboxRecorder *rec)
     185{
     186    QMutexLocker locker(&m_lock);
     187    m_recorder = rec;
     188}
     189
     190/* vim: set expandtab tabstop=4 shiftwidth=4: */
  • libs/libmythtv/freeboxmediasink.cpp

     
     1/**
     2 *  FreeboxMediaSink
     3 *  Copyright (c) 2006 by Laurent Arnal, Benjamin Lerman & Mickaël Remars
     4 *  Distributed as part of MythTV under GPL v2 and later.
     5 */
     6
     7#include "freeboxmediasink.h"
     8
     9#include "freeboxrecorder.h"
     10
     11
     12
     13FreeboxMediaSink::FreeboxMediaSink(UsageEnvironment& pEnv,
     14                                   FreeboxRecorder&  pRecorder,
     15                                   unsigned          bufferSize) :
     16    MediaSink(pEnv),
     17    fBufferSize(bufferSize),
     18    env(pEnv),
     19    recorder(pRecorder)
     20{
     21    // Setup the data buffer
     22    fBuffer = new unsigned char[fBufferSize];
     23}
     24
     25FreeboxMediaSink::~FreeboxMediaSink()
     26{
     27    // free the data buffer
     28    delete[] fBuffer;
     29}
     30
     31FreeboxMediaSink* FreeboxMediaSink::createNew(UsageEnvironment& env,
     32                                              FreeboxRecorder&  pRecorder,
     33                                              unsigned          bufferSize)
     34{
     35    return new FreeboxMediaSink(env, pRecorder, bufferSize);
     36}
     37
     38Boolean FreeboxMediaSink::continuePlaying()
     39{
     40    if (fSource == NULL) return False;
     41
     42    fSource->getNextFrame(fBuffer, fBufferSize,
     43                          afterGettingFrame, this,
     44                          onSourceClosure, this);
     45    return True;
     46}
     47
     48void FreeboxMediaSink::afterGettingFrame(
     49        void*          clientData,
     50        unsigned       frameSize,
     51        unsigned       /*numTruncatedBytes*/,
     52        struct timeval presentationTime,
     53        unsigned       /*durationInMicroseconds*/)
     54{
     55    FreeboxMediaSink* sink = (FreeboxMediaSink*)clientData;
     56    sink->afterGettingFrame1(frameSize, presentationTime);
     57}
     58
     59void FreeboxMediaSink::afterGettingFrame1(unsigned       frameSize,
     60                                          struct timeval presentationTime)
     61{
     62    addData(fBuffer, frameSize, presentationTime);
     63    continuePlaying();
     64}
     65
     66void FreeboxMediaSink::addData(unsigned char* data,
     67                               unsigned       dataSize,
     68                               struct timeval presentationTime)
     69{
     70    recorder.addData(data, dataSize, presentationTime);
     71}
     72
     73/* vim: set expandtab tabstop=4 shiftwidth=4: */
  • libs/libmythtv/dbcheck.cpp

     
    1010#include "mythdbcon.h"
    1111
    1212/// This is the DB schema version expected by the running MythTV instance.
    13 const QString currentDatabaseVersion = "1145";
     13const QString currentDatabaseVersion = "1146";
    1414
    1515static bool UpdateDBVersionNumber(const QString &newnumber);
    1616static bool performActualUpdate(const QString updates[], QString version,
     
    23082308//"ALTER TABLE capturecard DROP COLUMN dvb_hw_decoder;" in 0.21
    23092309//"ALTER TABLE cardinput DROP COLUMN  preference;" in 0.22
    23102310
     2311  if (dbver == "1145")
     2312    {
     2313        const QString updates[] = {
     2314"INSERT INTO profilegroups SET name = 'Freebox Input', cardtype = 'Freebox', is_default = 1;",
     2315""
     2316};
     2317
     2318        if (!performActualUpdate(updates, "1146", dbver))
     2319            return false;
     2320    }
     2321
     2322
    23112323    return true;
    23122324}
    23132325
     
    29342946"INSERT INTO profilegroups VALUES (8,"
    29352947" 'USB Mpeg-4 Encoder (Plextor ConvertX, etc)','GO7007',1,NULL);",
    29362948"INSERT INTO profilegroups VALUES (9,'DBOX2 Input','DBOX2',1,NULL);",
     2949"INSERT INTO `profilegroups` VALUES (10,'Freebox Input','Freebox',1,NULL);",
    29372950"INSERT INTO recordingprofiles VALUES (1,'Default',NULL,NULL,1);",
    29382951"INSERT INTO recordingprofiles VALUES (2,'Live TV',NULL,NULL,1);",
    29392952"INSERT INTO recordingprofiles VALUES (3,'High Quality',NULL,NULL,1);",
  • libs/libmythtv/freeboxchannelinfo.h

     
     1#ifndef _FREEBOXCHANNELINFO_H_
     2#define _FREEBOXCHANNELINFO_H_
     3
     4#include <qmap.h>
     5#include <qstring.h>
     6
     7class FreeboxChannelInfo
     8{
     9  public:
     10    FreeboxChannelInfo() : m_name(QString::null), m_url(QString::null) {}
     11
     12    FreeboxChannelInfo(const QString &name, const QString &url) :
     13        m_name(name), m_url(url) {}
     14
     15    bool isValid(void) const
     16    {
     17        return !m_name.isEmpty() && !m_url.isEmpty();
     18    }
     19
     20  public:
     21    QString m_name;
     22    QString m_url;
     23};
     24
     25typedef QMap<QString,FreeboxChannelInfo> fbox_chan_map_t;
     26
     27#endif //_FREEBOXCHANNELINFO_H_
     28
     29/* vim: set expandtab tabstop=4 shiftwidth=4: */
  • libs/libmythtv/freeboxchannelfetcher.cpp

     
     1#include "freeboxchannelfetcher.h"
     2
     3#include "libmyth/httpcomms.h"
     4#include "libmyth/mythcontext.h"
     5
     6#define LOC QString("FBChanFetch: ")
     7#define LOC_ERR QString("FBChanFetch, Error: ")
     8
     9QString FreeboxChannelFetcher::DownloadPlaylist(const QString& url)
     10{
     11    QString rwUrl(url);
     12    return QString::fromUtf8(HttpComms::getHttp(rwUrl));
     13}
     14
     15static bool parse_chan_info(const QString &line1,
     16                            QString &channum, QString &name)
     17{
     18    // each line contains ://
     19    // header:extension,channelNum - channelName rtsp://channelUrl
     20    //#EXTINF:0,2 - France 2 rtsp://mafreebox.freebox.fr/freeboxtv/201
     21
     22    QString msg = LOC_ERR +
     23        QString("Invalid header in channel list line \n\t\t\t%1").arg(line1);
     24
     25    channum = name = QString::null;
     26
     27    // Verify Line Header
     28    int pos = line1.find(":", 0);
     29    if ((pos < 0) || (line1.mid(0, pos) != "#EXTINF"))
     30    {
     31        VERBOSE(VB_IMPORTANT, msg);
     32        return false;
     33    }
     34
     35    // Parse extension portion
     36    pos = line1.find(",", pos + 1);
     37    if (pos < 0)
     38    {
     39        VERBOSE(VB_IMPORTANT, msg);
     40        return false;
     41    }
     42    //list.push_back(line1.mid(oldPos, pos - oldPos));
     43
     44    // Parse freebox channel number
     45    int oldpos = pos + 1;
     46    pos = line1.find(" ", pos + 1);
     47    if (pos < 0)
     48    {
     49        VERBOSE(VB_IMPORTANT, msg);
     50        return false;
     51    }
     52    channum = line1.mid(oldpos, pos - oldpos);
     53
     54    // Parse freebox channel name
     55    pos = line1.find("- ", pos + 1);
     56    if (pos < 0)
     57    {
     58        VERBOSE(VB_IMPORTANT, msg);
     59        return false;
     60    }
     61    name = line1.mid(pos + 2, line1.length());
     62
     63    return true;
     64}
     65
     66fbox_chan_map_t FreeboxChannelFetcher::ParsePlaylist(const QString& rawdata)
     67{
     68    fbox_chan_map_t chanmap;
     69
     70    // Verify header is ok
     71    QString header = rawdata.section("\n", 0, 0);
     72    if (header != "#EXTM3U")
     73    {
     74        VERBOSE(VB_IMPORTANT, LOC_ERR +
     75                QString("Invalid channel list header (%1)").arg(header));
     76
     77        return chanmap;
     78    }
     79
     80    // Parse each channel
     81    for (int i = 1; true; i += 2)
     82    {
     83        QString tmp = rawdata.section("\n", i+0, i+0);
     84        QString url = rawdata.section("\n", i+1, i+1);
     85        if (tmp.isEmpty() || url.isEmpty())
     86            break;
     87
     88        QString channum, name;
     89        if (parse_chan_info(tmp, channum, name))
     90        {
     91            chanmap[channum] = FreeboxChannelInfo(name, url);
     92        }
     93    }
     94
     95    return chanmap;
     96}
     97
     98/* vim: set expandtab tabstop=4 shiftwidth=4: */
  • libs/libmythtv/freeboxrecorder.cpp

     
     1/**
     2 *  FreeboxRecorder
     3 *  Copyright (c) 2006 by Laurent Arnal, Benjamin Lerman & Mickaël Remars
     4 *  Distributed as part of MythTV under GPL v2 and later.
     5 */
     6
     7#include "freeboxrecorder.h"
     8
     9#include <BasicUsageEnvironment.hh>
     10#include <MediaSession.hh>
     11#include <RTSPClient.hh>
     12#include <qwaitcondition.h>
     13#include <qmutex.h>
     14
     15#include "mpeg/mpegstreamdata.h"
     16#include "mpeg/streamlisteners.h"
     17#include "mpeg/tspacket.h"
     18#include "freeboxchannel.h"
     19#include "freeboxmediasink.h"
     20
     21
     22
     23// ============================================================================
     24// FreeboxData : Helper class use for static Callback handler
     25// ============================================================================
     26class FreeboxData
     27{
     28  public:
     29    FreeboxData(FreeboxRecorder *pFreeboxRecorder,
     30                MediaSubsession *pMediaSubSession) :
     31        freeboxRecorder(pFreeboxRecorder),
     32        mediaSubSession(pMediaSubSession)
     33    {
     34    }
     35   
     36    static void subsessionAfterPlayingCallback(void *clientData);
     37    static void subsessionByeHandlerCallback(void *clientData);
     38    void SubsessionAfterPlaying();
     39    void SubsessionByeHandler();
     40
     41  private:
     42    FreeboxRecorder *freeboxRecorder;
     43    MediaSubsession *mediaSubSession;
     44};
     45
     46void FreeboxData::subsessionAfterPlayingCallback(void *clientData)
     47{
     48    ((FreeboxData*)clientData)->SubsessionAfterPlaying();
     49}
     50
     51void FreeboxData::subsessionByeHandlerCallback(void *clientData)
     52{
     53    ((FreeboxData*)clientData)->SubsessionByeHandler();
     54}
     55
     56void FreeboxData::SubsessionAfterPlaying()
     57{
     58    MediaSubsession* subsession = mediaSubSession;
     59    Medium::close(subsession->sink);
     60    subsession->sink = NULL;
     61
     62    MediaSession& session = subsession->parentSession();
     63    MediaSubsessionIterator iter(session);
     64    while ((subsession = iter.next()) != NULL)
     65    {
     66        if (subsession->sink != NULL) return;
     67    }
     68}
     69
     70void FreeboxData::SubsessionByeHandler()
     71{
     72    SubsessionAfterPlaying();
     73}
     74
     75
     76
     77class FreeboxRecorderImpl : public MPEGSingleProgramStreamListener
     78{
     79  public:
     80    FreeboxRecorderImpl(FreeboxRecorder& thisRecorder,
     81                        FreeboxChannel&  channel) :
     82        _this(thisRecorder),
     83        _streamData(1,true),
     84        _curChanInfo(channel.GetCurrentChanInfo()),
     85        env(NULL),
     86        rtspClient(NULL),
     87        session(NULL),
     88        _channel(channel),
     89        _abort_rtsp(0),
     90        _abort_recording(false)
     91    {
     92        _streamData.AddMPEGSPListener(this);
     93    }
     94
     95    MPEGStreamData& StreamData(void)
     96        { return _streamData; }
     97    const FreeboxChannelInfo& CurrentChanInfo(void) const
     98        { return _curChanInfo; }
     99    void SetCurrentChanInfo(const FreeboxChannelInfo& info)
     100        { _curChanInfo = info; }
     101
     102  public: //MPEGSingleProgramStreamListener
     103    void HandleSingleProgramPAT(ProgramAssociationTable *pat);
     104    void HandleSingleProgramPMT(ProgramMapTable *pmt);
     105
     106  private:
     107    FreeboxRecorder& _this;
     108    MPEGStreamData   _streamData;
     109
     110    FreeboxChannelInfo _curChanInfo;
     111
     112  public: //TODO all members should be private
     113    // livemedia
     114    UsageEnvironment* env;
     115    RTSPClient* rtspClient;
     116    MediaSession* session;
     117
     118    // Current channel
     119    FreeboxChannel& _channel;
     120
     121    // condition  used to coordinate threads
     122    QWaitCondition _cond;
     123   
     124    // lock  used to coordinate threads
     125    QMutex _lock;
     126
     127    // var to check if we need to abort current rtsp session
     128    char _abort_rtsp;
     129
     130    // request abort for StartRecording method
     131    bool _abort_recording;
     132};
     133
     134void FreeboxRecorderImpl::HandleSingleProgramPAT(ProgramAssociationTable *pat)
     135{
     136    if (!pat)
     137        return;
     138
     139    int next = (pat->tsheader()->ContinuityCounter()+1)&0xf;
     140    pat->tsheader()->SetContinuityCounter(next);
     141    _this.BufferedWrite(*(reinterpret_cast<const TSPacket*>(pat->tsheader())));
     142}
     143
     144void FreeboxRecorderImpl::HandleSingleProgramPMT(ProgramMapTable *pmt)
     145{
     146    if (!pmt)
     147        return;
     148
     149    int next = (pmt->tsheader()->ContinuityCounter()+1)&0xf;
     150    pmt->tsheader()->SetContinuityCounter(next);
     151    _this.BufferedWrite(*(reinterpret_cast<const TSPacket*>(pmt->tsheader())));
     152}
     153
     154
     155
     156FreeboxRecorder::FreeboxRecorder(TVRec *rec, FreeboxChannel& channel) :
     157    DTVRecorder(rec),
     158    _impl(new FreeboxRecorderImpl(*this, channel))
     159{
     160    channel.SetRecorder(this);
     161}
     162
     163
     164
     165FreeboxRecorder::~FreeboxRecorder()
     166{
     167    _impl->_channel.SetRecorder(NULL);
     168    delete _impl;
     169}
     170
     171
     172
     173bool FreeboxRecorder::Open()
     174{
     175    bool result = StartRtsp();
     176    _error = !result;
     177    return result;
     178}
     179
     180
     181
     182void FreeboxRecorder::Close()
     183{
     184    if (_impl->session == NULL) return;
     185
     186    // Ensure RTSP cleanup, remove old RTSP session
     187    MediaSubsessionIterator iter(*_impl->session);
     188    MediaSubsession* subsession;
     189    while ((subsession = iter.next()) != NULL)
     190    {
     191        Medium::close(subsession->sink);
     192        subsession->sink = NULL;
     193    }
     194
     195    if (_impl->session == NULL) return;
     196
     197    _impl->rtspClient->teardownMediaSession(*_impl->session);
     198
     199    // Close all RTSP descriptor
     200    Medium::close(_impl->session);
     201    Medium::close(_impl->rtspClient);
     202}
     203
     204
     205
     206void FreeboxRecorder::ChannelChanged(const FreeboxChannelInfo& chaninfo)
     207{
     208    _impl->SetCurrentChanInfo(chaninfo);
     209    // Channel change, we need to close current RTSP flow, and open a new one
     210    ResetEventLoop();
     211}
     212
     213
     214
     215void FreeboxRecorder::SetOptionsFromProfile(RecordingProfile *profile,
     216                                            const QString    &videodev,
     217                                            const QString    &audiodev,
     218                                            const QString    &vbidev)
     219{
     220    (void)videodev;
     221    (void)audiodev;
     222    (void)vbidev;
     223    (void)profile;
     224}
     225
     226
     227
     228void FreeboxRecorder::StartRecording()
     229{
     230    _impl->_lock.lock();
     231    _recording = true;
     232    while(!_impl->_abort_recording && Open())
     233    {
     234        _impl->_lock.unlock();
     235        // Go into main RTSP loop, feeding data to mythtv
     236        _impl->env->taskScheduler().doEventLoop(&_impl->_abort_rtsp);
     237
     238        _impl->_lock.lock();
     239        FinishRecording();
     240        Close();
     241
     242        // Reset _abort_rtsp before unlocking ResetEventLoop()
     243        // to avoid race condition
     244        _impl->_abort_rtsp = 0;
     245        _impl->_cond.wakeAll();
     246    }
     247    _recording = false;
     248    _impl->_lock.unlock();
     249}
     250
     251void FreeboxRecorder::StopRecording(void)
     252{
     253    _impl->_abort_recording = true; // No lock needed
     254    ResetEventLoop();
     255}
     256
     257void FreeboxRecorder::ResetEventLoop()
     258{
     259    _impl->_lock.lock();
     260    _impl->_abort_rtsp = ~0;
     261    while(_recording && _impl->_abort_rtsp)
     262        _impl->_cond.wait(&_impl->_lock, 1000);
     263    _impl->_lock.unlock();
     264}
     265
     266// ======================================================================
     267// StartRtsp : start a new RTSP session for the current channel
     268// ======================================================================
     269bool FreeboxRecorder::StartRtsp()
     270{
     271    // Retrieve the RTSP channel URL
     272    FreeboxChannelInfo chaninfo = _impl->CurrentChanInfo();
     273    if (!chaninfo.isValid())
     274        return false;
     275    QString url = chaninfo.m_url;
     276
     277    // Begin by setting up our usage environment:
     278    TaskScheduler* scheduler = BasicTaskScheduler::createNew();
     279    _impl->env = BasicUsageEnvironment::createNew(*scheduler);
     280
     281
     282    // Create our client object:
     283    _impl->rtspClient = RTSPClient::createNew(*_impl->env, 0, "myRTSP", 0);
     284    if (_impl->rtspClient == NULL)
     285    {
     286        VERBOSE(VB_IMPORTANT,
     287                QString("Freebox # Failed to create RTSP client: %1")
     288                    .arg(_impl->env->getResultMsg()));
     289        return false;
     290    }
     291
     292    // Setup URL for the current session
     293    char* sdpDescription = _impl->rtspClient->describeURL(url);
     294    _impl->rtspClient->describeStatus();
     295    if (sdpDescription == NULL)
     296    {
     297        VERBOSE(VB_IMPORTANT, QString(
     298            "Freebox # Failed to get a SDP description from URL: %1 %2")
     299                .arg(url)
     300                .arg(_impl->env->getResultMsg()));
     301        return false;
     302    }
     303
     304    // Create a media session object from this SDP description:
     305    _impl->session = MediaSession::createNew(*_impl->env, sdpDescription);
     306    delete[] sdpDescription;
     307    if (_impl->session == NULL)
     308    {
     309        VERBOSE(VB_IMPORTANT,
     310                QString("Freebox # Failed to create MediaSession: %1")
     311                    .arg(_impl->env->getResultMsg()));
     312        return false;
     313    }
     314    else if (!_impl->session->hasSubsessions())
     315    {
     316        VERBOSE(VB_IMPORTANT,
     317                QString("Freebox # This session has no media subsessions"));
     318        return false;
     319    }
     320
     321    // Then, setup the "RTPSource"s for the session:
     322    MediaSubsessionIterator iter(*_impl->session);
     323    MediaSubsession *subsession;
     324    Boolean madeProgress = False;
     325    while ((subsession = iter.next()) != NULL)
     326    {
     327        if (!subsession->initiate(-1))
     328        {
     329            VERBOSE(VB_IMPORTANT, QString(
     330                "Freebox # Can't create receiver for: %1 / %2 subsession: %3")
     331                    .arg(subsession->mediumName())
     332                    .arg(subsession->codecName())
     333                    .arg(_impl->env->getResultMsg()));
     334        }
     335        else
     336        {
     337            madeProgress = True;
     338
     339            if (subsession->rtpSource() != NULL)
     340            {
     341                unsigned const thresh = 1000000; // 1 second
     342                subsession->rtpSource()
     343                    ->setPacketReorderingThresholdTime(thresh);
     344            }
     345        }
     346    }
     347
     348    if (!madeProgress) return false;
     349
     350    // Perform additional 'setup' on each subsession, before playing them:
     351    madeProgress = false;
     352    iter.reset();
     353    while ((subsession = iter.next()) != NULL)
     354    {
     355        if (subsession->clientPortNum() == 0) continue; // port # was not set
     356
     357        if (_impl->rtspClient->setupMediaSubsession(*subsession, False, false))
     358        {
     359            madeProgress = True;
     360        }
     361        else
     362        {
     363            VERBOSE(VB_IMPORTANT,
     364                    QString("Freebox # Failed to setup: %1 %2 : %3")
     365                        .arg(subsession->mediumName())
     366                        .arg(subsession->codecName())
     367                        .arg(_impl->env->getResultMsg()));
     368        }
     369    }
     370
     371    if (!madeProgress) return false;
     372
     373   // Create and start "FileSink"s for each subsession:
     374   // FileSink while receive Mpeg2 TS Data & will feed them to mythtv
     375    madeProgress = False;
     376    iter.reset();
     377    while ((subsession = iter.next()) != NULL)
     378    {
     379        if (subsession->readSource() == NULL) continue; // was not initiated
     380
     381        FreeboxMediaSink* freeboxMediaSink = FreeboxMediaSink::createNew(
     382                *_impl->env, *this, TSPacket::SIZE*128);
     383
     384        subsession->sink = freeboxMediaSink;
     385        if (subsession->sink == NULL)
     386        {
     387            VERBOSE(VB_IMPORTANT,
     388                    QString("Freebox # Failed to create sink: %1")
     389                        .arg(_impl->env->getResultMsg()));
     390        }
     391
     392        subsession->sink->startPlaying(
     393                *(subsession->readSource()),
     394                FreeboxData::subsessionAfterPlayingCallback,
     395                new FreeboxData(this, subsession));
     396
     397        if (subsession->rtcpInstance() != NULL)
     398        {
     399            subsession->rtcpInstance()->setByeHandler(
     400                    FreeboxData::subsessionByeHandlerCallback,
     401                    new FreeboxData(this, subsession));
     402        }
     403
     404        madeProgress = True;
     405    }
     406
     407    if (!madeProgress) return false;
     408
     409    // Setup player
     410    if (!(_impl->rtspClient->playMediaSession(*_impl->session)))
     411    {
     412        VERBOSE(VB_IMPORTANT,
     413                QString("Freebox # Failed to start playing session: %1")
     414                    .arg(_impl->env->getResultMsg()));
     415        return false;
     416    }
     417
     418    return true;
     419}
     420
     421// ===================================================
     422// findTSHeader : find a TS Header in flow
     423// ===================================================
     424static int FreeboxRecorder_findTSHeader(const unsigned char *data,
     425                                        unsigned            dataSize)
     426{
     427    unsigned int pos = 0;
     428    while (pos < dataSize)
     429    {
     430        if (data[pos] == 0x47)
     431            return pos;
     432        pos++;
     433    }
     434    return -1;
     435}
     436
     437// ===================================================
     438// addData : feed date from RTSP flow to mythtv
     439// ===================================================
     440void FreeboxRecorder::addData(unsigned char* data,
     441                              unsigned       dataSize,
     442                              struct timeval)
     443{
     444    unsigned int readIndex = 0;
     445
     446    // data may be compose from more than one packet, loop to consume all data
     447    while (readIndex < dataSize)
     448    {
     449        // If recorder is pause, stop there
     450        if (PauseAndWait())
     451        {
     452            return;
     453        }
     454
     455        // Find the next TS Header in data
     456        int tsPos = FreeboxRecorder_findTSHeader(data + readIndex, dataSize);
     457
     458        // if no TS, something bad happens
     459        if (tsPos == -1)
     460        {
     461            VERBOSE(VB_IMPORTANT, QString("FREEBOX: No TS header."));
     462            break;
     463        }
     464
     465        // if TS Header not at start of data, we receive out of sync data
     466        if (tsPos > 0)
     467        {
     468            VERBOSE(VB_IMPORTANT,
     469                    QString("FREEBOX: TS header at %1, not in sync.")
     470                        .arg(tsPos));
     471        }
     472
     473        // Check if the next packet in buffer is complete :
     474        // packet size is 188 bytes long
     475        if ((dataSize - tsPos) < TSPacket::SIZE)
     476        {
     477            VERBOSE(VB_IMPORTANT, QString(
     478                "FREEBOX: TS header at %1 but packet not yet complete."
     479                ).arg(tsPos));
     480            break;
     481        }
     482
     483        // Cast current found TS Packet to TSPacket structure
     484        const void *newData = data + tsPos + readIndex;
     485        ProcessTSPacket(*reinterpret_cast<const TSPacket*>(newData));
     486
     487        // follow to next packet
     488        readIndex += tsPos + TSPacket::SIZE;
     489    }
     490}
     491
     492void FreeboxRecorder::ProcessTSPacket(const TSPacket& tspacket)
     493{
     494    if (tspacket.TransportError())
     495        return;
     496
     497    if (tspacket.ScramplingControl())
     498        return;
     499
     500    MPEGStreamData& sd = _impl->StreamData();
     501    if (tspacket.HasAdaptationField())
     502        sd.HandleAdaptationFieldControl(&tspacket);
     503
     504    if (tspacket.HasPayload())
     505    {
     506        const unsigned int lpid = tspacket.PID();
     507
     508        // Pass or reject packets based on PID, and parse info from them
     509        if (lpid == sd.VideoPIDSingleProgram())
     510        {
     511            _buffer_packets = !FindMPEG2Keyframes(&tspacket);
     512            BufferedWrite(tspacket);
     513        }
     514        else if (sd.IsAudioPID(lpid))
     515            BufferedWrite(tspacket);
     516        else if (sd.IsListeningPID(lpid))
     517            sd.HandleTSTables(&tspacket);
     518        else if (sd.IsWritingPID(lpid))
     519            BufferedWrite(tspacket);
     520    }
     521}
     522
     523/* vim: set expandtab tabstop=4 shiftwidth=4: */
  • libs/libmythtv/DeviceReadBuffer.h

     
    1717class ReaderPausedCB
    1818{
    1919  public:
     20        virtual ~ReaderPausedCB() {}
    2021    virtual void ReaderPaused(int fd) = 0;
    2122};
    2223
  • libs/libmythtv/mpeg/streamlisteners.h

     
    3636class MPEGStreamListener
    3737{
    3838  public:
     39        virtual ~MPEGStreamListener() {}
    3940    virtual void HandlePAT(const ProgramAssociationTable*) = 0;
    4041    virtual void HandleCAT(const ConditionalAccessTable*) = 0;
    4142    virtual void HandlePMT(uint program_num, const ProgramMapTable*) = 0;
     
    4445class MPEGSingleProgramStreamListener
    4546{
    4647  public:
     48        virtual ~MPEGSingleProgramStreamListener() {}
    4749    virtual void HandleSingleProgramPAT(ProgramAssociationTable*) = 0;
    4850    virtual void HandleSingleProgramPMT(ProgramMapTable*) = 0;
    4951};
     
    5153class ATSCMainStreamListener
    5254{
    5355  public:
     56        virtual ~ATSCMainStreamListener() {}
    5457    virtual void HandleSTT(const SystemTimeTable*) = 0;
    5558    virtual void HandleMGT(const MasterGuideTable*) = 0;
    5659    virtual void HandleVCT(uint pid, const VirtualChannelTable*) = 0;
     
    5962class ATSCAuxStreamListener
    6063{
    6164  public:
     65        virtual ~ATSCAuxStreamListener() {}
    6266    virtual void HandleTVCT(uint pid,const TerrestrialVirtualChannelTable*)=0;
    6367    virtual void HandleCVCT(uint pid, const CableVirtualChannelTable*) = 0;
    6468    virtual void HandleRRT(const RatingRegionTable*) = 0;
     
    7074class ATSCEITStreamListener
    7175{
    7276  public:
     77        virtual ~ATSCEITStreamListener() {}
    7378    virtual void HandleEIT( uint pid, const EventInformationTable*) = 0;
    7479    virtual void HandleETT( uint pid, const ExtendedTextTable*) = 0;
    7580};
     
    7782class DVBMainStreamListener
    7883{
    7984  public:
     85        virtual ~DVBMainStreamListener() {}
    8086    virtual void HandleNIT(const NetworkInformationTable*) = 0;
    8187    virtual void HandleSDT(uint tsid, const ServiceDescriptionTable*) = 0;
    8288};
     
    8490class DVBOtherStreamListener
    8591{
    8692  public:
     93        virtual ~DVBOtherStreamListener() {}
    8794    virtual void HandleNITo(const NetworkInformationTable*) = 0;
    8895    virtual void HandleSDTo(uint tsid, const ServiceDescriptionTable*) = 0;
    8996};
     
    9198class DVBEITStreamListener
    9299{
    93100  public:
     101        virtual ~DVBEITStreamListener() {}
    94102    virtual void HandleEIT(const DVBEventInformationTable*) = 0;
    95103};
    96104
  • libs/libmythtv/cardutil.cpp

     
    571571
    572572    if (("FIREWIRE"  == cardtype) ||
    573573        ("DBOX2"     == cardtype) ||
     574        ("FREEBOX"   == cardtype) ||
    574575        ("HDHOMERUN" == cardtype) ||
    575576        ("CRC_IP"    == cardtype))
    576577    {
     
    804805
    805806    if (("FIREWIRE"  == cardtype) ||
    806807        ("DBOX2"     == cardtype) ||
     808        ("FREEBOX"   == cardtype) ||
    807809        ("HDHOMERUN" == cardtype) ||
    808810        ("CRC_IP"    == cardtype))
    809811    {
  • libs/libmythtv/freeboxmediasink.h

     
     1/**
     2 *  FreeboxMediaSink
     3 *  Copyright (c) 2006 by Laurent Arnal, Benjamin Lerman & Mickaël Remars
     4 *  Distributed as part of MythTV under GPL v2 and later.
     5 */
     6
     7#ifndef _FREEBOXMEDIASINK_H_
     8#define _FREEBOXMEDIASINK_H_
     9
     10#include <MediaSink.hh>
     11
     12class FreeboxRecorder;
     13
     14
     15
     16// ============================================================================
     17// FreeboxMediaSink : Helper class use to receive RTSP data from socket.
     18// ============================================================================
     19class FreeboxMediaSink: public MediaSink
     20{
     21  public:
     22    static FreeboxMediaSink* createNew(UsageEnvironment& env,
     23                                       FreeboxRecorder&  pRecorder,
     24                                       unsigned          bufferSize);
     25
     26    /// Callback function called when rtsp data are ready
     27    void addData(unsigned char* data,
     28                 unsigned       dataSize,
     29                 struct timeval presentationTime);
     30
     31  protected:
     32    FreeboxMediaSink(UsageEnvironment& env,
     33                     FreeboxRecorder&  pRecorder,
     34                     unsigned          bufferSize);
     35    virtual ~FreeboxMediaSink();
     36
     37    static void afterGettingFrame(void*          clientData,
     38                                  unsigned       frameSize,
     39                                  unsigned       numTruncatedBytes,
     40                                  struct timeval presentationTime,
     41                                  unsigned       durationInMicroseconds);
     42    virtual void afterGettingFrame1(unsigned       frameSize,
     43                                    struct timeval presentationTime);
     44
     45  private:
     46    virtual Boolean continuePlaying(void);
     47
     48  private:
     49    unsigned char*    fBuffer;
     50    unsigned          fBufferSize;
     51    UsageEnvironment& env;
     52    FreeboxRecorder&  recorder;
     53
     54  private:
     55    // avoid default contructors & operator=
     56    FreeboxMediaSink();
     57    FreeboxMediaSink(const FreeboxMediaSink&);
     58    FreeboxMediaSink& operator=(const FreeboxMediaSink&);
     59};
     60
     61#endif //_FREEBOXMEDIASINK_H_
     62
     63/* vim: set expandtab tabstop=4 shiftwidth=4: */
  • libs/libmythtv/videosource.cpp

     
    996996    }
    997997};
    998998
     999class FreeboxHost : public LineEditSetting, public CCSetting {
     1000  public:
     1001    FreeboxHost(const CaptureCard &parent):
     1002        CCSetting(parent, "videodevice")
     1003    {
     1004        setValue("http://mafreebox.freebox.fr/freeboxtv/playlist.m3u");
     1005        setLabel(QObject::tr("Freebox MRL"));
     1006        setHelpText(QObject::tr("The freebox Media Resource Locator (MRL)."));
     1007    }
     1008};
     1009
    9991010class HDHomeRunTunerIndex: public ComboBoxSetting, public CCSetting
    10001011{
    10011012  public:
     
    10081019    }
    10091020};
    10101021
     1022class FreeboxConfigurationGroup: public VerticalConfigurationGroup {
     1023  public:
     1024    FreeboxConfigurationGroup(CaptureCard& a_parent):
     1025       ConfigurationGroup(false, true, false, false),
     1026       VerticalConfigurationGroup(false, true, false, false),
     1027       parent(a_parent)
     1028    {
     1029        setUseLabel(false);
     1030        addChild(new FreeboxHost(parent));
     1031
     1032        //FIXME Create a generic class to replace duplicates
     1033        HDHRCardInput *defaultinput = new HDHRCardInput(parent);
     1034        addChild(defaultinput);
     1035        defaultinput->setVisible(false);
     1036    };
     1037  private:
     1038    CaptureCard& parent;
     1039};
     1040
    10111041void HDHRCardInput::fillSelections(const QString&)
    10121042{
    10131043    clearSelections();
     
    12321262    addTarget("DBOX2",     new DBOX2ConfigurationGroup(parent));
    12331263#endif // USING_DBOX2
    12341264
     1265#ifdef USING_FREEBOX
     1266    addTarget("FREEBOX",   new FreeboxConfigurationGroup(parent));
     1267#endif // USING_FREEBOX
     1268
    12351269#ifdef USING_HDHOMERUN
    12361270    addTarget("HDHOMERUN", new HDHomeRunConfigurationGroup(parent));
    12371271#endif // USING_HDHOMERUN
     
    13531387        QObject::tr("DBox2 TCP/IP cable box"), "DBOX2");
    13541388#endif // USING_DBOX2
    13551389
     1390#ifdef USING_FREEBOX
     1391    setting->addSelection(
     1392        QObject::tr("Freebox"), "FREEBOX");
     1393#endif // USING_FREEBOX
     1394
    13561395#ifdef USING_HDHOMERUN
    13571396    setting->addSelection(
    13581397        QObject::tr("HDHomeRun DTV tuner box"), "HDHOMERUN");
  • libs/libmythtv/freeboxrecorder.h

     
     1/**
     2 *  FreeboxRecorder
     3 *  Copyright (c) 2006 by Laurent Arnal, Benjamin Lerman & Mickaël Remars
     4 *  Distributed as part of MythTV under GPL v2 and later.
     5 */
     6
     7#ifndef FREEBOXRECORDER_H_
     8#define FREEBOXRECORDER_H_
     9
     10#include "dtvrecorder.h"
     11
     12class FreeboxChannel;
     13class FreeboxChannelInfo;
     14class FreeboxRecorderImpl;
     15
     16
     17
     18/**
     19 *  Constructs a FreeboxRecorder
     20 */
     21class FreeboxRecorder : public DTVRecorder
     22{
     23    friend class FreeboxChannel;
     24    friend class FreeboxMediaSink;
     25    friend class FreeboxRecorderImpl;
     26  public:
     27    FreeboxRecorder(TVRec *rec, FreeboxChannel& channel);
     28    ~FreeboxRecorder();
     29
     30    void StartRecording(void);
     31    void StopRecording(void);
     32
     33    void SetOptionsFromProfile(RecordingProfile *profile,
     34                               const QString    &videodev,
     35                               const QString    &audiodev,
     36                               const QString    &vbidev);
     37
     38  private:
     39    bool Open(void);
     40    void Close(void);
     41
     42    void ChannelChanged(const FreeboxChannelInfo& chaninfo);
     43
     44    /// Callback function to add MPEG2 TS data
     45    void addData(unsigned char* data,
     46                 unsigned       dataSize,
     47                 struct timeval presentationTime);
     48
     49    void ProcessTSPacket(const TSPacket& tspacket);
     50
     51    bool StartRtsp(void);
     52    void ResetEventLoop(void);
     53
     54  private:
     55    FreeboxRecorderImpl* _impl;
     56
     57  private:
     58    FreeboxRecorder& operator=(const FreeboxRecorder&); //< avoid default impl
     59    FreeboxRecorder(const FreeboxRecorder&);            //< avoid default impl
     60    FreeboxRecorder();                                  //< avoid default impl
     61};
     62
     63#endif //FREEBOXRECORDER_H_
     64
     65/* vim: set expandtab tabstop=4 shiftwidth=4: */
  • libs/libmythtv/eitscanner.h

     
    2121class EITSource
    2222{
    2323  public:
     24        virtual ~EITSource() {}
    2425    virtual void SetEITHelper(EITHelper*) = 0;
    2526    virtual void SetEITRate(float rate) = 0;
    2627};
  • libs/libmythtv/tv_rec.cpp

     
    4545#include "dvbchannel.h"
    4646#include "dbox2channel.h"
    4747#include "hdhrchannel.h"
     48#include "freeboxchannel.h"
    4849
    4950#include "recorderbase.h"
    5051#include "NuppelVideoRecorder.h"
     
    5354#include "dvbrecorder.h"
    5455#include "dbox2recorder.h"
    5556#include "hdhrrecorder.h"
     57#include "freeboxrecorder.h"
    5658
    5759#ifdef USING_CRC_IP_NETWORK_REC
    5860#include "crcipnetworkrecorder.h"
     
    178180        init_run = true;
    179181#endif
    180182    }
     183    else if (genOpt.cardtype == "FREEBOX")
     184    {
     185#ifdef USING_FREEBOX
     186        channel = new FreeboxChannel(this, genOpt.videodev, cardid);
     187        if (!channel->Open())
     188            return false;
     189        InitChannel(genOpt.defaultinput, startchannel);
     190        init_run = true;
     191#endif
     192    }   
    181193    else if (genOpt.cardtype == "HDHOMERUN")
    182194    {
    183195#ifdef USING_HDHOMERUN
     
    867879        recorder->SetOption("httpport", dboxOpt.httpport);
    868880#endif // USING_DBOX2
    869881    }
     882    else if (genOpt.cardtype == "FREEBOX")
     883    {
     884#ifdef USING_FREEBOX
     885        FreeboxChannel *chan = dynamic_cast<FreeboxChannel*>(channel);
     886        recorder = new FreeboxRecorder(this, *chan);
     887        recorder->SetOption("mrl", genOpt.videodev);
     888#endif // USING_FREEBOX
     889    }
    870890    else if (genOpt.cardtype == "HDHOMERUN")
    871891    {
    872892#ifdef USING_HDHOMERUN
     
    13621382    return ok;
    13631383}
    13641384
    1365 bool TVRec::GetDevices(int cardid,
     1385bool TVRec::GetDevices(int                cardid,
    13661386                       GeneralDBOptions   &gen_opts,
    13671387                       DVBDBOptions       &dvb_opts,
    13681388                       FireWireDBOptions  &firewire_opts,
  • libs/libmythtv/tv_rec.h

     
    104104    QString host;
    105105};
    106106
     107 
     108class FreeboxDBOptions
     109{
     110  public:
     111    FreeboxDBOptions() :
     112        mrl("http://mafreebox.freebox.fr/freeboxtv/playlist.m3u") {}
     113
     114   QString mrl;
     115};
     116
     117
    107118class TuningRequest
    108119{
    109120  public:
     
    236247    void SetPseudoLiveTVRecording(ProgramInfo*);
    237248    void TeardownAll(void);
    238249
    239     static bool GetDevices(int cardid,
     250    static bool GetDevices(int                cardid,
    240251                           GeneralDBOptions   &general_opts,
    241252                           DVBDBOptions       &dvb_opts,
    242253                           FireWireDBOptions  &firewire_opts,
     
    334345    DVBDBOptions       dvbOpt;
    335346    FireWireDBOptions  fwOpt;
    336347    DBox2DBOptions     dboxOpt;
     348    FreeboxDBOptions   freeboxOpt;
    337349
    338350    // State variables
    339351    QMutex         stateChangeLock;
  • settings.pro

     
    7979EXTRA_LIBS += $$CONFIG_AUDIO_JACK_LIBS
    8080EXTRA_LIBS += $$CONFIG_FIREWIRE_LIBS
    8181EXTRA_LIBS += $$CONFIG_DIRECTFB_LIBS
     82EXTRA_LIBS += $$CONFIG_LIVE_LIBS
    8283
    8384EXTRA_LIBS += $$LOCAL_LIBDIR_OGL
    8485EXTRA_LIBS += $$LOCAL_LIBDIR_X11