summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--demux/demux.c17
-rw-r--r--stream/cache2.c8
-rw-r--r--stream/stream.h1
-rw-r--r--stream/stream_dvd.c38
4 files changed, 58 insertions, 6 deletions
diff --git a/demux/demux.c b/demux/demux.c
index 94f54fcbfd..f95a134903 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -101,6 +101,8 @@ const demuxer_desc_t *const demuxer_list[] = {
NULL
};
+static void add_stream_chapters(struct demuxer *demuxer);
+
static int packet_destroy(void *ptr)
{
struct demux_packet *dp = ptr;
@@ -932,6 +934,7 @@ static struct demuxer *open_given_type(struct MPOpts *opts,
// Doesn't work, because stream_pts is a "guess".
demuxer->accurate_seek = false;
}
+ add_stream_chapters(demuxer);
demuxer_sort_chapters(demuxer);
return demuxer;
} else {
@@ -1300,6 +1303,20 @@ int demuxer_add_chapter(demuxer_t *demuxer, struct bstr name,
return 0;
}
+static void add_stream_chapters(struct demuxer *demuxer)
+{
+ if (demuxer->num_chapters)
+ return;
+ int num_chapters = demuxer_chapter_count(demuxer);
+ for (int n = 0; n < num_chapters; n++) {
+ double p = n;
+ if (stream_control(demuxer->stream, STREAM_CTRL_GET_CHAPTER_TIME, &p)
+ != STREAM_OK)
+ return;
+ demuxer_add_chapter(demuxer, bstr0(""), p * 1e9, 0);
+ }
+}
+
/**
* \brief demuxer_seek_chapter() seeks to a chapter in two possible ways:
* either using the demuxer->chapters structure set by the demuxer
diff --git a/stream/cache2.c b/stream/cache2.c
index 0c1c70a577..38c57d0af9 100644
--- a/stream/cache2.c
+++ b/stream/cache2.c
@@ -302,10 +302,11 @@ static int cache_execute_control(cache_vars_t *s) {
switch (s->control) {
case STREAM_CTRL_SEEK_TO_TIME:
needs_flush = 1;
- double_res = s->control_double_arg;
case STREAM_CTRL_GET_CURRENT_TIME:
case STREAM_CTRL_GET_ASPECT_RATIO:
case STREAM_CTRL_GET_START_TIME:
+ case STREAM_CTRL_GET_CHAPTER_TIME:
+ double_res = s->control_double_arg;
s->control_res = s->stream->control(s->stream, s->control, &double_res);
s->control_double_arg = double_res;
break;
@@ -661,6 +662,10 @@ int cache_do_control(stream_t *stream, int cmd, void *arg) {
case STREAM_CTRL_GET_START_TIME:
*(double *)arg = s->stream_start_time;
return s->stream_start_time != MP_NOPTS_VALUE ? STREAM_OK : STREAM_UNSUPPORTED;
+ case STREAM_CTRL_GET_CHAPTER_TIME:
+ s->control_double_arg = *(double *)arg;
+ s->control = cmd;
+ break;
case STREAM_CTRL_GET_LANG:
s->control_lang_arg = *(struct stream_lang_req *)arg;
case STREAM_CTRL_GET_NUM_TITLES:
@@ -705,6 +710,7 @@ int cache_do_control(stream_t *stream, int cmd, void *arg) {
case STREAM_CTRL_GET_CURRENT_TIME:
case STREAM_CTRL_GET_ASPECT_RATIO:
case STREAM_CTRL_GET_START_TIME:
+ case STREAM_CTRL_GET_CHAPTER_TIME:
*(double *)arg = s->control_double_arg;
break;
case STREAM_CTRL_GET_NUM_TITLES:
diff --git a/stream/stream.h b/stream/stream.h
index 2d4fd3862d..df4188ed94 100644
--- a/stream/stream.h
+++ b/stream/stream.h
@@ -104,6 +104,7 @@
// DVD/Bluray, signal general support for GET_CURRENT_TIME etc.
#define STREAM_CTRL_MANAGES_TIMELINE 19
#define STREAM_CTRL_GET_START_TIME 20
+#define STREAM_CTRL_GET_CHAPTER_TIME 21
struct stream_lang_req {
int type; // STREAM_AUDIO, STREAM_SUB
diff --git a/stream/stream_dvd.c b/stream/stream_dvd.c
index 5df9b390e7..dc2cdfd2ae 100644
--- a/stream/stream_dvd.c
+++ b/stream/stream_dvd.c
@@ -498,7 +498,8 @@ static int seek_to_chapter(stream_t *stream, ifo_handle_t *vts_file, tt_srpt_t *
return chapter;
}
-static void list_chapters(ifo_handle_t *vts_file, tt_srpt_t *tt_srpt, int title_no)
+// p: in=chapter number, out=PTS
+static int get_chapter_time(ifo_handle_t *vts_file, tt_srpt_t *tt_srpt, int title_no, double *p)
{
unsigned int i, cell, last_cell;
unsigned int t=0;
@@ -507,10 +508,10 @@ static void list_chapters(ifo_handle_t *vts_file, tt_srpt_t *tt_srpt, int title_
title_no = tt_srpt->title[title_no].vts_ttn - 1;
if(vts_file->vts_ptt_srpt->title[title_no].nr_of_ptts < 2)
- return;
+ return 0;
ptt = vts_file->vts_ptt_srpt->title[title_no].ptt;
- mp_msg(MSGT_IDENTIFY, MSGL_INFO, "CHAPTERS: ");
+ int cur = 0;
for(i=0; i<vts_file->vts_ptt_srpt->title[title_no].nr_of_ptts; i++)
{
pgc = vts_file->vts_pgcit->pgci_srp[ptt[i].pgcn-1].pgc;
@@ -519,15 +520,35 @@ static void list_chapters(ifo_handle_t *vts_file, tt_srpt_t *tt_srpt, int title_
last_cell = pgc->program_map[ptt[i].pgn];
else
last_cell = 0;
- mp_msg(MSGT_IDENTIFY, MSGL_INFO, "%02d:%02d:%02d.%03d,", t/3600000, (t/60000)%60, (t/1000)%60, t%1000);
do {
if(!(pgc->cell_playback[cell-1].block_type == BLOCK_TYPE_ANGLE_BLOCK &&
pgc->cell_playback[cell-1].block_mode != BLOCK_MODE_FIRST_CELL)
- )
+ ) {
+ if (cur == *p) {
+ *p = t / 1000.0;
+ return 1;
+ }
t += mp_dvdtimetomsec(&pgc->cell_playback[cell-1].playback_time);
+ cur++;
+ }
cell++;
} while(cell < last_cell);
}
+ return 0;
+}
+
+static void list_chapters(ifo_handle_t *vts_file, tt_srpt_t *tt_srpt, int title_no)
+{
+ mp_msg(MSGT_IDENTIFY, MSGL_INFO, "CHAPTERS: ");
+ for (int n = 0; ; n++) {
+ double p = n;
+ int r;
+ r = get_chapter_time(vts_file, tt_srpt, title_no, &p);
+ if (!r)
+ break;
+ int t = p * 1000;
+ mp_msg(MSGT_IDENTIFY, MSGL_INFO, "%02d:%02d:%02d.%03d,", t/3600000, (t/60000)%60, (t/1000)%60, t%1000);
+ }
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "\n");
}
@@ -642,6 +663,13 @@ static int control(stream_t *stream,int cmd,void* arg)
*((unsigned int *)arg) = r;
return 1;
}
+ case STREAM_CTRL_GET_CHAPTER_TIME:
+ {
+ int r;
+ r = get_chapter_time(d->vts_file, d->tt_srpt, d->cur_title-1, (double *)arg);
+ if(! r) return STREAM_UNSUPPORTED;
+ return 1;
+ }
case STREAM_CTRL_SEEK_TO_CHAPTER:
{
int r;