[MPlayer-dev-eng] Chapter selection via libmenu
Andrew Calkin
andrew.calkin at gmail.com
Mon Dec 10 10:33:46 CET 2007
Hi,
The attached patch does $subj. DVD and mkv files that have chapters
can be navigated via libmenu via seeks to chapter markers using this
patch. Please review.
//Andrew
-------------- next part --------------
diff -Naur MPlayer-r23358.orig/access_mpcontext.h MPlayer-r23358/access_mpcontext.h
--- MPlayer-r23358.orig/access_mpcontext.h 2007-05-25 17:57:54.000000000 +0200
+++ MPlayer-r23358/access_mpcontext.h 2007-05-25 18:05:47.000000000 +0200
@@ -1,4 +1,6 @@
struct MPContext;
+void *mpctx_get_demuxer(struct MPContext *mpctx);
+void *mpctx_get_stream(struct MPContext *mpctx);
void *mpctx_get_video_out(struct MPContext *mpctx);
void *mpctx_get_audio_out(struct MPContext *mpctx);
void *mpctx_get_playtree_iter(struct MPContext *mpctx);
diff -Naur MPlayer-r23358.orig/libmenu/Makefile MPlayer-r23358/libmenu/Makefile
--- MPlayer-r23358.orig/libmenu/Makefile 2007-05-25 17:57:54.000000000 +0200
+++ MPlayer-r23358/libmenu/Makefile 2007-05-25 17:58:31.000000000 +0200
@@ -8,6 +8,7 @@
menu_pt.c \
menu_list.c \
menu_filesel.c \
+ menu_chapsel.c \
menu_txt.c \
menu_console.c \
menu_param.c \
diff -Naur MPlayer-r23358.orig/libmenu/menu.c MPlayer-r23358/libmenu/menu.c
--- MPlayer-r23358.orig/libmenu/menu.c 2007-05-25 17:57:54.000000000 +0200
+++ MPlayer-r23358/libmenu/menu.c 2007-05-25 17:59:03.000000000 +0200
@@ -26,6 +26,7 @@
extern menu_info_t menu_info_cmdlist;
extern menu_info_t menu_info_pt;
extern menu_info_t menu_info_filesel;
+extern menu_info_t menu_info_chapsel;
extern menu_info_t menu_info_txt;
extern menu_info_t menu_info_console;
extern menu_info_t menu_info_pref;
@@ -38,6 +38,7 @@
&menu_info_pt,
&menu_info_cmdlist,
&menu_info_filesel,
+ &menu_info_chapsel,
&menu_info_txt,
&menu_info_console,
#ifdef HAS_DVBIN_SUPPORT
diff -Naur MPlayer-r23358.orig/libmenu/menu_chapsel.c MPlayer-r23358/libmenu/menu_chapsel.c
--- MPlayer-r23358.orig/libmenu/menu_chapsel.c 1970-01-01 01:00:00.000000000 +0100
+++ MPlayer-r23358/libmenu/menu_chapsel.c 2007-05-25 18:09:05.000000000 +0200
@@ -0,0 +1,160 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "config.h"
+
+#include "m_struct.h"
+#include "m_option.h"
+#include "input/input.h"
+
+#include "stream/stream.h"
+#include "stream/stream_dvd.h"
+#include "libmpdemux/demuxer.h"
+#include "access_mpcontext.h"
+
+#include "libmpcodecs/img_format.h"
+#include "libmpcodecs/mp_image.h"
+
+#include "menu.h"
+#include "menu_list.h"
+
+struct list_entry_s {
+ struct list_entry p;
+ int cid;
+};
+
+struct menu_priv_s {
+ menu_list_priv_t p;
+ char* title;
+ int auto_close;
+};
+
+static struct menu_priv_s cfg_dflt = {
+ MENU_LIST_PRIV_DFLT,
+ "Select chapter",
+ 0
+};
+
+#define ST_OFF(m) M_ST_OFF(struct menu_priv_s,m)
+
+static m_option_t cfg_fields[] = {
+ MENU_LIST_PRIV_FIELDS,
+ { "title", ST_OFF (title), CONF_TYPE_STRING, 0, 0, 0, NULL },
+ { "auto-close", ST_OFF (auto_close), CONF_TYPE_FLAG, 0, 0, 1, NULL },
+ { NULL, NULL, NULL, 0, 0, 0, NULL }
+};
+
+static int fill_menu (menu_t* menu)
+{
+ list_entry_t* e;
+ int cid;
+ demuxer_t* demuxer = mpctx_get_demuxer(menu->ctx);
+ stream_t* stream = mpctx_get_stream(menu->ctx);
+
+ if ((stream && stream->type == STREAMTYPE_DVD)
+ || (demuxer && demuxer->type == DEMUXER_TYPE_MATROSKA
+ && demuxer->num_chapters > 0))
+ {
+ menu_list_init (menu);
+
+ if (stream->type == STREAMTYPE_DVD)
+ {
+ dvd_priv_t *dvd_p = (dvd_priv_t *)stream->priv;
+ int dvd_title = dvd_p->cur_title-1;
+ char textbuf[3];
+
+ for (cid = 0;
+ cid < dvd_p->tt_srpt->title[dvd_title].nr_of_ptts;
+ cid++)
+ {
+ if ((e = calloc (1, sizeof (list_entry_t))) != NULL)
+ {
+ sprintf (textbuf, "%d", cid+1);
+ e->p.next = NULL;
+ e->p.txt = strdup (textbuf);
+ e->cid = cid;
+ menu_list_add_entry (menu, e);
+ }
+ }
+ }
+ else if (demuxer->type == DEMUXER_TYPE_MATROSKA)
+ {
+ for (cid = 0; cid < demuxer->num_chapters; cid++)
+ {
+ if ((e = calloc (1, sizeof (list_entry_t))) != NULL)
+ {
+ e->p.next = NULL;
+ e->p.txt = strdup (demuxer->chapters[cid].name);
+ e->cid = cid;
+ menu_list_add_entry (menu, e);
+ }
+ }
+ }
+ }
+ else
+ menu_list_read_cmd (menu, MENU_CMD_CANCEL);
+
+ return 1;
+}
+
+static void read_cmd (menu_t* menu, int cmd)
+{
+ demuxer_t* demuxer = mpctx_get_demuxer (menu->ctx);
+ stream_t* stream = mpctx_get_stream (menu->ctx);
+ int cid = menu->priv->p.current->cid;
+
+ switch (cmd)
+ {
+ case MENU_CMD_RIGHT:
+ case MENU_CMD_OK:
+ if (stream && stream->type == STREAMTYPE_DVD)
+ {
+ dvd_priv_t *dvd_p = (dvd_priv_t *)stream->priv;
+ stream_seek(stream,
+ dvd_p->cur_pgc->cell_playback[cid].first_sector*2048);
+ }
+ else if (demuxer && demuxer->type == DEMUXER_TYPE_MATROSKA)
+ demux_seek(demuxer,
+ demuxer->chapters[cid].start/1000.0,
+ 0,1);
+
+ if (menu->priv->auto_close)
+ mp_input_queue_cmd (mp_input_parse_cmd ("menu hide"));
+ break;
+ default:
+ menu_list_read_cmd (menu, cmd);
+ }
+}
+
+static void close_cs (menu_t* menu)
+{
+ menu_list_uninit (menu, NULL);
+}
+
+static int open_cs (menu_t* menu, char* args)
+{
+ args = NULL;
+
+ menu->draw = menu_list_draw;
+ menu->read_cmd = read_cmd;
+ menu->read_key = menu_dflt_read_key;
+ menu->close = close_cs;
+ menu->priv->p.title = menu->priv->title;
+
+ return fill_menu (menu);
+}
+
+const menu_info_t menu_info_chapsel = {
+ "Chapter selector menu",
+ "chapsel",
+ "Benjamin Zores",
+ "",
+ {
+ "chapsel_cfg",
+ sizeof(struct menu_priv_s),
+ &cfg_dflt,
+ cfg_fields
+ },
+ open_cs
+};
diff -Naur MPlayer-r23358.orig/mplayer.c MPlayer-r23358/mplayer.c
--- MPlayer-r23358.orig/mplayer.c 2007-05-25 17:57:54.000000000 +0200
+++ MPlayer-r23358/mplayer.c 2007-05-25 18:05:08.000000000 +0200
@@ -377,6 +377,16 @@
#define mp_basename2(s) (strrchr(s,'/')==NULL?(char*)s:(strrchr(s,'/')+1))
+void *mpctx_get_demuxer(MPContext *mpctx)
+{
+ return mpctx->demuxer;
+}
+
+void *mpctx_get_stream(MPContext *mpctx)
+{
+ return mpctx->stream;
+}
+
void *mpctx_get_video_out(MPContext *mpctx)
{
return mpctx->video_out;
More information about the MPlayer-dev-eng
mailing list