Ticket #3326: 3326-isbusy-v1.patch
| File 3326-isbusy-v1.patch, 34.8 KB (added by , 19 years ago) |
|---|
-
libs/libmythtv/remoteutil.h
27 27 int weight; 28 28 }; 29 29 30 class MPUBLIC InputInfo 31 { 32 public: 33 InputInfo() : name(QString::null), sourceid(0), inputid(0), cardid(0) {} 34 InputInfo(const QString &name, uint sourceid, uint inputid, uint cardid); 35 InputInfo(const InputInfo &other); 36 InputInfo &operator=(const InputInfo &other); 37 38 public: 39 QString name; 40 uint sourceid; 41 uint inputid; 42 uint cardid; 43 }; 44 30 45 MPUBLIC vector<ProgramInfo *> *RemoteGetRecordedList(bool deltype); 31 46 MPUBLIC vector<FileSystemInfo> RemoteGetFreeSpace(); 32 47 MPUBLIC bool RemoteGetLoad(float load[3]); … … 52 67 RemoteEncoder *RemoteRequestFreeRecorderFromList(QStringList &qualifiedRecorders); 53 68 MPUBLIC RemoteEncoder *RemoteGetExistingRecorder(ProgramInfo *pginfo); 54 69 MPUBLIC RemoteEncoder *RemoteGetExistingRecorder(int recordernum); 70 MPUBLIC vector<uint> RemoteRequestFreeRecorderList(void); 71 MPUBLIC vector<InputInfo> RemoteRequestFreeInputList( 72 uint cardid, vector<uint> excluded_cardids); 73 MPUBLIC InputInfo RemoteRequestBusyInputID(uint cardid); 55 74 MPUBLIC void RemoteGeneratePreviewPixmap(ProgramInfo *pginfo); 56 75 MPUBLIC QString RemoteGetPreviewLastModified(ProgramInfo *pginfo); 57 76 MPUBLIC void RemoteFillProginfo(ProgramInfo *pginfo, 58 77 const QString &playbackhostname); 78 MPUBLIC bool RemoteIsBusy(uint cardid); 59 79 MPUBLIC int RemoteIsRecording(void); 60 80 MPUBLIC int RemoteGetRecordingMask(void); 61 81 MPUBLIC int RemoteGetFreeRecorderCount(void); -
libs/libmythtv/cardutil.h
132 132 uint sid, const QString &val) 133 133 { return set_on_source(col, cid, sid, val); } 134 134 135 135 // Inputs 136 136 static QString GetDefaultInput(uint cardid); 137 137 static QStringList GetInputNames(uint cardid, uint sourceid); 138 static bool GetInputInfo(uint inputid, QString &inputname, 139 uint &sourceid, uint &cardid, 140 vector<uint> &groupids); 141 static uint GetCardID(uint inputid); 142 static QString GetInputName(uint inputid); 143 static QString GetDisplayName(uint inputid); 144 static QString GetDisplayName(uint cardid, const QString &inputname); 138 145 146 // Input Groups 147 static uint CreateInputGroup(const QString &name); 148 static bool LinkInputGroup(uint inputid, uint inputgroupid); 149 static bool UnlinkInputGroup(uint inputid, uint inputgroupid); 150 static vector<uint> GetInputGroups(uint inputid); 151 static vector<uint> GetGroupCardIDs(uint inputgroupid); 152 139 153 static QString GetDeviceLabel(uint cardid, 140 154 QString cardtype, 141 155 QString videodevice); … … 152 166 int parentid = 0); 153 167 154 168 static bool DeleteCard(uint cardid); 169 static vector<uint> GetCardList(bool primaryOnly = true); 155 170 156 // Input Groups157 static uint CreateInputGroup(const QString &name);158 static bool LinkInputGroup(uint inputid, uint inputgroupid);159 static bool UnlinkInputGroup(uint inputid, uint inputgroupid);160 161 171 // DTV info 162 172 static bool GetTimeouts(uint cardid, 163 173 uint &signal_timeout, -
libs/libmythtv/tv_play.h
258 258 QString GetQueuedChanNum(void) const; 259 259 uint GetQueuedChanID(void) const { return queuedChanID; } 260 260 261 void ToggleInputs(void); 261 void SwitchInputs(uint inputid); 262 void ToggleInputs(uint inputid = 0); 263 void SwitchCards(uint chanid = 0, QString channum = "", uint inputid = 0); 262 264 263 void SwitchCards(uint chanid = 0, QString channum = "");264 265 265 void ToggleSleepTimer(void); 266 266 void ToggleSleepTimer(const QString); 267 267 … … 419 419 mutable QMutex stateLock; 420 420 TVState internalState; 421 421 422 uint switchToInputId; 422 423 bool menurunning; 423 424 bool runMainLoop; 424 425 bool wantsToQuit; -
libs/libmythtv/sourceutil.h
10 10 class MPUBLIC SourceUtil 11 11 { 12 12 public: 13 static bool HasDigitalChannel(uint sourceid); 14 static QString GetSourceName(uint sourceid); 13 15 static QString GetChannelSeparator(uint sourceid); 14 16 static QString GetChannelFormat(uint sourceid); 15 17 static uint GetChannelCount(uint sourceid); -
libs/libmythtv/tv_play.cpp
4 4 #include <unistd.h> 5 5 #include <pthread.h> 6 6 7 #include <algorithm> 8 using namespace std; 9 7 10 #include <qapplication.h> 8 11 #include <qregexp.h> 9 12 #include <qfile.h> … … 40 43 #include "DVDRingBuffer.h" 41 44 #include "datadirect.h" 42 45 #include "sourceutil.h" 46 #include "cardutil.h" 43 47 44 48 #ifndef HAVE_ROUND 45 49 #define round(x) ((int) ((x) + 0.5)) … … 475 479 vbimode(VBIMode::None), 476 480 // State variables 477 481 internalState(kState_None), 482 switchToInputId(0), 478 483 menurunning(false), runMainLoop(false), wantsToQuit(true), 479 484 exitPlayer(false), paused(false), errored(false), 480 485 stretchAdjustment(false), … … 1987 1992 ClearInputQueues(true); 1988 1993 } 1989 1994 1995 if (switchToInputId) 1996 { 1997 uint tmp = switchToInputId; 1998 switchToInputId = 0; 1999 SwitchInputs(tmp); 2000 } 2001 1990 2002 if (class LCD * lcd = LCD::Get()) 1991 2003 { 1992 2004 QDateTime curTime = QDateTime::currentDateTime(); … … 3915 3927 muteTimer->start(kMuteTimeout, true); 3916 3928 } 3917 3929 3918 void TV::Switch Cards(uint chanid, QString channum)3930 void TV::SwitchInputs(uint inputid) 3919 3931 { 3932 VERBOSE(VB_PLAYBACK, LOC + QString("SwitchInputd(%1)").arg(inputid)); 3933 3934 if ((uint)activerecorder->GetRecorderNumber() == 3935 CardUtil::GetCardID(inputid)) 3936 { 3937 ToggleInputs(inputid); 3938 } 3939 else 3940 { 3941 SwitchCards(0, QString::null, inputid); 3942 } 3943 } 3944 3945 void TV::SwitchCards(uint chanid, QString channum, uint inputid) 3946 { 3920 3947 VERBOSE(VB_PLAYBACK, LOC + 3921 QString("SwitchCards(%1,'%2')").arg(chanid).arg(channum)); 3948 QString("SwitchCards(%1,'%2',%3)") 3949 .arg(chanid).arg(channum).arg(inputid)); 3922 3950 3923 3951 RemoteEncoder *testrec = NULL; 3924 3952 3925 3953 if (!StateIsLiveTV(GetState()) || (activenvp != nvp) || pipnvp) 3926 3954 return; 3927 3955 3928 if (/*chanid || */!channum.isEmpty()) 3956 // If we are switching to a channel not on the current recorder 3957 // we need to find the next free recorder with that channel. 3958 QStringList reclist; 3959 if (!channum.isEmpty()) 3960 reclist = GetValidRecorderList(chanid, channum); 3961 else if (inputid) 3929 3962 { 3930 // If we are switching to a channel not on the current recorder 3931 // we need to find the next free recorder with that channel. 3932 QStringList reclist = GetValidRecorderList(chanid, channum); 3933 testrec = RemoteRequestFreeRecorderFromList(reclist); 3963 uint cardid = CardUtil::GetCardID(inputid); 3964 if (cardid) 3965 reclist.push_back(QString::number(cardid)); 3934 3966 } 3935 3967 3968 if (!reclist.empty()) 3969 testrec = RemoteRequestFreeRecorderFromList(reclist); 3970 3936 3971 // If we are just switching recorders find first available recorder. 3937 3972 if (!testrec) 3938 3973 testrec = RemoteRequestNextFreeRecorder(recorder->GetRecorderNumber()); … … 4030 4065 ITVRestart(true); 4031 4066 } 4032 4067 4033 void TV::ToggleInputs( void)4068 void TV::ToggleInputs(uint inputid) 4034 4069 { 4035 4070 // If main Nuppel Video Player is paused, unpause it 4036 4071 if (activenvp == nvp && paused) … … 4047 4082 inputname = activerecorder->GetInput(); 4048 4083 else 4049 4084 { 4050 // Pause the backend recorder, send command, and then unpause.. 4051 PauseLiveTV(); 4052 lockTimerOn = false; 4053 inputname = activerecorder->SetInput("SwitchToNextInput"); 4054 UnpauseLiveTV(); 4085 inputname = "SwitchToNextInput"; 4086 if (inputid) 4087 { 4088 QString tmp = CardUtil::GetInputName(inputid); 4089 inputname = (tmp.isEmpty()) ? inputname : tmp; 4090 } 4091 4092 if (activerecorder->GetInput() != inputname) 4093 { 4094 // Pause the backend recorder, send command, and then unpause.. 4095 PauseLiveTV(); 4096 lockTimerOn = false; 4097 inputname = activerecorder->SetInput(inputname); 4098 UnpauseLiveTV(); 4099 } 4055 4100 } 4056 4101 4057 4102 // If activenvp is main nvp, show new input in on screen display … … 4640 4685 4641 4686 void TV::UpdateOSDInput(QString inputname) 4642 4687 { 4643 QString displayName = QString::null;4644 4645 4688 if (!activerecorder || !tvchain) 4646 4689 return; 4647 4690 … … 4650 4693 if (inputname.isEmpty()) 4651 4694 inputname = tvchain->GetInputName(-1); 4652 4695 4653 // Try to get display name 4654 MSqlQuery query(MSqlQuery::InitCon()); 4655 query.prepare("SELECT displayname " 4656 "FROM cardinput " 4657 "WHERE inputname = :INPUTNAME AND " 4658 " cardid = :CARDID"); 4659 query.bindValue(":CARDID", cardid); 4660 query.bindValue(":INPUTNAME", inputname); 4661 if (query.exec() && query.isActive() && query.next()) 4662 displayName = query.value(0).toString(); 4663 4696 QString displayName = CardUtil::GetDisplayName(cardid, inputname); 4664 4697 // If a display name doesn't exist use cardid and inputname 4665 4698 if (displayName.isEmpty()) 4666 4699 displayName = QString("%1: %2").arg(cardid).arg(inputname); … … 6527 6560 BrowseStart(); 6528 6561 else if (action == "PREVCHAN") 6529 6562 PreviousChannel(); 6563 else if (action.left(14) == "SWITCHTOINPUT_") 6564 switchToInputId = action.mid(14).toUInt(); 6530 6565 else 6531 6566 { 6532 6567 VERBOSE(VB_IMPORTANT, LOC_ERR + … … 6789 6824 6790 6825 if (freeRecorders) 6791 6826 { 6827 // Picture-in-Picture 6792 6828 item = new OSDGenericTree(treeMenu, tr("Picture-in-Picture")); 6793 6829 subitem = new OSDGenericTree(item, tr("Enable/Disable"), 6794 6830 "TOGGLEPIPMODE"); 6795 6831 subitem = new OSDGenericTree(item, tr("Swap PiP/Main"), "SWAPPIP"); 6796 6832 subitem = new OSDGenericTree(item, tr("Change Active Window"), 6797 6833 "TOGGLEPIPWINDOW"); 6834 6835 // Input switching 6836 item = NULL; 6837 6838 QMap<uint,InputInfo> sources; 6839 vector<uint> cardids = RemoteRequestFreeRecorderList(); 6840 uint cardid = activerecorder->GetRecorderNumber(); 6841 cardids.push_back(cardid); 6842 stable_sort(cardids.begin(), cardids.end()); 6843 6844 vector<uint> excluded_cardids; 6845 excluded_cardids.push_back(cardid); 6846 6847 InfoMap info; 6848 activerecorder->GetChannelInfo(info); 6849 uint sourceid = info["sourceid"].toUInt(); 6850 6851 vector<uint>::const_iterator it = cardids.begin(); 6852 for (; it != cardids.end(); ++it) 6853 { 6854 vector<InputInfo> inputs = RemoteRequestFreeInputList( 6855 *it, excluded_cardids); 6856 6857 if (inputs.empty()) 6858 continue; 6859 6860 if (!item) 6861 item = new OSDGenericTree(treeMenu, tr("Switch Input")); 6862 6863 for (uint i = 0; i < inputs.size(); i++) 6864 { 6865 // prefer the current card's input in sources list 6866 if ((sources.find(inputs[i].sourceid) == sources.end()) || 6867 ((cardid == inputs[i].cardid) && 6868 (cardid != sources[inputs[i].sourceid].cardid))) 6869 { 6870 sources[inputs[i].sourceid] = inputs[i]; 6871 } 6872 6873 // don't add current input to list 6874 if ((inputs[i].cardid == cardid) && 6875 (inputs[i].sourceid == sourceid)) 6876 { 6877 continue; 6878 } 6879 6880 QString name = CardUtil::GetDisplayName(inputs[i].inputid); 6881 if (name.isEmpty()) 6882 { 6883 name = tr("C", "Card") + ":" + QString::number(*it) + " " + 6884 tr("I", "Input") + ":" + inputs[i].name; 6885 } 6886 6887 subitem = new OSDGenericTree( 6888 item, name, 6889 QString("SWITCHTOINPUT_%1").arg(inputs[i].inputid)); 6890 } 6891 } 6892 6893 // Source switching 6894 6895 // delete current source from list 6896 sources.erase(sourceid); 6897 6898 // create menu if we have any sources left 6899 QMap<uint,InputInfo>::const_iterator sit = sources.begin(); 6900 if (sit != sources.end()) 6901 item = new OSDGenericTree(treeMenu, tr("Switch Source")); 6902 for (; sit != sources.end(); ++sit) 6903 { 6904 subitem = new OSDGenericTree( 6905 item, SourceUtil::GetSourceName((*sit).sourceid), 6906 QString("SWITCHTOINPUT_%1").arg((*sit).inputid)); 6907 } 6798 6908 } 6799 6909 6800 6910 if (!persistentbrowsemode) -
libs/libmythtv/cardutil.cpp
377 377 return list; 378 378 } 379 379 380 bool CardUtil::GetInputInfo( 381 uint inputid, 382 QString &inputname, uint &sourceid, uint &cardid, vector<uint> &groupids) 383 { 384 MSqlQuery query(MSqlQuery::InitCon()); 385 query.prepare("SELECT inputname, sourceid, cardid " 386 "FROM cardinput " 387 "WHERE cardinputid = :INPUTID"); 388 query.bindValue(":INPUTID", inputid); 389 390 if (!query.exec()) 391 { 392 MythContext::DBError("CardUtil::GetCardID(inputid)", query); 393 return false; 394 } 395 396 if (!query.next()) 397 return false; 398 399 inputname = query.value(0).toString(); 400 sourceid = query.value(1).toUInt(); 401 cardid = query.value(2).toUInt(); 402 groupids = GetInputGroups(inputid); 403 404 return true; 405 } 406 407 uint CardUtil::GetCardID(uint inputid) 408 { 409 MSqlQuery query(MSqlQuery::InitCon()); 410 query.prepare("SELECT cardid " 411 "FROM cardinput " 412 "WHERE cardinputid = :INPUTID"); 413 query.bindValue(":INPUTID", inputid); 414 415 if (!query.exec()) 416 MythContext::DBError("CardUtil::GetCardID(inputid)", query); 417 else if (query.next()) 418 return query.value(0).toUInt(); 419 420 return 0; 421 } 422 423 QString CardUtil::GetInputName(uint inputid) 424 { 425 MSqlQuery query(MSqlQuery::InitCon()); 426 query.prepare("SELECT inputname " 427 "FROM cardinput " 428 "WHERE cardinputid = :INPUTID"); 429 query.bindValue(":INPUTID", inputid); 430 431 if (!query.exec()) 432 MythContext::DBError("CardUtil::GetInputName()", query); 433 else if (query.next()) 434 return query.value(0).toString(); 435 436 return QString::null; 437 } 438 439 QString CardUtil::GetDisplayName(uint inputid) 440 { 441 MSqlQuery query(MSqlQuery::InitCon()); 442 query.prepare("SELECT displayname " 443 "FROM cardinput " 444 "WHERE cardinputid = :INPUTID"); 445 query.bindValue(":INPUTID", inputid); 446 447 if (!query.exec()) 448 MythContext::DBError("CardUtil::GetDisplayName(uint)", query); 449 else if (query.next()) 450 return QString::fromUtf8(query.value(0).toString()); 451 452 return QString::null; 453 } 454 455 QString CardUtil::GetDisplayName(uint cardid, const QString &inputname) 456 { 457 MSqlQuery query(MSqlQuery::InitCon()); 458 query.prepare("SELECT displayname " 459 "FROM cardinput " 460 "WHERE inputname = :INPUTNAME AND " 461 " cardid = :CARDID"); 462 query.bindValue(":INPUTNAME", inputname); 463 query.bindValue(":CARDID", cardid); 464 465 if (!query.exec()) 466 MythContext::DBError("CardUtil::GetDisplayName(uint,QString)", query); 467 else if (query.next()) 468 return QString::fromUtf8(query.value(0).toString()); 469 470 return QString::null; 471 } 472 380 473 uint CardUtil::CreateInputGroup(const QString &name) 381 474 { 382 475 MSqlQuery query(MSqlQuery::InitCon()); … … 476 569 return true; 477 570 } 478 571 572 vector<uint> CardUtil::GetInputGroups(uint inputid) 573 { 574 vector<uint> list; 575 576 MSqlQuery query(MSqlQuery::InitCon()); 577 578 query.prepare( 579 "SELECT inputgroupid " 580 "FROM inputgroup " 581 "WHERE cardinputid = :INPUTID " 582 "ORDER BY inputgroupid, cardinputid, inputgroupname"); 583 584 query.bindValue(":INPUTID", inputid); 585 586 if (!query.exec()) 587 { 588 MythContext::DBError("CardUtil::GetInputGroups()", query); 589 return list; 590 } 591 592 while (query.next()) 593 list.push_back(query.value(0).toUInt()); 594 595 return list; 596 } 597 598 vector<uint> CardUtil::GetGroupCardIDs(uint inputgroupid) 599 { 600 vector<uint> list; 601 602 MSqlQuery query(MSqlQuery::InitCon()); 603 604 query.prepare( 605 "SELECT cardinputid " 606 "FROM inputgroup " 607 "WHERE inputgroupid = :GROUPID " 608 "ORDER BY inputgroupid, cardinputid, inputgroupname"); 609 610 query.bindValue(":GROUPID", inputgroupid); 611 612 if (!query.exec()) 613 { 614 MythContext::DBError("CardUtil::GetInputGroups()", query); 615 return list; 616 } 617 618 while (query.next()) 619 list.push_back(query.value(0).toUInt()); 620 621 return list; 622 } 623 624 479 625 bool CardUtil::GetTimeouts(uint cardid, 480 626 uint &signal_timeout, uint &channel_timeout) 481 627 { … … 999 1145 return true; 1000 1146 } 1001 1147 1148 vector<uint> CardUtil::GetCardList(bool primaryOnly) 1149 { 1150 vector<uint> list; 1151 1152 MSqlQuery query(MSqlQuery::InitCon()); 1153 if (primaryOnly) 1154 { 1155 query.prepare( 1156 "SELECT cardid " 1157 "FROM capturecard " 1158 "WHERE parentid='0' " 1159 "ORDER BY cardid"); 1160 } 1161 else 1162 { 1163 query.prepare( 1164 "SELECT cardid " 1165 "FROM capturecard " 1166 "ORDER BY cardid"); 1167 } 1168 1169 if (!query.exec()) 1170 MythContext::DBError("CardUtil::GetCardList()", query); 1171 else 1172 { 1173 while (query.next()) 1174 list.push_back(query.value(0).toUInt()); 1175 } 1176 1177 return list; 1178 } 1179 1180 1002 1181 QString CardUtil::GetDeviceName(dvb_dev_type_t type, uint cardnum) 1003 1182 { 1004 1183 if (DVB_DEV_FRONTEND == type) -
libs/libmythtv/remoteutil.cpp
1 #include <qdeepcopy.h> 1 2 #include <qstringlist.h> 2 3 3 4 #include "util.h" … … 6 7 #include "mythcontext.h" 7 8 #include "remoteencoder.h" 8 9 10 InputInfo::InputInfo( 11 const QString &_name, uint _sourceid, uint _inputid, uint _cardid) : 12 name(QDeepCopy<QString>(_name)), 13 sourceid(_sourceid), 14 inputid(_inputid), 15 cardid(_cardid) 16 { 17 } 18 19 InputInfo::InputInfo(const InputInfo &other) : 20 name(QDeepCopy<QString>(other.name)), 21 sourceid(other.sourceid), 22 inputid(other.inputid), 23 cardid(other.cardid) 24 { 25 } 26 27 InputInfo &InputInfo::operator=(const InputInfo &other) 28 { 29 name = QDeepCopy<QString>(other.name); 30 sourceid = other.sourceid; 31 inputid = other.inputid; 32 cardid = other.cardid; 33 return *this; 34 } 35 9 36 vector<ProgramInfo *> *RemoteGetRecordedList(bool deltype) 10 37 { 11 38 QString str = "QUERY_RECORDINGS "; … … 291 318 return new RemoteEncoder(recordernum, hostname, port); 292 319 } 293 320 321 vector<uint> RemoteRequestFreeRecorderList(void) 322 { 323 vector<uint> list; 324 325 QStringList strlist = "GET_FREE_RECORDER_LIST"; 326 327 if (!gContext->SendReceiveStringList(strlist, true)) 328 return list; 329 330 QStringList::const_iterator it = strlist.begin(); 331 for (; it != strlist.end(); ++it) 332 list.push_back((*it).toUInt()); 333 334 return list; 335 } 336 337 vector<InputInfo> RemoteRequestFreeInputList(uint cardid, 338 vector<uint> excluded_cardids) 339 { 340 vector<InputInfo> list; 341 342 QStringList strlist = QString("QUERY_RECORDER %1").arg(cardid); 343 strlist << "GET_FREE_INPUTS"; 344 for (uint i = 0; i < excluded_cardids.size(); i++) 345 strlist << QString::number(excluded_cardids[i]); 346 347 if (!gContext->SendReceiveStringList(strlist)) 348 return list; 349 350 QStringList::const_iterator it = strlist.begin(); 351 if ((it == strlist.end()) || (*it == "EMPTY_LIST")) 352 return list; 353 354 while (it != strlist.end()) 355 { 356 QString inputname = *it; 357 uint sourceid, inputid, cardid; 358 ++it; 359 if (it == strlist.end()) 360 break; 361 sourceid = (*it).toUInt(); 362 ++it; 363 if (it == strlist.end()) 364 break; 365 inputid = (*it).toUInt(); 366 ++it; 367 if (it == strlist.end()) 368 break; 369 cardid = (*it).toUInt(); 370 ++it; 371 372 if (!inputname.isEmpty() && sourceid && inputid && cardid) 373 list.push_back(InputInfo(inputname, sourceid, inputid, cardid)); 374 } 375 376 return list; 377 } 378 379 InputInfo RemoteRequestBusyInputID(uint cardid) 380 { 381 InputInfo blank; 382 383 QStringList strlist = QString("QUERY_RECORDER %1").arg(cardid); 384 strlist << "GET_BUSY_INPUT"; 385 386 if (!gContext->SendReceiveStringList(strlist)) 387 return blank; 388 389 QStringList::const_iterator it = strlist.begin(); 390 if ((it == strlist.end()) || (*it == "EMPTY_LIST")) 391 return blank; 392 393 InputInfo info; 394 395 if (it == strlist.end()) 396 return blank; 397 info.name = *it; 398 399 ++it; 400 if (it == strlist.end()) 401 return blank; 402 info.sourceid = (*it).toUInt(); 403 404 ++it; 405 if (it == strlist.end()) 406 return blank; 407 info.inputid = (*it).toUInt(); 408 409 ++it; 410 if (it == strlist.end()) 411 return blank; 412 info.cardid = (*it).toUInt(); 413 414 if (!info.name.isEmpty() && info.sourceid && info.inputid && info.cardid) 415 return info; 416 417 return blank; 418 } 419 294 420 void RemoteSendMessage(const QString &message) 295 421 { 296 422 QStringList strlist = "MESSAGE"; … … 330 456 pginfo->FromStringList(strlist, 0); 331 457 } 332 458 459 bool RemoteIsBusy(uint cardid) 460 { 461 QStringList strlist = QString("QUERY_REMOTEENCODER %1").arg(cardid); 462 strlist << "IS_BUSY"; 463 464 if (!gContext->SendReceiveStringList(strlist) || strlist.empty()) 465 return true; 466 467 bool state = strlist[0].toInt(); 468 return state; 469 } 470 333 471 int RemoteIsRecording(void) 334 472 { 335 473 QStringList strlist = "QUERY_ISRECORDING"; -
libs/libmythtv/tv_rec.cpp
59 59 #include "hdhrrecorder.h" 60 60 #include "iptvrecorder.h" 61 61 #include "firewirerecorder.h" 62 #include "remoteutil.h" 63 #include "sourceutil.h" 62 64 63 65 #ifdef USING_V4L 64 66 #include "channel.h" … … 305 307 SetRingBuffer(NULL); 306 308 } 307 309 308 /** \fn TVRec::GetState() 310 /** \fn TVRec::GetState() const 309 311 * \brief Returns the TVState of the recorder. 310 312 * 311 313 * If there is a pending state change kState_ChangingState is returned. 312 314 * \sa EncoderLink::GetState(), \ref recorder_subsystem 313 315 */ 314 TVState TVRec::GetState(void) 316 TVState TVRec::GetState(void) const 315 317 { 316 318 if (changeState) 317 319 return kState_ChangingState; … … 2221 2223 HasFlags(kFlagDummyRecorderRunning)); 2222 2224 } 2223 2225 2224 /** \fn TVRec::IsBusy() 2226 /** \fn TVRec::IsBusy() const 2225 2227 * \brief Returns true if the recorder is busy, or will be within 2226 2228 * the next 5 seconds. 2227 2229 * \sa EncoderLink::IsBusy(), 2228 2230 */ 2229 bool TVRec::IsBusy(void) 2231 bool TVRec::IsBusy(void) const 2230 2232 { 2231 2233 QMutexLocker lock(&stateChangeLock); 2232 2234 … … 2717 2719 return ret / 655; 2718 2720 } 2719 2721 2722 static bool is_input_group_busy( 2723 uint inputid, 2724 uint groupid, 2725 const vector<uint> &excluded_cardids, 2726 QMap<uint,bool> &busygrp, 2727 QMap<uint,bool> &busyrec) 2728 { 2729 bool is_busy_grp = busygrp[groupid]; 2730 if (!is_busy_grp) 2731 return false; 2732 2733 // quick check... 2734 vector<uint> cardids = CardUtil::GetGroupCardIDs(groupid); 2735 for (uint i = 0; i < cardids.size() && !is_busy_grp; i++) 2736 { 2737 if (find(excluded_cardids.begin(), 2738 excluded_cardids.end(), cardids[i]) != excluded_cardids.end()) 2739 continue; 2740 2741 QMap<uint,bool>::const_iterator it = busyrec.find(cardids[i]); 2742 if (it == busyrec.end()) 2743 busyrec[cardids[i]] = RemoteIsBusy(cardids[i]); 2744 2745 is_busy_grp = busyrec[cardids[i]]; 2746 } 2747 2748 busygrp[groupid] = is_busy_grp; 2749 if (!is_busy_grp) 2750 return false; 2751 2752 // check more carefully... 2753 vector<InputInfo> conflicts; 2754 for (uint i = 0; i < cardids.size(); i++) 2755 { 2756 if (find(excluded_cardids.begin(), 2757 excluded_cardids.end(), cardids[i]) != excluded_cardids.end()) 2758 continue; 2759 2760 QMap<uint,bool>::const_iterator it = busyrec.find(cardids[i]); 2761 if (it == busyrec.end()) 2762 busyrec[cardids[i]] = RemoteIsBusy(cardids[i]); 2763 2764 if (!busyrec[cardids[i]]) 2765 continue; 2766 2767 InputInfo info = RemoteRequestBusyInputID(cardids[i]); 2768 conflicts.push_back(info); 2769 } 2770 2771 InputInfo in; 2772 vector<uint> groups; 2773 in.inputid = inputid; 2774 if (!CardUtil::GetInputInfo( 2775 inputid, in.name, in.sourceid, in.cardid, groups)) 2776 { 2777 return true; 2778 } 2779 2780 // If they aren't using the same source they are definately busy 2781 bool is_busy_input = false; 2782 for (uint i = 0; i < conflicts.size() && !is_busy_input; i++) 2783 is_busy_input = in.sourceid != conflicts[i].sourceid; 2784 if (is_busy_input) 2785 return true; 2786 2787 // If the source's channels aren't digitally tuned then there is a conflict 2788 return !SourceUtil::HasDigitalChannel(in.sourceid); 2789 } 2790 2791 /** \fn TVRec::GetFreeInputs(vector<uint>) const 2792 * \brief Returns TVRec's recorders available inputs. 2793 * 2794 * This filters the result of GetConnectedInputs() so that inputs 2795 * that belong to an input group which is busy are removed from the 2796 * list. Recorders in the excluded cardids will not be considered 2797 * busy for the sake of determining free inputs. 2798 * 2799 * Then additional information is added to the list, in addition 2800 * to the name of the input this adds the sourceid, inputid, 2801 * and cardid. 2802 * 2803 */ 2804 QStringList TVRec::GetFreeInputs(vector<uint> excluded_cardids) const 2805 { 2806 QStringList list = GetConnectedInputs(); 2807 if (list.empty()) 2808 return list; 2809 2810 // Check each input to make sure it doesn't belong to an 2811 // input group which is attached to a busy recorder. 2812 QStringList new_list; 2813 QMap<uint,bool> busygrp; 2814 QMap<uint,bool> busyrec; 2815 2816 busyrec[cardid] = IsBusy(); 2817 2818 QStringList::const_iterator it; 2819 for (it = list.begin(); it != list.end(); ++it) 2820 { 2821 uint inputid = channel->GetInputByName(*it); 2822 QString name; 2823 uint sourceid, cardid; 2824 vector<uint> groups; 2825 if (!CardUtil::GetInputInfo(inputid, name, sourceid, cardid, groups)) 2826 continue; 2827 2828 bool is_busy_grp = false; 2829 for (uint i = 0; i < groups.size() && !is_busy_grp; i++) 2830 { 2831 is_busy_grp |= is_input_group_busy( 2832 inputid, groups[i], excluded_cardids, busygrp, busyrec); 2833 } 2834 2835 if (!is_busy_grp) 2836 { 2837 new_list += name; 2838 new_list += QString::number(sourceid); 2839 new_list += QString::number(inputid); 2840 new_list += QString::number(cardid); 2841 } 2842 } 2843 2844 return new_list; 2845 } 2846 2847 QStringList TVRec::GetBusyInput(void) const 2848 { 2849 QMutexLocker lock(&stateChangeLock); 2850 2851 QStringList new_list; 2852 if (!channel) 2853 return new_list; 2854 2855 QStringList list = channel->GetConnectedInputs(); 2856 if (list.empty()) 2857 return new_list; 2858 2859 uint inputid = 0; 2860 if (GetState() != kState_None) 2861 inputid = channel->GetCurrentInputNum(); 2862 2863 if (!inputid && pendingRecording) 2864 { 2865 int timeLeft = QDateTime::currentDateTime().secsTo(recordPendingStart); 2866 if (timeLeft <= 5) 2867 { 2868 QString channum = QString::null, input = QString::null; 2869 if (pendingRecording->GetChannel(channum, input)) 2870 inputid = channel->GetInputByName(input); 2871 } 2872 } 2873 2874 if (inputid) 2875 { 2876 QString name; 2877 uint sourceid, cardid; 2878 vector<uint> groups; 2879 if (CardUtil::GetInputInfo(inputid, name, sourceid, cardid, groups)) 2880 { 2881 new_list += name; 2882 new_list += QString::number(sourceid); 2883 new_list += QString::number(inputid); 2884 new_list += QString::number(cardid); 2885 } 2886 } 2887 2888 return new_list; 2889 } 2890 2720 2891 /** \fn TVRec::GetConnectedInputs(void) const 2721 2892 * \brief Returns TVRec's recorders connected inputs. 2722 2893 */ -
libs/libmythtv/tv_rec.h
157 157 /// \brief Tells TVRec to stop event loop 158 158 void Stop(void) { ClearFlags(kFlagRunMainLoop); } 159 159 160 TVState GetState(void) ;160 TVState GetState(void) const; 161 161 /// \brief Returns "state == kState_RecordingPreRecorded" 162 162 bool IsPlaying(void) { return StateIsPlaying(internalState); } 163 163 /// \brief Returns "state == kState_RecordingRecordedOnly" … … 166 166 167 167 bool SetVideoFiltersForChannel(uint sourceid, const QString &channum); 168 168 169 bool IsBusy(void) ;169 bool IsBusy(void) const; 170 170 bool IsReallyRecording(void); 171 171 172 172 float GetFramerate(void); … … 182 182 183 183 void SetLiveRecording(int recording); 184 184 185 QStringList GetFreeInputs(vector<uint> excluded_cardids) const; 186 QStringList GetBusyInput(void) const; 185 187 QStringList GetConnectedInputs(void) const; 186 188 QString GetInput(void) const; 187 189 QString SetInput(QString input, uint requestType = kFlagDetect); … … 337 339 DBox2DBOptions dboxOpt; 338 340 339 341 // State variables 340 QMutexstateChangeLock;342 mutable QMutex stateChangeLock; 341 343 TVState internalState; 342 344 TVState desiredNextState; 343 345 bool changeState; -
libs/libmythtv/sourceutil.cpp
9 9 #include "mythdbcon.h" 10 10 #include "util.h" 11 11 12 bool SourceUtil::HasDigitalChannel(uint sourceid) 13 { 14 MSqlQuery query(MSqlQuery::InitCon()); 15 16 query.prepare( 17 "SELECT mplexid, atsc_minor_chan, serviceid " 18 "FROM videosource " 19 "WHERE sourceid = :SOURCEID"); 20 query.bindValue(":SOURCEID", sourceid); 21 22 if (!query.exec()) 23 { 24 MythContext::DBError("SourceUtil::HasDigitalChannel()", query); 25 return false; 26 } 27 28 if (!query.next()) 29 return false; 30 31 uint mplexid = query.value(0).toUInt(); 32 uint minor = query.value(1).toUInt(); 33 uint prognum = query.value(2).toUInt(); 34 35 mplexid = (32767 == mplexid) ? 0 : mplexid; 36 37 return mplexid && (minor || prognum); 38 } 39 40 QString SourceUtil::GetSourceName(uint sourceid) 41 { 42 MSqlQuery query(MSqlQuery::InitCon()); 43 44 query.prepare( 45 "SELECT name " 46 "FROM videosource " 47 "WHERE sourceid = :SOURCEID"); 48 query.bindValue(":SOURCEID", sourceid); 49 50 if (!query.exec()) 51 { 52 MythContext::DBError("SourceUtil::GetSourceName()", query); 53 return QString::null; 54 } 55 else if (!query.next()) 56 { 57 return QString::null; 58 } 59 60 return query.value(0).toString(); 61 } 62 12 63 QString SourceUtil::GetChannelSeparator(uint sourceid) 13 64 { 14 65 MSqlQuery query(MSqlQuery::InitCon()); -
programs/mythbackend/encoderlink.h
76 76 void PauseRecorder(void); 77 77 void SetLiveRecording(int); 78 78 void SetNextLiveTVDir(QString dir); 79 QStringList GetFreeInputs(vector<uint> excluded_cardids) const; 79 80 QStringList GetConnectedInputs(void) const; 80 81 QString GetInput(void) const; 81 82 QString SetInput(QString); -
programs/mythbackend/mainserver.cpp
2814 2814 enc->SetLiveRecording(recording); 2815 2815 retlist << "ok"; 2816 2816 } 2817 else if (command == "GET_FREE_INPUTS") 2818 { 2819 vector<uint> excluded_cardids; 2820 for (uint i = 2; i < slist.size(); i++) 2821 excluded_cardids.push_back(slist[i].toUInt()); 2822 2823 QStringList ret = enc->GetFreeInputs(excluded_cardids); 2824 2825 if (ret.empty()) 2826 retlist << "EMPTY_LIST"; 2827 else 2828 retlist += ret; 2829 } 2830 else if (command == "GET_BUSY_INPUT") 2831 { 2832 QStringList ret = enc->GetBusyInput(); 2833 if (ret.empty()) 2834 retlist << "EMPTY_LIST"; 2835 else 2836 retlist += ret; 2837 } 2817 2838 else if (command == "GET_CONNECTED_INPUTS") 2818 2839 { 2819 2840 QStringList ret = enc->GetConnectedInputs(); -
programs/mythbackend/encoderlink.cpp
586 586 sock->SetNextLiveTVDir(m_capturecardnum, dir); 587 587 } 588 588 589 /** \fn EncoderLink::GetFreeInputs(vector<uint>) const 590 * \brief Returns TVRec's recorders inputs available for recording now. 591 * <b>This only works on local recorders.</b> 592 * 593 * \sa TVRec::GetFreeInputs(vector<uint>) const 594 */ 595 QStringList EncoderLink::GetFreeInputs(vector<uint> excluded_cardids) const 596 { 597 QStringList list; 598 599 if (local) 600 list = tv->GetFreeInputs(excluded_cardids); 601 else 602 VERBOSE(VB_IMPORTANT, "Should be local only query: GetFreeInputs"); 603 604 return list; 605 } 606 589 607 /** \fn EncoderLink::GetConnectedInputs(void) const 590 608 * \brief Returns TVRec's recorders connected inputs. 591 609 * <b>This only works on local recorders.</b> … … 625 643 * 626 644 * You must call PauseRecorder(void) before calling this. 627 645 * 628 * \param input Input to switch to, or "SwitchToNe ctInput".646 * \param input Input to switch to, or "SwitchToNextInput". 629 647 * \return input we have switched to 630 648 * \sa TVRec::SetInput(QString) 631 649 */
