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:
1 parent
61416bd8b5
commit
7c13c58ffa
1 file changed
+16
-13
+16
-13
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user