fix sdl video sources who dont report a proper frame ts
Some checks failed
ContinuousDelivery / linux-ubuntu (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android-23]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android-23]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android-23]) (push) Has been cancelled
ContinuousDelivery / windows (windows-2022, ) (push) Has been cancelled
ContinuousDelivery / windows (windows-2022, asan) (push) Has been cancelled
ContinuousIntegration / on ubuntu-24.04-arm (push) Has been cancelled
ContinuousIntegration / asan on ubuntu-24.04-arm (push) Has been cancelled
ContinuousIntegration / on ubuntu-latest (push) Has been cancelled
ContinuousIntegration / asan on ubuntu-latest (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android-23]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android-23]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android-23]) (push) Has been cancelled
ContinuousIntegration / macos (push) Has been cancelled
ContinuousIntegration / windows (push) Has been cancelled
ContinuousDelivery / dumpsyms (push) Has been cancelled
ContinuousDelivery / release (push) Has been cancelled
Some checks failed
ContinuousDelivery / linux-ubuntu (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android-23]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android-23]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android-23]) (push) Has been cancelled
ContinuousDelivery / windows (windows-2022, ) (push) Has been cancelled
ContinuousDelivery / windows (windows-2022, asan) (push) Has been cancelled
ContinuousIntegration / on ubuntu-24.04-arm (push) Has been cancelled
ContinuousIntegration / asan on ubuntu-24.04-arm (push) Has been cancelled
ContinuousIntegration / on ubuntu-latest (push) Has been cancelled
ContinuousIntegration / asan on ubuntu-latest (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android-23]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android-23]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android-23]) (push) Has been cancelled
ContinuousIntegration / macos (push) Has been cancelled
ContinuousIntegration / windows (push) Has been cancelled
ContinuousDelivery / dumpsyms (push) Has been cancelled
ContinuousDelivery / release (push) Has been cancelled
see gamescope (0fps + constant ts)
This commit is contained in:
@@ -200,7 +200,7 @@ float DebugVideoTap::render(void) {
|
|||||||
auto delta = int64_t(new_frame_opt.value().timestampUS) - int64_t(view._v_last_ts);
|
auto delta = int64_t(new_frame_opt.value().timestampUS) - int64_t(view._v_last_ts);
|
||||||
view._v_last_ts = new_frame_opt.value().timestampUS;
|
view._v_last_ts = new_frame_opt.value().timestampUS;
|
||||||
|
|
||||||
if (view._v_interval_avg == 0) {
|
if (view._v_interval_avg == 0 || std::isinf(view._v_interval_avg) || std::isnan(view._v_interval_avg)) {
|
||||||
view._v_interval_avg = delta/1'000'000.f;
|
view._v_interval_avg = delta/1'000'000.f;
|
||||||
} else {
|
} else {
|
||||||
const float r = 0.05f;
|
const float r = 0.05f;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "./sdl_video_frame_stream2.hpp"
|
#include "./sdl_video_frame_stream2.hpp"
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
@@ -128,7 +129,12 @@ std::shared_ptr<FrameStream2I<SDLVideoFrame>> SDLVideo2InputDevice::subscribe(vo
|
|||||||
std::cout << "SDLVID: camera format: " << format_name << "\n";
|
std::cout << "SDLVID: camera format: " << format_name << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
_thread = std::thread([this, camera = std::move(camera), fps](void) {
|
_thread = std::thread([this, camera = std::move(camera)](void) {
|
||||||
|
bool use_chrono_fallback = false;
|
||||||
|
Uint64 last_timestampUS = 0;
|
||||||
|
|
||||||
|
double intervalUS_avg = 1.;
|
||||||
|
|
||||||
while (_ref > 0) {
|
while (_ref > 0) {
|
||||||
Uint64 timestampNS = 0;
|
Uint64 timestampNS = 0;
|
||||||
|
|
||||||
@@ -136,20 +142,45 @@ std::shared_ptr<FrameStream2I<SDLVideoFrame>> SDLVideo2InputDevice::subscribe(vo
|
|||||||
SDL_Surface* sdl_frame_next = SDL_AcquireCameraFrame(camera.get(), ×tampNS);
|
SDL_Surface* sdl_frame_next = SDL_AcquireCameraFrame(camera.get(), ×tampNS);
|
||||||
|
|
||||||
if (sdl_frame_next != nullptr) {
|
if (sdl_frame_next != nullptr) {
|
||||||
|
Uint64 timestampUS_correct = timestampNS/1000;
|
||||||
|
if (!use_chrono_fallback) {
|
||||||
|
if (timestampNS == 0 || last_timestampUS == timestampUS_correct) {
|
||||||
|
use_chrono_fallback = true;
|
||||||
|
std::cerr << "SDLVID: invalid or unreliable timestampNS from sdl, falling back to own mesurements!\n";
|
||||||
|
timestampUS_correct = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
|
||||||
|
} else if (last_timestampUS == 0) {
|
||||||
|
last_timestampUS = timestampUS_correct;
|
||||||
|
// HACK: skip first frame
|
||||||
|
std::cerr << "SDLVID: skipping first frame\n";
|
||||||
|
SDL_ReleaseCameraFrame(camera.get(), sdl_frame_next);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
timestampUS_correct = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last_timestampUS != 0 && timestampUS_correct != 0 && last_timestampUS != timestampUS_correct && last_timestampUS < timestampUS_correct) {
|
||||||
|
const double r = 0.15;
|
||||||
|
intervalUS_avg = std::clamp(intervalUS_avg * (1.-r) + (timestampUS_correct-last_timestampUS) * r, 1000., 500.*1000.);
|
||||||
|
}
|
||||||
|
|
||||||
SDLVideoFrame new_frame_non_owning {
|
SDLVideoFrame new_frame_non_owning {
|
||||||
timestampNS/1000,
|
timestampUS_correct,
|
||||||
sdl_frame_next
|
sdl_frame_next
|
||||||
};
|
};
|
||||||
|
|
||||||
// creates surface copies
|
// creates surface copies
|
||||||
push(new_frame_non_owning);
|
push(new_frame_non_owning);
|
||||||
|
|
||||||
|
|
||||||
|
last_timestampUS = timestampUS_correct;
|
||||||
|
|
||||||
SDL_ReleaseCameraFrame(camera.get(), sdl_frame_next);
|
SDL_ReleaseCameraFrame(camera.get(), sdl_frame_next);
|
||||||
}
|
}
|
||||||
|
|
||||||
// sleep for interval
|
// sleep for interval
|
||||||
// TODO: do we really need half?
|
// TODO: do we really need half?
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(int64_t((1000/fps)*0.5)));
|
std::this_thread::sleep_for(std::chrono::milliseconds(int64_t((intervalUS_avg/1000)*0.5)));
|
||||||
}
|
}
|
||||||
// camera destructor closes device here
|
// camera destructor closes device here
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user