diff --git a/pvr.hts/addon.xml.in b/pvr.hts/addon.xml.in index 72507ee7..50bcda0e 100644 --- a/pvr.hts/addon.xml.in +++ b/pvr.hts/addon.xml.in @@ -1,7 +1,7 @@ @ADDON_DEPENDS@ diff --git a/pvr.hts/changelog.txt b/pvr.hts/changelog.txt index d6f374a1..a438f5d6 100644 --- a/pvr.hts/changelog.txt +++ b/pvr.hts/changelog.txt @@ -1,3 +1,7 @@ +v22.2.0 +- Add support for TVH Parental Rating fields +- Misc cleanup and smaller fixes + v22.1.0 - PVR Add-on API v9.0.0 diff --git a/src/Tvheadend.cpp b/src/Tvheadend.cpp index 28e6ce1a..061a01a0 100644 --- a/src/Tvheadend.cpp +++ b/src/Tvheadend.cpp @@ -42,6 +42,7 @@ CTvheadend::CTvheadend(const kodi::addon::IInstanceInfo& instance) m_playingLiveStream(false), m_playingRecording(nullptr) { + m_dmx.reserve(m_settings->GetTotalTuners()); for (int i = 0; i < 1 || i < m_settings->GetTotalTuners(); i++) { m_dmx.emplace_back(new HTSPDemuxer(m_settings, *this, *m_conn)); @@ -206,10 +207,10 @@ void CTvheadend::QueryAvailableProfiles(std::unique_lock& if (str) profile.SetComment(str); - Logger::Log(LogLevel::LEVEL_INFO, " Name: %s, Comment: %s", - profile.GetName().c_str(), profile.GetComment().c_str()); + Logger::Log(LogLevel::LEVEL_INFO, " Name: %s, Comment: %s", profile.GetName().c_str(), + profile.GetComment().c_str()); - m_profiles.emplace_back(profile); + m_profiles.emplace_back(std::move(profile)); } htsmsg_destroy(m); @@ -218,9 +219,8 @@ void CTvheadend::QueryAvailableProfiles(std::unique_lock& bool CTvheadend::HasStreamingProfile(const std::string& streamingProfile) const { return std::find_if(m_profiles.cbegin(), m_profiles.cend(), - [&streamingProfile](const Profile& profile) { - return profile.GetName() == streamingProfile; - }) != m_profiles.cend(); + [&streamingProfile](const Profile& profile) + { return profile.GetName() == streamingProfile; }) != m_profiles.cend(); } /* ************************************************************************** @@ -246,6 +246,7 @@ PVR_ERROR CTvheadend::GetChannelGroups(bool radio, kodi::addon::PVRChannelGroups { std::lock_guard lock(m_mutex); + tags.reserve(m_tags.size()); for (const auto& entry : m_tags) { /* Does group contain channels of the requested type? */ @@ -260,14 +261,14 @@ PVR_ERROR CTvheadend::GetChannelGroups(bool radio, kodi::addon::PVRChannelGroups tag.SetIsRadio(radio); tag.SetPosition(entry.second.GetIndex()); - tags.emplace_back(tag); + tags.emplace_back(std::move(tag)); } } for (const auto& tag : tags) { /* Callback. */ - results.Add(tag); + results.Add(std::move(tag)); } return PVR_ERROR_NO_ERROR; @@ -284,13 +285,13 @@ PVR_ERROR CTvheadend::GetChannelGroupMembers(const kodi::addon::PVRChannelGroup& std::lock_guard lock(m_mutex); // Find the tag - const auto it = std::find_if(m_tags.cbegin(), m_tags.cend(), [group](const TagMapEntry& tag) { - return tag.second.GetName() == group.GetGroupName(); - }); + const auto it = std::find_if(m_tags.cbegin(), m_tags.cend(), [&group](const TagMapEntry& tag) + { return tag.second.GetName() == group.GetGroupName(); }); if (it != m_tags.cend()) { // Find all channels in this group that are of the correct type + gms.reserve(it->second.GetChannels().size()); for (const auto& channelId : it->second.GetChannels()) { auto cit = m_channels.find(channelId); @@ -304,7 +305,7 @@ PVR_ERROR CTvheadend::GetChannelGroupMembers(const kodi::addon::PVRChannelGroup& gm.SetChannelNumber(cit->second.GetNum()); gm.SetSubChannelNumber(cit->second.GetNumMinor()); - gms.emplace_back(gm); + gms.emplace_back(std::move(gm)); } } } @@ -313,7 +314,7 @@ PVR_ERROR CTvheadend::GetChannelGroupMembers(const kodi::addon::PVRChannelGroup& for (const auto& gm : gms) { /* Callback. */ - results.Add(gm); + results.Add(std::move(gm)); } return PVR_ERROR_NO_ERROR; @@ -342,6 +343,7 @@ PVR_ERROR CTvheadend::GetChannels(bool radio, kodi::addon::PVRChannelsResultSet& { std::lock_guard lock(m_mutex); + channels.reserve(m_channels.size()); for (const auto& entry : m_channels) { const auto& channel = entry.second; @@ -359,22 +361,23 @@ PVR_ERROR CTvheadend::GetChannels(bool radio, kodi::addon::PVRChannelsResultSet& chn.SetChannelName(channel.GetName()); chn.SetIconPath(channel.GetIcon()); - channels.emplace_back(chn); + channels.emplace_back(std::move(chn)); } } for (const auto& channel : channels) { /* Callback. */ - results.Add(channel); + results.Add(std::move(channel)); } return PVR_ERROR_NO_ERROR; } -PVR_ERROR CTvheadend::GetChannelStreamProperties(const kodi::addon::PVRChannel& channel, - PVR_SOURCE source, - std::vector& properties) +PVR_ERROR CTvheadend::GetChannelStreamProperties( + const kodi::addon::PVRChannel& channel, + PVR_SOURCE source, + std::vector& properties) { if (!m_settings->GetStreamingHTTP()) return PVR_ERROR_NO_ERROR; @@ -476,6 +479,7 @@ PVR_ERROR CTvheadend::GetRecordings(bool deleted, kodi::addon::PVRRecordingsResu std::lock_guard lock(m_mutex); char buf[128]; + recs.reserve(m_recordings.size()); for (const auto& entry : m_recordings) { const auto& recording = entry.second; @@ -604,14 +608,14 @@ PVR_ERROR CTvheadend::GetRecordings(bool deleted, kodi::addon::PVRRecordingsResu /* parental age rating source*/ rec.SetParentalRatingSource(recording.GetRatingSource()); - recs.emplace_back(rec); + recs.emplace_back(std::move(rec)); } } for (const auto& rec : recs) { /* Callback. */ - results.Add(rec); + results.Add(std::move(rec)); } return PVR_ERROR_NO_ERROR; @@ -684,7 +688,7 @@ PVR_ERROR CTvheadend::GetRecordingEdl(const kodi::addon::PVRRecording& rec, entry.SetType(PVR_EDL_TYPE_COMBREAK); break; } - edl.emplace_back(entry); + edl.emplace_back(std::move(entry)); Logger::Log(LogLevel::LEVEL_DEBUG, "edl start:%d end:%d action:%d", start, end, type); } @@ -1092,12 +1096,11 @@ bool CTvheadend::CreateTimer(const Recording& tvhTmr, kodi::addon::PVRTimer& tmr tmr.SetGenreType(0); // not supported by tvh? tmr.SetGenreSubType(0); // not supported by tvh? tmr.SetFullTextEpgSearch(false); // n/a for one-shot timers - tmr.SetParentClientIndex( - tmr.GetTimerType() == TIMER_ONCE_CREATED_BY_TIMEREC - ? m_timeRecordings.GetTimerIntIdFromStringId(tvhTmr.GetTimerecId()) - : tmr.GetTimerType() == TIMER_ONCE_CREATED_BY_AUTOREC - ? m_autoRecordings.GetTimerIntIdFromStringId(tvhTmr.GetAutorecId()) - : 0); + tmr.SetParentClientIndex(tmr.GetTimerType() == TIMER_ONCE_CREATED_BY_TIMEREC + ? m_timeRecordings.GetTimerIntIdFromStringId(tvhTmr.GetTimerecId()) + : tmr.GetTimerType() == TIMER_ONCE_CREATED_BY_AUTOREC + ? m_autoRecordings.GetTimerIntIdFromStringId(tvhTmr.GetAutorecId()) + : 0); return true; } @@ -1111,6 +1114,7 @@ PVR_ERROR CTvheadend::GetTimers(kodi::addon::PVRTimersResultSet& results) std::lock_guard lock(m_mutex); /* One-shot timers */ + timers.reserve(m_recordings.size()); for (const auto& entry : m_recordings) { const auto& recording = entry.second; @@ -1121,7 +1125,7 @@ PVR_ERROR CTvheadend::GetTimers(kodi::addon::PVRTimersResultSet& results) /* Setup entry */ kodi::addon::PVRTimer tmr; if (CreateTimer(recording, tmr)) - timers.emplace_back(tmr); + timers.emplace_back(std::move(tmr)); } /* Time-based repeating timers */ @@ -1134,7 +1138,7 @@ PVR_ERROR CTvheadend::GetTimers(kodi::addon::PVRTimersResultSet& results) for (const auto& timer : timers) { /* Callback. */ - results.Add(timer); + results.Add(std::move(timer)); } return PVR_ERROR_NO_ERROR; @@ -1401,7 +1405,7 @@ void CTvheadend::TransferEvent(kodi::addon::PVREPGTagsResultSet& results, const CreateEvent(event, tag); /* Transfer event to Kodi */ - results.Add(tag); + results.Add(std::move(tag)); } PVR_ERROR CTvheadend::GetEPGForChannel(int channelUid, @@ -1889,7 +1893,7 @@ void CTvheadend::PushEpgEventUpdate(const Event& epg, EPG_EVENT_STATE state) SHTSPEvent event = SHTSPEvent(HTSP_EVENT_EPG_UPDATE, epg, state); if (std::find(m_events.begin(), m_events.end(), event) == m_events.end()) - m_events.emplace_back(event); + m_events.emplace_back(std::move(event)); } void CTvheadend::SyncInitCompleted() @@ -2004,30 +2008,36 @@ void CTvheadend::SyncEpgCompleted() /* Schedules */ std::vector> deletedEvents; - utilities::erase_if(m_schedules, [&](const ScheduleMapEntry& entry) { - if (entry.second.IsDirty()) - { - // all events are dirty too! - for (auto& evt : entry.second.GetEvents()) - deletedEvents.emplace_back(std::make_pair(evt.second.GetId() /* event uid */, - entry.second.GetId() /* channel uid */)); - return true; - } - return false; - }); + utilities::erase_if(m_schedules, + [&](const ScheduleMapEntry& entry) + { + if (entry.second.IsDirty()) + { + // all events are dirty too! + for (auto& evt : entry.second.GetEvents()) + deletedEvents.emplace_back( + std::make_pair(evt.second.GetId() /* event uid */, + entry.second.GetId() /* channel uid */)); + return true; + } + return false; + }); /* Events */ for (auto& entry : m_schedules) { - utilities::erase_if(entry.second.GetEvents(), [&](const EventUidsMapEntry& mapEntry) { - if (mapEntry.second.IsDirty()) - { - deletedEvents.emplace_back(std::make_pair(mapEntry.second.GetId() /* event uid */, - entry.second.GetId() /* channel uid */)); - return true; - } - return false; - }); + utilities::erase_if(entry.second.GetEvents(), + [&](const EventUidsMapEntry& mapEntry) + { + if (mapEntry.second.IsDirty()) + { + deletedEvents.emplace_back( + std::make_pair(mapEntry.second.GetId() /* event uid */, + entry.second.GetId() /* channel uid */)); + return true; + } + return false; + }); } for (auto& entry : deletedEvents) @@ -2552,7 +2562,7 @@ void CTvheadend::ParseRecordingAddOrUpdate(htsmsg_t* msg, bool bAdd) str = htsmsg_get_str(msg, "ratingLabel"); if (str) rec.SetRatingLabel(str); - + str = htsmsg_get_str(msg, "ratingIcon"); if (str) rec.SetRatingIcon(GetImageURL(str)); @@ -2638,8 +2648,8 @@ void CTvheadend::ParseRecordingAddOrUpdate(htsmsg_t* msg, bool bAdd) { const std::string error = rec.GetError().empty() ? "n/a" : rec.GetError(); - Logger::Log(LogLevel::LEVEL_DEBUG, "recording id:%d, state:%s, title:%s, error:%s", - rec.GetId(), state, rec.GetTitle().c_str(), error.c_str()); + Logger::Log(LogLevel::LEVEL_DEBUG, "recording id:%d, state:%s, title:%s, error:%s", rec.GetId(), + state, rec.GetTitle().c_str(), error.c_str()); if (m_asyncState.GetState() > ASYNC_DVR) { @@ -2745,14 +2755,14 @@ bool CTvheadend::ParseEvent(htsmsg_t* msg, bool bAdd, Event& evt) if (!htsmsg_get_u32(msg, "ageRating", &u32)) evt.SetAge(u32); - str = htsmsg_get_str(msg, "ratingLabel"); // HTSP v36 required + str = htsmsg_get_str(msg, "ratingLabel"); // HTSP v36 required if (str) evt.SetRatingLabel(str); - str = htsmsg_get_str(msg, "ratingIcon"); // HTSP v36 required + str = htsmsg_get_str(msg, "ratingIcon"); // HTSP v36 required if (str) evt.SetRatingIcon(GetImageURL(str)); - + str = htsmsg_get_str(msg, "ratingAuthority"); if (str) { @@ -3143,7 +3153,8 @@ PVR_ERROR CTvheadend::GetStreamTimes(kodi::addon::PVRStreamTimes& times) { if (m_playingRecording->GetFilesStart() > 0) { - times.SetPTSEnd((std::time(nullptr) - m_playingRecording->GetFilesStart()) * STREAM_TIME_BASE); + times.SetPTSEnd((std::time(nullptr) - m_playingRecording->GetFilesStart()) * + STREAM_TIME_BASE); } else { diff --git a/src/Tvheadend.h b/src/Tvheadend.h index 007d8a41..25c8d1fc 100644 --- a/src/Tvheadend.h +++ b/src/Tvheadend.h @@ -97,9 +97,10 @@ class ATTR_DLL_LOCAL CTvheadend : public kodi::addon::CInstancePVRClient, PVR_ERROR GetChannelsAmount(int& amount) override; PVR_ERROR GetChannels(bool radio, kodi::addon::PVRChannelsResultSet& results) override; - PVR_ERROR GetChannelStreamProperties(const kodi::addon::PVRChannel& channel, - PVR_SOURCE source, - std::vector& properties) override; + PVR_ERROR GetChannelStreamProperties( + const kodi::addon::PVRChannel& channel, + PVR_SOURCE source, + std::vector& properties) override; PVR_ERROR GetRecordingsAmount(bool deleted, int& amount) override; PVR_ERROR GetRecordings(bool deleted, kodi::addon::PVRRecordingsResultSet& results) override; diff --git a/src/tvheadend/AutoRecordings.cpp b/src/tvheadend/AutoRecordings.cpp index 84543c31..dfb9990a 100644 --- a/src/tvheadend/AutoRecordings.cpp +++ b/src/tvheadend/AutoRecordings.cpp @@ -52,6 +52,8 @@ int AutoRecordings::GetAutorecTimerCount() const void AutoRecordings::GetAutorecTimers(std::vector& timers) { + timers.reserve(timers.size() + m_autoRecordings.size()); + for (const auto& rec : m_autoRecordings) { /* Setup entry */ @@ -103,7 +105,7 @@ void AutoRecordings::GetAutorecTimers(std::vector& timers tmr.SetFullTextEpgSearch(rec.second.GetFulltext()); tmr.SetParentClientIndex(0); - timers.emplace_back(tmr); + timers.emplace_back(std::move(tmr)); } } diff --git a/src/tvheadend/ChannelTuningPredictor.cpp b/src/tvheadend/ChannelTuningPredictor.cpp index 2d407f52..e8761220 100644 --- a/src/tvheadend/ChannelTuningPredictor.cpp +++ b/src/tvheadend/ChannelTuningPredictor.cpp @@ -39,9 +39,9 @@ ChannelPair ChannelTuningPredictor::MakeChannelPair(const entity::Channel& chann ChannelPairIterator ChannelTuningPredictor::GetIterator(uint32_t channelId) const { - return std::find_if( - m_channels.cbegin(), m_channels.cend(), - [channelId](const ChannelPair& channel) { return channel.first == channelId; }); + return std::find_if(m_channels.cbegin(), m_channels.cend(), + [channelId](const ChannelPair& channel) + { return channel.first == channelId; }); } uint32_t ChannelTuningPredictor::PredictNextChannelId(uint32_t tuningFrom, uint32_t tuningTo) const diff --git a/src/tvheadend/ChannelTuningPredictor.h b/src/tvheadend/ChannelTuningPredictor.h index 454877b7..f7e7cc3d 100644 --- a/src/tvheadend/ChannelTuningPredictor.h +++ b/src/tvheadend/ChannelTuningPredictor.h @@ -70,7 +70,7 @@ struct SortChannelPair { if (left.second < right.second) return true; - + if (right.second < left.second) return false; diff --git a/src/tvheadend/HTSPDemuxer.cpp b/src/tvheadend/HTSPDemuxer.cpp index fb8716cc..431ebd6a 100644 --- a/src/tvheadend/HTSPDemuxer.cpp +++ b/src/tvheadend/HTSPDemuxer.cpp @@ -630,7 +630,7 @@ bool HTSPDemuxer::AddRDSStream(uint32_t audioIdx, uint32_t rdsIdx) if (m_streams.size() < PVR_STREAM_MAX_STREAMS) { Logger::Log(LogLevel::LEVEL_DEBUG, "Adding rds stream. id: %d", rdsIdx); - m_streams.emplace_back(rdsStream); + m_streams.emplace_back(std::move(rdsStream)); return true; } else @@ -753,7 +753,7 @@ bool HTSPDemuxer::AddTVHStream(uint32_t idx, const char* type, htsmsg_field_t* f { Logger::Log(LogLevel::LEVEL_DEBUG, " id: %d, type %s, codec: %u", idx, type, stream.GetCodecId()); - m_streams.emplace_back(stream); + m_streams.emplace_back(std::move(stream)); return true; } else diff --git a/src/tvheadend/InstanceSettings.cpp b/src/tvheadend/InstanceSettings.cpp index aadaea94..300e3620 100644 --- a/src/tvheadend/InstanceSettings.cpp +++ b/src/tvheadend/InstanceSettings.cpp @@ -110,8 +110,8 @@ void InstanceSettings::ReadSettings() /* Streaming */ SetStreamingProfile(ReadStringSetting("streaming_profile", DEFAULT_STREAMING_PROFILE)); SetStreamingHTTP(ReadBoolSetting("streaming_http", DEFAULT_STREAMING_HTTP)); - SetStreamStalledThreshold(ReadIntSetting("stream_stalled_threshold", - DEFAULT_STREAM_STALLED_THRESHOLD)); + SetStreamStalledThreshold( + ReadIntSetting("stream_stalled_threshold", DEFAULT_STREAM_STALLED_THRESHOLD)); /* Default dvr settings */ SetDvrPriority(ReadIntSetting("dvr_priority", DEFAULT_DVR_PRIO)); diff --git a/src/tvheadend/TimeRecordings.cpp b/src/tvheadend/TimeRecordings.cpp index 16a13cd6..fbf52e32 100644 --- a/src/tvheadend/TimeRecordings.cpp +++ b/src/tvheadend/TimeRecordings.cpp @@ -48,6 +48,8 @@ int TimeRecordings::GetTimerecTimerCount() const void TimeRecordings::GetTimerecTimers(std::vector& timers) { + timers.reserve(timers.size() + m_timeRecordings.size()); + for (const auto& rec : m_timeRecordings) { /* Setup entry */ @@ -79,7 +81,7 @@ void TimeRecordings::GetTimerecTimers(std::vector& timers tmr.SetFullTextEpgSearch(false); // n/a for manual timers tmr.SetParentClientIndex(0); - timers.emplace_back(tmr); + timers.emplace_back(std::move(tmr)); } } diff --git a/src/tvheadend/entity/Entity.h b/src/tvheadend/entity/Entity.h index 635a3570..ba1d09c1 100644 --- a/src/tvheadend/entity/Entity.h +++ b/src/tvheadend/entity/Entity.h @@ -20,7 +20,7 @@ namespace entity class Entity { public: - Entity() : m_id(0), m_dirty(false){}; + Entity() : m_id(0), m_dirty(false) {} virtual ~Entity() = default; /** diff --git a/src/tvheadend/entity/Event.h b/src/tvheadend/entity/Event.h index f78afa99..e5ce4a75 100644 --- a/src/tvheadend/entity/Event.h +++ b/src/tvheadend/entity/Event.h @@ -56,10 +56,8 @@ class Event : public Entity m_recordingId == other.m_recordingId && m_seriesLink == other.m_seriesLink && m_year == other.m_year && m_writers == other.m_writers && m_directors == other.m_directors && m_cast == other.m_cast && - m_categories == other.m_categories && - m_ratingLabel == other.m_ratingLabel && - m_ratingIcon == other.m_ratingIcon && - m_ratingSource == other.m_ratingSource; + m_categories == other.m_categories && m_ratingLabel == other.m_ratingLabel && + m_ratingIcon == other.m_ratingIcon && m_ratingSource == other.m_ratingSource; } bool operator!=(const Event& other) const { return !(*this == other); } @@ -169,8 +167,8 @@ class Event : public Entity std::string m_cast; std::string m_categories; std::string m_aired; - std::string m_ratingLabel; // Label like 'PG' or 'FSK 12' - std::string m_ratingIcon; // Path to graphic for the above label. + std::string m_ratingLabel; // Label like 'PG' or 'FSK 12' + std::string m_ratingIcon; // Path to graphic for the above label. std::string m_ratingSource; // Parental rating source. }; diff --git a/src/tvheadend/entity/Recording.h b/src/tvheadend/entity/Recording.h index 5bbb0312..7d011a2c 100644 --- a/src/tvheadend/entity/Recording.h +++ b/src/tvheadend/entity/Recording.h @@ -83,8 +83,7 @@ class Recording : public Entity m_playPosition == other.m_playPosition && m_contentType == other.m_contentType && m_season == other.m_season && m_episode == other.m_episode && m_part == other.m_part && m_ageRating == other.m_ageRating && m_ratingLabel == other.m_ratingLabel && - m_ratingIcon == other.m_ratingIcon; - m_ratingSource == other.m_ratingSource; + m_ratingIcon == other.m_ratingIcon && m_ratingSource == other.m_ratingSource; } bool operator!=(const Recording& other) const { return !(*this == other); } diff --git a/src/tvheadend/utilities/AsyncState.h b/src/tvheadend/utilities/AsyncState.h index 4351641f..d1a95567 100644 --- a/src/tvheadend/utilities/AsyncState.h +++ b/src/tvheadend/utilities/AsyncState.h @@ -36,7 +36,7 @@ class AsyncState public: AsyncState(int timeout); - virtual ~AsyncState(){}; + virtual ~AsyncState() {} /** * @return the current state