From b01e8d6210adcf0b68313d1b31f904c121020401 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 4 May 2013 01:20:39 +0200 Subject: stream: report chapter times, use time seeks for DVD chapters Allow the stream layer to report chapter times. Extend stream_dvd to do this. I'm not 100% sure whether the re-used code is bug-free (because it was used for slave-mode and/or debugging only). MAke the frontend do time-based seeks when switching DVD chapters. I'm not sure if there's a real reason STREAM_CTRL_SEEK_TO_CHAPTER exists (maybe/hopefully not), but we will see. Note that querying chapter times in demuxer_chapter_time() with the new STREAM_CTRL_GET_CHAPTER_TIME could be excessively slow, especially with the cache enabled. The frontend likes to query chapter times very often. Additionally, stream_dvd uses some sort of quadratic algorithm to list times for all chapters. For this reason, we try to query all chapters on start (after the demuxer is opened), and add the chapters to the demuxer chapter list. demuxer_chapter_time() will get the time from that list, instead of asking the stream layer over and over again. This assumes stream_dvd knows the list of chapters at the start, and also that the list of chapters never changes during playback. This seems to be true, and the only exception, switching DVD titles, is not supported at runtime (and doesn't need to be supported). --- stream/stream_dvd.c | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) (limited to 'stream/stream_dvd.c') 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; ivts_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; -- cgit v1.2.3