summaryrefslogtreecommitdiffstats
path: root/player
diff options
context:
space:
mode:
authorMartin Herkt <lachs0r@srsfckn.biz>2016-01-18 07:27:03 +0100
committerMartin Herkt <lachs0r@srsfckn.biz>2016-01-18 07:27:03 +0100
commitba9b2f1e49732d597009ba514b0132a50562cd10 (patch)
treefa05f5feb181823ac9d3b5682a835ff825de6914 /player
parente1993d5ad2bdf3dd4c26474aaa2370cbc9c1cd1b (diff)
parent7b4ccb3e9f58a0745b58e473ee6e60b381242813 (diff)
downloadmpv-ba9b2f1e49732d597009ba514b0132a50562cd10.tar.bz2
mpv-ba9b2f1e49732d597009ba514b0132a50562cd10.tar.xz
Merge branch 'master' into release/current
Diffstat (limited to 'player')
-rw-r--r--player/audio.c23
-rw-r--r--player/client.c7
-rw-r--r--player/client.h1
-rw-r--r--player/command.c239
-rw-r--r--player/configfiles.c72
-rw-r--r--player/core.h80
-rw-r--r--player/external_files.c45
-rw-r--r--player/loadfile.c85
-rw-r--r--player/lua.c2
-rw-r--r--player/lua/ytdl_hook.lua9
-rw-r--r--player/main.c7
-rw-r--r--player/misc.c17
-rw-r--r--player/osd.c16
-rw-r--r--player/playloop.c144
-rw-r--r--player/screenshot.c15
-rw-r--r--player/sub.c281
-rw-r--r--player/video.c446
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(&params, &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) {