Start pause handling changes

Add separate pause_player() / unpause_player functions(), move some
pausing-related state into explicit variables and make commands while
paused not unpause. Not everything works properly while paused yet (no
screen updates etc).
This commit is contained in:
Uoti Urpala 2008-11-29 08:09:57 +02:00
parent 6fa90873cc
commit 77c709ad31
3 changed files with 88 additions and 48 deletions

View File

@ -2,6 +2,7 @@
#include <inttypes.h>
#include <unistd.h>
#include <string.h>
#include <stdbool.h>
#include "config.h"
#include "command.h"
@ -559,10 +560,27 @@ static int mp_property_metadata(m_option_t *prop, int action, void *arg,
return M_PROPERTY_NOT_IMPLEMENTED;
}
static int mp_property_pause(m_option_t * prop, int action, void *arg,
MPContext * mpctx)
static int mp_property_pause(m_option_t *prop, int action, void *arg,
void *ctx)
{
return m_property_flag_ro(prop, action, arg, mpctx->osd_function == OSD_PAUSE);
MPContext *mpctx = ctx;
switch (action) {
case M_PROPERTY_SET:
if (!arg)
return M_PROPERTY_ERROR;
if (mpctx->paused == (bool)*(int *) arg)
return M_PROPERTY_OK;
case M_PROPERTY_STEP_UP:
case M_PROPERTY_STEP_DOWN:
if (mpctx->paused)
unpause_player(mpctx);
else
pause_player(mpctx);
return M_PROPERTY_OK;
default:
return m_property_flag(prop, action, arg, &mpctx->paused);
}
}
@ -2212,6 +2230,7 @@ static struct {
{ "loop", MP_CMD_LOOP, 0, 0, -1, MSGTR_LoopStatus },
{ "chapter", MP_CMD_SEEK_CHAPTER, 0, 0, -1, NULL },
{ "angle", MP_CMD_SWITCH_ANGLE, 0, 0, -1, NULL },
{ "pause", MP_CMD_PAUSE, 0, 0, -1, NULL },
// audio
{ "volume", MP_CMD_VOLUME, 0, OSD_VOLUME, -1, MSGTR_Volume },
{ "mute", MP_CMD_MUTE, 1, 0, -1, MSGTR_MuteStatus },
@ -2503,9 +2522,8 @@ int run_command(MPContext *mpctx, mp_cmd_t *cmd)
} break;
case MP_CMD_FRAME_STEP:
case MP_CMD_PAUSE:
cmd->pausing = 1;
brk_cmd = 1;
mpctx->step_frames++;
unpause_player(mpctx);
break;
case MP_CMD_FILE_FILTER:
@ -3215,18 +3233,14 @@ int run_command(MPContext *mpctx, mp_cmd_t *cmd)
switch (cmd->pausing) {
case 1: // "pausing"
mpctx->osd_function = OSD_PAUSE;
pause_player(mpctx);
break;
case 3: // "pausing_toggle"
mpctx->was_paused = !mpctx->was_paused;
if (mpctx->was_paused)
mpctx->osd_function = OSD_PAUSE;
else if (mpctx->osd_function == OSD_PAUSE)
mpctx->osd_function = OSD_PLAY;
if (mpctx->paused)
unpause_player(mpctx);
else
pause_player(mpctx);
break;
case 2: // "pausing_keep"
if (mpctx->was_paused)
mpctx->osd_function = OSD_PAUSE;
}
return brk_cmd;
}

View File

@ -82,6 +82,8 @@ typedef struct MPContext {
// In the audio-only case used as a timer since the last seek
// by the audio CPU usage meter.
double delay;
// AV sync: time until next frame should be shown
float time_frame;
// Timestamp from the last time some timing functions read the
// current time, in (occasionally wrapping) microseconds. Used
@ -112,7 +114,9 @@ typedef struct MPContext {
int last_dvb_step;
int dvbin_reopen;
int was_paused;
int paused;
// step this many frames, then pause
int step_frames;
#ifdef CONFIG_DVDNAV
struct mp_image *nav_smpi; ///< last decoded dvdnav video image
@ -138,5 +142,7 @@ double playing_audio_pts(struct MPContext *mpctx);
void exit_player_with_rc(struct MPContext *mpctx, exit_reason_t how, int rc);
void add_subtitles(struct MPContext *mpctx, char *filename, float fps, int noerr);
int reinit_video_chain(struct MPContext *mpctx);
void pause_player(struct MPContext *mpctx);
void unpause_player(struct MPContext *mpctx);
#endif /* MPLAYER_MP_CORE_H */

View File

@ -1696,8 +1696,7 @@ static int check_framedrop(struct MPContext *mpctx, double frame_time) {
++total_frame_cnt;
// we should avoid dropping too many frames in sequence unless we
// are too late. and we allow 100ms A-V delay here:
if (d < -dropped_frames*frame_time-0.100 &&
mpctx->osd_function != OSD_PAUSE) {
if (d < -dropped_frames*frame_time-0.100 && !mpctx->paused) {
++drop_frame_cnt;
++dropped_frames;
return frame_dropping;
@ -2318,6 +2317,36 @@ static double update_video(struct MPContext *mpctx, int *blit_frame)
return frame_time;
}
void pause_player(struct MPContext *mpctx)
{
if (mpctx->paused)
return;
mpctx->paused = 1;
mpctx->osd_function = OSD_PAUSE;
mpctx->step_frames = 0;
mpctx->time_frame -= get_relative_time(mpctx);
if (mpctx->video_out && mpctx->sh_video && mpctx->video_out->config_ok)
vo_control(mpctx->video_out, VOCTRL_PAUSE, NULL);
if (mpctx->audio_out && mpctx->sh_audio)
mpctx->audio_out->pause(); // pause audio, keep data if possible
}
void unpause_player(struct MPContext *mpctx)
{
if (!mpctx->paused)
return;
mpctx->paused = 0;
mpctx->osd_function = OSD_PLAY;
if (mpctx->audio_out && mpctx->sh_audio)
mpctx->audio_out->resume(); // resume audio
if (mpctx->video_out && mpctx->sh_video && mpctx->video_out->config_ok)
vo_control(mpctx->video_out, VOCTRL_RESUME, NULL); // resume video
(void)get_relative_time(mpctx); // ignore time that passed during pause
}
static void pause_loop(struct MPContext *mpctx)
{
mp_cmd_t* cmd;
@ -2339,11 +2368,6 @@ static void pause_loop(struct MPContext *mpctx)
if (use_gui)
guiGetEvent(guiCEvent, (char *)guiSetPause);
#endif
if (mpctx->video_out && mpctx->sh_video && mpctx->video_out->config_ok)
vo_control(mpctx->video_out, VOCTRL_PAUSE, NULL);
if (mpctx->audio_out && mpctx->sh_audio)
mpctx->audio_out->pause(); // pause audio, keep data if possible
while ( (cmd = mp_input_get_cmd(mpctx->input, 20, 1, 1)) == NULL
|| cmd->id == MP_CMD_SET_MOUSE_POS || cmd->pausing == 4) {
@ -2369,16 +2393,6 @@ static void pause_loop(struct MPContext *mpctx)
#endif
usec_sleep(20000);
}
if (cmd && cmd->id == MP_CMD_PAUSE) {
cmd = mp_input_get_cmd(mpctx->input, 0,1,0);
mp_cmd_free(cmd);
}
mpctx->osd_function=OSD_PLAY;
if (mpctx->audio_out && mpctx->sh_audio)
mpctx->audio_out->resume(); // resume audio
if (mpctx->video_out && mpctx->sh_video && mpctx->video_out->config_ok)
vo_control(mpctx->video_out, VOCTRL_RESUME, NULL); // resume video
(void)get_relative_time(mpctx); // ignore time that passed during pause
#ifdef CONFIG_GUI
if (use_gui) {
if (guiIntfStruct.Playing == guiSetStop)
@ -3601,7 +3615,6 @@ if(verbose) term_osd = 0;
{
//int frame_corr_num=0; //
//float v_frame=0; // Video
float time_frame=0; // Timer
//float num_frames=0; // number of frames played
int frame_time_remaining=0; // flag
@ -3711,6 +3724,7 @@ if (mpctx->stream->type == STREAMTYPE_DVDNAV) {
#endif
get_relative_time(mpctx); // reset current delta
mpctx->time_frame = 0;
while(!mpctx->stop_play){
float aq_sleep_time=0;
@ -3771,7 +3785,7 @@ if(!mpctx->sh_video) {
else {
// might return with !eof && !blit_frame if !correct_pts
mpctx->num_buffered_frames += blit_frame;
time_frame += frame_time / opts->playback_speed; // for nosound
mpctx->time_frame += frame_time / opts->playback_speed; // for nosound
}
}
@ -3802,7 +3816,7 @@ if(!mpctx->sh_video) {
}
}
frame_time_remaining = sleep_until_update(mpctx, &time_frame, &aq_sleep_time);
frame_time_remaining = sleep_until_update(mpctx, &mpctx->time_frame, &aq_sleep_time);
//====================== FLIP PAGE (VIDEO BLT): =========================
@ -3817,7 +3831,7 @@ if(!mpctx->sh_video) {
}
//====================== A-V TIMESTAMP CORRECTION: =========================
adjust_sync_and_print_status(mpctx, frame_time_remaining, time_frame);
adjust_sync_and_print_status(mpctx, frame_time_remaining, mpctx->time_frame);
//============================ Auto QUALITY ============================
@ -3839,9 +3853,17 @@ if(auto_quality>0){
set_video_quality(mpctx->sh_video,output_quality);
}
if (play_n_frames >= 0 && !frame_time_remaining && blit_frame) {
--play_n_frames;
if (play_n_frames <= 0) mpctx->stop_play = PT_NEXT_ENTRY;
if (!frame_time_remaining && blit_frame) {
if (play_n_frames >= 0) {
--play_n_frames;
if (play_n_frames <= 0)
mpctx->stop_play = PT_NEXT_ENTRY;
}
if (mpctx->step_frames > 0) {
mpctx->step_frames--;
if (mpctx->step_frames == 0)
pause_player(mpctx);
}
}
@ -3871,13 +3893,6 @@ if(auto_quality>0){
//============================ Handle PAUSE ===============================
current_module="pause";
if (mpctx->osd_function == OSD_PAUSE) {
mpctx->was_paused = 1;
pause_loop(mpctx);
}
// handle -sstep
if(step_sec>0) {
mpctx->osd_function=OSD_FFW;
@ -3891,6 +3906,7 @@ if(step_sec>0) {
current_module="key_events";
{
while (1) {
mp_cmd_t* cmd;
int brk_cmd = 0;
while( !brk_cmd && (cmd = mp_input_get_cmd(mpctx->input, 0,0,0)) != NULL) {
@ -3899,8 +3915,12 @@ if(step_sec>0) {
if (brk_cmd == 2)
goto goto_enable_cache;
}
if (mpctx->paused && !mpctx->stop_play)
pause_loop(mpctx);
else
break;
}
}
mpctx->was_paused = 0;
/* Looping. */
if(mpctx->stop_play==AT_END_OF_FILE && opts->loop_times>=0) {