stream_dvdnav: keep cached duration in native time base

Store the duration in 90 kHz ticks instead of converting back and
forth. This also fixes STREAM_CTRL_GET_CURRENT_TIME's failure check,
which previously compared the already-converted value against -1 and
could never trigger.
This commit is contained in:
Kacper Michajłow committed 2026-08-26 01:47:41 +02:00
1 parent 61416bd8b5
commit 7c13c58ffa
1 file changed
+16 -13
+16 -13
View File
@@ -55,13 +55,17 @@
#define TITLE_MENU -1
#define TITLE_LONGEST -2
#define DVD_TIMEBASE 90000
#define DVD_TIME_TO_S(x) ((x) / (double)(DVD_TIMEBASE))
#define DVD_TIME_FROM_S(x) ((int64_t)((x) * DVD_TIMEBASE))
#define DVD_SRC_W_DEFAULT 720
#define DVD_SRC_H_DEFAULT 576
struct priv {
dvdnav_t *dvdnav; // handle to libdvdnav stuff
char *filename; // path
unsigned int duration; // in milliseconds
int64_t duration; // in 90 kHz PTS ticks
int title;
bool still_active; // fill_buffer() is holding a still
uint32_t spu_clut[16];
@@ -657,7 +661,7 @@ static int fill_buffer(stream_t *s, void *buf, int max_len)
dvdnav_cell_change_event_t *ev = (dvdnav_cell_change_event_t *)buf;
if (ev->pgc_length)
priv->duration = ev->pgc_length / 90;
priv->duration = ev->pgc_length;
break;
}
@@ -727,13 +731,13 @@ static int control(stream_t *stream, int cmd, void *arg)
free(parts);
break;
}
*ch = chapter > 0 ? parts[chapter - 1] / 90000.0 : 0;
*ch = chapter > 0 ? DVD_TIME_TO_S(parts[chapter - 1]) : 0;
free(parts);
return STREAM_OK;
}
case STREAM_CTRL_GET_TIME_LENGTH: {
if (priv->duration) {
*(double *)arg = (double)priv->duration / 1000.0;
if (priv->duration > 0) {
*(double *)arg = DVD_TIME_TO_S(priv->duration);
return STREAM_OK;
}
break;
@@ -744,10 +748,9 @@ static int control(stream_t *stream, int cmd, void *arg)
return STREAM_OK;
}
case STREAM_CTRL_GET_CURRENT_TIME: {
double tm;
tm = dvdnav_get_current_time(dvdnav) / 90000.0f;
int64_t tm = dvdnav_get_current_time(dvdnav);
if (tm != -1) {
*(double *)arg = tm;
*(double *)arg = DVD_TIME_TO_S(tm);
return STREAM_OK;
}
break;
@@ -772,7 +775,7 @@ static int control(stream_t *stream, int cmd, void *arg)
if (!parts)
break;
free(parts);
*(double *)arg = duration / 90000.0;
*(double *)arg = DVD_TIME_TO_S(duration);
return STREAM_OK;
}
case STREAM_CTRL_GET_CURRENT_TITLE: {
@@ -807,11 +810,11 @@ static int control(stream_t *stream, int cmd, void *arg)
int flags = args[1]; // from SEEK_* flags (demux.h)
if (flags & SEEK_HR)
d -= 10; // fudge offset; it's a hack, because fuck libdvd*
int64_t tm = (int64_t)(d * 90000);
int64_t tm = DVD_TIME_FROM_S(d);
if (tm < 0)
tm = 0;
if (priv->duration && tm >= (int64_t)priv->duration * 90)
tm = (int64_t)priv->duration * 90 - 1;
if (priv->duration > 0 && tm >= priv->duration)
tm = priv->duration - 1;
uint32_t pos, len;
if (dvdnav_get_position(dvdnav, &pos, &len) != DVDNAV_STATUS_OK)
break;
@@ -819,7 +822,7 @@ static int control(stream_t *stream, int cmd, void *arg)
if (dvdnav_time_search(dvdnav, tm) != DVDNAV_STATUS_OK)
break;
stream_drop_buffers(stream);
d = dvdnav_get_current_time(dvdnav) / 90000.0f;
d = DVD_TIME_TO_S(dvdnav_get_current_time(dvdnav));
MP_VERBOSE(stream, "landed at: %f\n", d);
if (dvdnav_get_position(dvdnav, &pos, &len) == DVDNAV_STATUS_OK)
MP_VERBOSE(stream, "block: %lu\n", (unsigned long)pos);