Index: DOCS/tech/slave.txt =================================================================== --- DOCS/tech/slave.txt (revision 25332) +++ DOCS/tech/slave.txt (working copy) @@ -241,6 +241,11 @@ 0 is a relative seek of +/- chapters (default). 1 is a seek to chapter . +chapter [N] + Seek to specific chapter. Here [N] is an integer. + If [N] is 0, will seek forward to next chapter (default). + If [N] larger than 0, seek to the [N]th chapter. + set_mouse_pos Tells MPlayer the coordinates of the mouse in the window. This command doesn't move the mouse! @@ -455,6 +460,7 @@ stream_start pos 0 X start pos in stream stream_end pos 0 X end pos in stream stream_length pos 0 X (end - start) +chapter int 0 X X X select chapter length time X length of file in seconds percent_pos int 0 100 X X X position in percent time_pos time 0 X X X position in seconds Index: command.c =================================================================== --- command.c (revision 25332) +++ command.c (working copy) @@ -369,6 +369,95 @@ mpctx->audio_out)); } +/// Current chapter (RW) +static int mp_property_chapter(m_option_t * prop, int action, void *arg, + MPContext * mpctx) +{ + int chapter; + float next_pts = 0; + int chapter_num; + int step_all; + char *chapter_name; + + switch (action) { + case M_PROPERTY_GET: + if (!arg) + return M_PROPERTY_ERROR; + *(int *) arg = demuxer_get_current_chapter(mpctx->demuxer); + return M_PROPERTY_OK; + case M_PROPERTY_PRINT: { + if (!arg) + return M_PROPERTY_ERROR; + *(char **) arg = malloc(64); + (*(char **) arg)[63] = 0; + + chapter = demuxer_get_current_chapter(mpctx->demuxer); + if (chapter < 0) + snprintf(*(char **) arg, 63, "(%d) %s", chapter+1, MSGTR_Unknown); + else { + chapter_name = demuxer_chapter_name(mpctx->demuxer, chapter); + if (chapter_name) { + snprintf(*(char **) arg, 63, "(%d) %s", chapter+1,chapter_name); + free(chapter_name); + } + else { + char tmp[16]; + chapter_num = demuxer_chapter_count(mpctx->demuxer); + if (chapter_num <= 0) + tmp[0] = '\0'; + else + sprintf(tmp, " of %3d", chapter_num); + snprintf(*(char **) arg, 63, "(%d) %s", chapter + 1, tmp); + } + } + return M_PROPERTY_OK; + } + case M_PROPERTY_SET: + if (!arg) + return M_PROPERTY_ERROR; + M_PROPERTY_CLAMP(prop, *(int*)arg); + chapter = demuxer_get_current_chapter(mpctx->demuxer); + if (chapter < 0) + return M_PROPERTY_UNAVAILABLE; + step_all = *(int *)arg - (chapter + 1); + chapter += step_all; + break; + case M_PROPERTY_STEP_UP: + case M_PROPERTY_STEP_DOWN: { + step_all = (arg && *(int*)arg != 0 ? *(int*)arg : 1) + * (action == M_PROPERTY_STEP_UP ? 1 : -1); + chapter = demuxer_get_current_chapter(mpctx->demuxer); + if (chapter < 0) + return M_PROPERTY_UNAVAILABLE; + chapter += step_all; + if (chapter < 0) + chapter = 0; + break; + } + default: + return M_PROPERTY_NOT_IMPLEMENTED; + } + rel_seek_secs = 0; + abs_seek_pos = 0; + chapter = demuxer_seek_chapter(mpctx->demuxer, chapter, 1, + &next_pts, &chapter_num, &chapter_name); + if (chapter >= 0) { + if (next_pts > -1.0) { + abs_seek_pos = 1; + rel_seek_secs = next_pts; + } + if (chapter_name) + set_osd_msg(OSD_MSG_TEXT, 1, osd_duration, + MSGTR_OSDChapter, chapter + 1, chapter_name); + } + else if (step_all > 0) + rel_seek_secs = 1000000000.; + else + set_osd_msg(OSD_MSG_TEXT, 1, osd_duration, + MSGTR_OSDChapter, 0, MSGTR_Unknown); + return M_PROPERTY_OK; +} + /// Demuxer meta data static int mp_property_metadata(m_option_t * prop, int action, void *arg, MPContext * mpctx) { @@ -1809,6 +1898,8 @@ M_OPT_RANGE, 0, 100, NULL }, { "time_pos", mp_property_time_pos, CONF_TYPE_TIME, M_OPT_MIN, 0, 0, NULL }, + { "chapter", mp_property_chapter, CONF_TYPE_INT, + M_OPT_MIN, 1, 0, NULL }, { "metadata", mp_property_metadata, CONF_TYPE_STRING_LIST, 0, 0, 0, NULL }, @@ -1998,6 +2089,7 @@ } set_prop_cmd[] = { // general { "loop", MP_CMD_LOOP, 0, 0, -1, MSGTR_LoopStatus }, + { "chapter", MP_CMD_CHAPTER, 1, 0, -1, NULL }, // audio { "volume", MP_CMD_VOLUME, 0, OSD_VOLUME, -1, MSGTR_Volume }, { "mute", MP_CMD_MUTE, 1, 0, -1, MSGTR_MuteStatus }, @@ -2905,34 +2997,8 @@ case MP_CMD_SEEK_CHAPTER:{ int seek = cmd->args[0].v.i; int abs = (cmd->nargs > 1) ? cmd->args[1].v.i : 0; - int chap; - float next_pts = 0; - int num_chapters; - char *chapter_name; - - rel_seek_secs = 0; - abs_seek_pos = 0; - chap = - demuxer_seek_chapter(mpctx->demuxer, seek, abs, - &next_pts, &num_chapters, - &chapter_name); - if (chap != -1) { - if (next_pts > -1.0) { - abs_seek_pos = 1; - rel_seek_secs = next_pts; - } - if (chapter_name) { - set_osd_msg(OSD_MSG_TEXT, 1, osd_duration, - MSGTR_OSDChapter, chap + 1, chapter_name); - free(chapter_name); - } - } else { - if (seek > 0) - rel_seek_secs = 1000000000.; - else - set_osd_msg(OSD_MSG_TEXT, 1, osd_duration, - MSGTR_OSDChapter, 0, MSGTR_Unknown); - } + mp_property_do("chapter", abs?M_PROPERTY_SET:M_PROPERTY_STEP_UP, + &seek, mpctx); break; } break; Index: input/input.c =================================================================== --- input/input.c (revision 25332) +++ input/input.c (working copy) @@ -184,6 +184,7 @@ { MP_CMD_STEP_PROPERTY, "step_property", 1, { {MP_CMD_ARG_STRING, {0}}, {MP_CMD_ARG_FLOAT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } }, { MP_CMD_SEEK_CHAPTER, "seek_chapter", 1, { {MP_CMD_ARG_INT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } }, + { MP_CMD_CHAPTER, "chapter", 0, { { MP_CMD_ARG_INT,{-1} }, {-1,{0}} } }, { MP_CMD_SET_MOUSE_POS, "set_mouse_pos", 2, { {MP_CMD_ARG_INT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } }, { 0, NULL, 0, {} } Index: input/input.h =================================================================== --- input/input.h (revision 25332) +++ input/input.h (working copy) @@ -103,6 +103,7 @@ #define MP_CMD_SUB_FILE 102 #define MP_CMD_SUB_VOB 103 #define MP_CMD_SUB_DEMUX 104 +#define MP_CMD_CHAPTER 105 #define MP_CMD_GUI_EVENTS 5000 #define MP_CMD_GUI_LOADFILE 5001