Ticket #3326: 3326-pendingrecording-v1.patch
File 3326-pendingrecording-v1.patch, 18.3 KB (added by , 17 years ago) |
---|
-
libs/libmythtv/tv_play.cpp
899 899 activerecorder->FinishRecording(); 900 900 } 901 901 902 void TV::AskAllowRecording(const QStringList &m essages, int timeuntil,902 void TV::AskAllowRecording(const QStringList &msg, int timeuntil, 903 903 bool hasrec) 904 904 { 905 905 if (!StateIsLiveTV(GetState())) 906 906 return; 907 907 908 QString title = messages[0]; 909 QString chanstr = messages[1]; 910 QString chansign = messages[2]; 911 QString channame = messages[3]; 908 ProgramInfo info; 909 QStringList::const_iterator it = msg.begin(); 910 info.FromStringList(it, msg.end()); 912 911 912 if (recorder->GetRecorderNumber() != info.cardid) 913 { 914 // Check if this is a shared tuner card, 915 // if so, then either lock mplexid or 916 // offer menu option to switch to a channel 917 // on the mplexid. 918 } 919 913 920 QString channel = gContext->GetSetting("ChannelFormat", "<num> <sign>"); 914 channel.replace("<num>", chanstr)915 .replace("<sign>", chansign)916 .replace("<name>", channame);921 channel.replace("<num>", info.chanstr) 922 .replace("<sign>", info.chansign) 923 .replace("<name>", info.channame); 917 924 918 925 QString message = QObject::tr( 919 926 "MythTV wants to record \"%1\" on %2 in %3 seconds. Do you want to:") 920 .arg( title).arg(channel).arg(" %d ");927 .arg(info.title).arg(channel).arg(" %d "); 921 928 922 929 while (!GetOSD()) 923 930 { … … 927 934 qApp->lock(); 928 935 } 929 936 937 bool is_this_rec = (recorder->GetRecorderNumber() == info.cardid); 938 930 939 QStringList options; 931 options += tr("Record and watch while it records"); 940 if (is_this_rec) 941 options += tr("Record and watch while it records"); 932 942 options += tr("Let it record and go back to the Main Menu"); 933 943 options += tr("Don't let it record, I want to watch TV"); 934 int sel = ( hasrec) ? 2: 0;944 int sel = (is_this_rec) ? ((hasrec) ? 2 : 0) : 0; 935 945 936 dialogname = "allowrecordingbox";946 dialogname = (is_this_rec) ? "allowrecordingbox" : "allowrecordingbox2"; 937 947 GetOSD()->NewDialogBox(dialogname, message, options, timeuntil, sel); 938 948 } 939 949 … … 2498 2508 break; 2499 2509 } 2500 2510 } 2501 else if (dialogname == "allowrecordingbox")2511 else if (dialogname.left(17) == "allowrecordingbox") 2502 2512 { 2503 2513 int result = GetOSD()->GetDialogResponse(dialogname); 2504 2514 2515 if ((dialogname == "allowrecordingbox2") && (result > 0)) 2516 result++; 2517 2505 2518 if (result == 1) 2506 2519 recorder->CancelNextRecording(false); 2507 2520 else if (result == 2) -
libs/libmythtv/programinfo.h
120 120 121 121 ProgramInfo& operator=(const ProgramInfo &other); 122 122 ProgramInfo& clone(const ProgramInfo &other); 123 bool FromStringList(QStringList &list, int offset); 124 bool FromStringList(QStringList &list, QStringList::iterator &it); 123 bool FromStringList(QStringList::const_iterator &it, 124 QStringList::const_iterator end); 125 bool FromStringList(const QStringList &list, uint offset); 126 125 127 bool FillInRecordInfo(const vector<ProgramInfo *> &reclist); 126 128 127 129 // Destructor -
libs/libmythtv/remoteutil.cpp
186 186 return 0; 187 187 } 188 188 189 QStringList:: iterator it = strList.at(1);189 QStringList::const_iterator it = strList.at(1); 190 190 for (int i = 0; i < numrecordings; i++) 191 191 { 192 192 ProgramInfo *pginfo = new ProgramInfo(); 193 pginfo->FromStringList( strList, it);193 pginfo->FromStringList(it, strList.end()); 194 194 reclist->push_back(pginfo); 195 195 } 196 196 } … … 418 418 419 419 QStringList::const_iterator it = strlist.begin(); 420 420 bool state = (*it).toInt(); 421 it++; 421 422 busy_input.FromStringList(it, strlist.end()); 422 423 423 424 return state; -
libs/libmythtv/tv_rec.cpp
78 78 static bool is_dishnet_eit(int cardid); 79 79 static QString load_profile(QString,void*,ProgramInfo*,RecordingProfile&); 80 80 81 uint RemoteGetFlags(uint cardid) 82 { 83 if (gContext->IsBackend()) 84 { 85 const TVRec *rec = TVRec::GetTVRec(cardid); 86 if (rec) 87 return rec->GetFlags(); 88 } 89 90 QStringList strlist = QString("QUERY_REMOTEENCODER %1").arg(cardid); 91 strlist << "GET_FLAGS"; 92 if (!gContext->SendReceiveStringList(strlist) || strlist.empty()) 93 return 0; 94 95 return strlist[0].toInt(); 96 } 97 98 bool RemoteRecordPending(uint cardid, const ProgramInfo *pginfo, 99 uint secsleft) 100 { 101 if (gContext->IsBackend()) 102 { 103 TVRec *rec = TVRec::GetTVRec(cardid); 104 if (rec) 105 { 106 rec->RecordPending(pginfo, secsleft); 107 return true; 108 } 109 } 110 111 QStringList strlist = QString("QUERY_REMOTEENCODER %1").arg(cardid); 112 strlist << "RECORD_PENDING"; 113 strlist << QString::number(secsleft); 114 pginfo->ToStringList(strlist); 115 116 if (!gContext->SendReceiveStringList(strlist) || strlist.empty()) 117 return false; 118 119 return strlist[0] == "OK"; 120 } 121 122 bool RemoteStopRecording(uint cardid) 123 { 124 if (gContext->IsBackend()) 125 { 126 TVRec *rec = TVRec::GetTVRec(cardid); 127 if (rec) 128 { 129 rec->StopRecording(); 130 return true; 131 } 132 } 133 134 QStringList strlist = QString("QUERY_REMOTEENCODER %1").arg(cardid); 135 strlist << "STOP_RECORDING"; 136 137 if (!gContext->SendReceiveStringList(strlist) || strlist.empty()) 138 return false; 139 140 return strlist[0] == "OK"; 141 } 142 81 143 /** \class TVRec 82 144 * \brief This is the coordinating class of the \ref recorder_subsystem. 83 145 * … … 362 424 * it. Depending on what that query returns, the recording will be 363 425 * started or not started. 364 426 * 365 * \sa TV::AskAllowRecording(const QStringList&, int )427 * \sa TV::AskAllowRecording(const QStringList&, int, bool) 366 428 * \param rcinfo ProgramInfo on pending program. 367 429 * \param secsleft Seconds left until pending recording begins. 368 430 */ 369 431 void TVRec::RecordPending(const ProgramInfo *rcinfo, int secsleft) 370 432 { 371 433 QMutexLocker lock(&stateChangeLock); 434 435 uint inputid = rcinfo->inputid; 436 cout<<endl; 437 VERBOSE(VB_RECORD, LOC + 438 QString("RecordPending on inputid %1").arg(inputid)); 439 372 440 if (pendingRecording) 373 441 delete pendingRecording; 374 442 375 443 pendingRecording = new ProgramInfo(*rcinfo); 376 444 recordPendingStart = QDateTime::currentDateTime().addSecs(secsleft); 377 445 SetFlags(kFlagAskAllowRecording); 446 447 if (rcinfo->cardid != cardid) 448 return; 449 450 // We also need to check our input groups 451 vector<uint> inputgroupids = CardUtil::GetInputGroups(inputid); 452 453 for (uint i = 0; i < inputgroupids.size(); i++) 454 { 455 VERBOSE(VB_RECORD, LOC + 456 QString(" Group ID %1").arg(inputgroupids[i])); 457 } 458 459 vector<uint> cardids; 460 for (uint i = 0; i < inputgroupids.size(); i++) 461 { 462 vector<uint> tmp = CardUtil::GetGroupCardIDs(inputgroupids[i]); 463 for (uint j = 0; j < tmp.size(); j++) 464 { 465 if (tmp[j] == (uint) cardid) 466 continue; 467 468 if (find(cardids.begin(), cardids.end(), tmp[j]) != cardids.end()) 469 continue; 470 471 cardids.push_back(tmp[j]); 472 } 473 } 474 475 for (uint i = 0; i < cardids.size(); i++) 476 VERBOSE(VB_RECORD, LOC + QString(" Card ID %1").arg(cardids[i])); 477 478 pendingRecordingCardIds = cardids; 479 480 stateChangeLock.unlock(); 481 for (uint i = 0; i < cardids.size(); i++) 482 RemoteRecordPending(cardids[i], rcinfo, secsleft); 483 stateChangeLock.lock(); 484 485 cout<<endl; 378 486 } 379 487 380 488 /** \fn TVRec::SetPseudoLiveTVRecording(ProgramInfo*) … … 467 575 // Flush out events... 468 576 WaitForEventThreadSleep(); 469 577 578 // If the needed input is in a shared input group, and we are 579 // not canceling the recording anyway, check other recorders 580 if (pendingRecording && pendingRecordingCardIds.size()) 581 { 582 cout<<endl; 583 VERBOSE(VB_RECORD, LOC + "Checking input group recorders - begin"); 584 vector<uint> &cardids = pendingRecordingCardIds; 585 586 // If any LiveTV session decided to cancel recording, don't record 587 for (uint i = 0; i < cardids.size(); i++) 588 { 589 uint flags = RemoteGetFlags(cardids[i]); 590 if (flags & kFlagCancelNextRecording) 591 { 592 SetFlags(kFlagCancelNextRecording); 593 break; 594 } 595 } 596 597 // Stop all the remote recordings 598 uint maxi = HasFlags(kFlagCancelNextRecording) ? cardids.size() : 0; 599 bool ok = true; 600 for (uint i = 0; (i < maxi) && ok; i++) 601 { 602 VERBOSE(VB_RECORD, LOC + QString("Attempting to stop card %1") 603 .arg(cardids[i])); 604 ok &= RemoteStopRecording(cardids[i]); 605 } 606 607 cardids.clear(); 608 609 // If we failed to stop the remote recordings, don't record 610 if (!ok) 611 SetFlags(kFlagCancelNextRecording); 612 VERBOSE(VB_RECORD, LOC + "Checking input group recorders - done\n"); 613 } 614 470 615 // If in post-roll, end recording 471 616 if (GetState() == kState_RecordingOnly && 472 617 !HasFlags(kFlagCancelNextRecording)) … … 476 621 stateChangeLock.lock(); 477 622 } 478 623 479 if (internalState == kState_None) 624 if (!HasFlags(kFlagCancelNextRecording) && 625 (GetState() == kState_None)) 480 626 { 481 627 if (tvchain) 482 628 { … … 1215 1361 .arg(cardid).arg(timeuntil) 1216 1362 .arg(pseudoLiveTVRecording ? 1 : 0); 1217 1363 VERBOSE(VB_IMPORTANT, LOC + query); 1218 QStringList messages; 1219 messages << pendingRecording->title 1220 << pendingRecording->chanstr 1221 << pendingRecording->chansign 1222 << pendingRecording->channame; 1223 MythEvent me(query, messages); 1364 1365 QStringList msg; 1366 pendingRecording->ToStringList(msg); 1367 MythEvent me(query, msg); 1224 1368 gContext->dispatch(me); 1225 1369 } 1226 1370 } -
libs/libmythtv/programinfo.cpp
275 275 /** \fn ProgramInfo::ToStringList(QStringList&) const 276 276 * \brief Serializes ProgramInfo into a QStringList which can be passed 277 277 * over a socket. 278 * \sa FromStringList(QStringList &,int),279 * FromStringList(QStringList&,QStringList::iterator&)278 * \sa FromStringList(QStringList::const_iterator&, 279 QStringList::const_iterator) 280 280 */ 281 281 void ProgramInfo::ToStringList(QStringList &list) const 282 282 { … … 327 327 STR_TO_LIST((storagegroup != "") ? storagegroup : "Default") 328 328 } 329 329 330 /** \fn ProgramInfo::FromStringList( QStringList&,int)330 /** \fn ProgramInfo::FromStringList(const QStringList&,uint) 331 331 * \brief Uses a QStringList to initialize this ProgramInfo instance. 332 * 333 * This is a convenience method which calls FromStringList( 334 QStringList::const_iterator&,QStringList::const_iterator) 335 * with an iterator created using list.at(offset). 336 * 332 337 * \param list QStringList containing serialized ProgramInfo. 333 338 * \param offset First field in list to treat as beginning of 334 339 * serialized ProgramInfo. 335 340 * \return true if it succeeds, false if it fails. 336 * \sa ToStringList(QStringList&), 337 * FromStringList(QStringList&,QStringList::iterator&) 341 * \sa FromStringList(QStringList::const_iterator&, 342 QStringList::const_iterator) 343 * ToStringList(QStringList&) const 338 344 */ 339 bool ProgramInfo::FromStringList( QStringList &list,int offset)345 bool ProgramInfo::FromStringList(const QStringList &list, uint offset) 340 346 { 341 QStringList:: iterator it = list.at(offset);342 return FromStringList( list, it);347 QStringList::const_iterator it = list.at(offset); 348 return FromStringList(it, list.end()); 343 349 } 344 350 345 351 #define NEXT_STR() if (it == listend) \ … … 365 371 366 372 #define FLOAT_FROM_LIST(x) NEXT_STR() (x) = atof(ts.ascii()); 367 373 368 /** \fn ProgramInfo::FromStringList(QStringList&,QStringList::iterator&) 374 /** \fn ProgramInfo::FromStringList(QStringList::const_iterator&, 375 QStringList::const_iterator) 369 376 * \brief Uses a QStringList to initialize this ProgramInfo instance. 370 * \param list QStringList containing serialized ProgramInfo. 371 * \param it Iterator pointing to first field in list to treat as 377 * \param beg Iterator pointing to first item in list to treat as 372 378 * beginning of serialized ProgramInfo. 379 * \param end Iterator that will stop parsing of the ProgramInfo 373 380 * \return true if it succeeds, false if it fails. 374 * \sa ToStringList(QStringList&), FromStringList(QStringList&,int) 381 * \sa FromStringList(const QStringList&,uint) 382 * ToStringList(QStringList&) const 375 383 */ 376 bool ProgramInfo::FromStringList(QStringList &list, QStringList::iterator &it) 384 385 bool ProgramInfo::FromStringList(QStringList::const_iterator &it, 386 QStringList::const_iterator listend) 377 387 { 378 const char* listerror = LOC + "FromStringList, not enough items in list.\n"; 379 QStringList::iterator listend = list.end(); 388 QString listerror = LOC + "FromStringList, not enough items in list."; 380 389 QString ts; 381 390 int ti; 382 391 … … 4476 4485 hasConflicts = slist[0].toInt(); 4477 4486 4478 4487 bool result = true; 4479 QStringList:: Iterator sit = slist.at(2);4488 QStringList::const_iterator sit = slist.at(2); 4480 4489 4481 4490 while (result && sit != slist.end()) 4482 4491 { 4483 4492 ProgramInfo *p = new ProgramInfo(); 4484 result = p->FromStringList(s list, sit);4493 result = p->FromStringList(sit, slist.end()); 4485 4494 if (result) 4486 4495 append(p); 4487 4496 else -
libs/libmythtv/tv_rec.h
223 223 224 224 void SetNextLiveTVDir(QString dir); 225 225 226 uint GetFlags(void) const { return stateFlags; } 227 226 228 static TVRec *GetTVRec(uint cardid); 227 229 228 230 public slots: … … 364 366 // Pending recording info 365 367 ProgramInfo *pendingRecording; 366 368 QDateTime recordPendingStart; 369 vector<uint> pendingRecordingCardIds; 367 370 368 371 // Pseudo LiveTV recording 369 372 ProgramInfo *pseudoLiveTVRecording; … … 378 381 RingBuffer *ringBuffer; 379 382 QString rbFileExt; 380 383 381 public:382 384 static QMutex cardsLock; 383 385 static QMap<uint,TVRec*> cards; 384 386 -
programs/mythbackend/encoderlink.h
54 54 bool IsBusyRecording(void); 55 55 56 56 TVState GetState(); 57 uint GetFlags(void) const; 57 58 bool IsRecording(const ProgramInfo *rec); // scheduler call only. 58 59 59 60 bool MatchesRecording(const ProgramInfo *rec); -
programs/mythbackend/mainserver.cpp
937 937 { 938 938 ProgramInfo pinfo; 939 939 ProgramList slavelist; 940 QStringList:: Iterator sit = slist.at(1);940 QStringList::const_iterator sit = slist.at(1); 941 941 while (sit != slist.end()) 942 942 { 943 if (!pinfo.FromStringList(s list, sit))943 if (!pinfo.FromStringList(sit, slist.end())) 944 944 break; 945 945 slavelist.append(new ProgramInfo(pinfo)); 946 946 } … … 3084 3084 { 3085 3085 retlist << QString::number((int)enc->GetState()); 3086 3086 } 3087 if (command == "IS_BUSY")3087 else if (command == "GET_FLAGS") 3088 3088 { 3089 retlist << QString::number(enc->GetFlags()); 3090 } 3091 else if (command == "IS_BUSY") 3092 { 3089 3093 TunedInputInfo busy_input; 3090 3094 retlist << QString::number((int)enc->IsBusy(&busy_input)); 3091 3095 busy_input.ToStringList(retlist); … … 3119 3123 retlist << "OK"; 3120 3124 delete pginfo; 3121 3125 } 3126 else if (command == "STOP_RECORDING") 3127 { 3128 enc->StopRecording(); 3129 retlist << "OK"; 3130 } 3122 3131 else if (command == "GET_MAX_BITRATE") 3123 3132 { 3124 3133 long long value = enc->GetMaxBitrate(); -
programs/mythbackend/encoderlink.cpp
15 15 #include "previewgenerator.h" 16 16 #include "storagegroup.h" 17 17 18 #define LOC QString("EncoderLink(%1): ").arg(m_capturecardnum) 19 #define LOC_ERR QString("EncoderLink(%1) Error: ").arg(m_capturecardnum) 20 18 21 /** 19 22 * \class EncoderLink 20 23 * \brief Provides an interface to both local and remote TVRec's for the mythbackend. … … 143 146 return retval; 144 147 } 145 148 149 /** \fn EncoderLink::GetFlags(void) const 150 * \brief Returns the flag state of the recorder. 151 * \sa TVRec::GetFlags(void) const, \ref recorder_subsystem 152 */ 153 uint EncoderLink::GetFlags(void) const 154 { 155 uint retval = 0; 156 157 if (!IsConnected()) 158 return retval; 159 160 if (local) 161 retval = tv->GetFlags(); 162 else if (sock) 163 retval = sock->GetEncoderState(m_capturecardnum); 164 else 165 VERBOSE(VB_IMPORTANT, LOC_ERR + "GetFlags failed"); 166 167 return retval; 168 } 169 146 170 /** \fn EncoderLink::IsRecording(const ProgramInfo *rec) 147 171 * \brief Returns true if rec is scheduled for recording. 148 172 * \param rec Recording to check.