stop gap toxav video sending interval
Some checks are pending
ContinuousDelivery / linux-ubuntu (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Waiting to run
ContinuousDelivery / windows (push) Waiting to run
ContinuousDelivery / windows-asan (push) Waiting to run
ContinuousDelivery / dumpsyms (push) Blocked by required conditions
ContinuousDelivery / release (push) Blocked by required conditions
ContinuousIntegration / linux (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Waiting to run
ContinuousIntegration / macos (push) Waiting to run
ContinuousIntegration / windows (push) Waiting to run

This commit is contained in:
Green Sky 2025-03-07 16:56:24 +01:00
parent e618732f43
commit 03f2c904ce
No known key found for this signature in database
GPG Key ID: DBE05085D874AB4A
4 changed files with 39 additions and 8 deletions

View File

@ -647,7 +647,7 @@ Screen* MainScreen::tick(float time_delta, bool& quit) {
//const float av_interval = std::pow(tav.toxavIterationInterval(), 1.18)/1000.f;
const float av_interval = tav.toxavIterationInterval()/1000.f;
tavvoip.tick();
const float av_voip_interval = tavvoip.tick();
#endif
tcm.iterate(time_delta); // compute
@ -694,6 +694,10 @@ Screen* MainScreen::tick(float time_delta, bool& quit) {
_min_tick_interval,
av_interval
);
_min_tick_interval = std::min<float>(
_min_tick_interval,
av_voip_interval
);
#endif
//std::cout << "MS: min tick interval: " << _min_tick_interval << "\n";

View File

@ -109,6 +109,9 @@ struct ToxAVI : public ToxAVEventProviderI {
ToxAVI(Tox* tox);
virtual ~ToxAVI(void);
// NOTE: interval timers are only interesting for receiving streams
// if we are only sending, it will always report 195ms
// interface
// if iterate is called on a different thread, it will fire events there
uint32_t toxavIterationInterval(void) const;

View File

@ -104,6 +104,7 @@ struct ToxAVCallVideoSink : public FrameStream2SinkI<SDLVideoFrame> {
uint32_t _fid;
std::shared_ptr<stream_type> _writer;
uint64_t _last_ts {0};
ToxAVCallVideoSink(ToxAVI& toxav, uint32_t fid) : _toxav(toxav), _fid(fid) {}
~ToxAVCallVideoSink(void) {
@ -139,6 +140,7 @@ struct ToxAVCallVideoSink : public FrameStream2SinkI<SDLVideoFrame> {
if (sub == _writer) {
_writer = nullptr;
_last_ts = 0;
/*auto err = */_toxav.toxavVideoSetBitRate(_fid, 0);
// print warning? on error?
@ -350,7 +352,7 @@ void ToxAVVoIPModel::audio_thread_tick(void) {
//* `((sample rate) * (audio length) / 1000)`, where audio length can be
//* 2.5, 5, 10, 20, 40 or 60 milliseconds.
// we likely needs to subdivide/repackage
// we likely need to subdivide/repackage
// frame size should be an option exposed to the user
// with 10ms as a default ?
// the larger the frame size, the less overhead but the more delay
@ -372,7 +374,7 @@ void ToxAVVoIPModel::audio_thread_tick(void) {
void ToxAVVoIPModel::video_thread_tick(void) {
//for (const auto& [oc, vsink] : _os.registry().view<ToxAVCallVideoSink*>().each()) {
std::lock_guard lg{_video_sinks_mutex};
for (const auto* vsink : _video_sinks) {
for (auto* vsink : _video_sinks) {
if (!vsink->_writer) {
continue;
}
@ -389,6 +391,15 @@ void ToxAVVoIPModel::video_thread_tick(void) {
continue;
}
// interval estimate based on 2 frames
if (vsink->_last_ts != 0 && vsink->_last_ts < new_frame.timestampUS) {
const auto interval_us = new_frame.timestampUS - vsink->_last_ts;
if (_video_recent_interval > interval_us) {
_video_recent_interval = interval_us;
}
}
vsink->_last_ts = new_frame.timestampUS;
// conversion is done in the sink's stream
SDL_Surface* surf = new_frame.surface.get();
assert(surf != nullptr);
@ -519,7 +530,7 @@ ToxAVVoIPModel::~ToxAVVoIPModel(void) {
}
}
void ToxAVVoIPModel::tick(void) {
float ToxAVVoIPModel::tick(void) {
std::lock_guard lg{_e_queue_mutex};
while (!_e_queue.empty()) {
const auto& e_var = _e_queue.front();
@ -536,6 +547,14 @@ void ToxAVVoIPModel::tick(void) {
_e_queue.pop_front();
}
// TODO: audio (ez, just do 60ms if sending audio)
auto interval = _video_recent_interval/1'000'000.f;
// funky if tickrate momentarily higher than frame rate
_video_recent_interval = 10'000'000;
return interval;
}
ObjectHandle ToxAVVoIPModel::enter(const Contact4 c, const Components::VoIP::DefaultConfig& defaults) {

View File

@ -10,6 +10,7 @@
#include <variant>
#include <deque>
#include <mutex>
#include <atomic>
// fwd
struct ToxAVCallAudioSink;
@ -24,7 +25,7 @@ class ToxAVVoIPModel : protected ToxAVEventI, public VoIPModelI {
uint64_t _pad0;
// these events need to be worked on the main thread instead
// TODO: replac ewith lockless queue
// TODO: replace with lockless queue
std::deque<
std::variant<
Events::FriendCall,
@ -42,6 +43,11 @@ class ToxAVVoIPModel : protected ToxAVEventI, public VoIPModelI {
std::mutex _video_sinks_mutex;
uint64_t _pad3;
// filled with min() in video_thread_tick()
// ms, 10sec means none
std::atomic<uint64_t> _video_recent_interval{10'000'000};
uint64_t _pad4;
// for faster lookup
std::unordered_map<uint32_t, ObjectHandle> _audio_sources;
std::unordered_map<uint32_t, ObjectHandle> _video_sources;
@ -54,8 +60,7 @@ class ToxAVVoIPModel : protected ToxAVEventI, public VoIPModelI {
void destroySession(ObjectHandle session);
// TODO: this needs to move to the toxav thread
// we could use "events" as pre/post audio/video iterate...
// we use "events" as pre/post audio/video iterate...
void audio_thread_tick(void);
void video_thread_tick(void);
@ -67,7 +72,7 @@ class ToxAVVoIPModel : protected ToxAVEventI, public VoIPModelI {
~ToxAVVoIPModel(void);
// handle events coming from toxav thread(s)
void tick(void);
float tick(void);
public: // voip model
ObjectHandle enter(const Contact4 c, const Components::VoIP::DefaultConfig& defaults) override;