| 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 "Warnings.h" // WarningHolder -- needed directly for NOPCH builds | ||
| 18 | |||
| 19 | #include "../log.h" | ||
| 20 | |||
| 21 | #include "PlaylistEntryRemap.h" | ||
| 22 | #include "channeloutput/ChannelOutputSetup.h" | ||
| 23 | #include "channeloutput/processors/RemapOutputProcessor.h" | ||
| 24 | |||
| 25 | /* | ||
| 26 | * | ||
| 27 | */ | ||
| 28 | 4 | PlaylistEntryRemap::PlaylistEntryRemap(Playlist* playlist, PlaylistEntryBase* parent) : | |
| 29 | PlaylistEntryBase(playlist, parent), | ||
| 30 | 4 | m_srcChannel(0), | |
| 31 | 4 | m_dstChannel(0), | |
| 32 | 4 | m_channelCount(0), | |
| 33 | 4 | m_loops(0), | |
| 34 | 4 | m_reverse(0) { | |
| 35 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | LogDebug(VB_PLAYLIST, "PlaylistEntryRemap::PlaylistEntryRemap()\n"); |
| 36 | |||
| 37 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | m_type = "remap"; |
| 38 | 4 | } | |
| 39 | |||
| 40 | /* | ||
| 41 | * | ||
| 42 | */ | ||
| 43 | 4 | PlaylistEntryRemap::~PlaylistEntryRemap() { | |
| 44 | 4 | } | |
| 45 | |||
| 46 | /* | ||
| 47 | * | ||
| 48 | */ | ||
| 49 | 4 | int PlaylistEntryRemap::Init(Json::Value& config) { | |
| 50 | 4 | LogDebug(VB_PLAYLIST, "PlaylistEntryRemap::Init()\n"); | |
| 51 | |||
| 52 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (!config.isMember("action")) { |
| 53 | ✗ | LogErr(VB_PLAYLIST, "Missing action entry\n"); | |
| 54 | ✗ | WarningHolder::AddWarningTimeout(60, 24, "Playlist channel-remap entry is missing the 'action' field"); | |
| 55 | ✗ | return 0; | |
| 56 | } | ||
| 57 | |||
| 58 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (!config.isMember("source")) { |
| 59 | ✗ | LogErr(VB_PLAYLIST, "Missing source entry\n"); | |
| 60 | ✗ | WarningHolder::AddWarningTimeout(60, 24, "Playlist channel-remap entry is missing the 'source' field"); | |
| 61 | ✗ | return 0; | |
| 62 | } | ||
| 63 | |||
| 64 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (!config.isMember("destination")) { |
| 65 | ✗ | LogErr(VB_PLAYLIST, "Missing destination entry\n"); | |
| 66 | ✗ | WarningHolder::AddWarningTimeout(60, 24, "Playlist channel-remap entry is missing the 'destination' field"); | |
| 67 | ✗ | return 0; | |
| 68 | } | ||
| 69 | |||
| 70 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (!config.isMember("count")) { |
| 71 | ✗ | LogErr(VB_PLAYLIST, "Missing count entry\n"); | |
| 72 | ✗ | WarningHolder::AddWarningTimeout(60, 24, "Playlist channel-remap entry is missing the 'count' field"); | |
| 73 | ✗ | return 0; | |
| 74 | } | ||
| 75 | |||
| 76 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (!config.isMember("loops")) { |
| 77 | ✗ | LogErr(VB_PLAYLIST, "Missing loops entry\n"); | |
| 78 | ✗ | WarningHolder::AddWarningTimeout(60, 24, "Playlist channel-remap entry is missing the 'loops' field"); | |
| 79 | ✗ | return 0; | |
| 80 | } | ||
| 81 | |||
| 82 |
2/4✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
4 | m_action = config["action"].asString(); |
| 83 | 4 | m_srcChannel = config["source"].asInt(); | |
| 84 | 4 | m_dstChannel = config["destination"].asInt(); | |
| 85 | 4 | m_channelCount = config["count"].asInt(); | |
| 86 | 4 | m_loops = config["loops"].asInt(); | |
| 87 | 4 | m_reverse = config["reverse"].asInt(); | |
| 88 | |||
| 89 | // need to be 0 based | ||
| 90 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | if (m_srcChannel) { |
| 91 | 4 | m_srcChannel--; | |
| 92 | } | ||
| 93 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | if (m_dstChannel) { |
| 94 | 4 | m_dstChannel--; | |
| 95 | } | ||
| 96 | |||
| 97 | 4 | return PlaylistEntryBase::Init(config); | |
| 98 | } | ||
| 99 | |||
| 100 | /* | ||
| 101 | * | ||
| 102 | */ | ||
| 103 | 6 | int PlaylistEntryRemap::StartPlaying(void) { | |
| 104 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | LogDebug(VB_PLAYLIST, "PlaylistEntryRemap::StartPlaying()\n"); |
| 105 | |||
| 106 |
2/4✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
|
6 | if (!CanPlay()) { |
| 107 | ✗ | FinishPlay(); | |
| 108 | ✗ | return 0; | |
| 109 | } | ||
| 110 | |||
| 111 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | PlaylistEntryBase::StartPlaying(); |
| 112 | |||
| 113 | 4 | auto f = [this](OutputProcessor* p2) -> bool { | |
| 114 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | if (p2->getType() == OutputProcessor::REMAP) { |
| 115 | 4 | RemapOutputProcessor* rp = (RemapOutputProcessor*)p2; | |
| 116 |
5/10✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
|
4 | return rp->getSourceChannel() == this->m_srcChannel && rp->getDestChannel() == this->m_dstChannel && rp->getLoops() == this->m_loops && rp->getCount() == this->m_channelCount && rp->getReverse() == this->m_reverse; |
| 117 | } | ||
| 118 | ✗ | return false; | |
| 119 | 6 | }; | |
| 120 |
3/4✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 2 times.
|
6 | if (m_action == "add") { |
| 121 | // Once per remap: an "add" in a repeating playlist used to stack | ||
| 122 | // another identical processor every loop, applying the remap again on | ||
| 123 | // each -- with overlapping ranges the data shifted further every pass. | ||
| 124 |
3/4✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
|
4 | if (!outputProcessors.find(f)) { |
| 125 |
3/8✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
2 | RemapOutputProcessor* processor = new RemapOutputProcessor(m_srcChannel, m_dstChannel, m_channelCount, m_loops, m_reverse); |
| 126 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | outputProcessors.addProcessor(processor); |
| 127 | } | ||
| 128 |
2/4✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | } else if (m_action == "remove") { |
| 129 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | OutputProcessor* p = outputProcessors.find(f); |
| 130 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if (p) { |
| 131 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | outputProcessors.removeProcessor(p); |
| 132 | } | ||
| 133 | } | ||
| 134 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | FinishPlay(); |
| 135 | 6 | return 1; | |
| 136 | } | ||
| 137 | |||
| 138 | /* | ||
| 139 | * | ||
| 140 | */ | ||
| 141 | ✗ | void PlaylistEntryRemap::Dump(void) { | |
| 142 | ✗ | PlaylistEntryBase::Dump(); | |
| 143 | |||
| 144 | ✗ | LogDebug(VB_PLAYLIST, "Source Channel : %d\n", m_srcChannel); | |
| 145 | ✗ | LogDebug(VB_PLAYLIST, "Destination Channel: %d\n", m_dstChannel); | |
| 146 | ✗ | LogDebug(VB_PLAYLIST, "Channel Count : %d\n", m_channelCount); | |
| 147 | ✗ | LogDebug(VB_PLAYLIST, "Loop Count : %d\n", m_loops); | |
| 148 | ✗ | } | |
| 149 | |||
| 150 | /* | ||
| 151 | * | ||
| 152 | */ | ||
| 153 | 12 | Json::Value PlaylistEntryRemap::GetConfig(void) { | |
| 154 | 12 | Json::Value result = PlaylistEntryBase::GetConfig(); | |
| 155 | |||
| 156 |
2/4✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
|
12 | result["source"] = m_srcChannel + 1; |
| 157 |
2/4✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
|
12 | result["destination"] = m_dstChannel + 1; |
| 158 |
2/4✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
|
12 | result["count"] = m_channelCount; |
| 159 |
2/4✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
|
12 | result["loops"] = m_loops; |
| 160 | |||
| 161 | 12 | return result; | |
| 162 | ✗ | } | |
| 163 |