summaryrefslogtreecommitdiffstats
path: root/video/out/vo.c
diff options
context:
space:
mode:
authorKacper Michajłow <kasper93@gmail.com>2023-10-21 04:55:41 +0200
committerDudemanguy <random342@airmail.cc>2023-11-05 17:36:17 +0000
commit174df99ffa53f1091589eaa4fa0c16cdd55a9326 (patch)
tree3a60d45615f18beed98a9b08267c28ed7e05dd5f /video/out/vo.c
parent3a8b107f6216b38a151d5ca1e9d4f2727e3418f5 (diff)
downloadmpv-174df99ffa53f1091589eaa4fa0c16cdd55a9326.tar.bz2
mpv-174df99ffa53f1091589eaa4fa0c16cdd55a9326.tar.xz
ALL: use new mp_thread abstraction
Diffstat (limited to 'video/out/vo.c')
-rw-r--r--video/out/vo.c184
1 files changed, 90 insertions, 94 deletions
diff --git a/video/out/vo.c b/video/out/vo.c
index 0893202e72..16178f2caa 100644
--- a/video/out/vo.c
+++ b/video/out/vo.c
@@ -17,7 +17,6 @@
#include <assert.h>
#include <math.h>
-#include <pthread.h>
#include <stdatomic.h>
#include <stdbool.h>
#include <stdio.h>
@@ -122,13 +121,13 @@ static const struct vo_driver *const video_out_drivers[] =
};
struct vo_internal {
- pthread_t thread;
+ mp_thread thread;
struct mp_dispatch_queue *dispatch;
struct dr_helper *dr_helper;
// --- The following fields are protected by lock
- pthread_mutex_t lock;
- pthread_cond_t wakeup;
+ mp_mutex lock;
+ mp_cond wakeup;
bool need_wakeup;
bool terminate;
@@ -181,7 +180,7 @@ struct vo_internal {
extern const struct m_sub_options gl_video_conf;
static void forget_frames(struct vo *vo);
-static void *vo_thread(void *ptr);
+static MP_THREAD_VOID vo_thread(void *ptr);
static bool get_desc(struct m_obj_desc *dst, int index)
{
@@ -229,9 +228,9 @@ static void read_opts(struct vo *vo)
{
struct vo_internal *in = vo->in;
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
in->timing_offset = (uint64_t)(vo->opts->timing_offset * 1e9);
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
}
static void update_opts(void *p)
@@ -272,8 +271,8 @@ static void dealloc_vo(struct vo *vo)
talloc_free(vo->gl_opts_cache);
talloc_free(vo->eq_opts_cache);
- pthread_mutex_destroy(&vo->in->lock);
- pthread_cond_destroy(&vo->in->wakeup);
+ mp_mutex_destroy(&vo->in->lock);
+ mp_cond_destroy(&vo->in->wakeup);
talloc_free(vo);
}
@@ -310,8 +309,8 @@ static struct vo *vo_create(bool probing, struct mpv_global *global,
.stats = stats_ctx_create(vo, global, "vo"),
};
mp_dispatch_set_wakeup_fn(vo->in->dispatch, dispatch_wakeup_cb, vo);
- pthread_mutex_init(&vo->in->lock, NULL);
- pthread_cond_init(&vo->in->wakeup, NULL);
+ mp_mutex_init(&vo->in->lock);
+ mp_cond_init(&vo->in->wakeup);
vo->opts_cache = m_config_cache_alloc(NULL, global, &vo_sub_opts);
vo->opts = vo->opts_cache->opts;
@@ -334,10 +333,10 @@ static struct vo *vo_create(bool probing, struct mpv_global *global,
if (!vo->priv)
goto error;
- if (pthread_create(&vo->in->thread, NULL, vo_thread, vo))
+ if (mp_thread_create(&vo->in->thread, vo_thread, vo))
goto error;
if (mp_rendezvous(vo, 0) < 0) { // init barrier
- pthread_join(vo->in->thread, NULL);
+ mp_thread_join(vo->in->thread);
goto error;
}
return vo;
@@ -391,7 +390,7 @@ void vo_destroy(struct vo *vo)
{
struct vo_internal *in = vo->in;
mp_dispatch_run(in->dispatch, terminate_vo, vo);
- pthread_join(vo->in->thread, NULL);
+ mp_thread_join(vo->in->thread);
dealloc_vo(vo);
}
@@ -551,16 +550,16 @@ static void update_vsync_timing_after_swap(struct vo *vo,
static void update_display_fps(struct vo *vo)
{
struct vo_internal *in = vo->in;
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
if (in->internal_events & VO_EVENT_WIN_STATE) {
in->internal_events &= ~(unsigned)VO_EVENT_WIN_STATE;
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
double fps = 0;
vo->driver->control(vo, VOCTRL_GET_DISPLAY_FPS, &fps);
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
in->reported_display_fps = fps;
}
@@ -581,7 +580,7 @@ static void update_display_fps(struct vo *vo)
wakeup_core(vo);
}
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
}
static void check_vo_caps(struct vo *vo)
@@ -629,12 +628,12 @@ static void run_reconfig(void *p)
vo->params = NULL;
}
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
talloc_free(in->current_frame);
in->current_frame = NULL;
forget_frames(vo);
reset_vsync_timings(vo);
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
update_display_fps(vo);
}
@@ -723,12 +722,10 @@ void vo_wait_default(struct vo *vo, int64_t until_time)
{
struct vo_internal *in = vo->in;
- pthread_mutex_lock(&in->lock);
- if (!in->need_wakeup) {
- struct timespec ts = mp_time_ns_to_realtime(until_time);
- pthread_cond_timedwait(&in->wakeup, &in->lock, &ts);
- }
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_lock(&in->lock);
+ if (!in->need_wakeup)
+ mp_cond_timedwait_until(&in->wakeup, &in->lock, until_time);
+ mp_mutex_unlock(&in->lock);
}
// Called unlocked.
@@ -741,16 +738,16 @@ static void wait_vo(struct vo *vo, int64_t until_time)
} else {
vo_wait_default(vo, until_time);
}
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
in->need_wakeup = false;
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
}
static void wakeup_locked(struct vo *vo)
{
struct vo_internal *in = vo->in;
- pthread_cond_broadcast(&in->wakeup);
+ mp_cond_broadcast(&in->wakeup);
if (vo->driver->wakeup)
vo->driver->wakeup(vo);
in->need_wakeup = true;
@@ -762,9 +759,9 @@ void vo_wakeup(struct vo *vo)
{
struct vo_internal *in = vo->in;
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
wakeup_locked(vo);
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
}
// Whether vo_queue_frame() can be called. If the VO is not ready yet, the
@@ -778,7 +775,7 @@ void vo_wakeup(struct vo *vo)
bool vo_is_ready_for_frame(struct vo *vo, int64_t next_pts)
{
struct vo_internal *in = vo->in;
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
bool blocked = vo->driver->initially_blocked &&
!(in->internal_events & VO_EVENT_INITIAL_UNBLOCK);
bool r = vo->config_ok && !in->frame_queued && !blocked &&
@@ -800,7 +797,7 @@ bool vo_is_ready_for_frame(struct vo *vo, int64_t next_pts)
wakeup_locked(vo);
}
}
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
return r;
}
@@ -810,7 +807,7 @@ bool vo_is_ready_for_frame(struct vo *vo, int64_t next_pts)
void vo_queue_frame(struct vo *vo, struct vo_frame *frame)
{
struct vo_internal *in = vo->in;
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
assert(vo->config_ok && !in->frame_queued &&
(!in->current_frame || in->current_frame->num_vsyncs < 1));
in->hasframe = true;
@@ -819,7 +816,7 @@ void vo_queue_frame(struct vo *vo, struct vo_frame *frame)
in->wakeup_pts = frame->display_synced
? 0 : frame->pts + MPMAX(frame->duration, 0);
wakeup_locked(vo);
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
}
// If a frame is currently being rendered (or queued), wait until it's done.
@@ -827,10 +824,10 @@ void vo_queue_frame(struct vo *vo, struct vo_frame *frame)
void vo_wait_frame(struct vo *vo)
{
struct vo_internal *in = vo->in;
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
while (in->frame_queued || in->rendering)
- pthread_cond_wait(&in->wakeup, &in->lock);
- pthread_mutex_unlock(&in->lock);
+ mp_cond_wait(&in->wakeup, &in->lock);
+ mp_mutex_unlock(&in->lock);
}
// Wait until realtime is >= ts
@@ -838,15 +835,14 @@ void vo_wait_frame(struct vo *vo)
static void wait_until(struct vo *vo, int64_t target)
{
struct vo_internal *in = vo->in;
- struct timespec ts = mp_time_ns_to_realtime(target);
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
while (target > mp_time_ns()) {
if (in->queued_events & VO_EVENT_LIVE_RESIZING)
break;
- if (pthread_cond_timedwait(&in->wakeup, &in->lock, &ts))
+ if (mp_cond_timedwait_until(&in->wakeup, &in->lock, target))
break;
}
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
}
static bool render_frame(struct vo *vo)
@@ -857,7 +853,7 @@ static bool render_frame(struct vo *vo)
update_display_fps(vo);
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
if (in->frame_queued) {
talloc_free(in->current_frame);
@@ -931,7 +927,7 @@ static bool render_frame(struct vo *vo)
// timer instead, but possibly benefits from preparing a frame early.
bool can_queue = !in->frame_queued &&
(in->current_frame->num_vsyncs < 1 || !use_vsync);
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
if (can_queue)
wakeup_core(vo);
@@ -961,7 +957,7 @@ static bool render_frame(struct vo *vo)
stats_time_end(in->stats, "video-flip");
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
in->dropped_frame = prev_drop_count < vo->in->drop_count;
in->rendering = false;
@@ -993,13 +989,13 @@ static bool render_frame(struct vo *vo)
if (in->frame_queued && in->frame_queued->display_synced)
more_frames = true;
- pthread_cond_broadcast(&in->wakeup); // for vo_wait_frame()
+ mp_cond_broadcast(&in->wakeup); // for vo_wait_frame()
wakeup_core(vo);
done:
if (!vo->driver->frame_owner)
talloc_free(frame);
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
return more_frames;
}
@@ -1011,7 +1007,7 @@ static void do_redraw(struct vo *vo)
if (!vo->config_ok || (vo->driver->caps & VO_CAP_NORETAIN))
return;
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
in->request_redraw = false;
bool full_redraw = in->dropped_frame;
struct vo_frame *frame = NULL;
@@ -1027,7 +1023,7 @@ static void do_redraw(struct vo *vo)
frame->still = true;
frame->pts = 0;
frame->duration = -1;
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
vo->driver->draw_frame(vo, frame);
vo->driver->flip_page(vo);
@@ -1043,13 +1039,13 @@ static struct mp_image *get_image_vo(void *ctx, int imgfmt, int w, int h,
return vo->driver->get_image(vo, imgfmt, w, h, stride_align, flags);
}
-static void *vo_thread(void *ptr)
+static MP_THREAD_VOID vo_thread(void *ptr)
{
struct vo *vo = ptr;
struct vo_internal *in = vo->in;
bool vo_paused = false;
- mpthread_set_name("vo");
+ mp_thread_set_name("vo");
if (vo->driver->get_image) {
in->dr_helper = dr_helper_create(in->dispatch, get_image_vo, vo);
@@ -1075,7 +1071,7 @@ static void *vo_thread(void *ptr)
int64_t now = mp_time_ns();
int64_t wait_until = now + (working ? 0 : (int64_t)1e9);
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
if (in->wakeup_pts) {
if (in->wakeup_pts > now) {
wait_until = MPMIN(wait_until, in->wakeup_pts);
@@ -1094,7 +1090,7 @@ static void *vo_thread(void *ptr)
in->send_reset = false;
bool send_pause = in->paused != vo_paused;
vo_paused = in->paused;
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
if (send_reset)
vo->driver->control(vo, VOCTRL_RESET, NULL);
@@ -1118,13 +1114,13 @@ static void *vo_thread(void *ptr)
vo->driver->uninit(vo);
done:
TA_FREEP(&in->dr_helper);
- return NULL;
+ MP_THREAD_RETURN();
}
void vo_set_paused(struct vo *vo, bool paused)
{
struct vo_internal *in = vo->in;
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
if (in->paused != paused) {
in->paused = paused;
if (in->paused && in->dropped_frame) {
@@ -1134,55 +1130,55 @@ void vo_set_paused(struct vo *vo, bool paused)
reset_vsync_timings(vo);
wakeup_locked(vo);
}
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
}
int64_t vo_get_drop_count(struct vo *vo)
{
- pthread_mutex_lock(&vo->in->lock);
+ mp_mutex_lock(&vo->in->lock);
int64_t r = vo->in->drop_count;
- pthread_mutex_unlock(&vo->in->lock);
+ mp_mutex_unlock(&vo->in->lock);
return r;
}
void vo_increment_drop_count(struct vo *vo, int64_t n)
{
- pthread_mutex_lock(&vo->in->lock);
+ mp_mutex_lock(&vo->in->lock);
vo->in->drop_count += n;
- pthread_mutex_unlock(&vo->in->lock);
+ mp_mutex_unlock(&vo->in->lock);
}
// Make the VO redraw the OSD at some point in the future.
void vo_redraw(struct vo *vo)
{
struct vo_internal *in = vo->in;
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
if (!in->request_redraw) {
in->request_redraw = true;
in->want_redraw = false;
wakeup_locked(vo);
}
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
}
bool vo_want_redraw(struct vo *vo)
{
struct vo_internal *in = vo->in;
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
bool r = in->want_redraw;
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
return r;
}
void vo_seek_reset(struct vo *vo)
{
struct vo_internal *in = vo->in;
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
forget_frames(vo);
reset_vsync_timings(vo);
in->send_reset = true;
wakeup_locked(vo);
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
}
// Return true if there is still a frame being displayed (or queued).
@@ -1190,9 +1186,9 @@ void vo_seek_reset(struct vo *vo)
bool vo_still_displaying(struct vo *vo)
{
struct vo_internal *in = vo->in;
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
bool working = in->rendering || in->frame_queued;
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
return working && in->hasframe;
}
@@ -1245,45 +1241,45 @@ void vo_get_src_dst_rects(struct vo *vo, struct mp_rect *out_src,
void vo_set_queue_params(struct vo *vo, int64_t offset_ns, int num_req_frames)
{
struct vo_internal *in = vo->in;
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
in->flip_queue_offset = offset_ns;
in->req_frames = MPCLAMP(num_req_frames, 1, VO_MAX_REQ_FRAMES);
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
}
int vo_get_num_req_frames(struct vo *vo)
{
struct vo_internal *in = vo->in;
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
int res = in->req_frames;
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
return res;
}
double vo_get_vsync_interval(struct vo *vo)
{
struct vo_internal *in = vo->in;
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
double res = vo->in->vsync_interval > 1 ? vo->in->vsync_interval : -1;
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
return res;
}
double vo_get_estimated_vsync_interval(struct vo *vo)
{
struct vo_internal *in = vo->in;
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
double res = in->estimated_vsync_interval;
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
return res;
}
double vo_get_estimated_vsync_jitter(struct vo *vo)
{
struct vo_internal *in = vo->in;
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
double res = in->estimated_vsync_jitter;
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
return res;
}
@@ -1296,7 +1292,7 @@ double vo_get_estimated_vsync_jitter(struct vo *vo)
double vo_get_delay(struct vo *vo)
{
struct vo_internal *in = vo->in;
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
assert (!in->frame_queued);
int64_t res = 0;
if (in->base_vsync && in->vsync_interval > 1 && in->current_frame) {
@@ -1306,33 +1302,33 @@ double vo_get_delay(struct vo *vo)
if (!in->current_frame->display_synced)
res = 0;
}
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
return res ? (res - mp_time_ns()) / 1e9 : 0;
}
void vo_discard_timing_info(struct vo *vo)
{
struct vo_internal *in = vo->in;
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
reset_vsync_timings(vo);
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
}
int64_t vo_get_delayed_count(struct vo *vo)
{
struct vo_internal *in = vo->in;
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
int64_t res = vo->in->delayed_count;
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
return res;
}
double vo_get_display_fps(struct vo *vo)
{
struct vo_internal *in = vo->in;
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
double res = vo->in->display_fps;
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
return res;
}
@@ -1341,14 +1337,14 @@ double vo_get_display_fps(struct vo *vo)
void vo_event(struct vo *vo, int event)
{
struct vo_internal *in = vo->in;
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
if ((in->queued_events & event & VO_EVENTS_USER) != (event & VO_EVENTS_USER))
wakeup_core(vo);
if (event)
wakeup_locked(vo);
in->queued_events |= event;
in->internal_events |= event;
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
}
// Check event flags set with vo_event(). Return the mask of events that was
@@ -1356,30 +1352,30 @@ void vo_event(struct vo *vo, int event)
int vo_query_and_reset_events(struct vo *vo, int events)
{
struct vo_internal *in = vo->in;
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
int r = in->queued_events & events;
in->queued_events &= ~(unsigned)r;
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
return r;
}
struct mp_image *vo_get_current_frame(struct vo *vo)
{
struct vo_internal *in = vo->in;
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
struct mp_image *r = NULL;
if (vo->in->current_frame)
r = mp_image_new_ref(vo->in->current_frame->current);
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
return r;
}
struct vo_frame *vo_get_current_vo_frame(struct vo *vo)
{
struct vo_internal *in = vo->in;
- pthread_mutex_lock(&in->lock);
+ mp_mutex_lock(&in->lock);
struct vo_frame *r = vo_frame_ref(vo->in->current_frame);
- pthread_mutex_unlock(&in->lock);
+ mp_mutex_unlock(&in->lock);
return r;
}