提交 0e4ea14b 编写于 作者: H Hans Petter Selasky

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: NHans Petter Selasky <hps@selasky.org>
上级 47058d9b
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include <obs.hpp> #include <obs.hpp>
#include <util/platform.h> #include <util/platform.h>
#include <util/util_uint64.h>
#include <graphics/vec4.h> #include <graphics/vec4.h>
#include <graphics/graphics.h> #include <graphics/graphics.h>
#include <graphics/math-extra.h> #include <graphics/math-extra.h>
...@@ -413,12 +414,14 @@ void AutoConfigTestPage::TestBandwidthThread() ...@@ -413,12 +414,14 @@ void AutoConfigTestPage::TestBandwidthThread()
cv.wait(ul); cv.wait(ul);
uint64_t total_time = os_gettime_ns() - t_start; uint64_t total_time = os_gettime_ns() - t_start;
if (total_time == 0)
total_time = 1;
int total_bytes = int total_bytes =
(int)obs_output_get_total_bytes(output) - start_bytes; (int)obs_output_get_total_bytes(output) - start_bytes;
uint64_t bitrate = (uint64_t)total_bytes * 8 * 1000000000 / uint64_t bitrate = util_mul_div64(
total_time / 1000; total_bytes, 8ULL * 1000000000ULL / 1000ULL,
total_time);
if (obs_output_get_frames_dropped(output) || if (obs_output_get_frames_dropped(output) ||
(int)bitrate < (wiz->startingBitrate * 75 / 100)) { (int)bitrate < (wiz->startingBitrate * 75 / 100)) {
server.bitrate = (int)bitrate * 70 / 100; server.bitrate = (int)bitrate * 70 / 100;
......
...@@ -360,6 +360,7 @@ set(libobs_util_HEADERS ...@@ -360,6 +360,7 @@ set(libobs_util_HEADERS
util/text-lookup.h util/text-lookup.h
util/bmem.h util/bmem.h
util/c99defs.h util/c99defs.h
util/util_uint64.h
util/util_uint128.h util/util_uint128.h
util/cf-parser.h util/cf-parser.h
util/threading.h util/threading.h
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#include "../../util/circlebuf.h" #include "../../util/circlebuf.h"
#include "../../util/platform.h" #include "../../util/platform.h"
#include "../../util/darray.h" #include "../../util/darray.h"
#include "../../util/util_uint64.h"
#include "../../obs-internal.h" #include "../../obs-internal.h"
#include "wasapi-output.h" #include "wasapi-output.h"
...@@ -78,8 +79,8 @@ static bool process_audio_delay(struct audio_monitor *monitor, float **data, ...@@ -78,8 +79,8 @@ static bool process_audio_delay(struct audio_monitor *monitor, float **data,
monitor->prev_video_ts = last_frame_ts; monitor->prev_video_ts = last_frame_ts;
} else if (monitor->prev_video_ts == last_frame_ts) { } else if (monitor->prev_video_ts == last_frame_ts) {
monitor->time_since_prev += (uint64_t)*frames * 1000000000ULL / monitor->time_since_prev += util_mul_div64(
(uint64_t)monitor->sample_rate; *frames, 1000000000ULL, monitor->sample_rate);
} else { } else {
monitor->time_since_prev = 0; monitor->time_since_prev = 0;
} }
...@@ -90,8 +91,8 @@ static bool process_audio_delay(struct audio_monitor *monitor, float **data, ...@@ -90,8 +91,8 @@ static bool process_audio_delay(struct audio_monitor *monitor, float **data,
circlebuf_peek_front(&monitor->delay_buffer, &cur_ts, circlebuf_peek_front(&monitor->delay_buffer, &cur_ts,
sizeof(ts)); sizeof(ts));
front_ts = cur_ts - ((uint64_t)pad * 1000000000ULL / front_ts = cur_ts - util_mul_div64(pad, 1000000000ULL,
(uint64_t)monitor->sample_rate); monitor->sample_rate);
diff = (int64_t)front_ts - (int64_t)last_frame_ts; diff = (int64_t)front_ts - (int64_t)last_frame_ts;
bad_diff = !last_frame_ts || llabs(diff) > 5000000000 || bad_diff = !last_frame_ts || llabs(diff) > 5000000000 ||
monitor->time_since_prev > 100000000ULL; monitor->time_since_prev > 100000000ULL;
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "../util/circlebuf.h" #include "../util/circlebuf.h"
#include "../util/platform.h" #include "../util/platform.h"
#include "../util/profiler.h" #include "../util/profiler.h"
#include "../util/util_uint64.h"
#include "audio-io.h" #include "audio-io.h"
#include "audio-resampler.h" #include "audio-resampler.h"
...@@ -78,11 +79,7 @@ struct audio_output { ...@@ -78,11 +79,7 @@ struct audio_output {
static inline double ts_to_frames(const audio_t *audio, uint64_t ts) static inline double ts_to_frames(const audio_t *audio, uint64_t ts)
{ {
double audio_offset_d = (double)ts; return util_mul_div64(ts, audio->info.samples_per_sec, 1000000000ULL);
audio_offset_d /= 1000000000.0;
audio_offset_d *= (double)audio->info.samples_per_sec;
return audio_offset_d;
} }
static inline double positive_round(double val) static inline double positive_round(double val)
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include "media-io-defs.h" #include "media-io-defs.h"
#include "../util/c99defs.h" #include "../util/c99defs.h"
#include "../util/util_uint128.h" #include "../util/util_uint64.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
...@@ -195,18 +195,12 @@ static inline size_t get_audio_size(enum audio_format format, ...@@ -195,18 +195,12 @@ static inline size_t get_audio_size(enum audio_format format,
static inline uint64_t audio_frames_to_ns(size_t sample_rate, uint64_t frames) static inline uint64_t audio_frames_to_ns(size_t sample_rate, uint64_t frames)
{ {
util_uint128_t val; return util_mul_div64(frames, 1000000000ULL, sample_rate);
val = util_mul64_64(frames, 1000000000ULL);
val = util_div128_32(val, (uint32_t)sample_rate);
return val.low;
} }
static inline uint64_t ns_to_audio_frames(size_t sample_rate, uint64_t frames) static inline uint64_t ns_to_audio_frames(size_t sample_rate, uint64_t frames)
{ {
util_uint128_t val; return util_mul_div64(frames, sample_rate, 1000000000ULL);
val = util_mul64_64(frames, sample_rate);
val = util_div128_32(val, 1000000000);
return val.low;
} }
#define AUDIO_OUTPUT_SUCCESS 0 #define AUDIO_OUTPUT_SUCCESS 0
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "../util/profiler.h" #include "../util/profiler.h"
#include "../util/threading.h" #include "../util/threading.h"
#include "../util/darray.h" #include "../util/darray.h"
#include "../util/util_uint64.h"
#include "format-conversion.h" #include "format-conversion.h"
#include "video-io.h" #include "video-io.h"
...@@ -234,8 +235,8 @@ int video_output_open(video_t **video, struct video_output_info *info) ...@@ -234,8 +235,8 @@ int video_output_open(video_t **video, struct video_output_info *info)
goto fail; goto fail;
memcpy(&out->info, info, sizeof(struct video_output_info)); memcpy(&out->info, info, sizeof(struct video_output_info));
out->frame_time = (uint64_t)(1000000000.0 * (double)info->fps_den / out->frame_time =
(double)info->fps_num); util_mul_div64(1000000000ULL, info->fps_den, info->fps_num);
out->initialized = false; out->initialized = false;
if (pthread_mutexattr_init(&attr) != 0) if (pthread_mutexattr_init(&attr) != 0)
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <inttypes.h> #include <inttypes.h>
#include "obs-internal.h" #include "obs-internal.h"
#include "util/util_uint64.h"
struct ts_info { struct ts_info {
uint64_t start; uint64_t start;
...@@ -41,7 +42,7 @@ static void push_audio_tree(obs_source_t *parent, obs_source_t *source, void *p) ...@@ -41,7 +42,7 @@ static void push_audio_tree(obs_source_t *parent, obs_source_t *source, void *p)
static inline size_t convert_time_to_frames(size_t sample_rate, uint64_t t) static inline size_t convert_time_to_frames(size_t sample_rate, uint64_t t)
{ {
return (size_t)(t * (uint64_t)sample_rate / 1000000000ULL); return util_mul_div64(t, sample_rate, 1000000000ULL);
} }
static inline void mix_audio(struct audio_output_data *mixes, static inline void mix_audio(struct audio_output_data *mixes,
...@@ -90,8 +91,8 @@ static void ignore_audio(obs_source_t *source, size_t channels, ...@@ -90,8 +91,8 @@ static void ignore_audio(obs_source_t *source, size_t channels,
source->audio_input_buf[ch].size); source->audio_input_buf[ch].size);
source->last_audio_input_buf_size = 0; source->last_audio_input_buf_size = 0;
source->audio_ts += (uint64_t)num_floats * 1000000000ULL / source->audio_ts +=
(uint64_t)sample_rate; util_mul_div64(num_floats, 1000000000ULL, sample_rate);
} }
} }
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "obs.h" #include "obs.h"
#include "obs-internal.h" #include "obs-internal.h"
#include "util/util_uint64.h"
#define encoder_active(encoder) os_atomic_load_bool(&encoder->active) #define encoder_active(encoder) os_atomic_load_bool(&encoder->active)
#define set_encoder_active(encoder, val) \ #define set_encoder_active(encoder, val) \
...@@ -1073,8 +1074,7 @@ static inline size_t calc_offset_size(struct obs_encoder *encoder, ...@@ -1073,8 +1074,7 @@ static inline size_t calc_offset_size(struct obs_encoder *encoder,
uint64_t v_start_ts, uint64_t a_start_ts) uint64_t v_start_ts, uint64_t a_start_ts)
{ {
uint64_t offset = v_start_ts - a_start_ts; uint64_t offset = v_start_ts - a_start_ts;
offset = (uint64_t)offset * (uint64_t)encoder->samplerate / offset = util_mul_div64(offset, encoder->samplerate, 1000000000ULL);
1000000000ULL;
return (size_t)offset * encoder->blocksize; return (size_t)offset * encoder->blocksize;
} }
...@@ -1121,8 +1121,8 @@ static bool buffer_audio(struct obs_encoder *encoder, struct audio_data *data) ...@@ -1121,8 +1121,8 @@ static bool buffer_audio(struct obs_encoder *encoder, struct audio_data *data)
/* audio starting point still not synced with video starting /* audio starting point still not synced with video starting
* point, so don't start audio */ * point, so don't start audio */
end_ts += (uint64_t)data->frames * 1000000000ULL / end_ts += util_mul_div64(data->frames, 1000000000ULL,
(uint64_t)encoder->samplerate; encoder->samplerate);
if (end_ts <= v_start_ts) { if (end_ts <= v_start_ts) {
success = false; success = false;
goto fail; goto fail;
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <inttypes.h> #include <inttypes.h>
#include "util/platform.h" #include "util/platform.h"
#include "util/util_uint64.h"
#include "obs.h" #include "obs.h"
#include "obs-internal.h" #include "obs-internal.h"
...@@ -1731,8 +1732,8 @@ static bool prepare_audio(struct obs_output *output, ...@@ -1731,8 +1732,8 @@ static bool prepare_audio(struct obs_output *output,
*new = *old; *new = *old;
if (old->timestamp < output->video_start_ts) { if (old->timestamp < output->video_start_ts) {
uint64_t duration = (uint64_t)old->frames * 1000000000 / uint64_t duration = util_mul_div64(old->frames, 1000000000ULL,
(uint64_t)output->sample_rate; output->sample_rate);
uint64_t end_ts = (old->timestamp + duration); uint64_t end_ts = (old->timestamp + duration);
uint64_t cutoff; uint64_t cutoff;
...@@ -1742,7 +1743,8 @@ static bool prepare_audio(struct obs_output *output, ...@@ -1742,7 +1743,8 @@ static bool prepare_audio(struct obs_output *output,
cutoff = output->video_start_ts - old->timestamp; cutoff = output->video_start_ts - old->timestamp;
new->timestamp += cutoff; new->timestamp += cutoff;
cutoff = cutoff * (uint64_t)output->sample_rate / 1000000000; cutoff = util_mul_div64(cutoff, output->sample_rate,
1000000000ULL);
for (size_t i = 0; i < output->planes; i++) for (size_t i = 0; i < output->planes; i++)
new->data[i] += output->audio_size *(uint32_t)cutoff; new->data[i] += output->audio_size *(uint32_t)cutoff;
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
******************************************************************************/ ******************************************************************************/
#include "util/threading.h" #include "util/threading.h"
#include "util/util_uint64.h"
#include "graphics/math-defs.h" #include "graphics/math-defs.h"
#include "obs-scene.h" #include "obs-scene.h"
...@@ -974,8 +975,8 @@ static void apply_scene_item_audio_actions(struct obs_scene_item *item, ...@@ -974,8 +975,8 @@ static void apply_scene_item_audio_actions(struct obs_scene_item *item,
if (timestamp < ts) if (timestamp < ts)
timestamp = ts; timestamp = ts;
new_frame_num = (timestamp - ts) * (uint64_t)sample_rate / new_frame_num = util_mul_div64(timestamp - ts, sample_rate,
1000000000ULL; 1000000000ULL);
if (ts && new_frame_num >= AUDIO_OUTPUT_FRAMES) if (ts && new_frame_num >= AUDIO_OUTPUT_FRAMES)
break; break;
...@@ -1024,8 +1025,8 @@ static bool apply_scene_item_volume(struct obs_scene_item *item, float **buf, ...@@ -1024,8 +1025,8 @@ static bool apply_scene_item_volume(struct obs_scene_item *item, float **buf,
pthread_mutex_unlock(&item->actions_mutex); pthread_mutex_unlock(&item->actions_mutex);
if (actions_pending) { if (actions_pending) {
uint64_t duration = (uint64_t)AUDIO_OUTPUT_FRAMES * uint64_t duration = util_mul_div64(AUDIO_OUTPUT_FRAMES,
1000000000ULL / (uint64_t)sample_rate; 1000000000ULL, sample_rate);
if (!ts || action.timestamp < (ts + duration)) { if (!ts || action.timestamp < (ts + duration)) {
apply_scene_item_audio_actions(item, buf, ts, apply_scene_item_audio_actions(item, buf, ts,
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
******************************************************************************/ ******************************************************************************/
#include "obs-internal.h" #include "obs-internal.h"
#include "util/util_uint64.h"
#include "graphics/math-extra.h" #include "graphics/math-extra.h"
#define lock_transition(transition) \ #define lock_transition(transition) \
...@@ -866,7 +867,7 @@ static inline float get_sample_time(obs_source_t *transition, ...@@ -866,7 +867,7 @@ static inline float get_sample_time(obs_source_t *transition,
uint64_t ts) uint64_t ts)
{ {
uint64_t sample_ts_offset = uint64_t sample_ts_offset =
(uint64_t)sample * 1000000000ULL / (uint64_t)sample_rate; util_mul_div64(sample, 1000000000ULL, sample_rate);
uint64_t i_ts = ts + sample_ts_offset; uint64_t i_ts = ts + sample_ts_offset;
return calc_time(transition, i_ts); return calc_time(transition, i_ts);
} }
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "media-io/audio-io.h" #include "media-io/audio-io.h"
#include "util/threading.h" #include "util/threading.h"
#include "util/platform.h" #include "util/platform.h"
#include "util/util_uint64.h"
#include "callback/calldata.h" #include "callback/calldata.h"
#include "graphics/matrix3.h" #include "graphics/matrix3.h"
#include "graphics/vec3.h" #include "graphics/vec3.h"
...@@ -1165,13 +1166,13 @@ static inline uint64_t conv_frames_to_time(const size_t sample_rate, ...@@ -1165,13 +1166,13 @@ static inline uint64_t conv_frames_to_time(const size_t sample_rate,
if (!sample_rate) if (!sample_rate)
return 0; return 0;
return (uint64_t)frames * 1000000000ULL / (uint64_t)sample_rate; return util_mul_div64(frames, 1000000000ULL, sample_rate);
} }
static inline size_t conv_time_to_frames(const size_t sample_rate, static inline size_t conv_time_to_frames(const size_t sample_rate,
const uint64_t duration) const uint64_t duration)
{ {
return (size_t)(duration * (uint64_t)sample_rate / 1000000000ULL); return (size_t)util_mul_div64(duration, sample_rate, 1000000000ULL);
} }
/* maximum buffer size */ /* maximum buffer size */
...@@ -1235,7 +1236,7 @@ static inline uint64_t uint64_diff(uint64_t ts1, uint64_t ts2) ...@@ -1235,7 +1236,7 @@ static inline uint64_t uint64_diff(uint64_t ts1, uint64_t ts2)
static inline size_t get_buf_placement(audio_t *audio, uint64_t offset) static inline size_t get_buf_placement(audio_t *audio, uint64_t offset)
{ {
uint32_t sample_rate = audio_output_get_sample_rate(audio); uint32_t sample_rate = audio_output_get_sample_rate(audio);
return (size_t)(offset * (uint64_t)sample_rate / 1000000000ULL); return (size_t)util_mul_div64(offset, sample_rate, 1000000000ULL);
} }
static void source_output_audio_place(obs_source_t *source, static void source_output_audio_place(obs_source_t *source,
......
/*
* Copyright (c) 2020 Hans Petter Selasky <hps@selasky.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
static inline uint64_t util_mul_div64(uint64_t num, uint64_t mul, uint64_t div)
{
const uint64_t rem = num % div;
return (num / div) * mul + (rem * mul) / div;
}
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <util/platform.h> #include <util/platform.h>
#include <util/threading.h> #include <util/threading.h>
#include <util/util_uint64.h>
#include <sstream> #include <sstream>
#include <algorithm> #include <algorithm>
...@@ -90,8 +91,8 @@ void DeckLinkDeviceInstance::HandleAudioPacket( ...@@ -90,8 +91,8 @@ void DeckLinkDeviceInstance::HandleAudioPacket(
if (decklink && !static_cast<DeckLinkInput *>(decklink)->buffering) { if (decklink && !static_cast<DeckLinkInput *>(decklink)->buffering) {
currentPacket.timestamp = os_gettime_ns(); currentPacket.timestamp = os_gettime_ns();
currentPacket.timestamp -= currentPacket.timestamp -=
(uint64_t)frameCount * 1000000000ULL / util_mul_div64(frameCount, 1000000000ULL,
(uint64_t)currentPacket.samples_per_sec; currentPacket.samples_per_sec);
} }
int maxdevicechannel = device->GetMaxChannel(); int maxdevicechannel = device->GetMaxChannel();
...@@ -113,7 +114,7 @@ void DeckLinkDeviceInstance::HandleAudioPacket( ...@@ -113,7 +114,7 @@ void DeckLinkDeviceInstance::HandleAudioPacket(
} }
nextAudioTS = timestamp + nextAudioTS = timestamp +
((uint64_t)frameCount * 1000000000ULL / 48000ULL) + 1; util_mul_div64(frameCount, 1000000000ULL, 48000ULL) + 1;
obs_source_output_audio( obs_source_output_audio(
static_cast<DeckLinkInput *>(decklink)->GetSource(), static_cast<DeckLinkInput *>(decklink)->GetSource(),
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "decklink-devices.hpp" #include "decklink-devices.hpp"
#include "../../libobs/media-io/video-scaler.h" #include "../../libobs/media-io/video-scaler.h"
#include "../../libobs/util/util_uint64.h"
static void decklink_output_destroy(void *data) static void decklink_output_destroy(void *data)
{ {
...@@ -127,8 +128,8 @@ static bool prepare_audio(DeckLinkOutput *decklink, ...@@ -127,8 +128,8 @@ static bool prepare_audio(DeckLinkOutput *decklink,
*output = *frame; *output = *frame;
if (frame->timestamp < decklink->start_timestamp) { if (frame->timestamp < decklink->start_timestamp) {
uint64_t duration = (uint64_t)frame->frames * 1000000000 / uint64_t duration = util_mul_div64(frame->frames, 1000000000ULL,
(uint64_t)decklink->audio_samplerate; decklink->audio_samplerate);
uint64_t end_ts = frame->timestamp + duration; uint64_t end_ts = frame->timestamp + duration;
uint64_t cutoff; uint64_t cutoff;
...@@ -138,7 +139,8 @@ static bool prepare_audio(DeckLinkOutput *decklink, ...@@ -138,7 +139,8 @@ static bool prepare_audio(DeckLinkOutput *decklink,
cutoff = decklink->start_timestamp - frame->timestamp; cutoff = decklink->start_timestamp - frame->timestamp;
output->timestamp += cutoff; 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++) for (size_t i = 0; i < decklink->audio_planes; i++)
output->data[i] += output->data[i] +=
......
...@@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. ...@@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <util/bmem.h> #include <util/bmem.h>
#include <util/platform.h> #include <util/platform.h>
#include <util/threading.h> #include <util/threading.h>
#include <util/util_uint64.h>
#include <obs-module.h> #include <obs-module.h>
#include <alsa/asoundlib.h> #include <alsa/asoundlib.h>
...@@ -562,8 +563,9 @@ void *_alsa_listen(void *attr) ...@@ -562,8 +563,9 @@ void *_alsa_listen(void *attr)
} }
out.frames = frames; out.frames = frames;
out.timestamp = os_gettime_ns() - out.timestamp =
((frames * NSEC_PER_SEC) / data->rate); os_gettime_ns() -
util_mul_div64(frames, NSEC_PER_SEC, data->rate);
if (!data->first_ts) if (!data->first_ts)
data->first_ts = out.timestamp + STARTUP_TIMEOUT_NS; data->first_ts = out.timestamp + STARTUP_TIMEOUT_NS;
......
...@@ -17,6 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. ...@@ -17,6 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <util/platform.h> #include <util/platform.h>
#include <util/bmem.h> #include <util/bmem.h>
#include <util/util_uint64.h>
#include <obs-module.h> #include <obs-module.h>
#include "pulse-wrapper.h" #include "pulse-wrapper.h"
...@@ -161,7 +162,7 @@ static pa_channel_map pulse_channel_map(enum speaker_layout layout) ...@@ -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) 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) static inline uint64_t get_sample_time(size_t frames, uint_fast32_t rate)
......
#include <obs-module.h> #include <obs-module.h>
#include <util/circlebuf.h> #include <util/circlebuf.h>
#include <util/util_uint64.h>
#ifndef SEC_TO_NSEC #ifndef SEC_TO_NSEC
#define SEC_TO_NSEC 1000000000ULL #define SEC_TO_NSEC 1000000000ULL
...@@ -199,7 +200,8 @@ async_delay_filter_audio(void *data, struct obs_audio_data *audio) ...@@ -199,7 +200,8 @@ async_delay_filter_audio(void *data, struct obs_audio_data *audio)
filter->last_audio_ts = audio->timestamp; 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; end_ts = audio->timestamp + duration;
for (size_t i = 0; i < MAX_AV_PLANES; i++) { for (size_t i = 0; i < MAX_AV_PLANES; i++) {
......
#include <obs-module.h> #include <obs-module.h>
#include <util/circlebuf.h> #include <util/circlebuf.h>
#include <util/util_uint64.h>
#define S_DELAY_MS "delay_ms" #define S_DELAY_MS "delay_ms"
#define T_DELAY_MS obs_module_text("DelayMs") #define T_DELAY_MS obs_module_text("DelayMs")
...@@ -90,8 +91,7 @@ static inline void check_interval(struct gpu_delay_filter_data *f) ...@@ -90,8 +91,7 @@ static inline void check_interval(struct gpu_delay_filter_data *f)
obs_get_video_info(&ovi); obs_get_video_info(&ovi);
interval_ns = interval_ns = util_mul_div64(ovi.fps_den, 1000000000ULL, ovi.fps_num);
(uint64_t)ovi.fps_den * 1000000000ULL / (uint64_t)ovi.fps_num;
if (interval_ns != f->interval_ns) if (interval_ns != f->interval_ns)
update_interval(f, interval_ns); update_interval(f, interval_ns);
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <windows.h> #include <windows.h>
#include <dxgi.h> #include <dxgi.h>
#include <util/sse-intrin.h> #include <util/sse-intrin.h>
#include <util/util_uint64.h>
#include <ipc-util/pipe.h> #include <ipc-util/pipe.h>
#include "obfuscate.h" #include "obfuscate.h"
#include "inject-library.h" #include "inject-library.h"
...@@ -729,7 +730,8 @@ static inline void reset_frame_interval(struct game_capture *gc) ...@@ -729,7 +730,8 @@ static inline void reset_frame_interval(struct game_capture *gc)
uint64_t interval = 0; uint64_t interval = 0;
if (obs_get_video_info(&ovi)) { 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 /* Always limit capture framerate to some extent. If a game
* running at 900 FPS is being captured without some sort of * running at 900 FPS is being captured without some sort of
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <util/windows/WinHandle.hpp> #include <util/windows/WinHandle.hpp>
#include <util/windows/CoTaskMemPtr.hpp> #include <util/windows/CoTaskMemPtr.hpp>
#include <util/threading.h> #include <util/threading.h>
#include <util/util_uint64.h>
using namespace std; using namespace std;
...@@ -464,8 +465,8 @@ bool WASAPISource::ProcessCaptureData() ...@@ -464,8 +465,8 @@ bool WASAPISource::ProcessCaptureData()
data.timestamp = useDeviceTiming ? ts * 100 : os_gettime_ns(); data.timestamp = useDeviceTiming ? ts * 100 : os_gettime_ns();
if (!useDeviceTiming) if (!useDeviceTiming)
data.timestamp -= (uint64_t)frames * 1000000000ULL / data.timestamp -= util_mul_div64(frames, 1000000000ULL,
(uint64_t)sampleRate; sampleRate);
obs_source_output_audio(source, &data); obs_source_output_audio(source, &data);
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#include <util/bmem.h> #include <util/bmem.h>
#include <util/threading.h> #include <util/threading.h>
#include <util/platform.h> #include <util/platform.h>
#include <util/util_uint64.h>
#include <obs.h> #include <obs.h>
struct sync_pair_aud { struct sync_pair_aud {
...@@ -54,7 +55,8 @@ static void *sync_pair_aud_thread(void *pdata) ...@@ -54,7 +55,8 @@ static void *sync_pair_aud_thread(void *pdata)
for (uint64_t i = 0; i < frames; i++) { for (uint64_t i = 0; i < frames; i++) {
uint64_t ts = uint64_t ts =
last_time + i * 1000000000ULL / sample_rate; last_time +
util_mul_div64(i, 1000000000ULL, sample_rate);
if (whitelist_time(ts, interval, fps_num, fps_den)) { if (whitelist_time(ts, interval, fps_num, fps_den)) {
cos_val += rate * M_PI_X2; cos_val += rate * M_PI_X2;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册