mirror of https://github.com/mpv-player/mpv
core, demux: fix --identify chapter output with ordered chapters
Information about individual chapters was printed during demuxer opening phase, and total chapter count (ID_CHAPTERS) was printed according to mpctx->demuxer->num_chapters. When playing a file with ordered chapters, this meant that chapter information about every source file was printed individually (even though only the chapters from the first file would be used for playback) and the total chapter count could be wrong. Remove the printing of chapter information from the demuxer layer and print the chapter information and count actually used for playback in core print_file_properties(). Also somewhat simplify the internal chapters API and remove possible inconsistencies.
This commit is contained in:
parent
c0b7851f23
commit
e3f5043233
14
command.c
14
command.c
|
@ -527,13 +527,13 @@ static int mp_property_chapter(m_option_t *prop, int action, void *arg,
|
|||
|
||||
double next_pts = 0;
|
||||
queue_seek(mpctx, MPSEEK_NONE, 0, 0);
|
||||
chapter = seek_chapter(mpctx, chapter, &next_pts, &chapter_name);
|
||||
chapter = seek_chapter(mpctx, chapter, &next_pts);
|
||||
if (chapter >= 0) {
|
||||
if (next_pts > -1.0)
|
||||
queue_seek(mpctx, MPSEEK_ABSOLUTE, next_pts, 0);
|
||||
if (chapter_name)
|
||||
set_osd_tmsg(OSD_MSG_TEXT, 1, opts->osd_duration,
|
||||
"Chapter: (%d) %s", chapter + 1, chapter_name);
|
||||
chapter_name = chapter_display_name(mpctx, chapter);
|
||||
set_osd_tmsg(OSD_MSG_TEXT, 1, opts->osd_duration,
|
||||
"Chapter: %s", chapter_name);
|
||||
} else if (step_all > 0)
|
||||
queue_seek(mpctx, MPSEEK_RELATIVE, 1000000000, 0);
|
||||
else
|
||||
|
@ -549,10 +549,8 @@ static int mp_property_chapters(m_option_t *prop, int action, void *arg,
|
|||
{
|
||||
if (!mpctx->demuxer)
|
||||
return M_PROPERTY_UNAVAILABLE;
|
||||
if (mpctx->demuxer->num_chapters == 0)
|
||||
stream_control(mpctx->demuxer->stream, STREAM_CTRL_GET_NUM_CHAPTERS,
|
||||
&mpctx->demuxer->num_chapters);
|
||||
return m_property_int_ro(prop, action, arg, mpctx->demuxer->num_chapters);
|
||||
int count = get_chapter_count(mpctx);
|
||||
return m_property_int_ro(prop, action, arg, count);
|
||||
}
|
||||
|
||||
/// Current dvd angle (RW)
|
||||
|
|
|
@ -1409,13 +1409,6 @@ int demuxer_add_chapter(demuxer_t *demuxer, struct bstr name,
|
|||
talloc_strndup(demuxer->chapters, name.start, name.len) :
|
||||
talloc_strdup(demuxer->chapters, mp_gtext("unknown"));
|
||||
|
||||
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_CHAPTER_ID=%d\n", demuxer->num_chapters);
|
||||
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_CHAPTER_%d_START=%"PRIu64"\n", demuxer->num_chapters, start / 1000000);
|
||||
if (end)
|
||||
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_CHAPTER_%d_END=%"PRIu64"\n", demuxer->num_chapters, end / 1000000);
|
||||
if (name.start)
|
||||
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_CHAPTER_%d_NAME=%.*s\n", demuxer->num_chapters, BSTR_P(name));
|
||||
|
||||
return demuxer->num_chapters++;
|
||||
}
|
||||
|
||||
|
@ -1425,12 +1418,10 @@ int demuxer_add_chapter(demuxer_t *demuxer, struct bstr name,
|
|||
* 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)
|
||||
* \param chapter_name name of chapter found (set by this function is param is not null)
|
||||
* \return -1 on error, current chapter if successful
|
||||
*/
|
||||
|
||||
int demuxer_seek_chapter(demuxer_t *demuxer, int chapter, double *seek_pts,
|
||||
char **chapter_name)
|
||||
int demuxer_seek_chapter(demuxer_t *demuxer, int chapter, double *seek_pts)
|
||||
{
|
||||
int ris;
|
||||
|
||||
|
@ -1446,18 +1437,6 @@ int demuxer_seek_chapter(demuxer_t *demuxer, int chapter, double *seek_pts,
|
|||
// (because e.g. dvds depend on sectors, not on pts)
|
||||
*seek_pts = -1.0;
|
||||
|
||||
if (chapter_name) {
|
||||
*chapter_name = NULL;
|
||||
int num_chapters;
|
||||
if (stream_control(demuxer->stream, STREAM_CTRL_GET_NUM_CHAPTERS,
|
||||
&num_chapters) == STREAM_UNSUPPORTED)
|
||||
num_chapters = 0;
|
||||
if (num_chapters) {
|
||||
*chapter_name = talloc_size(NULL, 16);
|
||||
sprintf(*chapter_name, " of %3d", num_chapters);
|
||||
}
|
||||
}
|
||||
|
||||
return ris != STREAM_UNSUPPORTED ? chapter : -1;
|
||||
} else { // chapters structure is set in the demuxer
|
||||
if (chapter >= demuxer->num_chapters)
|
||||
|
@ -1467,9 +1446,6 @@ int demuxer_seek_chapter(demuxer_t *demuxer, int chapter, double *seek_pts,
|
|||
|
||||
*seek_pts = demuxer->chapters[chapter].start / 1e9;
|
||||
|
||||
if (chapter_name)
|
||||
*chapter_name = talloc_strdup(NULL, demuxer->chapters[chapter].name);
|
||||
|
||||
return chapter;
|
||||
}
|
||||
}
|
||||
|
@ -1496,28 +1472,11 @@ 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 strdup(demuxer->chapters[chapter].name);
|
||||
return talloc_strdup(NULL, demuxer->chapters[chapter].name);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *demuxer_chapter_display_name(demuxer_t *demuxer, int chapter)
|
||||
{
|
||||
char *chapter_name = demuxer_chapter_name(demuxer, chapter);
|
||||
if (chapter_name) {
|
||||
char *tmp = talloc_asprintf(NULL, "(%d) %s", chapter + 1, chapter_name);
|
||||
free(chapter_name);
|
||||
return tmp;
|
||||
} else {
|
||||
int chapter_num = demuxer_chapter_count(demuxer);
|
||||
if (chapter_num <= 0)
|
||||
return talloc_asprintf(NULL, "(%d)", chapter + 1);
|
||||
else
|
||||
return talloc_asprintf(NULL, "(%d) of %d", chapter + 1,
|
||||
chapter_num);
|
||||
}
|
||||
}
|
||||
|
||||
float demuxer_chapter_time(demuxer_t *demuxer, int chapter, float *end)
|
||||
{
|
||||
if (demuxer->num_chapters && demuxer->chapters && chapter >= 0
|
||||
|
|
|
@ -400,15 +400,13 @@ int demuxer_add_attachment(struct demuxer *demuxer, struct bstr name,
|
|||
struct bstr type, struct bstr data);
|
||||
int demuxer_add_chapter(struct demuxer *demuxer, struct bstr name,
|
||||
uint64_t start, uint64_t end);
|
||||
int demuxer_seek_chapter(struct demuxer *demuxer, int chapter, double *seek_pts,
|
||||
char **chapter_name);
|
||||
int demuxer_seek_chapter(struct demuxer *demuxer, int chapter,
|
||||
double *seek_pts);
|
||||
|
||||
/// 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 display name by index.
|
||||
char *demuxer_chapter_display_name(struct demuxer *demuxer, int chapter);
|
||||
/// Get chapter start time and end time by index if available.
|
||||
float demuxer_chapter_time(struct demuxer *demuxer, int chapter, float *end);
|
||||
/// Get total chapter number.
|
||||
|
|
|
@ -242,13 +242,15 @@ void unpause_player(struct MPContext *mpctx);
|
|||
void add_step_frame(struct MPContext *mpctx);
|
||||
void queue_seek(struct MPContext *mpctx, enum seek_type type, double amount,
|
||||
int exact);
|
||||
int seek_chapter(struct MPContext *mpctx, int chapter, double *seek_pts,
|
||||
char **chapter_name);
|
||||
int seek_chapter(struct MPContext *mpctx, int chapter, double *seek_pts);
|
||||
double get_time_length(struct MPContext *mpctx);
|
||||
double get_current_time(struct MPContext *mpctx);
|
||||
int get_percent_pos(struct MPContext *mpctx);
|
||||
int get_current_chapter(struct MPContext *mpctx);
|
||||
char *chapter_display_name(struct MPContext *mpctx, int chapter);
|
||||
char *chapter_name(struct MPContext *mpctx, int chapter);
|
||||
double chapter_start_time(struct MPContext *mpctx, int chapter);
|
||||
int get_chapter_count(struct MPContext *mpctx);
|
||||
void update_subtitles(struct MPContext *mpctx, double refpts,
|
||||
double sub_offset, bool reset);
|
||||
|
||||
|
|
65
mplayer.c
65
mplayer.c
|
@ -567,12 +567,20 @@ static void print_file_properties(struct MPContext *mpctx, const char *filename)
|
|||
mpctx->stream->seek
|
||||
&& (!mpctx->demuxer || mpctx->demuxer->seekable));
|
||||
if (mpctx->demuxer) {
|
||||
if (mpctx->demuxer->num_chapters == 0)
|
||||
stream_control(mpctx->demuxer->stream,
|
||||
STREAM_CTRL_GET_NUM_CHAPTERS,
|
||||
&mpctx->demuxer->num_chapters);
|
||||
mp_msg(MSGT_IDENTIFY, MSGL_INFO,
|
||||
"ID_CHAPTERS=%d\n", mpctx->demuxer->num_chapters);
|
||||
int chapter_count = get_chapter_count(mpctx);
|
||||
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_CHAPTERS=%d\n", chapter_count);
|
||||
for (int i = 0; i < chapter_count; i++) {
|
||||
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_CHAPTER_ID=%d\n", i);
|
||||
// in milliseconds
|
||||
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_CHAPTER_%d_START=%"PRIu64"\n",
|
||||
i, (int64_t)(chapter_start_time(mpctx, i) * 1000.0));
|
||||
char *name = chapter_name(mpctx, i);
|
||||
if (name) {
|
||||
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_CHAPTER_%d_NAME=%s\n", i,
|
||||
name);
|
||||
talloc_free(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3431,21 +3439,50 @@ int get_current_chapter(struct MPContext *mpctx)
|
|||
return FFMAX(mpctx->last_chapter_seek, i - 1);
|
||||
}
|
||||
|
||||
// currently returns a string allocated with malloc, not talloc
|
||||
char *chapter_display_name(struct MPContext *mpctx, int chapter)
|
||||
{
|
||||
char *name = chapter_name(mpctx, chapter);
|
||||
if (name) {
|
||||
name = talloc_asprintf(name, "(%d) %s", chapter + 1, name);
|
||||
} else {
|
||||
int chapter_count = get_chapter_count(mpctx);
|
||||
if (chapter_count <= 0)
|
||||
name = talloc_asprintf(NULL, "(%d)", chapter + 1);
|
||||
else
|
||||
name = talloc_asprintf(NULL, "(%d) of %d", chapter + 1,
|
||||
chapter_count);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
// returns NULL if chapter name unavailable
|
||||
char *chapter_name(struct MPContext *mpctx, int chapter)
|
||||
{
|
||||
if (!mpctx->chapters)
|
||||
return demuxer_chapter_display_name(mpctx->demuxer, chapter);
|
||||
return demuxer_chapter_name(mpctx->demuxer, chapter);
|
||||
return talloc_strdup(NULL, mpctx->chapters[chapter].name);
|
||||
}
|
||||
|
||||
int seek_chapter(struct MPContext *mpctx, int chapter, double *seek_pts,
|
||||
char **chapter_name)
|
||||
// returns the start of the chapter in seconds
|
||||
double chapter_start_time(struct MPContext *mpctx, int chapter)
|
||||
{
|
||||
if (!mpctx->chapters)
|
||||
return demuxer_chapter_time(mpctx->demuxer, chapter, NULL);
|
||||
return mpctx->chapters[chapter].start;
|
||||
}
|
||||
|
||||
int get_chapter_count(struct MPContext *mpctx)
|
||||
{
|
||||
if (!mpctx->chapters)
|
||||
return demuxer_chapter_count(mpctx->demuxer);
|
||||
return mpctx->num_chapters;
|
||||
}
|
||||
|
||||
int seek_chapter(struct MPContext *mpctx, int chapter, double *seek_pts)
|
||||
{
|
||||
mpctx->last_chapter_seek = -2;
|
||||
if (!mpctx->chapters) {
|
||||
int res = demuxer_seek_chapter(mpctx->demuxer, chapter, seek_pts,
|
||||
chapter_name);
|
||||
int res = demuxer_seek_chapter(mpctx->demuxer, chapter, seek_pts);
|
||||
if (res >= 0) {
|
||||
if (*seek_pts == -1)
|
||||
seek_reset(mpctx, true);
|
||||
|
@ -3464,8 +3501,6 @@ int seek_chapter(struct MPContext *mpctx, int chapter, double *seek_pts,
|
|||
*seek_pts = mpctx->chapters[chapter].start;
|
||||
mpctx->last_chapter_seek = chapter;
|
||||
mpctx->last_chapter_pts = *seek_pts;
|
||||
if (chapter_name)
|
||||
*chapter_name = talloc_strdup(NULL, mpctx->chapters[chapter].name);
|
||||
return chapter;
|
||||
}
|
||||
|
||||
|
@ -4919,7 +4954,7 @@ goto_enable_cache:
|
|||
}
|
||||
if (opts->chapterrange[0] > 0) {
|
||||
double pts;
|
||||
if (seek_chapter(mpctx, opts->chapterrange[0] - 1, &pts, NULL) >= 0
|
||||
if (seek_chapter(mpctx, opts->chapterrange[0] - 1, &pts) >= 0
|
||||
&& pts > -1.0) {
|
||||
queue_seek(mpctx, MPSEEK_ABSOLUTE, pts, 0);
|
||||
seek(mpctx, mpctx->seek, false);
|
||||
|
|
Loading…
Reference in New Issue