| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * This file is part of the Falcon Player (FPP) and is Copyright (C) | ||
| 3 | * 2013-2022 by the Falcon Player Developers. | ||
| 4 | * | ||
| 5 | * The Falcon Player (FPP) is free software, and is covered under | ||
| 6 | * multiple Open Source licenses. Please see the included 'LICENSES' | ||
| 7 | * file for descriptions of what files are covered by each license. | ||
| 8 | * | ||
| 9 | * This source file is covered under the LGPL v2.1 as described in the | ||
| 10 | * included LICENSE.LGPL file. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include "fpp-pch.h" | ||
| 14 | |||
| 15 | #include "fpp-json.h" | ||
| 16 | |||
| 17 | #include <thread> | ||
| 18 | |||
| 19 | #include "../common.h" | ||
| 20 | #include "../log.h" | ||
| 21 | |||
| 22 | #include "PlaylistEntryBoth.h" | ||
| 23 | #include "mediadetails.h" | ||
| 24 | #include "../MultiSync.h" | ||
| 25 | |||
| 26 | // Longest the sequence waits for the media to become audible. Covers a cold | ||
| 27 | // audio output (~0.6 s on an AM335x, a PipeWire output stream gives up at 3 s) | ||
| 28 | // with margin; past it the sequence starts and the sync servo takes over. | ||
| 29 | static constexpr long long AUDIO_START_HOLD_MS = 4000; | ||
| 30 | |||
| 31 | 39 | PlaylistEntryBoth::PlaylistEntryBoth(Playlist* playlist, PlaylistEntryBase* parent) : | |
| 32 | PlaylistEntryBase(playlist, parent), | ||
| 33 | 39 | m_duration(0), | |
| 34 | 39 | m_mediaEntry(NULL), | |
| 35 | 39 | m_sequenceEntry(NULL) { | |
| 36 |
1/2✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
|
39 | LogDebug(VB_PLAYLIST, "PlaylistEntryBoth::PlaylistEntryBoth()\n"); |
| 37 | |||
| 38 |
1/2✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
|
39 | m_type = "both"; |
| 39 | 39 | } | |
| 40 | |||
| 41 | 76 | PlaylistEntryBoth::~PlaylistEntryBoth() { | |
| 42 |
1/2✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
|
38 | if (m_sequenceEntry) { |
| 43 |
1/2✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
|
38 | delete m_sequenceEntry; |
| 44 | } | ||
| 45 |
1/2✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
|
38 | if (m_mediaOwned) { |
| 46 |
1/2✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
|
38 | delete m_mediaOwned; |
| 47 | } | ||
| 48 | 76 | } | |
| 49 | |||
| 50 | /* | ||
| 51 | * | ||
| 52 | */ | ||
| 53 | 39 | int PlaylistEntryBoth::Init(Json::Value& config) { | |
| 54 | 39 | LogDebug(VB_PLAYLIST, "PlaylistEntryBoth::Init()\n"); | |
| 55 | |||
| 56 |
2/6✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 39 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
39 | m_sequenceEntry = new PlaylistEntrySequence(m_parentPlaylist, this); |
| 57 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
|
39 | if (!m_sequenceEntry) |
| 58 | ✗ | return 0; | |
| 59 | |||
| 60 |
2/6✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 39 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
39 | m_mediaOwned = new PlaylistEntryMedia(m_parentPlaylist, this); |
| 61 | 39 | m_mediaEntry = m_mediaOwned; | |
| 62 | |||
| 63 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
|
39 | if (!m_mediaEntry->Init(config)) { |
| 64 | // Media init failed — run sequence-only. The rest of this class | ||
| 65 | // already null-checks m_mediaEntry; the unconditional GetMediaName() | ||
| 66 | // call that used to sit below this branch dereferenced the pointer | ||
| 67 | // just nulled here. | ||
| 68 | ✗ | delete m_mediaOwned; | |
| 69 | ✗ | m_mediaOwned = nullptr; | |
| 70 | ✗ | m_mediaEntry = nullptr; | |
| 71 | } else { | ||
| 72 |
1/2✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
|
39 | m_mediaName = m_mediaEntry->GetMediaName(); |
| 73 | } | ||
| 74 | |||
| 75 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
|
39 | if (!m_sequenceEntry->Init(config)) |
| 76 | ✗ | return 0; | |
| 77 | |||
| 78 | 39 | m_sequenceName = m_sequenceEntry->GetSequenceName(); | |
| 79 | 39 | return PlaylistEntryBase::Init(config); | |
| 80 | } | ||
| 81 | |||
| 82 | /* | ||
| 83 | * | ||
| 84 | */ | ||
| 85 | 46 | int PlaylistEntryBoth::StartPlaying(void) { | |
| 86 |
1/2✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
|
46 | LogDebug(VB_PLAYLIST, "PlaylistEntryBoth::StartPlaying()\n"); |
| 87 | |||
| 88 |
1/2✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
|
46 | std::unique_lock<std::recursive_mutex> seqLock(m_mutex); |
| 89 |
2/4✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 46 times.
|
46 | if (!CanPlay()) { |
| 90 | ✗ | FinishPlay(); | |
| 91 | ✗ | return 0; | |
| 92 | } | ||
| 93 | |||
| 94 | // The sequence may start later than this (held until the media is | ||
| 95 | // audible, or after a media offset), and Process() acts on whether it is | ||
| 96 | // started or finished. On a repeating playlist's next pass it still | ||
| 97 | // carries the last pass's "started and finished" -- which ended the entry | ||
| 98 | // at once, so a repeating playlist ran through every entry in a fraction | ||
| 99 | // of a second at the wrap and never played again. | ||
| 100 |
1/2✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
|
46 | m_sequenceEntry->ResetPlayState(); |
| 101 | |||
| 102 | // Each pass decides afresh whether it has media. | ||
| 103 | 46 | m_mediaEntry = m_mediaOwned; | |
| 104 |
4/8✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 46 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 46 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 46 times.
|
46 | if (m_mediaEntry && !m_mediaEntry->PreparePlay()) { |
| 105 | ✗ | m_mediaEntry = nullptr; | |
| 106 | } | ||
| 107 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
|
46 | if (!m_mediaEntry) { |
| 108 | ✗ | LogDebug(VB_PLAYLIST, "Skipping media playlist entry, likely blacklisted audio: %s\n", m_mediaName.c_str()); | |
| 109 | } | ||
| 110 | // The media drives the timing when there is media; without it this pass, | ||
| 111 | // the sequence has to keep its own time. | ||
| 112 | 46 | m_sequenceEntry->setAdjustTiming(m_mediaEntry == nullptr); | |
| 113 |
2/4✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 46 times.
|
46 | if (!m_sequenceEntry->PreparePlay()) { |
| 114 | ✗ | LogDebug(VB_PLAYLIST, "Problems starting sequence: %s\n", m_sequenceEntry->GetSequenceName().c_str()); | |
| 115 | } | ||
| 116 | |||
| 117 |
6/8✓ Branch 0 taken 2 times.
✓ Branch 1 taken 44 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 44 times.
|
46 | if (multiSync->isMultiSyncEnabled() && m_mediaEntry && m_mediaEntry->m_openTime) { |
| 118 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | long long st = GetMonotonicTimeMS() - m_mediaEntry->m_openTime; |
| 119 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (st < PlaylistEntryMedia::m_openStartDelay) { |
| 120 | ✗ | std::this_thread::sleep_for(std::chrono::milliseconds(PlaylistEntryMedia::m_openStartDelay - st - 2)); | |
| 121 | } | ||
| 122 | } | ||
| 123 | |||
| 124 | // With media, the sequence normally starts from Process() once the media | ||
| 125 | // is audible rather than here. Starting both together put the lights | ||
| 126 | // ahead of the sound by however long the audio output took to come up -- | ||
| 127 | // most of a second on slow boards -- and they only caught up as the sync | ||
| 128 | // servo slowed them, which looks like the first second of audio is missing. | ||
| 129 |
4/6✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 46 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 37 times.
✓ Branch 5 taken 9 times.
|
46 | m_holdingForAudio = m_mediaEntry && m_mediaEntry->GetMediaOffsetMS() <= 0; |
| 130 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
|
46 | if (!m_mediaEntry) { |
| 131 | ✗ | if (!m_sequenceEntry->StartPlaying()) { | |
| 132 | ✗ | LogDebug(VB_PLAYLIST, "Could not start sequence: %s\n", m_sequenceEntry->GetSequenceName().c_str()); | |
| 133 | ✗ | FinishPlay(); | |
| 134 | ✗ | return 0; | |
| 135 | } | ||
| 136 | } | ||
| 137 |
6/8✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 46 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 45 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 45 times.
|
46 | if (m_mediaEntry && !m_mediaEntry->StartPlaying()) { |
| 138 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | LogDebug(VB_PLAYLIST, "Could not start media: %s\n", m_mediaName.c_str()); |
| 139 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | m_mediaEntry->Stop(); |
| 140 | 1 | m_mediaEntry = nullptr; | |
| 141 | 1 | m_holdingForAudio = false; | |
| 142 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | m_sequenceEntry->Stop(); |
| 143 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | FinishPlay(); |
| 144 | 1 | return 0; | |
| 145 | } | ||
| 146 |
1/2✓ Branch 0 taken 45 times.
✗ Branch 1 not taken.
|
45 | m_holdStartMS = GetMonotonicTimeMS(); |
| 147 | |||
| 148 |
1/2✓ Branch 0 taken 45 times.
✗ Branch 1 not taken.
|
45 | return PlaylistEntryBase::StartPlaying(); |
| 149 | 46 | } | |
| 150 | |||
| 151 | /* | ||
| 152 | * | ||
| 153 | */ | ||
| 154 | 121856 | int PlaylistEntryBoth::Process(void) { | |
| 155 |
1/2✓ Branch 0 taken 121856 times.
✗ Branch 1 not taken.
|
121856 | LogExcess(VB_PLAYLIST, "PlaylistEntryBoth::Process()\n"); |
| 156 |
1/2✓ Branch 0 taken 121856 times.
✗ Branch 1 not taken.
|
121856 | std::unique_lock<std::recursive_mutex> seqLock(m_mutex); |
| 157 | |||
| 158 |
1/2✓ Branch 0 taken 121856 times.
✗ Branch 1 not taken.
|
121856 | if (m_mediaEntry) |
| 159 |
1/2✓ Branch 0 taken 121856 times.
✗ Branch 1 not taken.
|
121856 | m_mediaEntry->Process(); |
| 160 | |||
| 161 |
3/4✓ Branch 0 taken 686 times.
✓ Branch 1 taken 121170 times.
✓ Branch 2 taken 686 times.
✗ Branch 3 not taken.
|
121856 | if (m_holdingForAudio && m_mediaEntry) { |
| 162 |
1/2✓ Branch 0 taken 686 times.
✗ Branch 1 not taken.
|
686 | long long held = GetMonotonicTimeMS() - m_holdStartMS; |
| 163 |
6/8✓ Branch 0 taken 686 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 650 times.
✓ Branch 3 taken 36 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 650 times.
✓ Branch 6 taken 36 times.
✓ Branch 7 taken 650 times.
|
686 | if (m_mediaEntry->IsAudible() || held >= AUDIO_START_HOLD_MS) { |
| 164 | 36 | m_holdingForAudio = false; | |
| 165 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
|
36 | if (held >= AUDIO_START_HOLD_MS) { |
| 166 | ✗ | LogWarn(VB_PLAYLIST, "No sound from %s after %lld ms, starting sequence %s anyway\n", | |
| 167 | m_mediaName.c_str(), held, m_sequenceEntry->GetSequenceName().c_str()); | ||
| 168 | } else { | ||
| 169 |
1/2✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
|
36 | LogDebug(VB_PLAYLIST, "Media audible after %lld ms, starting sequence %s\n", |
| 170 | held, m_sequenceEntry->GetSequenceName().c_str()); | ||
| 171 | } | ||
| 172 |
2/4✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 36 times.
|
36 | if (!m_sequenceEntry->StartPlaying()) { |
| 173 | ✗ | LogDebug(VB_PLAYLIST, "Could not start sequence: %s\n", m_sequenceEntry->GetSequenceName().c_str()); | |
| 174 | ✗ | m_mediaEntry->Stop(); | |
| 175 | ✗ | FinishPlay(); | |
| 176 | ✗ | return PlaylistEntryBase::Process(); | |
| 177 | } | ||
| 178 | } | ||
| 179 | } | ||
| 180 | |||
| 181 |
6/8✓ Branch 0 taken 121856 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 121856 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1663 times.
✓ Branch 5 taken 120193 times.
✓ Branch 6 taken 1663 times.
✓ Branch 7 taken 120193 times.
|
121856 | if (m_mediaEntry && m_mediaEntry->GetMediaOffsetMS() > 0) { |
| 182 |
1/2✓ Branch 0 taken 1663 times.
✗ Branch 1 not taken.
|
1663 | long long ct = GetMonotonicTimeMS(); |
| 183 | 1663 | long long df = ct - m_mediaEntry->m_startTime; | |
| 184 |
3/4✓ Branch 0 taken 1663 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1548 times.
✓ Branch 3 taken 115 times.
|
1663 | if (df > (m_mediaEntry->GetMediaOffsetMS() - m_sequenceEntry->GetSequenceFrameTime())) { |
| 185 |
3/4✓ Branch 0 taken 1548 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 1539 times.
|
1548 | if (!m_sequenceEntry->IsStarted()) { |
| 186 |
1/2✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
|
9 | m_sequenceEntry->StartPlaying(); |
| 187 | } | ||
| 188 | } | ||
| 189 | } | ||
| 190 |
3/4✓ Branch 0 taken 121856 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 121091 times.
✓ Branch 3 taken 765 times.
|
121856 | if (m_sequenceEntry->IsStarted()) { |
| 191 |
1/2✓ Branch 0 taken 121091 times.
✗ Branch 1 not taken.
|
121091 | m_sequenceEntry->Process(); |
| 192 | } | ||
| 193 | |||
| 194 |
6/8✓ Branch 0 taken 121856 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 121856 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15 times.
✓ Branch 5 taken 121841 times.
✓ Branch 6 taken 15 times.
✓ Branch 7 taken 121841 times.
|
121856 | if (m_mediaEntry && m_mediaEntry->IsFinished()) { |
| 195 |
1/2✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
|
15 | FinishPlay(); |
| 196 |
2/4✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15 times.
✗ Branch 3 not taken.
|
15 | if (!m_sequenceEntry->IsFinished()) { |
| 197 |
1/2✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
|
15 | m_sequenceEntry->Stop(); |
| 198 | } | ||
| 199 | } | ||
| 200 | |||
| 201 |
8/12✓ Branch 0 taken 121856 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 31 times.
✓ Branch 3 taken 121825 times.
✓ Branch 4 taken 31 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 31 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 31 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 31 times.
✓ Branch 11 taken 121825 times.
|
121856 | if (m_sequenceEntry->IsFinished() && (!m_mediaEntry || !m_mediaEntry->HasExtraAtEnd())) { |
| 202 |
1/2✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
|
31 | FinishPlay(); |
| 203 |
1/2✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
|
31 | if (m_mediaEntry) |
| 204 |
1/2✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
|
31 | m_mediaEntry->Stop(); |
| 205 | } | ||
| 206 | |||
| 207 | // FIXME PLAYLIST, handle sync in here somehow | ||
| 208 | |||
| 209 |
1/2✓ Branch 0 taken 121856 times.
✗ Branch 1 not taken.
|
121856 | return PlaylistEntryBase::Process(); |
| 210 | 121856 | } | |
| 211 | |||
| 212 | /* | ||
| 213 | * | ||
| 214 | */ | ||
| 215 | 6 | int PlaylistEntryBoth::Stop(void) { | |
| 216 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | LogDebug(VB_PLAYLIST, "PlaylistEntryBoth::Stop()\n"); |
| 217 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | std::unique_lock<std::recursive_mutex> seqLock(m_mutex); |
| 218 | 6 | m_holdingForAudio = false; | |
| 219 | |||
| 220 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | if (m_mediaEntry) |
| 221 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | m_mediaEntry->Stop(); |
| 222 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | m_sequenceEntry->Stop(); |
| 223 | |||
| 224 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
12 | return PlaylistEntryBase::Stop(); |
| 225 | 6 | } | |
| 226 | |||
| 227 | /* | ||
| 228 | * | ||
| 229 | */ | ||
| 230 | ✗ | void PlaylistEntryBoth::Dump(void) { | |
| 231 | ✗ | std::unique_lock<std::recursive_mutex> seqLock(m_mutex); | |
| 232 | ✗ | PlaylistEntryBase::Dump(); | |
| 233 | |||
| 234 | ✗ | if (m_mediaEntry) | |
| 235 | ✗ | m_mediaEntry->Dump(); | |
| 236 | ✗ | m_sequenceEntry->Dump(); | |
| 237 | ✗ | } | |
| 238 | |||
| 239 | 1388 | uint64_t PlaylistEntryBoth::GetLengthInMS() { | |
| 240 |
1/2✓ Branch 0 taken 1388 times.
✗ Branch 1 not taken.
|
1388 | std::unique_lock<std::recursive_mutex> seqLock(m_mutex); |
| 241 |
3/4✓ Branch 0 taken 1387 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1387 times.
✗ Branch 3 not taken.
|
1388 | uint64_t m = m_mediaEntry ? m_mediaEntry->GetLengthInMS() : 0; |
| 242 |
2/4✓ Branch 0 taken 1388 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1388 times.
✗ Branch 3 not taken.
|
1388 | uint64_t s = m_sequenceEntry ? m_sequenceEntry->GetLengthInMS() : 0; |
| 243 |
3/4✓ Branch 0 taken 1387 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1387 times.
|
1388 | if (m && m < s) { |
| 244 | // media drives it, when media completes, we stop | ||
| 245 | ✗ | return m; | |
| 246 | } | ||
| 247 | 1388 | return s; | |
| 248 | 1388 | } | |
| 249 | 2776 | uint64_t PlaylistEntryBoth::GetElapsedMS() { | |
| 250 |
1/2✓ Branch 0 taken 2776 times.
✗ Branch 1 not taken.
|
2776 | std::unique_lock<std::recursive_mutex> seqLock(m_mutex); |
| 251 |
2/2✓ Branch 0 taken 2774 times.
✓ Branch 1 taken 2 times.
|
2776 | if (m_mediaEntry) { |
| 252 |
1/2✓ Branch 0 taken 2774 times.
✗ Branch 1 not taken.
|
2774 | return m_mediaEntry->GetElapsedMS(); |
| 253 | } | ||
| 254 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if (m_sequenceEntry) { |
| 255 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | return m_sequenceEntry->GetElapsedMS(); |
| 256 | } | ||
| 257 | ✗ | return 0; | |
| 258 | 2776 | } | |
| 259 | |||
| 260 | /* | ||
| 261 | * | ||
| 262 | */ | ||
| 263 | 130 | Json::Value PlaylistEntryBoth::GetConfig(void) { | |
| 264 |
1/2✓ Branch 0 taken 130 times.
✗ Branch 1 not taken.
|
130 | std::unique_lock<std::recursive_mutex> seqLock(m_mutex); |
| 265 |
1/2✓ Branch 0 taken 130 times.
✗ Branch 1 not taken.
|
130 | Json::Value result = PlaylistEntryBase::GetConfig(); |
| 266 | |||
| 267 |
2/2✓ Branch 0 taken 129 times.
✓ Branch 1 taken 1 times.
|
130 | if (m_mediaEntry) { |
| 268 |
2/4✓ Branch 0 taken 129 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 129 times.
✗ Branch 3 not taken.
|
129 | result["media"] = m_mediaEntry->GetConfig(); |
| 269 | } else { | ||
| 270 | // fake it so the display will display the times | ||
| 271 | // where the sequence is | ||
| 272 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | result["media"] = m_sequenceEntry->GetConfig(); |
| 273 | } | ||
| 274 |
2/4✓ Branch 0 taken 130 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 130 times.
✗ Branch 3 not taken.
|
130 | result["sequence"] = m_sequenceEntry->GetConfig(); |
| 275 | |||
| 276 | 130 | return result; | |
| 277 | 130 | } | |
| 278 | |||
| 279 | ✗ | Json::Value PlaylistEntryBoth::GetMqttStatus(void) { | |
| 280 | ✗ | std::unique_lock<std::recursive_mutex> seqLock(m_mutex); | |
| 281 | ✗ | Json::Value result = PlaylistEntryBase::GetMqttStatus(); | |
| 282 | ✗ | if (m_mediaEntry) { | |
| 283 | ✗ | uint64_t l = m_mediaEntry->GetLengthInMS(); | |
| 284 | ✗ | uint64_t e = m_mediaEntry->GetElapsedMS(); | |
| 285 | ✗ | result["secondsRemaining"] = (int)((l - e) / 1000); | |
| 286 | ✗ | result["secondsTotal"] = (int)(l / 1000); | |
| 287 | ✗ | result["secondsElapsed"] = (int)(e / 1000); | |
| 288 | ✗ | result["mediaName"] = m_mediaEntry->GetMediaName(); | |
| 289 | } | ||
| 290 | ✗ | if (m_sequenceEntry) { | |
| 291 | ✗ | Json::Value se = m_sequenceEntry->GetMqttStatus(); | |
| 292 | ✗ | result["sequenceName"] = se["sequenceName"]; | |
| 293 | ✗ | result["secondsRemaining"] = se["secondsRemaining"]; | |
| 294 | ✗ | result["secondsTotal"] = se["secondsTotal"]; | |
| 295 | ✗ | result["secondsElapsed"] = se["secondsElapsed"]; | |
| 296 | ✗ | } | |
| 297 | |||
| 298 | ✗ | result["mediaTitle"] = MediaDetails::INSTANCE.title; | |
| 299 | ✗ | result["mediaArtist"] = MediaDetails::INSTANCE.artist; | |
| 300 | |||
| 301 | ✗ | return result; | |
| 302 | ✗ | } | |
| 303 | |||
| 304 | 3 | void PlaylistEntryBoth::Pause() { | |
| 305 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | std::unique_lock<std::recursive_mutex> seqLock(m_mutex); |
| 306 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | if (m_mediaEntry) |
| 307 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | m_mediaEntry->Pause(); |
| 308 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | m_sequenceEntry->Pause(); |
| 309 | 3 | } | |
| 310 | 244117 | bool PlaylistEntryBoth::IsPaused() { | |
| 311 |
1/2✓ Branch 0 taken 244117 times.
✗ Branch 1 not taken.
|
244117 | std::unique_lock<std::recursive_mutex> seqLock(m_mutex); |
| 312 |
2/2✓ Branch 0 taken 244115 times.
✓ Branch 1 taken 2 times.
|
244117 | if (m_mediaEntry) { |
| 313 |
1/2✓ Branch 0 taken 244115 times.
✗ Branch 1 not taken.
|
244115 | return m_mediaEntry->IsPaused(); |
| 314 | } | ||
| 315 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | return m_sequenceEntry->IsPaused(); |
| 316 | 244117 | } | |
| 317 | 3 | void PlaylistEntryBoth::Resume() { | |
| 318 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | std::unique_lock<std::recursive_mutex> seqLock(m_mutex); |
| 319 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | if (m_mediaEntry) |
| 320 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | m_mediaEntry->Resume(); |
| 321 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | m_sequenceEntry->Resume(); |
| 322 | 3 | } | |
| 323 |