summaryrefslogtreecommitdiffstats
path: root/mplayer.c
diff options
context:
space:
mode:
authorUoti Urpala <uau@mplayer2.org>2011-07-31 01:05:17 +0300
committerUoti Urpala <uau@mplayer2.org>2011-07-31 01:06:12 +0300
commitec72cb7a73535171273013040476b165b980eaae (patch)
tree0f4f94a848be8dc9f8bd38c3f7b7844ab4eb3a25 /mplayer.c
parentf1bb6fde3288cbbaf01175b980b9704f9406ce80 (diff)
downloadmpv-ec72cb7a73535171273013040476b165b980eaae.tar.bz2
mpv-ec72cb7a73535171273013040476b165b980eaae.tar.xz
core: audio: improve audio-only seeks and position reporting
Seeking while paused could result in the current audio pts being reported incorrectly due to relevant variables not being reinitialized after the seek until more audio was played. When playing audio-only files, this meant that current overall playback position could be reported incorrectly which in turn could break further seeks. Improve things on two levels: First, store the seek target position and use that as the current playback position for audio-only files until things can be reinitialized. Second, try to reinitialize audio decoding enough to know its current pts even while paused. Also avoid printing the actual huge negative value of MP_NOPTS_VALUE on the status line when pts could not be determined.
Diffstat (limited to 'mplayer.c')
-rw-r--r--mplayer.c42
1 files changed, 31 insertions, 11 deletions
diff --git a/mplayer.c b/mplayer.c
index 7f22b328b0..65596b3fae 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -1223,7 +1223,7 @@ static void sadd_hhmmssf(char *buf, unsigned *pos, int len, float time) {
int ss = (tenths / 10) % 60;
int mm = (tenths / 600) % 60;
int hh = tenths / 36000;
- if (time <= 0) {
+ if (time < 0) {
saddf(buf, pos, len, "unknown");
return;
}
@@ -1254,6 +1254,8 @@ static void print_status(struct MPContext *mpctx, double a_pos, bool at_frame)
if (opts->quiet)
return;
+ if (a_pos == MP_NOPTS_VALUE)
+ a_pos = -9; // don't print a huge negative number
int width;
char *line;
@@ -2375,6 +2377,13 @@ static void adjust_sync(struct MPContext *mpctx, double frame_time)
mpctx->total_avsync_change += change;
}
+static int write_to_ao(struct MPContext *mpctx, void *data, int len, int flags)
+{
+ if (mpctx->paused)
+ return 0;
+ return ao_play(mpctx->ao, data, len, flags);
+}
+
#define ASYNC_PLAY_DONE -3
static int audio_start_sync(struct MPContext *mpctx, int playsize)
{
@@ -2442,7 +2451,7 @@ static int audio_start_sync(struct MPContext *mpctx, int playsize)
* in playsize. */
char *p = malloc(playsize);
memset(p, fillbyte, playsize);
- playsize = ao_play(ao, p, playsize, 0);
+ playsize = write_to_ao(mpctx, p, playsize, 0);
free(p);
mpctx->delay += opts->playback_speed*playsize/(double)ao->bps;
return ASYNC_PLAY_DONE;
@@ -2475,7 +2484,10 @@ static int fill_audio_out_buffers(struct MPContext *mpctx)
// sync completely wrong; there should be no need to use ao->pts
// in get_space()
ao->pts = ((mpctx->sh_video?mpctx->sh_video->timer:0)+mpctx->delay)*90000.0;
- playsize = ao_get_space(ao);
+ if (mpctx->paused)
+ playsize = 1; // just initialize things (audio pts at least)
+ else
+ playsize = ao_get_space(ao);
// Fill buffer if needed:
current_module="decode_audio";
@@ -2535,7 +2547,7 @@ static int fill_audio_out_buffers(struct MPContext *mpctx)
// They're obviously badly broken in the way they handle av sync;
// would not having access to this make them more broken?
ao->pts = ((mpctx->sh_video?mpctx->sh_video->timer:0)+mpctx->delay)*90000.0;
- int played = ao_play(ao, ao->buffer.start, playsize, playflags);
+ int played = write_to_ao(mpctx, ao->buffer.start, playsize, playflags);
assert(played % unitsize == 0);
ao->buffer_playable_size = playsize - played;
@@ -2543,7 +2555,7 @@ static int fill_audio_out_buffers(struct MPContext *mpctx)
ao->buffer.len -= played;
memmove(ao->buffer.start, ao->buffer.start + played, ao->buffer.len);
mpctx->delay += opts->playback_speed * played / ao->bps;
- } else if (audio_eof && ao_get_delay(ao) < .04) {
+ } else if (!mpctx->paused && audio_eof && ao_get_delay(ao) < .04) {
// Sanity check to avoid hanging in case current ao doesn't output
// partial chunks and doesn't check for AOPLAY_FINAL_CHUNK
return -2;
@@ -3230,8 +3242,11 @@ static int seek(MPContext *mpctx, struct seek_params seek,
/* Use the target time as "current position" for further relative
* seeks etc until a new video frame has been decoded */
- if (seek.type == MPSEEK_ABSOLUTE)
+ if (seek.type == MPSEEK_ABSOLUTE) {
mpctx->video_pts = seek.amount;
+ mpctx->last_seek_pts = seek.amount;
+ } else
+ mpctx->last_seek_pts = MP_NOPTS_VALUE;
if (hr_seek) {
mpctx->hrseek_active = true;
@@ -3317,7 +3332,10 @@ double get_current_time(struct MPContext *mpctx)
struct sh_video *sh_video = demuxer->video->sh;
if (sh_video)
return mpctx->video_pts;
- return playing_audio_pts(mpctx);
+ double apts = playing_audio_pts(mpctx);
+ if (apts != MP_NOPTS_VALUE)
+ return apts;
+ return mpctx->last_seek_pts;
}
int get_percent_pos(struct MPContext *mpctx)
@@ -3419,8 +3437,10 @@ static void run_playloop(struct MPContext *mpctx)
/*========================== PLAY AUDIO ============================*/
- if (mpctx->sh_audio && !mpctx->paused
- && (!mpctx->restart_playback || !mpctx->sh_video)) {
+ if (!mpctx->sh_video)
+ mpctx->restart_playback = false;
+
+ if (mpctx->sh_audio && !mpctx->restart_playback) {
int status = fill_audio_out_buffers(mpctx);
full_audio_buffers = status >= 0 && !mpctx->ao->untimed;
if (status == -2)
@@ -3431,7 +3451,6 @@ static void run_playloop(struct MPContext *mpctx)
if (!mpctx->sh_video) {
- mpctx->restart_playback = false;
if (mpctx->step_frames) {
mpctx->step_frames = 0;
pause_player(mpctx);
@@ -3597,7 +3616,7 @@ static void run_playloop(struct MPContext *mpctx)
}
if (mpctx->restart_playback) {
mpctx->syncing_audio = true;
- if (mpctx->sh_audio && !mpctx->paused)
+ if (mpctx->sh_audio)
fill_audio_out_buffers(mpctx);
mpctx->restart_playback = false;
mpctx->time_frame = 0;
@@ -4790,6 +4809,7 @@ if(play_n_frames==0){
mpctx->drop_message_shown = 0;
mpctx->restart_playback = true;
mpctx->video_pts = 0;
+ mpctx->last_seek_pts = 0;
mpctx->hrseek_active = false;
mpctx->hrseek_framedrop = false;
mpctx->step_frames = 0;