void cXVDRServer::Action(void) { fd_set fds; struct timeval tv; cTimeMs channelReloadTimer; bool channelReloadTrigger = false; SetPriority(19); // get initial state of the recordings int recState = -1; Recordings.StateChanged(recState); // get initial state of the timers int timerState = -1; Timers.Modified(timerState); while (Running()) { FD_ZERO(&fds); FD_SET(m_ServerFD, &fds); tv.tv_sec = 0; tv.tv_usec = 250*1000; int r = select(m_ServerFD + 1, &fds, NULL, NULL, &tv); if (r == -1) { ERRORLOG("failed during select"); continue; } if (r == 0) { // remove disconnected clients for (ClientList::iterator i = m_clients.begin(); i != m_clients.end();) { if (!(*i)->Active()) { INFOLOG("Client with ID %u seems to be disconnected, removing from client list", (*i)->GetID()); delete (*i); i = m_clients.erase(i); } else { i++; } } // trigger clients to reload the modified channel list if(m_clients.size() > 0) { Channels.Lock(false); if(Channels.Modified() != 0) { channelReloadTrigger = true; channelReloadTimer.Set(0); } if(channelReloadTrigger && channelReloadTimer.Elapsed() >= 10*1000) { INFOLOG("Checking for channel updates ..."); for (ClientList::iterator i = m_clients.begin(); i != m_clients.end(); i++) (*i)->ChannelChange(); channelReloadTrigger = false; INFOLOG("Done."); } Channels.Unlock(); } // reset inactivity timeout as long as there are clients connected if(m_clients.size() > 0) { ShutdownHandler.SetUserInactiveTimeout(); } // update recordings if(Recordings.StateChanged(recState)) { INFOLOG("Recordings state changed (%i)", recState); INFOLOG("Requesting clients to reload recordings list"); for (ClientList::iterator i = m_clients.begin(); i != m_clients.end(); i++) (*i)->RecordingsChange(); } // update timers if(Timers.Modified(timerState)) { INFOLOG("Timers state changed (%i)", timerState); INFOLOG("Requesting clients to reload timers"); for (ClientList::iterator i = m_clients.begin(); i != m_clients.end(); i++) { (*i)->TimerChange(); } } continue; } int fd = accept(m_ServerFD, 0, 0); if (fd >= 0) { NewClientConnected(fd); } else { ERRORLOG("accept failed"); } } return; }
void cHTSPData::Action() { XBMC->Log(LOG_DEBUG, "%s - starting", __FUNCTION__); htsmsg_t* msg; if(!m_session.SendEnableAsync()) { XBMC->Log(LOG_ERROR, "%s - couldn't send EnableAsync().", __FUNCTION__); m_started.Signal(); return; } while (IsConnected() && Running()) { if((msg = m_session.ReadMessage()) == NULL) break; uint32_t seq; if(htsmsg_get_u32(msg, "seq", &seq) == 0) { CMD_LOCK; SMessages::iterator it = m_queue.find(seq); if(it != m_queue.end()) { it->second.msg = msg; it->second.event->Signal(); continue; } } const char* method; if((method = htsmsg_get_str(msg, "method")) == NULL) { htsmsg_destroy(msg); continue; } CMD_LOCK; if (strstr(method, "channelAdd")) cHTSPSession::ParseChannelUpdate(msg, m_channels); else if(strstr(method, "channelUpdate")) cHTSPSession::ParseChannelUpdate(msg, m_channels); else if(strstr(method, "channelDelete")) cHTSPSession::ParseChannelRemove(msg, m_channels); else if(strstr(method, "tagAdd")) cHTSPSession::ParseTagUpdate(msg, m_tags); else if(strstr(method, "tagUpdate")) cHTSPSession::ParseTagUpdate(msg, m_tags); else if(strstr(method, "tagDelete")) cHTSPSession::ParseTagRemove(msg, m_tags); else if(strstr(method, "initialSyncCompleted")) m_started.Signal(); else if(strstr(method, "dvrEntryAdd")) cHTSPSession::ParseDVREntryUpdate(msg, m_recordings, g_bShowTimerNotifications && m_session.SendNotifications()); else if(strstr(method, "dvrEntryUpdate")) cHTSPSession::ParseDVREntryUpdate(msg, m_recordings, g_bShowTimerNotifications && m_session.SendNotifications()); else if(strstr(method, "dvrEntryDelete")) cHTSPSession::ParseDVREntryDelete(msg, m_recordings, g_bShowTimerNotifications && m_session.SendNotifications()); else XBMC->Log(LOG_DEBUG, "%s - Unmapped action recieved '%s'", __FUNCTION__, method); htsmsg_destroy(msg); } m_started.Signal(); XBMC->Log(LOG_DEBUG, "%s - exiting", __FUNCTION__); }
bool cRecorder::NextFile(void) { if (recordFile && frameDetector->IndependentFrame()) { // every file shall start with an independent frame #ifdef USE_HARDLINKCUTTER if (fileSize > fileName->MaxFileSize() || RunningLowOnDiskSpace()) { #else if (fileSize > MEGABYTE(off_t(Setup.MaxVideoFileSize)) || RunningLowOnDiskSpace()) { #endif /* HARDLINKCUTTER */ recordFile = fileName->NextFile(); fileSize = 0; } } return recordFile != NULL; } void cRecorder::Activate(bool On) { if (On) Start(); else Cancel(3); } void cRecorder::Receive(uchar *Data, int Length) { if (Running()) { int p = ringBuffer->Put(Data, Length); if (p != Length && Running()) ringBuffer->ReportOverflow(Length - p); } } void cRecorder::Action(void) { time_t t = time(NULL); bool InfoWritten = false; bool FirstIframeSeen = false; #ifdef USE_LIVEBUFFER double fps = DEFAULTFRAMESPERSECOND; #endif /*USE_LIVEBUFFER*/ while (Running()) { int r; uchar *b = ringBuffer->Get(r); if (b) { int Count = frameDetector->Analyze(b, r); if (Count) { if (!Running() && frameDetector->IndependentFrame()) // finish the recording before the next independent frame break; if (frameDetector->Synced()) { #ifdef USE_LIVEBUFFER if(index && (frameDetector->FramesPerSecond() != fps)) { fps = frameDetector->FramesPerSecond(); index->SetFramesPerSecond(fps); } // if #endif /*USE_LIVEBUFFER*/ if (!InfoWritten) { cRecordingInfo RecordingInfo(recordingName); if (RecordingInfo.Read()) { if (frameDetector->FramesPerSecond() > 0 && DoubleEqual(RecordingInfo.FramesPerSecond(), DEFAULTFRAMESPERSECOND) && !DoubleEqual(RecordingInfo.FramesPerSecond(), frameDetector->FramesPerSecond())) { RecordingInfo.SetFramesPerSecond(frameDetector->FramesPerSecond()); RecordingInfo.Write(); Recordings.UpdateByName(recordingName); } } InfoWritten = true; } /* if (frameDetector->NewPayload()) { // We're at the first TS packet of a new payload... if (Buffering) esyslog("ERROR: encountered new payload while buffering - dropping some data!"); if (!frameDetector->NewFrame()) { // ...but the frame type is yet unknown, so we need to buffer packets until we see the frame type if (!Buffer) { dsyslog("frame type not in first packet of payload - buffering"); if (!(Buffer = MALLOC(uchar, BUFFERSIZE))) { esyslog("ERROR: can't allocate frame type buffer"); break; } } BufferIndex = 0; Buffering = true; } } else if (frameDetector->NewFrame()) // now we know the frame type, so stop buffering Buffering = false; if (Buffering) { if (BufferIndex + Count <= BUFFERSIZE) { memcpy(Buffer + BufferIndex, b, Count); BufferIndex += Count; } else esyslog("ERROR: too many bytes for frame type buffer (%d > %d) - dropped %d bytes", BufferIndex + Count, int(BUFFERSIZE), Count); } else if (FirstIframeSeen || frameDetector->IndependentFrame()) { */ #ifdef USE_LIVEBUFFER if(!FirstIframeSeen) FillInitialData(b, r); #endif /*USE_LIVEBUFFER*/ if (FirstIframeSeen || frameDetector->IndependentFrame()) { FirstIframeSeen = true; // start recording with the first I-frame if (!NextFile()) break; if (index && frameDetector->NewFrame()) index->Write(frameDetector->IndependentFrame(), fileName->Number(), fileSize); if (frameDetector->IndependentFrame()) { recordFile->Write(patPmtGenerator.GetPat(), TS_SIZE); fileSize += TS_SIZE; int Index = 0; while (uchar *pmt = patPmtGenerator.GetPmt(Index)) { recordFile->Write(pmt, TS_SIZE); fileSize += TS_SIZE; } } if (recordFile->Write(b, Count) < 0) { LOG_ERROR_STR(fileName->Name()); break; } fileSize += Count; t = time(NULL); } } ringBuffer->Del(Count); } } #ifdef USE_LIVEBUFFER if (handleError && (time(NULL) - t > MAXBROKENTIMEOUT)) { #else if (time(NULL) - t > MAXBROKENTIMEOUT) { #endif #if REELVDR Skins.QueueMessage(mtError, tr("can't record - check your configuration")); #else esyslog("ERROR: video data stream broken. Requesting Emergency Exit."); ShutdownHandler.RequestEmergencyExit(); #endif /*REELVDR*/ t = time(NULL); } } }
void cPluginMcli::Action (void) { netceiver_info_list_t *nc_list = nc_get_list (); // printf ("Looking for netceivers out there....\n"); bool channel_switch_ok = false; #define NOTIFY_CAM_CHANGE 1 #ifdef NOTIFY_CAM_CHANGE int cam_stats[CAM_POOL_MAX] = { 0 }; char menu_strings[CAM_POOL_MAX][MAX_MENU_STR_LEN]; bool first_run = true; for (int i = 0; i < CAM_POOL_MAX; i++) menu_strings[i][0] = '\0'; #endif /** lets inform vdr and its plugins if TunerChange event happened */ bool netCVChanged; while (Running ()) { netCVChanged = false; Lock (); if(!InitMcli()) { usleep (250 * 1000); continue; } nc_lock_list (); time_t now = time (NULL); bool tpa = false; for (int n = 0; n < nc_list->nci_num; n++) { netceiver_info_t *nci = nc_list->nci + n; //printf("cPluginMcli::Action: NCI Cam_Num: %d\n", nci->cam_num); if ((now - nci->lastseen) > MCLI_DEVICE_TIMEOUT) { if(CAMPoolDel(nci->uuid)) { printf ("Mcli::%s: Remove CAMs from NetCeiver: [%s]\n", __FUNCTION__, nci->uuid); netCVChanged = true; } } else { int cpa = CAMPoolAdd(nci); if(cpa==1) { printf ("Mcli::%s: Add CAMs from NetCeiver: [%s] -> %d\n", __FUNCTION__, nci->uuid, cpa); netCVChanged = true; } } if (netCVChanged) { for(int j = 0; j < nci->cam_num; j++) { const char *camstate; const char *cammode; switch(nci->cam[j].status) { case DVBCA_CAMSTATE_MISSING: camstate="MISSING"; break; case DVBCA_CAMSTATE_INITIALISING: camstate="INIT"; break; case DVBCA_CAMSTATE_READY: camstate="READY"; break; } switch(nci->cam[j].flags) { case CA_SINGLE: cammode="CA_SINGLE"; break; case CA_MULTI_SID: cammode="CA_MULTI_SID"; break; case CA_MULTI_TRANSPONDER: cammode="CA_MULTI_TRANSPONDER"; break; } if (nci->cam[j].status != DVBCA_CAMSTATE_MISSING) { printf("Mcli::%s: Slot:%d CamModule '%s' State:%s Mode:%s\n", __FUNCTION__, j, nci->cam[j].menu_string, camstate, cammode); } else { printf("Mcli::%s: Slot:%d CamModule State:%s\n", __FUNCTION__, j, camstate); } } } #if NOTIFY_CAM_CHANGE if (n == 0) { for(int j = 0; j < nci->cam_num && j < CAM_POOL_MAX; j++) { if (nci->cam[j].status != cam_stats[j]) { char buf[64]; if (nci->cam[j].status) { if(nci->cam[j].status == 2 && !first_run) { snprintf(buf, 64, tr("Module '%s' ready"), nci->cam[j].menu_string); Skins.QueueMessage(mtInfo, buf); } cam_stats[j] = nci->cam[j].status; strncpy(menu_strings[j], nci->cam[j].menu_string, MAX_MENU_STR_LEN); } else if (nci->cam[j].status == 0) { cam_stats[j] = nci->cam[j].status; if (!first_run) { snprintf(buf, 64, tr("Module '%s' removed"), (char*)menu_strings[j]); Skins.QueueMessage(mtInfo, buf); } menu_strings[j][0] = '\0'; } } } first_run = false; } #endif for (int i = 0; i < nci->tuner_num; i++) { tuner_pool_t *t = TunerFindByUUID (nci->tuner[i].uuid); if (((now - nci->lastseen) > MCLI_DEVICE_TIMEOUT) || (nci->tuner[i].preference < 0) || !strlen (nci->tuner[i].uuid)) { if (t) { int pos=TunerPoolDel(t); printf ("Mcli::%s: Remove Tuner %s [%s] @ %d\n", __FUNCTION__, nci->tuner[i].fe_info.name, nci->tuner[i].uuid, pos); //isyslog ("cPluginMcli::Action: Remove Tuner %s [%s] @ %d", nci->tuner[i].fe_info.name, nci->tuner[i].uuid, pos); netCVChanged = true; } continue; } if (!t) { tpa=TunerPoolAdd(nci->tuner+i); printf ("Mcli::%s: Add Tuner: %s [%s], Type %d @ %d\n", __FUNCTION__, nci->tuner[i].fe_info.name, nci->tuner[i].uuid, nci->tuner[i].fe_info.type, tpa); //isyslog ("cPluginMcli::Action: Add Tuner: %s [%s], Type %d @ %d", nci->tuner[i].fe_info.name, nci->tuner[i].uuid, nci->tuner[i].fe_info.type, tpa); netCVChanged = true; } } } nc_unlock_list (); Unlock (); UpdateDevices(); if (netCVChanged) { //RC: disabled, see mantis #995 //cPluginManager::CallAllServices("NetCeiver changed"); } //TB: reelvdr itself tunes if the first tuner appears, don't do it twice #if 1 //ndef REELVDR if (tpa) { if (!channel_switch_ok) { // the first tuner that was found, so make VDR retune to the channel it wants... cChannel *ch = Channels.GetByNumber (cDevice::CurrentChannel ()); if (ch) { printf("Mcli::%s: cDevice::PrimaryDevice (%p)\n", __FUNCTION__, cDevice::PrimaryDevice ()); channel_switch_ok = cDevice::PrimaryDevice ()->SwitchChannel (ch, true); } } } else { channel_switch_ok = 0; } #endif #ifdef TEMP_DISABLE_DEVICE TempDisableDevices(); #endif usleep (250 * 1000); } }
void cTrueColorDemo::Action(void) { cPixmap *FadeInPixmap = NULL; cPixmap *FadeOutPixmap = NULL; cPixmap *MovePixmap = NULL; cPixmap *NextPixmap = NULL; cPixmap *TilePixmap = NULL; cPixmap *ScrollPixmap = NULL; cPixmap *AnimPixmap = NULL; cFont *OsdFont = cFont::CreateFont(Setup.FontOsd, Setup.FontOsdSize); cFont *SmlFont = cFont::CreateFont(Setup.FontSml, Setup.FontSmlSize); cFont *LrgFont = cFont::CreateFont(Setup.FontOsd, osd->Height() / 10); int FrameTime = 40; // ms int FadeTime = 1000; // ms int MoveTime = 4000; // ms int TileTime = 6000; // ms int ScrollWaitTime = 1000; // ms int ScrollLineTime = 200; // ms int ScrollTotalTime = 8000; // ms uint64_t Start = 0; uint64_t ScrollStartTime = 0; int ScrollLineNumber = 0; cPoint MoveStart, MoveEnd; cPoint TileStart, TileEnd; cPoint ScrollStart, ScrollEnd; int Line = osd->Height() / 20; int StartLine = Line; cPoint OldCursor; int State = 0; while (Running()) { cPixmap::Lock(); bool Animated = false; uint64_t Now = cTimeMs::Now(); if (FadeInPixmap) { double t = min(double(Now - Start) / FadeTime, 1.0); int Alpha = t * ALPHA_OPAQUE; FadeInPixmap->SetAlpha(Alpha); if (t >= 1) FadeInPixmap = NULL; Animated = true; } if (FadeOutPixmap) { double t = min(double(Now - Start) / FadeTime, 1.0); int Alpha = ALPHA_OPAQUE - t * ALPHA_OPAQUE; FadeOutPixmap->SetAlpha(Alpha); if (t >= 1) FadeOutPixmap = NULL; Animated = true; } if (MovePixmap) { double t = min(double(Now - Start) / MoveTime, 1.0); int x = MoveStart.X() + t * (MoveEnd.X() - MoveStart.X()); int y = MoveStart.Y() + t * (MoveEnd.Y() - MoveStart.Y()); cRect r = MovePixmap->ViewPort(); r.SetPoint(x, y); MovePixmap->SetViewPort(r); if (t >= 1) MovePixmap = NULL; Animated = true; } if (TilePixmap) { double t = min(double(Now - Start) / TileTime, 1.0); int x = TileStart.X() + t * (TileEnd.X() - TileStart.X()); int y = TileStart.Y() + t * (TileEnd.Y() - TileStart.Y()); TilePixmap->SetDrawPortPoint(cPoint(x, y)); if (t >= 1) { destroyablePixmap = TilePixmap; TilePixmap = NULL; } Animated = true; } if (ScrollPixmap) { if (int(Now - Start) > ScrollWaitTime) { if (ScrollStartTime) { double t = min(double(Now - ScrollStartTime) / ScrollLineTime, 1.0); int x = ScrollStart.X() + t * (ScrollEnd.X() - ScrollStart.X()); int y = ScrollStart.Y() + t * (ScrollEnd.Y() - ScrollStart.Y()); ScrollPixmap->SetDrawPortPoint(cPoint(x, y)); if (t >= 1) { if (int(Now - Start) < ScrollTotalTime) { cRect r = ScrollPixmap->DrawPort(); r.SetPoint(-r.X(), -r.Y()); ScrollPixmap->Pan(cPoint(0, 0), r); cString s = cString::sprintf("Line %d", ++ScrollLineNumber); ScrollPixmap->DrawRectangle(cRect(0, ScrollPixmap->ViewPort().Height(), ScrollPixmap->DrawPort().Width(), ScrollPixmap->DrawPort().Height()), clrTransparent); ScrollPixmap->DrawText(cPoint(0, ScrollPixmap->ViewPort().Height()), s, clrYellow, clrTransparent, OsdFont); ScrollStartTime = Now; } else { FadeOutPixmap = ScrollPixmap; ScrollPixmap = NULL; Start = cTimeMs::Now(); } } } else ScrollStartTime = Now; } Animated = true; } if (AnimPixmap) { int d = AnimPixmap->ViewPort().Height(); if (clockwise) d = -d; cPoint p = AnimPixmap->DrawPort().Point().Shifted(0, d); if (clockwise && p.Y() <= -AnimPixmap->DrawPort().Height()) p.SetY(0); else if (!clockwise && p.Y() > 0) p.SetY(-(AnimPixmap->DrawPort().Height() - AnimPixmap->ViewPort().Height())); AnimPixmap->SetDrawPortPoint(p); } if (!Animated) { switch (State) { case 0: { FadeInPixmap = CreateTextPixmap("VDR", Line, 1, clrYellow, clrTransparent, LrgFont); if (FadeInPixmap) Line += FadeInPixmap->DrawPort().Height(); Start = cTimeMs::Now(); State++; } break; case 1: { FadeInPixmap = CreateTextPixmap("Video Disk Recorder", Line, 3, clrYellow, clrTransparent, OsdFont); if (FadeInPixmap) Line += FadeInPixmap->DrawPort().Height(); Start = cTimeMs::Now(); State++; } break; case 2: { FadeInPixmap = CreateTextPixmap("True Color OSD Demo", Line, 1, clrYellow, clrTransparent, OsdFont); if (FadeInPixmap) Line += FadeInPixmap->DrawPort().Height(); Start = cTimeMs::Now(); State++; } break; case 3: { NextPixmap = CreateTextPixmap("Millions of colors", Line, 1, clrYellow, clrTransparent, LrgFont); if (NextPixmap) { FadeInPixmap = NextPixmap; Start = cTimeMs::Now(); StartLine = Line; Line += NextPixmap->DrawPort().Height(); } State++; } break; case 4: { Line += osd->Height() / 10; int w = osd->Width() / 2; int h = osd->Height() - Line - osd->Height() / 10; cImage Image(cSize(w, h)); for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) Image.SetPixel(cPoint(x, y), HsvToColor(360 * double(x) / w, 1 - double(y) / h, 1) | 0xDF000000); } if (cPixmap *Pixmap = osd->CreatePixmap(2, cRect((osd->Width() - w) / 2, Line, w, h))) { Pixmap->DrawImage(cPoint(0, 0), Image); toggleablePixmap = Pixmap; } State++; } break; case 5: { if (NextPixmap) { MovePixmap = NextPixmap; MoveStart = MovePixmap->ViewPort().Point(); MoveEnd.Set(osd->Width() - MovePixmap->ViewPort().Width(), osd->Height() - MovePixmap->ViewPort().Height()); Start = cTimeMs::Now(); } State++; } break; case 6: { TilePixmap = CreateTextPixmap("Tiled Pixmaps", StartLine, 1, clrRed, clrWhite, OsdFont); if (TilePixmap) { TilePixmap->SetViewPort(TilePixmap->ViewPort().Grown(TilePixmap->DrawPort().Width(), TilePixmap->DrawPort().Height())); TilePixmap->SetAlpha(200); TilePixmap->SetTile(true); TileStart = TilePixmap->DrawPort().Point(); TileEnd = TileStart.Shifted(TilePixmap->ViewPort().Width(), TilePixmap->ViewPort().Height()); MovePixmap = TilePixmap; MoveStart = MovePixmap->ViewPort().Point(); MoveEnd.Set(10, osd->Height() - MovePixmap->ViewPort().Height() - 10); Start = cTimeMs::Now(); } State++; } break; case 7: { const char *Text = "Scrolling Pixmaps"; int w = OsdFont->Width(Text); int h = OsdFont->Height(); if (cPixmap *Pixmap = osd->CreatePixmap(2, cRect((osd->Width() - w) / 2, StartLine, w, 2 * h), cRect(0, 0, w, 3 * h))) { Pixmap->Clear(); Pixmap->DrawText(cPoint(0, 0), Text, clrYellow, clrTransparent, OsdFont); cString s = cString::sprintf("Line %d", ++ScrollLineNumber); Pixmap->DrawText(cPoint(0, Pixmap->ViewPort().Height()), s, clrYellow, clrTransparent, OsdFont); ScrollPixmap = Pixmap; ScrollStart.Set(0, 0); ScrollEnd.Set(0, -h); Start = cTimeMs::Now(); } State++; } break; case 8: { const char *Text = "Animation"; const int Size = SmlFont->Width(Text) + 10; const int NumDots = 12; const int AnimFrames = NumDots; // Temporarily using pixmap layer 0 to have the text alpha blended: AnimPixmap = osd->CreatePixmap(0, cRect((osd->Width() - Size) / 2, StartLine, Size, Size), cRect(0, 0, Size, Size * AnimFrames)); if (AnimPixmap) { AnimPixmap->SetAlpha(0); AnimPixmap->Clear(); const int Diameter = Size / 5; int xc = Size / 2 - Diameter / 2; for (int Frame = 0; Frame < AnimFrames; Frame++) { AnimPixmap->DrawEllipse(cRect(0, Frame * Size, Size, Size), 0xDDFFFFFF); int yc = Frame * Size + Size / 2 - Diameter / 2; int Color = 0xFF; int Delta = Color / NumDots / 3; for (int a = 0; a < NumDots; a++) { double t = 2 * M_PI * (Frame + a) / NumDots; int x = xc + ((Size - Diameter) / 2 - 5) * cos(t); int y = yc + ((Size - Diameter) / 2 - 5) * sin(t); AnimPixmap->DrawEllipse(cRect(x, y, Diameter, Diameter), ArgbToColor(0xFF, Color, Color, Color)); Color -= Delta; } AnimPixmap->DrawText(cPoint(0, Frame * Size), Text, clrBlack, clrTransparent, SmlFont, Size, Size, taCenter); } AnimPixmap->SetLayer(3); // now setting the actual pixmap layer FadeInPixmap = AnimPixmap; LOCK_THREAD; OldCursor = cursor = AnimPixmap->ViewPort().Point(); cursorLimits.Set(0, 0, osd->Width(), osd->Height()); cursorLimits.SetRight(cursorLimits.Right() - Size); cursorLimits.SetBottom(cursorLimits.Bottom() - Size); cursorLimits.Grow(-10, -10); Start = cTimeMs::Now(); } State++; } break; case 9: { LOCK_THREAD; if (cursor != OldCursor) { MovePixmap = AnimPixmap; MoveStart = MovePixmap->ViewPort().Point(); MoveEnd = OldCursor = cursor; MoveTime = 500; Start = cTimeMs::Now(); } } break; } } osd->Flush(); cPixmap::Unlock(); int Delta = cTimeMs::Now() - Now; if (Delta < FrameTime) cCondWait::SleepMs(FrameTime - Delta); } destroyablePixmap = NULL; toggleablePixmap = NULL; delete OsdFont; delete SmlFont; delete LrgFont; }
void cVNSIStatus::Action(void) { cTimeMs chanTimer(0); cTimeMs epgTimer(0); // get initial state of the recordings #if VDRVERSNUM >= 20301 cStateKey chanState; const cChannels *channels = cChannels::GetChannelsRead(chanState); chanState.Remove(false); #endif // get initial state of the recordings #if VDRVERSNUM >= 20301 cStateKey recState; const cRecordings *recordings = cRecordings::GetRecordingsRead(recState); recState.Remove(false); #else int recState = -1; Recordings.StateChanged(recState); #endif // get initial state of the timers #if VDRVERSNUM >= 20301 cStateKey timerState; const cTimers *timers = cTimers::GetTimersRead(timerState); timerState.Remove(false); #else int timerState = -1; Timers.Modified(timerState); #endif // vnsitimer int vnsitimerState; m_vnsiTimers->StateChange(vnsitimerState); // last update of epg #if VDRVERSNUM >= 20301 cStateKey epgState; const cSchedules *epg = cSchedules::GetSchedulesRead(epgState); epgState.Remove(false); #else time_t epgUpdate = cSchedules::Modified(); #endif // delete old timeshift file struct stat sb; if ((*TimeshiftBufferDir) && stat(TimeshiftBufferDir, &sb) == 0 && S_ISDIR(sb.st_mode)) { DeleteFiles(TimeshiftBufferDir, ".vnsi"); } else { #if VDRVERSNUM >= 20102 DeleteFiles(cVideoDirectory::Name(), ".vnsi"); #else DeleteFiles(VideoDirectory, ".vnsi"); #endif } // set thread priority SetPriority(1); while (Running()) { m_mutex.Lock(); // remove disconnected clients for (ClientList::iterator i = m_clients.begin(); i != m_clients.end();) { if (!i->Active()) { INFOLOG("Client with ID %u seems to be disconnected, removing from client list", i->GetID()); i = m_clients.erase(i); } else { i++; } } /*! * Don't to updates during running channel scan, KODI's PVR manager becomes * restarted of finished scan. */ if (!cVNSIClient::InhibidDataUpdates()) { // reset inactivity timeout as long as there are clients connected if (!m_clients.empty()) { ShutdownHandler.SetUserInactiveTimeout(); } // trigger clients to reload the modified channel list if(chanTimer.TimedOut()) { #if VDRVERSNUM >= 20301 if (channels->Lock(chanState)) { chanState.Remove(false); INFOLOG("Requesting clients to reload channel list"); for (auto &i : m_clients) i.ChannelsChange(); chanTimer.Set(5000); } #else int modified = Channels.Modified(); if (modified) { Channels.SetModified((modified == CHANNELSMOD_USER) ? true : false); INFOLOG("Requesting clients to reload channel list"); for (auto &i : m_clients) i.ChannelsChange(); } chanTimer.Set(5000); #endif } #if VDRVERSNUM >= 20301 if (recordings->Lock(recState)) { recState.Remove(); INFOLOG("Requesting clients to reload recordings list"); for (auto &i : m_clients) { i.RecordingsChange(); } } if (timers->Lock(timerState)) { timerState.Remove(false); INFOLOG("Requesting clients to reload timers"); for (auto &i : m_clients) { i.SignalTimerChange(); } } if (m_vnsiTimers->StateChange(vnsitimerState)) { INFOLOG("Requesting clients to reload vnsi-timers"); for (auto &i : m_clients) { i.SignalTimerChange(); } } if (epgTimer.TimedOut()) { if (epg->Lock(epgState)) { epgState.Remove(false); DEBUGLOG("Requesting clients to load epg"); int callAgain = 0; for (auto &i : m_clients) { callAgain |= i.EpgChange(); } if (callAgain & VNSI_EPG_AGAIN) { epgTimer.Set(100); epgState.Reset(); } else { if (callAgain & VNSI_EPG_PAUSE) { epgState.Reset(); } epgTimer.Set(5000); m_vnsiTimers->Scan(); } } } #else // update recordings if(Recordings.StateChanged(recState)) { INFOLOG("Recordings state changed (%i)", recState); INFOLOG("Requesting clients to reload recordings list"); for (auto &i : m_clients) i.RecordingsChange(); } // update timers if(Timers.Modified(timerState)) { INFOLOG("Timers state changed (%i)", timerState); INFOLOG("Requesting clients to reload timers"); for (auto &i : m_clients) { i.SignalTimerChange(); } } // update epg if((cSchedules::Modified() > epgUpdate + 10) || time(NULL) > epgUpdate + 300) { for (auto &i : m_clients) { i.EpgChange(); } epgUpdate = time(NULL); } #endif } m_mutex.Unlock(); usleep(250*1000); } }
/******************************************************************* * * エレベーター制御文 * *******************************************************************/ void Elevator::CntorolStatement() { switch(m_ControlState) { case CONTROL::FREE://フリー状態 break; case CONTROL::MOVE://目的フロア移動する状態 //目的地でなければ if( !m_CDataSupport.isDestination() ){ //エレベーター稼働 Running(); } //目的地ならば else{ //エレベーター停止処理 StopProcess(); //全搭乗口の進路ガイドの方向を進路方向に変える setAllGuideVector(m_CDataSupport.m_CourseDirection); //制御を到着状態に m_ControlState = CONTROL::ARRIVE; } break; case CONTROL::ARRIVE://フロアに到着した状態 //ゲートを開く if( m_CGate[m_Gate_Ypos]!=NULL ){ //ゲートに開閉指示をだす m_CGate[m_Gate_Ypos]->StartOperation(); } //制御を待機状態に m_ControlState = CONTROL::WAIT; break; case CONTROL::WAIT://待機状態 //ゲートが完全に開いたら if( m_CGate[m_Gate_Ypos]->getDoorState() == ELEVATOR::OPEN ){ //降りたい利用者を降ろす UserTakeDown(); break; } //ゲートが半端なら else if( m_CGate[m_Gate_Ypos]->getDoorState() == ELEVATOR::HALF ){ break; } //ゲートが完全に閉まっていれば else if( m_CGate[m_Gate_Ypos]->getDoorState() == ELEVATOR::CLOSE ){ //待機時間をリセット m_CGate[m_Gate_Ypos]->OperationReset(); //乗客がいれば if(m_isUserRiding){ //同フロア対策 m_State = m_CDataSupport.m_CourseDirection; //利用者の要求を追加 addUserRequest(); //始動準備させる StartSetting(); break; } //要求が無ければ if( !m_CDataSupport.isCallRequest() ) { DirectionClear();//エレベーターの方向データを全て初期化 m_CGate[m_Gate_Ypos]->StateReset();//ゲートの状態を初期化 m_ControlState = CONTROL::FREE;//制御をフリー状態に初期化 } } break; } }
unsigned char cN2Timer::Ctrl(void) { if(Running()) Update(); return ctrl; }
void cConnection::Action(void) { uint32_t kaTimeStamp; uint32_t channelID; uint32_t requestID; uint32_t opcode; uint32_t dataLength; uint8_t* data; while (Running()) { if (!m_socket.read((uint8_t*)&channelID, sizeof(uint32_t))) break; channelID = ntohl(channelID); if (channelID == 1) { if (!m_socket.read((uint8_t*)&requestID, sizeof(uint32_t), 10000)) break; requestID = ntohl(requestID); if (!m_socket.read((uint8_t*)&opcode, sizeof(uint32_t), 10000)) break; opcode = ntohl(opcode); if (!m_socket.read((uint8_t*)&dataLength, sizeof(uint32_t), 10000)) break; dataLength = ntohl(dataLength); if (dataLength > 200000) // a random sanity limit { esyslog("VNSI-Error: dataLength > 200000!"); break; } if (dataLength) { data = (uint8_t*)malloc(dataLength); if (!data) { esyslog("VNSI-Error: Extra data buffer malloc error"); break; } if (!m_socket.read(data, dataLength, 10000)) { esyslog("VNSI-Error: Could not read data"); free(data); break; } } else { data = NULL; } //LOGCONSOLE("Received chan=%lu, ser=%lu, op=%lu, edl=%lu", channelID, requestID, opcode, dataLength); if (!m_loggedIn && (opcode != 1)) { esyslog("VNSI-Error: Not logged in and opcode != 1"); if (data) free(data); break; } /* Handle channel open and close inside this thread */ if (opcode == VDR_CHANNELSTREAM_OPEN) { cResponsePacket *resp = new cResponsePacket(); if (!resp->init(requestID)) { esyslog("VNSI-Error: response packet init fail"); delete resp; continue; } uint32_t number = ntohl(*(uint32_t*)&data[0]); free(data); if (m_isStreaming) StopChannelStreaming(); const cChannel *channel = Channels.GetByNumber(number); if (channel != NULL) { if (StartChannelStreaming(channel, resp)) { isyslog("VNSI: Started streaming of channel %i - %s", number, channel->Name()); continue; } else { LOGCONSOLE("Can't stream channel %i - %s", number, channel->Name()); resp->add_U32(VDR_RET_DATALOCKED); } } else { esyslog("VNSI-Error: Can't find channel %i", number); resp->add_U32(VDR_RET_DATAINVALID); } resp->finalise(); m_socket.write(resp->getPtr(), resp->getLen()); } else if (opcode == VDR_CHANNELSTREAM_CLOSE) { if (m_isStreaming) StopChannelStreaming(); } else { cRequestPacket* req = new cRequestPacket(requestID, opcode, data, dataLength, this); m_cmdcontrol.recvRequest(req); } } else if (channelID == 3) { if (!m_socket.read((uint8_t*)&kaTimeStamp, sizeof(uint32_t), 1000)) break; kaTimeStamp = ntohl(kaTimeStamp); uint8_t buffer[8]; *(uint32_t*)&buffer[0] = htonl(3); // KA CHANNEL *(uint32_t*)&buffer[4] = htonl(kaTimeStamp); if (!m_socket.write(buffer, 8)) { esyslog("VNSI-Error: Could not send back KA reply"); break; } } else { esyslog("VNSI-Error: Incoming channel number unknown"); break; } } /* If thread is ended due to closed connection delete a possible running stream here */ StopChannelStreaming(); }
unsigned int cN2Timer::Cycles(void) { if(Running()) Update(); PRINTF(L_SYS_EMU,"n2timer %d: read %u %02x %02x = %02x",nr,cycles,ctrl&0xff,latch&0xff,val); return val; }
void cAction::Action(void) { if(pri>0) SetPriority(pri); struct pollfd *pfd=0; while(Running()) { if(filters.Count()<=0) { cCondWait::SleepMs(100); } else { // first build pfd data Lock(); delete[] pfd; pfd=new struct pollfd[filters.Count()]; if(!pfd) { PRINTF(L_GEN_ERROR,"action %s: pollfd: out of memory",id); break; } int num=0; cPidFilter *filter; for(filter=filters.First(); filter; filter=filters.Next(filter)) if(filter->Active()) { memset(&pfd[num],0,sizeof(struct pollfd)); pfd[num].fd=filter->fd; pfd[num].events=POLLIN; num++; } Unlock(); // now poll for data int r=poll(pfd,num,60); if(r<0 && errno!=EINTR) { PRINTF(L_GEN_ERROR,"action %s poll: %s",id,strerror(errno)); break; } if(r>0) { for(r=0 ; r<num ; r++) if(pfd[r].revents&POLLIN) { Lock(); for(filter=filters.First(); filter; filter=filters.Next(filter)) { if(filter->fd==pfd[r].fd) { unsigned char buff[MAX_SECT_SIZE]; int n=read(filter->fd,buff,sizeof(buff)); if(n<0 && errno!=EAGAIN) { if(errno==EOVERFLOW) { filter->Flush(); //PRINTF(L_GEN_ERROR,"action %s read: Buffer overflow",filter->id); } else PRINTF(L_GEN_ERROR,"action %s read: %s",filter->id,strerror(errno)); } if(n>0) { filter->lastTime.Set(); filter->forceRun=false; Process(filter,buff,n); // don't make any assumption about data-structs here // Process() may have changed them } break; } } Unlock(); } } // call filters which are idle too long Lock(); do { r=0; for(filter=filters.First(); filter; filter=filters.Next(filter)) { if(filter->forceRun || (filter->idleTime && filter->lastTime.Elapsed()>filter->idleTime)) { filter->lastTime.Set(); filter->forceRun=false; Process(filter,0,0); // don't make any assumption about data-structs here // Process() may have changed them r=1; break; } } } while(r); Unlock(); } } delete[] pfd; }
void cLiveStreamer::Action(void) { int size = 0; unsigned char *buf = NULL; m_startup = true; while (Running()) { size = 0; buf = Get(size); { cMutexLock lock(&m_FilterMutex); if (!IsAttached()) { INFOLOG("returning from streamer thread, receiver is no more attached"); Clear(); sendDetach(); return; } } if(!IsStarting() && (m_last_tick.Elapsed() > (uint64_t)(m_scanTimeout*1000)) && !m_SignalLost) { INFOLOG("timeout. signal lost!"); sendStatus(XVDR_STREAM_STATUS_SIGNALLOST); m_SignalLost = true; } // no data if (buf == NULL || size <= TS_SIZE) continue; // Sync to TS packet int used = 0; while (size > TS_SIZE) { if (buf[0] == TS_SYNC_BYTE && buf[TS_SIZE] == TS_SYNC_BYTE) break; used++; buf++; size--; } Del(used); while (size >= TS_SIZE) { if(!Running()) break; // TS packet sync not found ! if (buf[0] != TS_SYNC_BYTE) break; unsigned int ts_pid = TsPid(buf); { cMutexLock lock(&m_FilterMutex); cTSDemuxer *demuxer = FindStreamDemuxer(ts_pid); if (demuxer) demuxer->ProcessTSPacket(buf); } buf += TS_SIZE; size -= TS_SIZE; Del(TS_SIZE); } } }
void cRawWriter::Action(void) { uint64_t NextHeaderPos = 0ULL; uint64_t GetPos = 0ULL; cPoller Poller(m_fd, true); while (Running()) { if (!Poller.Poll(100)) continue; uint64_t StartPos; int Count = 0; int n; uchar *Data = m_RingBuffer.Get(Count); if (!Data || Count <= 0) continue; Lock(); // uint64_t m_DiscardStart can not be read atomically (IA32) StartPos = m_DiscardEnd; Unlock(); // Next frame ? if (NextHeaderPos == GetPos) { // Discard data ? if (StartPos > GetPos) { // we're at frame boundary Count = min(Count, (int)(StartPos - GetPos)); m_RingBuffer.Del(Count); GetPos += Count; NextHeaderPos = GetPos; continue; } // Next frame if (Count < 6) LOGMSG("cBackgroundWriter @NextHeaderPos: Count < header size !"); int packlen = DATA_IS_TS(Data) ? TS_SIZE : pes_packet_len(Data, Count); if (Count < packlen) ;//LOGMSG("Count = %d < %d", Count, // header->len + sizeof(stream_tcp_header_t)); else Count = packlen; NextHeaderPos = GetPos + packlen; } else { // end of prev frame Count = min(Count, (int)(NextHeaderPos-GetPos)); } errno = 0; n = write(m_fd, Data, Count); if (n <= 0) { if (n == 0) { LOGERR("cBackgroundWriter: Client disconnected data stream ?"); break; } if (errno == EINTR || errno == EWOULDBLOCK) continue; LOGERR("cBackgroundWriter: TCP write error"); break; } GetPos += n; m_RingBuffer.Del(n); } m_RingBuffer.Clear(); }
void cTcpWriter::Action(void) { uint64_t NextHeaderPos = 0; uint64_t GetPos = 0; cPoller Poller (m_fd, true); bool CorkReq = false; while (Running()) { if (!Poller.Poll(100)) continue; if (CorkReq && m_RingBuffer.Available() <= 0) { // Force TCP packet to avoid delaying control messages Cork(); CorkReq = false; } uint64_t StartPos; int Count = 0; int n; uchar *Data = m_RingBuffer.Get(Count); if (!Data || Count <= 0) continue; Lock(); // uint64_t m_DiscardStart can not be read atomically (IA32) StartPos = m_DiscardEnd; Unlock(); // Next frame ? if (NextHeaderPos == GetPos) { // Discard data ? if (StartPos > GetPos) { // we're at frame boundary // drop only data packets, not control messages stream_tcp_header_t *header = (stream_tcp_header_t*)Data; if (eStreamId(header->stream) == sidVdr) { Count = min(Count, (int)(StartPos - GetPos)); // size of next (complete) packet. // drop only one packet at time. int pkt_len = ntohl(header->len) + sizeof(stream_tcp_header_t); if (Count >= pkt_len) { // drop only complete packets. // some packets are not dropped (packets overlapping end of ringbuffer) Count = pkt_len; m_RingBuffer.Del(Count); GetPos += Count; NextHeaderPos = GetPos; CorkReq = true; // force sending last frame continue; } } } // Next frame if (Count < (int)sizeof(stream_tcp_header_t)) LOGMSG("cBackgroundWriter @NextHeaderPos: Count < header size !"); // limit single write to size of next (complete) packet. // (we need to track packet boundaries) stream_tcp_header_t *header = (stream_tcp_header_t*)Data; int pkt_len = ntohl(header->len) + sizeof(stream_tcp_header_t); if (Count > pkt_len) Count = pkt_len; // next packet start position in stream NextHeaderPos = GetPos + pkt_len; // check for control message if (eStreamId(header->stream) == sidControl) CorkReq = true; } else { // end of prev frame Count = min(Count, (int)(NextHeaderPos-GetPos)); } errno = 0; n = write(m_fd, Data, Count); if (n <= 0) { if (n == 0) { LOGERR("cBackgroundWriter: Client disconnected data stream ?"); break; } if (errno == EINTR || errno == EWOULDBLOCK) continue; LOGERR("cBackgroundWriter: TCP write error"); break; } GetPos += n; m_RingBuffer.Del(n); } m_RingBuffer.Clear(); }