mirror of https://github.com/mpv-player/mpv
player: remove demuxer chapoter API wrappers
Instead, always use the mpctx->chapters array. Before this commit, this array was used only for ordered chapters and such, but now it's always populated if there are chapters.
This commit is contained in:
parent
2c693a4732
commit
92d7dc9e88
|
@ -98,6 +98,7 @@ struct demux_stream {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void add_stream_chapters(struct demuxer *demuxer);
|
static void add_stream_chapters(struct demuxer *demuxer);
|
||||||
|
void demuxer_sort_chapters(demuxer_t *demuxer);
|
||||||
|
|
||||||
static void ds_free_packs(struct demux_stream *ds)
|
static void ds_free_packs(struct demux_stream *ds)
|
||||||
{
|
{
|
||||||
|
@ -881,7 +882,10 @@ static void add_stream_chapters(struct demuxer *demuxer)
|
||||||
{
|
{
|
||||||
if (demuxer->num_chapters)
|
if (demuxer->num_chapters)
|
||||||
return;
|
return;
|
||||||
int num_chapters = demuxer_chapter_count(demuxer);
|
int num_chapters = 0;
|
||||||
|
if (stream_control(demuxer->stream, STREAM_CTRL_GET_NUM_CHAPTERS,
|
||||||
|
&num_chapters) != STREAM_OK)
|
||||||
|
return;
|
||||||
for (int n = 0; n < num_chapters; n++) {
|
for (int n = 0; n < num_chapters; n++) {
|
||||||
double p = n;
|
double p = n;
|
||||||
if (stream_control(demuxer->stream, STREAM_CTRL_GET_CHAPTER_TIME, &p)
|
if (stream_control(demuxer->stream, STREAM_CTRL_GET_CHAPTER_TIME, &p)
|
||||||
|
@ -891,69 +895,6 @@ static void add_stream_chapters(struct demuxer *demuxer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief demuxer_seek_chapter() seeks to a chapter in two possible ways:
|
|
||||||
* either using the demuxer->chapters structure set by the demuxer
|
|
||||||
* or asking help to the stream layer (e.g. dvd)
|
|
||||||
* \param chapter - chapter number wished - 0-based
|
|
||||||
* \param seek_pts set by the function to the pts to seek to (if demuxer->chapters is set)
|
|
||||||
* \return -1 on error, current chapter if successful
|
|
||||||
*/
|
|
||||||
|
|
||||||
int demuxer_seek_chapter(demuxer_t *demuxer, int chapter, double *seek_pts)
|
|
||||||
{
|
|
||||||
if (chapter >= demuxer->num_chapters)
|
|
||||||
return -1;
|
|
||||||
if (chapter < 0)
|
|
||||||
chapter = 0;
|
|
||||||
|
|
||||||
*seek_pts = demuxer->chapters[chapter].start / 1e9;
|
|
||||||
|
|
||||||
return chapter;
|
|
||||||
}
|
|
||||||
|
|
||||||
int demuxer_get_current_chapter(demuxer_t *demuxer, double time_now)
|
|
||||||
{
|
|
||||||
int chapter = -2;
|
|
||||||
uint64_t now = time_now * 1e9 + 0.5;
|
|
||||||
for (chapter = demuxer->num_chapters - 1; chapter >= 0; --chapter) {
|
|
||||||
if (demuxer->chapters[chapter].start <= now)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return chapter;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *demuxer_chapter_name(demuxer_t *demuxer, int chapter)
|
|
||||||
{
|
|
||||||
if (demuxer->num_chapters && demuxer->chapters) {
|
|
||||||
if (chapter >= 0 && chapter < demuxer->num_chapters
|
|
||||||
&& demuxer->chapters[chapter].name)
|
|
||||||
return talloc_strdup(NULL, demuxer->chapters[chapter].name);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
double demuxer_chapter_time(demuxer_t *demuxer, int chapter)
|
|
||||||
{
|
|
||||||
if (demuxer->num_chapters && demuxer->chapters && chapter >= 0
|
|
||||||
&& chapter < demuxer->num_chapters) {
|
|
||||||
return demuxer->chapters[chapter].start / 1e9;
|
|
||||||
}
|
|
||||||
return -1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int demuxer_chapter_count(demuxer_t *demuxer)
|
|
||||||
{
|
|
||||||
if (!demuxer->num_chapters || !demuxer->chapters) {
|
|
||||||
int num_chapters = 0;
|
|
||||||
if (stream_control(demuxer->stream, STREAM_CTRL_GET_NUM_CHAPTERS,
|
|
||||||
&num_chapters) == STREAM_UNSUPPORTED)
|
|
||||||
num_chapters = 0;
|
|
||||||
return num_chapters;
|
|
||||||
} else
|
|
||||||
return demuxer->num_chapters;
|
|
||||||
}
|
|
||||||
|
|
||||||
double demuxer_get_time_length(struct demuxer *demuxer)
|
double demuxer_get_time_length(struct demuxer *demuxer)
|
||||||
{
|
{
|
||||||
double len;
|
double len;
|
||||||
|
|
|
@ -259,21 +259,10 @@ int demuxer_add_attachment(struct demuxer *demuxer, struct bstr name,
|
||||||
struct bstr type, struct bstr data);
|
struct bstr type, struct bstr data);
|
||||||
int demuxer_add_chapter(struct demuxer *demuxer, struct bstr name,
|
int demuxer_add_chapter(struct demuxer *demuxer, struct bstr name,
|
||||||
uint64_t start, uint64_t end, uint64_t demuxer_id);
|
uint64_t start, uint64_t end, uint64_t demuxer_id);
|
||||||
int demuxer_seek_chapter(struct demuxer *demuxer, int chapter,
|
|
||||||
double *seek_pts);
|
|
||||||
void demuxer_sort_chapters(demuxer_t *demuxer);
|
|
||||||
|
|
||||||
double demuxer_get_time_length(struct demuxer *demuxer);
|
double demuxer_get_time_length(struct demuxer *demuxer);
|
||||||
double demuxer_get_start_time(struct demuxer *demuxer);
|
double demuxer_get_start_time(struct demuxer *demuxer);
|
||||||
|
|
||||||
/// Get current chapter index if available.
|
|
||||||
int demuxer_get_current_chapter(struct demuxer *demuxer, double time_now);
|
|
||||||
/// Get chapter name by index if available.
|
|
||||||
char *demuxer_chapter_name(struct demuxer *demuxer, int chapter);
|
|
||||||
/// Get chapter start time by index if available.
|
|
||||||
double demuxer_chapter_time(struct demuxer *demuxer, int chapter);
|
|
||||||
/// Get total chapter number.
|
|
||||||
int demuxer_chapter_count(struct demuxer *demuxer);
|
|
||||||
/// Get current angle index.
|
/// Get current angle index.
|
||||||
int demuxer_get_current_angle(struct demuxer *demuxer);
|
int demuxer_get_current_angle(struct demuxer *demuxer);
|
||||||
/// Set angle.
|
/// Set angle.
|
||||||
|
|
|
@ -1002,6 +1002,24 @@ static void print_timeline(struct MPContext *mpctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void load_chapters(struct MPContext *mpctx)
|
||||||
|
{
|
||||||
|
if (!mpctx->chapters && mpctx->master_demuxer &&
|
||||||
|
mpctx->master_demuxer->num_chapters)
|
||||||
|
{
|
||||||
|
int count = mpctx->master_demuxer->num_chapters;
|
||||||
|
mpctx->chapters = talloc_array(NULL, struct chapter, count);
|
||||||
|
mpctx->num_chapters = count;
|
||||||
|
for (int n = 0; n < count; n++) {
|
||||||
|
struct demux_chapter *dchapter = &mpctx->master_demuxer->chapters[n];
|
||||||
|
mpctx->chapters[n] = (struct chapter){
|
||||||
|
.start = dchapter->start / 1e9,
|
||||||
|
.name = talloc_strdup(mpctx->chapters, dchapter->name),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* When demux performs a blocking operation (network connection or
|
/* When demux performs a blocking operation (network connection or
|
||||||
* cache filling) if the operation fails we use this function to check
|
* cache filling) if the operation fails we use this function to check
|
||||||
* if it was interrupted by the user.
|
* if it was interrupted by the user.
|
||||||
|
@ -1189,6 +1207,7 @@ goto_reopen_demuxer: ;
|
||||||
build_cue_timeline(mpctx);
|
build_cue_timeline(mpctx);
|
||||||
|
|
||||||
print_timeline(mpctx);
|
print_timeline(mpctx);
|
||||||
|
load_chapters(mpctx);
|
||||||
|
|
||||||
if (mpctx->timeline) {
|
if (mpctx->timeline) {
|
||||||
// With Matroska, the "master" file usually dictates track layout etc.
|
// With Matroska, the "master" file usually dictates track layout etc.
|
||||||
|
|
|
@ -509,9 +509,6 @@ int get_current_chapter(struct MPContext *mpctx)
|
||||||
break;
|
break;
|
||||||
return MPMAX(mpctx->last_chapter_seek, i - 1);
|
return MPMAX(mpctx->last_chapter_seek, i - 1);
|
||||||
}
|
}
|
||||||
if (mpctx->master_demuxer)
|
|
||||||
return MPMAX(mpctx->last_chapter_seek,
|
|
||||||
demuxer_get_current_chapter(mpctx->master_demuxer, current_pts));
|
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -544,8 +541,6 @@ char *chapter_name(struct MPContext *mpctx, int chapter)
|
||||||
return NULL;
|
return NULL;
|
||||||
return talloc_strdup(NULL, mpctx->chapters[chapter].name);
|
return talloc_strdup(NULL, mpctx->chapters[chapter].name);
|
||||||
}
|
}
|
||||||
if (mpctx->master_demuxer)
|
|
||||||
return demuxer_chapter_name(mpctx->master_demuxer, chapter);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,20 +549,14 @@ double chapter_start_time(struct MPContext *mpctx, int chapter)
|
||||||
{
|
{
|
||||||
if (chapter == -1)
|
if (chapter == -1)
|
||||||
return get_start_time(mpctx);
|
return get_start_time(mpctx);
|
||||||
if (mpctx->chapters)
|
if (mpctx->chapters && chapter < mpctx->num_chapters)
|
||||||
return mpctx->chapters[chapter].start;
|
return mpctx->chapters[chapter].start;
|
||||||
if (mpctx->master_demuxer)
|
return -1.0;
|
||||||
return demuxer_chapter_time(mpctx->master_demuxer, chapter);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_chapter_count(struct MPContext *mpctx)
|
int get_chapter_count(struct MPContext *mpctx)
|
||||||
{
|
{
|
||||||
if (mpctx->chapters)
|
return mpctx->num_chapters;
|
||||||
return mpctx->num_chapters;
|
|
||||||
if (mpctx->master_demuxer)
|
|
||||||
return demuxer_chapter_count(mpctx->master_demuxer);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Seek to a given chapter. Queues the seek.
|
// Seek to a given chapter. Queues the seek.
|
||||||
|
@ -581,23 +570,10 @@ bool mp_seek_chapter(struct MPContext *mpctx, int chapter)
|
||||||
|
|
||||||
mpctx->last_chapter_seek = -2;
|
mpctx->last_chapter_seek = -2;
|
||||||
|
|
||||||
double pts;
|
double pts = chapter_start_time(mpctx, chapter);
|
||||||
if (chapter == -1) {
|
if (pts == -1.0)
|
||||||
pts = get_start_time(mpctx);
|
return false;
|
||||||
goto do_seek;
|
|
||||||
} else if (mpctx->chapters) {
|
|
||||||
pts = mpctx->chapters[chapter].start;
|
|
||||||
goto do_seek;
|
|
||||||
} else if (mpctx->master_demuxer) {
|
|
||||||
int res = demuxer_seek_chapter(mpctx->master_demuxer, chapter, &pts);
|
|
||||||
if (res >= 0) {
|
|
||||||
chapter = res;
|
|
||||||
goto do_seek;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
|
|
||||||
do_seek:
|
|
||||||
queue_seek(mpctx, MPSEEK_ABSOLUTE, pts, 0, true);
|
queue_seek(mpctx, MPSEEK_ABSOLUTE, pts, 0, true);
|
||||||
mpctx->last_chapter_seek = chapter;
|
mpctx->last_chapter_seek = chapter;
|
||||||
mpctx->last_chapter_pts = pts;
|
mpctx->last_chapter_pts = pts;
|
||||||
|
|
|
@ -157,19 +157,25 @@ static struct demuxer *open_source(struct MPContext *mpctx, char *filename)
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static double demuxer_chapter_time(struct demuxer *demuxer, int n)
|
||||||
|
{
|
||||||
|
if (n < 0 || n >= demuxer->num_chapters)
|
||||||
|
return -1;
|
||||||
|
return demuxer->chapters[n].start / 1e9;
|
||||||
|
}
|
||||||
|
|
||||||
// Append all chapters from src to the chapters array.
|
// Append all chapters from src to the chapters array.
|
||||||
// Ignore chapters outside of the given time range.
|
// Ignore chapters outside of the given time range.
|
||||||
static void copy_chapters(struct chapter **chapters, int *num_chapters,
|
static void copy_chapters(struct chapter **chapters, int *num_chapters,
|
||||||
struct demuxer *src, double start, double len,
|
struct demuxer *src, double start, double len,
|
||||||
double dest_offset)
|
double dest_offset)
|
||||||
{
|
{
|
||||||
int count = demuxer_chapter_count(src);
|
for (int n = 0; n < src->num_chapters; n++) {
|
||||||
for (int n = 0; n < count; n++) {
|
|
||||||
double time = demuxer_chapter_time(src, n);
|
double time = demuxer_chapter_time(src, n);
|
||||||
if (time >= start && time <= start + len) {
|
if (time >= start && time <= start + len) {
|
||||||
struct chapter ch = {
|
struct chapter ch = {
|
||||||
.start = dest_offset + time - start,
|
.start = dest_offset + time - start,
|
||||||
.name = talloc_steal(*chapters, demuxer_chapter_name(src, n)),
|
.name = talloc_strdup(*chapters, src->chapters[n].name),
|
||||||
};
|
};
|
||||||
MP_TARRAY_APPEND(NULL, *chapters, *num_chapters, ch);
|
MP_TARRAY_APPEND(NULL, *chapters, *num_chapters, ch);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue