Ticket #11487: iptv-http-ts-streaming.patch

File iptv-http-ts-streaming.patch, 11.9 KB (added by torbjorn.jansson@…, 7 years ago)

the patch

  • mythtv/libs/libmythtv/iptv/iptvchannelfetcher.cpp

    diff --git a/mythtv/libs/libmythtv/iptv/iptvchannelfetcher.cpp b/mythtv/libs/libmythtv/iptv/iptvchannelfetcher.cpp
    index 57ba817..9889c4c 100644
    a b void IPTVChannelFetcher::run(void) 
    141141        QString channum = it.key();
    142142        QString name    = (*it).m_name;
    143143        QString xmltvid = (*it).m_xmltvid.isEmpty() ? "" : (*it).m_xmltvid;
     144        uint serviceid  = (*it).m_serviceid;
    144145        QString msg = QObject::tr("Channel #%1 : %2").arg(channum).arg(name);
    145146
    146147        int chanid = ChannelUtil::GetChanID(_sourceid, channum);
    void IPTVChannelFetcher::run(void) 
    154155            chanid = ChannelUtil::CreateChanID(_sourceid, channum);
    155156            ChannelUtil::CreateChannel(
    156157                0, _sourceid, chanid, name, name, channum,
    157                 0, 0, 0, false, false, false, QString::null,
     158                serviceid, 0, 0, false, false, false, QString::null,
    158159                QString::null, "Default", xmltvid);
    159160        }
    160161        else
    void IPTVChannelFetcher::run(void) 
    166167            }
    167168            ChannelUtil::UpdateChannel(
    168169                0, _sourceid, chanid, name, name, channum,
    169                 0, 0, 0, false, false, false, QString::null,
     170                serviceid, 0, 0, false, false, false, QString::null,
    170171                QString::null, "Default", xmltvid);
    171172        }
    172173
    static bool parse_chan_info(const QString &rawdata, 
    339340{
    340341    // #EXTINF:0,2 - France 2                <-- duration,channum - channame
    341342    // #EXTMYTHTV:xmltvid=C2.telepoche.com   <-- optional line (myth specific)
     343    // #EXTMYTHTV2:serviceid=1234            <-- optional if missing 1 is used (mythtv specific)
    342344    // #...                                  <-- ignored comments
    343345    // rtsp://maiptv.iptv.fr/iptvtv/201 <-- url
    344346
    345347    QString name;
    346348    QString xmltvid;
     349    uint serviceid=1;
    347350    while (true)
    348351    {
    349352        QString line = rawdata.section("\n", lineNum, lineNum);
    static bool parse_chan_info(const QString &rawdata, 
    365368                    xmltvid = data.mid(data.indexOf('=')+1);
    366369                }
    367370            }
     371            else if (line.startsWith("#EXTMYTHTV2:"))
     372            {
     373                QString data = line.mid(line.indexOf(':')+1);
     374                if (data.startsWith("serviceid="))
     375                {
     376                    serviceid = data.mid(data.indexOf('=')+1).toUInt();
     377                }
     378            }
    368379            else
    369380            {
    370381                // Just ignore other comments
    static bool parse_chan_info(const QString &rawdata, 
    375386            if (name.isEmpty())
    376387                return false;
    377388            QString url = line;
    378             info = IPTVChannelInfo(name, url, xmltvid);
     389            info = IPTVChannelInfo(name, url, xmltvid, serviceid);
    379390            return true;
    380391        }
    381392    }
  • mythtv/libs/libmythtv/iptv/iptvchannelinfo.h

    diff --git a/mythtv/libs/libmythtv/iptv/iptvchannelinfo.h b/mythtv/libs/libmythtv/iptv/iptvchannelinfo.h
    index d18014b..23544c15 100644
    a b class IPTVChannelInfo 
    2020
    2121    IPTVChannelInfo(const QString &name,
    2222                    const QString &url,
    23                     const QString &xmltvid) :
    24         m_name(name), m_url(url), m_xmltvid(xmltvid)
     23                    const QString &xmltvid,
     24                    const uint serviceid) :
     25        m_name(name), m_url(url), m_xmltvid(xmltvid),m_serviceid(serviceid)
    2526    {
    2627    }
    2728
    class IPTVChannelInfo 
    4041    QString m_name;
    4142    QString m_url;
    4243    QString m_xmltvid;
     44    uint m_serviceid;
    4345};
    4446
    4547typedef QMap<QString,IPTVChannelInfo> fbox_chan_map_t;
  • mythtv/libs/libmythtv/iptv/iptvfeederwrapper.cpp

    diff --git a/mythtv/libs/libmythtv/iptv/iptvfeederwrapper.cpp b/mythtv/libs/libmythtv/iptv/iptvfeederwrapper.cpp
    index 16eb5c7..6c8e35d 100644
    a b using namespace std; 
    1717#include "iptvfeederrtp.h"
    1818#include "iptvfeederfile.h"
    1919#include "iptvfeederhls.h"
     20#include "iptvfeederhttp.h"
    2021#include "mythcontext.h"
    2122#include "mythlogging.h"
    2223
    bool IPTVFeederWrapper::InitFeeder(const QString &url) 
    7475    {
    7576        tmp_feeder = new IPTVFeederHLS();
    7677    }
     78        else if(IPTVFeederHTTP::IsHTTP(url))
     79        {
     80                tmp_feeder = new IPTVFeederHTTP();
     81        }
    7782    else
    7883    {
    7984        LOG(VB_RECORD, LOG_ERR, LOC +
  • mythtv/libs/libmythtv/iptvchannel.cpp

    diff --git a/mythtv/libs/libmythtv/iptvchannel.cpp b/mythtv/libs/libmythtv/iptvchannel.cpp
    index bb7385e..822f8b9 100644
    a b bool IPTVChannel::SetChannelByString(const QString &channum) 
    9595        return false;
    9696
    9797    // Verify that channel exists
    98     if (!GetChanInfo(channum).isValid())
     98    IPTVChannelInfo chaninfo=GetChanInfo(channum);
     99    if (!chaninfo.isValid())
    99100    {
    100101        LOG(VB_GENERAL, LOG_ERR, LOC +
    101102                QString("SetChannelByString(%1)").arg(channum) +
    bool IPTVChannel::SetChannelByString(const QString &channum) 
    110111    // Set the dtv channel info for any additional multiplex tuning
    111112    SetDTVInfo(/*atsc_major*/ 0, /*atsc_minor*/ 0,
    112113               /*netid*/ 0,
    113                /*tsid*/ 0, /*mpeg_prog_num*/ 1);
     114               /*tsid*/ 0, /*mpeg_prog_num*/ chaninfo.m_serviceid);
    114115
    115116    HandleScript(channum /* HACK treat channum as freqid */);
    116117
  • mythtv/libs/libmythtv/libmythtv.pro

    diff --git a/mythtv/libs/libmythtv/libmythtv.pro b/mythtv/libs/libmythtv/libmythtv.pro
    index c815431..b23aa5a 100644
    a b using_backend { 
    567567        HEADERS += iptv/iptvfeederfile.h      iptv/iptvfeederlive.h
    568568        HEADERS += iptv/iptvfeederrtp.h       iptv/timeoutedtaskscheduler.h
    569569        HEADERS += iptv/iptvfeederhls.h
     570        HEADERS += iptv/iptvfeederhttp.h
    570571
    571572        SOURCES += iptvchannel.cpp            iptvrecorder.cpp
    572573        SOURCES += iptvsignalmonitor.cpp
    using_backend { 
    577578        SOURCES += iptv/iptvfeederfile.cpp    iptv/iptvfeederlive.cpp
    578579        SOURCES += iptv/iptvfeederrtp.cpp     iptv/timeoutedtaskscheduler.cpp
    579580        SOURCES += iptv/iptvfeederhls.cpp
     581        SOURCES += iptv/iptvfeederhttp.cpp
     582
     583        LIBS += -lccext2 -lccgnu2
    580584
    581585        DEFINES += USING_IPTV
    582586    }
  • new file mythtv/libs/libmythtv/iptv/iptvfeederhttp.cpp

    diff --git a/mythtv/libs/libmythtv/iptv/iptvfeederhttp.cpp b/mythtv/libs/libmythtv/iptv/iptvfeederhttp.cpp
    new file mode 100644
    index 0000000..5fd3dd8
    - +  
     1/** -*- Mode: c++ -*-
     2 *  IPTVFeederHTTP --
     3 *  Copyright (c)
     4 *  Distributed as part of MythTV under GPL v2 and later.
     5 */
     6#include <unistd.h>
     7#include "iptvfeederhttp.h"
     8
     9// MythTV headers
     10#include "mythlogging.h"
     11#include "streamlisteners.h"
     12
     13#define LOC QString("IPTVHTTP: ")
     14#define TS_SIZE 188
     15#define BUFFER_SIZE (128 * TS_SIZE)
     16
     17
     18IPTVFeederHTTP::IPTVFeederHTTP()
     19        : _lock(),_abort(false),_running(false)
     20{
     21        _stream.setTimeout(5000);
     22}
     23
     24IPTVFeederHTTP::~IPTVFeederHTTP()
     25{
     26        Close();
     27}
     28
     29bool IPTVFeederHTTP::IsHTTP(const QString &url)
     30{
     31        return url.startsWith("http://", Qt::CaseInsensitive);
     32}
     33
     34bool IPTVFeederHTTP::Open(const QString &url)
     35{
     36        QMutexLocker locker(&_lock);
     37        QUrl parse(url);
     38    if (parse.scheme().toLower() != "http")
     39    {
     40        LOG(VB_GENERAL, LOG_ERR, LOC + "Open() -- end 1");
     41        return false;
     42    }
     43        QByteArray p=parse.toEncoded();
     44
     45        URLStream::Error status;
     46        status = _stream.get(p.constData());
     47        if(status)
     48        {
     49                LOG(VB_RECORD, LOG_INFO, LOC + QString("Open() -- failed to open stream, error %1").arg(status));
     50                _stream.close();
     51        }
     52        return true;
     53}
     54
     55void IPTVFeederHTTP::Close(void)
     56{
     57        LOG(VB_RECORD, LOG_INFO, LOC + "Close() -- begin");
     58    Stop();
     59       
     60        QMutexLocker locker(&_lock);
     61        _stream.close();
     62}
     63
     64void IPTVFeederHTTP::Run(void)
     65{
     66        LOG(VB_RECORD, LOG_INFO, LOC + "Run() -- begin");
     67    _lock.lock();
     68    _running = true;
     69    _abort   = false;
     70    _lock.unlock();
     71    LOG(VB_RECORD, LOG_INFO, LOC + "Run() -- loop begin");
     72
     73        while(!_abort)
     74        {
     75                uint8_t buffer[BUFFER_SIZE];
     76                if(!_stream.isConnected())
     77                {
     78                        break;
     79                }
     80               
     81                if(_listeners.empty())
     82                {
     83                        usleep(50000);
     84                        continue;
     85                }
     86
     87                _stream.read((char*)buffer,BUFFER_SIZE);
     88                int size=_stream.gcount();
     89                if(size>0)
     90                {
     91                        //LOG(VB_RECORD, LOG_INFO, LOC + QString("Run() -- got %1 bytes of data").arg(size));
     92                        _lock.lock();
     93                        vector<TSDataListener*>::iterator it = _listeners.begin();
     94                        for (; it != _listeners.end(); ++it)
     95                                (*it)->AddData(buffer, size);
     96                        _lock.unlock();
     97                }
     98        }
     99
     100    LOG(VB_RECORD, LOG_INFO, LOC + "Run() -- loop end");
     101
     102    _lock.lock();
     103    _running = false;
     104    _cond.wakeAll();
     105    _lock.unlock();
     106    LOG(VB_RECORD, LOG_INFO, LOC + "Run() -- end");
     107}
     108
     109void IPTVFeederHTTP::Stop(void)
     110{
     111        LOG(VB_RECORD, LOG_INFO, LOC + "Stop() -- begin");
     112    QMutexLocker locker(&_lock);
     113    _abort = true;
     114
     115    while (_running)
     116        _cond.wait(&_lock, 500);
     117    LOG(VB_RECORD, LOG_INFO, LOC + "Stop() -- end");
     118}
     119
     120void IPTVFeederHTTP::AddListener(TSDataListener *item)
     121{
     122    LOG(VB_RECORD, LOG_INFO, LOC + QString("AddListener(0x%1) -- begin")
     123        .arg((uint64_t)item,0,16));
     124    if (!item)
     125    {
     126        LOG(VB_RECORD, LOG_INFO, LOC + QString("AddListener(0x%1) -- end")
     127            .arg((uint64_t)item,0,16));
     128        return;
     129    }
     130
     131    // avoid duplicates
     132    RemoveListener(item);
     133
     134    // add to local list
     135    QMutexLocker locker(&_lock);
     136    _listeners.push_back(item);
     137
     138    LOG(VB_RECORD, LOG_INFO, LOC + QString("AddListener(0x%1) -- end")
     139        .arg((uint64_t)item,0,16));
     140}
     141
     142void IPTVFeederHTTP::RemoveListener(TSDataListener *item)
     143{
     144    LOG(VB_RECORD, LOG_INFO, LOC + QString("RemoveListener(0x%1) -- begin")
     145        .arg((uint64_t)item,0,16));
     146    QMutexLocker locker(&_lock);
     147    vector<TSDataListener*>::iterator it =
     148    find(_listeners.begin(), _listeners.end(), item);
     149
     150    if (it == _listeners.end())
     151    {
     152        LOG(VB_RECORD, LOG_INFO, LOC + QString("RemoveListener(0x%1) -- end 1")
     153            .arg((uint64_t)item,0,16));
     154        return;
     155    }
     156
     157    // remove from local list..
     158    *it = *_listeners.rbegin();
     159    _listeners.resize(_listeners.size() - 1);
     160
     161    LOG(VB_RECORD, LOG_INFO, LOC + QString("RemoveListener(0x%1) -- end 2")
     162        .arg((uint64_t)item,0,16));
     163}
  • new file mythtv/libs/libmythtv/iptv/iptvfeederhttp.h

    diff --git a/mythtv/libs/libmythtv/iptv/iptvfeederhttp.h b/mythtv/libs/libmythtv/iptv/iptvfeederhttp.h
    new file mode 100644
    index 0000000..fadb484
    - +  
     1/** -*- Mode: c++ -*-
     2 *  IPTVFeederHTTP
     3 *  Copyright (c)
     4 *  Distributed as part of MythTV under GPL v2 and later.
     5 */
     6#ifndef _IPTV_FEEDER_HTTP_H_
     7#define _IPTV_FEEDER_HTTP_H_
     8
     9// C++ headers
     10#include <vector>
     11using namespace std;
     12#include <cc++/common.h>
     13using namespace ost;
     14
     15#include <stdint.h>
     16
     17// Qt headers
     18#include <QWaitCondition>
     19#include <QMutex>
     20#include <QUrl>
     21
     22// Mythtv headers
     23#include "iptvfeeder.h"
     24
     25class QString;
     26class TSDataListener;
     27
     28
     29class IPTVFeederHTTP : public IPTVFeeder
     30{
     31  public:
     32    IPTVFeederHTTP();
     33    virtual ~IPTVFeederHTTP();
     34
     35        bool CanHandle(const QString &url) const { return IsHTTP(url); };
     36        bool IsOpen(void) const { return _stream.isConnected(); };
     37
     38    bool Open(const QString &url);
     39    void Close(void);
     40
     41    void Run(void);
     42    void Stop(void);
     43
     44    void AddListener(TSDataListener*);
     45    void RemoveListener(TSDataListener*);
     46
     47        static bool IsHTTP(const QString &url);
     48
     49  private:
     50    IPTVFeederHTTP &operator=(const IPTVFeederHTTP&);
     51    IPTVFeederHTTP(const IPTVFeederHTTP&);
     52
     53  protected:
     54    mutable QMutex          _lock;
     55    vector<TSDataListener*> _listeners;
     56
     57  private:
     58    bool                    _abort;
     59    bool                    _running;
     60    QWaitCondition          _cond;
     61        URLStream               _stream;
     62};
     63
     64#endif // _IPTV_FEEDER_HTTP_H_