mirror of
https://github.com/mpv-player/mpv
synced 2025-01-12 18:02:36 +00:00
player: some further playloop cleanups
Handle --term-playing-msg at a better place. Move MPV_EVENT_TICK hack into a separate function. Also add some words to the client API that you shouldn't use it. (But better leave breaking it for later.) Handle --frames and frame_step differently. Remove the mess from the playloop, and do it after frame display. Give up on the weird semantics for audio-only mode (they didn't make sense anyway), and adjust the manpage accordingly.
This commit is contained in:
parent
0ddbf92d06
commit
0f5aed9c62
@ -106,7 +106,7 @@ List of Input Commands
|
||||
``revert_seek`` command itself.
|
||||
|
||||
``frame_step``
|
||||
Play one frame, then pause.
|
||||
Play one frame, then pause. Does nothing with audio-only playback.
|
||||
|
||||
``frame_back_step``
|
||||
Go back by one frame, then pause. Note that this can be very slow (it tries
|
||||
|
@ -919,11 +919,14 @@ OPTIONS
|
||||
Practical use of this feature is questionable. Disabled by default.
|
||||
|
||||
``--frames=<number>``
|
||||
Play/convert only first ``<number>`` video frames, then quit. For audio
|
||||
only, run ``<number>`` iteration of the playback loop, which is most likely
|
||||
not what you want. (This behavior also applies to the corner case when there
|
||||
are fewer video frames than ``<number>``, and audio is longer than the
|
||||
video.)
|
||||
Play/convert only first ``<number>`` video frames, then quit.
|
||||
|
||||
``--frames=0`` loads the file, but immediately quits before initializing
|
||||
playback. (Might be useful for scripts which just want to determine some
|
||||
file properties.)
|
||||
|
||||
For audio-only playback, any value greater than 0 will quit playback
|
||||
immediately after initialization. The value 0 works as with video.
|
||||
|
||||
``--fullscreen``, ``--fs``
|
||||
Fullscreen playback.
|
||||
|
@ -919,8 +919,10 @@ typedef enum mpv_event_id {
|
||||
*/
|
||||
MPV_EVENT_UNPAUSE = 13,
|
||||
/**
|
||||
* Sent every time after a video frame is displayed (or in lower frequency
|
||||
* if there is no video, or playback is paused).
|
||||
* Sent every time after a video frame is displayed. Note that currently,
|
||||
* this will be sent in lower frequency if there is no video, or playback
|
||||
* is paused - but that will be removed in the future, and it will be
|
||||
* restricted to video frames only.
|
||||
*/
|
||||
MPV_EVENT_TICK = 14,
|
||||
/**
|
||||
|
@ -712,12 +712,20 @@ static void handle_backstep(struct MPContext *mpctx)
|
||||
static void handle_sstep(struct MPContext *mpctx)
|
||||
{
|
||||
struct MPOpts *opts = mpctx->opts;
|
||||
if (opts->step_sec > 0 && !mpctx->stop_play && !mpctx->paused &&
|
||||
mpctx->restart_complete)
|
||||
{
|
||||
if (mpctx->stop_play || !mpctx->restart_complete)
|
||||
return;
|
||||
|
||||
if (opts->step_sec > 0 && !mpctx->paused) {
|
||||
set_osd_function(mpctx, OSD_FFW);
|
||||
queue_seek(mpctx, MPSEEK_RELATIVE, opts->step_sec, 0, true);
|
||||
}
|
||||
|
||||
if (mpctx->video_status >= STATUS_DRAINING) {
|
||||
if (mpctx->max_frames >= 0)
|
||||
mpctx->stop_play = PT_NEXT_ENTRY;
|
||||
if (mpctx->step_frames > 0 && !mpctx->paused)
|
||||
pause_player(mpctx);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_loop_file(struct MPContext *mpctx)
|
||||
@ -785,6 +793,17 @@ void handle_force_window(struct MPContext *mpctx, bool reconfig)
|
||||
}
|
||||
}
|
||||
|
||||
// Potentially needed by some Lua scripts, which assume TICK always comes.
|
||||
static void handle_dummy_ticks(struct MPContext *mpctx)
|
||||
{
|
||||
if (mpctx->video_status == STATUS_EOF || mpctx->paused) {
|
||||
if (mp_time_sec() - mpctx->last_idle_tick > 0.5) {
|
||||
mpctx->last_idle_tick = mp_time_sec();
|
||||
mp_notify(mpctx, MPV_EVENT_TICK, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static double get_wakeup_period(struct MPContext *mpctx)
|
||||
{
|
||||
double sleeptime = 100.0; // infinite for all practical purposes
|
||||
@ -806,7 +825,6 @@ void run_playloop(struct MPContext *mpctx)
|
||||
struct MPOpts *opts = mpctx->opts;
|
||||
double endpts = get_play_end_pts(mpctx);
|
||||
bool end_is_new_segment = false;
|
||||
int64_t shown_vframes = mpctx->shown_vframes;
|
||||
|
||||
#if HAVE_ENCODING
|
||||
if (encode_lavc_didfail(mpctx->encode_lavc_ctx)) {
|
||||
@ -840,13 +858,6 @@ void run_playloop(struct MPContext *mpctx)
|
||||
fill_audio_out_buffers(mpctx, endpts);
|
||||
write_video(mpctx, endpts);
|
||||
|
||||
if (mpctx->video_status == STATUS_EOF || mpctx->paused) {
|
||||
if (mp_time_sec() - mpctx->last_idle_tick > 0.5) {
|
||||
mpctx->last_idle_tick = mp_time_sec();
|
||||
mp_notify(mpctx, MPV_EVENT_TICK, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// We always make sure audio and video buffers are filled before actually
|
||||
// starting playback. This code handles starting them at the same time.
|
||||
if (mpctx->audio_status >= STATUS_READY &&
|
||||
@ -856,7 +867,6 @@ void run_playloop(struct MPContext *mpctx)
|
||||
mpctx->video_status = STATUS_PLAYING;
|
||||
get_relative_time(mpctx);
|
||||
mpctx->sleeptime = 0;
|
||||
shown_vframes -= 1; // make framestep think there was a new video frame
|
||||
}
|
||||
if (mpctx->audio_status == STATUS_READY)
|
||||
fill_audio_out_buffers(mpctx, endpts); // actually play prepared buffer
|
||||
@ -864,6 +874,13 @@ void run_playloop(struct MPContext *mpctx)
|
||||
mpctx->hrseek_active = false;
|
||||
mp_notify(mpctx, MPV_EVENT_PLAYBACK_RESTART, NULL);
|
||||
mpctx->restart_complete = true;
|
||||
if (opts->playing_msg && !mpctx->playing_msg_shown) {
|
||||
mpctx->playing_msg_shown = true;
|
||||
char *msg =
|
||||
mp_property_expand_escaped_string(mpctx, opts->playing_msg);
|
||||
MP_INFO(mpctx, "%s\n", msg);
|
||||
talloc_free(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -876,6 +893,8 @@ void run_playloop(struct MPContext *mpctx)
|
||||
mpctx->playback_pts = a_pos;
|
||||
}
|
||||
|
||||
handle_dummy_ticks(mpctx);
|
||||
|
||||
update_osd_msg(mpctx);
|
||||
update_subtitles(mpctx);
|
||||
|
||||
@ -908,37 +927,7 @@ void run_playloop(struct MPContext *mpctx)
|
||||
|
||||
handle_keep_open(mpctx);
|
||||
|
||||
if (!mpctx->stop_play && mpctx->restart_complete) {
|
||||
bool new_frame_shown = shown_vframes < mpctx->shown_vframes;
|
||||
|
||||
// If no more video is available, one frame means one playloop iteration.
|
||||
// Otherwise, one frame means one video frame.
|
||||
if (mpctx->video_status == STATUS_EOF)
|
||||
new_frame_shown = true;
|
||||
|
||||
if (opts->playing_msg && !mpctx->playing_msg_shown && new_frame_shown) {
|
||||
mpctx->playing_msg_shown = true;
|
||||
char *msg =
|
||||
mp_property_expand_escaped_string(mpctx, opts->playing_msg);
|
||||
MP_INFO(mpctx, "%s\n", msg);
|
||||
talloc_free(msg);
|
||||
}
|
||||
|
||||
if (mpctx->max_frames >= 0) {
|
||||
if (new_frame_shown)
|
||||
mpctx->max_frames--;
|
||||
if (mpctx->max_frames <= 0)
|
||||
mpctx->stop_play = PT_NEXT_ENTRY;
|
||||
}
|
||||
|
||||
if (mpctx->step_frames > 0 && !mpctx->paused) {
|
||||
if (new_frame_shown)
|
||||
mpctx->step_frames--;
|
||||
if (mpctx->step_frames == 0)
|
||||
pause_player(mpctx);
|
||||
}
|
||||
|
||||
}
|
||||
handle_sstep(mpctx);
|
||||
|
||||
handle_loop_file(mpctx);
|
||||
|
||||
@ -960,8 +949,6 @@ void run_playloop(struct MPContext *mpctx)
|
||||
|
||||
handle_backstep(mpctx);
|
||||
|
||||
handle_sstep(mpctx);
|
||||
|
||||
handle_chapter_change(mpctx);
|
||||
|
||||
handle_force_window(mpctx, false);
|
||||
@ -987,6 +974,7 @@ void idle_loop(struct MPContext *mpctx)
|
||||
handle_force_window(mpctx, true);
|
||||
}
|
||||
need_reinit = false;
|
||||
handle_dummy_ticks(mpctx);
|
||||
int uninit = INITIALIZED_AO;
|
||||
if (!mpctx->opts->force_vo)
|
||||
uninit |= INITIALIZED_VO;
|
||||
|
@ -896,4 +896,16 @@ void write_video(struct MPContext *mpctx, double endpts)
|
||||
|
||||
if (!mpctx->sync_audio_to_video)
|
||||
mpctx->video_status = STATUS_EOF;
|
||||
|
||||
if (mpctx->video_status != STATUS_EOF) {
|
||||
if (mpctx->step_frames > 0) {
|
||||
mpctx->step_frames--;
|
||||
if (!mpctx->step_frames && !opts->pause)
|
||||
pause_player(mpctx);
|
||||
}
|
||||
if (mpctx->max_frames == 0)
|
||||
mpctx->stop_play = PT_NEXT_ENTRY;
|
||||
if (mpctx->max_frames > 0)
|
||||
mpctx->max_frames--;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user