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:
wm4 2013-02-26 00:38:36 +01:00
parent 70346d3be6
commit 72bdc5d3af
9 changed files with 22 additions and 54 deletions

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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:
{

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;