MythTV  0.26-pre
encoderlink.cpp
Go to the documentation of this file.
00001 // C++ headers
00002 #include <iostream>
00003 using namespace std;
00004 
00005 // C headers
00006 #include <unistd.h>
00007 
00008 // MythTV headers
00009 #include "mythcorecontext.h"
00010 #include "encoderlink.h"
00011 #include "playbacksock.h"
00012 #include "tv_rec.h"
00013 #include "mythmiscutil.h"
00014 #include "previewgenerator.h"
00015 #include "storagegroup.h"
00016 #include "backendutil.h"
00017 #include "compat.h"
00018 
00019 #define LOC QString("EncoderLink(%1): ").arg(m_capturecardnum)
00020 #define LOC_ERR QString("EncoderLink(%1) Error: ").arg(m_capturecardnum)
00021 
00040 EncoderLink::EncoderLink(int capturecardnum, PlaybackSock *lsock,
00041                          QString lhostname)
00042     : m_capturecardnum(capturecardnum), sock(lsock), hostname(lhostname),
00043       freeDiskSpaceKB(-1), tv(NULL), local(false), locked(false),
00044       sleepStatus(sStatus_Undefined), chanid(0)
00045 {
00046     endRecordingTime = QDateTime::currentDateTime().addDays(-2);
00047     startRecordingTime = endRecordingTime;
00048 
00049     sleepStatusTime = QDateTime::currentDateTime();
00050     lastSleepTime   = QDateTime::currentDateTime();
00051     lastWakeTime    = QDateTime::currentDateTime();
00052 
00053     if (sock)
00054         sock->UpRef();
00055 }
00056 
00060 EncoderLink::EncoderLink(int capturecardnum, TVRec *ltv)
00061     : m_capturecardnum(capturecardnum), sock(NULL),
00062       freeDiskSpaceKB(-1), tv(ltv), local(true), locked(false),
00063       sleepStatus(sStatus_Undefined), chanid(0)
00064 {
00065     endRecordingTime = QDateTime::currentDateTime().addDays(-2);
00066     startRecordingTime = endRecordingTime;
00067 
00068     sleepStatusTime = QDateTime::currentDateTime();
00069     lastSleepTime   = QDateTime::currentDateTime();
00070     lastWakeTime    = QDateTime::currentDateTime();
00071 }
00072 
00077 EncoderLink::~EncoderLink(void)
00078 {
00079     if (tv)
00080     {
00081         delete tv;
00082         tv = NULL;
00083     }
00084 }
00085 
00091 void EncoderLink::SetSocket(PlaybackSock *lsock)
00092 {
00093     if (lsock)
00094     {
00095         lsock->UpRef();
00096 
00097         if (gCoreContext->GetSettingOnHost("SleepCommand", hostname).isEmpty())
00098             SetSleepStatus(sStatus_Undefined);
00099         else
00100             SetSleepStatus(sStatus_Awake);
00101     }
00102     else
00103     {
00104         if (IsFallingAsleep())
00105             SetSleepStatus(sStatus_Asleep);
00106         else
00107             SetSleepStatus(sStatus_Undefined);
00108     }
00109 
00110     if (sock)
00111         sock->DownRef();
00112     sock = lsock;
00113 }
00114 
00118 void EncoderLink::SetSleepStatus(SleepStatus newStatus)
00119 {
00120     sleepStatus     = newStatus;
00121     sleepStatusTime = QDateTime::currentDateTime();
00122 }
00123 
00129 bool EncoderLink::IsBusy(TunedInputInfo *busy_input, int time_buffer)
00130 {
00131     if (local)
00132         return tv->IsBusy(busy_input, time_buffer);
00133 
00134     if (sock)
00135         return sock->IsBusy(m_capturecardnum, busy_input, time_buffer);
00136 
00137     return false;
00138 }
00139 
00148 bool EncoderLink::IsBusyRecording(void)
00149 {
00150     bool retval = false;
00151 
00152     TVState state = GetState();
00153 
00154     if (state == kState_RecordingOnly || state == kState_WatchingRecording ||
00155         state == kState_WatchingLiveTV)
00156     {
00157         retval = true;
00158     }
00159 
00160     return retval;
00161 }
00162 
00167 TVState EncoderLink::GetState(void)
00168 {
00169     TVState retval = kState_Error;
00170 
00171     if (!IsConnected())
00172         return retval;
00173 
00174     if (local)
00175         retval = tv->GetState();
00176     else if (sock)
00177         retval = (TVState)sock->GetEncoderState(m_capturecardnum);
00178     else
00179         LOG(VB_GENERAL, LOG_ERR, QString("Broken for card: %1")
00180             .arg(m_capturecardnum));
00181 
00182     return retval;
00183 }
00184 
00189 uint EncoderLink::GetFlags(void) const
00190 {
00191     uint retval = 0;
00192 
00193     if (!IsConnected())
00194         return retval;
00195 
00196     if (local)
00197         retval = tv->GetFlags();
00198     else if (sock)
00199         retval = sock->GetEncoderState(m_capturecardnum);
00200     else
00201         LOG(VB_GENERAL, LOG_ERR, LOC + "GetFlags failed");
00202 
00203     return retval;
00204 }
00205 
00211 bool EncoderLink::IsRecording(const ProgramInfo *rec)
00212 {
00213     return (rec->GetChanID() == chanid &&
00214             rec->GetRecordingStartTime() == startRecordingTime);
00215 }
00216 
00225 bool EncoderLink::MatchesRecording(const ProgramInfo *rec)
00226 {
00227     bool retval = false;
00228     ProgramInfo *tvrec = NULL;
00229 
00230     if (local)
00231     {
00232         while (kState_ChangingState == GetState())
00233             usleep(100);
00234 
00235         if (IsBusyRecording())
00236             tvrec = tv->GetRecording();
00237 
00238         if (tvrec)
00239         {
00240             retval = tvrec->IsSameRecording(*rec);
00241             delete tvrec;
00242         }
00243     }
00244     else
00245     {
00246         if (sock)
00247             retval = sock->EncoderIsRecording(m_capturecardnum, rec);
00248     }
00249 
00250     return retval;
00251 }
00252 
00261 void EncoderLink::RecordPending(const ProgramInfo *rec, int secsleft,
00262                                 bool hasLater)
00263 {
00264     if (local)
00265         tv->RecordPending(rec, secsleft, hasLater);
00266     else if (sock)
00267         sock->RecordPending(m_capturecardnum, rec, secsleft, hasLater);
00268 }
00269 
00275 bool EncoderLink::WouldConflict(const ProgramInfo *rec)
00276 {
00277     if (!IsConnected())
00278         return true;
00279 
00280     if (rec->GetRecordingStartTime() < endRecordingTime)
00281         return true;
00282 
00283     return false;
00284 }
00285 
00287 bool EncoderLink::CheckFile(ProgramInfo *pginfo)
00288 {
00289     if (sock)
00290         return sock->CheckFile(pginfo);
00291 
00292     pginfo->SetPathname(GetPlaybackURL(pginfo));
00293     return pginfo->IsLocal();
00294 }
00295 
00301 void EncoderLink::GetDiskSpace(QStringList &o_strlist)
00302 {
00303     if (sock)
00304         sock->GetDiskSpace(o_strlist);
00305 }
00306 
00313 long long EncoderLink::GetMaxBitrate()
00314 {
00315     if (local)
00316         return tv->GetMaxBitrate();
00317     else if (sock)
00318         return sock->GetMaxBitrate(m_capturecardnum);
00319 
00320     return -1;
00321 }
00322 
00337 int EncoderLink::SetSignalMonitoringRate(int rate, int notifyFrontend)
00338 {
00339     if (local)
00340         return tv->SetSignalMonitoringRate(rate, notifyFrontend);
00341     else if (sock)
00342         return sock->SetSignalMonitoringRate(m_capturecardnum, rate,
00343                                              notifyFrontend);
00344     return -1;
00345 }
00346 
00349 bool EncoderLink::GoToSleep(void)
00350 {
00351     if (IsLocal() || !sock)
00352         return false;
00353 
00354     lastSleepTime = QDateTime::currentDateTime();
00355 
00356     return sock->GoToSleep();
00357 }
00358 
00363 int EncoderLink::LockTuner()
00364 {
00365     if (locked)
00366         return -2;
00367 
00368     locked = true;
00369     return m_capturecardnum;
00370 }
00371 
00379 RecStatusType EncoderLink::StartRecording(const ProgramInfo *rec)
00380 {
00381     RecStatusType retval = rsAborted;
00382 
00383     endRecordingTime = rec->GetRecordingEndTime();
00384     startRecordingTime = rec->GetRecordingStartTime();
00385     chanid = rec->GetChanID();
00386 
00387     if (local)
00388         retval = tv->StartRecording(rec);
00389     else if (sock)
00390         retval = sock->StartRecording(m_capturecardnum, rec);
00391     else
00392         LOG(VB_GENERAL, LOG_ERR,
00393             QString("Wanted to start recording on recorder %1,\n\t\t\t"
00394                     "but the backend is not there anymore\n")
00395                 .arg(m_capturecardnum));
00396 
00397     if (retval != rsRecording && retval != rsTuning)
00398     {
00399         endRecordingTime = QDateTime::currentDateTime().addDays(-2);
00400         startRecordingTime = endRecordingTime;
00401         chanid = 0;
00402     }
00403 
00404     return retval;
00405 }
00406 
00407 RecStatusType EncoderLink::GetRecordingStatus(void)
00408 {
00409     RecStatusType retval = rsAborted;
00410 
00411     if (local)
00412         retval = tv->GetRecordingStatus();
00413     else if (sock)
00414         retval = sock->GetRecordingStatus(m_capturecardnum);
00415     else
00416         LOG(VB_GENERAL, LOG_ERR,
00417             QString("Wanted to get status on recorder %1,\n\t\t\t"
00418                     "but the backend is not there anymore\n")
00419                 .arg(m_capturecardnum));
00420 
00421     if (retval != rsRecording && retval != rsTuning)
00422     {
00423         endRecordingTime = QDateTime::currentDateTime().addDays(-2);
00424         startRecordingTime = endRecordingTime;
00425         chanid = 0;
00426     }
00427 
00428     return retval;
00429 }
00430 
00437 ProgramInfo *EncoderLink::GetRecording(void)
00438 {
00439     ProgramInfo *info = NULL;
00440 
00441     if (local)
00442         info = tv->GetRecording();
00443     else if (sock)
00444         info = sock->GetRecording(m_capturecardnum);
00445 
00446     return info;
00447 }
00448 
00454 void EncoderLink::StopRecording(bool killFile)
00455 {
00456     endRecordingTime = QDateTime::currentDateTime().addDays(-2);
00457     startRecordingTime = endRecordingTime;
00458     chanid = 0;
00459 
00460     if (local)
00461     {
00462         tv->StopRecording(killFile);
00463         return;
00464     }
00465 }
00466 
00472 void EncoderLink::FinishRecording(void)
00473 {
00474     if (local)
00475     {
00476         tv->FinishRecording();
00477         return;
00478     }
00479     else
00480     {
00481         endRecordingTime = QDateTime::currentDateTime().addDays(-2);
00482     }
00483 }
00484 
00490 bool EncoderLink::IsReallyRecording(void)
00491 {
00492     if (local)
00493         return tv->IsReallyRecording();
00494 
00495     LOG(VB_GENERAL, LOG_ERR, "Should be local only query: IsReallyRecording");
00496     return false;
00497 }
00498 
00506 float EncoderLink::GetFramerate(void)
00507 {
00508     if (local)
00509         return tv->GetFramerate();
00510 
00511     LOG(VB_GENERAL, LOG_ERR, "Should be local only query: GetFramerate");
00512     return -1;
00513 }
00514 
00522 long long EncoderLink::GetFramesWritten(void)
00523 {
00524     if (local)
00525         return tv->GetFramesWritten();
00526 
00527     LOG(VB_GENERAL, LOG_ERR, "Should be local only query: GetFramesWritten");
00528     return -1;
00529 }
00530 
00537 long long EncoderLink::GetFilePosition(void)
00538 {
00539     if (local)
00540         return tv->GetFilePosition();
00541 
00542     LOG(VB_GENERAL, LOG_ERR, "Should be local only query: GetFilePosition");
00543     return -1;
00544 }
00545 
00552 int64_t EncoderLink::GetKeyframePosition(uint64_t desired)
00553 {
00554     if (local)
00555         return tv->GetKeyframePosition(desired);
00556 
00557     LOG(VB_GENERAL, LOG_ERR, "Should be local only query: GetKeyframePosition");
00558     return -1;
00559 }
00560 
00561 bool EncoderLink::GetKeyframePositions(
00562     int64_t start, int64_t end, frm_pos_map_t &map)
00563 {
00564     if (!local)
00565     {
00566         LOG(VB_GENERAL, LOG_ERR,
00567             "Should be local only query: GetKeyframePositions");
00568         return false;
00569     }
00570 
00571     return tv->GetKeyframePositions(start, end, map);
00572 }
00573 
00579 void EncoderLink::FrontendReady(void)
00580 {
00581     if (local)
00582         tv->FrontendReady();
00583     else
00584         LOG(VB_GENERAL, LOG_ERR, "Should be local only query: FrontendReady");
00585 }
00586 
00595 void EncoderLink::CancelNextRecording(bool cancel)
00596 {
00597     if (local)
00598         tv->CancelNextRecording(cancel);
00599     else
00600         sock->CancelNextRecording(m_capturecardnum, cancel);
00601 }
00602 
00614 void EncoderLink::SpawnLiveTV(LiveTVChain *chain, bool pip, QString startchan)
00615 {
00616     if (local)
00617         tv->SpawnLiveTV(chain, pip, startchan);
00618     else
00619         LOG(VB_GENERAL, LOG_ERR, "Should be local only query: SpawnLiveTV");
00620 }
00621 
00625 QString EncoderLink::GetChainID(void)
00626 {
00627     if (local)
00628         return tv->GetChainID();
00629 
00630     LOG(VB_GENERAL, LOG_ERR, "Should be local only query: SpawnLiveTV");
00631     return "";
00632 }
00633 
00639 void EncoderLink::StopLiveTV(void)
00640 {
00641     if (local)
00642         tv->StopLiveTV();
00643     else
00644         LOG(VB_GENERAL, LOG_ERR, "Should be local only query: StopLiveTV");
00645 }
00646 
00653 void EncoderLink::PauseRecorder(void)
00654 {
00655     if (local)
00656         tv->PauseRecorder();
00657     else
00658         LOG(VB_GENERAL, LOG_ERR, "Should be local only query: PauseRecorder");
00659 }
00660 
00666 void EncoderLink::SetLiveRecording(int recording)
00667 {
00668     if (local)
00669         tv->SetLiveRecording(recording);
00670     else
00671         LOG(VB_GENERAL, LOG_ERR,
00672             "Should be local only query: SetLiveRecording");
00673 }
00674 
00678 void EncoderLink::SetNextLiveTVDir(QString dir)
00679 {
00680     if (local)
00681         tv->SetNextLiveTVDir(dir);
00682     else
00683         sock->SetNextLiveTVDir(m_capturecardnum, dir);
00684 }
00685 
00691 vector<InputInfo> EncoderLink::GetFreeInputs(
00692     const vector<uint> &excluded_cardids) const
00693 {
00694     vector<InputInfo> list;
00695 
00696     if (local)
00697         list = tv->GetFreeInputs(excluded_cardids);
00698     else
00699         list = sock->GetFreeInputs(m_capturecardnum, excluded_cardids);
00700 
00701     return list;
00702 }
00703 
00710 QString EncoderLink::GetInput(void) const
00711 {
00712     if (local)
00713         return tv->GetInput();
00714 
00715     LOG(VB_GENERAL, LOG_ERR, "Should be local only query: GetInput");
00716     return QString();
00717 }
00718 
00729 QString EncoderLink::SetInput(QString input)
00730 {
00731     if (local)
00732         return tv->SetInput(input);
00733 
00734     LOG(VB_GENERAL, LOG_ERR, "Should be local only query: SetInput");
00735     return QString();
00736 }
00737 
00743 void EncoderLink::ToggleChannelFavorite(QString changroup)
00744 {
00745     if (local)
00746         tv->ToggleChannelFavorite(changroup);
00747     else
00748         LOG(VB_GENERAL, LOG_ERR,
00749             "Should be local only query: ToggleChannelFavorite");
00750 }
00751 
00758 void EncoderLink::ChangeChannel(ChannelChangeDirection channeldirection)
00759 {
00760     if (local)
00761         tv->ChangeChannel(channeldirection);
00762     else
00763         LOG(VB_GENERAL, LOG_ERR, "Should be local only query: ChangeChannel");
00764 }
00765 
00773 void EncoderLink::SetChannel(const QString &name)
00774 {
00775     if (local)
00776         tv->SetChannel(name);
00777     else
00778         LOG(VB_GENERAL, LOG_ERR, "Should be local only query: SetChannel");
00779 }
00780 
00789 int EncoderLink::GetPictureAttribute(PictureAttribute attr)
00790 {
00791     if (!local)
00792     {
00793         LOG(VB_GENERAL, LOG_ERR,
00794             "Should be local only query: GetPictureAttribute");
00795         return -1;
00796     }
00797 
00798     return tv->GetPictureAttribute(attr);
00799 }
00800 
00809 int EncoderLink::ChangePictureAttribute(PictureAdjustType type,
00810                                         PictureAttribute  attr,
00811                                         bool              direction)
00812 {
00813     if (!local)
00814     {
00815         LOG(VB_GENERAL, LOG_ERR,
00816             "Should be local only query: ChangePictureAttribute");
00817         return -1;
00818     }
00819 
00820     return tv->ChangePictureAttribute(type, attr, direction);
00821 }
00822 
00832 bool EncoderLink::CheckChannel(const QString &name)
00833 {
00834     if (local)
00835         return tv->CheckChannel(name);
00836 
00837     LOG(VB_GENERAL, LOG_ERR, "Should be local only query: CheckChannel");
00838     return false;
00839 }
00840 
00850 bool EncoderLink::ShouldSwitchToAnotherCard(const QString &channelid)
00851 {
00852     if (local)
00853         return tv->ShouldSwitchToAnotherCard(channelid);
00854 
00855     LOG(VB_GENERAL, LOG_ERR,
00856         "Should be local only query: ShouldSwitchToAnotherCard");
00857     return false;
00858 }
00859 
00867 bool EncoderLink::CheckChannelPrefix(
00868     const QString &prefix,
00869     uint          &is_complete_valid_channel_on_rec,
00870     bool          &is_extra_char_useful,
00871     QString       &needed_spacer)
00872 {
00873     if (local)
00874     {
00875         return tv->CheckChannelPrefix(
00876             prefix, is_complete_valid_channel_on_rec,
00877             is_extra_char_useful, needed_spacer);
00878     }
00879 
00880     LOG(VB_GENERAL, LOG_ERR, "Should be local only query: CheckChannelPrefix");
00881     is_complete_valid_channel_on_rec = false;
00882     is_extra_char_useful             = false;
00883     needed_spacer                    = "";
00884     return false;
00885 }
00886 
00892 void EncoderLink::GetNextProgram(BrowseDirection direction,
00893                                  QString &title,       QString &subtitle,
00894                                  QString &desc,        QString &category,
00895                                  QString &starttime,   QString &endtime,
00896                                  QString &callsign,    QString &iconpath,
00897                                  QString &channelname, uint    &_chanid,
00898                                  QString &seriesid,    QString &programid)
00899 {
00900     if (local)
00901     {
00902         tv->GetNextProgram(direction,
00903                            title, subtitle, desc, category, starttime,
00904                            endtime, callsign, iconpath, channelname,
00905                            _chanid, seriesid, programid);
00906     }
00907     else
00908         LOG(VB_GENERAL, LOG_ERR, "Should be local only query: GetNextProgram");
00909 }
00910 
00911 bool EncoderLink::GetChannelInfo(uint &chanid, uint &sourceid,
00912                                  QString &callsign, QString &channum,
00913                                  QString &channame, QString &xmltv) const
00914 {
00915     if (!local)
00916     {
00917         LOG(VB_GENERAL, LOG_ERR, "Should be local only query: GetChannelInfo");
00918         return false;
00919     }
00920 
00921     return tv->GetChannelInfo(chanid, sourceid,
00922                               callsign, channum, channame, xmltv);
00923 }
00924 
00925 bool EncoderLink::SetChannelInfo(uint chanid, uint sourceid,
00926                                  QString oldchannum,
00927                                  QString callsign, QString channum,
00928                                  QString channame, QString xmltv)
00929 {
00930     if (!local)
00931     {
00932         LOG(VB_GENERAL, LOG_ERR, "Should be local only query: SetChannelInfo");
00933         return false;
00934     }
00935 
00936     return tv->SetChannelInfo(chanid, sourceid, oldchannum,
00937                               callsign, channum, channame, xmltv);
00938 }
00939 
00940 /* vim: set expandtab tabstop=4 shiftwidth=4: */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends