From 2af0f16f1fdadf1e85493f8506d441df09199fa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Sat, 23 Oct 2010 13:18:24 +0200 Subject: mingw32-w64 port: '-no-undefined' part - use -no-undefined flag only for building shared libraries (libxine, plugins) - plugins LDFLAGS unification - move -no-undefined into LDFLAGS_NOUNDEFINED - attributes.m4 fix --- src/audio_out/Makefile.am | 18 ++--------------- src/demuxers/Makefile.am | 1 - src/dxr3/Makefile.am | 6 +++--- src/input/Makefile.am | 34 ++++++++++++++++---------------- src/input/libdvdnav/Makefile.am | 2 +- src/input/librtsp/Makefile.am | 2 +- src/input/vcd/Makefile.am | 2 +- src/libspucc/Makefile.am | 2 +- src/libxineadec/gsm610/Makefile.am | 2 +- src/post/audio/Makefile.am | 2 +- src/post/deinterlace/Makefile.am | 2 +- src/post/deinterlace/plugins/Makefile.am | 2 +- src/post/goom/Makefile.am | 2 +- src/post/mosaico/Makefile.am | 4 ++-- src/post/planar/Makefile.am | 2 +- src/post/visualizations/Makefile.am | 2 +- src/xine-engine/Makefile.am | 2 +- 17 files changed, 36 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/audio_out/Makefile.am b/src/audio_out/Makefile.am index 745fafadd..750d03915 100644 --- a/src/audio_out/Makefile.am +++ b/src/audio_out/Makefile.am @@ -2,6 +2,7 @@ include $(top_builddir)/misc/Makefile.plugins include $(top_srcdir)/misc/Makefile.common AM_CPPFLAGS = -DXINE_COMPILE +AM_LDFLAGS = $(xineplug_ldflags) EXTRA_DIST = audio_irixal_out.c @@ -77,81 +78,66 @@ xineplug_LTLIBRARIES = xineplug_ao_out_none.la xineplug_ao_out_file.la \ xineplug_ao_out_none_la_SOURCES = audio_none_out.c xineplug_ao_out_none_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) xineplug_ao_out_none_la_CFLAGS = $(VISIBILITY_FLAG) -xineplug_ao_out_none_la_LDFLAGS = -avoid-version -module xineplug_ao_out_file_la_SOURCES = audio_file_out.c xineplug_ao_out_file_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) xineplug_ao_out_file_la_CFLAGS = $(VISIBILITY_FLAG) -xineplug_ao_out_file_la_LDFLAGS = -avoid-version -module xineplug_ao_out_oss_la_SOURCES = audio_oss_out.c xineplug_ao_out_oss_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) xineplug_ao_out_oss_la_CFLAGS = $(VISIBILITY_FLAG) -xineplug_ao_out_oss_la_LDFLAGS = -avoid-version -module xineplug_ao_out_alsa_la_SOURCES = audio_alsa_out.c xineplug_ao_out_alsa_la_LIBADD = $(XINE_LIB) $(ALSA_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_ao_out_alsa_la_CFLAGS = $(VISIBILITY_FLAG) $(ALSA_CFLAGS) -xineplug_ao_out_alsa_la_LDFLAGS = -avoid-version -module xineplug_ao_out_esd_la_SOURCES = audio_esd_out.c xineplug_ao_out_esd_la_LIBADD = $(XINE_LIB) $(ESD_LIBS) $(LTLIBINTL) xineplug_ao_out_esd_la_CFLAGS = $(VISIBILITY_FLAG) $(ESD_CFLAGS) -xineplug_ao_out_esd_la_LDFLAGS = -avoid-version -module xineplug_ao_out_sun_la_SOURCES = audio_sun_out.c xineplug_ao_out_sun_la_LIBADD = $(XINE_LIB) xineplug_ao_out_sun_la_CFLAGS = $(VISIBILITY_FLAG) -xineplug_ao_out_sun_la_LDFLAGS = -avoid-version -module #xineplug_ao_out_irixal_la_SOURCES = audio_irixal_out.c #xineplug_ao_out_irixal_la_LIBADD = $(IRIXAL_LIBS) #xineplug_ao_out_irixal_la_CFLAGS = $(VISIBILITY_FLAG) $(IRIXAL_CFLAGS) -#xineplug_ao_out_irixal_la_LDFLAGS = -avoid-version -module xineplug_ao_out_arts_la_SOURCES = audio_arts_out.c xineplug_ao_out_arts_la_LIBADD = $(XINE_LIB) $(ARTS_LIBS) xineplug_ao_out_arts_la_CFLAGS = $(VISIBILITY_FLAG) $(ARTS_CFLAGS) -xineplug_ao_out_arts_la_LDFLAGS = -avoid-version -module xineplug_ao_out_directx_la_SOURCES = audio_directx_out.c xineplug_ao_out_directx_la_CPPFLAGS = $(DIRECTX_CPPFLAGS) xineplug_ao_out_directx_la_LIBADD = $(XINE_LIB) $(DIRECTX_AUDIO_LIBS) $(LTLIBINTL) xineplug_ao_out_directx_la_CFLAGS = $(VISIBILITY_FLAG) -xineplug_ao_out_directx_la_LDFLAGS = -avoid-version -module xineplug_ao_out_coreaudio_la_SOURCES = audio_coreaudio_out.c xineplug_ao_out_coreaudio_la_LIBADD = $(XINE_LIB) # The "-Wl,-framework -Wl,..." is needed for libtool versions before # 1.5.x (1.257): the default version that ships with Mac OS X is 1.5 (1.1220) -xineplug_ao_out_coreaudio_la_LDFLAGS = \ +xineplug_ao_out_coreaudio_la_LDFLAGS = $(AM_LDFLAGS) \ -Wl,-framework -Wl,Cocoa -framework CoreAudio \ -Wl,-framework -Wl,AudioUnit -framework AudioUnit \ - -avoid-version -module xineplug_ao_out_coreaudio_la_CFLAGS = -framework CoreAudio -framework AudioUnit $(VISIBILITY_FLAG) xineplug_ao_out_pulseaudio_la_SOURCES = audio_pulse_out.c xineplug_ao_out_pulseaudio_la_LIBADD = $(XINE_LIB) $(PULSEAUDIO_LIBS) $(LTLIBINTL) xineplug_ao_out_pulseaudio_la_CFLAGS = $(VISIBILITY_FLAG) $(PULSEAUDIO_CFLAGS) -xineplug_ao_out_pulseaudio_la_LDFLAGS = -avoid-version -module xineplug_ao_out_directx2_la_SOURCES = audio_directx2_out.c xineplug_ao_out_directx2_la_CPPFLAGS = $(DIRECTX_CPPFLAGS) xineplug_ao_out_directx2_la_LIBADD = $(XINE_LIB) $(DIRECTX_AUDIO_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_ao_out_directx2_la_CFLAGS = $(VISIBILITY_FLAG) -xineplug_ao_out_directx2_la_LDFLAGS = -avoid-version -module xineplug_ao_out_fusionsound_la_SOURCES = audio_fusionsound_out.c xineplug_ao_out_fusionsound_la_LIBADD = $(XINE_LIB) $(FUSIONSOUND_LIBS) xineplug_ao_out_fusionsound_la_CFLAGS = $(VISIBILITY_FLAG) $(FUSIONSOUND_CFLAGS) -xineplug_ao_out_fusionsound_la_LDFLAGS = -avoid-version -module xineplug_ao_out_jack_la_SOURCES = audio_jack_out.c xineplug_ao_out_jack_la_LIBADD = $(XINE_LIB) $(JACK_LIBS) $(LTLIBINTL) xineplug_ao_out_jack_la_CFLAGS = $(VISIBILITY_FLAG) $(JACK_CFLAGS) -xineplug_ao_out_jack_la_LDFLAGS = -avoid-version -module xineplug_ao_out_sndio_la_SOURCES = audio_sndio_out.c xineplug_ao_out_sndio_la_LIBADD = $(XINE_LIB) $(SNDIO_LIBS) xineplug_ao_out_sndio_la_CFLAGS = $(VISIBILITY_FLAG) $(SNDIO_CFLAGS) -xineplug_ao_out_sndio_la_LDFLAGS = -avoid-version -module diff --git a/src/demuxers/Makefile.am b/src/demuxers/Makefile.am index 027f6750f..01ec2a93e 100644 --- a/src/demuxers/Makefile.am +++ b/src/demuxers/Makefile.am @@ -106,7 +106,6 @@ xineplug_dmx_games_la_SOURCES = group_games.c demux_eawve.c \ demux_film.c demux_smjpeg.c demux_4xm.c \ demux_vmd.c xineplug_dmx_games_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) -xineplug_dmx_games_la_LDFLAGS = -avoid-version -module xineplug_dmx_audio_la_SOURCES = group_audio.c demux_aud.c demux_aiff.c \ demux_cdda.c demux_mpgaudio.c $(nsf_demuxer) \ diff --git a/src/dxr3/Makefile.am b/src/dxr3/Makefile.am index 1027d0e44..fadb8b736 100644 --- a/src/dxr3/Makefile.am +++ b/src/dxr3/Makefile.am @@ -25,7 +25,7 @@ xineplug_LTLIBRARIES = $(dxr3_modules) xineplug_decode_dxr3_video_la_SOURCES = dxr3_decode_video.c xineplug_decode_dxr3_video_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) xineplug_decode_dxr3_video_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) -xineplug_decode_dxr3_video_la_LDFLAGS = -avoid-version -module +xineplug_decode_dxr3_video_la_LDFLAGS = $(xineplug_ldflags) if HAVE_DVDNAV AM_CPPFLAGS = $(DVDNAV_CFLAGS) @@ -37,7 +37,7 @@ xineplug_decode_dxr3_spu_la_SOURCES = dxr3_decode_spu.c nav_read.c xineplug_decode_dxr3_spu_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) endif xineplug_decode_dxr3_spu_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) -xineplug_decode_dxr3_spu_la_LDFLAGS = -avoid-version -module +xineplug_decode_dxr3_spu_la_LDFLAGS = $(xineplug_ldflags) xineplug_vo_out_dxr3_la_SOURCES = \ dxr3_mpeg_encoders.c \ @@ -47,7 +47,7 @@ xineplug_vo_out_dxr3_la_SOURCES = \ xineplug_vo_out_dxr3_la_LIBADD = $(XINE_LIB) $(link_fame) $(link_rte) $(link_x_libs) $(LTLIBINTL) $(DYNAMIC_LD_LIBS) -lm xineplug_vo_out_dxr3_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) -xineplug_vo_out_dxr3_la_LDFLAGS = -avoid-version -module +xineplug_vo_out_dxr3_la_LDFLAGS = $(xineplug_ldflags) noinst_HEADERS = \ em8300.h \ diff --git a/src/input/Makefile.am b/src/input/Makefile.am index beb101f8c..2b75f7338 100644 --- a/src/input/Makefile.am +++ b/src/input/Makefile.am @@ -81,87 +81,87 @@ xineplug_LTLIBRARIES = \ xineplug_inp_file_la_SOURCES = input_file.c xineplug_inp_file_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) xineplug_inp_file_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) -xineplug_inp_file_la_LDFLAGS = -avoid-version -module +xineplug_inp_file_la_LDFLAGS = $(xineplug_ldflags) xineplug_inp_dvd_la_SOURCES = input_dvd.c media_helper.c xineplug_inp_dvd_la_LIBADD = $(XINE_LIB) $(link_dvdnav) $(PTHREAD_LIBS) $(DYNAMIC_LD_LIBS) $(LTLIBINTL) xineplug_inp_dvd_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) -xineplug_inp_dvd_la_LDFLAGS = -avoid-version -module +xineplug_inp_dvd_la_LDFLAGS = $(xineplug_ldflags) xineplug_inp_net_la_SOURCES = input_net.c net_buf_ctrl.c xineplug_inp_net_la_LIBADD = $(XINE_LIB) $(NET_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_inp_net_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) -xineplug_inp_net_la_LDFLAGS = -avoid-version -module +xineplug_inp_net_la_LDFLAGS = $(xineplug_ldflags) xineplug_inp_mms_la_SOURCES = input_mms.c net_buf_ctrl.c mms.c mmsh.c http_helper.c ../demuxers/asfheader.c xineplug_inp_mms_la_LIBADD = $(XINE_LIB) $(LTLIBICONV) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_inp_mms_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) -xineplug_inp_mms_la_LDFLAGS = -avoid-version -module +xineplug_inp_mms_la_LDFLAGS = $(xineplug_ldflags) xineplug_inp_vcdo_la_SOURCES = input_vcd.c media_helper.c xineplug_inp_vcdo_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) xineplug_inp_vcdo_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) -xineplug_inp_vcdo_la_LDFLAGS = -avoid-version -module +xineplug_inp_vcdo_la_LDFLAGS = $(xineplug_ldflags) xineplug_inp_stdin_fifo_la_SOURCES = input_stdin_fifo.c net_buf_ctrl.c xineplug_inp_stdin_fifo_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_inp_stdin_fifo_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) -xineplug_inp_stdin_fifo_la_LDFLAGS = -avoid-version -module +xineplug_inp_stdin_fifo_la_LDFLAGS = $(xineplug_ldflags) xineplug_inp_rtp_la_SOURCES = input_rtp.c net_buf_ctrl.c xineplug_inp_rtp_la_LIBADD = $(XINE_LIB) $(NET_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_inp_rtp_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) -xineplug_inp_rtp_la_LDFLAGS = -avoid-version -module +xineplug_inp_rtp_la_LDFLAGS = $(xineplug_ldflags) xineplug_inp_http_la_SOURCES = input_http.c net_buf_ctrl.c http_helper.c xineplug_inp_http_la_LIBADD = $(XINE_LIB) $(NET_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_inp_http_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) -xineplug_inp_http_la_LDFLAGS = -avoid-version -module +xineplug_inp_http_la_LDFLAGS = $(xineplug_ldflags) xineplug_inp_pnm_la_SOURCES = input_pnm.c net_buf_ctrl.c pnm.c xineplug_inp_pnm_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_inp_pnm_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) -xineplug_inp_pnm_la_LDFLAGS = -avoid-version -module +xineplug_inp_pnm_la_LDFLAGS = $(xineplug_ldflags) xineplug_inp_dvb_la_SOURCES = input_dvb.c net_buf_ctrl.c xineplug_inp_dvb_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_inp_dvb_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) -xineplug_inp_dvb_la_LDFLAGS = -avoid-version -module +xineplug_inp_dvb_la_LDFLAGS = $(xineplug_ldflags) xineplug_inp_rtsp_la_SOURCES = input_rtsp.c net_buf_ctrl.c xineplug_inp_rtsp_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL) libreal/libreal.la librtsp/librtsp.la xineplug_inp_rtsp_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) -xineplug_inp_rtsp_la_LDFLAGS = -avoid-version -module +xineplug_inp_rtsp_la_LDFLAGS = $(xineplug_ldflags) xineplug_inp_cdda_la_SOURCES = input_cdda.c media_helper.c sha1.c sha1.h base64.c base64.h xineplug_inp_cdda_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) xineplug_inp_cdda_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) -xineplug_inp_cdda_la_LDFLAGS = -avoid-version -module +xineplug_inp_cdda_la_LDFLAGS = $(xineplug_ldflags) xineplug_inp_v4l_la_SOURCES = input_v4l.c xineplug_inp_v4l_la_LIBADD = $(XINE_LIB) $(ALSA_LIBS) $(LTLIBINTL) xineplug_inp_v4l_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) -xineplug_inp_v4l_la_LDFLAGS = -avoid-version -module +xineplug_inp_v4l_la_LDFLAGS = $(xineplug_ldflags) xineplug_inp_v4l2_la_SOURCES = input_v4l2.c xineplug_inp_v4l2_la_LIBADD = $(XINE_LIB) $(ALSA_LIBS) $(LTLIBINTL) $(V4L2_LIBS) xineplug_inp_v4l2_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) $(V4L2_CFLAGS) -xineplug_inp_v4l2_la_LDFLAGS = -avoid-version -module +xineplug_inp_v4l2_la_LDFLAGS = $(xineplug_ldflags) xineplug_inp_gnome_vfs_la_SOURCES = input_gnome_vfs.c net_buf_ctrl.c xineplug_inp_gnome_vfs_la_LIBADD = $(XINE_LIB) $(GNOME_VFS_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_inp_gnome_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) -xineplug_inp_gnome_vfs_la_LDFLAGS = -avoid-version -module +xineplug_inp_gnome_vfs_la_LDFLAGS = $(xineplug_ldflags) xineplug_inp_smb_la_SOURCES = input_smb.c xineplug_inp_smb_la_LIBADD = $(XINE_LIB) $(LIBSMBCLIENT_LIBS) $(LTLIBINTL) xineplug_inp_smb_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) -xineplug_inp_smb_la_LDFLAGS = -avoid-version -module +xineplug_inp_smb_la_LDFLAGS = $(xineplug_ldflags) xineplug_inp_pvr_la_SOURCES = input_pvr.c xineplug_inp_pvr_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_inp_pvr_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) -xineplug_inp_pvr_la_LDFLAGS = -avoid-version -module +xineplug_inp_pvr_la_LDFLAGS = $(xineplug_ldflags) xineinclude_HEADERS = input_plugin.h noinst_HEADERS = net_buf_ctrl.h mms.h mmsh.h pnm.h media_helper.h videodev2.h http_helper.h diff --git a/src/input/libdvdnav/Makefile.am b/src/input/libdvdnav/Makefile.am index 1cf60a0e2..4d355bb4b 100644 --- a/src/input/libdvdnav/Makefile.am +++ b/src/input/libdvdnav/Makefile.am @@ -24,7 +24,7 @@ libdvdnav_la_SOURCES = \ dvd_udf.c libdvdnav_la_LIBADD = $(PTHREAD_LIBS) libdvdnav_la_CFLAGS = $(VISIBILITY_FLAG) -libdvdnav_la_LDFLAGS = -avoid-version -module +libdvdnav_la_LDFLAGS = $(xineplug_ldflags) noinst_HEADERS = \ decoder.h \ diff --git a/src/input/librtsp/Makefile.am b/src/input/librtsp/Makefile.am index bb85f9cf4..9ff7482af 100644 --- a/src/input/librtsp/Makefile.am +++ b/src/input/librtsp/Makefile.am @@ -9,7 +9,7 @@ librtsp_la_SOURCES = \ rtsp_session.c librtsp_la_CFLAGS = $(VISIBILITY_FLAG) -librtsp_la_LDFLAGS = -avoid-version -module +librtsp_la_LDFLAGS = $(xineplug_ldflags) noinst_HEADERS = \ rtsp.h \ diff --git a/src/input/vcd/Makefile.am b/src/input/vcd/Makefile.am index 61eac753b..e529bb6dc 100644 --- a/src/input/vcd/Makefile.am +++ b/src/input/vcd/Makefile.am @@ -13,7 +13,7 @@ xineplug_LTLIBRARIES = xineplug_inp_vcd.la AM_CFLAGS = $(LIBCDIO_CFLAGS) $(LIBVCD_CFLAGS) xineplug_inp_vcd_la_SOURCES = $(vcd_SRCS) -xineplug_inp_vcd_la_LDFLAGS = -avoid-version -module +xineplug_inp_vcd_la_LDFLAGS = $(xineplug_ldflags) if HAVE_VCDNAV xineplug_inp_vcd_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) $(LIBVCDINFO_LIBS) else diff --git a/src/libspucc/Makefile.am b/src/libspucc/Makefile.am index 1e170cdd5..cde6ecf05 100644 --- a/src/libspucc/Makefile.am +++ b/src/libspucc/Makefile.am @@ -6,6 +6,6 @@ xineplug_LTLIBRARIES = xineplug_decode_spucc.la xineplug_decode_spucc_la_SOURCES = cc_decoder.c xine_cc_decoder.c xineplug_decode_spucc_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) -fno-strict-aliasing xineplug_decode_spucc_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) -xineplug_decode_spucc_la_LDFLAGS = -avoid-version -module +xineplug_decode_spucc_la_LDFLAGS = $(xineplug_ldflags) noinst_HEADERS = cc_decoder.h diff --git a/src/libxineadec/gsm610/Makefile.am b/src/libxineadec/gsm610/Makefile.am index fe25ad9c3..6ec2e0a5e 100644 --- a/src/libxineadec/gsm610/Makefile.am +++ b/src/libxineadec/gsm610/Makefile.am @@ -15,7 +15,7 @@ libgsm610_la_SOURCES = \ table.c libgsm610_la_CFLAGS = $(VISIBILITY_FLAG) -libgsm610_la_LDFLAGS = -avoid-version -module +libgsm610_la_LDFLAGS = $(xineplug_ldflags) noinst_HEADERS = \ gsm_config.h \ diff --git a/src/post/audio/Makefile.am b/src/post/audio/Makefile.am index 5e587ef2f..78b94cd43 100644 --- a/src/post/audio/Makefile.am +++ b/src/post/audio/Makefile.am @@ -9,5 +9,5 @@ xineplug_post_audio_filters_la_SOURCES = \ upmix.c upmix_mono.c filter.c window.c stretch.c volnorm.c audio_filters.c xineplug_post_audio_filters_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL) -lm xineplug_post_audio_filters_la_CFLAGS = $(VISIBILITY_FLAG) -xineplug_post_audio_filters_la_LDFLAGS = -avoid-version -module +xineplug_post_audio_filters_la_LDFLAGS = $(xineplug_ldflags) diff --git a/src/post/deinterlace/Makefile.am b/src/post/deinterlace/Makefile.am index bf5b281a8..079ed5baf 100644 --- a/src/post/deinterlace/Makefile.am +++ b/src/post/deinterlace/Makefile.am @@ -13,7 +13,7 @@ xineplug_post_tvtime_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) $(PTHREAD_LIBS) \ $(top_builddir)/src/post/deinterlace/plugins/libdeinterlaceplugins.la xineplug_post_tvtime_la_CFLAGS = $(VISIBILITY_FLAG) -xineplug_post_tvtime_la_LDFLAGS = -avoid-version -module \ +xineplug_post_tvtime_la_LDFLAGS = $(xineplug_ldflags) \ @IMPURE_TEXT_LDFLAGS@ noinst_HEADERS = deinterlace.h pulldown.h speedtools.h speedy.h tvtime.h diff --git a/src/post/deinterlace/plugins/Makefile.am b/src/post/deinterlace/plugins/Makefile.am index 5f0997eb8..5e50c25f4 100644 --- a/src/post/deinterlace/plugins/Makefile.am +++ b/src/post/deinterlace/plugins/Makefile.am @@ -49,6 +49,6 @@ libdeinterlaceplugins_la_SOURCES = \ kdetv_greedyh.c \ kdetv_tomsmocomp.c libdeinterlaceplugins_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) -libdeinterlaceplugins_la_LDFLAGS = -avoid-version -module +libdeinterlaceplugins_la_LDFLAGS = $(xineplug_ldflags) noinst_HEADERS = plugins.h greedyhmacros.h diff --git a/src/post/goom/Makefile.am b/src/post/goom/Makefile.am index cd022c9b0..386c0b351 100644 --- a/src/post/goom/Makefile.am +++ b/src/post/goom/Makefile.am @@ -31,7 +31,7 @@ xineplug_post_goom_la_SOURCES = $(extra_files) xine_goom.c \ plugin_info.c sound_tester.c surf3d.c tentacle3d.c v3d.c xineplug_post_goom_la_LIBADD = $(XINE_LIB) $(GOOM_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) -lm xineplug_post_goom_la_CFLAGS = $(VISIBILITY_FLAG) -xineplug_post_goom_la_LDFLAGS = -avoid-version -module +xineplug_post_goom_la_LDFLAGS = $(xineplug_ldflags) noinst_HEADERS = cpu_info.h default_scripts.h drawmethods.h gfontlib.h goom.h \ goom_config.h goom_config_param.h goom_filters.h goom_fx.h goom_graphic.h \ diff --git a/src/post/mosaico/Makefile.am b/src/post/mosaico/Makefile.am index 56426c711..83f2b8f2a 100644 --- a/src/post/mosaico/Makefile.am +++ b/src/post/mosaico/Makefile.am @@ -6,9 +6,9 @@ xinepost_LTLIBRARIES = xineplug_post_mosaico.la xineplug_post_switch.la xineplug_post_mosaico_la_SOURCES = mosaico.c xineplug_post_mosaico_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_post_mosaico_la_CFLAGS = $(VISIBILITY_FLAG) -xineplug_post_mosaico_la_LDFLAGS = -avoid-version -module +xineplug_post_mosaico_la_LDFLAGS = $(xineplug_ldflags) xineplug_post_switch_la_SOURCES = switch.c xineplug_post_switch_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_post_switch_la_CFLAGS = $(VISIBILITY_FLAG) -xineplug_post_switch_la_LDFLAGS = -avoid-version -module +xineplug_post_switch_la_LDFLAGS = $(xineplug_ldflags) diff --git a/src/post/planar/Makefile.am b/src/post/planar/Makefile.am index 751ea390a..319152cba 100644 --- a/src/post/planar/Makefile.am +++ b/src/post/planar/Makefile.am @@ -27,7 +27,7 @@ xineplug_post_planar_la_SOURCES = planar.c invert.c expand.c fill.c boxblur.c \ denoise3d.c eq.c eq2.c unsharp.c pp.c noise.c xineplug_post_planar_la_DEPENDENCIES = $(postproc_dep) xineplug_post_planar_la_LIBADD = $(XINE_LIB) $(postproc_lib) -lm $(PTHREAD_LIBS) $(LTLIBINTL) -xineplug_post_planar_la_LDFLAGS = -avoid-version -module \ +xineplug_post_planar_la_LDFLAGS = $(xineplug_ldflags) \ @IMPURE_TEXT_LDFLAGS@ xineplug_post_planar_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) diff --git a/src/post/visualizations/Makefile.am b/src/post/visualizations/Makefile.am index a766bc10a..f3a759fae 100644 --- a/src/post/visualizations/Makefile.am +++ b/src/post/visualizations/Makefile.am @@ -9,6 +9,6 @@ xineplug_post_visualizations_la_SOURCES = \ visualizations.c fft.c fftscope.c oscope.c fftgraph.c xineplug_post_visualizations_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) -lm xineplug_post_visualizations_la_CFLAGS = $(VISIBILITY_FLAG) -xineplug_post_visualizations_la_LDFLAGS = -avoid-version -module +xineplug_post_visualizations_la_LDFLAGS = $(xineplug_ldflags) noinst_HEADERS = fft.h visualizations.h diff --git a/src/xine-engine/Makefile.am b/src/xine-engine/Makefile.am index 17dd96b10..576c61b14 100644 --- a/src/xine-engine/Makefile.am +++ b/src/xine-engine/Makefile.am @@ -10,7 +10,7 @@ lib_LTLIBRARIES = libxine.la XINEUTILS_LIB = $(top_builddir)/src/xine-utils/libxineutils.la DEF_FILE = libxine-$(XINE_MAJOR).def if WIN32 -def_ldflags="-Wl,--output-def,$(DEF_FILE)" +def_ldflags=-Wl,--output-def,$(DEF_FILE) $(LDFLAGS_NOUNDEFINED) endif libxine_la_SOURCES = xine.c metronom.c configfile.c buffer.c \ -- cgit v1.2.3 From e06c49677954d4675d002002cbd8f51a768591ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Sat, 23 Oct 2010 13:25:18 +0200 Subject: mingw32-w64 port: - mkdir/_mkdir function - prefer prepared POSIX version in CDDA plugin --- src/input/input_cdda.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/input/input_cdda.c b/src/input/input_cdda.c index 1751f031c..567f38dd0 100644 --- a/src/input/input_cdda.c +++ b/src/input/input_cdda.c @@ -1279,7 +1279,7 @@ static void _cdda_mkdir_safe(xine_t *xine, char *path) { hList = FindFirstFile(szDir, &FileData); if (hList == INVALID_HANDLE_VALUE) { - if(_mkdir(path) != 0) { + if(mkdir(path, 0) != 0) { xprintf(xine, XINE_VERBOSITY_DEBUG, "input_cdda: mkdir(%s) failed.\n", path); return; } -- cgit v1.2.3 From 561bae45e1e949710639e1825c8278785563ec6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Sat, 23 Oct 2010 13:26:58 +0200 Subject: mingw32-w64 port: - symbols in objects built by mingw64 not mangled - fixes build of deinterlace post plugin --- src/xine-utils/mangle.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/xine-utils/mangle.h b/src/xine-utils/mangle.h index 4ca7db7a5..a897e9229 100644 --- a/src/xine-utils/mangle.h +++ b/src/xine-utils/mangle.h @@ -36,10 +36,15 @@ // Use rip-relative addressing if compiling PIC code on x86-64. #if defined(__MINGW32__) || defined(__CYGWIN__) || defined(__DJGPP__) || \ defined(__OS2__) || (defined (__OpenBSD__) && !defined(__ELF__)) +# if defined(__MINGW64__) +# define EXTERN_PREFIX "" +# else +# define EXTERN_PREFIX "_" +# endif # if defined(__x86_64__) && defined(__PIC__) -# define MANGLE(a) "_" #a"(%%rip)" +# define MANGLE(a) EXTERN_PREFIX #a"(%%rip)" # else -# define MANGLE(a) "_" #a +# define MANGLE(a) EXTERN_PREFIX #a # endif #else # if defined(__x86_64__) && defined(__PIC__) -- cgit v1.2.3 From 9c01f73ab17e5d33bd7e70024d6dbf9423922cea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Sat, 23 Oct 2010 13:34:18 +0200 Subject: mingw32-w64 port: integer sizes portability - use interer types of exact size for using with eax/rax registers - fixes build of planar post plugin --- src/post/planar/noise.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/post/planar/noise.c b/src/post/planar/noise.c index 0f1fe98f7..41a3a9aeb 100644 --- a/src/post/planar/noise.c +++ b/src/post/planar/noise.c @@ -34,8 +34,10 @@ #ifdef ARCH_X86_64 # define REG_a "rax" +# define intarch_t int64_t #else # define REG_a "eax" +# define intarch_t int32_t #endif #define MAX_NOISE 4096 @@ -153,7 +155,7 @@ static inline void lineNoise_C(uint8_t *dst, uint8_t *src, int8_t *noise, int le #ifdef ARCH_X86 static inline void lineNoise_MMX(uint8_t *dst, uint8_t *src, int8_t *noise, int len, int shift){ - long mmx_len= len&(~7); + intarch_t mmx_len= len&(~7); noise+=shift; asm volatile( @@ -180,7 +182,7 @@ static inline void lineNoise_MMX(uint8_t *dst, uint8_t *src, int8_t *noise, int //duplicate of previous except movntq static inline void lineNoise_MMX2(uint8_t *dst, uint8_t *src, int8_t *noise, int len, int shift){ - long mmx_len= len&(~7); + intarch_t mmx_len= len&(~7); noise+=shift; asm volatile( @@ -223,7 +225,7 @@ static inline void lineNoiseAvg_C(uint8_t *dst, uint8_t *src, int len, int8_t ** #ifdef ARCH_X86 static inline void lineNoiseAvg_MMX(uint8_t *dst, uint8_t *src, int len, int8_t **shift){ - long mmx_len= len&(~7); + intarch_t mmx_len= len&(~7); asm volatile( "mov %5, %%"REG_a" \n\t" -- cgit v1.2.3 From 9bb2a01a243a688ba7318c884aadd44480c60c71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Sat, 23 Oct 2010 13:36:13 +0200 Subject: mingw32-w64 port: integer sizes portability - use type of enough size for pointer types (uintptr_t) - fixes "Unhandled exception" in memcpy code --- src/xine-utils/memcpy.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/xine-utils/memcpy.c b/src/xine-utils/memcpy.c index a19e700c5..b6836aebc 100644 --- a/src/xine-utils/memcpy.c +++ b/src/xine-utils/memcpy.c @@ -124,7 +124,7 @@ quote of the day: /* for small memory blocks (<256 bytes) this version is faster */ #define small_memcpy(to,from,n)\ {\ -register unsigned long int dummy;\ +register uintptr_t dummy;\ __asm__ __volatile__(\ "rep; movsb"\ :"=&D"(to), "=&S"(from), "=&c"(dummy)\ @@ -154,7 +154,7 @@ int d0, d1, d2; "movsb\n" "2:" : "=&c" (d0), "=&D" (d1), "=&S" (d2) - :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from) + :"0" (n/4), "q" (n),"1" ((uintptr_t) to),"2" ((uintptr_t) from) : "memory"); return (to); @@ -191,9 +191,9 @@ static void * sse_memcpy(void * to, const void * from, size_t len) if(len >= MIN_LEN) { - register unsigned long int delta; + register uintptr_t delta; /* Align destinition to MMREG_SIZE -boundary */ - delta = ((unsigned long int)to)&(SSE_MMREG_SIZE-1); + delta = ((uintptr_t)to)&(SSE_MMREG_SIZE-1); if(delta) { delta=SSE_MMREG_SIZE-delta; @@ -202,7 +202,7 @@ static void * sse_memcpy(void * to, const void * from, size_t len) } i = len >> 6; /* len/64 */ len&=63; - if(((unsigned long)from) & 15) + if(((uintptr_t)from) & 15) /* if SRC is misaligned */ for(; i>0; i--) { @@ -263,9 +263,9 @@ static void * mmx_memcpy(void * to, const void * from, size_t len) if(len >= MMX1_MIN_LEN) { - register unsigned long int delta; + register uintptr_t delta; /* Align destinition to MMREG_SIZE -boundary */ - delta = ((unsigned long int)to)&(MMX_MMREG_SIZE-1); + delta = ((uintptr_t)to)&(MMX_MMREG_SIZE-1); if(delta) { delta=MMX_MMREG_SIZE-delta; @@ -328,9 +328,9 @@ static void * mmx2_memcpy(void * to, const void * from, size_t len) if(len >= MIN_LEN) { - register unsigned long int delta; + register uintptr_t delta; /* Align destinition to MMREG_SIZE -boundary */ - delta = ((unsigned long int)to)&(MMX_MMREG_SIZE-1); + delta = ((uintptr_t)to)&(MMX_MMREG_SIZE-1); if(delta) { delta=MMX_MMREG_SIZE-delta; -- cgit v1.2.3 From a2ef98093f3e40a889c12ecca6e236505fdcbf05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Sat, 30 Oct 2010 11:35:28 +0200 Subject: Using binary mode when checking configfile. New configfile would not be written only when switching binaries for different platforms. --- src/xine-engine/configfile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/xine-engine/configfile.c b/src/xine-engine/configfile.c index 484d1d16f..507f0a81d 100644 --- a/src/xine-engine/configfile.c +++ b/src/xine-engine/configfile.c @@ -1012,8 +1012,8 @@ void xine_config_save (xine_t *xine, const char *filename) { lprintf("backing up configfile to %s\n", temp); - f_backup = fopen(temp, "w"); - f_config = fopen(filename, "r"); + f_backup = fopen(temp, "wb"); + f_config = fopen(filename, "rb"); if (f_config && f_backup && (stat(filename, &config_stat) == 0)) { char *buf = NULL; -- cgit v1.2.3 From cd7f17a9e7eb91803782a87164717269aa336273 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Sat, 30 Oct 2010 11:37:51 +0200 Subject: Using binary mode when writing raw data, in disabled debug code. --- src/demuxers/demux_qt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/demuxers/demux_qt.c b/src/demuxers/demux_qt.c index 463e82970..d446cc17b 100644 --- a/src/demuxers/demux_qt.c +++ b/src/demuxers/demux_qt.c @@ -447,7 +447,7 @@ static inline void dump_moov_atom(unsigned char *moov_atom, int moov_atom_size) FILE *f; - f = fopen(RAW_MOOV_FILENAME, "w"); + f = fopen(RAW_MOOV_FILENAME, "wb"); if (!f) { perror(RAW_MOOV_FILENAME); return; -- cgit v1.2.3 From 3a70a11d2871085ef8dcffdc81e3865c134de4d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Sat, 30 Oct 2010 11:40:31 +0200 Subject: Proper place for log mutex initialization (logging can start after xine_new()). Fixed a leak. --- src/xine-engine/xine.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c index 842d864ba..ea90e45a4 100644 --- a/src/xine-engine/xine.c +++ b/src/xine-engine/xine.c @@ -1561,6 +1561,8 @@ void xine_exit (xine_t *this) { if(this->port_ticket) this->port_ticket->dispose(this->port_ticket); + pthread_mutex_destroy(&this->log_lock); + #if defined(WIN32) WSACleanup(); #endif @@ -1604,6 +1606,7 @@ xine_t *xine_new (void) { * log buffers */ memset(this->log_buffers, 0, sizeof(this->log_buffers)); + pthread_mutex_init (&this->log_lock, NULL); #ifdef WIN32 @@ -1696,7 +1699,6 @@ void xine_init (xine_t *this) { * locks */ pthread_mutex_init (&this->streams_lock, NULL); - pthread_mutex_init (&this->log_lock, NULL); /* initialize color conversion tables and functions */ init_yuv_conversion(); -- cgit v1.2.3 From 9053a072c0edc3e45adc4131bb6eb8b0614eb6af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Sat, 30 Oct 2010 11:43:11 +0200 Subject: Try to meassure memcpy method speed by clock() when times() not available. --- src/xine-utils/memcpy.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/xine-utils/memcpy.c b/src/xine-utils/memcpy.c index b6836aebc..9056749e2 100644 --- a/src/xine-utils/memcpy.c +++ b/src/xine-utils/memcpy.c @@ -39,6 +39,8 @@ #ifdef HAVE_SYS_TIMES_H #include +#else +#include #endif #include @@ -429,7 +431,7 @@ static uint64_t rdtsc(int config_flags) struct tms tp; return times(&tp); #else - return ((uint64_t)0); + return clock(); #endif /* HAVE_SYS_TIMES_H */ } #endif -- cgit v1.2.3 From 6e86fc3b309d1b17635c2e129796839f3bead274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Wed, 10 Nov 2010 09:55:10 +0100 Subject: Option for disabling HW acceleration in directx. Useful for example when composite managers occupy the HW. --- src/video_out/video_out_directx.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/video_out/video_out_directx.c b/src/video_out/video_out_directx.c index 8cb72238a..834548091 100644 --- a/src/video_out/video_out_directx.c +++ b/src/video_out/video_out_directx.c @@ -110,6 +110,12 @@ typedef struct { * * ----------------------------------------- */ +typedef enum { + VO_DIRECTX_HWACCEL_FULL = 0, + VO_DIRECTX_HWACCEL_SCALE = 1, + VO_DIRECTX_HWACCEL_NONE = 2 +} vo_directx_hwaccel_enum; + typedef struct { vo_driver_t vo_driver; win32_visual_t *win32_visual; @@ -128,6 +134,7 @@ typedef struct { uint32_t width; /* frame with */ uint32_t height; /* frame height */ double ratio; /* frame ratio */ + vo_directx_hwaccel_enum hwaccel; /* requested level of HW acceleration */ yuv2rgb_factory_t *yuv2rgb_factory; /* used for format conversion */ yuv2rgb_t *yuv2rgb; /* used for format conversion */ @@ -144,6 +151,8 @@ typedef struct { xine_t *xine; } directx_class_t; +char *config_hwaccel_values[] = {"full", "scale", "none", NULL }; + /* ----------------------------------------- * * BEGIN : Direct Draw and win32 handlers @@ -322,6 +331,8 @@ static boolean CreateSecondary( win32_driver_t * win32_driver, int width, int he ddsd.dwWidth = width; ddsd.dwHeight = height; + if (win32_driver->hwaccel <= VO_DIRECTX_HWACCEL_FULL) { + if( format == XINE_IMGFMT_YV12 ) { /* the requested format is XINE_IMGFMT_YV12 */ @@ -378,6 +389,10 @@ static boolean CreateSecondary( win32_driver_t * win32_driver, int width, int he if( IDirectDraw_CreateSurface( win32_driver->ddobj, &ddsd, &win32_driver->secondary, 0 ) == DD_OK ) return TRUE; + } + + if (win32_driver->hwaccel <= VO_DIRECTX_HWACCEL_SCALE) { + /* Our fallback method is to create a back buffer * with the same image format as the primary surface */ @@ -392,10 +407,13 @@ static boolean CreateSecondary( win32_driver_t * win32_driver, int width, int he if( IDirectDraw_CreateSurface( win32_driver->ddobj, &ddsd, &win32_driver->secondary, 0 ) == DD_OK ) return TRUE; + } + /* Our second fallback - all w/o HW acceleration */ lprintf("CreateSecondary() - Falling back, disabling HW acceleration \n"); ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; + win32_driver->act_format = IMGFMT_NATIVE; if( (result = IDirectDraw_CreateSurface( win32_driver->ddobj, &ddsd, &win32_driver->secondary, 0 )) == DD_OK ) return TRUE; @@ -625,7 +643,7 @@ static boolean Overlay( LPDIRECTDRAWSURFACE src_surface, RECT * src_rect, } else { - Error( 0, "IDirectDrawSurface_UpdateOverlay : error 0x%lx", result ); + Error( 0, "IDirectDrawSurface_UpdateOverlay : error 0x%lx. You can try disable hardware acceleration (option video.directx.hwaccel).", result ); return FALSE; } } @@ -1265,6 +1283,15 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *wi win32_driver->vo_driver.dispose = win32_exit; win32_driver->vo_driver.redraw_needed = win32_redraw_needed; + win32_driver->hwaccel = class->config->register_enum(class->config, + "video.directx.hwaccel", 0, config_hwaccel_values, + _("HW acceleration level"), + _("Possible values (default full):\n\n" +"full: full acceleration\n" +"scale: disable colorspace conversion (HW scaling only)\n" +"none: disable all acceleration"), + 10, NULL, NULL); + if (!CreatePrimary( win32_driver )) { Destroy( win32_driver ); return NULL; -- cgit v1.2.3 From beec839ade34a0acb637f2d986b5e9118d52ea63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Tue, 23 Nov 2010 15:29:35 +0100 Subject: Build with -DLOG. --- src/libreal/xine_real_video_decoder.c | 2 +- src/xine-utils/xmlparser.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/libreal/xine_real_video_decoder.c b/src/libreal/xine_real_video_decoder.c index 4977ee889..c2909f57c 100644 --- a/src/libreal/xine_real_video_decoder.c +++ b/src/libreal/xine_real_video_decoder.c @@ -380,7 +380,7 @@ static void realdec_decode_data (video_decoder_t *this_gen, buf_element_t *buf) xine_hexdump (this->chunk_buffer, this->chunk_buffer_size); printf ("libreal: transform_in:\n"); - xine_hexdump ((uint8_t *) &transform_in, sizeof(rv_xform_in_t)); + xine_hexdump ((uint8_t *) &transform_in, sizeof(transform_in_t)); printf ("libreal: chunk_table:\n"); xine_hexdump ((uint8_t *) buf->decoder_info_ptr[2], diff --git a/src/xine-utils/xmlparser.c b/src/xine-utils/xmlparser.c index e32d38460..def9c3d17 100644 --- a/src/xine-utils/xmlparser.c +++ b/src/xine-utils/xmlparser.c @@ -134,7 +134,7 @@ static void xml_parser_free_props(xml_property_t *current_property) { } static void xml_parser_free_tree_rec(xml_node_t *current_node, int free_next) { - lprintf("xml_parser_free_tree_rec: %s\n", current_node->name); + lprintf("xml_parser_free_tree_rec: %s\n", current_node ? current_node->name : NULL); if (current_node) { /* properties */ -- cgit v1.2.3 From a643b3afeb34ef53e7aa4d583453c6b0a8fb025c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Sun, 28 Nov 2010 15:12:02 +0100 Subject: Header stripping support in matroska demuxer. Reserved space on the start of block_data for the headers during reading to avoid temporary memory buffers and memcpy()'s. --- src/demuxers/demux_matroska.c | 36 +++++++++++++++++++++++++----------- src/demuxers/demux_matroska.h | 1 + src/demuxers/matroska.h | 2 ++ 3 files changed, 28 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/demuxers/demux_matroska.c b/src/demuxers/demux_matroska.c index 0f83c73f8..694236833 100644 --- a/src/demuxers/demux_matroska.c +++ b/src/demuxers/demux_matroska.c @@ -304,8 +304,12 @@ static int parse_content_compression (demux_matroska_t *this, matroska_track_t * } break; case MATROSKA_ID_CE_COMPSETTINGS: - lprintf("ContentCompSettings (UNSUPPORTED)\n"); - if (!ebml_skip(ebml, &elem)) + lprintf("ContentCompSettings\n"); + track->compress_settings = calloc(1, elem.len); + track->compress_len = elem.len; + if (elem.len > this->compress_maxlen) + this->compress_maxlen = elem.len; + if(!ebml_read_binary(ebml, &elem, track->compress_settings)) return 0; break; default: @@ -1784,8 +1788,8 @@ static int find_track_by_id(demux_matroska_t *this, int track_num, } -static int read_block_data (demux_matroska_t *this, size_t len) { - alloc_block_data(this, len); +static int read_block_data (demux_matroska_t *this, size_t len, size_t offset) { + alloc_block_data(this, len + offset); /* block datas */ if (! this->block_data) { @@ -1793,7 +1797,7 @@ static int read_block_data (demux_matroska_t *this, size_t len) { "demux_matroska: memory allocation error\n"); return 0; } - if (this->input->read(this->input, this->block_data, len) != len) { + if (this->input->read(this->input, this->block_data + offset, len) != len) { off_t pos = this->input->get_current_pos(this->input); xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "demux_matroska: read error at position %" PRIdMAX "\n", @@ -1823,8 +1827,9 @@ static int parse_block (demux_matroska_t *this, size_t block_size, int16_t timecode_diff; int64_t pts, xduration; int decoder_flags = 0; + size_t headers_len = 0; - data = this->block_data; + data = this->block_data + this->compress_maxlen; if (!(num_len = parse_ebml_uint(this, data, &track_num))) return 0; data += num_len; @@ -1877,12 +1882,21 @@ static int parse_block (demux_matroska_t *this, size_t block_size, decoder_flags |= BUF_FLAG_PREVIEW; } + if (track->compress_algo == MATROSKA_COMPRESS_HEADER_STRIP) + headers_len = track->compress_len; + if (lacing == MATROSKA_NO_LACING) { size_t block_size_left; lprintf("no lacing\n"); - block_size_left = (this->block_data + block_size) - data; - lprintf("size: %d, block_size: %u\n", block_size_left, block_size); + block_size_left = (this->block_data + block_size + this->compress_maxlen) - data; + lprintf("size: %d, block_size: %u, block_offset: %u\n", block_size_left, block_size, this->compress_maxlen); + + if (headers_len) { + data -= headers_len; + xine_fast_memcpy(data, track->compress_settings, headers_len); + block_size_left += headers_len; + } if (track->handle_content != NULL) { track->handle_content((demux_plugin_t *)this, track, @@ -1912,7 +1926,7 @@ static int parse_block (demux_matroska_t *this, size_t block_size, "demux_matroska: too many frames: %d\n", lace_num); return 0; } - block_size_left = this->block_data + block_size - data; + block_size_left = this->block_data + block_size + this->compress_maxlen - data; switch (lacing) { case MATROSKA_XIPH_LACING: { @@ -2045,7 +2059,7 @@ static int parse_simpleblock(demux_matroska_t *this, size_t block_len, uint64_t if( file_len ) normpos = (int) ( (double) block_pos * 65535 / file_len ); - if (!read_block_data(this, block_len)) + if (!read_block_data(this, block_len, this->compress_maxlen)) return 0; has_block = 1; @@ -2084,7 +2098,7 @@ static int parse_block_group(demux_matroska_t *this, if( file_len ) normpos = (int) ( (double) block_pos * 65535 / file_len ); - if (!read_block_data(this, elem.len)) + if (!read_block_data(this, elem.len, this->compress_maxlen)) return 0; has_block = 1; diff --git a/src/demuxers/demux_matroska.h b/src/demuxers/demux_matroska.h index e1611f397..841847ec1 100644 --- a/src/demuxers/demux_matroska.h +++ b/src/demuxers/demux_matroska.h @@ -96,6 +96,7 @@ typedef struct { int num_sub_tracks; matroska_track_t *tracks[MAX_STREAMS]; + size_t compress_maxlen; /* maintain editions, number and capacity */ int num_editions, cap_editions; diff --git a/src/demuxers/matroska.h b/src/demuxers/matroska.h index 53fee5358..e8f124e9b 100644 --- a/src/demuxers/matroska.h +++ b/src/demuxers/matroska.h @@ -272,6 +272,8 @@ struct matroska_track_s { uint32_t codec_private_len; int default_flag; uint32_t compress_algo; + uint32_t compress_len; + char *compress_settings; uint32_t buf_type; fifo_buffer_t *fifo; -- cgit v1.2.3 From afc21c050464eec01f98a34455581e2f5d877c87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Tue, 30 Nov 2010 23:13:18 +0100 Subject: Various small memory leaks in xine engine. --- src/xine-engine/events.c | 1 + src/xine-engine/info_helper.c | 5 ++--- src/xine-engine/xine.c | 4 +++- 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/xine-engine/events.c b/src/xine-engine/events.c index a51813adc..04a599c50 100644 --- a/src/xine-engine/events.c +++ b/src/xine-engine/events.c @@ -193,6 +193,7 @@ void xine_event_dispose_queue (xine_event_queue_t *queue) { while ( (event = xine_event_get (queue)) ) { xine_event_free (event); } + xine_list_delete(queue->events); pthread_mutex_destroy(&queue->lock); pthread_cond_destroy(&queue->new_event); diff --git a/src/xine-engine/info_helper.c b/src/xine-engine/info_helper.c index e45336d98..9d0302cc1 100644 --- a/src/xine-engine/info_helper.c +++ b/src/xine-engine/info_helper.c @@ -241,9 +241,6 @@ static void meta_info_set_unlocked_encoding(xine_stream_t *stream, int info, con xprintf(stream->xine, XINE_VERBOSITY_LOG, _("info_helper: unsupported conversion %s -> UTF-8, no conversion performed\n"), enc); - if (system_enc) - free(system_enc); - if (cd != (iconv_t)-1) { char *utf8_value; ICONV_CONST char *inbuf; @@ -273,6 +270,8 @@ static void meta_info_set_unlocked_encoding(xine_stream_t *stream, int info, con return; } } + + free(system_enc); } #endif diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c index ea90e45a4..fad1785b4 100644 --- a/src/xine-engine/xine.c +++ b/src/xine-engine/xine.c @@ -654,6 +654,7 @@ xine_stream_t *xine_stream_new (xine_t *this, pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init (&stream->frontend_lock, &attr); + pthread_mutexattr_destroy(&attr); /* * Clear meta/stream info @@ -1488,6 +1489,8 @@ static void xine_dispose_internal (xine_stream_t *stream) { stream->metronom->exit (stream->metronom); + xine_list_delete(stream->event_queues); + pthread_mutex_lock(&stream->xine->streams_lock); ite = xine_list_find(stream->xine->streams, stream); if (ite) { @@ -1532,7 +1535,6 @@ void xine_dispose (xine_stream_t *stream) { if (stream->osd_renderer) stream->osd_renderer->close( stream->osd_renderer ); - _x_refcounter_dec(stream->refcounter); } -- cgit v1.2.3 From 74ed31516e0d2e1000d19ab2f97413e424453ae4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Tue, 30 Nov 2010 23:14:07 +0100 Subject: Small memory leaks in VCD input plugin class. --- src/input/vcd/xineplug_inp_vcd.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/input/vcd/xineplug_inp_vcd.c b/src/input/vcd/xineplug_inp_vcd.c index e238460db..70fcfe7ae 100644 --- a/src/input/vcd/xineplug_inp_vcd.c +++ b/src/input/vcd/xineplug_inp_vcd.c @@ -1525,6 +1525,10 @@ vcd_class_dispose (input_class_t *this_gen) { dbg_print((INPUT_DBG_CALL|INPUT_DBG_EXT), "called\n"); vcd_close(class); + free(class->vcd_device); + free(my_vcd.v_config.title_format); + free(my_vcd.v_config.comment_format); + free(class); } /* Update the xine player title text. */ -- cgit v1.2.3 From 4dd0040f8e622267e872ba425858babccdf27241 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Tue, 30 Nov 2010 23:16:23 +0100 Subject: Check boundaries during MPEG TS stream detection. --- src/demuxers/demux_ts.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index 86e216304..f31578073 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -2360,18 +2360,20 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, demux_ts_t *this; int i; int hdmv = -1; + int size; switch (stream->content_detection_method) { case METHOD_BY_CONTENT: { uint8_t buf[2069]; - if (!_x_demux_read_header(input, buf, sizeof(buf))) + size = _x_demux_read_header(input, buf, sizeof(buf)); + if (size < PKT_SIZE) return NULL; if (detect_ts(buf, sizeof(buf), PKT_SIZE)) hdmv = 0; - else if (detect_ts(buf, sizeof(buf), PKT_SIZE+4)) + else if (size >= PKT_SIZE + 4 && detect_ts(buf, sizeof(buf), PKT_SIZE+4)) hdmv = 1; else return NULL; -- cgit v1.2.3 From 344ae5270df7c64c0c02a3bcbfc65951d8c24f88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Wed, 1 Dec 2010 00:08:25 +0100 Subject: Update nosefart to 2.7-mls, fixes xine bug #84. There was added memory limits checks, which will improve stability when playing corrupted NSF files. --- .../nosefart/diff_to_nosefart_cvs.patch | 372 ++++++++-- src/libxineadec/nosefart/nes6502.c | 222 +++++- src/libxineadec/nosefart/nes6502.h | 25 +- src/libxineadec/nosefart/nes_apu.c | 102 ++- src/libxineadec/nosefart/nes_apu.h | 12 +- src/libxineadec/nosefart/nsf.c | 769 ++++++++++++++++----- src/libxineadec/nosefart/nsf.h | 92 ++- src/libxineadec/nosefart/types.h | 31 +- src/libxineadec/nosefart/version.h | 11 +- 9 files changed, 1300 insertions(+), 336 deletions(-) (limited to 'src') diff --git a/src/libxineadec/nosefart/diff_to_nosefart_cvs.patch b/src/libxineadec/nosefart/diff_to_nosefart_cvs.patch index 280cd89cb..e46633478 100644 --- a/src/libxineadec/nosefart/diff_to_nosefart_cvs.patch +++ b/src/libxineadec/nosefart/diff_to_nosefart_cvs.patch @@ -1,18 +1,147 @@ -diff -u -p -r1.1.1.1 types.h ---- types.h 26 Jul 2004 15:27:59 -0000 1.1.1.1 -+++ types.h 26 Aug 2004 16:00:07 -0000 -@@ -23,8 +23,8 @@ - ** $Id: diff_to_nosefart_cvs.patch,v 1.2 2005/05/07 09:11:39 valtri Exp $ +--- a/src/libxineadec/nosefart/log.h 2010-11-28 19:57:41.000000000 +0100 ++++ b/src/libxineadec/nosefart/log.h 2010-10-10 21:03:43.000000000 +0200 +@@ -27,11 +27,12 @@ + #define _LOG_H_ + + #include ++#include "attributes.h" + + extern int log_init(void); + extern void log_shutdown(void); + extern void log_print(const char *string); +-extern void log_printf(const char *format, ...); ++extern void log_printf(const char *format, ...) XINE_FORMAT_PRINTF(1, 2); + + #endif /* _LOG_H_ */ + +diff -r fe4287194cac src/libxineadec/nosefart/nes_apu.h +--- /src/libxineadec/nosefart/nes_apu.h 2007-12-14 05:46:22.000000000 +0100 ++++ /src/libxineadec/nosefart/nes_apu.h 2010-11-28 20:13:05.000000000 +0100 +@@ -289,6 +289,7 @@ extern void apu_write(uint32 address, ui + /* for visualization */ + extern void apu_getpcmdata(void **data, int *num_samples, int *sample_bits); + ++extern void apu_setcontext(apu_t *src_apu); + + #ifdef __cplusplus + } +diff -r fe4287194cac src/libxineadec/nosefart/fmopl.c +--- a/src/libxineadec/nosefart/fmopl.c Sun Nov 28 20:32:56 2010 +0100 ++++ b/src/libxineadec/nosefart/fmopl.c Sun Nov 28 20:22:51 2010 +0100 +@@ -18,9 +18,9 @@ + #include + #include + #include ++#include + //#include "driver.h" /* use M.A.M.E. */ + #include "fmopl.h" +-#include + + /* MPC - hacks */ + #include "types.h" +@@ -218,19 +218,6 @@ static INT32 feedback2; /* connect for + + /* --------------------- subroutines --------------------- */ + +-/* There's no good reason why I should have to do this, but using "pow" +-(the POSIX fuction) causes it to not compile on my machine +---Matthew Strait */ +-double mypow(float base, int power) +-{ +- int ans = 1, k; +- +- for( k = 0; k < power; k++) +- ans *= (int)base; +- +- return ans; +-} +- + INLINE int Limit( int val, int max, int min ) { + if ( val > max ) + val = max; +@@ -628,7 +615,7 @@ static int OPLOpenTable( void ) + } + /* make total level table */ + for (t = 0;t < EG_ENT-1 ;t++){ +- rate = ((1< voltage */ ++ rate = ((1< voltage */ + TL_TABLE[ t] = (int)rate; + TL_TABLE[TL_MAX+t] = -TL_TABLE[t]; + /* LOG(LOG_INF,("TotalLevel(%3d) = %x\n",t,TL_TABLE[t]));*/ +@@ -663,7 +650,7 @@ static int OPLOpenTable( void ) + for (i=0; i= EG_ENT ) pom = EG_ENT-1; */ + ENV_CURVE[i] = (int)pom; + /* DECAY ,RELEASE curve */ +@@ -1334,5 +1321,3 @@ int OPLTimerOver(FM_OPL *OPL,int c) + if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+c,(double)OPL->T[c]*OPL->TimerBase); + return OPL->status>>7; + } +- +- +diff -r d92191344055 src/libxineadec/nosefart/memguard.c +--- a/src/libxineadec/nosefart/memguard.c Sun Nov 28 20:42:19 2010 +0100 ++++ b/src/libxineadec/nosefart/memguard.c Sun Nov 28 20:47:08 2010 +0100 +@@ -33,6 +33,15 @@ + + #include + #include ++ ++#if HAVE_INTTYPES_H ++# include ++#else ++# if HAVE_STDINT_H ++# include ++# endif ++#endif ++ + #include "memguard.h" + #include "log.h" + +@@ -271,7 +280,7 @@ + char fail[256]; + + if (NULL == data || NULL == *data +- || 0xFFFFFFFF == (uint32) *data || 0xFFFFFFFF == (uint32) data) ++ || ((uintptr_t)-1) == (uintptr_t) *data || ((uintptr_t)-1) == (uintptr_t) data) + { + #ifdef NOFRENDO_DEBUG + sprintf(fail, "free: attempted to free NULL pointer at line %d of %s\n", +diff -r 075029931740 src/libxineadec/nosefart/osd.h +--- a/src/libxineadec/nosefart/osd.h Sun Nov 28 21:04:01 2010 +0100 ++++ b/src/libxineadec/nosefart/osd.h Sun Nov 28 15:12:02 2010 +0100 +@@ -27,7 +27,7 @@ + #define _OSD_H_ + + +-#ifdef __GNUC__ ++#if defined(__GNUC__) || defined(__ICC) + #define __PACKED__ __attribute__ ((packed)) + #define PATH_SEP '/' + #ifdef __DJGPP__ +diff -r 075029931740 src/libxineadec/nosefart/types.h +--- a/src/libxineadec/nosefart/types.h 2010-11-28 21:11:10.000000000 +0100 ++++ b/src/libxineadec/nosefart/types.h 2010-11-28 21:07:45.000000000 +0100 +@@ -23,8 +23,12 @@ + ** $Id: types.h,v 1.4 2004/08/27 19:33:37 valtri Exp $ */ -#ifndef _TYPES_H_ -#define _TYPES_H_ +#ifndef _NOSEFART_TYPES_H_ +#define _NOSEFART_TYPES_H_ ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif - #ifdef HAVE_CONFIG_H - #include "config.h" -@@ -88,7 +88,7 @@ typedef uint8 boolean; + /* Define this if running on little-endian (x86) systems */ + +@@ -95,7 +99,7 @@ #define ASSERT_MSG(msg) #endif @@ -20,56 +149,177 @@ diff -u -p -r1.1.1.1 types.h +#endif /* _NOSEFART_TYPES_H_ */ /* - ** $Log: diff_to_nosefart_cvs.patch,v $ - ** Revision 1.2 2005/05/07 09:11:39 valtri - ** *BUGFIX* - ** gcc4 patches from Dams Nadé (livna.org) and Keenan Pepper. - ** - ** Revision 1.1 2004/08/27 19:33:37 valtri - ** MINGW32 port. Engine library and most of plugins compiles now. - ** - ** List of some changes: - ** - replaced some _MSC_VER by more common WIN32 - ** - define INTLDIR, remove -static flag for included intl - ** - shared more common CFLAGS with DEBUG_CFLAGS - ** - use WIN32_CFLAGS for all building - ** - separate some flags into THREAD_CFLAGS_CONFIG, - ** THREAD_CFLAGS_CONFIG and ZLIB_LIB_CONFIG for public xine-config, - ** automatically use internal libs if necessary - ** - don't warn about missing X for mingw and cygwin - ** - libw32dll disabled for WIN32 (making native loader would be - ** interesting, or porting wine code to Windows? :->) - ** - DVB and RTP disabled for WIN32, not ported yet - ** - fix build and fix a warning in cdda - ** - fix build for nosefart and libfaad - ** - implement configure option --disable-freetype - ** - sync libxine.pc and xine-config.in - ** - add -liberty to goom under WIN32 - ** - move original build files from included phread and zlib into archives - ** and replace them by autotools - ** -Index: nes_apu.c -=================================================================== -RCS file: /home/valtri/CVS/xine-lib/src/libxineadec/nosefart/nes_apu.c,v -retrieving revision 1.1.1.1 -diff -u -p -r1.1.1.1 nes_apu.c ---- nes_apu.c 12 Dec 2004 13:57:16 -0000 1.1.1.1 -+++ nes_apu.c 7 May 2005 08:23:36 -0000 -@@ -1011,10 +1011,13 @@ void apu_process(void *buffer, int num_s - accum = -0x8000; - - /* signed 16-bit output, unsigned 8-bit */ -- if (16 == apu->sample_bits) -- *((int16 *) buffer)++ = (int16) accum; -- else -- *((uint8 *) buffer)++ = (accum >> 8) ^ 0x80; -+ if (16 == apu->sample_bits) { -+ *((int16 *) buffer) = (int16) accum; -+ buffer = (int16 *) buffer + 1; -+ } else { -+ *((uint8 *) buffer) = (accum >> 8) ^ 0x80; -+ buffer = (int8 *) buffer + 1; -+ } - } - - /* resync cycle counter */ + ** $Log: types.h,v $ +diff -r 075029931740 src/libxineadec/nosefart/nes6502.h +--- a/src/libxineadec/nosefart/nes6502.h Sun Nov 28 15:12:02 2010 +0100 ++++ b/src/libxineadec/nosefart/nes6502.h Sun Nov 28 21:18:28 2010 +0100 +@@ -23,6 +23,9 @@ + ** $Id: nes6502.h,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ + */ + ++/* straitm */ ++#include "types.h" ++ + /* NOTE: 16-bit addresses avoided like the plague: use 32-bit values + ** wherever humanly possible + */ +diff -r 075029931740 src/libxineadec/nosefart/nsf.c +--- a/src/libxineadec/nosefart/nsf.c 2007-12-14 05:46:22.000000000 +0100 ++++ b/src/libxineadec/nosefart/nsf.c 2010-11-28 21:31:22.000000000 +0100 +@@ -693,7 +693,7 @@ nsf_t * nsf_load_extended(struct nsf_loa + #if 0 + if (length <= NSF_HEADER_SIZE) { + log_printf("nsf : [%s] not an NSF format file\n", +- loader->fname(loader)); ++ loader->fname); + goto error; + } + #endif +@@ -701,14 +701,14 @@ nsf_t * nsf_load_extended(struct nsf_loa + /* Read magic */ + if (loader->read(loader, id, 5)) { + log_printf("nsf : [%s] error reading magic number\n", +- loader->fname(loader)); ++ loader->fname); + goto error; + } + + /* Check magic */ + if (memcmp(id, NSF_MAGIC, 5)) { + log_printf("nsf : [%s] is not an NSF format file\n", +- loader->fname(loader)); ++ loader->fname); + goto error; + } + +@@ -719,7 +719,7 @@ nsf_t * nsf_load_extended(struct nsf_loa + + if (NULL == temp_nsf) { + log_printf("nsf : [%s] error allocating nsf header\n", +- loader->fname(loader)); ++ loader->fname); + goto error; + } + /* $$$ ben : safety net */ +@@ -730,7 +730,7 @@ nsf_t * nsf_load_extended(struct nsf_loa + /* Read header (without MAGIC) */ + if (loader->read(loader, (int8 *)temp_nsf+5, NSF_HEADER_SIZE - 5)) { + log_printf("nsf : [%s] error reading nsf header\n", +- loader->fname(loader)); ++ loader->fname); + goto error; + } + +@@ -763,7 +763,7 @@ nsf_t * nsf_load_extended(struct nsf_loa + + if (temp_nsf->length <= 0) { + log_printf("nsf : [%s] not an NSF format file (missing data)\n", +- loader->fname(loader)); ++ loader->fname); + goto error; + } + +@@ -778,14 +778,14 @@ nsf_t * nsf_load_extended(struct nsf_loa + } + if (NULL == temp_nsf->data) { + log_printf("nsf : [%s] error allocating nsf data\n", +- loader->fname(loader)); ++ loader->fname); + goto error; + } + + /* Read data */ + if (loader->read(loader, temp_nsf->data, temp_nsf->length)) { + log_printf("nsf : [%s] error reading NSF data\n", +- loader->fname(loader)); ++ loader->fname); + goto error; + } + +@@ -805,7 +805,7 @@ nsf_t * nsf_load_extended(struct nsf_loa + + if (size < sizeof(nsf_file_ext)) { + log_printf("nsf : [%s] corrupt extension size (%d)\n", +- loader->fname(loader), size); ++ loader->fname, size); + /* Not a fatal error here. Just skip extension loading. */ + break; + } +@@ -827,7 +827,7 @@ nsf_t * nsf_load_extended(struct nsf_loa + + if (loader->read(loader, tmp_time, size)) { + log_printf("nsf : [%s] missing extension data\n", +- loader->fname(loader)); ++ loader->fname); + /* Not a fatal error here. Just skip extension loading. */ + break; + } +@@ -835,7 +835,7 @@ nsf_t * nsf_load_extended(struct nsf_loa + temp_nsf->song_frames = malloc(sizeof(*temp_nsf->song_frames) * songs); + if (!temp_nsf->song_frames) { + log_printf("nsf : [%s] extension alloc failed\n", +- loader->fname(loader)); ++ loader->fname); + /* Not a fatal error here. Just skip extension loading. */ + break; + } +@@ -858,7 +858,7 @@ nsf_t * nsf_load_extended(struct nsf_loa + } + } else if (loader->skip(loader, size)) { + log_printf("nsf : [%s] extension skip failed\n", +- loader->fname(loader)); ++ loader->fname); + /* Not a fatal error here. Just skip extension loading. */ + break; + } +diff -r 8bf4ad557dac src/libxineadec/nosefart/nsf.h +--- a/src/libxineadec/nosefart/nsf.h Tue Nov 30 23:30:19 2010 +0100 ++++ b/src/libxineadec/nosefart/nsf.h Tue Nov 30 23:38:15 2010 +0100 +@@ -67,22 +67,22 @@ + typedef struct nsf_s + { + /* NESM header */ +- uint8 id[5] __PACKED__; /* NESM\x1A */ +- uint8 version __PACKED__; /* spec version */ +- uint8 num_songs __PACKED__; /* total num songs */ +- uint8 start_song __PACKED__; /* first song */ +- uint16 load_addr __PACKED__; /* loc to load code */ +- uint16 init_addr __PACKED__; /* init call address */ +- uint16 play_addr __PACKED__; /* play call address */ +- uint8 song_name[32] __PACKED__; /* name of song */ +- uint8 artist_name[32] __PACKED__; /* artist name */ +- uint8 copyright[32] __PACKED__; /* copyright info */ +- uint16 ntsc_speed __PACKED__; /* playback speed (if NTSC) */ +- uint8 bankswitch_info[8] __PACKED__; /* initial code banking */ +- uint16 pal_speed __PACKED__; /* playback speed (if PAL) */ +- uint8 pal_ntsc_bits __PACKED__; /* NTSC/PAL determination bits */ +- uint8 ext_sound_type __PACKED__; /* type of external sound gen. */ +- uint8 reserved[4] __PACKED__; /* reserved */ ++ uint8 id[5]; /* NESM\x1A */ ++ uint8 version; /* spec version */ ++ uint8 num_songs; /* total num songs */ ++ uint8 start_song; /* first song */ ++ uint16 load_addr; /* loc to load code */ ++ uint16 init_addr; /* init call address */ ++ uint16 play_addr; /* play call address */ ++ uint8 song_name[32]; /* name of song */ ++ uint8 artist_name[32]; /* artist name */ ++ uint8 copyright[32]; /* copyright info */ ++ uint16 ntsc_speed; /* playback speed (if NTSC) */ ++ uint8 bankswitch_info[8]; /* initial code banking */ ++ uint16 pal_speed; /* playback speed (if PAL) */ ++ uint8 pal_ntsc_bits; /* NTSC/PAL determination bits */ ++ uint8 ext_sound_type; /* type of external sound gen. */ ++ uint8 reserved[4]; /* reserved */ + + /* things that the NSF player needs */ + uint8 *data; /* actual NSF data */ +@@ -105,7 +105,7 @@ + + /* our main processing routine, calls all external mixing routines */ + void (*process)(void *buffer, int num_samples); +-} nsf_t; ++} __PACKED__ nsf_t; + + /* $$$ ben : Generic loader struct */ + struct nsf_loader_t { diff --git a/src/libxineadec/nosefart/nes6502.c b/src/libxineadec/nosefart/nes6502.c index f1ca80af4..d84bae912 100644 --- a/src/libxineadec/nosefart/nes6502.c +++ b/src/libxineadec/nosefart/nes6502.c @@ -1117,8 +1117,17 @@ */ /* register push/pull */ -#define PUSH(value) stack_page[S--] = (uint8) (value) -#define PULL() stack_page[++S] +#ifdef NES6502_MEM_ACCESS_CTRL + +# define PUSH(value) stack_push((S--),(value)) +# define PULL() stack_pull((++S)) + +#else + +# define PUSH(value) stack_page[S--] = (uint8) (value) +# define PULL() stack_page[++S] + +#endif /* #ifdef NES6502_MEM_ACCESS_CTRL */ /* Sets the Z and N flags based on given data, taken from precomputed table */ #define SET_NZ_FLAGS(value) P &= ~(N_FLAG | Z_FLAG); \ @@ -1166,50 +1175,194 @@ static uint8 *nes6502_banks[NES6502_NUMBANKS]; static uint8 *ram = NULL; static uint8 *stack_page = NULL; +/* access flag for memory + * $$$ ben : I add this for the playing time calculation. + * Only if compiled with NES6502_MEM_ACCESS. + */ +#ifdef NES6502_MEM_ACCESS_CTRL + +uint8 *acc_nes6502_banks[NES6502_NUMBANKS]; +static uint8 *acc_ram = NULL; +static uint8 *acc_stack_page = NULL; +uint8 nes6502_mem_access = 0; + +/* $$$ ben : + * Set memory access check flags, and store ORed frame global check + * for music time calculation. + */ +static void chk_mem_access(uint8 * access, int flags) +{ + uint8 oldchk = * access; + if ((oldchk&flags) != flags) { + nes6502_mem_access |= flags; + *access = oldchk|flags; + } +} + +INLINE void stack_push(uint8 s, uint8 v) +{ + chk_mem_access(acc_stack_page+s, NES6502_WRITE_ACCESS); + stack_page[s] = v; +} + +INLINE uint8 stack_pull(uint8 s) +{ + chk_mem_access(acc_stack_page+s, NES6502_READ_ACCESS); + return stack_page[s]; +} + +INLINE uint8 zp_read(register uint32 addr) +{ + chk_mem_access(acc_ram+addr, NES6502_READ_ACCESS); + return ram[addr]; +} + +INLINE void zp_write(register uint32 addr, uint8 v) +{ + chk_mem_access(acc_ram+addr, NES6502_WRITE_ACCESS); + ram[addr] = v; +} + +#define ZP_READ(addr) zp_read((addr)) +#define ZP_WRITE(addr, value) zp_write((addr),(value)) + +#define bank_readbyte(address) _bank_readbyte((address), NES6502_READ_ACCESS) +#define bank_readbyte_pc(address) _bank_readbyte((address), NES6502_EXE_ACCESS) + +#else +# define chk_mem_access(access, flags) /* ** Zero-page helper macros */ - #define ZP_READ(addr) ram[(addr)] #define ZP_WRITE(addr, value) ram[(addr)] = (uint8) (value) +#define bank_readbyte(address) _bank_readbyte((address)) +#define bank_readbyte_pc(address) _bank_readbyte((address)) + +#endif /* #ifdef NES6502_MEM_ACCESS_CTRL */ -INLINE uint8 bank_readbyte(register uint32 address) +#ifdef NES6502_MEM_ACCESS_CTRL +int max_access[NES6502_NUMBANKS] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + +INLINE uint8 _bank_readbyte(register uint32 address, const uint8 flags) +#else +INLINE uint8 _bank_readbyte(register uint32 address) +#endif { ASSERT(nes6502_banks[address >> NES6502_BANKSHIFT]); + +#ifdef NES6502_MEM_ACCESS_CTRL + //printf("chk_mem_access(acc_nes6502_banks[%d] + %d, %d)\n", address>>NES6502_BANKSHIFT, address & NES6502_BANKMASK, flags); + + if((address & NES6502_BANKMASK) > max_access[address>>NES6502_BANKSHIFT]) + { + max_access[address>>NES6502_BANKSHIFT] = address & NES6502_BANKMASK; + //printf("max_access[%d] increased to %d\n", address>>NES6502_BANKSHIFT, max_access[address>>NES6502_BANKSHIFT]); + } +#endif + chk_mem_access(acc_nes6502_banks[address>>NES6502_BANKSHIFT] + + (address & NES6502_BANKMASK), + flags); + return nes6502_banks[address >> NES6502_BANKSHIFT][address & NES6502_BANKMASK]; } + INLINE void bank_writebyte(register uint32 address, register uint8 value) { ASSERT(nes6502_banks[address >> NES6502_BANKSHIFT]); + +#ifdef NES6502_MEM_ACCESS_CTRL + //printf("chk_mem_access(acc_nes6502_banks[%d] + %d, %d)\n", address>>NES6502_BANKSHIFT, address & NES6502_BANKMASK, NES6502_WRITE_ACCESS); + + if((address & NES6502_BANKMASK) > max_access[address>>NES6502_BANKSHIFT]) + { + max_access[address>>NES6502_BANKSHIFT] = address & NES6502_BANKMASK; + //printf("max_access[%d] increased to %d\n", address>>NES6502_BANKSHIFT, max_access[address>>NES6502_BANKSHIFT]); + } +#endif + + chk_mem_access(acc_nes6502_banks[address>>NES6502_BANKSHIFT] + + (address & NES6502_BANKMASK), + NES6502_WRITE_ACCESS); + nes6502_banks[address >> NES6502_BANKSHIFT][address & NES6502_BANKMASK] = value; } +/* Read a 16bit word */ +#define READ_SNES_16(bank,offset) \ +(\ + (offset) [ (uint8 *) (bank) ] |\ + ((unsigned int)( ((offset)+1) [ (uint8 *) (bank) ] ) << 8)\ +) + INLINE uint32 zp_address(register uint8 address) { - uint8 *x = ram + address; - return (x[1] << 8) | x[0]; + chk_mem_access(acc_ram+address, NES6502_READ_ACCESS); + chk_mem_access(acc_ram+address+1, NES6502_READ_ACCESS); + +#if defined (HOST_LITTLE_ENDIAN) && defined(HOST_UNALIGN_WORD) + /* TODO: this fails if src address is $xFFF */ + /* TODO: this fails if host architecture doesn't support byte alignment */ + /* $$$ ben : DONE */ + return (uint32) (*(uint16 *)(ram + address)); +#elif defined(TARGET_CPU_PPC) + return __lhbrx(ram, address); +#else + return READ_SNES_16(ram,address); +/* uint32 x = (uint32) *(uint16 *)(ram + address); */ +/* return (x << 8) | (x >> 8); */ +//#endif /* TARGET_CPU_PPC */ +#endif /* HOST_LITTLE_ENDIAN */ } INLINE uint32 bank_readaddress(register uint32 address) { - uint8 *x = nes6502_banks[address >> NES6502_BANKSHIFT] + (address & NES6502_BANKMASK); - return (x[1] << 8) | x[0]; + +#ifdef NES6502_MEM_ACCESS_CTRL + { + const unsigned int offset = address & NES6502_BANKMASK; + uint8 * addr = acc_nes6502_banks[address >> NES6502_BANKSHIFT]; + chk_mem_access(addr+offset+0, NES6502_READ_ACCESS); + chk_mem_access(addr+offset+1, NES6502_READ_ACCESS); + } +#endif + +#if defined (HOST_LITTLE_ENDIAN) && defined(HOST_UNALIGN_WORD) + /* TODO: this fails if src address is $xFFF */ + /* TODO: this fails if host architecture doesn't support byte alignment */ + /* $$$ ben : DONE */ + return (uint32) (*(uint16 *)(nes6502_banks[address >> NES6502_BANKSHIFT] + (address & NES6502_BANKMASK))); +#elif defined(TARGET_CPU_PPC) + return __lhbrx(nes6502_banks[address >> NES6502_BANKSHIFT], address & NES6502_BANKMASK); +#else + { + const unsigned int offset = address & NES6502_BANKMASK; + return READ_SNES_16(nes6502_banks[address >> NES6502_BANKSHIFT], offset); + } +/* uint32 x = (uint32) *(uint16 *)(nes6502_banks[address >> NES6502_BANKSHIFT] + (address & NES6502_BANKMASK)); */ +/* return (x << 8) | (x >> 8); */ +//#endif /* TARGET_CPU_PPC */ +#endif /* HOST_LITTLE_ENDIAN */ } + /* read a byte of 6502 memory */ static uint8 mem_read(uint32 address) { /* TODO: following cases are N2A03-specific */ /* RAM */ - if (address < 0x800) - return ram[address]; + if (address < 0x800) { + chk_mem_access(acc_ram + address, NES6502_READ_ACCESS); + return ram[address]; + } /* always paged memory */ // else if (address >= 0x6000) - else if (address >= 0x8000) - return bank_readbyte(address); + else if (address >= 0x8000) { + return bank_readbyte(address); + } /* check memory range handlers */ else { @@ -1230,6 +1383,7 @@ static void mem_write(uint32 address, uint8 value) /* RAM */ if (address < 0x800) { + chk_mem_access(acc_ram + address, NES6502_WRITE_ACCESS); ram[address] = value; return; } @@ -1258,11 +1412,19 @@ void nes6502_setcontext(nes6502_context *cpu) ASSERT(cpu); /* Set the page pointers */ - for (loop = 0; loop < NES6502_NUMBANKS; loop++) + for (loop = 0; loop < NES6502_NUMBANKS; loop++) { nes6502_banks[loop] = cpu->mem_page[loop]; +#ifdef NES6502_MEM_ACCESS_CTRL + acc_nes6502_banks[loop] = cpu->acc_mem_page[loop]; +#endif + } ram = nes6502_banks[0]; /* quicker zero-page/RAM references */ stack_page = ram + STACK_OFFSET; +#ifdef NES6502_MEM_ACCESS_CTRL + acc_ram = acc_nes6502_banks[0]; /* quicker zero-page/RAM references */ + acc_stack_page = acc_ram + STACK_OFFSET; +#endif pmem_read = cpu->read_handler; pmem_write = cpu->write_handler; @@ -1283,8 +1445,12 @@ void nes6502_getcontext(nes6502_context *cpu) int loop; /* Set the page pointers */ - for (loop = 0; loop < NES6502_NUMBANKS; loop++) + for (loop = 0; loop < NES6502_NUMBANKS; loop++) { cpu->mem_page[loop] = nes6502_banks[loop]; +#ifdef NES6502_MEM_ACCESS_CTRL + cpu->acc_mem_page[loop] = acc_nes6502_banks[loop]; +#endif + } cpu->read_handler = pmem_read; cpu->write_handler = pmem_write; @@ -1333,7 +1499,14 @@ int nes6502_execute(int remaining_cycles) GET_GLOBAL_REGS(); +#ifdef NES6502_MEM_ACCESS_CTRL + /* reset global memory access for this execute loop. */ + nes6502_mem_access = 0; +#endif + /* Continue until we run out of cycles */ + + while (remaining_cycles > 0) { instruction_cycles = 0; @@ -1373,9 +1546,10 @@ int nes6502_execute(int remaining_cycles) /* Fetch instruction */ //nes6502_disasm(PC, P, A, X, Y, S); - opcode = bank_readbyte(PC++); + opcode = bank_readbyte_pc(PC++); /* Execute instruction */ + switch (opcode) { case 0x00: /* BRK */ @@ -2363,16 +2537,20 @@ void nes6502_setdma(int cycles) dma_cycles += cycles; } +#ifdef NES6502_MEM_ACCESS_CTRL +void nes6502_chk_mem_access(uint8 * access, int flags) +{ + chk_mem_access(access, flags); +} +#endif + /* ** $Log: nes6502.c,v $ -** Revision 1.2 2003/01/09 19:50:03 jkeil -** NSF audio files were crashing on SPARC. -** -** - Define the correct HOST_ENDIAN for SPARC -** - remove unaligned memory accesses +** Revision 1.2 2003/05/01 22:34:19 benjihan +** New NSF plugin ** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources +** Revision 1.1 2003/04/08 20:53:00 ben +** Adding more files... ** ** Revision 1.6 2000/07/04 04:50:07 matt ** minor change to includes diff --git a/src/libxineadec/nosefart/nes6502.h b/src/libxineadec/nosefart/nes6502.h index 9b9be5811..8713304ec 100644 --- a/src/libxineadec/nosefart/nes6502.h +++ b/src/libxineadec/nosefart/nes6502.h @@ -23,6 +23,9 @@ ** $Id: nes6502.h,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ */ +/* straitm */ +#include "types.h" + /* NOTE: 16-bit addresses avoided like the plague: use 32-bit values ** wherever humanly possible */ @@ -47,6 +50,17 @@ #define NES6502_BANKMASK ((0x10000 / NES6502_NUMBANKS) - 1) +/* Add memory access control flags. This is a ram shadow memory that holds + * for each memory bytes access flags for read, write and execute access. + * The nes6502_mem_access holds all new access (all mode all location). It is + * used to determine if the player has loop in playing time calculation. + */ +#ifdef NES6502_MEM_ACCESS_CTRL +extern uint8 nes6502_mem_access; +# define NES6502_READ_ACCESS 1 +# define NES6502_WRITE_ACCESS 2 +# define NES6502_EXE_ACCESS 4 +#endif /* #ifdef NES6502_MEM_ACCESS_CTRL */ /* P (flag) register bitmasks */ #define N_FLAG 0x80 @@ -87,7 +101,10 @@ typedef struct typedef struct { - uint8 *mem_page[NES6502_NUMBANKS]; /* memory page pointers */ + uint8 * mem_page[NES6502_NUMBANKS]; /* memory page pointers */ +#ifdef NES6502_MEM_ACCESS_CTRL + uint8 * acc_mem_page[NES6502_NUMBANKS]; /* memory access page pointer */ +#endif nes6502_memread *read_handler; nes6502_memwrite *write_handler; int dma_cycles; @@ -110,6 +127,12 @@ extern uint8 nes6502_getbyte(uint32 address); extern uint32 nes6502_getcycles(boolean reset_flag); extern void nes6502_setdma(int cycles); +#ifdef NES6502_MEM_ACCESS_CTRL +extern void nes6502_chk_mem_access(uint8 * access, int flags); +#else +#define nes6502_chk_mem_access(access,flags) +#endif + /* Context get/set */ extern void nes6502_setcontext(nes6502_context *cpu); extern void nes6502_getcontext(nes6502_context *cpu); diff --git a/src/libxineadec/nosefart/nes_apu.c b/src/libxineadec/nosefart/nes_apu.c index 4a2ed8f4d..474e2ca1a 100644 --- a/src/libxineadec/nosefart/nes_apu.c +++ b/src/libxineadec/nosefart/nes_apu.c @@ -57,6 +57,11 @@ static int8 noise_long_lut[APU_NOISE_32K]; static int8 noise_short_lut[APU_NOISE_93]; #endif /* !REALTIME_NOISE */ +/* $$$ ben : last error */ +#define SET_APU_ERROR(APU,X) \ +if (APU) (APU)->errstr = "apu: " X; else + +#define APU_MIX_ENABLE(BIT) (apu->mix_enable&(1<<(BIT))) /* vblank length table used for rectangles, triangle, noise */ static const uint8 vbl_length[32] = @@ -102,27 +107,32 @@ const int dmc_clocks[16] = /* ratios of pos/neg pulse for rectangle waves */ static const int duty_lut[4] = { 2, 4, 8, 12 }; -#if 0 /* unused */ -static void apu_setcontext(apu_t *src_apu) + +void apu_setcontext(apu_t *src_apu) { apu = src_apu; + /* $$$ ben reset eoor string here. */ + SET_APU_ERROR(apu,"no error"); } -#endif /* ** Simple queue routines */ #define APU_QEMPTY() (apu->q_head == apu->q_tail) -static void apu_enqueue(apudata_t *d) +static int apu_enqueue(apudata_t *d) { ASSERT(apu); apu->queue[apu->q_head] = *d; apu->q_head = (apu->q_head + 1) & APUQUEUE_MASK; - if (APU_QEMPTY()) + if (APU_QEMPTY()) { log_printf("apu: queue overflow\n"); + SET_APU_ERROR(apu,"queue overflow"); + return -1; + } + return 0; } static apudata_t *apu_dequeue(void) @@ -131,19 +141,32 @@ static apudata_t *apu_dequeue(void) ASSERT(apu); - if (APU_QEMPTY()) - log_printf("apu: queue empty\n"); - + if (APU_QEMPTY()) { + log_printf("apu: queue empty\n"); + SET_APU_ERROR(apu,"queue empty"); + /* $$$ ben : should return 0 ??? */ + } loc = apu->q_tail; apu->q_tail = (apu->q_tail + 1) & APUQUEUE_MASK; return &apu->queue[loc]; } -void apu_setchan(int chan, boolean enabled) +int apu_setchan(int chan, boolean enabled) { - ASSERT(apu); - apu->mix_enable[chan] = enabled; + const unsigned int max = 6; + int old; + + ASSERT(apu); + if ((unsigned int)chan >= max) { + SET_APU_ERROR(apu,"channel out of range"); + return -1; + } + old = (apu->mix_enable>>chan) & 1; + if (enabled != (boolean)-1) { + apu->mix_enable = (apu->mix_enable & ~(1<cycle_rate); accum = 0; - if (apu->mix_enable[0]) accum += apu_rectangle(&apu->rectangle[0]); - if (apu->mix_enable[1]) accum += apu_rectangle(&apu->rectangle[1]); - if (apu->mix_enable[2]) accum += apu_triangle(&apu->triangle); - if (apu->mix_enable[3]) accum += apu_noise(&apu->noise); - if (apu->mix_enable[4]) accum += apu_dmc(&apu->dmc); + if (APU_MIX_ENABLE(0)) accum += apu_rectangle(&apu->rectangle[0]); + if (APU_MIX_ENABLE(1)) accum += apu_rectangle(&apu->rectangle[1]); + if (APU_MIX_ENABLE(2)) accum += apu_triangle(&apu->triangle); + if (APU_MIX_ENABLE(3)) accum += apu_noise(&apu->noise); + if (APU_MIX_ENABLE(4)) accum += apu_dmc(&apu->dmc); - if (apu->ext && apu->mix_enable[5]) accum += apu->ext->process(); + if (apu->ext && APU_MIX_ENABLE(5)) accum += apu->ext->process(); /* do any filtering */ if (APU_FILTER_NONE != apu->filter_type) @@ -1012,11 +1035,12 @@ void apu_process(void *buffer, int num_samples) /* signed 16-bit output, unsigned 8-bit */ if (16 == apu->sample_bits) { - *((int16 *) buffer) = (int16) accum; - buffer = (int16 *) buffer + 1; - } else { - *((uint8 *) buffer) = (accum >> 8) ^ 0x80; - buffer = (int8 *) buffer + 1; + *(int16 *)(buffer) = (int16) accum; + buffer += sizeof(int16); + } + else { + *(uint8 *)(buffer) = (accum >> 8) ^ 0x80; + buffer += sizeof(uint8); } } @@ -1025,10 +1049,18 @@ void apu_process(void *buffer, int num_samples) } /* set the filter type */ -void apu_setfilter(int filter_type) +/* $$$ ben : + * Add a get feature (filter_type == -1) and returns old filter type + */ +int apu_setfilter(int filter_type) { + int old; ASSERT(apu); - apu->filter_type = filter_type; + old = apu->filter_type; + if (filter_type != -1) { + apu->filter_type = filter_type; + } + return old; } void apu_reset(void) @@ -1057,7 +1089,7 @@ void apu_reset(void) apu->ext->reset(); } -static void apu_build_luts(int num_samples) +void apu_build_luts(int num_samples) { int i; @@ -1090,12 +1122,15 @@ static void apu_setactive(apu_t *active) apu_t *apu_create(int sample_rate, int refresh_rate, int sample_bits, boolean stereo) { apu_t *temp_apu; - int channel; +/* int channel; */ temp_apu = malloc(sizeof(apu_t)); if (NULL == temp_apu) return NULL; + /* $$$ ben : safety net, in case we forgot to init something */ + memset(temp_apu,0,sizeof(apu_t)); + SET_APU_ERROR(temp_apu,"no error"); temp_apu->sample_rate = sample_rate; temp_apu->refresh_rate = refresh_rate; temp_apu->sample_bits = sample_bits; @@ -1114,8 +1149,9 @@ apu_t *apu_create(int sample_rate, int refresh_rate, int sample_bits, boolean st apu_setactive(temp_apu); apu_reset(); - for (channel = 0; channel < 6; channel++) - apu_setchan(channel, TRUE); + temp_apu->mix_enable = 0x3F; +/* for (channel = 0; channel < 6; channel++) */ +/* apu_setchan(channel, TRUE); */ apu_setfilter(APU_FILTER_LOWPASS); @@ -1137,15 +1173,23 @@ void apu_destroy(apu_t *src_apu) } } -void apu_setext(apu_t *src_apu, apuext_t *ext) +int apu_setext(apu_t *src_apu, apuext_t *ext) { ASSERT(src_apu); + /* $$$ ben : seem cleaner like this */ + if (src_apu->ext) { + src_apu->ext->shutdown(); + } + src_apu->ext = ext; /* initialize it */ if (src_apu->ext) src_apu->ext->init(); + + /* $$$ ben : May be one day extension int () will return error code */ + return 0; } /* this exists for external mixing routines */ diff --git a/src/libxineadec/nosefart/nes_apu.h b/src/libxineadec/nosefart/nes_apu.h index 09b5842d9..9efbb560e 100644 --- a/src/libxineadec/nosefart/nes_apu.h +++ b/src/libxineadec/nosefart/nes_apu.h @@ -249,7 +249,7 @@ typedef struct apu_s void *buffer; /* pointer to output buffer */ int num_samples; - boolean mix_enable[6]; + int mix_enable; /* $$$ben : should improve emulation */ int filter_type; int32 cycle_rate; @@ -260,6 +260,9 @@ typedef struct apu_s void (*process)(void *buffer, int num_samples); + /* $$$ ben : last error string */ + const char * errstr; + /* external sound chip */ apuext_t *ext; } apu_t; @@ -272,11 +275,11 @@ extern "C" { /* Function prototypes */ extern apu_t *apu_create(int sample_rate, int refresh_rate, int sample_bits, boolean stereo); extern void apu_destroy(apu_t *apu); -extern void apu_setext(apu_t *apu, apuext_t *ext); -extern void apu_setfilter(int filter_type); +extern int apu_setext(apu_t *apu, apuext_t *ext); +extern int apu_setfilter(int filter_type); extern void apu_process(void *buffer, int num_samples); extern void apu_reset(void); -extern void apu_setchan(int chan, boolean enabled); +extern int apu_setchan(int chan, boolean enabled); extern int32 apu_getcyclerate(void); extern apu_t *apu_getcontext(void); @@ -286,6 +289,7 @@ extern void apu_write(uint32 address, uint8 value); /* for visualization */ extern void apu_getpcmdata(void **data, int *num_samples, int *sample_bits); +extern void apu_setcontext(apu_t *src_apu); #ifdef __cplusplus } diff --git a/src/libxineadec/nosefart/nsf.c b/src/libxineadec/nosefart/nsf.c index 6bbc96423..69f77546b 100644 --- a/src/libxineadec/nosefart/nsf.c +++ b/src/libxineadec/nosefart/nsf.c @@ -23,6 +23,7 @@ ** $Id: nsf.c,v 1.4 2006/09/26 00:52:17 dgp85 Exp $ */ + #include #include #include "types.h" @@ -50,25 +51,34 @@ static void nsf_setcontext(nsf_t *nsf) static uint8 read_mirrored_ram(uint32 address) { - return cur_nsf->cpu->mem_page[0][address & 0x7FF]; + nes6502_chk_mem_access(&cur_nsf->cpu->acc_mem_page[0][address & 0x7FF], + NES6502_READ_ACCESS); + return cur_nsf->cpu->mem_page[0][address & 0x7FF]; } static void write_mirrored_ram(uint32 address, uint8 value) { - cur_nsf->cpu->mem_page[0][address & 0x7FF] = value; + nes6502_chk_mem_access(&cur_nsf->cpu->acc_mem_page[0][address & 0x7FF], + NES6502_WRITE_ACCESS); + cur_nsf->cpu->mem_page[0][address & 0x7FF] = value; } /* can be used for both banked and non-bankswitched NSFs */ static void nsf_bankswitch(uint32 address, uint8 value) { int cpu_page; + int roffset; uint8 *offset; cpu_page = address & 0x0F; - offset = (cur_nsf->data - (cur_nsf->load_addr & 0x0FFF)) + (value << 12); + roffset = -(cur_nsf->load_addr & 0x0FFF) + ((int)value << 12); + offset = cur_nsf->data + roffset; nes6502_getcontext(cur_nsf->cpu); cur_nsf->cpu->mem_page[cpu_page] = offset; +#ifdef NES6502_MEM_ACCESS_CTRL + cur_nsf->cpu->acc_mem_page[cpu_page] = offset + cur_nsf->length; +#endif nes6502_setcontext(cur_nsf->cpu); } @@ -248,6 +258,18 @@ static void nsf_inittune(nsf_t *nsf) memset(nsf->cpu->mem_page[6], 0, 0x1000); memset(nsf->cpu->mem_page[7], 0, 0x1000); +#ifdef NES6502_MEM_ACCESS_CTRL + memset(nsf->cpu->acc_mem_page[0], 0, 0x800); + memset(nsf->cpu->acc_mem_page[6], 0, 0x1000); + memset(nsf->cpu->acc_mem_page[7], 0, 0x1000); + memset(nsf->data+nsf->length, 0, nsf->length); +#endif + nsf->cur_frame = 0; +/* nsf->last_access_frame = 0; */ + nsf->cur_frame_end = !nsf->song_frames + ? 0 + : nsf->song_frames[nsf->current_song]; + if (nsf->bankswitched) { /* the first hack of the NSF spec! */ @@ -289,36 +311,81 @@ static void nsf_inittune(nsf_t *nsf) void nsf_frame(nsf_t *nsf) { - //nsf_setcontext(nsf); /* future expansion =) */ + // This is how Matthew Conte left it + //nsf_setcontext(nsf); /* future expansion =) */ + + // This was suggested by Arne Morten Kvarving, who says: +/* Also, I fixed a bug that prevented Nosefart to play multiple tunes at + one time (actually it was just a few missing setcontext calls in the + playback routine, it had a nice TODO commented beside it. You had to set + the cpu and apu contexts not just the nsf context). + + it will affect any player that tries to use nosefart to play more than one + tune at a time. +*/ + nsf_setcontext(nsf); + apu_setcontext(nsf->apu); + nes6502_setcontext(nsf->cpu); /* one frame of NES processing */ nsf_setup_routine(nsf->play_addr, 0, 0); nes6502_execute((int) NES_FRAME_CYCLES); + + ++nsf->cur_frame; +#if defined(NES6502_MEM_ACCESS_CTRL) && 0 + if (nes6502_mem_access) { + uint32 sec = + (nsf->last_access_frame + nsf->playback_rate - 1) / nsf->playback_rate; + nsf->last_access_frame = nsf->cur_frame; + fprintf(stderr,"nsf : memory access [%x] at frame #%u [%u:%02u]\n", + nes6502_mem_access, + nsf->last_access_frame, + sec/60, sec%60); + } +#endif + } /* Deallocate memory */ -static void nes_shutdown(nsf_t *nsf) +void nes_shutdown(nsf_t *nsf) { int i; ASSERT(nsf); - + if (nsf->cpu) { if (nsf->cpu->mem_page[0]) - free(nsf->cpu->mem_page[0]); - for (i = 5; i <= 7; i++) - { - if (nsf->cpu->mem_page[i]) - free(nsf->cpu->mem_page[i]); + { + free(nsf->cpu->mem_page[0]);/*tracks 1 and 2 of lifeforce hang here.*/ + } + for (i = 5; i <= 7; i++) { + if (nsf->cpu->mem_page[i]) + { + free(nsf->cpu->mem_page[i]); + } } + +#ifdef NES6502_MEM_ACCESS_CTRL + if (nsf->cpu->acc_mem_page[0]) + { + free(nsf->cpu->acc_mem_page[0]); + } + for (i = 5; i <= 7; i++) { + if (nsf->cpu->acc_mem_page[i]) + { + free(nsf->cpu->acc_mem_page[i]); + } + } +#endif free(nsf->cpu); } } -void nsf_init(void) +int nsf_init(void) { nes6502_init(); + return 0; } /* Initialize NES CPU, hardware, etc. */ @@ -344,18 +411,27 @@ static int nsf_cpuinit(nsf_t *nsf) return -1; } +#ifdef NES6502_MEM_ACCESS_CTRL + nsf->cpu->acc_mem_page[0] = malloc(0x800); + if (NULL == nsf->cpu->acc_mem_page[0]) + return -1; + /* allocate some space for the NSF "player" MMC5 EXRAM, and WRAM */ + for (i = 5; i <= 7; i++) + { + nsf->cpu->acc_mem_page[i] = malloc(0x1000); + if (NULL == nsf->cpu->acc_mem_page[i]) + return -1; + } +#endif + nsf->cpu->read_handler = nsf_readhandler; nsf->cpu->write_handler = nsf_writehandler; return 0; } -static void nsf_setup(nsf_t *nsf) +static unsigned int nsf_playback_rate(nsf_t *nsf) { - int i; - - nsf->current_song = nsf->start_song; - if (nsf->pal_ntsc_bits & NSF_DEDICATED_PAL) { if (nsf->pal_speed) @@ -370,9 +446,17 @@ static void nsf_setup(nsf_t *nsf) else nsf->playback_rate = 60; /* 60 Hz */ } + return 0; +} - nsf->bankswitched = FALSE; +static void nsf_setup(nsf_t *nsf) +{ + int i; + + nsf->current_song = nsf->start_song; + nsf_playback_rate(nsf); + nsf->bankswitched = FALSE; for (i = 0; i < 8; i++) { if (nsf->bankswitch_info[i]) @@ -389,212 +473,551 @@ static void nsf_setup(nsf_t *nsf) #define SWAP_16(x) (((uint16) x >> 8) | (((uint16) x & 0xFF) << 8)) #endif /* !HOST_LITTLE_ENDIAN */ -/* Load a ROM image into memory */ -nsf_t *nsf_load(char *filename, void *source, int length) +/* $$$ ben : find extension. Should be OK with DOS, but not with some + * OS like RiscOS ... */ +static char * find_ext(char *fn) { - FILE *fp = NULL; - char *new_fn = NULL; - nsf_t *temp_nsf; + char * a, * b, * c; + a = strrchr(fn,'.'); + b = strrchr(fn,'/'); + c = strrchr(fn,'\\'); + if (a <= b || a <= c) { + a = 0; + } + return a; +} - if (NULL == filename && NULL == source) - return NULL; - - if (NULL == source) - { - fp = fopen(filename, "rb"); +/* $$$ ben : FILE loader */ +struct nsf_file_loader_t { + struct nsf_loader_t loader; + FILE *fp; + char * fname; + int name_allocated; +}; - /* Didn't find the file? Maybe the .NSF extension was omitted */ - if (NULL == fp) - { - new_fn = malloc(strlen(filename) + 5); - if (NULL == new_fn) - return NULL; - strcpy(new_fn, filename); +static int nfs_open_file(struct nsf_loader_t *loader) +{ + struct nsf_file_loader_t * floader = (struct nsf_file_loader_t *)loader; + + floader->name_allocated = 0; + floader->fp = 0; + if (!floader->fname) { + return -1; + } + floader->fp = fopen(floader->fname,"rb"); + if (!floader->fp) { + char * fname, * ext; + ext = find_ext(floader->fname); + if (ext) { + /* There was an extension, so we do not change it */ + return -1; + } + fname = malloc(strlen(floader->fname) + 5); + if (!fname) { + return -1; + } + /* try with .nsf extension. */ + strcpy(fname, floader->fname); + strcat(fname, ".nsf"); + floader->fp = fopen(fname,"rb"); + if (!floader->fp) { + free(fname); + return -1; + } + floader->fname = fname; + floader->name_allocated = 1; + } + return 0; +} - if (NULL == strrchr(new_fn, '.')) - strcat(new_fn, ".nsf"); +static void nfs_close_file(struct nsf_loader_t *loader) +{ + struct nsf_file_loader_t * floader = (struct nsf_file_loader_t *)loader; + if (floader->fp) { + fclose(floader->fp); + floader->fp = 0; + } + if (floader->fname && floader->name_allocated) { + free(floader->fname); + floader->fname = 0; + floader->name_allocated = 0; + } +} - fp = fopen(new_fn, "rb"); +static int nfs_read_file(struct nsf_loader_t *loader, void *data, int n) +{ + struct nsf_file_loader_t * floader = (struct nsf_file_loader_t *)loader; + int r = fread(data, 1, n, floader->fp); + if (r >= 0) { + r = n-r; + } + return r; +} - if (NULL == fp) - { - log_printf("could not find file '%s'\n", new_fn); - free(new_fn); - return NULL; - } - } - } +static int nfs_length_file(struct nsf_loader_t *loader) +{ + struct nsf_file_loader_t * floader = (struct nsf_file_loader_t *)loader; + long save, pos; + save = ftell(floader->fp); + fseek(floader->fp, 0, SEEK_END); + pos = ftell(floader->fp); + fseek(floader->fp, save, SEEK_SET); + return pos; +} - temp_nsf = malloc(sizeof(nsf_t)); - if (NULL == temp_nsf) { - fclose(fp); - free(new_fn); - return NULL; - } +static int nfs_skip_file(struct nsf_loader_t *loader, int n) +{ + struct nsf_file_loader_t * floader = (struct nsf_file_loader_t *)loader; + int r; + r = fseek(floader->fp, n, SEEK_CUR); + return r; +} - /* Read in the header */ - if (NULL == source) - fread(temp_nsf, 1, NSF_HEADER_SIZE, fp); - else - memcpy(temp_nsf, source, NSF_HEADER_SIZE); +static const char * nfs_fname_file(struct nsf_loader_t *loader) +{ + struct nsf_file_loader_t * floader = (struct nsf_file_loader_t *)loader; + return floader->fname ? floader->fname : ""; +} - if (memcmp(temp_nsf->id, NSF_MAGIC, 5)) - { - if (NULL == source) - { - log_printf("%s is not an NSF format file\n", new_fn); - fclose(fp); - free(new_fn); - } - nsf_free(&temp_nsf); - return NULL; - } +static struct nsf_file_loader_t nsf_file_loader = { + { + nfs_open_file, + nfs_close_file, + nfs_read_file, + nfs_length_file, + nfs_skip_file, + nfs_fname_file + }, + 0,0,0 +}; + +struct nsf_mem_loader_t { + struct nsf_loader_t loader; + uint8 *data; + unsigned long cur; + unsigned long len; + char fname[32]; +}; - /* fixup endianness */ - temp_nsf->load_addr = SWAP_16(temp_nsf->load_addr); - temp_nsf->init_addr = SWAP_16(temp_nsf->init_addr); - temp_nsf->play_addr = SWAP_16(temp_nsf->play_addr); - temp_nsf->ntsc_speed = SWAP_16(temp_nsf->ntsc_speed); - temp_nsf->pal_speed = SWAP_16(temp_nsf->pal_speed); +static int nfs_open_mem(struct nsf_loader_t *loader) +{ + struct nsf_mem_loader_t * mloader = (struct nsf_mem_loader_t *)loader; + if (!mloader->data) { + return -1; + } + mloader->cur = 0; + sprintf(mloader->fname,"", + mloader->data, (unsigned int)mloader->len); + return 0; +} - /* we're now at position 80h */ - if (NULL == source) - { - fseek(fp, 0, SEEK_END); - temp_nsf->length = ftell(fp) - NSF_HEADER_SIZE; - } - else - { - temp_nsf->length = length - NSF_HEADER_SIZE; - } +static void nfs_close_mem(struct nsf_loader_t *loader) +{ + struct nsf_mem_loader_t * mloader = (struct nsf_mem_loader_t *)loader; + mloader->data = 0; + mloader->cur = 0; + mloader->len = 0; +} - /* Allocate NSF space, and load it up! */ - temp_nsf->data = malloc(temp_nsf->length); - if (NULL == temp_nsf->data) - { - log_printf("error allocating memory for NSF data\n"); - nsf_free(&temp_nsf); - return NULL; - } +static int nfs_read_mem(struct nsf_loader_t *loader, void *data, int n) +{ + struct nsf_mem_loader_t * mloader = (struct nsf_mem_loader_t *)loader; + int rem; + if (n <= 0) { + return n; + } + if (!mloader->data) { + return -1; + } + rem = mloader->len - mloader->cur; + if (rem > n) { + rem = n; + } + memcpy(data, mloader->data + mloader->cur, rem); + mloader->cur += rem; + return n - rem; +} - /* seek to end of header, read in data */ - if (NULL == source) - { - fseek(fp, NSF_HEADER_SIZE, SEEK_SET); - fread(temp_nsf->data, temp_nsf->length, 1, fp); +static int nfs_length_mem(struct nsf_loader_t *loader) +{ + struct nsf_mem_loader_t * mloader = (struct nsf_mem_loader_t *)loader; + return mloader->len; +} - fclose(fp); +static int nfs_skip_mem(struct nsf_loader_t *loader, int n) +{ + struct nsf_mem_loader_t * mloader = (struct nsf_mem_loader_t *)loader; + unsigned long goal = mloader->cur + n; + mloader->cur = (goal > mloader->len) ? mloader->len : goal; + return goal - mloader->cur; +} - if (new_fn) - free(new_fn); - } - else - memcpy(temp_nsf->data, (uint8 *) source + NSF_HEADER_SIZE, length - NSF_HEADER_SIZE); +static const char * nfs_fname_mem(struct nsf_loader_t *loader) +{ + struct nsf_mem_loader_t * mloader = (struct nsf_mem_loader_t *)loader; + return mloader->fname; +} + +static struct nsf_mem_loader_t nsf_mem_loader = { + { nfs_open_mem, nfs_close_mem, nfs_read_mem, nfs_length_mem, nfs_skip_mem }, + 0,0,0 +}; + +nsf_t * nsf_load_extended(struct nsf_loader_t * loader) +{ + nsf_t *temp_nsf = 0; + int length; + char id[6]; + + struct { + uint8 magic[4]; /* always "NESM" */ + uint8 type[4]; /* defines extension type */ + uint8 size[4]; /* extension data size (this struct include) */ + } nsf_file_ext; + + /* no loader ! */ + if (!loader) { + return NULL; + } + + /* Open the "file" */ + if (loader->open(loader) < 0) { + return NULL; + } + + /* Get file size, and exit if there is not enough data for NSF header + * and more since it does not make sens to have header without data. + */ + length = loader->length(loader); + /* For version 2, we do not need file length. just check error later. */ +#if 0 + if (length <= NSF_HEADER_SIZE) { + log_printf("nsf : [%s] not an NSF format file\n", + loader->fname); + goto error; + } +#endif + + /* Read magic */ + if (loader->read(loader, id, 5)) { + log_printf("nsf : [%s] error reading magic number\n", + loader->fname); + goto error; + } + + /* Check magic */ + if (memcmp(id, NSF_MAGIC, 5)) { + log_printf("nsf : [%s] is not an NSF format file\n", + loader->fname); + goto error; + } + + /* $$$ ben : Now the file should be an NSF, we can start allocating. + * first : the nsf struct + */ + temp_nsf = malloc(sizeof(nsf_t)); + + if (NULL == temp_nsf) { + log_printf("nsf : [%s] error allocating nsf header\n", + loader->fname); + goto error; + } + /* $$$ ben : safety net */ + memset(temp_nsf,0,sizeof(nsf_t)); + /* Copy magic ID */ + memcpy(temp_nsf,id,5); + + /* Read header (without MAGIC) */ + if (loader->read(loader, (int8 *)temp_nsf+5, NSF_HEADER_SIZE - 5)) { + log_printf("nsf : [%s] error reading nsf header\n", + loader->fname); + goto error; + } + + /* fixup endianness */ + temp_nsf->load_addr = SWAP_16(temp_nsf->load_addr); + temp_nsf->init_addr = SWAP_16(temp_nsf->init_addr); + temp_nsf->play_addr = SWAP_16(temp_nsf->play_addr); + temp_nsf->ntsc_speed = SWAP_16(temp_nsf->ntsc_speed); + temp_nsf->pal_speed = SWAP_16(temp_nsf->pal_speed); + + /* we're now at position 80h */ + + + /* Here comes the specific codes for spec version 2 */ + + temp_nsf->length = 0; + + if (temp_nsf->version > 1) { + /* Get specified data size in reserved field (3 bytes). */ + temp_nsf->length = 0 + + temp_nsf->reserved[0] + + (temp_nsf->reserved[1]<<8) + + (temp_nsf->reserved[2]<<16); + + } + /* no specified size : try to guess with file length. */ + if (!temp_nsf->length) { + temp_nsf->length = length - NSF_HEADER_SIZE; + } + + if (temp_nsf->length <= 0) { + log_printf("nsf : [%s] not an NSF format file (missing data)\n", + loader->fname); + goto error; + } + + /* Allocate NSF space, and load it up! */ + { + int len = temp_nsf->length; +#ifdef NES6502_MEM_ACCESS_CTRL + /* $$$ twice memory for access control shadow mem. */ + len <<= 1; +#endif + temp_nsf->data = malloc(len); + } + if (NULL == temp_nsf->data) { + log_printf("nsf : [%s] error allocating nsf data\n", + loader->fname); + goto error; + } + + /* Read data */ + if (loader->read(loader, temp_nsf->data, temp_nsf->length)) { + log_printf("nsf : [%s] error reading NSF data\n", + loader->fname); + goto error; + } + + /* Here comes the second part of spec > 1 : get extension */ + while (!loader->read(loader, &nsf_file_ext, sizeof(nsf_file_ext)) + && !memcmp(nsf_file_ext.magic,id,4)) { + /* Got a NESM extension here. Checks for known extension type : + * right now, the only extension is "TIME" which give songs length. + * in frames. + */ + int size; + size = 0 + + nsf_file_ext.size[0] + + (nsf_file_ext.size[1] << 8) + + (nsf_file_ext.size[2] << 16) + + (nsf_file_ext.size[3] << 24); + + if (size < sizeof(nsf_file_ext)) { + log_printf("nsf : [%s] corrupt extension size (%d)\n", + loader->fname, size); + /* Not a fatal error here. Just skip extension loading. */ + break; + } + size -= sizeof(nsf_file_ext); + + if (!temp_nsf->song_frames + && !memcmp(nsf_file_ext.type,"TIME", 4) + && !(size & 3) + && (size >= 2*4) + && (size <= 256*4)) { + + uint8 tmp_time[256][4]; + int tsongs = size >> 2; + int i; + int songs = temp_nsf->num_songs; + + /* Add 1 for 0 which contains total time for all songs. */ + ++songs; + + if (loader->read(loader, tmp_time, size)) { + log_printf("nsf : [%s] missing extension data\n", + loader->fname); + /* Not a fatal error here. Just skip extension loading. */ + break; + } + /* Alloc song_frames for songs (not tsongs). */ + temp_nsf->song_frames = malloc(sizeof(*temp_nsf->song_frames) * songs); + if (!temp_nsf->song_frames) { + log_printf("nsf : [%s] extension alloc failed\n", + loader->fname); + /* Not a fatal error here. Just skip extension loading. */ + break; + } + + if (tsongs > songs) { + tsongs = songs; + } + + /* Copy time info. */ + for (i=0; isong_frames[i] = 0 + | tmp_time[i][0] + | (tmp_time[i][1] << 8) + | (tmp_time[i][2] << 16) + | (tmp_time[i][2] << 24); + } + /* Clear missing (safety net). */ + for (; isong_frames[i] = 0; + } + } else if (loader->skip(loader, size)) { + log_printf("nsf : [%s] extension skip failed\n", + loader->fname); + /* Not a fatal error here. Just skip extension loading. */ + break; + } + } + + + /* Close "file" */ + loader->close(loader); + loader = 0; /* Set up some variables */ nsf_setup(temp_nsf); - temp_nsf->apu = NULL; /* just make sure */ - if (nsf_cpuinit(temp_nsf)) - { - nsf_free(&temp_nsf); - return NULL; + if (nsf_cpuinit(temp_nsf)) { + log_printf("nsf : error cpu init\n"); + goto error; } - return temp_nsf; -} - -/* Free an NSF */ -void nsf_free(nsf_t **nsf) -{ - if (*nsf) - { - if ((*nsf)->apu) - apu_destroy((*nsf)->apu); - - nes_shutdown(*nsf); - if ((*nsf)->data) - free((*nsf)->data); - - free(*nsf); + /* $$$ ben : some people tell that goto are not clean. I am not agree with + * them. In most case, it allow to avoid code duplications, which are as + * most people know a source of error... Here we are sure of being clean + */ + error: + if (loader) { + loader->close(loader); + } + if (temp_nsf) { + nsf_free(&temp_nsf); } + return 0; } -void nsf_setchan(nsf_t *nsf, int chan, boolean enabled) +/* Load a ROM image into memory */ +nsf_t *nsf_load(const char *filename, void *source, int length) { - if (nsf) - { - nsf_setcontext(nsf); - apu_setchan(chan, enabled); - } + struct nsf_loader_t * loader = 0; + + /* $$$ ben : new loader */ + if (filename) { + nsf_file_loader.fname = (char *)filename; + loader = &nsf_file_loader.loader; + } else { + nsf_mem_loader.data = source; + nsf_mem_loader.len = length; + nsf_mem_loader.fname[0] = 0; + loader = &nsf_mem_loader.loader; + } + return nsf_load_extended(loader); } -void nsf_playtrack(nsf_t *nsf, int track, int sample_rate, int sample_bits, boolean stereo) +/* Free an NSF */ +void nsf_free(nsf_t **pnsf) { - ASSERT(nsf); + nsf_t *nsf; - /* make this NSF the current context */ - nsf_setcontext(nsf); + if (!pnsf) { + return; + } - /* create the APU */ - if (nsf->apu) + nsf = *pnsf; + /* $$$ ben : Don't see why passing a pointer to pointer + * is not to clear it :) */ + *pnsf = 0; + + if (nsf) { + if (nsf->apu) apu_destroy(nsf->apu); - nsf->apu = apu_create(sample_rate, nsf->playback_rate, sample_bits, stereo); - if (NULL == nsf->apu) - { - nsf_free(&nsf); - return; - } + nes_shutdown(nsf); + + if (nsf->data) + free(nsf->data); - apu_setext(nsf->apu, nsf_getext(nsf)); + if (nsf->song_frames) + free (nsf->song_frames); - /* go ahead and init all the read/write handlers */ - build_address_handlers(nsf); + free(nsf); + } +} - /* convenience? */ - nsf->process = nsf->apu->process; +int nsf_setchan(nsf_t *nsf, int chan, boolean enabled) +{ + if (!nsf) + return -1; - nes6502_setcontext(nsf->cpu); + nsf_setcontext(nsf); + return apu_setchan(chan, enabled); +} - if (track > nsf->num_songs) - track = nsf->num_songs; - else if (track < 1) - track = 1; +int nsf_playtrack(nsf_t *nsf, int track, int sample_rate, int sample_bits, + boolean stereo) +{ + if (!nsf) { + return -1; + } + + /* make this NSF the current context */ + nsf_setcontext(nsf); + + /* create the APU */ + if (nsf->apu) { + apu_destroy(nsf->apu); + } + + nsf->apu = apu_create(sample_rate, nsf->playback_rate, sample_bits, stereo); + if (NULL == nsf->apu) + { + /* $$$ ben : from my point of view this is not clean. Function should + * never destroy object it has not created... + */ + /* nsf_free(&nsf); */ + return -1; + } - nsf->current_song = track; + apu_setext(nsf->apu, nsf_getext(nsf)); + + /* go ahead and init all the read/write handlers */ + build_address_handlers(nsf); + + /* convenience? */ + nsf->process = nsf->apu->process; + + nes6502_setcontext(nsf->cpu); + + if (track > nsf->num_songs) + track = nsf->num_songs; + else if (track < 1) + track = 1; + + nsf->current_song = track; - apu_reset(); + apu_reset(); + + nsf_inittune(nsf); - nsf_inittune(nsf); + return nsf->current_song; } -void nsf_setfilter(nsf_t *nsf, int filter_type) +int nsf_setfilter(nsf_t *nsf, int filter_type) { - if (nsf) - { - nsf_setcontext(nsf); - apu_setfilter(filter_type); - } + if (!nsf) { + return -1; + } + nsf_setcontext(nsf); + return apu_setfilter(filter_type); } /* ** $Log: nsf.c,v $ -** Revision 1.4 2006/09/26 00:52:17 dgp85 -** Free the filename string and close the file pointer when returning. -** -** Found by Coverity Scan. -** -** Revision 1.3 2003/08/25 21:51:43 f1rmb -** Reduce GCC verbosity (various prototype declaration fixes). ffmpeg, wine and fft*post are untouched (fft: for now). +** Revision 1.3 2003/05/01 22:34:20 benjihan +** New NSF plugin ** -** Revision 1.2 2003/01/09 18:36:40 jkeil -** memcpy copies too much, corrupts malloc heap +** Revision 1.2 2003/04/09 14:50:32 ben +** Clean NSF api. ** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources +** Revision 1.1 2003/04/08 20:53:00 ben +** Adding more files... ** ** Revision 1.14 2000/07/05 14:54:45 matt ** fix for naughty Crystalis rip diff --git a/src/libxineadec/nosefart/nsf.h b/src/libxineadec/nosefart/nsf.h index 163e2f62f..356c187a3 100644 --- a/src/libxineadec/nosefart/nsf.h +++ b/src/libxineadec/nosefart/nsf.h @@ -60,28 +60,29 @@ enum { NSF_FILTER_NONE, NSF_FILTER_LOWPASS, - NSF_FILTER_WEIGHTED + NSF_FILTER_WEIGHTED, + NSF_FILTER_MAX, /* $$$ ben : add this one for range chacking */ }; typedef struct nsf_s { /* NESM header */ - uint8 id[5]; /* NESM\x1A */ - uint8 version; /* spec version */ - uint8 num_songs; /* total num songs */ - uint8 start_song; /* first song */ - uint16 load_addr; /* loc to load code */ - uint16 init_addr; /* init call address */ - uint16 play_addr; /* play call address */ - uint8 song_name[32]; /* name of song */ - uint8 artist_name[32]; /* artist name */ - uint8 copyright[32]; /* copyright info */ - uint16 ntsc_speed; /* playback speed (if NTSC) */ - uint8 bankswitch_info[8]; /* initial code banking */ - uint16 pal_speed; /* playback speed (if PAL) */ - uint8 pal_ntsc_bits; /* NTSC/PAL determination bits */ - uint8 ext_sound_type; /* type of external sound gen. */ - uint8 reserved[4]; /* reserved */ + uint8 id[5]; /* NESM\x1A */ + uint8 version; /* spec version */ + uint8 num_songs; /* total num songs */ + uint8 start_song; /* first song */ + uint16 load_addr; /* loc to load code */ + uint16 init_addr; /* init call address */ + uint16 play_addr; /* play call address */ + uint8 song_name[32]; /* name of song */ + uint8 artist_name[32]; /* artist name */ + uint8 copyright[32]; /* copyright info */ + uint16 ntsc_speed; /* playback speed (if NTSC) */ + uint8 bankswitch_info[8]; /* initial code banking */ + uint16 pal_speed; /* playback speed (if PAL) */ + uint8 pal_ntsc_bits; /* NTSC/PAL determination bits */ + uint8 ext_sound_type; /* type of external sound gen. */ + uint8 reserved[4]; /* reserved */ /* things that the NSF player needs */ uint8 *data; /* actual NSF data */ @@ -90,6 +91,14 @@ typedef struct nsf_s uint8 current_song; /* current song */ boolean bankswitched; /* is bankswitched? */ + /* $$$ ben : Playing time ... */ + uint32 cur_frame; + uint32 cur_frame_end; + uint32 * song_frames; + + /* $$$ ben : Last error string */ + const char * errstr; + /* CPU and APU contexts */ nes6502_context *cpu; apu_t *apu; @@ -98,30 +107,55 @@ typedef struct nsf_s void (*process)(void *buffer, int num_samples); } __PACKED__ nsf_t; +/* $$$ ben : Generic loader struct */ +struct nsf_loader_t { + /* Init and open. */ + int (*open)(struct nsf_loader_t * loader); + + /* Close and shutdown. */ + void (*close) (struct nsf_loader_t * loader); + + /* This function should return <0 on error, else the number of byte NOT read. + * that way a simple 0 test tell us if read was complete. + */ + int (*read) (struct nsf_loader_t * loader, void *data, int n); + + /* Get file length. */ + int (*length) (struct nsf_loader_t * loader); + + /* Skip n bytes. */ + int (*skip) (struct nsf_loader_t * loader,int n); + + /* Get filename (for debug). */ + const char * (*fname) (struct nsf_loader_t * loader); + +}; + /* Function prototypes */ -extern void nsf_init(void); +extern int nsf_init(void); -extern nsf_t *nsf_load(char *filename, void *source, int length); +extern nsf_t * nsf_load_extended(struct nsf_loader_t * loader); +extern nsf_t *nsf_load(const char *filename, void *source, int length); extern void nsf_free(nsf_t **nsf_info); -extern void nsf_playtrack(nsf_t *nsf, int track, int sample_rate, int sample_bits, - boolean stereo); +extern int nsf_playtrack(nsf_t *nsf, int track, int sample_rate, + int sample_bits, boolean stereo); extern void nsf_frame(nsf_t *nsf); -extern void nsf_setchan(nsf_t *nsf, int chan, boolean enabled); -extern void nsf_setfilter(nsf_t *nsf, int filter_type); +extern int nsf_setchan(nsf_t *nsf, int chan, boolean enabled); +extern int nsf_setfilter(nsf_t *nsf, int filter_type); #endif /* _NSF_H_ */ /* ** $Log: nsf.h,v $ -** Revision 1.3 2007/01/18 21:34:10 dgp85 -** __attribute__(packed) is used on the struct, not on its members. +** Revision 1.3 2003/05/01 22:34:20 benjihan +** New NSF plugin ** -** Revision 1.2 2003/12/05 15:55:01 f1rmb -** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... +** Revision 1.2 2003/04/09 14:50:32 ben +** Clean NSF api. ** -** Revision 1.1 2003/01/08 07:04:35 tmmm -** initial import of Nosefart sources +** Revision 1.1 2003/04/08 20:53:00 ben +** Adding more files... ** ** Revision 1.11 2000/07/04 04:59:24 matt ** removed DOS-specific stuff diff --git a/src/libxineadec/nosefart/types.h b/src/libxineadec/nosefart/types.h index 01f196035..c0293066c 100644 --- a/src/libxineadec/nosefart/types.h +++ b/src/libxineadec/nosefart/types.h @@ -31,10 +31,9 @@ #endif /* Define this if running on little-endian (x86) systems */ -#ifdef WORDS_BIGENDIAN -#undef HOST_LITTLE_ENDIAN -#else -#define HOST_LITTLE_ENDIAN + +#ifndef DCPLAYA +# define HOST_LITTLE_ENDIAN #endif #ifdef __GNUC__ @@ -46,13 +45,25 @@ #endif /* These should be changed depending on the platform */ -typedef char int8; -typedef short int16; -typedef int int32; -typedef unsigned char uint8; -typedef unsigned short uint16; -typedef unsigned int uint32; + + +#ifdef __BEOS__ /* added by Eli Dayan (for compiling under BeOS) */ + + /* use types in the BeOS Support Kit instead */ + #include +#elif defined (DCPLAYA) /* $$$ added by ben (for compiling with dcplaya) */ +# include +#else + typedef char int8; + typedef short int16; + typedef int int32; + + typedef unsigned char uint8; + typedef unsigned short uint16; + typedef unsigned int uint32; + +#endif typedef uint8 boolean; diff --git a/src/libxineadec/nosefart/version.h b/src/libxineadec/nosefart/version.h index d7dcb2e5d..38d69c61c 100644 --- a/src/libxineadec/nosefart/version.h +++ b/src/libxineadec/nosefart/version.h @@ -20,7 +20,7 @@ ** version.h ** ** Program name / version definitions -** $Id: version.h,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ +** $Id: version.h,v 1.1 2003/04/08 20:46:46 ben Exp $ */ #ifndef _VERSION_H_ @@ -32,17 +32,14 @@ #define APP_STRING "Nofrendo" #endif /* NSF_PLAYER */ -#define APP_VERSION "1.92" +#define APP_VERSION "2.3-mls" #endif /* _VERSION_H_ */ /* ** $Log: version.h,v $ -** Revision 1.2 2003/12/05 15:55:01 f1rmb -** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... -** -** Revision 1.1 2003/01/08 07:04:36 tmmm -** initial import of Nosefart sources +** Revision 1.1 2003/04/08 20:46:46 ben +** add new input for NES music file. ** ** Revision 1.7 2000/07/04 04:46:55 matt ** updated version number -- cgit v1.2.3 From 7331793b951e0ab9cbb8107ecefc9aabc8aaf986 Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Thu, 4 Nov 2010 16:31:50 +0000 Subject: Properly initialise and finalise {Image,Graphics}Magick context. --HG-- extra : rebase_source : 97225919cd1c6c2327ccbb43b17a6b049e82946c --- src/libxinevdec/image.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/libxinevdec/image.c b/src/libxinevdec/image.c index 2c19d36fb..d5a9cfff5 100644 --- a/src/libxinevdec/image.c +++ b/src/libxinevdec/image.c @@ -101,12 +101,14 @@ static void image_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { /* * this->image -> rgb data */ + InitializeMagick(NULL); wand = NewMagickWand(); status = MagickReadImageBlob(wand, this->image, this->index); this->index = 0; if (!status) { DestroyMagickWand(wand); + DestroyMagick(); lprintf("error loading image\n"); return; } @@ -116,6 +118,7 @@ static void image_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { img_buf = malloc(width * height * 3); MagickGetImagePixels(wand, 0, 0, width, height, "RGB", CharPixel, img_buf); DestroyMagickWand(wand); + DestroyMagick(); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, width); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, height); -- cgit v1.2.3 From 56007cdc8b390ebe647bcb0c62cd521c61a6b223 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Sun, 12 Dec 2010 12:38:19 +0100 Subject: Add .ass extension to be recognized as subtitle file. --- src/libsputext/demux_sputext.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/libsputext/demux_sputext.c b/src/libsputext/demux_sputext.c index b0e1299d9..f97d038f7 100644 --- a/src/libsputext/demux_sputext.c +++ b/src/libsputext/demux_sputext.c @@ -1386,7 +1386,8 @@ static demux_plugin_t *open_demux_plugin (demux_class_t *class_gen, xine_stream_ (strncasecmp(ending, ".sub", 4) != 0) && (strncasecmp(ending, ".srt", 4) != 0) && (strncasecmp(ending, ".smi", 4) != 0) && - (strncasecmp(ending, ".ssa", 4) != 0))) { + (strncasecmp(ending, ".ssa", 4) != 0) && + (strncasecmp(ending, ".ass", 4) != 0))) { free (this); return NULL; } -- cgit v1.2.3 From ef273be4edfd6f136e864190aa096fdbb6bfa0dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Sun, 12 Dec 2010 12:46:37 +0100 Subject: List .ass in supported in extensions too. --- src/libsputext/demux_sputext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/libsputext/demux_sputext.c b/src/libsputext/demux_sputext.c index f97d038f7..dd5958044 100644 --- a/src/libsputext/demux_sputext.c +++ b/src/libsputext/demux_sputext.c @@ -1433,7 +1433,7 @@ static const char *get_demux_identifier (demux_class_t *this_gen) { } static const char *get_demux_extensions (demux_class_t *this_gen) { - return "asc txt sub srt smi ssa"; + return "asc txt sub srt smi ssa ass"; } static const char *get_demux_mimetypes (demux_class_t *this_gen) { -- cgit v1.2.3 From d741057648d888a9967d6b80153d026d124a76ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reinhard=20Ni=C3=9Fl?= Date: Thu, 20 Jan 2011 23:38:16 +0100 Subject: Avoid video clock errors due to decoder flush at discontinuity. H.264 decoders store a couple of frames in their display picture buffer. Calling flush before discontinuity my yield images with pts beyond pts boundery and therefore cause clock errors. Calling discontinuity before flush resets all pts to 0 before yielding the images. --HG-- extra : transplant_source : %9CNpV%B5%83%83%23%F5%C3%09%E43%E2%DFo.%7E%D9%C7 --- src/xine-engine/video_decoder.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c index f70bb82bb..984a71bf8 100644 --- a/src/xine-engine/video_decoder.c +++ b/src/xine-engine/video_decoder.c @@ -307,10 +307,10 @@ static void *video_decoder_loop (void *stream_gen) { if (stream->video_decoder_plugin) { running_ticket->acquire(running_ticket, 0); - /* it might be a long time before we get back from a discontinuity, so we better flush - * the decoder before */ - stream->video_decoder_plugin->flush (stream->video_decoder_plugin); stream->video_decoder_plugin->discontinuity (stream->video_decoder_plugin); + /* it might be a long time before we get back from a handle_video_discontinuity, + * so we better flush the decoder before */ + stream->video_decoder_plugin->flush (stream->video_decoder_plugin); running_ticket->release(running_ticket, 0); } @@ -323,10 +323,10 @@ static void *video_decoder_loop (void *stream_gen) { if (stream->video_decoder_plugin) { running_ticket->acquire(running_ticket, 0); - /* it might be a long time before we get back from a discontinuity, so we better flush - * the decoder before */ - stream->video_decoder_plugin->flush (stream->video_decoder_plugin); stream->video_decoder_plugin->discontinuity (stream->video_decoder_plugin); + /* it might be a long time before we get back from a handle_video_discontinuity, + * so we better flush the decoder before */ + stream->video_decoder_plugin->flush (stream->video_decoder_plugin); running_ticket->release(running_ticket, 0); } -- cgit v1.2.3 From 1bd15df285dcf1650c03460d530b7ffea656241a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reinhard=20Ni=C3=9Fl?= Date: Fri, 21 Jan 2011 00:28:23 +0100 Subject: Disable decoder flush at discontinuity to avoid decoding errors. Flushing the decoder at a pts wrap causes decoding errors for images after the pts wrap. It is likely that the flush is still required for the issues it was introduced (DVD still images), but they may have been resolved differently meanwhile (e. g. by supporting sequence end code). So for now a configureable option has been introduced which keeps the current behaviour by default. --HG-- extra : transplant_source : %9Cs%D1%9A%E5Sk%27%18%A6%94%5D%AB%0Dd%CA%7E%7E%BA%FD --- src/xine-engine/video_decoder.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c index 984a71bf8..ef61edebd 100644 --- a/src/xine-engine/video_decoder.c +++ b/src/xine-engine/video_decoder.c @@ -102,6 +102,11 @@ int _x_spu_decoder_sleep(xine_stream_t *stream, int64_t next_spu_vpts) return thread_vacant; } +static void video_decoder_update_disable_flush_at_discontinuity(void *disable_decoder_flush_at_discontinuity, xine_cfg_entry_t *entry) +{ + *(int *)disable_decoder_flush_at_discontinuity = entry->num_value; +} + static void *video_decoder_loop (void *stream_gen) { buf_element_t *buf; @@ -112,6 +117,7 @@ static void *video_decoder_loop (void *stream_gen) { int prof_video_decode = -1; int prof_spu_decode = -1; uint32_t buftype_unknown = 0; + int disable_decoder_flush_at_discontinuity; #ifndef WIN32 /* nice(-value) will fail silently for normal users. @@ -127,6 +133,15 @@ static void *video_decoder_loop (void *stream_gen) { if (prof_spu_decode == -1) prof_spu_decode = xine_profiler_allocate_slot ("spu decoder"); + disable_decoder_flush_at_discontinuity = stream->xine->config->register_bool(stream->xine->config, "engine.decoder.disable_flush_at_discontinuity", 0, + _("disable decoder flush at discontinuity"), + _("when watching live tv a discontinuity happens for example about every 26.5 hours due to a pts wrap.\n" + "flushing the decoder at that time causes decoding errors for images after the pts wrap.\n" + "to avoid the decoding errors, decoder flush at discontinuity should be disabled.\n\n" + "WARNING: as the flush was introduced to fix some issues when playing DVD still images, it is\n" + "likely that these issues may reappear in case they haven't been fixed differently meanwhile.\n"), + 20, video_decoder_update_disable_flush_at_discontinuity, &disable_decoder_flush_at_discontinuity); + while (running) { lprintf ("getting buffer...\n"); @@ -310,7 +325,8 @@ static void *video_decoder_loop (void *stream_gen) { stream->video_decoder_plugin->discontinuity (stream->video_decoder_plugin); /* it might be a long time before we get back from a handle_video_discontinuity, * so we better flush the decoder before */ - stream->video_decoder_plugin->flush (stream->video_decoder_plugin); + if (!disable_decoder_flush_at_discontinuity) + stream->video_decoder_plugin->flush (stream->video_decoder_plugin); running_ticket->release(running_ticket, 0); } @@ -326,7 +342,8 @@ static void *video_decoder_loop (void *stream_gen) { stream->video_decoder_plugin->discontinuity (stream->video_decoder_plugin); /* it might be a long time before we get back from a handle_video_discontinuity, * so we better flush the decoder before */ - stream->video_decoder_plugin->flush (stream->video_decoder_plugin); + if (!disable_decoder_flush_at_discontinuity) + stream->video_decoder_plugin->flush (stream->video_decoder_plugin); running_ticket->release(running_ticket, 0); } -- cgit v1.2.3 From 1e7611bff8c1e5cb6b54f9bcba006a5f18aeb6ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reinhard=20Ni=C3=9Fl?= Date: Fri, 21 Jan 2011 00:51:59 +0100 Subject: Disable decoder flush from video out to avoid decoding errors. Video out flushes the decoder when it runs out of images for displaying, because the decoder hasn't delivered new frames for quite a while. But flushing the decoder causes decoding errors for images after the flush. It is likely that the flush is still required for the issues it was introduced (DVD still images), but they may have been resolved differently meanwhile (e. g. by supporting sequence end code). So for now a configureable option has been introduced which keeps the current behaviour by default. --HG-- extra : transplant_source : %AB%B3u%1F%E7%3D%10%0C%3D%40%B2%B0%CB%8E%84%FE%E6%87p%AA --- src/xine-engine/video_out.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c index 26ad98290..bd7333a0b 100644 --- a/src/xine-engine/video_out.c +++ b/src/xine-engine/video_out.c @@ -1124,6 +1124,11 @@ static void paused_loop( vos_t *this, int64_t vpts ) pthread_mutex_unlock( &this->free_img_buf_queue->mutex ); } +static void video_out_update_disable_flush_from_video_out(void *disable_decoder_flush_from_video_out, xine_cfg_entry_t *entry) +{ + *(int *)disable_decoder_flush_from_video_out = entry->num_value; +} + static void *video_out_loop (void *this_gen) { int64_t vpts, diff; @@ -1131,6 +1136,7 @@ static void *video_out_loop (void *this_gen) { vos_t *this = (vos_t *) this_gen; int64_t next_frame_vpts = 0; int64_t usec_to_sleep; + int disable_decoder_flush_from_video_out; #ifndef WIN32 /* nice(-value) will fail silently for normal users. @@ -1141,6 +1147,16 @@ static void *video_out_loop (void *this_gen) { nice(-2); #endif /* WIN32 */ + disable_decoder_flush_from_video_out = this->xine->config->register_bool(this->xine->config, "engine.decoder.disable_flush_from_video_out", 0, + _("disable decoder flush from video out"), + _("video out causes a decoder flush when video out runs out of frames for displaying,\n" + "because the decoder hasn't deliverd new frames for quite a while.\n" + "flushing the decoder causes decoding errors for images decoded after the flush.\n" + "to avoid the decoding errors, decoder flush at video out should be disabled.\n\n" + "WARNING: as the flush was introduced to fix some issues when playing DVD still images, it is\n" + "likely that these issues may reappear in case they haven't been fixed differently meanwhile.\n"), + 20, video_out_update_disable_flush_from_video_out, &disable_decoder_flush_from_video_out); + /* * here it is - the heart of xine (or rather: one of the hearts * of xine) : the video output loop @@ -1191,7 +1207,7 @@ static void *video_out_loop (void *this_gen) { ite = xine_list_next(this->streams, ite)) { xine_stream_t *stream = xine_list_get_value(this->streams, ite); if (stream == XINE_ANON_STREAM) continue; - if (stream->video_decoder_plugin && stream->video_fifo) { + if (stream->video_decoder_plugin && stream->video_fifo && !disable_decoder_flush_from_video_out) { buf_element_t *buf; lprintf ("flushing current video decoder plugin\n"); -- cgit v1.2.3