void MP4Reader::Output(TrackType aTrack, MediaData* aSample) { #ifdef LOG_SAMPLE_DECODE VLOG("Decoded %s sample time=%lld dur=%lld", TrackTypeToStr(aTrack), aSample->mTime, aSample->mDuration); #endif if (!aSample) { NS_WARNING("MP4Reader::Output() passed a null sample"); Error(aTrack); return; } auto& decoder = GetDecoderData(aTrack); // Don't accept output while we're flushing. MonitorAutoLock mon(decoder.mMonitor); if (decoder.mIsFlushing) { LOG("MP4Reader produced output while flushing, discarding."); mon.NotifyAll(); return; } decoder.mOutput.AppendElement(aSample); decoder.mNumSamplesOutput++; if (NeedInput(decoder) || decoder.HasPromise()) { ScheduleUpdate(aTrack); } }
/* RemoveSlave -- * Unmanage and delete the slave. * * NOTES/ASSUMPTIONS: * * [1] It's safe to call Tk_UnmapWindow / Tk_UnmaintainGeometry even if this * routine is called from the slave's DestroyNotify event handler. */ static void RemoveSlave(Ttk_Manager *mgr, int index) { Ttk_Slave *slave = mgr->slaves[index]; int i; /* Notify manager: */ mgr->managerSpec->SlaveRemoved(mgr->managerData, index); /* Remove from array: */ --mgr->nSlaves; for (i = index ; i < mgr->nSlaves; ++i) { mgr->slaves[i] = mgr->slaves[i+1]; } /* Clean up: */ Tk_DeleteEventHandler( slave->slaveWindow, SlaveEventMask, SlaveEventHandler, slave); /* Note [1] */ Tk_UnmaintainGeometry(slave->slaveWindow, mgr->masterWindow); Tk_UnmapWindow(slave->slaveWindow); DeleteSlave(slave); ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED); }
/** * \fn UPNPScanner::AddServer(const QString&, const QString&) * Adds the server identified by usn and reachable via url to the list of * known media servers and schedules an update to initiate a connection. */ void UPNPScanner::AddServer(const QString &usn, const QString &url) { if (url.isEmpty()) { RemoveServer(usn); return; } // sometimes initialisation is too early and m_masterHost is empty if (m_masterHost.isEmpty()) { m_masterHost = gCoreContext->GetSetting("MasterServerIP"); m_masterPort = gCoreContext->GetSettingOnHost("BackendStatusPort", m_masterHost, "6544").toInt(); } QUrl qurl(url); if (qurl.host() == m_masterHost && qurl.port() == m_masterPort) { LOG(VB_UPNP, LOG_INFO, LOC + "Ignoring master backend."); return; } m_lock.lock(); if (!m_servers.contains(usn)) { m_servers.insert(usn, new MediaServer(url)); LOG(VB_GENERAL, LOG_INFO, LOC + QString("Adding: %1").arg(usn)); ScheduleUpdate(); } m_lock.unlock(); }
void CRepositoryUpdater::OnJobComplete(unsigned int jobID, bool success, CJob* job) { CSingleLock lock(m_criticalSection); m_jobs.erase(std::find(m_jobs.begin(), m_jobs.end(), job)); if (m_jobs.empty()) { CLog::Log(LOGDEBUG, "CRepositoryUpdater: done."); m_doneEvent.Set(); if (CSettings::GetInstance().GetInt(CSettings::SETTING_GENERAL_ADDONUPDATES) == AUTO_UPDATES_NOTIFY) { VECADDONS hasUpdate; if (CAddonMgr::GetInstance().GetAllOutdatedAddons(hasUpdate) && !hasUpdate.empty()) { if (hasUpdate.size() == 1) CGUIDialogKaiToast::QueueNotification( hasUpdate[0]->Icon(), hasUpdate[0]->Name(), g_localizeStrings.Get(24068), TOAST_DISPLAY_TIME, false, TOAST_DISPLAY_TIME); else CGUIDialogKaiToast::QueueNotification( "", g_localizeStrings.Get(24001), g_localizeStrings.Get(24061), TOAST_DISPLAY_TIME, false, TOAST_DISPLAY_TIME); } } if (CSettings::GetInstance().GetInt(CSettings::SETTING_GENERAL_ADDONUPDATES) == AUTO_UPDATES_ON) CAddonInstaller::GetInstance().InstallUpdates(); ScheduleUpdate(); CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE); g_windowManager.SendThreadMessage(msg); } }
void MP4Reader::DrainComplete(TrackType aTrack) { DecoderData& data = GetDecoderData(aTrack); MonitorAutoLock mon(data.mMonitor); data.mDrainComplete = true; ScheduleUpdate(aTrack); }
void MP4Reader::InputExhausted(TrackType aTrack) { DecoderData& data = GetDecoderData(aTrack); MonitorAutoLock mon(data.mMonitor); data.mInputExhausted = true; ScheduleUpdate(aTrack); }
void CRepositoryUpdater::OnEvent(const ADDON::AddonEvent& event) { if (typeid(event) == typeid(ADDON::AddonEvents::Enabled)) { if (m_addonMgr.HasType(event.id, ADDON_REPOSITORY)) ScheduleUpdate(); } }
/* ++ RecomputeSize -- * Recomputes the required size of the master window, * makes geometry request. */ static void RecomputeSize(Ttk_Manager *mgr) { int width = 1, height = 1; if (mgr->managerSpec->RequestedSize(mgr->managerData, &width, &height)) { Tk_GeometryRequest(mgr->masterWindow, width, height); ScheduleUpdate(mgr, MGR_RELAYOUT_REQUIRED); } mgr->flags &= ~MGR_RESIZE_REQUIRED; }
/** * \fn UPNPScanner::replyFinished(void) * Validates network responses against known requests and parses expected * responses for the required data. */ void UPNPScanner::replyFinished(QNetworkReply *reply) { if (!reply) return; QUrl url = reply->url(); bool valid = reply->error() == QNetworkReply::NoError; if (!valid) { LOG(VB_UPNP, LOG_ERR, LOC + QString("Network request for '%1' returned error '%2'") .arg(url.toString()).arg(reply->errorString())); } bool description = false; bool browse = false; m_lock.lock(); if (m_descriptionRequests.contains(url, reply)) { m_descriptionRequests.remove(url, reply); description = true; } else if (m_browseRequests.contains(url, reply)) { m_browseRequests.remove(url, reply); browse = true; } m_lock.unlock(); if (browse && valid) { ParseBrowse(url, reply); // a complete scan is event driven, so trigger the next browse BrowseNextContainer(); } else if (description) { if (!valid || (valid && !ParseDescription(url, reply))) { // if there will be no more attempts, update the logs CheckFailure(url); // try again ScheduleUpdate(); } } else LOG(VB_UPNP, LOG_ERR, LOC + "Received unknown reply"); reply->deleteLater(); }
void Ttk_GeometryRequestProc(ClientData clientData, Tk_Window slaveWindow) { Ttk_Manager *mgr = clientData; int slaveIndex = Ttk_SlaveIndex(mgr, slaveWindow); int reqWidth = Tk_ReqWidth(slaveWindow); int reqHeight= Tk_ReqHeight(slaveWindow); if (mgr->managerSpec->SlaveRequest( mgr->managerData, slaveIndex, reqWidth, reqHeight)) { ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED); } }
void MP4Reader::DisableHardwareAcceleration() { if (HasVideo() && mSharedDecoderManager) { mSharedDecoderManager->DisableHardwareAcceleration(); const VideoInfo& video = mDemuxer->VideoConfig(); if (!mSharedDecoderManager->Recreate(video)) { MonitorAutoLock mon(mVideo.mMonitor); mVideo.mError = true; if (mVideo.HasPromise()) { mVideo.RejectPromise(DECODE_ERROR, __func__); } } else { MonitorAutoLock lock(mVideo.mMonitor); ScheduleUpdate(TrackInfo::kVideoTrack); } } }
/** * \fn UPNPScanner::Update(void) * Iterates through the list of known servers and initialises a connection by * requesting the device description. */ void UPNPScanner::Update(void) { // decide which servers still need to be checked m_lock.lock(); if (m_servers.isEmpty()) { m_lock.unlock(); return; } // if our network queue is full, then we may need to come back later bool reschedule = false; QHashIterator<QString,MediaServer*> it(m_servers); while (it.hasNext()) { it.next(); if ((it.value()->m_connectionAttempts < MAX_ATTEMPTS) && (it.value()->m_controlURL.isEmpty())) { bool sent = false; QUrl url = it.value()->m_URL; if (!m_descriptionRequests.contains(url) && (m_descriptionRequests.size() < MAX_REQUESTS) && url.isValid()) { QNetworkReply *reply = m_network->get(QNetworkRequest(url)); if (reply) { sent = true; m_descriptionRequests.insert(url, reply); it.value()->m_connectionAttempts++; } } if (!sent) reschedule = true; } } if (reschedule) ScheduleUpdate(); m_lock.unlock(); }
void MP4Reader::DisableHardwareAcceleration() { if (HasVideo() && mSharedDecoderManager) { mSharedDecoderManager->DisableHardwareAcceleration(); const VideoDecoderConfig& video = mDemuxer->VideoConfig(); if (!mSharedDecoderManager->Recreate(video, mLayersBackendType, mDecoder->GetImageContainer())) { MonitorAutoLock mon(mVideo.mMonitor); mVideo.mError = true; if (mVideo.HasPromise()) { mVideo.RejectPromise(DECODE_ERROR, __func__); } } else { MonitorAutoLock lock(mVideo.mMonitor); ScheduleUpdate(kVideo); } } }
void CRepositoryUpdater::OnJobComplete(unsigned int jobID, bool success, CJob* job) { CSingleLock lock(m_criticalSection); m_jobs.erase(std::find(m_jobs.begin(), m_jobs.end(), job)); if (m_jobs.empty()) { CLog::Log(LOGDEBUG, "CRepositoryUpdater: done."); m_doneEvent.Set(); VECADDONS updates = CAddonMgr::GetInstance().GetAvailableUpdates(); if (CSettings::GetInstance().GetInt(CSettings::SETTING_ADDONS_AUTOUPDATES) == AUTO_UPDATES_NOTIFY) { if (!updates.empty()) { if (updates.size() == 1) CGUIDialogKaiToast::QueueNotification( updates[0]->Icon(), updates[0]->Name(), g_localizeStrings.Get(24068), TOAST_DISPLAY_TIME, false, TOAST_DISPLAY_TIME); else CGUIDialogKaiToast::QueueNotification( "", g_localizeStrings.Get(24001), g_localizeStrings.Get(24061), TOAST_DISPLAY_TIME, false, TOAST_DISPLAY_TIME); for (const auto &addon : updates) CEventLog::GetInstance().Add(EventPtr(new CAddonManagementEvent(addon, 24068))); } } if (CSettings::GetInstance().GetInt(CSettings::SETTING_ADDONS_AUTOUPDATES) == AUTO_UPDATES_ON) { for (const auto& addon : updates) { if (!CAddonMgr::GetInstance().IsBlacklisted(addon->ID())) CAddonInstaller::GetInstance().InstallOrUpdate(addon->ID()); } } ScheduleUpdate(); m_events.Publish(RepositoryUpdated{}); } }
nsRefPtr<MediaDecoderReader::VideoDataPromise> MP4Reader::RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThreshold) { MOZ_ASSERT(GetTaskQueue()->IsCurrentThreadIn()); VLOG("skip=%d time=%lld", aSkipToNextKeyframe, aTimeThreshold); if (!EnsureDecodersSetup()) { NS_WARNING("Error constructing MP4 decoders"); return VideoDataPromise::CreateAndReject(DECODE_ERROR, __func__); } if (mShutdown) { NS_WARNING("RequestVideoData on shutdown MP4Reader!"); return VideoDataPromise::CreateAndReject(CANCELED, __func__); } MOZ_ASSERT(HasVideo() && mPlatform && mVideo.mDecoder); bool eos = false; if (ShouldSkip(aSkipToNextKeyframe, aTimeThreshold)) { uint32_t parsed = 0; eos = !SkipVideoDemuxToNextKeyFrame(aTimeThreshold, parsed); if (!eos && NS_FAILED(mVideo.mDecoder->Flush())) { NS_WARNING("Failed to skip/flush video when skipping-to-next-keyframe."); } mDecoder->NotifyDecodedFrames(parsed, 0, parsed); } MonitorAutoLock lock(mVideo.mMonitor); nsRefPtr<VideoDataPromise> p = mVideo.mPromise.Ensure(__func__); if (mVideo.mError) { mVideo.mPromise.Reject(DECODE_ERROR, __func__); } else if (eos) { mVideo.mPromise.Reject(END_OF_STREAM, __func__); } else { ScheduleUpdate(kVideo); } return p; }
/* ++ InsertSlave -- * Adds slave to the list of managed windows. */ static void InsertSlave(Ttk_Manager *mgr, Ttk_Slave *slave, int index) { int endIndex = mgr->nSlaves++; mgr->slaves = (Ttk_Slave**)ckrealloc( (ClientData)mgr->slaves, mgr->nSlaves * sizeof(Ttk_Slave *)); while (endIndex > index) { mgr->slaves[endIndex] = mgr->slaves[endIndex - 1]; --endIndex; } mgr->slaves[index] = slave; Tk_ManageGeometry(slave->slaveWindow, &mgr->managerSpec->tkGeomMgr, (ClientData)mgr); Tk_CreateEventHandler(slave->slaveWindow, SlaveEventMask, SlaveEventHandler, (ClientData)slave); ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED); }
nsRefPtr<MediaDecoderReader::AudioDataPromise> MP4Reader::RequestAudioData() { MOZ_ASSERT(GetTaskQueue()->IsCurrentThreadIn()); VLOG(""); if (!EnsureDecodersSetup()) { NS_WARNING("Error constructing MP4 decoders"); return AudioDataPromise::CreateAndReject(DECODE_ERROR, __func__); } if (mShutdown) { NS_WARNING("RequestAudioData on shutdown MP4Reader!"); return AudioDataPromise::CreateAndReject(CANCELED, __func__); } MonitorAutoLock lock(mAudio.mMonitor); nsRefPtr<AudioDataPromise> p = mAudio.mPromise.Ensure(__func__); ScheduleUpdate(kAudio); return p; }
BOOL MediaThrottler::IsFrameUpdateAllowed() { double curr_time = g_op_time_info->GetRuntimeMS(); if (IsThrottlingNeeded(curr_time)) { BOOL allowed = IsUpdateAllowed(curr_time); if (allowed) { UpdateTimestamps(TRUE, curr_time); } else { ScheduleUpdate(curr_time); } return allowed; } return TRUE; }
/* ++ Ttk_ReorderSlave(mgr, fromIndex, toIndex) -- * Change slave order. */ void Ttk_ReorderSlave(Ttk_Manager *mgr, int fromIndex, int toIndex) { Ttk_Slave *moved = mgr->slaves[fromIndex]; /* Shuffle down: */ while (fromIndex > toIndex) { mgr->slaves[fromIndex] = mgr->slaves[fromIndex - 1]; --fromIndex; } /* Or, shuffle up: */ while (fromIndex < toIndex) { mgr->slaves[fromIndex] = mgr->slaves[fromIndex + 1]; ++fromIndex; } /* ASSERT: fromIndex == toIndex */ mgr->slaves[fromIndex] = moved; /* Schedule a relayout. In general, rearranging slaves * may also change the size: */ ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED); }
void CRepositoryUpdater::Start() { ScheduleUpdate(); }
void CRepositoryUpdater::OnSettingChanged(const CSetting* setting) { if (setting->GetId() == CSettings::SETTING_ADDONS_AUTOUPDATES) ScheduleUpdate(); }
/* LayoutChanged, SizeChanged -- * Schedule a relayout, resp. resize request. */ void Ttk_ManagerLayoutChanged(Ttk_Manager *mgr) { ScheduleUpdate(mgr, MGR_RELAYOUT_REQUIRED); }
void Ttk_ManagerSizeChanged(Ttk_Manager *mgr) { ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED); }
void CRepositoryUpdater::Start() { m_addonMgr.Events().Subscribe(this, &CRepositoryUpdater::OnEvent); ScheduleUpdate(); }