00001
00002 #include <iostream>
00003 using namespace std;
00004
00005
00006 #include <unistd.h>
00007
00008
00009 #include "mythcontext.h"
00010 #include "encoderlink.h"
00011 #include "playbacksock.h"
00012 #include "tv_rec.h"
00013 #include "programinfo.h"
00014 #include "util.h"
00015 #include "previewgenerator.h"
00016 #include "storagegroup.h"
00017 #include "backendutil.h"
00018 #include "compat.h"
00019
00020 #define LOC QString("EncoderLink(%1): ").arg(m_capturecardnum)
00021 #define LOC_ERR QString("EncoderLink(%1) Error: ").arg(m_capturecardnum)
00022
00041 EncoderLink::EncoderLink(int capturecardnum, PlaybackSock *lsock,
00042 QString lhostname)
00043 : m_capturecardnum(capturecardnum), sock(lsock), hostname(lhostname),
00044 freeDiskSpaceKB(-1), tv(NULL), local(false), locked(false),
00045 chanid("")
00046 {
00047 endRecordingTime = QDateTime::currentDateTime().addDays(-2);
00048 startRecordingTime = endRecordingTime;
00049
00050 if (sock)
00051 sock->UpRef();
00052 }
00053
00057 EncoderLink::EncoderLink(int capturecardnum, TVRec *ltv)
00058 : m_capturecardnum(capturecardnum), sock(NULL), hostname(QString::null),
00059 freeDiskSpaceKB(-1), tv(ltv), local(true), locked(false),
00060 chanid("")
00061 {
00062 endRecordingTime = QDateTime::currentDateTime().addDays(-2);
00063 startRecordingTime = endRecordingTime;
00064 }
00065
00070 EncoderLink::~EncoderLink(void)
00071 {
00072 if (tv)
00073 tv->deleteLater();
00074 }
00075
00081 void EncoderLink::SetSocket(PlaybackSock *lsock)
00082 {
00083 if (lsock)
00084 lsock->UpRef();
00085
00086 if (sock)
00087 sock->DownRef();
00088 sock = lsock;
00089 }
00090
00096 bool EncoderLink::IsBusy(TunedInputInfo *busy_input, int time_buffer)
00097 {
00098 if (local)
00099 return tv->IsBusy(busy_input, time_buffer);
00100
00101 if (sock)
00102 return sock->IsBusy(m_capturecardnum, busy_input, time_buffer);
00103
00104 return false;
00105 }
00106
00115 bool EncoderLink::IsBusyRecording(void)
00116 {
00117 bool retval = false;
00118
00119 TVState state = GetState();
00120
00121 if (state == kState_RecordingOnly || state == kState_WatchingRecording ||
00122 state == kState_WatchingLiveTV)
00123 {
00124 retval = true;
00125 }
00126
00127 return retval;
00128 }
00129
00134 TVState EncoderLink::GetState(void)
00135 {
00136 TVState retval = kState_Error;
00137
00138 if (!IsConnected())
00139 return retval;
00140
00141 if (local)
00142 retval = tv->GetState();
00143 else if (sock)
00144 retval = (TVState)sock->GetEncoderState(m_capturecardnum);
00145 else
00146 cerr << "Broken for card: " << m_capturecardnum << endl;
00147
00148 return retval;
00149 }
00150
00155 uint EncoderLink::GetFlags(void) const
00156 {
00157 uint retval = 0;
00158
00159 if (!IsConnected())
00160 return retval;
00161
00162 if (local)
00163 retval = tv->GetFlags();
00164 else if (sock)
00165 retval = sock->GetEncoderState(m_capturecardnum);
00166 else
00167 VERBOSE(VB_IMPORTANT, LOC_ERR + "GetFlags failed");
00168
00169 return retval;
00170 }
00171
00177 bool EncoderLink::IsRecording(const ProgramInfo *rec)
00178 {
00179 bool retval = false;
00180
00181 if (rec->chanid == chanid && rec->recstartts == startRecordingTime)
00182 retval = true;
00183
00184 return retval;
00185 }
00186
00195 bool EncoderLink::MatchesRecording(const ProgramInfo *rec)
00196 {
00197 bool retval = false;
00198 ProgramInfo *tvrec = NULL;
00199
00200 if (local)
00201 {
00202 while (kState_ChangingState == GetState())
00203 usleep(100);
00204
00205 if (IsBusyRecording())
00206 tvrec = tv->GetRecording();
00207
00208 if (tvrec)
00209 {
00210 if (tvrec->chanid == rec->chanid &&
00211 tvrec->recstartts == rec->recstartts)
00212 {
00213 retval = true;
00214 }
00215
00216 delete tvrec;
00217 }
00218 }
00219 else
00220 {
00221 if (sock)
00222 retval = sock->EncoderIsRecording(m_capturecardnum, rec);
00223 }
00224
00225 return retval;
00226 }
00227
00236 void EncoderLink::RecordPending(const ProgramInfo *rec, int secsleft,
00237 bool hasLater)
00238 {
00239 if (local)
00240 tv->RecordPending(rec, secsleft, hasLater);
00241 else if (sock)
00242 sock->RecordPending(m_capturecardnum, rec, secsleft, hasLater);
00243 }
00244
00250 bool EncoderLink::WouldConflict(const ProgramInfo *rec)
00251 {
00252 if (!IsConnected())
00253 return true;
00254
00255 if (rec->recstartts < endRecordingTime)
00256 return true;
00257
00258 return false;
00259 }
00260
00261 bool EncoderLink::CheckFile(ProgramInfo *pginfo)
00262 {
00263 if (sock)
00264 return sock->CheckFile(pginfo);
00265 else
00266 {
00267 pginfo->pathname = GetPlaybackURL(pginfo);
00268 if (pginfo->pathname.left(1) == "/")
00269 return true;
00270 }
00271 return false;
00272 }
00273
00279 void EncoderLink::GetDiskSpace(QStringList &o_strlist)
00280 {
00281 if (sock)
00282 sock->GetDiskSpace(o_strlist);
00283 }
00284
00291 long long EncoderLink::GetMaxBitrate()
00292 {
00293 if (local)
00294 return tv->GetMaxBitrate();
00295 else if (sock)
00296 return sock->GetMaxBitrate(m_capturecardnum);
00297
00298 return -1;
00299 }
00300
00315 int EncoderLink::SetSignalMonitoringRate(int rate, int notifyFrontend)
00316 {
00317 if (local)
00318 return tv->SetSignalMonitoringRate(rate, notifyFrontend);
00319 else if (sock)
00320 return sock->SetSignalMonitoringRate(m_capturecardnum, rate,
00321 notifyFrontend);
00322 return -1;
00323 }
00324
00329 int EncoderLink::LockTuner()
00330 {
00331 if (locked)
00332 return -2;
00333
00334 locked = true;
00335 return m_capturecardnum;
00336 }
00337
00345 RecStatusType EncoderLink::StartRecording(const ProgramInfo *rec)
00346 {
00347 RecStatusType retval = rsAborted;
00348
00349 endRecordingTime = rec->recendts;
00350 startRecordingTime = rec->recstartts;
00351 chanid = rec->chanid;
00352
00353 if (local)
00354 retval = tv->StartRecording(rec);
00355 else if (sock)
00356 retval = sock->StartRecording(m_capturecardnum, rec);
00357 else
00358 VERBOSE(VB_IMPORTANT,
00359 QString("Wanted to start recording on recorder %1,\n\t\t\t"
00360 "but the backend is not there anymore\n")
00361 .arg(m_capturecardnum));
00362
00363 if (retval != rsRecording)
00364 {
00365 endRecordingTime = QDateTime::currentDateTime().addDays(-2);
00366 startRecordingTime = endRecordingTime;
00367 chanid = "";
00368 }
00369
00370 return retval;
00371 }
00372
00379 ProgramInfo *EncoderLink::GetRecording(void)
00380 {
00381 ProgramInfo *info = NULL;
00382
00383 if (local)
00384 info = tv->GetRecording();
00385 else if (sock)
00386 info = sock->GetRecording(m_capturecardnum);
00387
00388 return info;
00389 }
00390
00396 void EncoderLink::StopRecording(void)
00397 {
00398 endRecordingTime = QDateTime::currentDateTime().addDays(-2);
00399 startRecordingTime = endRecordingTime;
00400 chanid = "";
00401
00402 if (local)
00403 {
00404 tv->StopRecording();
00405 return;
00406 }
00407 }
00408
00414 void EncoderLink::FinishRecording(void)
00415 {
00416 if (local)
00417 {
00418 tv->FinishRecording();
00419 return;
00420 }
00421 else
00422 {
00423 endRecordingTime = QDateTime::currentDateTime().addDays(-2);
00424 }
00425 }
00426
00432 bool EncoderLink::IsReallyRecording(void)
00433 {
00434 if (local)
00435 return tv->IsReallyRecording();
00436
00437 VERBOSE(VB_IMPORTANT, "Should be local only query: IsReallyRecording");
00438 return false;
00439 }
00440
00448 float EncoderLink::GetFramerate(void)
00449 {
00450 if (local)
00451 return tv->GetFramerate();
00452
00453 VERBOSE(VB_IMPORTANT, "Should be local only query: GetFramerate");
00454 return -1;
00455 }
00456
00464 long long EncoderLink::GetFramesWritten(void)
00465 {
00466 if (local)
00467 return tv->GetFramesWritten();
00468
00469 VERBOSE(VB_IMPORTANT, "Should be local only query: GetFramesWritten");
00470 return -1;
00471 }
00472
00479 long long EncoderLink::GetFilePosition(void)
00480 {
00481 if (local)
00482 return tv->GetFilePosition();
00483
00484 VERBOSE(VB_IMPORTANT, "Should be local only query: GetFilePosition");
00485 return -1;
00486 }
00487
00495 long long EncoderLink::GetKeyframePosition(long long desired)
00496 {
00497 if (local)
00498 return tv->GetKeyframePosition(desired);
00499
00500 VERBOSE(VB_IMPORTANT, "Should be local only query: GetKeyframePosition");
00501 return -1;
00502 }
00503
00509 void EncoderLink::FrontendReady(void)
00510 {
00511 if (local)
00512 tv->FrontendReady();
00513 else
00514 VERBOSE(VB_IMPORTANT, "Should be local only query: FrontendReady");
00515 }
00516
00525 void EncoderLink::CancelNextRecording(bool cancel)
00526 {
00527 if (local)
00528 tv->CancelNextRecording(cancel);
00529 else
00530 sock->CancelNextRecording(m_capturecardnum, cancel);
00531 }
00532
00544 void EncoderLink::SpawnLiveTV(LiveTVChain *chain, bool pip, QString startchan)
00545 {
00546 if (local)
00547 tv->SpawnLiveTV(chain, pip, startchan);
00548 else
00549 VERBOSE(VB_IMPORTANT, "Should be local only query: SpawnLiveTV");
00550 }
00551
00555 QString EncoderLink::GetChainID(void)
00556 {
00557 if (local)
00558 return tv->GetChainID();
00559
00560 VERBOSE(VB_IMPORTANT, "Should be local only query: SpawnLiveTV");
00561 return "";
00562 }
00563
00569 void EncoderLink::StopLiveTV(void)
00570 {
00571 if (local)
00572 tv->StopLiveTV();
00573 else
00574 VERBOSE(VB_IMPORTANT, "Should be local only query: StopLiveTV");
00575 }
00576
00583 void EncoderLink::PauseRecorder(void)
00584 {
00585 if (local)
00586 tv->PauseRecorder();
00587 else
00588 VERBOSE(VB_IMPORTANT, "Should be local only query: PauseRecorder");
00589 }
00590
00596 void EncoderLink::SetLiveRecording(int recording)
00597 {
00598 if (local)
00599 tv->SetLiveRecording(recording);
00600 else
00601 VERBOSE(VB_IMPORTANT, "Should be local only query: SetLiveRecording");
00602 }
00603
00607 void EncoderLink::SetNextLiveTVDir(QString dir)
00608 {
00609 if (local)
00610 tv->SetNextLiveTVDir(dir);
00611 else
00612 sock->SetNextLiveTVDir(m_capturecardnum, dir);
00613 }
00614
00620 vector<InputInfo> EncoderLink::GetFreeInputs(
00621 const vector<uint> &excluded_cardids) const
00622 {
00623 vector<InputInfo> list;
00624
00625 if (local)
00626 list = tv->GetFreeInputs(excluded_cardids);
00627 else
00628 list = sock->GetFreeInputs(m_capturecardnum, excluded_cardids);
00629
00630 return list;
00631 }
00632
00639 QString EncoderLink::GetInput(void) const
00640 {
00641 if (local)
00642 return tv->GetInput();
00643
00644 VERBOSE(VB_IMPORTANT, "Should be local only query: GetInput");
00645 return QString::null;
00646 }
00647
00658 QString EncoderLink::SetInput(QString input)
00659 {
00660 if (local)
00661 return tv->SetInput(input);
00662
00663 VERBOSE(VB_IMPORTANT, "Should be local only query: SetInput");
00664 return QString::null;
00665 }
00666
00672 void EncoderLink::ToggleChannelFavorite(void)
00673 {
00674 if (local)
00675 tv->ToggleChannelFavorite();
00676 else
00677 VERBOSE(VB_IMPORTANT, "Should be local only query: ToggleChannelFavorite");
00678 }
00679
00687 void EncoderLink::ChangeChannel(int channeldirection)
00688 {
00689 if (local)
00690 tv->ChangeChannel((ChannelChangeDirection)channeldirection);
00691 else
00692 VERBOSE(VB_IMPORTANT, "Should be local only query: ChangeChannel");
00693 }
00694
00702 void EncoderLink::SetChannel(const QString &name)
00703 {
00704 if (local)
00705 tv->SetChannel(name);
00706 else
00707 VERBOSE(VB_IMPORTANT, "Should be local only query: SetChannel");
00708 }
00709
00718 int EncoderLink::GetPictureAttribute(PictureAttribute attr)
00719 {
00720 if (!local)
00721 {
00722 VERBOSE(VB_IMPORTANT, "Should be local only query: "
00723 "GetPictureAttribute");
00724 return -1;
00725 }
00726
00727 return tv->GetPictureAttribute(attr);
00728 }
00729
00738 int EncoderLink::ChangePictureAttribute(PictureAdjustType type,
00739 PictureAttribute attr,
00740 bool direction)
00741 {
00742 if (!local)
00743 {
00744 VERBOSE(VB_IMPORTANT, "Should be local only query: "
00745 "ChangePictureAttribute");
00746 return -1;
00747 }
00748
00749 return tv->ChangePictureAttribute(type, attr, direction);
00750 }
00751
00761 bool EncoderLink::CheckChannel(const QString &name)
00762 {
00763 if (local)
00764 return tv->CheckChannel(name);
00765
00766 VERBOSE(VB_IMPORTANT, "Should be local only query: CheckChannel");
00767 return false;
00768 }
00769
00779 bool EncoderLink::ShouldSwitchToAnotherCard(const QString &channelid)
00780 {
00781 if (local)
00782 return tv->ShouldSwitchToAnotherCard(channelid);
00783
00784 VERBOSE(VB_IMPORTANT, "Should be local only query: ShouldSwitchToAnotherCard");
00785 return false;
00786 }
00787
00795 bool EncoderLink::CheckChannelPrefix(
00796 const QString &prefix,
00797 uint &is_complete_valid_channel_on_rec,
00798 bool &is_extra_char_useful,
00799 QString &needed_spacer)
00800 {
00801 if (local)
00802 {
00803 return tv->CheckChannelPrefix(
00804 prefix, is_complete_valid_channel_on_rec,
00805 is_extra_char_useful, needed_spacer);
00806 }
00807
00808 VERBOSE(VB_IMPORTANT, "Should be local only query: CheckChannelPrefix");
00809 is_complete_valid_channel_on_rec = false;
00810 is_extra_char_useful = false;
00811 needed_spacer = "";
00812 return false;
00813 }
00814
00820 void EncoderLink::GetNextProgram(int direction,
00821 QString &title, QString &subtitle,
00822 QString &desc, QString &category,
00823 QString &starttime, QString &endtime,
00824 QString &callsign, QString &iconpath,
00825 QString &channelname, QString &chanid,
00826 QString &seriesid, QString &programid)
00827 {
00828 if (local)
00829 tv->GetNextProgram(direction,
00830 title, subtitle, desc, category, starttime,
00831 endtime, callsign, iconpath, channelname, chanid,
00832 seriesid, programid);
00833 else
00834 VERBOSE(VB_IMPORTANT, "Should be local only query: GetNextProgram");
00835 }
00836
00837 bool EncoderLink::GetChannelInfo(uint &chanid, uint &sourceid,
00838 QString &callsign, QString &channum,
00839 QString &channame, QString &xmltv) const
00840 {
00841 if (!local)
00842 {
00843 VERBOSE(VB_IMPORTANT, "Should be local only query: GetChannelInfo");
00844 return false;
00845 }
00846
00847 return tv->GetChannelInfo(chanid, sourceid,
00848 callsign, channum, channame, xmltv);
00849 }
00850
00851 bool EncoderLink::SetChannelInfo(uint chanid, uint sourceid,
00852 QString oldchannum,
00853 QString callsign, QString channum,
00854 QString channame, QString xmltv)
00855 {
00856 if (!local)
00857 {
00858 VERBOSE(VB_IMPORTANT, "Should be local only query: SetChannelInfo");
00859 return false;
00860 }
00861
00862 return tv->SetChannelInfo(chanid, sourceid, oldchannum,
00863 callsign, channum, channame, xmltv);
00864 }
00865
00866