summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--command.c44
-rw-r--r--mp_core.h8
-rw-r--r--mplayer.c84
3 files changed, 88 insertions, 48 deletions
diff --git a/command.c b/command.c
index 9d4c38726b..e642944ada 100644
--- a/command.c
+++ b/command.c
@@ -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;
}
diff --git a/mp_core.h b/mp_core.h
index 1287d9ad2b..09df4e7719 100644
--- a/mp_core.h
+++ b/mp_core.h
@@ -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 */
diff --git a/mplayer.c b/mplayer.c
index caa96b143e..04e8dc54b4 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -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) {