2 changed files with 34 additions and 0 deletions
@ -0,0 +1,31 @@
|
||||
/* Плавно меняет потолок QP по выходному видеобитрейту. Один video worker, время в микросекундах.
|
||||
* reset вызывается при смене пользовательских настроек/encoder. update учитывает только новые encoded bytes. |
||||
* Выбранный потолок — нижняя граница адаптации: при перерасходе допускается рост до 51, затем возврат. */ |
||||
#pragma once |
||||
#include <cstdint> |
||||
|
||||
class StreamQpControl { |
||||
int m_base = -1, m_limit = -1, m_target = 0; |
||||
bool m_adaptive = false, m_sampled = false; |
||||
int64_t m_at = 0; |
||||
uint64_t m_bytes = 0, m_bitrate = 0; |
||||
public: |
||||
void reset(int base, int target, bool adaptive, int64_t now) { |
||||
m_base = m_limit = base; m_target = target; m_adaptive = adaptive; |
||||
m_at = now; m_bytes = m_bitrate = 0; m_sampled = false; |
||||
} |
||||
int limit() const { return m_limit; } |
||||
uint64_t bitrate() const { return m_bitrate; } // Сглаженный выходной битрейт, бит/с.
|
||||
int update(uint64_t bytes, int64_t now) { |
||||
m_bytes += bytes; |
||||
const int64_t elapsed = now - m_at; |
||||
if (elapsed < 2000000) return m_limit; |
||||
const uint64_t measured = m_bytes * 8000000 / elapsed; |
||||
m_bitrate = m_sampled ? (m_bitrate + measured) / 2 : measured; |
||||
m_sampled = true; m_bytes = 0; m_at = now; |
||||
if (!m_adaptive || m_base < 0 || m_target <= 0) return m_limit; |
||||
if (m_bitrate > uint64_t(m_target) * 108 / 100 && m_limit < 51) ++m_limit; |
||||
else if (m_bitrate < uint64_t(m_target) * 90 / 100 && m_limit > m_base) --m_limit; |
||||
return m_limit; |
||||
} |
||||
}; |
||||
Loading…
Reference in new issue