9#include "RTSPAudioStreamer.h"
37template <
typename Platform>
42 LOGD(
"Creating RTSP Audio streamer with task");
43 m_taskRunning =
false;
44 m_throttled = throttled;
54 void setTaskParameters(uint32_t stackSize, uint8_t priority,
int core = -1) {
56 m_taskStackSize = stackSize;
57 m_taskPriority = priority;
59 LOGI(
"Task parameters set: stack=%d bytes, priority=%d, core=%d",
60 stackSize, priority, core);
62 LOGW(
"Cannot change task parameters while streaming is active");
67 LOGI(
"Starting RTP Stream with task");
69 if (this->m_audioSource !=
nullptr && !m_taskRunning) {
71 if (!m_streamingTask.
create(
"RTSPStreaming", m_taskStackSize,
72 m_taskPriority, m_taskCore)) {
73 LOGE(
"Failed to create streaming task");
74 m_taskRunning =
false;
77 m_streamingTask.setReference(
this);
79 m_last_throttle_us = micros();
80 if (m_streamingTask.begin([
this]() { this->streamingTaskLoop(); })) {
81 LOGI(
"Streaming task started successfully");
82 LOGI(
"Task: stack=%d bytes, priority=%d, core=%d, period=%d us",
83 m_taskStackSize, m_taskPriority, m_taskCore,
84 this->m_timer_period_us);
86 LOGI(
"Free heap size: %i KB", esp_get_free_heap_size() / 1000);
89 LOGE(
"Failed to start streaming task");
90 m_taskRunning =
false;
96 LOGI(
"Stopping RTP Stream with task");
98 m_taskRunning =
false;
99 m_streamingTask.
end();
103 LOGI(
"RTP Stream with task stopped - ready for restart");
106 bool isTaskRunning()
const {
return m_taskRunning; }
107 void setThrottled(
bool isThrottled) { m_throttled = isThrottled; }
108 void setFixedDelayMs(uint32_t delayUs) { this->m_fixed_delay_ms = delayUs; m_throttled =
false; }
109 void setThrottleInterval(uint32_t interval) { m_throttle_interval = interval; }
113 volatile bool m_taskRunning;
114 uint32_t m_taskStackSize = 8192;
115 uint8_t m_taskPriority = 5;
117 bool m_throttled =
true;
118 uint16_t m_fixed_delay_ms = 1;
119 uint32_t m_throttle_interval = 50;
120 uint32_t m_send_counter = 0;
121 unsigned long m_last_throttle_us = 0;
123 void streamingTaskLoop() {
124 LOGD(
"Streaming task loop iteration");
125 auto iterationStartUs = micros();
127 applyThrottling(iterationStartUs);
130 inline void applyThrottling(
unsigned long iterationStartUs) {
132 delay(m_fixed_delay_ms);
133 if (m_throttled && m_throttle_interval > 0) {
135 LOGI(
"Timer period updated; resetting throttle window to %u us",
136 (
unsigned)this->m_timer_period_us);
138 m_last_throttle_us = iterationStartUs;
141 if (m_send_counter >= m_throttle_interval) {
142 uint64_t expectedUs = (uint64_t)m_throttle_interval * (uint64_t)this->
getTimerPeriodUs();
143 unsigned long nowUs = micros();
144 uint64_t actualUs = (uint64_t)(nowUs - m_last_throttle_us);
145 if (actualUs < expectedUs) {
146 uint32_t remainingUs = (uint32_t)(expectedUs - actualUs);
147 if (remainingUs >= 1000) delay(remainingUs / 1000);
148 uint32_t remUs = remainingUs % 1000;
149 if (remUs > 0) delayMicroseconds(remUs);
152 m_last_throttle_us = micros();