Ticket #1966: 1966.patch

File 1966.patch, 101.9 KB (added by danielk, 19 years ago)

Fixes the atscsrcid problem (lightly tested).

  • libs/libmythtv/previouslist.cpp

     
    4040    hourFormat = gContext->GetSetting("TimeFormat");
    4141    timeFormat = gContext->GetSetting("ShortDateFormat") + " " + hourFormat;
    4242    fullDateFormat = dayFormat + " " + hourFormat;
    43     channelOrdering = gContext->GetSetting("ChannelOrdering", "channum + 0");
    4443    channelFormat = gContext->GetSetting("ChannelFormat", "<num> <sign>");
    4544
    4645    allowEvents = true;
  • libs/libmythtv/channelutil.h

     
    88
    99class NetworkInformationTable;
    1010
     11class DBChannel
     12{
     13  public:
     14    DBChannel(const QString &_channum, const QString &_callsign,
     15              uint _chanid, uint _major_chan, uint _minor_chan,
     16              uint _favorite,
     17              const QString &_name, const QString &_icon) :
     18        channum(_channum), callsign(_callsign), chanid(_chanid),
     19        major_chan(_major_chan), minor_chan(_minor_chan),
     20        favorite(_favorite),
     21        name(_name), icon(_icon) {}
     22
     23    bool operator == (uint _chanid) const
     24        { return chanid == _chanid; }
     25
     26    QString channum;
     27    QString callsign;
     28    uint    chanid;
     29    uint    major_chan;
     30    uint    minor_chan;
     31    uint    favorite;
     32    QString name;
     33    QString icon;
     34};
     35typedef vector<DBChannel> DBChanList;
     36
     37
    1138/** \class ChannelUtil
    1239 *  \brief Collection of helper utilities for channel DB use
    1340 */
     
    4471    static int     GetBetterMplexID(int current_mplexid,
    4572                                    int transport_id, int network_id);
    4673
    47     static int     GetTuningParams(int mplexid, QString &modulation);
     74    static bool    GetTuningParams(uint mplexid,
     75                                   QString  &modulation,
     76                                   uint64_t &frequency,
     77                                   uint     &dvb_transportid,
     78                                   uint     &dvb_networkid);
     79
    4880    static bool    GetATSCChannel(uint sourceid, const QString &channum,
    4981                                  uint &major,   uint          &minor);
     82    static bool    IsATSCChannel(uint sourceid, const QString &channum)
     83        { uint m1, m2; GetATSCChannel(sourceid, channum, m1,m2); return m2; }
     84
    5085    // Channel/Service Stuff
    5186    static int     CreateChanID(uint sourceid, const QString &chan_num);
    5287
     
    90125
    91126    static int     GetChanID(uint sourceid, const QString &channum)
    92127        { return GetChannelValueInt("chanid", sourceid, channum); }
    93     static int     GetATSCSRCID(uint sourceid, const QString &channum)
    94         { return GetChannelValueInt("atscsrcid", sourceid, channum); }
     128    static bool    GetChannelData(
     129        uint    sourceid,         const QString &channum,
     130        QString &tvformat,        QString       &modulation,
     131        QString &freqtable,       QString       &freqid,
     132        int     &finetune,        uint64_t      &frequency,
     133        int     &mpeg_prog_num,
     134        uint    &atsc_major,      uint          &atsc_minor,
     135        uint    &dvb_transportid, uint          &dvb_networkid,
     136        uint    &mplexid,         bool          &commfree);
     137    static uint    GetSourceID(uint cardid, const QString &inputname);
    95138    static int     GetProgramNumber(uint sourceid, const QString &channum)
    96139        { return GetChannelValueInt("serviceid", sourceid, channum); }
    97140    static QString GetVideoFilters(uint sourceid, const QString &channum)
    98141        { return GetChannelValueStr("videofilters", sourceid, channum); }
    99142
    100     static QString GetNextChannel(uint           cardid,
    101                                   const QString &inputname,
    102                                   const QString &channum,
    103                                   int            direction,
    104                                   QString       &channelorder,
    105                                   uint          &chanid);
     143    static DBChanList GetChannels(uint srcid, bool vis_only, QString grp="");
     144    static void    SortChannels(DBChanList &list, const QString &order);
    106145
    107     static uint    GetNextChannel(uint           cardid,
    108                                   const QString &inputname,
    109                                   const QString &channum,
    110                                   int            direction,
    111                                   QString       &channelorder)
    112     {
    113         uint chanid = 0;
    114         GetNextChannel(cardid,    inputname,    channum,
    115                        direction, channelorder, chanid);
    116         return chanid;
    117     }
     146    static uint    GetNextChannel(const DBChanList &sorted,
     147                                  uint old_chanid, int direction);
    118148
    119149    static QString GetChannelValueStr(const QString &channel_field,
    120150                                      uint           sourceid,
  • libs/libmythtv/proglist.cpp

     
    2323#include "mythcontext.h"
    2424#include "remoteutil.h"
    2525#include "mythdbcon.h"
     26#include "channelutil.h"
    2627
    2728ProgLister::ProgLister(ProgListType pltype,
    2829                       const QString &view, const QString &from,
     
    3940    hourFormat = gContext->GetSetting("TimeFormat");
    4041    timeFormat = gContext->GetSetting("ShortDateFormat") + " " + hourFormat;
    4142    fullDateFormat = dayFormat + " " + hourFormat;
    42     channelOrdering = gContext->GetSetting("ChannelOrdering", "channum + 0");
     43    channelOrdering = gContext->GetSetting("ChannelOrdering", "channum");
    4344    channelFormat = gContext->GetSetting("ChannelFormat", "<num> <sign>");
    4445
    4546    switch (pltype)
     
    977978    stationList.clear();
    978979    stationList << "";
    979980
    980     query.prepare(QString("SELECT channel.chanid, channel.channum, "
    981                   "channel.callsign, channel.name FROM channel "
    982                   "WHERE channel.visible = 1 "
    983                   "GROUP BY callsign "
    984                   "ORDER BY ") + channelOrdering + ";");
    985     query.exec();
     981    DBChanList channels = ChannelUtil::GetChannels(0, false, "callsign");
     982    ChannelUtil::SortChannels(channels, channelOrdering);
    986983
    987     if (query.isActive() && query.size())
     984    for (uint i = 0; i < channels.size(); i++)
    988985    {
    989         while (query.next())
    990         {
    991             QString chanid = query.value(0).toString();
    992             QString channum = query.value(1).toString();
    993             QString chansign = QString::fromUtf8(query.value(2).toString());
    994             QString channame = QString::fromUtf8(query.value(3).toString());
     986        QString chantext = QDeepCopy<QString>(channelFormat);
     987        chantext
     988            .replace("<num>",  channels[i].channum)
     989            .replace("<sign>", channels[i].callsign)
     990            .replace("<name>", channels[i].name);
    995991
    996             QString chantext = channelFormat;
    997             chantext.replace("<num>", channum)
    998                 .replace("<sign>", chansign)
    999                 .replace("<name>", channame);
     992        viewList << QString::number(channels[i].chanid);
     993        viewTextList << chantext;
    1000994
    1001             viewList << chanid;
    1002             viewTextList << chantext;
    1003 
    1004             powerStation->insertItem(chantext);
    1005             stationList << chansign;
    1006             if (chansign == field[5])
    1007                 powerStation->setCurrentItem(powerStation->count() - 1);
    1008         }
     995        powerStation->insertItem(chantext);
     996        stationList << channels[i].callsign;
     997        if (channels[i].callsign == field[5])
     998            powerStation->setCurrentItem(powerStation->count() - 1);
    1009999    }
     1000
    10101001    powerPopup->addWidget(powerStation);
    10111002
    10121003    powerOkButton = new MythPushButton(powerPopup);
     
    11851176
    11861177    if (type == plChannel) // list by channel
    11871178    {
    1188         MSqlQuery query(MSqlQuery::InitCon());
    1189         query.prepare(QString("SELECT channel.chanid, channel.channum, "
    1190                       "channel.callsign, channel.name FROM channel "
    1191                       "WHERE channel.visible = 1 "
    1192                       "GROUP BY channum, callsign "
    1193                       "ORDER BY ") + channelOrdering + ";");
    1194         query.exec();
     1179        DBChanList channels = ChannelUtil::GetChannels(0, false, "callsign");
     1180        ChannelUtil::SortChannels(channels, channelOrdering);
    11951181
    1196         if (query.isActive() && query.size())
     1182        for (uint i = 0; i < channels.size(); i++)
    11971183        {
    1198             while (query.next())
    1199             {
    1200                 QString chanid = query.value(0).toString();
    1201                 QString channum = query.value(1).toString();
    1202                 QString chansign = QString::fromUtf8(query.value(2).toString());
    1203                 QString channame = QString::fromUtf8(query.value(3).toString());
     1184            QString chantext = QDeepCopy<QString>(channelFormat);
     1185            chantext
     1186                .replace("<num>",  channels[i].channum)
     1187                .replace("<sign>", channels[i].callsign)
     1188                .replace("<name>", channels[i].name);
    12041189
    1205                 QString chantext = channelFormat;
    1206                 chantext.replace("<num>", channum)
    1207                     .replace("<sign>", chansign)
    1208                     .replace("<name>", channame);
    1209 
    1210                 viewList << chanid;
    1211                 viewTextList << chantext;
    1212             }
     1190            viewList << QString::number(channels[i].chanid);
     1191            viewTextList << chantext;
    12131192        }
    1214         if (view != "")
     1193
     1194        if (!view.isEmpty())
    12151195            curView = viewList.findIndex(view);
    12161196    }
    12171197    else if (type == plCategory) // list by category
  • libs/libmythtv/guidegrid.cpp

     
    3131#include "customedit.h"
    3232#include "util.h"
    3333#include "remoteutil.h"
     34#include "channelutil.h"
    3435
    3536bool RunProgramGuide(uint &chanid, QString &channum,
    3637                     bool thread, TV *player,
     
    179180            container->SetDrawFontShadow(false);
    180181    }
    181182
    182     channelOrdering = gContext->GetSetting("ChannelOrdering", "channum + 0");
     183    channelOrdering = gContext->GetSetting("ChannelOrdering", "channum");
    183184    dateformat = gContext->GetSetting("ShortDateFormat", "ddd d");
    184185    unknownTitle = gContext->GetSetting("UnknownTitle", "Unknown");
    185186    unknownCategory = gContext->GetSetting("UnknownCategory", "Unknown");
     
    559560
    560561void GuideGrid::fillChannelInfos(bool gotostartchannel)
    561562{
    562     MSqlQuery query(MSqlQuery::InitCon());
    563 
    564563    m_channelInfos.clear();
    565564
     565    DBChanList channels = ChannelUtil::GetChannels(0, true, "callsign");
     566    ChannelUtil::SortChannels(channels, channelOrdering);
     567
    566568    if (showFavorites)
    567569    {
    568         query.prepare(
    569             "SELECT channel.channum, channel.callsign, "
    570             "       channel.icon,    channel.chanid, "
    571             "       favorites.favid, channel.name "
    572             "FROM videosource, cardinput, favorites, channel "
    573             "WHERE channel.chanid       = favorites.chanid     AND "
    574             "      visible              = 1                    AND "
    575             "      channel.sourceid     = videosource.sourceid AND "
    576             "      videosource.sourceid = cardinput.sourceid "
    577             "GROUP BY channum, callsign "
    578             "ORDER BY " + channelOrdering);
    579 
    580         if (query.exec() && query.isActive())
    581             showFavorites = query.size();
    582         else
    583             MythContext::DBError("fillChannelInfos -- favorites", query);
    584     }
    585 
    586     if (!showFavorites)
    587     {
    588         query.prepare(
    589             "SELECT channel.channum, channel.callsign, "
    590             "       channel.icon,    channel.chanid, "
    591             "       favorites.favid, channel.name "
    592             "FROM videosource, cardinput, "
    593             "       channel LEFT JOIN favorites "
    594             "       ON favorites.chanid = channel.chanid "
    595             "WHERE visible              = 1                    AND "
    596             "      channel.sourceid     = videosource.sourceid AND "
    597             "      videosource.sourceid = cardinput.sourceid "
    598             "GROUP BY channum, callsign "
    599             "ORDER BY " + channelOrdering);
    600 
    601         if (!query.exec() || !query.isActive())
     570        DBChanList tmp;
     571        for (uint i = 0; i < channels.size(); i++)
    602572        {
    603             MythContext::DBError("fillChannelInfos -- all connected", query);
    604             return;
     573            if (channels[i].favorite)
     574                tmp.push_back(channels[i]);
    605575        }
     576
     577        if (!tmp.empty())
     578            channels = tmp;
    606579    }
    607  
     580
    608581    bool startingset = false;
    609     while (query.next())
     582    for (uint i = 0; i < channels.size(); i++)
    610583    {
    611584        ChannelInfo val;
    612 
    613         val.chanstr  = query.value(0).toString();
    614         val.chanid   = query.value(3).toInt();
    615 
    616         // validate the channum and chanid, skip channel if these are invalid
    617         if (val.chanstr == "" || !val.chanid)
    618             continue;
    619 
    620         // fill in the rest of the data...
    621         val.callsign = QString::fromUtf8(query.value(1).toString());
    622         val.iconpath = query.value(2).toString();
    623         val.favid    = query.value(4).toInt();
    624         val.channame = QString::fromUtf8(query.value(5).toString());
     585        val.chanstr  = channels[i].channum;
     586        val.chanid   = channels[i].chanid;
     587        val.callsign = channels[i].callsign;
     588        val.favid    = channels[i].favorite;
     589        val.channame = channels[i].name;
     590        val.iconpath = channels[i].icon;
    625591        val.iconload = false;
    626592
    627593        // set starting channel index if it hasn't been set
     
    633599            m_currentStartChannel = m_channelInfos.size();
    634600            startingset = true;
    635601        }
    636                
     602
    637603        // add the new channel to the list
    638604        m_channelInfos.push_back(val);
    639605    }
     606 
    640607    // set starting channel index to 0 if it hasn't been set
    641608    if (gotostartchannel)
    642609        m_currentStartChannel = (startingset) ? m_currentStartChannel : 0;
  • 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 = "1146";
     13const QString currentDatabaseVersion = "1147";
    1414
    1515static bool UpdateDBVersionNumber(const QString &newnumber);
    1616static bool performActualUpdate(const QString updates[], QString version,
     
    276276update the listings. Using the on-air-guide is currently experimental
    277277and must be selected when you compile %MythTV. Finally, the 'atscsrcid'
    278278field currently contains both the major and minor atsc channels, encoded
    279 in the form (majorChannel * 256 | minorChannel) when using DVB drivers.
     279in the form (atsc_major_chan * 256 | atsc_minor_chan).
    280280
    281281\section program_table Program Entry Table (program)
    282282'category_type' holds one of these exact four strings:
     
    23152315            return false;
    23162316    }
    23172317
     2318    if (dbver == "1146")
     2319    {
     2320        const QString updates[] = {
     2321"ALTER TABLE channel ADD atsc_major_chan INT UNSIGNED NOT NULL default '0';",
     2322"ALTER TABLE channel ADD atsc_minor_chan INT UNSIGNED NOT NULL default '0';",
     2323"UPDATE channel SET atsc_major_chan = atscsrcid / 256;",
     2324"UPDATE channel SET atsc_minor_chan = atscsrcid % 256;",
     2325"UPDATE settings SET data='channum' WHERE value='ChannelOrdering' AND data!='callsign';",
     2326""
     2327};
     2328
     2329        if (!performActualUpdate(updates, "1147", dbver))
     2330            return false;
     2331    }
     2332
    23182333//"ALTER TABLE capturecard DROP COLUMN dvb_recordts;" in 0.21
    23192334//"ALTER TABLE capturecard DROP COLUMN dvb_hw_decoder;" in 0.21
    2320 //"ALTER TABLE cardinput DROP COLUMN  preference;" in 0.22
     2335//"ALTER TABLE cardinput DROP COLUMN preference;" in 0.22
     2336//"ALTER TABLE channel DROP COLUMN atscsrcid;" in 0.22
    23212337
    23222338    return true;
    23232339}
  • libs/libmythtv/eithelper.cpp

     
    1717
    1818const uint EITHelper::kChunkSize = 20;
    1919
    20 static int get_chan_id_from_db(uint sourceid,  uint atscsrcid);
    21 static int get_chan_id_from_db(uint sourceid,  uint serviceid,
    22                                uint networkid, uint transportid);
     20static uint get_chan_id_from_db(uint sourceid,
     21                                uint atscmajor, uint atscminor);
     22static uint get_chan_id_from_db(uint sourceid,  uint serviceid,
     23                                uint networkid, uint transportid);
    2324static void init_fixup(QMap<uint64_t,uint> &fix);
    2425static int calc_eit_utc_offset(void);
    2526
     
    109110    return insertCount;
    110111}
    111112
    112 void EITHelper::SetFixup(uint atscsrcid, uint eitfixup)
     113void EITHelper::SetFixup(uint atsc_major, uint atsc_minor, uint eitfixup)
    113114{
    114115    QMutexLocker locker(&eitList_lock);
    115     fixup[atscsrcid] = eitfixup;
     116    uint atsc_key = (atsc_major << 16) | atsc_minor;
     117    fixup[atsc_key] = eitfixup;
    116118}
    117119
    118120void EITHelper::SetLanguagePreferences(const QStringList &langPref)
     
    138140    sourceid = _sourceid;
    139141}
    140142
    141 void EITHelper::AddEIT(uint atscsrcid, const EventInformationTable *eit)
     143void EITHelper::AddEIT(uint atsc_major, uint atsc_minor,
     144                       const EventInformationTable *eit)
    142145{
    143     EventIDToATSCEvent &events = incomplete_events[atscsrcid];
    144     EventIDToETT &etts = unmatched_etts[atscsrcid];
     146    uint atsc_key = (atsc_major << 16) | atsc_minor;
     147    EventIDToATSCEvent &events = incomplete_events[atsc_key];
     148    EventIDToETT &etts = unmatched_etts[atsc_key];
    145149
    146150    for (uint i = 0; i < eit->EventCount(); i++)
    147151    {
     
    154158
    155159        if (it != etts.end())
    156160        {
    157             CompleteEvent(atscsrcid, ev, *it);
     161            CompleteEvent(atsc_major, atsc_minor, ev, *it);
    158162            etts.erase(it);
    159163        }
    160164        else if (!ev.etm)
    161165        {
    162             CompleteEvent(atscsrcid, ev, QString::null);
     166            CompleteEvent(atsc_major, atsc_minor, ev, QString::null);
    163167        }
    164168        else
    165169        {
     
    171175    }
    172176}
    173177
    174 void EITHelper::AddETT(uint atscsrcid, const ExtendedTextTable *ett)
     178void EITHelper::AddETT(uint atsc_major, uint atsc_minor,
     179                       const ExtendedTextTable *ett)
    175180{
     181    uint atsc_key = (atsc_major << 16) | atsc_minor;
    176182    // Try to complete an Event
    177     ATSCSRCToEvents::iterator eits_it = incomplete_events.find(atscsrcid);
     183    ATSCSRCToEvents::iterator eits_it = incomplete_events.find(atsc_key);
    178184    if (eits_it != incomplete_events.end())
    179185    {
    180186        EventIDToATSCEvent::iterator it = (*eits_it).find(ett->EventID());
    181187        if (it != (*eits_it).end())
    182188        {
    183             CompleteEvent(atscsrcid, *it, ett->ExtendedTextMessage()
    184                           .GetBestMatch(languagePreferences));
     189            CompleteEvent(
     190                atsc_major, atsc_minor, *it,
     191                ett->ExtendedTextMessage().GetBestMatch(languagePreferences));
     192
    185193            if ((*it).desc)
    186194                delete [] (*it).desc;
     195
    187196            (*eits_it).erase(it);
     197
    188198            return;
    189199        }
    190200    }
    191201
    192202    // Couldn't find matching EIT. If not yet in unmatched ETT map, insert it.
    193     EventIDToETT &elist = unmatched_etts[atscsrcid];
     203    EventIDToETT &elist = unmatched_etts[atsc_key];
    194204    if (elist.find(ett->EventID()) == elist.end())
    195205    {
    196206        elist[ett->EventID()] = ett->ExtendedTextMessage()
     
    345355// private methods and functions below this line                    //
    346356//////////////////////////////////////////////////////////////////////
    347357
    348 void EITHelper::CompleteEvent(uint atscsrcid,
     358void EITHelper::CompleteEvent(uint atsc_major, uint atsc_minor,
    349359                              const ATSCEvent &event,
    350360                              const QString   &ett)
    351361{
    352     uint chanid = GetChanID(atscsrcid);
     362    uint chanid = GetChanID(atsc_major, atsc_minor);
    353363    if (!chanid)
    354364        return;
    355365
     
    363373    bool captioned = MPEGDescriptor::Find(list, DescriptorID::caption_service);
    364374    bool stereo = false;
    365375
     376    uint atsc_key = (atsc_major << 16) | atsc_minor;
     377
    366378    QMutexLocker locker(&eitList_lock);
    367379    db_events.enqueue(new DBEvent(chanid, QDeepCopy<QString>(event.title),
    368380                                  QDeepCopy<QString>(ett),
    369381                                  starttime, endtime,
    370                                   fixup[atscsrcid], captioned, stereo));
     382                                  fixup[atsc_key], captioned, stereo));
    371383}
    372384
    373 uint EITHelper::GetChanID(uint atscsrcid)
     385uint EITHelper::GetChanID(uint atsc_major, uint atsc_minor)
    374386{
    375     uint key = sourceid << 16 | atscsrcid;
     387    uint64_t key;
     388    key  = ((uint64_t) sourceid);
     389    key |= ((uint64_t) atsc_minor) << 16;
     390    key |= ((uint64_t) atsc_major) << 32;
     391
    376392    ServiceToChanID::const_iterator it = srv_to_chanid.find(key);
    377393    if (it != srv_to_chanid.end())
    378394        return max(*it, 0);
    379395
    380     int chanid = get_chan_id_from_db(sourceid, atscsrcid);
    381     if (chanid != 0)
     396    uint chanid = get_chan_id_from_db(sourceid, atsc_major, atsc_minor);
     397    if (chanid)
    382398        srv_to_chanid[key] = chanid;
    383399
    384     return max(chanid, 0);
     400    return chanid;
    385401}
    386402
    387403uint EITHelper::GetChanID(uint serviceid, uint networkid, uint tsid)
     
    396412    if (it != srv_to_chanid.end())
    397413        return max(*it, 0);
    398414
    399     int chanid = get_chan_id_from_db(sourceid, serviceid, networkid, tsid);
    400     if (chanid != 0)
     415    uint chanid = get_chan_id_from_db(sourceid, serviceid, networkid, tsid);
     416    if (chanid)
    401417        srv_to_chanid[key] = chanid;
    402418
    403     return max(chanid, 0);
     419    return chanid;
    404420}
    405421
    406 static int get_chan_id_from_db(uint sourceid, uint atscsrcid)
     422static uint get_chan_id_from_db(uint sourceid,
     423                                uint atsc_major, uint atsc_minor)
    407424{
    408425    MSqlQuery query(MSqlQuery::InitCon());
    409426    query.prepare(
    410427            "SELECT chanid, useonairguide "
    411428            "FROM channel "
    412             "WHERE atscsrcid = :ATSCSRCID AND "
    413             "      sourceid  = :SOURCEID");
    414     query.bindValue(":ATSCSRCID", atscsrcid);
     429            "WHERE atsc_major_chan = :MAJORCHAN AND "
     430            "      atsc_minor_chan = :MINORCHAN AND "
     431            "      sourceid        = :SOURCEID");
     432    query.bindValue(":MAJORCHAN", atsc_major);
     433    query.bindValue(":MINORCHAN", atsc_minor);
    415434    query.bindValue(":SOURCEID",  sourceid);
    416435
    417436    if (!query.exec() || !query.isActive())
     
    419438    else if (query.next())
    420439    {
    421440        bool useOnAirGuide = query.value(1).toBool();
    422         return (useOnAirGuide) ? query.value(0).toInt() : -1;
     441        return (useOnAirGuide) ? query.value(0).toUInt() : 0;
    423442    }
    424443
    425     return -1;
     444    return 0;
    426445}
    427446
    428447// Figure out the chanid for this channel
    429 static int get_chan_id_from_db(uint sourceid, uint serviceid,
    430                                uint networkid, uint transportid)
     448static uint get_chan_id_from_db(uint sourceid, uint serviceid,
     449                                uint networkid, uint transportid)
    431450{
    432451    MSqlQuery query(MSqlQuery::InitCon());
    433452
     
    457476    {
    458477        // Check to see if we are interseted in this channel
    459478        bool useOnAirGuide = query.value(1).toBool();
    460         return (useOnAirGuide) ? query.value(0).toInt() : -1;       
     479        return (useOnAirGuide) ? query.value(0).toUInt() : 0;
    461480    }
    462481
    463     return -1;
     482    return 0;
    464483}
    465484
    466485static void init_fixup(QMap<uint64_t,uint> &fix)
  • libs/libmythtv/channelbase.h

     
    1010#include <qsqldatabase.h>
    1111
    1212// MythTV headers
    13 
     13#include "channelutil.h"
    1414#include "frequencies.h"
    1515#include "tv.h"
    1616
     
    3131
    3232    InputBase(QString _name,            QString _startChanNum,
    3333              QString _tuneToChannel,   QString _externalChanger,
    34               uint    _sourceid,        uint    _cardid) :
     34              uint    _sourceid,        uint    _cardid,
     35              const DBChanList &_channels) :
    3536        name(_name),                    startChanNum(_startChanNum),
    3637        tuneToChannel(_tuneToChannel),  externalChanger(_externalChanger),
    3738        sourceid(_sourceid),            cardid(_cardid),
     39        channels(_channels),
    3840        inputNumV4L(-1),
    3941        videoModeV4L1(0),               videoModeV4L2(0) {}
    4042
     
    4749    QString externalChanger; // for using a cable box...
    4850    uint    sourceid;        // associated channel listings source
    4951    uint    cardid;          // input card id
     52    DBChanList channels;
    5053    int     inputNumV4L;
    5154    int     videoModeV4L1;
    5255    int     videoModeV4L2;
     
    8386    virtual int GetFd(void) const { return -1; };
    8487
    8588    // Gets
     89    virtual uint GetNextChannel(uint chanid, int direction) const;
     90    virtual uint GetNextChannel(const QString &channum, int direction) const;
    8691    virtual int GetInputByName(const QString &input) const;
    8792    virtual QString GetInputByNum(int capchannel) const;
    8893    virtual QString GetCurrentName(void) const
     
    101106        { return inputs[GetCurrentInputNum()]->sourceid; }
    102107    virtual uint GetInputCardID(int inputNum) const;
    103108    virtual QStringList GetConnectedInputs(void) const;
    104     virtual QString GetOrdering(void) const
    105         { return channelorder; }
    106109    /// \brief Returns true iff commercial detection is not required
    107110    //         on current channel, for BBC, CBC, etc.
    108111    bool IsCommercialFree(void) const { return commfree; }
     
    110113    virtual QString GetDevice(void) const { return ""; }
    111114
    112115    // Sets
    113     virtual void SetChannelOrdering(const QString &chanorder)
    114         { channelorder = chanorder; }
    115116    virtual void Renumber(uint srcid, const QString &oldChanNum,
    116117                          const QString &newChanNum);
    117118
     
    148149    /// \brief Returns program number in PAT, -1 if unknown.
    149150    virtual int GetProgramNumber(void) const
    150151        { return currentProgramNum; };
    151     /// \brief Returns major channel, -1 if unknown.
    152     virtual int GetMajorChannel(void) const
     152    /// \brief Returns major channel, 0 if unknown.
     153    virtual uint GetMajorChannel(void) const
    153154        { return currentATSCMajorChannel; };
    154     /// \brief Returns minor channel, -1 if unknown.
    155     virtual int GetMinorChannel(void) const
     155    /// \brief Returns minor channel, 0 if unknown.
     156    virtual uint GetMinorChannel(void) const
    156157        { return currentATSCMinorChannel; };
    157     /// \brief Returns DVB original_network_id, -1 if unknown.
    158     virtual int GetOriginalNetworkID(void) const
     158    /// \brief Returns DVB original_network_id, 0 if unknown.
     159    virtual uint GetOriginalNetworkID(void) const
    159160        { return currentOriginalNetworkID; };
    160     /// \brief Returns DVB transport_stream_id, -1 if unknown.
    161     virtual int GetTransportID(void) const
     161    /// \brief Returns DVB transport_stream_id, 0 if unknown.
     162    virtual uint GetTransportID(void) const
    162163        { return currentTransportID; };
    163164
    164165    // \brief Set cardid for scanning
     
    177178    static void StoreInputChannels(const InputMap&);
    178179
    179180    TVRec   *pParent;
    180     QString  channelorder;
    181181    QString  curchannelname;
    182182    int      currentInputID;
    183183    bool     commfree;
    184184    uint     cardid;
    185185    InputMap inputs;
    186186
    187     int     currentATSCMajorChannel;
    188     int     currentATSCMinorChannel;
    189187    int     currentProgramNum;
    190     int     currentOriginalNetworkID;
    191     int     currentTransportID;
     188    uint    currentATSCMajorChannel;
     189    uint    currentATSCMinorChannel;
     190    uint    currentTransportID;
     191    uint    currentOriginalNetworkID;
    192192};
    193193
    194194#endif
  • libs/libmythtv/previouslist.h

     
    4848    QString hourFormat;
    4949    QString timeFormat;
    5050    QString fullDateFormat;
    51     QString channelOrdering;
    5251    QString channelFormat;
    5352
    5453    RecSearchType searchtype;
  • libs/libmythtv/hdhrchannel.cpp

     
    308308
    309309bool HDHRChannel::SetChannelByString(const QString &channum)
    310310{
    311     VERBOSE(VB_CHANNEL, LOC + QString("Set channel '%1'").arg(channum));
     311    QString loc = LOC + QString("SetChannelByString(%1)").arg(channum);
     312    VERBOSE(VB_CHANNEL, loc);
     313   
    312314    if (!Open())
    313315    {
    314         VERBOSE(VB_IMPORTANT, LOC_ERR +
    315                 "Set channel request without active connection");
     316        VERBOSE(VB_IMPORTANT, loc + "Error, Channel object will not open, "
     317                "can not change channels.");
    316318        return false;
    317319    }
    318320
    319321    QString inputName;
    320322    if (!CheckChannel(channum, inputName))
    321323    {
    322         VERBOSE(VB_IMPORTANT, LOC_ERR + "CheckChannel failed. " +
    323                 QString("Please verify channel '%1'").arg(channum) +
    324                 " in the \"mythtv-setup\" Channel Editor.");
     324        VERBOSE(VB_IMPORTANT, loc + "CheckChannel failed. Please verify " +
     325                "the channel in the 'mythtv-setup' Channel Editor.");
    325326        return false;
    326327    }
    327328
     
    337338    if (it == inputs.end())
    338339        return false;
    339340
    340     MSqlQuery query(MSqlQuery::InitCon());
    341     QString thequery = QString(
    342         "SELECT finetune, freqid, tvformat, freqtable, "
    343         "       atscsrcid, commfree, mplexid "
    344         "FROM channel, videosource "
    345         "WHERE videosource.sourceid = channel.sourceid AND "
    346         "      channum = '%1' AND channel.sourceid = '%2'")
    347         .arg(channum).arg((*it)->sourceid);
     341    // Fetch tuning data from the database.
     342    QString tvformat, modulation, freqtable, freqid;
     343    int finetune;
     344    uint64_t frequency;
     345    int mpeg_prog_num;
     346    uint atsc_major, atsc_minor, mplexid, tsid, netid;
    348347
    349     query.prepare(thequery);
    350 
    351     if (!query.exec() || !query.isActive())
    352         MythContext::DBError("fetchtuningparams", query);
    353     if (!query.next())
     348    if (!ChannelUtil::GetChannelData(
     349        (*it)->sourceid, channum,
     350        tvformat, modulation, freqtable, freqid,
     351        finetune, frequency,
     352        mpeg_prog_num, atsc_major, atsc_minor, tsid, netid,
     353        mplexid, commfree))
    354354    {
    355         VERBOSE(VB_IMPORTANT, LOC_ERR + QString(
    356                     "CheckChannel failed because it could not\n"
    357                     "\t\t\tfind channel number '%2' in DB for source '%3'.")
    358                 .arg(channum).arg((*it)->sourceid));
    359355        return false;
    360356    }
    361357
    362     int     finetune  = query.value(0).toInt();
    363     QString freqid    = query.value(1).toString();
    364     QString tvformat  = query.value(2).toString();
    365     QString freqtable = query.value(3).toString();
    366     uint    atscsrcid = query.value(4).toInt();
    367     commfree          = query.value(5).toBool();
    368     uint    mplexid   = query.value(6).toInt();
    369 
    370     QString modulation;
    371     int frequency = ChannelUtil::GetTuningParams(mplexid, modulation);
     358    // If the frequency is zeroed out, don't use it directly.
    372359    bool ok = (frequency > 0);
    373 
    374360    if (!ok)
    375361    {
    376362        frequency = (freqid.toInt(&ok) + finetune) * 1000;
     
    378364    }
    379365    bool isFrequency = ok && (frequency > 10000000);
    380366
    381     curchannelname = channum;
    382     inputs[currentInputID]->startChanNum = curchannelname;
    383 
    384     VERBOSE(VB_CHANNEL, LOC +
    385             QString("freqid = %1, atscsrcid = %2, mplexid = %3")
    386             .arg(freqid).arg(atscsrcid).arg(mplexid));
    387 
    388     if (isFrequency)
     367    // Tune to proper frequency
     368    if ((*it)->externalChanger.isEmpty())
    389369    {
    390         if (!Tune(frequency, inputName, modulation))
    391             return false;
     370        if (isFrequency)
     371        {
     372            if (!Tune(frequency, inputName, modulation))
     373                return false;
     374        }
     375        else
     376        {
     377            if (!TuneTo(freqid.toInt()))
     378                return false;
     379        }
    392380    }
     381    else if (!ChangeExternalChannel(freqid))
     382        return false;
     383
     384    // Set the current channum to the new channel's channum
     385    curchannelname = QDeepCopy<QString>(channum);
     386
     387    // Set the major and minor channel for any additional multiplex tuning
     388    if (atsc_major || atsc_minor)
     389        SetCachedATSCInfo(QString("%1_%2").arg(atsc_major).arg(atsc_minor));
    393390    else
    394     {
    395         if (!TuneTo(freqid.toInt()))
    396             return false;
    397     }
     391        SetCachedATSCInfo(QString("%1_0").arg(channum));
    398392
    399     QString min_maj = QString("%1_0").arg(channum);
    400     if (atscsrcid > 255)
    401     {
    402         min_maj = QString("%1_%2").arg(atscsrcid >> 8).arg(atscsrcid & 0xff);
    403     }
    404     SetCachedATSCInfo(min_maj);
     393    // Set this as the future start channel for this source
     394    inputs[currentInputID]->startChanNum = curchannelname;
    405395
    406396    return true;
    407397}
  • libs/libmythtv/channelbase.cpp

     
    3232
    3333ChannelBase::ChannelBase(TVRec *parent)
    3434    :
    35     pParent(parent), channelorder("channum + 0"), curchannelname(""),
     35    pParent(parent), curchannelname(""),
    3636    currentInputID(-1), commfree(false), cardid(0),
    37     currentATSCMajorChannel(-1), currentATSCMinorChannel(-1),
    38     currentProgramNum(-1), currentOriginalNetworkID(-1),
    39     currentTransportID(-1)
     37    currentProgramNum(-1),
     38    currentATSCMajorChannel(0), currentATSCMinorChannel(0),
     39    currentTransportID(0),      currentOriginalNetworkID(0)
    4040{
    4141}
    4242
     
    4646
    4747bool ChannelBase::SetChannelByDirection(ChannelChangeDirection dir)
    4848{
    49     bool fTune = false;
    50     uint chanid;
    51     QString start, nextchan;
    52     start = nextchan = ChannelUtil::GetNextChannel(
    53         GetCardID(), GetCurrentInput(), GetCurrentName(),
    54         dir,         channelorder,      chanid);
     49    uint startchanid = GetNextChannel(GetCurrentName(), dir);
     50    uint nextchanid  = startchanid;
    5551
     52    bool ok = false;
    5653    do
    5754    {
    58        fTune = SetChannelByString(nextchan);
    59        if (!fTune)
    60        {
    61            nextchan = ChannelUtil::GetNextChannel(
    62                GetCardID(), GetCurrentInput(), GetCurrentName(),
    63                dir,         channelorder,      chanid);
    64        }
     55        if (!(ok = SetChannelByString(ChannelUtil::GetChanNum(nextchanid))))
     56            nextchanid = GetNextChannel(nextchanid, dir);
    6557    }
    66     while (!fTune && nextchan != start);
     58    while (!ok && (nextchanid != startchanid));
    6759
    68     return fTune;
     60    return ok;
    6961}
    7062
     63uint ChannelBase::GetNextChannel(uint chanid, int direction) const
     64{
     65    InputMap::const_iterator it = inputs.find(currentInputID);
     66    if (it == inputs.end())
     67        return 0;
     68
     69    return ChannelUtil::GetNextChannel((*it)->channels, chanid, direction);
     70}
     71
     72uint ChannelBase::GetNextChannel(const QString &channum, int direction) const
     73{
     74    InputMap::const_iterator it = inputs.find(currentInputID);
     75    if (it == inputs.end())
     76        return 0;
     77
     78    uint chanid = ChannelUtil::GetChanID((*it)->sourceid, channum);
     79    return GetNextChannel(chanid, direction);
     80}
     81
    7182int ChannelBase::GetNextInputNum(void) const
    7283{
    7384    // Exit early if inputs don't exist..
     
    349360    int chansep = chan.find("_");
    350361
    351362    currentProgramNum        = -1;
    352     currentOriginalNetworkID = -1;
    353     currentTransportID       = -1;
    354     currentATSCMajorChannel  = -1;
    355     currentATSCMinorChannel  = -1;
     363    currentOriginalNetworkID = 0;
     364    currentTransportID       = 0;
     365    currentATSCMajorChannel  = 0;
     366    currentATSCMinorChannel  = 0;
    356367
    357368    if (progsep >= 0)
    358369    {
     
    375386        }
    376387    }
    377388
    378     if (currentATSCMinorChannel >= 0)
     389    if (currentATSCMinorChannel > 0)
    379390        VERBOSE(VB_CHANNEL,
    380391                QString("ChannelBase(%1)::SetCachedATSCInfo(%2): %3_%4")
    381392                .arg(GetDevice()).arg(chan)
    382393                .arg(currentATSCMajorChannel).arg(currentATSCMinorChannel));
    383     else if ((-1 == currentATSCMajorChannel) && (-1 == currentProgramNum))
     394    else if ((0 == currentATSCMajorChannel) && (0 == currentProgramNum))
    384395        VERBOSE(VB_CHANNEL,
    385396                QString("ChannelBase(%1)::SetCachedATSCInfo(%2): RESET")
    386397                .arg(GetDevice()).arg(chan));
     
    486497        uint inputcardid = query.value(6).toUInt();
    487498        inputcardid = (inputcardid) ? inputcardid : cardid;
    488499
     500        uint sourceid = query.value(5).toUInt();
     501        DBChanList channels = ChannelUtil::GetChannels(sourceid, false);
     502
     503        QString order = gContext->GetSetting("ChannelOrdering", "channum");
     504        ChannelUtil::SortChannels(channels, order);
     505
    489506        inputs[query.value(0).toUInt()] = new InputBase(
    490507            query.value(1).toString(), query.value(2).toString(),
    491508            query.value(3).toString(), query.value(4).toString(),
    492             query.value(5).toUInt(),   inputcardid);
     509            sourceid, inputcardid, channels);
    493510    }
    494511
    495512    // Set initial input to first connected input
  • libs/libmythtv/dvbchannel.h

     
    7676  private:
    7777    int  GetChanID(void) const;
    7878    bool GetTransportOptions(int mplexid);
    79     bool GetChannelOptions(const QString &channum);
     79    bool InitChannelParams(uint sourceid, const QString &channum);
    8080
    8181    void CheckOptions();
    8282    bool CheckModulation(fe_modulation_t modulation) const;
  • libs/libmythtv/eithelper.h

     
    6060    uint GetGPSOffset(void) const { return (uint) (0 - gps_offset); }
    6161
    6262    void SetGPSOffset(uint _gps_offset) { gps_offset = 0 - _gps_offset; }
    63     void SetFixup(uint atscsrcid, uint eitfixup);
     63    void SetFixup(uint atsc_major, uint atsc_minor, uint eitfixup);
    6464    void SetLanguagePreferences(const QStringList &langPref);
    6565    void SetSourceID(uint _sourceid);
    6666
    6767#ifdef USING_BACKEND
    68     void AddEIT(uint atscsrcid, const EventInformationTable *eit);
    69     void AddETT(uint atscsrcid, const ExtendedTextTable     *ett);
     68    void AddEIT(uint atsc_major, uint atsc_minor,
     69                const EventInformationTable *eit);
     70    void AddETT(uint atsc_major, uint atsc_minor,
     71                const ExtendedTextTable     *ett);
    7072    void AddEIT(const DVBEventInformationTable *eit);
    7173#else // if !USING_BACKEND
    7274    void AddEIT(uint, const EventInformationTable*) {}
     
    7779    void PruneCache(uint timestamp);
    7880
    7981  private:
    80     uint GetChanID(uint atscsrcid);
     82    uint GetChanID(uint atsc_major, uint atsc_minor);
    8183    uint GetChanID(uint serviceid, uint networkid, uint transportid);
    8284
    83     void CompleteEvent(uint atscsrcid,
     85    void CompleteEvent(uint atsc_major, uint atsc_minor,
    8486                       const ATSCEvent &event,
    8587                       const QString   &ett);
    8688
  • libs/libmythtv/datadirect.cpp

     
    3030static QString html_escape(QString str);
    3131static void    get_atsc_stuff(QString channum, int sourceid, int freqid,
    3232                              int &major, int &minor, long long &freq);
    33 static uint    create_atscsrcid(QString chan_major, QString chan_minor);
    3433static QString process_dd_station(uint sourceid,
    3534                                  QString  chan_major, QString  chan_minor,
    36                                   QString &tvformat,   uint    &freqid,
    37                                   uint    &atscsrcid);
     35                                  QString &tvformat,   uint    &freqid);
    3836static void    update_channel_basic(uint    sourceid,   bool    insert,
    3937                                    QString xmltvid,    QString callsign,
    4038                                    QString name,       uint    freqid,
     
    680678        "UPDATE channel "
    681679        "SET callsign  = :CALLSIGN,  name   = :NAME, "
    682680        "    channum   = :CHANNUM,   freqid = :FREQID, "
    683         "    atscsrcid = :ATSCSRCID "
     681        "    atsc_major_chan = :MAJORCHAN, "
     682        "    atsc_minor_chan = :MINORCHAN "
    684683        "WHERE xmltvid = :STATIONID AND sourceid = :SOURCEID");
    685684
    686685    while (dd_station_info.next())       
    687686    {
    688         uint    atscsrcid  = 0;
    689687        uint    freqid     = dd_station_info.value(3).toUInt();
    690688        QString chan_major = dd_station_info.value(4).toString();
    691689        QString chan_minor = dd_station_info.value(5).toString();
    692690        QString tvformat   = QString::null;
    693691        QString channum    = process_dd_station(
    694             sourceid, chan_major, chan_minor, tvformat, freqid, atscsrcid);
     692            sourceid, chan_major, chan_minor, tvformat, freqid);
    695693
    696694        chan_update_q.bindValue(":CALLSIGN",  dd_station_info.value(0));
    697695        chan_update_q.bindValue(":NAME",      dd_station_info.value(1));
     
    699697        chan_update_q.bindValue(":CHANNUM",   channum);
    700698        chan_update_q.bindValue(":SOURCEID",  sourceid);
    701699        chan_update_q.bindValue(":FREQID",    freqid);
    702         chan_update_q.bindValue(":ATSCSRCID", atscsrcid);
     700        chan_update_q.bindValue(":MAJORCHAN", chan_major.toUInt());
     701        chan_update_q.bindValue(":MINORCHAN", chan_minor.toUInt());
    703702
    704703        if (!chan_update_q.exec())
    705704        {
     
    17561755    }
    17571756}
    17581757
    1759 static uint create_atscsrcid(QString chan_major, QString chan_minor)
    1760 {
    1761     bool ok;
    1762     uint major = chan_major.toUInt(&ok), atscsrcid = 0;
    1763     if (!ok)
    1764         return atscsrcid;
    1765 
    1766     atscsrcid = major << 8;
    1767     if (chan_minor.isEmpty())
    1768         return atscsrcid;
    1769 
    1770     return atscsrcid | chan_minor.toUInt();
    1771 }
    1772 
    17731758static QString process_dd_station(
    17741759    uint sourceid, QString chan_major, QString chan_minor,
    1775     QString &tvformat, uint &freqid, uint &atscsrcid)
     1760    QString &tvformat, uint &freqid)
    17761761{
    17771762    QString channum = chan_major;
    1778     atscsrcid = create_atscsrcid(chan_major, chan_minor);
     1763    bool ok;
     1764    uint minor = chan_minor.toUInt(&ok);
     1765
    17791766    tvformat = "Default";
    17801767
    1781     if (atscsrcid & 0xff)
     1768    if (minor && ok)
    17821769    {
    17831770        tvformat = "atsc";
    17841771        channum += SourceUtil::GetChannelSeparator(sourceid) + chan_minor;
    17851772    }
    1786 
    1787     if (!freqid && !(atscsrcid & 0xff))
     1773    else if (!freqid)
    17881774        freqid = chan_major.toInt();
    17891775
    17901776    return channum;
     
    17971783{
    17981784    callsign = (callsign.isEmpty()) ? name : callsign;
    17991785
    1800     uint atscsrcid;
    18011786    QString tvformat;
    18021787    QString channum = process_dd_station(
    1803         sourceid, chan_major, chan_minor, tvformat, freqid, atscsrcid);
     1788        sourceid, chan_major, chan_minor, tvformat, freqid);
    18041789
    18051790    // First check if channel already in DB, but without xmltvid
    18061791    MSqlQuery query(MSqlQuery::DDCon());
    18071792    query.prepare("SELECT chanid FROM channel "
    18081793                  "WHERE sourceid = :SOURCEID AND "
    1809                   "      (channum=:CHANNUM OR atscsrcid=:ATSCSRCID)");
     1794                  "      ( channum = :CHANNUM OR "
     1795                  "        ( atsc_major_chan = :MAJORCHAN AND "
     1796                  "          atsc_minor_chan = :MINORCHAN ) )");
    18101797    query.bindValue(":SOURCEID",  sourceid);
    18111798    query.bindValue(":CHANNUM",   channum);
    1812     query.bindValue(":ATSCSRCID", atscsrcid);
     1799    query.bindValue(":MAJORCHAN", chan_major.toUInt());
     1800    query.bindValue(":MINORCHAN", chan_minor.toUInt());
    18131801
    18141802    if (!query.exec() || !query.isActive())
    18151803    {
  • libs/libmythtv/channelutil.cpp

     
    193193
    194194        // Use the frequency we already have for this mplex
    195195        // as it may be one of the other_frequencies for this mplex
    196         QString modulation;
    197196        int mux = ChannelUtil::GetMplexID(sourceid, tsid, netid);
    198         if (mux != -1)
    199             freq = ChannelUtil::GetTuningParams(mux, modulation);
     197        if (mux > 0)
     198        {
     199            QString dummy_mod;
     200            uint dummy_tsid, dummy_netid;
     201            ChannelUtil::GetTuningParams(mux, dummy_mod, freq,
     202                                         dummy_tsid, dummy_netid);
     203        }
    200204
    201205        mux = ChannelUtil::CreateMultiplex(
    202206            sourceid,            "dvb",
     
    566570    return -1;
    567571}
    568572
    569 int ChannelUtil::GetTuningParams(int mplexid, QString &modulation)
     573bool ChannelUtil::GetTuningParams(uint      mplexid,
     574                                  QString  &modulation,
     575                                  uint64_t &frequency,
     576                                  uint     &dvb_transportid,
     577                                  uint     &dvb_networkid)
    570578{
    571     if (mplexid <= 0)
    572         return -1;
     579    if (!mplexid)
     580        return false;
    573581
    574582    MSqlQuery query(MSqlQuery::InitCon());
    575     query.prepare(QString("SELECT frequency, modulation "
    576                           "FROM dtv_multiplex "
    577                           "WHERE mplexid=%1").arg(mplexid));
     583    query.prepare(
     584        "SELECT transportid, networkid, frequency, modulation "
     585        "FROM dtv_multiplex "
     586        "WHERE mplexid = :MPLEXID");
     587    query.bindValue(":MPLEXID", mplexid);
    578588
    579589    if (!query.exec() || !query.isActive())
    580590    {
    581591        MythContext::DBError("GetTuningParams failed ", query);
    582         return -1;
     592        return false;
    583593    }
    584594
    585     if (!query.size())
    586         return -1;
     595    if (!query.next())
     596        return false;
    587597
    588     query.next();
     598    dvb_transportid = query.value(0).toUInt();
     599    dvb_networkid   = query.value(1).toUInt();
     600    frequency       = (uint64_t) query.value(2).toDouble(); // Qt 3.1 compat
     601    modulation      = query.value(3).toString();
    589602
    590     modulation = query.value(1).toString();
    591     return query.value(0).toInt();
     603    return true;
    592604}
    593605
    594606QString ChannelUtil::GetChannelStringField(int chan_id, const QString &field)
     
    796808    return query.exec();
    797809}
    798810
    799 QString ChannelUtil::GetNextChannel(
    800     uint           cardid,       const QString &inputname,
    801     const QString &channum,      int            direction,
    802     QString       &channelorder, uint          &chanid)
    803 {
    804     chanid = 0;
    805     bool isNum = true;
    806     channum.toULong(&isNum);
    807 
    808     if (!isNum && channelorder == "channum + 0")
    809     {
    810         bool has_atsc = GetChannelValueInt("atscsrcid", cardid,
    811                                            inputname, channum);
    812         channelorder = (has_atsc) ? "atscsrcid" : "channum";
    813         if (!has_atsc)
    814         {
    815             QString msg = QString(
    816                 "Your channel ordering method \"channel number (numeric)\"\n"
    817                 "\t\t\twill not work with channels like: '%1' \n"
    818                 "\t\t\tConsider switching to order by \"database order\"  \n"
    819                 "\t\t\tor \"channel number (alpha)\" in the general       \n"
    820                 "\t\t\tsettings section of the frontend setup             \n"
    821                 "\t\t\tSwitched to '%2' order.")
    822                 .arg(channum).arg(channelorder);
    823             VERBOSE(VB_IMPORTANT, LOC + msg);
    824         }
    825     }
    826 
    827     MSqlQuery query(MSqlQuery::InitCon());
    828 
    829     QString querystr = QString(
    830         "SELECT %1 "
    831         "FROM channel,capturecard,cardinput "
    832         "WHERE channel.channum      = :CHANNUM           AND "
    833         "      channel.sourceid     = cardinput.sourceid AND "
    834         "      cardinput.cardid     = capturecard.cardid AND "
    835         "      capturecard.cardid   = :CARDID            AND "
    836         "      capturecard.hostname = :HOSTNAME").arg(channelorder);
    837     query.prepare(querystr);
    838     query.bindValue(":CHANNUM",  channum);
    839     query.bindValue(":CARDID",   cardid);
    840     query.bindValue(":HOSTNAME", gContext->GetHostName());
    841 
    842     QString id = QString::null;
    843 
    844     if (!query.exec() || !query.isActive())
    845         MythContext::DBError("getnextchannel 1", query);
    846     else if (query.next())
    847         id = query.value(0).toString();
    848 
    849     if (id.isEmpty())
    850     {
    851         QString msg = QString(
    852             "Channel: '%1' was not found in the database.\n"
    853             "\t\t\tMost likely, the default channel set for this input\n"
    854             "\t\t\tcardid %2, input '%3'\n"
    855             "\t\t\tin setup is wrong\n")
    856             .arg(channum).arg(cardid).arg(inputname);
    857         VERBOSE(VB_IMPORTANT, LOC + msg);
    858 
    859         querystr = QString(
    860             "SELECT %1 "
    861             "FROM channel, capturecard, cardinput "
    862             "WHERE channel.sourceid     = cardinput.sourceid AND "
    863             "      cardinput.cardid     = capturecard.cardid AND "
    864             "      capturecard.cardid   = :CARDID            AND "
    865             "      capturecard.hostname = :HOSTNAME "
    866             "ORDER BY %2 "
    867             "LIMIT 1").arg(channelorder).arg(channelorder);
    868         query.prepare(querystr);
    869         query.bindValue(":CARDID",   cardid);
    870         query.bindValue(":HOSTNAME", gContext->GetHostName());
    871 
    872         if (!query.exec() || !query.isActive())
    873             MythContext::DBError("getnextchannel 2", query);
    874         else if (query.next())
    875             id = query.value(0).toString();
    876     }
    877 
    878     if (id.isEmpty())
    879     {
    880         VERBOSE(VB_IMPORTANT, LOC_ERR +
    881                 "Couldn't find any channels in the database,\n"
    882                 "\t\t\tplease make sure your inputs are associated\n"
    883                 "\t\t\tproperly with your cards.");
    884         return "";
    885     }
    886 
    887     // Now let's try finding the next channel in the desired direction
    888     QString comp = ">";
    889     QString ordering = "";
    890     QString fromfavorites = "";
    891     QString wherefavorites = "";
    892 
    893     if (direction == CHANNEL_DIRECTION_DOWN)
    894     {
    895         comp = "<";
    896         ordering = " DESC ";
    897     }
    898     else if (direction == CHANNEL_DIRECTION_FAVORITE)
    899     {
    900         fromfavorites = ",favorites";
    901         wherefavorites = "AND favorites.chanid = channel.chanid";
    902     }
    903     else if (direction == CHANNEL_DIRECTION_SAME)
    904     {
    905         comp = "=";
    906     }
    907 
    908     QString wherepart = QString(
    909         "cardinput.cardid     = capturecard.cardid AND "
    910         "capturecard.cardid   = :CARDID            AND "
    911         "capturecard.hostname = :HOSTNAME          AND "
    912         "channel.visible      = 1                  AND "
    913         "cardinput.sourceid = channel.sourceid ");
    914 
    915     querystr = QString(
    916         "SELECT channel.channum, channel.chanid "
    917         "FROM channel, capturecard, cardinput%1 "
    918         "WHERE channel.%2 %3 :ID %4 AND "
    919         "      %5 "
    920         "ORDER BY channel.%6 %7 "
    921         "LIMIT 1")
    922         .arg(fromfavorites).arg(channelorder)
    923         .arg(comp).arg(wherefavorites)
    924         .arg(wherepart).arg(channelorder).arg(ordering);
    925 
    926     query.prepare(querystr);
    927     query.bindValue(":CARDID",   cardid);
    928     query.bindValue(":HOSTNAME", gContext->GetHostName());
    929     query.bindValue(":ID",       id);
    930 
    931     if (!query.exec() || !query.isActive())
    932     {
    933         MythContext::DBError("getnextchannel 3", query);
    934     }
    935     else if (query.next())
    936     {
    937         chanid = query.value(1).toUInt();
    938         return query.value(0).toString();
    939     }
    940     else
    941     {
    942         // Couldn't find the channel going in the desired direction,
    943         // so loop around and find it on the flip side...
    944         comp = "<";
    945         if (direction == CHANNEL_DIRECTION_DOWN)
    946             comp = ">";
    947 
    948         // again, %9 is the limit for this
    949         querystr = QString(
    950             "SELECT channel.channum, channel.chanid "
    951             "FROM channel, capturecard, cardinput%1 "
    952             "WHERE channel.%2 %3 :ID %4 AND "
    953             "      %5 "
    954             "ORDER BY channel.%6 %7 "
    955             "LIMIT 1")
    956             .arg(fromfavorites).arg(channelorder)
    957             .arg(comp).arg(wherefavorites)
    958             .arg(wherepart).arg(channelorder).arg(ordering);
    959 
    960         query.prepare(querystr);
    961         query.bindValue(":CARDID",   cardid);
    962         query.bindValue(":HOSTNAME", gContext->GetHostName());
    963         query.bindValue(":ID",       id);
    964 
    965         if (!query.exec() || !query.isActive())
    966         {
    967             MythContext::DBError("getnextchannel", query);
    968         }
    969         else if (query.next())
    970         {
    971             chanid = query.value(1).toUInt();
    972             return query.value(0).toString();
    973         }
    974         else
    975         {
    976             VERBOSE(VB_IMPORTANT, "getnextchannel, query failed: "<<querystr);
    977         }
    978     }
    979 
    980     // just stay on same channel
    981     chanid = max(GetChannelValueInt("chanid", cardid, inputname, channum), 0);
    982     return channum;
    983 }
    984 
    985811int ChannelUtil::GetChanID(int mplexid,       int service_transport_id,
    986812                           int major_channel, int minor_channel,
    987813                           int program_number)
    988814{
    989     // Currently we don't use the service transport id,
    990     // but we should use it according to ATSC std 65.
    991     (void) service_transport_id;
    992    
    993     MSqlQuery query(MSqlQuery::InitCon());
     815    MSqlQuery query(MSqlQuery::DDCon());
    994816
    995     // This works for transports inserted by a scan
    996     query.prepare(QString("SELECT chanid FROM channel "
    997                           "WHERE serviceID=%1 AND mplexid=%2")
    998                   .arg(program_number).arg(mplexid));
    999    
    1000     if (!query.exec() || !query.isActive())
    1001     {
    1002         MythContext::DBError("Selecting channel/dtv_multiplex 1", query);
    1003         return -1;
    1004     }
    1005     if (query.size())
    1006     {
    1007         query.next();
    1008         return query.value(0).toInt();
    1009     }
    1010 
    1011     if (major_channel <= 0)
    1012         return -1;
    1013 
    1014817    // find source id, so we can find manually inserted ATSC channels
    1015     query.prepare(QString("SELECT sourceid FROM dtv_multiplex "
    1016                           "WHERE mplexid=%2").arg(mplexid));
     818    query.prepare("SELECT sourceid "
     819                  "FROM dtv_multiplex "
     820                  "WHERE mplexid = :MPLEXID");
     821    query.bindValue(":MPLEXID", mplexid);
    1017822    if (!query.exec() || !query.isActive() || !query.size())
    1018823    {
    1019824        MythContext::DBError("Selecting channel/dtv_multiplex 2", query);
    1020825        return -1;
    1021826    }
    1022     query.next();
     827    if (!query.next())
     828        return -1;
     829
    1023830    int source_id = query.value(0).toInt();
    1024831
    1025     uint atsc_src_id = (major_channel << 8) | (minor_channel & 0xff);
    1026 
    1027     // Find manually inserted/edited channels...
    1028832    QString qstr[] =
    1029833    {
    1030         // find based on pcHDTV formatted major and minor channels
     834        // find a proper ATSC channel
     835        QString("SELECT chanid FROM channel,dtv_multiplex "
     836                "WHERE channel.sourceid          = %1 AND "
     837                "      atsc_major_chan           = %2 AND "
     838                "      atsc_minor_chan           = %3 AND "
     839                "      dtv_multiplex.transportid = %4 AND "
     840                "      dtv_multiplex.mplexid     = %5 AND "
     841                "      dtv_multiplex.sourceid    = channel.sourceid AND "
     842                "      dtv_multiplex.mplexid     = channel.mplexid")
     843        .arg(source_id).arg(major_channel).arg(minor_channel)
     844        .arg(service_transport_id).arg(mplexid),
     845
     846        // Find manually inserted/edited channels in order of scariness.
     847
     848        // find renamed channel, where atsc is valid
    1031849        QString("SELECT chanid FROM channel "
     850                "WHERE sourceid=%1 AND "
     851                "atsc_major_chan=%2 AND "
     852                "atsc_minor_chan=%3")
     853        .arg(source_id).arg(major_channel).arg(minor_channel),
     854        // find based on mpeg program number and mplexid alone
     855        QString("SELECT chanid FROM channel "
     856                "WHERE sourceid=%1 AND serviceID=%1 AND mplexid=%2")
     857        .arg(source_id).arg(program_number).arg(mplexid),
     858        // find based on OLD pcHDTV formatted major and minor channels
     859        QString("SELECT chanid FROM channel "
    1032860                "WHERE sourceid=%1 AND channum='%2_%3'")
    1033861        .arg(source_id).arg(major_channel).arg(minor_channel),
    1034         // find based on pcHDTV formatted major channel and program number
    1035         // really old format, still used in freq_id, but we don't check that.
     862        // find based on OLD pcHDTV formatted major channel and program number
    1036863        QString("SELECT chanid FROM channel "
    1037864                "WHERE sourceid=%1 AND channum='%2-%3'")
    1038865        .arg(source_id).arg(major_channel).arg(program_number),
    1039         // find based on DVB formatted major and minor channels
     866        // find based on OLD DVB formatted major and minor channels
    1040867        QString("SELECT chanid FROM channel "
    1041868                "WHERE sourceid=%1 AND channum='%2%3'")
    1042869        .arg(source_id).arg(major_channel).arg(minor_channel),
    1043         // find renamed channel, where atscsrcid is valid
    1044         QString("SELECT chanid FROM channel "
    1045                 "WHERE sourceid=%1 AND atscsrcid=%2")
    1046         .arg(source_id).arg(atsc_src_id),
    1047870    };
    1048871
    1049     for (uint i = 0; i < 4; i++)
     872    for (uint i = 0; i < 6; i++)
    1050873    {
    1051874        query.prepare(qstr[i]);
    1052875        if (!query.exec() || !query.isActive())
    1053         {
    1054876            MythContext::DBError("Selecting channel/dtv_multiplex 3", query);
    1055             return -1;
    1056         }
    1057         if (query.size())
    1058         {
    1059             query.next();
     877        if (query.next())
    1060878            return query.value(0).toInt();
    1061         }
    1062879    }
    1063880
    1064881    return -1;
     
    1164981    QString chanNum = (chan_num == "-1") ?
    1165982        QString::number(service_id) : chan_num;
    1166983
    1167     uint atsc_src_id = (atsc_major_channel << 8) | (atsc_minor_channel & 0xff);
    1168 
    1169984    query.prepare(
    1170985        "INSERT INTO channel "
    1171986        "  (chanid,        channum,    sourceid,   callsign,  "
    1172         "   name,          mplexid,    serviceid,  atscsrcid, "
     987        "   name,          mplexid,    serviceid,             "
     988        "   atsc_major_chan,           atsc_minor_chan,       "
    1173989        "   useonairguide, visible,    freqid,     tvformat,  "
    1174990        "   icon,          xmltvid) "
    1175991        "VALUES "
    1176992        "  (:CHANID,       :CHANNUM,   :SOURCEID,  :CALLSIGN,  "
    1177         "   :NAME,         :MPLEXID,   :SERVICEID, :ATSCSRCID, "
     993        "   :NAME,         :MPLEXID,   :SERVICEID,             "
     994        "   :MAJORCHAN,                :MINORCHAN,             "
    1178995        "   :USEOAG,       :VISIBLE,   :FREQID,    :TVFORMAT,  "
    1179996        "   :ICON,         :XMLTVID)");
    1180997
     
    11881005        query.bindValue(":MPLEXID",   db_mplexid);
    11891006
    11901007    query.bindValue(":SERVICEID", service_id);
    1191     query.bindValue(":ATSCSRCID", atsc_src_id);
     1008    query.bindValue(":MAJORCHAN", atsc_major_channel);
     1009    query.bindValue(":MINORCHAN", atsc_minor_channel);
    11921010    query.bindValue(":USEOAG",    use_on_air_guide);
    11931011    query.bindValue(":VISIBLE",   !hidden);
    11941012    (void) hidden_in_guide; // MythTV can't hide the channel in just the guide.
     
    12231041{
    12241042    MSqlQuery query(MSqlQuery::InitCon());
    12251043
    1226     uint atsc_src_id = (atsc_major_channel << 8) | (atsc_minor_channel & 0xff);
     1044    query.prepare(
     1045        "UPDATE channel "
     1046        "SET mplexid         = :MPLEXID,   serviceid       = :SERVICEID, "
     1047        "    atsc_major_chan = :MAJORCHAN, atsc_minor_chan = :MINORCHAN, "
     1048        "    callsign        = :CALLSIGN,  name            = :NAME,      "
     1049        "    channum         = :CHANNUM,   freqid          = :FREQID,    "
     1050        "    tvformat        = :TVFORMAT,  sourceid        = :SOURCEID   "
     1051        "WHERE chanid=:CHANID");
    12271052
    1228     query.prepare("UPDATE channel "
    1229                   "SET mplexid=:MPLEXID,     serviceid=:SERVICEID, "
    1230                   "    atscsrcid=:ATSCSRCID, callsign=:CALLSIGN, "
    1231                   "    name=:NAME,           channum=:CHANNUM, "
    1232                   "    freqid=:FREQID,       tvformat=:TVFORMAT, "
    1233                   "    sourceid=:SOURCEID "
    1234                   "WHERE chanid=:CHANID");
    1235 
    12361053    query.bindValue(":MPLEXID",   db_mplexid);
    12371054    query.bindValue(":SERVICEID", service_id);
    1238     query.bindValue(":ATSCSRCID", atsc_src_id);
     1055    query.bindValue(":MAJORCHAN", atsc_major_channel);
     1056    query.bindValue(":MINORCHAN", atsc_minor_channel);
    12391057    query.bindValue(":CALLSIGN",  callsign.utf8());
    12401058    query.bindValue(":NAME",      service_name.utf8());
    12411059    query.bindValue(":SOURCEID",  source_id);
     
    12441062        query.bindValue(":CHANNUM",   chan_num);
    12451063    if (freqid > 0)
    12461064        query.bindValue(":FREQID",    freqid);
    1247     if (atsc_major_channel > 0)
     1065    if (atsc_minor_channel > 0)
    12481066        query.bindValue(":TVFORMAT",  "ATSC");
    12491067
    12501068    if (!query.exec() || !query.isActive())
     
    13211139
    13221140    return query.value(0).toString();
    13231141}
     1142
     1143                   
     1144bool ChannelUtil::GetATSCChannel(uint sourceid, const QString &channum,
     1145                                 uint &major,   uint          &minor)
     1146{
     1147    major = minor = 0;
     1148
     1149    MSqlQuery query(MSqlQuery::InitCon());
     1150    query.prepare(
     1151        "SELECT atsc_major_chan, atsc_minor_chan "
     1152        "FROM channel "
     1153        "WHERE channum  = :CHANNUM AND "
     1154        "      sourceid = :SOURCEID");
     1155
     1156    query.bindValue(":SOURCEID", sourceid);
     1157    query.bindValue(":CHANNUM",  channum);
     1158
     1159    if (!query.exec() || !query.isActive())
     1160        MythContext::DBError("getchannelvalue", query);
     1161    else if (query.next())
     1162    {
     1163        major = query.value(0).toUInt();
     1164        minor = query.value(1).toUInt();
     1165        return true;
     1166    }
     1167
     1168    return false;
     1169}
     1170
     1171bool ChannelUtil::GetChannelData(
     1172    uint    sourceid,         const QString &channum,
     1173    QString &tvformat,        QString       &modulation,
     1174    QString &freqtable,       QString       &freqid,
     1175    int     &finetune,        uint64_t      &frequency,
     1176    int     &mpeg_prog_num,
     1177    uint    &atsc_major,      uint          &atsc_minor,
     1178    uint    &dvb_transportid, uint          &dvb_networkid,
     1179    uint    &mplexid,
     1180    bool    &commfree)
     1181{
     1182    tvformat      = modulation = freqtable = freqid = QString::null;
     1183    finetune      = 0;
     1184    frequency     = 0;
     1185    mpeg_prog_num = -1;
     1186    atsc_major    = atsc_minor = mplexid = 0;
     1187    commfree      = false;
     1188
     1189    MSqlQuery query(MSqlQuery::InitCon());
     1190    query.prepare(
     1191        "SELECT finetune, freqid, tvformat, freqtable, "
     1192        "       commfree, mplexid, "
     1193        "       atsc_major_chan, atsc_minor_chan, serviceid "
     1194        "FROM channel, videosource "
     1195        "WHERE videosource.sourceid = channel.sourceid AND "
     1196        "      channum              = :CHANNUM         AND "
     1197        "      channel.sourceid     = :SOURCEID");
     1198    query.bindValue(":CHANNUM",  channum);
     1199    query.bindValue(":SOURCEID", sourceid);
     1200
     1201    if (!query.exec() || !query.isActive())
     1202    {
     1203        MythContext::DBError("GetChannelData", query);
     1204        return false;
     1205    }
     1206    else if (!query.next())
     1207    {
     1208        VERBOSE(VB_IMPORTANT, QString(
     1209                    "GetChannelData() failed because it could not\n"
     1210                    "\t\t\tfind channel number '%1' in DB for source '%2'.")
     1211                .arg(channum).arg(sourceid));
     1212        return false;
     1213    }
     1214
     1215    finetune      = query.value(0).toInt();
     1216    freqid        = query.value(1).toString();
     1217    tvformat      = query.value(2).toString();
     1218    freqtable     = query.value(3).toString();
     1219    commfree      = query.value(4).toBool();
     1220    mplexid       = query.value(5).toUInt();
     1221    atsc_major    = query.value(6).toUInt();
     1222    atsc_minor    = query.value(7).toUInt();
     1223    mpeg_prog_num = query.value(8).toUInt();
     1224
     1225    if (!mplexid)
     1226        return true;
     1227
     1228    return GetTuningParams(mplexid, modulation, frequency,
     1229                           dvb_transportid, dvb_networkid);
     1230}
     1231
     1232DBChanList ChannelUtil::GetChannels(uint sourceid, bool vis_only, QString grp)
     1233{
     1234    DBChanList list;
     1235    QMap<uint,uint> favorites;
     1236    MSqlQuery query(MSqlQuery::InitCon());
     1237    query.prepare(
     1238        "SELECT chanid, favid "
     1239        "FROM favorites");
     1240    if (!query.exec() || !query.isActive())
     1241        MythContext::DBError("get channels -- favorites", query);
     1242    else
     1243    {
     1244        while (query.next())
     1245            favorites[query.value(0).toUInt()] = query.value(1).toUInt();
     1246    }
     1247
     1248    QString qstr =
     1249        "SELECT channum, callsign, chanid, "
     1250        "       atsc_major_chan, atsc_minor_chan, "
     1251        "       name, icon "
     1252        "FROM channel ";
     1253
     1254    if (sourceid)
     1255        qstr += QString("WHERE sourceid='%1' ").arg(sourceid);
     1256    else
     1257        qstr += ",cardinput,capturecard "
     1258            "WHERE cardinput.sourceid = channel.sourceid   AND "
     1259            "      cardinput.cardid   = capturecard.cardid     ";
     1260
     1261    if (vis_only)
     1262        qstr += "AND visible=1 ";
     1263
     1264    if (!grp.isEmpty())
     1265        qstr += QString("GROUP BY %1 ").arg(grp);
     1266
     1267    query.prepare(qstr);
     1268    if (!query.exec() || !query.isActive())
     1269    {
     1270        MythContext::DBError("get channels -- sourceid", query);
     1271        return list;
     1272    }
     1273
     1274    while (query.next())
     1275    {
     1276        if (query.value(0).toString().isEmpty() || !query.value(2).toUInt())
     1277            continue; // skip if channum blank, or chanid empty
     1278
     1279        DBChannel chan(
     1280            query.value(0).toString(),                    /* channum    */
     1281            QString::fromUtf8(query.value(1).toString()), /* callsign   */
     1282            query.value(2).toUInt(),                      /* chanid     */
     1283            query.value(3).toUInt(),                      /* ATSC major */
     1284            query.value(4).toUInt(),                      /* ATSC minor */
     1285            favorites[query.value(2).toUInt()],           /* favid      */
     1286            QString::fromUtf8(query.value(5).toString()), /* name       */
     1287            query.value(6).toString());                   /* icon       */
     1288
     1289        list.push_back(chan);
     1290    }
     1291
     1292    return list;
     1293}
     1294
     1295inline bool lt_callsign(const DBChannel &a, const DBChannel &b)
     1296{
     1297    return QString::localeAwareCompare(a.callsign, b.callsign) < 0;
     1298}
     1299
     1300inline bool lt_smart(const DBChannel &a, const DBChannel &b)
     1301{
     1302    int cmp = 0;
     1303    if (a.major_chan && b.major_chan)
     1304    {
     1305        if ((cmp = a.major_chan - b.major_chan))
     1306            return cmp < 0;
     1307
     1308        if ((cmp = a.minor_chan - b.minor_chan))
     1309            return cmp < 0;
     1310    }
     1311
     1312    bool isIntA, isIntB;
     1313    int a_int = a.channum.toUInt(&isIntA);
     1314    int b_int = a.channum.toUInt(&isIntB);
     1315    if (isIntA && isIntB)
     1316    {
     1317        cmp = a_int - b_int;
     1318        if (cmp)
     1319            return cmp < 0;
     1320    }
     1321    else
     1322    {
     1323        return QString::localeAwareCompare(a.channum, b.channum) < 0;
     1324    }
     1325
     1326    return lt_callsign(a,b);
     1327}
     1328
     1329void ChannelUtil::SortChannels(DBChanList &list, const QString &order)
     1330{
     1331    if (order.lower() == "callsign")
     1332        sort(list.begin(), list.end(), lt_callsign);
     1333    else /* if (sortorder == "channum") */
     1334        sort(list.begin(), list.end(), lt_smart);
     1335}
     1336
     1337uint ChannelUtil::GetNextChannel(const DBChanList &sorted,
     1338                                 uint old_chanid, int direction)
     1339{
     1340    DBChanList::const_iterator it =
     1341        find(sorted.begin(), sorted.end(), old_chanid);
     1342
     1343    if (it == sorted.end())
     1344        it = sorted.begin(); // not in list, pretend we are on first channel
     1345
     1346    if (it == sorted.end())
     1347        return 0; // no channels..
     1348
     1349    if (CHANNEL_DIRECTION_DOWN == direction)
     1350    {
     1351        if (it == sorted.begin())
     1352            return sorted.rbegin()->chanid;
     1353        it--;
     1354    }
     1355    else if (CHANNEL_DIRECTION_UP == direction)
     1356    {
     1357        it++;
     1358        if (it == sorted.end())
     1359            it = sorted.begin();
     1360    }
     1361    else if (CHANNEL_DIRECTION_FAVORITE == direction)
     1362    {
     1363        DBChanList::const_iterator it_orig = it;
     1364        for (;;++it)
     1365        {
     1366            if (it == sorted.end())
     1367                it = sorted.begin();
     1368
     1369            if (it == it_orig)
     1370            {
     1371                if (!it->favorite)
     1372                    ++it;
     1373                break; // no (other?) favorites
     1374            }
     1375
     1376            if (it->favorite)
     1377                break; // found next favorite
     1378        }
     1379    }
     1380
     1381    return it->chanid;
     1382}
  • libs/libmythtv/mpeg/atscstreamdata.cpp

     
    117117    _eit_version.clear();
    118118    _eit_section_seen.clear();
    119119
    120     _sourceid_to_atscsrcid.clear();
     120    _sourceid_to_atsc_maj_min.clear();
    121121    _atsc_eit_pids.clear();
    122122    _atsc_ett_pids.clear();
    123123
     
    275275            for (uint i = 0; i < _atsc_eit_listeners.size(); i++)
    276276                _atsc_eit_listeners[i]->HandleEIT(pid, &eit);
    277277
    278             const uint atscsrcid = GetATSCSRCID(eit.SourceID());
    279             if (atscsrcid && _eit_helper)
    280                 _eit_helper->AddEIT(atscsrcid, &eit);
     278            const uint mm = GetATSCMajorMinor(eit.SourceID());
     279            if (mm && _eit_helper)
     280                _eit_helper->AddEIT(mm >> 16, mm & 0xffff, &eit);
    281281               
    282282            return true;
    283283        }
     
    291291
    292292            if (ett.IsEventETM() && _eit_helper) // Guide ETTs
    293293            {
    294                 const uint atscsrcid = GetATSCSRCID(ett.SourceID());
    295                 if (atscsrcid)
    296                     _eit_helper->AddETT(atscsrcid, &ett);
     294                const uint mm = GetATSCMajorMinor(ett.SourceID());
     295                if (mm)
     296                    _eit_helper->AddETT(mm >> 16, mm & 0xffff, &ett);
    297297            }
    298298
    299299            return true;
     
    452452    for (uint i = 0; i < _atsc_main_listeners.size(); i++)
    453453        _atsc_main_listeners[i]->HandleVCT(tsid, vct);
    454454
    455     _sourceid_to_atscsrcid.clear();
     455    _sourceid_to_atsc_maj_min.clear();
    456456    for (uint i = 0; i < vct->ChannelCount() ; i++)
    457457    {
    458458        if (vct->IsHiddenInGuide(i))
     
    477477                .arg(vct->MajorChannel(i))
    478478                .arg(vct->MinorChannel(i)));
    479479
    480         _sourceid_to_atscsrcid[vct->SourceID(i)] =
    481             vct->MajorChannel(i) << 8 | vct->MinorChannel(i);
     480        _sourceid_to_atsc_maj_min[vct->SourceID(i)] =
     481            vct->MajorChannel(i) << 16 | vct->MinorChannel(i);
    482482    }
    483483}
    484484
  • libs/libmythtv/mpeg/atscstreamdata.h

     
    3838    /// Current UTC to GPS time offset in seconds
    3939    uint GPSOffset(void) const { return _GPS_UTC_offset; }
    4040
    41     inline uint GetATSCSRCID(uint eit_sourceid) const;
    42     inline bool HasATSCSRCIDMap(void) const;
     41    inline uint GetATSCMajorMinor(uint eit_sourceid) const;
     42    inline bool HasATSCMajorMinorMap(void) const;
    4343    bool HasEITPIDChanges(const uint_vec_t &in_use_pid) const;
    4444    bool GetEITPIDChanges(const uint_vec_t &in_use_pid,
    4545                          uint_vec_t &pids_to_add,
     
    120120    atsc_eit_pid_map_t        _atsc_eit_pids;
    121121    atsc_ett_pid_map_t        _atsc_ett_pids;
    122122
    123     QMap<uint,uint>           _sourceid_to_atscsrcid;
     123    QMap<uint,uint>           _sourceid_to_atsc_maj_min;
    124124
    125125
    126126    // Signals
     
    146146};
    147147
    148148
    149 inline uint ATSCStreamData::GetATSCSRCID(uint eit_sourceid) const
     149inline uint ATSCStreamData::GetATSCMajorMinor(uint eit_sourceid) const
    150150{
    151151    QMutexLocker locker(&_listener_lock);
    152     return _sourceid_to_atscsrcid[eit_sourceid];
     152    return _sourceid_to_atsc_maj_min[eit_sourceid];
    153153}
    154154
    155 inline bool ATSCStreamData::HasATSCSRCIDMap(void) const
     155inline bool ATSCStreamData::HasATSCMajorMinorMap(void) const
    156156{
    157157    QMutexLocker locker(&_listener_lock);
    158     return _sourceid_to_atscsrcid.size();
     158    return !_sourceid_to_atsc_maj_min.empty();
    159159}
    160160
    161161inline int ATSCStreamData::VersionTVCT(uint tsid) const
  • libs/libmythtv/dvbchannel.cpp

     
    5252#include "mythdbcon.h"
    5353#include "tv_rec.h"
    5454#include "cardutil.h"
     55#include "channelutil.h"
    5556
    5657#include "dvbtypes.h"
    5758#include "dvbchannel.h"
     
    242243    return true;
    243244}
    244245
    245 bool DVBChannel::SetChannelByString(const QString &chan)
     246bool DVBChannel::SetChannelByString(const QString &channum)
    246247{
    247     QString func = QString("SetChannelByString(%1)").arg(chan);
    248     VERBOSE(VB_CHANNEL, LOC + func);
     248    QString tmp     = QString("SetChannelByString(%1): ").arg(channum);
     249    QString loc     = LOC + tmp;
     250    QString loc_err = LOC_ERR + tmp;
     251
     252    VERBOSE(VB_CHANNEL, loc);
    249253    if (fd_frontend < 0)
    250254    {
    251         VERBOSE(VB_IMPORTANT, LOC_ERR + func + QString(": not open"));
     255        VERBOSE(VB_IMPORTANT, loc_err + "Channel object "
     256                "will not open, can not change channels.");
    252257
    253258        return false;
    254259    }
    255260
    256     if (curchannelname == chan && !first_tune)
     261    if (curchannelname == channum && !first_tune)
    257262    {
    258         VERBOSE(VB_CHANNEL, LOC + func + ": already on channel");
     263        VERBOSE(VB_CHANNEL, loc + "Already on channel");
    259264        return true;
    260265    }
    261266
    262267    QString inputName;
    263     if (!CheckChannel(chan, inputName))
     268    if (!CheckChannel(channum, inputName))
    264269    {
    265         VERBOSE(VB_IMPORTANT, LOC + "CheckChannel failed. " +
    266                 QString("Please verify channel '%1'").arg(chan) +
    267                 " in the \"mythtv-setup\" Channel Editor.");
     270        VERBOSE(VB_IMPORTANT, loc_err +
     271                "CheckChannel failed. Please verify the channel "
     272                "in the 'mythtv-setup' Channel Editor.");
     273
    268274        return false;
    269275    }
    270     // If CheckChannel filled in the inputName we need to
    271     // change inputs.
    272     if (!inputName.isEmpty())
     276
     277    // If CheckChannel filled in the inputName we need to change inputs.
     278    if (!inputName.isEmpty() && (nextInputID == currentInputID))
    273279        nextInputID = GetInputByName(inputName);
    274    
    275     if (GetChannelOptions(chan) == false)
     280
     281    // Get the input data for the channel
     282    int inputid = (nextInputID >= 0) ? nextInputID : currentInputID;
     283    InputMap::const_iterator it = inputs.find(inputid);
     284    if (it == inputs.end())
     285        return false;
     286
     287    // Initialize all the tuning parameters
     288    if (!InitChannelParams((*it)->sourceid, channum))
    276289    {
    277         VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to get channel options for " +
    278                 QString("channel '%1'.").arg(chan));
    279        
     290        VERBOSE(VB_IMPORTANT, loc_err +
     291                "Failed to initialize channel options");
     292
    280293        return false;
    281294    }
    282295
     
    285298
    286299    if (!Tune(cur_tuning))
    287300    {
    288         VERBOSE(VB_IMPORTANT, LOC_ERR + "Tuning to frequency for " +
    289                 QString("channel '%1'.").arg(chan));
     301        VERBOSE(VB_IMPORTANT, loc_err + "Tuning to frequency.");
    290302
    291303        return false;
    292304    }
    293305
    294     curchannelname = chan;
     306    curchannelname = QDeepCopy<QString>(channum);
    295307
    296     VERBOSE(VB_CHANNEL, LOC + "Tuned to frequency for " +
    297             QString("channel '%1'.").arg(chan));
     308    VERBOSE(VB_CHANNEL, loc + "Tuned to frequency.");
    298309
    299310    currentInputID = nextInputID;
    300     inputs[currentInputID]->startChanNum = curchannelname;
     311    inputs[currentInputID]->startChanNum = QDeepCopy<QString>(curchannelname);
    301312
    302313    return true;
    303314}
     
    333344    return SetChannelByString((*it)->startChanNum);
    334345}
    335346
    336 /** \fn DVBChannel::GetChannelOptions(const QString &)
    337  *  \brief This function called when tuning to a specific stream.
     347/** \fn DVBChannel::InitChannelParams(uint,const QString&)
     348 *  \brief Initializes all variables pertaining to a channel.
     349 *
     350 *  \sa GetTransportOptions(int) which this calls to initialize
     351 *         variables required to initially tune to the
     352 *         transport where the channel may be found.
     353 *
     354 *  \return true on success and false on failure
    338355 */
    339 bool DVBChannel::GetChannelOptions(const QString &channum)
     356bool DVBChannel::InitChannelParams(uint sourceid, const QString &channum)
    340357{
    341     // Reset Channel data
    342     currentATSCMajorChannel = currentATSCMinorChannel = -1;
    343     currentProgramNum = -1;
    344     currentOriginalNetworkID = currentTransportID = -1;
     358    QString tvformat, modulation, freqtable, freqid;
     359    int finetune;
     360    uint64_t frequency;
     361    uint mplexid;
    345362
    346     MSqlQuery query(MSqlQuery::InitCon());
    347     query.prepare(
    348         "SELECT chanid, serviceid, channel.mplexid, atscsrcid, "
    349         "       cardinputid, networkid, transportid "
    350         "FROM channel, cardinput, capturecard, dtv_multiplex "
    351         "WHERE channel.mplexid    = dtv_multiplex.mplexid AND "
    352         "      cardinput.sourceid = channel.sourceid      AND "
    353         "      capturecard.cardid = cardinput.cardid      AND "
    354         "      cardinput.cardid   = :CARDID               AND "
    355         "      channel.channum    = :CHANNUM");
    356     query.bindValue(":CARDID",  GetCardID());
    357     query.bindValue(":CHANNUM", channum);
    358 
    359     if (!query.exec() || !query.isActive())
     363    if (!ChannelUtil::GetChannelData(
     364            sourceid,   channum,
     365            tvformat,   modulation,   freqtable,   freqid,
     366            finetune,   frequency,    currentProgramNum,
     367            currentATSCMajorChannel,  currentATSCMinorChannel,
     368            currentTransportID,       currentOriginalNetworkID,
     369            mplexid,    commfree))
    360370    {
    361         MythContext::DBError("GetChannelOptions - ChanID", query);
    362371        return false;
    363372    }
    364373
    365     uint mplexid = 0;
    366     while (query.next() && !mplexid)
    367     {
    368         if (query.value(4).toInt() != nextInputID)
    369             continue;
     374    if (currentATSCMinorChannel)
     375        currentProgramNum = -1;
    370376
    371         currentProgramNum = query.value(1).toUInt();
    372         mplexid           = query.value(2).toUInt();
    373 
    374         if (query.value(3).toUInt() & 0xff)
    375         {
    376             currentATSCMajorChannel  = query.value(3).toUInt() >> 8;
    377             currentATSCMinorChannel  = query.value(3).toUInt() & 0xff;
    378             currentTransportID       = query.value(6).toUInt();
    379             currentProgramNum        = -1;
    380         }
    381         else if (query.value(5).toUInt() > 0)
    382         {
    383             currentOriginalNetworkID = query.value(5).toUInt();
    384             currentTransportID       = query.value(6).toUInt();
    385         }
    386     }
    387 
    388377    if (mplexid)
    389378        return GetTransportOptions(mplexid);
    390379
     
    395384/** \fn DVBChannel::GetTransportOptions(int mplexid)
    396385 *  \brief Initializes tuning from database using mplexid.
    397386 *
    398  *  \todo pParent doesn't exist when you create a DVBChannel from videosource
    399  *        but this is important (i think) for remote backends
    400387 *  \return true on success and false on failure
    401388 */
    402389bool DVBChannel::GetTransportOptions(int mplexid)
  • libs/libmythtv/videosource.cpp

     
    2929#include "scanwizard.h"
    3030#include "cardutil.h"
    3131#include "sourceutil.h"
     32#include "channelutil.h"
    3233#include "frequencies.h"
    3334
    3435#ifdef USING_DVB
     
    16141615    else if (query.next())
    16151616        startChan = query.value(0).toString();
    16161617
    1617     // Get the existing channels on the connected source
    1618     query.prepare(
    1619         "SELECT channum "
    1620         "FROM channel "
    1621         "WHERE sourceid = :SOURCEID "
    1622         "ORDER BY atscsrcid, channum");
    1623     query.bindValue(":SOURCEID", sourceid.toUInt());
     1618    DBChanList channels = ChannelUtil::GetChannels(sourceid.toUInt(), false);
    16241619
    1625     QString nnsc = startChan.isEmpty() ? "" : startChan;
    1626     if (!query.exec() || !query.isActive())
     1620    if (channels.empty())
    16271621    {
    1628         addSelection(tr("DB Error, see console"), nnsc);
    1629         MythContext::DBError("SetSourceID -- get channels", query);
     1622        addSelection(tr("Please add channels to this source"),
     1623                     startChan.isEmpty() ? "" : startChan);
     1624        return;
    16301625    }
    1631     else if (query.size() > 0)
     1626
     1627    // If there are channels sort them, then add them
     1628    // (selecting the old start channel if it is there).
     1629    QString order = gContext->GetSetting("ChannelOrdering", "channum");
     1630    ChannelUtil::SortChannels(channels, order);
     1631    for (uint i = 0; i < channels.size(); i++)
    16321632    {
    1633         // If there are channels add them, and
    1634         // highlight the old start channel
    1635         while (query.next())
    1636         {
    1637             const QString channum = query.value(0).toString();
    1638             addSelection(channum, channum, channum == startChan);
    1639         }
     1633        const QString channum = channels[i].channum;
     1634        addSelection(channum, channum, channum == startChan);
    16401635    }
    1641     else
    1642     {
    1643         addSelection(tr("Please add channels to this source"), nnsc);
    1644     }
    16451636}
    16461637
    16471638class InputPriority: public SpinBoxSetting, public CISetting {
  • libs/libmythtv/tv_rec.cpp

     
    10691069        channel->SetChannelByString(startchannel);
    10701070    else
    10711071        channel->SwitchToInput(inputname, startchannel);
    1072 
    1073     // Set channel ordering, and check validity...
    1074     QString chanorder = gContext->GetSetting("ChannelOrdering", "channum + 0");
    1075     ChannelUtil::GetNextChannel(cardid, inputname, startchannel,
    1076                                 BROWSE_SAME, chanorder);
    1077     channel->SetChannelOrdering(chanorder);
    10781072}
    10791073
    10801074void TVRec::CloseChannel(void)
     
    28152809{
    28162810    QString compare     = "<=";
    28172811    QString sortorder   = "desc";
    2818     QString input       = channel->GetCurrentInput();
    2819     QString order       = channel->GetOrdering();
    2820     int     chanid      = -1;
     2812    uint     chanid     = 0;
    28212813
    28222814    if (BROWSE_SAME == direction)
    2823         chanid = ChannelUtil::GetNextChannel(
    2824             cardid, input, channum, CHANNEL_DIRECTION_SAME, order);
     2815        chanid = channel->GetNextChannel(channum, CHANNEL_DIRECTION_SAME);
    28252816    else if (BROWSE_UP == direction)
    2826         chanid = ChannelUtil::GetNextChannel(
    2827             cardid, input, channum, CHANNEL_DIRECTION_UP, order);
     2817        chanid = channel->GetNextChannel(channum, CHANNEL_DIRECTION_UP);
    28282818    else if (BROWSE_DOWN == direction)
    2829         chanid = ChannelUtil::GetNextChannel(
    2830             cardid, input, channum, CHANNEL_DIRECTION_DOWN, order);
     2819        chanid = channel->GetNextChannel(channum, CHANNEL_DIRECTION_DOWN);
    28312820    else if (BROWSE_FAVORITE == direction)
    2832         chanid = ChannelUtil::GetNextChannel(
    2833             cardid, input, channum, CHANNEL_DIRECTION_FAVORITE, order);
     2821        chanid = channel->GetNextChannel(channum, CHANNEL_DIRECTION_FAVORITE);
    28342822    else if (BROWSE_LEFT == direction)
    28352823    {
    2836         chanid = ChannelUtil::GetNextChannel(
    2837             cardid, input, channum, CHANNEL_DIRECTION_SAME, order);
     2824        chanid = channel->GetNextChannel(channum, CHANNEL_DIRECTION_SAME);
    28382825        compare = "<";
    28392826    }
    28402827    else if (BROWSE_RIGHT == direction)
    28412828    {
    2842         chanid = ChannelUtil::GetNextChannel(
    2843             cardid, input, channum, CHANNEL_DIRECTION_SAME, order);
     2829        chanid = channel->GetNextChannel(channum, CHANNEL_DIRECTION_SAME);
    28442830        compare = ">";
    28452831        sortorder = "asc";
    28462832    }
     
    30473033
    30483034    if (channel && !channum.isEmpty() && (channum.find("NextChannel") >= 0))
    30493035    {
    3050         int dir = channum.right(channum.length() - 12).toInt();
    3051         uint chanid;
    3052         QString channelordering = channel->GetOrdering();
    3053         channum = ChannelUtil::GetNextChannel(
    3054             cardid,                    channel->GetCurrentInput(),
    3055             channel->GetCurrentName(), dir,
    3056             channelordering,           chanid);
     3036        int dir     = channum.right(channum.length() - 12).toInt();
     3037        uint chanid = channel->GetNextChannel(0, dir);
     3038        channum     = ChannelUtil::GetChanNum(chanid);
    30573039    }
    30583040
    30593041    return channum;
     
    30813063
    30823064        if (atsc)
    30833065        {
    3084             uint atscsrcid = ChannelUtil::GetATSCSRCID(sourceid, newchannum);
    3085             uint major = atscsrcid >> 8;
    3086             uint minor = atscsrcid & 0xff;
     3066            uint major, minor = 0;
     3067            ChannelUtil::GetATSCChannel(sourceid, newchannum, major, minor);
    30873068
    30883069            if (minor && atsc->HasChannel(major, minor))
    30893070            {
  • libs/libmythtv/programinfo.cpp

     
    40024002        querystr += " GROUP BY program.starttime, channel.channum, "
    40034003            "  channel.callsign, program.title ";
    40044004    if (!sql.contains(" ORDER BY "))
    4005         querystr += QString(" ORDER BY program.starttime, ") +
    4006                     gContext->GetSetting("ChannelOrdering", "channum+0") + " ";
     4005        querystr += " ORDER BY program.starttime, program.chanid ";
    40074006    if (!sql.contains(" LIMIT "))
    40084007        querystr += " LIMIT 1000 ";
    40094008
     
    40964095
    40974096    QString ip        = gContext->GetSetting("BackendServerIP");
    40984097    QString port      = gContext->GetSetting("BackendServerPort");
    4099     QString chanorder = gContext->GetSetting("ChannelOrdering", "channum + 0");
    41004098
    41014099    // ----------------------------------------------------------------------
    41024100
     
    41344132
    41354133    // ----------------------------------------------------------------------
    41364134
    4137     QString thequery = "SELECT recorded.chanid,recorded.starttime,recorded.endtime,"
    4138                        "recorded.title,recorded.subtitle,recorded.description,"
    4139                        "recorded.hostname,channum,name,callsign,commflagged,cutlist,"
    4140                        "recorded.autoexpire,editing,bookmark,recorded.category,"
    4141                        "recorded.recgroup,record.dupin,record.dupmethod,"
    4142                        "record.recordid,outputfilters,"
    4143                        "recorded.seriesid,recorded.programid,recorded.filesize, "
    4144                        "recorded.lastmodified, recorded.findid, "
    4145                        "recorded.originalairdate, recorded.playgroup, "
    4146                        "recorded.basename, recorded.progstart, "
    4147                        "recorded.progend, recorded.stars, "
    4148                        "recordedprogram.stereo, recordedprogram.hdtv, "
    4149                        "recordedprogram.closecaptioned "
    4150                        "FROM recorded "
    4151                        "LEFT JOIN record ON recorded.recordid = record.recordid "
    4152                        "LEFT JOIN channel ON recorded.chanid = channel.chanid "
    4153                        "LEFT JOIN recordedprogram ON (recorded.chanid = recordedprogram.chanid "
    4154                               "AND recorded.starttime = recordedprogram.starttime) "
    4155                        "WHERE (recorded.deletepending = 0 OR "
    4156                               "DATE_ADD(recorded.lastmodified, "
    4157                                        "INTERVAL 5 MINUTE) <= NOW()) "
    4158                        "ORDER BY recorded.starttime";
     4135    QString thequery =
     4136        "SELECT recorded.chanid,recorded.starttime,recorded.endtime,"
     4137        "recorded.title,recorded.subtitle,recorded.description,"
     4138        "recorded.hostname,channum,name,callsign,commflagged,cutlist,"
     4139        "recorded.autoexpire,editing,bookmark,recorded.category,"
     4140        "recorded.recgroup,record.dupin,record.dupmethod,"
     4141        "record.recordid,outputfilters,"
     4142        "recorded.seriesid,recorded.programid,recorded.filesize, "
     4143        "recorded.lastmodified, recorded.findid, "
     4144        "recorded.originalairdate, recorded.playgroup, "
     4145        "recorded.basename, recorded.progstart, "
     4146        "recorded.progend, recorded.stars, "
     4147        "recordedprogram.stereo, recordedprogram.hdtv, "
     4148        "recordedprogram.closecaptioned "
     4149        "FROM recorded "
     4150        "LEFT JOIN record ON recorded.recordid = record.recordid "
     4151        "LEFT JOIN channel ON recorded.chanid = channel.chanid "
     4152        "LEFT JOIN recordedprogram ON "
     4153        " ( recorded.chanid    = recordedprogram.chanid AND "
     4154        "   recorded.starttime = recordedprogram.starttime ) "
     4155        "WHERE ( recorded.deletepending = 0 OR "
     4156        "        DATE_ADD(recorded.lastmodified,  INTERVAL 5 MINUTE) <= NOW() "
     4157        "      ) "
     4158        "ORDER BY recorded.starttime";
    41594159
    41604160    if ( bDescending )
    41614161        thequery += " DESC";
    41624162
    4163     thequery += ", " + chanorder + " DESC;";
     4163    QString chanorder = gContext->GetSetting("ChannelOrdering", "channum");
     4164    if (chanorder.left(5) != "smart")
     4165        thequery += ", " + chanorder + " DESC;";
     4166    else // approximation which the DB can handle
     4167        thequery += ",atsc_major_chan,atsc_minor_chan,channum,callsign DESC;";
    41644168
    41654169    query.prepare(thequery);
    41664170
    4167     if (query.exec() && query.isActive() && query.size() > 0)
     4171    if (!query.exec() || !query.isActive())
    41684172    {
     4173        MythContext::DBError("ProgramList::FromRecorded", query);
     4174        return true;
     4175    }
     4176    else
     4177    {
    41694178        while (query.next())
    41704179        {
    41714180            ProgramInfo *proginfo = new ProgramInfo;
  • libs/libmythtv/eitscanner.cpp

     
    232232            "      channum             != ''               AND "
    233233            "      cardinput.cardid     = :CARDID "
    234234            "GROUP BY mplexid "
    235             "ORDER BY cardinput.sourceid, atscsrcid, mplexid");
     235            "ORDER BY cardinput.sourceid, mplexid, "
     236            "         atsc_major_chan, atsc_minor_chan ");
    236237        query.bindValue(":CARDID", rec->GetCaptureCardNum());
    237238
    238239        if (!query.exec() || !query.isActive())
  • libs/libmythtv/channel.cpp

     
    411411    return finished;
    412412}
    413413
    414 bool Channel::SetChannelByString(const QString &chan)
     414bool Channel::SetChannelByString(const QString &channum)
    415415{
    416     VERBOSE(VB_CHANNEL, QString("Channel(%1)::SetChannelByString(%2)")
    417             .arg(device).arg(chan));
     416    QString loc = LOC + QString("SetChannelByString(%1)").arg(channum);
     417    VERBOSE(VB_CHANNEL, loc);
    418418   
    419419    if (!Open())
    420420    {
    421         VERBOSE(VB_IMPORTANT, QString(
    422                     "Channel(%1)::SetChannelByString(): Channel object "
    423                     "wasn't open, can't change channels").arg(device));
     421        VERBOSE(VB_IMPORTANT, loc + "Error, Channel object will not open, "
     422                "can not change channels.");
    424423        return false;
    425424    }
    426425
    427426    QString inputName;
    428     if (!CheckChannel(chan, inputName))
     427    if (!CheckChannel(channum, inputName))
    429428    {
    430         VERBOSE(VB_IMPORTANT, LOC + "CheckChannel failed. " +
    431                 QString("Please verify channel '%1'").arg(chan) +
    432                 " in the \"mythtv-setup\" Channel Editor.");
     429        VERBOSE(VB_IMPORTANT, loc + "CheckChannel failed. Please verify " +
     430                "the channel in the 'mythtv-setup' Channel Editor.");
    433431        return false;
    434432    }
    435433
     
    437435    // change inputs and return, since the act of changing
    438436    // inputs will change the channel as well.
    439437    if (!inputName.isEmpty())
    440         return ChannelBase::SwitchToInput(inputName, chan);
     438        return ChannelBase::SwitchToInput(inputName, channum);
    441439
    442440    SetCachedATSCInfo("");
    443441
     
    445443    if (it == inputs.end())
    446444        return false;
    447445
    448     MSqlQuery query(MSqlQuery::InitCon());
    449     QString thequery = QString(
    450         "SELECT finetune, freqid, tvformat, freqtable, "
    451         "       atscsrcid, commfree, mplexid "
    452         "FROM channel, videosource "
    453         "WHERE videosource.sourceid = channel.sourceid AND "
    454         "      channum = '%1' AND channel.sourceid = '%2'")
    455         .arg(chan).arg((*it)->sourceid);
     446    // Fetch tuning data from the database.
     447    QString tvformat, modulation, freqtable, freqid;
     448    int finetune;
     449    uint64_t frequency;
     450    int mpeg_prog_num;
     451    uint atsc_major, atsc_minor, mplexid, tsid, netid;
    456452
    457     query.prepare(thequery);
    458 
    459     if (!query.exec() || !query.isActive())
    460         MythContext::DBError("fetchtuningparams", query);
    461     if (query.size() <= 0)
     453    if (!ChannelUtil::GetChannelData(
     454        (*it)->sourceid, channum,
     455        tvformat, modulation, freqtable, freqid,
     456        finetune, frequency,
     457        mpeg_prog_num, atsc_major, atsc_minor, tsid, netid,
     458        mplexid, commfree))
    462459    {
    463         VERBOSE(VB_IMPORTANT, QString(
    464                     "Channel(%1): CheckChannel failed because it could not\n"
    465                     "\t\t\tfind channel number '%2' in DB for source '%3'.")
    466                 .arg(device).arg(chan).arg((*it)->sourceid));
    467460        return false;
    468461    }
    469     query.next();
    470462
    471     int finetune      = query.value(0).toInt();
    472     QString freqid    = query.value(1).toString();
    473     QString tvformat  = query.value(2).toString();
    474     QString freqtable = query.value(3).toString();
    475     uint atscsrcid    = query.value(4).toInt();
    476     commfree          = query.value(5).toBool();
    477     uint mplexid      = query.value(6).toInt();
    478 
    479     QString modulation;
    480     int frequency = ChannelUtil::GetTuningParams(mplexid, modulation);
     463    // If the frequency is zeroed out, don't use it directly.
    481464    bool ok = (frequency > 0);
    482 
    483465    if (!ok)
    484466    {
    485467        frequency = (freqid.toInt(&ok) + finetune) * 1000;
     
    487469    }
    488470    bool isFrequency = ok && (frequency > 10000000);
    489471
     472    // If we are tuning to a freqid, rather than an actual frequency,
     473    // we need to set the frequency table to use.
    490474    if (!isFrequency)
    491475    {
    492         if (freqtable == "default" || freqtable.isNull() || freqtable.isEmpty())
     476        if (freqtable == "default" || freqtable.isEmpty())
    493477            SetFreqTable(defaultFreqTable);
    494478        else
    495479            SetFreqTable(freqtable);
    496480    }
    497481
     482    // Set NTSC, PAL, ATSC, etc.
    498483    SetFormat(tvformat);
    499484
    500     curchannelname = chan;
    501 
     485    // Setup filters & recording picture attributes for framegrabing recorders.
    502486    if (pParent)
    503         pParent->SetVideoFiltersForChannel(GetCurrentSourceID(), chan);
    504 
     487        pParent->SetVideoFiltersForChannel(GetCurrentSourceID(), channum);
    505488    InitPictureAttributes();
    506489
    507     inputs[currentInputID]->startChanNum = curchannelname;
    508 
    509     // Tune
     490    // Tune to proper frequency
    510491    if ((*it)->externalChanger.isEmpty())
    511492    {
    512493        if (isFrequency)
     
    523504    else if (!ChangeExternalChannel(freqid))
    524505        return false;
    525506
    526     QString min_maj = QString("%1_0").arg(chan);
    527     if (atscsrcid > 255)
    528         min_maj = QString("%1_%2")
    529             .arg(atscsrcid >> 8).arg(atscsrcid & 0xff);
     507    // Set the current channum to the new channel's channum
     508    curchannelname = QDeepCopy<QString>(channum);
    530509
    531     SetCachedATSCInfo(min_maj);
     510    // Set the major and minor channel for any additional multiplex tuning
     511    if (atsc_major || atsc_minor)
     512        SetCachedATSCInfo(QString("%1_%2").arg(atsc_major).arg(atsc_minor));
     513    else
     514        SetCachedATSCInfo(QString("%1_0").arg(channum));
    532515
     516    // Set this as the future start channel for this source
     517    inputs[currentInputID]->startChanNum = curchannelname;
     518
    533519    return true;
    534520}
    535521
  • programs/mythfrontend/globalsettings.cpp

     
    983983{
    984984    HostComboBox *gc = new HostComboBox("ChannelOrdering");
    985985    gc->setLabel(QObject::tr("Channel ordering"));
    986     gc->addSelection(QObject::tr("channel number (numeric)"), "channum + 0");
    987     gc->addSelection(QObject::tr("channel number (alpha)"), "channum");
    988     gc->addSelection(QObject::tr("database order"), "chanid");
    989     gc->addSelection(QObject::tr("channel name"), "callsign");
    990     gc->addSelection(QObject::tr("ATSC channel"), "atscsrcid");
     986    gc->addSelection(QObject::tr("channel number"), "channum");
     987    gc->addSelection(QObject::tr("channel name"),   "callsign");
    991988    return gc;
    992989}
    993990
  • programs/mythfrontend/manualschedule.cpp

     
    3434#include "libmythtv/scheduledrecording.h"
    3535#include "libmythtv/recordingtypes.h"
    3636#include "libmythtv/remoteutil.h"
     37#include "libmythtv/channelutil.h"
    3738
    3839ManualSchedule::ManualSchedule(MythMainWindow *parent, const char *name)
    3940              : MythDialog(parent, name)
     
    7273    m_channel->setBackgroundOrigin(WindowOrigin);
    7374
    7475
    75     QString chanorder = gContext->GetSetting("ChannelOrdering", "channum + 0");
     76    QString longChannelFormat = gContext->GetSetting("LongChannelFormat",
     77                                                     "<num> <name>");
     78    QString chanorder = gContext->GetSetting("ChannelOrdering", "channum");
     79    DBChanList channels = ChannelUtil::GetChannels(0, false, "callsign");
     80    ChannelUtil::SortChannels(channels, chanorder);
    7681
    77     MSqlQuery query(MSqlQuery::InitCon());
    78     query.prepare(QString("SELECT chanid, channum, callsign, name "
    79                           "FROM channel GROUP BY channum, callsign "
    80                           "ORDER BY %1;").arg(chanorder));
     82    for (uint i = 0; i < channels.size(); i++)
     83    {
     84        QString chantext = QDeepCopy<QString>(longChannelFormat);
     85        chantext
     86            .replace("<num>",  channels[i].channum)
     87            .replace("<sign>", channels[i].callsign)
     88            .replace("<name>", channels[i].name);
    8189
    82     QString longChannelFormat =
    83         gContext->GetSetting("LongChannelFormat", "<num> <name>");
    84 
    85     if (query.exec() && query.isActive() && query.size()) {
    86       while(query.next()) {
    87           QString channel = longChannelFormat;
    88           channel.replace("<num>", query.value(1).toString())
    89               .replace("<sign>", QString::fromUtf8(query.value(2).toString()))
    90               .replace("<name>", QString::fromUtf8(query.value(3).toString()));
    91           m_channel->insertItem(channel);
    92           m_chanids << query.value(0).toString();
    93       }
    94      
     90        m_channel->insertItem(chantext);
     91        m_chanids << QString::number(channels[i].chanid);
    9592    }
    9693
    9794    hbox->addWidget(m_channel);
  • programs/mythbackend/mainserver.cpp

     
    987987
    988988    QString ip = gContext->GetSetting("BackendServerIP");
    989989    QString port = gContext->GetSetting("BackendServerPort");
    990     QString chanorder = gContext->GetSetting("ChannelOrdering", "channum + 0");
    991990
    992991    QMap<QString, int> inUseMap;
    993992    QString inUseKey;
     
    10191018        }
    10201019
    10211020
    1022     QString thequery = "SELECT recorded.chanid,recorded.starttime,recorded.endtime,"
    1023                        "recorded.title,recorded.subtitle,recorded.description,"
    1024                        "recorded.hostname,channum,name,callsign,commflagged,cutlist,"
    1025                        "recorded.autoexpire,editing,bookmark,recorded.category,"
    1026                        "recorded.recgroup,record.dupin,record.dupmethod,"
    1027                        "record.recordid,outputfilters,"
    1028                        "recorded.seriesid,recorded.programid,recorded.filesize, "
    1029                        "recorded.lastmodified, recorded.findid, "
    1030                        "recorded.originalairdate, recorded.playgroup, "
    1031                        "recorded.basename, recorded.progstart, "
    1032                        "recorded.progend, recorded.stars, "
    1033                        "recordedprogram.stereo, recordedprogram.hdtv, "
    1034                        "recordedprogram.closecaptioned, transcoded, "
    1035                        "recorded.recpriority "
    1036                        "FROM recorded "
    1037                        "LEFT JOIN record ON recorded.recordid = record.recordid "
    1038                        "LEFT JOIN channel ON recorded.chanid = channel.chanid "
    1039                        "LEFT JOIN recordedprogram ON (recorded.chanid = recordedprogram.chanid "
    1040                               "AND recorded.starttime = recordedprogram.starttime) "
    1041                        "WHERE (recorded.deletepending = 0 OR "
    1042                               "DATE_ADD(recorded.lastmodified, "
    1043                                        "INTERVAL 5 MINUTE) <= NOW()) "
    1044                        "ORDER BY recorded.starttime";
     1021    QString thequery =
     1022        "SELECT recorded.chanid,recorded.starttime,recorded.endtime,"
     1023        "recorded.title,recorded.subtitle,recorded.description,"
     1024        "recorded.hostname,channum,name,callsign,commflagged,cutlist,"
     1025        "recorded.autoexpire,editing,bookmark,recorded.category,"
     1026        "recorded.recgroup,record.dupin,record.dupmethod,"
     1027        "record.recordid,outputfilters,"
     1028        "recorded.seriesid,recorded.programid,recorded.filesize, "
     1029        "recorded.lastmodified, recorded.findid, "
     1030        "recorded.originalairdate, recorded.playgroup, "
     1031        "recorded.basename, recorded.progstart, "
     1032        "recorded.progend, recorded.stars, "
     1033        "recordedprogram.stereo, recordedprogram.hdtv, "
     1034        "recordedprogram.closecaptioned, transcoded, "
     1035        "recorded.recpriority "
     1036        "FROM recorded "
     1037        "LEFT JOIN record ON recorded.recordid = record.recordid "
     1038        "LEFT JOIN channel ON recorded.chanid = channel.chanid "
     1039        "LEFT JOIN recordedprogram ON "
     1040        " ( recorded.chanid = recordedprogram.chanid AND "
     1041        "  recorded.starttime = recordedprogram.starttime ) "
     1042        "WHERE ( recorded.deletepending = 0 OR "
     1043        "        DATE_ADD(recorded.lastmodified,  INTERVAL 5 MINUTE) <= NOW() "
     1044        "      ) "
     1045        "ORDER BY recorded.starttime";
    10451046
    10461047    if (type == "Delete")
    10471048        thequery += " DESC";
    10481049
    1049     thequery += ", " + chanorder + " DESC;";
     1050    QString chanorder = gContext->GetSetting("ChannelOrdering", "channum");
     1051    if (chanorder.left(5) != "smart")
     1052        thequery += ", " + chanorder + " DESC;";
     1053    else // approximation which the DB can handle
     1054        thequery += ",atsc_major_chan,atsc_minor_chan,channum,callsign DESC;";
    10501055
    10511056    QStringList outputlist;
    10521057    QString fileprefix = gContext->GetFilePrefix();
     
    10551060
    10561061    query.prepare(thequery);
    10571062
    1058     if (query.exec() && query.isActive() && query.size() > 0)
     1063    if (!query.exec() || !query.isActive())
    10591064    {
     1065        MythContext::DBError("ProgramList::FromRecorded", query);
     1066        outputlist << "0";
     1067    }
     1068    else
     1069    {
    10601070        outputlist << QString::number(query.size());
    10611071
    10621072        while (query.next())
     
    12481258            delete proginfo;
    12491259        }
    12501260    }
    1251     else
    1252         outputlist << "0";
    12531261
    12541262    for (ri = schedList.begin(); ri != schedList.end(); ri++)
    12551263        delete (*ri);