diff options
author | Martin Herkt <lachs0r@srsfckn.biz> | 2016-01-18 07:27:03 +0100 |
---|---|---|
committer | Martin Herkt <lachs0r@srsfckn.biz> | 2016-01-18 07:27:03 +0100 |
commit | ba9b2f1e49732d597009ba514b0132a50562cd10 (patch) | |
tree | fa05f5feb181823ac9d3b5682a835ff825de6914 /player | |
parent | e1993d5ad2bdf3dd4c26474aaa2370cbc9c1cd1b (diff) | |
parent | 7b4ccb3e9f58a0745b58e473ee6e60b381242813 (diff) | |
download | mpv-ba9b2f1e49732d597009ba514b0132a50562cd10.tar.bz2 mpv-ba9b2f1e49732d597009ba514b0132a50562cd10.tar.xz |
Merge branch 'master' into release/current
Diffstat (limited to 'player')
-rw-r--r-- | player/audio.c | 23 | ||||
-rw-r--r-- | player/client.c | 7 | ||||
-rw-r--r-- | player/client.h | 1 | ||||
-rw-r--r-- | player/command.c | 239 | ||||
-rw-r--r-- | player/configfiles.c | 72 | ||||
-rw-r--r-- | player/core.h | 80 | ||||
-rw-r--r-- | player/external_files.c | 45 | ||||
-rw-r--r-- | player/loadfile.c | 85 | ||||
-rw-r--r-- | player/lua.c | 2 | ||||
-rw-r--r-- | player/lua/ytdl_hook.lua | 9 | ||||
-rw-r--r-- | player/main.c | 7 | ||||
-rw-r--r-- | player/misc.c | 17 | ||||
-rw-r--r-- | player/osd.c | 16 | ||||
-rw-r--r-- | player/playloop.c | 144 | ||||
-rw-r--r-- | player/screenshot.c | 15 | ||||
-rw-r--r-- | player/sub.c | 281 | ||||
-rw-r--r-- | player/video.c | 446 |
17 files changed, 723 insertions, 766 deletions
diff --git a/player/audio.c b/player/audio.c index 96345366fd..a7a5f727c7 100644 --- a/player/audio.c +++ b/player/audio.c @@ -23,7 +23,7 @@ #include <assert.h> #include "config.h" -#include "talloc.h" +#include "mpv_talloc.h" #include "common/msg.h" #include "common/encode.h" @@ -218,7 +218,7 @@ void reinit_audio_chain(struct MPContext *mpctx) mpctx->d_audio->header = sh; mpctx->d_audio->pool = mp_audio_pool_create(mpctx->d_audio); mpctx->d_audio->afilter = af_new(mpctx->global); - mpctx->d_audio->afilter->replaygain_data = sh->audio->replaygain_data; + mpctx->d_audio->afilter->replaygain_data = sh->codec->replaygain_data; mpctx->d_audio->spdif_passthrough = true; mpctx->ao_buffer = mp_audio_buffer_create(NULL); if (!audio_init_best_codec(mpctx->d_audio)) @@ -361,9 +361,10 @@ double written_audio_pts(struct MPContext *mpctx) if (a_pts == MP_NOPTS_VALUE) return MP_NOPTS_VALUE; - // d_audio->pts is the timestamp of the latest input packet with - // known pts that the decoder has decoded. d_audio->pts_bytes is - // the amount of bytes the decoder has written after that timestamp. + // d_audio->pts is the timestamp of the first sample of the latest frame + // the with a known pts that the decoder has returned. d_audio->pts_offset + // is the amount of samples the decoder has returned after that timestamp + // (includes the frame size). a_pts += d_audio->pts_offset / (double)in_format.rate; // Now a_pts hopefully holds the pts for end of audio from decoder. @@ -467,7 +468,7 @@ static bool get_sync_samples(struct MPContext *mpctx, int *skip) if (written_pts == MP_NOPTS_VALUE && !mp_audio_buffer_samples(mpctx->ao_buffer)) return false; // no audio read yet - bool sync_to_video = mpctx->d_video && mpctx->sync_audio_to_video && + bool sync_to_video = mpctx->vo_chain && mpctx->sync_audio_to_video && mpctx->video_status != STATUS_EOF; double sync_pts = MP_NOPTS_VALUE; @@ -486,11 +487,12 @@ static bool get_sync_samples(struct MPContext *mpctx, int *skip) double ptsdiff = written_pts - sync_pts; // Missing timestamp, or PTS reset, or just broken. - if (written_pts == MP_NOPTS_VALUE || fabs(ptsdiff) > 3600) { + if (written_pts == MP_NOPTS_VALUE) { MP_WARN(mpctx, "Failed audio resync.\n"); mpctx->audio_status = STATUS_FILLING; return true; } + ptsdiff = MPCLAMP(ptsdiff, -3600, 3600); int align = af_format_sample_alignment(out_format.format); *skip = (int)(-ptsdiff * play_samplerate) / align * align; @@ -543,6 +545,13 @@ void fill_audio_out_buffers(struct MPContext *mpctx, double endpts) return; // try again next iteration } + if (mpctx->vo_chain && d_audio->pts_reset) { + MP_VERBOSE(mpctx, "Reset playback due to audio timestamp reset.\n"); + reset_playback_state(mpctx); + mpctx->sleeptime = 0; + return; + } + struct mp_audio out_format = {0}; ao_get_format(mpctx->ao, &out_format); double play_samplerate = out_format.rate / mpctx->audio_speed; diff --git a/player/client.c b/player/client.c index f4758f653c..3abc8d8086 100644 --- a/player/client.c +++ b/player/client.c @@ -21,6 +21,7 @@ #include <assert.h> #include "common/common.h" +#include "common/global.h" #include "common/msg.h" #include "common/msg_control.h" #include "input/input.h" @@ -137,6 +138,7 @@ void mp_clients_init(struct MPContext *mpctx) *mpctx->clients = (struct mp_client_api) { .mpctx = mpctx, }; + mpctx->global->client_api = mpctx->clients; pthread_mutex_init(&mpctx->clients->lock, NULL); } @@ -264,6 +266,11 @@ struct MPContext *mp_client_get_core(struct mpv_handle *ctx) return ctx->mpctx; } +struct MPContext *mp_client_api_get_core(struct mp_client_api *api) +{ + return api->mpctx; +} + static void wakeup_client(struct mpv_handle *ctx) { pthread_mutex_lock(&ctx->wakeup_lock); diff --git a/player/client.h b/player/client.h index 5bc3c770eb..a9d6cbde52 100644 --- a/player/client.h +++ b/player/client.h @@ -31,6 +31,7 @@ void mp_client_property_change(struct MPContext *mpctx, const char *name); struct mpv_handle *mp_new_client(struct mp_client_api *clients, const char *name); struct mp_log *mp_client_get_log(struct mpv_handle *ctx); struct MPContext *mp_client_get_core(struct mpv_handle *ctx); +struct MPContext *mp_client_api_get_core(struct mp_client_api *api); void mp_resume_all(struct mpv_handle *ctx); diff --git a/player/command.c b/player/command.c index cc30d2b21a..3c7cfb282d 100644 --- a/player/command.c +++ b/player/command.c @@ -30,7 +30,7 @@ #include <libavutil/common.h> #include "config.h" -#include "talloc.h" +#include "mpv_talloc.h" #include "client.h" #include "common/msg.h" #include "common/msg_control.h" @@ -240,7 +240,7 @@ static char *format_file_size(int64_t size) static char *format_delay(double time) { - return talloc_asprintf(NULL, "%d ms", ROUND(time * 1000)); + return talloc_asprintf(NULL, "%d ms", (int)lrint(time * 1000)); } // Property-option bridge. (Maps the property to the option with the same name.) @@ -391,6 +391,9 @@ static int mp_property_media_title(void *ctx, struct m_property *prop, if (name && name[0]) return m_property_strdup_ro(action, arg, name); if (mpctx->master_demuxer) { + name = mp_tags_get_str(mpctx->master_demuxer->metadata, "service_name"); + if (name && name[0]) + return m_property_strdup_ro(action, arg, name); name = mp_tags_get_str(mpctx->master_demuxer->metadata, "title"); if (name && name[0]) return m_property_strdup_ro(action, arg, name); @@ -533,7 +536,7 @@ static int mp_property_avsync(void *ctx, struct m_property *prop, int action, void *arg) { MPContext *mpctx = ctx; - if (!mpctx->d_audio || !mpctx->d_video) + if (!mpctx->d_audio || !mpctx->vo_chain) return M_PROPERTY_UNAVAILABLE; if (action == M_PROPERTY_PRINT) { *(char **)arg = talloc_asprintf(NULL, "%7.3f", mpctx->last_av_difference); @@ -546,7 +549,7 @@ static int mp_property_total_avsync_change(void *ctx, struct m_property *prop, int action, void *arg) { MPContext *mpctx = ctx; - if (!mpctx->d_audio || !mpctx->d_video) + if (!mpctx->d_audio || !mpctx->vo_chain) return M_PROPERTY_UNAVAILABLE; if (mpctx->total_avsync_change == MP_NOPTS_VALUE) return M_PROPERTY_UNAVAILABLE; @@ -557,17 +560,17 @@ static int mp_property_drop_frame_cnt(void *ctx, struct m_property *prop, int action, void *arg) { MPContext *mpctx = ctx; - if (!mpctx->d_video) + if (!mpctx->vo_chain) return M_PROPERTY_UNAVAILABLE; - return m_property_int_ro(action, arg, mpctx->dropped_frames_total); + return m_property_int_ro(action, arg, mpctx->vo_chain->video_src->dropped_frames); } static int mp_property_mistimed_frame_count(void *ctx, struct m_property *prop, int action, void *arg) { MPContext *mpctx = ctx; - if (!mpctx->d_video || !mpctx->display_sync_active) + if (!mpctx->vo_chain || !mpctx->display_sync_active) return M_PROPERTY_UNAVAILABLE; return m_property_int_ro(action, arg, mpctx->mistimed_frames_total); @@ -577,7 +580,7 @@ static int mp_property_vsync_ratio(void *ctx, struct m_property *prop, int action, void *arg) { MPContext *mpctx = ctx; - if (!mpctx->d_video || !mpctx->display_sync_active) + if (!mpctx->vo_chain || !mpctx->display_sync_active) return M_PROPERTY_UNAVAILABLE; int vsyncs = 0, frames = 0; @@ -599,7 +602,7 @@ static int mp_property_vo_drop_frame_count(void *ctx, struct m_property *prop, int action, void *arg) { MPContext *mpctx = ctx; - if (!mpctx->d_video) + if (!mpctx->vo_chain) return M_PROPERTY_UNAVAILABLE; return m_property_int_ro(action, arg, vo_get_drop_count(mpctx->video_out)); @@ -609,7 +612,7 @@ static int mp_property_vo_delayed_frame_count(void *ctx, struct m_property *prop int action, void *arg) { MPContext *mpctx = ctx; - if (!mpctx->d_video) + if (!mpctx->vo_chain) return M_PROPERTY_UNAVAILABLE; return m_property_int_ro(action, arg, vo_get_delayed_count(mpctx->video_out)); @@ -791,9 +794,7 @@ static int mp_property_chapter(void *ctx, struct m_property *prop, int step_all; if (action == M_PROPERTY_SWITCH) { struct m_property_switch_arg *sarg = arg; - step_all = ROUND(sarg->inc); - if (num < 2) // semi-broken file; ignore for user convenience - return M_PROPERTY_UNAVAILABLE; + step_all = lrint(sarg->inc); // Check threshold for relative backward seeks if (mpctx->opts->chapter_seek_threshold >= 0 && step_all < 0) { double current_chapter_start = @@ -814,6 +815,9 @@ static int mp_property_chapter(void *ctx, struct m_property *prop, if (mpctx->opts->keep_open) { seek_to_last_frame(mpctx); } else { + // semi-broken file; ignore for user convenience + if (action == M_PROPERTY_SWITCH && num < 2) + return M_PROPERTY_UNAVAILABLE; if (!mpctx->stop_play) mpctx->stop_play = PT_NEXT_ENTRY; } @@ -1233,9 +1237,9 @@ static int mp_property_filter_metadata(void *ctx, struct m_property *prop, struct mp_tags metadata = {0}; int res = CONTROL_UNKNOWN; if (strcmp(type, "vf") == 0) { - if (!(mpctx->d_video && mpctx->d_video->vfilter)) + if (!mpctx->vo_chain) return M_PROPERTY_UNAVAILABLE; - struct vf_chain *vf = mpctx->d_video->vfilter; + struct vf_chain *vf = mpctx->vo_chain->vf; res = vf_control_by_label(vf, VFCTRL_GET_METADATA, &metadata, key); } else if (strcmp(type, "af") == 0) { if (!(mpctx->d_audio && mpctx->d_audio->afilter)) @@ -1692,7 +1696,7 @@ static int mp_property_audio_delay(void *ctx, struct m_property *prop, int action, void *arg) { MPContext *mpctx = ctx; - if (!(mpctx->d_audio && mpctx->d_video)) + if (!(mpctx->d_audio && mpctx->vo_chain)) return M_PROPERTY_UNAVAILABLE; float delay = mpctx->opts->audio_delay; switch (action) { @@ -1712,7 +1716,7 @@ static int mp_property_audio_codec_name(void *ctx, struct m_property *prop, int action, void *arg) { MPContext *mpctx = ctx; - const char *c = mpctx->d_audio ? mpctx->d_audio->header->codec : NULL; + const char *c = mpctx->d_audio ? mpctx->d_audio->header->codec->codec : NULL; return m_property_strdup_ro(action, arg, c); } @@ -1929,8 +1933,7 @@ static int property_switch_track_ff(void *ctx, struct m_property *prop, static int track_channels(struct track *track) { - return track->stream && track->stream->audio - ? track->stream->audio->channels.num : 0; + return track->stream ? track->stream->codec->channels.num : 0; } static int get_track_entry(int item, int action, void *arg, void *ctx) @@ -1938,7 +1941,7 @@ static int get_track_entry(int item, int action, void *arg, void *ctx) struct MPContext *mpctx = ctx; struct track *track = mpctx->tracks[item]; - const char *codec = track->stream ? track->stream->codec : NULL; + const char *codec = track->stream ? track->stream->codec->codec : NULL; struct m_sub_property props[] = { {"id", SUB_PROP_INT(track->user_tid)}, @@ -2098,8 +2101,9 @@ static int mp_property_hwdec(void *ctx, struct m_property *prop, int action, void *arg) { MPContext *mpctx = ctx; + struct track *track = mpctx->current_track[0][STREAM_VIDEO]; + struct dec_video *vd = track ? track->d_video : NULL; struct MPOpts *opts = mpctx->opts; - struct dec_video *vd = mpctx->d_video; if (action == M_PROPERTY_SET) { int new = *(int *)arg; @@ -2130,7 +2134,8 @@ static int mp_property_hwdec_active(void *ctx, struct m_property *prop, int action, void *arg) { MPContext *mpctx = ctx; - struct dec_video *vd = mpctx->d_video; + struct track *track = mpctx->current_track[0][STREAM_VIDEO]; + struct dec_video *vd = track ? track->d_video : NULL; bool active = false; if (vd) { int current = 0; @@ -2144,7 +2149,8 @@ static int mp_property_detected_hwdec(void *ctx, struct m_property *prop, int action, void *arg) { MPContext *mpctx = ctx; - struct dec_video *vd = mpctx->d_video; + struct track *track = mpctx->current_track[0][STREAM_VIDEO]; + struct dec_video *vd = track ? track->d_video : NULL; switch (action) { case M_PROPERTY_GET_TYPE: { @@ -2181,10 +2187,10 @@ static bool probe_deint_filter(struct MPContext *mpctx, const char *filt) static bool check_output_format(struct MPContext *mpctx, int imgfmt) { - struct dec_video *vd = mpctx->d_video; - if (!vd) + struct vo_chain *vo_c = mpctx->vo_chain; + if (!vo_c) return false; - return vd->vfilter->allowed_output_formats[imgfmt - IMGFMT_START]; + return vo_c->vf->allowed_output_formats[imgfmt - IMGFMT_START]; } static int probe_deint_filters(struct MPContext *mpctx) @@ -2207,20 +2213,20 @@ static int probe_deint_filters(struct MPContext *mpctx) if (check_output_format(mpctx, IMGFMT_VAAPI) && probe_deint_filter(mpctx, "vavpp")) return 0; - if (probe_deint_filter(mpctx, "yadif:mode=field:interlaced-only=yes")) + if (probe_deint_filter(mpctx, "yadif")) return 0; return -1; } static int get_deinterlacing(struct MPContext *mpctx) { - struct dec_video *vd = mpctx->d_video; + struct vo_chain *vo_c = mpctx->vo_chain; int enabled = 0; - if (video_vf_vo_control(vd, VFCTRL_GET_DEINTERLACE, &enabled) != CONTROL_OK) + if (video_vf_vo_control(vo_c, VFCTRL_GET_DEINTERLACE, &enabled) != CONTROL_OK) enabled = -1; if (enabled < 0) { // vf_lavfi doesn't support VFCTRL_GET_DEINTERLACE - if (vf_find_by_label(vd->vfilter, VF_DEINTERLACE_LABEL)) + if (vf_find_by_label(vo_c->vf, VF_DEINTERLACE_LABEL)) enabled = 1; } return enabled; @@ -2233,14 +2239,14 @@ void remove_deint_filter(struct MPContext *mpctx) void set_deinterlacing(struct MPContext *mpctx, bool enable) { - struct dec_video *vd = mpctx->d_video; - if (vf_find_by_label(vd->vfilter, VF_DEINTERLACE_LABEL)) { + struct vo_chain *vo_c = mpctx->vo_chain; + if (vf_find_by_label(vo_c->vf, VF_DEINTERLACE_LABEL)) { if (!enable) remove_deint_filter(mpctx); } else { if ((get_deinterlacing(mpctx) > 0) != enable) { int arg = enable; - if (video_vf_vo_control(vd, VFCTRL_SET_DEINTERLACE, &arg) != CONTROL_OK) + if (video_vf_vo_control(vo_c, VFCTRL_SET_DEINTERLACE, &arg) != CONTROL_OK) probe_deint_filters(mpctx); } } @@ -2251,7 +2257,7 @@ static int mp_property_deinterlace(void *ctx, struct m_property *prop, int action, void *arg) { MPContext *mpctx = ctx; - if (!mpctx->d_video || !mpctx->d_video->vfilter) + if (!mpctx->vo_chain) return mp_property_generic_option(mpctx, prop, action, arg); switch (action) { case M_PROPERTY_GET: @@ -2355,11 +2361,11 @@ static int get_frame_count(struct MPContext *mpctx) { struct demuxer *demuxer = mpctx->demuxer; if (!demuxer) - return 0; - if (!mpctx->d_video) - return 0; + return -1; + if (!mpctx->vo_chain) + return -1; double len = get_time_length(mpctx); - double fps = mpctx->d_video->fps; + double fps = mpctx->vo_chain->container_fps; if (len < 0 || fps <= 0) return 0; @@ -2370,33 +2376,23 @@ static int mp_property_frame_number(void *ctx, struct m_property *prop, int action, void *arg) { MPContext *mpctx = ctx; - if (!mpctx->d_video) + int frames = get_frame_count(mpctx); + if (frames < 0) return M_PROPERTY_UNAVAILABLE; - int frame_number = ROUND(get_current_pos_ratio(mpctx, false) * - (double)get_frame_count(mpctx)); - return m_property_int_ro(action, arg, frame_number); + return m_property_int_ro(action, arg, + lrint(get_current_pos_ratio(mpctx, false) * frames)); } static int mp_property_frame_count(void *ctx, struct m_property *prop, int action, void *arg) { MPContext *mpctx = ctx; - - if (!mpctx->d_video) - return M_PROPERTY_UNAVAILABLE; - - return m_property_int_ro(action, arg, get_frame_count(mpctx)); -} - -static int mp_property_framedrop(void *ctx, struct m_property *prop, - int action, void *arg) -{ - MPContext *mpctx = ctx; - if (!mpctx->d_video) + int frames = get_frame_count(mpctx); + if (frames < 0) return M_PROPERTY_UNAVAILABLE; - return mp_property_generic_option(mpctx, prop, action, arg); + return m_property_int_ro(action, arg, frames); } static int mp_property_video_color(void *ctx, struct m_property *prop, @@ -2404,17 +2400,17 @@ static int mp_property_video_color(void *ctx, struct m_property *prop, { const char *name = prop->priv ? prop->priv : prop->name; MPContext *mpctx = ctx; - if (!mpctx->d_video) + if (!mpctx->vo_chain) return M_PROPERTY_UNAVAILABLE; switch (action) { case M_PROPERTY_SET: { - if (video_set_colors(mpctx->d_video, name, *(int *) arg) <= 0) + if (video_set_colors(mpctx->vo_chain, name, *(int *) arg) <= 0) return M_PROPERTY_UNAVAILABLE; break; } case M_PROPERTY_GET: - if (video_get_colors(mpctx->d_video, name, (int *)arg) <= 0) + if (video_get_colors(mpctx->vo_chain, name, (int *)arg) <= 0) return M_PROPERTY_UNAVAILABLE; // Write new value to option variable mp_property_generic_option(mpctx, prop, M_PROPERTY_SET, arg); @@ -2431,7 +2427,8 @@ static int mp_property_video_format(void *ctx, struct m_property *prop, int action, void *arg) { MPContext *mpctx = ctx; - const char *c = mpctx->d_video ? mpctx->d_video->header->codec : NULL; + struct track *track = mpctx->current_track[0][STREAM_VIDEO]; + const char *c = track && track->stream ? track->stream->codec->codec : NULL; return m_property_strdup_ro(action, arg, c); } @@ -2440,7 +2437,8 @@ static int mp_property_video_codec(void *ctx, struct m_property *prop, int action, void *arg) { MPContext *mpctx = ctx; - const char *c = mpctx->d_video ? mpctx->d_video->decoder_desc : NULL; + struct track *track = mpctx->current_track[0][STREAM_VIDEO]; + const char *c = track->d_video ? track->d_video->decoder_desc : NULL; return m_property_strdup_ro(action, arg, c); } @@ -2449,8 +2447,8 @@ static int property_imgparams(struct mp_image_params p, int action, void *arg) if (!p.imgfmt) return M_PROPERTY_UNAVAILABLE; - double dar = p.d_w / (double)p.d_h; - double sar = p.w / (double)p.h; + int d_w, d_h; + mp_image_params_get_dsize(&p, &d_w, &d_h); struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(p.imgfmt); int bpp = 0; @@ -2465,10 +2463,10 @@ static int property_imgparams(struct mp_image_params p, int action, void *arg) .unavailable = !(desc.flags & MP_IMGFLAG_PLANAR)}, {"w", SUB_PROP_INT(p.w)}, {"h", SUB_PROP_INT(p.h)}, - {"dw", SUB_PROP_INT(p.d_w)}, - {"dh", SUB_PROP_INT(p.d_h)}, - {"aspect", SUB_PROP_FLOAT(dar)}, - {"par", SUB_PROP_FLOAT(dar / sar)}, + {"dw", SUB_PROP_INT(d_w)}, + {"dh", SUB_PROP_INT(d_h)}, + {"aspect", SUB_PROP_FLOAT(d_w / (double)d_h)}, + {"par", SUB_PROP_FLOAT(p.p_w / (double)p.p_h)}, {"colormatrix", SUB_PROP_STR(m_opt_choice_str(mp_csp_names, p.colorspace))}, {"colorlevels", @@ -2492,11 +2490,10 @@ static int property_imgparams(struct mp_image_params p, int action, void *arg) static struct mp_image_params get_video_out_params(struct MPContext *mpctx) { - if (!mpctx->d_video || !mpctx->d_video->vfilter || - mpctx->d_video->vfilter->initialized < 1) + if (!mpctx->vo_chain || mpctx->vo_chain->vf->initialized < 1) return (struct mp_image_params){0}; - return mpctx->d_video->vfilter->output_params; + return mpctx->vo_chain->vf->output_params; } static int mp_property_vo_imgparams(void *ctx, struct m_property *prop, @@ -2509,18 +2506,20 @@ static int mp_property_vd_imgparams(void *ctx, struct m_property *prop, int action, void *arg) { MPContext *mpctx = ctx; - struct dec_video *vd = mpctx->d_video; - if (!vd) + struct vo_chain *vo_c = mpctx->vo_chain; + struct track *track = mpctx->current_track[0][STREAM_VIDEO]; + if (!vo_c || !track) return M_PROPERTY_UNAVAILABLE; - struct sh_video *sh = vd->header->video; - if (vd->vfilter->override_params.imgfmt) { - return property_imgparams(vd->vfilter->override_params, action, arg); - } else if (sh->disp_w && sh->disp_h) { + struct mp_codec_params *c = + track && track->stream ? track->stream->codec : NULL; + if (vo_c->vf->input_params.imgfmt) { + return property_imgparams(vo_c->vf->input_params, action, arg); + } else if (c && c->disp_w && c->disp_h) { // Simplistic fallback for stupid scripts querying "width"/"height" // before the first frame is decoded. struct m_sub_property props[] = { - {"w", SUB_PROP_INT(sh->disp_w)}, - {"h", SUB_PROP_INT(sh->disp_h)}, + {"w", SUB_PROP_INT(c->disp_w)}, + {"h", SUB_PROP_INT(c->disp_h)}, {0} }; return m_property_read_sub(props, action, arg); @@ -2561,8 +2560,8 @@ static int mp_property_window_scale(void *ctx, struct m_property *prop, return M_PROPERTY_UNAVAILABLE; struct mp_image_params params = get_video_out_params(mpctx); - int vid_w = params.d_w; - int vid_h = params.d_h; + int vid_w, vid_h; + mp_image_params_get_dsize(¶ms, &vid_w, &vid_h); if (vid_w < 1 || vid_h < 1) return M_PROPERTY_UNAVAILABLE; @@ -2743,7 +2742,7 @@ static int mp_property_fps(void *ctx, struct m_property *prop, int action, void *arg) { MPContext *mpctx = ctx; - float fps = mpctx->d_video ? mpctx->d_video->fps : 0; + float fps = mpctx->vo_chain ? mpctx->vo_chain->container_fps : 0; if (fps < 0.1 || !isfinite(fps)) return M_PROPERTY_UNAVAILABLE;; return m_property_float_ro(action, arg, fps); @@ -2753,7 +2752,7 @@ static int mp_property_vf_fps(void *ctx, struct m_property *prop, int action, void *arg) { MPContext *mpctx = ctx; - if (!mpctx->d_video) + if (!mpctx->vo_chain) return M_PROPERTY_UNAVAILABLE; double avg = calc_average_frame_duration(mpctx); if (avg <= 0) @@ -2769,22 +2768,33 @@ static int mp_property_aspect(void *ctx, struct m_property *prop, switch (action) { case M_PROPERTY_SET: { mpctx->opts->movie_aspect = *(float *)arg; - if (mpctx->d_video) { - reinit_video_filters(mpctx); + struct track *track = mpctx->current_track[0][STREAM_VIDEO]; + if (track && track->d_video) { + video_reset_aspect(track->d_video); mp_force_video_refresh(mpctx); } return M_PROPERTY_OK; } + case M_PROPERTY_PRINT: { + if (mpctx->opts->movie_aspect <= 0) { + *(char **)arg = talloc_strdup(NULL, "(original)"); + return M_PROPERTY_OK; + } + break; + } case M_PROPERTY_GET: { float aspect = mpctx->opts->movie_aspect; - if (mpctx->d_video && aspect <= 0) { - struct dec_video *d_video = mpctx->d_video; - struct sh_video *sh_video = d_video->header->video; - struct mp_image_params *params = &d_video->vfilter->override_params; - if (params && params->d_w && params->d_h) { - aspect = (float)params->d_w / params->d_h; - } else if (sh_video->disp_w && sh_video->disp_h) { - aspect = (float)sh_video->disp_w / sh_video->disp_h; + struct track *track = mpctx->current_track[0][STREAM_VIDEO]; + if (track && track->d_video && mpctx->vo_chain && aspect <= 0) { + struct dec_video *d_video = track->d_video; + struct mp_codec_params *c = d_video->header->codec; + struct mp_image_params *params = &mpctx->vo_chain->vf->input_params; + if (params && params->p_w > 0 && params->p_h > 0) { + int d_w, d_h; + mp_image_params_get_dsize(params, &d_w, &d_h); + aspect = (float)d_w / d_h; + } else if (c->disp_w && c->disp_h) { + aspect = (float)c->disp_w / c->disp_h; } } *(float *)arg = aspect; @@ -2978,7 +2988,6 @@ static int mp_property_dvb_channel(void *ctx, struct m_property *prop, int r; switch (action) { case M_PROPERTY_SET: - mpctx->last_dvb_step = 1; r = prop_stream_ctrl(mpctx, STREAM_CTRL_DVB_SET_CHANNEL, arg); if (r == M_PROPERTY_OK && !mpctx->stop_play) mpctx->stop_play = PT_RELOAD_FILE; @@ -2986,7 +2995,6 @@ static int mp_property_dvb_channel(void *ctx, struct m_property *prop, case M_PROPERTY_SWITCH: { struct m_property_switch_arg *sa = arg; int dir = sa->inc >= 0 ? 1 : -1; - mpctx->last_dvb_step = dir; r = prop_stream_ctrl(mpctx, STREAM_CTRL_DVB_STEP_CHANNEL, &dir); if (r == M_PROPERTY_OK && !mpctx->stop_play) mpctx->stop_play = PT_RELOAD_FILE; @@ -2999,6 +3007,35 @@ static int mp_property_dvb_channel(void *ctx, struct m_property *prop, return M_PROPERTY_NOT_IMPLEMENTED; } +static int mp_property_dvb_channel_name(void *ctx, struct m_property *prop, + int action, void *arg) +{ + MPContext *mpctx = ctx; + int r; + switch (action) { + case M_PROPERTY_SET: + r = prop_stream_ctrl(mpctx, STREAM_CTRL_DVB_SET_CHANNEL_NAME, arg); + if (r == M_PROPERTY_OK && !mpctx->stop_play) + mpctx->stop_play = PT_RELOAD_FILE; + return r; + case M_PROPERTY_SWITCH: { + struct m_property_switch_arg *sa = arg; + int dir = sa->inc >= 0 ? 1 : -1; + r = prop_stream_ctrl(mpctx, STREAM_CTRL_DVB_STEP_CHANNEL, &dir); + if (r == M_PROPERTY_OK && !mpctx->stop_play) + mpctx->stop_play = PT_RELOAD_FILE; + return r; + } + case M_PROPERTY_GET: { + return prop_stream_ctrl(mpctx, STREAM_CTRL_DVB_GET_CHANNEL_NAME, arg); + } + case M_PROPERTY_GET_TYPE: + *(struct m_option *)arg = (struct m_option){.type = CONF_TYPE_STRING}; + return M_PROPERTY_OK; + } + return M_PROPERTY_NOT_IMPLEMENTED; +} + static int mp_property_playlist_pos(void *ctx, struct m_property *prop, int action, void *arg) { @@ -3538,7 +3575,7 @@ static const struct m_property mp_properties[] = { {"ontop", mp_property_ontop}, {"border", mp_property_border}, {"on-all-workspaces", mp_property_all_workspaces}, - {"framedrop", mp_property_framedrop}, + {"framedrop", mp_property_generic_option}, {"gamma", mp_property_video_color}, {"brightness", mp_property_video_color}, {"contrast", mp_property_video_color}, @@ -3626,6 +3663,7 @@ static const struct m_property mp_properties[] = { {"tv-scan", mp_property_tv_scan}, {"tv-channel", mp_property_tv_channel}, {"dvb-channel", mp_property_dvb_channel}, + {"dvb-channel-name", mp_property_dvb_channel_name}, {"cursor-autohide", mp_property_cursor_autohide}, @@ -3695,14 +3733,14 @@ static const char *const *const mp_event_property_change[] = { "samplerate", "channels", "audio", "volume", "mute", "balance", "volume-restore-data", "current-ao", "audio-codec-name", "audio-params", "audio-out-params"), - E(MPV_EVENT_SEEK, "seeking", "core-idle"), - E(MPV_EVENT_PLAYBACK_RESTART, "seeking", "core-idle"), + E(MPV_EVENT_SEEK, "seeking", "core-idle", "eof-reached"), + E(MPV_EVENT_PLAYBACK_RESTART, "seeking", "core-idle", "eof-reached"), E(MPV_EVENT_METADATA_UPDATE, "metadata", "filtered-metadata", "media-title"), E(MPV_EVENT_CHAPTER_CHANGE, "chapter", "chapter-metadata"), E(MP_EVENT_CACHE_UPDATE, "cache", "cache-free", "cache-used", "cache-idle", "demuxer-cache-duration", "demuxer-cache-idle", "paused-for-cache", "demuxer-cache-time"), - E(MP_EVENT_WIN_RESIZE, "window-scale"), + E(MP_EVENT_WIN_RESIZE, "window-scale", "osd-width", "osd-height", "osd-par"), E(MP_EVENT_WIN_STATE, "window-minimized", "display-names", "display-fps", "fullscreen"), }; #undef E @@ -4526,7 +4564,8 @@ int run_command(struct MPContext *mpctx, struct mp_cmd *cmd, struct mpv_node *re case MP_CMD_SUB_SEEK: { if (!mpctx->playback_initialized) return -1; - struct dec_sub *sub = mpctx->d_sub[0]; + struct track *track = mpctx->current_track[0][STREAM_SUB]; + struct dec_sub *sub = track ? track->d_sub : NULL; double refpts = get_current_time(mpctx); if (sub && refpts != MP_NOPTS_VALUE) { double a[2]; @@ -4906,8 +4945,8 @@ int run_command(struct MPContext *mpctx, struct mp_cmd *cmd, struct mpv_node *re char state[3] = {'p', cmd->is_mouse_button ? 'm' : '-'}; if (cmd->is_up_down) state[0] = cmd->repeated ? 'r' : (cmd->is_up ? 'u' : 'd'); - event.num_args = 3; - event.args = (const char*[3]){"key-binding", name, state}; + event.num_args = 4; + event.args = (const char*[4]){"key-binding", name, state, cmd->key_name}; if (mp_client_send_event_dup(mpctx, target, MPV_EVENT_CLIENT_MESSAGE, &event) < 0) { diff --git a/player/configfiles.c b/player/configfiles.c index db19685c0f..3c42331de0 100644 --- a/player/configfiles.c +++ b/player/configfiles.c @@ -25,7 +25,7 @@ #include <libavutil/md5.h> #include "config.h" -#include "talloc.h" +#include "mpv_talloc.h" #include "osdep/io.h" @@ -273,11 +273,35 @@ static bool needs_config_quoting(const char *s) return false; } +static void write_filename(struct MPContext *mpctx, FILE *file, char *filename) +{ + if (mpctx->opts->write_filename_in_watch_later_config) { |