mirror of
https://github.com/obsproject/obs-studio.git
synced 2026-09-24 23:31:36 +08:00
libobs: Implement and use better scaling function for 64-bit integers
As os_gettime_ns() gets large the current scaling methods, mostly by casting to uint64_t, may lead to numerical overflows. Sweep the code and use util_mul_div64() where applicable. Signed-off-by: Hans Petter Selasky <hps@selasky.org>
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <util/platform.h>
|
||||
#include <util/threading.h>
|
||||
#include <util/util_uint64.h>
|
||||
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
@@ -90,8 +91,8 @@ void DeckLinkDeviceInstance::HandleAudioPacket(
|
||||
if (decklink && !static_cast<DeckLinkInput *>(decklink)->buffering) {
|
||||
currentPacket.timestamp = os_gettime_ns();
|
||||
currentPacket.timestamp -=
|
||||
(uint64_t)frameCount * 1000000000ULL /
|
||||
(uint64_t)currentPacket.samples_per_sec;
|
||||
util_mul_div64(frameCount, 1000000000ULL,
|
||||
currentPacket.samples_per_sec);
|
||||
}
|
||||
|
||||
int maxdevicechannel = device->GetMaxChannel();
|
||||
@@ -113,7 +114,7 @@ void DeckLinkDeviceInstance::HandleAudioPacket(
|
||||
}
|
||||
|
||||
nextAudioTS = timestamp +
|
||||
((uint64_t)frameCount * 1000000000ULL / 48000ULL) + 1;
|
||||
util_mul_div64(frameCount, 1000000000ULL, 48000ULL) + 1;
|
||||
|
||||
obs_source_output_audio(
|
||||
static_cast<DeckLinkInput *>(decklink)->GetSource(),
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "decklink-devices.hpp"
|
||||
|
||||
#include "../../libobs/media-io/video-scaler.h"
|
||||
#include "../../libobs/util/util_uint64.h"
|
||||
|
||||
static void decklink_output_destroy(void *data)
|
||||
{
|
||||
@@ -127,8 +128,8 @@ static bool prepare_audio(DeckLinkOutput *decklink,
|
||||
*output = *frame;
|
||||
|
||||
if (frame->timestamp < decklink->start_timestamp) {
|
||||
uint64_t duration = (uint64_t)frame->frames * 1000000000 /
|
||||
(uint64_t)decklink->audio_samplerate;
|
||||
uint64_t duration = util_mul_div64(frame->frames, 1000000000ULL,
|
||||
decklink->audio_samplerate);
|
||||
uint64_t end_ts = frame->timestamp + duration;
|
||||
uint64_t cutoff;
|
||||
|
||||
@@ -138,7 +139,8 @@ static bool prepare_audio(DeckLinkOutput *decklink,
|
||||
cutoff = decklink->start_timestamp - frame->timestamp;
|
||||
output->timestamp += cutoff;
|
||||
|
||||
cutoff *= (uint64_t)decklink->audio_samplerate / 1000000000;
|
||||
cutoff = util_mul_div64(cutoff, decklink->audio_samplerate,
|
||||
1000000000ULL);
|
||||
|
||||
for (size_t i = 0; i < decklink->audio_planes; i++)
|
||||
output->data[i] +=
|
||||
|
||||
@@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include <util/bmem.h>
|
||||
#include <util/platform.h>
|
||||
#include <util/threading.h>
|
||||
#include <util/util_uint64.h>
|
||||
#include <obs-module.h>
|
||||
|
||||
#include <alsa/asoundlib.h>
|
||||
@@ -562,8 +563,9 @@ void *_alsa_listen(void *attr)
|
||||
}
|
||||
|
||||
out.frames = frames;
|
||||
out.timestamp = os_gettime_ns() -
|
||||
((frames * NSEC_PER_SEC) / data->rate);
|
||||
out.timestamp =
|
||||
os_gettime_ns() -
|
||||
util_mul_div64(frames, NSEC_PER_SEC, data->rate);
|
||||
|
||||
if (!data->first_ts)
|
||||
data->first_ts = out.timestamp + STARTUP_TIMEOUT_NS;
|
||||
|
||||
@@ -17,6 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <util/platform.h>
|
||||
#include <util/bmem.h>
|
||||
#include <util/util_uint64.h>
|
||||
#include <obs-module.h>
|
||||
|
||||
#include "pulse-wrapper.h"
|
||||
@@ -161,7 +162,7 @@ static pa_channel_map pulse_channel_map(enum speaker_layout layout)
|
||||
|
||||
static inline uint64_t samples_to_ns(size_t frames, uint_fast32_t rate)
|
||||
{
|
||||
return frames * NSEC_PER_SEC / rate;
|
||||
return util_mul_div64(frames, NSEC_PER_SEC, rate);
|
||||
}
|
||||
|
||||
static inline uint64_t get_sample_time(size_t frames, uint_fast32_t rate)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <obs-module.h>
|
||||
#include <util/circlebuf.h>
|
||||
#include <util/util_uint64.h>
|
||||
|
||||
#ifndef SEC_TO_NSEC
|
||||
#define SEC_TO_NSEC 1000000000ULL
|
||||
@@ -199,7 +200,8 @@ async_delay_filter_audio(void *data, struct obs_audio_data *audio)
|
||||
|
||||
filter->last_audio_ts = audio->timestamp;
|
||||
|
||||
duration = (uint64_t)audio->frames * SEC_TO_NSEC / filter->samplerate;
|
||||
duration =
|
||||
util_mul_div64(audio->frames, SEC_TO_NSEC, filter->samplerate);
|
||||
end_ts = audio->timestamp + duration;
|
||||
|
||||
for (size_t i = 0; i < MAX_AV_PLANES; i++) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <obs-module.h>
|
||||
#include <util/circlebuf.h>
|
||||
#include <util/util_uint64.h>
|
||||
|
||||
#define S_DELAY_MS "delay_ms"
|
||||
#define T_DELAY_MS obs_module_text("DelayMs")
|
||||
@@ -90,8 +91,7 @@ static inline void check_interval(struct gpu_delay_filter_data *f)
|
||||
|
||||
obs_get_video_info(&ovi);
|
||||
|
||||
interval_ns =
|
||||
(uint64_t)ovi.fps_den * 1000000000ULL / (uint64_t)ovi.fps_num;
|
||||
interval_ns = util_mul_div64(ovi.fps_den, 1000000000ULL, ovi.fps_num);
|
||||
|
||||
if (interval_ns != f->interval_ns)
|
||||
update_interval(f, interval_ns);
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <windows.h>
|
||||
#include <dxgi.h>
|
||||
#include <util/sse-intrin.h>
|
||||
#include <util/util_uint64.h>
|
||||
#include <ipc-util/pipe.h>
|
||||
#include "obfuscate.h"
|
||||
#include "inject-library.h"
|
||||
@@ -729,7 +730,8 @@ static inline void reset_frame_interval(struct game_capture *gc)
|
||||
uint64_t interval = 0;
|
||||
|
||||
if (obs_get_video_info(&ovi)) {
|
||||
interval = ovi.fps_den * 1000000000ULL / ovi.fps_num;
|
||||
interval =
|
||||
util_mul_div64(ovi.fps_den, 1000000000ULL, ovi.fps_num);
|
||||
|
||||
/* Always limit capture framerate to some extent. If a game
|
||||
* running at 900 FPS is being captured without some sort of
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <util/windows/WinHandle.hpp>
|
||||
#include <util/windows/CoTaskMemPtr.hpp>
|
||||
#include <util/threading.h>
|
||||
#include <util/util_uint64.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -464,8 +465,8 @@ bool WASAPISource::ProcessCaptureData()
|
||||
data.timestamp = useDeviceTiming ? ts * 100 : os_gettime_ns();
|
||||
|
||||
if (!useDeviceTiming)
|
||||
data.timestamp -= (uint64_t)frames * 1000000000ULL /
|
||||
(uint64_t)sampleRate;
|
||||
data.timestamp -= util_mul_div64(frames, 1000000000ULL,
|
||||
sampleRate);
|
||||
|
||||
obs_source_output_audio(source, &data);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user