diff options
Diffstat (limited to 'player')
-rw-r--r-- | player/audio.c | 87 | ||||
-rw-r--r-- | player/client.c | 355 | ||||
-rw-r--r-- | player/command.c | 1726 | ||||
-rw-r--r-- | player/command.h | 7 | ||||
-rw-r--r-- | player/configfiles.c | 266 | ||||
-rw-r--r-- | player/core.h | 81 | ||||
-rw-r--r-- | player/external_files.c | 109 | ||||
-rw-r--r-- | player/external_files.h | 2 | ||||
-rw-r--r-- | player/javascript.c | 165 | ||||
-rw-r--r-- | player/javascript/defaults.js | 120 | ||||
-rw-r--r-- | player/javascript/meson.build | 6 | ||||
-rw-r--r-- | player/loadfile.c | 430 | ||||
-rw-r--r-- | player/lua.c | 180 | ||||
-rw-r--r-- | player/lua/auto_profiles.lua | 67 | ||||
-rw-r--r-- | player/lua/console.lua | 1043 | ||||
-rw-r--r-- | player/lua/defaults.lua | 86 | ||||
-rw-r--r-- | player/lua/input.lua | 69 | ||||
-rw-r--r-- | player/lua/meson.build | 11 | ||||
-rw-r--r-- | player/lua/options.lua | 17 | ||||
-rw-r--r-- | player/lua/osc.lua | 536 | ||||
-rw-r--r-- | player/lua/stats.lua | 1003 | ||||
-rw-r--r-- | player/lua/ytdl_hook.lua | 456 | ||||
-rw-r--r-- | player/main.c | 77 | ||||
-rw-r--r-- | player/meson.build | 11 | ||||
-rw-r--r-- | player/misc.c | 27 | ||||
-rw-r--r-- | player/osd.c | 17 | ||||
-rw-r--r-- | player/playloop.c | 102 | ||||
-rw-r--r-- | player/screenshot.c | 135 | ||||
-rw-r--r-- | player/scripting.c | 112 | ||||
-rw-r--r-- | player/sub.c | 86 | ||||
-rw-r--r-- | player/video.c | 170 |
31 files changed, 5372 insertions, 2187 deletions
diff --git a/player/audio.c b/player/audio.c index 50c0faaf09..da91dd4340 100644 --- a/player/audio.c +++ b/player/audio.c @@ -22,7 +22,6 @@ #include <math.h> #include <assert.h> -#include "config.h" #include "mpv_talloc.h" #include "common/msg.h" @@ -64,9 +63,17 @@ static void update_speed_filters(struct MPContext *mpctx) speed = 1.0; } - if (mpctx->display_sync_active && mpctx->opts->video_sync == VS_DISP_ADROP) { - drop *= speed * resample; - resample = speed = 1.0; + if (mpctx->display_sync_active) { + switch (mpctx->video_out->opts->video_sync) { + case VS_DISP_ADROP: + drop *= speed * resample; + resample = speed = 1.0; + break; + case VS_DISP_TEMPO: + speed = mpctx->audio_speed; + resample = 1.0; + break; + } } mp_output_chain_set_audio_speed(ao_c->filter, speed, resample, drop); @@ -168,6 +175,7 @@ void audio_update_volume(struct MPContext *mpctx) float gain = MPMAX(opts->softvol_volume / 100.0, 0); gain = pow(gain, 3); gain *= compute_replaygain(mpctx); + gain *= db_gain(opts->softvol_gain); if (opts->softvol_mute == 1) gain = 0.0; @@ -183,11 +191,24 @@ void update_playback_speed(struct MPContext *mpctx) update_speed_filters(mpctx); } +static bool has_video_track(struct MPContext *mpctx) +{ + if (mpctx->vo_chain && mpctx->vo_chain->is_coverart) + return false; + + for (int n = 0; n < mpctx->num_tracks; n++) { + struct track *track = mpctx->tracks[n]; + if (track->type == STREAM_VIDEO && !track->attached_picture && !track->image) + return true; + } + + return false; +} + static void ao_chain_reset_state(struct ao_chain *ao_c) { ao_c->last_out_pts = MP_NOPTS_VALUE; ao_c->out_eof = false; - ao_c->underrun = false; ao_c->start_pts_known = false; ao_c->start_pts = MP_NOPTS_VALUE; ao_c->untimed_throttle = false; @@ -281,8 +302,7 @@ static bool keep_weak_gapless_format(struct mp_aframe *old, struct mp_aframe* ne { bool res = false; struct mp_aframe *new_mod = mp_aframe_new_ref(new); - if (!new_mod) - abort(); + MP_HANDLE_OOM(new_mod); // If the sample formats are compatible (== libswresample generally can // convert them), keep the AO. On other changes, recreate it. @@ -314,6 +334,7 @@ static void ao_chain_set_ao(struct ao_chain *ao_c, struct ao *ao) mp_async_queue_set_notifier(ao_c->queue_filter, ao_c->ao_filter); // Make sure filtering never stops with frames stuck in access filter. mp_filter_set_high_priority(ao_c->queue_filter, true); + audio_update_volume(ao_c->mpctx); } if (ao_c->filter->ao_needs_update) @@ -322,7 +343,7 @@ static void ao_chain_set_ao(struct ao_chain *ao_c, struct ao *ao) mp_filter_wakeup(ao_c->ao_filter); } -static void reinit_audio_filters_and_output(struct MPContext *mpctx) +static int reinit_audio_filters_and_output(struct MPContext *mpctx) { struct MPOpts *opts = mpctx->opts; struct ao_chain *ao_c = mpctx->ao_chain; @@ -333,8 +354,7 @@ static void reinit_audio_filters_and_output(struct MPContext *mpctx) // The "ideal" filter output format struct mp_aframe *out_fmt = mp_aframe_new_ref(ao_c->filter->output_aformat); - if (!out_fmt) - abort(); + MP_HANDLE_OOM(out_fmt); if (!mp_aframe_config_is_valid(out_fmt)) { talloc_free(out_fmt); @@ -359,13 +379,13 @@ static void reinit_audio_filters_and_output(struct MPContext *mpctx) { ao_chain_set_ao(ao_c, mpctx->ao); talloc_free(out_fmt); - return; + return 0; } // Wait until all played. if (mpctx->ao && ao_is_playing(mpctx->ao)) { talloc_free(out_fmt); - return; + return 0; } // Format change during syncing. Force playback start early, then wait. if (ao_c->ao_queue && mp_async_queue_get_frames(ao_c->ao_queue) && @@ -374,11 +394,11 @@ static void reinit_audio_filters_and_output(struct MPContext *mpctx) mpctx->audio_status = STATUS_READY; mp_wakeup_core(mpctx); talloc_free(out_fmt); - return; + return 0; } if (mpctx->audio_status == STATUS_READY) { talloc_free(out_fmt); - return; + return 0; } uninit_audio_out(mpctx); @@ -411,6 +431,9 @@ static void reinit_audio_filters_and_output(struct MPContext *mpctx) opts->audio_output_channels.num_chmaps); } + if (!has_video_track(mpctx)) + ao_flags |= AO_INIT_MEDIA_ROLE_MUSIC; + mpctx->ao_filter_fmt = out_fmt; mpctx->ao = ao_init_best(mpctx->global, ao_flags, mp_wakeup_core_cb, @@ -446,7 +469,7 @@ static void reinit_audio_filters_and_output(struct MPContext *mpctx) reset_audio_state(mpctx); mp_output_chain_reset_harder(ao_c->filter); mp_wakeup_core(mpctx); // reinit with new format next time - return; + return 0; } MP_ERR(mpctx, "Could not open/initialize audio device -> no sound.\n"); @@ -464,7 +487,8 @@ static void reinit_audio_filters_and_output(struct MPContext *mpctx) ao_c->ao_resume_time = opts->audio_wait_open > 0 ? mp_time_sec() + opts->audio_wait_open : 0; - ao_set_paused(mpctx->ao, get_internal_paused(mpctx)); + bool eof = mpctx->audio_status == STATUS_EOF; + ao_set_paused(mpctx->ao, get_internal_paused(mpctx), eof); ao_chain_set_ao(ao_c, mpctx->ao); @@ -477,12 +501,13 @@ static void reinit_audio_filters_and_output(struct MPContext *mpctx) mp_wakeup_core(mpctx); mp_notify(mpctx, MPV_EVENT_AUDIO_RECONFIG, NULL); - return; + return 0; init_error: uninit_audio_chain(mpctx); uninit_audio_out(mpctx); error_on_track(mpctx, track); + return -1; } int init_audio_decoder(struct MPContext *mpctx, struct track *track) @@ -516,7 +541,8 @@ void reinit_audio_chain(struct MPContext *mpctx) struct track *track = NULL; track = mpctx->current_track[0][STREAM_AUDIO]; if (!track || !track->stream) { - uninit_audio_out(mpctx); + if (!mpctx->encode_lavc_ctx) + uninit_audio_out(mpctx); error_on_track(mpctx, track); return; } @@ -592,7 +618,7 @@ double playing_audio_pts(struct MPContext *mpctx) double pts = written_audio_pts(mpctx); if (pts == MP_NOPTS_VALUE || !mpctx->ao) return pts; - return pts - mpctx->audio_speed * ao_get_delay(mpctx->ao); + return pts - ao_get_delay(mpctx->ao); } // This garbage is needed for untimed AOs. These consume audio infinitely fast, @@ -634,7 +660,7 @@ static void ao_process(struct mp_filter *f) return; } - // Due to mp_async_queue_set_notifier() thhis function is called when the + // Due to mp_async_queue_set_notifier() this function is called when the // queue becomes full. This affects state changes in the normal playloop, // so wake it up. But avoid redundant wakeups during normal playback. if (mpctx->audio_status != STATUS_PLAYING && @@ -698,7 +724,8 @@ static void ao_process(struct mp_filter *f) mpctx->shown_aframes += samples; double real_samplerate = mp_aframe_get_rate(af) / mpctx->audio_speed; - mpctx->delay += samples / real_samplerate; + if (mpctx->video_status != STATUS_EOF) + mpctx->delay += samples / real_samplerate; ao_c->last_out_pts = mp_aframe_end_pts(af); update_throttle(mpctx); @@ -802,7 +829,8 @@ void audio_start_ao(struct MPContext *mpctx) double pts = MP_NOPTS_VALUE; if (!get_sync_pts(mpctx, &pts)) return; - double apts = playing_audio_pts(mpctx); // (basically including mpctx->delay) + double apts = written_audio_pts(mpctx); + apts -= apts != MP_NOPTS_VALUE ? mpctx->audio_speed * ao_get_delay(mpctx->ao) : 0; if (pts != MP_NOPTS_VALUE && apts != MP_NOPTS_VALUE && pts < apts && mpctx->video_status != STATUS_EOF) { @@ -818,10 +846,13 @@ void audio_start_ao(struct MPContext *mpctx) } MP_VERBOSE(mpctx, "starting audio playback\n"); + ao_c->audio_started = true; ao_start(ao_c->ao); mpctx->audio_status = STATUS_PLAYING; - if (ao_c->out_eof) + if (ao_c->out_eof) { mpctx->audio_status = STATUS_DRAINING; + MP_VERBOSE(mpctx, "audio draining\n"); + } ao_c->underrun = false; mpctx->logged_async_diff = -1; mp_wakeup_core(mpctx); @@ -849,8 +880,10 @@ void fill_audio_out_buffers(struct MPContext *mpctx) return; } - if (ao_c->filter->ao_needs_update) - reinit_audio_filters_and_output(mpctx); + if (ao_c->filter->ao_needs_update) { + if (reinit_audio_filters_and_output(mpctx) < 0) + return; + } if (mpctx->vo_chain && ao_c->track && ao_c->track->dec && mp_decoder_wrapper_get_pts_reset(ao_c->track->dec)) @@ -870,8 +903,10 @@ void fill_audio_out_buffers(struct MPContext *mpctx) // until the old audio is fully played. // (Buggy if AO underruns.) if (mpctx->ao && ao_is_playing(mpctx->ao) && - mpctx->video_status != STATUS_EOF) + mpctx->video_status != STATUS_EOF) { + MP_VERBOSE(mpctx, "blocked, waiting for old audio to play\n"); ok = false; + } if (ao_c->start_pts_known != ok || ao_c->start_pts != pts) { ao_c->start_pts_known = ok; diff --git a/player/client.c b/player/client.c index 27f42afd74..5087f89885 100644 --- a/player/client.c +++ b/player/client.c @@ -13,14 +13,15 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include <assert.h> +#include <errno.h> +#include <fcntl.h> +#include <math.h> +#include <stdatomic.h> #include <stddef.h> #include <stdint.h> #include <stdlib.h> #include <unistd.h> -#include <fcntl.h> -#include <errno.h> -#include <math.h> -#include <assert.h> #include "common/common.h" #include "common/global.h" @@ -39,7 +40,6 @@ #include "options/m_property.h" #include "options/path.h" #include "options/parse_configfile.h" -#include "osdep/atomic.h" #include "osdep/threads.h" #include "osdep/timer.h" #include "osdep/io.h" @@ -64,7 +64,7 @@ struct mp_client_api { struct MPContext *mpctx; - pthread_mutex_t lock; + mp_mutex lock; // -- protected by lock @@ -106,7 +106,7 @@ struct observe_property { }; struct mpv_handle { - // -- immmutable + // -- immutable char name[MAX_CLIENT_NAME]; struct mp_log *log; struct MPContext *mpctx; @@ -118,10 +118,10 @@ struct mpv_handle { struct mpv_event_property cur_property_event; struct observe_property *cur_property; - pthread_mutex_t lock; + mp_mutex lock; - pthread_mutex_t wakeup_lock; - pthread_cond_t wakeup; + mp_mutex wakeup_lock; + mp_cond wakeup; // -- protected by wakeup_lock bool need_wakeup; @@ -185,7 +185,7 @@ void mp_clients_init(struct MPContext *mpctx) .mpctx = mpctx, }; mpctx->global->client_api = mpctx->clients; - pthread_mutex_init(&mpctx->clients->lock, NULL); + mp_mutex_init(&mpctx->clients->lock); } void mp_clients_destroy(struct MPContext *mpctx) @@ -201,7 +201,7 @@ void mp_clients_destroy(struct MPContext *mpctx) abort(); } - pthread_mutex_destroy(&mpctx->clients->lock); + mp_mutex_destroy(&mpctx->clients->lock); talloc_free(mpctx->clients); mpctx->clients = NULL; } @@ -211,14 +211,14 @@ void mp_clients_destroy(struct MPContext *mpctx) bool mp_clients_all_initialized(struct MPContext *mpctx) { bool all_ok = true; - pthread_mutex_lock(&mpctx->clients->lock); + mp_mutex_lock(&mpctx->clients->lock); for (int n = 0; n < mpctx->clients->num_clients; n++) { struct mpv_handle *ctx = mpctx->clients->clients[n]; - pthread_mutex_lock(&ctx->lock); + mp_mutex_lock(&ctx->lock); all_ok &= ctx->fuzzy_initialized; - pthread_mutex_unlock(&ctx->lock); + mp_mutex_unlock(&ctx->lock); } - pthread_mutex_unlock(&mpctx->clients->lock); + mp_mutex_unlock(&mpctx->clients->lock); return all_ok; } @@ -253,15 +253,15 @@ static struct mpv_handle *find_client(struct mp_client_api *clients, bool mp_client_id_exists(struct MPContext *mpctx, int64_t id) { - pthread_mutex_lock(&mpctx->clients->lock); + mp_mutex_lock(&mpctx->clients->lock); bool r = find_client_id(mpctx->clients, id); - pthread_mutex_unlock(&mpctx->clients->lock); + mp_mutex_unlock(&mpctx->clients->lock); return r; } struct mpv_handle *mp_new_client(struct mp_client_api *clients, const char *name) { - pthread_mutex_lock(&clients->lock); + mp_mutex_lock(&clients->lock); char nname[MAX_CLIENT_NAME]; for (int n = 1; n < 1000; n++) { @@ -278,7 +278,7 @@ struct mpv_handle *mp_new_client(struct mp_client_api *clients, const char *name } if (!nname[0] || clients->shutting_down) { - pthread_mutex_unlock(&clients->lock); + mp_mutex_unlock(&clients->lock); return NULL; } @@ -296,9 +296,9 @@ struct mpv_handle *mp_new_client(struct mp_client_api *clients, const char *name .event_mask = (1ULL << INTERNAL_EVENT_BASE) - 1, // exclude internal events .wakeup_pipe = {-1, -1}, }; - pthread_mutex_init(&client->lock, NULL); - pthread_mutex_init(&client->wakeup_lock, NULL); - pthread_cond_init(&client->wakeup, NULL); + mp_mutex_init(&client->lock); + mp_mutex_init(&client->wakeup_lock); + mp_cond_init(&client->wakeup); snprintf(client->name, sizeof(client->name), "%s", nname); @@ -308,7 +308,7 @@ struct mpv_handle *mp_new_client(struct mp_client_api *clients, const char *name if (clients->num_clients == 1 && !clients->mpctx->is_cli) client->fuzzy_initialized = true; - pthread_mutex_unlock(&clients->lock); + mp_mutex_unlock(&clients->lock); mpv_request_event(client, MPV_EVENT_TICK, 0); @@ -317,9 +317,9 @@ struct mpv_handle *mp_new_client(struct mp_client_api *clients, const char *name void mp_client_set_weak(struct mpv_handle *ctx) { - pthread_mutex_lock(&ctx->lock); + mp_mutex_lock(&ctx->lock); ctx->is_weak = true; - pthread_mutex_unlock(&ctx->lock); + mp_mutex_unlock(&ctx->lock); } const char *mpv_client_name(mpv_handle *ctx) @@ -344,52 +344,41 @@ struct mpv_global *mp_client_get_global(struct mpv_handle *ctx) static void wakeup_client(struct mpv_handle *ctx) { - pthread_mutex_lock(&ctx->wakeup_lock); + mp_mutex_lock(&ctx->wakeup_lock); if (!ctx->need_wakeup) { ctx->need_wakeup = true; - pthread_cond_broadcast(&ctx->wakeup); + mp_cond_broadcast(&ctx->wakeup); if (ctx->wakeup_cb) ctx->wakeup_cb(ctx->wakeup_cb_ctx); if (ctx->wakeup_pipe[0] != -1) (void)write(ctx->wakeup_pipe[1], &(char){0}, 1); } - pthread_mutex_unlock(&ctx->wakeup_lock); + mp_mutex_unlock(&ctx->wakeup_lock); } // Note: the caller has to deal with sporadic wakeups. static int wait_wakeup(struct mpv_handle *ctx, int64_t end) { int r = 0; - pthread_mutex_unlock(&ctx->lock); - pthread_mutex_lock(&ctx->wakeup_lock); - if (!ctx->need_wakeup) { - struct timespec ts = mp_time_us_to_timespec(end); - r = pthread_cond_timedwait(&ctx->wakeup, &ctx->wakeup_lock, &ts); - } + mp_mutex_unlock(&ctx->lock); + mp_mutex_lock(&ctx->wakeup_lock); + if (!ctx->need_wakeup) + r = mp_cond_timedwait_until(&ctx->wakeup, &ctx->wakeup_lock, end); if (r == 0) ctx->need_wakeup = false; - pthread_mutex_unlock(&ctx->wakeup_lock); - pthread_mutex_lock(&ctx->lock); + mp_mutex_unlock(&ctx->wakeup_lock); + mp_mutex_lock(&ctx->lock); return r; } void mpv_set_wakeup_callback(mpv_handle *ctx, void (*cb)(void *d), void *d) { - pthread_mutex_lock(&ctx->wakeup_lock); + mp_mutex_lock(&ctx->wakeup_lock); ctx->wakeup_cb = cb; ctx->wakeup_cb_ctx = d; if (ctx->wakeup_cb) ctx->wakeup_cb(ctx->wakeup_cb_ctx); - pthread_mutex_unlock(&ctx->wakeup_lock); -} - -void mpv_suspend(mpv_handle *ctx) -{ - MP_ERR(ctx, "mpv_suspend() is deprecated and does nothing.\n"); -} - -void mpv_resume(mpv_handle *ctx) -{ + mp_mutex_unlock(&ctx->wakeup_lock); } static void lock_core(mpv_handle *ctx) @@ -404,10 +393,10 @@ static void unlock_core(mpv_handle *ctx) void mpv_wait_async_requests(mpv_handle *ctx) { - pthread_mutex_lock(&ctx->lock); + mp_mutex_lock(&ctx->lock); while (ctx->reserved_events || ctx->async_counter) wait_wakeup(ctx, INT64_MAX); - pthread_mutex_unlock(&ctx->lock); + mp_mutex_unlock(&ctx->lock); } // Send abort signal to all matching work items. @@ -416,7 +405,7 @@ void mpv_wait_async_requests(mpv_handle *ctx) static void abort_async(struct MPContext *mpctx, mpv_handle *ctx, int type, uint64_t id) { - pthread_mutex_lock(&mpctx->abort_lock); + mp_mutex_lock(&mpctx->abort_lock); // Destroy all => ensure any newly appearing work is aborted immediately. if (ctx == NULL) @@ -431,12 +420,12 @@ static void abort_async(struct MPContext *mpctx, mpv_handle *ctx, } } - pthread_mutex_unlock(&mpctx->abort_lock); + mp_mutex_unlock(&mpctx->abort_lock); } -static void get_thread(void *ptr) +static void get_thread_id(void *ptr) { - *(pthread_t *)ptr = pthread_self(); + *(mp_thread_id *)ptr = mp_thread_current_id(); } static void mp_destroy_client(mpv_handle *ctx, bool terminate) @@ -452,7 +441,7 @@ static void mp_destroy_client(mpv_handle *ctx, bool terminate) if (terminate) mpv_command(ctx, (const char*[]){"quit", NULL}); - pthread_mutex_lock(&ctx->lock); + mp_mutex_lock(&ctx->lock); ctx->destroying = true; @@ -464,7 +453,7 @@ static void mp_destroy_client(mpv_handle *ctx, bool terminate) prop_unref(ctx->cur_property); ctx->cur_property = NULL; - pthread_mutex_unlock(&ctx->lock); + mp_mutex_unlock(&ctx->lock); abort_async(mpctx, ctx, 0, 0); @@ -476,7 +465,7 @@ static void mp_destroy_client(mpv_handle *ctx, bool terminate) osd_set_external_remove_owner(mpctx->osd, ctx); mp_input_remove_sections_by_owner(mpctx->input, ctx->name); - pthread_mutex_lock(&clients->lock); + mp_mutex_lock(&clients->lock); for (int n = 0; n < clients->num_clients; n++) { if (clients->clients[n] == ctx) { @@ -488,9 +477,9 @@ static void mp_destroy_client(mpv_handle *ctx, bool terminate) ctx->num_events--; } mp_msg_log_buffer_destroy(ctx->messages); - pthread_cond_destroy(&ctx->wakeup); - pthread_mutex_destroy(&ctx->wakeup_lock); - pthread_mutex_destroy(&ctx->lock); + mp_cond_destroy(&ctx->wakeup); + mp_mutex_destroy(&ctx->wakeup_lock); + mp_mutex_destroy(&ctx->lock); if (ctx->wakeup_pipe[0] != -1) { close(ctx->wakeup_pipe[0]); close(ctx->wakeup_pipe[1]); @@ -522,7 +511,7 @@ static void mp_destroy_client(mpv_handle *ctx, bool terminate) // mp_hook_test_completion() also relies on this a bit. mp_wakeup_core(mpctx); - pthread_mutex_unlock(&clients->lock); + mp_mutex_unlock(&clients->lock); // Note that even if num_clients==0, having set have_terminator keeps mpctx // and the core thread alive. @@ -533,17 +522,17 @@ static void mp_destroy_client(mpv_handle *ctx, bool terminate) mpctx->stop_play = PT_QUIT; mp_dispatch_unlock(mpctx->dispatch); - pthread_t playthread; - mp_dispatch_run(mpctx->dispatch, get_thread, &playthread); + mp_thread_id playthread; + mp_dispatch_run(mpctx->dispatch, get_thread_id, &playthread); // Ask the core thread to stop. - pthread_mutex_lock(&clients->lock); + mp_mutex_lock(&clients->lock); clients->terminate_core_thread = true; - pthread_mutex_unlock(&clients->lock); + mp_mutex_unlock(&clients->lock); mp_wakeup_core(mpctx); // Blocking wait for all clients and core thread to terminate. - pthread_join(playthread, NULL); + mp_thread_join_id(playthread); mp_destroy(mpctx); } @@ -554,11 +543,6 @@ void mpv_destroy(mpv_handle *ctx) mp_destroy_client(ctx, false); } -void mpv_detach_destroy(mpv_handle *ctx) -{ - mpv_destroy(ctx); -} - void mpv_terminate_destroy(mpv_handle *ctx) { mp_destroy_client(ctx, true); @@ -573,7 +557,7 @@ void mp_shutdown_clients(struct MPContext *mpctx) // Forcefully abort async work after 2 seconds of waiting. double abort_time = mp_time_sec() + 2; - pthread_mutex_lock(&clients->lock); + mp_mutex_lock(&clients->lock); // Prevent that new clients can appear. clients->shutting_down = true; @@ -582,7 +566,7 @@ void mp_shutdown_clients(struct MPContext *mpctx) while (clients->num_clients || mpctx->outstanding_async || !(mpctx->is_cli || clients->terminate_core_thread)) { - pthread_mutex_unlock(&clients->lock); + mp_mutex_unlock(&clients->lock); double left = abort_time - mp_time_sec(); if (left >= 0) { @@ -597,26 +581,26 @@ void mp_shutdown_clients(struct MPContext *mpctx) mp_client_broadcast_event(mpctx, MPV_EVENT_SHUTDOWN, NULL); mp_wait_events(mpctx); - pthread_mutex_lock(&clients->lock); + mp_mutex_lock(&clients->lock); } - pthread_mutex_unlock(&clients->lock); + mp_mutex_unlock(&clients->lock); } bool mp_is_shutting_down(struct MPContext *mpctx) { struct mp_client_api *clients = mpctx->clients; - pthread_mutex_lock(&clients->lock); + mp_mutex_lock(&clients->lock); bool res = clients->shutting_down; - pthread_mutex_unlock(&clients->lock); + mp_mutex_unlock(&clients->lock); return res; } -static void *core_thread(void *p) +static MP_THREAD_VOID core_thread(void *p) { struct MPContext *mpctx = p; - mpthread_set_name("mpv core"); + mp_thread_set_name("core"); while (!mpctx->initialized && mpctx->stop_play != PT_QUIT) mp_idle(mpctx); @@ -629,7 +613,7 @@ static void *core_thread(void *p) // the last mpv_handle. mp_shutdown_clients(mpctx); - return NULL; + MP_THREAD_RETURN(); } mpv_handle *mpv_create(void) @@ -646,8 +630,8 @@ mpv_handle *mpv_create(void) return NULL; } - pthread_t thread; - if (pthread_create(&thread, NULL, core_thread, mpctx) != 0) { + mp_thread thread; + if (mp_thread_create(&thread, core_thread, mpctx) != 0) { ctx->clients->have_terminator = true; // avoid blocking mpv_terminate_destroy(ctx); mp_destroy(mpctx); @@ -720,13 +704,13 @@ static void dup_event_data(struct mpv_event *ev) static int reserve_reply(struct mpv_handle *ctx) { int res = MPV_ERROR_EVENT_QUEUE_FULL; - pthread_mutex_lock(&ctx->lock); + mp_mutex_lock(&ctx->lock); if (ctx->reserved_events + ctx->num_events < ctx->max_events && !ctx->choked) { ctx->reserved_events++; res = 0; } - pthread_mutex_unlock(&ctx->lock); + mp_mutex_unlock(&ctx->lock); return res; } @@ -746,7 +730,7 @@ static int append_event(struct mpv_handle *ctx, struct mpv_event event, bool cop static int send_event(struct mpv_handle *ctx, struct mpv_event *event, bool copy) { - pthread_mutex_lock(&ctx->lock); + mp_mutex_lock(&ctx->lock); uint64_t mask = 1ULL << event->event_id; if (ctx->property_event_masks & mask) notify_property_events(ctx, event->event_id); @@ -762,7 +746,7 @@ static int send_event(struct mpv_handle *ctx, struct mpv_event *event, bool copy ctx->choked = true; } } - pthread_mutex_unlock(&ctx->lock); + mp_mutex_unlock(&ctx->lock); return r; } @@ -772,20 +756,20 @@ static void send_reply(struct mpv_handle *ctx, uint64_t userdata, struct mpv_event *event) { event->reply_userdata = userdata; - pthread_mutex_lock(&ctx->lock); + mp_mutex_lock(&ctx->lock); // If this fails, reserve_reply() probably wasn't called. assert(ctx->reserved_events > 0); ctx->reserved_events--; if (append_event(ctx, *event, false) < 0) - abort(); // not reached - pthread_mutex_unlock(&ctx->lock); + MP_ASSERT_UNREACHABLE(); + mp_mutex_unlock(&ctx->lock); } void mp_client_broadcast_event(struct MPContext *mpctx, int event, void *data) { struct mp_client_api *clients = mpctx->clients; - pthread_mutex_lock(&clients->lock); + mp_mutex_lock(&clients->lock); for (int n = 0; n < clients->num_clients; n++) { struct mpv_event event_data = { @@ -795,7 +779,7 @@ void mp_client_broadcast_event(struct MPContext *mpctx, int event, void *data) send_event(clients->clients[n], &event_data, true); } - pthread_mutex_unlock(&clients->lock); + mp_mutex_unlock(&clients->lock); } // Like mp_client_broadcast_event(), but can be called from any thread. @@ -828,7 +812,7 @@ int mp_client_send_event(struct MPContext *mpctx, const char *client_name, .reply_userdata = reply_userdata, }; - pthread_mutex_lock(&clients->lock); + mp_mutex_lock(&clients->lock); struct mpv_handle *ctx = find_client(clients, client_name); if (ctx) { @@ -838,7 +822,7 @@ int mp_client_send_event(struct MPContext *mpctx, const char *client_name, talloc_free(data); } - pthread_mutex_unlock(&clients->lock); + mp_mutex_unlock(&clients->lock); return r; } @@ -860,16 +844,9 @@ int mp_client_send_event_dup(struct MPContext *mpctx, const char *client_name, return mp_client_send_event(mpctx, client_name, 0, event, event_data.data); } -static bool deprecated_events[] = { - [MPV_EVENT_TRACKS_CHANGED] = true, - [MPV_EVENT_TRACK_SWITCHED] = true, +static const bool deprecated_events[] = { [MPV_EVENT_IDLE] = true, - [MPV_EVENT_PAUSE] = true, - [MPV_EVENT_UNPAUSE] = true, [MPV_EVENT_TICK] = true, - [MPV_EVENT_SCRIPT_INPUT_DISPATCH] = true, - [MPV_EVENT_METADATA_UPDATE] = true, - [MPV_EVENT_CHAPTER_CHANGE] = true, }; int mpv_request_event(mpv_handle *ctx, mpv_event_id event, int enable) @@ -879,7 +856,7 @@ int mpv_request_event(mpv_handle *ctx, mpv_event_id event, int enable) if (event == MPV_EVENT_SHUTDOWN && !enable) return MPV_ERROR_INVALID_PARAMETER; assert(event < (int)INTERNAL_EVENT_BASE); // excluded above; they have no name - pthread_mutex_lock(&ctx->lock); + mp_mutex_lock(&ctx->lock); uint64_t bit = 1ULL << event; ctx->event_mask = enable ? ctx->event_mask | bit : ctx->event_mask & ~bit; if (enable && event < MP_ARRAY_SIZE(deprecated_events) && @@ -888,7 +865,7 @@ int mpv_request_event(mpv_handle *ctx, mpv_event_id event, int enable) MP_WARN(ctx, "The '%s' event is deprecated and will be removed.\n", mpv_event_name(event)); } - pthread_mutex_unlock(&ctx->lock); + mp_mutex |