Ticket #6614: livetv_inputgroups.patch

File livetv_inputgroups.patch, 6.5 KB (added by stichnot@…, 15 years ago)
  • mythtv/programs/mythbackend/mainserver.cpp

    old new  
    2525
    2626#include <list>
    2727#include <iostream>
     28#include <algorithm>
    2829using namespace std;
    2930
    3031#include <sys/stat.h>
     
    4142#include "libmyth/mythcontext.h"
    4243#include "libmyth/util.h"
    4344#include "libmyth/mythdbcon.h"
     45#include "libmythtv/cardutil.h"
     46#include "libmythtv/sourceutil.h"
    4447
    4548#include "mainserver.h"
    4649#include "scheduler.h"
     
    100103
    101104};
    102105
     106// This is a copy of is_input_group_busy from channelbase.cpp.
     107static bool is_input_group_busy(
     108    uint                       inputid,
     109    uint                       groupid,
     110    const vector<uint>        &excluded_cardids,
     111    QMap<uint,bool>           &busygrp,
     112    QMap<uint,bool>           &busyrec,
     113    QMap<uint,TunedInputInfo> &busyin,
     114    uint                      &mplexid_restriction)
     115{
     116    // If none are busy, we don't need to check further
     117    QMap<uint,bool>::const_iterator bit = busygrp.find(groupid);
     118    if ((bit != busygrp.end()) && !*bit)
     119        return false;
     120
     121    vector<TunedInputInfo> conflicts;
     122    vector<uint> cardids = CardUtil::GetGroupCardIDs(groupid);
     123    for (uint i = 0; i < cardids.size(); i++)
     124    {
     125        if (find(excluded_cardids.begin(),
     126                 excluded_cardids.end(), cardids[i]) != excluded_cardids.end())
     127        {
     128            continue;
     129        }
     130
     131        TunedInputInfo info;
     132        QMap<uint,bool>::const_iterator it = busyrec.find(cardids[i]);
     133        if (it == busyrec.end())
     134        {
     135            busyrec[cardids[i]] = RemoteIsBusy(cardids[i], info);
     136            it = busyrec.find(cardids[i]);
     137            if (*it)
     138                busyin[cardids[i]] = info;
     139        }
     140
     141        if (*it)
     142            conflicts.push_back(busyin[cardids[i]]);
     143    }
     144
     145    // If none are busy, we don't need to check further
     146    busygrp[groupid] = !conflicts.empty();
     147    if (conflicts.empty())
     148        return false;
     149
     150    InputInfo in;
     151    in.inputid = inputid;
     152    if (!CardUtil::GetInputInfo(in))
     153        return true;
     154
     155    // If they aren't using the same source they are definately busy
     156    bool is_busy_input = false;
     157
     158    for (uint i = 0; i < conflicts.size() && !is_busy_input; i++)
     159        is_busy_input = (in.sourceid != conflicts[i].sourceid);
     160
     161    if (is_busy_input)
     162        return true;
     163
     164    // If the source's channels aren't digitally tuned then there is a conflict
     165    is_busy_input = !SourceUtil::HasDigitalChannel(in.sourceid);
     166    if (!is_busy_input && conflicts[0].chanid)
     167    {
     168        MSqlQuery query(MSqlQuery::InitCon());
     169        query.prepare(
     170            "SELECT mplexid "
     171            "FROM channel "
     172            "WHERE chanid = :CHANID");
     173        query.bindValue(":CHANID", conflicts[0].chanid);
     174        if (!query.exec())
     175            MythContext::DBError("is_input_group_busy", query);
     176        else if (query.next())
     177        {
     178            mplexid_restriction = query.value(0).toUInt();
     179            mplexid_restriction = (32767 == mplexid_restriction) ?
     180                0 : mplexid_restriction;
     181        }
     182    }
     183
     184    return is_busy_input;
     185}
     186
     187// This is a copy of is_input_busy from channelbase.cpp.
     188static bool is_input_busy(
     189    uint                       inputid,
     190    const vector<uint>        &groupids,
     191    const vector<uint>        &excluded_cardids,
     192    QMap<uint,bool>           &busygrp,
     193    QMap<uint,bool>           &busyrec,
     194    QMap<uint,TunedInputInfo> &busyin,
     195    uint                      &mplexid_restriction)
     196{
     197    bool is_busy = false;
     198    for (uint i = 0; i < groupids.size() && !is_busy; i++)
     199    {
     200        is_busy |= is_input_group_busy(
     201            inputid, groupids[i], excluded_cardids,
     202            busygrp, busyrec, busyin, mplexid_restriction);
     203    }
     204    return is_busy;
     205}
     206
     207static bool is_input_in_busy_group(uint inputid)
     208{
     209    vector<uint> groupids = CardUtil::GetInputGroups(inputid);
     210    vector<uint> excluded_cardids;
     211    excluded_cardids.push_back(CardUtil::GetCardID(inputid));
     212    QMap<uint,bool>           busygrp;
     213    QMap<uint,bool>           busyrec;
     214    QMap<uint,TunedInputInfo> busyin;
     215    uint mplexid_restriction = 0;
     216    return is_input_busy(inputid, groupids, excluded_cardids,
     217                         busygrp, busyrec, busyin, mplexid_restriction);
     218}
     219
     220static bool is_card_in_busy_group(uint cardid)
     221{
     222    vector<uint> inputids = CardUtil::GetInputIDs(cardid);
     223    for (uint i = 0; i < inputids.size(); i++)
     224    {
     225        if (is_input_in_busy_group(inputids[i]))
     226            return true;
     227    }
     228    return false;
     229}
     230
     231
    103232QMutex MainServer::truncate_and_close_lock;
    104233
    105234class ProcessRequestThread : public QThread
     
    25282657        if ((enchost == pbshost) &&
    25292658            (elink->IsConnected()) &&
    25302659            (!elink->IsBusy()) &&
     2660            !is_card_in_busy_group(elink->GetCardID()) &&
    25312661            (!elink->IsTunerLocked()))
    25322662        {
    25332663            encoder = elink;
     
    26462776                enchost = elink->GetHostName();
    26472777
    26482778            if (enchost == pbshost && elink->IsConnected() &&
    2649                 !elink->IsBusy() && !elink->IsTunerLocked())
     2779                !elink->IsBusy() &&
     2780                !is_card_in_busy_group(elink->GetCardID()) &&
     2781                !elink->IsTunerLocked())
    26502782            {
    26512783                encoder = elink;
    26522784                retval = iter.key();
     
    26572789        }
    26582790
    26592791        if ((retval == -1 || lastcard) && elink->IsConnected() &&
    2660             !elink->IsBusy() && !elink->IsTunerLocked())
     2792            !elink->IsBusy() &&
     2793            !is_card_in_busy_group(elink->GetCardID()) &&
     2794            !elink->IsTunerLocked())
    26612795        {
    26622796            encoder = elink;
    26632797            retval = iter.key();
     
    27072841
    27082842        if ((elink->IsConnected()) &&
    27092843            (!elink->IsBusy()) &&
     2844            !is_card_in_busy_group(elink->GetCardID()) &&
    27102845            (!elink->IsTunerLocked()))
    27112846        {
    27122847            count++;
     
    27312866
    27322867        if ((elink->IsConnected()) &&
    27332868            (!elink->IsBusy()) &&
     2869            !is_card_in_busy_group(elink->GetCardID()) &&
    27342870            (!elink->IsTunerLocked()))
    27352871        {
    27362872            strlist << QString::number(iter.key());
     
    27802916            if ((retval == -1) &&
    27812917                (elink->IsConnected()) &&
    27822918                (!elink->IsBusy()) &&
     2919                !is_card_in_busy_group(elink->GetCardID()) &&
    27832920                (!elink->IsTunerLocked()))
    27842921            {
    27852922                encoder = elink;