[MPlayer-cvslog] r19348 - in trunk: DOCS/man/en/mplayer.1 DOCS/tech/slave.txt help/help_mp-en.h input/input.c input/input.h libmpdemux/demux_mkv.c libmpdemux/demuxer.c libmpdemux/demuxer.h libmpdemux/ebml.h mplayer.c
eugeni
subversion at mplayerhq.hu
Sun Aug 6 20:55:35 CEST 2006
Author: eugeni
Date: Sun Aug 6 20:55:34 2006
New Revision: 19348
Modified:
trunk/help/help_mp-en.h
trunk/input/input.c
trunk/input/input.h
trunk/libmpdemux/demux_mkv.c
trunk/libmpdemux/demuxer.c
trunk/libmpdemux/demuxer.h
trunk/libmpdemux/ebml.h
trunk/mplayer.c
Changes in other areas also in this revision:
Modified:
trunk/DOCS/man/en/mplayer.1
trunk/DOCS/tech/slave.txt
Log:
Add matroska chapter seeking capability.
Modified: trunk/help/help_mp-en.h
==============================================================================
--- trunk/help/help_mp-en.h (original)
+++ trunk/help/help_mp-en.h Sun Aug 6 20:55:34 2006
@@ -210,6 +210,7 @@
#define MSGTR_OSDSubDelay "Sub delay: %d ms"
#define MSGTR_OSDSpeed "Speed: x %6.2f"
#define MSGTR_OSDosd "OSD: %s"
+#define MSGTR_OSDChapter "Chapter: (%d) %s"
// property values
#define MSGTR_Enabled "enabled"
Modified: trunk/input/input.c
==============================================================================
--- trunk/input/input.c (original)
+++ trunk/input/input.c Sun Aug 6 20:55:34 2006
@@ -146,6 +146,8 @@
{ MP_CMD_SET_PROPERTY, "set_property", 2, { {MP_CMD_ARG_STRING, {0}}, {MP_CMD_ARG_STRING, {0}}, {-1,{0}} } },
{ MP_CMD_GET_PROPERTY, "get_property", 1, { {MP_CMD_ARG_STRING, {0}}, {-1,{0}} } },
+ { MP_CMD_SEEK_CHAPTER, "seek_chapter", 1, { {MP_CMD_ARG_INT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
+
{ 0, NULL, 0, {} }
};
@@ -392,6 +394,9 @@
{ { KEY_MUTE, 0 }, "mute" },
{ { KEY_CLOSE_WIN, 0 }, "quit" },
+
+ { { '!', 0 }, "seek_chapter -1" },
+ { { '@', 0 }, "seek_chapter 1" },
{ { 0 }, NULL }
};
Modified: trunk/input/input.h
==============================================================================
--- trunk/input/input.h (original)
+++ trunk/input/input.h Sun Aug 6 20:55:34 2006
@@ -70,6 +70,7 @@
#define MP_CMD_SET_PROPERTY 68
#define MP_CMD_GET_PROPERTY 69
#define MP_CMD_OSD_SHOW_PROPERTY_TEXT 70
+#define MP_CMD_SEEK_CHAPTER 71
#define MP_CMD_GUI_EVENTS 5000
#define MP_CMD_GUI_LOADFILE 5001
Modified: trunk/libmpdemux/demux_mkv.c
==============================================================================
--- trunk/libmpdemux/demux_mkv.c (original)
+++ trunk/libmpdemux/demux_mkv.c Sun Aug 6 20:55:34 2006
@@ -141,11 +141,6 @@
uint64_t timecode, filepos;
} mkv_index_t;
-typedef struct mkv_chapter
-{
- uint64_t start, end;
-} mkv_chapter_t;
-
typedef struct mkv_attachment
{
char* name;
@@ -188,8 +183,6 @@
int64_t skip_to_timecode;
int v_skip_to_keyframe, a_skip_to_keyframe;
- mkv_chapter_t *chapters;
- int num_chapters;
int64_t stop_timecode;
int last_aid;
@@ -1328,7 +1321,7 @@
uint64_t length, l;
int il;
- if (mkv_d->chapters)
+ if (demuxer->chapters)
{
ebml_read_skip (s, NULL);
return 0;
@@ -1359,18 +1352,13 @@
case MATROSKA_ID_CHAPTERATOM:
{
uint64_t len, start=0, end=0;
+ char* name = 0;
int i;
+ int cid;
len = ebml_read_length (s, &i);
l = len + i;
- if (mkv_d->chapters == NULL)
- mkv_d->chapters = malloc (32*sizeof(*mkv_d->chapters));
- else if (!(mkv_d->num_chapters % 32))
- mkv_d->chapters = realloc (mkv_d->chapters,
- (mkv_d->num_chapters + 32)
- * sizeof(*mkv_d->chapters));
-
while (len > 0)
{
uint64_t l;
@@ -1386,6 +1374,32 @@
end = ebml_read_uint (s, &l) / 1000000;
break;
+ case MATROSKA_ID_CHAPTERDISPLAY:
+ {
+ uint64_t len;
+ int i;
+
+ len = ebml_read_length (s, &i);
+ l = len + i;
+ while (len > 0)
+ {
+ uint64_t l;
+ int il;
+
+ switch (ebml_read_id (s, &il))
+ {
+ case MATROSKA_ID_CHAPSTRING:
+ name = ebml_read_utf8 (s, &l);
+ break;
+ default:
+ ebml_read_skip (s, &l);
+ break;
+ }
+ len -= l + il;
+ }
+ }
+ break;
+
default:
ebml_read_skip (s, &l);
break;
@@ -1393,12 +1407,15 @@
len -= l + il;
}
- mkv_d->chapters[mkv_d->num_chapters].start = start;
- mkv_d->chapters[mkv_d->num_chapters].end = end;
+ if (!name)
+ name = strdup("(unnamed)");
+
+ cid = demuxer_add_chapter(demuxer, name, start, end);
+
mp_msg(MSGT_DEMUX, MSGL_V,
"[mkv] Chapter %u from %02d:%02d:%02d."
- "%03d to %02d:%02d:%02d.%03d\n",
- ++mkv_d->num_chapters,
+ "%03d to %02d:%02d:%02d.%03d, %s\n",
+ cid,
(int) (start / 60 / 60 / 1000),
(int) ((start / 60 / 1000) % 60),
(int) ((start / 1000) % 60),
@@ -1406,7 +1423,9 @@
(int) (end / 60 / 60 / 1000),
(int) ((end / 60 / 1000) % 60),
(int) ((end / 1000) % 60),
- (int) (end % 1000));
+ (int) (end % 1000), name);
+
+ free(name);
break;
}
@@ -2581,19 +2600,19 @@
else
demuxer->sub->id = -2;
- if (mkv_d->chapters)
+ if (demuxer->chapters)
{
- for (i=0; i < (int)mkv_d->num_chapters; i++)
+ for (i=0; i < (int)demuxer->num_chapters; i++)
{
- mkv_d->chapters[i].start -= mkv_d->first_tc;
- mkv_d->chapters[i].end -= mkv_d->first_tc;
+ demuxer->chapters[i].start -= mkv_d->first_tc;
+ demuxer->chapters[i].end -= mkv_d->first_tc;
}
- if (dvd_last_chapter > 0 && dvd_last_chapter <= mkv_d->num_chapters)
+ if (dvd_last_chapter > 0 && dvd_last_chapter <= demuxer->num_chapters)
{
- if (mkv_d->chapters[dvd_last_chapter-1].end != 0)
- mkv_d->stop_timecode = mkv_d->chapters[dvd_last_chapter-1].end;
- else if (dvd_last_chapter + 1 <= mkv_d->num_chapters)
- mkv_d->stop_timecode = mkv_d->chapters[dvd_last_chapter].start;
+ if (demuxer->chapters[dvd_last_chapter-1].end != 0)
+ mkv_d->stop_timecode = demuxer->chapters[dvd_last_chapter-1].end;
+ else if (dvd_last_chapter + 1 <= demuxer->num_chapters)
+ mkv_d->stop_timecode = demuxer->chapters[dvd_last_chapter].start;
}
}
@@ -2604,7 +2623,7 @@
demuxer->movi_start = s->start_pos;
demuxer->movi_end = s->end_pos;
demuxer->seekable = 1;
- if (mkv_d->chapters && dvd_chapter>1 && dvd_chapter<=mkv_d->num_chapters)
+ if (demuxer->chapters && dvd_chapter>1 && dvd_chapter<=demuxer->num_chapters)
{
if (!mkv_d->has_first_tc)
{
@@ -2612,7 +2631,7 @@
mkv_d->has_first_tc = 1;
}
demux_mkv_seek (demuxer,
- mkv_d->chapters[dvd_chapter-1].start/1000.0, 0.0, 1);
+ demuxer->chapters[dvd_chapter-1].start/1000.0, 0.0, 1);
}
}
@@ -2659,8 +2678,6 @@
free (mkv_d->indexes);
if (mkv_d->cluster_positions)
free (mkv_d->cluster_positions);
- if (mkv_d->chapters)
- free (mkv_d->chapters);
if (mkv_d->parsed_cues)
free (mkv_d->parsed_cues);
if (mkv_d->parsed_seekhead)
Modified: trunk/libmpdemux/demuxer.c
==============================================================================
--- trunk/libmpdemux/demuxer.c (original)
+++ trunk/libmpdemux/demuxer.c Sun Aug 6 20:55:34 2006
@@ -287,6 +287,12 @@
}
if(demuxer->filename)
free(demuxer->filename);
+ if (demuxer->chapters) {
+ for (i=0; i<demuxer->num_chapters; i++)
+ if (demuxer->chapters[i].name)
+ free(demuxer->chapters[i].name);
+ free(demuxer->chapters);
+ }
free(demuxer);
}
@@ -1024,3 +1030,17 @@
index = demuxer->audio->id;
return index;
}
+
+int demuxer_add_chapter(demuxer_t* demuxer, const char* name, uint64_t start, uint64_t end){
+ if (demuxer->chapters == NULL)
+ demuxer->chapters = malloc (32*sizeof(*demuxer->chapters));
+ else if (!(demuxer->num_chapters % 32))
+ demuxer->chapters = realloc (demuxer->chapters, (demuxer->num_chapters + 32) * sizeof(*demuxer->chapters));
+
+ demuxer->chapters[demuxer->num_chapters].start = start;
+ demuxer->chapters[demuxer->num_chapters].end = end;
+ demuxer->chapters[demuxer->num_chapters].name = strdup(name);
+
+ return demuxer->num_chapters ++;
+}
+
Modified: trunk/libmpdemux/demuxer.h
==============================================================================
--- trunk/libmpdemux/demuxer.h (original)
+++ trunk/libmpdemux/demuxer.h Sun Aug 6 20:55:34 2006
@@ -172,6 +172,12 @@
int (*control)(struct demuxer_st *demuxer, int cmd, void *arg); ///< Optional
} demuxer_desc_t;
+typedef struct demux_chapter_s
+{
+ uint64_t start, end;
+ char* name;
+} demux_chapter_t;
+
typedef struct demuxer_st {
demuxer_desc_t *desc; ///< Demuxer description structure
off_t filepos; // input stream current pos.
@@ -192,6 +198,9 @@
void* a_streams[MAX_A_STREAMS]; // audio streams (sh_audio_t)
void* v_streams[MAX_V_STREAMS]; // video sterams (sh_video_t)
char s_streams[32]; // dvd subtitles (flag)
+
+ demux_chapter_t* chapters;
+ int num_chapters;
void* priv; // fileformat-dependent data
char** info;
@@ -370,3 +379,6 @@
extern void demuxer_help(void);
extern int get_demuxer_type_from_name(char *demuxer_name, int *force);
+
+int demuxer_add_chapter(demuxer_t* demuxer, const char* name, uint64_t start, uint64_t end);
+
Modified: trunk/libmpdemux/ebml.h
==============================================================================
--- trunk/libmpdemux/ebml.h (original)
+++ trunk/libmpdemux/ebml.h Sun Aug 6 20:55:34 2006
@@ -128,6 +128,8 @@
#define MATROSKA_ID_CHAPTERATOM 0xB6
#define MATROSKA_ID_CHAPTERTIMESTART 0x91
#define MATROSKA_ID_CHAPTERTIMEEND 0x92
+#define MATROSKA_ID_CHAPTERDISPLAY 0x80
+#define MATROSKA_ID_CHAPSTRING 0x85
/* IDs in the cluster master */
#define MATROSKA_ID_CLUSTERTIMECODE 0xE7
Modified: trunk/mplayer.c
==============================================================================
--- trunk/mplayer.c (original)
+++ trunk/mplayer.c Sun Aug 6 20:55:34 2006
@@ -4807,6 +4807,50 @@
case MP_CMD_KEYDOWN_EVENTS : {
mplayer_put_key(cmd->args[0].v.i);
} break;
+ case MP_CMD_SEEK_CHAPTER : {
+ int seek = cmd->args[0].v.i;
+ int abs = (cmd->nargs > 1) ? cmd->args[1].v.i : 0;
+ int total;
+ int current;
+
+ if (!demuxer->num_chapters || !demuxer->chapters) {
+ if (seek > 0) {
+ abs_seek_pos = 0;
+ rel_seek_secs = 1000000000.;
+ } else
+ set_osd_msg(OSD_MSG_TEXT, 1, osd_duration, MSGTR_OSDChapter, 0, MSGTR_Unknown);
+ break;
+ }
+
+ total = demuxer->num_chapters;
+
+ if (abs) {
+ current = seek;
+ } else {
+ uint64_t now;
+ now = (sh_video ? sh_video->pts : (sh_audio ? sh_audio->pts : 0.)) * 1000 + .5;
+
+ for (current = total - 1; current >= 0; --current) {
+ demux_chapter_t* chapter = demuxer->chapters + current;
+ if (chapter->start <= now)
+ break;
+ }
+ current += seek;
+ }
+
+ if (current < 0) current = 0;
+ if (current >= total) {
+ current = total - 1;
+ abs_seek_pos = 0;
+ rel_seek_secs = 1000000000.;
+ } else {
+ abs_seek_pos = 1;
+ rel_seek_secs = demuxer->chapters[current].start / 1000.;
+ }
+
+ set_osd_msg(OSD_MSG_TEXT, 1, osd_duration, MSGTR_OSDChapter,
+ current, demuxer->chapters[current].name);
+ } break;
default : {
#ifdef HAVE_NEW_GUI
if ( ( use_gui )&&( cmd->id > MP_CMD_GUI_EVENTS ) ) guiGetEvent( guiIEvent,(char *)cmd->id );
More information about the MPlayer-cvslog
mailing list