diff --git a/sources b/sources index 1c6234a..17f8c2d 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (vdr-live-3.5.3.tar.gz) = b41e559d8bfe1d21301bfc852f91c92155baed49823d2bbf8fe9d36955b93ddd8aaebf4e4ba2fc1427c60876f2889a36846ca894f320fb5e6b7cdb37f6ac2a58 +SHA512 (vdr-live-3.3.5.tar.gz) = 1ca2fc854f691acea3efebbd4cbac0b211801e8fe7d80b3d9678c71d86d392de4133a2837322fdc9b28ca3f27ce8e3b05cead512e670ff9d98ea42affb4bbffa diff --git a/vdr-live-timerconflict.patch b/vdr-live-timerconflict.patch new file mode 100644 index 0000000..847ccef --- /dev/null +++ b/vdr-live-timerconflict.patch @@ -0,0 +1,15 @@ +diff --git a/timerconflict.h b/timerconflict.h +index f394f0b..9d61493 100644 +--- a/timerconflict.h ++++ b/timerconflict.h +@@ -7,6 +7,10 @@ + #include + #include + ++#if TNTVERSION >= 30000 ++ #include // must be loaded before any vdr include because of duplicate macros (LOG_ERROR, LOG_DEBUG, LOG_INFO) ++#endif ++ + #include + + namespace vdrlive { diff --git a/vdr-live.spec b/vdr-live.spec index 4c5997e..4494f19 100644 --- a/vdr-live.spec +++ b/vdr-live.spec @@ -1,26 +1,23 @@ -# https://github.com/MarkusEh/vdr-plugin-live/commit/9967f1d6757a4f4855a6b07abf526258838dd5ac -%global commit0 9967f1d6757a4f4855a6b07abf526258838dd5ac +# https://github.com/MarkusEh/vdr-plugin-live/commit/0fbd9b32fc6afcdbe8722daa0e772260cd058f41 +%global commit0 0fbd9b32fc6afcdbe8722daa0e772260cd058f41 %global shortcommit0 %(c=%{commit0}; echo ${c:0:7}) -%global gitdate 20241103 -# Set vdr_version based on Fedora version -%if 0%{?fedora} >= 43 -%global vdr_version 2.7.7 -%elif 0%{?fedora} == 42 -%global vdr_version 2.7.4 -%else -%global vdr_version 2.6.9 +%global gitdate 20211228 +# version we want build against +%global vdr_version 2.6.3 +%if 0%{?fedora} >= 40 +%global vdr_version 2.6.7 %endif Name: vdr-live -Version: 3.5.3 -# Release: 0.2.%%{gitdate}git%%{shortcommit0}%%{?dist} +Version: 3.3.5 +#Release: 0.4.%%{gitdate}git%%{shortcommit0}%%{?dist} Release: 1%{?dist} Summary: An interactive web interface with HTML5 live stream support for VDR -# The entire source code is GPL-2.0-or-later except live/js/mootools/ which is LicenseRef-Callaway-MIT -License: GPL-2.0-or-later AND LicenseRef-Callaway-MIT +# The entire source code is GPLv2+ except live/js/mootools/ which is MIT +License: GPLv2+ and MIT URL: https://github.com/MarkusEh/vdr-plugin-live -# Source0: https://github.com/MarkusEh/vdr-plugin-live/archive/%%{commit0}/%%{name}-%%{version}-%%{shortcommit0}.tar.gz +#Source0: https://github.com/MarkusEh/vdr-plugin-live/archive/%%{commit0}/%%{name}-%%{version}-%%{shortcommit0}.tar.gz Source0: https://github.com/MarkusEh/vdr-plugin-live/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz Source1: %{name}.conf @@ -53,7 +50,7 @@ Requires: %{name} = %{version}-%{release} This package contains images, themes and JavaScript. %prep -#%%autosetup -p1 -n vdr-plugin-live-%{commit0} +#%%autosetup -p1 -n vdr-plugin-live-%%{commit0} %autosetup -p1 -n vdr-plugin-live-%{version} # delete unused directories and files @@ -80,98 +77,12 @@ install -Dpm 644 %{SOURCE1} \ %doc CONTRIBUTORS README %license COPYING %config(noreplace) %{_sysconfdir}/sysconfig/vdr-plugins.d/live.conf -%config(noreplace) %{_sysconfdir}/vdr/plugins/live/ffmpeg.conf %{vdr_plugindir}/libvdr-*.so.%{vdr_apiversion} %files data %{vdr_resdir}/plugins/live/ %changelog -* Fri Dec 19 2025 Martin Gansser - 3.5.3-1 -- Update to 3.5.3 - -* Fri Oct 10 2025 Martin Gansser - 3.5.2-1 -- Update to 3.5.2 - -* Fri Jul 25 2025 Martin Gansser - 3.5.1-3 -- Rebuilt for new VDR API version 2.7.7 - -* Fri Jul 25 2025 Fedora Release Engineering - 3.5.1-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild - -* Tue Jul 01 2025 Martin Gansser - 3.5.1-1 -- Update to 3.5.1 - -* Sat Jun 21 2025 Martin Gansser - 3.5.0-3 -- Rebuilt for new VDR API version 2.7.6 - -* Tue May 27 2025 Martin Gansser - 3.5.0-2 -- Rebuilt for new VDR API version 2.7.5 - -* Sat Apr 19 2025 Martin Gansser - 3.5.0-1 -- Update to 3.5.0 - -* Sun Mar 02 2025 Martin Gansser - 3.4.2-1 -- Update to 3.4.2 - -* Fri Feb 28 2025 Martin Gansser - 3.4.1-3 -- Rebuilt for new VDR API version 2.7.4 - -* Thu Feb 06 2025 Martin Gansser - 3.4.1-2 -- Rebuild - -* Tue Feb 04 2025 Martin Gansser - 3.4.1-1 -- Update to 3.4.1 - -* Sun Jan 19 2025 Fedora Release Engineering - 3.4.0-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild - -* Thu Jan 02 2025 Martin Gansser - 3.4.0-1 -- Update to 3.4.0 - -* Sun Dec 22 2024 Martin Gansser - 3.3.12-1 -- Update to 3.3.12 - -* Wed Dec 11 2024 Martin Gansser - 3.3.11-1 -- Update to 3.3.11 - -* Tue Nov 19 2024 Martin Gansser - 3.3.10-1 -- Update to 3.3.10 - -* Tue Nov 05 2024 Martin Gansser - 3.3.9-1 -- Update to 3.3.9 - -* Sun Nov 03 2024 Martin Gansser - 3.3.9-0.2.20241103git9967f1d -- Update to 3.3.9-0.2.20241103git9967f1d - -* Sat Nov 02 2024 Martin Gansser - 3.3.9-0.1.20241101gitf67dfc0 -- Update to 3.3.9-0.1.20241101gitf67dfc0 - -* Sat Oct 26 2024 Martin Gansser - 3.3.8-1 -- Update to 3.3.8 - -* Tue Oct 22 2024 Martin Gansser - 3.3.8-0.2.20241022git8b97db3 -- Update to 3.3.8-0.2.20241022git8b97db3 - -* Wed Oct 09 2024 Martin Gansser - 3.3.8-0.1.20241008git80b8da8 -- Rebuilt for new VDR API version 2.7.2 -- Update to 3.3.8-0.1.20241008git80b8da8 - -* Mon Sep 30 2024 Martin Gansser - 3.3.7-1 -- Update to 3.3.7 - -* Wed Sep 04 2024 Miroslav Suchý - 3.3.5-5 -- convert license to SPDX - -* Sat Jul 20 2024 Fedora Release Engineering - 3.3.5-4 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild - -* Mon Jul 15 2024 Martin Gansser - 3.3.5-3 -- Rebuilt for new VDR API version 2.6.9 - -* Fri Jul 12 2024 Martin Gansser - 3.3.5-2 -- Rebuilt for new VDR API version 2.6.8 - * Fri Apr 12 2024 Martin Gansser - 3.3.5-1 - Update to 3.3.5 - Rebuilt for new VDR API version diff --git a/vdr-plugin-live-noCopyTimer.patch b/vdr-plugin-live-noCopyTimer.patch new file mode 100644 index 0000000..50603ca --- /dev/null +++ b/vdr-plugin-live-noCopyTimer.patch @@ -0,0 +1,378 @@ +diff -Naur vdr-plugin-live-3.0.10/pages/searchresults.ecpp vdr-plugin-live-master/pages/searchresults.ecpp +--- vdr-plugin-live-3.0.10/pages/searchresults.ecpp 2021-07-18 14:51:47.000000000 +0200 ++++ vdr-plugin-live-master/pages/searchresults.ecpp 2021-09-10 14:11:46.000000000 +0200 +@@ -62,53 +62,60 @@ + <%cpp> + std::string current_day = ""; + +-#if VDRVERSNUM >= 20301 +- LOCK_CHANNELS_READ; +-#endif + for (SearchResults::iterator result = results.begin(); result != results.end(); ++result) { + #if VDRVERSNUM >= 20301 +- cChannel* channel = (cChannel *)Channels->GetByChannelID(result->Channel()); ++ cStateKey StateKey; ++ if (const cChannels *Channels = cChannels::GetChannelsRead(StateKey)) { ++ #ifdef DEBUG_LOCK ++ dsyslog("live: pages/searchresults.ecpp LOCK_CHANNELS_READ"); ++ #endif ++ cChannel* channel = (cChannel *)Channels->GetByChannelID(result->Channel()); + #else + cChannel* channel = Channels.GetByChannelID(result->Channel()); + #endif +- if (!channel) continue; +- std::string channelname = channel->Name(); +- int channelnr = channel->Number(); +- std::string start(result->StartTime() ? FormatDateTime(tr("%I:%M %p"), result->StartTime()) : ""); +- std::string end(result->StopTime() ? FormatDateTime(tr("%I:%M %p"), result->StopTime()) : ""); +- std::string day(result->StartTime() ? FormatDateTime(tr("%A, %b %d %Y"), result->StartTime()) : ""); +- std::string description = result->Description(); +- std::string epgid = EpgEvents::EncodeDomId(result->Channel(), result->EventId()); ++ if (!channel) { ++ StateKey.Remove(); ++ continue; ++ } ++ std::string channelname = channel->Name(); ++ int channelnr = channel->Number(); ++ std::string start(result->StartTime() ? FormatDateTime(tr("%I:%M %p"), result->StartTime()) : ""); ++ std::string end(result->StopTime() ? FormatDateTime(tr("%I:%M %p"), result->StopTime()) : ""); ++ std::string day(result->StartTime() ? FormatDateTime(tr("%A, %b %d %Y"), result->StartTime()) : ""); ++ std::string description = result->Description(); ++ std::string epgid = EpgEvents::EncodeDomId(result->Channel(), result->EventId()); + +- bool truncated = false; ++ bool truncated = false; + +- bool bottom = false; +- SearchResults::iterator nextResult = result; ++nextResult; +- if (nextResult == results.end()) +- bottom = true; +- else { +- std::string nextDay(nextResult->StartTime() ? FormatDateTime(tr("%A, %b %d %Y"), nextResult->StartTime()) : ""); +- bottom = (day != nextDay); +- } ++ bool bottom = false; ++ SearchResults::iterator nextResult = result; ++nextResult; ++ if (nextResult == results.end()) ++ bottom = true; ++ else { ++ std::string nextDay(nextResult->StartTime() ? FormatDateTime(tr("%A, %b %d %Y"), nextResult->StartTime()) : ""); ++ bottom = (day != nextDay); ++ } + +- if (current_day != day) { +- if (current_day != "") { ++ if (current_day != day) { ++ if (current_day != "") { + +- +- +- ++ ++ ++ ++% } ++ ++
<$ day $>
++ ++% current_day = day; + % } +- +-
<$ day $>
+- +-% current_day = day; ++% StateKey.Remove(); // release channels read lock before calling event_timer which make a timers read lock ++ ++ "><& pageelems.event_timer epgid=(epgid) &> ++ "> ++ ">
<$ start $> - <$ end $>
++ "> ++ + % } +- +- "><& pageelems.event_timer epgid=(epgid) &> +- "> +- ">
<$ start $> - <$ end $>
+- "> +- + % } + + +diff -Naur vdr-plugin-live-3.0.10/pages/timers.ecpp vdr-plugin-live-master/pages/timers.ecpp +--- vdr-plugin-live-3.0.10/pages/timers.ecpp 2021-07-18 14:51:47.000000000 +0200 ++++ vdr-plugin-live-master/pages/timers.ecpp 2021-09-10 14:11:46.000000000 +0200 +@@ -37,7 +37,7 @@ + timer = 0; + if ( !timerid.empty() ) { + std::string tId = SortedTimers::DecodeDomId(timerid); +- // dsyslog("live: DEBUG: TIMER: tId = %s", tId.c_str()); ++// dsyslog("live: DEBUG: TIMER: tId = %s", tId.c_str()); + timer = timers.GetByTimerId(tId); + if ( timer == 0 ) + throw HtmlError( tr("Couldn't find timer. Maybe you mistyped your request?") ); +@@ -70,25 +70,26 @@ + <& pageelems.logo &> + <& menu active=("timers") component=("timers.timer_actions")> +
+-% if (timers.size() == 0) { ++<%cpp> ++ #ifdef DEBUG_LOCK ++ dsyslog("live: pages/timers.ecpp LOCK_TIMERS_READ"); ++ #endif ++ LOCK_TIMERS_READ; ++ cSortedTimers sortedTimers(Timers); ++ if (sortedTimers.Size() == 0) { ++ + <$ tr("No timer defined") $> + % } else { + + <%cpp> + // output of the timer list: +- for (SortedTimers::iterator timer = timers.begin(); timer != timers.end(); ++timer) { +- EpgInfoPtr epgEvent; ++ for (int i = 0; i < sortedTimers.Size(); i++) { ++ const cTimer *timer = sortedTimers[i]; ++ EpgInfoPtr epgEvent; + std::string longDescription; + std::string searchTimName; + std::string searchTimId; +-#if VDRVERSNUM >= 20301 +- if (!timer->Event()) { +- LOCK_SCHEDULES_READ; +- timer->SetEventFromSchedule(Schedules); +- } +-#else +- if (!timer->Event()) timer->SetEventFromSchedule(); +-#endif ++ + if (timer->Event()) + { + epgEvent = EpgEvents::CreateEpgInfo(timer->Channel(), timer->Event()); +@@ -98,13 +99,13 @@ + searchTimName = SortedTimers::SearchTimerInfo(*timer, "searchtimer"); + searchTimId = SortedTimers::SearchTimerInfo(*timer, "s-id"); + } +- std::string currentDay = SortedTimers::GetTimerDays(*timer); +- SortedTimers::iterator nextTimer = timer; ++nextTimer; ++ std::string currentDay = SortedTimers::GetTimerDays(timer); ++ const cTimer *nextTimer = NULL; ++ if (i < (sortedTimers.Size() - 1)) nextTimer = sortedTimers[i + 1]; + bool bottom = false; +- if (nextTimer == timers.end()) +- bottom = true; ++ if (i == sortedTimers.Size() - 1) bottom = true; + else { +- std::string nextDay = SortedTimers::GetTimerDays(*nextTimer); ++ std::string nextDay = SortedTimers::GetTimerDays(nextTimer); + bottom = (currentDay != nextDay); + } + if (previousDay != currentDay) { +diff -Naur vdr-plugin-live-3.0.10/timers.cpp vdr-plugin-live-master/timers.cpp +--- vdr-plugin-live-3.0.10/timers.cpp 2021-07-18 14:51:47.000000000 +0200 ++++ vdr-plugin-live-master/timers.cpp 2021-09-10 14:11:46.000000000 +0200 +@@ -11,11 +11,6 @@ + #include + #include + +-static bool operator<( cTimer const& left, cTimer const& right ) +-{ +- return left.Compare( right ) < 0; +-} +- + namespace vdrlive { + + static char const* const TIMER_DELETE = "DELETE"; +@@ -26,7 +21,6 @@ + : m_state( 0 ) + #endif + { +- ReloadTimers(); + } + + std::string SortedTimers::GetTimerId( cTimer const& timer ) +@@ -46,6 +40,11 @@ + } + + #if VDRVERSNUM >= 20301 ++ #ifdef DEBUG_LOCK ++ dsyslog("live: timers.cpp SortedTimers::GetByTimerId() LOCK_TIMERS_READ"); ++ dsyslog("live: timers.cpp SortedTimers::GetByTimerId() LOCK_CHANNELS_READ"); ++ #endif ++ LOCK_TIMERS_READ + LOCK_CHANNELS_READ; + cChannel* channel = (cChannel *)Channels->GetByChannelID( tChannelID::FromString( parts[0].c_str() ) ); + #else +@@ -64,7 +63,7 @@ + + cMutexLock MutexLock(&m_mutex); + +- for ( SortedTimers::iterator timer = begin(); timer != end(); ++timer ) { ++ for (cTimer* timer = (cTimer *)Timers->First(); timer; timer = (cTimer *)Timers->Next(timer)) { + if ( timer->Channel() == channel && + ( ( weekdays != 0 && timer->WeekDays() == weekdays ) || ( weekdays == 0 && timer->Day() == day ) ) && + timer->Start() == start && timer->Stop() == stop ) +@@ -94,33 +93,12 @@ + } + + +- void SortedTimers::ReloadTimers() +- { +-// dsyslog("live: SortedTimers::ReloadTimers() reloading timers"); +- +- cMutexLock MutexLock(&m_mutex); +- +- clear(); +-#if VDRVERSNUM >= 20301 +- { +- LOCK_TIMERS_READ; +- for ( cTimer* timer = (cTimer *)Timers->First(); timer; timer = (cTimer *)Timers->Next( timer ) ) { +- push_back( *timer ); +- } +- } +-#else +- for ( cTimer* timer = Timers.First(); timer; timer = Timers.Next( timer ) ) { +- push_back( *timer ); +- } +-#endif +- sort(); +- } +- +- std::string SortedTimers::GetTimerDays(cTimer const& timer) ++ std::string SortedTimers::GetTimerDays(cTimer const *timer) + { +- std::string currentDay = timer.WeekDays() > 0 ? +- *cTimer::PrintDay(0, timer.WeekDays(), true) : +- FormatDateTime(tr("%A, %x"), timer.Day()); ++ if (!timer) return ""; ++ std::string currentDay = timer->WeekDays() > 0 ? ++ *cTimer::PrintDay(0, timer->WeekDays(), true) : ++ FormatDateTime(tr("%A, %x"), timer->Day()); + return currentDay; + } + +@@ -269,7 +247,6 @@ + if ( m_updateTimers.size() > 0 ) { + DoUpdateTimers(); + } +- DoReloadTimers(); + // dsyslog("live: SV: signalling waiters"); + m_updateWait.Broadcast(); + } +@@ -332,6 +309,9 @@ + } + #if VDRVERSNUM >= 20301 + dsyslog("live: DoInsertTimer() add local timer"); ++ #ifdef DEBUG_LOCK ++ dsyslog("live: timers.cpp TimerManager::DoInsertTimer() LOCK_TIMERS_WRITE"); ++ #endif + LOCK_TIMERS_WRITE; + Timers->SetExplicitModify(); + const cTimer *checkTimer = Timers->GetTimer( newTimer.get() ); +@@ -418,6 +398,9 @@ + else { // old and new are local + dsyslog("live: DoUpdateTimer() old and new timer are local"); + #if VDRVERSNUM >= 20301 ++ #ifdef DEBUG_LOCK ++ dsyslog("live: timers.cpp TimerManager::DoUpdateTimer() LOCK_TIMERS_WRITE"); ++ #endif + LOCK_TIMERS_WRITE; + Timers->SetExplicitModify(); + cTimer* oldTimer = Timers->GetById( timerData.id, timerData.oldRemote ); +@@ -494,6 +477,9 @@ + #endif + + #if VDRVERSNUM >= 20301 ++ #ifdef DEBUG_LOCK ++ dsyslog("live: timers.cpp TimerManager::DoDeleteTimer() LOCK_TIMERS_WRITE"); ++ #endif + LOCK_TIMERS_WRITE; + Timers->SetExplicitModify(); + cTimer* oldTimer = Timers->GetById( timerData.id, timerData.remote ); +@@ -527,6 +513,9 @@ + void TimerManager::DoToggleTimer( timerStruct& timerData ) + { + if ( timerData.remote ) { // toggle remote timer via svdrpsend ++ #ifdef DEBUG_LOCK ++ dsyslog("live: timers.cpp TimerManager::DoToggleTimer() LOCK_TIMERS_READ"); ++ #endif + LOCK_TIMERS_READ; + const cTimer* toggleTimer = Timers->GetById( timerData.id, timerData.remote ); + std::string command = "MODT "; +@@ -571,6 +560,9 @@ + #endif + + #if VDRVERSNUM >= 20301 ++ #ifdef DEBUG_LOCK ++ dsyslog("live: timers.cpp TimerManager::DoToggleTimer() LOCK_TIMERS_WRITE"); ++ #endif + LOCK_TIMERS_WRITE; + Timers->SetExplicitModify(); + cTimer* toggleTimer = Timers->GetById( timerData.id, timerData.remote ); +@@ -616,20 +608,18 @@ + const cTimer* TimerManager::GetTimer(tEventID eventid, tChannelID channelid) + { + cMutexLock timersLock( &LiveTimerManager() ); +- SortedTimers& timers = LiveTimerManager().GetTimers(); + +- for ( SortedTimers::iterator timer = timers.begin(); timer != timers.end(); ++timer ) ++ #ifdef DEBUG_LOCK ++ dsyslog("live: timers.cpp TimerManager::GetTimer() LOCK_TIMERS_READ"); ++ #endif ++ LOCK_TIMERS_READ; ++ for (cTimer* timer = (cTimer *)Timers->First(); timer; timer = (cTimer *)Timers->Next(timer)) { + if (timer->Channel() && timer->Channel()->GetChannelID() == channelid) + { +-#if VDRVERSNUM >= 20301 +- LOCK_SCHEDULES_READ; +- if (!timer->Event()) timer->SetEventFromSchedule(Schedules); +-#else +- if (!timer->Event()) timer->SetEventFromSchedule(); +-#endif + if (timer->Event() && timer->Event()->EventID() == eventid) + return &*timer; + } ++ } + return NULL; + } + +diff -Naur vdr-plugin-live-3.0.10/timers.h vdr-plugin-live-master/timers.h +--- vdr-plugin-live-3.0.10/timers.h 2021-07-18 14:51:47.000000000 +0200 ++++ vdr-plugin-live-master/timers.h 2021-09-10 14:11:46.000000000 +0200 +@@ -31,7 +31,7 @@ + bool Modified() { return Timers.Modified(m_state); } + #endif + +- static std::string GetTimerDays(cTimer const& timer); ++ static std::string GetTimerDays(cTimer const *timer); + static std::string GetTimerInfo(cTimer const& timer); + static std::string SearchTimerInfo(cTimer const& timer, std::string const& value); + +@@ -47,7 +47,6 @@ + int m_state; + #endif + +- void ReloadTimers(); + }; + + class TimerManager: public cMutex +@@ -64,7 +63,6 @@ + void ToggleTimerActive( int timerId, const char* remote); + // may only be called from Plugin::MainThreadHook + void DoPendingWork(); +- void DoReloadTimers() { m_timers.ReloadTimers(); m_reloadTimers = false; } + const cTimer* GetTimer(tEventID eventid, tChannelID channelid); + void SetReloadTimers() { m_reloadTimers = true; } + +diff -Naur vdr-plugin-live-3.0.10/tools.h vdr-plugin-live-master/tools.h +--- vdr-plugin-live-3.0.10/tools.h 2021-07-18 14:51:47.000000000 +0200 ++++ vdr-plugin-live-master/tools.h 2021-09-10 14:11:46.000000000 +0200 +@@ -1,6 +1,9 @@ + #ifndef VDR_LIVE_TOOLS_H + #define VDR_LIVE_TOOLS_H + ++// uncomment to debug lock sequence ++// #define DEBUG_LOCK ++ + // STL headers need to be before VDR tools.h (included by ) + #include + #include