[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