aboutsummaryrefslogtreecommitdiffstats
path: root/utils/cec-follower/cec-processing.cpp
diff options
context:
space:
mode:
authorDeborah Brouwer <deborahbrouwer3563@gmail.com>2021-07-12 23:09:20 -0700
committerHans Verkuil <hverkuil-cisco@xs4all.nl>2021-07-13 09:02:23 +0200
commitd7c8faa5e6b81151866514016276db002916fe0d (patch)
treee28e906fd52bc0d419f6f428905fea11fc56a88c /utils/cec-follower/cec-processing.cpp
parent7e07a868f273af25a85c8cf7aec730853971d93c (diff)
cec-follower: emulate programmed timer recordings
Start and stop recording as timers are scheduled. Schedule future timers if a completed timer has a recording sequence. Delete overlapped and unfinished timers. Reduce available media space when a recording is completed. Signed-off-by: Deborah Brouwer <deborahbrouwer3563@gmail.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Diffstat (limited to 'utils/cec-follower/cec-processing.cpp')
-rw-r--r--utils/cec-follower/cec-processing.cpp65
1 files changed, 65 insertions, 0 deletions
diff --git a/utils/cec-follower/cec-processing.cpp b/utils/cec-follower/cec-processing.cpp
index 32375966..566444a4 100644
--- a/utils/cec-follower/cec-processing.cpp
+++ b/utils/cec-follower/cec-processing.cpp
@@ -1164,6 +1164,71 @@ void testProcessing(struct node *node, bool wallclock)
node->state.deck_skip_start = 0;
update_deck_state(node, me, CEC_OP_DECK_INFO_PLAY);
}
+
+ if (!programmed_timers.empty()) {
+ std::set<struct Timer>::iterator it = programmed_timers.begin();
+ /* Use the current minute because timers do not have second precision. */
+ time_t current_minute = time(nullptr) / 60;
+ time_t timer_start_minute = it->start_time / 60;
+ time_t timer_end_minute = (it->start_time + it->duration) / 60;
+
+ /* Start the timed recording only if the deck is not already recording. */
+ if (timer_start_minute == current_minute && !node->state.one_touch_record_on) {
+ node->state.one_touch_record_on = true;
+ node->state.recording_controlled_by_timer = true;
+ print_timers(node);
+ }
+
+ /* Delete an overlapped timer. Recording will be at best incomplete. */
+ if (timer_start_minute < current_minute &&
+ (!node->state.recording_controlled_by_timer || !node->state.one_touch_record_on)) {
+ programmed_timers.erase(*it);
+ if (show_info)
+ printf("Deleted overlapped timer.\n");
+ print_timers(node);
+ }
+
+ /* Delete finished timers. */
+ if (timer_end_minute == current_minute && node->state.recording_controlled_by_timer) {
+ node->state.one_touch_record_on = false;
+ node->state.recording_controlled_by_timer = false;
+ node->state.media_space_available -= it->duration; /* 1 MB per second */
+ /*
+ * TODO: We are only ever decreasing the amount of space available,
+ * there is no heuristic that reclaims the space.
+ */
+
+ if (it->recording_seq) {
+ struct tm *last_start_time = localtime(&(it->start_time));
+ int next_wday = (last_start_time->tm_wday + 1) % 7;
+ int days_to_move_ahead = 1;
+
+ while ((it->recording_seq & (1 << next_wday)) == 0) {
+ days_to_move_ahead++;
+ next_wday = (next_wday + 1) % 7;
+ }
+ struct Timer next_timer = {};
+ next_timer = *it;
+ last_start_time->tm_mday += days_to_move_ahead;
+ last_start_time->tm_isdst = -1;
+ next_timer.start_time = mktime(last_start_time);
+ programmed_timers.insert(next_timer);
+ }
+ programmed_timers.erase(*it);
+ if (show_info)
+ printf("Deleted finished timer.\n");
+ print_timers(node);
+ /*
+ * If the finished timer was recording, and standby was received during recording,
+ * enter standby when the recording stops unless recording device is the active source.
+ */
+ if (node->state.record_received_standby) {
+ if (node->phys_addr != node->state.active_source_pa)
+ enter_standby(node);
+ node->state.record_received_standby = false;
+ }
+ }
+ }
}
mode = CEC_MODE_INITIATOR;
doioctl(node, CEC_S_MODE, &mode);

Privacy Policy