--- Makefile	2006-01-27 01:06:37.000000000 +0100
+++ Makefile	2006-02-10 00:01:16.000000000 +0100
@@ -132,6 +132,10 @@
               $(FONTCONFIG_LIB) \
               $(ENCA_LIB) \
 
+ifeq ($(LIBMPDVDNAV),yes)
+COMMON_LIBS += libmpdvdnav/libmpdvdnav.a
+endif
+
 CFLAGS = $(OPTFLAGS) -I. \
          $(CACA_INC) \
          $(CDPARANOIA_INC) \
@@ -210,6 +214,9 @@
 ifeq ($(TREMOR),yes)
 PARTS += tremor
 endif
+ifeq ($(LIBMPDVDNAV),yes)
+PARTS += libmpdvdnav
+endif
 
 ALL_PRG = $(PRG)
 ifeq ($(MENCODER),yes)
@@ -261,6 +268,9 @@
 COMMON_DEPS += libmpdvdkit2/libmpdvdkit.a
 endif
 endif
+ifeq ($(LIBMPDVDNAV),yes)
+COMMON_DEPS += libmpdvdnav/libmpdvdnav.a
+endif
 
 ifeq ($(GUI),yes)
 COMMON_DEPS += Gui/libgui.a
@@ -282,6 +292,9 @@
 libmpdvdkit2/libmpdvdkit.a:
 	$(MAKE) -C libmpdvdkit2
 
+libmpdvdnav/libmpdvdnav.a:
+	$(MAKE) -C libmpdvdnav
+
 libmpdvdkit2/libmpdvdkit.so:
 	$(MAKE) -C libmpdvdkit2 libmpdvdkit.so
 
--- mplayer.c	2006-02-09 20:39:50.000000000 +0100
+++ mplayer.c	2006-02-11 19:27:56.000000000 +0100
@@ -63,8 +63,18 @@
 #include "codec-cfg.h"
 
 #ifdef USE_DVDNAV
+#ifdef USE_MPDVDNAV
+#include <libmpdemux/stream_dvdnav.h>
+
+int dvdnav_wait = 0;
+int dvdnav_still = 0;
+int dvdnav_reopen = 0;
+int dvdnav_decodeok = 0;
+int dvdnav_seek_counter = 0;
+#else
 #include <dvdnav.h>
 #endif
+#endif
 
 #ifdef USE_EDL
 #include "edl.h"
@@ -185,6 +195,9 @@
 
 #include "libmpcodecs/dec_audio.h"
 #include "libmpcodecs/dec_video.h"
+#ifdef USE_MPDVDNAV
+#include "libmpcodecs/vd_videostill.h"
+#endif
 #include "libmpcodecs/mp_image.h"
 #include "libmpcodecs/vf.h"
 #include "libmpcodecs/vd.h"
@@ -1763,6 +1776,9 @@
     }
 #endif /* HAVE_NEW_GUI */
 
+#ifdef USE_MPDVDNAV
+//  if(!dvdnav_continue_play)
+#endif
 while (player_idle_mode && !filename) {
     play_tree_t * entry = NULL;
     mp_cmd_t * cmd;
@@ -1872,6 +1888,9 @@
 
 //============ Open & Sync STREAM --- fork cache2 ====================
 
+#ifdef USE_MPDVDNAV
+  if(!dvdnav_continue_play)
+#endif
   stream=NULL;
   demuxer=NULL;
   if (d_audio) {
@@ -1886,7 +1905,13 @@
   sh_video=NULL;
 
   current_module="open_stream";
+#ifdef USE_MPDVDNAV
+  if(!dvdnav_continue_play || !stream) stream=open_stream(filename,0,&file_format);
+  dvdnav_reopen=dvdnav_continue_play;
+  dvdnav_continue_play=0;
+#else
   stream=open_stream(filename,0,&file_format);
+#endif
   if(!stream) { // error...
     eof = libmpdemux_was_interrupted(PT_NEXT_ENTRY);
     goto goto_next_file;
@@ -1956,6 +1981,16 @@
 
 #ifdef USE_DVDNAV
   if (stream->type==STREAMTYPE_DVDNAV) stream_cache_size=0;	// must disable caching...
+#ifdef USE_MPDVDNAV
+if(stream->type==STREAMTYPE_DVDNAV){
+  current_module="dvd lang->id";
+  if(audio_id==-1) audio_id=dvd_aid_from_lang(stream,audio_lang);
+  if(dvdsub_lang && dvdsub_id==-1) dvdsub_id=dvd_sid_from_lang(stream,dvdsub_lang);
+  global_sub_indices[SUB_SOURCE_DEMUX] = global_sub_size; // the global # of the first demux-specific sub.
+  global_sub_size += dvdnav_number_of_subs((dvdnav_priv_t*)(stream->priv));
+  current_module=NULL;
+}
+#endif
 #endif
 
 // CACHE2: initial prefill: 20%  later: 5%  (should be set by -cacheopts)
@@ -1973,7 +2008,20 @@
 //============ Open DEMUXERS --- DETECT file type =======================
 current_module="demux_open";
 
-demuxer=demux_open(stream,file_format,audio_id,video_id,dvdsub_id,filename);
+#ifdef USE_MPDVDNAV
+if (stream->type==STREAMTYPE_DVDNAV) {
+    if (dvdnav_isevent_lock((dvdnav_priv_t*)(stream->priv)))
+	demuxer=demux_open(stream,file_format,audio_id,video_id,dvdsub_id,filename,0,128,1);
+	else
+	demuxer=demux_open(stream,file_format,audio_id,video_id,dvdsub_id,filename,0,0,1);
+	}	
+    else
+#endif
+    demuxer=demux_open(stream,file_format,audio_id,video_id,dvdsub_id,filename,0,0,0);
+#ifdef USE_MPDVDNAV
+if (demuxer && stream->type==STREAMTYPE_DVDNAV)
+    demuxer_set_max_packet( demuxer, 0 , 0 , 1 );	// restore max packs & hide err mess
+#endif
 
 // HACK to get MOV Reference Files working
 
@@ -2187,6 +2235,9 @@
 //================== Read SUBTITLES (DVD & TEXT) ==========================
 if(vo_spudec==NULL && sh_video &&
      (stream->type==STREAMTYPE_DVD || demuxer->type==DEMUXER_TYPE_MATROSKA ||
+#ifdef USE_MPDVDNAV
+	stream->type==STREAMTYPE_DVDNAV ||
+#endif
       d_dvdsub->id >= 0)){
 
 if (spudec_ifo) {
@@ -2202,6 +2253,7 @@
   vo_spudec=spudec_new_scaled(dvdnav_stream_get_palette((dvdnav_priv_t*)(stream->priv)),
 			    sh_video->disp_w, sh_video->disp_h);
 }
+if (dvdsub_id>=0 && stream->type==STREAMTYPE_DVDNAV) dvdnav_go_spu=2;
 #endif
 
 #ifdef USE_DVDREAD
@@ -2344,7 +2396,11 @@
 if(!sh_video) goto main; // audio-only
 
 //================== Init VIDEO (codec & libvo) ==========================
+#ifdef USE_MPDVDNAV
 if(!fixed_vo || !(inited_flags&INITED_VO)){
+#else
+if(!(fixed_vo || (dvdnav_continue_play && dvdnav_fixed_vo)) || !(inited_flags&INITED_VO)){
+#endif
 current_module="preinit_libvo";
 
 vo_config_count=0;
@@ -2560,6 +2616,11 @@
 #ifdef USE_DVDNAV
 if (stream->type==STREAMTYPE_DVDNAV) {
   dvdnav_stream_fullstart((dvdnav_priv_t *)stream->priv);
+#ifdef USE_MPDVDNAV
+  dvdnav_set_language((dvdnav_priv_t *)stream->priv, dvdsub_lang, audio_lang, NULL);
+  dvdnav_event_lock((dvdnav_priv_t *)stream->priv,0);	/* unlock */
+  clearsmpi(); /* clear correct still image */
+#endif
 }
 #endif
 
@@ -2653,8 +2714,16 @@
 	int in_size;
 	// get it!
 	current_module="video_read_frame";
+#ifdef USE_MPDVDNAV
+        in_size=video_read_frame(sh_video,&next_frame_time,&start,force_fps);
+	if (stream->type==STREAMTYPE_DVDNAV) { if (dvdnav_reallyeof((dvdnav_priv_t*)(stream->priv))) {eof=1; break;}
+	  if (in_size<0) {sh_video->num_frames++; sh_video->num_frames_decoded++; sh_video->pts+=next_frame_time;}
+	  sh_video->config_lock=1;
+	  } else {if(in_size<0) {eof=1; break;}}
+#else
         in_size=video_read_frame(sh_video,&next_frame_time,&start,force_fps);
 	if(in_size<0){ eof=1; break; }
+#endif
 	if(in_size>max_framesize) max_framesize=in_size; // stats
 	sh_video->timer+=frame_time;
 	if(sh_audio) sh_audio->delay-=frame_time;
@@ -2683,6 +2752,17 @@
 	// decode:
 	current_module="decode_video";
 //	printf("Decode! %p  %d  \n",start,in_size);
+#ifdef USE_MPDVDNAV
+	if (stream->type==STREAMTYPE_DVDNAV)
+	    {
+	    dvdnav_decodeok=0;
+	    blit_frame=decode_video_still(sh_video,start,in_size,drop_frame,1);
+//printf("decode_video_still: blit_frame: %i <<<<<<<<--------------------\n",blit_frame);
+	    if (blit_frame && in_size<0 && sh_video && sh_audio) sh_video->pts=d_video->pts=d_audio->pts;
+	    if (blit_frame && in_size>0) dvdnav_decodeok=1;
+	    }
+	    else
+#endif
 	blit_frame=decode_video(sh_video,start,in_size,drop_frame);
 	break;
     }
@@ -2697,6 +2777,8 @@
     }
 
   }
+//if (stream->type==STREAMTYPE_DVDNAV && d_video->eof || d_audio->eof) {d_video->eof=0; d_audio->eof=0; stream->eof=0;}
+//printf("decode frame... %5.3f ****\n",frame_time);
 
 // ==========================================================================
     
@@ -3065,9 +3147,11 @@
 }
 
 #ifdef USE_DVDNAV
+#ifndef USE_MPDVDNAV
 if (stream->type==STREAMTYPE_DVDNAV && dvd_nav_still)
     dvdnav_stream_sleeping((dvdnav_priv_t*)stream->priv);
 #endif
+#endif
 
 //================= EDL =========================================
 
@@ -3097,6 +3181,329 @@
  }
 #endif
 
+#ifdef USE_MPDVDNAV
+current_module="dvdnav_event";
+if (stream->type==STREAMTYPE_DVDNAV) {
+if (((dvdnav_priv_t*)(stream->priv))->event.eventflag.stop) { 
+  eof=1; 
+  mp_msg(MSGT_CPLAYER,MSGL_ERR,MSGTR_MPDVDNAV_StopEvent); } 
+  else {
+int nav_demux_seek = 0;
+int nav_new_demux = 0;
+int nav_menu = 0;
+if (dvdnav_reopen)
+  {
+	switch (((dvdnav_priv_t*)(stream->priv))->aspect) {	/* set current ascpet */
+    	    case 0 : { // 4:3
+#ifdef USE_MPDVDNAV_TRACE
+	    if (dvdnav_trace) mp_msg(MSGT_CPLAYER,MSGL_INFO, "dvdnav: set aspect 4:3\n");
+#endif
+    		movie_aspect = (float) 4 / 3;
+    		mpcodecs_config_vo (sh_video, sh_video->disp_w, sh_video->disp_h, 0);
+    		break; }
+    	    case 3 :   // FIXME: 16:9???
+    	    case 2 : { // 16:9
+#ifdef USE_MPDVDNAV_TRACE
+	    if (dvdnav_trace) mp_msg(MSGT_CPLAYER,MSGL_INFO, "dvdnav: set aspect 16:9\n");
+#endif
+    		movie_aspect = (float) 16 / 9;
+    		mpcodecs_config_vo (sh_video, sh_video->disp_w, sh_video->disp_h, 0);
+    		break; } 
+	    default: {
+#ifdef USE_MPDVDNAV_TRACE
+	    if (dvdnav_trace) mp_msg(MSGT_CPLAYER,MSGL_INFO, "dvdnav: unknow aspect %i\n",((dvdnav_priv_t*)(stream->priv))->aspect);
+#endif
+		break; }}
+  dvdnav_reopen=0;
+  }
+if (((dvdnav_priv_t*)(stream->priv))->event.eventflag.wait)
+    {
+    mp_msg(MSGT_CPLAYER,MSGL_V,MSGTR_MPDVDNAV_WaitEvent);
+    }
+if (((dvdnav_priv_t*)(stream->priv))->event.eventflag.still_frame)
+    {
+    mp_msg(MSGT_CPLAYER,MSGL_V,MSGTR_MPDVDNAV_StillFrameEvent);
+    ds_free_packs(demuxer->audio);
+    ds_free_packs(demuxer->video);
+    if (dvdnav_decodeok) nav_demux_seek=1;
+    dvdnav_still=1;				// still mode on
+    }
+if (((dvdnav_priv_t*)(stream->priv))->event.eventflag.vts_change)
+    {
+    mp_msg(MSGT_CPLAYER,MSGL_V,MSGTR_MPDVDNAV_VtsChangeEvent);
+
+    sh_video->config_lock=0;
+    if (((dvdnav_priv_t*)(stream->priv))->aspect!=((dvdnav_priv_t*)(stream->priv))->lastaspect)
+      {
+	switch (((dvdnav_priv_t*)(stream->priv))->aspect) {	/* set current ascpet */
+    	    case 0 : { // 4:3
+#ifdef USE_MPDVDNAV_TRACE
+	    if (dvdnav_trace) mp_msg(MSGT_CPLAYER,MSGL_INFO, "dvdnav: set aspect 4:3\n");
+#endif
+    		movie_aspect = (float) 4 / 3;
+    		mpcodecs_config_vo (sh_video, sh_video->disp_w, sh_video->disp_h, 0);
+    		break; }
+    	    case 3 :   // FIXME: 16:9???
+    	    case 2 : { // 16:9
+#ifdef USE_MPDVDNAV_TRACE
+	    if (dvdnav_trace) mp_msg(MSGT_CPLAYER,MSGL_INFO, "dvdnav: set aspect 16:9\n");
+#endif
+    		movie_aspect = (float) 16 / 9;
+    		mpcodecs_config_vo (sh_video, sh_video->disp_w, sh_video->disp_h, 0);
+    		break; } 
+	    default: {
+#ifdef USE_MPDVDNAV_TRACE
+	    if (dvdnav_trace) mp_msg(MSGT_CPLAYER,MSGL_INFO, "dvdnav: unknow aspect %i\n",((dvdnav_priv_t*)(stream->priv))->aspect);
+#endif
+		break; }}
+	((dvdnav_priv_t*)(stream->priv))->lastaspect=((dvdnav_priv_t*)(stream->priv))->aspect;
+	}
+    if (((dvdnav_priv_t*)(stream->priv))->old_vts_domain==-1) 
+	((dvdnav_priv_t*)(stream->priv))->old_vts_domain=((dvdnav_priv_t*)(stream->priv))->vts_domain;
+    if (((dvdnav_priv_t*)(stream->priv))->title!=((dvdnav_priv_t*)(stream->priv))->lasttitle || 
+	    ((dvdnav_priv_t*)(stream->priv))->vts_domain!=((dvdnav_priv_t*)(stream->priv))->old_vts_domain || !sh_audio)
+	{
+// enter to vts domain (no cell change)
+	// store current event
+	((dvdnav_priv_t*)(stream->priv))->event.eventflag.vts_change=0;	// clear vts change event
+	if (((dvdnav_priv_t*)(stream->priv))->vts_domain) {
+        audio_id=((dvdnav_priv_t*)(stream->priv))->alang;		// set new audio id
+        dvdsub_id=((dvdnav_priv_t*)(stream->priv))->slang;	// set new sub id
+	  nav_new_demux=1;
+	  demuxer_update_time_length(demuxer, stream->start_pos, stream->end_pos);
+	  } else {
+// return from vts domain (no cell change)
+	  dvdnav_event_lock(((dvdnav_priv_t*)(stream->priv)),0);
+	  if (stream->end_pos>0) {
+	    stream->start_pos=0;
+	    stream->end_pos=0; 
+	    demuxer->movi_end=0;
+	    demuxer_update_time_length(demuxer, stream->start_pos, stream->end_pos);
+	    nav_demux_seek=1;
+	    if (dvdnav_real_still) dvdnav_seek_counter=2;
+	    dvdnav_seek_counter=2;
+	    } else  {
+	    demuxer_update_time_length(demuxer, stream->start_pos, stream->end_pos);
+	    nav_new_demux=1;
+	    }
+	  }
+	}
+	else
+	{
+	nav_demux_seek=1;
+	dvdnav_seek_counter=2;
+	demuxer_update_time_length(demuxer, stream->start_pos, stream->end_pos);
+	if (((dvdnav_priv_t*)(stream->priv))->event.eventflag.wait) dvdnav_still=0;	// still mode off
+	dvdnav_wait=!((dvdnav_priv_t*)(stream->priv))->event.eventflag.wait;
+	}
+    }
+if (((dvdnav_priv_t*)(stream->priv))->event.eventflag.cell_change && !((dvdnav_priv_t*)(stream->priv))->event.eventflag.still_frame && !((dvdnav_priv_t*)(stream->priv))->event.eventflag.vts_change)
+    {
+    mp_msg(MSGT_CPLAYER,MSGL_V,MSGTR_MPDVDNAV_CellChangeEvent);
+    sh_video->config_lock=0;
+    if (((dvdnav_priv_t*)(stream->priv))->aspect!=((dvdnav_priv_t*)(stream->priv))->lastaspect)
+      {
+	switch (((dvdnav_priv_t*)(stream->priv))->aspect) {	/* set current ascpet */
+    	    case 0 : { // 4:3
+#ifdef USE_MPDVDNAV_TRACE
+	    if (dvdnav_trace) mp_msg(MSGT_CPLAYER,MSGL_INFO, "dvdnav: set aspect 4:3\n");
+#endif
+    		movie_aspect = (float) 4 / 3;
+    		mpcodecs_config_vo (sh_video, sh_video->disp_w, sh_video->disp_h, 0);
+    		break; }
+    	    case 3 :   // FIXME: 16:9???
+    	    case 2 : { // 16:9
+#ifdef USE_MPDVDNAV_TRACE
+	    if (dvdnav_trace) mp_msg(MSGT_CPLAYER,MSGL_INFO, "dvdnav: set aspect 16:9\n");
+#endif
+    		movie_aspect = (float) 16 / 9;
+    		mpcodecs_config_vo (sh_video, sh_video->disp_w, sh_video->disp_h, 0);
+    		break; } 
+	    default: {
+#ifdef USE_MPDVDNAV_TRACE
+	    if (dvdnav_trace) mp_msg(MSGT_CPLAYER,MSGL_INFO, "dvdnav: unknow aspect %i\n",((dvdnav_priv_t*)(stream->priv))->aspect);
+#endif
+		break; }}
+	((dvdnav_priv_t*)(stream->priv))->lastaspect=((dvdnav_priv_t*)(stream->priv))->aspect;
+	}
+    if (((dvdnav_priv_t*)(stream->priv))->lasttitle==-1) 
+	((dvdnav_priv_t*)(stream->priv))->lasttitle=((dvdnav_priv_t*)(stream->priv))->title;
+    if (((dvdnav_priv_t*)(stream->priv))->title!=((dvdnav_priv_t*)(stream->priv))->lasttitle || !sh_audio)
+	{
+	// store current event
+	if (((dvdnav_priv_t*)(stream->priv))->event.cell_really_change || dvdnav_seek_counter)
+	  {
+          audio_id=((dvdnav_priv_t*)(stream->priv))->alang;		// set new audio id
+          dvdsub_id=((dvdnav_priv_t*)(stream->priv))->slang;	// set new sub id
+	  dvdnav_set_language((dvdnav_priv_t *)stream->priv, dvdsub_lang, audio_lang, NULL);	/* FIXME: it's don't work!!! */
+	  nav_new_demux=1;
+	  }
+	} else {
+	if ((!((dvdnav_priv_t*)(stream->priv))->event.eventflag.wait || dvdnav_still || dvdnav_wait || dvdnav_seek_counter ||
+	((dvdnav_priv_t*)(stream->priv))->event.cell_really_change)) {
+	    if (((dvdnav_priv_t*)(stream->priv))->event.eventflag.wait) dvdnav_still=0;	// still mode off
+	    dvdnav_wait=!((dvdnav_priv_t*)(stream->priv))->event.eventflag.wait;
+	    nav_demux_seek=1;
+	    }
+	}
+    ((dvdnav_priv_t*)(stream->priv))->lasttitle=((dvdnav_priv_t*)(stream->priv))->title;
+    ((dvdnav_priv_t*)(stream->priv))->lastpart=((dvdnav_priv_t*)(stream->priv))->part;
+    ((dvdnav_priv_t*)(stream->priv))->old_vts_domain=((dvdnav_priv_t*)(stream->priv))->vts_domain;
+    if (!((dvdnav_priv_t*)(stream->priv))->vts_domain && ((dvdnav_priv_t*)(stream->priv))->back_from_timer) nav_demux_seek=1;
+    ((dvdnav_priv_t*)(stream->priv))->back_from_timer=0;
+    nav_menu=1;
+    }
+
+if (((dvdnav_priv_t*)(stream->priv))->event.eventflag.spu_clut_change)
+    {
+    mp_msg(MSGT_CPLAYER,MSGL_V,MSGTR_MPDVDNAV_SpuClutChangeEvent);
+    if (vo_spudec) {
+	spudec_update_palette(vo_spudec, ((dvdnav_priv_t*)(stream->priv))->event.spu_clut);
+	if(!((dvdnav_priv_t*)(stream->priv))->vts_domain && (dvdnav_menutype==DVDNAV_MENUTYPE_SPU || dvdnav_menutype==DVDNAV_MENUTYPE_SPU_BOX)) {
+	    spudec_dvdnav_palette(vo_spudec,((dvdnav_priv_t*)(stream->priv))->event.spu_palette); 
+    	    vo_osd_changed(OSDTYPE_SPU); }
+       if (((dvdnav_priv_t*)(stream->priv))->vts_domain) spudec_reset(vo_spudec);
+	}
+    nav_menu=1;
+    }
+if (((dvdnav_priv_t*)(stream->priv))->event.eventflag.highlight)
+    {
+    mp_msg(MSGT_CPLAYER,MSGL_V,MSGTR_MPDVDNAV_HighlightEvent);
+// dvdnav menu button update
+    nav_menu=1;
+    }
+if (((dvdnav_priv_t*)(stream->priv))->event.eventflag.nav_packet)
+    {
+    mp_msg(MSGT_CPLAYER,MSGL_DBG2,MSGTR_MPDVDNAV_NavPacketEvent);
+    if (!(((dvdnav_priv_t*)(stream->priv))->vts_domain)) nav_menu=1;
+    }
+
+((dvdnav_priv_t*)(stream->priv))->lasttitle=((dvdnav_priv_t*)(stream->priv))->title;
+((dvdnav_priv_t*)(stream->priv))->lastpart=((dvdnav_priv_t*)(stream->priv))->part;
+((dvdnav_priv_t*)(stream->priv))->old_vts_domain=((dvdnav_priv_t*)(stream->priv))->vts_domain;
+d_video->eof=0;
+d_audio->eof=0;
+stream->eof=0;
+demuxer->stream->eof=0;
+demuxer->audio->eof=0;
+demuxer->video->eof=0;
+
+// dvdnav event clear
+dvdnav_event_clear((dvdnav_priv_t*)(stream->priv));
+
+if (nav_new_demux)
+    {
+    if (((dvdnav_priv_t*)(stream->priv))->vts_domain) {
+	  dvdnav_event_lock(((dvdnav_priv_t*)(stream->priv)),1);	/* lock event while get stream time length */
+	  spudec_dvdnav_mode(vo_spudec, 0);	/* spu menu button off */
+	  dvdnav_box_area(0,0,0,0,0);	/* nav box button off */
+	  vo_osd_changed(OSDTYPE_DVDNAV); 
+	  stream->start_pos=(((dvdnav_priv_t*)(stream->priv))->tpos)*2048;	/* set stream size */
+	  stream->end_pos=(((dvdnav_priv_t*)(stream->priv))->tpos+((dvdnav_priv_t*)(stream->priv))->tlen)*2048;
+	  } else {
+	  dvdnav_event_lock(((dvdnav_priv_t*)(stream->priv)),0);
+	  spudec_dvdnav_mode(vo_spudec, 1);	/* spu menu button on */
+	  stream->start_pos=0;	/* clear stream size */
+	  stream->end_pos=0; }
+    dvdnav_continue_play=1;					// close&open demuxer, video_sh, etc. and no close dvdnav stream!
+    goto goto_next_file;
+    }
+if (nav_menu)
+    {
+    if (!(((dvdnav_priv_t*)(stream->priv))->vts_domain)) {
+// vts0 - set menu button
+	dvdnav_highlight_event_t highlight;
+	dvdnav_get_highlight((dvdnav_priv_t*)(stream->priv),&highlight);	/* get spu botton area & palette */
+	if (vo_spudec && (dvdnav_menutype==DVDNAV_MENUTYPE_SPU || dvdnav_menutype==DVDNAV_MENUTYPE_SPU_BOX)) {
+	    if(d_dvdsub->id!=0) {d_dvdsub->id=0; spudec_reset(vo_spudec);}
+	    spudec_dvdnav_mode(vo_spudec, 1);	/* spu menu button on */
+	    spudec_dvdnav_area(vo_spudec,highlight.sx,highlight.sy,highlight.ex,highlight.ey,highlight.palette); /* set spu button area & palette */
+	    vo_osd_changed(OSDTYPE_SPU); }
+	if (dvdnav_menutype==DVDNAV_MENUTYPE_BOX || dvdnav_menutype==DVDNAV_MENUTYPE_SPU_BOX) {
+	    dvdnav_box_area(highlight.sx,highlight.sy,highlight.ex,highlight.ey,1); /* set box button area & on */
+	    vo_osd_changed(OSDTYPE_DVDNAV); }
+	} else {
+// reset spu info
+        global_sub_size = 0;
+        { int i; for (i = 0; i < SUB_SOURCES; i++) global_sub_indices[i] = -1; }
+        global_sub_quiet_osd_hack = 1;
+        global_sub_indices[SUB_SOURCE_DEMUX] = global_sub_size; // the global # of the first demux-specific sub.
+        global_sub_size += dvdnav_number_of_subs((dvdnav_priv_t*)(stream->priv));
+        if (dvdnav_menutype==DVDNAV_MENUTYPE_BOX || dvdnav_menutype==DVDNAV_MENUTYPE_SPU_BOX) {
+	    dvdnav_box_area(0,0,0,0,0);	/* nav box button off */
+	    vo_osd_changed(OSDTYPE_DVDNAV); }
+	spudec_dvdnav_mode(vo_spudec, 0);	/* spu menu button off */
+	spudec_reset(vo_spudec);
+	}
+    }
+if (nav_demux_seek && (!((dvdnav_priv_t*)(stream->priv))->stillok || !dvdnav_still))
+    {
+    if (dvdnav_seek_counter) dvdnav_seek_counter--;
+    if (sh_audio) {
+    audio_id=((dvdnav_priv_t*)(stream->priv))->alang;
+    int v = demuxer_switch_audio(demuxer, audio_id);} // switch audio channel
+//	if(sh_video) sh_video->pts=d_video->pts;
+//    ds_free_packs(demuxer->video);
+    rel_seek_secs = 0.00;
+    abs_seek_pos = 0;
+    if(demux_seek(demuxer,rel_seek_secs,abs_seek_pos)){	// demuxer reset???
+	rel_seek_secs = 0.00;
+        abs_seek_pos = 0;
+    	if(sh_video){
+    	    current_module="seek_video_reset";
+    	    resync_video_stream(sh_video);
+    	if(vo_config_count) video_out->control(VOCTRL_RESET,NULL); }
+    	if(sh_audio){
+    	    current_module="seek_audio_reset";
+    	    audio_out->reset(); } // stop audio, throwing away buffered data
+    	if(vo_spudec) spudec_reset(vo_spudec); } 
+    }
+#ifdef HAVE_NEW_GUI
+if (!(((dvdnav_priv_t*)(stream->priv))->vts_domain))
+    {
+    dvdnav_window_orig_width=sh_video->disp_w;		/* set original video window size */
+    dvdnav_window_orig_height=sh_video->disp_h;		/* required on calculate mouse position */
+    dvdnav_mouse((dvdnav_priv_t*)(stream->priv));	/* process mouse positon: set menu button */
+    }
+#endif
+// play to new title
+if (dvdnav_go_title>0)
+    {
+    dvdnav_title_play((dvdnav_t*)((dvdnav_priv_t*)(stream->priv))->dvdnav, dvdnav_go_title);
+    dvdnav_go_title=dvdnav_go_part=dvdnav_go_menu=dvdnav_go_audio=dvdnav_go_spu=0;
+    }
+// play to new chapter
+if (dvdnav_go_part>0)
+    {
+    dvdnav_part_play((dvdnav_t*)((dvdnav_priv_t*)(stream->priv))->dvdnav, ((dvdnav_priv_t*)(stream->priv))->title, dvdnav_go_part);
+    dvdnav_go_title=dvdnav_go_part=dvdnav_go_menu=dvdnav_go_audio=dvdnav_go_spu=0;
+    }
+// go main DVD menu
+if (dvdnav_go_menu>0)
+    {
+    dvdnav_menu_call((dvdnav_t*)((dvdnav_priv_t*)(stream->priv))->dvdnav,DVD_MENU_Root);
+    dvdnav_go_title=dvdnav_go_part=dvdnav_go_menu=dvdnav_go_audio=dvdnav_go_spu=0;
+    }
+if (dvdnav_go_menu_force)
+    {
+    dvdnav_menu_force((dvdnav_priv_t*)(stream->priv));	/* go main menu with skip intro */
+    dvdnav_go_title=dvdnav_go_part=dvdnav_go_menu=dvdnav_go_menu_force=dvdnav_go_audio=dvdnav_go_spu=0;
+    }
+// switch audio channel
+if (dvdnav_go_audio)
+    {
+    if (sh_audio) demuxer_switch_audio(demuxer, audio_id); 
+    dvdnav_go_audio=0;
+    }
+// switch spu subtitle
+if (dvdnav_go_spu)
+    {
+    d_dvdsub->id = dvdsub_id;
+    if (vo_spudec) { spudec_reset(vo_spudec); dvdnav_go_spu--;}
+    }
+} }
+#endif
+
 //================= Keyboard events, SEEKing ====================
 
   current_module="key_events";
@@ -3834,6 +4241,12 @@
                     spudec_reset(vo_spudec);
                 }
 #endif
+#ifdef USE_MPDVDNAV
+                if (vo_spudec && stream->type == STREAMTYPE_DVDNAV) {
+                    d_dvdsub->id = dvdsub_id;
+                    spudec_reset(vo_spudec);
+                }
+#endif
 #ifdef HAVE_OGGVORBIS
                 if (demuxer->type == DEMUXER_TYPE_OGG)
                     d_dvdsub->id = demux_ogg_sub_id(demuxer, dvdsub_id);
@@ -3866,6 +4279,9 @@
 #ifdef USE_SUB
             vo_osd_changed(OSDTYPE_SUBTITLE); 
 #endif
+#ifdef USE_MPDVDNAV
+	    if(vo_spudec && stream->type==STREAMTYPE_DVDNAV) {dvdsub_id=-1; if (d_dvdsub) d_dvdsub->id = -1;}
+#endif
 	}
         // it's annoying and dumb to show osd saying "off" at every subless file...
         global_sub_quiet_osd_hack = 0;
@@ -3945,6 +4361,7 @@
           /* be silent about this one */
                 break;
           }
+#ifndef USE_MPDVDNAV
       case DVDNAV_HIGHLIGHT: {
           dvdnav_highlight_event_t *hevent = (dvdnav_highlight_event_t*)(dvdnav_event->details);
           if (!hevent) {
@@ -3983,6 +4400,7 @@
             usec_sleep(1000); /* 1ms */
           }
           dvdnav_stream_sleep(dvdnav_priv,still_event->length);
+//    	  dvdnav_still_skip(dvdnav_priv->dvdnav); // don't let dvdnav stall on this image
         break;
         }
       case DVDNAV_STOP: {
@@ -4048,6 +4466,7 @@
                 d_audio->id=dvdsub_id=aid_temp;
                 if(sh_audio) resync_audio_stream(sh_audio);
         }
+        if(sh_audio) resync_audio_stream(sh_audio);
 
         break;
       }
@@ -4092,8 +4511,8 @@
         mp_msg(MSGT_FIXME, MSGL_FIXME, MSGTR_DvdnavNavSeekDone);
         break;
         }
+#endif
       }
-
       // free the dvdnav event
       free(dvdnav_event->details);
       free(dvdnav_event);
@@ -4101,10 +4520,22 @@
     }
     case MP_CMD_DVDNAV: {
       dvdnav_priv_t * dvdnav_priv=(dvdnav_priv_t*)stream->priv;
-
       /* ignore these events if we're not in dvd_nav mode */
       if (stream->type != STREAMTYPE_DVDNAV) break;
-
+#ifdef USE_MPDVDNAV
+      switch (cmd->args[0].v.i) {
+        case MP_CMD_DVDNAV_UP:
+        case MP_CMD_DVDNAV_DOWN:
+        case MP_CMD_DVDNAV_LEFT:
+        case MP_CMD_DVDNAV_RIGHT:
+        case MP_CMD_DVDNAV_MENU:
+        case MP_CMD_DVDNAV_SELECT:
+	  dvdnav_menu_action(dvdnav_priv, cmd->args[0].v.i);
+	  break;
+        default:
+//          mp_msg(MSGT_CPLAYER, MSGL_V, "Weird DVD Nav cmd %d\n",cmd->args[0].v.i);
+          break; }
+#else
       switch (cmd->args[0].v.i) {
         case MP_CMD_DVDNAV_UP:
           dvdnav_upper_button_select(dvdnav_priv->dvdnav);
@@ -4129,6 +4560,7 @@
           mp_msg(MSGT_CPLAYER, MSGL_V, "Weird DVD Nav cmd %d\n",cmd->args[0].v.i);
           break;
       }
+#endif
       break;
     }
 #endif /* USE_DVDNAV */
@@ -4338,6 +4770,11 @@
                   if (vo_spudec && dvdsub_id >= 0) {
                       char lang[3] = "\0\0\0";
                       int code = 0;
+#ifdef USE_MPDVDNAV
+		      if(stream->type==STREAMTYPE_DVDNAV)
+                        code = dvdnav_lang_from_sid((dvdnav_priv_t*)(stream->priv), dvdsub_id);
+			else
+#endif
                       code = dvd_lang_from_sid(stream, dvdsub_id);
                       if (code) {
                           lang[0] = code >> 8;
@@ -4432,8 +4869,13 @@
       if(timestamp < 0) timestamp = 0;
       else spudec_assemble(vo_spudec,packet,len,timestamp);
   }
-  
+//printf("spudec_visible: %i\n",spudec_visible(vo_spudec));  
   /* detect wether the sub has changed or not */
+#ifdef USE_MPDVDNAV
+    /* still image now process data, because next frame reseek: delete read spu packet */
+  if(stream->type==STREAMTYPE_DVDNAV) {
+   if(dvdnav_still || !((dvdnav_priv_t*)(stream->priv))->vts_domain) spudec_heartbeat(vo_spudec,90000*sh_video->timer); }
+#endif
   if(spudec_changed(vo_spudec))
     vo_osd_changed(OSDTYPE_SPU);
   current_module=NULL;
@@ -4476,7 +4918,11 @@
 }
 
 // time to uninit all, except global stuff:
+#ifdef USE_MPDVDNAV
+uninit_player(INITED_ALL-(INITED_GUI+INITED_INPUT+((fixed_vo || (dvdnav_continue_play && dvdnav_fixed_vo))?INITED_VO:0))+(dvdnav_continue_play?INITED_STREAM:0));
+#else
 uninit_player(INITED_ALL-(INITED_GUI+INITED_INPUT+(fixed_vo?INITED_VO:0)));
+#endif
 
 #ifdef USE_SUB  
   if ( set_of_sub_size > 0 ) 
@@ -4490,6 +4936,13 @@
    }
 #endif
 
+#ifdef USE_MPDVDNAV
+if(dvdnav_continue_play) {
+  eof = 0;
+  goto play_next_file;
+}
+#endif
+
 if(eof == PT_NEXT_ENTRY || eof == PT_PREV_ENTRY) {
   eof = eof == PT_NEXT_ENTRY ? 1 : -1;
   if(play_tree_iter_step(playtree_iter,play_tree_step,0) == PLAY_TREE_ITER_ENTRY) {
@@ -4515,6 +4968,15 @@
 
 if(eof == 0) eof = 1;
 
+/*
+#ifdef USE_MPDVDNAV
+if(dvdnav_continue_play) {
+  eof = 0;
+  goto play_next_file;
+}
+#endif
+*/
+
 while(playtree_iter != NULL) {
   filename = play_tree_iter_get_file(playtree_iter,eof);
   if(filename == NULL) {
--- mencoder.c	2006-02-09 20:39:50.000000000 +0100
+++ mencoder.c	2006-02-10 00:01:16.000000000 +0100
@@ -50,6 +50,9 @@
 #include "parser-mecmd.h"
 
 #include "libmpdemux/stream.h"
+#ifdef USE_MPDVDNAV
+#include "libmpdemux/stream_dvdnav.h"
+#endif
 #include "libmpdemux/demuxer.h"
 #include "libmpdemux/stheader.h"
 #include "libmpdemux/mp3_hdr.h"
@@ -63,6 +66,9 @@
 #include "libmpcodecs/mp_image.h"
 #include "libmpcodecs/dec_audio.h"
 #include "libmpcodecs/dec_video.h"
+#ifdef USE_MPDVDNAV
+#include "libmpcodecs/vd_videostill.h"
+#endif
 #include "libmpcodecs/vf.h"
 
 // for MPEGLAYER3WAVEFORMAT:
@@ -494,7 +500,7 @@
 if (frameno_filename) {
   stream2=open_stream(frameno_filename,0,&i);
   if(stream2){
-    demuxer2=demux_open(stream2,DEMUXER_TYPE_AVI,-1,-1,-2,NULL);
+    demuxer2=demux_open(stream2,DEMUXER_TYPE_AVI,-1,-1,-2,NULL,0,0,0);
     if(demuxer2) mp_msg(MSGT_MENCODER, MSGL_INFO, MSGTR_UsingPass3ControllFile, frameno_filename);
     else mp_msg(MSGT_DEMUXER,MSGL_ERR,MSGTR_FormatNotRecognized);
   }
@@ -573,7 +579,7 @@
   if(demuxer2) audio_id=-2; /* do NOT read audio packets... */
 
   //demuxer=demux_open(stream,file_format,video_id,audio_id,dvdsub_id);
-  demuxer=demux_open(stream,file_format,audio_id,video_id,dvdsub_id,filename);
+  demuxer=demux_open(stream,file_format,audio_id,video_id,dvdsub_id,filename,0,0,0);
   if(!demuxer){
     mp_msg(MSGT_DEMUXER, MSGL_FATAL, MSGTR_FormatNotRecognized);
     mp_msg(MSGT_DEMUXER, MSGL_FATAL, MSGTR_CannotOpenDemuxer);
--- spudec.h	2003-09-21 16:21:11.000000000 +0200
+++ spudec.h	2006-02-10 00:01:16.000000000 +0100
@@ -5,6 +5,12 @@
 
 void spudec_heartbeat(void *this, unsigned int pts100);
 void spudec_assemble(void *this, unsigned char *packet, unsigned int len, unsigned int pts100);
+#ifdef USE_MPDVDNAV
+void spudec_dvdnav_mode(void *this, int mode);
+void spudec_dvdnav_area(void *this, uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint32_t palette);
+void spudec_dvdnav_palette(void *this, uint32_t palette);
+int spudec_dvdnav_menu_box(void *this);
+#endif
 void spudec_draw(void *this, void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride));
 void spudec_draw_scaled(void *this, unsigned int dxs, unsigned int dys, void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride));
 void spudec_update_palette(void *this, unsigned int *palette);
--- spudec.c	2005-06-19 15:50:50.000000000 +0200
+++ spudec.c	2006-02-10 00:01:16.000000000 +0100
@@ -91,6 +91,23 @@
   int spu_changed;
   unsigned int forced_subs_only;     /* flag: 0=display all subtitle, !0 display only forced subtitles */
   unsigned int is_forced_sub;         /* true if current subtitle is a forced subtitle */
+#ifdef USE_MPDVDNAV
+  int dvdnav_menu;		/* flag: 0=normal subtitle, 1=dvdnav menu */
+  unsigned int dvdnav_sx;	/* dvdnav menu item box */
+  unsigned int dvdnav_ex;
+  unsigned int dvdnav_sy;
+  unsigned int dvdnav_ey;
+  unsigned int dvdnav_modify;	/* dvdnav menu item box is modify */
+  uint32_t     dvdnav_palette;	/* dvdnav menu button palette */
+  unsigned int dvdnav_x0;	/* dvdnav menu item draw_alpha coordinates */
+  unsigned int dvdnav_y0;
+  unsigned int dvdnav_w;
+  unsigned int dvdnav_h;
+  unsigned char *dvdnav_image;	/* dvdnav menu item image */
+  unsigned char *dvdnav_aimage;	/* dvdnav menu item alpha */
+  unsigned int dvdnav_stride;
+  unsigned int dvdnav_allocated;
+#endif
 } spudec_handle_t;
 
 static void spudec_queue_packet(spudec_handle_t *this, packet_t *packet)
@@ -226,6 +243,13 @@
   this->height = packet->height;
   this->width = packet->width;
   this->stride = packet->stride;
+#ifdef USE_MPDVDNAV
+  if (this->dvdnav_menu)
+    for (i = 0; i < 4; ++i) {	/* use button palette */
+      packet->alpha[i]=(this->dvdnav_palette >> ((3-i)*4)) & 0x0f;
+      packet->palette[i]=(this->dvdnav_palette >> (16+(3-i)*4)) & 0x0f;
+      }
+#endif
   for (i = 0; i < 4; ++i) {
     alpha[i] = mkalpha(packet->alpha[i]);
     if (alpha[i] == 0)
@@ -241,7 +265,12 @@
 	cmap[i] = 256 - alpha[i];
     }
   }
-
+#ifdef USE_MPDVDNAV
+mp_msg(MSGT_CPLAYER,MSGL_DBG2,"spu: dvdnav_menu: %i palette: %i alpha: %x %x %x %x cmap: %x %x %x %x \n",this->dvdnav_menu,this->dvdnav_palette,
+    alpha[0],alpha[1],alpha[2],alpha[3],cmap[0],cmap[1],cmap[2],cmap[3]);
+//printf("spu: dvdnav_menu: %i palette: %i alpha: %x %x %x %x cmap: %x %x %x %x \n",this->dvdnav_menu,this->dvdnav_palette,
+//    alpha[0],alpha[1],alpha[2],alpha[3],cmap[0],cmap[1],cmap[2],cmap[3]);
+#endif
   if (this->image_size < this->stride * this->height) {
     if (this->image != NULL) {
       free(this->image);
@@ -377,6 +406,10 @@
 	end_pts = UINT_MAX;
 	display = 1;
 	this->is_forced_sub=~0; // current subtitle is forced
+#ifdef USE_MPDVDNAV
+//printf("spu packet cmd=00\n");
+	mp_msg(MSGT_CPLAYER,MSGL_DBG2,"spu packet cmd=00\n");
+#endif
 	break;
       case 0x01:
 	/* Start display */
@@ -385,6 +418,10 @@
 	end_pts = UINT_MAX;
 	display = 1;
 	this->is_forced_sub=0;
+#ifdef USE_MPDVDNAV
+//printf("spu packet cmd=01\n");
+	mp_msg(MSGT_CPLAYER,MSGL_DBG2,"spu packet cmd=01\n");
+#endif
 	break;
       case 0x02:
 	/* Stop display */
@@ -602,12 +639,16 @@
   }
 }
 
+
 int spudec_visible(void *this){
     spudec_handle_t *spu = (spudec_handle_t *)this;
+#ifdef USE_MPDVDNAV
+    if(!spu) return 0;
+    if (spu->dvdnav_menu && spu->height > 0) return 1;
+#endif
     int ret=(spu->start_pts <= spu->now_pts &&
 	     spu->now_pts < spu->end_pts &&
 	     spu->height > 0);
-//    printf("spu visible: %d  \n",ret);
     return ret;
 }
 
@@ -624,6 +665,14 @@
     spudec_handle_t *spu = (spudec_handle_t *)this;
     if (spu->start_pts <= spu->now_pts && spu->now_pts < spu->end_pts && spu->image)
     {
+#ifdef USE_MPDVDNAV
+	if (spu->dvdnav_menu) {	/* spu menu mode? */
+	      if (spudec_dvdnav_menu_box(spu))	/* cut button area and show */
+		draw_alpha(spu->dvdnav_x0,spu->dvdnav_y0,spu->dvdnav_w,spu->dvdnav_h,
+		   spu->dvdnav_image, spu->dvdnav_aimage, spu->dvdnav_stride);
+	}
+	else
+#endif
 	draw_alpha(spu->start_col, spu->start_row, spu->width, spu->height,
 		   spu->image, spu->aimage, spu->stride);
 	spu->spu_changed = 0;
@@ -762,6 +811,101 @@
 	sws_freeContext(ctx);
 }
 
+#ifdef USE_MPDVDNAV
+#undef max
+#define max(x,y) ((x) > (y) ? (x) : (y))
+#undef min
+#define min(x,y) ((x) < (y) ? (x) : (y))
+
+void spudec_dvdnav_mode(void *this, int mode){		/* set/clear spu menu mode */
+  spudec_handle_t *spu = (spudec_handle_t *)this;
+  if (!spu) return;
+  spu->dvdnav_menu=mode;
+  return;
+}
+
+void spudec_dvdnav_area(void *this, uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint32_t palette)
+{
+  spudec_handle_t *spu = this;
+  if (!spu) return;
+  spu->dvdnav_sx=min(sx,ex);		/* set spu button area, palette & on */
+  spu->dvdnav_ex=max(sx,ex);
+  spu->dvdnav_sy=min(sy,ey);
+  spu->dvdnav_ey=max(sy,ey);
+  spu->dvdnav_palette=palette;
+  spu->dvdnav_modify=1;
+  return;
+}
+
+void spudec_dvdnav_palette(void *this, uint32_t palette)
+{
+  spudec_handle_t *spu = this;
+  if (!spu) return;
+  spu->dvdnav_palette=palette;		/* set spu button palette */
+  return;
+}
+
+int spudec_dvdnav_menu_box(void *this)	/* cut spu button area */
+{
+  spudec_handle_t *spu = this;
+
+  if ( !spu->dvdnav_modify && spu->dvdnav_image && spu->dvdnav_aimage ) return 1;	// not modify
+  if ( !spu->dvdnav_sx && !spu->dvdnav_ex && !spu->dvdnav_sy && !spu->dvdnav_ey ) return 1; // none button
+// cut: spu & nav button area 
+
+  spu->dvdnav_x0=max(spu->dvdnav_sx,spu->start_col);	/* intersection of spu area & button area  */
+  spu->dvdnav_y0=max(spu->dvdnav_sy,spu->start_row);
+  spu->dvdnav_w=min(spu->dvdnav_ex,spu->start_col+spu->width)-spu->dvdnav_x0;
+  spu->dvdnav_h=min(spu->dvdnav_ey,spu->start_row+spu->height)-spu->dvdnav_y0;
+  if ((signed int)spu->dvdnav_h<=0 || (signed int)spu->dvdnav_w<=0)	// not valid cut area
+    {
+    if (spu->dvdnav_image) free(spu->dvdnav_image);
+    spu->dvdnav_image=NULL;
+    if (spu->dvdnav_aimage) free(spu->dvdnav_aimage);
+    spu->dvdnav_aimage=NULL;
+    spu->dvdnav_allocated = 0;
+    return 0;
+    }
+
+  spu->dvdnav_modify=0;
+
+  /* alloc buffer */
+  int len;
+  spu->dvdnav_stride = (spu->dvdnav_w+7)&(~7);
+  len = spu->dvdnav_stride*spu->dvdnav_h;
+    if (spu->dvdnav_allocated<len) {				// alloc new image & alpha buffer
+	spu->dvdnav_allocated = len;
+	if (spu->dvdnav_image) free(spu->dvdnav_image);		// free old image memory
+	if (spu->dvdnav_aimage) free(spu->dvdnav_aimage);
+	spu->dvdnav_image = (unsigned char *)memalign(16, len);	// allocate image memory
+	spu->dvdnav_aimage = (unsigned char *)memalign(16, len);
+	memset(spu->dvdnav_image,0,len);			// clear image memory
+	memset(spu->dvdnav_aimage,0,len);
+    }
+  unsigned char *ptr;	/* source image pointer */
+  unsigned char *aptr;	/* source aimage pointer */
+  unsigned char *dptr;	/* destination image pointer */
+  unsigned char *daptr;	/* destination image pointer */
+  ptr=spu->image+(spu->dvdnav_y0-spu->start_row)*spu->stride+(spu->dvdnav_x0-spu->start_col);	// start pos
+  aptr=spu->aimage+(spu->dvdnav_y0-spu->start_row)*spu->stride+(spu->dvdnav_x0-spu->start_col);
+  int y;
+  dptr=spu->dvdnav_image;
+  daptr=spu->dvdnav_aimage;
+  for(y=0; y < spu->dvdnav_h; y++)				// copy spu|button -> cut image
+    {
+//    memcpy(dptr,ptr,spu->dvdnav_w);
+//    memcpy(daptr,aptr,spu->dvdnav_w);
+    memcpy(dptr,ptr,spu->dvdnav_stride);
+    memcpy(daptr,aptr,spu->dvdnav_stride);
+    ptr+=spu->stride;
+    aptr+=spu->stride;
+    dptr+=spu->dvdnav_stride;
+    daptr+=spu->dvdnav_stride;
+    }
+  return 1;
+}
+#endif
+
 void spudec_draw_scaled(void *me, unsigned int dxs, unsigned int dys, void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride))
 {
   spudec_handle_t *spu = (spudec_handle_t *)me;
@@ -779,6 +923,16 @@
 	|| (spu->orig_frame_width == dxs && spu->orig_frame_height == dys))) {
       if (spu->image)
       {
+#ifdef USE_MPDVDNAV
+	if (spu->dvdnav_menu) {
+          if (spudec_dvdnav_menu_box(spu))
+		draw_alpha(spu->dvdnav_x0,spu->dvdnav_y0,spu->dvdnav_w,spu->dvdnav_h,
+		   spu->dvdnav_image, spu->dvdnav_aimage, spu->dvdnav_stride);
+	}
+//	  draw_alpha(x0, y0, w, h,
+//		   spu->image, spu->aimage, spu->stride);} 
+	else
+#endif
 	draw_alpha(spu->start_col, spu->start_row, spu->width, spu->height,
 		   spu->image, spu->aimage, spu->stride);
 	spu->spu_changed = 0;
@@ -1170,6 +1324,13 @@
 	free(spu->scaled_image);
     if (spu->image)
       free(spu->image);
+#ifdef USE_MPDVDNAV
+    if (spu->dvdnav_image)
+      free(spu->dvdnav_image);
+    if (spu->dvdnav_aimage)
+      free(spu->dvdnav_aimage);
+    spu->dvdnav_allocated = 0;
+#endif
     free(spu);
   }
 }
--- cfg-common.h	2006-02-04 01:08:54.000000000 +0100
+++ cfg-common.h	2006-02-10 00:01:16.000000000 +0100
@@ -28,6 +28,23 @@
 	{"dvdnav", "-dvdnav is deprecated, use dvdnav:// instead.\n", CONF_TYPE_PRINT, 0, 0, 1, NULL},
 	{"skipopening", &dvd_nav_skip_opening, CONF_TYPE_FLAG, 0, 0, 1, NULL},
 	{"noskipopening", &dvd_nav_skip_opening, CONF_TYPE_FLAG, 0, 1, 0, NULL},
+#ifdef USE_MPDVDNAV
+	{"mlang", &dvdmenu_lang, CONF_TYPE_STRING, 0, 0, 0, NULL},
+	{"dvdnav-menutype", &dvdnav_menutype, CONF_TYPE_INT, CONF_RANGE|CONF_GLOBAL, 0, 2, NULL},
+	{"dvdnav-realstill", &dvdnav_real_still, CONF_TYPE_FLAG, 0, 0, 1, NULL},
+	{"dvdnav-norealstill", &dvdnav_real_still, CONF_TYPE_FLAG, 0, 1, 0, NULL},
+	{"dvdnav-fixed-vo", &dvdnav_fixed_vo, CONF_TYPE_FLAG, 0, 0, 1, NULL},
+	{"dvdnav-nofixed-vo", &dvdnav_fixed_vo, CONF_TYPE_FLAG, 0, 1, 0, NULL},
+//	{"dvdnav-skipintro", &dvdnav_skipintro, CONF_TYPE_FLAG, 0, 0, 1, NULL},
+//	{"dvdnav-noskipintro", &dvdnav_skipintro, CONF_TYPE_FLAG, 0, 1, 0, NULL},
+#ifdef USE_MPDVDNAV_TRACE
+	{"dvdnav-trace", &dvdnav_trace, CONF_TYPE_FLAG, 0, 0, 1, NULL},
+	{"dvdnav-notrace", &dvdnav_trace, CONF_TYPE_FLAG, 0, 1, 0, NULL},
+#else
+	{"dvdnav-trace", "MPlayer was compiled without dvdnav trace support.\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
+	{"dvdnav-notrace", "MPlayer was compiled without dvdnav trace support.\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
+#endif
+#endif
 #endif
 #ifdef USE_DVDREAD
 	{"dvd-device", &dvd_device,  CONF_TYPE_STRING, 0, 0, 0, NULL}, 
--- configure	2006-01-30 21:58:11.000000000 +0100
+++ configure	2006-02-10 00:01:16.000000000 +0100
@@ -1532,6 +1532,8 @@
 _have_dvd=no
 # dvdnav disabled, it does not work
 #_dvdnav=no
+_dvdnav=no
+_dvdnav_trace=no
 _dvdread=auto
 _dvdkit=auto
 _xanim=auto
@@ -1752,6 +1754,10 @@
 # dvdnav disabled, it does not work
 #  --enable-dvdnav)	_dvdnav=yes	;;
 #  --disable-dvdnav)	_dvdnav=no	;;
+  --enable-dvdnav)	_dvdnav=yes	;;
+  --disable-dvdnav)	_dvdnav=no	;;
+  --enable-dvdnav-trace) 	_dvdnav_trace=yes	;;
+  --disable-dvdnav-trace)	_dvdnav_trace=no	;;
   --enable-xanim)	_xanim=yes	;;
   --disable-xanim)	_xanim=no	;;
   --enable-real)	_real=yes	;;
@@ -5117,6 +5123,25 @@
 #   _noinputmodules="dvdnav $_noinputmodules"
 #   echores "no"
 # fi
+echocheck "DVDNAV support"
+if test "$_dvdnav" = yes ; then
+  _largefiles=yes
+  _def_dvdnav='#define USE_DVDNAV 1'
+  _def_mpdvdnav='#define USE_MPDVDNAV 1'
+if test "$_dvdnav_trace" = yes ; then
+  _def_mpdvdnav_trace='#define USE_MPDVDNAV_TRACE 1'
+  _inputmodules="dvdnav(dvdnav-trace) $_inputmodules"
+else
+  _inputmodules="dvdnav $_inputmodules"
+fi
+  _dvdnav_version='0110'
+  _def_dvdnav_version="#define DVDNAVVERSION $_dvdnav_version"
+  _def_dvdnav_sversion="#define DVDNAVSVERSION \"0.1.10\""
+  echores "yes"
+else
+  _noinputmodules="dvdnav $_noinputmodules"
+fi
+echores "$_dvdnav"
 
 echocheck "cdparanoia"
 if test "$_cdparanoia" = auto ; then
@@ -7263,6 +7288,7 @@
 DVDKIT = $_dvdkit
 DVDKIT2 = $_dvdkit2
 DVDKIT_SHARED = no
+LIBMPDVDNAV = $_dvdnav
 SDL_INC = $_inc_sdl
 W32_DEP = $_dep_win32
 W32_LIB = $_ld_win32
@@ -7638,6 +7664,9 @@
 /* DVD navigation support using libdvdnav */
 $_def_dvdnav
 $_def_dvdnav_version
+$_def_dvdnav_sversion
+$_def_mpdvdnav
+$_def_mpdvdnav_trace
 
 /* Define this to enable MPEG 1/2 image postprocessing (requires a FAST CPU!) */
 #define MPEG12_POSTPROC 1
--- libmpdemux/Makefile	2006-02-06 17:04:17.000000000 +0100
+++ libmpdemux/Makefile	2006-02-10 00:01:16.000000000 +0100
@@ -23,12 +23,15 @@
         cddb.c \
         cdinfo.c \
         cue_read.c \
-        dvdnav_stream.c \
+        stream_dvdnav.c \
         parse_es.c \
         parse_mp4.c \
         yuv4mpeg.c \
         yuv4mpeg_ratio.c \
 
+#	dvdnav_stream replaced: stream_dvdnav
+#        dvdnav_stream.c \
+
 # Stream readers/writers
 SRCS += stream.c \
         stream_file.c \
--- libmpdemux/demuxer.c	2006-02-09 20:39:51.000000000 +0100
+++ libmpdemux/demuxer.c	2006-02-11 18:45:26.000000000 +0100
@@ -16,6 +16,9 @@
 #include "libvo/fastmemcpy.h"
 
 #include "stream.h"
+#ifdef USE_MPDVDNAV
+#include "stream_dvdnav.h"
+#endif
 #include "demuxer.h"
 #include "stheader.h"
 #include "mf.h"
@@ -147,7 +150,6 @@
   ds->pos=0;
   ds->dpos=0;
   ds->pack_no=0;
-//---------------
   ds->packs=0;
   ds->bytes=0;
   ds->first=ds->last=ds->current=NULL;
@@ -182,7 +184,7 @@
 }
 
 
-demuxer_t* new_demuxer(stream_t *stream,int type,int a_id,int v_id,int s_id,char *filename){
+demuxer_t* new_demuxer(stream_t *stream,int type,int a_id,int v_id,int s_id,char *filename,int maxvpacks, int maxapacks, int hideerrmess){
   demuxer_t *d=malloc(sizeof(demuxer_t));
   memset(d,0,sizeof(demuxer_t));
   d->stream=stream;
@@ -195,6 +197,13 @@
   d->video=new_demuxer_stream(d,v_id);
   d->sub=new_demuxer_stream(d,s_id);
   d->type=type;
+// --------------
+  if (maxvpacks==0) d->max_video_packs=MAX_PACKS; else d->max_video_packs=maxvpacks;
+  d->max_video_bytes=MAX_PACK_BYTES;
+  if (maxapacks==0) d->max_audio_packs=MAX_PACKS; else d->max_audio_packs=maxapacks;
+  d->max_audio_bytes=MAX_PACK_BYTES;
+  d->hide_packs_err_mess=hideerrmess;
+// --------------
   if(type)
     if (!(d->desc = get_demuxer_desc_from_type(type)))
       mp_msg(MSGT_DEMUXER,MSGL_ERR,"BUG! Invalid demuxer type in new_demuxer(), big troubles ahead.");
@@ -252,6 +261,12 @@
         if (identify && !demux_aid_vid_mismatch)
           mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_VIDEO_ID=%d\n", id);
     }
+#ifdef USE_MPDVDNAV
+  ((sh_video_t*)demuxer->v_streams[id])->config_lock=0;
+  ((sh_video_t*)demuxer->v_streams[id])->config_w=0;
+  ((sh_video_t*)demuxer->v_streams[id])->config_h=0;
+  ((sh_video_t*)demuxer->v_streams[id])->config_outfmt=0;
+#endif
     return demuxer->v_streams[id];
 }
 
@@ -370,14 +385,16 @@
       --ds->packs;
       return 1; //ds->buffer_size;
     }
-    if(demux->audio->packs>=MAX_PACKS || demux->audio->bytes>=MAX_PACK_BYTES){
+    if(demux->audio->packs>=demux->max_audio_packs || demux->audio->bytes>=demux->max_audio_bytes){
+      if (!(demux->hide_packs_err_mess)) {
       mp_msg(MSGT_DEMUXER,MSGL_ERR,MSGTR_TooManyAudioInBuffer,demux->audio->packs,demux->audio->bytes);
-      mp_msg(MSGT_DEMUXER,MSGL_HINT,MSGTR_MaybeNI);
+        mp_msg(MSGT_DEMUXER,MSGL_HINT,MSGTR_MaybeNI); }
       break;
     }
-    if(demux->video->packs>=MAX_PACKS || demux->video->bytes>=MAX_PACK_BYTES){
+    if(demux->video->packs>=demux->max_video_packs || demux->video->bytes>=demux->max_video_bytes){
+      if (!(demux->hide_packs_err_mess)) {
       mp_msg(MSGT_DEMUXER,MSGL_ERR,MSGTR_TooManyVideoInBuffer,demux->video->packs,demux->video->bytes);
-      mp_msg(MSGT_DEMUXER,MSGL_HINT,MSGTR_MaybeNI);
+        mp_msg(MSGT_DEMUXER,MSGL_HINT,MSGTR_MaybeNI);}
       break;
     }
     if(!demux_fill_buffer(demux,ds)){
@@ -620,7 +637,7 @@
 
 static demuxer_t* demux_open_stream(stream_t *stream, int file_format,
                     int force, int audio_id, int video_id, int dvdsub_id,
-                    char* filename) {
+                    char* filename,int maxvpacks, int maxapacks, int hideerrmess) {
 
 //int file_format=(*file_format_ptr);
 
@@ -637,7 +654,7 @@
 // If somebody requested a demuxer check it
 if (file_format) {
   if ((demuxer_desc = get_demuxer_desc_from_type(file_format))) {
-    demuxer = new_demuxer(stream,demuxer_desc->type,audio_id,video_id,dvdsub_id,filename);
+    demuxer = new_demuxer(stream,demuxer_desc->type,audio_id,video_id,dvdsub_id,filename, maxvpacks, maxapacks, hideerrmess);
     if (demuxer_desc->check_file) {
       fformat = demuxer_desc->check_file(demuxer);
       if (force)
@@ -651,7 +668,7 @@
           // Format changed after check, recurse
           free_demuxer(demuxer);
           return demux_open_stream(stream, fformat, force,
-                   audio_id, video_id, dvdsub_id, filename);
+                   audio_id, video_id, dvdsub_id, filename, maxvpacks, maxapacks, hideerrmess);
         }
       } else {
         // Check failed for forced demuxer, quit
@@ -668,7 +685,7 @@
 // Test demuxers with safe file checks
 for (i = 0; (demuxer_desc = demuxer_list[i]); i++) {
   if (demuxer_desc->safe_check) {
-    demuxer = new_demuxer(stream,demuxer_desc->type,audio_id,video_id,dvdsub_id,filename);
+    demuxer = new_demuxer(stream,demuxer_desc->type,audio_id,video_id,dvdsub_id,filename, maxvpacks, maxapacks, hideerrmess);
     if ((fformat = demuxer_desc->check_file(demuxer)) != 0) {
       if (fformat == demuxer_desc->type) {
         mp_msg(MSGT_DEMUXER, MSGL_INFO, MSGTR_Detected_XXX_FileFormat, demuxer_desc->shortdesc);
@@ -680,7 +697,7 @@
         // Format changed after check, recurse
         free_demuxer(demuxer);
         demuxer=demux_open_stream(stream, fformat, force,
-                  audio_id, video_id, dvdsub_id, filename);
+                  audio_id, video_id, dvdsub_id, filename, maxvpacks, maxapacks, hideerrmess);
         if(demuxer) return demuxer; // done!
         file_format = DEMUXER_TYPE_UNKNOWN;
       }
@@ -703,7 +720,7 @@
   if(file_format!=DEMUXER_TYPE_UNKNOWN){
     // we like recursion :)
     demuxer=demux_open_stream(stream, file_format, force,
-              audio_id, video_id, dvdsub_id, filename);
+              audio_id, video_id, dvdsub_id, filename, maxvpacks, maxapacks, hideerrmess);
     if(demuxer) return demuxer; // done!
     file_format=DEMUXER_TYPE_UNKNOWN; // continue fuzzy guessing...
     mp_msg(MSGT_DEMUXER,MSGL_V,"demuxer: continue fuzzy content-based format guessing...\n");
@@ -713,7 +730,7 @@
 // Try detection for all other demuxers
 for (i = 0; (demuxer_desc = demuxer_list[i]); i++) {
   if (!demuxer_desc->safe_check && demuxer_desc->check_file) {
-    demuxer = new_demuxer(stream,demuxer_desc->type,audio_id,video_id,dvdsub_id,filename);
+    demuxer = new_demuxer(stream,demuxer_desc->type,audio_id,video_id,dvdsub_id,filename, maxvpacks, maxapacks, hideerrmess);
     if ((fformat = demuxer_desc->check_file(demuxer)) != 0) {
       if (fformat == demuxer_desc->type) {
         mp_msg(MSGT_DEMUXER, MSGL_INFO, MSGTR_Detected_XXX_FileFormat, demuxer_desc->shortdesc);
@@ -725,7 +742,7 @@
         // Format changed after check, recurse
         free_demuxer(demuxer);
         demuxer=demux_open_stream(stream, fformat, force,
-                  audio_id, video_id, dvdsub_id, filename);
+                  audio_id, video_id, dvdsub_id, filename, maxvpacks, maxapacks, hideerrmess);
         if(demuxer) return demuxer; // done!
         file_format = DEMUXER_TYPE_UNKNOWN;
       }
@@ -778,7 +795,7 @@
 extern float stream_cache_min_percent;
 extern float stream_cache_seek_min_percent;
 
-demuxer_t* demux_open(stream_t *vs,int file_format,int audio_id,int video_id,int dvdsub_id,char* filename){
+demuxer_t* demux_open(stream_t *vs,int file_format,int audio_id,int video_id,int dvdsub_id,char* filename,int maxvpacks, int maxapacks, int hideerrmess){
   stream_t *as = NULL,*ss = NULL;
   demuxer_t *vd,*ad = NULL,*sd = NULL;
   int afmt =DEMUXER_TYPE_UNKNOWN,sfmt = DEMUXER_TYPE_UNKNOWN ;
@@ -823,7 +840,7 @@
 
   vd = demux_open_stream(vs, demuxer_type ? demuxer_type : file_format,
          demuxer_force, audio_stream ? -2 : audio_id, video_id,
-         sub_stream ? -2 : dvdsub_id, filename);
+         sub_stream ? -2 : dvdsub_id, filename, maxvpacks, maxapacks, hideerrmess);
   if(!vd) {
     if(as) free_stream(as);
     if(ss) free_stream(ss);
@@ -831,7 +848,7 @@
   }
   if(as) {
     ad = demux_open_stream(as, audio_demuxer_type ? audio_demuxer_type : afmt,
-           audio_demuxer_force, audio_id, -2, -2, audio_stream);
+           audio_demuxer_force, audio_id, -2, -2, audio_stream, maxvpacks, maxapacks, hideerrmess);
     if(!ad) {
       mp_msg(MSGT_DEMUXER,MSGL_WARN,MSGTR_OpeningAudioDemuxerFailed,audio_stream);
       free_stream(as);
@@ -841,7 +858,7 @@
   }
   if(ss) {
     sd = demux_open_stream(ss, sub_demuxer_type ? sub_demuxer_type : sfmt,
-           sub_demuxer_force, -2, -2, dvdsub_id, sub_stream);
+           sub_demuxer_force, -2, -2, dvdsub_id, sub_stream, maxvpacks, maxapacks, hideerrmess);
     if(!sd) {
       mp_msg(MSGT_DEMUXER,MSGL_WARN,MSGTR_OpeningSubtitlesDemuxerFailed,sub_stream);
       free_stream(ss);
@@ -960,6 +977,17 @@
 
 int demux_control(demuxer_t *demuxer, int cmd, void *arg) {
 
+    switch (cmd) {
+      case DEMUXER_CTRL_SETMAXAUDIOPACKS:
+        demuxer->max_audio_packs=*((int*)arg);
+        return DEMUXER_CTRL_OK;
+      case DEMUXER_CTRL_SETMAXVIDEOPACKS:
+        demuxer->max_video_packs=*((int*)arg);
+        return DEMUXER_CTRL_OK;
+      case DEMUXER_CTRL_SETHIDEPACKSERR:
+        demuxer->hide_packs_err_mess=*((int*)arg);
+        return DEMUXER_CTRL_OK;
+      }
     if (demuxer->desc->control)
       return demuxer->desc->control(demuxer,cmd,arg);
 
@@ -1005,3 +1033,20 @@
       index = demuxer->audio->id;
     return index;
 }
+
+void demuxer_set_max_packet(demuxer_t *demuxer, int maxvideopacket, int maxaudiopacket, int hideflg)
+{
+    if (maxvideopacket==0) maxvideopacket=MAX_PACKS;	// restore default
+    if (maxaudiopacket==0) maxaudiopacket=MAX_PACKS;	// restore default
+    demux_control(demuxer, DEMUXER_CTRL_SETMAXAUDIOPACKS,(void *)&maxaudiopacket);
+    demux_control(demuxer, DEMUXER_CTRL_SETMAXVIDEOPACKS,(void *)&maxvideopacket);
+    demux_control(demuxer, DEMUXER_CTRL_SETHIDEPACKSERR,(void *)&hideflg);
+    return;
+}
+
+void demuxer_update_time_length(demuxer_t *demuxer, off_t startpos, off_t endpos) {
+demuxer->movi_end=endpos;
+demuxer->stream->start_pos=startpos;
+demuxer->stream->end_pos=endpos;
+demux_control(demuxer, DEMUXER_CTRL_SET_TIME_LENGTH,(void *)&endpos);
+}
--- libmpdemux/demuxer.h	2006-02-09 20:39:51.000000000 +0100
+++ libmpdemux/demuxer.h	2006-02-11 18:45:13.000000000 +0100
@@ -76,6 +76,13 @@
 #define DEMUXER_CTRL_GET_PERCENT_POS 11
 #define DEMUXER_CTRL_SWITCH_AUDIO 12
 
+// DEMUXER ds_fill_buffer packs/bytes command
+#define DEMUXER_CTRL_SETMAXAUDIOPACKS 13
+#define DEMUXER_CTRL_SETMAXVIDEOPACKS 14
+#define DEMUXER_CTRL_SETHIDEPACKSERR 15
+
+#define DEMUXER_CTRL_SET_TIME_LENGTH 16
+
 // Holds one packet/frame/whatever
 typedef struct demux_packet_st {
   int len;
@@ -171,6 +178,13 @@
   demux_stream_t *audio; // audio buffer/demuxer
   demux_stream_t *video; // video buffer/demuxer
   demux_stream_t *sub;   // dvd subtitle buffer/demuxer
+// --------------
+  int max_video_packs;
+  int max_video_bytes;
+  int max_audio_packs;
+  int max_audio_bytes;
+  int hide_packs_err_mess;
+// --------------
 
   // stream headers:
   void* a_streams[MAX_A_STREAMS]; // audio streams (sh_audio_t)
@@ -236,7 +250,7 @@
 }
 
 demux_stream_t* new_demuxer_stream(struct demuxer_st *demuxer,int id);
-demuxer_t* new_demuxer(stream_t *stream,int type,int a_id,int v_id,int s_id,char *filename);
+demuxer_t* new_demuxer(stream_t *stream,int type,int a_id,int v_id,int s_id,char *filename,int maxvpacks, int maxapacks, int hideerrmess);
 void free_demuxer_stream(demux_stream_t *ds);
 void free_demuxer(demuxer_t *demuxer);
 
@@ -299,7 +313,7 @@
   return a*10+b;
 }
 
-demuxer_t* demux_open(stream_t *stream,int file_format,int aid,int vid,int sid,char* filename);
+demuxer_t* demux_open(stream_t *stream,int file_format,int aid,int vid,int sid,char* filename,int maxvpacks, int maxapacks, int hideerrmess);
 int demux_seek(demuxer_t *demuxer,float rel_seek_secs,int flags);
 demuxer_t*  new_demuxers_demuxer(demuxer_t* vd, demuxer_t* ad, demuxer_t* sd);
 
@@ -333,3 +347,7 @@
 
 extern void demuxer_help(void);
 extern int get_demuxer_type_from_name(char *demuxer_name, int *force);
+
+void demuxer_set_max_packet(demuxer_t *demuxer, int maxvideopacket, int maxaudiopacket, int hideflg);
+
+void demuxer_update_time_length(demuxer_t *demuxer, off_t startpos, off_t endpos);
--- libmpdemux/stream.c	2005-12-14 22:52:41.000000000 +0100
+++ libmpdemux/stream.c	2006-02-10 00:01:16.000000000 +0100
@@ -116,7 +116,7 @@
   &stream_info_dvd,
 #endif
 #ifdef USE_DVDNAV
-  &stream_info_dvdnav;
+  &stream_info_dvdnav,
 #endif
 
   &stream_info_null,
--- libmpdemux/stream.h	2005-11-18 15:39:20.000000000 +0100
+++ libmpdemux/stream.h	2006-02-10 00:01:16.000000000 +0100
@@ -267,9 +267,6 @@
 
 extern char * audio_stream;
 
-#ifdef USE_DVDNAV
-#include "dvdnav_stream.h"
-#endif
 
 #ifdef USE_DVDREAD
 
@@ -330,6 +327,10 @@
 int dvd_sid_from_lang(stream_t *stream, unsigned char* lang);
 int dvd_chapter_from_cell(dvd_priv_t *dvd,int title,int cell);
 
+//#ifdef USE_MPDVDNAV
+//#include "stream_dvdnav.h"
+//#endif
+
 #endif
 							    
 #endif // __STREAM_H
--- libmpdemux/stheader.h	2005-02-25 12:17:43.000000000 +0100
+++ libmpdemux/stheader.h	2006-02-11 09:39:53.000000000 +0100
@@ -80,6 +80,12 @@
   void* ImageDesc; // for quicktime codecs
   // codec-specific:
   void* context;   // codec-specific stuff (usually HANDLE or struct pointer)
+#ifdef USE_MPDVDNAV
+  int config_lock;
+  int config_w;
+  int config_h;
+  unsigned int config_outfmt;
+#endif
 } sh_video_t;
 
 // demuxer.c:
--- libmpdemux/demux_mpg.c	2006-02-09 20:39:51.000000000 +0100
+++ libmpdemux/demux_mpg.c	2006-02-11 18:46:00.000000000 +0100
@@ -836,6 +836,44 @@
             *((int*)arg) = demuxer->audio->id;
             return DEMUXER_CTRL_OK;
 
+	case DEMUXER_CTRL_SET_TIME_LENGTH: {
+//                demuxer->movi_end=((off_t *)arg);
+/* calc timestamp */
+		stream_t *s = demuxer->stream;
+		off_t pos = stream_tell(s);
+//		off_t end_seq_start = demuxer->movi_end-500000; // 500000 is a wild guess
+		off_t end_seq_start = demuxer->movi_end-50000; // 500000 is a wild guess
+		float half_pts = 0.0;
+		if (!ds_fill_buffer(demuxer->video)) return DEMUXER_CTRL_DONTKNOW;
+		mpg_d->final_pts = 0.0;
+		mpg_d->has_valid_timestamps = 1;
+		mpg_d->num_a_streams = 0;
+		if (demuxer->seekable && stream_tell(demuxer->stream) < end_seq_start) {
+		    stream_seek(s,(pos + end_seq_start / 2));
+		    while ((!s->eof) && ds_fill_buffer(demuxer->video) && half_pts == 0.0) {
+    			half_pts = mpg_d->last_pts;
+			}
+		stream_seek(s,end_seq_start);
+		while ((!s->eof) && ds_fill_buffer(demuxer->video)) {
+    		    if (mpg_d->final_pts < mpg_d->last_pts) mpg_d->final_pts = mpg_d->last_pts;
+		    }
+		// educated guess about validity of timestamps
+		if (mpg_d->final_pts > 3 * half_pts || mpg_d->final_pts < 1.5 * half_pts) {
+    		    mpg_d->has_valid_timestamps = 0;
+		    }
+		ds_free_packs(demuxer->audio);
+		ds_free_packs(demuxer->video);
+		demuxer->stream->eof=0; // clear eof flag
+		demuxer->video->eof=0;
+		demuxer->audio->eof=0;
+
+//		stream_seek(s,pos);
+		stream_seek(s,0);
+		ds_fill_buffer(demuxer->video);
+		}
+              return DEMUXER_CTRL_OK;
+	      }
+
 	default:
 	    return DEMUXER_CTRL_NOTIMPL;
     }
--- libmpdemux/demux_avi.c	2006-02-09 20:39:51.000000000 +0100
+++ libmpdemux/demux_avi.c	2006-02-10 00:01:16.000000000 +0100
@@ -891,7 +891,7 @@
       stream_t* s;
       demuxer_t  *od;
       s = new_ds_stream(demuxer->audio);
-      od = new_demuxer(s,DEMUXER_TYPE_OGG,-1,-2,-2,NULL);
+      od = new_demuxer(s,DEMUXER_TYPE_OGG,-1,-2,-2,NULL,0,0,0);
       if(!demux_ogg_open(od)) {
         mp_msg( MSGT_DEMUXER,MSGL_ERR,MSGTR_ErrorOpeningOGGDemuxer);
         free_stream(s);
--- libmpdemux/demux_ogg.c	2006-02-09 15:07:56.000000000 +0100
+++ libmpdemux/demux_ogg.c	2006-02-10 00:01:16.000000000 +0100
@@ -1388,7 +1388,7 @@
 
   // Create the ds_stream and the ogg demuxer
   s = new_ds_stream(demuxer->audio);
-  od = new_demuxer(s,DEMUXER_TYPE_OGG,0,-2,-2,NULL);
+  od = new_demuxer(s,DEMUXER_TYPE_OGG,0,-2,-2,NULL,0,0,0);
 
   /// Add the header packets in the ogg demuxer audio stream
   // Initial header
--- libmpdemux/demux_rtp.cpp	2005-09-24 00:35:03.000000000 +0200
+++ libmpdemux/demux_rtp.cpp	2006-02-10 00:01:16.000000000 +0100
@@ -237,7 +237,7 @@
   if (demux_is_multiplexed_rtp_stream(demuxer)) {
     stream_t* s = new_ds_stream(demuxer->video);
     demuxer_t* od = demux_open(s, DEMUXER_TYPE_UNKNOWN,
-			       audio_id, video_id, dvdsub_id, NULL);
+			       audio_id, video_id, dvdsub_id, NULL, 0, 0, 0);
     demuxer = new_demuxers_demuxer(od, od, od);
   }
 
--- libmpdemux/test.c	2005-11-18 15:39:20.000000000 +0100
+++ libmpdemux/test.c	2006-02-10 00:01:16.000000000 +0100
@@ -69,7 +69,7 @@
   if(stream_cache_size)
       stream_enable_cache(stream,stream_cache_size,0,0);
 
-  demuxer=demux_open(stream,file_format,-1,-1,-1,NULL);
+  demuxer=demux_open(stream,file_format,-1,-1,-1,NULL,0,0,0);
   if(!demuxer){
 	printf("Cannot open demuxer\n");
 	exit(1);
--- libvo/sub.h	2006-02-09 15:07:59.000000000 +0100
+++ libvo/sub.h	2006-02-10 00:01:16.000000000 +0100
@@ -10,6 +10,11 @@
 #define OSDTYPE_SUBTITLE 2
 #define OSDTYPE_PROGBAR 3
 #define OSDTYPE_SPU 4
+#ifdef USE_DVDNAV
+#ifdef USE_MPDVDNAV
+#define OSDTYPE_DVDNAV 5
+#endif
+#endif
 
 #define OSDFLAG_VISIBLE 1
 #define OSDFLAG_CHANGED 2
--- libvo/sub.c	2006-02-09 15:07:58.000000000 +0100
+++ libvo/sub.c	2006-02-10 00:01:16.000000000 +0100
@@ -67,6 +67,14 @@
 int sub_bg_color=0; /* subtitles background color */
 int sub_bg_alpha=0;
 int sub_justify=0;
+#ifdef USE_MPDVDNAV
+uint16_t  dvdnav_sx=0;
+uint16_t  dvdnav_ex=0;
+uint16_t  dvdnav_sy=0;
+uint16_t  dvdnav_ey=0;
+int	  dvdnav_show=0;
+
+#endif
 
 // return the real height of a char:
 static inline int get_height(int c,int h){
@@ -177,6 +185,49 @@
         }
 }
 
+#ifdef USE_DVDNAV
+#ifdef USE_MPDVDNAV
+#undef max
+#define max(x,y) ((x) > (y) ? (x) : (y))
+#undef min
+#define min(x,y) ((x) < (y) ? (x) : (y))
+
+void dvdnav_box_area(int sx, int sy, int ex, int ey, int show)
+{
+  dvdnav_sx=min(sx,ex);
+  dvdnav_ex=max(sx,ex);
+  dvdnav_sy=min(sy,ey);
+  dvdnav_ey=max(sy,ey);
+  dvdnav_show=show;
+}
+
+
+inline static void vo_update_dvdnav(mp_osd_obj_t* obj,int dxs,int dys){
+
+unsigned char * bitmap_buffer;
+unsigned char * alpha_buffer;
+int len;
+int stride;
+
+if (dvdnav_show)
+    {
+    obj->bbox.x1=obj->x=dvdnav_sx;
+    obj->bbox.y1=obj->y=dvdnav_sy;
+    obj->bbox.x2=dvdnav_ex;
+    obj->bbox.y2=dvdnav_ey;
+    alloc_buf(obj);
+    len = obj->stride*(obj->bbox.y2-obj->bbox.y1);
+    memset(obj->bitmap_buffer,0x7f,len);
+    memset(obj->alpha_buffer,0x7f,len);
+    obj->flags|=OSDFLAG_BBOX|OSDFLAG_VISIBLE|OSDFLAG_CHANGED;
+    }
+    else
+    obj->flags&=~OSDFLAG_VISIBLE;
+}
+
+#endif
+#endif
+
 int vo_osd_progbar_type=-1;
 int vo_osd_progbar_value=100;   // 0..256
 
@@ -801,6 +852,14 @@
         int vis=obj->flags&OSDFLAG_VISIBLE;
 	obj->flags&=~OSDFLAG_BBOX;
 	switch(obj->type){
+#ifdef USE_DVDNAV
+#ifdef USE_MPDVDNAV
+	case OSDTYPE_DVDNAV:
+	    vo_update_dvdnav(obj,dxs,dys);
+    	    obj->flags|=OSDFLAG_CHANGED;
+	    break;
+#endif
+#endif
 	case OSDTYPE_SUBTITLE:
 	    vo_update_text_sub(obj,dxs,dys);
 	    break;
@@ -868,6 +927,11 @@
     new_osd_obj(OSDTYPE_SUBTITLE);
     new_osd_obj(OSDTYPE_PROGBAR);
     new_osd_obj(OSDTYPE_SPU);
+#ifdef USE_DVDNAV
+#ifdef USE_MPDVDNAV
+    new_osd_obj(OSDTYPE_DVDNAV);
+#endif
+#endif
 #ifdef HAVE_FREETYPE
     force_load_font = 1;
 #endif
@@ -903,6 +967,11 @@
 	case OSDTYPE_SPU:
 	    vo_draw_spudec_sub(obj, draw_alpha); // FIXME
 	    break;
+#ifdef USE_DVDNAV
+#ifdef USE_MPDVDNAV
+	case OSDTYPE_DVDNAV:
+#endif
+#endif
 	case OSDTYPE_OSD:
 	case OSDTYPE_SUBTITLE:
 	case OSDTYPE_PROGBAR:
--- libmpcodecs/Makefile	2006-02-01 00:45:46.000000000 +0100
+++ libmpcodecs/Makefile	2006-02-10 00:01:16.000000000 +0100
@@ -71,6 +71,7 @@
                vd_xvid4.c \
                vd_xvid.c \
                vd_zrmjpeg.c \
+               vd_videostill.c \
 
 ifeq ($(CONFIG_LIBAVCODEC),yes)
 VIDEO_SRCS_OPT+=vd_ffmpeg.c
--- libmpcodecs/vd_libmpeg2.c	2005-11-18 15:39:22.000000000 +0100
+++ libmpcodecs/vd_libmpeg2.c	2006-02-11 15:13:25.000000000 +0100
@@ -156,14 +156,34 @@
 	    // video parameters inited/changed, (re)init libvo:
 	    if (info->sequence->width >> 1 == info->sequence->chroma_width &&
 		info->sequence->height >> 1 == info->sequence->chroma_height) {
+#ifdef USE_MPDVDNAV
+//printf("lock: %i w:%i (%i) h: %i (%i) fmt: %i (%i) \n",sh->config_lock,sh->config_w,info->sequence->picture_width,
+//    sh->config_h,info->sequence->picture_height,sh->config_outfmt,IMGFMT_YV12);
+		if (sh->config_lock && sh->config_w==info->sequence->picture_width &&
+		    sh->config_h ==info->sequence->picture_height && sh->config_outfmt == IMGFMT_YV12) break;
+#endif
 		if(!mpcodecs_config_vo(sh,
 				       info->sequence->picture_width,
 				       info->sequence->picture_height, IMGFMT_YV12)) return 0;
+#ifdef USE_MPDVDNAV
+		if(sh->config_lock) {sh->config_w=info->sequence->picture_width; 
+		    sh->config_h=info->sequence->picture_height; sh->config_outfmt=IMGFMT_YV12;}
+#endif
 	    } else if (info->sequence->width >> 1 == info->sequence->chroma_width &&
 		info->sequence->height == info->sequence->chroma_height) {
+#ifdef USE_MPDVDNAV
+//printf("lock: %i w:%i (%i) h: %i (%i) fmt: %i (%i) \n",sh->config_lock,sh->config_w,info->sequence->picture_width,
+//    sh->config_h,info->sequence->picture_height,sh->config_outfmt,IMGFMT_422P);
+		if (sh->config_lock && sh->config_w==info->sequence->picture_width &&
+		    sh->config_h ==info->sequence->picture_height && sh->config_outfmt == IMGFMT_422P) break;
+#endif
 		if(!mpcodecs_config_vo(sh,
 				       info->sequence->picture_width,
 				       info->sequence->picture_height, IMGFMT_422P)) return 0;
+#ifdef USE_MPDVDNAV
+		if(sh->config_lock) {sh->config_w=info->sequence->picture_width; 
+		    sh->config_h=info->sequence->picture_height; sh->config_outfmt=IMGFMT_422P;}
+#endif
 	    } else return 0;
 	    break;
 	case STATE_PICTURE:
--- help/help_mp-en.h	2006-01-30 20:37:17.000000000 +0100
+++ help/help_mp-en.h	2006-02-10 00:01:16.000000000 +0100
@@ -24,6 +24,10 @@
 #ifdef USE_DVDREAD
 " dvd://<titleno>   play DVD title from device instead of plain file\n"
 " -alang/-slang    select DVD audio/subtitle language (by 2-char country code)\n"
+#ifdef USE_MPDVDNAV
+" -mlang           select DVD menu language (by 2-char country code)\n"
+" -dvdnav-menutype set DVD menu button type: 0: spu (default), 1: simple box, 2: spu & simple box\n"
+#endif
 #endif
 " -ss <timepos>    seek to given (seconds or hh:mm:ss) position\n"
 " -nosound         do not play sound\n"
@@ -1408,3 +1412,153 @@
 #define MSGTR_MPDEMUX_NW_NoPasswdProvidedTryingBlank "No password provided, trying blank password.\n"
 #define MSGTR_MPDEMUX_NW_ErrServerReturned "Server return %d: %s\n"
 #define MSGTR_MPDEMUX_NW_CacheSizeSetTo "Cache size set to %d KBytes\n"
+
+// mpdvdnav - gui
+#define MSGTR_MENU_DVDNAV "DVDNAV"
+#define MSGTR_MENU_PlayDVDNAV "Play DVDNAV..."
+#define MSGTR_MENU_MenuDVDNAV "Main DVD Menu"
+
+// mpdvdnav
+
+#define MSGTR_MPDVDNAV_StopEvent "DVDNAV Event: STOP!\n"
+#define MSGTR_MPDVDNAV_WaitEvent "DVDNAV Event: Wait\n"
+#define MSGTR_MPDVDNAV_StillFrameEvent "DVDNAV Event: Still frame\n"
+#define MSGTR_MPDVDNAV_VtsChangeEvent "DVDNAV Event: Vts change\n"
+#define MSGTR_MPDVDNAV_CellChangeEvent "DVDNAV Event: Cell change\n"
+#define MSGTR_MPDVDNAV_SpuClutChangeEvent "DVDNAV Event: Spu clut change\n"
+#define MSGTR_MPDVDNAV_HighlightEvent "DVDNAV Event: Highlight\n"
+#define MSGTR_MPDVDNAV_NavPacketEvent "DVDNAV Event: Nav packet\n"
+
+#define MSGTR_MPDVDNAV_StillFrameDecodeError "Still frame decode error\n"
+#define MSGTR_MPDVDNAV_StillSkip "Dvdnav still skip\n"
+#define MSGTR_MPDVDNAV_CellN "cellN      : %i\n"
+#define MSGTR_MPDVDNAV_PgN "pgN        : %d\n"
+#define MSGTR_MPDVDNAV_CellLength "cell_length: %d\n"
+#define MSGTR_MPDVDNAV_PgLength "pg_lenght  : %d\n"
+#define MSGTR_MPDVDNAV_PgcLength "pgc_lenght : %d\n"
+#define MSGTR_MPDVDNAV_CellStart "cell_start : %d\n"
+#define MSGTR_MPDVDNAV_PgStart "pg_start   : %d\n"
+#define MSGTR_MPDVDNAV_Title "DVDNAV new title: %i\n"
+#define MSGTR_MPDVDNAV_Part  "DVDNAV new part: %i\n"
+#define MSGTR_MPDVDNAV_Aspect43 "Aspect 4/3\n"
+#define MSGTR_MPDVDNAV_Aspect169 "Aspect 16/9\n"
+#define MSGTR_MPDVDNAV_AspectOther "Aspect ? (%i)\n"
+#define MSGTR_MPDVDNAV_AudioID "DVDNAV new audio ID: %i\n"
+#define MSGTR_MPDVDNAV_DvdSubID "DVDNAV new dvdsub ID: %i\n"
+#define MSGTR_MPDVDNAV_Len "DVDNAV len: %i\n"
+#define MSGTR_MPDVDNAV_ReadInStillActive "%s: got a stream_read while I should be asleep!\n"
+#define MSGTR_MPDVDNAV_ErrorGetNextBlock "Error getting next block from DVD (%s)\n"
+#define MSGTR_MPDVDNAV_ErrorStreamRead "DVDNAV stream read error: %s\n"
+#define MSGTR_MPDVDNAV_ErrorSeek "DVDNAV stream seek error: %s (%llx)\n"
+#define MSGTR_MPDVDNAV_ErrorNav "DVDNAV navigation error: %s\n"
+
+// ----------------------- libmpdvdnav error -----------------------
+// libmpdvdnav - dvdnav.c
+#define MSGTR_LIBMPDVDNAV_ErrorInitialisingTheDVDVM "Error initialising the DVD VM.\n"
+#define MSGTR_LIBMPDVDNAV_ErrorStartingTheVM "Error starting the VM / opening the DVD device.\n"
+#define MSGTR_LIBMPDVDNAV_PassedANullPointer "Passed a NULL pointer.\n"
+#define MSGTR_LIBMPDVDNAV_VirtualDVDMachineNotStarted "Virtual DVD machine not started.\n"
+#define MSGTR_LIBMPDVDNAV_ErrorRestartingTheVM "Error restarting the VM.\n"
+#define MSGTR_LIBMPDVDNAV_ErrorReadingNAVPacket "Error reading NAV packet.\n"
+#define MSGTR_LIBMPDVDNAV_ExpectedNAVPacketButNoneFound "Expected NAV packet but none found.\n"
+#define MSGTR_LIBMPDVDNAV_UnknownDomainWhenChangingVTS "Unknown domain when changing VTS.\n"
+#define MSGTR_LIBMPDVDNAV_ErrorOpeningVtsDomain "Error opening vtsN=%i, domain=%i.\n"
+#define MSGTR_LIBMPDVDNAV_ErrorReadingNAVPacket "Error reading NAV packet.\n"
+#define MSGTR_LIBMPDVDNAV_AttemptingToReadWithoutOpeningFile "Attempting to read without opening file.\n"
+#define MSGTR_LIBMPDVDNAV_ErrorReadingFromDVD "Error reading from DVD.\n"
+#define MSGTR_LIBMPDVDNAV_NoCurrentPGC "No current PGC.\n"
+#define MSGTR_LIBMPDVDNAV_PassedAnInvalidAngleNumber "Passed an invalid angle number.\n"
+// libmpdvdnav - searching.c
+#define MSGTR_LIBMPDVDNAV_CannotSeekInAStillFrame "Cannot seek in a still frame.\n"
+#define MSGTR_LIBMPDVDNAV_RequestToSeekBehindEnd "Request to seek behind end.\n"
+#define MSGTR_LIBMPDVDNAV_RequestToSeekBeforeStart "Request to seek before start.\n"
+#define MSGTR_LIBMPDVDNAV_IllegalSeekMode "Illegal seek mode."
+#define MSGTR_LIBMPDVDNAV_ErrorErrorWhenSeeking "Error when seeking.\n"
+#define MSGTR_LIBMPDVDNAV_SkipToPreviousChapterFailed "Skip to previous chapter failed.\n"
+#define MSGTR_LIBMPDVDNAV_SkipToTopChapterFailed "Skip to top chapter failed.\n"
+#define MSGTR_LIBMPDVDNAV_SkipToNextChapterFailed "Skip to next chapter failed.\n"
+#define MSGTR_LIBMPDVDNAV_NoSuchMenuOrMenuNotReachable "No such menu or menu not reachable.\n"
+#define MSGTR_LIBMPDVDNAV_NewPositionNotYetDetermined "New position not yet determined.\n"
+// libmpdvdnav - highlight.c
+#define MSGTR_LIBMPDVDNAV_BadVMState "Bad VM state.\n"
+#define MSGTR_LIBMPDVDNAV_PassedATitleNumberOutOfRange "Passed a title number out of range.\n"
+#define MSGTR_LIBMPDVDNAV_NotInATitleOrMenu "Not in a title or menu.\n"
+#define MSGTR_LIBMPDVDNAV_TitleOutOfRange "Title out of range.\n"
+#define MSGTR_LIBMPDVDNAV_PartOutOfRange "Part out of range.\n"
+#define MSGTR_LIBMPDVDNAV_NotImplementedYet "Not implemented yet.\n"
+#define MSGTR_LIBMPDVDNAV_NotInAMenu "Not in a menu."
+#define MSGTR_LIBMPDVDNAV_ThisNAVHasAlreadyBeenLeft "This NAV has already been left."
+#define MSGTR_LIBMPDVDNAV_ButtonDoesNotExist "Button does not exist."
+// libmpdvdnav - settings.c
+#define MSGTR_LIBMPDVDNAV_PassedIllegalLanguageCode "Passed illegal language code.\n"
+
+// ----------------------- libmpdvdnav -----------------------------
+// libmpdvdnav - dvdnav.c
+#define MSGTR_LIBMPDVDNAV_Using "libdvdnav: Using dvdnav version %s from http://dvd.sf.net\n"
+#define MSGTR_LIBMPDVDNAV_Demux_error "libdvdnav: demux error! %02x %02x %02x (should be 0x000001) \n"
+// libmpdvdnav - read_cache.c
+#define MSGTR_LIBMPDVDNAV_PreCacheDVDReadReallocHappened "pre_cache DVD read realloc happened\n"
+#define MSGTR_LIBMPDVDNAV_PreCacheDVDReadMalloc "pre_cache DVD read malloc %d blocks\n"
+#define MSGTR_LIBMPDVDNAV_PreCachingWasImpossible "pre_caching was impossible, no cache chunk available\n"
+#define MSGTR_LIBMPDVDNAV_ReadCacheSectorInfo "libdvdnav: sector=%d, start_sector=%d, last_sector=%d\n"
+#define MSGTR_LIBMPDVDNAV_ReadCacheReadAheadSize "libdvdnav: read_ahead_size=%d, size=%d\n"
+#define MSGTR_LIBMPDVDNAV_CacheMissOnSector "cache miss on sector %d\n"
+// libmpdvdnav - remap.c
+#define MSGTR_LIBMPDVDNAV_UnableToFindMapFile "libdvdnav: Unable to find map file '%s'\n"
+#define MSGTR_LIBMPDVDNAV_IgnoringMapLine "libdvdnav: Ignoring map line (%d): %s\n"
+#define MSGTR_LIBMPDVDNAV_RemapInfo "libdvdnav: %s: domain %d, title %d, program %d, start %lx, next %lx\n"
+#define MSGTR_LIBMPDVDNAV_RedirectedTo "libdvdnav: Redirected to %lx\n"
+// libmpdvdnav - searching.c
+#define MSGTR_LIBMPDVDNAV_UnknownDomainForSeeking "libdvdnav: Error: Unknown domain for seeking.\n"
+#define MSGTR_LIBMPDVDNAV_CouldNotLocateBlock "libdvdnav: Could not locate block\n"
+#define MSGTR_LIBMPDVDNAV_AdmapNotLocated "libdvdnav: admap not located\n"
+#define MSGTR_LIBMPDVDNAV_ErrorWhenSeeking "libdvdnav: Error when seeking\n"
+#define MSGTR_LIBMPDVDNAV_FIXMEImplementSeekingToLocation "libdvdnav: FIXME: Implement seeking to location %u\n"
+#define MSGTR_LIBMPDVDNAV_PreviousChapterFailed "libdvdnav: previous chapter failed.\n"
+#define MSGTR_LIBMPDVDNAV_TopChapterFailed "libdvdnav: top chapter failed.\n"
+#define MSGTR_LIBMPDVDNAV_NextChapterFailed "libdvdnav: next chapter failed.\n"
+#define MSGTR_LIBMPDVDNAV_SearchChapterFailed "libdvdnav: search chapter failed.\n"
+// libmpdvdnav - decoder.c
+#define MSGTR_LIBMPDVDNAV_BadCallToVMGetbits "libdvdnav: Bad call to vm_getbits. Parameter out of range\n"
+#define MSGTR_LIBMPDVDNAV_SuspectedRCERegionProtection "libdvdnav: Suspected RCE Region Protection!!!\n"
+#define MSGTR_LIBMPDVDNAV_EvalCompareInvalidComparisonCode "libdvdnav: eval_compare: Invalid comparison code\n"
+#define MSGTR_LIBMPDVDNAV_UnknownInstrution "libdvdnav: Unknown Instruction!\n"
+#define MSGTR_LIBMPDVDNAV_WarningUnknownComman "libdvdnav: WARNING: Unknown Command=%x\n"
+#define MSGTR_LIBMPDVDNAV_DecoderCWarningUnknownBits "libdvdnav: decoder.c: [WARNING, unknown bits:"
+#define MSGTR_LIBMPDVDNAV_DecoderCButton "libdvdnav: %s (button %d)\n"
+#define MSGTR_LIBMPDVDNAV_DecoderCButton2 "libdvdnav: %s %d (button %d)\n"
+#define MSGTR_LIBMPDVDNAV_DecoderCVtsTitleMenu "libdvdnav: %s vts %d title %d menu %d\n"
+#define MSGTR_LIBMPDVDNAV_DecoderCResumeCell "libdvdnav: %s resume cell %d\n"
+#define MSGTR_LIBMPDVDNAV_DecoderCResumeCell2 "libdvdnav: %s %d resume cell %d\n"
+// libmpdvdnav - vm.c
+#define MSGTR_LIBMPDVDNAV_VmCDVDTitle "libdvdnav: DVD Title: "
+#define MSGTR_LIBMPDVDNAV_VmCDVDSerialNumber "\nlibdvdnav: DVD Serial Number: "
+#define MSGTR_LIBMPDVDNAV_VmCDVDTitleAlternative "\nlibdvdnav: DVD Title (Alternative): "
+#define MSGTR_LIBMPDVDNAV_VmCCantReadNameBlock "libdvdnav: Can't read name block. Probably not a DVD-ROM device.\n"
+#define MSGTR_LIBMPDVDNAV_VmCCantSeekToBlock "libdvdnav: Can't seek to block %u\n"
+#define MSGTR_LIBMPDVDNAV_VmCNameOpenFailed "NAME OPEN FAILED\n"
+#define MSGTR_LIBMPDVDNAV_VmCIfoOpenVTSIFailed "libdvdnav: ifoOpenVTSI failed - CRASHING!!!\n"
+#define MSGTR_LIBMPDVDNAV_VmCIfoReadVTSPTTSRPTFailed "libdvdnav: ifoRead_VTS_PTT_SRPT failed - CRASHING!!!\n"
+#define MSGTR_LIBMPDVDNAV_VmCIfoReadPGCITFailed "libdvdnav: ifoRead_PGCIT failed - CRASHING!!!\n"
+#define MSGTR_LIBMPDVDNAV_VmCIfoReadPGCIUTFailed "libdvdnav: ifoRead_PGCI_UT failed - CRASHING!!!\n"
+#define MSGTR_LIBMPDVDNAV_VmCIfoReadVOBUADMAPVtsiFailed "libdvdnav: ifoRead_VOBU_ADMAP vtsi failed - CRASHING\n"
+#define MSGTR_LIBMPDVDNAV_VmCIfoReadTITLEVOBUADMAPVtsiFailed "libdvdnav: ifoRead_TITLE_VOBU_ADMAP vtsi failed - CRASHING\n"
+#define MSGTR_LIBMPDVDNAV_VmCVmFaildToOpenReadTheDVD "libdvdnav: vm: faild to open/read the DVD\n"
+#define MSGTR_LIBMPDVDNAV_VmCVmFaildToReadVIDEOTSIFO "libdvdnav: vm: faild to read VIDEO_TS.IFO\n"
+#define MSGTR_LIBMPDVDNAV_VmCVmIfoReadFPPGCFailed "libdvdnav: vm: ifoRead_FP_PGC failed\n"
+#define MSGTR_LIBMPDVDNAV_VmCVmIfoReadTTSRPTFailed "libdvdnav: vm: ifoRead_TT_SRPT failed\n"
+#define MSGTR_LIBMPDVDNAV_VmCVmIfoReadPGCIUTFailed "libdvdnav: vm: ifoRead_PGCI_UT failed\n"
+#define MSGTR_LIBMPDVDNAV_VmCVmIfoReadPRLMAITFailed "libdvdnav: vm: ifoRead_PTL_MAIT failed\n"
+#define MSGTR_LIBMPDVDNAV_VmCVmIfoReadVTSATRTFailed "libdvdnav: vm: ifoRead_VTS_ATRT failed\n"
+#define MSGTR_LIBMPDVDNAV_VmCVmIfoReadVOBUADMAPVgmiFailed "libdvdnav: vm: ifoRead_VOBU_ADMAP vgmi failed\n"
+#define MSGTR_LIBMPDVDNAV_VmCDVDDiskReportsItselfWithRegionMask "libdvdnav: DVD disk reports itself with Region mask 0x%08x. Regions:"
+#define MSGTR_LIBMPDVDNAV_VmCChapterNotFound "libdvdnav: chapter NOT FOUND!\n"
+#define MSGTR_LIBMPDVDNAV_VmCInvalidAngleBlock "libdvdnav: Invalid angle block\n"
+#define MSGTR_LIBMPDVDNAV_VmCInvalidBlockMode "libdvdnav: Invalid? Cell block_mode (%d), block_type (%d)\n"
+#define MSGTR_LIBMPDVDNAV_VmCCellIsInBlockButDidNotEnter "libdvdnav: Cell is in block but did not enter at first cell!\n"
+#define MSGTR_LIBMPDVDNAV_VmCTryingToResumeWithoutAnyResume "libdvdnav: trying to resume without any resume info set\n"
+#define MSGTR_LIBMPDVDNAV_VmCRandomOrShuffleTitlesAreNotHandledYet "libdvdnav: RANDOM or SHUFFLE titles are NOT handled yet.\n"
+#define MSGTR_LIBMPDVDNAV_VmCGetPGCNFailed "libdvdnav: get_PGCN failed. Was trying to find pgcN in domain %d\n"
+#define MSGTR_LIBMPDVDNAV_VmCPgciUtHandleIsNULL "libdvdnav: *** pgci_ut handle is NULL ***\n"
+#define MSGTR_LIBMPDVDNAV_VmCLanguageNotFound "libdvdnav: Language '%c%c' not found, using '%c%c' instead\n"
+#define MSGTR_LIBMPDVDNAV_VmCMenuLanguagesAvailable "libdvdnav: Menu Languages available: "
