diff --git a/tools/chatgui/src/call_video_encoder.cpp b/tools/chatgui/src/call_video_encoder.cpp index 5eca0fdb..39cfb0bb 100644 --- a/tools/chatgui/src/call_video_encoder.cpp +++ b/tools/chatgui/src/call_video_encoder.cpp @@ -4,9 +4,10 @@ #include // Профиль и envelope задаются явно: автоматический выбор level при смене bitrate запрещён. -bool CallVideoEncoder::open(const LiveVideoConfig& config, uint64_t generation) { +bool CallVideoEncoder::open(const LiveVideoConfig& config, uint64_t generation, uint32_t maximumBitrate) { if (!generation || config.profile == LiveVideoProfile::Automatic || config.references != 1 - || config.bitrate < CALL_VIDEO_RATE_MIN_BPS || config.bitrate > CALL_VIDEO_RATE_MAX_BPS) { + || maximumBitrate < CALL_VIDEO_RATE_MIN_BPS || maximumBitrate > CALL_VIDEO_RATE_MAX_BPS + || config.bitrate < CALL_VIDEO_RATE_MIN_BPS || config.bitrate > maximumBitrate) { m_error = "Invalid call video encoder configuration"; DEBUG_ERROR(DEBUG_CATEGORY_CALL, "call video open invalid generation=%llu bitrate=%d profile=%d refs=%d", (unsigned long long)generation, config.bitrate, (int)config.profile, config.references); return false; @@ -16,6 +17,7 @@ bool CallVideoEncoder::open(const LiveVideoConfig& config, uint64_t generation) m_error = candidate->error(); DEBUG_ERROR(DEBUG_CATEGORY_CALL, "call video open failed: %s", qPrintable(m_error)); return false; } close(); m_encoder = std::move(candidate); m_config = config; m_config.backend = m_encoder->name(); m_generation = generation; + m_maximumBitrate = maximumBitrate; DEBUG_INFO(DEBUG_CATEGORY_CALL, "call video encoder opened generation=%llu codec=%d encoder=%s bitrate=%d level=%d", (unsigned long long)generation, config.codec, qPrintable(m_config.backend), config.bitrate, config.level); return true; } @@ -24,13 +26,14 @@ void CallVideoEncoder::close() { if (m_encoder) DEBUG_DEBUG(DEBUG_CATEGORY_CALL, "call video encoder close generation=%llu pending_request=%llu", (unsigned long long)m_generation, (unsigned long long)m_request); m_encoder.reset(); m_config = {}; m_config.bitrate = 0; m_error.clear(); - m_generation = m_request = m_lastRequest = m_lastPts = m_lastKey = 0; m_pendingBitrate = 0; m_haveFrame = false; + m_generation = m_request = m_lastRequest = m_lastPts = m_lastKey = 0; + m_pendingBitrate = m_maximumBitrate = 0; m_haveFrame = false; } // Ядро сериализует команды; повторные/чужие requests не заменяют уже ожидающую команду. bool CallVideoEncoder::requestBitrate(uint64_t generation, uint64_t request, uint32_t bitrate) { if (!m_encoder || generation != m_generation || !request || request <= m_lastRequest || m_request - || bitrate < CALL_VIDEO_RATE_MIN_BPS || bitrate > CALL_VIDEO_RATE_MAX_BPS) { + || bitrate < CALL_VIDEO_RATE_MIN_BPS || bitrate > m_maximumBitrate) { DEBUG_WARN(DEBUG_CATEGORY_CALL, "call video bitrate rejected generation=%llu/%llu request=%llu last=%llu pending=%llu bitrate=%u", (unsigned long long)generation, (unsigned long long)m_generation, (unsigned long long)request, (unsigned long long)m_lastRequest, (unsigned long long)m_request, bitrate); return false; diff --git a/tools/chatgui/src/call_video_encoder.h b/tools/chatgui/src/call_video_encoder.h index 61901d5f..21a6a6b4 100644 --- a/tools/chatgui/src/call_video_encoder.h +++ b/tools/chatgui/src/call_video_encoder.h @@ -13,7 +13,7 @@ struct CallVideoRateCompletion { class CallVideoEncoder { public: - bool open(const LiveVideoConfig& config, uint64_t generation); + bool open(const LiveVideoConfig& config, uint64_t generation, uint32_t maximumBitrate); void close(); bool requestBitrate(uint64_t generation, uint64_t request, uint32_t bitrate); // Один вход -> один выход. На false output не меняется; completion нужно обработать и на ошибке. @@ -25,6 +25,6 @@ private: LiveVideoConfig m_config; QString m_error; uint64_t m_generation = 0, m_request = 0, m_lastRequest = 0, m_lastPts = 0, m_lastKey = 0; - uint32_t m_pendingBitrate = 0; + uint32_t m_pendingBitrate = 0, m_maximumBitrate = 0; bool m_haveFrame = false; };