/** * @RDE_HEADER@ * DefaultAvMenus * $Id$ * $HeadURL$ * $Author$ * Created by Christian Fröbel, NLSE, 2018-03-14 */ #include "default_av_menus.h" #include "exercise.h" #include "object_video_team.h" #include "audio_video_handler_impl.h" #include #include #include #include #include #include #include #include #include namespace { std::set mountingPointsOfInterest(const InfrastructureManagement::MainStructureElement &building) { std::set mountingPoints; for (const auto &se : building.elements) { if (se.structureElementTypeId != InfrastructureManagement::StructureElementType::MountingPoint) continue; if (se.mountingPointTypeId == InfrastructureManagement::MountingPointType::AnnouncementUnit || se.mountingPointTypeId == InfrastructureManagement::MountingPointType::IndoorCamera || se.mountingPointTypeId == InfrastructureManagement::MountingPointType::OutdoorCamera) mountingPoints.insert(se.id); } return mountingPoints; } bool isStreamOfInterest(const AudioVideoManagement::Stream &stream, bool isAudio) { using AudioVideoManagement::StreamType; switch (stream.type) { case StreamType::Video: return !isAudio; case StreamType::AudioIn: return false; case StreamType::AudioOut: case StreamType::AudioInOut: return isAudio; } Q_ASSERT(false); return false; } } // anonymous namespace namespace AudioVideoManagement { DefaultAvMenus::DefaultAvMenus(const ExerciseContext &context, Interface::Dts *dts, HandlerVideoTeam *handlerVideoTeams, InfrastructureManagement::Interface::Dtc *ismDtc) : m_logger(getLogger("DefaultAvMenus")) , m_isInitialized(false) , m_context(context) , m_dts(dts) , m_videoTeamHandler(handlerVideoTeams) , m_ismDtc(ismDtc) , m_timer(new QTimer) { Q_ASSERT(dts); Q_ASSERT(ismDtc); if(!m_ismDtc->isMainStructureElementEnabled()) m_ismDtc->enableMainStructureElement(); m_timer->setInterval(1000); m_timer->setSingleShot(true); connect(m_videoTeamHandler, &HandlerVideoTeam::mvsChanged, this, &DefaultAvMenus::onStreamMvsChanged); connect(m_timer.get(), &QTimer::timeout, this, &DefaultAvMenus::updateMenus); m_timer->start(); } DefaultAvMenus::~DefaultAvMenus() = default; void DefaultAvMenus::onStreamChanged(const Stream &stream) { m_streams[stream.id] = stream; m_timer->start(); } void DefaultAvMenus::onStreamMvsChanged() { m_timer->start(); } void DefaultAvMenus::onMainStructureElementChanged(const InfrastructureManagement::MainStructureElement &data, DataModification modType) { QString buildingDisplayName = getDisplayNameForBuilding(data); if(modType == DataModification::eRemoved) { m_buildingDisplayNameForId.remove(data.id); m_timer->start(); } else if(modType == DataModification::eAdded) { m_buildingDisplayNameForId[data.id] = buildingDisplayName; m_timer->start(); } else { if(m_buildingDisplayNameForId.value(data.id,buildingDisplayName) == buildingDisplayName) return; m_buildingDisplayNameForId[data.id] = buildingDisplayName; m_timer->start(); } } void DefaultAvMenus::onStreamRemoved(int32_t streamId) { auto removeCount = m_streams.erase(streamId); Q_ASSERT(removeCount == 1); m_timer->start(); } void DefaultAvMenus::updateMenus() { updateMenu(true); // isAudio updateMenu(false); // !isAudio = Video } void DefaultAvMenus::removeMenus() { m_dts->removeMenuStructByKey(menuStructId(true)); // isAudio m_dts->removeMenuStructByKey(menuStructId(false)); // !isAudio = Video } void DefaultAvMenus::updateMenu(bool isAudio) { MenuStruct menu; menu.id = menuStructId(isAudio); menu.isDefault = true; menu.name = "Default"; menu.isAudio = isAudio; std::vector allEntries; const auto &buildings = m_ismDtc->mainStructureElements(); for (const auto &building : buildings) { m_buildingDisplayNameForId[building.id] = getDisplayNameForBuilding(building); std::vector subMenu = subMenuForBuilding(building, isAudio); std::move(subMenu.begin(), subMenu.end(), std::back_inserter(allEntries)); } if (!isAudio) { bool addMenu = false; AvMenuEntry mvsStreams; mvsStreams.id = 1000000; mvsStreams.parentId = menuStructId(isAudio); mvsStreams.name = "MVS"; mvsStreams.isGroup = true; const auto &videoTeams = m_videoTeamHandler->videoTeams(); for (const auto &videoTeam : videoTeams) { if (videoTeam.exerciseId != m_context.id()) continue; addMenu = true; AvMenuEntry streamEntry; streamEntry.id = videoTeam.id; streamEntry.parentId = mvsStreams.id; streamEntry.mountingPointId = -1 * videoTeam.id; // Also set the stream name which makes it easier for the clients. streamEntry.name = videoTeam.streamName; streamEntry.isGroup = false; allEntries.push_back(streamEntry); // What about the rowId? } if (addMenu) { allEntries.push_back(mvsStreams); } } menu.menuEntries = allEntries; HandlerMenuStruct::sortEntries(menu); m_dts->publish(menu); if(!m_isInitialized) { connect(m_ismDtc, &InfrastructureManagement::Interface::Dtc::mainStructureElementChanged, this, &DefaultAvMenus::onMainStructureElementChanged); m_isInitialized = true; } } QString DefaultAvMenus::getDisplayNameForBuilding(const InfrastructureManagement::MainStructureElement &data) { for (auto structure : data.elements) { if(structure.structureElementTypeId == InfrastructureManagement::StructureElementType::Building) return QString::fromStdString(structure.displayName); } return QString::fromStdString(data.name); } std::vector DefaultAvMenus::subMenuForBuilding(const InfrastructureManagement::MainStructureElement &building, bool isAudio) { std::vector entries; std::vector streams = streamsForBuilding(building, isAudio); if (streams.empty()) return entries; entries.reserve(streams.size() + 1); AvMenuEntry buildingEntry; buildingEntry.id = building.id; buildingEntry.parentId = menuStructId(isAudio); buildingEntry.name = getDisplayNameForBuilding(building).toStdString(); buildingEntry.isGroup = true; // What about the rowId? entries.push_back(buildingEntry); for (const auto &stream : streams) { AvMenuEntry streamEntry; streamEntry.id = stream.mountingPointId; streamEntry.parentId = buildingEntry.id; streamEntry.mountingPointId = stream.mountingPointId; // Also set the stream name which makes it easier for the clients. streamEntry.name = AudioVideoHandlerImpl::internalStreamName(stream.mountingPointId).toStdString(); streamEntry.isGroup = false; // What about the rowId? entries.push_back(streamEntry); } return entries; } std::vector DefaultAvMenus::streamsForBuilding(const InfrastructureManagement::MainStructureElement &building, bool isAudio) { std::set mountingPoints = mountingPointsOfInterest(building); std::vector streams; for (const auto &keyValue : m_streams) { const Stream &stream = keyValue.second; if (!isStreamOfInterest(stream, isAudio)) continue; if (!mountingPoints.count(stream.mountingPointId)) continue; streams.push_back(stream); } return streams; } int32_t DefaultAvMenus::menuStructId(bool isAudio) { return m_context.id() + (isAudio ? 20000000 : 10000000); } } // namespace AudioVideoManagement