1
0
mirror of https://github.com/mpv-player/mpv synced 2024-12-26 00:42:57 +00:00

Support chapter seeking with ordered chapters

This commit is contained in:
Uoti Urpala 2009-04-02 05:00:22 +03:00
parent f12c83b85b
commit 2d91b19956
5 changed files with 70 additions and 8 deletions

View File

@ -5,6 +5,7 @@
#include <stdbool.h>
#include "config.h"
#include "talloc.h"
#include "command.h"
#include "input/input.h"
#include "stream/stream.h"
@ -391,7 +392,7 @@ static int mp_property_chapter(m_option_t *prop, int action, void *arg,
char *chapter_name = NULL;
if (mpctx->demuxer)
chapter = demuxer_get_current_chapter(mpctx->demuxer);
chapter = get_current_chapter(mpctx);
if (chapter < 0)
return M_PROPERTY_UNAVAILABLE;
@ -404,7 +405,7 @@ static int mp_property_chapter(m_option_t *prop, int action, void *arg,
case M_PROPERTY_PRINT: {
if (!arg)
return M_PROPERTY_ERROR;
chapter_name = demuxer_chapter_display_name(mpctx->demuxer, chapter);
chapter_name = chapter_display_name(mpctx, chapter);
if (!chapter_name)
return M_PROPERTY_UNAVAILABLE;
*(char **) arg = chapter_name;
@ -431,8 +432,7 @@ static int mp_property_chapter(m_option_t *prop, int action, void *arg,
}
double next_pts = 0;
chapter = demuxer_seek_chapter(mpctx->demuxer, chapter, &next_pts,
&chapter_name);
chapter = seek_chapter(mpctx, chapter, &next_pts, &chapter_name);
mpctx->rel_seek_secs = 0;
mpctx->abs_seek_pos = 0;
if (chapter >= 0) {

View File

@ -1170,6 +1170,7 @@ static uint64_t read_one_chapter(struct demuxer *demuxer, stream_t *s)
m->num_ordered_chapters + 1);
chapter.start = start;
chapter.end = end;
chapter.name = talloc_strdup(m->ordered_chapters, name);
// Will be undone later if this is a normal chapter rather than ordered
m->ordered_chapters[m->num_ordered_chapters] = chapter;
m->num_ordered_chapters++;

View File

@ -198,6 +198,7 @@ struct matroska_data {
uint64_t end;
bool has_segment_uid;
unsigned char segment_uid[16];
char *name;
} *ordered_chapters;
int num_ordered_chapters;
};

View File

@ -58,6 +58,11 @@ struct timeline_part {
struct content_source *source;
};
struct chapter {
double start;
char *name;
};
typedef struct MPContext {
struct MPOpts opts;
struct m_config *mconfig;
@ -85,6 +90,8 @@ typedef struct MPContext {
struct timeline_part *timeline;
int num_timeline_parts;
int timeline_part;
struct chapter *chapters;
int num_chapters;
double video_offset;
struct stream *stream;
@ -130,7 +137,7 @@ typedef struct MPContext {
unsigned int last_time;
// Used to communicate the parameters of a seek between parts
float rel_seek_secs;
double rel_seek_secs;
int abs_seek_pos;
float begin_skip; ///< start time of the current skip while on edlout mode
@ -188,5 +195,9 @@ int reinit_video_chain(struct MPContext *mpctx);
void pause_player(struct MPContext *mpctx);
void unpause_player(struct MPContext *mpctx);
void add_step_frame(struct MPContext *mpctx);
int seek_chapter(struct MPContext *mpctx, int chapter, double *seek_pts,
char **chapter_name);
int get_current_chapter(struct MPContext *mpctx);
char *chapter_display_name(struct MPContext *mpctx, int chapter);
#endif /* MPLAYER_MP_CORE_H */

View File

@ -579,6 +579,8 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask){
talloc_free(mpctx->timeline);
mpctx->timeline = NULL;
mpctx->num_timeline_parts = 0;
talloc_free(mpctx->chapters);
mpctx->num_chapters = 0;
mpctx->video_offset = 0;
if(mpctx->demuxer){
mpctx->stream=mpctx->demuxer->stream;
@ -2618,6 +2620,43 @@ static int seek(MPContext *mpctx, double amount, int style)
return 0;
}
int get_current_chapter(struct MPContext *mpctx)
{
if (!mpctx->chapters || !mpctx->sh_video)
return demuxer_get_current_chapter(mpctx->demuxer);
int i;
double current_pts = mpctx->sh_video->pts;
for (i = 1; i < mpctx->num_chapters; i++)
if (current_pts < mpctx->chapters[i].start)
break;
return i - 1;
}
// currently returns a string allocated with malloc, not talloc
char *chapter_display_name(struct MPContext *mpctx, int chapter)
{
if (!mpctx->chapters || !mpctx->sh_video)
return demuxer_chapter_display_name(mpctx->demuxer, chapter);
return strdup(mpctx->chapters[chapter].name);
}
int seek_chapter(struct MPContext *mpctx, int chapter, double *seek_pts,
char **chapter_name)
{
if (!mpctx->chapters || !mpctx->sh_video)
return demuxer_seek_chapter(mpctx->demuxer, chapter, seek_pts,
chapter_name);
if (chapter >= mpctx->num_chapters)
return -1;
if (chapter < 0)
chapter = 0;
*seek_pts = mpctx->chapters[chapter].start;
if (chapter_name)
*chapter_name = talloc_strdup(NULL, mpctx->chapters[chapter].name);
return chapter;
}
static int find_ordered_chapter_sources(struct MPContext *mpctx,
struct content_source *sources,
int num_sources,
@ -2726,9 +2765,12 @@ static void build_ordered_chapter_timeline(struct MPContext *mpctx)
struct timeline_part *timeline = talloc_array_ptrtype(NULL, timeline,
m->num_ordered_chapters + 1);
struct chapter *chapters = talloc_array_ptrtype(NULL, chapters,
m->num_ordered_chapters);
uint64_t starttime = 0;
uint64_t missing_time = 0;
int part_count = 0;
int num_chapters = 0;
for (int i = 0; i < m->num_ordered_chapters; i++) {
struct matroska_chapter *c = m->ordered_chapters + i;
@ -2740,6 +2782,8 @@ static void build_ordered_chapter_timeline(struct MPContext *mpctx)
missing_time += c->end - c->start;
continue;
found2:;
chapters[num_chapters].start = starttime / 1000.;
chapters[num_chapters].name = talloc_strdup(chapters, c->name);
// Only add a separate part if the time or file actually changes
uint64_t prev_end = !part_count ? 0 : starttime
- timeline[part_count - 1].start
@ -2747,11 +2791,12 @@ static void build_ordered_chapter_timeline(struct MPContext *mpctx)
if (part_count == 0 || c->start != prev_end
|| sources + j != timeline[part_count - 1].source) {
timeline[part_count].source = sources + j;
timeline[part_count].start = starttime / 1000.;
timeline[part_count].start = chapters[num_chapters].start;
timeline[part_count].source_start = c->start / 1000.;
part_count++;
}
starttime += c->end - c->start;
num_chapters++;
}
timeline[part_count].start = starttime / 1000.;
@ -2759,6 +2804,7 @@ static void build_ordered_chapter_timeline(struct MPContext *mpctx)
// None of the parts come from the file itself???
talloc_free(sources);
talloc_free(timeline);
talloc_free(chapters);
return;
}
@ -2784,6 +2830,9 @@ static void build_ordered_chapter_timeline(struct MPContext *mpctx)
mpctx->num_sources = num_sources;
mpctx->timeline = timeline;
mpctx->num_timeline_parts = part_count;
mpctx->num_chapters = num_chapters;
mpctx->chapters = chapters;
mpctx->timeline_part = 0;
mpctx->video_offset = timeline[0].source_start;
mpctx->demuxer = timeline[0].source->demuxer;
@ -3593,7 +3642,7 @@ if(!mpctx->demuxer)
if(dvd_chapter>1) {
double pts;
if (demuxer_seek_chapter(mpctx->demuxer, dvd_chapter-1, &pts, NULL) >= 0 && pts > -1.0)
if (seek_chapter(mpctx, dvd_chapter-1, &pts, NULL) >= 0 && pts > -1.0)
seek(mpctx, pts, SEEK_ABSOLUTE);
}
@ -3993,7 +4042,7 @@ while(!mpctx->stop_play){
float aq_sleep_time=0;
if(dvd_last_chapter>0) {
int cur_chapter = demuxer_get_current_chapter(mpctx->demuxer);
int cur_chapter = get_current_chapter(mpctx);
if(cur_chapter!=-1 && cur_chapter+1>dvd_last_chapter)
goto goto_next_file;
}