Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vo: change vsync base to nanoseconds #12371

Merged
merged 13 commits into from
Sep 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions audio/out/ao_audiotrack.c
Original file line number Diff line number Diff line change
Expand Up @@ -372,26 +372,26 @@ static uint32_t AudioTrack_getPlaybackHeadPosition(struct ao *ao)
return 0;
JNIEnv *env = MP_JNI_GET_ENV(ao);
uint32_t pos = 0;
int64_t now = mp_raw_time_us();
int64_t now = mp_raw_time_ns();
int state = MP_JNI_CALL_INT(p->audiotrack, AudioTrack.getPlayState);

int stable_count = 20;
int64_t wait = p->timestamp_stable < stable_count ? 50000 : 3000000;
int64_t wait = p->timestamp_stable < stable_count ? 50000000 : 3000000000;

if (state == AudioTrack.PLAYSTATE_PLAYING && p->format != AudioFormat.ENCODING_IEC61937 &&
(p->timestamp_fetched == 0 || now - p->timestamp_fetched >= wait)) {
if (!p->timestamp_fetched)
p->timestamp_stable = 0;

int64_t utime1 = MP_JNI_GET_LONG(p->timestamp, AudioTimestamp.nanoTime) / 1000;
int64_t time1 = MP_JNI_GET_LONG(p->timestamp, AudioTimestamp.nanoTime);
if (MP_JNI_CALL_BOOL(p->audiotrack, AudioTrack.getTimestamp, p->timestamp)) {
p->timestamp_set = true;
p->timestamp_fetched = now;
if (p->timestamp_stable < stable_count) {
uint32_t fpos = 0xFFFFFFFFL & MP_JNI_GET_LONG(p->timestamp, AudioTimestamp.framePosition);
int64_t utime2 = MP_JNI_GET_LONG(p->timestamp, AudioTimestamp.nanoTime) / 1000;
//MP_VERBOSE(ao, "getTimestamp: fpos= %u / time= %"PRId64" / now= %"PRId64" / stable= %d\n", fpos, utime2, now, p->timestamp_stable);
if (utime1 != utime2 && utime2 != 0 && fpos != 0) {
int64_t time2 = MP_JNI_GET_LONG(p->timestamp, AudioTimestamp.nanoTime);
//MP_VERBOSE(ao, "getTimestamp: fpos= %u / time= %"PRId64" / now= %"PRId64" / stable= %d\n", fpos, time2, now, p->timestamp_stable);
if (time1 != time2 && time2 != 0 && fpos != 0) {
p->timestamp_stable++;
}
}
Expand All @@ -404,19 +404,19 @@ static uint32_t AudioTrack_getPlaybackHeadPosition(struct ao *ao)
if (p->timestamp_set) {
pos = 0xFFFFFFFFL & MP_JNI_GET_LONG(p->timestamp, AudioTimestamp.framePosition);
uint32_t fpos = pos;
int64_t utime = MP_JNI_GET_LONG(p->timestamp, AudioTimestamp.nanoTime) / 1000;
if (utime == 0)
int64_t time = MP_JNI_GET_LONG(p->timestamp, AudioTimestamp.nanoTime);
if (time == 0)
fpos = pos = 0;
if (p->needs_timestamp_offset) {
if (utime != 0 && !p->timestamp_offset)
p->timestamp_offset = now - utime;
utime += p->timestamp_offset;
if (time != 0 && !p->timestamp_offset)
p->timestamp_offset = now - time;
time += p->timestamp_offset;
}
if (fpos != 0 && utime != 0 && state == AudioTrack.PLAYSTATE_PLAYING) {
double diff = (double)(now - utime) / 1e6;
if (fpos != 0 && time != 0 && state == AudioTrack.PLAYSTATE_PLAYING) {
double diff = (double)(now - time) / 1e9;
pos += diff * ao->samplerate;
}
//MP_VERBOSE(ao, "position = %u via getTimestamp (state = %d / fpos= %u / time= %"PRId64")\n", pos, state, fpos, utime);
//MP_VERBOSE(ao, "position = %u via getTimestamp (state = %d / fpos= %u / time= %"PRId64")\n", pos, state, fpos, time);
} else {
pos = 0xFFFFFFFFL & MP_JNI_CALL_INT(p->audiotrack, AudioTrack.getPlaybackHeadPosition);
//MP_VERBOSE(ao, "playbackHeadPosition = %u (reset_pending=%d)\n", pos, p->reset_pending);
Expand Down
3 changes: 1 addition & 2 deletions common/stats.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,7 @@ struct stat_entry {
// Overflows only after I'm dead.
static int64_t get_thread_cpu_time_ns(pthread_t thread)
{
#if defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0 && defined(_POSIX_THREAD_CPUTIME) && \
!HAVE_WIN32_INTERNAL_PTHREADS
#if defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0 && defined(_POSIX_THREAD_CPUTIME)
clockid_t id;
struct timespec tv;
if (pthread_getcpuclockid(thread, &id) == 0 &&
Expand Down
2 changes: 1 addition & 1 deletion demux/demux.c
Original file line number Diff line number Diff line change
Expand Up @@ -2557,7 +2557,7 @@ static void *demux_thread(void *pctx)
if (thread_work(in))
continue;
pthread_cond_signal(&in->wakeup);
struct timespec until = mp_time_us_to_timespec(in->next_cache_update);
struct timespec until = mp_time_us_to_realtime(in->next_cache_update);
pthread_cond_timedwait(&in->wakeup, &in->lock, &until);
}

Expand Down
1 change: 1 addition & 0 deletions demux/demux_lavf.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
*/

#include <pthread.h>
#include <stdlib.h>
#include <limits.h>
#include <stdbool.h>
Expand Down
2 changes: 1 addition & 1 deletion filters/filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ bool mp_filter_graph_run(struct mp_filter *filter)

int64_t end_time = 0;
if (isfinite(r->max_run_time))
end_time = mp_add_timeout(mp_time_us(), MPMAX(r->max_run_time, 0));
end_time = mp_time_us_add(mp_time_us(), MPMAX(r->max_run_time, 0));

// (could happen with separate filter graphs calling each other, for now
// ignore this issue as we don't use such a setup anywhere)
Expand Down
2 changes: 1 addition & 1 deletion input/input.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include "config.h"

#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
Expand All @@ -28,7 +29,6 @@
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <pthread.h>
#include <assert.h>

#include "osdep/io.h"
Expand Down
12 changes: 6 additions & 6 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ libswresample = dependency('libswresample', version: '>= 3.9.100')
libswscale = dependency('libswscale', version: '>= 5.9.100')

libass = dependency('libass', version: '>= 0.12.2')
pthreads = dependency('threads')

# the dependency order of libass -> ffmpeg is necessary due to
# static linking symbol resolution between fontconfig and MinGW
Expand All @@ -34,8 +33,7 @@ dependencies = [libass,
libavformat,
libavutil,
libswresample,
libswscale,
pthreads]
libswscale]

# Keeps track of all enabled/disabled features
features = {
Expand Down Expand Up @@ -359,11 +357,13 @@ win32_pthreads = get_option('win32-internal-pthreads').require(
features += {'win32-internal-pthreads': win32_pthreads.allowed()}
if features['win32-internal-pthreads']
flags += ['-isystem', '-I', '-DIN_WINPTHREAD']
# Note: Adding this include causes POSIX_TIMERS to be defined for
# unclear reasons (some confusion with <pthread.h> probably).
# Hack around it by using HAVE_WIN32_INTERNAL_PTHREADS.
includedir += include_directories('osdep/win32/include')
sources += files('osdep/win32/pthread.c')
else
# pthreads is intentionally left undefined in win32 branch to find incorrect
# uses of it immediately
pthreads = dependency('threads')
dependencies += pthreads
kasper93 marked this conversation as resolved.
Show resolved Hide resolved
endif

pthread_debug = get_option('pthread-debug').require(
Expand Down
4 changes: 2 additions & 2 deletions misc/dispatch.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ void mp_dispatch_run(struct mp_dispatch_queue *queue,
void mp_dispatch_queue_process(struct mp_dispatch_queue *queue, double timeout)
{
pthread_mutex_lock(&queue->lock);
queue->wait = timeout > 0 ? mp_add_timeout(mp_time_us(), timeout) : 0;
queue->wait = timeout > 0 ? mp_time_us_add(mp_time_us(), timeout) : 0;
assert(!queue->in_process); // recursion not allowed
queue->in_process = true;
queue->in_process_thread = pthread_self();
Expand Down Expand Up @@ -310,7 +310,7 @@ void mp_dispatch_queue_process(struct mp_dispatch_queue *queue, double timeout)
item->completed = true;
}
} else if (queue->wait > 0 && !queue->interrupted) {
struct timespec ts = mp_time_us_to_timespec(queue->wait);
struct timespec ts = mp_time_us_to_realtime(queue->wait);
if (pthread_cond_timedwait(&queue->cond, &queue->lock, &ts))
queue->wait = 0;
} else {
Expand Down
10 changes: 5 additions & 5 deletions osdep/timer-darwin.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,24 @@
#include "common/msg.h"
#include "timer.h"

static double timebase_ratio;
static double timebase_ratio_ns;

void mp_sleep_us(int64_t us)
{
uint64_t deadline = us / 1e6 / timebase_ratio + mach_absolute_time();
uint64_t deadline = us * 1e3 / timebase_ratio_ns + mach_absolute_time();

mach_wait_until(deadline);
}

uint64_t mp_raw_time_us(void)
uint64_t mp_raw_time_ns(void)
{
return mach_absolute_time() * timebase_ratio * 1e6;
return mach_absolute_time() * timebase_ratio_ns;
}

void mp_raw_time_init(void)
{
struct mach_timebase_info timebase;

mach_timebase_info(&timebase);
timebase_ratio = (double)timebase.numer / (double)timebase.denom * 1e-9;
timebase_ratio_ns = (double)timebase.numer / (double)timebase.denom;
}
22 changes: 7 additions & 15 deletions osdep/timer-linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
*/

#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include "timer.h"

void mp_sleep_us(int64_t us)
Expand All @@ -34,22 +32,16 @@ void mp_sleep_us(int64_t us)
nanosleep(&ts, NULL);
}

#if defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0 && defined(CLOCK_MONOTONIC)
uint64_t mp_raw_time_us(void)
uint64_t mp_raw_time_ns(void)
{
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts))
abort();
return ts.tv_sec * 1000000LL + ts.tv_nsec / 1000;
}
struct timespec tp = {0};
#if defined(CLOCK_MONOTONIC_RAW)
clock_gettime(CLOCK_MONOTONIC_RAW, &tp);
#else
uint64_t mp_raw_time_us(void)
{
struct timeval tv;
gettimeofday(&tv,NULL);
kasper93 marked this conversation as resolved.
Show resolved Hide resolved
return tv.tv_sec * 1000000LL + tv.tv_usec;
}
timespec_get(&tp, TIME_UTC);
sfan5 marked this conversation as resolved.
Show resolved Hide resolved
#endif
return tp.tv_sec * UINT64_C(1000000000) + tp.tv_nsec;
}

void mp_raw_time_init(void)
{
Expand Down
8 changes: 4 additions & 4 deletions osdep/timer-win2.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,16 @@ void mp_sleep_us(int64_t us)
mp_end_hires_timers(hrt);
}

uint64_t mp_raw_time_us(void)
uint64_t mp_raw_time_ns(void)
{
LARGE_INTEGER perf_count;
QueryPerformanceCounter(&perf_count);

// Convert QPC units (1/perf_freq seconds) to microseconds. This will work
// Convert QPC units (1/perf_freq seconds) to nanoseconds. This will work
// without overflow because the QPC value is guaranteed not to roll-over
// within 100 years, so perf_freq must be less than 2.9*10^9.
return perf_count.QuadPart / perf_freq.QuadPart * 1000000 +
perf_count.QuadPart % perf_freq.QuadPart * 1000000 / perf_freq.QuadPart;
return perf_count.QuadPart / perf_freq.QuadPart * UINT64_C(1000000000) +
perf_count.QuadPart % perf_freq.QuadPart * UINT64_C(1000000000) / perf_freq.QuadPart;
}

void mp_raw_time_init(void)
Expand Down
Loading