|
MythTV
0.26-pre
|
00001 #include <QStringList> 00002 00003 using namespace std; 00004 00005 #include "compat.h" 00006 #include "playbacksock.h" 00007 #include "programinfo.h" 00008 #include "mainserver.h" 00009 00010 #include "mythcorecontext.h" 00011 #include "mythmiscutil.h" 00012 #include "inputinfo.h" 00013 00014 #define LOC QString("PlaybackSock: ") 00015 #define LOC_ERR QString("PlaybackSock, Error: ") 00016 00017 PlaybackSock::PlaybackSock(MainServer *parent, MythSocket *lsock, 00018 QString lhostname, PlaybackSockEventsMode eventsMode) 00019 { 00020 m_parent = parent; 00021 QString localhostname = gCoreContext->GetHostName(); 00022 00023 refCount = 0; 00024 00025 sock = lsock; 00026 hostname = lhostname; 00027 m_eventsMode = eventsMode; 00028 ip = ""; 00029 backend = false; 00030 mediaserver = false; 00031 expectingreply = false; 00032 00033 disconnected = false; 00034 blockshutdown = true; 00035 00036 if (hostname == localhostname) 00037 local = true; 00038 else 00039 local = false; 00040 } 00041 00042 PlaybackSock::~PlaybackSock() 00043 { 00044 sock->DownRef(); 00045 } 00046 00047 void PlaybackSock::UpRef(void) 00048 { 00049 QMutexLocker locker(&refLock); 00050 refCount++; 00051 } 00052 00053 bool PlaybackSock::DownRef(void) 00054 { 00055 QMutexLocker locker(&refLock); 00056 00057 refCount--; 00058 if (refCount < 0) 00059 { 00060 m_parent->DeletePBS(this); 00061 return true; 00062 } 00063 return false; 00064 } 00065 00066 bool PlaybackSock::wantsEvents(void) const 00067 { 00068 return (m_eventsMode != kPBSEvents_None); 00069 } 00070 00071 bool PlaybackSock::wantsNonSystemEvents(void) const 00072 { 00073 return ((m_eventsMode == kPBSEvents_Normal) || 00074 (m_eventsMode == kPBSEvents_NonSystem)); 00075 } 00076 00077 bool PlaybackSock::wantsSystemEvents(void) const 00078 { 00079 return ((m_eventsMode == kPBSEvents_Normal) || 00080 (m_eventsMode == kPBSEvents_SystemOnly)); 00081 } 00082 00083 bool PlaybackSock::wantsOnlySystemEvents(void) const 00084 { 00085 return (m_eventsMode == kPBSEvents_SystemOnly); 00086 } 00087 00088 PlaybackSockEventsMode PlaybackSock::eventsMode(void) const 00089 { 00090 return m_eventsMode; 00091 } 00092 00093 bool PlaybackSock::SendReceiveStringList( 00094 QStringList &strlist, uint min_reply_length) 00095 { 00096 bool ok = false; 00097 00098 sock->Lock(); 00099 sock->UpRef(); 00100 00101 { 00102 QMutexLocker locker(&sockLock); 00103 expectingreply = true; 00104 00105 sock->writeStringList(strlist); 00106 ok = sock->readStringList(strlist); 00107 00108 while (ok && strlist[0] == "BACKEND_MESSAGE") 00109 { 00110 // oops, not for us 00111 if (strlist.size() >= 2) 00112 { 00113 QString message = strlist[1]; 00114 strlist.pop_front(); 00115 strlist.pop_front(); 00116 MythEvent me(message, strlist); 00117 gCoreContext->dispatch(me); 00118 } 00119 00120 ok = sock->readStringList(strlist); 00121 } 00122 00123 expectingreply = false; 00124 } 00125 00126 sock->Unlock(); 00127 sock->DownRef(); 00128 00129 if (!ok) 00130 { 00131 LOG(VB_GENERAL, LOG_ERR, 00132 "PlaybackSock::SendReceiveStringList(): No response."); 00133 return false; 00134 } 00135 00136 if (min_reply_length && ((uint)strlist.size() < min_reply_length)) 00137 { 00138 LOG(VB_GENERAL, LOG_ERR, 00139 "PlaybackSock::SendReceiveStringList(): Response too short"); 00140 return false; 00141 } 00142 00143 return true; 00144 } 00145 00148 bool PlaybackSock::GoToSleep(void) 00149 { 00150 QStringList strlist(QString("GO_TO_SLEEP")); 00151 00152 return SendReceiveStringList(strlist, 1) && (strlist[0] == "OK"); 00153 } 00154 00158 void PlaybackSock::GetDiskSpace(QStringList &o_strlist) 00159 { 00160 QStringList strlist(QString("QUERY_FREE_SPACE")); 00161 00162 SendReceiveStringList(strlist); 00163 00164 o_strlist += strlist; 00165 00166 } 00167 00168 int PlaybackSock::CheckRecordingActive(const ProgramInfo *pginfo) 00169 { 00170 QStringList strlist(QString("CHECK_RECORDING")); 00171 pginfo->ToStringList(strlist); 00172 00173 if (SendReceiveStringList(strlist, 1)) 00174 return strlist[0].toInt(); 00175 00176 return 0; 00177 } 00178 00179 int PlaybackSock::DeleteFile(const QString &filename, const QString &sgroup) 00180 { 00181 QStringList strlist("DELETE_FILE"); 00182 strlist << filename; 00183 strlist << sgroup; 00184 00185 if (SendReceiveStringList(strlist, 1)) 00186 return strlist[0].toInt(); 00187 00188 return 0; 00189 } 00190 00191 int PlaybackSock::StopRecording(const ProgramInfo *pginfo) 00192 { 00193 QStringList strlist(QString("STOP_RECORDING")); 00194 pginfo->ToStringList(strlist); 00195 00196 if (SendReceiveStringList(strlist, 1)) 00197 return strlist[0].toInt(); 00198 00199 return 0; 00200 } 00201 00202 int PlaybackSock::DeleteRecording(const ProgramInfo *pginfo, 00203 bool forceMetadataDelete) 00204 { 00205 QStringList strlist; 00206 00207 if (forceMetadataDelete) 00208 strlist = QStringList( QString("FORCE_DELETE_RECORDING")); 00209 else 00210 strlist = QStringList( QString("DELETE_RECORDING")); 00211 00212 pginfo->ToStringList(strlist); 00213 00214 if (SendReceiveStringList(strlist, 1)) 00215 return strlist[0].toInt(); 00216 00217 return 0; 00218 } 00219 00220 bool PlaybackSock::FillProgramInfo(ProgramInfo &pginfo, 00221 const QString &playbackhost) 00222 { 00223 QStringList strlist(QString("FILL_PROGRAM_INFO")); 00224 strlist << playbackhost; 00225 pginfo.ToStringList(strlist); 00226 00227 if (SendReceiveStringList(strlist)) 00228 { 00229 ProgramInfo tmp(strlist); 00230 if (tmp.HasPathname() || tmp.GetChanID()) 00231 { 00232 pginfo.clone(tmp, true); 00233 return true; 00234 } 00235 } 00236 00237 return false; 00238 } 00239 00240 QStringList PlaybackSock::GetSGFileList(QString &host, QString &groupname, 00241 QString &directory, bool fileNamesOnly) 00242 { 00243 QStringList strlist(QString("QUERY_SG_GETFILELIST")); 00244 strlist << host; 00245 strlist << groupname; 00246 strlist << directory; 00247 strlist << QString::number(fileNamesOnly); 00248 00249 SendReceiveStringList(strlist); 00250 00251 return strlist; 00252 } 00253 00254 QStringList PlaybackSock::GetSGFileQuery(QString &host, QString &groupname, 00255 QString &filename) 00256 { 00257 QStringList strlist(QString("QUERY_SG_FILEQUERY")); 00258 strlist << host; 00259 strlist << groupname; 00260 strlist << filename; 00261 00262 SendReceiveStringList(strlist); 00263 00264 return strlist; 00265 } 00266 00267 QString PlaybackSock::GetFileHash(QString filename, QString storageGroup) 00268 { 00269 QStringList strlist(QString("QUERY_FILE_HASH")); 00270 strlist << filename 00271 << storageGroup; 00272 00273 SendReceiveStringList(strlist); 00274 return strlist[0]; 00275 } 00276 00277 QStringList PlaybackSock::GenPreviewPixmap(const QString &token, 00278 const ProgramInfo *pginfo) 00279 { 00280 QStringList strlist(QString("QUERY_GENPIXMAP2")); 00281 strlist += token; 00282 pginfo->ToStringList(strlist); 00283 00284 SendReceiveStringList(strlist); 00285 00286 return strlist; 00287 } 00288 00289 QStringList PlaybackSock::GenPreviewPixmap(const QString &token, 00290 const ProgramInfo *pginfo, 00291 bool time_fmt_sec, 00292 long long time, 00293 const QString &outputFile, 00294 const QSize &outputSize) 00295 { 00296 QStringList strlist(QString("QUERY_GENPIXMAP2")); 00297 strlist += token; 00298 pginfo->ToStringList(strlist); 00299 strlist.push_back(time_fmt_sec ? "s" : "f"); 00300 strlist.push_back(QString::number(time)); 00301 strlist.push_back((outputFile.isEmpty()) ? "<EMPTY>" : outputFile); 00302 strlist.push_back(QString::number(outputSize.width())); 00303 strlist.push_back(QString::number(outputSize.height())); 00304 00305 SendReceiveStringList(strlist); 00306 00307 return strlist; 00308 } 00309 00310 QDateTime PlaybackSock::PixmapLastModified(const ProgramInfo *pginfo) 00311 { 00312 QStringList strlist(QString("QUERY_PIXMAP_LASTMODIFIED")); 00313 pginfo->ToStringList(strlist); 00314 00315 SendReceiveStringList(strlist); 00316 00317 QDateTime datetime; 00318 if (!strlist.empty() && strlist[0] != "BAD") 00319 { 00320 uint timet = strlist[0].toUInt(); 00321 datetime.setTime_t(timet); 00322 } 00323 return datetime; 00324 } 00325 00326 bool PlaybackSock::CheckFile(ProgramInfo *pginfo) 00327 { 00328 QStringList strlist("QUERY_CHECKFILE"); 00329 strlist << QString::number(0); // don't check slaves 00330 pginfo->ToStringList(strlist); 00331 00332 if (SendReceiveStringList(strlist, 2)) 00333 { 00334 pginfo->SetPathname(strlist[1]); 00335 return strlist[0].toInt(); 00336 } 00337 00338 return false; 00339 } 00340 00341 bool PlaybackSock::IsBusy(int capturecardnum, InputInfo *busy_input, 00342 int time_buffer) 00343 { 00344 QStringList strlist(QString("QUERY_REMOTEENCODER %1").arg(capturecardnum)); 00345 00346 strlist << "IS_BUSY"; 00347 strlist << QString::number(time_buffer); 00348 00349 if (!SendReceiveStringList(strlist, 1)) 00350 { 00351 LOG(VB_GENERAL, LOG_ERR, LOC + "IsBusy: " + 00352 QString("QUERY_REMOTEENCODER %1").arg(capturecardnum) + 00353 " gave us no response."); 00354 } 00355 00356 bool state = false; 00357 00358 if (!strlist.isEmpty()) 00359 { 00360 QStringList::const_iterator it = strlist.begin(); 00361 state = (*it).toInt(); 00362 00363 if (busy_input) 00364 { 00365 ++it; 00366 if (!busy_input->FromStringList(it, strlist.end())) 00367 { 00368 LOG(VB_GENERAL, LOG_ERR, LOC + "IsBusy: " 00369 "Failed to parse response to " + 00370 QString("QUERY_REMOTEENCODER %1").arg(capturecardnum)); 00371 state = false; 00372 // pretend it's not busy if we can't parse response 00373 } 00374 } 00375 } 00376 00377 return state; 00378 } 00379 00384 int PlaybackSock::GetEncoderState(int capturecardnum) 00385 { 00386 QStringList strlist(QString("QUERY_REMOTEENCODER %1").arg(capturecardnum)); 00387 strlist << "GET_STATE"; 00388 00389 if (!SendReceiveStringList(strlist, 1)) 00390 { 00391 LOG(VB_GENERAL, LOG_ERR, LOC + "GetEncoderState: " + 00392 QString("QUERY_REMOTEENCODER %1").arg(capturecardnum) + 00393 " gave us no response."); 00394 00395 return kState_Error; 00396 } 00397 00398 return strlist[0].toInt(); 00399 } 00400 00401 long long PlaybackSock::GetMaxBitrate(int capturecardnum) 00402 { 00403 QStringList strlist(QString("QUERY_REMOTEENCODER %1").arg(capturecardnum)); 00404 strlist << "GET_MAX_BITRATE"; 00405 00406 if (SendReceiveStringList(strlist, 2)) 00407 return strlist[0].toLongLong(); 00408 00409 return 20200000LL; // Peak bit rate for HD-PVR 00410 } 00411 00416 ProgramInfo *PlaybackSock::GetRecording(uint cardid) 00417 { 00418 QStringList strlist(QString("QUERY_REMOTEENCODER %1").arg(cardid)); 00419 strlist << "GET_CURRENT_RECORDING"; 00420 00421 if (!SendReceiveStringList(strlist)) 00422 return NULL; 00423 00424 ProgramInfo *pginfo = new ProgramInfo(strlist); 00425 if (!pginfo->HasPathname() && !pginfo->GetChanID()) 00426 { 00427 delete pginfo; 00428 pginfo = NULL; 00429 } 00430 00431 return pginfo; 00432 } 00433 00434 bool PlaybackSock::EncoderIsRecording(int capturecardnum, 00435 const ProgramInfo *pginfo) 00436 { 00437 QStringList strlist(QString("QUERY_REMOTEENCODER %1").arg(capturecardnum)); 00438 strlist << "MATCHES_RECORDING"; 00439 pginfo->ToStringList(strlist); 00440 00441 if (SendReceiveStringList(strlist, 1)) 00442 return (bool) strlist[0].toInt(); 00443 00444 return false; 00445 } 00446 00447 RecStatusType PlaybackSock::StartRecording(int capturecardnum, 00448 const ProgramInfo *pginfo) 00449 { 00450 QStringList strlist(QString("QUERY_REMOTEENCODER %1").arg(capturecardnum)); 00451 strlist << "START_RECORDING"; 00452 pginfo->ToStringList(strlist); 00453 00454 if (SendReceiveStringList(strlist, 1)) 00455 return RecStatusType(strlist[0].toInt()); 00456 00457 return rsUnknown; 00458 } 00459 00460 RecStatusType PlaybackSock::GetRecordingStatus(int capturecardnum) 00461 { 00462 QStringList strlist(QString("QUERY_REMOTEENCODER %1").arg(capturecardnum)); 00463 strlist << "GET_RECORDING_STATUS"; 00464 00465 if (!SendReceiveStringList(strlist, 1)) 00466 { 00467 LOG(VB_GENERAL, LOG_ERR, LOC + "GetRecordingStatus: " + 00468 QString("QUERY_REMOTEENCODER %1").arg(capturecardnum) + 00469 " did not respond."); 00470 00471 return rsUnknown; 00472 } 00473 00474 return RecStatusType(strlist[0].toInt()); 00475 } 00476 00477 void PlaybackSock::RecordPending(int capturecardnum, const ProgramInfo *pginfo, 00478 int secsleft, bool hasLater) 00479 { 00480 QStringList strlist(QString("QUERY_REMOTEENCODER %1").arg(capturecardnum)); 00481 strlist << "RECORD_PENDING"; 00482 strlist << QString::number(secsleft); 00483 strlist << QString::number(hasLater); 00484 pginfo->ToStringList(strlist); 00485 00486 SendReceiveStringList(strlist); 00487 } 00488 00489 int PlaybackSock::SetSignalMonitoringRate(int capturecardnum, 00490 int rate, int notifyFrontend) 00491 { 00492 QStringList strlist(QString("QUERY_REMOTEENCODER %1").arg(capturecardnum)); 00493 strlist << "SET_SIGNAL_MONITORING_RATE"; 00494 strlist << QString::number(rate); 00495 strlist << QString::number(notifyFrontend); 00496 00497 if (SendReceiveStringList(strlist, 1)) 00498 return strlist[0].toInt(); 00499 00500 return -1; 00501 } 00502 00503 void PlaybackSock::SetNextLiveTVDir(int capturecardnum, QString dir) 00504 { 00505 QStringList strlist(QString("SET_NEXT_LIVETV_DIR %1 %2") 00506 .arg(capturecardnum) 00507 .arg(dir)); 00508 00509 SendReceiveStringList(strlist); 00510 } 00511 00512 vector<InputInfo> PlaybackSock::GetFreeInputs(int capturecardnum, 00513 const vector<uint> &excluded_cardids) 00514 { 00515 QStringList strlist(QString("QUERY_REMOTEENCODER %1").arg(capturecardnum)); 00516 strlist << "GET_FREE_INPUTS"; 00517 00518 for (uint i = 0; i < excluded_cardids.size(); i++) 00519 strlist << QString::number(excluded_cardids[i]); 00520 00521 SendReceiveStringList(strlist); 00522 00523 vector<InputInfo> list; 00524 00525 QStringList::const_iterator it = strlist.begin(); 00526 if ((it == strlist.end()) || (*it == "EMPTY_LIST")) 00527 return list; 00528 00529 while (it != strlist.end()) 00530 { 00531 InputInfo info; 00532 if (!info.FromStringList(it, strlist.end())) 00533 break; 00534 list.push_back(info); 00535 } 00536 00537 return list; 00538 } 00539 00540 void PlaybackSock::CancelNextRecording(int capturecardnum, bool cancel) 00541 { 00542 QStringList strlist(QString("QUERY_REMOTEENCODER %1") 00543 .arg(capturecardnum)); 00544 00545 strlist << "CANCEL_NEXT_RECORDING"; 00546 strlist << QString::number(cancel); 00547 00548 SendReceiveStringList(strlist); 00549 } 00550 00551 QStringList PlaybackSock::ForwardRequest(const QStringList &slist) 00552 { 00553 QStringList strlist = slist; 00554 00555 if (SendReceiveStringList(strlist)) 00556 return strlist; 00557 00558 return QStringList(); 00559 } 00560 00561 /* vim: set expandtab tabstop=4 shiftwidth=4: */
1.7.6.1