mirror of
https://github.com/mpv-player/mpv
synced 2024-12-24 07:33:46 +01:00
core: use playback time to determine playback percent position
The percent position is used for the OSD, the status line, and for the OSD bar (shown on seeks). By default, the PTS of the last demuxed packet was used to calculate it. This led to a "jumpy" display when the percentage value (casted to int) was changing. The reasons for this were the presence of video frame reordering (packet PTS is not monotonic), or getting PTS values from different streams (like audio/subs). Since these rely on PTS values and correct file durations anyway, simplify it by calculating it with the current playback position in mplayer.c instead.
This commit is contained in:
parent
70346d3be6
commit
72bdc5d3af
@ -2970,18 +2970,28 @@ double get_current_time(struct MPContext *mpctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static double get_start_time(struct MPContext *mpctx)
|
||||
{
|
||||
struct demuxer *demuxer = mpctx->demuxer;
|
||||
if (!demuxer)
|
||||
return 0;
|
||||
double time = 0;
|
||||
demux_control(demuxer, DEMUXER_CTRL_GET_START_TIME, &time);
|
||||
return time;
|
||||
}
|
||||
|
||||
int get_percent_pos(struct MPContext *mpctx)
|
||||
{
|
||||
struct demuxer *demuxer = mpctx->demuxer;
|
||||
if (!demuxer)
|
||||
return 0;
|
||||
int ans = 0;
|
||||
if (mpctx->timeline)
|
||||
ans = get_current_time(mpctx) * 100 /
|
||||
mpctx->timeline[mpctx->num_timeline_parts].start;
|
||||
else if (demux_control(demuxer, DEMUXER_CTRL_GET_PERCENT_POS, &ans) > 0)
|
||||
;
|
||||
else {
|
||||
double start = get_start_time(mpctx);
|
||||
double len = get_time_length(mpctx);
|
||||
double pos = get_current_time(mpctx);
|
||||
if (len > 0) {
|
||||
ans = (pos - start) / len * 100;
|
||||
} else {
|
||||
int len = (demuxer->movi_end - demuxer->movi_start) / 100;
|
||||
int64_t pos = demuxer->filepos > 0 ?
|
||||
demuxer->filepos : stream_tell(demuxer->stream);
|
||||
|
@ -91,7 +91,7 @@ enum timestamp_type {
|
||||
#define DEMUXER_CTRL_OK 1
|
||||
#define DEMUXER_CTRL_GUESS 2
|
||||
#define DEMUXER_CTRL_GET_TIME_LENGTH 10
|
||||
#define DEMUXER_CTRL_GET_PERCENT_POS 11
|
||||
#define DEMUXER_CTRL_GET_START_TIME 11
|
||||
#define DEMUXER_CTRL_SWITCH_AUDIO 12
|
||||
#define DEMUXER_CTRL_RESYNC 13
|
||||
#define DEMUXER_CTRL_SWITCH_VIDEO 14
|
||||
|
@ -614,9 +614,6 @@ static int demux_asf_control(demuxer_t *demuxer,int cmd, void *arg){
|
||||
*((double *)arg)=asf->movielength;
|
||||
return DEMUXER_CTRL_OK;
|
||||
|
||||
case DEMUXER_CTRL_GET_PERCENT_POS:
|
||||
return DEMUXER_CTRL_DONTKNOW;
|
||||
|
||||
default:
|
||||
return DEMUXER_CTRL_NOTIMPL;
|
||||
}
|
||||
|
@ -794,14 +794,6 @@ static int demux_avi_control(demuxer_t *demuxer,int cmd, void *arg){
|
||||
if (sh_video->video.dwLength<=1) return DEMUXER_CTRL_GUESS;
|
||||
return DEMUXER_CTRL_OK;
|
||||
|
||||
case DEMUXER_CTRL_GET_PERCENT_POS:
|
||||
if (!priv->numberofframes || !sh_video) {
|
||||
return DEMUXER_CTRL_DONTKNOW;
|
||||
}
|
||||
*((int *)arg)=(int)(priv->video_pack_no*100/priv->numberofframes);
|
||||
if (sh_video->video.dwLength<=1) return DEMUXER_CTRL_GUESS;
|
||||
return DEMUXER_CTRL_OK;
|
||||
|
||||
case DEMUXER_CTRL_SWITCH_AUDIO:
|
||||
case DEMUXER_CTRL_SWITCH_VIDEO: {
|
||||
int audio = (cmd == DEMUXER_CTRL_SWITCH_AUDIO);
|
||||
|
@ -765,15 +765,10 @@ static int demux_lavf_control(demuxer_t *demuxer, int cmd, void *arg)
|
||||
*((double *)arg) = (double)priv->avfc->duration / AV_TIME_BASE;
|
||||
return DEMUXER_CTRL_OK;
|
||||
|
||||
case DEMUXER_CTRL_GET_PERCENT_POS:
|
||||
if (priv->seek_by_bytes)
|
||||
return DEMUXER_CTRL_DONTKNOW; // let it use the fallback code
|
||||
if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)
|
||||
return DEMUXER_CTRL_DONTKNOW;
|
||||
|
||||
*((int *)arg) = (int)((priv->last_pts - priv->avfc->start_time) * 100 /
|
||||
priv->avfc->duration);
|
||||
case DEMUXER_CTRL_GET_START_TIME:
|
||||
*((double *)arg) = (double)priv->avfc->start_time / AV_TIME_BASE;
|
||||
return DEMUXER_CTRL_OK;
|
||||
|
||||
case DEMUXER_CTRL_SWITCH_AUDIO:
|
||||
case DEMUXER_CTRL_SWITCH_VIDEO:
|
||||
{
|
||||
|
@ -248,12 +248,6 @@ static int demux_control_mf(demuxer_t *demuxer, int cmd, void *arg) {
|
||||
*((double *)arg) = (double)mf->nr_of_files / mf->sh->fps;
|
||||
return DEMUXER_CTRL_OK;
|
||||
|
||||
case DEMUXER_CTRL_GET_PERCENT_POS:
|
||||
if (mf->nr_of_files < 1)
|
||||
return DEMUXER_CTRL_DONTKNOW;
|
||||
*((int *)arg) = 100 * mf->curr_frame / mf->nr_of_files;
|
||||
return DEMUXER_CTRL_OK;
|
||||
|
||||
case DEMUXER_CTRL_CORRECT_PTS:
|
||||
return DEMUXER_CTRL_OK;
|
||||
|
||||
|
@ -2505,14 +2505,6 @@ static int demux_mkv_control(demuxer_t *demuxer, int cmd, void *arg)
|
||||
*((double *) arg) = (double) mkv_d->duration;
|
||||
return DEMUXER_CTRL_OK;
|
||||
|
||||
case DEMUXER_CTRL_GET_PERCENT_POS:
|
||||
if (mkv_d->duration == 0) {
|
||||
return DEMUXER_CTRL_DONTKNOW;
|
||||
}
|
||||
|
||||
*((int *) arg) = (int) (100 * mkv_d->last_pts / mkv_d->duration);
|
||||
return DEMUXER_CTRL_OK;
|
||||
|
||||
case DEMUXER_CTRL_SWITCH_AUDIO:;
|
||||
int new_aid = *(int *) arg;
|
||||
int current_aid = demuxer->audio->id;
|
||||
|
@ -589,18 +589,6 @@ static int demux_mng_control(demuxer_t * demuxer, int cmd, void * arg)
|
||||
}
|
||||
break;
|
||||
|
||||
// get position in movie
|
||||
case DEMUXER_CTRL_GET_PERCENT_POS:
|
||||
if (mng_priv->header_processed && mng_priv->total_time_ms > 0) {
|
||||
*(int *)arg = (100 * mng_priv->show_cur_time_ms
|
||||
+ mng_priv->total_time_ms / 2)
|
||||
/ mng_priv->total_time_ms;
|
||||
return DEMUXER_CTRL_OK;
|
||||
} else {
|
||||
return DEMUXER_CTRL_DONTKNOW;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return DEMUXER_CTRL_NOTIMPL;
|
||||
|
||||
|
@ -1074,9 +1074,9 @@ static int demux_mpg_control(demuxer_t *demuxer, int cmd, void *arg)
|
||||
}
|
||||
return DEMUXER_CTRL_DONTKNOW;
|
||||
|
||||
case DEMUXER_CTRL_GET_PERCENT_POS:
|
||||
case DEMUXER_CTRL_GET_START_TIME:
|
||||
if (mpg_d && mpg_d->has_valid_timestamps && mpg_d->first_to_final_pts_len > 0.0) {
|
||||
*((int *)arg)=(int)(100 * (mpg_d->last_pts-mpg_d->first_pts) / mpg_d->first_to_final_pts_len);
|
||||
*((float *)arg)=mpg_d->first_pts;
|
||||
return DEMUXER_CTRL_OK;
|
||||
}
|
||||
return DEMUXER_CTRL_DONTKNOW;
|
||||
|
Loading…
Reference in New Issue
Block a user