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);
  }
}
示例#2
0
文件: ttkManager.c 项目: Starlink/tk
/* 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);
}
示例#3
0
/**
 * \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();
}
示例#4
0
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);
}
示例#7
0
void CRepositoryUpdater::OnEvent(const ADDON::AddonEvent& event)
{
  if (typeid(event) == typeid(ADDON::AddonEvents::Enabled))
  {
    if (m_addonMgr.HasType(event.id, ADDON_REPOSITORY))
      ScheduleUpdate();
  }
}
示例#8
0
文件: ttkManager.c 项目: Starlink/tk
/* ++ 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;
}
示例#9
0
/**
 * \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();
}
示例#10
0
文件: ttkManager.c 项目: Starlink/tk
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);
    }
}
示例#11
0
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);
    }
  }
}
示例#12
0
/**
 * \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();
}
示例#13
0
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);
    }
  }
}
示例#14
0
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{});
  }
}
示例#15
0
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;
}
示例#16
0
文件: ttkManager.c 项目: Starlink/tk
/* ++ 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);
}
示例#17
0
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;
}
示例#18
0
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;
}
示例#19
0
文件: ttkManager.c 项目: Starlink/tk
/* ++ 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);
}
示例#20
0
void CRepositoryUpdater::Start()
{
  ScheduleUpdate();
}
示例#21
0
void CRepositoryUpdater::OnSettingChanged(const CSetting* setting)
{
  if (setting->GetId() == CSettings::SETTING_ADDONS_AUTOUPDATES)
    ScheduleUpdate();
}
示例#22
0
文件: ttkManager.c 项目: Starlink/tk
/* LayoutChanged, SizeChanged --
 * 	Schedule a relayout, resp. resize request.
 */
void Ttk_ManagerLayoutChanged(Ttk_Manager *mgr)
{
    ScheduleUpdate(mgr, MGR_RELAYOUT_REQUIRED);
}
示例#23
0
文件: ttkManager.c 项目: Starlink/tk
void Ttk_ManagerSizeChanged(Ttk_Manager *mgr)
{
    ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED);
}
示例#24
0
void CRepositoryUpdater::Start()
{
  m_addonMgr.Events().Subscribe(this, &CRepositoryUpdater::OnEvent);
  ScheduleUpdate();
}