summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am1
-rw-r--r--src/audio_out/Makefile.am17
-rw-r--r--src/audio_out/audio_alsa_out.c48
-rw-r--r--src/audio_out/audio_arts_out.c4
-rw-r--r--src/audio_out/audio_coreaudio_out.c4
-rw-r--r--src/audio_out/audio_directx2_out.c470
-rw-r--r--src/audio_out/audio_directx_out.c10
-rw-r--r--src/audio_out/audio_esd_out.c4
-rw-r--r--src/audio_out/audio_file_out.c4
-rw-r--r--src/audio_out/audio_fusionsound_out.c6
-rw-r--r--src/audio_out/audio_jack_out.c1144
-rw-r--r--src/audio_out/audio_none_out.c4
-rw-r--r--src/audio_out/audio_oss_out.c81
-rw-r--r--src/audio_out/audio_pulse_out.c771
-rw-r--r--src/audio_out/audio_sndio_out.c410
-rw-r--r--src/audio_out/audio_sun_out.c4
-rw-r--r--src/combined/Makefile.am3
-rw-r--r--src/combined/combined_wavpack.c2
-rw-r--r--src/combined/combined_wavpack.h3
-rw-r--r--src/combined/decoder_flac.c6
-rw-r--r--src/combined/decoder_wavpack.c4
-rw-r--r--src/combined/demux_flac.c17
-rw-r--r--src/combined/demux_wavpack.c8
-rw-r--r--src/combined/ffmpeg/Makefile.am81
-rw-r--r--src/combined/ffmpeg/ff_audio_decoder.c (renamed from src/libffmpeg/ff_audio_decoder.c)250
-rw-r--r--src/combined/ffmpeg/ff_dvaudio_decoder.c (renamed from src/libffmpeg/ff_dvaudio_decoder.c)18
-rw-r--r--src/combined/ffmpeg/ff_mpeg_parser.c (renamed from src/libffmpeg/ff_mpeg_parser.c)2
-rw-r--r--src/combined/ffmpeg/ff_mpeg_parser.h (renamed from src/libffmpeg/ff_mpeg_parser.h)0
-rw-r--r--src/combined/ffmpeg/ff_video_decoder.c (renamed from src/libffmpeg/ff_video_decoder.c)560
-rw-r--r--src/combined/ffmpeg/ffmpeg_decoder.c (renamed from src/libffmpeg/ffmpeg_decoder.c)2
-rw-r--r--src/combined/ffmpeg/ffmpeg_decoder.h (renamed from src/libffmpeg/ffmpeg_decoder.h)10
-rw-r--r--src/combined/ffmpeg/ffmpeg_encoder.c (renamed from src/libffmpeg/ffmpeg_encoder.c)8
-rwxr-xr-xsrc/combined/ffmpeg/mkcodeclist.pl95
-rw-r--r--src/combined/ffmpeg/xine_audio.list55
-rw-r--r--src/combined/ffmpeg/xine_video.list109
-rw-r--r--src/demuxers/Makefile.am9
-rw-r--r--src/demuxers/asfheader.c92
-rw-r--r--src/demuxers/asfheader.h3
-rw-r--r--src/demuxers/demux_4xm.c61
-rw-r--r--src/demuxers/demux_aac.c13
-rw-r--r--src/demuxers/demux_ac3.c15
-rw-r--r--src/demuxers/demux_aiff.c43
-rw-r--r--src/demuxers/demux_asf.c59
-rw-r--r--src/demuxers/demux_aud.c6
-rw-r--r--src/demuxers/demux_avi.c38
-rw-r--r--src/demuxers/demux_cdda.c4
-rw-r--r--src/demuxers/demux_dts.c89
-rw-r--r--src/demuxers/demux_eawve.c34
-rw-r--r--src/demuxers/demux_elem.c4
-rw-r--r--src/demuxers/demux_film.c23
-rw-r--r--src/demuxers/demux_flac.c69
-rw-r--r--src/demuxers/demux_fli.c6
-rw-r--r--src/demuxers/demux_flv.c292
-rw-r--r--src/demuxers/demux_idcin.c4
-rw-r--r--src/demuxers/demux_iff.c38
-rw-r--r--src/demuxers/demux_image.c4
-rw-r--r--src/demuxers/demux_ipmovie.c9
-rw-r--r--src/demuxers/demux_matroska.c224
-rw-r--r--src/demuxers/demux_mng.c18
-rw-r--r--src/demuxers/demux_mod.c35
-rw-r--r--src/demuxers/demux_mpc.c26
-rw-r--r--src/demuxers/demux_mpeg.c28
-rw-r--r--src/demuxers/demux_mpeg_block.c9
-rw-r--r--src/demuxers/demux_mpeg_pes.c14
-rw-r--r--src/demuxers/demux_mpgaudio.c350
-rw-r--r--src/demuxers/demux_nsf.c18
-rw-r--r--src/demuxers/demux_nsv.c21
-rw-r--r--src/demuxers/demux_ogg.c143
-rw-r--r--src/demuxers/demux_pva.c4
-rw-r--r--src/demuxers/demux_qt.c209
-rw-r--r--src/demuxers/demux_rawdv.c7
-rw-r--r--src/demuxers/demux_real.c849
-rw-r--r--src/demuxers/demux_realaudio.c169
-rw-r--r--src/demuxers/demux_roq.c10
-rw-r--r--src/demuxers/demux_shn.c6
-rw-r--r--src/demuxers/demux_slave.c15
-rw-r--r--src/demuxers/demux_smjpeg.c24
-rw-r--r--src/demuxers/demux_snd.c8
-rw-r--r--src/demuxers/demux_str.c39
-rw-r--r--src/demuxers/demux_ts.c64
-rw-r--r--src/demuxers/demux_tta.c16
-rw-r--r--src/demuxers/demux_vmd.c6
-rw-r--r--src/demuxers/demux_voc.c8
-rw-r--r--src/demuxers/demux_vox.c6
-rw-r--r--src/demuxers/demux_vqa.c8
-rw-r--r--src/demuxers/demux_wav.c115
-rw-r--r--src/demuxers/demux_wc3movie.c33
-rw-r--r--src/demuxers/demux_yuv4mpeg2.c74
-rw-r--r--src/demuxers/demux_yuv_frames.c21
-rw-r--r--src/demuxers/ebml.c22
-rw-r--r--src/demuxers/ebml.h4
-rw-r--r--src/demuxers/id3.c110
-rw-r--r--src/demuxers/id3.h35
-rw-r--r--src/demuxers/iff.h4
-rw-r--r--src/demuxers/matroska.h3
-rw-r--r--src/demuxers/real_common.h56
-rw-r--r--src/dxr3/Makefile.am1
-rw-r--r--src/dxr3/dxr3_decode_spu.c10
-rw-r--r--src/dxr3/dxr3_decode_video.c8
-rw-r--r--src/dxr3/dxr3_mpeg_encoders.c4
-rw-r--r--src/dxr3/dxr3_scr.c2
-rw-r--r--src/dxr3/video_out_dxr3.c18
-rw-r--r--src/input/Makefile.am1
-rw-r--r--src/input/http_helper.c3
-rw-r--r--src/input/input_cdda.c308
-rw-r--r--src/input/input_dvb.c178
-rw-r--r--src/input/input_dvd.c69
-rw-r--r--src/input/input_file.c58
-rw-r--r--src/input/input_gnome_vfs.c7
-rw-r--r--src/input/input_http.c125
-rw-r--r--src/input/input_mms.c11
-rw-r--r--src/input/input_net.c18
-rw-r--r--src/input/input_plugin.h90
-rw-r--r--src/input/input_pnm.c26
-rw-r--r--src/input/input_pvr.c41
-rw-r--r--src/input/input_rtp.c18
-rw-r--r--src/input/input_rtsp.c29
-rw-r--r--src/input/input_smb.c61
-rw-r--r--src/input/input_stdin_fifo.c19
-rw-r--r--src/input/input_v4l.c218
-rw-r--r--src/input/input_vcd.c89
-rw-r--r--src/input/libdvdnav/bswap.h2
-rw-r--r--src/input/libdvdnav/diff_against_cvs.patch2
-rw-r--r--src/input/libdvdnav/dvd_reader.c24
-rw-r--r--src/input/libdvdnav/dvd_reader.h4
-rw-r--r--src/input/libdvdnav/ifo_read.c6
-rw-r--r--src/input/libdvdnav/md5.c2
-rw-r--r--src/input/libdvdnav/remap.c1
-rw-r--r--src/input/libreal/asmrp.c6
-rw-r--r--src/input/libreal/real.c15
-rw-r--r--src/input/libreal/rmff.c144
-rw-r--r--src/input/libreal/rmff.h14
-rw-r--r--src/input/libreal/sdpplin.c42
-rw-r--r--src/input/libreal/sdpplin.h6
-rw-r--r--src/input/librtsp/rtsp.c60
-rw-r--r--src/input/librtsp/rtsp.h2
-rw-r--r--src/input/librtsp/rtsp_session.c12
-rw-r--r--src/input/librtsp/rtsp_session.h2
-rw-r--r--src/input/mms.c24
-rw-r--r--src/input/mmsh.c6
-rw-r--r--src/input/net_buf_ctrl.c6
-rw-r--r--src/input/net_buf_ctrl.h8
-rw-r--r--src/input/pnm.c23
-rw-r--r--src/input/vcd/Makefile.am1
-rw-r--r--src/input/vcd/libcdio/FreeBSD/freebsd.c2
-rw-r--r--src/input/vcd/libcdio/MSWindows/aspi32.c4
-rw-r--r--src/input/vcd/xine-extra.c10
-rw-r--r--src/input/vcd/xineplug_inp_vcd.c16
-rw-r--r--src/liba52/Makefile.am1
-rw-r--r--src/liba52/parse.c2
-rw-r--r--src/liba52/xine_a52_decoder.c6
-rw-r--r--src/libdts/Makefile.am1
-rw-r--r--src/libdts/xine_dts_decoder.c40
-rw-r--r--src/libfaad/Makefile.am34
-rw-r--r--src/libfaad/analysis.h9
-rw-r--r--src/libfaad/bits.c156
-rw-r--r--src/libfaad/bits.h162
-rw-r--r--src/libfaad/cfft.c29
-rw-r--r--src/libfaad/cfft.h9
-rw-r--r--src/libfaad/cfft_tab.h17
-rw-r--r--src/libfaad/codebook/hcb.h9
-rw-r--r--src/libfaad/codebook/hcb_1.h9
-rw-r--r--src/libfaad/codebook/hcb_10.h9
-rw-r--r--src/libfaad/codebook/hcb_11.h9
-rw-r--r--src/libfaad/codebook/hcb_2.h9
-rw-r--r--src/libfaad/codebook/hcb_3.h9
-rw-r--r--src/libfaad/codebook/hcb_4.h9
-rw-r--r--src/libfaad/codebook/hcb_5.h9
-rw-r--r--src/libfaad/codebook/hcb_6.h9
-rw-r--r--src/libfaad/codebook/hcb_7.h9
-rw-r--r--src/libfaad/codebook/hcb_8.h9
-rw-r--r--src/libfaad/codebook/hcb_9.h9
-rw-r--r--src/libfaad/codebook/hcb_sf.h9
-rw-r--r--src/libfaad/common.c23
-rw-r--r--src/libfaad/common.h106
-rw-r--r--src/libfaad/decoder.c125
-rw-r--r--src/libfaad/decoder.h9
-rw-r--r--src/libfaad/drc.c9
-rw-r--r--src/libfaad/drc.h9
-rw-r--r--src/libfaad/drm_dec.c117
-rw-r--r--src/libfaad/drm_dec.h11
-rw-r--r--src/libfaad/error.c16
-rw-r--r--src/libfaad/error.h11
-rw-r--r--src/libfaad/faad.h217
-rw-r--r--src/libfaad/filtbank.c9
-rw-r--r--src/libfaad/filtbank.h9
-rw-r--r--src/libfaad/fixed.h28
-rw-r--r--src/libfaad/hcr.c33
-rw-r--r--src/libfaad/huffman.c9
-rw-r--r--src/libfaad/huffman.h9
-rw-r--r--src/libfaad/ic_predict.c20
-rw-r--r--src/libfaad/ic_predict.h9
-rw-r--r--src/libfaad/iq_table.h9
-rw-r--r--src/libfaad/is.c11
-rw-r--r--src/libfaad/is.h9
-rw-r--r--src/libfaad/kbd_win.h9
-rw-r--r--src/libfaad/lt_predict.c14
-rw-r--r--src/libfaad/lt_predict.h9
-rw-r--r--src/libfaad/mdct.c11
-rw-r--r--src/libfaad/mdct.h9
-rw-r--r--src/libfaad/mdct_tab.h9
-rw-r--r--src/libfaad/mp4.c25
-rw-r--r--src/libfaad/mp4.h9
-rw-r--r--src/libfaad/ms.c11
-rw-r--r--src/libfaad/ms.h9
-rw-r--r--src/libfaad/output.c71
-rw-r--r--src/libfaad/output.h9
-rw-r--r--src/libfaad/pns.c34
-rw-r--r--src/libfaad/pns.h12
-rw-r--r--src/libfaad/ps_dec.c159
-rw-r--r--src/libfaad/ps_dec.h9
-rw-r--r--src/libfaad/ps_syntax.c22
-rw-r--r--src/libfaad/ps_tables.h19
-rw-r--r--src/libfaad/pulse.c12
-rw-r--r--src/libfaad/pulse.h9
-rw-r--r--src/libfaad/rvlc.c9
-rw-r--r--src/libfaad/rvlc.h9
-rw-r--r--src/libfaad/sbr_dct.c838
-rw-r--r--src/libfaad/sbr_dct.h9
-rw-r--r--src/libfaad/sbr_dec.c106
-rw-r--r--src/libfaad/sbr_dec.h19
-rw-r--r--src/libfaad/sbr_e_nf.c9
-rw-r--r--src/libfaad/sbr_e_nf.h9
-rw-r--r--src/libfaad/sbr_fbt.c9
-rw-r--r--src/libfaad/sbr_fbt.h9
-rw-r--r--src/libfaad/sbr_hfadj.c54
-rw-r--r--src/libfaad/sbr_hfadj.h15
-rw-r--r--src/libfaad/sbr_hfgen.c10
-rw-r--r--src/libfaad/sbr_hfgen.h9
-rw-r--r--src/libfaad/sbr_huff.c9
-rw-r--r--src/libfaad/sbr_huff.h9
-rw-r--r--src/libfaad/sbr_noise.h9
-rw-r--r--src/libfaad/sbr_qmf.c27
-rw-r--r--src/libfaad/sbr_qmf.h9
-rw-r--r--src/libfaad/sbr_qmf_c.h17
-rw-r--r--src/libfaad/sbr_syntax.c71
-rw-r--r--src/libfaad/sbr_syntax.h12
-rw-r--r--src/libfaad/sbr_tf_grid.c9
-rw-r--r--src/libfaad/sbr_tf_grid.h9
-rw-r--r--src/libfaad/sine_win.h9
-rw-r--r--src/libfaad/specrec.c174
-rw-r--r--src/libfaad/specrec.h9
-rw-r--r--src/libfaad/ssr.c9
-rw-r--r--src/libfaad/ssr.h9
-rw-r--r--src/libfaad/ssr_fb.c9
-rw-r--r--src/libfaad/ssr_fb.h15
-rw-r--r--src/libfaad/ssr_ipqf.c9
-rw-r--r--src/libfaad/ssr_ipqf.h15
-rw-r--r--src/libfaad/ssr_win.h15
-rw-r--r--src/libfaad/structs.h28
-rw-r--r--src/libfaad/syntax.c308
-rw-r--r--src/libfaad/syntax.h16
-rw-r--r--src/libfaad/tns.c19
-rw-r--r--src/libfaad/tns.h9
-rw-r--r--src/libfaad/xine_faad_decoder.c43
-rw-r--r--src/libffmpeg/Makefile.am39
-rw-r--r--src/libffmpeg/libavcodec/i386/Makefile.am3
-rw-r--r--src/libmad/Makefile.am1
-rw-r--r--src/libmad/bit.c3
-rw-r--r--src/libmad/layer12.c3
-rw-r--r--src/libmad/layer3.c3
-rw-r--r--src/libmad/xine_mad_decoder.c64
-rw-r--r--src/libmpeg2/Makefile.am3
-rw-r--r--src/libmpeg2/decode.c7
-rw-r--r--src/libmpeg2/motion_comp.c2
-rw-r--r--src/libmpeg2/mpeg2.h6
-rw-r--r--src/libmpeg2/slice_xvmc_vld.c4
-rw-r--r--src/libmpeg2/xine_mpeg2_decoder.c8
-rw-r--r--src/libmpeg2new/Makefile.am19
-rw-r--r--src/libmpeg2new/include/Makefile.am5
-rw-r--r--src/libmpeg2new/include/attributes.h6
-rw-r--r--src/libmpeg2new/libmpeg2/Makefile.am9
-rw-r--r--src/libmpeg2new/libmpeg2/motion_comp_alpha.c6
-rw-r--r--src/libmpeg2new/libmpeg2/motion_comp_altivec.c4
-rw-r--r--src/libmpeg2new/libmpeg2/motion_comp_vis.c10
-rw-r--r--src/libmpeg2new/xine_mpeg2new_decoder.c26
-rw-r--r--src/libmusepack/Makefile.am1
-rw-r--r--src/libmusepack/xine_musepack_decoder.c10
-rw-r--r--src/libreal/Makefile.am1
-rw-r--r--src/libreal/real_common.c4
-rw-r--r--src/libreal/xine_real_audio_decoder.c183
-rw-r--r--src/libreal/xine_real_video_decoder.c59
-rw-r--r--src/libspucc/Makefile.am1
-rw-r--r--src/libspucc/cc_decoder.c10
-rw-r--r--src/libspucc/cc_decoder.h8
-rw-r--r--src/libspucc/xine_cc_decoder.c18
-rw-r--r--src/libspucmml/Makefile.am1
-rw-r--r--src/libspucmml/xine_cmml_decoder.c149
-rw-r--r--src/libspudec/Makefile.am5
-rw-r--r--src/libspudec/spu.c6
-rw-r--r--src/libspudec/spu.h2
-rw-r--r--src/libspudec/xine_spu_decoder.c28
-rw-r--r--src/libspudvb/Makefile.am1
-rw-r--r--src/libspudvb/xine_spudvb_decoder.c564
-rw-r--r--src/libsputext/Makefile.am1
-rw-r--r--src/libsputext/demux_sputext.c858
-rw-r--r--src/libsputext/xine_sputext_decoder.c91
-rw-r--r--src/libw32dll/Makefile.am1
-rw-r--r--src/libw32dll/qt_decoder.c8
-rw-r--r--src/libw32dll/w32codec.c12
-rw-r--r--src/libw32dll/wine/Makefile.am3
-rw-r--r--src/libw32dll/wine/driver.c2
-rw-r--r--src/libw32dll/wine/elfdll.c2
-rw-r--r--src/libw32dll/wine/pe_image.c2
-rw-r--r--src/libw32dll/wine/pe_resource.c2
-rw-r--r--src/libw32dll/wine/registry.c3
-rw-r--r--src/libw32dll/wine/resource.c2
-rw-r--r--src/libw32dll/wine/vfl.c2
-rw-r--r--src/libw32dll/wine/win32.c19
-rw-r--r--src/libxineadec/Makefile.am3
-rw-r--r--src/libxineadec/fooaudio.c8
-rw-r--r--src/libxineadec/gsm610.c6
-rw-r--r--src/libxineadec/gsm610/long_term.c4
-rw-r--r--src/libxineadec/gsm610/lpc.c4
-rw-r--r--src/libxineadec/gsm610/rpe.c4
-rw-r--r--src/libxineadec/gsm610/short_term.c4
-rw-r--r--src/libxineadec/nsf.c10
-rw-r--r--src/libxineadec/xine_lpcm_decoder.c35
-rw-r--r--src/libxineadec/xine_speex_decoder.c21
-rw-r--r--src/libxineadec/xine_vorbis_decoder.c254
-rw-r--r--src/libxinevdec/Makefile.am3
-rw-r--r--src/libxinevdec/bitplane.c36
-rw-r--r--src/libxinevdec/foovideo.c8
-rw-r--r--src/libxinevdec/gdkpixbuf.c9
-rw-r--r--src/libxinevdec/image.c12
-rw-r--r--src/libxinevdec/rgb.c10
-rw-r--r--src/libxinevdec/xine_theora_decoder.c4
-rw-r--r--src/libxinevdec/yuv.c8
-rw-r--r--src/post/audio/Makefile.am1
-rw-r--r--src/post/audio/audio_filters.c3
-rw-r--r--src/post/audio/filter.c2
-rw-r--r--src/post/audio/filter.h2
-rw-r--r--src/post/audio/stretch.c10
-rw-r--r--src/post/audio/upmix.c8
-rw-r--r--src/post/audio/upmix_mono.c38
-rw-r--r--src/post/audio/volnorm.c14
-rw-r--r--src/post/deinterlace/Makefile.am3
-rw-r--r--src/post/deinterlace/plugins/Makefile.am6
-rw-r--r--src/post/deinterlace/plugins/tomsmocomp/tomsmocompmacros.h2
-rw-r--r--src/post/deinterlace/tvtime.c14
-rw-r--r--src/post/deinterlace/tvtime.h5
-rw-r--r--src/post/deinterlace/xine_plugin.c17
-rw-r--r--src/post/goom/Makefile.am1
-rw-r--r--src/post/goom/convolve_fx.c4
-rw-r--r--src/post/goom/diff_against_release.patch37
-rw-r--r--src/post/goom/goom_core.c12
-rw-r--r--src/post/goom/ppc_zoom_ultimate.h2
-rw-r--r--src/post/goom/xine_goom.c6
-rw-r--r--src/post/mosaico/Makefile.am1
-rw-r--r--src/post/mosaico/mosaico.c13
-rw-r--r--src/post/mosaico/switch.c4
-rw-r--r--src/post/planar/Makefile.am5
-rw-r--r--src/post/planar/boxblur.c6
-rw-r--r--src/post/planar/denoise3d.c6
-rw-r--r--src/post/planar/eq.c6
-rw-r--r--src/post/planar/eq2.c37
-rw-r--r--src/post/planar/expand.c2
-rw-r--r--src/post/planar/fill.c2
-rw-r--r--src/post/planar/invert.c2
-rw-r--r--src/post/planar/noise.c6
-rw-r--r--src/post/planar/planar.c4
-rw-r--r--src/post/planar/pp.c22
-rw-r--r--src/post/planar/unsharp.c13
-rw-r--r--src/post/visualizations/Makefile.am1
-rw-r--r--src/post/visualizations/fftgraph.c6
-rw-r--r--src/post/visualizations/fftscope.c6
-rw-r--r--src/post/visualizations/fooviz.c6
-rw-r--r--src/post/visualizations/oscope.c6
-rw-r--r--src/video_out/Makefile.am24
-rw-r--r--src/video_out/deinterlace.c18
-rw-r--r--src/video_out/deinterlace.h13
-rw-r--r--src/video_out/macosx/XineOpenGLView.m2
-rw-r--r--src/video_out/video_out_aa.c6
-rw-r--r--src/video_out/video_out_caca.c16
-rw-r--r--src/video_out/video_out_directfb.c14
-rw-r--r--src/video_out/video_out_directx.c141
-rw-r--r--src/video_out/video_out_fb.c32
-rw-r--r--src/video_out/video_out_macosx.m8
-rw-r--r--src/video_out/video_out_none.c6
-rw-r--r--src/video_out/video_out_opengl.c75
-rw-r--r--src/video_out/video_out_pgx32.c6
-rw-r--r--src/video_out/video_out_pgx64.c6
-rw-r--r--src/video_out/video_out_raw.c610
-rw-r--r--src/video_out/video_out_sdl.c22
-rw-r--r--src/video_out/video_out_stk.c6
-rw-r--r--src/video_out/video_out_syncfb.c6
-rw-r--r--src/video_out/video_out_vidix.c6
-rw-r--r--src/video_out/video_out_xcbshm.c6
-rw-r--r--src/video_out/video_out_xcbxv.c248
-rw-r--r--src/video_out/video_out_xshm.c8
-rw-r--r--src/video_out/video_out_xv.c233
-rw-r--r--src/video_out/video_out_xvmc.c102
-rw-r--r--src/video_out/video_out_xxmc.c232
-rw-r--r--src/video_out/x11osd.c2
-rw-r--r--src/video_out/xcbosd.c2
-rw-r--r--src/video_out/xv_common.h83
-rw-r--r--src/video_out/xxmc.h10
-rw-r--r--src/video_out/yuv2rgb.c2
-rw-r--r--src/video_out/yuv2rgb_mlib.c2
-rw-r--r--src/xine-engine/alphablend.c12
-rw-r--r--src/xine-engine/alphablend.h21
-rw-r--r--src/xine-engine/audio_decoder.c6
-rw-r--r--src/xine-engine/audio_out.c64
-rw-r--r--src/xine-engine/audio_out.h2
-rw-r--r--src/xine-engine/broadcaster.c6
-rw-r--r--src/xine-engine/broadcaster.h6
-rw-r--r--src/xine-engine/buffer.c4
-rw-r--r--src/xine-engine/buffer.h36
-rw-r--r--src/xine-engine/buffer_types.c47
-rw-r--r--src/xine-engine/configfile.c43
-rw-r--r--src/xine-engine/configfile.h2
-rw-r--r--src/xine-engine/demux.c94
-rw-r--r--src/xine-engine/info_helper.c23
-rw-r--r--src/xine-engine/input_cache.c4
-rw-r--r--src/xine-engine/input_rip.c9
-rw-r--r--src/xine-engine/load_plugins.c457
-rw-r--r--src/xine-engine/lrb.c2
-rw-r--r--src/xine-engine/metronom.c9
-rw-r--r--src/xine-engine/metronom.h4
-rw-r--r--src/xine-engine/osd.c67
-rw-r--r--src/xine-engine/osd.h2
-rw-r--r--src/xine-engine/post.c21
-rw-r--r--src/xine-engine/refcounter.c7
-rw-r--r--src/xine-engine/refcounter.h6
-rw-r--r--src/xine-engine/scratch.c15
-rw-r--r--src/xine-engine/scratch.h2
-rw-r--r--src/xine-engine/video_decoder.c2
-rw-r--r--src/xine-engine/video_out.c6
-rw-r--r--src/xine-engine/video_out.h6
-rw-r--r--src/xine-engine/video_overlay.c10
-rw-r--r--src/xine-engine/video_overlay.h2
-rw-r--r--src/xine-engine/vo_scale.c4
-rw-r--r--src/xine-engine/vo_scale.h4
-rw-r--r--src/xine-engine/xine.c309
-rw-r--r--src/xine-engine/xine_interface.c9
-rw-r--r--src/xine-engine/xine_internal.h9
-rw-r--r--src/xine-utils/Makefile.am5
-rw-r--r--src/xine-utils/array.c2
-rw-r--r--src/xine-utils/array.h2
-rw-r--r--src/xine-utils/attributes.h61
-rw-r--r--src/xine-utils/color.c10
-rw-r--r--src/xine-utils/cpu_accel.c4
-rw-r--r--src/xine-utils/list.c4
-rw-r--r--src/xine-utils/list.h2
-rw-r--r--src/xine-utils/mangle.h54
-rw-r--r--src/xine-utils/monitor.c13
-rw-r--r--src/xine-utils/pool.c2
-rw-r--r--src/xine-utils/pool.h2
-rw-r--r--src/xine-utils/ring_buffer.h2
-rw-r--r--src/xine-utils/sorted_array.h2
-rw-r--r--src/xine-utils/utils.c79
-rw-r--r--src/xine-utils/xine_buffer.c8
-rw-r--r--src/xine-utils/xine_check.c79
-rw-r--r--src/xine-utils/xine_check.h39
-rw-r--r--src/xine-utils/xine_mmx.h490
-rw-r--r--src/xine-utils/xineutils.h492
-rw-r--r--src/xine-utils/xmllexer.c9
-rw-r--r--src/xine-utils/xmlparser.c19
458 files changed, 13163 insertions, 8220 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 6718b4805..249bbc2b6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -11,6 +11,7 @@ SUBDIRS = \
demuxers \
libffmpeg \
libmpeg2 \
+ libmpeg2new \
liba52 \
libspudec \
libspucc \
diff --git a/src/audio_out/Makefile.am b/src/audio_out/Makefile.am
index b0c3d292e..07ad19c8d 100644
--- a/src/audio_out/Makefile.am
+++ b/src/audio_out/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
AM_CPPFLAGS = -DXINE_COMPILE
@@ -49,6 +50,10 @@ if HAVE_JACK
jack_module = xineplug_ao_out_jack.la
endif
+if HAVE_SNDIO
+sndio_module = xineplug_ao_out_sndio.la
+endif
+
##
# IMPORTANT:
# ---------
@@ -66,7 +71,8 @@ xineplug_LTLIBRARIES = xineplug_ao_out_none.la xineplug_ao_out_file.la \
$(pulseaudio_module) \
$(directx2_module) \
$(fusionsound_module) \
- $(jack_module)
+ $(jack_module) \
+ $(sndio_module)
xineplug_ao_out_none_la_SOURCES = audio_none_out.c
xineplug_ao_out_none_la_LIBADD = $(XINE_LIB) $(LTLIBINTL)
@@ -110,7 +116,7 @@ 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)
+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
@@ -131,7 +137,7 @@ 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)
+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
@@ -144,3 +150,8 @@ 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/audio_out/audio_alsa_out.c b/src/audio_out/audio_alsa_out.c
index 4ce2b1be3..470cd953a 100644
--- a/src/audio_out/audio_alsa_out.c
+++ b/src/audio_out/audio_alsa_out.c
@@ -1350,7 +1350,7 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da
#define A52_PASSTHRU 12
int speakers;
- this = (alsa_driver_t *) xine_xmalloc (sizeof (alsa_driver_t));
+ this = calloc(1, sizeof (alsa_driver_t));
if (!this)
return NULL;
@@ -1497,70 +1497,73 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da
"formats you want to play to your sound card's digital output."),
0, alsa_speaker_arrangement_cb, this);
- xprintf(class->xine, XINE_VERBOSITY_LOG, _("audio_alsa_out : supported modes are "));
+ char *logmsg = strdup (_("audio_alsa_out : supported modes are"));
+
if (!(snd_pcm_hw_params_test_format(this->audio_fd, params, SND_PCM_FORMAT_U8))) {
this->capabilities |= AO_CAP_8BITS;
- xprintf(class->xine, XINE_VERBOSITY_LOG, _("8bit "));
+ xine_strcat_realloc (&logmsg, _(" 8bit"));
}
/* ALSA automatically appends _LE or _BE depending on the CPU */
if (!(snd_pcm_hw_params_test_format(this->audio_fd, params, SND_PCM_FORMAT_S16))) {
this->capabilities |= AO_CAP_16BITS;
- xprintf(class->xine, XINE_VERBOSITY_LOG, _("16bit "));
+ xine_strcat_realloc (&logmsg, _(" 16bit"));
}
if (!(snd_pcm_hw_params_test_format(this->audio_fd, params, SND_PCM_FORMAT_S24))) {
this->capabilities |= AO_CAP_24BITS;
- xprintf(class->xine, XINE_VERBOSITY_LOG, _("24bit "));
+ xine_strcat_realloc (&logmsg, _(" 24bit"));
}
if (!(snd_pcm_hw_params_test_format(this->audio_fd, params, SND_PCM_FORMAT_FLOAT))) {
this->capabilities |= AO_CAP_FLOAT32;
- xprintf(class->xine, XINE_VERBOSITY_LOG, _("32bit "));
+ xine_strcat_realloc (&logmsg, _(" 32bit"));
}
if (0 == (this->capabilities & (AO_CAP_FLOAT32 | AO_CAP_24BITS | AO_CAP_16BITS | AO_CAP_8BITS))) {
- xprintf (this->class->xine, XINE_VERBOSITY_DEBUG,
- "\naudio_alsa_out: no supported PCM format found\n");
+ xprintf(class->xine, XINE_VERBOSITY_LOG, "%s\n", logmsg);
+ free (logmsg);
+ xprintf (class->xine, XINE_VERBOSITY_DEBUG,
+ "audio_alsa_out: no supported PCM format found\n");
snd_pcm_close(this->audio_fd);
free(this);
return NULL;
}
if (!(snd_pcm_hw_params_test_channels(this->audio_fd, params, 1))) {
this->capabilities |= AO_CAP_MODE_MONO;
- xprintf(class->xine, XINE_VERBOSITY_LOG, _("mono "));
+ xine_strcat_realloc (&logmsg, _(" mono"));
}
if (!(snd_pcm_hw_params_test_channels(this->audio_fd, params, 2))) {
this->capabilities |= AO_CAP_MODE_STEREO;
- xprintf(class->xine, XINE_VERBOSITY_LOG, _("stereo "));
+ xine_strcat_realloc (&logmsg, _(" stereo"));
}
if (!(snd_pcm_hw_params_test_channels(this->audio_fd, params, 4)) &&
( speakers == SURROUND4 )) {
this->capabilities |= AO_CAP_MODE_4CHANNEL;
- xprintf(class->xine, XINE_VERBOSITY_LOG, _("4-channel "));
+ xine_strcat_realloc (&logmsg, _(" 4-channel"));
}
else
- xprintf(class->xine, XINE_VERBOSITY_LOG, _("(4-channel not enabled in xine config) "));
+ xine_strcat_realloc (&logmsg, _(" (4-channel not enabled in xine config)"));
if (!(snd_pcm_hw_params_test_channels(this->audio_fd, params, 6)) &&
( speakers == SURROUND41 )) {
this->capabilities |= AO_CAP_MODE_4_1CHANNEL;
- xprintf(class->xine, XINE_VERBOSITY_LOG, _("4.1-channel "));
+ xine_strcat_realloc (&logmsg, _(" 4.1-channel"));
}
else
- xprintf(class->xine, XINE_VERBOSITY_LOG, _("(4.1-channel not enabled in xine config) "));
+ xine_strcat_realloc (&logmsg, _(" (4.1-channel not enabled in xine config)"));
if (!(snd_pcm_hw_params_test_channels(this->audio_fd, params, 6)) &&
( speakers == SURROUND5 )) {
this->capabilities |= AO_CAP_MODE_5CHANNEL;
- xprintf(class->xine, XINE_VERBOSITY_LOG, _("5-channel "));
+ xine_strcat_realloc (&logmsg, _(" 5-channel"));
}
else
- xprintf(class->xine, XINE_VERBOSITY_LOG, _("(5-channel not enabled in xine config) "));
+ xine_strcat_realloc (&logmsg, _(" (5-channel not enabled in xine config)"));
if (!(snd_pcm_hw_params_test_channels(this->audio_fd, params, 6)) &&
( speakers >= SURROUND51 )) {
this->capabilities |= AO_CAP_MODE_5_1CHANNEL;
- xprintf(class->xine, XINE_VERBOSITY_LOG, _("5.1-channel "));
+ xine_strcat_realloc (&logmsg, _(" 5.1-channel"));
}
else
- xprintf(class->xine, XINE_VERBOSITY_LOG, _("(5.1-channel not enabled in xine config) "));
+ xine_strcat_realloc (&logmsg, _(" (5.1-channel not enabled in xine config)"));
this->has_pause_resume = 0; /* This is checked at open time instead */
this->is_paused = 0;
@@ -1583,10 +1586,13 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da
if ( speakers == A52_PASSTHRU ) {
this->capabilities |= AO_CAP_MODE_A52;
this->capabilities |= AO_CAP_MODE_AC5;
- xprintf(class->xine, XINE_VERBOSITY_LOG, _("a/52 and DTS pass-through\n"));
+ xine_strcat_realloc (&logmsg, _(" a/52 and DTS pass-through"));
}
else
- xprintf(class->xine, XINE_VERBOSITY_LOG, _("(a/52 and DTS pass-through not enabled in xine config)\n"));
+ xine_strcat_realloc (&logmsg, _(" (a/52 and DTS pass-through not enabled in xine config)"));
+
+ xprintf(class->xine, XINE_VERBOSITY_LOG, "%s\n", logmsg);
+ free (logmsg);
/* printf("audio_alsa_out: capabilities 0x%X\n",this->capabilities); */
@@ -1682,7 +1688,7 @@ static void *init_class (xine_t *xine, void *data) {
alsa_class_t *this;
- this = (alsa_class_t *) xine_xmalloc (sizeof (alsa_class_t));
+ this = calloc(1, sizeof (alsa_class_t));
if (!this)
return NULL;
diff --git a/src/audio_out/audio_arts_out.c b/src/audio_out/audio_arts_out.c
index 0f0467b4a..14bf5c965 100644
--- a/src/audio_out/audio_arts_out.c
+++ b/src/audio_out/audio_arts_out.c
@@ -303,7 +303,7 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da
lprintf ("audio_arts_out: open_plugin called\n");
- this = (arts_driver_t *) xine_xmalloc (sizeof (arts_driver_t));
+ this = calloc(1, sizeof (arts_driver_t));
if (!this)
return NULL;
@@ -384,7 +384,7 @@ static void *init_class (xine_t *xine, void *data) {
lprintf ("audio_arts_out: init class\n");
- this = (arts_class_t *) xine_xmalloc (sizeof (arts_class_t));
+ this = calloc(1, sizeof (arts_class_t));
if (!this)
return NULL;
diff --git a/src/audio_out/audio_coreaudio_out.c b/src/audio_out/audio_coreaudio_out.c
index eecab8f95..642f920c7 100644
--- a/src/audio_out/audio_coreaudio_out.c
+++ b/src/audio_out/audio_coreaudio_out.c
@@ -530,7 +530,7 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen,
lprintf ("open_plugin called\n");
- this = (coreaudio_driver_t *) xine_xmalloc (sizeof (coreaudio_driver_t));
+ this = calloc(1, sizeof (coreaudio_driver_t));
if (!this)
return NULL;
@@ -582,7 +582,7 @@ static void *init_class (xine_t *xine, void *data) {
lprintf ("init class\n");
- this = (coreaudio_class_t *) xine_xmalloc (sizeof (coreaudio_class_t));
+ this = calloc(1, sizeof (coreaudio_class_t));
if (!this)
return NULL;
diff --git a/src/audio_out/audio_directx2_out.c b/src/audio_out/audio_directx2_out.c
index d9688b647..6bee2066c 100644
--- a/src/audio_out/audio_directx2_out.c
+++ b/src/audio_out/audio_directx2_out.c
@@ -31,6 +31,9 @@
*
* Authors:
* - Frantisek Dvorak <valtri@atlas.cz>
+ * - Original version with slotted ring buffer
+ * - Matthias Ringald <mringwal@inf.ethz.ch>
+ * - non-slotted simpler version for ring buffer handling
*
* Inspiration:
* - mplayer for workarounding -lguid idea
@@ -55,8 +58,8 @@
#define LOG_MODULE "audio_directx2_out"
#define LOG_VERBOSE
/*
-#define LOG
-*/
+ #define LOG
+ */
#include "xine_internal.h"
#include "audio_out.h"
@@ -64,29 +67,33 @@
#define AO_OUT_DIRECTX2_IFACE_VERSION 8
+
+/*
+ * If GAP_TOLERANCE is lower than AO_MAX_GAP, xine will
+ * try to smooth playback without skipping frames or
+ * inserting silence.
+ */
+#define GAP_TOLERANCE (AO_MAX_GAP/3)
+
/*
* buffer size in miliseconds
* (one second takes 11-192 KB)
*/
#define BUFFER_MS 1000
-/*
- * number of parts in the buffer,
- * one is always locked for playing
+/*
+ * buffer below this threshold is considered a buffer underrun
*/
-#define PARTS 3
+#define BUFFER_MIN_MS 200
/*
* base power factor for volume remapping
*/
#define FACTOR 60.0
-
-/* experiments */
-/*#define EXACT_WAIT*/
-/*#define EXACT_SLEEP*/
-/*#define PANIC_OVERRUN*/
-
+/*
+ * buffer handler status
+ */
#define STATUS_START 0
#define STATUS_WAIT 1
#define STATUS_RUNNING 2
@@ -108,12 +115,14 @@ typedef struct {
LPDIRECTSOUND ds; /* DirectSound device */
LPDIRECTSOUNDBUFFER dsbuffer; /* DirectSound buffer */
- DSBPOSITIONNOTIFY events[PARTS]; /* position events */
- LPDIRECTSOUNDNOTIFY notify; /* notify interface */
size_t buffer_size; /* size of the buffer */
- size_t part_size; /* second half of buffer */
- size_t read_size; /* size of prepared data */
+ size_t write_pos; /* positition in ring buffer for writing*/
+
+ int status; /* current status of the driver */
+ int paused; /* paused mode */
+ int finished; /* driver finished */
+ int failed; /* don't open modal dialog again */
uint32_t bits;
uint32_t rate;
@@ -123,12 +132,6 @@ typedef struct {
int volume;
int muted;
- int status; /* current status of the driver */
- int paused; /* paused mode */
- int finished; /* driver finished */
- int failed; /* don't open modal dialog again */
- int count; /* current free part number */
-
pthread_t buffer_service; /* service thread for operating with DSB */
pthread_cond_t data_cond; /* signals on data */
pthread_mutex_t data_mutex; /* data lock */
@@ -140,17 +143,19 @@ typedef struct {
* Defining them here allows us to get rid of the dxguid library during
* the linking stage.
*****************************************************************************/
-static const GUID IID_IDirectSoundNotify = {
- 0xB0210783, 0x89CD, 0x11D0, {0xAF, 0x08, 0x00, 0xA0, 0xC9, 0x25, 0xCD, 0x16}
+static const GUID xine_IID_IDirectSoundNotify = {
+0xB0210783, 0x89CD, 0x11D0, {0xAF, 0x08, 0x00, 0xA0, 0xC9, 0x25, 0xCD, 0x16}
};
+#ifdef IID_IDirectSoundNotify
+# undef IID_IDirectSoundNotify
+#endif
+#define IID_IDirectSoundNotify xine_IID_IDirectSoundNotify
-static int buffer_ready(dx2_driver_t *this);
-
/* popup a dialog with error */
static void XINE_FORMAT_PRINTF(1, 2)
- error_message(const char *fmt, ...) {
+error_message(const char *fmt, ...) {
char message[256];
va_list ap;
@@ -214,7 +219,7 @@ static LPDIRECTSOUND dsound_create() {
/* destroy direct sound object */
static void dsound_destroy(LPDIRECTSOUND ds) {
- IDirectSound_Release(ds);
+ IDirectSound_Release(ds);
}
@@ -266,12 +271,10 @@ static int audio_create_buffers(dx2_driver_t *this) {
HRESULT err;
size_t buffer_size;
- buffer_size = this->rate * this->frame_size * BUFFER_MS / 1000;
+ buffer_size = this->rate * BUFFER_MS / 1000 * this->frame_size;
if (buffer_size > DSBSIZE_MAX) buffer_size = DSBSIZE_MAX;
if (buffer_size < DSBSIZE_MIN) buffer_size = DSBSIZE_MIN;
- this->part_size = (buffer_size / PARTS / this->frame_size) * this->frame_size;
- if (!this->part_size) this->part_size = this->frame_size;
- this->buffer_size = this->part_size * PARTS;
+ this->buffer_size = buffer_size;
flags = DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY;
dsound_fill_wfx(&wfx, this->bits, this->rate, this->channels, this->frame_size);
@@ -282,7 +285,7 @@ static int audio_create_buffers(dx2_driver_t *this) {
return 0;
}
- lprintf("created direct sound buffer, size = %u, part = %u\n", this->buffer_size, this->part_size);
+ lprintf("created direct sound buffer, size = %u\n", this->buffer_size);
return 1;
}
@@ -293,43 +296,6 @@ static void audio_destroy_buffers(dx2_driver_t *this) {
}
-/* create position events */
-static int audio_create_events(dx2_driver_t *this) {
- HANDLE handle[PARTS];
- HRESULT err;
- int i;
-
- for (i = 0; i < PARTS; i++) {
- handle[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (!handle[i]) {
- error_message(_("Unable to create buffer position events."));
- return 0;
- }
- this->events[i].dwOffset = i * this->part_size;
- this->events[i].hEventNotify = handle[i];
- }
-
- if ((err = IDirectSoundBuffer_QueryInterface(this->dsbuffer, &IID_IDirectSoundNotify, (void **)&this->notify)) != DS_OK) {
- audio_error(this, err, _("Unable to get notification interface"));
- return 0;
- }
-
- if ((err = IDirectSoundNotify_SetNotificationPositions(this->notify, PARTS, this->events)) != DS_OK) {
- audio_error(this, err, _("Unable to set notification positions"));
- IDirectSoundNotify_Release(this->notify);
- return 0;
- }
-
- return 1;
-}
-
-
-/* destroy notification interface */
-static void audio_destroy_events(dx2_driver_t *this) {
- IDirectSoundNotify_Release(this->notify);
-}
-
-
/* start playback */
static int audio_play(dx2_driver_t *this) {
HRESULT err;
@@ -385,8 +351,7 @@ static int audio_seek(dx2_driver_t *this, size_t pos) {
/* flush audio buffers */
static int audio_flush(dx2_driver_t *this) {
this->status = STATUS_WAIT;
- this->count = 0;
- this->read_size = 0;
+ this->write_pos = 0;
return audio_seek(this, 0);
}
@@ -421,12 +386,12 @@ static int audio_fill(dx2_driver_t *this, char *data, size_t size) {
HRESULT err;
/* lock a part of the buffer, begin position on free space */
- err = IDirectSoundBuffer_Lock(this->dsbuffer, (this->count * this->part_size + this->read_size) % this->buffer_size, size, &ptr1, &size1, &ptr2, &size2, 0);
+ err = IDirectSoundBuffer_Lock(this->dsbuffer, this->write_pos, size, &ptr1, &size1, &ptr2, &size2, 0);
/* try to restore the buffer, if necessary */
if (err == DSERR_BUFFERLOST) {
xine_log(this->class->xine, XINE_LOG_MSG, _(LOG_MODULE ": buffer lost, tryig to restore\n"));
IDirectSoundBuffer_Restore(this->dsbuffer);
- err = IDirectSoundBuffer_Lock(this->dsbuffer, (this->count * this->part_size + this->read_size) % this->buffer_size, size, &ptr1, &size1, &ptr2, &size2, 0); }
+ err = IDirectSoundBuffer_Lock(this->dsbuffer, this->write_pos, size, &ptr1, &size1, &ptr2, &size2, 0); }
if (err != DS_OK) {
audio_error(this, err, _("Couldn't lock direct sound buffer"));
return 0;
@@ -436,19 +401,15 @@ static int audio_fill(dx2_driver_t *this, char *data, size_t size) {
if (ptr1 && size1) xine_fast_memcpy(ptr1, data, size1);
if (ptr2 && size2) xine_fast_memcpy(ptr2, data + size1, size2);
- this->read_size += size;
+ // this->read_size += size;
+ this->write_pos = (this->write_pos + size ) % this->buffer_size;
+ lprintf("size %u, write_pos %u\n", size, this->write_pos);
if ((err = IDirectSoundBuffer_Unlock(this->dsbuffer, ptr1, size1, ptr2, size2)) != DS_OK) {
audio_error(this, err, _("Couldn't unlock direct sound buffer"));
return 0;
}
- /* signal, if are waiting and need wake up */
- if ((this->status == STATUS_WAIT) && buffer_ready(this)) {
- lprintf("buffer ready, waking up\n");
- pthread_cond_signal(&this->data_cond);
- }
-
return 1;
}
@@ -458,28 +419,28 @@ static int mode2channels(uint32_t mode) {
int channels;
switch(mode) {
- case AO_CAP_MODE_MONO:
- channels = 1;
- break;
-
- case AO_CAP_MODE_STEREO:
- channels = 2;
- break;
-
- case AO_CAP_MODE_4CHANNEL:
- channels = 4;
- break;
-
- case AO_CAP_MODE_5CHANNEL:
- channels = 5;
- break;
-
- case AO_CAP_MODE_5_1CHANNEL:
- channels = 6;
- break;
-
- default:
- return 0;
+ case AO_CAP_MODE_MONO:
+ channels = 1;
+ break;
+
+ case AO_CAP_MODE_STEREO:
+ channels = 2;
+ break;
+
+ case AO_CAP_MODE_4CHANNEL:
+ channels = 4;
+ break;
+
+ case AO_CAP_MODE_5CHANNEL:
+ channels = 5;
+ break;
+
+ case AO_CAP_MODE_5_1CHANNEL:
+ channels = 6;
+ break;
+
+ default:
+ return 0;
}
return channels;
@@ -556,109 +517,94 @@ static int test_capabilities(dx2_driver_t *this) {
/* size of free space in the ring buffer */
static size_t buffer_free_size(dx2_driver_t *this) {
- size_t used_full_size;
+
+ int ret;
+ size_t play_pos;
+ size_t free_space;
- used_full_size = this->read_size + ((this->status != STATUS_WAIT) ? this->part_size : 0);
- _x_assert(used_full_size <= this->buffer_size);
- return this->buffer_size - used_full_size;
+ // get current play pos
+ ret = audio_tell(this, &play_pos);
+ if (!ret)
+ return 0;
+
+ // calc free space (-1)
+ free_space = (this->buffer_size + play_pos - this->write_pos - 1) % this->buffer_size;
+
+ return free_space;
}
-/* enough data in the ring buffer for playing next part? */
-static int buffer_ready(dx2_driver_t *this) {
- return this->read_size >= this->part_size;
+/* size of occupied space in the ring buffer */
+static size_t buffer_occupied_size(dx2_driver_t *this) {
+ int ret;
+ size_t play_pos;
+ size_t used_space;
+
+ // get current play pos
+ ret = audio_tell(this, &play_pos);
+ if (!ret) return 0;
+
+ // calc used space
+ used_space = (this->buffer_size + this->write_pos - play_pos) % this->buffer_size;
+
+ return used_space;
}
/* service thread working with direct sound buffer */
static void *buffer_service(void *data) {
dx2_driver_t *this = (dx2_driver_t *)data;
- HANDLE handles[PARTS];
- DWORD ret;
- int i;
-#if defined(EXACT_SLEEP) || defined(EXACT_WAIT)
- size_t play_pos, req_delay;
-#endif
+ size_t buffer_min;
+ size_t data_in_buffer;
/* prepare empty buffer */
audio_flush(this);
- for (i = 0; i < PARTS; i++) handles[i] = this->events[i].hEventNotify;
-
+ /* prepare min buffer fill */
+ buffer_min = BUFFER_MIN_MS * this->rate / 1000 * this->frame_size;
+
/* we live! */
pthread_mutex_lock(&this->data_mutex);
pthread_cond_signal(&this->data_cond);
pthread_mutex_unlock(&this->data_mutex);
while (!this->finished) {
+
pthread_mutex_lock(&this->data_mutex);
- if (!buffer_ready(this)) {
- if (!audio_stop(this)) goto fail;
- lprintf("no data (count=%d,free=%" PRIsizet ",avail=%" PRIsizet "), sleeping...\n", this->count, buffer_free_size(this), this->read_size);
- this->status = STATUS_WAIT;
- pthread_cond_wait(&this->data_cond, &this->data_mutex);
- lprintf("wake up (count=%d,free=%" PRIsizet "--,avail=%" PRIsizet ")\n", this->count, buffer_free_size(this), this->read_size);
- if (this->finished) goto finished;
- if (!audio_seek(this, this->count * this->part_size)) goto fail;
- if (!this->paused) {
- if (!audio_play(this)) goto fail;
- }
- this->status = STATUS_RUNNING;
- this->count = (this->count + 1) % PARTS;
- this->read_size -= this->part_size;
- pthread_mutex_unlock(&this->data_mutex);
- lprintf("wait for playback (newcount=%d,free=%" PRIsizet ",avail=%" PRIsizet ")\n", this->count, buffer_free_size(this), this->read_size);
- do {
- ret = WaitForMultipleObjects(PARTS, handles, FALSE, 250) - WAIT_OBJECT_0;
+ switch( this->status){
+
+ case STATUS_WAIT:
+
+ // pre: stop/buffer flushed
+ lprintf("no data, sleeping...\n");
+ pthread_cond_wait(&this->data_cond, &this->data_mutex);
+ lprintf("woke up (write_pos=%d,free=%" PRIsizet")\n", this->write_pos, buffer_free_size(this));
if (this->finished) goto finished;
- } while (ret > PARTS);
- lprintf("playback started (newcount=%d,ev=%d,free=%" PRIsizet ",avail=%" PRIsizet ")\n", this->count, ret, buffer_free_size(this), this->read_size);
- _x_assert(ret == ((PARTS + this->count - 1) % PARTS));
- } else {
- this->count = (this->count + 1) % PARTS;
- this->read_size -= this->part_size;
- pthread_mutex_unlock(&this->data_mutex);
- }
- lprintf("waiting for sound event(count=%d,free=%" PRIsizet ",avail=%" PRIsizet ")...\n", this->count, buffer_free_size(this), this->read_size);
- do {
- ret = WaitForMultipleObjects(PARTS, handles, FALSE, 250) - WAIT_OBJECT_0;
- if (this->finished) goto finished;
- } while (ret > PARTS);
- lprintf("end wait(ev=%" PRIdword ",count=%d,free=%" PRIsizet ",avail=%" PRIsizet ")\n", ret, this->count, buffer_free_size(this), this->read_size);
-#ifdef PANIC_OVERRUN
- _x_abort(ret == this->count);
-#else
- if (ret != this->count) {
- xine_log(this->class->xine, XINE_LOG_MSG, _(LOG_MODULE ": play cursor overran, flushing buffers\n"));
- pthread_mutex_lock(&this->data_mutex);
- if (!audio_stop(this)) goto fail;
- if (!audio_flush(this)) goto fail;
- pthread_mutex_unlock(&this->data_mutex);
- }
-#endif
-
-#if defined(EXACT_SLEEP) || defined(EXACT_WAIT)
- /* ugly hack: wait for right time, + little over for sure */
- pthread_mutex_lock(&this->data_mutex);
- if (!audio_tell(this, &play_pos)) goto fail;
- req_delay = (this->buffer_size + play_pos - this->count * this->part_size) % this->buffer_size;
- pthread_mutex_unlock(&this->data_mutex);
- if (req_delay > (this->buffer_size >> 1)) {
- long delay;
-
- delay = 1000 * (this->buffer_size - req_delay) / (this->frame_size * this->rate) + 1 + BUFFER_MS / PARTS / 4;
- xine_log(this->class->xine, XINE_LOG_MSG, _(LOG_MODULE ": delayed by %ld msec\n"), delay);
- printf("should be delayed %ld msec\n", delay);
-#ifdef EXACT_SLEEP
- xine_usec_sleep(delay * 1000);
-#endif
-#ifdef EXACT_WAIT
- WaitForMultipleObjects(PARTS, handles, FALSE, delay);
-#endif
+ if (!audio_seek(this, 0)) goto fail;
+ if (!this->paused) {
+ if (!audio_play(this)) goto fail;
+ }
+ this->status = STATUS_RUNNING;
+ pthread_mutex_unlock(&this->data_mutex);
+ break;
+
+ case STATUS_RUNNING:
+
+ // check for buffer underrun
+ data_in_buffer = buffer_occupied_size(this);
+ if ( data_in_buffer < buffer_min){
+ xine_log(this->class->xine, XINE_LOG_MSG, _(LOG_MODULE ": play cursor overran (data %u, min %u), flushing buffers\n"),
+ data_in_buffer, buffer_min);
+ if (!audio_stop(this)) goto fail;
+ if (!audio_flush(this)) goto fail;
+ }
+ pthread_mutex_unlock(&this->data_mutex);
+
+ // just wait BUFFER_MIN_MS before next check
+ xine_usec_sleep(BUFFER_MIN_MS * 1000);
+ break;
}
-#endif
}
-
return NULL;
fail:
@@ -683,15 +629,15 @@ static int ao_dx2_get_property(ao_driver_t *this_gen, int property) {
switch(property) {
- case AO_PROP_MIXER_VOL:
- case AO_PROP_PCM_VOL:
- return this->volume;
+ case AO_PROP_MIXER_VOL:
+ case AO_PROP_PCM_VOL:
+ return this->volume;
- case AO_PROP_MUTE_VOL:
- return this->muted;
+ case AO_PROP_MUTE_VOL:
+ return this->muted;
- default:
- return 0;
+ default:
+ return 0;
}
}
@@ -702,26 +648,26 @@ static int ao_dx2_set_property(ao_driver_t *this_gen, int property, int value) {
switch(property) {
- case AO_PROP_MIXER_VOL:
- case AO_PROP_PCM_VOL:
- lprintf("set volume to %d\n", value);
- pthread_mutex_lock(&this->data_mutex);
- if (!this->muted) {
- if (this->dsbuffer && !audio_set_volume(this, value)) return ~value;
- }
- this->volume = value;
- pthread_mutex_unlock(&this->data_mutex);
- break;
+ case AO_PROP_MIXER_VOL:
+ case AO_PROP_PCM_VOL:
+ lprintf("set volume to %d\n", value);
+ pthread_mutex_lock(&this->data_mutex);
+ if (!this->muted) {
+ if (this->dsbuffer && !audio_set_volume(this, value)) return ~value;
+ }
+ this->volume = value;
+ pthread_mutex_unlock(&this->data_mutex);
+ break;
- case AO_PROP_MUTE_VOL:
- pthread_mutex_lock(&this->data_mutex);
- if (this->dsbuffer && !audio_set_volume(this, value ? 0 : this->volume)) return ~value;
- this->muted = value;
- pthread_mutex_unlock(&this->data_mutex);
- break;
+ case AO_PROP_MUTE_VOL:
+ pthread_mutex_lock(&this->data_mutex);
+ if (this->dsbuffer && !audio_set_volume(this, value ? 0 : this->volume)) return ~value;
+ this->muted = value;
+ pthread_mutex_unlock(&this->data_mutex);
+ break;
- default:
- return ~value;
+ default:
+ return ~value;
}
@@ -747,18 +693,17 @@ static int ao_dx2_open(ao_driver_t *this_gen, uint32_t bits, uint32_t rate, int
this->status = STATUS_START;
if (!audio_create_buffers(this)) return 0;
- if (!audio_create_events(this)) goto fail_buffers;
- if (!audio_set_volume(this, this->volume)) goto fail_events;
+ if (!audio_set_volume(this, this->volume)) goto fail_buffers;
if (pthread_cond_init(&this->data_cond, NULL) != 0) {
xine_log(this->class->xine, XINE_LOG_MSG, _(LOG_MODULE ": can't create pthread condition: %s\n"), strerror(errno));
- goto fail_events;
+ goto fail_buffers;
}
if (pthread_mutex_init(&this->data_mutex, NULL) != 0) {
xine_log(this->class->xine, XINE_LOG_MSG, _(LOG_MODULE ": can't create pthread mutex: %s\n"), strerror(errno));
goto fail_cond;
}
-
+
/* creating the service thread and waiting for its signal */
pthread_mutex_lock(&this->data_mutex);
if (pthread_create(&this->buffer_service, NULL, buffer_service, this) != 0) {
@@ -775,8 +720,6 @@ fail_mutex:
pthread_mutex_destroy(&this->data_mutex);
fail_cond:
pthread_cond_destroy(&this->data_cond);
-fail_events:
- audio_destroy_events(this);
fail_buffers:
audio_destroy_buffers(this);
return 0;
@@ -803,22 +746,26 @@ static int ao_dx2_bytes_per_frame(ao_driver_t *this_gen) {
static int ao_dx2_delay(ao_driver_t *this_gen) {
dx2_driver_t *this = (dx2_driver_t *)this_gen;
- int frames;
- size_t final_pos, play_pos;
-
- if (this->status != STATUS_RUNNING) return this->read_size / this->frame_size;
+ int frames = 0;
+ int ret;
+ size_t play_pos;
pthread_mutex_lock(&this->data_mutex);
- if (!audio_tell(this, &play_pos)) {
- pthread_mutex_unlock(&this->data_mutex);
- return 0;
- }
- final_pos = this->read_size + (((PARTS + this->count - 1) % PARTS) + 1) * this->part_size - 1;
- frames = (this->buffer_size + final_pos - play_pos) % this->buffer_size / this->frame_size;
+
+ if (this->status != STATUS_RUNNING){
+ frames = this->write_pos / this->frame_size;
+ } else {
+ ret = audio_tell(this, &play_pos);
+ if (ret){
+ frames = buffer_occupied_size(this) / this->frame_size;
+ }
+ }
+
pthread_mutex_unlock(&this->data_mutex);
#ifdef LOG
- if ((rand() % 10) == 0) lprintf("frames=%d, play_pos=%" PRIdword ", block=%" PRIsizet "..%" PRIsizet "\n", frames, play_pos, final_pos - this->part_size + 1, final_pos);
+ if ((rand() % 10) == 0)
+ lprintf("frames=%d, play_pos=%" PRIdword ", write_pos=%u\n", frames, play_pos, this->write_pos);
#endif
return frames;
@@ -840,7 +787,7 @@ static int ao_dx2_write(ao_driver_t *this_gen, int16_t* audio_data, uint32_t num
while (((free_size = buffer_free_size(this)) == 0) && !this->finished) {
lprintf("buffer full, waiting\n");
pthread_mutex_unlock(&this->data_mutex);
- xine_usec_sleep(1000 * BUFFER_MS / PARTS / 5);
+ xine_usec_sleep(1000 * BUFFER_MS / 10);
pthread_mutex_lock(&this->data_mutex);
}
if (free_size >= input_size) size = input_size;
@@ -856,6 +803,12 @@ static int ao_dx2_write(ao_driver_t *this_gen, int16_t* audio_data, uint32_t num
input_size -= size;
}
+ /* signal, if are waiting and need wake up */
+ if ((this->status == STATUS_WAIT) && (buffer_occupied_size(this) > BUFFER_MIN_MS * this->rate / 1000 * this->frame_size)) {
+ lprintf("buffer ready, waking up\n");
+ pthread_cond_signal(&this->data_cond);
+ }
+
return 1;
}
@@ -881,7 +834,6 @@ static void ao_dx2_close(ao_driver_t *this_gen) {
if (pthread_mutex_destroy(&this->data_mutex) != 0) {
xine_log(this->class->xine, XINE_LOG_MSG, _(LOG_MODULE ": can't destroy pthread mutex: %s\n"), strerror(errno));
}
- audio_destroy_events(this);
audio_destroy_buffers(this);
}
@@ -896,12 +848,8 @@ static void ao_dx2_exit(ao_driver_t *this_gen) {
}
-/*
- * TODO: check
- */
static int ao_dx2_get_gap_tolerance(ao_driver_t *this_gen) {
- /* half of part of the buffer in pts (1 msec = 90 pts) */
- return (90 * (BUFFER_MS / PARTS)) >> 1;
+ return GAP_TOLERANCE;
}
@@ -910,36 +858,36 @@ static int ao_dx2_control(ao_driver_t *this_gen, int cmd, ...) {
switch(cmd) {
- case AO_CTRL_PLAY_PAUSE:
- lprintf("control pause\n");
- pthread_mutex_lock(&this->data_mutex);
- if (!this->paused) {
- audio_stop(this);
- this->paused = 1;
- }
- pthread_mutex_unlock(&this->data_mutex);
- break;
+ case AO_CTRL_PLAY_PAUSE:
+ lprintf("control pause\n");
+ pthread_mutex_lock(&this->data_mutex);
+ if (!this->paused) {
+ audio_stop(this);
+ this->paused = 1;
+ }
+ pthread_mutex_unlock(&this->data_mutex);
+ break;
- case AO_CTRL_PLAY_RESUME:
- lprintf("control resume\n");
- pthread_mutex_lock(&this->data_mutex);
- if (this->paused) {
- if (this->status != STATUS_WAIT) audio_play(this);
- this->paused = 0;
- }
- pthread_mutex_unlock(&this->data_mutex);
- break;
-
- case AO_CTRL_FLUSH_BUFFERS:
- lprintf("control flush\n");
- pthread_mutex_lock(&this->data_mutex);
- audio_stop(this);
- audio_flush(this);
- pthread_mutex_unlock(&this->data_mutex);
- break;
+ case AO_CTRL_PLAY_RESUME:
+ lprintf("control resume\n");
+ pthread_mutex_lock(&this->data_mutex);
+ if (this->paused) {
+ if (this->status != STATUS_WAIT) audio_play(this);
+ this->paused = 0;
+ }
+ pthread_mutex_unlock(&this->data_mutex);
+ break;
+
+ case AO_CTRL_FLUSH_BUFFERS:
+ lprintf("control flush\n");
+ pthread_mutex_lock(&this->data_mutex);
+ audio_stop(this);
+ audio_flush(this);
+ pthread_mutex_unlock(&this->data_mutex);
+ break;
- default:
- xine_log(this->class->xine, XINE_LOG_MSG, _(LOG_MODULE ": unknown control command %d\n"), cmd);
+ default:
+ xine_log(this->class->xine, XINE_LOG_MSG, _(LOG_MODULE ": unknown control command %d\n"), cmd);
}
@@ -955,7 +903,7 @@ static ao_driver_t *open_plugin(audio_driver_class_t *class_gen, const void *dat
lprintf("open plugin called\n");
- this = (dx2_driver_t *)xine_xmalloc(sizeof(dx2_driver_t));
+ this = calloc(1, sizeof(dx2_driver_t));
if (!this)
return NULL;
@@ -1009,7 +957,7 @@ static void *init_class(xine_t *xine, void *data) {
lprintf("init class\n");
- this = (dx2_class_t *)xine_xmalloc(sizeof(dx2_class_t));
+ this = calloc(1, sizeof(dx2_class_t));
if (!this)
return NULL;
diff --git a/src/audio_out/audio_directx_out.c b/src/audio_out/audio_directx_out.c
index 77e3e15b9..21ba23d91 100644
--- a/src/audio_out/audio_directx_out.c
+++ b/src/audio_out/audio_directx_out.c
@@ -60,9 +60,13 @@ typedef unsigned char boolean;
* the linking stage.
*****************************************************************************/
#if 1
-static const GUID IID_IDirectSoundNotify = {
+static const GUID xine_IID_IDirectSoundNotify = {
0xB0210783,0x89CD,0x11D0,{0xAF,0x08,0x00,0xA0,0xC9,0x25,0xCD,0x16}
};
+#ifdef IID_IDirectSoundNotify
+# undef IID_IDirectSoundNotify
+#endif
+#define IID_IDirectSoundNotify xine_IID_IDirectSoundNotify
#endif
@@ -790,7 +794,7 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da
audiox_class_t *class = (audiox_class_t *) class_gen;
ao_directx_t *ao_directx;
- ao_directx = ( ao_directx_t * ) xine_xmalloc( sizeof( ao_directx_t ) );
+ ao_directx = calloc(1, sizeof(ao_directx_t));
if (!ao_directx)
return NULL;
@@ -841,7 +845,7 @@ static void *init_class (xine_t *xine, void *data) {
/*
* from this point on, nothing should go wrong anymore
*/
- audiox = (audiox_class_t *) xine_xmalloc (sizeof (audiox_class_t));
+ audiox = calloc(1, sizeof (audiox_class_t));
if (!audiox)
return NULL;
diff --git a/src/audio_out/audio_esd_out.c b/src/audio_out/audio_esd_out.c
index 4b209bea1..63c54b546 100644
--- a/src/audio_out/audio_esd_out.c
+++ b/src/audio_out/audio_esd_out.c
@@ -521,7 +521,7 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen,
esd_close(audio_fd);
- this = (esd_driver_t *) xine_xmalloc (sizeof (esd_driver_t));
+ this = calloc(1, sizeof (esd_driver_t));
if (!this)
return NULL;
this->xine = class->xine;
@@ -583,7 +583,7 @@ static void *init_class (xine_t *xine, void *data) {
esd_class_t *this;
- this = (esd_class_t *) xine_xmalloc (sizeof (esd_class_t));
+ this = calloc(1, sizeof (esd_class_t));
if (!this)
return NULL;
diff --git a/src/audio_out/audio_file_out.c b/src/audio_out/audio_file_out.c
index 225d64d0e..699a5cf54 100644
--- a/src/audio_out/audio_file_out.c
+++ b/src/audio_out/audio_file_out.c
@@ -323,7 +323,7 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen,
lprintf ("open_plugin called\n");
- this = (file_driver_t *) xine_xmalloc (sizeof (file_driver_t));
+ this = calloc(1, sizeof (file_driver_t));
if (!this)
return NULL;
@@ -375,7 +375,7 @@ static void *init_class (xine_t *xine, void *data) {
lprintf ("init class\n");
- this = (file_class_t *) xine_xmalloc (sizeof (file_class_t));
+ this = calloc(1, sizeof (file_class_t));
if (!this)
return NULL;
diff --git a/src/audio_out/audio_fusionsound_out.c b/src/audio_out/audio_fusionsound_out.c
index 92eadc6cf..6c3a0ae33 100644
--- a/src/audio_out/audio_fusionsound_out.c
+++ b/src/audio_out/audio_fusionsound_out.c
@@ -389,11 +389,11 @@ static ao_driver_t* open_plugin(audio_driver_class_t *ao_class,
fusionsound_class_t *class = (fusionsound_class_t *) ao_class;
fusionsound_driver_t *this;
const char *args[] = { "xine", "--dfb:no-sighandler", "--fs:no-banner" };
- int argn = sizeof(args) / sizeof(args[0]);
+ const size_t argn = sizeof(args) / sizeof(args[0]);
char **argp = (char **) args;
DFBResult ret;
- this = (fusionsound_driver_t *) xine_xmalloc (sizeof(fusionsound_driver_t));
+ this = calloc(1, sizeof(fusionsound_driver_t));
if (!this) {
xprintf (class->xine, XINE_VERBOSITY_LOG,
"audio_fusionsound_out: driver interface allocation failed!\n");
@@ -460,7 +460,7 @@ static void* init_class(xine_t *xine, void *data) {
return NULL;
}
- class = (fusionsound_class_t *) xine_xmalloc (sizeof( fusionsound_class_t));
+ class = calloc(1, sizeof( fusionsound_class_t));
if (!class) {
xprintf (xine, XINE_VERBOSITY_LOG,
"audio_fusionsound_out: class interface allocation failed!\n");
diff --git a/src/audio_out/audio_jack_out.c b/src/audio_out/audio_jack_out.c
index 1bc070527..10c58c774 100644
--- a/src/audio_out/audio_jack_out.c
+++ b/src/audio_out/audio_jack_out.c
@@ -1,3 +1,6 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
#include <stdio.h>
#include <errno.h>
@@ -17,431 +20,942 @@
#define AO_OUT_JACK_IFACE_VERSION 8
#define GAP_TOLERANCE AO_MAX_GAP
-#define BUFSIZE 81920
+/* maximum number of channels supported, avoids lots of mallocs */
+#define MAX_CHANS 6
-typedef struct jack_driver_s {
+typedef struct jack_driver_s
+{
+ ao_driver_t ao_driver;
+ xine_t *xine;
+
+ int capabilities;
+ int mode;
+ int paused;
+ int underrun;
+
+ int32_t output_sample_rate, input_sample_rate;
+ uint32_t num_channels;
+ uint32_t bits_per_sample;
+ uint32_t bytes_per_frame;
+ uint32_t bytes_in_buffer; /* number of bytes writen to audio hardware */
+ uint32_t fragment_size;
+
+ jack_client_t *client;
+ jack_port_t *ports[MAX_CHANS];
+
+ /*! buffer for audio data */
+ unsigned char *buffer;
+
+ /*! buffer read position, may only be modified by playback thread or while it is stopped */
+ uint32_t read_pos;
+ /*! buffer write position, may only be modified by MPlayer's thread */
+ uint32_t write_pos;
+
+ struct
+ {
+ int volume;
+ int mute;
+ } mixer;
- ao_driver_t ao_driver;
- xine_t *xine;
+} jack_driver_t;
- int capabilities;
+typedef struct
+{
+ audio_driver_class_t driver_class;
+ config_values_t *config;
+ xine_t *xine;
+} jack_class_t;
- int32_t sample_rate;
- uint32_t num_channels;
- uint32_t bits_per_sample;
- uint32_t bytes_per_frame;
- jack_client_t *client;
- jack_port_t *port_1;
- jack_port_t *port_2;
- float buf_1[BUFSIZE];
- float buf_2[BUFSIZE];
- uint32_t buf_read;
- uint32_t buf_write;
+/**************************************************************
+ *
+ * Simple ringbuffer implementation
+ * Lifted from mplayer ao_jack.c
+ *
+**************************************************************/
+
+
+/*! size of one chunk, if this is too small Xine will start to "stutter" */
+/*! after a short time of playback */
+#define CHUNK_SIZE (16 * 1024)
+/*! number of "virtual" chunks the buffer consists of */
+#define NUM_CHUNKS 8
+/* This type of ring buffer may never fill up completely, at least */
+/* one byte must always be unused. */
+/* For performance reasons (alignment etc.) one whole chunk always stays */
+/* empty, not only one byte. */
+#define BUFFSIZE ((NUM_CHUNKS + 1) * CHUNK_SIZE)
+
+/**
+ * \brief get the number of free bytes in the buffer
+ * \return number of free bytes in buffer
+ *
+ * may only be called by Xine's thread
+ * return value may change between immediately following two calls,
+ * and the real number of free bytes might be larger!
+ */
+static int buf_free (jack_driver_t *this)
+{
+ int free = this->read_pos - this->write_pos - CHUNK_SIZE;
+ if (free < 0)
+ free += BUFFSIZE;
+ return free;
+}
- uint32_t volume;
- uint32_t mute;
+/**
+ * \brief get amount of data available in the buffer
+ * \return number of bytes available in buffer
+ *
+ * may only be called by the playback thread
+ * return value may change between immediately following two calls,
+ * and the real number of buffered bytes might be larger!
+ */
+static int buf_used (jack_driver_t *this)
+{
+ int used = this->write_pos - this->read_pos;
+ if (used < 0)
+ used += BUFFSIZE;
+ return used;
+}
-} jack_driver_t;
+/**
+ * \brief insert len bytes into buffer
+ * \param data data to insert
+ * \param len length of data
+ * \return number of bytes inserted into buffer
+ *
+ * If there is not enough room, the buffer is filled up
+ *
+ * TODO: Xine should really pass data as float, perhaps in V1.2?
+ */
+static int write_buffer_32 (jack_driver_t *this, unsigned char *data, int len)
+{
+ int first_len = BUFFSIZE - this->write_pos;
+ int free = buf_free (this);
+ if (len > free)
+ len = free;
+ if (first_len > len)
+ first_len = len;
+
+ /* copy from current write_pos to end of buffer */
+ memcpy (&(this->buffer[this->write_pos]), data, first_len);
+ if (len > first_len) { /* we have to wrap around */
+ /* remaining part from beginning of buffer */
+ memcpy (this->buffer, &data[first_len], len - first_len);
+ }
+ this->write_pos = (this->write_pos + len) % BUFFSIZE;
+
+ return len;
+}
+
+static int write_buffer_16 (jack_driver_t *this, unsigned char *data, int len)
+{
+ int samples_free = buf_free (this) / (sizeof (float));
+ int samples = len / 2;
+ if (samples > samples_free)
+ samples = samples_free;
+
+ /* Rename some pointers so that the next bit of gymnastics is easier to read */
+ uint32_t write_pos = this->write_pos;
+ float *p_write;
+ int16_t *p_read = (int16_t *) data;
+ int i;
+ for (i = 0; i < samples; i++) {
+ /* Read in 16bits, write out floats */
+ p_write = (float *) (&(this->buffer[write_pos]));
+ *p_write = ((float) (p_read[i])) / 32767.0f;
+ write_pos = (write_pos + sizeof (float)) % BUFFSIZE;
+ }
+ this->write_pos = write_pos;
+
+ return samples * 2;
+}
-typedef struct {
- audio_driver_class_t driver_class;
- config_values_t *config;
- xine_t *xine;
-} jack_class_t;
-static int jack_process(jack_nframes_t nframes, void *arg)
+/**
+ * \brief read data from buffer and splitting it into channels
+ * \param bufs num_bufs float buffers, each will contain the data of one channel
+ * \param cnt number of samples to read per channel
+ * \param num_bufs number of channels to split the data into
+ * \return number of samples read per channel, equals cnt unless there was too
+ * little data in the buffer
+ *
+ * Assumes the data in the buffer is of type float, the number of bytes
+ * read is res * num_bufs * sizeof(float), where res is the return value.
+ * If there is not enough data in the buffer remaining parts will be filled
+ * with silence.
+ */
+static int read_buffer (jack_driver_t *this, float **bufs, int cnt,
+ int num_bufs, float gain)
{
- jack_driver_t *this = (jack_driver_t *)arg;
- uint32_t local_buf_read = this->buf_read;
- uint32_t local_buf_write = this->buf_write;
- uint32_t src_channel, target_channel;
- uint32_t frame;
- float *buf, *out;
- float gain = 0;
-
- if (!this->client) return 0;
-
- if (!this->mute) {
- gain = (float)this->volume / 100.0;
+ int buffered = buf_used (this);
+ int i, j;
+ int orig_cnt = cnt;
+ if (cnt * sizeof (float) * num_bufs > buffered)
+ cnt = buffered / (sizeof (float) * num_bufs);
+
+ uint32_t read_pos = this->read_pos;
+ unsigned char *buffer = this->buffer;
+ for (i = 0; i < cnt; i++) {
+ for (j = 0; j < num_bufs; j++) {
+ bufs[j][i] = *((float *) (&(buffer[read_pos]))) * gain;
+ read_pos = (read_pos + sizeof (float)) % BUFFSIZE;
}
+ }
+ this->read_pos = read_pos;
+ for (i = cnt; i < orig_cnt; i++)
+ for (j = 0; j < num_bufs; j++)
+ bufs[j][i] = 0;
- for (target_channel = 0; target_channel < 2; ++target_channel) {
-
- if (target_channel < this->num_channels) src_channel = target_channel;
- else src_channel = 0;
+ return cnt;
+}
- jack_port_t *port = (target_channel ? this->port_2 : this->port_1);
- if (!port) continue;
+/**
+ * \brief fill the buffers with silence
+ * \param bufs num_bufs float buffers, each will contain the data of one channel
+ * \param cnt number of samples in each buffer
+ * \param num_bufs number of buffers
+ */
+static void silence (float **bufs, int cnt, int num_bufs)
+{
+ int i, j;
+ for (i = 0; i < cnt; i++)
+ for (j = 0; j < num_bufs; j++)
+ bufs[j][i] = 0;
+}
- buf = (src_channel ? this->buf_2 : this->buf_1);
- out = (float *)jack_port_get_buffer(port, nframes);
- local_buf_read = this->buf_read;
- frame = 0;
+/**************************************************************
+ *
+ * Jack interface functions
+ *
+**************************************************************/
- while (frame < nframes && local_buf_read != local_buf_write) {
- // local_buf_write doesn't change during this process,
- // so we can safely defer updating buf_read until after
+/**
+ * \brief stop playing and empty buffers (for seeking/pause)
+ */
+static void jack_reset (jack_driver_t *this)
+{
+ this->paused = 1;
+ this->read_pos = this->write_pos = 0;
+ this->paused = 0;
+}
- out[frame++] = buf[local_buf_read] * gain;
- if (++local_buf_read == BUFSIZE) local_buf_read = 0;
- }
+static int jack_callback (jack_nframes_t nframes, void *arg)
+{
+ jack_driver_t *this = (jack_driver_t *) arg;
- if (frame < nframes) {
-// printf("jack_process: underrun: %u required, %u available\n",
-// nframes, frame);
- while (frame < nframes) {
- out[frame++] = 0.0f;
- }
- }
+ if (!this->client) {
+ xprintf (this->xine, XINE_VERBOSITY_LOG,
+ "jack_callback: called without a client parameter? silently trying to continue...\n");
+ return 0;
+ }
+
+ float gain = 0;
+ if (!this->mixer.mute) {
+ gain = (float) this->mixer.volume / 100.0;
+ gain *= gain; /* experiment with increasing volume range */
+ }
+
+ float *bufs[MAX_CHANS];
+ int i;
+ for (i = 0; i < this->num_channels; i++)
+ bufs[i] = jack_port_get_buffer (this->ports[i], nframes);
+
+ if (this->paused || this->underrun) {
+ silence (bufs, nframes, this->num_channels);
+ } else {
+ int frames_read = read_buffer (this, bufs, nframes, this->num_channels, gain);
+ if (frames_read < nframes) {
+ xprintf (this->xine, XINE_VERBOSITY_LOG,
+ "jack_callback: underrun - frames read: %d\n", frames_read);
+ this->underrun = 1;
}
+ }
- this->buf_read = local_buf_read;
+ return 0;
+}
-// printf("jack_process: buf_read %u, buf_write %u\n", this->buf_read, this->buf_write);
+static void jack_shutdown (void *arg)
+{
+ jack_driver_t *this = (jack_driver_t *) arg;
+ this->client = NULL;
+}
- return 0;
+/*
+ * Open the Jack audio device
+ * Return 1 on success, 0 on failure
+ * All error handling rests with the caller, we just try to open the device here
+ */
+static int jack_open_device (ao_driver_t *this_gen, char *jack_device,
+ int32_t *poutput_sample_rate, int num_channels)
+{
+ jack_driver_t *this = (jack_driver_t *) this_gen;
+ const char **matching_ports = NULL;
+ char *port_name = NULL;
+ jack_client_t *client = this->client;
+
+ int port_flags = JackPortIsInput;
+ int i;
+ int num_ports;
+
+ if (num_channels > MAX_CHANS) {
+ xprintf (this->xine, XINE_VERBOSITY_LOG,
+ "jack_open_device: Invalid number of channels: %i\n",
+ num_channels);
+ goto err_out;
+ }
+ /* Try to create a client called "xine" */
+ if ((client = jack_client_new ("xine")) == 0) {
+ /* If that doesn't work it could be because running two copies of xine - try using a unique name */
+ char client_name[20];
+ sprintf (client_name, "xine (%d)", (int) getpid ());
+
+ if ((client = jack_client_new (client_name)) == 0) {
+ xprintf (this->xine, XINE_VERBOSITY_LOG,
+ "\njack_open_device: Error: Failed to connect to JACK server\n");
+ xprintf (this->xine, XINE_VERBOSITY_LOG,
+ "jack_open_device: (did you start 'jackd' server?)\n");
+ goto err_out;
+ }
+ }
+
+ /* Save the new client */
+ this->client = client;
+
+ jack_reset (this);
+ jack_set_process_callback (client, jack_callback, this);
+
+ /* list matching ports */
+ if (!jack_device)
+ port_flags |= JackPortIsPhysical;
+ matching_ports = jack_get_ports (client, jack_device, NULL, port_flags);
+ for (num_ports = 0; matching_ports && matching_ports[num_ports];
+ num_ports++);
+ if (!num_ports) {
+ xprintf (this->xine, XINE_VERBOSITY_LOG,
+ "jack_open_device: no physical ports available\n");
+ goto err_out;
+ }
+ if (num_ports < num_channels) {
+ xprintf (this->xine, XINE_VERBOSITY_LOG,
+ "jack_open_device: not enough physical ports available\n");
+ goto err_out;
+ }
+
+ /* create output ports */
+ for (i = 0; i < num_channels; i++) {
+ char pname[50];
+ snprintf (pname, 50, "out_%d", i);
+ this->ports[i] =
+ jack_port_register (client, pname, JACK_DEFAULT_AUDIO_TYPE,
+ JackPortIsOutput, 0);
+ if (!this->ports[i]) {
+ xprintf (this->xine, XINE_VERBOSITY_LOG,
+ "jack_open_device: could not create output ports? Why not?\n");
+ goto err_out;
+ }
+ }
+ if (jack_activate (client)) {
+ xprintf (this->xine, XINE_VERBOSITY_LOG,
+ "jack_open_device: jack_activate() failed\n");
+ goto err_out;
+ }
+ for (i = 0; i < num_channels; i++) {
+ if (jack_connect
+ (client, jack_port_name (this->ports[i]), matching_ports[i])) {
+ xprintf (this->xine, XINE_VERBOSITY_LOG,
+ "jack_open_device: jack_connect() failed\n");
+ goto err_out;
+ }
+ }
+ *poutput_sample_rate = jack_get_sample_rate (client);
+
+ free (matching_ports);
+ return 1;
+
+err_out:
+ free (matching_ports);
+ if (client) {
+ jack_client_close (client);
+ this->client = NULL;
+ }
+ return 0;
}
-
-static void jack_shutdown(void *arg)
+
+/**************************************************************
+ *
+ * Xine interface functions
+ *
+**************************************************************/
+
+
+/**
+ * close the device and reset the play position
+ */
+static void ao_jack_close (ao_driver_t *this_gen)
{
- jack_driver_t *this = (jack_driver_t *)arg;
- this->client = 0;
+ jack_driver_t *this = (jack_driver_t *) this_gen;
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG, "ao_jack_close: closing\n");
+
+ jack_reset (this);
+ if (this->client) {
+ jack_client_close (this->client);
+ this->client = NULL;
+ }
}
/*
* open the audio device for writing to
*/
-static int ao_jack_open(ao_driver_t *this_gen, uint32_t bits, uint32_t rate, int mode)
+static int ao_jack_open (ao_driver_t *this_gen, uint32_t bits, uint32_t rate,
+ int mode)
{
- jack_driver_t *this = (jack_driver_t *) this_gen;
+ jack_driver_t *this = (jack_driver_t *) this_gen;
+ config_values_t *config = this->xine->config;
+ char *jack_device;
- if (bits != 16) {
- fprintf(stderr, "ao_jack_open: bits=%u expected %u\n", bits, 16);
- return 0;
- }
+ jack_device =
+ config->lookup_entry (config, "audio.device.jack_device_name")->str_value;
- rate = jack_get_sample_rate(this->client);
- fprintf(stderr, "ao_jack_open: JACK sample rate is %u\n", rate);
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG,
+ "ao_jack_open: ao_open rate=%d, mode=%d, bits=%d dev=%s\n", rate,
+ mode, bits, jack_device);
- switch (mode) {
- case AO_CAP_MODE_MONO:
- this->num_channels = 1;
- break;
- case AO_CAP_MODE_STEREO:
- this->num_channels = 2;
- break;
+ if ((bits != 16) && (bits != 32)) {
+ xprintf (this->xine, XINE_VERBOSITY_LOG,
+ "ao_jack_open: bits=%u expected 16 or 32bit only\n", bits);
+ return 0;
+ }
+
+ if ((mode & this->capabilities) == 0) {
+ xprintf (this->xine, XINE_VERBOSITY_LOG,
+ "ao_jack_open: unsupported mode %08x\n", mode);
+ return 0;
+ }
+
+ /* If device open already then either re-use it or close it */
+ if (this->client) {
+ if ((mode == this->mode) && (rate == this->input_sample_rate)) {
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG,
+ "ao_jack_open: device already open, reusing it\n");
+ return this->output_sample_rate;
}
- this->buf_read = this->buf_write = 0;
- this->sample_rate = rate;
- this->bits_per_sample = bits;
- this->capabilities = AO_CAP_16BITS | AO_CAP_MODE_MONO | \
- AO_CAP_MODE_STEREO | AO_CAP_MIXER_VOL | AO_CAP_MUTE_VOL;
- this->bytes_per_frame = this->num_channels * (bits / 8);
+ ao_jack_close (this_gen);
+ }
+
+
+ this->mode = mode;
+ this->input_sample_rate = rate;
+ this->bits_per_sample = bits;
+ this->bytes_in_buffer = 0;
+ this->read_pos = this->write_pos = 0;
+ this->paused = 0;
+ this->underrun = 0;
+
+ /*
+ * set number of channels / a52 passthrough
+ */
+ switch (mode) {
+ case AO_CAP_MODE_MONO:
+ this->num_channels = 1;
+ break;
+ case AO_CAP_MODE_STEREO:
+ this->num_channels = 2;
+ break;
+ case AO_CAP_MODE_4CHANNEL:
+ this->num_channels = 4;
+ break;
+ case AO_CAP_MODE_4_1CHANNEL:
+ case AO_CAP_MODE_5CHANNEL:
+ case AO_CAP_MODE_5_1CHANNEL:
+ this->num_channels = 6;
+ break;
+ case AO_CAP_MODE_A52:
+ case AO_CAP_MODE_AC5:
+ /* FIXME: Is this correct...? */
+ this->num_channels = 2;
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG,
+ "ao_jack_open: AO_CAP_MODE_A52\n");
+ break;
+ default:
+ xprintf (this->xine, XINE_VERBOSITY_LOG,
+ "ao_jack_open: JACK Driver does not support the requested mode: 0x%X\n",
+ mode);
+ return 0;
+ }
+
+ xprintf (this->xine, XINE_VERBOSITY_LOG,
+ "ao_jack_open: %d channels output\n", this->num_channels);
+ this->bytes_per_frame = (this->bits_per_sample * this->num_channels) / 8;
- fprintf(stderr, "ao_jack_open: bits=%d rate=%d, mode=%d OK\n", bits, rate, mode);
+ /*
+ * open audio device
+ */
+ if (!jack_open_device (this_gen, jack_device, &(this->output_sample_rate),
+ this->num_channels))
+ return 0;
- return rate;
+ if (this->input_sample_rate != this->output_sample_rate) {
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG,
+ "ao_jack_open: audio rate : %d requested, %d provided by device\n",
+ this->input_sample_rate, this->output_sample_rate);
+ }
+
+ return this->output_sample_rate;
}
-static int ao_jack_num_channels(ao_driver_t *this_gen)
+static int ao_jack_num_channels (ao_driver_t *this_gen)
{
- jack_driver_t *this = (jack_driver_t *) this_gen;
- return this->num_channels;
+ jack_driver_t *this = (jack_driver_t *) this_gen;
+ return this->num_channels;
}
-static int ao_jack_bytes_per_frame(ao_driver_t *this_gen)
+static int ao_jack_bytes_per_frame (ao_driver_t *this_gen)
{
- jack_driver_t *this = (jack_driver_t *) this_gen;
- return this->bytes_per_frame;
+ jack_driver_t *this = (jack_driver_t *) this_gen;
+ return this->bytes_per_frame;
}
static int ao_jack_get_gap_tolerance (ao_driver_t *this_gen)
{
- return GAP_TOLERANCE;
+ return GAP_TOLERANCE;
}
-static int last_write_space = 0;
-
-static int ao_jack_write(ao_driver_t *this_gen, int16_t *data,
- uint32_t num_frames)
+/*
+ * Return the number of outstanding frames in all output buffers
+ * need to account for ring buffer plus Jack, plus soundcard
+ */
+static int ao_jack_delay (ao_driver_t *this_gen)
{
- jack_driver_t *this = (jack_driver_t *) this_gen;
- uint32_t frame, channel;
-
- uint32_t local_buf_read = this->buf_read;
- uint32_t local_buf_write = this->buf_write;
- uint32_t space = (local_buf_read + BUFSIZE - local_buf_write - 1) % BUFSIZE;
- uint32_t first_frame = 0;
-
- int c = 0;
- while (space < num_frames) {
- if (++c == 10) return 0;
- usleep(10000);
- local_buf_read = this->buf_read;
- space = (local_buf_read + BUFSIZE - local_buf_write - 1) % BUFSIZE;
- }
-
-// if (space < num_frames) return 0;
-
-// printf("ao_jack_write: %u frames on %u channels, space is %u\n", num_frames, this->num_channels, space);
- last_write_space = space;
-
- for (frame = first_frame; frame < num_frames; ++frame) {
- for (channel = 0; channel < this->num_channels; ++channel) {
- float *buf = (channel ? this->buf_2 : this->buf_1);
- int16_t sample = data[frame * this->num_channels + channel];
- buf[local_buf_write] = ((float)sample) / 32767.0f;
-// printf("%6f ", buf[local_buf_write]);
-// if (++c == 8) { printf("\n"); c = 0; }
- }
- if (++local_buf_write == BUFSIZE) local_buf_write = 0;
- }
-
- this->buf_write = local_buf_write;
+ jack_driver_t *this = (jack_driver_t *) this_gen;
+ int frames_played = jack_frames_since_cycle_start (this->client);
-// printf("ao_jack_write: buf_read %u, buf_write %u\n", this->buf_read, this->buf_write);
+ int delay = 0;
+ /* Ring Buffer always stores floats */
+ /* TODO: Unsure if the delay should be fragment_size*2 or *3? */
+ delay = buf_used (this) / (sizeof (float) * this->num_channels) +
+ this->fragment_size * 3 - frames_played;
- return 1;
+ return delay;
}
-static int ao_jack_delay (ao_driver_t *this_gen)
+ /* Write audio samples
+ * num_frames is the number of audio frames present
+ * audio frames are equivalent one sample on each channel.
+ * I.E. Stereo 16 bits audio frames are 4 bytes.
+ * MUST SIMULATE BLOCKING WRITES
+ */
+static int ao_jack_write (ao_driver_t *this_gen, int16_t *frame_buffer,
+ uint32_t num_frames)
{
- jack_driver_t *this = (jack_driver_t *) this_gen;
-
- uint32_t local_buf_read = this->buf_read;
- uint32_t local_buf_write = this->buf_write;
+ jack_driver_t *this = (jack_driver_t *) this_gen;
+ int written = 0;
+ int num_bytes = num_frames * this->bytes_per_frame;
+
+ /* First try and write all the bytes in one go */
+ this->underrun = 0;
+ /* TODO: In the future Xine should pass only floats to us, so no conversion needed */
+ if (this->bits_per_sample == 16)
+ written = write_buffer_16 (this, (char *) frame_buffer, num_bytes);
+ else if (this->bits_per_sample == 32)
+ written = write_buffer_32 (this, (char *) frame_buffer, num_bytes);
+
+ /* If this fails then need to spin and keep trying until everything written */
+ int spin_count = 0;
+ while ((written < num_bytes) && (spin_count < 40)) {
+ num_bytes -= written;
+ frame_buffer += written / 2;
+
+ /* Sleep to save CPU */
+ int until_callback =
+ this->fragment_size - jack_frames_since_cycle_start (this->client);
+ if ((until_callback < 0) || (until_callback > this->fragment_size)) {
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG,
+ "ao_jack_write: Invalid until_callback %d\n", until_callback);
+ until_callback = this->fragment_size;
+ }
+ xine_usec_sleep (((until_callback +
+ 100) * 1000.0 * 1000.0) / this->output_sample_rate);
- int delay = 0;
+ if (this->bits_per_sample == 16)
+ written = write_buffer_16 (this, (char *) frame_buffer, num_bytes);
+ else if (this->bits_per_sample == 32)
+ written = write_buffer_32 (this, (char *) frame_buffer, num_bytes);
- if (local_buf_write > local_buf_read) {
- delay = local_buf_write - local_buf_read;
- } else {
- delay = ((local_buf_write + BUFSIZE - local_buf_read) % BUFSIZE);
- }
+ if (written == 0)
+ spin_count++;
+ else
+ spin_count = 0;
- return delay;// - jack_get_buffer_size(this->client);
-}
+ if (written == 0)
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG,
+ "ao_jack_write: unusual, couldn't write anything\n");
+ };
-static void ao_jack_close(ao_driver_t *this_gen)
-{
- // nothing
-}
+ if (spin_count)
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG,
+ "Nonzero spin_count...%d\n", spin_count);
-static uint32_t ao_jack_get_capabilities (ao_driver_t *this_gen) {
- jack_driver_t *this = (jack_driver_t *) this_gen;
- return this->capabilities;
+ return spin_count ? 0 : 1; /* return 1 on success, 0 if we got stuck for some reason */
}
-static void ao_jack_exit(ao_driver_t *this_gen)
+static uint32_t ao_jack_get_capabilities (ao_driver_t *this_gen)
{
- jack_driver_t *this = (jack_driver_t *) this_gen;
- jack_client_t *client = this->client;
- ao_jack_close(this_gen);
- this->client = 0;
- if (client) jack_client_close(client);
- free (this);
+ jack_driver_t *this = (jack_driver_t *) this_gen;
+ return this->capabilities;
}
-static int ao_jack_get_property (ao_driver_t *this_gen, int property) {
- jack_driver_t *this = (jack_driver_t *) this_gen;
-
- switch(property) {
- case AO_PROP_PCM_VOL:
- case AO_PROP_MIXER_VOL:
-// printf("ao_jack_get_property(AO_PROP_MIXER_VOL): %u\n", this->volume);
- return this->volume;
- break;
- case AO_PROP_MUTE_VOL:
-// printf("ao_jack_get_property(AO_PROP_MUTE_VOL): %u\n", this->mute);
- return this->mute;
- break;
- }
+static void ao_jack_exit (ao_driver_t *this_gen)
+{
+ jack_driver_t *this = (jack_driver_t *) this_gen;
- return 0;
+ ao_jack_close (this_gen);
+ if (this->buffer)
+ free (this->buffer);
+ free (this);
}
-static int ao_jack_set_property (ao_driver_t *this_gen, int property, int value) {
- jack_driver_t *this = (jack_driver_t *) this_gen;
-
- switch(property) {
- case AO_PROP_PCM_VOL:
- case AO_PROP_MIXER_VOL:
-// printf("ao_jack_set_property(AO_PROP_MIXER_VOL): %u\n", value);
- this->volume = value;
- break;
- case AO_PROP_MUTE_VOL:
-// printf("ao_jack_get_property(AO_PROP_MUTE_VOL): %u\n", value);
- this->mute = value;
- break;
- }
+static int ao_jack_get_property (ao_driver_t *this_gen, int property)
+{
+ jack_driver_t *this = (jack_driver_t *) this_gen;
+
+ switch (property) {
+ case AO_PROP_PCM_VOL:
+ case AO_PROP_MIXER_VOL:
+ return this->mixer.volume;
+ break;
+ case AO_PROP_MUTE_VOL:
+ return this->mixer.mute;
+ break;
+ }
+
+ return 0;
+}
- return ~value;
+static int ao_jack_set_property (ao_driver_t *this_gen, int property, int value)
+{
+ jack_driver_t *this = (jack_driver_t *) this_gen;
+
+ switch (property) {
+ case AO_PROP_PCM_VOL:
+ case AO_PROP_MIXER_VOL:
+ this->mixer.volume = value;
+ return value;
+ break;
+ case AO_PROP_MUTE_VOL:
+ this->mixer.mute = value;
+ return value;
+ break;
+ }
+
+ return -1;
}
-static int ao_jack_ctrl(ao_driver_t *this_gen, int cmd, ...) {
- jack_driver_t *this = (jack_driver_t *) this_gen;
+static int ao_jack_ctrl (ao_driver_t *this_gen, int cmd, ...)
+{
+ jack_driver_t *this = (jack_driver_t *) this_gen;
- switch (cmd) {
+ switch (cmd) {
- case AO_CTRL_PLAY_PAUSE:
- break;
+ case AO_CTRL_PLAY_PAUSE:
+ this->paused = 1;
+ break;
- case AO_CTRL_PLAY_RESUME:
- break;
+ case AO_CTRL_PLAY_RESUME:
+ this->paused = 0;
+ break;
- case AO_CTRL_FLUSH_BUFFERS:
-// fprintf(stderr, "ao_jack_ctrl(AO_CTRL_FLUSH_BUFFERS)\n");
- this->buf_write = this->buf_read = 0;
- break;
- }
+ case AO_CTRL_FLUSH_BUFFERS:
+ jack_reset (this);
+ break;
+ }
- return 0;
+ return 0;
}
+static void jack_speaker_arrangement_cb (void *user_data,
+ xine_cfg_entry_t *entry);
+
static ao_driver_t *open_jack_plugin (audio_driver_class_t *class_gen,
const void *data)
{
- jack_class_t *class = (jack_class_t *) class_gen;
- jack_driver_t *this;
- jack_client_t *client;
- uint32_t rate;
- const char **port_names;
- int i;
-
- if ((client = jack_client_new("xine")) == 0) {
-
- char name[20];
- sprintf(name, "xine (%d)", (int)getpid());
-
- if ((client = jack_client_new(name)) == 0) {
- fprintf(stderr, "\nopen_jack_plugin: Error: Failed to connect to JACK server\n");
- fprintf(stderr, "open_jack_plugin: (did you start 'jackd' server?)\n");
- return 0;
- }
- }
-
- this = (jack_driver_t *) xine_xmalloc (sizeof (jack_driver_t));
-
- this->client = client;
-
- jack_set_process_callback(client, jack_process, this);
- jack_on_shutdown(client, jack_shutdown, this);
-
- rate = jack_get_sample_rate(client);
- fprintf(stderr, "open_jack_plugin: JACK sample rate is %u\n", rate);
-
- // We support up to 2-channel output
-
- for (i = 0; i < 2; ++i) {
- jack_port_t *port = jack_port_register
- (client, (i ? "out_r" : "out_l"),
- JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
- if (!port) {
- fprintf(stderr, "ao_jack_open: failed to register port %u\n", i);
- }
- if (i) this->port_2 = port;
- else this->port_1 = port;
- }
-
- this->buf_read = this->buf_write = 0;
- this->volume = 100;
- this->mute = 0;
-
- if (jack_activate(client)) {
- fprintf(stderr, "ao_jack_open: failed to activate JACK client\n");
- return 0;
- }
-
- if ((port_names = jack_get_ports(client, NULL, NULL,
- JackPortIsPhysical | JackPortIsInput)) != NULL) {
- if (port_names[0]) {
- jack_connect(client, jack_port_name(this->port_1), port_names[0]);
- }
- if (port_names[1] && this->port_2) {
- jack_connect(client, jack_port_name(this->port_2), port_names[1]);
- }
- free(port_names);
+ jack_class_t *class = (jack_class_t *) class_gen;
+ config_values_t *config = class->config;
+ jack_driver_t *this;
+
+ jack_client_t *client;
+ uint32_t rate;
+ char *jack_device;
+ const char **matching_ports = NULL;
+ const char **port_names;
+
+ /* for usability reasons, keep this in sync with audio_oss_out.c */
+ static char *speaker_arrangement[] = {
+ "Mono 1.0", "Stereo 2.0", "Headphones 2.0", "Stereo 2.1",
+ "Surround 3.0", "Surround 4.0", "Surround 4.1", "Surround 5.0",
+ "Surround 5.1", "Surround 6.0",
+ "Surround 6.1", "Surround 7.1", "Pass Through", NULL
+ };
+#define MONO 0
+#define STEREO 1
+#define HEADPHONES 2
+#define SURROUND21 3
+#define SURROUND3 4
+#define SURROUND4 5
+#define SURROUND41 6
+#define SURROUND5 7
+#define SURROUND51 8
+#define SURROUND6 9
+#define SURROUND61 10
+#define SURROUND71 11
+#define A52_PASSTHRU 12
+ int speakers;
+
+ /* Try to create a client called "xine" */
+ if ((client = jack_client_new ("xine")) == 0) {
+ /* If that doesn't work it could be because running two copies of xine - try using a unique name */
+ char name[20];
+ sprintf (name, "xine (%d)", (int) getpid ());
+
+ if ((client = jack_client_new (name)) == 0) {
+ xprintf (class->xine, XINE_VERBOSITY_LOG,
+ "\nopen_jack_plugin: Error: Failed to connect to JACK server\n");
+ xprintf (class->xine, XINE_VERBOSITY_LOG,
+ "open_jack_plugin: (did you start 'jackd' server?)\n");
+ return 0;
}
+ }
+
+ this = calloc(1, sizeof (jack_driver_t));
+
+ rate = jack_get_sample_rate (client);
+ xprintf (class->xine, XINE_VERBOSITY_DEBUG,
+ "open_jack_plugin: JACK sample rate is %u\n", rate);
+
+ /* devname_val is offset used to select auto, /dev/dsp, or /dev/sound/dsp */
+ jack_device = config->register_string (config,
+ "audio.device.jack_device_name",
+ "",
+ _("JACK audio device name"),
+ _("Specifies the jack audio device name, "
+ "leave blank for the default physical output port."),
+ 10, NULL, NULL);
+
+ this->capabilities = 0;
+
+
+ /* for usability reasons, keep this in sync with audio_alsa_out.c */
+ speakers =
+ config->register_enum (config, "audio.output.speaker_arrangement",
+ STEREO, speaker_arrangement,
+ _("speaker arrangement"),
+ _("Select how your speakers are arranged, "
+ "this determines which speakers xine uses for sound output. "
+ "The individual values are:\n\n"
+ "Mono 1.0: You have only one speaker.\n"
+ "Stereo 2.0: You have two speakers for left and right channel.\n"
+ "Headphones 2.0: You use headphones.\n"
+ "Stereo 2.1: You have two speakers for left and right channel, and one "
+ "subwoofer for the low frequencies.\n"
+ "Surround 3.0: You have three speakers for left, right and rear channel.\n"
+ "Surround 4.0: You have four speakers for front left and right and rear "
+ "left and right channels.\n"
+ "Surround 4.1: You have four speakers for front left and right and rear "
+ "left and right channels, and one subwoofer for the low frequencies.\n"
+ "Surround 5.0: You have five speakers for front left, center and right and "
+ "rear left and right channels.\n"
+ "Surround 5.1: You have five speakers for front left, center and right and "
+ "rear left and right channels, and one subwoofer for the low frequencies.\n"
+ "Surround 6.0: You have six speakers for front left, center and right and "
+ "rear left, center and right channels.\n"
+ "Surround 6.1: You have six speakers for front left, center and right and "
+ "rear left, center and right channels, and one subwoofer for the low frequencies.\n"
+ "Surround 7.1: You have seven speakers for front left, center and right, "
+ "left and right and rear left and right channels, and one subwoofer for the "
+ "low frequencies.\n"
+ "Pass Through: Your sound system will receive undecoded digital sound from xine. "
+ "You need to connect a digital surround decoder capable of decoding the "
+ "formats you want to play to your sound card's digital output."),
+ 0, jack_speaker_arrangement_cb, this);
+
+ int port_flags = JackPortIsInput;
+ int num_ports;
+ /* list matching ports */
+ if (!jack_device)
+ port_flags |= JackPortIsPhysical;
+ /* Find all the ports matching either the desired device regexp or physical output ports */
+ matching_ports = jack_get_ports (client, jack_device, NULL, port_flags);
+ /* Count 'em */
+ for (num_ports = 0; matching_ports && matching_ports[num_ports];
+ num_ports++)
+ /**/;
+ if (!num_ports) {
+ xprintf (this->xine, XINE_VERBOSITY_LOG,
+ "open_jack_plugin: no physical ports available\n");
+ goto err_out;
+ }
+
+
+/* TODO: We deliberately don't offer mono, let Xine upsample instead? */
+/* if (num_ports >= 1) { */
+/* this->capabilities |= AO_CAP_MODE_MONO; */
+/* xprintf(class->xine, XINE_VERBOSITY_DEBUG, "mono "); */
+/* } */
+
+ if (num_ports >= 2) {
+ this->capabilities |= AO_CAP_MODE_STEREO;
+ xprintf (class->xine, XINE_VERBOSITY_DEBUG, "stereo ");
+ }
+
+ if (num_ports >= 4) {
+ if (speakers == SURROUND4) {
+ this->capabilities |= AO_CAP_MODE_4CHANNEL;
+ xprintf (class->xine, XINE_VERBOSITY_DEBUG, "4-channel ");
+ } else
+ xprintf (class->xine, XINE_VERBOSITY_DEBUG,
+ "(4-channel not enabled in xine config) ");
+ }
+
+ if (num_ports >= 5) {
+ if (speakers == SURROUND5) {
+ this->capabilities |= AO_CAP_MODE_5CHANNEL;
+ xprintf (class->xine, XINE_VERBOSITY_DEBUG, "5-channel ");
+ } else
+ xprintf (class->xine, XINE_VERBOSITY_DEBUG,
+ "(5-channel not enabled in xine config) ");
+ }
+
+ if (num_ports >= 6) {
+ if (speakers == SURROUND51) {
+ this->capabilities |= AO_CAP_MODE_5_1CHANNEL;
+ xprintf (class->xine, XINE_VERBOSITY_DEBUG, "5.1-channel ");
+ } else
+ xprintf (class->xine, XINE_VERBOSITY_DEBUG,
+ "(5.1-channel not enabled in xine config) ");
+ }
+
+ this->buffer = (unsigned char *) malloc (BUFFSIZE);
+ jack_reset (this);
+
+ this->capabilities |= AO_CAP_MIXER_VOL;
+ this->capabilities |= AO_CAP_MUTE_VOL;
+ /* TODO: Currently not respected by Xine, perhaps v1.2? */
+ this->capabilities |= AO_CAP_FLOAT32;
+
+
+ this->mixer.mute = 0;
+ this->mixer.volume = 100;
+
+ this->output_sample_rate = jack_get_sample_rate (client);
+ this->fragment_size = jack_get_buffer_size (client);
+
+ /* Close our JACK client */
+ jack_client_close (client);
+
+ this->xine = class->xine;
+
+ this->ao_driver.get_capabilities = ao_jack_get_capabilities;
+ this->ao_driver.get_property = ao_jack_get_property;
+ this->ao_driver.set_property = ao_jack_set_property;
+ this->ao_driver.open = ao_jack_open;
+ this->ao_driver.num_channels = ao_jack_num_channels;
+ this->ao_driver.bytes_per_frame = ao_jack_bytes_per_frame;
+ this->ao_driver.delay = ao_jack_delay;
+ this->ao_driver.write = ao_jack_write;
+ this->ao_driver.close = ao_jack_close;
+ this->ao_driver.exit = ao_jack_exit;
+ this->ao_driver.get_gap_tolerance = ao_jack_get_gap_tolerance;
+ this->ao_driver.control = ao_jack_ctrl;
+
+ return &this->ao_driver;
+
+err_out:
+ free (matching_ports);
+ if (client)
+ jack_client_close (client);
+ return 0;
+}
- this->sample_rate = rate;
-
- this->xine = class->xine;
- this->capabilities = AO_CAP_FLOAT32 | AO_CAP_MODE_MONO |
- AO_CAP_MODE_STEREO | AO_CAP_MIXER_VOL | AO_CAP_MUTE_VOL;
-
- this->ao_driver.get_capabilities = ao_jack_get_capabilities;
- this->ao_driver.get_property = ao_jack_get_property;
- this->ao_driver.set_property = ao_jack_set_property;
- this->ao_driver.open = ao_jack_open;
- this->ao_driver.num_channels = ao_jack_num_channels;
- this->ao_driver.bytes_per_frame = ao_jack_bytes_per_frame;
- this->ao_driver.delay = ao_jack_delay;
- this->ao_driver.write = ao_jack_write;
- this->ao_driver.close = ao_jack_close;
- this->ao_driver.exit = ao_jack_exit;
- this->ao_driver.get_gap_tolerance = ao_jack_get_gap_tolerance;
- this->ao_driver.control = ao_jack_ctrl;
-
- fprintf(stderr, "jack open_jack_plugin returning %p\n", (void *)(&this->ao_driver));
- return &this->ao_driver;
+static void jack_speaker_arrangement_cb (void *user_data,
+ xine_cfg_entry_t *entry)
+{
+ jack_driver_t *this = (jack_driver_t *) user_data;
+ int32_t value = entry->num_value;
+ if (value == SURROUND4) {
+ this->capabilities |= AO_CAP_MODE_4CHANNEL;
+ } else {
+ this->capabilities &= ~AO_CAP_MODE_4CHANNEL;
+ }
+ if (value == SURROUND41) {
+ this->capabilities |= AO_CAP_MODE_4_1CHANNEL;
+ } else {
+ this->capabilities &= ~AO_CAP_MODE_4_1CHANNEL;
+ }
+ if (value == SURROUND5) {
+ this->capabilities |= AO_CAP_MODE_5CHANNEL;
+ } else {
+ this->capabilities &= ~AO_CAP_MODE_5CHANNEL;
+ }
+ if (value >= SURROUND51) {
+ this->capabilities |= AO_CAP_MODE_5_1CHANNEL;
+ } else {
+ this->capabilities &= ~AO_CAP_MODE_5_1CHANNEL;
+ }
}
/*
* class functions
*/
-static char* get_identifier (audio_driver_class_t *this_gen) {
- return "jack";
+static char *get_identifier (audio_driver_class_t *this_gen)
+{
+ return "jack";
}
-static char* get_description (audio_driver_class_t *this_gen) {
- return _("xine output plugin for JACK Audio Connection Kit");
+static char *get_description (audio_driver_class_t *this_gen)
+{
+ return _("xine output plugin for JACK Audio Connection Kit");
}
-static void dispose_class (audio_driver_class_t *this_gen) {
-
- jack_class_t *this = (jack_class_t *) this_gen;
- free (this);
+static void dispose_class (audio_driver_class_t *this_gen)
+{
+ jack_class_t *this = (jack_class_t *) this_gen;
+ free (this);
}
-static void *init_class (xine_t *xine, void *data) {
-
- jack_class_t *this;
-
- this = (jack_class_t *) xine_xmalloc (sizeof (jack_class_t));
+static void *init_class (xine_t *xine, void *data)
+{
+ jack_class_t *this;
- this->driver_class.open_plugin = open_jack_plugin;
- this->driver_class.get_identifier = get_identifier;
- this->driver_class.get_description = get_description;
- this->driver_class.dispose = dispose_class;
+ this = calloc(1, sizeof (jack_class_t));
- this->config = xine->config;
- this->xine = xine;
+ this->driver_class.open_plugin = open_jack_plugin;
+ this->driver_class.get_identifier = get_identifier;
+ this->driver_class.get_description = get_description;
+ this->driver_class.dispose = dispose_class;
- fprintf(stderr, "jack init_class returning %p\n", (void *)this);
+ this->config = xine->config;
+ this->xine = xine;
- return this;
+ return this;
}
-static ao_info_t ao_info_jack = {
- 6
-};
+static ao_info_t ao_info_jack = { 6 };
/*
* exported plugin catalog entry
*/
const plugin_info_t xine_plugin_info[] EXPORTED = {
- /* type, API, "name", version, special_info, init_function */
- { PLUGIN_AUDIO_OUT, AO_OUT_JACK_IFACE_VERSION, "jack", XINE_VERSION_CODE /* XINE_VERSION_CODE */, &ao_info_jack, init_class },
- { PLUGIN_NONE, 0, "", 0, NULL, NULL }
+ /* type, API, "name", version, special_info, init_function */
+ { PLUGIN_AUDIO_OUT, AO_OUT_JACK_IFACE_VERSION, "jack", XINE_VERSION_CODE,
+ &ao_info_jack, init_class },
+ { PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
-
diff --git a/src/audio_out/audio_none_out.c b/src/audio_out/audio_none_out.c
index a815d645a..9ba9a00ca 100644
--- a/src/audio_out/audio_none_out.c
+++ b/src/audio_out/audio_none_out.c
@@ -186,7 +186,7 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen,
lprintf ("open_plugin called\n");
- this = (none_driver_t *) xine_xmalloc (sizeof (none_driver_t));
+ this = calloc(1, sizeof (none_driver_t));
if (!this)
return NULL;
@@ -236,7 +236,7 @@ static void *init_class (xine_t *xine, void *data) {
lprintf ("init class\n");
- this = (none_class_t *) xine_xmalloc (sizeof (none_class_t));
+ this = calloc(1, sizeof (none_class_t));
if (!this)
return NULL;
diff --git a/src/audio_out/audio_oss_out.c b/src/audio_out/audio_oss_out.c
index a6e0fe494..ba1044ed4 100644
--- a/src/audio_out/audio_oss_out.c
+++ b/src/audio_out/audio_oss_out.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2003 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -405,6 +405,18 @@ static int ao_oss_delay(ao_driver_t *this_gen) {
if (bytes_left<=0) /* buffer ran dry */
bytes_left = 0;
break;
+ case OSS_SYNC_GETODELAY:
+#ifdef SNDCTL_DSP_GETODELAY
+ if (ioctl (this->audio_fd, SNDCTL_DSP_GETODELAY, &bytes_left)) {
+ perror ("audio_oss_out: DSP_GETODELAY ioctl():");
+ }
+ if (bytes_left<0)
+ bytes_left = 0;
+
+ lprintf ("%d bytes left\n", bytes_left);
+
+ break;
+#endif
case OSS_SYNC_GETOPTR:
if (ioctl (this->audio_fd, SNDCTL_DSP_GETOPTR, &info)) {
perror ("audio_oss_out: SNDCTL_DSP_GETOPTR failed:");
@@ -424,16 +436,6 @@ static int ao_oss_delay(ao_driver_t *this_gen) {
}
this->last_getoptr = info.bytes;
break;
- case OSS_SYNC_GETODELAY:
- if (ioctl (this->audio_fd, SNDCTL_DSP_GETODELAY, &bytes_left)) {
- perror ("audio_oss_out: DSP_GETODELAY ioctl():");
- }
- if (bytes_left<0)
- bytes_left = 0;
-
- lprintf ("%d bytes left\n", bytes_left);
-
- break;
}
return bytes_left / this->bytes_per_frame;
@@ -727,7 +729,7 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da
int speakers;
- this = (oss_driver_t *) xine_xmalloc (sizeof (oss_driver_t));
+ this = calloc(1, sizeof (oss_driver_t));
if (!this)
return NULL;
@@ -840,10 +842,13 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da
* check if SNDCTL_DSP_GETODELAY works. if so, using it is preferred.
*/
+#ifdef SNDCTL_DSP_GETODELAY
if (ioctl(audio_fd, SNDCTL_DSP_GETODELAY, &info) != -1) {
xprintf(class->xine, XINE_VERBOSITY_DEBUG, "audio_oss_out: using SNDCTL_DSP_GETODELAY\n");
this->sync_method = OSS_SYNC_GETODELAY;
- } else if (ioctl(audio_fd, SNDCTL_DSP_GETOPTR, &info) != -1) {
+ } else
+#endif
+ if (ioctl(audio_fd, SNDCTL_DSP_GETOPTR, &info) != -1) {
xprintf(class->xine, XINE_VERBOSITY_DEBUG, "audio_oss_out: using SNDCTL_DSP_GETOPTR\n");
this->sync_method = OSS_SYNC_GETOPTR;
} else {
@@ -872,15 +877,10 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da
if (this->sync_method == OSS_SYNC_PROBEBUFFER) {
char *buf;
int c;
-
- xprintf(class->xine, XINE_VERBOSITY_LOG,
- _("audio_oss_out: Audio driver realtime sync disabled...\n"
- "audio_oss_out: ...probing output buffer size: "));
+
this->buffer_size = 0;
- if( (buf=malloc(1024)) != NULL ) {
- memset(buf,0,1024);
-
+ if( (buf=calloc(1, 1024)) != NULL ) {
do {
c = write(audio_fd,buf,1024);
if( c != -1 )
@@ -891,7 +891,8 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da
}
close(audio_fd);
xprintf(class->xine, XINE_VERBOSITY_LOG,
- _("%d bytes\naudio_oss_out: ...there may be audio/video synchronization issues\n"), this->buffer_size);
+ _("audio_oss_out: Audio driver realtime sync disabled...\n"
+ "audio_oss_out: ...probing output buffer size: %d bytes\naudio_oss_out: ...there may be audio/video synchronization issues\n"), this->buffer_size);
audio_fd=open(this->audio_dev, O_WRONLY|O_NONBLOCK);
@@ -954,48 +955,48 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da
0, oss_speaker_arrangement_cb, this);
- xprintf(class->xine, XINE_VERBOSITY_DEBUG, "audio_oss_out: supported modes are ");
+ char *logmsg = strdup (_("audio_oss_out: supported modes are"));
num_channels = 1;
status = ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &num_channels);
if ( (status != -1) && (num_channels==1) ) {
this->capabilities |= AO_CAP_MODE_MONO;
- xprintf(class->xine, XINE_VERBOSITY_DEBUG, "mono ");
+ xine_strcat_realloc (&logmsg, _(" mono"));
}
num_channels = 2;
status = ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &num_channels);
if ( (status != -1) && (num_channels==2) ) {
this->capabilities |= AO_CAP_MODE_STEREO;
- xprintf(class->xine, XINE_VERBOSITY_DEBUG, "stereo ");
+ xine_strcat_realloc (&logmsg, _(" stereo"));
}
num_channels = 4;
status = ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &num_channels);
if ( (status != -1) && (num_channels==4) ) {
if ( speakers == SURROUND4 ) {
this->capabilities |= AO_CAP_MODE_4CHANNEL;
- xprintf(class->xine, XINE_VERBOSITY_DEBUG, "4-channel ");
+ xine_strcat_realloc (&logmsg, _(" 4-channel"));
}
else
- xprintf(class->xine, XINE_VERBOSITY_DEBUG, "(4-channel not enabled in xine config) " );
+ xine_strcat_realloc (&logmsg, _(" (4-channel not enabled in xine config)"));
}
num_channels = 5;
status = ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &num_channels);
if ( (status != -1) && (num_channels==5) ) {
if ( speakers == SURROUND5 ) {
this->capabilities |= AO_CAP_MODE_5CHANNEL;
- xprintf(class->xine, XINE_VERBOSITY_DEBUG, "5-channel ");
+ xine_strcat_realloc (&logmsg, _(" 5-channel"));
}
else
- xprintf(class->xine, XINE_VERBOSITY_DEBUG, "(5-channel not enabled in xine config) " );
+ xine_strcat_realloc (&logmsg, _(" (5-channel not enabled in xine config)"));
}
num_channels = 6;
status = ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &num_channels);
if ( (status != -1) && (num_channels==6) ) {
if ( speakers == SURROUND51 ) {
this->capabilities |= AO_CAP_MODE_5_1CHANNEL;
- xprintf(class->xine, XINE_VERBOSITY_DEBUG, "5.1-channel ");
+ xine_strcat_realloc (&logmsg, _(" 5.1-channel"));
}
else
- xprintf(class->xine, XINE_VERBOSITY_DEBUG, "(5.1-channel not enabled in xine config) " );
+ xine_strcat_realloc (&logmsg, _(" (5.1-channel not enabled in xine config)"));
}
ioctl(audio_fd,SNDCTL_DSP_GETFMTS,&caps);
@@ -1005,10 +1006,13 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da
if ( speakers == A52_PASSTHRU ) {
this->capabilities |= AO_CAP_MODE_A52;
this->capabilities |= AO_CAP_MODE_AC5;
- xprintf(class->xine, XINE_VERBOSITY_DEBUG, "a/52-pass-through ");
+ xine_strcat_realloc (&logmsg, _(" a/52 pass-through"));
}
else
- xprintf(class->xine, XINE_VERBOSITY_DEBUG, "(a/52-pass-through not enabled in xine config)");
+ xine_strcat_realloc (&logmsg, _(" (a/52 pass-through not enabled in xine config)"));
+
+ xprintf(class->xine, XINE_VERBOSITY_DEBUG, "%s\n", logmsg);
+ free (logmsg);
/*
* mixer initialisation.
@@ -1035,20 +1039,17 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da
if ((parse = strstr(mixer_name, "dsp"))) {
parse[0] = '\0';
parse += 3;
- this->mixer.name = (char *)malloc(strlen(mixer_name) + sizeof("mixer") + 2);
if (devname_val == 0)
- sprintf(this->mixer.name, "%smixer%s", mixer_name, parse);
+ asprintf(&(this->mixer.name), "%smixer%s", mixer_name, parse);
else {
if (mixer_num == -1)
- sprintf(this->mixer.name, "%smixer", mixer_name);
+ asprintf(&(this->mixer.name), "%smixer", mixer_name);
else
- sprintf(this->mixer.name, "%smixer%d", mixer_name, mixer_num);
+ asprintf(&(this->mixer.name), "%smixer%d", mixer_name, mixer_num);
}
} else {
- this->mixer.name = (char *)malloc(1);
- this->mixer.name[0] = '\0';
+ _x_abort();
}
- _x_assert(this->mixer.name[0] != '\0');
this->mixer.fd = open(this->mixer.name, O_RDONLY);
@@ -1165,7 +1166,7 @@ static void *init_class (xine_t *xine, void *data) {
oss_class_t *this;
- this = (oss_class_t *) xine_xmalloc (sizeof (oss_class_t));
+ this = calloc(1, sizeof (oss_class_t));
if (!this)
return NULL;
diff --git a/src/audio_out/audio_pulse_out.c b/src/audio_out/audio_pulse_out.c
index 26d121bf6..4b66fbaed 100644
--- a/src/audio_out/audio_pulse_out.c
+++ b/src/audio_out/audio_pulse_out.c
@@ -1,28 +1,28 @@
-/*
- * Copyright (C) 2000-2007 the xine project
- *
+/* -*- Mode: C; c-basic-offset: 2; indent-tabs-mode: nil -*- */
+
+/*
+ * Copyright (C) 2000-2008 the xine project
+ *
* This file is part of xine, a free video player.
- *
+ *
* xine is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* xine is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
- * ao plugin for pulseaudio (rename of polypaudio):
+ * ao plugin for PulseAudio:
* http://0pointer.de/lennart/projects/pulsaudio/
*
- * originally written for polypaudio simple api. Lennart then suggested
- * using the async api for better control (such as volume), therefore, a lot
- * of this code comes from Lennart's patch to mplayer.
+ * Diego Petteno, Lennart Poettering
*/
#ifdef HAVE_CONFIG_H
@@ -48,15 +48,9 @@
#define GAP_TOLERANCE AO_MAX_GAP
-/* CHECKME: should this be conditional on autotools? */
-extern const char *__progname;
-
typedef struct {
audio_driver_class_t driver_class;
xine_t *xine;
-
- struct pa_context *context; /*< Pulseaudio connection context */
- struct pa_threaded_mainloop *mainloop; /*< Main event loop object */
} pulse_class_t;
typedef struct pulse_driver_s {
@@ -67,11 +61,13 @@ typedef struct pulse_driver_s {
char *host; /*< The host to connect to */
char *sink; /*< The sink to connect to */
- struct pa_stream *stream; /*< Pulseaudio playback stream object */
- pthread_mutex_t info_mutex; /**< Mutex for info callback signaling */
+ pa_threaded_mainloop *mainloop; /*< Main event loop object */
+ pa_context *context; /*< Pulseaudio connection context */
+ pa_stream *stream; /*< Pulseaudio playback stream object */
pa_volume_t swvolume;
+ int muted;
pa_cvolume cvolume;
int capabilities;
@@ -82,67 +78,117 @@ typedef struct pulse_driver_s {
uint32_t bits_per_sample;
uint32_t bytes_per_frame;
- uint32_t frames_written;
-
} pulse_driver_t;
/**
- * @brief Callback function called when a stream operation succeed
- * @param stream Stream which operation has succeeded
- * @param success The success value for the operation (ignored)
- * @param this_Gen pulse_driver_t pointer for the PulseAudio output
- * instance.
+ * @brief Callback function called when the state of the context is changed
+ * @param c Context which changed status
+ * @param this_gen pulse_class_t pointer for the PulseAudio output class
*/
-static void __xine_pa_stream_success_callback(pa_stream *const stream, const int success,
- void *const mutex_gen)
+static void __xine_pa_context_state_callback(pa_context *c, void *this_gen)
{
- pthread_mutex_t *const completion_mutex = (pthread_mutex_t*)mutex_gen;
+ pulse_driver_t * this = (pulse_driver_t*) this_gen;
+
+ switch (pa_context_get_state(c)) {
- pthread_mutex_unlock(completion_mutex);
+ case PA_CONTEXT_READY:
+ case PA_CONTEXT_TERMINATED:
+ case PA_CONTEXT_FAILED:
+ pa_threaded_mainloop_signal(this->mainloop, 0);
+ break;
+
+ case PA_CONTEXT_CONNECTING:
+ case PA_CONTEXT_UNCONNECTED:
+ case PA_CONTEXT_AUTHORIZING:
+ case PA_CONTEXT_SETTING_NAME:
+ break;
+ }
}
/**
- * @brief Callback function called when the state of the context is changed
- * @param ctx Context which operation has succeeded
+ * @brief Callback function called when the state of the stream is changed
+ * @param s Stream that changed status
* @param this_gen pulse_driver_t pointer for the PulseAudio output
* instance.
*/
-static void __xine_pa_context_status_callback(pa_context *const ctx, void *const this_gen)
+static void __xine_pa_stream_state_callback(pa_stream *s, void *this_gen)
{
- pulse_driver_t *const this = (pulse_driver_t*)this_gen;
-
- switch (pa_context_get_state(ctx)) {
- case PA_CONTEXT_READY:
- case PA_CONTEXT_TERMINATED:
- case PA_CONTEXT_FAILED:
- pa_threaded_mainloop_signal(this->pa_class->mainloop, 0);
- break;
-
- case PA_CONTEXT_CONNECTING:
- case PA_CONTEXT_UNCONNECTED:
- case PA_CONTEXT_AUTHORIZING:
- case PA_CONTEXT_SETTING_NAME:
- break;
+ pulse_driver_t * this = (pulse_driver_t*) this_gen;
+
+ switch (pa_stream_get_state(s)) {
+
+ case PA_STREAM_READY:
+ case PA_STREAM_TERMINATED:
+ case PA_STREAM_FAILED:
+ pa_threaded_mainloop_signal(this->mainloop, 0);
+ break;
+
+ case PA_STREAM_UNCONNECTED:
+ case PA_STREAM_CREATING:
+ break;
}
}
/**
- * @brief Callback function called when a context operation succeed
+ * @brief Callback function called when PA asks for more audio data.
+ * @param s Stream on which data is requested
+ * @param nbytes the number of bytes PA requested
+ * @param this_gen pulse_driver_t pointer for the PulseAudio output
+ * instance.
+ */
+static void __xine_pa_stream_request_callback(pa_stream *s, size_t nbytes, void *this_gen)
+{
+ pulse_driver_t * this = (pulse_driver_t*) this_gen;
+
+ pa_threaded_mainloop_signal(this->mainloop, 0);
+}
+
+/**
+ * @brief Callback function called when PA notifies about something
+ * @param s Stream on which the notification happened
+ * @param this_gen pulse_driver_t pointer for the PulseAudio output
+ * instance.
+ */
+static void __xine_pa_stream_notify_callback(pa_stream *s, void *this_gen)
+{
+ pulse_driver_t * this = (pulse_driver_t*) this_gen;
+
+ pa_threaded_mainloop_signal(this->mainloop, 0);
+}
+
+/**
+ * @brief Callback function called when PA completed an operation
* @param ctx Context which operation has succeeded
- * @param success The success value for the operation (ignored)
+ * @param nbytes the number of bytes PA requested
+ * @param this_gen pulse_driver_t pointer for the PulseAudio output
+ * instance.
+ */
+static void __xine_pa_stream_success_callback(pa_stream *s, int success, void *this_gen)
+{
+ pulse_driver_t * this = (pulse_driver_t*) this_gen;
+
+ if (!success)
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: stream operation failed: %s\n", pa_strerror(pa_context_errno(this->context)));
+
+ pa_threaded_mainloop_signal(this->mainloop, 0);
+}
+
+/**
+ * @brief Callback function called when PA completed an operation
+ * @param c Context on which operation has succeeded
+ * @param nbytes the number of bytes PA requested
* @param this_gen pulse_driver_t pointer for the PulseAudio output
* instance.
*/
-static void __xine_pa_context_success_callback(pa_context *const ctx, const int success,
- void *const this_gen)
+static void __xine_pa_context_success_callback(pa_context *c, int success, void *this_gen)
{
- pulse_driver_t *const this = (pulse_driver_t*)this_gen;
+ pulse_driver_t *this = (pulse_driver_t*) this_gen;
- _x_assert(ctx); _x_assert(this);
- _x_assert(ctx == this->pa_class->context);
+ if (!success)
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: context operation failed: %s\n", pa_strerror(pa_context_errno(this->context)));
- pa_threaded_mainloop_signal(this->pa_class->mainloop, 0);
+ pa_threaded_mainloop_signal(this->mainloop, 0);
}
/**
@@ -156,14 +202,14 @@ static void __xine_pa_context_success_callback(pa_context *const ctx, const int
* This function saves the volume field of the passed structure to the
* @c cvolume variable of the output instance.
*/
-static void __xine_pa_sink_info_callback(pa_context *const ctx, const pa_sink_input_info *const info,
- const int is_last, void *const userdata) {
+static void __xine_pa_sink_info_callback(pa_context *c, const pa_sink_input_info *info,
+ int is_last, void *userdata) {
pulse_driver_t *const this = (pulse_driver_t *) userdata;
if (is_last < 0) {
xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: Failed to get sink input info: %s\n",
- pa_strerror(pa_context_errno(this->pa_class->context)));
+ pa_strerror(pa_context_errno(this->context)));
return;
}
@@ -171,36 +217,95 @@ static void __xine_pa_sink_info_callback(pa_context *const ctx, const pa_sink_in
return;
this->cvolume = info->volume;
+ this->swvolume = pa_cvolume_avg(&info->volume);
+#if PA_PROTOCOL_VERSION >= 11
+ /* PulseAudio 0.9.7 and newer */
+ this->muted = info->mute;
+#else
+ this->muted = pa_cvolume_is_muted (&this->cvolume);
+#endif
+}
+
+static int connect_context(pulse_driver_t *this) {
+
+ if (this->context && (pa_context_get_state(this->context) == PA_CONTEXT_FAILED ||
+ pa_context_get_state(this->context) == PA_CONTEXT_TERMINATED)) {
+ pa_context_unref(this->context);
+ this->context = NULL;
+ }
+
+ if (!this->context) {
+ char fn[PATH_MAX], *p;
+
+ if (pa_get_binary_name(fn, sizeof(fn)))
+ p = pa_path_get_filename(fn);
+ else
+ p = "Xine";
- pthread_mutex_unlock(&this->info_mutex);
+ this->context = pa_context_new(pa_threaded_mainloop_get_api(this->mainloop), p);
+ _x_assert(this->context);
+
+ pa_context_set_state_callback(this->context, __xine_pa_context_state_callback, this);
+ }
+
+ if (pa_context_get_state(this->context) == PA_CONTEXT_UNCONNECTED) {
+
+ if (pa_context_connect(this->context, this->host, 0, NULL) < 0) {
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: failed to connect context object %s\n", pa_strerror(pa_context_errno(this->context)));
+ return -1;
+ }
+ }
+
+ for (;;) {
+ pa_context_state_t state = pa_context_get_state(this->context);
+
+ if (state == PA_CONTEXT_FAILED || state == PA_CONTEXT_TERMINATED) {
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: failed to connect context object: %s\n", pa_strerror(pa_context_errno(this->context)));
+ return -1;
+ }
+
+ if (state == PA_CONTEXT_READY)
+ break;
+
+ pa_threaded_mainloop_wait(this->mainloop);
+ }
+
+ return 0;
}
/*
* open the audio device for writing to
*/
static int ao_pulse_open(ao_driver_t *this_gen,
- uint32_t bits, uint32_t rate, int mode)
+ uint32_t bits, uint32_t rate, int mode)
{
pulse_driver_t *this = (pulse_driver_t *) this_gen;
- struct pa_sample_spec ss;
- struct pa_buffer_attr a;
- pa_stream_state_t streamstate;
+ pa_sample_spec ss;
+ pa_channel_map cm;
+ int r;
xprintf (this->xine, XINE_VERBOSITY_DEBUG,
- "audio_pulse_out: ao_open bits=%d rate=%d, mode=%d\n", bits, rate, mode);
+ "audio_pulse_out: ao_open bits=%d rate=%d, mode=%d\n", bits, rate, mode);
if ( (mode & this->capabilities) == 0 ) {
xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: unsupported mode %08x\n", mode);
return 0;
}
+ pa_threaded_mainloop_lock(this->mainloop);
+
if (this->stream) {
- if ( mode == this->mode && rate == this->sample_rate &&
- bits == this->bits_per_sample )
+ if (mode == this->mode && rate == this->sample_rate &&
+ bits == this->bits_per_sample) {
+
+ pa_threaded_mainloop_unlock(this->mainloop);
return this->sample_rate;
+ }
- this_gen->close(this_gen);
+ pa_stream_disconnect(this->stream);
+ pa_stream_unref(this->stream);
+ this->stream = NULL;
}
this->mode = mode;
@@ -221,6 +326,8 @@ static int ao_pulse_open(ao_driver_t *this_gen,
case 32:
ss.format = PA_SAMPLE_FLOAT32NE;
break;
+ default:
+ _x_assert(!"Should not be reached");
}
if (!pa_sample_spec_valid(&ss)) {
@@ -228,69 +335,86 @@ static int ao_pulse_open(ao_driver_t *this_gen,
goto fail;
}
- if ( this->pa_class->context && pa_context_get_state(this->pa_class->context) > PA_CONTEXT_READY ) {
- pa_context_unref(this->pa_class->context);
- this->pa_class->context = NULL;
- }
-
- if ( this->pa_class->context == NULL ) {
- this->pa_class->context = pa_context_new(pa_threaded_mainloop_get_api(this->pa_class->mainloop),
- __progname);
- }
-
- pa_context_ref(this->pa_class->context);
+ cm.channels = ss.channels;
- if ( pa_context_get_state(this->pa_class->context) == PA_CONTEXT_UNCONNECTED ) {
- int ret;
+ switch (mode) {
+ case AO_CAP_MODE_MONO:
+ cm.map[0] = PA_CHANNEL_POSITION_MONO;
+ _x_assert(cm.channels == 1);
+ break;
- pa_threaded_mainloop_lock(this->pa_class->mainloop);
- ret = pa_context_connect(this->pa_class->context, this->host, 1, NULL);
- if ( ret < 0 )
- goto fail;
+ case AO_CAP_MODE_STEREO:
+ cm.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
+ cm.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
+ _x_assert(cm.channels == 2);
+ break;
- pa_context_set_state_callback(this->pa_class->context, __xine_pa_context_status_callback, this);
+ case AO_CAP_MODE_4CHANNEL:
+ cm.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
+ cm.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
+ cm.map[2] = PA_CHANNEL_POSITION_REAR_LEFT;
+ cm.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
+ _x_assert(cm.channels == 4);
+ break;
- pa_threaded_mainloop_wait(this->pa_class->mainloop);
- pa_threaded_mainloop_unlock(this->pa_class->mainloop);
+ case AO_CAP_MODE_4_1CHANNEL:
+ case AO_CAP_MODE_5CHANNEL:
+ case AO_CAP_MODE_5_1CHANNEL:
+ cm.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
+ cm.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
+ cm.map[2] = PA_CHANNEL_POSITION_REAR_LEFT;
+ cm.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
+ cm.map[4] = PA_CHANNEL_POSITION_FRONT_CENTER;
+ cm.map[5] = PA_CHANNEL_POSITION_LFE;
+ cm.channels = 6;
+ break;
+ default:
+ _x_assert(!"Should not be reached");
}
- if (pa_context_get_state(this->pa_class->context) != PA_CONTEXT_READY) {
- xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: Failed to connect to server: %s\n",
- pa_strerror(pa_context_errno(this->pa_class->context)));
+ if (!pa_channel_map_valid(&cm)) {
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: Invalid channel map\n");
goto fail;
}
- this->stream = pa_stream_new(this->pa_class->context, "audio stream", &ss, NULL);
+ if (connect_context(this) < 0)
+ goto fail;
+
+ _x_assert(!this->stream);
+ this->stream = pa_stream_new(this->context, "Audio Stream", &ss, &cm);
_x_assert(this->stream);
- a.maxlength = pa_bytes_per_second(&ss)*1;
- a.tlength = a.maxlength*9/10;
- a.prebuf = a.tlength/2;
- a.minreq = a.tlength/10;
+ pa_stream_set_state_callback(this->stream, __xine_pa_stream_state_callback, this);
+ pa_stream_set_write_callback(this->stream, __xine_pa_stream_request_callback, this);
+ pa_stream_set_latency_update_callback(this->stream, __xine_pa_stream_notify_callback, this);
- pa_stream_connect_playback(this->stream, this->sink, &a,
- PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE,
+ r = pa_stream_connect_playback(this->stream, this->sink, NULL,
+ PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE,
NULL, NULL);
- do {
- xine_usec_sleep (100);
+ for (;;) {
+ pa_context_state_t cstate = pa_context_get_state(this->context);
+ pa_stream_state_t sstate = pa_stream_get_state(this->stream);
- streamstate = pa_stream_get_state(this->stream);
- } while (streamstate < PA_STREAM_READY);
-
- if (streamstate != PA_STREAM_READY) {
- xprintf (this->xine, XINE_VERBOSITY_LOG, "audio_pulse_out: Failed to connect to server: %s\n",
- pa_strerror(pa_context_errno(this->pa_class->context)));
- goto fail;
+ if (cstate == PA_CONTEXT_FAILED || cstate == PA_CONTEXT_TERMINATED ||
+ sstate == PA_STREAM_FAILED || sstate == PA_STREAM_TERMINATED) {
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: failed to connect context object: %s\n", pa_strerror(pa_context_errno(this->context)));
+ goto fail;
+ }
+
+ if (sstate == PA_STREAM_READY)
+ break;
+
+ pa_threaded_mainloop_wait(this->mainloop);
}
- this->frames_written = 0;
- this->ao_driver.set_property(this, AO_PROP_PCM_VOL, 100);
+ pa_threaded_mainloop_unlock(this->mainloop);
return this->sample_rate;
-fail:
- pa_threaded_mainloop_unlock(this->pa_class->mainloop);
+ fail:
+
+ pa_threaded_mainloop_unlock(this->mainloop);
this_gen->close(this_gen);
return 0;
}
@@ -318,217 +442,367 @@ static int ao_pulse_write(ao_driver_t *this_gen, int16_t *data,
{
pulse_driver_t *this = (pulse_driver_t *) this_gen;
size_t size = num_frames * this->bytes_per_frame;
- int ret = 0;
-
- if ( !this->stream || !this->pa_class->context)
- return -1;
+ int ret = -1;
+ size_t done = 0;
- switch( pa_stream_get_state(this->stream) ) {
- case PA_STREAM_READY:
- while (size > 0) {
- size_t l;
+ pa_threaded_mainloop_lock(this->mainloop);
- while (!(l = pa_stream_writable_size(this->stream))) {
- xine_usec_sleep (10000);
- }
+ while (size > 0) {
+ size_t l;
- if (l > size)
- l = size;
-
- pa_stream_write(this->stream, data, l, NULL, 0, PA_SEEK_RELATIVE);
- data = (int16_t *) ((uint8_t*) data + l);
- size -= l;
- }
+ for (;;) {
+
+ if (!this->stream ||
+ !this->context ||
+ pa_context_get_state(this->context) != PA_CONTEXT_READY ||
+ pa_stream_get_state(this->stream) != PA_STREAM_READY)
+ goto finish;
- this->frames_written += num_frames;
+ if ((l = pa_stream_writable_size(this->stream)) == (size_t) -1)
+ goto finish;
- if (pa_stream_get_state(this->stream) == PA_STREAM_READY)
- ret = 1;
+ if (l > 0)
+ break;
- break;
+ pa_threaded_mainloop_wait(this->mainloop);
+ }
+
+ if (l > size)
+ l = size;
+
+ pa_stream_write(this->stream, data, l, NULL, 0, PA_SEEK_RELATIVE);
+ data = (int16_t *) ((uint8_t*) data + l);
+ size -= l;
+ done += l;
}
+ ret = done;
+
+finish:
+
+ pa_threaded_mainloop_unlock(this->mainloop);
+
+/* fprintf(stderr, "write-out\n"); */
+
return ret;
-}
+}
static int ao_pulse_delay (ao_driver_t *this_gen)
{
pulse_driver_t *this = (pulse_driver_t *) this_gen;
- pa_usec_t latency = 0;
- unsigned int delay_frames;
+ int ret = 0;
- if ( ! this->stream ) return this->frames_written;
+/* fprintf(stderr, "delay-in\n"); */
- if (pa_stream_get_latency(this->stream, &latency, NULL) < 0) {
- pa_context_unref(this->pa_class->context);
- this->pa_class->context = NULL;
+ pa_threaded_mainloop_lock(this->mainloop);
- pa_stream_disconnect(this->stream);
- pa_stream_unref(this->stream);
- this->stream = NULL;
+ for (;;) {
+ pa_usec_t latency = 0;
- return 0;
+ if (!this->stream ||
+ !this->context ||
+ pa_context_get_state(this->context) != PA_CONTEXT_READY ||
+ pa_stream_get_state(this->stream) != PA_STREAM_READY)
+ goto finish;
+
+ if (pa_stream_get_latency(this->stream, &latency, NULL) >= 0) {
+ ret = (int) ((latency * this->sample_rate) / 1000000);
+ goto finish;
+ }
+
+ if (pa_context_errno(this->context) != PA_ERR_NODATA) {
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: failed to query latency: %s\n", pa_strerror(pa_context_errno(this->context)));
+ goto finish;
+ }
+
+ pa_threaded_mainloop_wait(this->mainloop);
}
- /* convert latency (us) to frame units. */
- delay_frames = (int)(latency * this->sample_rate / 1000000);
+finish:
+
+ pa_threaded_mainloop_unlock(this->mainloop);
- if( delay_frames > this->frames_written )
- return this->frames_written;
- else
- return delay_frames;
+ return ret;
}
static void ao_pulse_close(ao_driver_t *this_gen)
{
pulse_driver_t *this = (pulse_driver_t *) this_gen;
-
- if (this->stream) {
- if (pa_stream_get_state(this->stream) == PA_STREAM_READY) {
- pthread_mutex_t completion_callback = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&completion_callback);
- pa_stream_drain(this->stream, __xine_pa_stream_success_callback, &completion_callback);
- pthread_mutex_lock(&completion_callback);
- pthread_mutex_destroy(&completion_callback);
- }
+ pa_threaded_mainloop_lock(this->mainloop);
+ if (this->stream) {
pa_stream_disconnect(this->stream);
pa_stream_unref(this->stream);
this->stream = NULL;
-
- pa_context_unref(this->pa_class->context);
}
+
+ pa_threaded_mainloop_unlock(this->mainloop);
}
static uint32_t ao_pulse_get_capabilities (ao_driver_t *this_gen) {
pulse_driver_t *this = (pulse_driver_t *) this_gen;
+
return this->capabilities;
}
-static void ao_pulse_exit(ao_driver_t *this_gen)
-{
+static void ao_pulse_exit(ao_driver_t *this_gen) {
pulse_driver_t *this = (pulse_driver_t *) this_gen;
- free (this);
+ ao_pulse_close(this_gen);
+
+ pa_threaded_mainloop_lock(this->mainloop);
+
+ if (this->context) {
+ pa_context_disconnect(this->context);
+ pa_context_unref(this->context);
+ }
+
+ pa_threaded_mainloop_unlock(this->mainloop);
+
+ pa_threaded_mainloop_free(this->mainloop);
+
+ free(this->host);
+ free(this->sink);
+ free(this);
+}
+
+static int wait_for_operation(pulse_driver_t *this, pa_operation *o) {
+
+ for (;;) {
+
+ if (!this->stream ||
+ !this->context ||
+ pa_context_get_state(this->context) != PA_CONTEXT_READY ||
+ pa_stream_get_state(this->stream) != PA_STREAM_READY)
+ return -1;
+
+ if (pa_operation_get_state(o) != PA_OPERATION_RUNNING)
+ return 0;
+
+ pa_threaded_mainloop_wait(this->mainloop);
+ }
}
static int ao_pulse_get_property (ao_driver_t *this_gen, int property) {
pulse_driver_t *this = (pulse_driver_t *) this_gen;
int result = 0;
+ pa_operation *o = NULL;
- if ( ! this->stream || ! this->pa_class->context )
+ pa_threaded_mainloop_lock(this->mainloop);
+
+ if (!this->stream ||
+ !this->context ||
+ pa_context_get_state(this->context) != PA_CONTEXT_READY ||
+ pa_stream_get_state(this->stream) != PA_STREAM_READY) {
+ pa_threaded_mainloop_unlock(this->mainloop);
return 0;
+ }
switch(property) {
- case AO_PROP_PCM_VOL:
- case AO_PROP_MIXER_VOL:
- {
- pthread_mutex_lock(&this->info_mutex);
- pa_operation *o = pa_context_get_sink_input_info(this->pa_class->context,
- pa_stream_get_index(this->stream),
- __xine_pa_sink_info_callback, this);
- if ( ! o ) return 0;
- pthread_mutex_lock(&this->info_mutex); pthread_mutex_unlock(&this->info_mutex);
-
- result = (pa_sw_volume_to_linear(this->swvolume)*100);
- }
- break;
- case AO_PROP_MUTE_VOL:
- result = pa_cvolume_is_muted(&this->cvolume);
- break;
+ case AO_PROP_MUTE_VOL:
+ case AO_PROP_PCM_VOL:
+ case AO_PROP_MIXER_VOL:
+
+ o = pa_context_get_sink_input_info(this->context, pa_stream_get_index(this->stream),
+ __xine_pa_sink_info_callback, this);
+
+ break;
+ }
+
+ if (o) {
+ wait_for_operation(this, o);
+ pa_operation_unref(o);
+ }
+
+ switch(property) {
+
+ case AO_PROP_MUTE_VOL:
+ result = this->muted;
+ break;
+
+ case AO_PROP_PCM_VOL:
+ case AO_PROP_MIXER_VOL:
+ result = (int) (pa_sw_volume_to_linear(this->swvolume)*100);
+ break;
}
-
+
+ pa_threaded_mainloop_unlock(this->mainloop);
+
return result;
}
static int ao_pulse_set_property (ao_driver_t *this_gen, int property, int value) {
pulse_driver_t *this = (pulse_driver_t *) this_gen;
int result = ~value;
+ pa_operation *o = NULL;
- if ( ! this->stream || ! this->pa_class->context )
- return result;
+ pa_threaded_mainloop_lock(this->mainloop);
+
+ if (!this->stream ||
+ !this->context ||
+ pa_context_get_state(this->context) != PA_CONTEXT_READY ||
+ pa_stream_get_state(this->stream) != PA_STREAM_READY) {
+ pa_threaded_mainloop_unlock(this->mainloop);
+ return 0;
+ }
switch(property) {
- case AO_PROP_PCM_VOL:
- case AO_PROP_MIXER_VOL:
- this->swvolume = pa_sw_volume_from_linear((double)value/100.0);
- pa_cvolume_set(&this->cvolume, pa_stream_get_sample_spec(this->stream)->channels, this->swvolume);
+ case AO_PROP_PCM_VOL:
+ case AO_PROP_MIXER_VOL:
+
+ this->swvolume = pa_sw_volume_from_linear((double)value/100.0);
+ pa_cvolume_set(&this->cvolume, pa_stream_get_sample_spec(this->stream)->channels, this->swvolume);
- pa_context_set_sink_input_volume(this->pa_class->context, pa_stream_get_index(this->stream),
- &this->cvolume, __xine_pa_context_success_callback, this);
+ o = pa_context_set_sink_input_volume(this->context, pa_stream_get_index(this->stream),
+ &this->cvolume, __xine_pa_context_success_callback, this);
- result = value;
- break;
+ result = value;
+ break;
- case AO_PROP_MUTE_VOL:
- if ( value )
- pa_cvolume_mute(&this->cvolume, pa_stream_get_sample_spec(this->stream)->channels);
- else
- pa_cvolume_set(&this->cvolume, pa_stream_get_sample_spec(this->stream)->channels, this->swvolume);
+ case AO_PROP_MUTE_VOL:
- pa_context_set_sink_input_volume(this->pa_class->context, pa_stream_get_index(this->stream),
- &this->cvolume, __xine_pa_context_success_callback, this);
-
- result = value;
- break;
+ this->muted = value;
+
+#if PA_PROTOCOL_VERSION >= 11
+ /* PulseAudio 0.9.7 and newer */
+ o = pa_context_set_sink_input_mute(this->context, pa_stream_get_index(this->stream),
+ value, __xine_pa_context_success_callback, this);
+#else
+ /* Get the current volume, so we can restore it properly. */
+ o = pa_context_get_sink_input_info(this->context, pa_stream_get_index(this->stream),
+ __xine_pa_sink_info_callback, this);
+
+ if (o) {
+ wait_for_operation(this, o);
+ pa_operation_unref(o);
+ }
+
+ if ( value )
+ pa_cvolume_mute(&this->cvolume, pa_stream_get_sample_spec(this->stream)->channels);
+ else
+ pa_cvolume_set(&this->cvolume, pa_stream_get_sample_spec(this->stream)->channels, this->swvolume);
+
+ o = pa_context_set_sink_input_volume(this->context, pa_stream_get_index(this->stream),
+ &this->cvolume, __xine_pa_context_success_callback, this);
+#endif
+ result = value;
}
-
+
+ if (o) {
+ wait_for_operation(this, o);
+ pa_operation_unref(o);
+ }
+
+ pa_threaded_mainloop_unlock(this->mainloop);
+
return result;
}
static int ao_pulse_ctrl(ao_driver_t *this_gen, int cmd, ...) {
pulse_driver_t *this = (pulse_driver_t *) this_gen;
+ pa_operation *o = NULL;
- if ( ! this->stream ) return 0;
+ pa_threaded_mainloop_lock(this->mainloop);
+
+ if (!this->stream ||
+ !this->context ||
+ pa_context_get_state(this->context) != PA_CONTEXT_READY ||
+ pa_stream_get_state(this->stream) != PA_STREAM_READY) {
+ pa_threaded_mainloop_unlock(this->mainloop);
+ return 0;
+ }
switch (cmd) {
- case AO_CTRL_FLUSH_BUFFERS:
- _x_assert(this->stream && this->pa_class->context);
+ case AO_CTRL_FLUSH_BUFFERS:
- if(pa_stream_get_state(this->stream) == PA_STREAM_READY) {
- pthread_mutex_t completion_callback = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&completion_callback);
- pa_stream_flush(this->stream, __xine_pa_stream_success_callback, &completion_callback);
+ o = pa_stream_flush(this->stream, __xine_pa_stream_success_callback, this);
+ break;
- pthread_mutex_lock(&completion_callback);
- pthread_mutex_destroy(&completion_callback);
- }
+ case AO_CTRL_PLAY_RESUME:
+ case AO_CTRL_PLAY_PAUSE:
- this->frames_written = 0;
+ o = pa_stream_cork(this->stream, cmd == AO_CTRL_PLAY_PAUSE, __xine_pa_stream_success_callback, this);
+ break;
+ }
- break;
+ if (o) {
+ wait_for_operation(this, o);
+ pa_operation_unref(o);
}
+ pa_threaded_mainloop_unlock(this->mainloop);
+
return 0;
}
static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *data) {
pulse_class_t *class = (pulse_class_t *) class_gen;
pulse_driver_t *this;
- char *device;
+ const char* device;
+ int r;
lprintf ("audio_pulse_out: open_plugin called\n");
- this = (pulse_driver_t *) xine_xmalloc (sizeof (pulse_driver_t));
+ this = calloc(1, sizeof (pulse_driver_t));
if (!this)
return NULL;
+
this->xine = class->xine;
+ this->host = NULL;
+ this->sink = NULL;
+ this->context = NULL;
+ this->mainloop = NULL;
+
+ device = class->xine->config->register_string(class->xine->config,
+ "audio.pulseaudio_device",
+ "",
+ _("device used for pulseaudio"),
+ _("use 'server[:sink]' for setting the "
+ "pulseaudio sink device."),
+ 10, NULL,
+ NULL);
+
+ if (device && *device) {
+ char *sep = strrchr(device, ':');
+ if ( sep ) {
+ if (!(this->host = strndup(device, sep-device))) {
+ free(this);
+ return NULL;
+ }
+
+ if (!(this->sink = strdup(sep+1))) {
+ free(this->host);
+ free(this);
+ return NULL;
+ }
+ } else {
+
+ if (!(this->host = strdup(device))) {
+ free(this);
+ return NULL;
+ }
+ }
+ }
+
+ this->mainloop = pa_threaded_mainloop_new();
+ _x_assert(this->mainloop);
+ pa_threaded_mainloop_start(this->mainloop);
/*
* set capabilities
*/
- this->capabilities = AO_CAP_MODE_MONO | AO_CAP_MODE_STEREO | AO_CAP_MODE_4CHANNEL |
- AO_CAP_MODE_4_1CHANNEL | AO_CAP_MODE_5CHANNEL |
- AO_CAP_MODE_5_1CHANNEL | AO_CAP_MIXER_VOL |
- AO_CAP_PCM_VOL | AO_CAP_MUTE_VOL | AO_CAP_8BITS |
- AO_CAP_16BITS | AO_CAP_FLOAT32;
+ this->capabilities =
+ AO_CAP_MODE_MONO | AO_CAP_MODE_STEREO | AO_CAP_MODE_4CHANNEL |
+ AO_CAP_MODE_4_1CHANNEL | AO_CAP_MODE_5CHANNEL | AO_CAP_MODE_5_1CHANNEL |
+ AO_CAP_MIXER_VOL | AO_CAP_PCM_VOL | AO_CAP_MUTE_VOL |
+ AO_CAP_8BITS | AO_CAP_16BITS | AO_CAP_FLOAT32;
this->sample_rate = 0;
- this->host = NULL;
- this->sink = NULL;
-
+
this->ao_driver.get_capabilities = ao_pulse_get_capabilities;
this->ao_driver.get_property = ao_pulse_get_property;
this->ao_driver.set_property = ao_pulse_set_property;
@@ -540,33 +814,22 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da
this->ao_driver.close = ao_pulse_close;
this->ao_driver.exit = ao_pulse_exit;
this->ao_driver.get_gap_tolerance = ao_pulse_get_gap_tolerance;
- this->ao_driver.control = ao_pulse_ctrl;
-
- device = this->xine->config->register_string(this->xine->config,
- "audio.pulseaudio_device",
- "",
- _("device used for pulseaudio"),
- _("use 'server[:sink]' for setting the "
- "pulseaudio sink device."),
- 10, NULL,
- NULL);
-
- if (device && *device) {
- char *sep = strchr(device, ':');
- if ( sep ) {
- this->host = strndup(device, sep-device);
- this->sink = strdup(&sep[1]);
- } else
- this->host = strdup(device);
- }
-
- pthread_mutex_init(&this->info_mutex, NULL);
+ this->ao_driver.control = ao_pulse_ctrl;
xprintf (class->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: host %s sink %s\n",
this->host ? this->host : "(null)", this->sink ? this->sink : "(null)");
this->pa_class = class;
+ pa_threaded_mainloop_lock(this->mainloop);
+ r = connect_context(this);
+ pa_threaded_mainloop_unlock(this->mainloop);
+
+ if (r < 0) {
+ ao_pulse_exit((ao_driver_t *) this);
+ return NULL;
+ }
+
return &this->ao_driver;
}
@@ -586,13 +849,7 @@ static void dispose_class (audio_driver_class_t *this_gen) {
pulse_class_t *this = (pulse_class_t *) this_gen;
- if ( this->context )
- pa_context_unref(this->context);
-
- pa_threaded_mainloop_stop(this->mainloop);
- pa_threaded_mainloop_free(this->mainloop);
-
- free (this);
+ free(this);
}
static void *init_class (xine_t *xine, void *data) {
@@ -601,29 +858,21 @@ static void *init_class (xine_t *xine, void *data) {
lprintf ("audio_pulse_out: init class\n");
- this = (pulse_class_t *) xine_xmalloc (sizeof (pulse_class_t));
+ this = calloc(1, sizeof (pulse_class_t));
if (!this)
return NULL;
+ this->xine = xine;
this->driver_class.open_plugin = open_plugin;
this->driver_class.get_identifier = get_identifier;
this->driver_class.get_description = get_description;
this->driver_class.dispose = dispose_class;
- this->xine = xine;
-
- this->mainloop = pa_threaded_mainloop_new();
- _x_assert(this->mainloop);
-
- pa_threaded_mainloop_start(this->mainloop);
-
- this->context = NULL;
-
return this;
}
static const ao_info_t ao_info_pulse = {
- 6
+ 12
};
/*
@@ -635,5 +884,3 @@ const plugin_info_t xine_plugin_info[] EXPORTED = {
{ PLUGIN_AUDIO_OUT, 8, "pulseaudio", XINE_VERSION_CODE, &ao_info_pulse, init_class },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
-
-
diff --git a/src/audio_out/audio_sndio_out.c b/src/audio_out/audio_sndio_out.c
new file mode 100644
index 000000000..7c3040e6e
--- /dev/null
+++ b/src/audio_out/audio_sndio_out.c
@@ -0,0 +1,410 @@
+/*
+ * Copyright (c) 2008 Brad Smith <brad@comstyle.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* ao plugin for sndio by Brad Smith <brad@comstyle.com>. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <math.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include <pthread.h>
+
+#include <sndio.h>
+
+#include "xine_internal.h"
+#include "xineutils.h"
+#include "audio_out.h"
+#include "bswap.h"
+
+#define GAP_TOLERANCE AO_MAX_GAP
+#define PCT_TO_MIDI(p) (((p) * SIO_MAXVOL + 50) / 100)
+
+typedef struct {
+ audio_driver_class_t driver_class;
+ xine_t *xine;
+} sndio_class_t;
+
+typedef struct sndio_driver_s {
+ ao_driver_t ao_driver;
+ xine_t *xine;
+
+ struct sio_hdl *hdl;
+ long long realpos, playpos;
+ int capabilities;
+
+ int num_channels;
+ u_int32_t bits_per_sample;
+ u_int32_t bytes_per_frame;
+
+ struct {
+ int volume;
+ int mute;
+ } mixer;
+} sndio_driver_t;
+
+/*
+ * Callback to notify of frames processed by the hw. It is
+ * called from the mail loop called from sio_write().
+ */
+static void ao_sndio_onmove_cb(void *addr, int delta)
+{
+ sndio_driver_t *this = (sndio_driver_t *)addr;
+
+ this->realpos += delta;
+}
+
+/*
+ * Open the audio device for writing to.
+ */
+static int ao_sndio_open(ao_driver_t *this_gen,
+ uint32_t bits, uint32_t rate, int mode)
+{
+ sndio_driver_t *this = (sndio_driver_t *) this_gen;
+ struct sio_par par;
+
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG,
+ "audio_sndio_out: ao_sndio_open bits=%d rate=%d, mode=%d\n",
+ bits, rate, mode);
+
+ if (this->hdl != NULL) {
+ sio_close (this->hdl);
+ this->hdl = NULL;
+ }
+
+ this->hdl = sio_open(NULL, SIO_PLAY, 0);
+ if (this->hdl == NULL)
+ goto bad;
+
+ sio_initpar(&par);
+
+ switch (mode) {
+ case AO_CAP_MODE_MONO:
+ par.pchan = 1;
+ break;
+ case AO_CAP_MODE_STEREO:
+ par.pchan = 2;
+ break;
+ case AO_CAP_MODE_4CHANNEL:
+ par.pchan = 4;
+ break;
+ case AO_CAP_MODE_4_1CHANNEL:
+ case AO_CAP_MODE_5CHANNEL:
+ case AO_CAP_MODE_5_1CHANNEL:
+ par.pchan = 6;
+ break;
+ default:
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG,
+ "audio_sndio_out: ao_sndio_open does not support the requested mode: 0x%X\n",
+ mode);
+ goto bad;
+ }
+
+ switch (bits) {
+ case 8:
+ par.bits = 8;
+ par.sig = 0;
+ break;
+ case 16:
+ par.bits = 16;
+ par.sig = 1;
+ break;
+ default:
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG,
+ "audio_sndio_out: ao_sndio_open bits per sample not supported: %d\n", bits);
+ goto bad;
+ }
+
+ par.rate = rate;
+ par.appbufsz = par.rate * 250 / 1000; /* 250ms buffer */
+
+ if (!sio_setpar(this->hdl, &par)) {
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG,
+ "audio_sndio_out: ao_sndio_open could not set params\n");
+ goto bad;
+ }
+
+ if (!sio_getpar(this->hdl, &par)) {
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG,
+ "audio_sndio_out: ao_sndio_open could not get params\n");
+ goto bad;
+ }
+
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG,
+ "audio_sndio_out: ao_sndio_open %d channels output\n",
+ par.pchan);
+
+ this->num_channels = par.pchan;
+ this->bytes_per_frame = par.bps * par.pchan;
+ this->playpos = 0;
+ this->realpos = 0;
+ sio_onmove(this->hdl, ao_sndio_onmove_cb, this);
+
+ if (!sio_start(this->hdl)) {
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG,
+ "audio_sndio_out: ao_sndio_open could not start\n");
+ goto bad;
+ }
+
+ return par.rate;
+
+bad:
+ if (this->hdl != NULL)
+ sio_close(this->hdl);
+ return 0;
+}
+
+static int ao_sndio_num_channels(ao_driver_t *this_gen)
+{
+ sndio_driver_t *this = (sndio_driver_t *) this_gen;
+
+ return this->num_channels;
+}
+
+static int ao_sndio_bytes_per_frame(ao_driver_t *this_gen)
+{
+ sndio_driver_t *this = (sndio_driver_t *) this_gen;
+
+ return this->bytes_per_frame;
+}
+
+static int ao_sndio_get_gap_tolerance (ao_driver_t *this_gen)
+{
+ return GAP_TOLERANCE;
+}
+
+static int ao_sndio_write(ao_driver_t *this_gen, int16_t *data,
+ uint32_t num_frames)
+{
+ sndio_driver_t *this = (sndio_driver_t *) this_gen;
+ size_t ret, size = num_frames * this->bytes_per_frame;
+
+ ret = sio_write(this->hdl, data, size);
+ if (ret == 0)
+ return 0;
+
+ this->playpos += num_frames;
+
+ return 1;
+}
+
+static int ao_sndio_delay (ao_driver_t *this_gen)
+{
+ sndio_driver_t *this = (sndio_driver_t *) this_gen;
+ int bufused;
+
+ if (this->realpos < 0)
+ bufused = this->playpos;
+ else
+ bufused = this->playpos - this->realpos;
+
+ return bufused;
+}
+
+static void ao_sndio_close(ao_driver_t *this_gen)
+{
+ sndio_driver_t *this = (sndio_driver_t *) this_gen;
+
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG,
+ "audio_sndio_out: ao_sndio_close called\n");
+
+ if (!sio_stop(this->hdl)) {
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG,
+ "audio_sndio_out: ao_sndio_close could not stop\n");
+ }
+
+ sio_close(this->hdl);
+ this->hdl = NULL;
+}
+
+static uint32_t ao_sndio_get_capabilities (ao_driver_t *this_gen)
+{
+ sndio_driver_t *this = (sndio_driver_t *) this_gen;
+
+ return this->capabilities;
+}
+
+static void ao_sndio_exit(ao_driver_t *this_gen)
+{
+ sndio_driver_t *this = (sndio_driver_t *) this_gen;
+
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG,
+ "audio_sndio_out: ao_sndio_exit called\n");
+
+ if (this->hdl != NULL)
+ sio_close(this->hdl);
+}
+
+static int ao_sndio_get_property (ao_driver_t *this_gen, int property)
+{
+ sndio_driver_t *this = (sndio_driver_t *) this_gen;
+
+ switch (property) {
+ case AO_PROP_MIXER_VOL:
+ return this->mixer.volume;
+ break;
+ case AO_PROP_MUTE_VOL:
+ return this->mixer.mute;
+ break;
+ }
+
+ return 0;
+}
+
+static int ao_sndio_set_property (ao_driver_t *this_gen, int property, int value)
+{
+ sndio_driver_t *this = (sndio_driver_t *) this_gen;
+ int vol;
+
+ if (this->hdl == NULL)
+ return 0;
+
+ switch(property) {
+ case AO_PROP_MIXER_VOL:
+ this->mixer.volume = value;
+ if (!this->mixer.mute)
+ sio_setvol(this->hdl, PCT_TO_MIDI(this->mixer.volume));
+ return this->mixer.volume;
+ break;
+
+ case AO_PROP_MUTE_VOL:
+ this->mixer.mute = (value) ? 1 : 0;
+ vol = 0;
+ if (!this->mixer.mute)
+ vol = PCT_TO_MIDI(this->mixer.volume);
+ sio_setvol(this->hdl, vol);
+ return value;
+ break;
+ }
+
+ return value;
+}
+
+/*
+ * pause, resume, flush buffers
+ */
+static int ao_sndio_ctrl(ao_driver_t *this_gen, int cmd, ...)
+{
+ sndio_driver_t *this = (sndio_driver_t *) this_gen;
+
+ /*
+ * sndio pauses automatically if there are no more samples to play
+ * and resumes when there are samples again. So we leave this empty
+ * for the moment.
+ */
+
+ return 0;
+}
+
+static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *data)
+{
+ sndio_class_t *class = (sndio_class_t *) class_gen;
+ sndio_driver_t *this;
+
+ lprintf ("audio_sndio_out: open_plugin called\n");
+
+ this = calloc(1, sizeof (sndio_driver_t));
+ if (!this)
+ return NULL;
+
+ this->xine = class->xine;
+
+ /*
+ * Set capabilities
+ */
+ this->capabilities = AO_CAP_MODE_MONO | AO_CAP_MODE_STEREO |
+ AO_CAP_MODE_4CHANNEL | AO_CAP_MODE_4_1CHANNEL |
+ AO_CAP_MODE_5CHANNEL | AO_CAP_MODE_5_1CHANNEL |
+ AO_CAP_MIXER_VOL | AO_CAP_MUTE_VOL | AO_CAP_8BITS |
+ AO_CAP_16BITS;
+
+ this->ao_driver.get_capabilities = ao_sndio_get_capabilities;
+ this->ao_driver.get_property = ao_sndio_get_property;
+ this->ao_driver.set_property = ao_sndio_set_property;
+ this->ao_driver.open = ao_sndio_open;
+ this->ao_driver.num_channels = ao_sndio_num_channels;
+ this->ao_driver.bytes_per_frame = ao_sndio_bytes_per_frame;
+ this->ao_driver.delay = ao_sndio_delay;
+ this->ao_driver.write = ao_sndio_write;
+ this->ao_driver.close = ao_sndio_close;
+ this->ao_driver.exit = ao_sndio_exit;
+ this->ao_driver.get_gap_tolerance = ao_sndio_get_gap_tolerance;
+ this->ao_driver.control = ao_sndio_ctrl;
+
+ return &this->ao_driver;
+}
+
+/*
+ * class functions
+ */
+
+static char* get_identifier (audio_driver_class_t *this_gen)
+{
+ return "sndio";
+}
+
+static char* get_description (audio_driver_class_t *this_gen)
+{
+ return _("xine audio output plugin using sndio audio devices/drivers ");
+}
+
+static void dispose_class (audio_driver_class_t *this_gen)
+{
+ sndio_class_t *this = (sndio_class_t *) this_gen;
+
+ free(this);
+}
+
+static void *init_class (xine_t *xine, void *data)
+{
+ sndio_class_t *this;
+
+ lprintf ("audio_sndio_out: init class\n");
+
+ this = calloc(1, sizeof (sndio_class_t));
+ if (!this)
+ return NULL;
+
+ this->driver_class.open_plugin = open_plugin;
+ this->driver_class.get_identifier = get_identifier;
+ this->driver_class.get_description = get_description;
+ this->driver_class.dispose = dispose_class;
+
+ this->xine = xine;
+
+ return this;
+}
+
+static const ao_info_t ao_info_sndio = {
+ 12
+};
+
+/*
+ * exported plugin catalog entry
+ */
+
+const plugin_info_t xine_plugin_info[] EXPORTED = {
+ /* type, API, "name", version, special_info, init_function */
+ { PLUGIN_AUDIO_OUT, 8, "sndio", XINE_VERSION_CODE, &ao_info_sndio, init_class },
+ { PLUGIN_NONE, 0, "", 0, NULL, NULL }
+};
diff --git a/src/audio_out/audio_sun_out.c b/src/audio_out/audio_sun_out.c
index b23955b77..048db6b86 100644
--- a/src/audio_out/audio_sun_out.c
+++ b/src/audio_out/audio_sun_out.c
@@ -909,7 +909,7 @@ static ao_driver_t *ao_sun_open_plugin (audio_driver_class_t *class_gen, const v
int status;
audio_info_t info;
- this = (sun_driver_t *) xine_xmalloc (sizeof (sun_driver_t));
+ this = calloc(1, sizeof (sun_driver_t));
if (!this)
return NULL;
@@ -1032,7 +1032,7 @@ static void ao_sun_dispose_class (audio_driver_class_t *this_gen) {
static void *ao_sun_init_class (xine_t *xine, void *data) {
sun_class_t *this;
- this = (sun_class_t *) xine_xmalloc (sizeof (sun_class_t));
+ this = calloc(1, sizeof (sun_class_t));
if (!this)
return NULL;
diff --git a/src/combined/Makefile.am b/src/combined/Makefile.am
index 884fcf0cc..6a43fed47 100644
--- a/src/combined/Makefile.am
+++ b/src/combined/Makefile.am
@@ -1,5 +1,8 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
+SUBDIRS = ffmpeg
+
if HAVE_WAVPACK
xineplug_wavpack = xineplug_wavpack.la
endif
diff --git a/src/combined/combined_wavpack.c b/src/combined/combined_wavpack.c
index 893ee99be..98bbe5b57 100644
--- a/src/combined/combined_wavpack.c
+++ b/src/combined/combined_wavpack.c
@@ -33,7 +33,7 @@ static uint32_t audio_types[] = {
static const decoder_info_t decoder_info_wv = {
audio_types, /* supported types */
- 7 /* priority */
+ 8 /* priority */
};
const plugin_info_t xine_plugin_info[] EXPORTED = {
diff --git a/src/combined/combined_wavpack.h b/src/combined/combined_wavpack.h
index 61a504a4f..3cfa78509 100644
--- a/src/combined/combined_wavpack.h
+++ b/src/combined/combined_wavpack.h
@@ -21,6 +21,7 @@
*/
#include "os_types.h"
+#include "attributes.h"
typedef struct {
uint32_t idcode; /* This should always be the string "wvpk" */
@@ -35,7 +36,7 @@ typedef struct {
uint32_t samples_count; /* Count of samples in the current frame */
uint32_t flags; /* Misc flags */
uint32_t decoded_crc32; /* CRC32 of the decoded data */
-} __attribute__((packed)) wvheader_t;
+} XINE_PACKED wvheader_t;
#ifdef WORDS_BIGENDIAN
static const uint32_t wvpk_signature = ('k' + ('p' << 8) + ('v' << 16) + ('w' << 24));
diff --git a/src/combined/decoder_flac.c b/src/combined/decoder_flac.c
index 2230056cd..e5884006a 100644
--- a/src/combined/decoder_flac.c
+++ b/src/combined/decoder_flac.c
@@ -166,6 +166,7 @@ flac_write_callback (const FLAC__StreamDecoder *decoder,
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
}
+#ifdef LEGACY_FLAC
static void
flac_metadata_callback (const FLAC__StreamDecoder *decoder,
const FLAC__StreamMetadata *metadata,
@@ -188,6 +189,7 @@ flac_metadata_callback (const FLAC__StreamDecoder *decoder,
return;
}
+#endif
static void
flac_error_callback (const FLAC__StreamDecoder *decoder,
@@ -335,7 +337,7 @@ static audio_decoder_t *
open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) {
flac_decoder_t *this ;
- this = (flac_decoder_t *) xine_xmalloc (sizeof (flac_decoder_t));
+ this = calloc(1, sizeof (flac_decoder_t));
this->audio_decoder.decode_data = flac_decode_data;
this->audio_decoder.reset = flac_reset;
@@ -407,7 +409,7 @@ static void *
init_plugin (xine_t *xine, void *data) {
flac_class_t *this;
- this = (flac_class_t *) xine_xmalloc (sizeof (flac_class_t));
+ this = calloc(1, sizeof (flac_class_t));
this->decoder_class.open_plugin = open_plugin;
this->decoder_class.get_identifier = get_identifier;
diff --git a/src/combined/decoder_wavpack.c b/src/combined/decoder_wavpack.c
index f8a301c9f..36bf0deab 100644
--- a/src/combined/decoder_wavpack.c
+++ b/src/combined/decoder_wavpack.c
@@ -291,7 +291,7 @@ static void wavpack_dispose (audio_decoder_t *this_gen) {
}
static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) {
- wavpack_decoder_t * const this = (wavpack_decoder_t *) xine_xmalloc (sizeof (wavpack_decoder_t));
+ wavpack_decoder_t * const this = calloc(1, sizeof (wavpack_decoder_t));
this->audio_decoder.decode_data = wavpack_decode_data;
this->audio_decoder.reset = wavpack_reset;
@@ -324,7 +324,7 @@ static void dispose_class (audio_decoder_class_t *this) {
void *decoder_wavpack_init_plugin (xine_t *xine, void *data) {
wavpack_class_t *this;
- this = (wavpack_class_t *) xine_xmalloc (sizeof (wavpack_class_t));
+ this = calloc(1, sizeof (wavpack_class_t));
this->decoder_class.open_plugin = open_plugin;
this->decoder_class.get_identifier = get_identifier;
diff --git a/src/combined/demux_flac.c b/src/combined/demux_flac.c
index 85f98e876..fc638fe35 100644
--- a/src/combined/demux_flac.c
+++ b/src/combined/demux_flac.c
@@ -583,7 +583,7 @@ open_plugin (demux_class_t *class_gen,
}
break;
case METHOD_BY_EXTENSION: {
- char *ending, *mrl;
+ const char *ending, *mrl;
mrl = input->get_mrl (input);
@@ -607,7 +607,7 @@ open_plugin (demux_class_t *class_gen,
* if we reach this point, the input has been accepted.
*/
- this = xine_xmalloc (sizeof (demux_flac_t));
+ this = calloc(1, sizeof (demux_flac_t));
this->stream = stream;
this->input = input;
@@ -715,24 +715,25 @@ open_plugin (demux_class_t *class_gen,
/* FLAC Demuxer class */
-static char *
+static const char *
get_description (demux_class_t *this_gen) {
return "FLAC demux plugin";
}
-static char *
+static const char *
get_identifier (demux_class_t *this_gen) {
return "FLAC";
}
-static char *
+static const char *
get_extensions (demux_class_t *this_gen) {
return "flac";
}
-static char *
+static const char *
get_mimetypes (demux_class_t *this_gen) {
- return "application/x-flac: flac: FLAC Audio;";
+ return "audio/x-flac: flac: FLAC Audio;"
+ "audio/flac: flac: FLAC Audio;";
}
static void
@@ -751,7 +752,7 @@ demux_flac_init_class (xine_t *xine, void *data) {
lprintf("demux_flac_init_class\n");
- this = xine_xmalloc (sizeof (demux_flac_class_t));
+ this = calloc(1, sizeof (demux_flac_class_t));
this->config = xine->config;
this->xine = xine;
diff --git a/src/combined/demux_wavpack.c b/src/combined/demux_wavpack.c
index e8081bca9..2c3e6ce55 100644
--- a/src/combined/demux_wavpack.c
+++ b/src/combined/demux_wavpack.c
@@ -332,7 +332,7 @@ static int demux_wv_get_optional_data(demux_plugin_t *const this_gen,
static demux_plugin_t *open_plugin (demux_class_t *const class_gen,
xine_stream_t *const stream,
input_plugin_t *const input) {
- demux_wv_t *const this = xine_xmalloc (sizeof (demux_wv_t));
+ demux_wv_t *const this = calloc(1, sizeof (demux_wv_t));
this->stream = stream;
this->input = input;
@@ -387,11 +387,11 @@ static const char *get_identifier (demux_class_t *const this_gen) {
}
static const char *get_extensions (demux_class_t *const this_gen) {
- return "wv";
+ return "wv wvp";
}
static const char *get_mimetypes (demux_class_t *const this_gen) {
- return NULL;
+ return "audio/x-wavpack: wv,wvp: WavPack audio;";
}
static void class_dispose (demux_class_t *const this_gen) {
@@ -401,7 +401,7 @@ static void class_dispose (demux_class_t *const this_gen) {
}
void *demux_wv_init_plugin (xine_t *const xine, void *const data) {
- demux_wv_class_t *const this = xine_xmalloc (sizeof (demux_wv_class_t));
+ demux_wv_class_t *const this = calloc(1, sizeof (demux_wv_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/combined/ffmpeg/Makefile.am b/src/combined/ffmpeg/Makefile.am
new file mode 100644
index 000000000..24cab7577
--- /dev/null
+++ b/src/combined/ffmpeg/Makefile.am
@@ -0,0 +1,81 @@
+include $(top_builddir)/misc/Makefile.plugins
+include $(top_srcdir)/misc/Makefile.common
+
+DEFAULT_INCLUDES = -I.
+
+if HAVE_FFMPEG
+ff_cppflags = $(FFMPEG_CFLAGS) $(FFMPEG_POSTPROC_CFLAGS)
+link_ffmpeg = $(FFMPEG_LIBS) $(FFMPEG_UTIL_LIBS) $(FFMPEG_POSTPROC_LIBS)
+else
+ff_cppflags = -I$(top_builddir)/src/libffmpeg -I$(top_srcdir)/src/libffmpeg/libavcodec -I$(top_srcdir)/src/libffmpeg/libavutil
+link_ffmpeg = \
+ $(top_builddir)/src/libffmpeg/libavcodec/libavcodec.la \
+ $(top_builddir)/src/libffmpeg/libavutil/libavutil.la \
+ $(top_builddir)/src/libffmpeg/libavcodec/libpostproc/libpostprocess.la
+endif
+
+ff_generated = \
+ avcodec_video.list avcodec_audio.list \
+ ff_video_list.h ff_audio_list.h
+
+BUILT_SOURCES = $(ff_generated)
+
+# ffmpeg_config.h is generated by configure
+DISTCLEANFILES = ffmpeg_config.h $(ff_generated)
+
+# this must always be included, even if the current machine has no DXR3...
+EXTRA_DIST = ffmpeg_encoder.c \
+ xine_video.list xine_audio.list mkcodeclist.pl
+
+xineplug_LTLIBRARIES = xineplug_decode_ff.la xineplug_decode_dvaudio.la
+
+if HAVE_DXR3
+AM_CPPFLAGS = -I$(top_srcdir)/src/dxr3 $(X_CFLAGS) $(ff_cppflags) \
+ $(ZLIB_CPPFLAGS)
+xineplug_decode_ff_la_SOURCES = ffmpeg_decoder.c ff_audio_decoder.c ff_video_decoder.c \
+ ffmpeg_encoder.c ff_mpeg_parser.c ffmpeg_decoder.h \
+ ff_mpeg_parser.h
+else
+AM_CPPFLAGS = $(ff_cppflags) $(ZLIB_CPPFLAGS)
+xineplug_decode_ff_la_SOURCES = ffmpeg_decoder.c ff_audio_decoder.c ff_video_decoder.c \
+ ff_mpeg_parser.c ffmpeg_decoder.h ff_mpeg_parser.h
+endif
+
+xineplug_decode_ff_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS)
+xineplug_decode_ff_la_LDFLAGS = $(xineplug_ldflags) $(IMPURE_TEXT_LDFLAGS)
+xineplug_decode_ff_la_LIBADD = $(XINE_LIB) $(MLIB_LIBS) -lm $(ZLIB_LIBS) \
+ $(link_ffmpeg) $(PTHREAD_LIBS) $(LTLIBINTL)
+
+xineplug_decode_dvaudio_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS)
+xineplug_decode_dvaudio_la_LDFLAGS = $(xineplug_ldflags)
+xineplug_decode_dvaudio_la_SOURCES = ff_dvaudio_decoder.c
+xineplug_decode_dvaudio_la_LIBADD = $(XINE_LIB) $(LTLIBINTL)
+
+$(top_srcdir)/src/libffmpeg/libavcodec/libavcodec.la:
+ make -C $(top_srcdir)/src/libffmpeg
+
+# Generation of ffmpeg->xine codec mapping lists (see xine_*.list).
+
+AV_CPP = $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS)
+
+# Extract some CODEC_ID_* from avcodec.h. Requires some sed mangling.
+avcodec_audio.list: AV_CODECS:=/CODEC_ID_PCM_S16LE/,/CODEC_ID_DVD_SUBTITLE/
+avcodec_video.list: AV_CODECS:=/CODEC_ID_MPEG1VIDEO/,/CODEC_ID_PCM_S16LE/
+
+avcodec_audio.list avcodec_video.list:
+ echo '#include "$(srcdir)/ffmpeg_decoder.h"' | $(AV_CPP) - |\
+ sed -e $(AV_CODECS)'! d; s/^[ \t]*//; s/[=,].*//; /^$$/ d' >$@
+
+# Generate the mappings. These are #included where needed.
+ff_%_list.h: $(srcdir)/mkcodeclist.pl avcodec_%.list $(srcdir)/xine_%.list
+ $(PERL) $^ $@
+
+ff_audio_decoder.c: ff_audio_list.h
+ff_video_decoder.c: ff_video_list.h
+
+# 'make report' prints tokens corresponding to any unhandled codecs.
+report: avcodec_audio.list avcodec_video.list
+ @$(top_srcdir)/src/combined/ffmpeg/mkcodeclist.pl avcodec_audio.list xine_audio.list - audio
+ @$(top_srcdir)/src/combined/ffmpeg/mkcodeclist.pl avcodec_video.list xine_video.list - video
+
+.PHONY: report
diff --git a/src/libffmpeg/ff_audio_decoder.c b/src/combined/ffmpeg/ff_audio_decoder.c
index 5f197bed5..24c193b44 100644
--- a/src/libffmpeg/ff_audio_decoder.c
+++ b/src/combined/ffmpeg/ff_audio_decoder.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2001-2005 the xine project
+ * Copyright (C) 2001-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -22,7 +22,7 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
-#include "ffmpeg_config.h"
+#include "../../libffmpeg/ffmpeg_config.h"
#endif
#include <stdlib.h>
@@ -73,42 +73,7 @@ typedef struct ff_audio_decoder_s {
} ff_audio_decoder_t;
-static const ff_codec_t ff_audio_lookup[] = {
- {BUF_AUDIO_WMAV1, CODEC_ID_WMAV1, "MS Windows Media Audio 1 (ffmpeg)"},
- {BUF_AUDIO_WMAV2, CODEC_ID_WMAV2, "MS Windows Media Audio 2 (ffmpeg)"},
- {BUF_AUDIO_14_4, CODEC_ID_RA_144, "Real 14.4 (ffmpeg)"},
- {BUF_AUDIO_28_8, CODEC_ID_RA_288, "Real 28.8 (ffmpeg)"},
- {BUF_AUDIO_MPEG, CODEC_ID_MP3, "MP3 (ffmpeg)"},
- {BUF_AUDIO_MSADPCM, CODEC_ID_ADPCM_MS, "MS ADPCM (ffmpeg)"},
- {BUF_AUDIO_QTIMAADPCM, CODEC_ID_ADPCM_IMA_QT, "QT IMA ADPCM (ffmpeg)"},
- {BUF_AUDIO_MSIMAADPCM, CODEC_ID_ADPCM_IMA_WAV, "MS IMA ADPCM (ffmpeg)"},
- {BUF_AUDIO_DK3ADPCM, CODEC_ID_ADPCM_IMA_DK3, "Duck DK3 ADPCM (ffmpeg)"},
- {BUF_AUDIO_DK4ADPCM, CODEC_ID_ADPCM_IMA_DK4, "Duck DK4 ADPCM (ffmpeg)"},
- {BUF_AUDIO_VQA_IMA, CODEC_ID_ADPCM_IMA_WS, "Westwood Studios IMA (ffmpeg)"},
- {BUF_AUDIO_SMJPEG_IMA, CODEC_ID_ADPCM_IMA_SMJPEG, "SMJPEG IMA (ffmpeg)"},
- {BUF_AUDIO_XA_ADPCM, CODEC_ID_ADPCM_XA, "CD-ROM/XA ADPCM (ffmpeg)"},
- {BUF_AUDIO_4X_ADPCM, CODEC_ID_ADPCM_4XM, "4X ADPCM (ffmpeg)"},
- {BUF_AUDIO_EA_ADPCM, CODEC_ID_ADPCM_EA, "Electronic Arts ADPCM (ffmpeg)"},
- {BUF_AUDIO_MULAW, CODEC_ID_PCM_MULAW, "mu-law logarithmic PCM (ffmpeg)"},
- {BUF_AUDIO_ALAW, CODEC_ID_PCM_ALAW, "A-law logarithmic PCM (ffmpeg)"},
- {BUF_AUDIO_ROQ, CODEC_ID_ROQ_DPCM, "RoQ DPCM (ffmpeg)"},
- {BUF_AUDIO_INTERPLAY, CODEC_ID_INTERPLAY_DPCM, "Interplay DPCM (ffmpeg)"},
- {BUF_AUDIO_MAC3, CODEC_ID_MACE3, "MACE 3:1 (ffmpeg)"},
- {BUF_AUDIO_MAC6, CODEC_ID_MACE6, "MACE 6:1 (ffmpeg)"},
- {BUF_AUDIO_XAN_DPCM, CODEC_ID_XAN_DPCM, "Origin Xan DPCM (ffmpeg)"},
- {BUF_AUDIO_VMD, CODEC_ID_VMDAUDIO, "Sierra VMD Audio (ffmpeg)"},
- {BUF_AUDIO_FLAC, CODEC_ID_FLAC, "FLAC (ffmpeg)"},
- {BUF_AUDIO_SHORTEN, CODEC_ID_SHORTEN, "Shorten (ffmpeg)"},
- {BUF_AUDIO_ALAC, CODEC_ID_ALAC, "ALAC (ffmpeg)"},
- {BUF_AUDIO_QDESIGN2, CODEC_ID_QDM2, "QDesign (ffmpeg)"},
- {BUF_AUDIO_COOK, CODEC_ID_COOK, "RealAudio Cooker (ffmpeg)"},
- {BUF_AUDIO_TRUESPEECH, CODEC_ID_TRUESPEECH, "TrueSpeech (ffmpeg)"},
- {BUF_AUDIO_TTA, CODEC_ID_TTA, "True Audio Lossless (ffmpeg)"},
- {BUF_AUDIO_SMACKER, CODEC_ID_SMACKAUDIO, "Smacker (ffmpeg)"},
- {BUF_AUDIO_FLVADPCM, CODEC_ID_ADPCM_SWF, "Flash ADPCM (ffmpeg)"},
- {BUF_AUDIO_WAVPACK, CODEC_ID_WAVPACK, "WavPack (ffmpeg)"},
-};
-
+#include "ff_audio_list.h"
static void ff_audio_ensure_buffer_size(ff_audio_decoder_t *this, int size) {
if (size > this->bufsize) {
@@ -177,7 +142,7 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
this->context->bit_rate = audio_header->nAvgBytesPerSec * 8;
if(audio_header->cbSize > 0) {
- this->context->extradata = xine_xmalloc(audio_header->cbSize);
+ this->context->extradata = malloc(audio_header->cbSize);
this->context->extradata_size = audio_header->cbSize;
memcpy( this->context->extradata,
(uint8_t *)audio_header + sizeof(xine_waveformatex),
@@ -199,10 +164,10 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
this->audio_channels = this->buf[0x37];
/* this->audio_bits = buf->content[0x35] */
- this->context->block_align = _X_BE_16(&this->buf[0x2A]);
-
+ this->context->block_align = _X_BE_32(&this->buf[0x18]);
+
this->context->extradata_size = 5*sizeof(short);
- this->context->extradata = xine_xmalloc(this->context->extradata_size);
+ this->context->extradata = malloc(this->context->extradata_size);
ptr = (short *) this->context->extradata;
@@ -211,7 +176,51 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
ptr[2] = _X_BE_16(&this->buf[0x16]); /* subpacket flavour */
ptr[3] = _X_BE_32(&this->buf[0x18]); /* coded frame size */
ptr[4] = 0; /* codec's data length */
+
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ "ffmpeg_audio_dec: 28_8 audio channels %d bits %d sample rate %d block align %d\n",
+ this->audio_channels, this->audio_bits, this->audio_sample_rate,
+ this->context->block_align);
break;
+ case BUF_AUDIO_COOK:
+ {
+ int version;
+ int data_len;
+ int extradata;
+
+ version = _X_BE_16 (this->buf+4);
+ if (version == 4) {
+ this->audio_sample_rate = _X_BE_16 (this->buf+48);
+ this->audio_bits = _X_BE_16 (this->buf+52);
+ this->audio_channels = _X_BE_16 (this->buf+54);
+ data_len = _X_BE_32 (this->buf+67);
+ extradata = 71;
+ } else {
+ this->audio_sample_rate = _X_BE_16 (this->buf+54);
+ this->audio_bits = _X_BE_16 (this->buf+58);
+ this->audio_channels = _X_BE_16 (this->buf+60);
+ data_len = _X_BE_32 (this->buf+74);
+ extradata = 78;
+ }
+ this->context->block_align = _X_BE_16 (this->buf+44);
+
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ "ffmpeg_audio_dec: cook audio channels %d bits %d sample rate %d block align %d\n",
+ this->audio_channels, this->audio_bits, this->audio_sample_rate,
+ this->context->block_align);
+
+ if (extradata + data_len > this->size)
+ break; /* abort early - extradata length is bad */
+ if (extradata > INT_MAX - data_len)
+ break;/*integer overflow*/
+
+ this->context->extradata_size = data_len;
+ this->context->extradata = malloc(this->context->extradata_size +
+ FF_INPUT_BUFFER_PADDING_SIZE);
+ xine_fast_memcpy (this->context->extradata, this->buf + extradata,
+ this->context->extradata_size);
+ break;
+ }
default:
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
"ffmpeg_audio_dec: unknown header with buf type 0x%X\n", codec_type);
@@ -228,11 +237,12 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
this->context->sample_rate = this->audio_sample_rate;
this->context->channels = this->audio_channels;
this->context->codec_id = this->codec->id;
+ this->context->codec_type = this->codec->type;
this->context->codec_tag = _x_stream_info_get(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC);
this->size = 0;
- this->decode_buffer = xine_xmalloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
+ this->decode_buffer = calloc(1, AVCODEC_MAX_AUDIO_FRAME_SIZE);
return;
}
@@ -240,8 +250,8 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
(buf->decoder_info[1] == BUF_SPECIAL_STSD_ATOM)) {
this->context->extradata_size = buf->decoder_info[2];
- this->context->extradata = xine_xmalloc(buf->decoder_info[2] +
- FF_INPUT_BUFFER_PADDING_SIZE);
+ this->context->extradata = malloc(buf->decoder_info[2] +
+ FF_INPUT_BUFFER_PADDING_SIZE);
memcpy(this->context->extradata, buf->decoder_info_ptr[2],
buf->decoder_info[2]);
@@ -267,7 +277,26 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
this->decoder_ok = 1;
}
+ if( buf->decoder_flags & BUF_FLAG_PREVIEW )
+ return;
+
+ ff_audio_ensure_buffer_size(this, this->size + buf->size);
+ xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size);
+ this->size += buf->size;
+
if (!this->output_open) {
+ if (!this->audio_bits || !this->audio_sample_rate || !this->audio_channels) {
+ avcodec_decode_audio2 (this->context,
+ (int16_t *)this->decode_buffer,
+ &decode_buffer_size,
+ &this->buf[0],
+ this->size);
+ this->audio_bits = this->context->bits_per_sample;
+ this->audio_sample_rate = this->context->sample_rate;
+ this->audio_channels = this->context->channels;
+ if (!this->audio_bits || !this->audio_sample_rate || !this->audio_channels)
+ return;
+ }
this->output_open = (this->stream->audio_out->open) (this->stream->audio_out,
this->stream, this->audio_bits, this->audio_sample_rate,
_x_ao_channels2mode(this->audio_channels));
@@ -277,13 +306,6 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
if (!this->output_open)
return;
- if( buf->decoder_flags & BUF_FLAG_PREVIEW )
- return;
-
- ff_audio_ensure_buffer_size(this, this->size + buf->size);
- xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size);
- this->size += buf->size;
-
if (buf->decoder_flags & BUF_FLAG_FRAME_END) { /* time to decode a frame */
offset = 0;
@@ -309,6 +331,13 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
/* dispatch the decoded audio */
out = 0;
while (out < decode_buffer_size) {
+ int stream_status = xine_get_status(this->stream);
+
+ if (stream_status == XINE_STATUS_QUIT || stream_status == XINE_STATUS_STOP) {
+ this->size = 0;
+ return;
+ }
+
audio_buffer =
this->stream->audio_out->get_buffer (this->stream->audio_out);
if (audio_buffer->mem_size == 0) {
@@ -324,7 +353,7 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
/* fill up this buffer */
xine_fast_memcpy(audio_buffer->mem, &this->decode_buffer[out],
- bytes_to_send);
+ bytes_to_send);
/* byte count / 2 (bytes / sample) / channels */
audio_buffer->num_frames = bytes_to_send / 2 / this->audio_channels;
@@ -355,7 +384,8 @@ static void ff_audio_reset (audio_decoder_t *this_gen) {
if( this->context && this->decoder_ok ) {
pthread_mutex_lock (&ffmpeg_lock);
avcodec_close (this->context);
- avcodec_open (this->context, this->codec);
+ if (avcodec_open (this->context, this->codec) < 0)
+ this->decoder_ok = 0;
pthread_mutex_unlock (&ffmpeg_lock);
}
}
@@ -384,7 +414,7 @@ static void ff_audio_dispose (audio_decoder_t *this_gen) {
free(this->context->extradata);
if(this->context)
- free(this->context);
+ av_free(this->context);
free (this_gen);
}
@@ -393,7 +423,7 @@ static audio_decoder_t *ff_audio_open_plugin (audio_decoder_class_t *class_gen,
ff_audio_decoder_t *this ;
- this = (ff_audio_decoder_t *) xine_xmalloc (sizeof (ff_audio_decoder_t));
+ this = calloc(1, sizeof (ff_audio_decoder_t));
this->audio_decoder.decode_data = ff_audio_decode_data;
this->audio_decoder.reset = ff_audio_reset;
@@ -429,7 +459,7 @@ void *init_audio_plugin (xine_t *xine, void *data) {
ff_audio_class_t *this ;
- this = (ff_audio_class_t *) xine_xmalloc (sizeof (ff_audio_class_t));
+ this = calloc(1, sizeof (ff_audio_class_t));
this->decoder_class.open_plugin = ff_audio_open_plugin;
this->decoder_class.get_identifier = ff_audio_get_identifier;
@@ -441,111 +471,7 @@ void *init_audio_plugin (xine_t *xine, void *data) {
return this;
}
-static uint32_t supported_audio_types[] = {
- #ifdef CONFIG_WMAV1_DECODER
- BUF_AUDIO_WMAV1,
- #endif
- #ifdef CONFIG_WMAV2_DECODER
- BUF_AUDIO_WMAV2,
- #endif
- #ifdef CONFIG_RA_144_DECODER
- BUF_AUDIO_14_4,
- #endif
- #ifdef CONFIG_RA_288_DECODER
- BUF_AUDIO_28_8,
- #endif
- #ifdef CONFIG_MP3_DECODER
- BUF_AUDIO_MPEG,
- #endif
- #ifdef CONFIG_ADPCM_MS_DECODER
- BUF_AUDIO_MSADPCM,
- #endif
- #ifdef CONFIG_ADPCM_IMA_QT_DECODER
- BUF_AUDIO_QTIMAADPCM,
- #endif
- #ifdef CONFIG_ADPCM_IMA_WAV_DECODER
- BUF_AUDIO_MSIMAADPCM,
- #endif
- #ifdef CONFIG_ADPCM_IMA_DK3_DECODER
- BUF_AUDIO_DK3ADPCM,
- #endif
- #ifdef CONFIG_ADPCM_IMA_DK4_DECODER
- BUF_AUDIO_DK4ADPCM,
- #endif
- #ifdef CONFIG_ADPCM_IMA_WS_DECODER
- BUF_AUDIO_VQA_IMA,
- #endif
- #ifdef CONFIG_ADPCM_IMA_SMJPEG_DECODER
- BUF_AUDIO_SMJPEG_IMA,
- #endif
- #ifdef CONFIG_ADPCM_XA_DECODER
- BUF_AUDIO_XA_ADPCM,
- #endif
- #ifdef CONFIG_ADPCM_4XM_DECODER
- BUF_AUDIO_4X_ADPCM,
- #endif
- #ifdef CONFIG_ADPCM_EA_DECODER
- BUF_AUDIO_EA_ADPCM,
- #endif
- #ifdef CONFIG_PCM_MULAW_DECODER
- BUF_AUDIO_MULAW,
- #endif
- #ifdef CONFIG_PCM_ALAW_DECODER
- BUF_AUDIO_ALAW,
- #endif
- #ifdef CONFIG_ROQ_DPCM_DECODER
- BUF_AUDIO_ROQ,
- #endif
- #ifdef CONFIG_INTERPLAY_DPCM_DECODER
- BUF_AUDIO_INTERPLAY,
- #endif
- #ifdef CONFIG_MACE3_DECODER
- BUF_AUDIO_MAC3,
- #endif
- #ifdef CONFIG_MACE6_DECODER
- BUF_AUDIO_MAC6,
- #endif
- #ifdef CONFIG_XAN_DPCM_DECODER
- BUF_AUDIO_XAN_DPCM,
- #endif
- #ifdef CONFIG_VMDAUDIO_DECODER
- BUF_AUDIO_VMD,
- #endif
- #ifdef CONFIG_FLAC_DECODER
- BUF_AUDIO_FLAC,
- #endif
- #ifdef CONFIG_SHORTEN_DECODER
- BUF_AUDIO_SHORTEN,
- #endif
- #ifdef CONFIG_ALAC_DECODER
- BUF_AUDIO_ALAC,
- #endif
- #ifdef CONFIG_QDM2_DECODER
- BUF_AUDIO_QDESIGN2,
- #endif
- #ifdef CONFIG_COOK_DECODER
- BUF_AUDIO_COOK,
- #endif
- #ifdef CONFIG_TRUESPEECH_DECODER
- BUF_AUDIO_TRUESPEECH,
- #endif
- #ifdef CONFIG_TTA_DECODER
- BUF_AUDIO_TTA,
- #endif
- #ifdef CONFIG_SMACKAUDIO_DECODER
- BUF_AUDIO_SMACKER,
- #endif
- #ifdef CONFIG_ADPCM_SWF_DECODER
- BUF_AUDIO_FLVADPCM,
- #endif
- #ifdef CONFIG_WAVPACK_DECODER
- BUF_AUDIO_WAVPACK,
- #endif
-
- 0
-};
-
decoder_info_t dec_info_ffmpeg_audio = {
supported_audio_types, /* supported types */
- 6 /* priority */
+ 7 /* priority */
};
diff --git a/src/libffmpeg/ff_dvaudio_decoder.c b/src/combined/ffmpeg/ff_dvaudio_decoder.c
index 0796b3862..6a102f627 100644
--- a/src/libffmpeg/ff_dvaudio_decoder.c
+++ b/src/combined/ffmpeg/ff_dvaudio_decoder.c
@@ -52,14 +52,16 @@
# undef uint64_t
#endif
-#ifdef HAVE_FFMPEG
+#ifdef HAVE_FFMPEG_AVUTIL_H
# include <avcodec.h>
-# include "libavcodec/dvdata.h"
+#elif defined HAVE_FFMPEG
+# include <libavcodec/avcodec.h>
#else
-# include "libavcodec/avcodec.h"
-# include "libavcodec/dvdata.h"
+# include "../../libffmpeg/libavcodec/avcodec.h"
#endif
+#include "../../libffmpeg/libavcodec/dvdata.h"
+
#ifdef _MSC_VER
# undef malloc
# undef free
@@ -249,10 +251,10 @@ static void dvaudio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
return;
if (buf->decoder_flags & BUF_FLAG_STDHEADER) {
- this->buf = xine_xmalloc(AUDIOBUFSIZE);
+ this->buf = calloc(1, AUDIOBUFSIZE);
this->bufsize = AUDIOBUFSIZE;
this->size = 0;
- this->decode_buffer = xine_xmalloc(MAXFRAMESIZE);
+ this->decode_buffer = calloc(1, MAXFRAMESIZE);
this->audio_sample_rate = buf->decoder_info[1];
this->audio_bits = buf->decoder_info[2];
@@ -366,7 +368,7 @@ static audio_decoder_t *dvaudio_open_plugin (audio_decoder_class_t *class_gen, x
dvaudio_decoder_t *this ;
- this = (dvaudio_decoder_t *) xine_xmalloc (sizeof (dvaudio_decoder_t));
+ this = calloc(1, sizeof (dvaudio_decoder_t));
this->audio_decoder.decode_data = dvaudio_decode_data;
this->audio_decoder.reset = dvaudio_reset;
@@ -399,7 +401,7 @@ static void *init_dvaudio_plugin (xine_t *xine, void *data) {
dvaudio_class_t *this ;
- this = (dvaudio_class_t *) xine_xmalloc (sizeof (dvaudio_class_t));
+ this = calloc(1, sizeof (dvaudio_class_t));
this->decoder_class.open_plugin = dvaudio_open_plugin;
this->decoder_class.get_identifier = dvaudio_get_identifier;
diff --git a/src/libffmpeg/ff_mpeg_parser.c b/src/combined/ffmpeg/ff_mpeg_parser.c
index 70901d93b..3c2c2cf48 100644
--- a/src/libffmpeg/ff_mpeg_parser.c
+++ b/src/combined/ffmpeg/ff_mpeg_parser.c
@@ -50,7 +50,7 @@ static const int frame_rate_tab[][2] = {
void mpeg_parser_init (mpeg_parser_t *parser)
{
- parser->chunk_buffer = xine_xmalloc(BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
+ parser->chunk_buffer = malloc(BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
mpeg_parser_reset(parser);
}
diff --git a/src/libffmpeg/ff_mpeg_parser.h b/src/combined/ffmpeg/ff_mpeg_parser.h
index ea43a6ce4..ea43a6ce4 100644
--- a/src/libffmpeg/ff_mpeg_parser.h
+++ b/src/combined/ffmpeg/ff_mpeg_parser.h
diff --git a/src/libffmpeg/ff_video_decoder.c b/src/combined/ffmpeg/ff_video_decoder.c
index dc07abb9f..2742e3f2e 100644
--- a/src/libffmpeg/ff_video_decoder.c
+++ b/src/combined/ffmpeg/ff_video_decoder.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2001-2007 the xine project
+ * Copyright (C) 2001-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -22,7 +22,7 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
-#include "ffmpeg_config.h"
+#include "../../libffmpeg/ffmpeg_config.h"
#endif
#include <stdlib.h>
@@ -45,10 +45,10 @@
#include "ffmpeg_decoder.h"
#include "ff_mpeg_parser.h"
-#ifdef HAVE_FFMPEG
+#ifdef HAVE_FFMPEG_AVUTIL_H
# include <postprocess.h>
#else
-# include "libavcodec/libpostproc/postprocess.h"
+# include <libpostproc/postprocess.h>
#endif
#define VIDEOBUFSIZE (128*1024)
@@ -58,6 +58,12 @@
#define ENABLE_DIRECT_RENDERING
+/* reordered_opaque appeared in libavcodec 51.68.0 */
+#define AVCODEC_HAS_REORDERED_OPAQUE
+#if LIBAVCODEC_VERSION_INT < 0x334400
+# undef AVCODEC_HAS_REORDERED_OPAQUE
+#endif
+
typedef struct ff_video_decoder_s ff_video_decoder_t;
typedef struct ff_video_class_s {
@@ -78,7 +84,14 @@ struct ff_video_decoder_s {
xine_stream_t *stream;
int64_t pts;
+#ifdef AVCODEC_HAS_REORDERED_OPAQUE
+ uint64_t pts_tag_mask;
+ uint64_t pts_tag;
+ int pts_tag_counter;
+ int pts_tag_stable_counter;
+#endif /* AVCODEC_HAS_REORDERED_OPAQUE */
int video_step;
+ int reported_video_step;
uint8_t decoder_ok:1;
uint8_t decoder_init_mode:1;
@@ -121,6 +134,10 @@ struct ff_video_decoder_s {
yuv_planes_t yuv;
AVPaletteControl palette_control;
+
+#ifdef LOG
+ enum PixelFormat debug_fmt;
+#endif
};
@@ -152,7 +169,7 @@ static int get_buffer(AVCodecContext *context, AVFrame *av_frame){
avcodec_align_dimensions(context, &width, &height);
- if( this->context->pix_fmt != PIX_FMT_YUV420P ) {
+ if( this->context->pix_fmt != PIX_FMT_YUV420P && this->context->pix_fmt != PIX_FMT_YUVJ420P ) {
if (!this->is_direct_rendering_disabled) {
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
_("ffmpeg_video_dec: unsupported frame format, DR1 disabled.\n"));
@@ -208,6 +225,11 @@ static int get_buffer(AVCodecContext *context, AVFrame *av_frame){
av_frame->type= FF_BUFFER_TYPE_USER;
+#ifdef AVCODEC_HAS_REORDERED_OPAQUE
+ /* take over pts for this frame to have it reordered */
+ av_frame->reordered_opaque = context->reordered_opaque;
+#endif
+
xine_list_push_back(this->dr1_frames, av_frame);
return 0;
@@ -240,84 +262,7 @@ static void release_buffer(struct AVCodecContext *context, AVFrame *av_frame){
}
#endif
-static const ff_codec_t ff_video_lookup[] = {
- {BUF_VIDEO_MSMPEG4_V1, CODEC_ID_MSMPEG4V1, "Microsoft MPEG-4 v1 (ffmpeg)"},
- {BUF_VIDEO_MSMPEG4_V2, CODEC_ID_MSMPEG4V2, "Microsoft MPEG-4 v2 (ffmpeg)"},
- {BUF_VIDEO_MSMPEG4_V3, CODEC_ID_MSMPEG4V3, "Microsoft MPEG-4 v3 (ffmpeg)"},
- {BUF_VIDEO_WMV7, CODEC_ID_WMV1, "MS Windows Media Video 7 (ffmpeg)"},
- {BUF_VIDEO_WMV8, CODEC_ID_WMV2, "MS Windows Media Video 8 (ffmpeg)"},
- {BUF_VIDEO_WMV9, CODEC_ID_WMV3, "MS Windows Media Video 9 (ffmpeg)"},
- {BUF_VIDEO_VC1, CODEC_ID_VC1, "MS Windows Media Video VC-1 (ffmpeg)"},
- {BUF_VIDEO_MPEG4, CODEC_ID_MPEG4, "ISO MPEG-4 (ffmpeg)"},
- {BUF_VIDEO_XVID, CODEC_ID_MPEG4, "ISO MPEG-4 (XviD, ffmpeg)"},
- {BUF_VIDEO_DIVX5, CODEC_ID_MPEG4, "ISO MPEG-4 (DivX5, ffmpeg)"},
- {BUF_VIDEO_3IVX, CODEC_ID_MPEG4, "ISO MPEG-4 (3ivx, ffmpeg)"},
- {BUF_VIDEO_JPEG, CODEC_ID_MJPEG, "Motion JPEG (ffmpeg)"},
- {BUF_VIDEO_MJPEG, CODEC_ID_MJPEG, "Motion JPEG (ffmpeg)"},
- {BUF_VIDEO_MJPEG_B, CODEC_ID_MJPEGB, "Motion JPEG B (ffmpeg)"},
- {BUF_VIDEO_I263, CODEC_ID_H263I, "ITU H.263 (ffmpeg)"},
- {BUF_VIDEO_H263, CODEC_ID_H263, "H.263 (ffmpeg)"},
- {BUF_VIDEO_RV10, CODEC_ID_RV10, "Real Video 1.0 (ffmpeg)"},
- {BUF_VIDEO_RV20, CODEC_ID_RV20, "Real Video 2.0 (ffmpeg)"},
- {BUF_VIDEO_IV31, CODEC_ID_INDEO3, "Indeo Video 3.1 (ffmpeg)"},
- {BUF_VIDEO_IV32, CODEC_ID_INDEO3, "Indeo Video 3.2 (ffmpeg)"},
- {BUF_VIDEO_SORENSON_V1, CODEC_ID_SVQ1, "Sorenson Video 1 (ffmpeg)"},
- {BUF_VIDEO_SORENSON_V3, CODEC_ID_SVQ3, "Sorenson Video 3 (ffmpeg)"},
- {BUF_VIDEO_DV, CODEC_ID_DVVIDEO, "DV (ffmpeg)"},
- {BUF_VIDEO_HUFFYUV, CODEC_ID_HUFFYUV, "HuffYUV (ffmpeg)"},
- {BUF_VIDEO_VP31, CODEC_ID_VP3, "On2 VP3.1 (ffmpeg)"},
- {BUF_VIDEO_VP5, CODEC_ID_VP5, "On2 VP5 (ffmpeg)"},
- {BUF_VIDEO_VP6, CODEC_ID_VP6, "On2 VP6 (ffmpeg)"},
- {BUF_VIDEO_VP6F, CODEC_ID_VP6F, "On2 VP6 (ffmpeg)"},
- {BUF_VIDEO_4XM, CODEC_ID_4XM, "4X Video (ffmpeg)"},
- {BUF_VIDEO_CINEPAK, CODEC_ID_CINEPAK, "Cinepak (ffmpeg)"},
- {BUF_VIDEO_MSVC, CODEC_ID_MSVIDEO1, "Microsoft Video 1 (ffmpeg)"},
- {BUF_VIDEO_MSRLE, CODEC_ID_MSRLE, "Microsoft RLE (ffmpeg)"},
- {BUF_VIDEO_RPZA, CODEC_ID_RPZA, "Apple Quicktime Video/RPZA (ffmpeg)"},
- {BUF_VIDEO_CYUV, CODEC_ID_CYUV, "Creative YUV (ffmpeg)"},
- {BUF_VIDEO_ROQ, CODEC_ID_ROQ, "Id Software RoQ (ffmpeg)"},
- {BUF_VIDEO_IDCIN, CODEC_ID_IDCIN, "Id Software CIN (ffmpeg)"},
- {BUF_VIDEO_WC3, CODEC_ID_XAN_WC3, "Xan (ffmpeg)"},
- {BUF_VIDEO_VQA, CODEC_ID_WS_VQA, "Westwood Studios VQA (ffmpeg)"},
- {BUF_VIDEO_INTERPLAY, CODEC_ID_INTERPLAY_VIDEO, "Interplay MVE (ffmpeg)"},
- {BUF_VIDEO_FLI, CODEC_ID_FLIC, "FLIC Video (ffmpeg)"},
- {BUF_VIDEO_8BPS, CODEC_ID_8BPS, "Planar RGB (ffmpeg)"},
- {BUF_VIDEO_SMC, CODEC_ID_SMC, "Apple Quicktime Graphics/SMC (ffmpeg)"},
- {BUF_VIDEO_DUCKTM1, CODEC_ID_TRUEMOTION1,"Duck TrueMotion v1 (ffmpeg)"},
- {BUF_VIDEO_DUCKTM2, CODEC_ID_TRUEMOTION2,"Duck TrueMotion v2 (ffmpeg)"},
- {BUF_VIDEO_VMD, CODEC_ID_VMDVIDEO, "Sierra VMD Video (ffmpeg)"},
- {BUF_VIDEO_ZLIB, CODEC_ID_ZLIB, "ZLIB Video (ffmpeg)"},
- {BUF_VIDEO_MSZH, CODEC_ID_MSZH, "MSZH Video (ffmpeg)"},
- {BUF_VIDEO_ASV1, CODEC_ID_ASV1, "ASV v1 Video (ffmpeg)"},
- {BUF_VIDEO_ASV2, CODEC_ID_ASV2, "ASV v2 Video (ffmpeg)"},
- {BUF_VIDEO_ATIVCR1, CODEC_ID_VCR1, "ATI VCR-1 (ffmpeg)"},
- {BUF_VIDEO_FLV1, CODEC_ID_FLV1, "Flash Video (ffmpeg)"},
- {BUF_VIDEO_QTRLE, CODEC_ID_QTRLE, "Apple Quicktime Animation/RLE (ffmpeg)"},
- {BUF_VIDEO_H264, CODEC_ID_H264, "H.264/AVC (ffmpeg)"},
- {BUF_VIDEO_H261, CODEC_ID_H261, "H.261 (ffmpeg)"},
- {BUF_VIDEO_AASC, CODEC_ID_AASC, "Autodesk Video (ffmpeg)"},
- {BUF_VIDEO_LOCO, CODEC_ID_LOCO, "LOCO (ffmpeg)"},
- {BUF_VIDEO_QDRW, CODEC_ID_QDRAW, "QuickDraw (ffmpeg)"},
- {BUF_VIDEO_QPEG, CODEC_ID_QPEG, "Q-Team QPEG (ffmpeg)"},
- {BUF_VIDEO_TSCC, CODEC_ID_TSCC, "TechSmith Video (ffmpeg)"},
- {BUF_VIDEO_ULTI, CODEC_ID_ULTI, "IBM UltiMotion (ffmpeg)"},
- {BUF_VIDEO_WNV1, CODEC_ID_WNV1, "Winnow Video (ffmpeg)"},
- {BUF_VIDEO_XL, CODEC_ID_VIXL, "Miro/Pinnacle VideoXL (ffmpeg)"},
- {BUF_VIDEO_RT21, CODEC_ID_INDEO2, "Indeo/RealTime 2 (ffmpeg)"},
- {BUF_VIDEO_FPS1, CODEC_ID_FRAPS, "Fraps (ffmpeg)"},
- {BUF_VIDEO_MPEG, CODEC_ID_MPEG1VIDEO, "MPEG 1/2 (ffmpeg)"},
- {BUF_VIDEO_CSCD, CODEC_ID_CSCD, "CamStudio (ffmpeg)"},
- {BUF_VIDEO_AVS, CODEC_ID_AVS, "AVS (ffmpeg)"},
- {BUF_VIDEO_ALGMM, CODEC_ID_MMVIDEO, "American Laser Games MM (ffmpeg)"},
- {BUF_VIDEO_ZMBV, CODEC_ID_ZMBV, "Zip Motion Blocks Video (ffmpeg)"},
- {BUF_VIDEO_SMACKER, CODEC_ID_SMACKVIDEO, "Smacker (ffmpeg)"},
- {BUF_VIDEO_NUV, CODEC_ID_NUV, "NuppelVideo (ffmpeg)"},
- {BUF_VIDEO_KMVC, CODEC_ID_KMVC, "Karl Morton's Video Codec (ffmpeg)"},
- {BUF_VIDEO_FLASHSV, CODEC_ID_FLASHSV, "Flash Screen Video (ffmpeg)"},
- {BUF_VIDEO_CAVS, CODEC_ID_CAVS, "Chinese AVS (ffmpeg)"},
- {BUF_VIDEO_VMNC, CODEC_ID_VMNC, "VMware Screen Codec (ffmpeg)"},
- {BUF_VIDEO_THEORA_RAW, CODEC_ID_THEORA, "Theora (ffmpeg)"},
-};
+#include "ff_video_list.h"
static const char *const skip_loop_filter_enum_names[] = {
"default", /* AVDISCARD_DEFAULT */
@@ -377,7 +322,7 @@ static void init_video_codec (ff_video_decoder_t *this, unsigned int codec_type)
/* Some codecs (eg rv10) copy flags in init so it's necessary to set
* this flag here in case we are going to use direct rendering */
- if(this->codec->capabilities & CODEC_CAP_DR1) {
+ if(this->codec->capabilities & CODEC_CAP_DR1 && this->codec->id != CODEC_ID_H264) {
this->context->flags |= CODEC_FLAG_EMU_EDGE;
}
@@ -589,6 +534,11 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {
int y;
uint8_t *dy, *du, *dv, *sy, *su, *sv;
+#ifdef LOG
+ if (this->debug_fmt != this->context->pix_fmt)
+ printf ("frame format == %08x\n", this->debug_fmt = this->context->pix_fmt);
+#endif
+
dy = img->base[0];
du = img->base[1];
dv = img->base[2];
@@ -596,6 +546,10 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {
su = this->av_frame->data[1];
sv = this->av_frame->data[2];
+ /* Some segfaults & heap corruption have been observed with img->height,
+ * so we use this->bih.biHeight instead (which is the displayed height)
+ */
+
if (this->context->pix_fmt == PIX_FMT_YUV410P) {
yuv9_to_yv12(
@@ -616,7 +570,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {
img->pitches[2],
/* width x height */
img->width,
- img->height);
+ this->bih.biHeight);
} else if (this->context->pix_fmt == PIX_FMT_YUV411P) {
@@ -638,15 +592,15 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {
img->pitches[2],
/* width x height */
img->width,
- img->height);
+ this->bih.biHeight);
- } else if (this->context->pix_fmt == PIX_FMT_RGBA32) {
+ } else if (this->context->pix_fmt == PIX_FMT_RGB32) {
int x, plane_ptr = 0;
uint32_t *argb_pixels;
uint32_t argb;
- for(y = 0; y < img->height; y++) {
+ for(y = 0; y < this->bih.biHeight; y++) {
argb_pixels = (uint32_t *)sy;
for(x = 0; x < img->width; x++) {
uint8_t r, g, b;
@@ -674,7 +628,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {
uint8_t *src;
uint16_t pixel16;
- for(y = 0; y < img->height; y++) {
+ for(y = 0; y < this->bih.biHeight; y++) {
src = sy;
for(x = 0; x < img->width; x++) {
uint8_t r, g, b;
@@ -703,7 +657,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {
uint8_t *src;
uint16_t pixel16;
- for(y = 0; y < img->height; y++) {
+ for(y = 0; y < this->bih.biHeight; y++) {
src = sy;
for(x = 0; x < img->width; x++) {
uint8_t r, g, b;
@@ -731,7 +685,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {
int x, plane_ptr = 0;
uint8_t *src;
- for(y = 0; y < img->height; y++) {
+ for(y = 0; y < this->bih.biHeight; y++) {
src = sy;
for(x = 0; x < img->width; x++) {
uint8_t r, g, b;
@@ -755,7 +709,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {
int x, plane_ptr = 0;
uint8_t *src;
- for(y = 0; y < img->height; y++) {
+ for(y = 0; y < this->bih.biHeight; y++) {
src = sy;
for(x = 0; x < img->width; x++) {
uint8_t r, g, b;
@@ -798,7 +752,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {
v_palette[x] = COMPUTE_V(r, g, b);
}
- for(y = 0; y < img->height; y++) {
+ for(y = 0; y < this->bih.biHeight; y++) {
src = sy;
for(x = 0; x < img->width; x++) {
pixel = *src++;
@@ -815,7 +769,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {
} else {
- for (y=0; y<img->height; y++) {
+ for (y = 0; y < this->bih.biHeight; y++) {
xine_fast_memcpy (dy, sy, img->width);
dy += img->pitches[0];
@@ -823,7 +777,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {
sy += this->av_frame->linesize[0];
}
- for (y=0; y<(img->height/2); y++) {
+ for (y = 0; y < this->bih.biHeight / 2; y++) {
if (this->context->pix_fmt != PIX_FMT_YUV444P) {
@@ -886,7 +840,7 @@ static void ff_handle_preview_buffer (ff_video_decoder_t *this, buf_element_t *b
if (codec_type == BUF_VIDEO_MPEG) {
this->is_mpeg12 = 1;
if ( this->mpeg_parser == NULL ) {
- this->mpeg_parser = xine_xmalloc(sizeof(mpeg_parser_t));
+ this->mpeg_parser = calloc(1, sizeof(mpeg_parser_t));
mpeg_parser_init(this->mpeg_parser);
this->decoder_init_mode = 0;
}
@@ -941,9 +895,29 @@ static void ff_handle_header_buffer (ff_video_decoder_t *this, buf_element_t *bu
this->context->sub_id = _X_BE_32(&this->buf[30]);
- this->context->slice_offset = xine_xmalloc(sizeof(int)*SLICE_OFFSET_SIZE);
+ this->context->slice_offset = calloc(SLICE_OFFSET_SIZE, sizeof(int));
this->slice_offset_size = SLICE_OFFSET_SIZE;
+ this->context->extradata_size = this->size - 26;
+ if (this->context->extradata_size < 8) {
+ this->context->extradata_size= 8;
+ this->context->extradata = malloc(this->context->extradata_size +
+ FF_INPUT_BUFFER_PADDING_SIZE);
+ ((uint32_t *)this->context->extradata)[0] = 0;
+ if (codec_type == BUF_VIDEO_RV10)
+ ((uint32_t *)this->context->extradata)[1] = 0x10000000;
+ else
+ ((uint32_t *)this->context->extradata)[1] = 0x10003001;
+ } else {
+ this->context->extradata = malloc(this->context->extradata_size +
+ FF_INPUT_BUFFER_PADDING_SIZE);
+ memcpy(this->context->extradata, this->buf + 26,
+ this->context->extradata_size);
+ }
+
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ "ffmpeg_video_dec: buf size %d\n", this->size);
+
lprintf("w=%d, h=%d\n", this->bih.biWidth, this->bih.biHeight);
break;
@@ -969,8 +943,8 @@ static void ff_handle_special_buffer (ff_video_decoder_t *this, buf_element_t *b
lprintf("BUF_SPECIAL_STSD_ATOM\n");
this->context->extradata_size = buf->decoder_info[2];
- this->context->extradata = xine_xmalloc(buf->decoder_info[2] +
- FF_INPUT_BUFFER_PADDING_SIZE);
+ this->context->extradata = malloc(buf->decoder_info[2] +
+ FF_INPUT_BUFFER_PADDING_SIZE);
memcpy(this->context->extradata, buf->decoder_info_ptr[2],
buf->decoder_info[2]);
@@ -979,8 +953,8 @@ static void ff_handle_special_buffer (ff_video_decoder_t *this, buf_element_t *b
lprintf("BUF_SPECIAL_DECODER_CONFIG\n");
this->context->extradata_size = buf->decoder_info[2];
- this->context->extradata = xine_xmalloc(buf->decoder_info[2] +
- FF_INPUT_BUFFER_PADDING_SIZE);
+ this->context->extradata = malloc(buf->decoder_info[2] +
+ FF_INPUT_BUFFER_PADDING_SIZE);
memcpy(this->context->extradata, buf->decoder_info_ptr[2],
buf->decoder_info[2]);
@@ -1144,6 +1118,54 @@ static void ff_handle_mpeg12_buffer (ff_video_decoder_t *this, buf_element_t *bu
}
}
+#ifdef AVCODEC_HAS_REORDERED_OPAQUE
+static uint64_t ff_tag_pts(ff_video_decoder_t *this, uint64_t pts)
+{
+ return pts | this->pts_tag;
+}
+
+static uint64_t ff_untag_pts(ff_video_decoder_t *this, uint64_t pts)
+{
+ if (this->pts_tag_mask == 0)
+ return pts; /* pts tagging inactive */
+
+ if (this->pts_tag != 0 && (pts & this->pts_tag_mask) != this->pts_tag)
+ return 0; /* reset pts if outdated while waiting for first pass (see below) */
+
+ return pts & ~this->pts_tag_mask;
+}
+
+static void ff_check_pts_tagging(ff_video_decoder_t *this, uint64_t pts)
+{
+ if (this->pts_tag_mask == 0)
+ return; /* pts tagging inactive */
+ if ((pts & this->pts_tag_mask) != this->pts_tag) {
+ this->pts_tag_stable_counter = 0;
+ return; /* pts still outdated */
+ }
+
+ /* the tag should be stable for 100 frames */
+ this->pts_tag_stable_counter++;
+
+ if (this->pts_tag != 0) {
+ if (this->pts_tag_stable_counter >= 100) {
+ /* first pass: reset pts_tag */
+ this->pts_tag = 0;
+ this->pts_tag_stable_counter = 0;
+ }
+ } else if (pts == 0)
+ return; /* cannot detect second pass */
+ else {
+ if (this->pts_tag_stable_counter >= 100) {
+ /* second pass: reset pts_tag_mask and pts_tag_counter */
+ this->pts_tag_mask = 0;
+ this->pts_tag_counter = 0;
+ this->pts_tag_stable_counter = 0;
+ }
+ }
+}
+
+#endif /* AVCODEC_HAS_REORDERED_OPAQUE */
static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
uint8_t *chunk_buf = this->buf;
AVRational avr00 = {0, 1};
@@ -1168,6 +1190,15 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
this->size = 0;
}
+#ifdef AVCODEC_HAS_REORDERED_OPAQUE
+ if (this->size == 0) {
+ /* take over pts when we are about to buffer a frame */
+ this->av_frame->reordered_opaque = ff_tag_pts(this, this->pts);
+ this->context->reordered_opaque = ff_tag_pts(this, this->pts);
+ this->pts = 0;
+ }
+#endif /* AVCODEC_HAS_REORDERED_OPAQUE */
+
/* data accumulation */
if (buf->size > 0) {
if ((this->size == 0) &&
@@ -1220,6 +1251,12 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
len = avcodec_decode_video (this->context, this->av_frame,
&got_picture, &chunk_buf[offset],
this->size);
+
+#ifdef AVCODEC_HAS_REORDERED_OPAQUE
+ /* reset consumed pts value */
+ this->context->reordered_opaque = ff_tag_pts(this, 0);
+#endif /* AVCODEC_HAS_REORDERED_OPAQUE */
+
lprintf("consumed size: %d, got_picture: %d\n", len, got_picture);
if ((len <= 0) || (len > this->size)) {
xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
@@ -1235,12 +1272,27 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
ff_check_bufsize(this, this->size);
memmove (this->buf, &chunk_buf[offset], this->size);
chunk_buf = this->buf;
+
+#ifdef AVCODEC_HAS_REORDERED_OPAQUE
+ /* take over pts for next access unit */
+ this->av_frame->reordered_opaque = ff_tag_pts(this, this->pts);
+ this->context->reordered_opaque = ff_tag_pts(this, this->pts);
+ this->pts = 0;
+#endif /* AVCODEC_HAS_REORDERED_OPAQUE */
}
}
}
/* use externally provided video_step or fall back to stream's time_base otherwise */
- video_step_to_use = (this->video_step || !this->context->time_base.den) ? this->video_step : (int)(90000ll * this->context->time_base.num / this->context->time_base.den);
+ video_step_to_use = (this->video_step || !this->context->time_base.den)
+ ? this->video_step
+ : (int)(90000ll
+#if LIBAVCODEC_VERSION_INT >= 0x341400
+ * this->context->ticks_per_frame
+#elif LIBAVCODEC_VERSION_INT >= 0x340000
+# warning Building without avcodec ticks_per_frame support; you should upgrade your libavcodec and recompile
+#endif
+ * this->context->time_base.num / this->context->time_base.den);
/* aspect ratio provided by ffmpeg, override previous setting */
if ((this->aspect_ratio_prio < 2) &&
@@ -1266,7 +1318,7 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
/* initialize the colorspace converter */
if (!this->cs_convert_init) {
- if ((this->context->pix_fmt == PIX_FMT_RGBA32) ||
+ if ((this->context->pix_fmt == PIX_FMT_RGB32) ||
(this->context->pix_fmt == PIX_FMT_RGB565) ||
(this->context->pix_fmt == PIX_FMT_RGB555) ||
(this->context->pix_fmt == PIX_FMT_BGR24) ||
@@ -1329,15 +1381,24 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
ff_convert_frame(this, img);
}
+#ifndef AVCODEC_HAS_REORDERED_OPAQUE
img->pts = this->pts;
this->pts = 0;
+#else /* AVCODEC_HAS_REORDERED_OPAQUE */
+ img->pts = ff_untag_pts(this, this->av_frame->reordered_opaque);
+ ff_check_pts_tagging(this, this->av_frame->reordered_opaque); /* only check for valid frames */
+ this->av_frame->reordered_opaque = 0;
+#endif /* AVCODEC_HAS_REORDERED_OPAQUE */
/* workaround for weird 120fps streams */
if( video_step_to_use == 750 ) {
/* fallback to the VIDEO_PTS_MODE */
video_step_to_use = 0;
}
-
+
+ if (video_step_to_use && video_step_to_use != this->reported_video_step)
+ _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, (this->reported_video_step = video_step_to_use));
+
if (this->av_frame->repeat_pict)
img->duration = video_step_to_use * 3 / 2;
else
@@ -1370,8 +1431,13 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
this->output_format,
VO_BOTH_FIELDS|this->frame_flags);
/* set PTS to allow early syncing */
+#ifndef AVCODEC_HAS_REORDERED_OPAQUE
img->pts = this->pts;
this->pts = 0;
+#else /* AVCODEC_HAS_REORDERED_OPAQUE */
+ img->pts = ff_untag_pts(this, this->av_frame->reordered_opaque);
+ this->av_frame->reordered_opaque = 0;
+#endif /* AVCODEC_HAS_REORDERED_OPAQUE */
img->duration = video_step_to_use;
@@ -1396,7 +1462,7 @@ static void ff_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
if (buf->decoder_flags & BUF_FLAG_FRAMERATE) {
this->video_step = buf->decoder_info[0];
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->video_step);
+ _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, (this->reported_video_step = this->video_step));
}
if (buf->decoder_flags & BUF_FLAG_PREVIEW) {
@@ -1456,6 +1522,13 @@ static void ff_reset (video_decoder_t *this_gen) {
if (this->is_mpeg12)
mpeg_parser_reset(this->mpeg_parser);
+
+#ifdef AVCODEC_HAS_REORDERED_OPAQUE
+ this->pts_tag_mask = 0;
+ this->pts_tag = 0;
+ this->pts_tag_counter = 0;
+ this->pts_tag_stable_counter = 0;
+#endif /* AVCODEC_HAS_REORDERED_OPAQUE */
}
static void ff_discontinuity (video_decoder_t *this_gen) {
@@ -1463,6 +1536,41 @@ static void ff_discontinuity (video_decoder_t *this_gen) {
lprintf ("ff_discontinuity\n");
this->pts = 0;
+
+#ifdef AVCODEC_HAS_REORDERED_OPAQUE
+ /*
+ * there is currently no way to reset all the pts which are stored in the decoder.
+ * therefore, we add a unique tag (generated from pts_tag_counter) to pts (see
+ * ff_tag_pts()) and wait for it to appear on returned frames.
+ * until then, any retrieved pts value will be reset to 0 (see ff_untag_pts()).
+ * when we see the tag returned, pts_tag will be reset to 0. from now on, any
+ * untagged pts value is valid already.
+ * when tag 0 appears too, there are no tags left in the decoder so pts_tag_mask
+ * and pts_tag_counter will be reset to 0 too (see ff_check_pts_tagging()).
+ */
+ this->pts_tag_counter++;
+ this->pts_tag_mask = 0;
+ this->pts_tag = 0;
+ this->pts_tag_stable_counter = 0;
+ {
+ /* pts values typically don't use the uppermost bits. therefore we put the tag there */
+ int counter_mask = 1;
+ int counter = 2 * this->pts_tag_counter + 1; /* always set the uppermost bit in tag_mask */
+ uint64_t tag_mask = 0x8000000000000000ull;
+ while (this->pts_tag_counter >= counter_mask)
+ {
+ /*
+ * mirror the counter into the uppermost bits. this allows us to enlarge mask as
+ * necessary and while previous taggings can still be detected to be outdated.
+ */
+ if (counter & counter_mask)
+ this->pts_tag |= tag_mask;
+ this->pts_tag_mask |= tag_mask;
+ tag_mask >>= 1;
+ counter_mask <<= 1;
+ }
+ }
+#endif /* AVCODEC_HAS_REORDERED_OPAQUE */
}
static void ff_dispose (video_decoder_t *this_gen) {
@@ -1500,10 +1608,10 @@ static void ff_dispose (video_decoder_t *this_gen) {
free_yuv_planes(&this->yuv);
if( this->context )
- free( this->context );
+ av_free( this->context );
if( this->av_frame )
- free( this->av_frame );
+ av_free( this->av_frame );
if (this->buf)
free(this->buf);
@@ -1528,7 +1636,7 @@ static video_decoder_t *ff_video_open_plugin (video_decoder_class_t *class_gen,
lprintf ("open_plugin\n");
- this = (ff_video_decoder_t *) xine_xmalloc (sizeof (ff_video_decoder_t));
+ this = calloc(1, sizeof (ff_video_decoder_t));
this->video_decoder.decode_data = ff_decode_data;
this->video_decoder.flush = ff_flush;
@@ -1547,7 +1655,7 @@ static video_decoder_t *ff_video_open_plugin (video_decoder_class_t *class_gen,
this->decoder_ok = 0;
this->decoder_init_mode = 1;
- this->buf = xine_xmalloc(VIDEOBUFSIZE + FF_INPUT_BUFFER_PADDING_SIZE);
+ this->buf = calloc(1, VIDEOBUFSIZE + FF_INPUT_BUFFER_PADDING_SIZE);
this->bufsize = VIDEOBUFSIZE;
this->is_mpeg12 = 0;
@@ -1561,6 +1669,10 @@ static video_decoder_t *ff_video_open_plugin (video_decoder_class_t *class_gen,
this->dr1_frames = xine_list_new();
+#ifdef LOG
+ this->debug_fmt = -1;
+#endif
+
return &this->video_decoder;
}
@@ -1581,7 +1693,7 @@ void *init_video_plugin (xine_t *xine, void *data) {
ff_video_class_t *this;
config_values_t *config;
- this = (ff_video_class_t *) xine_xmalloc (sizeof (ff_video_class_t));
+ this = calloc(1, sizeof (ff_video_class_t));
this->decoder_class.open_plugin = ff_video_open_plugin;
this->decoder_class.get_identifier = ff_video_get_identifier;
@@ -1635,234 +1747,6 @@ void *init_video_plugin (xine_t *xine, void *data) {
return this;
}
-static uint32_t supported_video_types[] = {
- #ifdef CONFIG_MSMPEG4V1_DECODER
- BUF_VIDEO_MSMPEG4_V1,
- #endif
- #ifdef CONFIG_MSMPEG4V2_DECODER
- BUF_VIDEO_MSMPEG4_V2,
- #endif
- #ifdef CONFIG_MSMPEG4V3_DECODER
- BUF_VIDEO_MSMPEG4_V3,
- #endif
- #ifdef CONFIG_WMV1_DECODER
- BUF_VIDEO_WMV7,
- #endif
- #ifdef CONFIG_WMV2_DECODER
- BUF_VIDEO_WMV8,
- #endif
- #ifdef CONFIG_WMV3_DECODER
- BUF_VIDEO_WMV9,
- #endif
- #ifdef CONFIG_VC1_DECODER
- BUF_VIDEO_VC1,
- #endif
- #ifdef CONFIG_MPEG4_DECODER
- BUF_VIDEO_MPEG4,
- #endif
- #ifdef CONFIG_MPEG4_DECODER
- BUF_VIDEO_XVID,
- #endif
- #ifdef CONFIG_MPEG4_DECODER
- BUF_VIDEO_DIVX5,
- #endif
- #ifdef CONFIG_MPEG4_DECODER
- BUF_VIDEO_3IVX,
- #endif
- #ifdef CONFIG_MJPEG_DECODER
- BUF_VIDEO_JPEG,
- #endif
- #ifdef CONFIG_MJPEG_DECODER
- BUF_VIDEO_MJPEG,
- #endif
- #ifdef CONFIG_MJPEGB_DECODER
- BUF_VIDEO_MJPEG_B,
- #endif
- #ifdef CONFIG_H263I_DECODER
- BUF_VIDEO_I263,
- #endif
- #ifdef CONFIG_H263_DECODER
- BUF_VIDEO_H263,
- #endif
- #ifdef CONFIG_RV10_DECODER
- BUF_VIDEO_RV10,
- #endif
- #ifdef CONFIG_RV20_DECODER
- BUF_VIDEO_RV20,
- #endif
- #ifdef CONFIG_INDEO3_DECODER
- BUF_VIDEO_IV31,
- #endif
- #ifdef CONFIG_INDEO3_DECODER
- BUF_VIDEO_IV32,
- #endif
- #ifdef CONFIG_SVQ1_DECODER
- BUF_VIDEO_SORENSON_V1,
- #endif
- #ifdef CONFIG_SVQ3_DECODER
- BUF_VIDEO_SORENSON_V3,
- #endif
- #ifdef CONFIG_DVVIDEO_DECODER
- BUF_VIDEO_DV,
- #endif
- #ifdef CONFIG_HUFFYUV_DECODER
- BUF_VIDEO_HUFFYUV,
- #endif
- #ifdef CONFIG_VP3_DECODER
- BUF_VIDEO_VP31,
- #endif
- #ifdef CONFIG_VP5_DECODER
- BUF_VIDEO_VP5,
- #endif
- #ifdef CONFIG_VP6_DECODER
- BUF_VIDEO_VP6,
- BUF_VIDEO_VP6F,
- #endif
- #ifdef CONFIG_4XM_DECODER
- BUF_VIDEO_4XM,
- #endif
- #ifdef CONFIG_CINEPAK_DECODER
- BUF_VIDEO_CINEPAK,
- #endif
- #ifdef CONFIG_MSVIDEO1_DECODER
- BUF_VIDEO_MSVC,
- #endif
- #ifdef CONFIG_MSRLE_DECODER
- BUF_VIDEO_MSRLE,
- #endif
- #ifdef CONFIG_RPZA_DECODER
- BUF_VIDEO_RPZA,
- #endif
- #ifdef CONFIG_CYUV_DECODER
- BUF_VIDEO_CYUV,
- #endif
- #ifdef CONFIG_ROQ_DECODER
- BUF_VIDEO_ROQ,
- #endif
- #ifdef CONFIG_IDCIN_DECODER
- BUF_VIDEO_IDCIN,
- #endif
- #ifdef CONFIG_XAN_WC3_DECODER
- BUF_VIDEO_WC3,
- #endif
- #ifdef CONFIG_WS_VQA_DECODER
- BUF_VIDEO_VQA,
- #endif
- #ifdef CONFIG_INTERPLAY_VIDEO_DECODER
- BUF_VIDEO_INTERPLAY,
- #endif
- #ifdef CONFIG_FLIC_DECODER
- BUF_VIDEO_FLI,
- #endif
- #ifdef CONFIG_8BPS_DECODER
- BUF_VIDEO_8BPS,
- #endif
- #ifdef CONFIG_SMC_DECODER
- BUF_VIDEO_SMC,
- #endif
- #ifdef CONFIG_TRUEMOTION1_DECODER
- BUF_VIDEO_DUCKTM1,
- #endif
- #ifdef CONFIG_TRUEMOTION2_DECODER
- BUF_VIDEO_DUCKTM2,
- #endif
- #ifdef CONFIG_VMDVIDEO_DECODER
- BUF_VIDEO_VMD,
- #endif
- #ifdef CONFIG_ZLIB_DECODER
- BUF_VIDEO_ZLIB,
- #endif
- #ifdef CONFIG_MSZH_DECODER
- BUF_VIDEO_MSZH,
- #endif
- #ifdef CONFIG_ASV1_DECODER
- BUF_VIDEO_ASV1,
- #endif
- #ifdef CONFIG_ASV2_DECODER
- BUF_VIDEO_ASV2,
- #endif
- #ifdef CONFIG_VCR1_DECODER
- BUF_VIDEO_ATIVCR1,
- #endif
- #ifdef CONFIG_FLV_DECODER
- BUF_VIDEO_FLV1,
- #endif
- #ifdef CONFIG_QTRLE_DECODER
- BUF_VIDEO_QTRLE,
- #endif
- #ifdef CONFIG_H264_DECODER
- BUF_VIDEO_H264,
- #endif
- #ifdef CONFIG_H261_DECODER
- BUF_VIDEO_H261,
- #endif
- #ifdef CONFIG_AASC_DECODER
- BUF_VIDEO_AASC,
- #endif
- #ifdef CONFIG_LOCO_DECODER
- BUF_VIDEO_LOCO,
- #endif
- #ifdef CONFIG_QDRAW_DECODER
- BUF_VIDEO_QDRW,
- #endif
- #ifdef CONFIG_QPEG_DECODER
- BUF_VIDEO_QPEG,
- #endif
- #ifdef CONFIG_TSCC_DECODER
- BUF_VIDEO_TSCC,
- #endif
- #ifdef CONFIG_ULTI_DECODER
- BUF_VIDEO_ULTI,
- #endif
- #ifdef CONFIG_WNV1_DECODER
- BUF_VIDEO_WNV1,
- #endif
- #ifdef CONFIG_VIXL_DECODER
- BUF_VIDEO_XL,
- #endif
- #ifdef CONFIG_INDEO2_DECODER
- BUF_VIDEO_RT21,
- #endif
- #ifdef CONFIG_FRAPS_DECODER
- BUF_VIDEO_FPS1,
- #endif
- #ifdef CONFIG_MPEG1VIDEO_DECODER
- BUF_VIDEO_MPEG,
- #endif
- #ifdef CONFIG_CSCD_DECODER
- BUF_VIDEO_CSCD,
- #endif
- #ifdef CONFIG_AVS_DECODER
- BUF_VIDEO_AVS,
- #endif
- #ifdef CONFIG_MMVIDEO_DECODER
- BUF_VIDEO_ALGMM,
- #endif
- #ifdef CONFIG_ZMBV_DECODER
- BUF_VIDEO_ZMBV,
- #endif
- #ifdef CONFIG_SMACKVIDEO_DECODER
- BUF_VIDEO_SMACKER,
- #endif
- #ifdef CONFIG_NUV_DECODER
- BUF_VIDEO_NUV,
- #endif
- #ifdef CONFIG_KMVC_DECODER
- BUF_VIDEO_KMVC,
- #endif
- #ifdef CONFIG_FLASHSV_DECODER
- BUF_VIDEO_FLASHSV,
- #endif
- #ifdef CONFIG_CAVS_DECODER
- BUF_VIDEO_CAVS,
- #endif
- #ifdef CONFIG_VMNC_DECODER
- BUF_VIDEO_VMNC,
- #endif
- BUF_VIDEO_THEORA_RAW,
- 0
-};
-
static uint32_t wmv8_video_types[] = {
BUF_VIDEO_WMV8,
0
diff --git a/src/libffmpeg/ffmpeg_decoder.c b/src/combined/ffmpeg/ffmpeg_decoder.c
index d0175184f..776e07df9 100644
--- a/src/libffmpeg/ffmpeg_decoder.c
+++ b/src/combined/ffmpeg/ffmpeg_decoder.c
@@ -22,7 +22,7 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
-#include "ffmpeg_config.h"
+#include "../../libffmpeg/ffmpeg_config.h"
#endif
#include "xine_internal.h"
diff --git a/src/libffmpeg/ffmpeg_decoder.h b/src/combined/ffmpeg/ffmpeg_decoder.h
index 14788cf29..0f4ff1f1e 100644
--- a/src/libffmpeg/ffmpeg_decoder.h
+++ b/src/combined/ffmpeg/ffmpeg_decoder.h
@@ -25,10 +25,16 @@
#include "config.h"
#endif
-#ifdef HAVE_FFMPEG
+#ifdef HAVE_FFMPEG_AVUTIL_H
# include <avcodec.h>
+#elif defined HAVE_FFMPEG
+# include <libavcodec/avcodec.h>
#else
-# include "libavcodec/avcodec.h"
+# include "../../libffmpeg/libavcodec/avcodec.h"
+#endif
+
+#if LIBAVCODEC_VERSION_MAJOR > 51
+#define bits_per_sample bits_per_coded_sample
#endif
typedef struct ff_codec_s {
diff --git a/src/libffmpeg/ffmpeg_encoder.c b/src/combined/ffmpeg/ffmpeg_encoder.c
index c8a450b0d..84243a56f 100644
--- a/src/libffmpeg/ffmpeg_encoder.c
+++ b/src/combined/ffmpeg/ffmpeg_encoder.c
@@ -38,10 +38,12 @@
#include "video_out_dxr3.h"
-#ifdef HAVE_FFMPEG
+#ifdef HAVE_FFMPEG_AVUTIL_H
# include <avcodec.h>
+#elif defined HAVE_FFMPEG
+# include <libavcodec/avcodec.h>
#else
-# include "libavcodec/avcodec.h"
+# include "../../libffmpeg/libavcodec/avcodec.h"
#endif
/* buffer size for encoded mpeg1 stream; will hold one intra frame
@@ -76,7 +78,7 @@ int dxr3_encoder_init(dxr3_driver_t *drv)
avcodec_register_all();
lprintf("lavc init , version %x\n", avcodec_version());
- this = xine_xmalloc(sizeof(lavc_data_t));
+ this = calloc(1, sizeof(lavc_data_t));
if (!this) return 0;
this->encoder_data.type = ENC_LAVC;
diff --git a/src/combined/ffmpeg/mkcodeclist.pl b/src/combined/ffmpeg/mkcodeclist.pl
new file mode 100755
index 000000000..b4a10921a
--- /dev/null
+++ b/src/combined/ffmpeg/mkcodeclist.pl
@@ -0,0 +1,95 @@
+#! /usr/bin/perl -w
+
+# Make codec lists for #inclusion by ff_*_decoder.c.
+# Parameters:
+# list of ffmpeg CODEC_ID_* (pre-processed, one per line)
+# list of codecs recognised by xine-lib (see list for details)
+# output file name, or "-" to generate a report on unhandled codecs
+
+my ($ffmpeg, $xine, $out) = @ARGV;
+my $line;
+
+# Read in the ffmpeg codec IDs
+my %codecs;
+open LIST, "< $ffmpeg" or die $!;
+$line = <LIST>;
+while (defined $line) {
+ chomp $line;
+ $line =~ s/^CODEC_ID_//o;
+ $codecs{$line} = 0;
+ $line = <LIST>;
+}
+close LIST or die $!;
+
+# Read in the xine-lib codec IDs
+my %config;
+my @known;
+my $type = 'audio'; # default type
+my $Type = 'AUDIO';
+my ($a, $f, $t);
+open LIST, "< $xine" or die $!;
+while (defined ($line = <LIST>)) {
+ next if substr ($line, 0, 1) eq '#' or $line =~ /^\s*$/o;
+ chomp $line;
+ if (substr ($line, 0, 5) eq 'type=') {
+ # codec type; "FOO" in "BUF_FOO_BAR"
+ $type = substr ($line, 5);
+ $type =~ tr/A-Z/a-z/;
+ $Type = $type;
+ $Type =~ tr/a-z/A-Z/;
+ } elsif (substr ($line, 0, 7) eq 'config=') {
+ # "#ifdef CONFIG_FOO_DECODER" mappings
+ ($a, $f, $t) = split (/=/, $line, 3);
+ $config{$f} = $t;
+ } else {
+ # codec details
+ push @known, [split (/\s+/, $line, 3)];
+ }
+}
+close LIST or die $!;
+
+# Look through the mappings.
+# Mark what we can handle and report on what the installed ffmpeg can't
+foreach $line (@known) {
+ if (defined $codecs{$line->[1]}) {
+ ++$codecs{$line->[1]};
+ } else {
+ print "Ignored $line->[0] = $line->[1]\n";
+ }
+}
+
+my $w = ($out ne '-');
+
+if ($w) {
+ # Write the C source code for the codec lists
+ open LIST, "> $out" or die $!;
+ print LIST "static const ff_codec_t ff_${type}_lookup[] = {\n" or die $!;
+ foreach $line (@known) {
+ next if $line->[0] eq '!';
+ next unless defined $codecs{$line->[1]};
+ print LIST " { BUF_${Type}_$line->[0], CODEC_ID_$line->[1], \"$line->[2] (ffmpeg)\" },\n" or die $!;
+ }
+ print LIST "};\n\nstatic uint32_t supported_${type}_types[] = {\n" or die $!;
+ foreach $line (@known) {
+ next if $line->[0] eq '!';
+ next unless defined $codecs{$line->[1]};
+ $a = $line->[1];
+ $a = $config{$a} if defined $config{$a};
+ if ($a eq '') {
+ print LIST " BUF_${Type}_$line->[0],\n" or die $!;
+ } else {
+ print LIST " #ifdef CONFIG_${a}_DECODER\n BUF_${Type}_$line->[0],\n #endif\n" or die $!;
+ }
+ }
+ print LIST " 0,\n};\n" or die $!;
+ close LIST or die $!;
+}
+else {
+ # Report on ffmpeg codecs which we don't handle
+ print "Unhandled $type codecs:\n";
+ foreach $line (sort keys %codecs) {
+ print " $line\n" if $codecs{$line} == 0;
+ }
+}
+
+exit 0;
diff --git a/src/combined/ffmpeg/xine_audio.list b/src/combined/ffmpeg/xine_audio.list
new file mode 100644
index 000000000..4b6932474
--- /dev/null
+++ b/src/combined/ffmpeg/xine_audio.list
@@ -0,0 +1,55 @@
+type=audio
+config=MP3ADU=
+
+# xine-lib BUF_AUDIO_ ffmpeg CODEC_ID_ description or comment
+# ("!"=ignore) (quote any "s)
+
+WMAV1 WMAV1 MS Windows Media Audio 1
+WMAV2 WMAV2 MS Windows Media Audio 2
+14_4 RA_144 Real 14.4
+28_8 RA_288 Real 28.8
+MPEG MP3 MP3
+MP3ADU MP3ADU MPEG-3 adu
+MSADPCM ADPCM_MS MS ADPCM
+QTIMAADPCM ADPCM_IMA_QT QT IMA ADPCM
+MSIMAADPCM ADPCM_IMA_WAV MS IMA ADPCM
+DK3ADPCM ADPCM_IMA_DK3 Duck DK3 ADPCM
+DK4ADPCM ADPCM_IMA_DK4 Duck DK4 ADPCM
+VQA_IMA ADPCM_IMA_WS Westwood Studios IMA
+SMJPEG_IMA ADPCM_IMA_SMJPEG SMJPEG IMA
+XA_ADPCM ADPCM_XA CD-ROM/XA ADPCM
+4X_ADPCM ADPCM_4XM 4X ADPCM
+EA_ADPCM ADPCM_EA Electronic Arts ADPCM
+MULAW PCM_MULAW mu-law logarithmic PCM
+ALAW PCM_ALAW A-law logarithmic PCM
+ROQ ROQ_DPCM RoQ DPCM
+INTERPLAY INTERPLAY_DPCM Interplay DPCM
+MAC3 MACE3 MACE 3:1
+MAC6 MACE6 MACE 6:1
+XAN_DPCM XAN_DPCM Origin Xan DPCM
+VMD VMDAUDIO Sierra VMD Audio
+FLAC FLAC FLAC
+SHORTEN SHORTEN Shorten
+ALAC ALAC ALAC
+QDESIGN2 QDM2 QDesign
+COOK COOK RealAudio Cooker
+TRUESPEECH TRUESPEECH TrueSpeech
+TTA TTA True Audio Lossless
+SMACKER SMACKAUDIO Smacker
+FLVADPCM ADPCM_SWF Flash ADPCM
+WAVPACK WAVPACK WavPack
+AMR_NB AMR_NB AMR narrow band
+AMR_WB AMR_WB AMR wide band
+
+# disabled codecs (ref. configure.ac)
+! AAC
+! AC3
+! ADPCM_ADX
+! ADPCM_G726
+! DSICINAUDIO
+! DVAUDIO
+! IMC
+! MP3ON4
+! SONIC
+! SONIC_LS
+! VORBIS
diff --git a/src/combined/ffmpeg/xine_video.list b/src/combined/ffmpeg/xine_video.list
new file mode 100644
index 000000000..a3c961d13
--- /dev/null
+++ b/src/combined/ffmpeg/xine_video.list
@@ -0,0 +1,109 @@
+type=video
+config=VP6F=VP6
+config=FLV1=FLV
+config=THEORA=
+
+# xine-lib BUF_VIDEO_ ffmpeg CODEC_ID_ description or comment
+# ("!"=ignore) (quote any "s)
+
+MSMPEG4_V1 MSMPEG4V1 Microsoft MPEG-4 v1
+MSMPEG4_V2 MSMPEG4V2 Microsoft MPEG-4 v2
+MSMPEG4_V3 MSMPEG4V3 Microsoft MPEG-4 v3
+WMV7 WMV1 MS Windows Media Video 7
+WMV8 WMV2 MS Windows Media Video 8
+WMV9 WMV3 MS Windows Media Video 9
+VC1 VC1 MS Windows Media Video VC-1
+MPEG4 MPEG4 ISO MPEG-4
+XVID MPEG4 ISO MPEG-4 (XviD)
+DIVX5 MPEG4 ISO MPEG-4 (DivX5)
+3IVX MPEG4 ISO MPEG-4 (3ivx)
+JPEG MJPEG Motion JPEG
+MJPEG MJPEG Motion JPEG
+MJPEG_B MJPEGB Motion JPEG B
+I263 H263I ITU H.263
+H263 H263 H.263
+RV10 RV10 Real Video 1.0
+RV20 RV20 Real Video 2.0
+IV31 INDEO3 Indeo Video 3.1
+IV32 INDEO3 Indeo Video 3.2
+SORENSON_V1 SVQ1 Sorenson Video 1
+SORENSON_V3 SVQ3 Sorenson Video 3
+DV DVVIDEO DV
+HUFFYUV HUFFYUV HuffYUV
+VP31 VP3 On2 VP3.1
+VP5 VP5 On2 VP5
+VP6 VP6 On2 VP6
+VP6F VP6F On2 VP6
+4XM 4XM 4X Video
+CINEPAK CINEPAK Cinepak
+MSVC MSVIDEO1 Microsoft Video 1
+MSRLE MSRLE Microsoft RLE
+RPZA RPZA Apple Quicktime Video/RPZA
+CYUV CYUV Creative YUV
+ROQ ROQ Id Software RoQ
+IDCIN IDCIN Id Software CIN
+WC3 XAN_WC3 Xan
+VQA WS_VQA Westwood Studios VQA
+INTERPLAY INTERPLAY_VIDEO Interplay MVE
+FLI FLIC FLIC Video
+8BPS 8BPS Planar RGB
+SMC SMC Apple Quicktime Graphics/SMC
+DUCKTM1 TRUEMOTION1 Duck TrueMotion v1
+DUCKTM2 TRUEMOTION2 Duck TrueMotion v2
+VMD VMDVIDEO Sierra VMD Video
+ZLIB ZLIB ZLIB Video
+MSZH MSZH MSZH Video
+ASV1 ASV1 ASV v1 Video
+ASV2 ASV2 ASV v2 Video
+ATIVCR1 VCR1 ATI VCR-1
+FLV1 FLV1 Flash Video
+QTRLE QTRLE Apple Quicktime Animation/RLE
+H264 H264 H.264/AVC
+H261 H261 H.261
+AASC AASC Autodesk Video
+LOCO LOCO LOCO
+QDRW QDRAW QuickDraw
+QPEG QPEG Q-Team QPEG
+TSCC TSCC TechSmith Video
+ULTI ULTI IBM UltiMotion
+WNV1 WNV1 Winnow Video
+XL VIXL Miro/Pinnacle VideoXL
+RT21 INDEO2 Indeo/RealTime 2
+FPS1 FRAPS Fraps
+MPEG MPEG1VIDEO MPEG 1/2
+CSCD CSCD CamStudio
+AVS AVS AVS
+ALGMM MMVIDEO American Laser Games MM
+ZMBV ZMBV Zip Motion Blocks Video
+SMACKER SMACKVIDEO Smacker
+NUV NUV NuppelVideo
+KMVC KMVC Karl Morton's Video Codec
+FLASHSV FLASHSV Flash Screen Video
+CAVS CAVS Chinese AVS
+VMNC VMNC VMware Screen Codec
+THEORA_RAW THEORA Theora
+SNOW SNOW Snow
+
+# disabled codecs (ref. configure.ac)
+! BMP
+! CLJR
+! DSICINVIDEO
+! FFV1
+! FFVHUFF
+! GIF
+! H263P
+! JPEGLS
+! LJPEG
+! MDEC
+! PAM
+! PBM
+! PGM
+! PGMYUV
+! PNG
+! PPM
+! RAWVIDEO
+! SP5X
+! TARGA
+! TIERTEXSEQVIDEO
+! TIFF
+! XVID ⇒ MPEG4
diff --git a/src/demuxers/Makefile.am b/src/demuxers/Makefile.am
index ffbfa0a8d..3bc1103ec 100644
--- a/src/demuxers/Makefile.am
+++ b/src/demuxers/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
AM_CFLAGS = $(VISIBILITY_FLAG)
@@ -70,10 +71,10 @@ xineplug_dmx_mpeg_pes_la_SOURCES = demux_mpeg_pes.c
xineplug_dmx_mpeg_pes_la_LIBADD = $(XINE_LIB) $(LTLIBINTL)
xineplug_dmx_mpeg_ts_la_SOURCES = demux_ts.c
-xineplug_dmx_mpeg_ts_la_LIBADD = $(XINE_LIB)
+xineplug_dmx_mpeg_ts_la_LIBADD = $(XINE_LIB) $(LTLIBINTL)
xineplug_dmx_qt_la_SOURCES = demux_qt.c
-xineplug_dmx_qt_la_LIBADD = $(XINE_LIB) $(ZLIB_LIBS)
+xineplug_dmx_qt_la_LIBADD = $(XINE_LIB) $(ZLIB_LIBS) $(LTLIBINTL)
xineplug_dmx_qt_la_CPPFLAGS = $(ZLIB_CPPFLAGS)
xineplug_dmx_asf_la_SOURCES = demux_asf.c asfheader.c
@@ -130,7 +131,7 @@ xineplug_dmx_nsv_la_SOURCES = demux_nsv.c
xineplug_dmx_nsv_la_LIBADD = $(XINE_LIB)
xineplug_dmx_matroska_la_SOURCES = demux_matroska.c ebml.c
-xineplug_dmx_matroska_la_LIBADD = $(XINE_LIB) $(ZLIB_LIBS)
+xineplug_dmx_matroska_la_LIBADD = $(XINE_LIB) $(ZLIB_LIBS) $(LTLIBINTL)
xineplug_dmx_matroska_la_CPPFLAGS = $(ZLIB_CPPFLAGS)
xineplug_dmx_matroska_la_CFLAGS = $(AM_CFLAGS) -fno-strict-aliasing
@@ -141,4 +142,4 @@ xineplug_dmx_flv_la_SOURCES = demux_flv.c
xineplug_dmx_flv_la_LIBADD = $(XINE_LIB) $(LTLIBINTL)
xineinclude_HEADERS = demux.h
-noinst_HEADERS = asfheader.h qtpalette.h group_games.h group_audio.h id3.h ebml.h matroska.h iff.h flacutils.h
+noinst_HEADERS = asfheader.h qtpalette.h group_games.h group_audio.h id3.h ebml.h matroska.h iff.h flacutils.h real_common.h
diff --git a/src/demuxers/asfheader.c b/src/demuxers/asfheader.c
index ea92f878b..e9a36fc29 100644
--- a/src/demuxers/asfheader.c
+++ b/src/demuxers/asfheader.c
@@ -142,9 +142,9 @@ static uint8_t *asf_reader_get_bytes(asf_reader_t *reader, size_t size) {
static char *asf_reader_get_string(asf_reader_t *reader, size_t size, iconv_t cd) {
char *inbuf, *outbuf;
size_t inbytesleft, outbytesleft;
- char scratch[2048];
+ char scratch[2048];
- if ((reader->size - reader->pos) < size)
+ if ((size == 0) ||((reader->size - reader->pos) < size))
return NULL;
inbuf = (char *)reader->buffer + reader->pos;
@@ -399,7 +399,7 @@ static int asf_header_parse_stream_extended_properties(asf_header_t *header, uin
if (asf_stream_extension->stream_name_count) {
asf_stream_extension->stream_names = malloc (asf_stream_extension->stream_name_count * sizeof(void*));
for (i = 0; i < asf_stream_extension->stream_name_count; i++) {
- uint16_t lang_index, length;
+ uint16_t lang_index, length = 0;
asf_reader_get_16(&reader, &lang_index);
asf_reader_get_16(&reader, &length);
asf_stream_extension->stream_names[i] = (char*)asf_reader_get_bytes(&reader, length); /* store them */
@@ -411,7 +411,7 @@ static int asf_header_parse_stream_extended_properties(asf_header_t *header, uin
for (i = 0; i < asf_stream_extension->payload_extension_system_count; i++) {
GUID guid;
uint16_t data_size;
- uint32_t length;
+ uint32_t length = 0;
asf_reader_get_guid(&reader, &guid);
asf_reader_get_16(&reader, &data_size);
asf_reader_get_32(&reader, &length);
@@ -427,7 +427,7 @@ static int asf_header_parse_stream_extended_properties(asf_header_t *header, uin
/* embeded stream properties */
if (asf_reader_get_size(&reader) >= 24) {
GUID guid;
- uint64_t object_length;
+ uint64_t object_length = 0;
asf_reader_get_guid(&reader, &guid);
asf_reader_get_64(&reader, &object_length);
@@ -490,8 +490,8 @@ static int asf_header_parse_stream_bitrate_properties(asf_header_t *header_pub,
lprintf (" bitrate count: %d\n", bitrate_count);
for(i = 0; i < bitrate_count; i++) {
- uint16_t flags;
- uint32_t bitrate;
+ uint16_t flags = 0;
+ uint32_t bitrate = 0;
int stream_number;
uint8_t *bitrate_pointer;
@@ -511,6 +511,61 @@ static int asf_header_parse_stream_bitrate_properties(asf_header_t *header_pub,
return 1;
}
+static int asf_header_parse_metadata(asf_header_t *header_pub, uint8_t *buffer, int buffer_len)
+{
+ asf_header_internal_t *header = (asf_header_internal_t *)header_pub;
+ asf_reader_t reader;
+ uint16_t i, records_count;
+ iconv_t iconv_cd;
+
+ if (buffer_len < 2)
+ return 0;
+
+ if ((iconv_cd = iconv_open ("UTF-8", "UCS-2LE")) == (iconv_t)-1)
+ return 0;
+
+ asf_reader_init(&reader, buffer, buffer_len);
+ asf_reader_get_16(&reader, &records_count);
+
+ for (i = 0; i < records_count; i++)
+ {
+ uint16_t index, stream, name_len = 0, data_type;
+ uint32_t data_len = 0;
+ int stream_id;
+
+ asf_reader_get_16 (&reader, &index);
+ asf_reader_get_16 (&reader, &stream);
+ stream &= 0x7f;
+ asf_reader_get_16 (&reader, &name_len);
+ asf_reader_get_16 (&reader, &data_type);
+ asf_reader_get_32 (&reader, &data_len);
+
+ stream_id = asf_header_get_stream_id (&header->pub, stream);
+
+ if (data_len >= 4)
+ {
+ char *name = asf_reader_get_string (&reader, name_len, iconv_cd);
+ if (name && !strcmp (name, "AspectRatioX"))
+ {
+ asf_reader_get_32 (&reader, &header->pub.aspect_ratios[stream_id].x);
+ data_len -= 4;
+ }
+ else if (name && !strcmp (name, "AspectRatioY"))
+ {
+ asf_reader_get_32 (&reader, &header->pub.aspect_ratios[stream_id].y);
+ data_len -= 4;
+ }
+ free (name);
+ asf_reader_skip (&reader, data_len);
+ }
+ else
+ asf_reader_skip (&reader, data_len + name_len);
+ }
+
+ iconv_close (iconv_cd);
+ return 1;
+}
+
static int asf_header_parse_header_extension(asf_header_t *header, uint8_t *buffer, int buffer_len) {
asf_reader_t reader;
@@ -533,7 +588,7 @@ static int asf_header_parse_header_extension(asf_header_t *header, uint8_t *buff
GUID guid;
int object_id;
- uint64_t object_length, object_data_length;
+ uint64_t object_length = 0, object_data_length;
if (asf_reader_get_size(&reader) < 24) {
printf("invalid buffer size\n");
@@ -549,12 +604,14 @@ static int asf_header_parse_header_extension(asf_header_t *header, uint8_t *buff
case GUID_EXTENDED_STREAM_PROPERTIES:
asf_header_parse_stream_extended_properties(header, asf_reader_get_buffer(&reader), object_data_length);
break;
+ case GUID_METADATA:
+ asf_header_parse_metadata(header, asf_reader_get_buffer(&reader), object_data_length);
+ break;
case GUID_ADVANCED_MUTUAL_EXCLUSION:
case GUID_GROUP_MUTUAL_EXCLUSION:
case GUID_STREAM_PRIORITIZATION:
case GUID_BANDWIDTH_SHARING:
case GUID_LANGUAGE_LIST:
- case GUID_METADATA:
case GUID_METADATA_LIBRARY:
case GUID_INDEX_PARAMETERS:
case GUID_MEDIA_OBJECT_INDEX_PARAMETERS:
@@ -581,10 +638,9 @@ static int asf_header_parse_content_description(asf_header_t *header_pub, uint8_
if (buffer_len < 10)
return 0;
- content = malloc(sizeof(asf_content_t));
+ content = calloc(1, sizeof(asf_content_t));
if (!content)
return 0;
- memset(content, 0, sizeof(asf_content_t));
asf_reader_init(&reader, buffer, buffer_len);
asf_reader_get_16(&reader, &title_length);
@@ -599,6 +655,12 @@ static int asf_header_parse_content_description(asf_header_t *header_pub, uint8_
content->description = asf_reader_get_string(&reader, description_length, header->iconv_cd);
content->rating = asf_reader_get_string(&reader, rating_length, header->iconv_cd);
+ lprintf("title: %d chars: \"%s\"\n", title_length, content->title);
+ lprintf("author: %d chars: \"%s\"\n", author_length, content->author);
+ lprintf("copyright: %d chars: \"%s\"\n", copyright_length, content->copyright);
+ lprintf("description: %d chars: \"%s\"\n", description_length, content->description);
+ lprintf("rating: %d chars: \"%s\"\n", rating_length, content->rating);
+
header->pub.content = content;
return 1;
}
@@ -611,10 +673,9 @@ asf_header_t *asf_header_new (uint8_t *buffer, int buffer_len) {
uint32_t object_count;
uint16_t junk;
- asf_header = malloc(sizeof(asf_header_internal_t));
+ asf_header = calloc(1, sizeof(asf_header_internal_t));
if (!asf_header)
return NULL;
- memset(asf_header, 0, sizeof(asf_header_internal_t));
lprintf("parsing_asf_header\n");
if (buffer_len < 6) {
@@ -638,7 +699,7 @@ asf_header_t *asf_header_new (uint8_t *buffer, int buffer_len) {
GUID guid;
int object_id;
- uint64_t object_length, object_data_length;
+ uint64_t object_length = 0, object_data_length;
if (asf_reader_get_size(&reader) < 24) {
printf("invalid buffer size\n");
@@ -697,10 +758,9 @@ asf_header_t *asf_header_new (uint8_t *buffer, int buffer_len) {
}
if (!asf_header->pub.content) {
lprintf("no content object present\n");
- asf_header->pub.content = malloc(sizeof(asf_content_t));
+ asf_header->pub.content = calloc(1, sizeof(asf_content_t));
if (!asf_header->pub.content)
goto exit_error;
- memset(asf_header->pub.content, 0, sizeof(asf_content_t));
}
return &asf_header->pub;
diff --git a/src/demuxers/asfheader.h b/src/demuxers/asfheader.h
index 4bd13ab3f..265f0e643 100644
--- a/src/demuxers/asfheader.h
+++ b/src/demuxers/asfheader.h
@@ -320,6 +320,7 @@ struct asf_header_s {
asf_stream_t *streams[ASF_MAX_NUM_STREAMS];
asf_stream_extension_t *stream_extensions[ASF_MAX_NUM_STREAMS];
uint32_t bitrates[ASF_MAX_NUM_STREAMS];
+ struct { uint32_t x, y; } aspect_ratios[ASF_MAX_NUM_STREAMS];
};
struct asf_file_s {
@@ -389,7 +390,7 @@ struct asf_stream_extension_s {
int asf_find_object_id (GUID *g);
void asf_get_guid (uint8_t *buffer, GUID *value);
-asf_header_t *asf_header_new (uint8_t *buffer, int buffer_len);
+asf_header_t *asf_header_new (uint8_t *buffer, int buffer_len) XINE_MALLOC;
void asf_header_choose_streams (asf_header_t *header, uint32_t bandwidth,
int *video_id, int *audio_id);
void asf_header_disable_streams (asf_header_t *header,
diff --git a/src/demuxers/demux_4xm.c b/src/demuxers/demux_4xm.c
index 24aee1ac4..397a271b8 100644
--- a/src/demuxers/demux_4xm.c
+++ b/src/demuxers/demux_4xm.c
@@ -125,25 +125,15 @@ static float get_le_float(unsigned char *buffer)
* This function is called from the _open() function of this demuxer.
* It returns 1 if 4xm file was opened successfully. */
static int open_fourxm_file(demux_fourxm_t *fourxm) {
-
unsigned char preview[12];
- int header_size;
- unsigned char *header;
- int i;
- unsigned int fourcc_tag;
- unsigned int size;
- unsigned int current_track;
- unsigned int audio_type;
- unsigned int total_frames;
- float fps;
/* the file signature will be in the first 12 bytes */
if (_x_demux_read_header(fourxm->input, preview, 12) != 12)
return 0;
/* check for the signature tags */
- if ((_X_LE_32(&preview[0]) != RIFF_TAG) ||
- (_X_LE_32(&preview[8]) != _4XMV_TAG))
+ if (!_x_is_fourcc(&preview[0], "RIFF") ||
+ !_x_is_fourcc(&preview[8], "4XMV"))
return 0;
/* file is qualified; skip over the header bytes in the stream */
@@ -152,14 +142,14 @@ static int open_fourxm_file(demux_fourxm_t *fourxm) {
/* fetch the LIST-HEAD header */
if (fourxm->input->read(fourxm->input, preview, 12) != 12)
return 0;
- if ((_X_LE_32(&preview[0]) != LIST_TAG) ||
- (_X_LE_32(&preview[8]) != HEAD_TAG))
+ if (!_x_is_fourcc(&preview[0], "LIST") ||
+ !_x_is_fourcc(&preview[8], "HEAD") )
return 0;
/* read the whole header */
- header_size = _X_LE_32(&preview[4]) - 4;
- header = xine_xmalloc(header_size);
- if (fourxm->input->read(fourxm->input, header, header_size) != header_size) {
+ const uint32_t header_size = _X_LE_32(&preview[4]) - 4;
+ uint8_t *const header = malloc(header_size);
+ if (!header || fourxm->input->read(fourxm->input, header, header_size) != header_size) {
free(header);
return 0;
}
@@ -171,12 +161,13 @@ static int open_fourxm_file(demux_fourxm_t *fourxm) {
fourxm->video_pts_inc = 0;
/* take the lazy approach and search for any and all vtrk and strk chunks */
+ int i;
for (i = 0; i < header_size - 8; i++) {
- fourcc_tag = _X_LE_32(&header[i]);
- size = _X_LE_32(&header[i + 4]);
+ const uint32_t fourcc_tag = _X_LE_32(&header[i]);
+ const uint32_t size = _X_LE_32(&header[i + 4]);
if (fourcc_tag == std__TAG) {
- fps = get_le_float(&header[i + 12]);
+ const float fps = get_le_float(&header[i + 12]);
fourxm->video_pts_inc = (int64_t)(90000.0 / fps);
} else if (fourcc_tag == vtrk_TAG) {
/* check that there is enough data */
@@ -184,7 +175,7 @@ static int open_fourxm_file(demux_fourxm_t *fourxm) {
free(header);
return 0;
}
- total_frames = _X_LE_32(&header[i + 24]);
+ const uint32_t total_frames = _X_LE_32(&header[i + 24]);
fourxm->duration_in_ms = total_frames;
fourxm->duration_in_ms *= fourxm->video_pts_inc;
fourxm->duration_in_ms /= 90000;
@@ -198,9 +189,13 @@ static int open_fourxm_file(demux_fourxm_t *fourxm) {
free(header);
return 0;
}
- current_track = _X_LE_32(&header[i + 8]);
- if (current_track + 1 > fourxm->track_count) {
+ const uint32_t current_track = _X_LE_32(&header[i + 8]);
+ if (current_track >= fourxm->track_count) {
fourxm->track_count = current_track + 1;
+ if (!fourxm->track_count || fourxm->track_count >= UINT_MAX / sizeof(audio_track_t)) {
+ free(header);
+ return 0;
+ }
fourxm->tracks = realloc(fourxm->tracks,
fourxm->track_count * sizeof(audio_track_t));
if (!fourxm->tracks) {
@@ -212,7 +207,7 @@ static int open_fourxm_file(demux_fourxm_t *fourxm) {
fourxm->tracks[current_track].channels = _X_LE_32(&header[i + 36]);
fourxm->tracks[current_track].sample_rate = _X_LE_32(&header[i + 40]);
fourxm->tracks[current_track].bits = _X_LE_32(&header[i + 44]);
- audio_type = _X_LE_32(&header[i + 12]);
+ const uint32_t audio_type = _X_LE_32(&header[i + 12]);
if (audio_type == 0)
fourxm->tracks[current_track].audio_type = BUF_AUDIO_LPCM_LE;
else if (audio_type == 1)
@@ -239,20 +234,18 @@ static int demux_fourxm_send_chunk(demux_plugin_t *this_gen) {
demux_fourxm_t *this = (demux_fourxm_t *) this_gen;
buf_element_t *buf = NULL;
- unsigned int fourcc_tag;
- unsigned int size;
- unsigned char header[8];
unsigned int remaining_bytes;
unsigned int current_track;
/* read the next header */
+ uint8_t header[8];
if (this->input->read(this->input, header, 8) != 8) {
this->status = DEMUX_FINISHED;
return this->status;
}
- fourcc_tag = _X_LE_32(&header[0]);
- size = _X_LE_32(&header[4]);
+ const uint32_t fourcc_tag = _X_LE_32(&header[0]);
+ const uint32_t size = _X_LE_32(&header[4]);
switch (fourcc_tag) {
@@ -472,7 +465,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
demux_fourxm_t *this;
- this = xine_xmalloc (sizeof (demux_fourxm_t));
+ this = calloc(1, sizeof(demux_fourxm_t));
this->stream = stream;
this->input = input;
@@ -491,10 +484,8 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
switch (stream->content_detection_method) {
case METHOD_BY_EXTENSION: {
- const char *extensions, *mrl;
-
- mrl = input->get_mrl (input);
- extensions = class_gen->get_extensions (class_gen);
+ const char *const mrl = input->get_mrl (input);
+ const char *const extensions = class_gen->get_extensions (class_gen);
if (!_x_demux_check_extension (mrl, extensions)) {
free (this);
@@ -546,7 +537,7 @@ static void class_dispose (demux_class_t *this_gen) {
void *demux_fourxm_init_plugin (xine_t *xine, void *data) {
demux_fourxm_class_t *this;
- this = xine_xmalloc (sizeof (demux_fourxm_class_t));
+ this = calloc(1, sizeof(demux_fourxm_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_aac.c b/src/demuxers/demux_aac.c
index d80413f83..68a684ffa 100644
--- a/src/demuxers/demux_aac.c
+++ b/src/demuxers/demux_aac.c
@@ -95,8 +95,7 @@ static int open_aac_file(demux_aac_t *this) {
return 0;
/* Check for an ADIF header - should be at the start of the file */
- if ((peak[0] == 'A') && (peak[1] == 'D') &&
- (peak[2] == 'I') && (peak[3] == 'F')) {
+ if (_x_is_fourcc(peak, "AIDF")) {
lprintf("found ADIF header\n");
return 1;
}
@@ -134,9 +133,7 @@ static int open_aac_file(demux_aac_t *this) {
if ((frame_size > 0) &&
(data_start+frame_size < MAX_PREVIEW_SIZE-1) &&
/* first 28 bits must be identical */
- (peak[data_start ] ==peak[data_start+frame_size ]) &&
- (peak[data_start+1] ==peak[data_start+frame_size+1]) &&
- (peak[data_start+2] ==peak[data_start+frame_size+2]) &&
+ memcmp(&peak[data_start], &peak[data_start+frame_size], 4) == 0 &&
(peak[data_start+3]>>4==peak[data_start+frame_size+3]>>4))
{
lprintf("found second ADTS header\n");
@@ -176,7 +173,7 @@ static int demux_aac_send_chunk(demux_plugin_t *this_gen) {
buf->extra_info->input_time = (8*current_pos) / (bitrate/1000);
bytes_read = this->input->read(this->input, buf->content, buf->max_size);
- if (bytes_read == 0) {
+ if (bytes_read <= 0) {
buf->free_buffer(buf);
this->status = DEMUX_FINISHED;
return this->status;
@@ -262,7 +259,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
demux_aac_t *this;
- this = xine_xmalloc (sizeof (demux_aac_t));
+ this = calloc(1, sizeof(demux_aac_t));
this->stream = stream;
this->input = input;
@@ -333,7 +330,7 @@ static void class_dispose (demux_class_t *this_gen) {
void *demux_aac_init_plugin (xine_t *xine, void *data) {
demux_aac_class_t *this;
- this = xine_xmalloc (sizeof (demux_aac_class_t));
+ this = calloc(1, sizeof(demux_aac_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_ac3.c b/src/demuxers/demux_ac3.c
index c0fae275b..711bb0b45 100644
--- a/src/demuxers/demux_ac3.c
+++ b/src/demuxers/demux_ac3.c
@@ -37,6 +37,9 @@
#ifdef HAVE_ALLOCA_H
#include <alloca.h>
#endif
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
#define LOG_MODULE "demux_ac3"
#define LOG_VERBOSE
@@ -308,13 +311,7 @@ static int demux_ac3_send_chunk (demux_plugin_t *this_gen) {
this->frame_size);
}
- if (buf->size == 0) {
- buf->free_buffer(buf);
- this->status = DEMUX_FINISHED;
- return this->status;
- }
-
- if (buf->size == 0) {
+ if (buf->size <= 0) {
buf->free_buffer(buf);
this->status = DEMUX_FINISHED;
return this->status;
@@ -417,7 +414,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
demux_ac3_t *this;
- this = xine_xmalloc (sizeof (demux_ac3_t));
+ this = calloc(1, sizeof(demux_ac3_t));
this->stream = stream;
this->input = input;
@@ -491,7 +488,7 @@ static void class_dispose (demux_class_t *this_gen) {
void *demux_ac3_init_plugin (xine_t *xine, void *data) {
demux_ac3_class_t *this;
- this = xine_xmalloc (sizeof (demux_ac3_class_t));
+ this = calloc(1, sizeof(demux_ac3_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_aiff.c b/src/demuxers/demux_aiff.c
index 3f2d0df11..273992f64 100644
--- a/src/demuxers/demux_aiff.c
+++ b/src/demuxers/demux_aiff.c
@@ -46,6 +46,10 @@
#define COMM_TAG FOURCC_TAG('C', 'O', 'M', 'M')
#define SSND_TAG FOURCC_TAG('S', 'S', 'N', 'D')
#define APCM_TAG FOURCC_TAG('A', 'P', 'C', 'M')
+#define NAME_TAG FOURCC_TAG('N', 'A', 'M', 'E')
+#define AUTH_TAG FOURCC_TAG('A', 'U', 'T', 'H')
+#define COPY_TAG FOURCC_TAG('(', 'c', ')', ' ')
+#define ANNO_TAG FOURCC_TAG('A', 'N', 'N', 'O')
#define PREAMBLE_SIZE 8
#define AIFF_SIGNATURE_SIZE 12
@@ -80,6 +84,24 @@ typedef struct {
demux_class_t demux_class;
} demux_aiff_class_t;
+/* converts IEEE 80bit extended into int, based on FFMPEG code */
+static int extended_to_int(const unsigned char p[10])
+{
+ uint64_t m = 0;
+ int e, i;
+
+ for (i = 0; i < 8; i++)
+ m = (m<<8) + p[2+i];;
+ e = (((int)p[0]&0x7f)<<8) | p[1];
+ if (e == 0x7fff && m)
+ return 0.0/0.0;
+ e -= 16383 + 63;
+
+ if (p[0]&0x80)
+ m= -m;
+ return (int) ldexp(m, e);
+}
+
/* returns 1 if the AIFF file was opened successfully, 0 otherwise */
static int open_aiff_file(demux_aiff_t *this) {
@@ -87,13 +109,14 @@ static int open_aiff_file(demux_aiff_t *this) {
unsigned char preamble[PREAMBLE_SIZE];
unsigned int chunk_type;
unsigned int chunk_size;
+ unsigned char extended_sample_rate[10];
if (_x_demux_read_header(this->input, signature, AIFF_SIGNATURE_SIZE) != AIFF_SIGNATURE_SIZE)
return 0;
/* check the signature */
- if ((_X_BE_32(&signature[0]) != FORM_TAG) ||
- (_X_BE_32(&signature[8]) != AIFF_TAG))
+ if( !_x_is_fourcc(&signature[0], "FORM") ||
+ !_x_is_fourcc(&signature[8], "AIFF") )
return 0;
/* file is qualified; skip over the header bytes in the stream */
@@ -135,7 +158,8 @@ static int open_aiff_file(demux_aiff_t *this) {
this->audio_channels = _X_BE_16(&buffer[0]);
this->audio_frames = _X_BE_32(&buffer[2]);
this->audio_bits = _X_BE_16(&buffer[6]);
- this->audio_sample_rate = _X_BE_16(&buffer[0x0A]);
+ memcpy(&extended_sample_rate, &buffer[8], sizeof(extended_sample_rate));
+ this->audio_sample_rate = extended_to_int(extended_sample_rate);
this->audio_bytes_per_second = this->audio_channels *
(this->audio_bits / 8) * this->audio_sample_rate;
@@ -150,11 +174,18 @@ static int open_aiff_file(demux_aiff_t *this) {
(this->audio_bits / 8);
this->running_time = (this->audio_frames / this->audio_sample_rate) * 1000;
- this->audio_block_align = PCM_BLOCK_ALIGN;
+ /* we should send only complete frames to decoder, as it
+ * doesn't handle underconsumption yet */
+ this->audio_block_align = PCM_BLOCK_ALIGN - PCM_BLOCK_ALIGN % (this->audio_bits / 8 * this->audio_channels);
break;
} else {
+ /* if chunk contains metadata, it will be word-aligned (as seen at sox and ffmpeg) */
+ if ( ((chunk_type == NAME_TAG) || (chunk_type==AUTH_TAG) ||
+ (chunk_type == COPY_TAG) || (chunk_type==ANNO_TAG)) && (chunk_size&1))
+ chunk_size++;
+
/* unrecognized; skip it */
this->input->seek(this->input, chunk_size, SEEK_CUR);
}
@@ -338,7 +369,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
demux_aiff_t *this;
- this = xine_xmalloc (sizeof (demux_aiff_t));
+ this = calloc(1, sizeof(demux_aiff_t));
this->stream = stream;
this->input = input;
@@ -414,7 +445,7 @@ static void class_dispose (demux_class_t *this_gen) {
void *demux_aiff_init_plugin (xine_t *xine, void *data) {
demux_aiff_class_t *this;
- this = xine_xmalloc (sizeof (demux_aiff_class_t));
+ this = calloc(1, sizeof(demux_aiff_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_asf.c b/src/demuxers/demux_asf.c
index 9aab59977..d79782026 100644
--- a/src/demuxers/demux_asf.c
+++ b/src/demuxers/demux_asf.c
@@ -70,6 +70,7 @@
#define ASF_MODE_HTTP_REF 2
#define ASF_MODE_ASF_REF 3
#define ASF_MODE_ENCRYPTED_CONTENT 4
+#define ASF_MODE_NO_CONTENT 5
typedef struct {
int seq;
@@ -351,6 +352,14 @@ static void asf_send_video_header (demux_asf_t *this, int stream) {
BUF_FLAG_FRAME_END;
buf->decoder_info[0] = 0;
+
+ if (this->asf_header->aspect_ratios[stream].x && this->asf_header->aspect_ratios[stream].y)
+ {
+ buf->decoder_flags |= BUF_FLAG_ASPECT;
+ buf->decoder_info[1] = bih->biWidth * this->asf_header->aspect_ratios[stream].x;
+ buf->decoder_info[2] = bih->biHeight * this->asf_header->aspect_ratios[stream].y;
+ }
+
buf->size = asf_stream->private_data_length - 11;
memcpy (buf->content, bih, buf->size);
buf->type = this->streams[stream].buf_type;
@@ -379,10 +388,21 @@ static int asf_read_header (demux_asf_t *this) {
char *asf_header_buffer = NULL;
asf_header_len = get_le64(this);
- asf_header_buffer = alloca(asf_header_len);
+ if (asf_header_len > 4 * 1024 * 1024)
+ {
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "demux_asf: asf_read_header: overly-large header? (%"PRIu64" bytes)\n",
+ asf_header_len);
+ return 0;
+ }
+
+ asf_header_buffer = malloc (asf_header_len);
if (this->input->read (this->input, asf_header_buffer, asf_header_len) != asf_header_len)
+ {
+ free (asf_header_buffer);
return 0;
+ }
/* delete previous header */
if (this->asf_header) {
@@ -395,7 +415,11 @@ static int asf_read_header (demux_asf_t *this) {
*/
this->asf_header = asf_header_new(asf_header_buffer, asf_header_len);
if (!this->asf_header)
+ {
+ free (asf_header_buffer);
return 0;
+ }
+ free (asf_header_buffer);
lprintf("asf header parsing ok\n");
@@ -420,6 +444,17 @@ static int asf_read_header (demux_asf_t *this) {
asf_stream_t *asf_stream = this->asf_header->streams[i];
asf_demux_stream_t *demux_stream = &this->streams[i];
+ if (!asf_stream) {
+ if (this->mode != ASF_MODE_NO_CONTENT) {
+ xine_log(this->stream->xine, XINE_LOG_MSG,
+ _("demux_asf: warning: A stream appears to be missing.\n"));
+ _x_message(this->stream, XINE_MSG_READ_ERROR,
+ _("Media stream missing?"), NULL);
+ this->mode = ASF_MODE_NO_CONTENT;
+ }
+ return 0;
+ }
+
if (asf_stream->encrypted_flag) {
if (this->mode != ASF_MODE_ENCRYPTED_CONTENT) {
xine_log(this->stream->xine, XINE_LOG_MSG,
@@ -703,7 +738,10 @@ static void asf_send_buffer_nodefrag (demux_asf_t *this, asf_demux_stream_t *str
bufsize = stream->fifo->buffer_pool_buf_size;
buf = stream->fifo->buffer_pool_alloc (stream->fifo);
- this->input->read (this->input, buf->content, bufsize);
+ if (this->input->read (this->input, buf->content, bufsize) != bufsize) {
+ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: input buffer starved\n");
+ return ;
+ }
lprintf ("data: %d %d %d %d\n", buf->content[0], buf->content[1], buf->content[2], buf->content[3]);
@@ -723,6 +761,9 @@ static void asf_send_buffer_nodefrag (demux_asf_t *this, asf_demux_stream_t *str
buf->size = bufsize;
timestamp = 0;
+ if (stream->frag_offset == 0)
+ buf->decoder_flags |= BUF_FLAG_FRAME_START;
+
stream->frag_offset += bufsize;
frag_len -= bufsize;
@@ -733,10 +774,6 @@ static void asf_send_buffer_nodefrag (demux_asf_t *this, asf_demux_stream_t *str
else
check_newpts (this, buf->pts, PTS_AUDIO, package_done);
-
- if (frag_offset == 0)
- buf->decoder_flags |= BUF_FLAG_FRAME_START;
-
/* test if whole packet read */
if (package_done) {
buf->decoder_flags |= BUF_FLAG_FRAME_END;
@@ -783,7 +820,10 @@ static void asf_send_buffer_defrag (demux_asf_t *this, asf_demux_stream_t *strea
if( stream->frag_offset + frag_len > DEFRAG_BUFSIZE ) {
xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: buffer overflow on defrag!\n");
} else {
- this->input->read (this->input, &stream->buffer[stream->frag_offset], frag_len);
+ if (this->input->read (this->input, &stream->buffer[stream->frag_offset], frag_len) != frag_len) {
+ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: input buffer starved\n");
+ return ;
+ }
stream->frag_offset += frag_len;
}
@@ -1657,6 +1697,7 @@ static int demux_asf_send_chunk (demux_plugin_t *this_gen) {
return demux_asf_parse_asf_references(this);
case ASF_MODE_ENCRYPTED_CONTENT:
+ case ASF_MODE_NO_CONTENT:
this->status = DEMUX_FINISHED;
return this->status;
@@ -2059,7 +2100,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen,
return NULL;
}
- this = xine_xmalloc (sizeof (demux_asf_t));
+ this = calloc(1, sizeof(demux_asf_t));
this->stream = stream;
this->input = input;
@@ -2134,7 +2175,7 @@ static void *init_class (xine_t *xine, void *data) {
demux_asf_class_t *this;
- this = xine_xmalloc (sizeof (demux_asf_class_t));
+ this = calloc(1, sizeof(demux_asf_class_t));
this->config = xine->config;
this->xine = xine;
diff --git a/src/demuxers/demux_aud.c b/src/demuxers/demux_aud.c
index a6f88ff48..7730de1fa 100644
--- a/src/demuxers/demux_aud.c
+++ b/src/demuxers/demux_aud.c
@@ -143,7 +143,7 @@ static int demux_aud_send_chunk(demux_plugin_t *this_gen) {
}
/* validate the chunk */
- if (_X_LE_32(&chunk_preamble[4]) != 0x0000DEAF) {
+ if (!_x_is_fourcc(&chunk_preamble[4], "\xAF\xDE\x00\x00")) {
this->status = DEMUX_FINISHED;
return this->status;
}
@@ -270,7 +270,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
demux_aud_t *this;
- this = xine_xmalloc (sizeof (demux_aud_t));
+ this = calloc(1, sizeof(demux_aud_t));
this->stream = stream;
this->input = input;
@@ -343,7 +343,7 @@ static void class_dispose (demux_class_t *this_gen) {
void *demux_aud_init_plugin (xine_t *xine, void *data) {
demux_aud_class_t *this;
- this = xine_xmalloc (sizeof (demux_aud_class_t));
+ this = calloc(1, sizeof(demux_aud_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_avi.c b/src/demuxers/demux_avi.c
index 6bb0b289c..0ab3448bb 100644
--- a/src/demuxers/demux_avi.c
+++ b/src/demuxers/demux_avi.c
@@ -317,6 +317,8 @@ typedef struct {
getIndex==0, but an operation has been
performed that needs an index */
+#define AVI_ERR_BAD_SIZE 14 /* A chunk has an invalid size */
+
#define AVI_HEADER_UNKNOWN -1
#define AVI_HEADER_AUDIO 0
#define AVI_HEADER_VIDEO 1
@@ -719,7 +721,7 @@ static void reset_idx(demux_avi_t *this, avi_t *AVI) {
}
}
-static avi_t *AVI_init(demux_avi_t *this) {
+static avi_t *XINE_MALLOC AVI_init(demux_avi_t *this) {
avi_t *AVI;
int i, j, idx_type;
@@ -739,7 +741,7 @@ static avi_t *AVI_init(demux_avi_t *this) {
/* Create avi_t structure */
lprintf("start\n");
- AVI = (avi_t *) xine_xmalloc(sizeof(avi_t));
+ AVI = (avi_t *) calloc(1, sizeof(avi_t));
if(AVI==NULL) {
this->AVI_errno = AVI_ERR_NO_MEM;
return 0;
@@ -780,7 +782,7 @@ static avi_t *AVI_init(demux_avi_t *this) {
lprintf("chunk: %c%c%c%c, size: %" PRId64 "\n",
data[0], data[1], data[2], data[3], (int64_t)n);
- if((strncasecmp(data,"LIST",4) == 0) && (n >= 4)) {
+ if (n >= 4 && strncasecmp(data,"LIST",4) == 0) {
if( this->input->read(this->input, data,4) != 4 ) ERR_EXIT(AVI_ERR_READ);
n -= 4;
@@ -790,7 +792,7 @@ static avi_t *AVI_init(demux_avi_t *this) {
if(strncasecmp(data,"hdrl",4) == 0) {
hdrl_len = n;
- hdrl_data = (unsigned char *) xine_xmalloc(n);
+ hdrl_data = (unsigned char *) malloc(n);
if(hdrl_data==0)
ERR_EXIT(AVI_ERR_NO_MEM);
if (this->input->read(this->input, hdrl_data,n) != n )
@@ -812,9 +814,8 @@ static avi_t *AVI_init(demux_avi_t *this) {
break if this is not the case */
AVI->n_idx = AVI->max_idx = n / 16;
- if (AVI->idx)
- free(AVI->idx); /* On the off chance there are multiple index chunks */
- AVI->idx = (unsigned char((*)[16])) xine_xmalloc(n);
+ free(AVI->idx); /* On the off chance there are multiple index chunks */
+ AVI->idx = (unsigned char((*)[16])) malloc(n);
if (AVI->idx == 0)
ERR_EXIT(AVI_ERR_NO_MEM);
@@ -836,6 +837,8 @@ static avi_t *AVI_init(demux_avi_t *this) {
/* Interpret the header list */
for (i = 0; i < hdrl_len;) {
+ const int old_i = i;
+
/* List tags are completly ignored */
lprintf("tag: %c%c%c%c\n",
hdrl_data[i], hdrl_data[i+1], hdrl_data[i+2], hdrl_data[i+3]);
@@ -877,12 +880,11 @@ static avi_t *AVI_init(demux_avi_t *this) {
} else if (strncasecmp (hdrl_data+i,"auds",4) ==0 /* && ! auds_strh_seen*/) {
if(AVI->n_audio < MAX_AUDIO_STREAMS) {
- avi_audio_t *a = (avi_audio_t *) xine_xmalloc(sizeof(avi_audio_t));
+ avi_audio_t *a = (avi_audio_t *) calloc(1, sizeof(avi_audio_t));
if(a==NULL) {
this->AVI_errno = AVI_ERR_NO_MEM;
return 0;
}
- memset((void *)a,0,sizeof(avi_audio_t));
AVI->audio[AVI->n_audio] = a;
a->audio_strn = num_stream;
@@ -922,7 +924,7 @@ static avi_t *AVI_init(demux_avi_t *this) {
if(lasttag == 1) {
/* lprintf ("size : %d\n",sizeof(AVI->bih)); */
AVI->bih = (xine_bmiheader *)
- xine_xmalloc((n < sizeof(xine_bmiheader)) ? sizeof(xine_bmiheader) : n);
+ malloc((n < sizeof(xine_bmiheader)) ? sizeof(xine_bmiheader) : n);
if(AVI->bih == NULL) {
this->AVI_errno = AVI_ERR_NO_MEM;
return 0;
@@ -973,6 +975,10 @@ static avi_t *AVI_init(demux_avi_t *this) {
xine_waveformatex *wavex;
wavex = (xine_waveformatex *)malloc(n);
+ if (!wavex) {
+ this->AVI_errno = AVI_ERR_NO_MEM;
+ return 0;
+ }
memcpy((void *)wavex, hdrl_data+i, n);
_x_waveformatex_le2me( wavex );
@@ -1079,6 +1085,8 @@ static avi_t *AVI_init(demux_avi_t *this) {
lasttag = 0;
}
i += n;
+ if (i <= old_i)
+ ERR_EXIT(AVI_ERR_BAD_SIZE);
}
if( hdrl_data )
@@ -1237,6 +1245,9 @@ static avi_t *AVI_init(demux_avi_t *this) {
/* read from file */
chunk_start = en = malloc (AVI->video_superindex->aIndex[j].dwSize+hdrl_len);
+ if (!chunk_start)
+ ERR_EXIT(AVI_ERR_NO_MEM);
+
if (this->input->seek(this->input, AVI->video_superindex->aIndex[j].qwOffset, SEEK_SET) == (off_t)-1) {
lprintf("cannot seek to 0x%" PRIx64 "\n", AVI->video_superindex->aIndex[j].qwOffset);
free(chunk_start);
@@ -1308,6 +1319,9 @@ static avi_t *AVI_init(demux_avi_t *this) {
/* read from file */
chunk_start = en = malloc (audio->audio_superindex->aIndex[j].dwSize+hdrl_len);
+ if (!chunk_start)
+ ERR_EXIT(AVI_ERR_NO_MEM);
+
if (this->input->seek(this->input, audio->audio_superindex->aIndex[j].qwOffset, SEEK_SET) == (off_t)-1) {
lprintf("cannot seek to 0x%" PRIx64 "\n", audio->audio_superindex->aIndex[j].qwOffset);
free(chunk_start);
@@ -2271,7 +2285,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
return NULL;
}
- this = xine_xmalloc (sizeof (demux_avi_t));
+ this = calloc(1, sizeof(demux_avi_t));
this->stream = stream;
this->input = input;
@@ -2337,7 +2351,7 @@ static void class_dispose (demux_class_t *this_gen) {
static void *init_class (xine_t *xine, void *data) {
demux_avi_class_t *this;
- this = xine_xmalloc (sizeof (demux_avi_class_t));
+ this = calloc(1, sizeof(demux_avi_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_cdda.c b/src/demuxers/demux_cdda.c
index 0f34a7cec..8e9ad3679 100644
--- a/src/demuxers/demux_cdda.c
+++ b/src/demuxers/demux_cdda.c
@@ -187,7 +187,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
demux_cdda_t *this;
- this = xine_xmalloc (sizeof (demux_cdda_t));
+ this = calloc(1, sizeof(demux_cdda_t));
this->stream = stream;
this->input = input;
@@ -250,7 +250,7 @@ static void class_dispose (demux_class_t *this_gen) {
void *demux_cdda_init_plugin (xine_t *xine, void *data) {
demux_cdda_class_t *this;
- this = xine_xmalloc (sizeof (demux_cdda_class_t));
+ this = calloc(1, sizeof(demux_cdda_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_dts.c b/src/demuxers/demux_dts.c
index 7c9b47fcd..ed1f16d33 100644
--- a/src/demuxers/demux_dts.c
+++ b/src/demuxers/demux_dts.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005 the xine project
+ * Copyright (C) 2005-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -33,6 +33,9 @@
#ifdef HAVE_ALLOCA_H
#include <alloca.h>
#endif
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
#define LOG_MODULE "demux_dts"
#define LOG_VERBOSE
@@ -140,29 +143,69 @@ static int open_dts_file(demux_dts_t *this) {
}
}
+ /* DTS bitstream encoding version
+ * -1 - not detected
+ * 0 - 16 bits and big endian
+ * 1 - 16 bits and low endian (detection not implemented)
+ * 2 - 14 bits and big endian (detection not implemented)
+ * 3 - 14 bits and low endian
+ */
+ int dts_version = -1;
+
/* Look for a valid DTS syncword */
for (i=offset; i<peak_size-1; i++) {
+ /* 16 bits and big endian bitstream */
+ if (syncword == 0x7ffe8001) {
+ dts_version = 0;
+ break;
+ }
/* 14 bits and little endian bitstream */
- if ((syncword == 0xff1f00e8) &&
- ((peak[i] & 0xf0) == 0xf0) && (peak[i+1] == 0x07)) {
- this->data_start = i-4;
- lprintf("found DTS syncword at offset %d\n", i-4);
- break;
+ else if ((syncword == 0xff1f00e8) &&
+ ((peak[i] & 0xf0) == 0xf0) && (peak[i+1] == 0x07)) {
+ dts_version = 3;
+ break;
}
syncword = (syncword << 8) | peak[i];
}
+ if (dts_version == -1) {
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
+ LOG_MODULE ": unsupported DTS stream type, or not a DTS stream\n");
+ return 0;
+ }
+
+ this->data_start = i-4;
+ lprintf("found DTS syncword at offset %d\n", i-4);
+
if (i < peak_size-9) {
unsigned int nblks, fsize, sfreq;
+ switch (dts_version)
+ {
+ case 0: /* BE16 */
+ nblks = ((peak[this->data_start+4] & 0x01) << 6) |
+ ((peak[this->data_start+5] & 0xfc) >> 2);
+ fsize = (((peak[this->data_start+5] & 0x03) << 12) |(peak[this->data_start+6] << 4) |
+ ((peak[this->data_start+7] & 0xf0) >> 4)) + 1;
+ sfreq = (peak[this->data_start+8] & 0x3c) >> 2;
+ break;
- /* 14 bits and little endian bitstream */
- nblks = ((peak[this->data_start+4] & 0x07) << 4) |
- ((peak[this->data_start+7] & 0x3c) >> 2);
- fsize = (((peak[this->data_start+7] & 0x03) << 12) |
- (peak[this->data_start+6] << 4) |
- ((peak[this->data_start+9] & 0x3c) >> 2)) + 1;
- sfreq = peak[this->data_start+8] & 0x0f;
+ case 3: /* LE14 */
+ nblks = ((peak[this->data_start+4] & 0x07) << 4) |
+ ((peak[this->data_start+7] & 0x3c) >> 2);
+ fsize = (((peak[this->data_start+7] & 0x03) << 12) |
+ (peak[this->data_start+6] << 4) |
+ ((peak[this->data_start+9] & 0x3c) >> 2)) + 1;
+ sfreq = peak[this->data_start+8] & 0x0f;
+ break;
+
+ default:
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
+ LOG_MODULE ": unsupported DTS bitstream encoding %d\n",
+ dts_version);
+ return 0;
+
+ }
if ((sfreq > sizeof(dts_sample_rates)/sizeof(int)) ||
(dts_sample_rates[sfreq] == 0))
@@ -170,7 +213,19 @@ static int open_dts_file(demux_dts_t *this) {
/* Big assumption - this is CBR data */
this->samples_per_frame = (nblks + 1) * 32;
- this->frame_size = fsize * 8 / 14 * 2;
+
+ switch (dts_version)
+ {
+ case 0: /* BE16 */
+ case 1: /* LE16 */
+ this->frame_size = fsize * 8 / 16 * 2;
+ break;
+ case 2: /* BE14 */
+ case 3: /* LE14 */
+ this->frame_size = fsize * 8 / 14 * 2;
+ break;
+ }
+
this->sample_rate = dts_sample_rates[sfreq];
lprintf("samples per frame: %d\n", this->samples_per_frame);
@@ -223,7 +278,7 @@ static int demux_dts_send_chunk (demux_plugin_t *this_gen) {
this->frame_size);
}
- if (buf->size == 0) {
+ if (buf->size <= 0) {
buf->free_buffer(buf);
this->status = DEMUX_FINISHED;
return this->status;
@@ -346,7 +401,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
demux_dts_t *this;
- this = xine_xmalloc (sizeof (demux_dts_t));
+ this = calloc(1, sizeof(demux_dts_t));
this->stream = stream;
this->input = input;
@@ -418,7 +473,7 @@ static void class_dispose (demux_class_t *this_gen) {
void *demux_dts_init_plugin (xine_t *xine, void *data) {
demux_dts_class_t *this;
- this = xine_xmalloc (sizeof (demux_dts_class_t));
+ this = calloc(1, sizeof(demux_dts_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_eawve.c b/src/demuxers/demux_eawve.c
index 2359d3baf..7a21635cb 100644
--- a/src/demuxers/demux_eawve.c
+++ b/src/demuxers/demux_eawve.c
@@ -78,16 +78,16 @@ typedef struct {
*/
static uint32_t read_arbitary(input_plugin_t *input){
- uint8_t size, byte;
- int i;
- uint32_t word;
+ uint8_t size;
if (input->read(input, (void*)&size, 1) != 1) {
return 0;
}
- word = 0;
+ uint32_t word = 0;
+ int i;
for (i=0;i<size;i++) {
+ uint8_t byte;
if (input->read(input, (void*)&byte, 1) != 1) {
return 0;
}
@@ -104,33 +104,25 @@ static uint32_t read_arbitary(input_plugin_t *input){
*/
static int process_header(demux_eawve_t *this){
- int inHeader;
- uint32_t blockid, size;
+ uint8_t header[12];
if (this->input->get_current_pos(this->input) != 0)
this->input->seek(this->input, 0, SEEK_SET);
- if (this->input->read(this->input, (void*)&blockid, 4) != 4) {
- return 0;
- }
- if (be2me_32(blockid) != FOURCC_TAG('S', 'C', 'H', 'l')) {
+ if (this->input->read(this->input, header, sizeof(header)) != sizeof(header))
return 0;
- }
- if (this->input->read(this->input, (void*)&size, 4) != 4) {
+ if (!_x_is_fourcc(&header[0], "SCHl"))
return 0;
- }
- size = le2me_32(size);
- if (this->input->read(this->input, (void*)&blockid, 4) != 4) {
- return 0;
- }
- if (be2me_32(blockid) != FOURCC_TAG('P', 'T', '\0', '\0')) {
+ if (!_x_is_fourcc(&header[8], "PT\0\0")) {
lprintf("PT header missing\n");
return 0;
}
- inHeader = 1;
+ const uint32_t size = _X_LE_32(&header[4]);
+
+ int inHeader = 1;
while (inHeader) {
int inSubheader;
uint8_t byte;
@@ -349,7 +341,7 @@ static demux_plugin_t* open_plugin(demux_class_t *class_gen, xine_stream_t *stre
if (!INPUT_IS_SEEKABLE(input))
return NULL;
- this = xine_xmalloc(sizeof(demux_eawve_t));
+ this = calloc(1, sizeof(demux_eawve_t));
this->stream = stream;
this->input = input;
@@ -421,7 +413,7 @@ static void class_dispose(demux_class_t *this){
void *demux_eawve_init_plugin(xine_t *xine, void *data) {
demux_eawve_class_t *this;
- this = xine_xmalloc(sizeof(demux_eawve_class_t));
+ this = calloc(1, sizeof(demux_eawve_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_elem.c b/src/demuxers/demux_elem.c
index d0a821504..a66befe01 100644
--- a/src/demuxers/demux_elem.c
+++ b/src/demuxers/demux_elem.c
@@ -240,7 +240,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
return NULL;
}
- this = xine_xmalloc (sizeof (demux_mpeg_elem_t));
+ this = calloc(1, sizeof(demux_mpeg_elem_t));
this->stream = stream;
this->input = input;
@@ -284,7 +284,7 @@ static void class_dispose (demux_class_t *this_gen) {
static void *init_plugin (xine_t *xine, void *data) {
demux_mpeg_elem_class_t *this;
- this = xine_xmalloc (sizeof (demux_mpeg_elem_class_t));
+ this = calloc(1, sizeof(demux_mpeg_elem_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_film.c b/src/demuxers/demux_film.c
index 13036afc1..dcd57f76c 100644
--- a/src/demuxers/demux_film.c
+++ b/src/demuxers/demux_film.c
@@ -141,9 +141,9 @@ static int open_film_file(demux_film_t *film) {
return 0;
/* FILM signature correct? */
- if (strncmp(scratch, "FILM", 4)) {
+ if (!_x_is_fourcc(scratch, "FILM"))
return 0;
- }
+
llprintf(DEBUG_FILM_LOAD, "found 'FILM' signature\n");
/* file is qualified; skip over the header bytes in the stream */
@@ -151,7 +151,7 @@ static int open_film_file(demux_film_t *film) {
/* header size = header size - 16-byte FILM signature */
film_header_size = _X_BE_32(&scratch[4]) - 16;
- film_header = xine_xmalloc(film_header_size);
+ film_header = malloc(film_header_size);
if (!film_header)
return 0;
strncpy(film->version, &scratch[8], 4);
@@ -256,7 +256,9 @@ static int open_film_file(demux_film_t *film) {
film->frequency = _X_BE_32(&film_header[i + 8]);
film->sample_count = _X_BE_32(&film_header[i + 12]);
film->sample_table =
- xine_xmalloc(film->sample_count * sizeof(film_sample_t));
+ calloc(film->sample_count, sizeof(film_sample_t));
+ if (!film->sample_table)
+ goto film_abort;
for (j = 0; j < film->sample_count; j++) {
film->sample_table[j].sample_offset =
@@ -329,15 +331,16 @@ static int open_film_file(demux_film_t *film) {
/* allocate enough space in the interleave preload buffer for the
* first chunk (which will be more than enough for successive chunks) */
if (film->audio_type) {
- if (film->interleave_buffer)
- free(film->interleave_buffer);
- film->interleave_buffer =
- xine_xmalloc(film->sample_table[0].sample_size);
+ free(film->interleave_buffer);
+ film->interleave_buffer = calloc(1, film->sample_table[0].sample_size);
+ if (!film->interleave_buffer)
+ goto film_abort;
}
break;
default:
xine_log(film->stream->xine, XINE_LOG_MSG, _("unrecognized FILM chunk\n"));
+ film_abort:
free (film->interleave_buffer);
free (film->sample_table);
free (film_header);
@@ -853,7 +856,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
demux_film_t *this;
- this = xine_xmalloc (sizeof (demux_film_t));
+ this = calloc(1, sizeof(demux_film_t));
this->stream = stream;
this->input = input;
@@ -927,7 +930,7 @@ static void class_dispose (demux_class_t *this_gen) {
void *demux_film_init_plugin (xine_t *xine, void *data) {
demux_film_class_t *this;
- this = xine_xmalloc (sizeof (demux_film_class_t));
+ this = calloc(1, sizeof(demux_film_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_flac.c b/src/demuxers/demux_flac.c
index 3afb5b031..c14536040 100644
--- a/src/demuxers/demux_flac.c
+++ b/src/demuxers/demux_flac.c
@@ -164,8 +164,10 @@ static int open_flac_file(demux_flac_t *flac) {
case 3:
lprintf ("SEEKTABLE metadata, %d bytes\n", block_length);
flac->seekpoint_count = block_length / FLAC_SEEKPOINT_SIZE;
- flac->seekpoints = xine_xmalloc(flac->seekpoint_count *
+ flac->seekpoints = calloc(flac->seekpoint_count,
sizeof(flac_seekpoint_t));
+ if (flac->seekpoint_count && !flac->seekpoints)
+ return 0;
for (i = 0; i < flac->seekpoint_count; i++) {
if (flac->input->read(flac->input, buffer, FLAC_SEEKPOINT_SIZE) != FLAC_SEEKPOINT_SIZE)
return 0;
@@ -189,7 +191,7 @@ static int open_flac_file(demux_flac_t *flac) {
case 4:
lprintf ("VORBIS_COMMENT metadata\n");
{
- char comments[block_length];
+ char comments[block_length + 1]; /* last byte for NUL termination */
char *ptr = comments;
uint32_t length, user_comment_list_length;
int cn;
@@ -202,18 +204,25 @@ static int open_flac_file(demux_flac_t *flac) {
length = _X_LE_32(ptr);
ptr += 4 + length;
+ if (length > block_length - 8)
+ return 0; /* bad length or too little left in the buffer */
user_comment_list_length = _X_LE_32(ptr);
ptr += 4;
cn = 0;
for (; cn < user_comment_list_length; cn++) {
+ if (ptr > comments + block_length - 4)
+ return 0; /* too little left in the buffer */
+
length = _X_LE_32(ptr);
ptr += 4;
+ if (length >= block_length || ptr + length > comments + block_length)
+ return 0; /* bad length */
comment = (char*) ptr;
c = comment[length];
- comment[length] = 0;
+ comment[length] = 0; /* NUL termination */
lprintf ("comment[%02d] = %s\n", cn, comment);
@@ -223,6 +232,9 @@ static int open_flac_file(demux_flac_t *flac) {
} else if ((strncasecmp ("ARTIST=", comment, 7) == 0)
&& (length - 7 > 0)) {
_x_meta_info_set_utf8 (flac->stream, XINE_META_INFO_ARTIST, comment + 7);
+ } else if ((strncasecmp ("COMPOSER=", comment, 9) == 0)
+ && (length - 9 > 0)) {
+ _x_meta_info_set_utf8 (flac->stream, XINE_META_INFO_COMPOSER, comment + 9);
} else if ((strncasecmp ("ALBUM=", comment, 6) == 0)
&& (length - 6 > 0)) {
_x_meta_info_set_utf8 (flac->stream, XINE_META_INFO_ALBUM, comment + 6);
@@ -248,8 +260,8 @@ static int open_flac_file(demux_flac_t *flac) {
}
if ((tracknumber > 0) && (tracktotal > 0)) {
- char tn[16];
- snprintf (tn, 16, "%02d/%02d", tracknumber, tracktotal);
+ char tn[24];
+ snprintf (tn, 24, "%02d/%02d", tracknumber, tracktotal);
_x_meta_info_set(flac->stream, XINE_META_INFO_TRACK_NUMBER, tn);
}
else if (tracknumber > 0) {
@@ -381,12 +393,13 @@ static int demux_flac_seek (demux_plugin_t *this_gen,
demux_flac_t *this = (demux_flac_t *) this_gen;
int seekpoint_index = 0;
int64_t start_pts;
+ unsigned char buf[4];
start_pos = (off_t) ( (double) start_pos / 65535 *
this->data_size );
/* if thread is not running, initialize demuxer */
- if( !playing ) {
+ if( !playing && !start_pos) {
/* send new pts */
_x_demux_control_newpts(this->stream, 0, 0);
@@ -394,28 +407,39 @@ static int demux_flac_seek (demux_plugin_t *this_gen,
this->status = DEMUX_OK;
} else {
- if (this->seekpoints == NULL) {
+ if (this->seekpoints == NULL && !start_pos) {
/* cannot seek if there is no seekpoints */
this->status = DEMUX_OK;
return this->status;
}
- /* do a lazy, linear seek based on the assumption that there are not
- * that many seek points */
+ /* Don't use seekpoints if start_pos != 0. This allows smooth seeking */
if (start_pos) {
/* offset-based seek */
- if (start_pos < this->seekpoints[0].offset)
- seekpoint_index = 0;
- else {
- for (seekpoint_index = 0; seekpoint_index < this->seekpoint_count - 1;
- seekpoint_index++) {
- if (start_pos < this->seekpoints[seekpoint_index + 1].offset) {
- break;
- }
- }
+ this->status = DEMUX_OK;
+ start_pos += this->data_start;
+ this->input->seek(this->input, start_pos, SEEK_SET);
+ while(1){ /* here we try to find something that resembles a frame header */
+
+ if (this->input->read(this->input, buf, 2) != 2){
+ this->status = DEMUX_FINISHED; /* we sought past the end of stream ? */
+ break;
+ }
+
+ if (buf[0] == 0xff && buf[1] == 0xf8)
+ break; /* this might be the frame header... or it may be not. We pass it to the decoder
+ * to decide, but this way we reduce the number of warnings */
+ start_pos +=2;
}
+
+ _x_demux_flush_engine(this->stream);
+ this->input->seek(this->input, start_pos, SEEK_SET);
+ _x_demux_control_newpts(this->stream, 0, BUF_FLAG_SEEK);
+ return this->status;
+
} else {
- /* time-based seek */
+ /* do a lazy, linear seek based on the assumption that there are not
+ * that many seek points; time-based seek */
start_pts = start_time;
start_pts *= 90;
if (start_pts < this->seekpoints[0].pts)
@@ -482,7 +506,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
return NULL;
}
- this = xine_xmalloc (sizeof (demux_flac_t));
+ this = calloc(1, sizeof(demux_flac_t));
this->stream = stream;
this->input = input;
@@ -544,7 +568,8 @@ static const char *get_extensions (demux_class_t *this_gen) {
}
static const char *get_mimetypes (demux_class_t *this_gen) {
- return NULL;
+ return "audio/x-flac: flac: FLAC Audio;"
+ "audio/flac: flac: FLAC Audio;";
}
static void class_dispose (demux_class_t *this_gen) {
@@ -556,7 +581,7 @@ static void class_dispose (demux_class_t *this_gen) {
void *demux_flac_init_plugin (xine_t *xine, void *data) {
demux_flac_class_t *this;
- this = xine_xmalloc (sizeof (demux_flac_class_t));
+ this = calloc(1, sizeof(demux_flac_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_fli.c b/src/demuxers/demux_fli.c
index 99843a68c..12ae81609 100644
--- a/src/demuxers/demux_fli.c
+++ b/src/demuxers/demux_fli.c
@@ -244,7 +244,7 @@ static void demux_fli_send_headers(demux_plugin_t *this_gen) {
BUF_FLAG_FRAME_END;
buf->decoder_info[0] = this->frame_pts_inc; /* initial video_step */
buf->size = this->bih.biSize;
- memcpy(buf->content, &this->bih, sizeof(xine_bmiheader) + this->bih.biSize);
+ memcpy(buf->content, &this->bih, this->bih.biSize);
buf->type = BUF_VIDEO_FLI;
this->video_fifo->put (this->video_fifo, buf);
}
@@ -303,7 +303,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
demux_fli_t *this;
- this = xine_xmalloc (sizeof (demux_fli_t));
+ this = calloc(1, sizeof(demux_fli_t));
this->stream = stream;
this->input = input;
@@ -377,7 +377,7 @@ static void class_dispose (demux_class_t *this_gen) {
static void *init_plugin (xine_t *xine, void *data) {
demux_fli_class_t *this;
- this = xine_xmalloc (sizeof (demux_fli_class_t));
+ this = calloc(1, sizeof(demux_fli_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_flv.c b/src/demuxers/demux_flv.c
index bdb33d21d..d3da20136 100644
--- a/src/demuxers/demux_flv.c
+++ b/src/demuxers/demux_flv.c
@@ -21,10 +21,10 @@
/*
* Flash Video (.flv) File Demuxer
* by Mike Melanson (melanson@pcisys.net) and
- * Claudio Ciccani (klan@directfb.org)
+ * Claudio Ciccani (klan@users.sf.net)
*
* For more information on the FLV file format, visit:
- * http://download.macromedia.com/pub/flash/flash_file_format_specification.pdf
+ * http://www.adobe.com/devnet/flv/pdf/video_file_format_spec_v9.pdf
*/
#ifdef HAVE_CONFIG_H
@@ -85,7 +85,7 @@ typedef struct {
off_t filesize;
flv_index_entry_t *index;
- int num_indices;
+ unsigned int num_indices;
unsigned int cur_pts;
@@ -110,14 +110,20 @@ typedef struct {
#define FLV_SOUND_FORMAT_ADPCM 0x01
#define FLV_SOUND_FORMAT_MP3 0x02
#define FLV_SOUND_FORMAT_PCM_LE 0x03
+#define FLV_SOUND_FORMAT_NELLY16 0x04 /* Nellymoser 16KHz */
#define FLV_SOUND_FORMAT_NELLY8 0x05 /* Nellymoser 8KHz */
#define FLV_SOUND_FORMAT_NELLY 0x06 /* Nellymoser */
+#define FLV_SOUND_FORMAT_ALAW 0x07 /* G.711 A-LAW */
+#define FLV_SOUND_FORMAT_MULAW 0x08 /* G.711 MU-LAW */
+#define FLV_SOUND_FORMAT_AAC 0x0a
+#define FLV_SOUND_FORMAT_MP38 0x0e /* MP3 8KHz */
#define FLV_VIDEO_FORMAT_FLV1 0x02 /* Sorenson H.263 */
#define FLV_VIDEO_FORMAT_SCREEN 0x03
#define FLV_VIDEO_FORMAT_VP6 0x04 /* On2 VP6 */
#define FLV_VIDEO_FORMAT_VP6A 0x05 /* On2 VP6 with alphachannel */
#define FLV_VIDEO_FORMAT_SCREEN2 0x06
+#define FLV_VIDEO_FORMAT_H264 0x07
#define FLV_DATA_TYPE_NUMBER 0x00
#define FLV_DATA_TYPE_BOOL 0x01
@@ -209,7 +215,7 @@ static int parse_flv_var(demux_flv_t *this,
unsigned char *end = buf + size;
char *str;
unsigned char type;
- int len, num;
+ unsigned int len, num;
if (size < 1)
return 0;
@@ -283,6 +289,8 @@ static int parse_flv_var(demux_flv_t *this,
str = tmp + 2;
tmp += len + 2;
len = parse_flv_var(this, tmp, end-tmp, str, len);
+ if (!len)
+ return 0;
tmp += len;
}
if (*tmp++ != FLV_DATA_TYPE_ENDOBJECT)
@@ -298,6 +306,8 @@ static int parse_flv_var(demux_flv_t *this,
str = tmp + 2;
tmp += len + 2;
len = parse_flv_var(this, tmp, end-tmp, str, len);
+ if (!len)
+ return 0;
tmp += len;
}
break;
@@ -306,10 +316,14 @@ static int parse_flv_var(demux_flv_t *this,
num = _X_BE_32(tmp);
tmp += 4;
if (key && keylen == 5 && !strncmp(key, "times", 5)) {
- if (this->index)
- free (this->index);
- this->index = xine_xmalloc(num*sizeof(flv_index_entry_t));
- this->num_indices = num;
+ if (!this->index || this->num_indices != num) {
+ if (this->index)
+ free(this->index);
+ this->index = calloc(num, sizeof(flv_index_entry_t));
+ if (!this->index)
+ return 0;
+ this->num_indices = num;
+ }
for (num = 0; num < this->num_indices && tmp < end; num++) {
if (*tmp++ == FLV_DATA_TYPE_NUMBER) {
lprintf(" got number (%f)\n", BE_F64(tmp));
@@ -320,19 +334,27 @@ static int parse_flv_var(demux_flv_t *this,
break;
}
if (key && keylen == 13 && !strncmp(key, "filepositions", 13)) {
- if (this->index && this->num_indices == num) {
- for (num = 0; num < this->num_indices && tmp < end; num++) {
- if (*tmp++ == FLV_DATA_TYPE_NUMBER) {
- lprintf(" got number (%f)\n", BE_F64(tmp));
- this->index[num].offset = BE_F64(tmp);
- tmp += 8;
- }
+ if (!this->index || this->num_indices != num) {
+ if (this->index)
+ free(this->index);
+ this->index = calloc(num, sizeof(flv_index_entry_t));
+ if (!this->index)
+ return 0;
+ this->num_indices = num;
+ }
+ for (num = 0; num < this->num_indices && tmp < end; num++) {
+ if (*tmp++ == FLV_DATA_TYPE_NUMBER) {
+ lprintf(" got number (%f)\n", BE_F64(tmp));
+ this->index[num].offset = BE_F64(tmp);
+ tmp += 8;
}
- break;
}
+ break;
}
while (num-- && tmp < end) {
len = parse_flv_var(this, tmp, end-tmp, NULL, 0);
+ if (!len)
+ return 0;
tmp += len;
}
break;
@@ -349,12 +371,12 @@ static int parse_flv_var(demux_flv_t *this,
}
static void parse_flv_script(demux_flv_t *this, int size) {
- unsigned char *buf = xine_xmalloc(size);
+ unsigned char *buf = malloc(size);
unsigned char *tmp = buf;
unsigned char *end = buf + size;
int len;
- if (this->input->read(this->input, buf, size ) != size) {
+ if (!buf || this->input->read(this->input, buf, size ) != size) {
this->status = DEMUX_FINISHED;
free(buf);
return;
@@ -413,11 +435,24 @@ static int read_flv_packet(demux_flv_t *this, int preview) {
buf_type = BUF_AUDIO_FLVADPCM;
break;
case FLV_SOUND_FORMAT_MP3:
+ case FLV_SOUND_FORMAT_MP38:
buf_type = BUF_AUDIO_MPEG;
break;
case FLV_SOUND_FORMAT_PCM_LE:
buf_type = BUF_AUDIO_LPCM_LE;
break;
+ case FLV_SOUND_FORMAT_ALAW:
+ buf_type = BUF_AUDIO_ALAW;
+ break;
+ case FLV_SOUND_FORMAT_MULAW:
+ buf_type = BUF_AUDIO_MULAW;
+ break;
+ case FLV_SOUND_FORMAT_AAC:
+ buf_type = BUF_AUDIO_AAC;
+ /* AAC extra header */
+ this->input->read(this->input, buffer, 1 );
+ remaining_bytes--;
+ break;
default:
lprintf(" unsupported audio format (%d)...\n", buffer[0] >> 4);
buf_type = BUF_AUDIO_UNKNOWN;
@@ -448,8 +483,17 @@ static int read_flv_packet(demux_flv_t *this, int preview) {
}
remaining_bytes--;
- if ((buffer[0] >> 4) == 0x01)
- buf_flags = BUF_FLAG_KEYFRAME;
+ switch ((buffer[0] >> 4)) {
+ case 0x01:
+ buf_flags = BUF_FLAG_KEYFRAME;
+ break;
+ case 0x05:
+ /* skip server command */
+ this->input->seek(this->input, remaining_bytes, SEEK_CUR);
+ continue;
+ default:
+ break;
+ }
this->videocodec = buffer[0] & 0x0F; /* override */
switch (this->videocodec) {
@@ -468,6 +512,12 @@ static int read_flv_packet(demux_flv_t *this, int preview) {
this->input->read(this->input, buffer, 4);
remaining_bytes -= 4;
break;
+ case FLV_VIDEO_FORMAT_H264:
+ buf_type = BUF_VIDEO_H264;
+ /* AVC extra header */
+ this->input->read(this->input, buffer, 4);
+ remaining_bytes -= 4;
+ break;
default:
lprintf(" unsupported video format (%d)...\n", buffer[0] & 0x0F);
buf_type = BUF_VIDEO_UNKNOWN;
@@ -495,6 +545,23 @@ static int read_flv_packet(demux_flv_t *this, int preview) {
bih->biSize++;
buf->size++;
}
+ else if (buf_type == BUF_VIDEO_H264 && buffer[0] == 0) {
+ /* AVC sequence header */
+ if (remaining_bytes > buf->max_size-buf->size) {
+ xprintf(this->xine, XINE_VERBOSITY_LOG,
+ _("sequence header too big (%u bytes)!\n"), remaining_bytes);
+ this->input->read(this->input, buf->content+buf->size, buf->max_size-buf->size);
+ this->input->seek(this->input, remaining_bytes-buf->max_size-buf->size, SEEK_CUR);
+ bih->biSize = buf->max_size;
+ buf->size = buf->max_size;
+ }
+ else {
+ this->input->read(this->input, buf->content+buf->size, remaining_bytes);
+ bih->biSize += remaining_bytes;
+ buf->size += remaining_bytes;
+ }
+ remaining_bytes = 0;
+ }
fifo->put(fifo, buf);
this->got_video_header = 1;
}
@@ -502,9 +569,9 @@ static int read_flv_packet(demux_flv_t *this, int preview) {
case FLV_TAG_TYPE_SCRIPT:
lprintf(" got script tag...\n");
- parse_flv_script(this, remaining_bytes);
-
if (preview) {
+ parse_flv_script(this, remaining_bytes);
+
/* send init info to decoders using script information as reference */
if (!this->got_audio_header && this->audiocodec) {
buf = this->audio_fifo->buffer_pool_alloc(this->audio_fifo);
@@ -521,11 +588,21 @@ static int read_flv_packet(demux_flv_t *this, int preview) {
buf->type = BUF_AUDIO_FLVADPCM;
break;
case FLV_SOUND_FORMAT_MP3:
+ case FLV_SOUND_FORMAT_MP38:
buf->type = BUF_AUDIO_MPEG;
break;
case FLV_SOUND_FORMAT_PCM_LE:
buf->type = BUF_AUDIO_LPCM_LE;
break;
+ case FLV_SOUND_FORMAT_ALAW:
+ buf->type = BUF_AUDIO_ALAW;
+ break;
+ case FLV_SOUND_FORMAT_MULAW:
+ buf->type = BUF_AUDIO_MULAW;
+ break;
+ case FLV_SOUND_FORMAT_AAC:
+ buf->type = BUF_AUDIO_AAC;
+ break;
default:
buf->type = BUF_AUDIO_UNKNOWN;
break;
@@ -533,9 +610,10 @@ static int read_flv_packet(demux_flv_t *this, int preview) {
buf->size = 0;
this->audio_fifo->put(this->audio_fifo, buf);
this->got_audio_header = 1;
+ lprintf(" got audio header from metadata...\n");
}
- if (!this->got_video_header && this->videocodec) {
+ if (!this->got_video_header && this->videocodec && this->videocodec != FLV_VIDEO_FORMAT_H264) {
xine_bmiheader *bih;
buf = this->video_fifo->buffer_pool_alloc(this->video_fifo);
buf->decoder_flags = BUF_FLAG_HEADER | BUF_FLAG_STDHEADER |
@@ -567,10 +645,13 @@ static int read_flv_packet(demux_flv_t *this, int preview) {
}
this->video_fifo->put(this->video_fifo, buf);
this->got_video_header = 1;
+ lprintf(" got video header from metadata...\n");
}
return this->status;
- }
+ }
+ /* no preview */
+ this->input->seek(this->input, remaining_bytes, SEEK_CUR);
continue;
default:
@@ -582,33 +663,61 @@ static int read_flv_packet(demux_flv_t *this, int preview) {
while (remaining_bytes) {
buf = fifo->buffer_pool_alloc(fifo);
buf->type = buf_type;
- buf->pts = (int64_t) pts * 90;
-
- if (!preview)
- check_newpts(this, buf->pts, (tag_type == FLV_TAG_TYPE_VIDEO));
buf->extra_info->input_time = pts;
if (this->input->get_length(this->input)) {
buf->extra_info->input_normpos =
(int)((double)this->input->get_current_pos(this->input) * 65535.0 / this->size);
}
+
+ if ((buf_type == BUF_VIDEO_H264 || buf_type == BUF_AUDIO_AAC) && buffer[0] == 0) {
+ /* AVC/AAC sequence header */
+ buf->pts = 0;
+ buf->size = 0;
+
+ buf->decoder_flags = BUF_FLAG_SPECIAL | BUF_FLAG_HEADER;
+ if (preview)
+ buf->decoder_flags |= BUF_FLAG_PREVIEW;
- if (remaining_bytes > buf->max_size)
- buf->size = buf->max_size;
- else
- buf->size = remaining_bytes;
- remaining_bytes -= buf->size;
-
- buf->decoder_flags = buf_flags;
- if (preview)
- buf->decoder_flags |= BUF_FLAG_PREVIEW;
- if (!remaining_bytes)
- buf->decoder_flags |= BUF_FLAG_FRAME_END;
-
- if (this->input->read(this->input, buf->content, buf->size) != buf->size) {
- buf->free_buffer(buf);
- this->status = DEMUX_FINISHED;
- break;
+ buf->decoder_info[1] = BUF_SPECIAL_DECODER_CONFIG;
+ buf->decoder_info[2] = MIN(remaining_bytes, buf->max_size);
+ buf->decoder_info_ptr[2] = buf->mem;
+
+ if (this->input->read(this->input, buf->mem, buf->decoder_info[2]) != buf->decoder_info[2]) {
+ buf->free_buffer(buf);
+ this->status = DEMUX_FINISHED;
+ break;
+ }
+
+ if (remaining_bytes > buf->max_size) {
+ xprintf(this->xine, XINE_VERBOSITY_LOG,
+ _("sequence header too big (%u bytes)!\n"), remaining_bytes);
+ this->input->seek(this->input, remaining_bytes-buf->max_size, SEEK_CUR);
+ }
+ remaining_bytes = 0;
+ }
+ else {
+ buf->pts = (int64_t) pts * 90;
+ if (!preview)
+ check_newpts(this, buf->pts, (tag_type == FLV_TAG_TYPE_VIDEO));
+
+ if (remaining_bytes > buf->max_size)
+ buf->size = buf->max_size;
+ else
+ buf->size = remaining_bytes;
+ remaining_bytes -= buf->size;
+
+ buf->decoder_flags = buf_flags;
+ if (preview)
+ buf->decoder_flags |= BUF_FLAG_PREVIEW;
+ if (!remaining_bytes)
+ buf->decoder_flags |= BUF_FLAG_FRAME_END;
+
+ if (this->input->read(this->input, buf->content, buf->size) != buf->size) {
+ buf->free_buffer(buf);
+ this->status = DEMUX_FINISHED;
+ break;
+ }
}
fifo->put(fifo, buf);
@@ -631,8 +740,8 @@ static void seek_flv_file(demux_flv_t *this, off_t seek_pos, int seek_pts) {
lprintf(" seeking %s to %d...\n",
do_rewind ? "backward" : "forward", seek_pts);
-
- if (seek_pts == 0) {
+
+ if (seek_pos == 0 && seek_pts == 0) {
this->input->seek(this->input, this->start, SEEK_SET);
this->cur_pts = 0;
return;
@@ -658,11 +767,9 @@ static void seek_flv_file(demux_flv_t *this, off_t seek_pos, int seek_pts) {
this->input->seek(this->input, this->index[i].offset-4, SEEK_SET);
this->cur_pts = this->index[i].pts;
- return;
}
}
-
- if (seek_pos && this->videocodec) {
+ else if (seek_pos && this->videocodec && abs(seek_pts-this->cur_pts) > 300000) {
off_t pos, size;
pos = this->input->get_current_pos(this->input);
@@ -697,49 +804,50 @@ static void seek_flv_file(demux_flv_t *this, off_t seek_pos, int seek_pts) {
lprintf(" ...resync failed!\n");
this->input->seek(this->input, pos, SEEK_SET);
- return;
}
-
- while (do_rewind ? (seek_pts < this->cur_pts) : (seek_pts > this->cur_pts)) {
- unsigned char tag_type;
- int data_size;
- int ptag_size;
+ else if (seek_pts) {
+ while (do_rewind ? (seek_pts < this->cur_pts) : (seek_pts > this->cur_pts)) {
+ unsigned char tag_type;
+ int data_size;
+ int ptag_size;
- if (next_tag)
- this->input->seek(this->input, next_tag, SEEK_CUR);
+ if (next_tag)
+ this->input->seek(this->input, next_tag, SEEK_CUR);
- len = this->input->read(this->input, buffer, 16);
- if (len != 16) {
- len = (len < 0) ? 0 : len;
- break;
- }
+ len = this->input->read(this->input, buffer, 16);
+ if (len != 16) {
+ len = (len < 0) ? 0 : len;
+ break;
+ }
- ptag_size = _X_BE_32(&buffer[0]);
- tag_type = buffer[4];
- data_size = _X_BE_24(&buffer[5]);
- pts = _X_BE_24(&buffer[8]) | (buffer[11] << 24);
+ ptag_size = _X_BE_32(&buffer[0]);
+ tag_type = buffer[4];
+ data_size = _X_BE_24(&buffer[5]);
+ pts = _X_BE_24(&buffer[8]) | (buffer[11] << 24);
- if (do_rewind) {
- if (!ptag_size) break; /* beginning of movie */
- next_tag = -(ptag_size + 16 + 4);
- }
- else {
- next_tag = data_size - 1;
- }
+ if (do_rewind) {
+ if (!ptag_size)
+ break; /* beginning of movie */
+ next_tag = -(ptag_size + 16 + 4);
+ }
+ else {
+ next_tag = data_size - 1;
+ }
- if (this->flags & FLV_FLAG_HAS_VIDEO) {
- /* sync to video key frame */
- if (tag_type != FLV_TAG_TYPE_VIDEO || (buffer[15] >> 4) != 0x01)
- continue;
- lprintf(" video keyframe found at %d...\n", pts);
+ if (this->flags & FLV_FLAG_HAS_VIDEO) {
+ /* sync to video key frame */
+ if (tag_type != FLV_TAG_TYPE_VIDEO || (buffer[15] >> 4) != 0x01)
+ continue;
+ lprintf(" video keyframe found at %d...\n", pts);
+ }
+ this->cur_pts = pts;
}
- this->cur_pts = pts;
- }
- /* seek back to the beginning of the tag */
- this->input->seek(this->input, -len, SEEK_CUR);
+ /* seek back to the beginning of the tag */
+ this->input->seek(this->input, -len, SEEK_CUR);
- lprintf( " seeked to %d.\n", pts);
+ lprintf( " seeked to %d.\n", pts);
+ }
}
@@ -789,8 +897,12 @@ static int demux_flv_seek (demux_plugin_t *this_gen,
this->status = DEMUX_OK;
if (INPUT_IS_SEEKABLE(this->input)) {
- if (start_pos && !start_time)
- start_time = (int64_t) this->length * start_pos / 65535;
+ if (start_pos && !start_time) {
+ if (this->length)
+ start_time = (int64_t) this->length * start_pos / 65535;
+ else if (this->index)
+ start_time = this->index[(int)(start_pos * (this->num_indices-1) / 65535)].pts;
+ }
if (!this->length || start_time < this->length) {
seek_flv_file(this, start_pos, start_time);
@@ -838,7 +950,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
input_plugin_t *input) {
demux_flv_t *this;
- this = xine_xmalloc(sizeof (demux_flv_t));
+ this = calloc(1, sizeof(demux_flv_t));
this->xine = stream->xine;
this->stream = stream;
this->input = input;
@@ -857,12 +969,6 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
switch (stream->content_detection_method) {
case METHOD_BY_EXTENSION:
- if (!_x_demux_check_extension(input->get_mrl(input), "flv")) {
- free (this);
- return NULL;
- }
-
- /* falling through is intended */
case METHOD_BY_CONTENT:
case METHOD_EXPLICIT:
if (!open_flv_file(this)) {
@@ -906,7 +1012,7 @@ static void class_dispose (demux_class_t *this_gen) {
static void *init_plugin (xine_t *xine, void *data) {
demux_flv_class_t *this;
- this = xine_xmalloc (sizeof (demux_flv_class_t));
+ this = calloc(1, sizeof(demux_flv_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_idcin.c b/src/demuxers/demux_idcin.c
index 99754c797..d44f03ab3 100644
--- a/src/demuxers/demux_idcin.c
+++ b/src/demuxers/demux_idcin.c
@@ -472,7 +472,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
demux_idcin_t *this;
- this = xine_xmalloc (sizeof (demux_idcin_t));
+ this = calloc(1, sizeof(demux_idcin_t));
this->stream = stream;
this->input = input;
@@ -547,7 +547,7 @@ static void class_dispose (demux_class_t *this_gen) {
void *demux_idcin_init_plugin (xine_t *xine, void *data) {
demux_idcin_class_t *this;
- this = xine_xmalloc (sizeof (demux_idcin_class_t));
+ this = calloc(1, sizeof(demux_idcin_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_iff.c b/src/demuxers/demux_iff.c
index d914405db..1785e86d7 100644
--- a/src/demuxers/demux_iff.c
+++ b/src/demuxers/demux_iff.c
@@ -212,7 +212,7 @@ static int read_iff_chunk(demux_iff_t *this) {
break;
case IFF_VHDR_CHUNK:
if( this->vhdr == NULL )
- this->vhdr = (Voice8Header *)xine_xmalloc(sizeof(Voice8Header));
+ this->vhdr = (Voice8Header *)calloc(1, sizeof(Voice8Header));
this->vhdr->oneShotHiSamples = _X_BE_32(&buffer[0]);
this->vhdr->repeatHiSamples = _X_BE_32(&buffer[4]);
this->vhdr->samplesPerHiCycle = _X_BE_32(&buffer[8]);
@@ -330,7 +330,7 @@ static int read_iff_chunk(demux_iff_t *this) {
break;
case IFF_BMHD_CHUNK:
if( this->bmhd == NULL )
- this->bmhd = (BitMapHeader *)xine_xmalloc(sizeof(BitMapHeader));
+ this->bmhd = (BitMapHeader *)calloc(1, sizeof(BitMapHeader));
this->bmhd->w = _X_BE_16(&buffer[0]);
this->bmhd->h = _X_BE_16(&buffer[2]);
this->bmhd->x = _X_BE_16(&buffer[4]);
@@ -399,20 +399,20 @@ static int read_iff_chunk(demux_iff_t *this) {
case IFF_CMAP_CHUNK:
/* every color contains red, green and blue componente using 8Bit */
this->cmap_num = junk_size / PIC_SIZE_OF_COLOR_REGISTER;
- this->cmap = (ColorRegister *)xine_xmalloc(junk_size);
+ this->cmap = (ColorRegister *)malloc(junk_size);
this->video_send_palette = 1;
- if (this->input->read(this->input, (char *)this->cmap, junk_size) != junk_size)
+ if (!this->cmap || this->input->read(this->input, (char *)this->cmap, junk_size) != junk_size)
return 0;
break;
case IFF_GRAB_CHUNK:
if( this->grab == NULL )
- this->grab = (Point2D *)xine_xmalloc(sizeof(Point2D));
+ this->grab = (Point2D *)calloc(1, sizeof(Point2D));
this->grab->x = _X_BE_16(&buffer[0]);
this->grab->y = _X_BE_16(&buffer[2]);
break;
case IFF_DEST_CHUNK:
if( this->dest == NULL )
- this->dest = (DestMerge *)xine_xmalloc(sizeof(DestMerge));
+ this->dest = (DestMerge *)calloc(1, sizeof(DestMerge));
this->dest->depth = buffer[0];
this->dest->pad1 = buffer[1];
this->dest->plane_pick = _X_BE_16(&buffer[2]);
@@ -424,7 +424,7 @@ static int read_iff_chunk(demux_iff_t *this) {
break;
case IFF_CAMG_CHUNK:
if( this->camg == NULL )
- this->camg = (CamgChunk *)xine_xmalloc(sizeof(CamgChunk));
+ this->camg = (CamgChunk *)calloc(1, sizeof(CamgChunk));
this->camg->view_modes = _X_BE_32(&buffer[0]);
this->bih.biCompression = this->camg->view_modes;
if( this->camg->view_modes & CAMG_PAL &&
@@ -443,7 +443,7 @@ static int read_iff_chunk(demux_iff_t *this) {
break;
case IFF_CCRT_CHUNK:
if( this->ccrt == NULL )
- this->ccrt = (CcrtChunk *)xine_xmalloc(sizeof(CcrtChunk));
+ this->ccrt = (CcrtChunk *)calloc(1, sizeof(CcrtChunk));
this->ccrt->direction = _X_BE_16(&buffer[0]);
this->ccrt->start = buffer[2];
this->ccrt->end = buffer[3];
@@ -453,13 +453,13 @@ static int read_iff_chunk(demux_iff_t *this) {
break;
case IFF_DPI_CHUNK:
if( this->dpi == NULL )
- this->dpi = (DPIHeader *)xine_xmalloc(sizeof(DPIHeader));
+ this->dpi = (DPIHeader *)calloc(1, sizeof(DPIHeader));
this->dpi->x = _X_BE_16(&buffer[0]);
this->dpi->y = _X_BE_16(&buffer[0]);
break;
case IFF_ANHD_CHUNK:
if( this->anhd == NULL )
- this->anhd = (AnimHeader *)xine_xmalloc(sizeof(AnimHeader));
+ this->anhd = (AnimHeader *)calloc(1, sizeof(AnimHeader));
this->anhd->operation = buffer[0];
this->anhd->mask = buffer[1];
this->anhd->w = _X_BE_16(&buffer[2]);
@@ -500,7 +500,7 @@ static int read_iff_chunk(demux_iff_t *this) {
break;
case IFF_DPAN_CHUNK:
if( this->dpan == NULL )
- this->dpan = (DPAnimChunk *)xine_xmalloc(sizeof(DPAnimChunk));
+ this->dpan = (DPAnimChunk *)calloc(1, sizeof(DPAnimChunk));
this->dpan->version = _X_BE_16(&buffer[0]);
this->dpan->nframes = _X_BE_16(&buffer[2]);
this->dpan->fps = buffer[4];
@@ -709,11 +709,19 @@ static int demux_iff_send_chunk(demux_plugin_t *this_gen) {
/* load the whole chunk into the buffer */
if (this->audio_buffer_filled == 0) {
if (this->audio_interleave_buffer_size > 0)
+ {
this->audio_interleave_buffer =
- xine_xmalloc(this->audio_interleave_buffer_size);
+ calloc(1, this->audio_interleave_buffer_size);
+ if (!this->audio_interleave_buffer)
+ return this->status = DEMUX_FINISHED;
+ }
if (this->audio_read_buffer_size > 0)
+ {
this->audio_read_buffer =
- xine_xmalloc(this->audio_read_buffer_size);
+ calloc(1, this->audio_read_buffer_size);
+ if (!this->audio_read_buffer)
+ return this->status = DEMUX_FINISHED;
+ }
if (this->audio_read_buffer) {
if (this->input->read(this->input, this->audio_read_buffer,
this->data_size) != this->data_size) {
@@ -1234,7 +1242,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
demux_iff_t *this;
- this = xine_xmalloc (sizeof (demux_iff_t));
+ this = calloc(1, sizeof(demux_iff_t));
this->stream = stream;
this->input = input;
@@ -1315,7 +1323,7 @@ static void class_dispose (demux_class_t *this_gen) {
static void *init_plugin (xine_t *xine, void *data) {
demux_iff_class_t *this;
- this = xine_xmalloc (sizeof (demux_iff_class_t));
+ this = calloc(1, sizeof(demux_iff_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_image.c b/src/demuxers/demux_image.c
index 9f53e4173..feaf3ceaa 100644
--- a/src/demuxers/demux_image.c
+++ b/src/demuxers/demux_image.c
@@ -198,7 +198,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen,
* if we reach this point, the input has been accepted.
*/
- this = xine_xmalloc (sizeof (demux_image_t));
+ this = calloc(1, sizeof(demux_image_t));
this->stream = stream;
this->input = input;
@@ -249,7 +249,7 @@ static void class_dispose (demux_class_t *this_gen) {
static void *init_class (xine_t *xine, void *data) {
demux_image_class_t *this;
- this = xine_xmalloc (sizeof (demux_image_class_t));
+ this = calloc(1, sizeof(demux_image_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_ipmovie.c b/src/demuxers/demux_ipmovie.c
index cd21896c0..4ef877988 100644
--- a/src/demuxers/demux_ipmovie.c
+++ b/src/demuxers/demux_ipmovie.c
@@ -283,9 +283,10 @@ static int process_ipmovie_chunk(demux_ipmovie_t *this) {
this->bih.biWidth = _X_LE_16(&scratch[0]) * 8;
this->bih.biHeight = _X_LE_16(&scratch[2]) * 8;
/* set up staging area for decode map */
- this->decode_map_size = (this->bih.biWidth * this->bih.biHeight) /
- (8 * 8) / 2;
+ this->decode_map_size = (this->bih.biWidth / 8) * (this->bih.biHeight / 8) / 2;
this->decode_map = xine_xmalloc(this->decode_map_size);
+ if (!this->decode_map)
+ this->status = DEMUX_FINISHED;
lprintf("video resolution: %d x %d\n",
this->bih.biWidth, this->bih.biHeight);
break;
@@ -671,7 +672,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
demux_ipmovie_t *this;
- this = xine_xmalloc (sizeof (demux_ipmovie_t));
+ this = calloc(1, sizeof(demux_ipmovie_t));
this->stream = stream;
this->input = input;
@@ -746,7 +747,7 @@ static void class_dispose (demux_class_t *this_gen) {
void *demux_ipmovie_init_plugin (xine_t *xine, void *data) {
demux_ipmovie_class_t *this;
- this = xine_xmalloc (sizeof (demux_ipmovie_class_t));
+ this = calloc(1, sizeof(demux_ipmovie_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_matroska.c b/src/demuxers/demux_matroska.c
index b973c1caf..5cf783bf5 100644
--- a/src/demuxers/demux_matroska.c
+++ b/src/demuxers/demux_matroska.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2007 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -58,13 +58,6 @@
#define WRAP_THRESHOLD 90000
-#if !defined(MIN)
-#define MIN(a, b) ((a)<(b)?(a):(b))
-#endif
-#if !defined(MAX)
-#define MAX(a, b) ((a)>(b)?(a):(b))
-#endif
-
typedef struct {
int track_num;
off_t *pos;
@@ -113,7 +106,7 @@ typedef struct {
/* block */
uint8_t *block_data;
- int block_data_size;
+ size_t block_data_size;
/* current tracks */
matroska_track_t *video_track; /* to remove */
@@ -614,6 +607,8 @@ static void init_codec_xiph(demux_matroska_t *this, matroska_track_t *track) {
int i;
uint8_t *data;
+ if (track->codec_private_len < 3)
+ return;
nb_lace = track->codec_private[0];
if (nb_lace != 2)
return;
@@ -621,6 +616,8 @@ static void init_codec_xiph(demux_matroska_t *this, matroska_track_t *track) {
frame[0] = track->codec_private[1];
frame[1] = track->codec_private[2];
frame[2] = track->codec_private_len - frame[0] - frame[1] - 3;
+ if (frame[2] < 0)
+ return;
data = track->codec_private + 3;
for (i = 0; i < 3; i++) {
@@ -635,9 +632,7 @@ static void init_codec_xiph(demux_matroska_t *this, matroska_track_t *track) {
}
buf->size = frame[i];
- buf->decoder_flags = BUF_FLAG_HEADER;
- if (i == 2)
- buf->decoder_flags |= BUF_FLAG_FRAME_END;
+ buf->decoder_flags = BUF_FLAG_HEADER | BUF_FLAG_FRAME_START | BUF_FLAG_FRAME_END;
buf->type = track->buf_type;
buf->pts = 0;
@@ -685,7 +680,11 @@ static void init_codec_aac(demux_matroska_t *this, matroska_track_t *track) {
/* Create a DecoderSpecificInfo for initialising libfaad */
sr_index = aac_get_sr_index(atrack->sampling_freq);
- if (!strncmp (&track->codec_id[12], "MAIN", 4))
+ /* newer specification with appended CodecPrivate */
+ if (strlen(track->codec_id) <= 12)
+ profile = 3;
+ /* older specification */
+ else if (!strncmp (&track->codec_id[12], "MAIN", 4))
profile = 0;
else if (!strncmp (&track->codec_id[12], "LC", 2))
profile = 1;
@@ -884,7 +883,7 @@ static void init_codec_vobsub(demux_matroska_t *this,
static void handle_realvideo (demux_plugin_t *this_gen, matroska_track_t *track,
int decoder_flags,
- uint8_t *data, int data_len,
+ uint8_t *data, size_t data_len,
int64_t data_pts, int data_duration,
int input_normpos, int input_time) {
demux_matroska_t *this = (demux_matroska_t *) this_gen;
@@ -933,7 +932,7 @@ static void handle_realvideo (demux_plugin_t *this_gen, matroska_track_t *track,
static void handle_sub_ssa (demux_plugin_t *this_gen, matroska_track_t *track,
int decoder_flags,
- uint8_t *data, int data_len,
+ uint8_t *data, size_t data_len,
int64_t data_pts, int data_duration,
int input_normpos, int input_time) {
buf_element_t *buf;
@@ -1008,7 +1007,7 @@ static void handle_sub_ssa (demux_plugin_t *this_gen, matroska_track_t *track,
static void handle_sub_utf8 (demux_plugin_t *this_gen, matroska_track_t *track,
int decoder_flags,
- uint8_t *data, int data_len,
+ uint8_t *data, size_t data_len,
int64_t data_pts, int data_duration,
int input_normpos, int input_time) {
demux_matroska_t *this = (demux_matroska_t *) this_gen;
@@ -1055,7 +1054,7 @@ static void handle_sub_utf8 (demux_plugin_t *this_gen, matroska_track_t *track,
*/
static void handle_vobsub (demux_plugin_t *this_gen, matroska_track_t *track,
int decoder_flags,
- uint8_t *data, int data_len,
+ uint8_t *data, size_t data_len,
int64_t data_pts, int data_duration,
int input_normpos, int input_time) {
demux_matroska_t *this = (demux_matroska_t *) this_gen;
@@ -1179,19 +1178,21 @@ static int parse_track_entry(demux_matroska_t *this, matroska_track_t *track) {
break;
case MATROSKA_ID_TR_CODECID: {
- char *codec_id = malloc (elem.len + 1);
+ char *codec_id = ebml_alloc_read_ascii (ebml, &elem);
lprintf("CodecID\n");
- if (!ebml_read_ascii(ebml, &elem, codec_id)) {
- free(codec_id);
+ if (!codec_id)
return 0;
- }
- codec_id[elem.len] = '\0';
track->codec_id = codec_id;
}
break;
case MATROSKA_ID_TR_CODECPRIVATE: {
- char *codec_private = malloc (elem.len);
+ char *codec_private;
+ if (elem.len >= 0x80000000)
+ return 0;
+ codec_private = malloc (elem.len);
+ if (! codec_private)
+ return 0;
lprintf("CodecPrivate\n");
if (!ebml_read_binary(ebml, &elem, codec_private)) {
free(codec_private);
@@ -1203,13 +1204,10 @@ static int parse_track_entry(demux_matroska_t *this, matroska_track_t *track) {
break;
case MATROSKA_ID_TR_LANGUAGE: {
- char *language = malloc (elem.len + 1);
+ char *language = ebml_alloc_read_ascii (ebml, &elem);
lprintf("Language\n");
- if (!ebml_read_ascii(ebml, &elem, language)) {
- free(language);
+ if (!language)
return 0;
- }
- language[elem.len] = '\0';
track->language = language;
}
break;
@@ -1218,7 +1216,7 @@ static int parse_track_entry(demux_matroska_t *this, matroska_track_t *track) {
lprintf("Video\n");
if (track->video_track)
return 1;
- track->video_track = (matroska_video_track_t *)xine_xmalloc(sizeof(matroska_video_track_t));
+ track->video_track = (matroska_video_track_t *)calloc(1, sizeof(matroska_video_track_t));
if (!ebml_read_master (ebml, &elem))
return 0;
if ((elem.len > 0) && !parse_video_track(this, track->video_track))
@@ -1229,7 +1227,7 @@ static int parse_track_entry(demux_matroska_t *this, matroska_track_t *track) {
lprintf("Audio\n");
if (track->audio_track)
return 1;
- track->audio_track = (matroska_audio_track_t *)xine_xmalloc(sizeof(matroska_audio_track_t));
+ track->audio_track = (matroska_audio_track_t *)calloc(1, sizeof(matroska_audio_track_t));
if (!ebml_read_master (ebml, &elem))
return 0;
if ((elem.len > 0) && !parse_audio_track(this, track->audio_track))
@@ -1298,12 +1296,14 @@ static int parse_track_entry(demux_matroska_t *this, matroska_track_t *track) {
if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_VFW_FOURCC)) {
xine_bmiheader *bih;
- lprintf("MATROSKA_CODEC_ID_V_VFW_FOURCC\n");
- bih = (xine_bmiheader*)track->codec_private;
- _x_bmiheader_le2me(bih);
+ if (track->codec_private_len >= sizeof(xine_bmiheader)) {
+ lprintf("MATROSKA_CODEC_ID_V_VFW_FOURCC\n");
+ bih = (xine_bmiheader*)track->codec_private;
+ _x_bmiheader_le2me(bih);
- track->buf_type = _x_fourcc_to_buf_video(bih->biCompression);
- init_codec = init_codec_video;
+ track->buf_type = _x_fourcc_to_buf_video(bih->biCompression);
+ init_codec = init_codec_video;
+ }
} else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_UNCOMPRESSED)) {
} else if ((!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_MPEG4_SP)) ||
@@ -1312,8 +1312,11 @@ static int parse_track_entry(demux_matroska_t *this, matroska_track_t *track) {
xine_bmiheader *bih;
lprintf("MATROSKA_CODEC_ID_V_MPEG4_*\n");
+ if (track->codec_private_len > 0x7fffffff - sizeof(xine_bmiheader))
+ track->codec_private_len = 0x7fffffff - sizeof(xine_bmiheader);
+
/* create a bitmap info header struct for MPEG 4 */
- bih = malloc(sizeof(xine_bmiheader) + track->codec_private_len);
+ bih = calloc(1, sizeof(xine_bmiheader) + track->codec_private_len);
bih->biSize = sizeof(xine_bmiheader) + track->codec_private_len;
bih->biCompression = ME_FOURCC('M', 'P', '4', 'S');
bih->biWidth = track->video_track->pixel_width;
@@ -1333,8 +1336,11 @@ static int parse_track_entry(demux_matroska_t *this, matroska_track_t *track) {
xine_bmiheader *bih;
lprintf("MATROSKA_CODEC_ID_V_MPEG4_AVC\n");
+ if (track->codec_private_len > 0x7fffffff - sizeof(xine_bmiheader))
+ track->codec_private_len = 0x7fffffff - sizeof(xine_bmiheader);
+
/* create a bitmap info header struct for h264 */
- bih = malloc(sizeof(xine_bmiheader) + track->codec_private_len);
+ bih = calloc(1, sizeof(xine_bmiheader) + track->codec_private_len);
bih->biSize = sizeof(xine_bmiheader) + track->codec_private_len;
bih->biCompression = ME_FOURCC('a', 'v', 'c', '1');
bih->biWidth = track->video_track->pixel_width;
@@ -1409,11 +1415,13 @@ static int parse_track_entry(demux_matroska_t *this, matroska_track_t *track) {
xine_waveformatex *wfh;
lprintf("MATROSKA_CODEC_ID_A_ACM\n");
- wfh = (xine_waveformatex*)track->codec_private;
- _x_waveformatex_le2me(wfh);
+ if (track->codec_private_len >= sizeof(xine_waveformatex)) {
+ wfh = (xine_waveformatex*)track->codec_private;
+ _x_waveformatex_le2me(wfh);
- track->buf_type = _x_formattag_to_buf_audio(wfh->wFormatTag);
- init_codec = init_codec_audio;
+ track->buf_type = _x_formattag_to_buf_audio(wfh->wFormatTag);
+ init_codec = init_codec_audio;
+ }
} else if (!strncmp(track->codec_id, MATROSKA_CODEC_ID_A_AAC,
sizeof(MATROSKA_CODEC_ID_A_AAC) - 1)) {
lprintf("MATROSKA_CODEC_ID_A_AAC\n");
@@ -1494,9 +1502,14 @@ static int parse_track_entry(demux_matroska_t *this, matroska_track_t *track) {
break;
}
- if (init_codec)
+ if (init_codec) {
+ if (! track->fifo) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ "demux_matroska: Error: fifo not set up for track of type type %" PRIu32 "\n", track->track_type);
+ return 0;
+ }
init_codec(this, track);
-
+ }
}
}
@@ -1519,7 +1532,7 @@ static int parse_tracks(demux_matroska_t *this) {
matroska_track_t *track;
/* alloc and initialize a track with 0 */
- track = xine_xmalloc(sizeof(matroska_track_t));
+ track = calloc(1, sizeof(matroska_track_t));
track->compress_algo = MATROSKA_COMPRESS_NONE;
this->tracks[this->num_tracks] = track;
@@ -1746,7 +1759,7 @@ static int parse_tags(demux_matroska_t *this) {
return 1;
}
-static void alloc_block_data (demux_matroska_t *this, int len) {
+static void alloc_block_data (demux_matroska_t *this, size_t len) {
/* memory management */
if (this->block_data_size < len) {
if (this->block_data)
@@ -1818,10 +1831,15 @@ static int find_track_by_id(demux_matroska_t *this, int track_num,
}
-static int read_block_data (demux_matroska_t *this, int len) {
+static int read_block_data (demux_matroska_t *this, size_t len) {
alloc_block_data(this, len);
/* block datas */
+ if (! this->block_data) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ "demux_matroska: memory allocation error\n");
+ return 0;
+ }
if (this->input->read(this->input, this->block_data, len) != len) {
off_t pos = this->input->get_current_pos(this->input);
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
@@ -1832,15 +1850,24 @@ static int read_block_data (demux_matroska_t *this, int len) {
return 1;
}
-static int parse_block (demux_matroska_t *this, uint64_t block_size,
+static int parse_int16(uint8_t *data) {
+ int value = (int)_X_BE_16(data);
+ if (value & 1<<15)
+ {
+ value -= 1<<16;
+ }
+ return value;
+}
+
+static int parse_block (demux_matroska_t *this, size_t block_size,
uint64_t cluster_timecode, uint64_t block_duration,
int normpos, int is_key) {
matroska_track_t *track;
- int64_t track_num;
+ uint64_t track_num;
uint8_t *data;
uint8_t flags;
int gap, lacing, num_len;
- int timecode_diff;
+ int16_t timecode_diff;
int64_t pts, xduration;
int decoder_flags = 0;
@@ -1848,14 +1875,15 @@ static int parse_block (demux_matroska_t *this, uint64_t block_size,
if (!(num_len = parse_ebml_uint(this, data, &track_num)))
return 0;
data += num_len;
-
- timecode_diff = (int)_X_BE_16(data);
+
+ /* timecode_diff is signed */
+ timecode_diff = (int16_t)parse_int16(data);
data += 2;
flags = *data;
data += 1;
- lprintf("track_num: %" PRId64 ", timecode_diff: %d, flags: 0x%x\n", track_num, timecode_diff, flags);
+ lprintf("track_num: %" PRIu64 ", timecode_diff: %d, flags: 0x%x\n", track_num, timecode_diff, flags);
gap = flags & 1;
lacing = (flags >> 1) & 0x3;
@@ -1863,7 +1891,7 @@ static int parse_block (demux_matroska_t *this, uint64_t block_size,
if (!find_track_by_id(this, (int)track_num, &track)) {
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
- "demux_matroska: invalid track id: %" PRId64 "\n", track_num);
+ "demux_matroska: invalid track id: %" PRIu64 "\n", track_num);
return 0;
}
@@ -1897,11 +1925,11 @@ static int parse_block (demux_matroska_t *this, uint64_t block_size,
}
if (lacing == MATROSKA_NO_LACING) {
- int block_size_left;
+ size_t block_size_left;
lprintf("no lacing\n");
block_size_left = (this->block_data + block_size) - data;
- lprintf("size: %d, block_size: %" PRIu64 "\n", block_size_left, block_size);
+ lprintf("size: %d, block_size: %u\n", block_size_left, block_size);
if (track->handle_content != NULL) {
track->handle_content((demux_plugin_t *)this, track,
@@ -1917,9 +1945,9 @@ static int parse_block (demux_matroska_t *this, uint64_t block_size,
}
} else {
- int block_size_left;
+ size_t block_size_left;
uint8_t lace_num;
- int frame[MAX_FRAMES];
+ size_t frame[MAX_FRAMES];
int i;
/* number of laced frames */
@@ -1972,24 +2000,51 @@ static int parse_block (demux_matroska_t *this, uint64_t block_size,
break;
case MATROSKA_EBML_LACING: {
- int64_t tmp;
+ uint64_t first_frame_size;
lprintf("ebml lacing\n");
/* size of each frame */
- if (!(num_len = parse_ebml_uint(this, data, &tmp)))
+ if (!(num_len = parse_ebml_uint(this, data, &first_frame_size)))
+ return 0;
+ if (num_len > block_size_left) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ "demux_matroska: block too small\n");
+ return 0;
+ }
+ if (first_frame_size > INT_MAX) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ "demux_matroska: invalid first frame size (%" PRId64 ")\n",
+ first_frame_size);
return 0;
+ }
data += num_len; block_size_left -= num_len;
- frame[0] = (int) tmp;
+ frame[0] = (int) first_frame_size;
lprintf("first frame len: %d\n", frame[0]);
block_size_left -= frame[0];
for (i = 1; i < lace_num; i++) {
- if (!(num_len = parse_ebml_sint(this, data, &tmp)))
+ int64_t frame_size_diff;
+ int64_t frame_size;
+
+ if (!(num_len = parse_ebml_sint(this, data, &frame_size_diff)))
return 0;
+ if (num_len > block_size_left) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ "demux_matroska: block too small\n");
+ return 0;
+ }
data += num_len; block_size_left -= num_len;
- frame[i] = frame[i-1] + tmp;
+
+ frame_size = frame[i-1] + frame_size_diff;
+ if (frame_size > INT_MAX || frame_size < 0) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ "demux_matroska: invalid frame size (%" PRId64 ")\n",
+ frame_size);
+ return 0;
+ }
+ frame[i] = frame_size;
block_size_left -= frame[i];
}
@@ -2023,6 +2078,31 @@ static int parse_block (demux_matroska_t *this, uint64_t block_size,
return 1;
}
+static int parse_simpleblock(demux_matroska_t *this, size_t block_len, uint64_t cluster_timecode, uint64_t block_duration)
+{
+ int has_block = 0;
+ off_t block_pos = 0;
+ off_t file_len = 0;
+ int normpos = 0;
+ int is_key = 1;
+
+ lprintf("simpleblock\n");
+ block_pos = this->input->get_current_pos(this->input);
+ file_len = this->input->get_length(this->input);
+ if( file_len )
+ normpos = (int) ( (double) block_pos * 65535 / file_len );
+
+ if (!read_block_data(this, block_len))
+ return 0;
+
+ has_block = 1;
+ /* we have the duration, we can parse the block now */
+ if (!parse_block(this, block_len, cluster_timecode, block_duration,
+ normpos, is_key))
+ return 0;
+ return 1;
+}
+
static int parse_block_group(demux_matroska_t *this,
uint64_t cluster_timecode,
uint64_t cluster_duration) {
@@ -2033,7 +2113,7 @@ static int parse_block_group(demux_matroska_t *this,
off_t block_pos = 0;
off_t file_len = 0;
int normpos = 0;
- int block_len = 0;
+ size_t block_len = 0;
int is_key = 1;
while (next_level == 3) {
@@ -2087,7 +2167,8 @@ static int parse_block_group(demux_matroska_t *this,
static int parse_cluster(demux_matroska_t *this) {
ebml_parser_t *ebml = this->ebml;
- int next_level = 2;
+ int this_level = ebml->level;
+ int next_level = this_level;
uint64_t timecode = 0;
uint64_t duration = 0;
@@ -2104,7 +2185,7 @@ static int parse_cluster(demux_matroska_t *this) {
this->first_cluster_found = 1;
}
- while (next_level == 2) {
+ while (next_level == this_level) {
ebml_elem_t elem;
if (!ebml_read_elem_head(ebml, &elem))
@@ -2128,6 +2209,11 @@ static int parse_cluster(demux_matroska_t *this) {
if ((elem.len > 0) && !parse_block_group(this, timecode, duration))
return 0;
break;
+ case MATROSKA_ID_CL_SIMPLEBLOCK:
+ lprintf("simpleblock\n");
+ if (!parse_simpleblock(this, elem.len, timecode, duration))
+ return 0;
+ break;
case MATROSKA_ID_CL_BLOCK:
lprintf("block\n");
if (!ebml_skip(ebml, &elem))
@@ -2274,6 +2360,7 @@ static int parse_top_level_head(demux_matroska_t *this, int *next_level) {
ebml_elem_t elem;
int ret_value = 1;
off_t current_pos;
+
current_pos = this->input->get_current_pos(this->input);
lprintf("current_pos: %" PRIdMAX "\n", (intmax_t)current_pos);
@@ -2824,7 +2911,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
return NULL;
}
- this = xine_xmalloc (sizeof (demux_matroska_t));
+ this = calloc(1, sizeof(demux_matroska_t));
this->demux_plugin.send_headers = demux_matroska_send_headers;
this->demux_plugin.send_chunk = demux_matroska_send_chunk;
@@ -2884,7 +2971,8 @@ static const char *get_extensions (demux_class_t *this_gen) {
static const char *get_mimetypes (demux_class_t *this_gen) {
- return "video/mkv: mkv: matroska;";
+ return "video/mkv: mkv: matroska;"
+ "video/x-matroska: mkv: matroska;";
}
@@ -2899,7 +2987,7 @@ static void *init_class (xine_t *xine, void *data) {
demux_matroska_class_t *this;
- this = xine_xmalloc (sizeof (demux_matroska_class_t));
+ this = calloc(1, sizeof(demux_matroska_class_t));
this->xine = xine;
this->demux_class.open_plugin = open_plugin;
diff --git a/src/demuxers/demux_mng.c b/src/demuxers/demux_mng.c
index 12da8ca86..d0d83ff80 100644
--- a/src/demuxers/demux_mng.c
+++ b/src/demuxers/demux_mng.c
@@ -104,7 +104,12 @@ static mng_bool mymng_close_stream(mng_handle mngh){
static mng_bool mymng_read_stream(mng_handle mngh, mng_ptr buffer, mng_uint32 size, mng_uint32 *bytesread){
demux_mng_t *this = (demux_mng_t*)mng_get_userdata(mngh);
- *bytesread = this->input->read(this->input, buffer, size);
+ off_t n = this->input->read(this->input, buffer, size);
+ if (n < 0) {
+ *bytesread = 0;
+ return MNG_FALSE;
+ }
+ *bytesread = n;
return MNG_TRUE;
}
@@ -112,11 +117,16 @@ static mng_bool mymng_read_stream(mng_handle mngh, mng_ptr buffer, mng_uint32 si
static mng_bool mymng_process_header(mng_handle mngh, mng_uint32 width, mng_uint32 height){
demux_mng_t *this = (demux_mng_t*)mng_get_userdata(mngh);
+ if (width > 0x8000 || height > 0x8000)
+ return MNG_FALSE;
+
this->bih.biWidth = (width + 7) & ~7;
this->bih.biHeight = height;
this->left_edge = (this->bih.biWidth - width) / 2;
- this->image = malloc(this->bih.biWidth * height * 3);
+ this->image = malloc((mng_size_t)this->bih.biWidth * (mng_size_t)height * 3);
+ if (!this->image)
+ return MNG_FALSE;
mng_set_canvasstyle(mngh, MNG_CANVAS_RGB8);
@@ -260,7 +270,7 @@ static demux_plugin_t* open_plugin(demux_class_t *class_gen, xine_stream_t *stre
demux_mng_t *this;
- this = xine_xmalloc (sizeof (demux_mng_t));
+ this = calloc(1, sizeof(demux_mng_t));
this->stream = stream;
this->input = input;
@@ -360,7 +370,7 @@ static void class_dispose(demux_class_t *this){
static void *init_plugin(xine_t *xine, void *data){
demux_mng_class_t *this;
- this = xine_xmalloc (sizeof (demux_mng_class_t));
+ this = calloc(1, sizeof(demux_mng_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_mod.c b/src/demuxers/demux_mod.c
index e7c6f86b3..34b8ebabe 100644
--- a/src/demuxers/demux_mod.c
+++ b/src/demuxers/demux_mod.c
@@ -73,7 +73,7 @@ typedef struct {
char *title;
char *artist;
char *copyright;
- off_t filesize;
+ size_t filesize;
char *buffer;
@@ -130,11 +130,22 @@ static int probe_mod_file(demux_mod_t *this) {
/* returns 1 if the MOD file was opened successfully, 0 otherwise */
static int open_mod_file(demux_mod_t *this) {
int total_read;
+ off_t input_length;
/* Get size and create buffer */
- this->filesize = this->input->get_length(this->input);
+ input_length = this->input->get_length(this->input);
+ /* Avoid potential issues with signed variables and e.g. read() returning -1 */
+ if (input_length > 0x7FFFFFFF || input_length < 0) {
+ xine_log(this->stream->xine, XINE_LOG_PLUGIN, "modplug - size overflow\n");
+ return 0;
+ }
+ this->filesize = input_length;
this->buffer = (char *)malloc(this->filesize);
-
+ if(!this->buffer) {
+ xine_log(this->stream->xine, XINE_LOG_PLUGIN, "modplug - allocation failure\n");
+ return 0;
+ }
+
/* Seek to beginning */
this->input->seek(this->input, 0, SEEK_SET);
@@ -305,7 +316,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
return NULL;
}
- this = xine_xmalloc (sizeof (demux_mod_t));
+ this = calloc(1, sizeof(demux_mod_t));
this->stream = stream;
this->input = input;
@@ -368,7 +379,19 @@ static const char *get_extensions (demux_class_t *this_gen) {
}
static const char *get_mimetypes (demux_class_t *this_gen) {
- return NULL;
+ return "audio/x-mod: mod: SoundTracker/NoiseTracker/ProTracker Module;"
+ "audio/mod: mod: SoundTracker/NoiseTracker/ProTracker Module;"
+ "audio/it: it: ImpulseTracker Module;"
+ "audio/x-it: it: ImpulseTracker Module;"
+ "audio/x-stm: stm: ScreamTracker 2 Module;"
+ "audio/x-s3m: s3m: ScreamTracker 3 Module;"
+ "audio/s3m: s3m: ScreamTracker 3 Module;"
+ "application/playerpro: 669: 669 Tracker Module;"
+ "application/adrift: amf: ADRIFT Module File;"
+ "audio/med: med: Amiga MED/OctaMED Tracker Module Sound File;"
+ "audio/x-amf: amf: ADRIFT Module File;"
+ "audio/x-xm: xm: FastTracker II Audio;"
+ "audio/xm: xm: FastTracker II Audio;";
}
static void class_dispose (demux_class_t *this_gen) {
@@ -380,7 +403,7 @@ static void class_dispose (demux_class_t *this_gen) {
void *demux_mod_init_plugin (xine_t *xine, void *data) {
demux_mod_class_t *this;
- this = xine_xmalloc (sizeof (demux_mod_class_t));
+ this = calloc(1, sizeof(demux_mod_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_mpc.c b/src/demuxers/demux_mpc.c
index 346f0c2e6..220e1b8b6 100644
--- a/src/demuxers/demux_mpc.c
+++ b/src/demuxers/demux_mpc.c
@@ -47,6 +47,7 @@
#include "buffer.h"
#include "bswap.h"
#include "group_audio.h"
+#include "id3.h"
/* Note that the header is actually 25 bytes long, so we'd only read 28
* (because of byte swapping we have to round up to nearest multiple of 4)
@@ -89,17 +90,13 @@ static int open_mpc_file(demux_mpc_t *this) {
/* TODO: non-seeking version */
if (INPUT_IS_SEEKABLE(this->input)) {
/* Check for id3v2 tag */
- if ((this->header[0] == 'I') ||
- (this->header[1] == 'D') ||
- (this->header[2] == '3')) {
+ if (id3v2_istag(this->header)) {
lprintf("found id3v2 header\n");
/* Read tag size */
- id3v2_size = (this->header[6] << 21) +
- (this->header[7] << 14) +
- (this->header[8] << 7) +
- this->header[9] + 10;
+
+ id3v2_size = _X_BE_32_synchsafe(&this->header[6]) + 10;
/* Add footer size if one is present */
if (this->header[5] & 0x10)
@@ -118,9 +115,7 @@ static int open_mpc_file(demux_mpc_t *this) {
}
/* Validate signature - We only support SV 7.x at the moment */
- if ((this->header[0] != 'M') ||
- (this->header[1] != 'P') ||
- (this->header[2] != '+') ||
+ if ( memcmp(this->header, "MP+", 3) != 0 ||
((this->header[3]&0x0f) != 0x07))
return 0;
@@ -214,7 +209,7 @@ static int demux_mpc_send_chunk(demux_plugin_t *this_gen) {
/* Read data */
bytes_read = this->input->read(this->input, buf->content, bytes_to_read);
- if(bytes_read == 0) {
+ if(bytes_read <= 0) {
buf->free_buffer(buf);
this->status = DEMUX_FINISHED;
return this->status;
@@ -324,7 +319,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
demux_mpc_t *this;
- this = xine_xmalloc (sizeof (demux_mpc_t));
+ this = calloc(1, sizeof(demux_mpc_t));
this->stream = stream;
this->input = input;
@@ -381,11 +376,12 @@ static const char *get_identifier (demux_class_t *this_gen) {
}
static const char *get_extensions (demux_class_t *this_gen) {
- return "mpc mp+";
+ return "mpc mp+ mpp";
}
static const char *get_mimetypes (demux_class_t *this_gen) {
- return NULL;
+ return "audio/musepack: mpc, mp+, mpp: Musepack audio;"
+ "audio/x-musepack: mpc, mp+, mpp: Musepack audio;";
}
static void class_dispose (demux_class_t *this_gen) {
@@ -397,7 +393,7 @@ static void class_dispose (demux_class_t *this_gen) {
void *demux_mpc_init_plugin (xine_t *xine, void *data) {
demux_mpc_class_t *this;
- this = xine_xmalloc (sizeof (demux_mpc_class_t));
+ this = calloc(1, sizeof(demux_mpc_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_mpeg.c b/src/demuxers/demux_mpeg.c
index 4419f8404..85b62f48e 100644
--- a/src/demuxers/demux_mpeg.c
+++ b/src/demuxers/demux_mpeg.c
@@ -279,6 +279,10 @@ static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, int64_t scr)
if((this->dummy_space[0] & 0xE0) == 0x20) {
buf = this->input->read_block (this->input, this->video_fifo, len-1);
+ if (! buf) {
+ this->status = DEMUX_FINISHED;
+ return;
+ }
track = (this->dummy_space[0] & 0x1f);
@@ -298,6 +302,10 @@ static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, int64_t scr)
int spu_id = this->dummy_space[1] & 0x03;
buf = this->input->read_block (this->input, this->video_fifo, len-1);
+ if (! buf) {
+ this->status = DEMUX_FINISHED;
+ return;
+ }
buf->type = BUF_SPU_SVCD + spu_id;
buf->pts = pts;
@@ -318,6 +326,10 @@ static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, int64_t scr)
if((this->dummy_space[0] & 0xfc) == 0x00) {
buf = this->input->read_block (this->input, this->video_fifo, len-1);
+ if (! buf) {
+ this->status = DEMUX_FINISHED;
+ return;
+ }
buf->type = BUF_SPU_CVD + (this->dummy_space[0] & 0x03);
buf->pts = pts;
@@ -330,7 +342,7 @@ static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, int64_t scr)
if((this->dummy_space[0] & 0xf0) == 0x80) {
/* read rest of header - AC3 */
- i = this->input->read (this->input, this->dummy_space+1, 3);
+ this->input->read (this->input, this->dummy_space+1, 3);
/* contents */
for (i = len - 4; i > 0; i -= (this->audio_fifo)
@@ -376,6 +388,10 @@ static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, int64_t scr)
i = this->input->read (this->input, this->dummy_space+1, 6);
buf = this->input->read_block (this->input, this->video_fifo, len-7);
+ if (! buf) {
+ this->status = DEMUX_FINISHED;
+ return;
+ }
buf->type = BUF_AUDIO_LPCM_BE + track;
buf->decoder_flags |= BUF_FLAG_SPECIAL;
@@ -431,7 +447,7 @@ static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, int64_t scr)
header_len -= 5 ;
}
- i = this->input->read (this->input, this->dummy_space, header_len);
+ this->input->read (this->input, this->dummy_space, header_len);
for (i = len; i > 0; i -= (this->audio_fifo)
? this->audio_fifo->buffer_pool_buf_size : this->video_fifo->buffer_pool_buf_size) {
@@ -503,7 +519,7 @@ static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, int64_t scr)
}
/* read rest of header */
- i = this->input->read (this->input, this->dummy_space, header_len);
+ this->input->read (this->input, this->dummy_space, header_len);
/* contents */
@@ -920,7 +936,7 @@ static void demux_mpeg_resync (demux_mpeg_t *this, uint32_t buf) {
if (pos == len) {
len = this->input->read(this->input, dummy_buf, sizeof(dummy_buf));
pos = 0;
- if (len == 0) {
+ if (len <= 0) {
this->status = DEMUX_FINISHED;
break;
}
@@ -1067,7 +1083,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
input_plugin_t *input) {
demux_mpeg_t *this;
- this = xine_xmalloc (sizeof (demux_mpeg_t));
+ this = calloc(1, sizeof(demux_mpeg_t));
this->stream = stream;
this->input = input;
@@ -1246,7 +1262,7 @@ static void class_dispose (demux_class_t *this_gen) {
static void *init_plugin (xine_t *xine, void *data) {
demux_mpeg_class_t *this;
- this = xine_xmalloc (sizeof (demux_mpeg_class_t));
+ this = calloc(1, sizeof(demux_mpeg_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_mpeg_block.c b/src/demuxers/demux_mpeg_block.c
index 32638129d..ffbc63f3d 100644
--- a/src/demuxers/demux_mpeg_block.c
+++ b/src/demuxers/demux_mpeg_block.c
@@ -1190,14 +1190,14 @@ static int demux_mpeg_detect_blocksize(demux_mpeg_block_t *this,
input_plugin_t *input)
{
input->seek(input, 2048, SEEK_SET);
- if (!input->read(input, this->scratch, 4))
+ if (input->read(input, this->scratch, 4) != 4)
return 0;
if (this->scratch[0] || this->scratch[1]
|| (this->scratch[2] != 0x01) || (this->scratch[3] != 0xba)) {
input->seek(input, 2324, SEEK_SET);
- if (!input->read(input, this->scratch, 4))
+ if (input->read(input, this->scratch, 4) != 4)
return 0;
if (this->scratch[0] || this->scratch[1]
|| (this->scratch[2] != 0x01) || (this->scratch[3] != 0xba))
@@ -1371,7 +1371,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
input_plugin_t *input = (input_plugin_t *) input_gen;
demux_mpeg_block_t *this;
- this = xine_xmalloc (sizeof (demux_mpeg_block_t));
+ this = calloc(1, sizeof(demux_mpeg_block_t));
this->stream = stream;
this->input = input;
@@ -1417,6 +1417,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
}
input->seek(input, 0, SEEK_SET);
+ memset (this->scratch, 255, 5); /* result of input->read() won't matter */
if (input->read(input, this->scratch, this->blocksize)) {
lprintf("open_plugin:read worked\n");
@@ -1540,7 +1541,7 @@ static void *init_plugin (xine_t *xine, void *data) {
demux_mpeg_block_class_t *this;
- this = xine_xmalloc (sizeof (demux_mpeg_block_class_t));
+ this = calloc(1, sizeof(demux_mpeg_block_class_t));
this->config = xine->config;
this->xine = xine;
diff --git a/src/demuxers/demux_mpeg_pes.c b/src/demuxers/demux_mpeg_pes.c
index 423da5e24..b7c0e7e6d 100644
--- a/src/demuxers/demux_mpeg_pes.c
+++ b/src/demuxers/demux_mpeg_pes.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2006 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -257,7 +257,6 @@ static void demux_mpeg_pes_parse_pack (demux_mpeg_pes_t *this, int preview_mode)
uint8_t *p;
int32_t result;
off_t i;
- int32_t n;
uint8_t buf6[ 6 ];
this->scr = 0;
@@ -274,7 +273,7 @@ static void demux_mpeg_pes_parse_pack (demux_mpeg_pes_t *this, int preview_mode)
while ((p[2] != 1) || p[0] || p[1]) {
/* resync code */
- for(n=0;n<5;n++) p[n]=p[n+1];
+ memmove(p, p+1, 5);
i = read_data(this, p+5, (off_t) 1);
if (i != 1) {
this->status = DEMUX_FINISHED;
@@ -306,8 +305,7 @@ static void demux_mpeg_pes_parse_pack (demux_mpeg_pes_t *this, int preview_mode)
p = buf->mem;
/* copy local buffer to fifo element. */
- for (n = 0; n < sizeof (buf6); n++)
- p[ n ] = buf6[ n ];
+ memcpy(p, buf6, sizeof(buf6));
if (preview_mode)
buf->decoder_flags = BUF_FLAG_PREVIEW;
@@ -1613,7 +1611,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
input_plugin_t *input = (input_plugin_t *) input_gen;
demux_mpeg_pes_t *this;
- this = xine_xmalloc (sizeof (demux_mpeg_pes_t));
+ this = calloc(1, sizeof(demux_mpeg_pes_t));
this->stream = stream;
this->input = input;
@@ -1688,7 +1686,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
if (((input->get_capabilities(input) & INPUT_CAP_SEEKABLE) != 0) ) {
input->seek(input, 0, SEEK_SET);
- if (input->read(input, (char *)this->scratch, 6)) {
+ if (input->read(input, (char *)this->scratch, 6) == 6) {
lprintf("open_plugin:read worked\n");
if (this->scratch[0] || this->scratch[1]
@@ -1786,7 +1784,7 @@ static void class_dispose (demux_class_t *this_gen) {
static void *init_plugin (xine_t *xine, void *data) {
demux_mpeg_pes_class_t *this;
- this = xine_xmalloc (sizeof (demux_mpeg_pes_class_t));
+ this = calloc(1, sizeof(demux_mpeg_pes_class_t));
this->config = xine->config;
this->xine = xine;
diff --git a/src/demuxers/demux_mpgaudio.c b/src/demuxers/demux_mpgaudio.c
index 3730da6e4..a87de5f97 100644
--- a/src/demuxers/demux_mpgaudio.c
+++ b/src/demuxers/demux_mpgaudio.c
@@ -33,7 +33,7 @@
#include <string.h>
#include <stdlib.h>
-#define LOG_MODULE "demux_mpeg_audio"
+#define LOG_MODULE "demux_mpgaudio"
#define LOG_VERBOSE
/*
#define LOG
@@ -51,8 +51,8 @@
* the second mp3 frame is sent to the decoder
*/
#define NUM_PREVIEW_BUFFERS 2
+#define NUM_VALID_FRAMES 3
-#define WRAP_THRESHOLD 120000
#define FOURCC_TAG BE_FOURCC
#define RIFF_CHECK_BYTES 1024
@@ -79,16 +79,16 @@
/* mp3 frame struct */
typedef struct {
/* header */
- double duration;
- uint32_t size; /* in bytes */
+ double duration; /* in milliseconds */
+ uint32_t size; /* in bytes; including padding */
uint32_t bitrate; /* in bit per second */
uint16_t freq; /* in Hz */
-
uint8_t layer;
-
uint8_t version_idx:2; /* 0: mpeg1, 1: mpeg2, 2: mpeg2.5 */
uint8_t lsf_bit:1;
uint8_t channel_mode:3;
+ uint8_t padding:3; /* in bytes */
+ uint8_t is_free_bitrate:1;
} mpg_audio_frame_t;
/* Xing Vbr Header struct */
@@ -131,7 +131,13 @@ typedef struct {
int br; /* bitrate in bits/second */
uint32_t blocksize;
+ /* current mp3 frame */
mpg_audio_frame_t cur_frame;
+
+ /* next mp3 frame, used when the frame size cannot be computed from the
+ * current frame header */
+ mpg_audio_frame_t next_frame;
+
double cur_time; /* in milliseconds */
off_t mpg_frame_start; /* offset */
@@ -141,7 +147,15 @@ typedef struct {
int check_vbr_header;
xing_header_t *xing_header;
vbri_header_t *vbri_header;
-
+
+ int found_next_frame:1;
+ int free_bitrate_count;
+ off_t free_bitrate_size; /* use this size if 3 free bitrate frames are encountered */
+ uint8_t next_header[4];
+ int mpg_version;
+ int mpg_layer;
+ int valid_frames;
+
} demux_mpgaudio_t ;
/* demuxer class struct */
@@ -212,14 +226,14 @@ static int parse_frame_header(mpg_audio_frame_t *const frame, const uint8_t *con
const uint32_t head = _X_BE_32(buf);
const uint16_t frame_sync = head >> 21;
- lprintf("header: %08X\n", head);
if (frame_sync != 0x7ff) {
- lprintf("invalid frame sync\n");
+ lprintf("invalid frame sync %08X\n", head);
return 0;
}
+ lprintf("header: %08X\n", head);
frame_header.mpeg25_bit = (head >> 20) & 0x1;
- frame->lsf_bit = (head >> 19) & 0x1;
+ frame->lsf_bit = (head >> 19) & 0x1;
if (!frame_header.mpeg25_bit) {
if (frame->lsf_bit) {
lprintf("reserved mpeg25 lsf combination\n");
@@ -240,14 +254,14 @@ static int parse_frame_header(mpg_audio_frame_t *const frame, const uint8_t *con
}
frame_header.bitrate_idx = (head >> 12) & 0xf;
- if ((frame_header.bitrate_idx == 0) || (frame_header.bitrate_idx == 15)) {
- lprintf("invalid bitrate index\n");
+ if (frame_header.bitrate_idx == 15) {
+ lprintf("invalid bitrate index: %d\n", frame_header.bitrate_idx);
return 0;
}
frame_header.freq_idx = (head >> 10) & 0x3;
if (frame_header.freq_idx == 3) {
- lprintf("invalid frequence index\n");
+ lprintf("invalid frequence index: %d\n", frame_header.freq_idx);
return 0;
}
@@ -280,19 +294,27 @@ static int parse_frame_header(mpg_audio_frame_t *const frame, const uint8_t *con
const uint16_t samples = mp3_samples[frame->version_idx][frame->layer - 1];
frame->bitrate = mp3_bitrates[frame->version_idx][frame->layer - 1][frame_header.bitrate_idx] * 1000;
frame->freq = mp3_freqs[frame->version_idx][frame_header.freq_idx];
-
- frame->size = samples * (frame->bitrate / 8);
- frame->size /= frame->freq;
- /* Padding: only if padding_bit is set; 4 bytes for Layer 1 and 1 byte for others */
- frame->size += ( frame_header.padding_bit ? ( frame->layer == 1 ? 4 : 1 ) : 0 );
-
frame->duration = 1000.0f * (double)samples / (double)frame->freq;
+ frame->padding = ( frame_header.padding_bit ? ( frame->layer == 1 ? 4 : 1 ) : 0 );
+ frame->channel_mode = frame_header.channel_mode;
+
+ if (frame->bitrate > 0) {
+ frame->size = samples * (frame->bitrate / 8);
+ frame->size /= frame->freq;
+ /* Padding: only if padding_bit is set; 4 bytes for Layer 1 and 1 byte for others */
+ frame->size += frame->padding;
+ } else {
+ /* Free bitrate frame, the size of the frame cannot be computed from the header. */
+ frame->is_free_bitrate = 1;
+ frame->size = 0;
+ }
}
- lprintf("mpeg %d, layer %d\n", frame->version_idx + 1, frame->layer);
- lprintf("bitrate: %d bps, samplerate: %d Hz\n", frame->bitrate, frame->freq);
+ lprintf("mpeg %d, layer %d, channel_mode: %d\n", frame->version_idx + 1,
+ frame->layer, frame->channel_mode);
+ lprintf("bitrate: %d bps, output freq: %d Hz\n", frame->bitrate, frame->freq);
lprintf("length: %d bytes, %f ms\n", frame->size, frame->duration);
- lprintf("padding: %d bytes\n", ( frame_header.padding_bit ? ( frame->layer == 1 ? 4 : 1 ) : 0 ));
+ lprintf("padding: %d bytes\n", frame->padding);
return 1;
}
@@ -300,8 +322,8 @@ static int parse_frame_header(mpg_audio_frame_t *const frame, const uint8_t *con
* Parse a Xing header
* return the Xing header or NULL on error
*/
-static xing_header_t* parse_xing_header(mpg_audio_frame_t *frame,
- uint8_t *buf, int bufsize) {
+static xing_header_t *XINE_MALLOC parse_xing_header(mpg_audio_frame_t *frame,
+ uint8_t *buf, int bufsize) {
uint8_t *ptr = buf;
xing_header_t *xing = NULL;
@@ -325,11 +347,11 @@ static xing_header_t* parse_xing_header(mpg_audio_frame_t *frame,
int has_frames_flag = 0;
int has_bytes_flag = 0;
- xing = xine_xmalloc (sizeof (xing_header_t));
+ xing = calloc(1, sizeof(xing_header_t));
if (!xing)
goto exit_error;
- lprintf("Xing header found\n");
+ lprintf("found Xing header\n");
ptr += 4;
if (ptr >= (buf + bufsize - 4)) goto exit_error;
@@ -416,14 +438,14 @@ exit_error:
* Parse a Vbri header
* return the Vbri header or NULL on error
*/
-static vbri_header_t* parse_vbri_header(mpg_audio_frame_t *frame,
- uint8_t *buf, int bufsize) {
+static vbri_header_t *XINE_MALLOC parse_vbri_header(mpg_audio_frame_t *frame,
+ uint8_t *buf, int bufsize) {
int i;
uint8_t *ptr = buf;
vbri_header_t *vbri;
- vbri = xine_xmalloc (sizeof (vbri_header_t));
+ vbri = calloc(1, sizeof(vbri_header_t));
if (!vbri)
return NULL;
@@ -432,7 +454,7 @@ static vbri_header_t* parse_vbri_header(mpg_audio_frame_t *frame,
if ((ptr + 4) >= (buf + bufsize)) return 0;
lprintf("Checking %08X\n", *ptr);
if (_X_BE_32(ptr) == VBRI_TAG) {
- lprintf("Vbri header found\n");
+ lprintf("found Vbri header\n");
ptr += 4;
if ((ptr + 22) >= (buf + bufsize)) return 0;
@@ -456,7 +478,7 @@ static vbri_header_t* parse_vbri_header(mpg_audio_frame_t *frame,
lprintf("entry_frames: %d\n", vbri->entry_frames);
if ((ptr + (vbri->toc_entries + 1) * vbri->entry_size) >= (buf + bufsize)) return 0;
- vbri->toc = xine_xmalloc (sizeof(int) * (vbri->toc_entries + 1));
+ vbri->toc = calloc (vbri->toc_entries + 1, sizeof (int));
if (!vbri->toc) {
free (vbri);
return NULL;
@@ -496,6 +518,7 @@ static vbri_header_t* parse_vbri_header(mpg_audio_frame_t *frame,
}
}
+
/*
* Parse a mp3 frame paylod
* return 1 on success, 0 on error
@@ -506,43 +529,97 @@ static int parse_frame_payload(demux_mpgaudio_t *this,
buf_element_t *buf;
off_t frame_pos, len;
uint64_t pts = 0;
+ int payload_size = 0;
frame_pos = this->input->get_current_pos(this->input) - 4;
- lprintf("frame_pos = %"PRId64"\n", frame_pos);
+ lprintf("frame_pos = %"PRId64", header: %08X\n", frame_pos, _X_BE_32(frame_header));
buf = this->audio_fifo->buffer_pool_alloc(this->audio_fifo);
if (this->cur_frame.size > buf->max_size) {
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
- "demux_mpgaudio: frame size is greater than fifo buffer size\n");
+ LOG_MODULE ": frame size is greater than fifo buffer size\n");
buf->free_buffer(buf);
return 0;
}
-
- /* the decoder needs the frame header */
- memcpy(buf->mem, frame_header, 4);
- len = this->input->read(this->input, buf->mem + 4, this->cur_frame.size - 4);
- if (len != (this->cur_frame.size - 4)) {
- buf->free_buffer(buf);
- return 0;
+ memcpy(buf->content, frame_header, 4);
+
+ /* compute the payload size */
+ if (this->cur_frame.size > 0) {
+ payload_size = this->cur_frame.size - 4;
+ this->free_bitrate_count = 0;
+ } else if (this->free_bitrate_count >= NUM_VALID_FRAMES) {
+ payload_size = this->free_bitrate_size + this->cur_frame.padding - 4;
+ this->cur_frame.size = payload_size + 4;
+ } else {
+ this->free_bitrate_count++;
+ payload_size = 0;
+ }
+
+ /* Read the payload data. */
+ if (payload_size > 0) {
+ off_t len;
+
+ /* If we know the payload size, it's easy */
+ this->found_next_frame = 0;
+ len = this->input->read(this->input, buf->content + 4, payload_size);
+ if (len != payload_size) {
+ buf->free_buffer(buf);
+ return 0;
+ }
+ } else {
+ /* Search for the beginning of the next frame and deduce the size of the
+ * current frame from the position of the next one. */
+ int payload_size = 0;
+ int max_size = buf->max_size - 4;
+
+ while (payload_size < max_size) {
+ len = this->input->read(this->input, &buf->content[4 + payload_size], 1);
+ if (len != 1) {
+ lprintf("EOF\n");
+ buf->free_buffer(buf);
+ return 0;
+ }
+ payload_size += len;
+
+ if (parse_frame_header(&this->next_frame, &buf->content[payload_size])) {
+ lprintf("found next frame header\n");
+
+ if (this->free_bitrate_size == 0) {
+ this->free_bitrate_size = payload_size - this->cur_frame.padding;
+ }
+
+ /* don't read the frame header twice */
+ this->found_next_frame = 1;
+ memcpy(&this->next_header[0], &buf->content[payload_size], 4);
+ payload_size -= 4;
+ break;
+ }
+ }
+ this->cur_frame.size = payload_size + 4;
+ this->cur_frame.bitrate = 8000 * this->cur_frame.size / this->cur_frame.duration;
+ lprintf("free bitrate: bitrate: %d, frame size: %d\n", this->br, this->cur_frame.size);
}
if (this->check_vbr_header) {
this->check_vbr_header = 0;
this->mpg_frame_start = frame_pos;
- this->xing_header = parse_xing_header(&this->cur_frame, buf->mem, this->cur_frame.size);
+ this->xing_header = parse_xing_header(&this->cur_frame, buf->content, this->cur_frame.size);
if (this->xing_header) {
buf->free_buffer(buf);
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ LOG_MODULE ": found Xing header at offset %"PRId64"\n", frame_pos);
return 1;
}
- this->vbri_header = parse_vbri_header(&this->cur_frame, buf->mem, this->cur_frame.size);
+ this->vbri_header = parse_vbri_header(&this->cur_frame, buf->content, this->cur_frame.size);
if (this->vbri_header) {
buf->free_buffer(buf);
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ LOG_MODULE ": found Vbri header at offset %"PRId64"\n", frame_pos);
return 1;
}
}
-
pts = (int64_t)(this->cur_time * 90.0f);
@@ -551,8 +628,7 @@ static int parse_frame_payload(demux_mpgaudio_t *this,
buf->extra_info->input_time = this->cur_time;
buf->pts = pts;
- buf->size = len + 4;
- buf->content = buf->mem;
+ buf->size = this->cur_frame.size;
buf->type = BUF_AUDIO_MPEG;
buf->decoder_info[0] = 1;
buf->decoder_flags = decoder_flags | BUF_FLAG_FRAME_END;
@@ -572,8 +648,8 @@ static int parse_frame_payload(demux_mpgaudio_t *this,
}
}
+ lprintf("send buffer: size=%d, pts=%"PRId64"\n", buf->size, pts);
this->audio_fifo->put(this->audio_fifo, buf);
- lprintf("send buffer: pts=%"PRId64"\n", pts);
this->cur_time += this->cur_frame.duration;
return 1;
}
@@ -583,11 +659,12 @@ static int parse_frame_payload(demux_mpgaudio_t *this,
* 32-bit MP3 frame header.
* return 1 if found, 0 if not found
*/
-static int sniff_buffer_looks_like_mp3 (uint8_t *buf, int buflen)
+static int sniff_buffer_looks_like_mp3 (uint8_t *buf, int buflen, int *version, int *layer)
{
int offset;
mpg_audio_frame_t frame;
+ *version = *layer = 0;
if (buf == NULL)
return 0;
@@ -596,20 +673,21 @@ static int sniff_buffer_looks_like_mp3 (uint8_t *buf, int buflen)
if (parse_frame_header(&frame, buf + offset)) {
size_t size = frame.size;
- /* Since one frame is available, is there another frame
- * just to be sure this is more likely to be a real MP3
- * buffer? */
- offset += size;
-
- if (offset + 4 >= buflen) {
- return 0;
- }
+ if (size > 0) {
+ /* Since one frame is available, is there another frame
+ * just to be sure this is more likely to be a real MP3
+ * buffer? */
+ if (offset + size + 4 >= buflen) {
+ return 0;
+ }
- if (parse_frame_header(&frame, buf + offset)) {
- lprintf("mpeg audio frame detected\n");
- return 1;
+ if (parse_frame_header(&frame, buf + offset + size)) {
+ *version = frame.version_idx + 1;
+ *layer = frame.layer;
+ lprintf("frame detected, mpeg %d layer %d\n", *version, *layer);
+ return 1;
+ }
}
- break;
}
}
return 0;
@@ -637,40 +715,51 @@ static int read_frame_header(demux_mpgaudio_t *this, uint8_t *header_buf, int by
* Parse next mp3 frame
*/
static int demux_mpgaudio_next (demux_mpgaudio_t *this, int decoder_flags, int send_header) {
- uint8_t header_buf[4];
- int bytes = 4;
-
- for (;;) {
-
- if (read_frame_header(this, header_buf, bytes)) {
-
- if (parse_frame_header(&this->cur_frame, header_buf)) {
-
- /* send header buffer */
- if ( send_header ) {
- buf_element_t *buf;
-
- buf = this->audio_fifo->buffer_pool_alloc(this->audio_fifo);
-
- buf->type = BUF_AUDIO_MPEG;
- buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END;
-
- buf->decoder_info[0] = 0;
- buf->decoder_info[1] = this->cur_frame.freq;
- buf->decoder_info[2] = 0; /* bits_per_sample */
-
- /* Only for channel_mode == 3 (mono) there is one channel, for any other case, there are 2 */
- buf->decoder_info[3] = ( this->cur_frame.channel_mode == 3 ) ? 1 : 2;
-
- buf->size = 0; /* No extra header data */
-
- this->audio_fifo->put(this->audio_fifo, buf);
- }
-
- return parse_frame_payload(this, header_buf, decoder_flags);
-
- } else if ( id3v2_istag(header_buf) ) {
- if (!id3v2_parse_tag(this->input, this->stream, header_buf)) {
+ uint8_t buffer[4];
+ uint8_t *header = buffer;
+
+ if (this->found_next_frame) {
+ lprintf("skip header reading\n");
+ header = this->next_header;
+ memcpy(&this->cur_frame, &this->next_frame, sizeof(mpg_audio_frame_t));
+ } else {
+ int bytes = 4;
+ int loose_sync = 0;
+
+ for (;;) {
+ if (!read_frame_header(this, header, bytes))
+ return 0;
+ if (parse_frame_header(&this->cur_frame, header)) {
+ lprintf("frame found\n");
+
+ /* additionnal checks */
+ if ((this->mpg_version == (this->cur_frame.version_idx + 1)) &&
+ (this->mpg_layer == this->cur_frame.layer)) {
+ this->valid_frames++;
+ break;
+ } else {
+ if (this->valid_frames >= NUM_VALID_FRAMES) {
+ lprintf("invalid frame. expected mpeg %d, layer %d\n", this->mpg_version, this->mpg_layer);
+ } else {
+ this->mpg_version = this->cur_frame.version_idx + 1;
+ this->mpg_layer = this->cur_frame.layer;
+ this->valid_frames = 0;
+ break;
+ }
+ }
+ }
+
+ if (!loose_sync) {
+ off_t frame_pos = this->input->get_current_pos(this->input) - 4;
+ loose_sync = 1;
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ LOG_MODULE ": loose mp3 sync at offset %"PRId64"\n", frame_pos);
+ }
+ /* the stream is broken, don't keep info about previous frames */
+ this->free_bitrate_size = 0;
+
+ if ( id3v2_istag(header) ) {
+ if (!id3v2_parse_tag(this->input, this->stream, header)) {
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
LOG_MODULE ": ID3V2 tag parsing error\n");
bytes = 1; /* resync */
@@ -681,12 +770,31 @@ static int demux_mpgaudio_next (demux_mpgaudio_t *this, int decoder_flags, int s
/* skip */
bytes = 1;
}
-
- } else {
- lprintf("read error\n");
- return 0;
}
}
+
+ /* send header buffer */
+ if ( send_header ) {
+ buf_element_t *buf;
+
+ buf = this->audio_fifo->buffer_pool_alloc(this->audio_fifo);
+
+ buf->type = BUF_AUDIO_MPEG;
+ buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END;
+
+ buf->decoder_info[0] = 0;
+ buf->decoder_info[1] = this->cur_frame.freq;
+ buf->decoder_info[2] = 0; /* bits_per_sample */
+
+ /* Only for channel_mode == 3 (mono) there is one channel, for any other case, there are 2 */
+ buf->decoder_info[3] = ( this->cur_frame.channel_mode == 3 ) ? 1 : 2;
+
+ buf->size = 0; /* No extra header data */
+
+ this->audio_fifo->put(this->audio_fifo, buf);
+ }
+
+ return parse_frame_payload(this, header, decoder_flags);
}
static int demux_mpgaudio_send_chunk (demux_plugin_t *this_gen) {
@@ -742,12 +850,13 @@ static int demux_mpgaudio_read_head(input_plugin_t *input, uint8_t *buf) {
* mp3 stream detection
* return 1 if detected, 0 otherwise
*/
-static int detect_mpgaudio_file(input_plugin_t *input) {
- mpg_audio_frame_t frame;
+static int detect_mpgaudio_file(input_plugin_t *input,
+ int *version, int *layer) {
uint8_t buf[MAX_PREVIEW_SIZE];
int preview_len;
uint32_t head;
+ *version = *layer = 0;
preview_len = demux_mpgaudio_read_head(input, buf);
if (preview_len < 4)
return 0;
@@ -774,15 +883,15 @@ static int detect_mpgaudio_file(input_plugin_t *input) {
lprintf("cannot read mp3 frame header\n");
return 0;
}
- if (!parse_frame_header(&frame, &buf[10 + tag_size])) {
- lprintf ("invalid mp3 frame header\n");
+ if (!sniff_buffer_looks_like_mp3(&buf[10 + tag_size], preview_len - 10 - tag_size, version, layer)) {
+ lprintf ("sniff_buffer_looks_like_mp3 failed\n");
return 0;
} else {
lprintf ("a valid mp3 frame follows the id3v2 tag\n");
}
} else if (head == MPEG_MARKER) {
return 0;
- } else if (!sniff_buffer_looks_like_mp3(buf, preview_len)) {
+ } else if (!sniff_buffer_looks_like_mp3(buf, preview_len, version, layer)) {
lprintf ("sniff_buffer_looks_like_mp3 failed\n");
return 0;
}
@@ -821,11 +930,12 @@ static void demux_mpgaudio_send_headers (demux_plugin_t *this_gen) {
*/
this->check_vbr_header = 1;
for (i = 0; i < NUM_PREVIEW_BUFFERS; i++) {
+ lprintf("preview buffer number %d / %d\n", i + 1, NUM_PREVIEW_BUFFERS);
if (!demux_mpgaudio_next (this, BUF_FLAG_PREVIEW, i == 0)) {
break;
}
}
-
+
if (this->xing_header) {
xing_header_t *xing = this->xing_header;
@@ -836,7 +946,7 @@ static void demux_mpgaudio_send_headers (demux_plugin_t *this_gen) {
if (this->stream_length) {
this->br = ((uint64_t)xing->stream_size * 8 * 1000) / this->stream_length;
}
-
+
} else if (this->vbri_header) {
vbri_header_t *vbri = this->vbri_header;
@@ -879,7 +989,7 @@ static void demux_mpgaudio_send_headers (demux_plugin_t *this_gen) {
{
char scratch_buf[256];
char *mpeg_ver[3] = {"1", "2", "2.5"};
-
+
snprintf(scratch_buf, 256, "MPEG %s Layer %1d%s",
mpeg_ver[this->cur_frame.version_idx], this->cur_frame.layer,
(this->xing_header)? " VBR" : " CBR" );
@@ -1007,7 +1117,8 @@ static int demux_mpgaudio_seek (demux_plugin_t *this_gen,
/* assume seeking is always perfect... */
this->cur_time = start_time;
this->input->seek (this->input, seek_pos, SEEK_SET);
-
+ this->found_next_frame = 0;
+
if (playing) {
_x_demux_flush_engine(this->stream);
}
@@ -1047,13 +1158,15 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
input_plugin_t *input) {
demux_mpgaudio_t *this;
+ int version = 0;
+ int layer = 0;
lprintf("trying to open %s...\n", input->get_mrl(input));
switch (stream->content_detection_method) {
case METHOD_BY_CONTENT: {
- if (!detect_mpgaudio_file(input))
+ if (!detect_mpgaudio_file(input, &version, &layer))
return NULL;
}
break;
@@ -1076,8 +1189,8 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
default:
return NULL;
}
-
- this = xine_xmalloc (sizeof (demux_mpgaudio_t));
+
+ this = calloc(1, sizeof(demux_mpgaudio_t));
this->demux_plugin.send_headers = demux_mpgaudio_send_headers;
this->demux_plugin.send_chunk = demux_mpgaudio_send_chunk;
@@ -1088,12 +1201,17 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
this->demux_plugin.get_capabilities = demux_mpgaudio_get_capabilities;
this->demux_plugin.get_optional_data = demux_mpgaudio_get_optional_data;
this->demux_plugin.demux_class = class_gen;
-
- this->input = input;
- this->audio_fifo = stream->audio_fifo;
- this->status = DEMUX_FINISHED;
- this->stream = stream;
-
+
+ this->input = input;
+ this->audio_fifo = stream->audio_fifo;
+ this->status = DEMUX_FINISHED;
+ this->stream = stream;
+
+ this->mpg_version = version;
+ this->mpg_layer = layer;
+ if (version || layer) {
+ this->valid_frames = NUM_VALID_FRAMES;
+ }
return &this->demux_plugin;
}
@@ -1147,7 +1265,7 @@ void *demux_mpgaudio_init_class (xine_t *xine, void *data) {
demux_mpgaudio_class_t *this;
- this = xine_xmalloc (sizeof (demux_mpgaudio_class_t));
+ this = calloc(1, sizeof(demux_mpgaudio_class_t));
this->xine = xine;
this->demux_class.open_plugin = open_plugin;
diff --git a/src/demuxers/demux_nsf.c b/src/demuxers/demux_nsf.c
index 81f42044f..926ea97e1 100644
--- a/src/demuxers/demux_nsf.c
+++ b/src/demuxers/demux_nsf.c
@@ -97,18 +97,14 @@ static int open_nsf_file(demux_nsf_t *this) {
return 0;
/* check for the signature */
- if ((header[0] != 'N') ||
- (header[1] != 'E') ||
- (header[2] != 'S') ||
- (header[3] != 'M') ||
- (header[4] != 0x1A))
+ if (memcmp(header, "NESM\x1A", 5) != 0)
return 0;
this->total_songs = header[6];
this->current_song = header[7];
- this->title = strdup(&header[0x0E]);
- this->artist = strdup(&header[0x2E]);
- this->copyright = strdup(&header[0x4E]);
+ this->title = strndup((char*)&header[0x0E], 0x20);
+ this->artist = strndup((char*)&header[0x2E], 0x20);
+ this->copyright = strndup((char*)&header[0x4E], 0x20);
this->filesize = this->input->get_length(this->input);
@@ -128,7 +124,7 @@ static int demux_nsf_send_chunk(demux_plugin_t *this_gen) {
buf->type = BUF_AUDIO_NSF;
bytes_read = this->input->read(this->input, buf->content, buf->max_size);
- if (bytes_read == 0) {
+ if (bytes_read <= 0) {
/* the file has been completely loaded, free the buffer and start
* sending control buffers */
buf->free_buffer(buf);
@@ -303,7 +299,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
return NULL;
}
- this = xine_xmalloc (sizeof (demux_nsf_t));
+ this = calloc(1, sizeof(demux_nsf_t));
this->stream = stream;
this->input = input;
@@ -377,7 +373,7 @@ static void class_dispose (demux_class_t *this_gen) {
void *demux_nsf_init_plugin (xine_t *xine, void *data) {
demux_nsf_class_t *this;
- this = xine_xmalloc (sizeof (demux_nsf_class_t));
+ this = calloc(1, sizeof(demux_nsf_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_nsv.c b/src/demuxers/demux_nsv.c
index 44bb18c79..42d31ca14 100644
--- a/src/demuxers/demux_nsv.c
+++ b/src/demuxers/demux_nsv.c
@@ -50,7 +50,6 @@
#define FOURCC_TAG BE_FOURCC
#define NSVf_TAG FOURCC_TAG('N', 'S', 'V', 'f')
#define NSVs_TAG FOURCC_TAG('N', 'S', 'V', 's')
-#define NONE_TAG FOURCC_TAG('N', 'O', 'N', 'E')
#define BEEF 0xEFBE
@@ -256,17 +255,11 @@ static int open_nsv_file(demux_nsv_t *this) {
return 0;
/* check for a 'NSV' signature */
- if ((preview[0] != 'N') ||
- (preview[1] != 'S') ||
- (preview[2] != 'V'))
- {
- if ((preview[0] != 'Z') ||
- (preview[1] != 0) ||
- (preview[2] != '9'))
- return 0;
+ if ( memcmp(preview, "Z\09", 3) == 0) {
this->is_ultravox = preview[3];
this->ultravox_first = 1;
- }
+ } else if ( memcmp(preview, "NSV", 3) != 0 )
+ return 0;
lprintf("NSV file detected, ultravox=%d\n", this->is_ultravox);
@@ -302,13 +295,13 @@ static int open_nsv_file(demux_nsv_t *this) {
return 0;
this->video_fourcc = _X_ME_32(&preview[4]);
- if (_X_BE_32(&preview[4]) == NONE_TAG)
+ if (_x_is_fourcc(&preview[4], "NONE"))
this->video_type = 0;
else
this->video_type = _x_fourcc_to_buf_video(this->video_fourcc);
this->audio_fourcc = _X_ME_32(&preview[8]);
- if (_X_BE_32(&preview[8]) == NONE_TAG)
+ if (_x_is_fourcc(&preview[8], "NONE"))
this->audio_type = 0;
else
this->audio_type = _x_formattag_to_buf_audio(this->audio_fourcc);
@@ -594,7 +587,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
demux_nsv_t *this;
- this = xine_xmalloc (sizeof (demux_nsv_t));
+ this = calloc(1, sizeof(demux_nsv_t));
this->stream = stream;
this->input = input;
@@ -668,7 +661,7 @@ static void class_dispose (demux_class_t *this_gen) {
static void *demux_nsv_init_plugin (xine_t *xine, void *data) {
demux_nsv_class_t *this;
- this = xine_xmalloc (sizeof (demux_nsv_class_t));
+ this = calloc(1, sizeof(demux_nsv_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_ogg.c b/src/demuxers/demux_ogg.c
index 9ed39f12d..e3a9b20c4 100644
--- a/src/demuxers/demux_ogg.c
+++ b/src/demuxers/demux_ogg.c
@@ -194,7 +194,7 @@ static int get_stream (demux_ogg_t *this, int serno) {
static int new_stream_info (demux_ogg_t *this, const int cur_serno) {
int stream_num;
- this->si[this->num_streams] = (stream_info_t *)xine_xmalloc(sizeof(stream_info_t));
+ this->si[this->num_streams] = (stream_info_t *)calloc(1, sizeof(stream_info_t));
ogg_stream_init(&this->si[this->num_streams]->oss, cur_serno);
stream_num = this->num_streams;
this->si[stream_num]->buf_types = 0;
@@ -237,7 +237,7 @@ static int read_ogg_packet (demux_ogg_t *this) {
while (ogg_sync_pageout(&this->oy,&this->og)!=1) {
buffer = ogg_sync_buffer(&this->oy, CHUNKSIZE);
bytes = this->input->read(this->input, buffer, CHUNKSIZE);
- if (bytes == 0) {
+ if (bytes <= 0) {
if (total == 0) {
lprintf("read_ogg_packet read nothing\n");
return 0;
@@ -304,10 +304,10 @@ static void send_ogg_packet (demux_ogg_t *this,
buf_element_t *buf;
int done=0,todo=op->bytes;
- int op_size = sizeof(ogg_packet);
+ const size_t op_size = sizeof(ogg_packet);
while (done<todo) {
- int offset=0;
+ size_t offset=0;
buf = fifo->buffer_pool_alloc (fifo);
buf->decoder_flags = decoder_flags;
if (done==0) {
@@ -498,7 +498,7 @@ static void read_chapter_comment (demux_ogg_t *this, ogg_packet *op) {
lprintf("time: %d %d %d %d\n", hour, min,sec,msec);
if (!this->chapter_info) {
- this->chapter_info = (chapter_info_t *)xine_xmalloc(sizeof(chapter_info_t));
+ this->chapter_info = (chapter_info_t *)calloc(1, sizeof(chapter_info_t));
this->chapter_info->current_chapter = -1;
}
this->chapter_info->max_chapter = chapter_no;
@@ -531,34 +531,34 @@ static void update_chapter_display (demux_ogg_t *this, int stream_num, ogg_packe
chapter--;
if (chapter != this->chapter_info->current_chapter){
- xine_event_t uevent;
- xine_ui_data_t data;
- int title_len;
- char *title;
+ xine_ui_data_t data = {
+ .str = { 0, },
+ .str_len = 0
+ };
+ xine_event_t uevent = {
+ .type = XINE_EVENT_UI_SET_TITLE,
+ .stream = this->stream,
+ .data = &data,
+ .data_length = sizeof(data)
+ };
this->chapter_info->current_chapter = chapter;
- if (chapter >= 0) {
- char t_title[256];
+ if (chapter >= 0) {
if (this->title) {
- snprintf(t_title, sizeof (t_title), "%s / %s", this->title, this->chapter_info->entries[chapter].name);
+ data.str_len = snprintf(data.str, sizeof(data.str), "%s / %s", this->title, this->chapter_info->entries[chapter].name);
} else {
- snprintf(t_title, sizeof (t_title), "%s", this->chapter_info->entries[chapter].name);
+ strncpy(data.str, this->chapter_info->entries[chapter].name, sizeof(data.str)-1);
}
- title = t_title;
} else {
- title = this->title;
+ strncpy(data.str, this->title, sizeof(data.str));
}
- _x_meta_info_set(this->stream, XINE_META_INFO_TITLE, title);
- lprintf("new TITLE: %s\n", title);
-
- uevent.type = XINE_EVENT_UI_SET_TITLE;
- uevent.stream = this->stream;
- uevent.data = &data;
- uevent.data_length = sizeof(data);
- title_len = strlen(title) + 1;
- memcpy(data.str, title, title_len);
- data.str_len = title_len;
+ if ( data.str_len == 0 )
+ data.str_len = strlen(data.str);
+
+ _x_meta_info_set(this->stream, XINE_META_INFO_TITLE, data.str);
+ lprintf("new TITLE: %s\n", data.str);
+
xine_event_send(this->stream, &uevent);
}
}
@@ -1020,7 +1020,7 @@ static void decode_dshow_header (demux_ogg_t *this, const int stream_num, ogg_pa
this->si[stream_num]->headers = 0; /* header is sent below */
- if ( (_X_LE_32(&op->packet[96]) == 0x05589f80) && (op->bytes >= 184)) {
+ if ( _x_is_fourcc(&op->packet[96], "\x05\x58\x9f\x80") && (op->bytes >= 184)) {
buf_element_t *buf;
xine_bmiheader bih;
@@ -1079,7 +1079,7 @@ static void decode_dshow_header (demux_ogg_t *this, const int stream_num, ogg_pa
this->ignore_keyframes = 1;
- } else if (_X_LE_32(&op->packet[96]) == 0x05589F81) {
+ } else if (_x_is_fourcc(&op->packet[96], "\x05\x58\x9f\x81")) {
#if 0
/* FIXME: no test streams */
@@ -1194,27 +1194,27 @@ static void decode_theora_header (demux_ogg_t *this, const int stream_num, ogg_p
static void decode_flac_header (demux_ogg_t *this, const int stream_num, ogg_packet *op) {
xine_flac_metadata_header header;
- xine_flac_streaminfo_block streaminfo;
+ xine_flac_streaminfo_block streaminfo = {};
buf_element_t *buf;
xine_waveformatex wave;
- /* Packet type */
- _x_assert(op->packet[0] == 0x7F);
+ static const uint8_t flac_signature_1[] =
+ {
+ /* Packet type */
+ 0x7F,
+ /* OggFLAC signature */
+ 'F', 'L', 'A', 'C',
+ /* Version: only 1.0 supported */
+ 1, 0
+ };
+ static const uint8_t flac_signature_2[] = "fLaC";
- /* OggFLAC signature */
- _x_assert(op->packet[1] == 'F'); _x_assert(op->packet[2] == 'L');
- _x_assert(op->packet[3] == 'A'); _x_assert(op->packet[4] == 'C');
-
- /* Version: supported only 1.0 */
- _x_assert(op->packet[5] == 1); _x_assert(op->packet[6] == 0);
+ _x_assert(memcmp(&op->packet[0], flac_signature_1, sizeof(flac_signature_1)) == 0);
+ _x_assert(memcmp(&op->packet[9], flac_signature_2, sizeof(flac_signature_2)) == 0);
/* Header count */
this->si[stream_num]->headers = 0/*_X_BE_16(&op->packet[7]) +1*/;
- /* fLaC signature */
- _x_assert(op->packet[9] == 'f'); _x_assert(op->packet[10] == 'L');
- _x_assert(op->packet[11] == 'a'); _x_assert(op->packet[12] == 'C');
-
_x_parse_flac_metadata_header(&op->packet[13], &header);
switch ( header.blocktype ) {
@@ -1267,8 +1267,8 @@ static void decode_annodex_header (demux_ogg_t *this, const int stream_num, ogg_
static void decode_anxdata_header (demux_ogg_t *this, const int stream_num, ogg_packet *op) {
int64_t granule_rate_n, granule_rate_d;
uint32_t secondary_headers;
- char content_type[1024];
- int content_type_length;
+ const char *content_type = "";
+ size_t content_type_length = 0;
lprintf("AnxData stream detected\n");
@@ -1280,11 +1280,16 @@ static void decode_anxdata_header (demux_ogg_t *this, const int stream_num, ogg_
lprintf("granule_rate %" PRId64 "/%" PRId64 ", %d secondary headers\n",
granule_rate_n, granule_rate_d, secondary_headers);
- /* read "Content-Tyoe" MIME header */
- sscanf(&op->packet[28], "Content-Type: %1023s\r\n", content_type);
- content_type_length = strlen(content_type);
+ /* read "Content-Type" MIME header */
+ const char *startline = &op->packet[28];
+ const char *endline;
+ if ( strcmp(&op->packet[28], "Content-Type: ") == 0 &&
+ (endline = strstr(startline, "\r\n")) ) {
+ content_type = startline + sizeof("Content-Type: ");
+ content_type_length = startline - endline;
+ }
- lprintf("Content-Type: %s (length:%d)\n", content_type, content_type_length);
+ lprintf("Content-Type: %s (length:%td)\n", content_type, content_type_length);
/* how many header packets in the AnxData stream? */
this->si[stream_num]->headers = secondary_headers + 1;
@@ -1352,7 +1357,7 @@ static void send_header (demux_ogg_t *this) {
this->ignore_keyframes = 0;
while (!done) {
- if (!read_ogg_packet(this)) {
+ if (!read_ogg_packet(this) || !this->og.header || !this->og.body) {
return;
}
/* now we've got at least one new page */
@@ -1478,6 +1483,12 @@ static int demux_ogg_send_chunk (demux_plugin_t *this_gen) {
return this->status;
}
+ if (!this->og.header || !this->og.body) {
+ this->status = DEMUX_FINISHED;
+ lprintf ("EOF\n");
+ return this->status;
+ }
+
/* now we've got one new page */
cur_serno = ogg_page_serialno (&this->og);
@@ -1924,11 +1935,7 @@ static int detect_ogg_content (int detection_method, demux_class_t *class_gen,
if (_x_demux_read_header(input, buf, 4) != 4)
return 0;
- if ((buf[0] == 'O') && (buf[1] == 'g') && (buf[2] == 'g') &&
- (buf[3] == 'S'))
- return 1;
- else
- return 0;
+ return _x_is_fourcc(buf, "OggS");
}
case METHOD_BY_EXTENSION: {
@@ -2026,8 +2033,7 @@ static demux_plugin_t *anx_open_plugin (demux_class_t *class_gen,
* if we reach this point, the input has been accepted.
*/
- this = xine_xmalloc (sizeof (demux_ogg_t));
- memset (this, 0, sizeof(demux_ogg_t));
+ this = calloc(1, sizeof(demux_ogg_t));
this->stream = stream;
this->input = input;
@@ -2072,8 +2078,7 @@ static demux_plugin_t *ogg_open_plugin (demux_class_t *class_gen,
* if we reach this point, the input has been accepted.
*/
- this = xine_xmalloc (sizeof (demux_ogg_t));
- memset (this, 0, sizeof(demux_ogg_t));
+ this = calloc(1, sizeof(demux_ogg_t));
this->stream = stream;
this->input = input;
@@ -2118,7 +2123,12 @@ static const char *anx_get_extensions (demux_class_t *this_gen) {
}
static const char *anx_get_mimetypes (demux_class_t *this_gen) {
- return "application/x-annodex: ogg: Annodex media;";
+ return "application/annodex: anx: Annodex media;"
+ "application/x-annodex: anx: Annodex media;"
+ "audio/annodex: axa: Annodex audio;"
+ "audio/x-annodex: axa: Annodex audio;"
+ "video/annodex: axv: Annodex video;"
+ "video/x-annodex: axv: Annodex video;";
}
static void anx_class_dispose (demux_class_t *this_gen) {
@@ -2130,7 +2140,7 @@ static void anx_class_dispose (demux_class_t *this_gen) {
static void *anx_init_class (xine_t *xine, void *data) {
demux_anx_class_t *this;
- this = xine_xmalloc (sizeof (demux_anx_class_t));
+ this = calloc(1, sizeof(demux_anx_class_t));
this->demux_class.open_plugin = anx_open_plugin;
this->demux_class.get_description = anx_get_description;
@@ -2155,14 +2165,19 @@ static const char *ogg_get_identifier (demux_class_t *this_gen) {
}
static const char *ogg_get_extensions (demux_class_t *this_gen) {
- return "ogg ogm spx";
+ return "ogx ogv oga ogg spx ogm";
}
static const char *ogg_get_mimetypes (demux_class_t *this_gen) {
- return "audio/x-ogg: ogg: OggVorbis Audio;"
- "audio/x-speex: ogg: Speex Audio;"
- "application/x-ogg: ogg: Ogg Stream;"
- "application/ogg: ogg: Ogg Stream;";
+ return "application/ogg: ogx: Ogg Stream;"
+ "application/x-ogg: ogx: Ogg Stream;"
+ "application/x-ogm: ogx: Ogg Stream;"
+ "application/x-ogm-audio: oga: Ogg Audio;"
+ "application/x-ogm-video: ogv: Ogg Video;"
+ "audio/ogg: oga: Ogg Audio;"
+ "audio/x-ogg: oga: Ogg Audio;"
+ "video/ogg: ogv: Ogg Video;"
+ "video/x-ogg: ogv: Ogg Video;";
}
static void ogg_class_dispose (demux_class_t *this_gen) {
@@ -2174,7 +2189,7 @@ static void ogg_class_dispose (demux_class_t *this_gen) {
static void *ogg_init_class (xine_t *xine, void *data) {
demux_ogg_class_t *this;
- this = xine_xmalloc (sizeof (demux_ogg_class_t));
+ this = calloc(1, sizeof(demux_ogg_class_t));
this->demux_class.open_plugin = ogg_open_plugin;
this->demux_class.get_description = ogg_get_description;
diff --git a/src/demuxers/demux_pva.c b/src/demuxers/demux_pva.c
index 298d936b5..ddd32b63c 100644
--- a/src/demuxers/demux_pva.c
+++ b/src/demuxers/demux_pva.c
@@ -430,7 +430,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
return NULL;
}
- this = xine_xmalloc (sizeof (demux_pva_t));
+ this = calloc(1, sizeof(demux_pva_t));
this->stream = stream;
this->input = input;
@@ -503,7 +503,7 @@ static void class_dispose (demux_class_t *this_gen) {
static void *init_plugin (xine_t *xine, void *data) {
demux_pva_class_t *this;
- this = xine_xmalloc (sizeof (demux_pva_class_t));
+ this = calloc(1, sizeof(demux_pva_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_qt.c b/src/demuxers/demux_qt.c
index a55a0aef3..5aba5b479 100644
--- a/src/demuxers/demux_qt.c
+++ b/src/demuxers/demux_qt.c
@@ -134,7 +134,7 @@ typedef unsigned int qt_atom;
#define MAX_PTS_DIFF 100000
/* network bandwidth, cribbed from src/input/input_mms.c */
-const int64_t bandwidths[]={14400,19200,28800,33600,34430,57600,
+static const int64_t bandwidths[]={14400,19200,28800,33600,34430,57600,
115200,262200,393216,524300,1544000,10485800};
/* these are things that can go wrong */
@@ -581,7 +581,7 @@ static void find_moov_atom(input_plugin_t *input, off_t *moov_offset,
static qt_info *create_qt_info(void) {
qt_info *info;
- info = (qt_info *)xine_xmalloc(sizeof(qt_info));
+ info = (qt_info *)calloc(1, sizeof(qt_info));
if (!info)
return NULL;
@@ -738,39 +738,67 @@ static void parse_meta_atom(qt_info *info, unsigned char *meta_atom) {
if (current_atom == ART_ATOM) {
string_size = _X_BE_32(&meta_atom[i + 4]) - 16 + 1;
+ if (string_size <= 0)
+ continue;
info->artist = xine_xmalloc(string_size);
- strncpy(info->artist, &meta_atom[i + 20], string_size - 1);
- info->artist[string_size - 1] = 0;
+ if (info->artist) {
+ strncpy(info->artist, &meta_atom[i + 20], string_size - 1);
+ info->artist[string_size - 1] = 0;
+ }
} else if (current_atom == NAM_ATOM) {
string_size = _X_BE_32(&meta_atom[i + 4]) - 16 + 1;
+ if (string_size <= 0)
+ continue;
info->name = xine_xmalloc(string_size);
- strncpy(info->name, &meta_atom[i + 20], string_size - 1);
- info->name[string_size - 1] = 0;
+ if (info->name) {
+ strncpy(info->name, &meta_atom[i + 20], string_size - 1);
+ info->name[string_size - 1] = 0;
+ }
} else if (current_atom == ALB_ATOM) {
string_size = _X_BE_32(&meta_atom[i + 4]) - 16 + 1;
+ if (string_size <= 0)
+ continue;
info->album = xine_xmalloc(string_size);
- strncpy(info->album, &meta_atom[i + 20], string_size - 1);
- info->album[string_size - 1] = 0;
+ if (info->album) {
+ strncpy(info->album, &meta_atom[i + 20], string_size - 1);
+ info->album[string_size - 1] = 0;
+ }
} else if (current_atom == GEN_ATOM) {
string_size = _X_BE_32(&meta_atom[i + 4]) - 16 + 1;
+ if (string_size <= 0)
+ continue;
info->genre = xine_xmalloc(string_size);
- strncpy(info->genre, &meta_atom[i + 20], string_size - 1);
- info->genre[string_size - 1] = 0;
+ if (info->genre) {
+ strncpy(info->genre, &meta_atom[i + 20], string_size - 1);
+ info->genre[string_size - 1] = 0;
+ }
} else if (current_atom == TOO_ATOM) {
string_size = _X_BE_32(&meta_atom[i + 4]) - 16 + 1;
+ if (string_size <= 0)
+ continue;
info->comment = xine_xmalloc(string_size);
- strncpy(info->comment, &meta_atom[i + 20], string_size - 1);
- info->comment[string_size - 1] = 0;
+ if (info->comment) {
+ strncpy(info->comment, &meta_atom[i + 20], string_size - 1);
+ info->comment[string_size - 1] = 0;
+ }
} else if (current_atom == WRT_ATOM) {
string_size = _X_BE_32(&meta_atom[i + 4]) - 16 + 1;
+ if (string_size <= 0)
+ continue;
info->composer = xine_xmalloc(string_size);
- strncpy(info->composer, &meta_atom[i + 20], string_size - 1);
- info->composer[string_size - 1] = 0;
+ if (info->composer) {
+ strncpy(info->composer, &meta_atom[i + 20], string_size - 1);
+ info->composer[string_size - 1] = 0;
+ }
} else if (current_atom == DAY_ATOM) {
string_size = _X_BE_32(&meta_atom[i + 4]) - 16 + 1;
+ if (string_size <= 0)
+ continue;
info->year = xine_xmalloc(string_size);
- strncpy(info->year, &meta_atom[i + 20], string_size - 1);
- info->year[string_size - 1] = 0;
+ if (info->year) {
+ strncpy(info->year, &meta_atom[i + 20], string_size - 1);
+ info->year[string_size - 1] = 0;
+ }
}
}
@@ -897,8 +925,8 @@ static qt_error parse_trak_atom (qt_trak *trak,
debug_atom_load(" qt elst atom (edit list atom): %d entries\n",
trak->edit_list_count);
- trak->edit_list_table = (edit_list_table_t *)xine_xmalloc(
- trak->edit_list_count * sizeof(edit_list_table_t));
+ trak->edit_list_table = (edit_list_table_t *)calloc(
+ trak->edit_list_count, sizeof(edit_list_table_t));
if (!trak->edit_list_table) {
last_error = QT_NO_MEMORY;
goto free_trak;
@@ -933,18 +961,25 @@ static qt_error parse_trak_atom (qt_trak *trak,
/* allocate space for each of the properties unions */
trak->stsd_atoms_count = _X_BE_32(&trak_atom[i + 8]);
- trak->stsd_atoms = xine_xmalloc(trak->stsd_atoms_count * sizeof(properties_t));
+ if (trak->stsd_atoms_count <= 0) {
+ last_error = QT_HEADER_TROUBLE;
+ goto free_trak;
+ }
+ trak->stsd_atoms = calloc(trak->stsd_atoms_count, sizeof(properties_t));
if (!trak->stsd_atoms) {
last_error = QT_NO_MEMORY;
goto free_trak;
}
- memset(trak->stsd_atoms, 0, trak->stsd_atoms_count * sizeof(properties_t));
atom_pos = i + 0x10;
properties_offset = 0x0C;
for (k = 0; k < trak->stsd_atoms_count; k++) {
current_stsd_atom_size = _X_BE_32(&trak_atom[atom_pos - 4]);
+ if (current_stsd_atom_size < 4) {
+ last_error = QT_HEADER_TROUBLE;
+ goto free_trak;
+ }
if (trak->type == MEDIA_VIDEO) {
@@ -955,6 +990,10 @@ static qt_error parse_trak_atom (qt_trak *trak,
trak->stsd_atoms[k].video.properties_atom_size = current_stsd_atom_size - 4;
trak->stsd_atoms[k].video.properties_atom =
xine_xmalloc(trak->stsd_atoms[k].video.properties_atom_size);
+ if (!trak->stsd_atoms[k].video.properties_atom) {
+ last_error = QT_NO_MEMORY;
+ goto free_trak;
+ }
memcpy(trak->stsd_atoms[k].video.properties_atom, &trak_atom[atom_pos],
trak->stsd_atoms[k].video.properties_atom_size);
@@ -1094,6 +1133,10 @@ static qt_error parse_trak_atom (qt_trak *trak,
trak->stsd_atoms[k].audio.properties_atom_size = current_stsd_atom_size - 4;
trak->stsd_atoms[k].audio.properties_atom =
xine_xmalloc(trak->stsd_atoms[k].audio.properties_atom_size);
+ if (!trak->stsd_atoms[k].audio.properties_atom) {
+ last_error = QT_NO_MEMORY;
+ goto free_trak;
+ }
memcpy(trak->stsd_atoms[k].audio.properties_atom, &trak_atom[atom_pos],
trak->stsd_atoms[k].audio.properties_atom_size);
@@ -1185,10 +1228,11 @@ static qt_error parse_trak_atom (qt_trak *trak,
if (_X_BE_32(&trak_atom[atom_pos + 0x2C]))
trak->stsd_atoms[k].audio.bytes_per_sample =
_X_BE_32(&trak_atom[atom_pos + 0x2C]);
- trak->stsd_atoms[k].audio.samples_per_frame =
- (trak->stsd_atoms[k].audio.bytes_per_frame /
- trak->stsd_atoms[k].audio.bytes_per_packet) *
- trak->stsd_atoms[k].audio.samples_per_packet;
+ if (trak->stsd_atoms[k].audio.bytes_per_packet)
+ trak->stsd_atoms[k].audio.samples_per_frame =
+ (trak->stsd_atoms[k].audio.bytes_per_frame /
+ trak->stsd_atoms[k].audio.bytes_per_packet) *
+ trak->stsd_atoms[k].audio.samples_per_packet;
}
/* see if the trak deserves a promotion to VBR */
@@ -1210,6 +1254,10 @@ static qt_error parse_trak_atom (qt_trak *trak,
trak->stsd_atoms[k].audio.properties_atom_size = 36;
trak->stsd_atoms[k].audio.properties_atom =
xine_xmalloc(trak->stsd_atoms[k].audio.properties_atom_size);
+ if (!trak->stsd_atoms[k].audio.properties_atom) {
+ last_error = QT_NO_MEMORY;
+ goto free_trak;
+ }
memcpy(trak->stsd_atoms[k].audio.properties_atom,
&trak_atom[atom_pos + 0x20],
trak->stsd_atoms[k].audio.properties_atom_size);
@@ -1231,6 +1279,10 @@ static qt_error parse_trak_atom (qt_trak *trak,
(current_atom_size >= (0x4C + wave_size))) {
trak->stsd_atoms[k].audio.wave_size = wave_size;
trak->stsd_atoms[k].audio.wave = xine_xmalloc(wave_size);
+ if (!trak->stsd_atoms[k].audio.wave) {
+ last_error = QT_NO_MEMORY;
+ goto free_trak;
+ }
memcpy(trak->stsd_atoms[k].audio.wave, &trak_atom[atom_pos + 0x4C],
wave_size);
_x_waveformatex_le2me(trak->stsd_atoms[k].audio.wave);
@@ -1300,8 +1352,16 @@ static qt_error parse_trak_atom (qt_trak *trak,
j += mp4_read_descr_len( &trak_atom[j], &len );
debug_atom_load(" decoder config is %d (0x%X) bytes long\n",
len, len);
+ if (len > current_atom_size - (j - i)) {
+ last_error = QT_NOT_A_VALID_FILE;
+ goto free_trak;
+ }
trak->decoder_config = realloc(trak->decoder_config, len);
trak->decoder_config_len = len;
+ if (!trak->decoder_config) {
+ last_error = QT_NO_MEMORY;
+ goto free_trak;
+ }
memcpy(trak->decoder_config,&trak_atom[j],len);
}
}
@@ -1331,8 +1391,8 @@ static qt_error parse_trak_atom (qt_trak *trak,
/* allocate space and load table only if sample size is 0 */
if (trak->sample_size == 0) {
- trak->sample_size_table = (unsigned int *)malloc(
- trak->sample_size_count * sizeof(unsigned int));
+ trak->sample_size_table = (unsigned int *)calloc(
+ trak->sample_size_count, sizeof(unsigned int));
if (!trak->sample_size_table) {
last_error = QT_NO_MEMORY;
goto free_trak;
@@ -1362,8 +1422,8 @@ static qt_error parse_trak_atom (qt_trak *trak,
debug_atom_load(" qt stss atom (sample sync atom): %d sync samples\n",
trak->sync_sample_count);
- trak->sync_sample_table = (unsigned int *)malloc(
- trak->sync_sample_count * sizeof(unsigned int));
+ trak->sync_sample_table = (unsigned int *)calloc(
+ trak->sync_sample_count, sizeof(unsigned int));
if (!trak->sync_sample_table) {
last_error = QT_NO_MEMORY;
goto free_trak;
@@ -1391,8 +1451,8 @@ static qt_error parse_trak_atom (qt_trak *trak,
debug_atom_load(" qt stco atom (32-bit chunk offset atom): %d chunk offsets\n",
trak->chunk_offset_count);
- trak->chunk_offset_table = (int64_t *)malloc(
- trak->chunk_offset_count * sizeof(int64_t));
+ trak->chunk_offset_table = (int64_t *)calloc(
+ trak->chunk_offset_count, sizeof(int64_t));
if (!trak->chunk_offset_table) {
last_error = QT_NO_MEMORY;
goto free_trak;
@@ -1419,8 +1479,8 @@ static qt_error parse_trak_atom (qt_trak *trak,
debug_atom_load(" qt co64 atom (64-bit chunk offset atom): %d chunk offsets\n",
trak->chunk_offset_count);
- trak->chunk_offset_table = (int64_t *)malloc(
- trak->chunk_offset_count * sizeof(int64_t));
+ trak->chunk_offset_table = (int64_t *)calloc(
+ trak->chunk_offset_count, sizeof(int64_t));
if (!trak->chunk_offset_table) {
last_error = QT_NO_MEMORY;
goto free_trak;
@@ -1450,8 +1510,8 @@ static qt_error parse_trak_atom (qt_trak *trak,
debug_atom_load(" qt stsc atom (sample-to-chunk atom): %d entries\n",
trak->sample_to_chunk_count);
- trak->sample_to_chunk_table = (sample_to_chunk_table_t *)malloc(
- trak->sample_to_chunk_count * sizeof(sample_to_chunk_table_t));
+ trak->sample_to_chunk_table = (sample_to_chunk_table_t *)calloc(
+ trak->sample_to_chunk_count, sizeof(sample_to_chunk_table_t));
if (!trak->sample_to_chunk_table) {
last_error = QT_NO_MEMORY;
goto free_trak;
@@ -1475,7 +1535,8 @@ static qt_error parse_trak_atom (qt_trak *trak,
} else if (current_atom == STTS_ATOM) {
/* there should only be one of these atoms */
- if (trak->time_to_sample_table) {
+ if (trak->time_to_sample_table
+ || current_atom_size < 12 || current_atom_size >= UINT_MAX) {
last_error = QT_HEADER_TROUBLE;
goto free_trak;
}
@@ -1485,8 +1546,13 @@ static qt_error parse_trak_atom (qt_trak *trak,
debug_atom_load(" qt stts atom (time-to-sample atom): %d entries\n",
trak->time_to_sample_count);
- trak->time_to_sample_table = (time_to_sample_table_t *)malloc(
- (trak->time_to_sample_count+1) * sizeof(time_to_sample_table_t));
+ if (trak->time_to_sample_count > (current_atom_size - 12) / 8) {
+ last_error = QT_HEADER_TROUBLE;
+ goto free_trak;
+ }
+
+ trak->time_to_sample_table = (time_to_sample_table_t *)calloc(
+ trak->time_to_sample_count+1, sizeof(time_to_sample_table_t));
if (!trak->time_to_sample_table) {
last_error = QT_NO_MEMORY;
goto free_trak;
@@ -1537,44 +1603,46 @@ static qt_error parse_reference_atom (reference_t *ref,
qt_atom current_atom;
unsigned int current_atom_size;
+ if (ref_atom_size >= 0x80000000)
+ return QT_NOT_A_VALID_FILE;
+
/* initialize reference atom */
ref->url = NULL;
ref->data_rate = 0;
ref->qtim_version = 0;
/* traverse through the atom looking for the key atoms */
- for (i = ATOM_PREAMBLE_SIZE; i < ref_atom_size - 4; i++) {
+ for (i = ATOM_PREAMBLE_SIZE; i + 4 < ref_atom_size; i++) {
current_atom_size = _X_BE_32(&ref_atom[i - 4]);
current_atom = _X_BE_32(&ref_atom[i]);
if (current_atom == RDRF_ATOM) {
+ size_t string_size = _X_BE_32(&ref_atom[i + 12]);
+ size_t url_offset = 0;
+
+ if (string_size >= current_atom_size || string_size >= ref_atom_size - i)
+ return QT_NOT_A_VALID_FILE;
/* if the URL starts with "http://", copy it */
- if (strncmp(&ref_atom[i + 16], "http://", 7) == 0
- || strncmp(&ref_atom[i + 16], "rtsp://", 7) == 0) {
+ if ( memcmp(&ref_atom[i + 16], "http://", 7) &&
+ memcmp(&ref_atom[i + 16], "rtsp://", 7) &&
+ base_mrl )
+ url_offset = strlen(base_mrl);
+ if (url_offset >= 0x80000000)
+ return QT_NOT_A_VALID_FILE;
- /* URL is spec'd to terminate with a NULL; don't trust it */
- ref->url = xine_xmalloc(_X_BE_32(&ref_atom[i + 12]) + 1);
- strncpy(ref->url, &ref_atom[i + 16], _X_BE_32(&ref_atom[i + 12]));
- ref->url[_X_BE_32(&ref_atom[i + 12]) - 1] = '\0';
+ /* otherwise, append relative URL to base MRL */
+ string_size += url_offset;
- } else {
+ ref->url = xine_xmalloc(string_size + 1);
- int string_size;
+ if ( url_offset )
+ strcpy(ref->url, base_mrl);
- if (base_mrl)
- string_size = strlen(base_mrl) + _X_BE_32(&ref_atom[i + 12]) + 1;
- else
- string_size = _X_BE_32(&ref_atom[i + 12]) + 1;
+ memcpy(ref->url + url_offset, &ref_atom[i + 16], _X_BE_32(&ref_atom[i + 12]));
- /* otherwise, append relative URL to base MRL */
- ref->url = xine_xmalloc(string_size);
- if (base_mrl)
- strcpy(ref->url, base_mrl);
- strncat(ref->url, &ref_atom[i + 16], _X_BE_32(&ref_atom[i + 12]));
- ref->url[string_size - 1] = '\0';
- }
+ ref->url[string_size] = '\0';
debug_atom_load(" qt rdrf URL reference:\n %s\n", ref->url);
@@ -1686,8 +1754,7 @@ static qt_error build_frame_table(qt_trak *trak,
/* in this case, the total number of frames is equal to the number of
* entries in the sample size table */
trak->frame_count = trak->sample_size_count;
- trak->frames = (qt_frame *)malloc(
- trak->frame_count * sizeof(qt_frame));
+ trak->frames = (qt_frame *)calloc(trak->frame_count, sizeof(qt_frame));
if (!trak->frames)
return QT_NO_MEMORY;
trak->current_frame = 0;
@@ -1699,10 +1766,9 @@ static qt_error build_frame_table(qt_trak *trak,
pts_index_countdown =
trak->time_to_sample_table[pts_index].count;
- media_id_counts = xine_xmalloc(trak->stsd_atoms_count * sizeof(int));
+ media_id_counts = calloc(trak->stsd_atoms_count, sizeof(int));
if (!media_id_counts)
return QT_NO_MEMORY;
- memset(media_id_counts, 0, trak->stsd_atoms_count * sizeof(int));
/* iterate through each start chunk in the stsc table */
for (i = 0; i < trak->sample_to_chunk_count; i++) {
@@ -1837,8 +1903,7 @@ static qt_error build_frame_table(qt_trak *trak,
/* in this case, the total number of frames is equal to the number of
* chunks */
trak->frame_count = trak->chunk_offset_count;
- trak->frames = (qt_frame *)malloc(
- trak->frame_count * sizeof(qt_frame));
+ trak->frames = (qt_frame *)calloc(trak->frame_count, sizeof(qt_frame));
if (!trak->frames)
return QT_NO_MEMORY;
@@ -1993,8 +2058,12 @@ static void parse_moov_atom(qt_info *info, unsigned char *moov_atom,
info->references = (reference_t *)realloc(info->references,
info->reference_count * sizeof(reference_t));
- parse_reference_atom(&info->references[info->reference_count - 1],
- &moov_atom[i - 4], info->base_mrl);
+ error = parse_reference_atom(&info->references[info->reference_count - 1],
+ &moov_atom[i - 4], info->base_mrl);
+ if (error != QT_OK) {
+ info->last_error = error;
+ return;
+ }
} else {
debug_atom_load(" qt: unknown atom into the moov atom (0x%08X)\n", current_atom);
@@ -2145,7 +2214,7 @@ static qt_error open_qt_file(qt_info *info, input_plugin_t *input,
}
/* check if moov is compressed */
- if (_X_BE_32(&moov_atom[12]) == CMOV_ATOM) {
+ if (_X_BE_32(&moov_atom[12]) == CMOV_ATOM && moov_atom_size >= 0x28) {
info->compressed_header = 1;
@@ -2944,7 +3013,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
return NULL;
}
- this = xine_xmalloc (sizeof (demux_qt_t));
+ this = calloc(1, sizeof(demux_qt_t));
this->stream = stream;
this->input = input;
@@ -3059,7 +3128,9 @@ static const char *get_mimetypes (demux_class_t *this_gen) {
return "video/quicktime: mov,qt: Quicktime animation;"
"video/x-quicktime: mov,qt: Quicktime animation;"
"audio/x-m4a: m4a,m4b: MPEG-4 audio;"
- "application/x-quicktimeplayer: qtl: Quicktime list;";
+ "application/x-quicktimeplayer: qtl: Quicktime list;"
+ "video/mp4: mp4,mpg4: MPEG-4 video;"
+ "audio/mp4: mp4,mpg4: MPEG-4 audio;";
}
static void class_dispose (demux_class_t *this_gen) {
@@ -3073,7 +3144,7 @@ static void *init_plugin (xine_t *xine, void *data) {
demux_qt_class_t *this;
- this = xine_xmalloc (sizeof (demux_qt_class_t));
+ this = calloc(1, sizeof(demux_qt_class_t));
this->config = xine->config;
this->xine = xine;
diff --git a/src/demuxers/demux_rawdv.c b/src/demuxers/demux_rawdv.c
index 2d21f080d..86f777ec6 100644
--- a/src/demuxers/demux_rawdv.c
+++ b/src/demuxers/demux_rawdv.c
@@ -347,7 +347,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
demux_raw_dv_t *this;
- this = xine_xmalloc (sizeof (demux_raw_dv_t));
+ this = calloc(1, sizeof(demux_raw_dv_t));
this->stream = stream;
this->input = input;
@@ -374,8 +374,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
}
/* DIF (DV) movie file */
- if (!((buf[0] == 0x1f) && (buf[1] == 0x07) && (buf[2] == 00) &&
- (buf[4] ^ 0x01))) {
+ if (memcmp(buf, "\x1F\x07\x00", 3) != 0 || !(buf[4] ^ 0x01)) {
free (this);
return NULL;
}
@@ -436,7 +435,7 @@ static void class_dispose (demux_class_t *this_gen) {
static void *init_plugin (xine_t *xine, void *data) {
demux_raw_dv_class_t *this;
- this = xine_xmalloc (sizeof (demux_raw_dv_class_t));
+ this = calloc(1, sizeof(demux_raw_dv_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_real.c b/src/demuxers/demux_real.c
index 9206bfc74..8f1e4f539 100644
--- a/src/demuxers/demux_real.c
+++ b/src/demuxers/demux_real.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2005 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -55,13 +55,13 @@
#include "demux.h"
#include "bswap.h"
+#include "real_common.h"
+
#define FOURCC_TAG BE_FOURCC
-#define RMF_TAG FOURCC_TAG('.', 'R', 'M', 'F')
#define PROP_TAG FOURCC_TAG('P', 'R', 'O', 'P')
#define MDPR_TAG FOURCC_TAG('M', 'D', 'P', 'R')
#define CONT_TAG FOURCC_TAG('C', 'O', 'N', 'T')
#define DATA_TAG FOURCC_TAG('D', 'A', 'T', 'A')
-#define INDX_TAG FOURCC_TAG('I', 'N', 'D', 'X')
#define RA_TAG FOURCC_TAG('.', 'r', 'a', 0xfd)
#define VIDO_TAG FOURCC_TAG('V', 'I', 'D', 'O')
@@ -90,11 +90,11 @@ typedef struct {
uint32_t start_time;
uint32_t preroll;
uint32_t duration;
- char stream_name_size;
+ size_t stream_name_size;
char *stream_name;
- char mime_type_size;
+ size_t mime_type_size;
char *mime_type;
- uint32_t type_specific_len;
+ size_t type_specific_len;
char *type_specific_data;
} mdpr_t;
@@ -113,6 +113,12 @@ typedef struct {
int index_entries;
mdpr_t *mdpr;
+ int sps, cfs, w, h;
+ int block_align;
+ size_t frame_size;
+ uint8_t *frame_buffer;
+ uint32_t frame_num_bytes;
+ uint32_t sub_packet_cnt;
} real_stream_t;
typedef struct {
@@ -168,15 +174,13 @@ typedef struct {
demux_class_t demux_class;
} demux_real_class_t;
-
static void real_parse_index(demux_real_t *this) {
off_t next_index_chunk = this->index_start;
off_t original_pos = this->input->get_current_pos(this->input);
unsigned char index_chunk_header[INDEX_CHUNK_HEADER_SIZE];
unsigned char index_record[INDEX_RECORD_SIZE];
- int i, entries, stream_num;
- real_index_entry_t **index;
+ int i;
while(next_index_chunk) {
lprintf("reading index chunk at %"PRIX64"\n", next_index_chunk);
@@ -192,69 +196,68 @@ static void real_parse_index(demux_real_t *this) {
}
/* Check chunk is actually an index chunk */
- if(_X_BE_32(&index_chunk_header[0]) == INDX_TAG) {
- unsigned short version;
+ if(!_x_is_fourcc(&index_chunk_header[0], "INDX")) {
+ lprintf("expected index chunk found chunk type: %.4s\n", &index_chunk_header[0]);
+ break;
+ }
- /* Check version */
- version = _X_BE_16(&index_chunk_header[8]);
- if(version != 0) {
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_real: unknown object version in INDX: 0x%04x\n", version);
- break;
- }
+ /* Check version */
+ const uint16_t version = _X_BE_16(&index_chunk_header[8]);
+ if(version != 0) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "demux_real: unknown object version in INDX: 0x%04x\n", version);
+ break;
+ }
- /* Read data from header */
- entries = _X_BE_32(&index_chunk_header[10]);
- stream_num = _X_BE_16(&index_chunk_header[14]);
- next_index_chunk = _X_BE_32(&index_chunk_header[16]);
-
- /* Find which stream this index is for */
- index = NULL;
- for(i = 0; i < this->num_video_streams; i++) {
- if(stream_num == this->video_streams[i].mdpr->stream_number) {
- index = &this->video_streams[i].index;
- this->video_streams[i].index_entries = entries;
- lprintf("found index chunk for video stream with num %d\n", stream_num);
- break;
- }
+ /* Read data from header */
+ const uint32_t entries = _X_BE_32(&index_chunk_header[10]);
+ const uint16_t stream_num = _X_BE_16(&index_chunk_header[14]);
+ next_index_chunk = _X_BE_32(&index_chunk_header[16]);
+
+ /* Find which stream this index is for */
+ real_index_entry_t **index = NULL;
+ for(i = 0; i < this->num_video_streams; i++) {
+ if(stream_num == this->video_streams[i].mdpr->stream_number) {
+ index = &this->video_streams[i].index;
+ this->video_streams[i].index_entries = entries;
+ lprintf("found index chunk for video stream with num %d\n", stream_num);
+ break;
}
+ }
- if(!index) {
- for(i = 0; i < this->num_audio_streams; i++) {
- if(stream_num == this->audio_streams[i].mdpr->stream_number) {
- index = &this->audio_streams[i].index;
- this->audio_streams[i].index_entries = entries;
- lprintf("found index chunk for audio stream with num %d\n", stream_num);
- break;
- }
- }
+ if(!index) {
+ for(i = 0; i < this->num_audio_streams; i++) {
+ if(stream_num == this->audio_streams[i].mdpr->stream_number) {
+ index = &this->audio_streams[i].index;
+ this->audio_streams[i].index_entries = entries;
+ lprintf("found index chunk for audio stream with num %d\n", stream_num);
+ break;
+ }
}
+ }
- if(index && entries) {
- /* Allocate memory for index */
- *index = xine_xmalloc(entries * sizeof(real_index_entry_t));
+ if(index && entries)
+ /* Allocate memory for index */
+ *index = calloc(entries, sizeof(real_index_entry_t));
- /* Read index */
- for(i = 0; i < entries; i++) {
- if(this->input->read(this->input, index_record, INDEX_RECORD_SIZE)
- != INDEX_RECORD_SIZE) {
- lprintf("index record not read\n");
- free(*index);
- *index = NULL;
- break;
- }
-
- (*index)[i].timestamp = _X_BE_32(&index_record[2]);
- (*index)[i].offset = _X_BE_32(&index_record[6]);
- (*index)[i].packetno = _X_BE_32(&index_record[10]);
- }
- } else {
- lprintf("unused index chunk with %d entries for stream num %d\n",
- entries, stream_num);
+ if(index && entries && *index) {
+ /* Read index */
+ for(i = 0; i < entries; i++) {
+ if(this->input->read(this->input, index_record, INDEX_RECORD_SIZE)
+ != INDEX_RECORD_SIZE) {
+ lprintf("index record not read\n");
+ free(*index);
+ *index = NULL;
+ break;
+ }
+
+ (*index)[i].timestamp = _X_BE_32(&index_record[2]);
+ (*index)[i].offset = _X_BE_32(&index_record[6]);
+ (*index)[i].packetno = _X_BE_32(&index_record[10]);
}
} else {
- lprintf("expected index chunk found chunk type: %.4s\n", &index_chunk_header[0]);
- break;
+ lprintf("unused index chunk with %d entries for stream num %d\n",
+ entries, stream_num);
}
}
@@ -262,8 +265,12 @@ static void real_parse_index(demux_real_t *this) {
this->input->seek(this->input, original_pos, SEEK_SET);
}
-static mdpr_t *real_parse_mdpr(const char *data) {
- mdpr_t *mdpr=malloc(sizeof(mdpr_t));
+static mdpr_t *real_parse_mdpr(const char *data, const unsigned int size)
+{
+ if (size < 38)
+ return NULL;
+
+ mdpr_t *mdpr=calloc(sizeof(mdpr_t), 1);
mdpr->stream_number=_X_BE_16(&data[2]);
mdpr->max_bit_rate=_X_BE_32(&data[4]);
@@ -275,17 +282,29 @@ static mdpr_t *real_parse_mdpr(const char *data) {
mdpr->duration=_X_BE_32(&data[28]);
mdpr->stream_name_size=data[32];
- mdpr->stream_name=malloc(sizeof(char)*(mdpr->stream_name_size+1));
+ if (size < 38 + mdpr->stream_name_size)
+ goto fail;
+ mdpr->stream_name=malloc(mdpr->stream_name_size+1);
+ if (!mdpr->stream_name)
+ goto fail;
memcpy(mdpr->stream_name, &data[33], mdpr->stream_name_size);
mdpr->stream_name[(int)mdpr->stream_name_size]=0;
mdpr->mime_type_size=data[33+mdpr->stream_name_size];
- mdpr->mime_type=malloc(sizeof(char)*(mdpr->mime_type_size+1));
+ if (size < 38 + mdpr->stream_name_size + mdpr->mime_type_size)
+ goto fail;
+ mdpr->mime_type=malloc(mdpr->mime_type_size+1);
+ if (!mdpr->mime_type)
+ goto fail;
memcpy(mdpr->mime_type, &data[34+mdpr->stream_name_size], mdpr->mime_type_size);
mdpr->mime_type[(int)mdpr->mime_type_size]=0;
mdpr->type_specific_len=_X_BE_32(&data[34+mdpr->stream_name_size+mdpr->mime_type_size]);
- mdpr->type_specific_data=malloc(sizeof(char)*(mdpr->type_specific_len));
+ if (size < 38 + mdpr->stream_name_size + mdpr->mime_type_size + mdpr->type_specific_data)
+ goto fail;
+ mdpr->type_specific_data=malloc(mdpr->type_specific_len);
+ if (!mdpr->type_specific_data)
+ goto fail;
memcpy(mdpr->type_specific_data,
&data[38+mdpr->stream_name_size+mdpr->mime_type_size], mdpr->type_specific_len);
@@ -305,6 +324,13 @@ static mdpr_t *real_parse_mdpr(const char *data) {
#endif
return mdpr;
+
+fail:
+ free (mdpr->stream_name);
+ free (mdpr->mime_type);
+ free (mdpr->type_specific_data);
+ free (mdpr);
+ return NULL;
}
static void real_free_mdpr (mdpr_t *mdpr) {
@@ -314,43 +340,109 @@ static void real_free_mdpr (mdpr_t *mdpr) {
free (mdpr);
}
+static void real_parse_audio_specific_data (demux_real_t *this,
+ real_stream_t * stream)
+{
+ if (stream->mdpr->type_specific_len < 46) {
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
+ "demux_real: audio data size smaller than header length!\n");
+ return;
+ }
+
+ uint8_t * data = stream->mdpr->type_specific_data;
+ const uint32_t coded_frame_size = _X_BE_32 (data+24);
+ const uint16_t codec_data_length = _X_BE_16 (data+40);
+ const uint16_t coded_frame_size2 = _X_BE_16 (data+42);
+ const uint16_t subpacket_size = _X_BE_16 (data+44);
+
+ stream->sps = subpacket_size;
+ stream->w = coded_frame_size2;
+ stream->h = codec_data_length;
+ stream->block_align = coded_frame_size2;
+ stream->cfs = coded_frame_size;
+
+ switch (stream->buf_type) {
+ case BUF_AUDIO_COOK:
+ case BUF_AUDIO_ATRK:
+ stream->block_align = subpacket_size;
+ break;
+
+ case BUF_AUDIO_14_4:
+ break;
+
+ case BUF_AUDIO_28_8:
+ stream->block_align = stream->cfs;
+ break;
+
+ case BUF_AUDIO_SIPRO:
+ /* this->block_align = 19; */
+ break;
+
+ default:
+ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "demux_real: error, i don't handle buf type 0x%08x\n", stream->buf_type);
+ }
+
+ /*
+ * when stream->sps is set it used to do this:
+ * stream->frame_size = stream->w / stream->sps * stream->h * stream->sps;
+ * but it looks pointless? the compiler will probably optimise it away, I suppose?
+ */
+ if (stream->w < 32768 && stream->h < 32768) {
+ stream->frame_size = stream->w * stream->h;
+ stream->frame_buffer = calloc(stream->frame_size, 1);
+ } else {
+ stream->frame_size = 0;
+ stream->frame_buffer = NULL;
+ }
+
+ stream->frame_num_bytes = 0;
+ stream->sub_packet_cnt = 0;
+
+ if (!stream->frame_buffer)
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
+ "demux_real: failed to allocate the audio frame buffer!\n");
+
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
+ "demux_real: buf type 0x%08x frame size %zu block align %d\n", stream->buf_type,
+ stream->frame_size, stream->block_align);
+
+}
static void real_parse_headers (demux_real_t *this) {
char preamble[PREAMBLE_SIZE];
unsigned int chunk_type = 0;
unsigned int chunk_size;
- unsigned short version;
- unsigned char *chunk_buffer;
- int field_size;
- int stream_ptr;
- unsigned char data_chunk_header[DATA_CHUNK_HEADER_SIZE];
- unsigned char signature[REAL_SIGNATURE_SIZE];
-
- this->data_start = 0;
- this->data_size = 0;
- this->num_video_streams = 0;
- this->num_audio_streams = 0;
if (INPUT_IS_SEEKABLE(this->input))
this->input->seek (this->input, 0, SEEK_SET);
- if (this->input->read(this->input, signature, REAL_SIGNATURE_SIZE) !=
- REAL_SIGNATURE_SIZE) {
+ {
+ uint8_t signature[REAL_SIGNATURE_SIZE];
+ if (this->input->read(this->input, signature, REAL_SIGNATURE_SIZE) !=
+ REAL_SIGNATURE_SIZE) {
+
+ lprintf ("signature not read\n");
+ this->status = DEMUX_FINISHED;
+ return;
+ }
+
+ if ( !_x_is_fourcc(signature, ".RMF") ) {
+ this->status = DEMUX_FINISHED;
+ lprintf ("signature not found '%.4s'\n", signature);
+ return;
+ }
- lprintf ("signature not read\n");
- this->status = DEMUX_FINISHED;
- return;
+ /* skip to the start of the first chunk and start traversing */
+ chunk_size = _X_BE_32(&signature[4]);
}
- if (_X_BE_32(signature) != RMF_TAG) {
- this->status = DEMUX_FINISHED;
- lprintf ("signature not found '%.4s'\n", signature);
- return;
- }
+ this->data_start = 0;
+ this->data_size = 0;
+ this->num_video_streams = 0;
+ this->num_audio_streams = 0;
- /* skip to the start of the first chunk and start traversing */
- chunk_size = _X_BE_32(&signature[4]);
this->input->seek(this->input, chunk_size-8, SEEK_CUR);
/* iterate through chunks and gather information until the first DATA
@@ -371,171 +463,190 @@ static void real_parse_headers (demux_real_t *this) {
case PROP_TAG:
case MDPR_TAG:
case CONT_TAG:
-
- chunk_size -= PREAMBLE_SIZE;
- chunk_buffer = xine_xmalloc(chunk_size);
- if (this->input->read(this->input, chunk_buffer, chunk_size) !=
- chunk_size) {
- free (chunk_buffer);
- this->status = DEMUX_FINISHED;
- return;
- }
+ {
+ if (chunk_size < PREAMBLE_SIZE+1) {
+ this->status = DEMUX_FINISHED;
+ return;
+ }
+ chunk_size -= PREAMBLE_SIZE;
+ uint8_t *const chunk_buffer = malloc(chunk_size);
+ if (! chunk_buffer ||
+ this->input->read(this->input, chunk_buffer, chunk_size) !=
+ chunk_size) {
+ free (chunk_buffer);
+ this->status = DEMUX_FINISHED;
+ return;
+ }
- version = _X_BE_16(&chunk_buffer[0]);
+ uint16_t version = _X_BE_16(&chunk_buffer[0]);
- if (chunk_type == PROP_TAG) {
+ if (chunk_type == PROP_TAG) {
- if(version != 0) {
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demuxe_real: unknown object version in PROP: 0x%04x\n", version);
- free(chunk_buffer);
- this->status = DEMUX_FINISHED;
- return;
- }
-
- this->duration = _X_BE_32(&chunk_buffer[22]);
- this->index_start = _X_BE_32(&chunk_buffer[30]);
- this->data_start = _X_BE_32(&chunk_buffer[34]);
- this->avg_bitrate = _X_BE_32(&chunk_buffer[6]);
-
- lprintf("PROP: duration: %d ms\n", this->duration);
- lprintf("PROP: index start: %"PRIX64"\n", this->index_start);
- lprintf("PROP: data start: %"PRIX64"\n", this->data_start);
- lprintf("PROP: average bit rate: %"PRId64"\n", this->avg_bitrate);
-
- if (this->avg_bitrate<1)
- this->avg_bitrate = 1;
-
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_BITRATE,
+ if(version != 0) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "demuxe_real: unknown object version in PROP: 0x%04x\n", version);
+ free(chunk_buffer);
+ this->status = DEMUX_FINISHED;
+ return;
+ }
+
+ this->duration = _X_BE_32(&chunk_buffer[22]);
+ this->index_start = _X_BE_32(&chunk_buffer[30]);
+ this->data_start = _X_BE_32(&chunk_buffer[34]);
+ this->avg_bitrate = _X_BE_32(&chunk_buffer[6]);
+
+ lprintf("PROP: duration: %d ms\n", this->duration);
+ lprintf("PROP: index start: %"PRIX64"\n", this->index_start);
+ lprintf("PROP: data start: %"PRIX64"\n", this->data_start);
+ lprintf("PROP: average bit rate: %"PRId64"\n", this->avg_bitrate);
+
+ if (this->avg_bitrate<1)
+ this->avg_bitrate = 1;
+
+ _x_stream_info_set(this->stream, XINE_STREAM_INFO_BITRATE,
this->avg_bitrate);
- } else if (chunk_type == MDPR_TAG) {
-
- mdpr_t *mdpr;
- uint32_t fourcc;
-
- if (version != 0) {
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_real: unknown object version in MDPR: 0x%04x\n", version);
- free(chunk_buffer);
- continue;
- }
+ } else if (chunk_type == MDPR_TAG) {
+ if (version != 0) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "demux_real: unknown object version in MDPR: 0x%04x\n", version);
+ free(chunk_buffer);
+ continue;
+ }
- mdpr = real_parse_mdpr (chunk_buffer);
-
- lprintf ("parsing type specific data...\n");
-
- if(_X_BE_32(mdpr->type_specific_data) == RA_TAG) {
- int version, len;
-
- if(this->num_audio_streams == MAX_AUDIO_STREAMS) {
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_real: maximum number of audio stream exceeded\n");
- goto unknown;
- }
+ mdpr_t *const mdpr = real_parse_mdpr (chunk_buffer, chunk_size);
+
+ lprintf ("parsing type specific data...\n");
+ if (!mdpr) {
+ free (chunk_buffer);
+ this->status = DEMUX_FINISHED;
+ return;
+ }
+ if(!strcmp(mdpr->mime_type, "audio/X-MP3-draft-00")) {
+ lprintf ("mpeg layer 3 audio detected...\n");
+
+ static const uint32_t fourcc = ME_FOURCC('a', 'd', 'u', 0x55);
+ this->audio_streams[this->num_audio_streams].fourcc = fourcc;
+ this->audio_streams[this->num_audio_streams].buf_type = _x_formattag_to_buf_audio(fourcc);
+ this->audio_streams[this->num_audio_streams].index = NULL;
+ this->audio_streams[this->num_audio_streams].mdpr = mdpr;
+ this->num_audio_streams++;
+ } else if(_X_BE_32(mdpr->type_specific_data) == RA_TAG &&
+ mdpr->type_specific_len >= 6) {
+ if(this->num_audio_streams == MAX_AUDIO_STREAMS) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "demux_real: maximum number of audio stream exceeded\n");
+ goto unknown;
+ }
- version = _X_BE_16(mdpr->type_specific_data + 4);
+ const uint16_t version = _X_BE_16(mdpr->type_specific_data + 4);
- lprintf("audio version %d detected\n", version);
+ lprintf("audio version %d detected\n", version);
- switch(version) {
+ char *fourcc_ptr = "\0\0\0";
+ switch(version) {
case 3:
/* Version 3 header stores fourcc after meta info - cheat by reading backwards from the
* end of the header instead of having to parse it all */
- fourcc = _X_ME_32(mdpr->type_specific_data + mdpr->type_specific_len - 5);
+ if (mdpr->type_specific_len >= 5)
+ fourcc_ptr = mdpr->type_specific_data + mdpr->type_specific_len - 5;
break;
- case 4:
- len = *(mdpr->type_specific_data + 56);
- fourcc = _X_ME_32(mdpr->type_specific_data + 58 + len);
+ case 4: {
+ if (mdpr->type_specific_len >= 57) {
+ const uint8_t len = *(mdpr->type_specific_data + 56);
+ if (mdpr->type_specific_len >= 62 + len)
+ fourcc_ptr = mdpr->type_specific_data + 58 + len;
+ }
+ }
break;
case 5:
- fourcc = _X_ME_32(mdpr->type_specific_data + 66);
+ if (mdpr->type_specific_len >= 70)
+ fourcc_ptr = mdpr->type_specific_data + 66;
break;
default:
lprintf("unsupported audio header version %d\n", version);
goto unknown;
- }
+ }
+ lprintf("fourcc = %.4s\n", fourcc_ptr);
- lprintf("fourcc = %.4s\n", (char *) &fourcc);
+ const uint32_t fourcc = _X_ME_32(fourcc_ptr);
- this->audio_streams[this->num_audio_streams].fourcc = fourcc;
- this->audio_streams[this->num_audio_streams].buf_type = _x_formattag_to_buf_audio(fourcc);
- this->audio_streams[this->num_audio_streams].index = NULL;
- this->audio_streams[this->num_audio_streams].mdpr = mdpr;
+ this->audio_streams[this->num_audio_streams].fourcc = fourcc;
+ this->audio_streams[this->num_audio_streams].buf_type = _x_formattag_to_buf_audio(fourcc);
+ this->audio_streams[this->num_audio_streams].index = NULL;
+ this->audio_streams[this->num_audio_streams].mdpr = mdpr;
- this->num_audio_streams++;
+ real_parse_audio_specific_data (this,
+ &this->audio_streams[this->num_audio_streams]);
+ this->num_audio_streams++;
- } else if(_X_BE_32(mdpr->type_specific_data + 4) == VIDO_TAG) {
+ } else if(_X_BE_32(mdpr->type_specific_data + 4) == VIDO_TAG &&
+ mdpr->type_specific_len >= 34) {
- if(this->num_video_streams == MAX_VIDEO_STREAMS) {
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_real: maximum number of video stream exceeded\n");
- goto unknown;
- }
+ if(this->num_video_streams == MAX_VIDEO_STREAMS) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "demux_real: maximum number of video stream exceeded\n");
+ goto unknown;
+ }
- lprintf ("video detected\n");
- fourcc = _X_ME_32(mdpr->type_specific_data + 8);
- lprintf("fourcc = %.4s\n", (char *) &fourcc);
-
- this->video_streams[this->num_video_streams].fourcc = fourcc;
- this->video_streams[this->num_video_streams].buf_type = _x_fourcc_to_buf_video(fourcc);
- this->video_streams[this->num_video_streams].format = _X_BE_32(mdpr->type_specific_data + 30);
- this->video_streams[this->num_video_streams].index = NULL;
- this->video_streams[this->num_video_streams].mdpr = mdpr;
-
- this->num_video_streams++;
-
- } else {
- lprintf("unrecognised type specific data\n");
-
-unknown:
- real_free_mdpr(mdpr);
- }
-
- } else if (chunk_type == CONT_TAG) {
-
- if(version != 0) {
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_real: unknown object version in CONT: 0x%04x\n", version);
- free(chunk_buffer);
- continue;
- }
+ lprintf ("video detected\n");
+ const uint32_t fourcc = _X_ME_32(mdpr->type_specific_data + 8);
+ lprintf("fourcc = %.4s\n", (char *) &fourcc);
+
+ this->video_streams[this->num_video_streams].fourcc = fourcc;
+ this->video_streams[this->num_video_streams].buf_type = _x_fourcc_to_buf_video(fourcc);
+ this->video_streams[this->num_video_streams].format = _X_BE_32(mdpr->type_specific_data + 30);
+ this->video_streams[this->num_video_streams].index = NULL;
+ this->video_streams[this->num_video_streams].mdpr = mdpr;
+
+ this->num_video_streams++;
+
+ } else {
+ lprintf("unrecognised type specific data\n");
+
+ unknown:
+ real_free_mdpr(mdpr);
+ }
+
+ } else if (chunk_type == CONT_TAG) {
+
+ if(version != 0) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "demux_real: unknown object version in CONT: 0x%04x\n", version);
+ free(chunk_buffer);
+ continue;
+ }
+
+ int stream_ptr = 2;
+#define SET_METADATA_STRING(type) \
+ do { \
+ const uint16_t field_size = _X_BE_16(&chunk_buffer[stream_ptr]); \
+ stream_ptr += 2; \
+ _x_meta_info_n_set(this->stream, type, \
+ &chunk_buffer[stream_ptr], field_size); \
+ stream_ptr += field_size; \
+ } while(0)
+
+ /* load the title string */
+ SET_METADATA_STRING(XINE_META_INFO_TITLE);
+
+ /* load the author string */
+ SET_METADATA_STRING(XINE_META_INFO_ARTIST);
+
+ /* load the copyright string as the year */
+ SET_METADATA_STRING(XINE_META_INFO_YEAR);
+
+ /* load the comment string */
+ SET_METADATA_STRING(XINE_META_INFO_COMMENT);
+ }
- stream_ptr = 2;
-
- /* load the title string */
- field_size = _X_BE_16(&chunk_buffer[stream_ptr]);
- stream_ptr += 2;
- _x_meta_info_n_set(this->stream, XINE_META_INFO_TITLE,
- &chunk_buffer[stream_ptr], field_size);
- stream_ptr += field_size;
-
- /* load the author string */
- field_size = _X_BE_16(&chunk_buffer[stream_ptr]);
- stream_ptr += 2;
- _x_meta_info_n_set(this->stream, XINE_META_INFO_ARTIST,
- &chunk_buffer[stream_ptr], field_size);
- stream_ptr += field_size;
-
- /* load the copyright string as the year */
- field_size = _X_BE_16(&chunk_buffer[stream_ptr]);
- stream_ptr += 2;
- _x_meta_info_n_set(this->stream, XINE_META_INFO_YEAR,
- &chunk_buffer[stream_ptr], field_size);
- stream_ptr += field_size;
-
- /* load the comment string */
- field_size = _X_BE_16(&chunk_buffer[stream_ptr]);
- stream_ptr += 2;
- _x_meta_info_n_set(this->stream, XINE_META_INFO_COMMENT,
- &chunk_buffer[stream_ptr], field_size);
- stream_ptr += field_size;
+ free(chunk_buffer);
}
-
- free(chunk_buffer);
break;
- case DATA_TAG:
+ case DATA_TAG: {
+ uint8_t data_chunk_header[DATA_CHUNK_HEADER_SIZE];
+
if (this->input->read(this->input, data_chunk_header,
DATA_CHUNK_HEADER_SIZE) != DATA_CHUNK_HEADER_SIZE) {
this->status = DEMUX_FINISHED;
@@ -543,7 +654,7 @@ unknown:
}
/* check version */
- version = _X_BE_16(&data_chunk_header[0]);
+ const uint16_t version = _X_BE_16(&data_chunk_header[0]);
if(version != 0) {
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
"demux_real: unknown object version in DATA: 0x%04x\n", version);
@@ -554,7 +665,8 @@ unknown:
this->current_data_chunk_packet_count = _X_BE_32(&data_chunk_header[2]);
this->next_data_chunk_offset = _X_BE_32(&data_chunk_header[6]);
this->data_chunk_size = chunk_size;
- break;
+ }
+ break;
default:
/* this should not occur, but in case it does, skip the chunk */
@@ -570,16 +682,9 @@ unknown:
real_parse_index(this);
/* Simple stream selection case - 0/1 audio/video streams */
- if(this->num_video_streams == 1)
- this->video_stream = &this->video_streams[0];
- else
- this->video_stream = NULL;
+ this->video_stream = (this->num_video_streams == 1) ? &this->video_streams[0] : NULL;
+ this->audio_stream = (this->num_audio_streams == 1) ? &this->audio_streams[0] : NULL;
- if(this->num_audio_streams == 1)
- this->audio_stream = &this->audio_streams[0];
- else
- this->audio_stream = NULL;
-
/* In the case of multiple audio/video streams select the first
streams found in the file */
if((this->num_video_streams > 1) || (this->num_audio_streams > 1)) {
@@ -619,15 +724,13 @@ unknown:
while((offset < len) &&
((!this->video_stream && (this->num_video_streams > 0)) ||
(!this->audio_stream && (this->num_audio_streams > 0)))) {
- uint32_t id;
- int i, stream;
+ int i;
/* Check for end of the data chunk */
- if(((id = _X_BE_32(&search_buffer[offset])) == DATA_TAG) ||
- (id == INDX_TAG))
- break;
+ if (_x_is_fourcc(&search_buffer[offset], "INDX") || _x_is_fourcc(&search_buffer[offset], "DATA"))
+ break;
- stream = _X_BE_16(&search_buffer[offset + 4]);
+ const int stream = _X_BE_16(&search_buffer[offset + 4]);
for(i = 0; !this->video_stream && (i < this->num_video_streams); i++) {
if(stream == this->video_streams[i].mdpr->stream_number) {
@@ -661,14 +764,12 @@ unknown:
/* Send headers and set meta info */
if(this->video_stream) {
- buf_element_t *buf;
-
/* Check for recognised codec*/
if(!this->video_stream->buf_type)
this->video_stream->buf_type = BUF_VIDEO_UNKNOWN;
/* Send header */
- buf = this->video_fifo->buffer_pool_alloc(this->video_fifo);
+ buf_element_t *const buf = this->video_fifo->buffer_pool_alloc(this->video_fifo);
buf->content = buf->mem;
memcpy(buf->content, this->video_stream->mdpr->type_specific_data,
@@ -690,7 +791,7 @@ unknown:
this->video_stream->mdpr->avg_bit_rate);
/* Allocate fragment offset table */
- this->fragment_tab = xine_xmalloc(FRAGMENT_TAB_SIZE*sizeof(uint32_t));
+ this->fragment_tab = calloc(FRAGMENT_TAB_SIZE, sizeof(uint32_t));
this->fragment_tab_max = FRAGMENT_TAB_SIZE;
}
@@ -701,10 +802,9 @@ unknown:
/* Send headers */
if(this->audio_fifo) {
- mdpr_t *mdpr = this->audio_stream->mdpr;
- buf_element_t *buf;
+ mdpr_t *const mdpr = this->audio_stream->mdpr;
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf_element_t *buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
buf->type = this->audio_stream->buf_type;
buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_FRAME_END;
@@ -714,7 +814,7 @@ unknown:
* The second is the codec initialisation data found at the end of
* the type specific data for the audio stream */
if(buf->type == BUF_AUDIO_AAC) {
- int version = _X_BE_16(mdpr->type_specific_data + 4);
+ const uint16_t version = _X_BE_16(mdpr->type_specific_data + 4);
if(version != 5) {
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
@@ -745,6 +845,13 @@ unknown:
memcpy(buf->content, mdpr->type_specific_data + 79,
buf->decoder_info[2]);
+ } else if(buf->type == BUF_AUDIO_MP3ADU) {
+ buf->decoder_flags |= BUF_FLAG_STDHEADER | BUF_FLAG_FRAME_END;
+ buf->size = 0;
+ buf->decoder_info[0] = 0;
+ buf->decoder_info[1] = 0;
+ buf->decoder_info[2] = 0;
+ buf->decoder_info[3] = 0;
} else {
memcpy(buf->content, mdpr->type_specific_data,
mdpr->type_specific_len);
@@ -868,9 +975,7 @@ static int demux_real_parse_references( demux_real_t *this) {
#define PTS_VIDEO 1
static void check_newpts (demux_real_t *this, int64_t pts, int video, int preview) {
- int64_t diff;
-
- diff = pts - this->last_pts[video];
+ const int64_t diff = pts - this->last_pts[video];
lprintf ("check_newpts %"PRId64"\n", pts);
if (!preview && pts &&
@@ -976,18 +1081,14 @@ static int demux_real_send_chunk(demux_plugin_t *this_gen) {
demux_real_t *this = (demux_real_t *) this_gen;
char header[DATA_PACKET_HEADER_SIZE];
- int stream, size, keyframe, input_time = 0;
- unsigned short version;
- uint32_t id, timestamp;
- int64_t pts;
- off_t offset, input_length = 0;
+ int keyframe, input_time = 0;
int normpos = 0;
if(this->reference_mode)
return demux_real_parse_references(this);
/* load a header from wherever the stream happens to be pointing */
- if ( (size=this->input->read(this->input, header, DATA_PACKET_HEADER_SIZE)) !=
+ if ( this->input->read(this->input, header, DATA_PACKET_HEADER_SIZE) !=
DATA_PACKET_HEADER_SIZE) {
xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
@@ -998,15 +1099,14 @@ static int demux_real_send_chunk(demux_plugin_t *this_gen) {
}
/* Check to see if we've gone past the end of the data chunk */
- if(((id = _X_BE_32(&header[0])) == DATA_TAG) ||
- (id == INDX_TAG)) {
+ if (_x_is_fourcc(&header[0], "INDX") || _x_is_fourcc(&header[0], "DATA")) {
lprintf("finished reading data chunk\n");
this->status = DEMUX_FINISHED;
return this->status;
}
/* check version */
- version = _X_BE_16(&header[0]);
+ const uint16_t version = _X_BE_16(&header[0]);
if(version > 1) {
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
"demux_real: unknown object version in data packet: 0x%04x\n", version);
@@ -1015,11 +1115,11 @@ static int demux_real_send_chunk(demux_plugin_t *this_gen) {
}
/* read the packet information */
- stream = _X_BE_16(&header[4]);
- offset = this->input->get_current_pos(this->input);
- size = _X_BE_16(&header[2]) - DATA_PACKET_HEADER_SIZE;
- timestamp= _X_BE_32(&header[6]);
- pts = (int64_t) timestamp * 90;
+ const uint16_t stream = _X_BE_16(&header[4]);
+ const off_t offset __attr_unused = this->input->get_current_pos(this->input);
+ uint16_t size = _X_BE_16(&header[2]) - DATA_PACKET_HEADER_SIZE;
+ const uint32_t timestamp= _X_BE_32(&header[6]);
+ int64_t pts = (int64_t) timestamp * 90;
/* Data packet header with version 1 contains 1 extra byte */
if(version == 0)
@@ -1034,11 +1134,9 @@ static int demux_real_send_chunk(demux_plugin_t *this_gen) {
if (this->video_stream && (stream == this->video_stream->mdpr->stream_number)) {
- int vpkg_header, vpkg_length, vpkg_offset;
int vpkg_seqnum = -1;
int vpkg_subseq = 0;
buf_element_t *buf;
- int n, fragment_size;
uint32_t decoder_flags;
lprintf ("video chunk detected.\n");
@@ -1053,21 +1151,20 @@ static int demux_real_send_chunk(demux_plugin_t *this_gen) {
* bit 6: 1=short header (only one block?)
*/
- vpkg_header = stream_read_char (this); size--;
+ const int vpkg_header = stream_read_char (this); size--;
lprintf ("vpkg_hdr: %02x (size=%d)\n", vpkg_header, size);
+ int vpkg_length, vpkg_offset;
if (0x40==(vpkg_header&0xc0)) {
/*
* seems to be a very short header
* 2 bytes, purpose of the second byte yet unknown
*/
- int bummer;
-
- bummer = stream_read_char (this); size--;
+ const int bummer __attr_unused = stream_read_char (this);
lprintf ("bummer == %02X\n",bummer);
vpkg_offset = 0;
- vpkg_length = size;
+ vpkg_length = --size;
} else {
@@ -1128,9 +1225,8 @@ static int demux_real_send_chunk(demux_plugin_t *this_gen) {
input_time = (int)((int64_t) this->input->get_current_pos(this->input)
* 8 * 1000 / this->avg_bitrate);
- if(this->data_start && this->data_chunk_size)
- input_length = this->data_start + 18 + this->data_chunk_size;
- if( input_length )
+ const off_t input_length = this->data_start + 18 + this->data_chunk_size;
+ if( input_length > 18 )
normpos = (int)((double) this->input->get_current_pos(this->input) * 65535 / input_length);
check_newpts (this, pts, PTS_VIDEO, 0);
@@ -1175,13 +1271,17 @@ static int demux_real_send_chunk(demux_plugin_t *this_gen) {
* calc size of fragment
*/
- if ((vpkg_header & 0xc0) == 0x080)
+ int fragment_size;
+ switch(vpkg_header & 0xc0) {
+ case 0x80:
fragment_size = vpkg_offset;
- else {
- if (0x00 == (vpkg_header&0xc0))
- fragment_size = size;
- else
- fragment_size = vpkg_length;
+ break;
+ case 0x00:
+ fragment_size = size;
+ break;
+ default:
+ fragment_size = vpkg_length;
+ break;
}
lprintf ("fragment size is %d\n", fragment_size);
@@ -1189,14 +1289,11 @@ static int demux_real_send_chunk(demux_plugin_t *this_gen) {
* read fragment_size bytes of data
*/
- n = fragment_size;
+ int n = fragment_size;
while(n) {
buf = this->video_fifo->buffer_pool_alloc(this->video_fifo);
- if(n>buf->max_size)
- buf->size = buf->max_size;
- else
- buf->size = n;
+ buf->size = MIN(n, buf->max_size);
buf->decoder_flags = decoder_flags;
decoder_flags &= ~BUF_FLAG_FRAME_START;
@@ -1280,12 +1377,9 @@ static int demux_real_send_chunk(demux_plugin_t *this_gen) {
input_time = (int)((int64_t) this->input->get_current_pos(this->input)
* 8 * 1000 / this->avg_bitrate);
- if(this->data_start && this->data_chunk_size)
- input_length = this->data_start + 18 + this->data_chunk_size;
- else
- input_length = 0;
+ const off_t input_length = this->data_start + 18 + this->data_chunk_size;
- if( input_length )
+ if( input_length > 18 )
normpos = (int)((double) this->input->get_current_pos(this->input) * 65535 / input_length);
check_newpts (this, pts, PTS_AUDIO, 0);
@@ -1293,13 +1387,14 @@ static int demux_real_send_chunk(demux_plugin_t *this_gen) {
/* Each packet of AAC is made up of several AAC frames preceded by a
* header defining the size of the frames */
if(this->audio_stream->buf_type == BUF_AUDIO_AAC) {
- int i, frames, *sizes;
+ int i;
/* Upper 4 bits of second byte is frame count */
- frames = (stream_read_word(this) & 0xf0) >> 4;
+ const int frames = (stream_read_word(this) & 0xf0) >> 4;
/* 2 bytes per frame size */
- sizes = xine_xmalloc(frames*sizeof(int));
+ int sizes[frames];
+
for(i = 0; i < frames; i++)
sizes[i] = stream_read_word(this);
@@ -1311,15 +1406,77 @@ static int demux_real_send_chunk(demux_plugin_t *this_gen) {
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
"demux_real: failed to read AAC frame\n");
- free(sizes);
this->status = DEMUX_FINISHED;
return this->status;
}
pts = 0; /* Only set pts on first frame */
}
-
- free(sizes);
+ } else if (this->audio_stream->buf_type == BUF_AUDIO_COOK ||
+ this->audio_stream->buf_type == BUF_AUDIO_ATRK ||
+ this->audio_stream->buf_type == BUF_AUDIO_28_8 ||
+ this->audio_stream->buf_type == BUF_AUDIO_SIPRO) {
+ /* reorder */
+ uint8_t * buffer = this->audio_stream->frame_buffer;
+ int sps = this->audio_stream->sps;
+ int sph = this->audio_stream->h;
+ int cfs = this->audio_stream->cfs;
+ int w = this->audio_stream->w;
+ int spc = this->audio_stream->sub_packet_cnt;
+ int x;
+ off_t pos;
+ const size_t fs = this->audio_stream->frame_size;
+
+ if (!buffer) {
+ this->status = DEMUX_FINISHED;
+ return this->status;
+ }
+
+ switch (this->audio_stream->buf_type) {
+ case BUF_AUDIO_28_8:
+ for (x = 0; x < sph / 2; x++) {
+ pos = x * 2 * w + spc * cfs;
+ if(pos + cfs > fs || this->input->read(this->input, buffer + pos, cfs) < cfs) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "demux_real: failed to read audio chunk\n");
+
+ this->status = DEMUX_FINISHED;
+ return this->status;
+ }
+ }
+ break;
+ case BUF_AUDIO_COOK:
+ case BUF_AUDIO_ATRK:
+ for (x = 0; x < w / sps; x++) {
+ pos = sps * (sph * x + ((sph + 1) / 2) * (spc & 1) + (spc >> 1));
+ if(pos + sps > fs || this->input->read(this->input, buffer + pos, sps) < sps) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "demux_real: failed to read audio chunk\n");
+
+ this->status = DEMUX_FINISHED;
+ return this->status;
+ }
+ }
+ break;
+ case BUF_AUDIO_SIPRO:
+ pos = spc * w;
+ if(pos + w > fs || this->input->read(this->input, buffer + pos, w) < w) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "demux_real: failed to read audio chunk\n");
+
+ this->status = DEMUX_FINISHED;
+ return this->status;
+ }
+ if (spc == sph - 1)
+ demux_real_sipro_swap (buffer, sph * w * 2 / 96);
+ break;
+ }
+ if(++this->audio_stream->sub_packet_cnt == sph) {
+ this->audio_stream->sub_packet_cnt = 0;
+ _x_demux_send_data(this->audio_fifo, buffer, this->audio_stream->frame_size,
+ pts, this->audio_stream->buf_type, 0, normpos, input_time,
+ this->duration, 0);
+ }
} else {
if(_x_demux_read_send_data(this->audio_fifo, this->input, size, pts,
this->audio_stream->buf_type, 0, normpos,
@@ -1352,18 +1509,10 @@ discard:
/* check if it's time to reload */
if (!this->current_data_chunk_packet_count &&
this->next_data_chunk_offset) {
- char preamble[PREAMBLE_SIZE];
unsigned char data_chunk_header[DATA_CHUNK_HEADER_SIZE];
/* seek to the next DATA chunk offset */
- this->input->seek(this->input, this->next_data_chunk_offset, SEEK_SET);
-
- /* load the DATA chunk preamble */
- if (this->input->read(this->input, preamble, PREAMBLE_SIZE) !=
- PREAMBLE_SIZE) {
- this->status = DEMUX_FINISHED;
- return this->status;
- }
+ this->input->seek(this->input, this->next_data_chunk_offset + PREAMBLE_SIZE, SEEK_SET);
/* load the rest of the DATA chunk header */
if (this->input->read(this->input, data_chunk_header,
@@ -1469,6 +1618,9 @@ static int demux_real_seek (demux_plugin_t *this_gen,
this->input->seek(this->input, index[i].offset, SEEK_SET);
if(playing) {
+ if(this->audio_stream)
+ this->audio_stream->sub_packet_cnt = 0;
+
this->buf_flag_seek = 1;
_x_demux_flush_engine(this->stream);
}
@@ -1499,19 +1651,16 @@ static void demux_real_dispose (demux_plugin_t *this_gen) {
for(i = 0; i < this->num_video_streams; i++) {
real_free_mdpr(this->video_streams[i].mdpr);
- if(this->video_streams[i].index)
- free(this->video_streams[i].index);
+ free(this->video_streams[i].index);
}
for(i = 0; i < this->num_audio_streams; i++) {
real_free_mdpr(this->audio_streams[i].mdpr);
- if(this->audio_streams[i].index)
- free(this->audio_streams[i].index);
+ free(this->audio_streams[i].index);
+ free(this->audio_streams[i].frame_buffer);
}
- if(this->fragment_tab)
- free(this->fragment_tab);
-
+ free(this->fragment_tab);
free(this);
}
@@ -1538,21 +1687,27 @@ static int demux_real_get_optional_data(demux_plugin_t *this_gen,
}
/* help function to discover stream type. returns:
+ * -1 if couldn't read
* 0 if not known.
* 1 if normal stream.
* 2 if reference stream.
*/
-static int real_check_stream_type(uint8_t *buf, int len)
+static int real_check_stream_type(input_plugin_t *input)
{
- if ((buf[0] == 0x2e)
- && (buf[1] == 'R')
- && (buf[2] == 'M')
- && (buf[3] == 'F'))
+ uint8_t buf[1024];
+ off_t len = _x_demux_read_header(input, buf, sizeof(buf));
+
+ if ( len < 4 )
+ return -1;
+
+ if ( memcmp(buf, "\x2eRMF", 4) == 0 )
return 1;
- buf[len] = '\0';
- if( strstr(buf,"pnm://") || strstr(buf,"rtsp://") || strstr(buf,"<smil>") ||
- !strncmp(buf,"http://",7) )
+#define my_strnstr(haystack, haystacklen, needle) \
+ memmem(haystack, haystacklen, needle, sizeof(needle))
+
+ if( my_strnstr(buf, len, "pnm://") || my_strnstr(buf, len, "rtsp://") ||
+ my_strnstr(buf, len, "<smil>") || !strncmp(buf, "http://", MIN(7, len)) )
return 2;
return 0;
@@ -1561,32 +1716,24 @@ static int real_check_stream_type(uint8_t *buf, int len)
static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream,
input_plugin_t *input) {
- demux_real_t *this;
- uint8_t buf[1024+1];
- int len, stream_type=0;
-
- switch (stream->content_detection_method) {
-
- case METHOD_BY_CONTENT:{
+ /* discover stream type */
+ const int stream_type = real_check_stream_type(input);
- if (! (len = _x_demux_read_header(input, buf, 1024)) )
- return NULL;
+ if ( stream_type < 0 )
+ return NULL;
- lprintf ("read 4 bytes: %02x %02x %02x %02x\n",
- buf[0], buf[1], buf[2], buf[3]);
+ switch (stream->content_detection_method) {
- if (!(stream_type = real_check_stream_type(buf,len)))
+ case METHOD_BY_CONTENT:
+ if ( stream_type < 1 )
return NULL;
- }
-
- lprintf ("by content accepted.\n");
- break;
+
+ lprintf ("by content accepted.\n");
+ break;
case METHOD_BY_EXTENSION: {
- const char *extensions, *mrl;
-
- mrl = input->get_mrl (input);
- extensions = class_gen->get_extensions (class_gen);
+ const char *const mrl = input->get_mrl (input);
+ const char *const extensions = class_gen->get_extensions (class_gen);
lprintf ("by extension '%s'\n", mrl);
@@ -1605,17 +1752,11 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
return NULL;
}
-
- this = xine_xmalloc (sizeof (demux_real_t));
+ demux_real_t *this = calloc(1, sizeof(demux_real_t));
this->stream = stream;
this->input = input;
- /* discover stream type */
- if(!stream_type)
- if ( (len = _x_demux_read_header(this->input, buf, 1024)) )
- stream_type = real_check_stream_type(buf,len);
-
if(stream_type == 2){
this->reference_mode = 1;
lprintf("reference stream detected\n");
@@ -1662,9 +1803,7 @@ static void class_dispose (demux_class_t *this_gen) {
}
static void *init_class (xine_t *xine, void *data) {
- demux_real_class_t *this;
-
- this = xine_xmalloc (sizeof (demux_real_class_t));
+ demux_real_class_t *const this = calloc(1, sizeof(demux_real_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_realaudio.c b/src/demuxers/demux_realaudio.c
index 70c9b310a..44449667c 100644
--- a/src/demuxers/demux_realaudio.c
+++ b/src/demuxers/demux_realaudio.c
@@ -41,6 +41,8 @@
#include "bswap.h"
#include "group_audio.h"
+#include "real_common.h"
+
#define RA_FILE_HEADER_PREV_SIZE 22
typedef struct {
@@ -62,6 +64,12 @@ typedef struct {
off_t data_start;
off_t data_size;
+ uint32_t cfs;
+ uint16_t w, h;
+ int frame_len;
+ size_t frame_size;
+ uint8_t *frame_buffer;
+
unsigned char *header;
unsigned int header_size;
} demux_ra_t;
@@ -70,25 +78,23 @@ typedef struct {
demux_class_t demux_class;
} demux_ra_class_t;
+/* Map flavour to bytes per second */
+static const int sipr_fl2bps[4] = {813, 1062, 625, 2000}; // 6.5, 8.5, 5, 16 kbit per second
+
/* returns 1 if the RealAudio file was opened successfully, 0 otherwise */
static int open_ra_file(demux_ra_t *this) {
- unsigned char file_header[RA_FILE_HEADER_PREV_SIZE], len;
- unsigned short version;
- off_t offset;
-
+ uint8_t file_header[RA_FILE_HEADER_PREV_SIZE];
/* check the signature */
if (_x_demux_read_header(this->input, file_header, RA_FILE_HEADER_PREV_SIZE) !=
RA_FILE_HEADER_PREV_SIZE)
return 0;
- if ((file_header[0] != '.') ||
- (file_header[1] != 'r') ||
- (file_header[2] != 'a'))
+ if ( memcmp(file_header, ".ra", 3) != 0 )
return 0;
/* read version */
- version = _X_BE_16(&file_header[0x04]);
+ const uint16_t version = _X_BE_16(&file_header[0x04]);
/* read header size according to version */
if (version == 3)
@@ -101,14 +107,15 @@ static int open_ra_file(demux_ra_t *this) {
}
/* allocate for and read header data */
- this->header = xine_xmalloc(this->header_size);
+ this->header = malloc(this->header_size);
- if (_x_demux_read_header(this->input, this->header, this->header_size) != this->header_size) {
+ if (!this->header || _x_demux_read_header(this->input, this->header, this->header_size) != this->header_size) {
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_realaudio: unable to read header\n");
free(this->header);
return 0;
}
+ off_t offset;
/* read header data according to version */
if((version == 3) && (this->header_size >= 32)) {
this->data_size = _X_BE_32(&this->header[0x12]);
@@ -138,47 +145,81 @@ static int open_ra_file(demux_ra_t *this) {
}
/* Read title */
- len = this->header[offset];
- if(len && ((offset+len+2) < this->header_size)) {
- _x_meta_info_n_set(this->stream, XINE_META_INFO_TITLE,
- &this->header[offset+1], len);
- offset += len+1;
- } else
- offset++;
+ {
+ const uint8_t len = this->header[offset];
+ if(len && ((offset+len+2) < this->header_size)) {
+ _x_meta_info_n_set(this->stream, XINE_META_INFO_TITLE,
+ &this->header[offset+1], len);
+ offset += len+1;
+ } else
+ offset++;
+ }
/* Author */
- len = this->header[offset];
- if(len && ((offset+len+1) < this->header_size)) {
- _x_meta_info_n_set(this->stream, XINE_META_INFO_ARTIST,
- &this->header[offset+1], len);
- offset += len+1;
- } else
- offset++;
+ {
+ const uint8_t len = this->header[offset];
+ if(len && ((offset+len+1) < this->header_size)) {
+ _x_meta_info_n_set(this->stream, XINE_META_INFO_ARTIST,
+ &this->header[offset+1], len);
+ offset += len+1;
+ } else
+ offset++;
+ }
/* Copyright/Date */
- len = this->header[offset];
- if(len && ((offset+len) <= this->header_size)) {
- _x_meta_info_n_set(this->stream, XINE_META_INFO_YEAR,
- &this->header[offset+1], len);
- offset += len+1;
- } else
- offset++;
+ {
+ const uint8_t len = this->header[offset];
+ if(len && ((offset+len) <= this->header_size)) {
+ _x_meta_info_n_set(this->stream, XINE_META_INFO_YEAR,
+ &this->header[offset+1], len);
+ offset += len+1;
+ } else
+ offset++;
+ }
/* Fourcc for version 3 comes after meta info */
- if((version == 3) && ((offset+7) <= this->header_size)) {
- if(this->header[offset+2] == 4)
- this->fourcc = _X_ME_32(&this->header[offset+3]);
- else {
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_realaudio: invalid fourcc size %d\n", this->header[offset+2]);
- free(this->header);
- return 0;
+ if(version == 3) {
+ if (((offset+7) <= this->header_size)) {
+ if(this->header[offset+2] == 4)
+ this->fourcc = _X_ME_32(&this->header[offset+3]);
+ else {
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "demux_realaudio: invalid fourcc size %d\n", this->header[offset+2]);
+ free(this->header);
+ return 0;
+ }
+ } else {
+ this->fourcc = ME_FOURCC('l', 'p', 'c', 'J');
}
}
_x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC, this->fourcc);
this->audio_type = _x_formattag_to_buf_audio(this->fourcc);
+ if (version == 4) {
+ const uint16_t sps = _X_BE_16 (this->header+44) ? : 1;
+ this->w = _X_BE_16 (this->header+42);
+ this->h = _X_BE_16 (this->header+40);
+ this->cfs = _X_BE_32 (this->header+24);
+
+ if (this->w < 0x8000 && this->h < 0x8000) {
+ uint64_t fs;
+ this->frame_len = this->w * this->h;
+ fs = (uint64_t) this->frame_len * sps;
+ if (fs < 0x80000000) {
+ this->frame_size = fs;
+ this->frame_buffer = calloc(this->frame_size, 1);
+ }
+ }
+ if (! this->frame_buffer) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_realaudio: malloc failed\n");
+ return 0;
+ }
+
+ if (this->audio_type == BUF_AUDIO_28_8 || this->audio_type == BUF_AUDIO_SIPRO)
+ this->block_align = this->cfs;
+ }
+
/* seek to start of data */
this->data_start = this->header_size;
if (this->input->seek(this->input, this->data_start, SEEK_SET) !=
@@ -197,7 +238,6 @@ static int demux_ra_send_chunk(demux_plugin_t *this_gen) {
demux_ra_t *this = (demux_ra_t *) this_gen;
off_t current_normpos = 0;
- int64_t current_pts;
/* just load data chunks from wherever the stream happens to be
* pointing; issue a DEMUX_FINISHED status if EOF is reached */
@@ -205,14 +245,45 @@ static int demux_ra_send_chunk(demux_plugin_t *this_gen) {
current_normpos = (int)( (double) (this->input->get_current_pos (this->input) - this->data_start) *
65535 / this->data_size );
- current_pts = 0; /* let the engine sort out the pts for now */
+ const int64_t current_pts = 0; /* let the engine sort out the pts for now */
if (this->seek_flag) {
_x_demux_control_newpts(this->stream, current_pts, BUF_FLAG_SEEK);
this->seek_flag = 0;
}
- if(_x_demux_read_send_data(this->audio_fifo, this->input, this->block_align,
+ if (this->audio_type == BUF_AUDIO_28_8 || this->audio_type == BUF_AUDIO_SIPRO) {
+ if (this->audio_type == BUF_AUDIO_SIPRO) {
+ if(this->input->read(this->input, this->frame_buffer, this->frame_len) < this->frame_len) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "demux_realaudio: failed to read audio chunk\n");
+
+ this->status = DEMUX_FINISHED;
+ return this->status;
+ }
+ demux_real_sipro_swap (this->frame_buffer, this->frame_len * 2 / 96);
+ } else {
+ int x, y;
+
+ for (y = 0; y < this->h; y++)
+ for (x = 0; x < this->h / 2; x++) {
+ const int pos = x * 2 * this->w + y * this->cfs;
+ if(this->input->read(this->input, this->frame_buffer + pos,
+ this->cfs) < this->cfs) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "demux_realaudio: failed to read audio chunk\n");
+
+ this->status = DEMUX_FINISHED;
+ return this->status;
+ }
+ }
+ }
+
+ _x_demux_send_data(this->audio_fifo,
+ this->frame_buffer, this->frame_size,
+ current_pts, this->audio_type, 0,
+ current_normpos, current_pts / 90, 0, 0);
+ } else if(_x_demux_read_send_data(this->audio_fifo, this->input, this->block_align,
current_pts, this->audio_type, 0, current_normpos,
current_pts / 90, 0, 0) < 0) {
this->status = DEMUX_FINISHED;
@@ -244,10 +315,7 @@ static void demux_ra_send_headers(demux_plugin_t *this_gen) {
buf->type = this->audio_type;
buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_FRAME_END;
- if(this->header_size > buf->max_size)
- buf->size = buf->max_size;
- else
- buf->size = this->header_size;
+ buf->size = MIN(this->header_size, buf->max_size);
memcpy(buf->content, this->header, buf->size);
@@ -299,6 +367,8 @@ static void demux_ra_dispose (demux_plugin_t *this_gen) {
if(this->header)
free(this->header);
+ if (this->frame_buffer)
+ free(this->frame_buffer);
free(this);
}
@@ -311,8 +381,6 @@ static int demux_ra_get_status (demux_plugin_t *this_gen) {
/* return the approximate length in miliseconds */
static int demux_ra_get_stream_length (demux_plugin_t *this_gen) {
- demux_ra_t *this = (demux_ra_t *) this_gen;
-
return 0;
}
@@ -330,9 +398,10 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
demux_ra_t *this;
- this = xine_xmalloc (sizeof (demux_ra_t));
+ this = calloc(1, sizeof(demux_ra_t));
this->stream = stream;
this->input = input;
+ this->frame_buffer = NULL;
this->demux_plugin.send_headers = demux_ra_send_headers;
this->demux_plugin.send_chunk = demux_ra_send_chunk;
@@ -404,7 +473,7 @@ static void class_dispose (demux_class_t *this_gen) {
void *demux_realaudio_init_plugin (xine_t *xine, void *data) {
demux_ra_class_t *this;
- this = xine_xmalloc (sizeof (demux_ra_class_t));
+ this = calloc(1, sizeof(demux_ra_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_roq.c b/src/demuxers/demux_roq.c
index 18edaea87..df2fb76a5 100644
--- a/src/demuxers/demux_roq.c
+++ b/src/demuxers/demux_roq.c
@@ -47,7 +47,6 @@
#include "bswap.h"
#include "group_games.h"
-#define RoQ_MAGIC_NUMBER 0x1084
#define RoQ_CHUNK_PREAMBLE_SIZE 8
#define RoQ_AUDIO_SAMPLE_RATE 22050
@@ -93,8 +92,9 @@ static int open_roq_file(demux_roq_t *this) {
return 0;
/* check for the RoQ magic numbers */
- if ((_X_LE_16(&preamble[0]) != RoQ_MAGIC_NUMBER) ||
- (_X_LE_32(&preamble[2]) != 0xFFFFFFFF))
+ static const uint8_t RoQ_MAGIC_STRING[] =
+ { 0x10, 0x84, 0xFF, 0xFF, 0xFF, 0xFF };
+ if( memcmp(preamble, RoQ_MAGIC_STRING, sizeof(RoQ_MAGIC_STRING)) != 0 )
return 0;
this->bih.biSize = sizeof(xine_bmiheader);
@@ -411,7 +411,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
return NULL;
}
- this = xine_xmalloc (sizeof (demux_roq_t));
+ this = calloc(1, sizeof(demux_roq_t));
this->stream = stream;
this->input = input;
@@ -485,7 +485,7 @@ static void class_dispose (demux_class_t *this_gen) {
void *demux_roq_init_plugin (xine_t *xine, void *data) {
demux_roq_class_t *this;
- this = xine_xmalloc (sizeof (demux_roq_class_t));
+ this = calloc(1, sizeof(demux_roq_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_shn.c b/src/demuxers/demux_shn.c
index 87324ab45..ccc34b57f 100644
--- a/src/demuxers/demux_shn.c
+++ b/src/demuxers/demux_shn.c
@@ -88,7 +88,7 @@ static int demux_shn_send_chunk(demux_plugin_t *this_gen) {
buf->pts = 0;
bytes_read = this->input->read(this->input, buf->content, buf->max_size);
- if (bytes_read == 0) {
+ if (bytes_read <= 0) {
buf->free_buffer(buf);
this->status = DEMUX_FINISHED;
return this->status;
@@ -182,7 +182,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
demux_shn_t *this;
- this = xine_xmalloc (sizeof (demux_shn_t));
+ this = calloc(1, sizeof(demux_shn_t));
this->stream = stream;
this->input = input;
@@ -253,7 +253,7 @@ static void class_dispose (demux_class_t *this_gen) {
void *demux_shn_init_plugin (xine_t *xine, void *data) {
demux_shn_class_t *this;
- this = xine_xmalloc (sizeof (demux_shn_class_t));
+ this = calloc(1, sizeof(demux_shn_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_slave.c b/src/demuxers/demux_slave.c
index 436d37579..abb4d01e5 100644
--- a/src/demuxers/demux_slave.c
+++ b/src/demuxers/demux_slave.c
@@ -90,10 +90,11 @@ static int demux_slave_next (demux_slave_t *this) {
/* fill the scratch buffer */
n = this->input->read(this->input, &this->scratch[this->scratch_used],
SCRATCH_SIZE - this->scratch_used);
- this->scratch_used += n;
+ if (n > 0)
+ this->scratch_used += n;
this->scratch[this->scratch_used] = '\0';
- if( !n ) {
+ if (n <= 0) {
lprintf("connection closed\n");
this->status = DEMUX_FINISHED;
return 0;
@@ -186,10 +187,8 @@ static int demux_slave_next (demux_slave_t *this) {
buf->decoder_flags = decoder_flags;
/* set decoder info */
- for( i = 0; i < BUF_NUM_DEC_INFO; i++ ) {
- buf->decoder_info[i] = this->decoder_info[i];
- buf->decoder_info_ptr[i] = this->decoder_info_ptr[i];
- }
+ memcpy(buf->decoder_info, this->decoder_info, sizeof(this->decoder_info));
+ memcpy(buf->decoder_info_ptr, this->decoder_info_ptr, sizeof(this->decoder_info));
memset(this->decoder_info, 0, sizeof(this->decoder_info));
memset(this->decoder_info_ptr, 0, sizeof(this->decoder_info_ptr));
@@ -331,7 +330,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
demux_slave_t *this;
static char slave_id_str[] = "master xine v1\n";
- this = xine_xmalloc (sizeof (demux_slave_t));
+ this = calloc(1, sizeof(demux_slave_t));
switch (stream->content_detection_method) {
@@ -414,7 +413,7 @@ static void class_dispose (demux_class_t *this_gen) {
static void *init_plugin (xine_t *xine, void *data) {
demux_slave_class_t *this;
- this = xine_xmalloc (sizeof (demux_slave_class_t));
+ this = calloc(1, sizeof(demux_slave_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_smjpeg.c b/src/demuxers/demux_smjpeg.c
index 899fbf7e3..aacd55503 100644
--- a/src/demuxers/demux_smjpeg.c
+++ b/src/demuxers/demux_smjpeg.c
@@ -55,7 +55,6 @@
#define vidD_TAG FOURCC_TAG('v', 'i', 'd', 'D')
#define APCM_TAG FOURCC_TAG('A', 'P', 'C', 'M')
-#define SMJPEG_SIGNATURE_SIZE 8
/* 16 is the max size of a header chunk (the video header) */
#define SMJPEG_VIDEO_HEADER_SIZE 16
#define SMJPEG_AUDIO_HEADER_SIZE 12
@@ -98,23 +97,18 @@ static int open_smjpeg_file(demux_smjpeg_t *this) {
unsigned char header_chunk[SMJPEG_HEADER_CHUNK_MAX_SIZE];
unsigned int audio_codec = 0;
- if (_x_demux_read_header(this->input, signature, SMJPEG_SIGNATURE_SIZE) !=
- SMJPEG_SIGNATURE_SIZE)
+ static const uint8_t SMJPEG_SIGNATURE[8] =
+ { 0x00, 0x0A, 'S', 'M', 'J', 'P', 'E', 'G' };
+
+ if (_x_demux_read_header(this->input, signature, sizeof(SMJPEG_SIGNATURE)) !=
+ sizeof(SMJPEG_SIGNATURE))
return 0;
- /* check for the SMJPEG signature */
- if ((signature[0] != 0x00) ||
- (signature[1] != 0x0A) ||
- (signature[2] != 'S') ||
- (signature[3] != 'M') ||
- (signature[4] != 'J') ||
- (signature[5] != 'P') ||
- (signature[6] != 'E') ||
- (signature[7] != 'G'))
+ if (memcmp(signature, SMJPEG_SIGNATURE, sizeof(SMJPEG_SIGNATURE)) != 0)
return 0;
/* file is qualified; jump over the header + version to the duration */
- this->input->seek(this->input, SMJPEG_SIGNATURE_SIZE + 4, SEEK_SET);
+ this->input->seek(this->input, sizeof(SMJPEG_SIGNATURE) + 4, SEEK_SET);
if (this->input->read(this->input, header_chunk, 4) != 4)
return 0;
this->duration = _X_BE_32(&header_chunk[0]);
@@ -400,7 +394,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
return NULL;
}
- this = xine_xmalloc (sizeof (demux_smjpeg_t));
+ this = calloc(1, sizeof(demux_smjpeg_t));
this->stream = stream;
this->input = input;
@@ -474,7 +468,7 @@ static void class_dispose (demux_class_t *this_gen) {
void *demux_smjpeg_init_plugin (xine_t *xine, void *data) {
demux_smjpeg_class_t *this;
- this = xine_xmalloc (sizeof (demux_smjpeg_class_t));
+ this = calloc(1, sizeof(demux_smjpeg_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_snd.c b/src/demuxers/demux_snd.c
index 0965a75ae..b98b66758 100644
--- a/src/demuxers/demux_snd.c
+++ b/src/demuxers/demux_snd.c
@@ -42,8 +42,6 @@
#define SND_HEADER_SIZE 24
#define PCM_BLOCK_ALIGN 1024
-/* this is the big-endian hex value '.snd' */
-#define snd_TAG 0x2E736E64
typedef struct {
demux_plugin_t demux_plugin;
@@ -83,7 +81,7 @@ static int open_snd_file(demux_snd_t *this) {
return 0;
/* check the signature */
- if (_X_BE_32(&header[0]) != snd_TAG)
+ if ( !_x_is_fourcc(&header[0], ".snd") )
return 0;
/* file is qualified; skip over the header bytes in the stream */
@@ -318,7 +316,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
demux_snd_t *this;
- this = xine_xmalloc (sizeof (demux_snd_t));
+ this = calloc(1, sizeof(demux_snd_t));
this->stream = stream;
this->input = input;
@@ -395,7 +393,7 @@ static void class_dispose (demux_class_t *this_gen) {
void *demux_snd_init_plugin (xine_t *xine, void *data) {
demux_snd_class_t *this;
- this = xine_xmalloc (sizeof (demux_snd_class_t));
+ this = calloc(1, sizeof(demux_snd_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_str.c b/src/demuxers/demux_str.c
index 2cf542014..442bffadc 100644
--- a/src/demuxers/demux_str.c
+++ b/src/demuxers/demux_str.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2003 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -139,20 +139,15 @@
#define CD_RAW_SECTOR_SIZE 2352
+#define STR_MAGIC "\x60\x01\x01\x80"
#define STR_MAX_CHANNELS 32
-#define STR_MAGIC (0x80010160)
-
#define CDXA_TYPE_MASK 0x0E
#define CDXA_TYPE_DATA 0x08
#define CDXA_TYPE_AUDIO 0x04
#define CDXA_TYPE_VIDEO 0x02
#define CDXA_SUBMODE_EOF 0x80 /* set if EOF */
-#define FOURCC_TAG BE_FOURCC
-#define RIFF_TAG FOURCC_TAG('R', 'I', 'F', 'F')
-#define CDXA_TAG FOURCC_TAG('C', 'D', 'X', 'A')
-
/* FIXME */
#define FRAME_DURATION 45000
@@ -188,9 +183,7 @@ static int open_str_file(demux_str_t *this) {
unsigned char check_bytes[STR_CHECK_BYTES];
int local_offset, sector, channel;
- for (channel = 0; channel < STR_MAX_CHANNELS; channel++) {
- this->channel_type[channel] = 0;
- }
+ memset(this->channel_type, 0, sizeof(this->channel_type));
this->input->seek(this->input, 0, SEEK_SET);
if (this->input->read(this->input, check_bytes, STR_CHECK_BYTES) !=
@@ -200,8 +193,8 @@ static int open_str_file(demux_str_t *this) {
}
/* check for STR with a RIFF header */
- if ((_X_BE_32(&check_bytes[0]) == RIFF_TAG) &&
- (_X_BE_32(&check_bytes[8]) == CDXA_TAG))
+ if ( _x_is_fourcc(&check_bytes[0], "RIFF") &&
+ _x_is_fourcc(&check_bytes[8], "CDXA") )
local_offset = 0x2C;
else
local_offset = 0;
@@ -218,16 +211,20 @@ static int open_str_file(demux_str_t *this) {
check_bytes[local_offset + 0x13]);
/* check for 12-byte sync marker */
- if ((_X_BE_32(&check_bytes[local_offset + 0]) != 0x00FFFFFF) ||
- (_X_BE_32(&check_bytes[local_offset + 4]) != 0xFFFFFFFF) ||
- (_X_BE_32(&check_bytes[local_offset + 8]) != 0xFFFFFF00)) {
+ static const uint8_t sync_marker[12] =
+ { 0x00, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x00, 0xFF, 0xFF, 0X00
+ };
+ if ( memcmp(&check_bytes[local_offset],
+ sync_marker, sizeof(sync_marker)) != 0 ) {
lprintf("sector %d sync error\n", sector);
return 0;
}
/* the 32 bits starting at 0x10 and at 0x14 should be the same */
- if (_X_BE_32(&check_bytes[local_offset + 0x10]) !=
- _X_BE_32(&check_bytes[local_offset + 0x14])) {
+ if (memcmp(&check_bytes[local_offset + 0x10],
+ &check_bytes[local_offset + 0x14], 4) != 0) {
lprintf("sector %d control bits copy error\n", sector);
return 0;
}
@@ -246,7 +243,7 @@ static int open_str_file(demux_str_t *this) {
case CDXA_TYPE_VIDEO:
/* first time we have seen video/data in this channel? */
if ((!(this->channel_type[channel] & CDXA_TYPE_DATA)) &&
- (_X_LE_32(&check_bytes[local_offset + 0x18]) == STR_MAGIC)) {
+ (_x_is_fourcc(&check_bytes[local_offset + 0x18], STR_MAGIC))) {
/* mark this channel as having video data */
this->channel_type[channel] |= CDXA_TYPE_VIDEO;
@@ -347,7 +344,7 @@ static int demux_str_send_chunk(demux_plugin_t *this_gen) {
case CDXA_TYPE_DATA:
/* video chunk */
- if (_X_LE_32(&sector[0x18]) != STR_MAGIC ||
+ if (!_x_is_fourcc(&sector[0x18], STR_MAGIC) ||
channel != this->default_video_channel) {
return 0;
}
@@ -555,7 +552,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
return NULL;
}
- this = xine_xmalloc (sizeof (demux_str_t));
+ this = calloc(1, sizeof(demux_str_t));
this->stream = stream;
this->input = input;
@@ -628,7 +625,7 @@ static void class_dispose (demux_class_t *this_gen) {
void *demux_str_init_plugin (xine_t *xine, void *data) {
demux_str_class_t *this;
- this = xine_xmalloc (sizeof (demux_str_class_t));
+ this = calloc(1, sizeof(demux_str_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c
index 86a14f019..98de1f9ea 100644
--- a/src/demuxers/demux_ts.c
+++ b/src/demuxers/demux_ts.c
@@ -185,9 +185,6 @@
#define INVALID_PROGRAM ((unsigned int)(-1))
#define INVALID_CC ((unsigned int)(-1))
-#define MIN(a,b) (((a)<(b))?(a):(b))
-#define MAX(a,b) (((a)>(b))?(a):(b))
-
#define PROG_STREAM_MAP 0xBC
#define PRIVATE_STREAM1 0xBD
#define PADDING_STREAM 0xBE
@@ -220,7 +217,9 @@
ISO_13818_PART7_AUDIO = 0x0f, /* ISO/IEC 13818-7 Audio with ADTS transport sytax */
ISO_14496_PART2_VIDEO = 0x10, /* ISO/IEC 14496-2 Visual (MPEG-4) */
ISO_14496_PART3_AUDIO = 0x11, /* ISO/IEC 14496-3 Audio with LATM transport syntax */
- ISO_14496_PART10_VIDEO = 0x1b /* ISO/IEC 14496-10 Video (MPEG-4 part 10/AVC, aka H.264) */
+ ISO_14496_PART10_VIDEO = 0x1b, /* ISO/IEC 14496-10 Video (MPEG-4 part 10/AVC, aka H.264) */
+ STREAM_VIDEO_MPEG = 0x80,
+ STREAM_AUDIO_AC3 = 0x81,
} streamType;
#define WRAP_THRESHOLD 270000
@@ -246,10 +245,11 @@ typedef struct {
int64_t pts;
buf_element_t *buf;
unsigned int counter;
- uint8_t descriptor_tag;
+ uint16_t descriptor_tag; /* +0x100 for PES stream IDs (no available TS descriptor tag?) */
int64_t packet_count;
int corrupted_pes;
uint32_t buffered_bytes;
+ int autodetected;
} demux_ts_media;
@@ -752,15 +752,16 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m,
* we check the descriptor tag first because some stations
* do not include any of the ac3 header info in their audio tracks
* these "raw" streams may begin with a byte that looks like a stream type.
+ * For audio streams, m->type already contains the stream no.
*/
- if((m->descriptor_tag == 0x81) || /* ac3 - raw */
+ if((m->descriptor_tag == STREAM_AUDIO_AC3) || /* ac3 - raw */
(p[0] == 0x0B && p[1] == 0x77)) { /* ac3 - syncword */
m->content = p;
m->size = packet_len;
m->type |= BUF_AUDIO_A52;
return 1;
- } else if (m->descriptor_tag == 0x06
+ } else if (m->descriptor_tag == ISO_13818_PES_PRIVATE
&& p[0] == 0x20 && p[1] == 0x00) {
/* DVBSUB */
long payload_len = ((buf[4] << 8) | buf[5]) - header_len - 3;
@@ -808,6 +809,7 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m,
switch (m->descriptor_tag) {
case ISO_11172_VIDEO:
case ISO_13818_VIDEO:
+ case STREAM_VIDEO_MPEG:
lprintf ("demux_ts: found MPEG video type.\n");
m->type = BUF_VIDEO_MPEG;
break;
@@ -931,9 +933,11 @@ static void demux_ts_buffer_pes(demux_ts_t*this, unsigned char *ts,
m->buf->free_buffer(m->buf);
m->buf = NULL;
- if (m->corrupted_pes > CORRUPT_PES_THRESHOLD) {
- if (this->videoPid == m->pid)
+ if (m->corrupted_pes > CORRUPT_PES_THRESHOLD && m->autodetected) {
+ if (this->videoPid == m->pid) {
this->videoPid = INVALID_PID;
+ this->last_pmt_crc = 0;
+ }
} else {
m->corrupted_pes++;
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
@@ -982,7 +986,7 @@ static void demux_ts_pes_new(demux_ts_t*this,
unsigned int mediaIndex,
unsigned int pid,
fifo_buffer_t *fifo,
- uint8_t descriptor) {
+ uint16_t descriptor) {
demux_ts_media *m = &this->media[mediaIndex];
@@ -1193,6 +1197,15 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num
return;
}
+ if (!section_length) {
+ free (this->pmt[program_count]);
+ this->pmt[program_count] = NULL;
+#ifdef TS_PMT_LOG
+ printf ("ts_demux: eek, zero-length section?\n");
+#endif
+ return;
+ }
+
#ifdef TS_PMT_LOG
printf ("ts_demux: have all TS packets for the PMT section\n");
#endif
@@ -1230,6 +1243,15 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num
}
}
+ /*
+ * Forget the current video, audio and subtitle PIDs; if the PMT has not
+ * changed, we'll pick them up again when we parse this PMT, while if the
+ * PMT has changed (e.g. an IPTV streamer that's just changed its source),
+ * we'll get new PIDs that we should follow.
+ */
+ this->audio_tracks_count = 0;
+ this->videoPid = INVALID_PID;
+ this->spu_pid = INVALID_PID;
/*
* ES definitions start here...we are going to learn upto one video
@@ -1331,7 +1353,6 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num
case ISO_13818_PES_PRIVATE:
for (i = 5; i < coded_length; i += stream[i+1] + 2) {
if ((stream[i] == 0x6a) && (this->audio_tracks_count < MAX_AUDIO_TRACKS)) {
- uint32_t format_identifier=0;
int i, found = 0;
for(i = 0; i < this->audio_tracks_count; i++) {
if(this->audio_tracks[i].pid == pid) {
@@ -1344,7 +1365,7 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num
printf ("demux_ts: PMT AC3 audio pid 0x%.4x type %2.2x\n", pid, stream[0]);
#endif
demux_ts_pes_new(this, this->media_num, pid,
- this->audio_fifo, 0x81);
+ this->audio_fifo, STREAM_AUDIO_AC3);
this->audio_tracks[this->audio_tracks_count].pid = pid;
this->audio_tracks[this->audio_tracks_count].media_index = this->media_num;
@@ -1555,7 +1576,7 @@ static unsigned char * demux_synchronise(demux_ts_t* this) {
do {
read_length = this->input->read(this->input, this->buf,
PKT_SIZE * NPKT_PER_READ);
- if (read_length % PKT_SIZE) {
+ if (read_length < 0 || read_length % PKT_SIZE) {
xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
"demux_ts: read returned %d bytes (not a multiple of %d!)\n",
read_length, PKT_SIZE);
@@ -1837,7 +1858,8 @@ static void demux_ts_parse_packet (demux_ts_t*this) {
} else if (!found) {
this->videoPid = pid;
this->videoMedia = this->media_num;
- demux_ts_pes_new(this, this->media_num++, pid, this->video_fifo, pes_stream_id);
+ this->media[this->videoMedia].autodetected = 1;
+ demux_ts_pes_new(this, this->media_num++, pid, this->video_fifo, 0x100 + pes_stream_id);
}
if (this->videoPid != INVALID_PID) {
@@ -1859,11 +1881,12 @@ static void demux_ts_parse_packet (demux_ts_t*this) {
xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
"demux_ts: auto-detected audio pid 0x%.4x\n", pid);
#endif
+ /* store PID, index and stream no. */
this->audio_tracks[this->audio_tracks_count].pid = pid;
this->audio_tracks[this->audio_tracks_count].media_index = this->media_num;
this->media[this->media_num].type = this->audio_tracks_count;
demux_ts_pes_new(this, this->media_num++, pid,
- this->audio_fifo,pes_stream_id);
+ this->audio_fifo, 0x100 + pes_stream_id);
this->audio_tracks_count++;
}
}
@@ -2229,7 +2252,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen,
* if we reach this point, the input has been accepted.
*/
- this = xine_xmalloc(sizeof(*this));
+ this = calloc(1, sizeof(*this));
this->stream = stream;
this->input = input;
this->blockSize = PKT_SIZE;
@@ -2250,6 +2273,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen,
for (i = 0; i < MAX_PIDS; i++) {
this->media[i].pid = INVALID_PID;
this->media[i].buf = NULL;
+ this->media[i].autodetected = 0;
}
for (i = 0; i < MAX_PMTS; i++) {
@@ -2270,12 +2294,6 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen,
this->status = DEMUX_FINISHED;
-#ifdef TS_READ_STATS
- for (i=0; i<=NPKT_PER_READ; i++) {
- this->rstat[i] = 0;
- }
-#endif
-
/* DVBSUB */
this->spu_pid = INVALID_PID;
this->spu_langs_count = 0;
@@ -2320,7 +2338,7 @@ static void *init_class (xine_t *xine, void *data) {
demux_ts_class_t *this;
- this = xine_xmalloc (sizeof (demux_ts_class_t));
+ this = calloc(1, sizeof(demux_ts_class_t));
this->config = xine->config;
this->xine = xine;
diff --git a/src/demuxers/demux_tta.c b/src/demuxers/demux_tta.c
index f6eadd652..24a983157 100644
--- a/src/demuxers/demux_tta.c
+++ b/src/demuxers/demux_tta.c
@@ -21,6 +21,10 @@
* Inspired by tta libavformat demuxer by Alex Beregszaszi
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#define LOG_MODULE "demux_tta"
#define LOG_VERBOSE
@@ -72,7 +76,7 @@ static int open_tta_file(demux_tta_t *this) {
if (_x_demux_read_header(this->input, peek, 4) != 4)
return 0;
- if ( _X_BE_32(peek) != FOURCC_32('T', 'T', 'A', '1') )
+ if ( !_x_is_fourcc(peek, "TTA1") )
return 0;
if ( this->input->read(this->input, this->header.buffer, sizeof(this->header)) != sizeof(this->header) )
@@ -87,7 +91,7 @@ static int open_tta_file(demux_tta_t *this) {
return 0;
}
- this->seektable = xine_xmalloc(sizeof(uint32_t)*this->totalframes);
+ this->seektable = calloc(this->totalframes, sizeof(uint32_t));
this->input->read(this->input, this->seektable, sizeof(uint32_t)*this->totalframes);
/* Skip the CRC32 */
@@ -126,6 +130,10 @@ static int demux_tta_send_chunk(demux_plugin_t *this_gen) {
/* buf->extra_info->input_time = this->current_sample / this->samplerate; */
bytes_read = this->input->read(this->input, buf->content, ( bytes_to_read > buf->max_size ) ? buf->max_size : bytes_to_read);
+ if (bytes_read < 0) {
+ this->status = DEMUX_FINISHED;
+ break;
+ }
buf->size = bytes_read;
@@ -233,7 +241,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
demux_tta_t *this;
- this = xine_xmalloc (sizeof (demux_tta_t));
+ this = calloc(1, sizeof(demux_tta_t));
this->stream = stream;
this->input = input;
@@ -307,7 +315,7 @@ static void class_dispose (demux_class_t *this_gen) {
void *demux_tta_init_plugin (xine_t *xine, void *data) {
demux_tta_class_t *this;
- this = xine_xmalloc (sizeof (demux_tta_class_t));
+ this = calloc(1, sizeof(demux_tta_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_vmd.c b/src/demuxers/demux_vmd.c
index 8b0087417..b81e4575e 100644
--- a/src/demuxers/demux_vmd.c
+++ b/src/demuxers/demux_vmd.c
@@ -168,7 +168,7 @@ static int open_vmd_file(demux_vmd_t *this) {
return 0;
}
- this->frame_table = xine_xmalloc(this->frame_count * sizeof(vmd_frame_t));
+ this->frame_table = calloc(this->frame_count, sizeof(vmd_frame_t));
current_offset = this->data_start = _X_LE_32(&vmd_header[20]);
this->data_size = toc_offset - this->data_start;
@@ -421,7 +421,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
demux_vmd_t *this;
- this = xine_xmalloc (sizeof (demux_vmd_t));
+ this = calloc(1, sizeof(demux_vmd_t));
this->stream = stream;
this->input = input;
@@ -495,7 +495,7 @@ static void class_dispose (demux_class_t *this_gen) {
void *demux_vmd_init_plugin (xine_t *xine, void *data) {
demux_vmd_class_t *this;
- this = xine_xmalloc (sizeof (demux_vmd_class_t));
+ this = calloc(1, sizeof(demux_vmd_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_voc.c b/src/demuxers/demux_voc.c
index 0439980f8..e825f6869 100644
--- a/src/demuxers/demux_voc.c
+++ b/src/demuxers/demux_voc.c
@@ -85,7 +85,7 @@ static int open_voc_file(demux_voc_t *this) {
return 0;
/* check the signature */
- if (strncmp(header, VOC_SIGNATURE, strlen(VOC_SIGNATURE)) != 0)
+ if (memcmp(header, VOC_SIGNATURE, sizeof(VOC_SIGNATURE)-1) != 0)
return 0;
/* file is qualified */
@@ -106,7 +106,7 @@ static int open_voc_file(demux_voc_t *this) {
}
/* assemble 24-bit, little endian length */
- this->data_size = preamble[1] | (preamble[2] << 8) | (preamble[3] << 16);
+ this->data_size = _X_LE_24(&preamble[1]);
/* get the next 2 bytes (re-use preamble bytes) */
if (this->input->read(this->input, preamble, 2) != 2)
@@ -296,7 +296,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
demux_voc_t *this;
- this = xine_xmalloc (sizeof (demux_voc_t));
+ this = calloc(1, sizeof(demux_voc_t));
this->stream = stream;
this->input = input;
@@ -370,7 +370,7 @@ static void class_dispose (demux_class_t *this_gen) {
void *demux_voc_init_plugin (xine_t *xine, void *data) {
demux_voc_class_t *this;
- this = xine_xmalloc (sizeof (demux_voc_class_t));
+ this = calloc(1, sizeof(demux_voc_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_vox.c b/src/demuxers/demux_vox.c
index 3ce2ad705..1b34106ad 100644
--- a/src/demuxers/demux_vox.c
+++ b/src/demuxers/demux_vox.c
@@ -77,7 +77,7 @@ static int demux_vox_send_chunk (demux_plugin_t *this_gen) {
buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
buf->type = BUF_AUDIO_DIALOGIC_IMA;
bytes_read = this->input->read(this->input, buf->content, buf->max_size);
- if (bytes_read == 0) {
+ if (bytes_read <= 0) {
buf->free_buffer(buf);
this->status = DEMUX_FINISHED;
return this->status;
@@ -203,7 +203,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
return NULL;
}
- this = xine_xmalloc (sizeof (demux_vox_t));
+ this = calloc(1, sizeof(demux_vox_t));
this->stream = stream;
this->input = input;
@@ -247,7 +247,7 @@ static void class_dispose (demux_class_t *this_gen) {
void *demux_vox_init_plugin (xine_t *xine, void *data) {
demux_vox_class_t *this;
- this = xine_xmalloc (sizeof (demux_vox_class_t));
+ this = calloc(1, sizeof(demux_vox_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_vqa.c b/src/demuxers/demux_vqa.c
index 40242476b..5fb8273dd 100644
--- a/src/demuxers/demux_vqa.c
+++ b/src/demuxers/demux_vqa.c
@@ -96,8 +96,8 @@ static int open_vqa_file(demux_vqa_t *this) {
return 0;
/* check for the VQA signatures */
- if ((_X_BE_32(&scratch[0]) != FORM_TAG) ||
- (_X_BE_32(&scratch[8]) != WVQA_TAG))
+ if (!_x_is_fourcc(&scratch[0], "FORM") ||
+ !_x_is_fourcc(&scratch[8], "WVQA") )
return 0;
/* file is qualified; skip to the start of the VQA header */
@@ -334,7 +334,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
demux_vqa_t *this;
- this = xine_xmalloc (sizeof (demux_vqa_t));
+ this = calloc(1, sizeof(demux_vqa_t));
this->stream = stream;
this->input = input;
@@ -408,7 +408,7 @@ static void class_dispose (demux_class_t *this_gen) {
void *demux_vqa_init_plugin (xine_t *xine, void *data) {
demux_vqa_class_t *this;
- this = xine_xmalloc (sizeof (demux_vqa_class_t));
+ this = calloc(1, sizeof(demux_vqa_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_wav.c b/src/demuxers/demux_wav.c
index 33baaf973..99c50ad67 100644
--- a/src/demuxers/demux_wav.c
+++ b/src/demuxers/demux_wav.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2001-2005 the xine project
+ * Copyright (C) 2001-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -41,9 +41,11 @@
#include "bswap.h"
#include "group_audio.h"
-#define WAV_SIGNATURE_SIZE 16
+#define WAV_SIGNATURE_SIZE 12
/* this is the hex value for 'data' */
#define data_TAG 0x61746164
+/* this is the hex value for 'fmt ' */
+#define fmt_TAG 0x20746D66
#define PCM_BLOCK_ALIGN 1024
#define PREFERED_BLOCK_SIZE 4096
@@ -74,31 +76,62 @@ typedef struct {
static int demux_wav_get_stream_length (demux_plugin_t *this_gen);
-/* returns 1 if the WAV file was opened successfully, 0 otherwise */
-static int open_wav_file(demux_wav_t *this) {
- uint8_t signature[WAV_SIGNATURE_SIZE];
+/* searches for the chunk with the given tag from the beginning of WAV file
+ * returns 1 if chunk was found, 0 otherwise,
+ * fills chunk_size and chunk_pos if chunk was found
+ * NOTE: chunk_pos is set to the position of the first byte of chunk data */
+static int find_chunk_by_tag(demux_wav_t *this, const uint32_t given_chunk_tag,
+ uint32_t *found_chunk_size, off_t *found_chunk_pos) {
uint32_t chunk_tag;
uint32_t chunk_size;
uint8_t chunk_preamble[8];
+ /* search for the chunks from the start of the WAV file */
+ this->input->seek(this->input, WAV_SIGNATURE_SIZE, SEEK_SET);
+
+ while (1) {
+ if (this->input->read(this->input, chunk_preamble, 8) != 8) {
+ return 0;
+ }
+
+ chunk_tag = _X_LE_32(&chunk_preamble[0]);
+ chunk_size = _X_LE_32(&chunk_preamble[4]);
+
+ if (chunk_tag == given_chunk_tag) {
+ if (found_chunk_size)
+ *found_chunk_size = _X_LE_32(&chunk_preamble[4]);
+ if (found_chunk_pos)
+ *found_chunk_pos = this->input->get_current_pos(this->input);
+ return 1;
+ } else {
+ this->input->seek(this->input, chunk_size, SEEK_CUR);
+ }
+ }
+}
+
+/* returns 1 if the WAV file was opened successfully, 0 otherwise */
+static int open_wav_file(demux_wav_t *this) {
+ uint8_t signature[WAV_SIGNATURE_SIZE];
+ off_t wave_pos;
+ uint32_t wave_size;
+
/* check the signature */
if (_x_demux_read_header(this->input, signature, WAV_SIGNATURE_SIZE) != WAV_SIGNATURE_SIZE)
return 0;
- if (memcmp(signature, "RIFF", 4) || memcmp(&signature[8], "WAVEfmt ", 8) )
+ if (memcmp(signature, "RIFF", 4) || memcmp(&signature[8], "WAVE", 4) )
return 0;
- /* file is qualified; skip over the header bytes in the stream */
- this->input->seek(this->input, WAV_SIGNATURE_SIZE, SEEK_SET);
-
- /* go after the format structure */
- if (this->input->read(this->input,
- (unsigned char *)&this->wave_size, 4) != 4)
+ /* search for the 'fmt ' chunk first */
+ wave_pos = 0;
+ if (find_chunk_by_tag(this, fmt_TAG, &wave_size, &wave_pos)==0)
return 0;
- this->wave_size = le2me_32(this->wave_size);
- this->wave = xine_xmalloc( this->wave_size );
-
- if (this->input->read(this->input, (void *)this->wave, this->wave_size) !=
+ this->wave_size = wave_size;
+
+ this->input->seek(this->input, wave_pos, SEEK_SET);
+ this->wave = malloc( this->wave_size );
+
+ if (!this->wave || this->input->read(this->input, (void *)this->wave, this->wave_size) !=
this->wave_size) {
free (this->wave);
return 0;
@@ -114,28 +147,21 @@ static int open_wav_file(demux_wav_t *this) {
return 0;
}
- /* traverse through the chunks to find the 'data' chunk */
+ /* search for the 'data' chunk */
this->data_start = this->data_size = 0;
- while (this->data_start == 0) {
-
- if (this->input->read(this->input, chunk_preamble, 8) != 8) {
- free (this->wave);
- return 0;
- }
- chunk_tag = _X_LE_32(&chunk_preamble[0]);
- chunk_size = _X_LE_32(&chunk_preamble[4]);
-
- if (chunk_tag == data_TAG) {
- this->data_start = this->input->get_current_pos(this->input);
- /* Get the data length from the file itself, instead of the data
- * TAG, for broken files */
- this->data_size = this->input->get_length(this->input);
- } else {
- this->input->seek(this->input, chunk_size, SEEK_CUR);
- }
+ if (find_chunk_by_tag(this, data_TAG, NULL, &this->data_start)==0)
+ {
+ free (this->wave);
+ return 0;
+ }
+ else
+ {
+ /* Get the data length from the file itself, instead of the data
+ * TAG, for broken files */
+ this->input->seek(this->input, this->data_start, SEEK_SET);
+ this->data_size = this->input->get_length(this->input);
+ return 1;
}
-
- return 1;
}
static int demux_wav_send_chunk(demux_plugin_t *this_gen) {
@@ -184,11 +210,16 @@ static int demux_wav_send_chunk(demux_plugin_t *this_gen) {
buf->size = remaining_sample_bytes;
remaining_sample_bytes -= buf->size;
- if (this->input->read(this->input, buf->content, buf->size) !=
+ off_t read;
+ if ((read = this->input->read(this->input, buf->content, buf->size)) !=
buf->size) {
- buf->free_buffer(buf);
- this->status = DEMUX_FINISHED;
- break;
+ if (read == 0) {
+ buf->free_buffer(buf);
+ this->status = DEMUX_FINISHED;
+ break;
+ } else {
+ buf->size = read;
+ }
}
#if 0
@@ -337,7 +368,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
demux_wav_t *this;
uint32_t align;
- this = xine_xmalloc (sizeof (demux_wav_t));
+ this = calloc(1, sizeof(demux_wav_t));
this->stream = stream;
this->input = input;
@@ -423,7 +454,7 @@ static void class_dispose (demux_class_t *this_gen) {
void *demux_wav_init_plugin (xine_t *xine, void *data) {
demux_wav_class_t *this;
- this = xine_xmalloc (sizeof (demux_wav_class_t));
+ this = calloc(1, sizeof(demux_wav_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_wc3movie.c b/src/demuxers/demux_wc3movie.c
index 596d47f4a..7750c3e0e 100644
--- a/src/demuxers/demux_wc3movie.c
+++ b/src/demuxers/demux_wc3movie.c
@@ -102,7 +102,7 @@ typedef struct {
} demux_mve_class_t;
/* bizarre palette lookup table */
-const unsigned char wc3_pal_lookup[] = {
+static const unsigned char wc3_pal_lookup[] = {
0x00, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0E, 0x10, 0x12, 0x13, 0x15, 0x16,
0x18, 0x19, 0x1A,
0x1C, 0x1D, 0x1F, 0x20, 0x21, 0x23, 0x24, 0x25, 0x27, 0x28, 0x29, 0x2A, 0x2C,
@@ -357,9 +357,9 @@ static int open_mve_file(demux_mve_t *this) {
if (_x_demux_read_header(this->input, header, WC3_HEADER_SIZE) != WC3_HEADER_SIZE)
return 0;
- if ((_X_BE_32(&header[0]) != FORM_TAG) ||
- (_X_BE_32(&header[8]) != MOVE_TAG) ||
- (_X_BE_32(&header[12]) != PC_TAG))
+ if ( !_x_is_fourcc(&header[0], "FORM") ||
+ !_x_is_fourcc(&header[8], "MOVE") ||
+ !_x_is_fourcc(&header[12], "_PC_") )
return 0;
/* file is qualified */
@@ -378,17 +378,21 @@ static int open_mve_file(demux_mve_t *this) {
this->number_of_shots = _X_LE_32(&preamble[0]);
/* allocate space for the shot offset index and set offsets to 0 */
- this->shot_offsets = xine_xmalloc(this->number_of_shots * sizeof(off_t));
+ this->shot_offsets = calloc(this->number_of_shots, sizeof(off_t));
this->current_shot = 0;
- for (i = 0; i < this->number_of_shots; i++)
- this->shot_offsets[i] = 0;
/* skip the SOND chunk */
this->input->seek(this->input, 12, SEEK_CUR);
/* load the palette chunks */
- this->palettes = xine_xmalloc(this->number_of_shots * PALETTE_SIZE *
+ this->palettes = calloc(this->number_of_shots, PALETTE_SIZE *
sizeof(palette_entry_t));
+
+ if (!this->shot_offsets || !this->palettes) {
+ free (this->shot_offsets);
+ return 0;
+ }
+
for (i = 0; i < this->number_of_shots; i++) {
/* make sure there was a valid palette chunk preamble */
if (this->input->read(this->input, preamble, PREAMBLE_SIZE) !=
@@ -398,8 +402,8 @@ static int open_mve_file(demux_mve_t *this) {
return 0;
}
- if ((_X_BE_32(&preamble[0]) != PALT_TAG) ||
- (_X_BE_32(&preamble[4]) != PALETTE_CHUNK_SIZE)) {
+ if ( !_x_is_fourcc(&preamble[0], "PALT") ||
+ (_X_BE_32(&preamble[4]) != PALETTE_CHUNK_SIZE)) {
xine_log(this->stream->xine, XINE_LOG_MSG,
_("demux_wc3movie: There was a problem while loading palette chunks\n"));
free (this->palettes);
@@ -460,8 +464,9 @@ static int open_mve_file(demux_mve_t *this) {
case BNAM_TAG:
/* load the name into the stream attributes */
- title = realloc (title, chunk_size);
- if (this->input->read(this->input, title, chunk_size) != chunk_size) {
+ free (title);
+ title = malloc (chunk_size);
+ if (!title || this->input->read(this->input, title, chunk_size) != chunk_size) {
free (title);
free (this->palettes);
free (this->shot_offsets);
@@ -667,7 +672,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
demux_mve_t *this;
- this = xine_xmalloc (sizeof (demux_mve_t));
+ this = calloc(1, sizeof(demux_mve_t));
this->stream = stream;
this->input = input;
@@ -741,7 +746,7 @@ static void class_dispose (demux_class_t *this_gen) {
void *demux_wc3movie_init_plugin (xine_t *xine, void *data) {
demux_mve_class_t *this;
- this = xine_xmalloc (sizeof (demux_mve_class_t));
+ this = calloc(1, sizeof(demux_mve_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_yuv4mpeg2.c b/src/demuxers/demux_yuv4mpeg2.c
index 9c5856710..2387fc7a7 100644
--- a/src/demuxers/demux_yuv4mpeg2.c
+++ b/src/demuxers/demux_yuv4mpeg2.c
@@ -197,21 +197,13 @@ static int open_yuv4mpeg2_file(demux_yuv4mpeg2_t *this) {
this->frame_pts_inc = (90000 * this->fps_d) / this->fps_n;
/* finally, look for the first frame */
- while ((header_ptr - header) < (Y4M_HEADER_BYTES - 4)) {
- if((header_ptr[0] == 'F') &&
- (header_ptr[1] == 'R') &&
- (header_ptr[2] == 'A') &&
- (header_ptr[3] == 'M') &&
- (header_ptr[4] == 'E')) {
- this->data_start = header_ptr - header;
- break;
- } else
- header_ptr++;
- }
-
+ char *data_start_ptr = memmem(header_ptr, Y4M_HEADER_BYTES, "FRAME", 5);
+
/* make sure the first frame was found */
- if(!this->data_start)
+ if ( !data_start_ptr )
return 0;
+
+ this->data_start = data_start_ptr - header;
/* compute size of all frames */
if (INPUT_IS_SEEKABLE(this->input)) {
@@ -228,29 +220,26 @@ static int open_yuv4mpeg2_file(demux_yuv4mpeg2_t *this) {
static int demux_yuv4mpeg2_send_chunk(demux_plugin_t *this_gen) {
demux_yuv4mpeg2_t *this = (demux_yuv4mpeg2_t *) this_gen;
- buf_element_t *buf = NULL;
- unsigned char preamble[Y4M_FRAME_SIGNATURE_SIZE];
- int bytes_remaining;
- off_t current_file_pos;
- int64_t pts;
-
/* validate that this is an actual frame boundary */
- if (this->input->read(this->input, preamble, Y4M_FRAME_SIGNATURE_SIZE) !=
- Y4M_FRAME_SIGNATURE_SIZE) {
- this->status = DEMUX_FINISHED;
- return this->status;
- }
- if (memcmp(preamble, Y4M_FRAME_SIGNATURE, Y4M_FRAME_SIGNATURE_SIZE) !=
- 0) {
- this->status = DEMUX_FINISHED;
- return this->status;
+ {
+ uint8_t preamble[Y4M_FRAME_SIGNATURE_SIZE];
+ if (this->input->read(this->input, preamble, Y4M_FRAME_SIGNATURE_SIZE) !=
+ Y4M_FRAME_SIGNATURE_SIZE) {
+ this->status = DEMUX_FINISHED;
+ return this->status;
+ }
+ if (memcmp(preamble, Y4M_FRAME_SIGNATURE, Y4M_FRAME_SIGNATURE_SIZE) !=
+ 0) {
+ this->status = DEMUX_FINISHED;
+ return this->status;
+ }
}
/* load and dispatch the raw frame */
- bytes_remaining = this->frame_size;
- current_file_pos =
+ int bytes_remaining = this->frame_size;
+ off_t current_file_pos =
this->input->get_current_pos(this->input) - this->data_start;
- pts = current_file_pos;
+ int64_t pts = current_file_pos;
pts /= (this->frame_size + Y4M_FRAME_SIGNATURE_SIZE);
pts *= this->frame_pts_inc;
@@ -261,17 +250,14 @@ static int demux_yuv4mpeg2_send_chunk(demux_plugin_t *this_gen) {
}
while(bytes_remaining) {
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+ buf_element_t *buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_VIDEO_I420;
if( this->data_size )
buf->extra_info->input_normpos = (int)((double) current_file_pos * 65535 / this->data_size);
buf->extra_info->input_time = pts / 90;
buf->pts = pts;
- if (bytes_remaining > buf->max_size)
- buf->size = buf->max_size;
- else
- buf->size = bytes_remaining;
+ buf->size = MIN(bytes_remaining, buf->max_size);
bytes_remaining -= buf->size;
if (this->input->read(this->input, buf->content, buf->size) !=
@@ -291,7 +277,6 @@ static int demux_yuv4mpeg2_send_chunk(demux_plugin_t *this_gen) {
static void demux_yuv4mpeg2_send_headers(demux_plugin_t *this_gen) {
demux_yuv4mpeg2_t *this = (demux_yuv4mpeg2_t *) this_gen;
- buf_element_t *buf;
this->video_fifo = this->stream->video_fifo;
this->audio_fifo = this->stream->audio_fifo;
@@ -310,7 +295,7 @@ static void demux_yuv4mpeg2_send_headers(demux_plugin_t *this_gen) {
_x_demux_control_start(this->stream);
/* send init info to decoders */
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+ buf_element_t *buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAMERATE|
BUF_FLAG_FRAME_END;
buf->decoder_info[0] = this->frame_pts_inc; /* initial video step */
@@ -400,10 +385,7 @@ static int demux_yuv4mpeg2_get_optional_data(demux_plugin_t *this_gen,
static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream,
input_plugin_t *input) {
-
- demux_yuv4mpeg2_t *this;
-
- this = xine_xmalloc (sizeof (demux_yuv4mpeg2_t));
+ demux_yuv4mpeg2_t *this = calloc(1, sizeof(demux_yuv4mpeg2_t));
this->stream = stream;
this->input = input;
@@ -422,10 +404,8 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
switch (stream->content_detection_method) {
case METHOD_BY_EXTENSION: {
- const char *extensions, *mrl;
-
- mrl = input->get_mrl (input);
- extensions = class_gen->get_extensions (class_gen);
+ const char *const mrl = input->get_mrl (input);
+ const char *const extensions = class_gen->get_extensions (class_gen);
if (!_x_demux_check_extension (mrl, extensions)) {
free (this);
@@ -477,7 +457,7 @@ static void class_dispose (demux_class_t *this_gen) {
static void *init_plugin (xine_t *xine, void *data) {
demux_yuv4mpeg2_class_t *this;
- this = xine_xmalloc (sizeof (demux_yuv4mpeg2_class_t));
+ this = calloc(1, sizeof(demux_yuv4mpeg2_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/demux_yuv_frames.c b/src/demuxers/demux_yuv_frames.c
index 774329c05..089207f58 100644
--- a/src/demuxers/demux_yuv_frames.c
+++ b/src/demuxers/demux_yuv_frames.c
@@ -70,8 +70,6 @@ static int demux_yuv_frames_get_status (demux_plugin_t *this_gen) {
}
static int switch_buf(demux_yuv_frames_t *this , buf_element_t *buf){
- int result = 0;
-
if (!buf)
return 0;
@@ -88,8 +86,7 @@ static int switch_buf(demux_yuv_frames_t *this , buf_element_t *buf){
case BUF_VIDEO_I420:
case BUF_VIDEO_YUY2:
this->video_fifo->put(this->video_fifo, buf);
- result = 1; /* 1, we still should read audio */
- break;
+ return 1; /* 1, we still should read audio */
case BUF_AUDIO_LPCM_LE:
if (!_x_stream_info_get(this->stream, XINE_STREAM_INFO_HAS_VIDEO))
_x_demux_control_newpts(this->stream, buf->pts, 0);
@@ -100,7 +97,7 @@ static int switch_buf(demux_yuv_frames_t *this , buf_element_t *buf){
buf->free_buffer(buf);
}
- return result;
+ return 0;
}
static int demux_yuv_frames_send_chunk (demux_plugin_t *this_gen){
@@ -129,13 +126,19 @@ static void demux_yuv_frames_send_headers (demux_plugin_t *this_gen){
if(_x_stream_info_get(this->stream, XINE_STREAM_INFO_HAS_AUDIO)) {
buf = this->input->read_block(this->input, this->audio_fifo, 0);
- this->audio_fifo->put(this->audio_fifo, buf);
+ if (buf)
+ this->audio_fifo->put(this->audio_fifo, buf);
+ else
+ this->status = DEMUX_FINISHED;
}
if(_x_stream_info_get(this->stream, XINE_STREAM_INFO_HAS_VIDEO)) {
buf = this->input->read_block(this->input, this->video_fifo, 0);
- this->video_fifo->put(this->video_fifo, buf);
+ if (buf)
+ this->video_fifo->put(this->video_fifo, buf);
+ else
+ this->status = DEMUX_FINISHED;
}
this->status = DEMUX_OK;
@@ -203,7 +206,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen,
* if we reach this point, the input has been accepted.
*/
- this = xine_xmalloc (sizeof (demux_yuv_frames_t));
+ this = calloc(1, sizeof(demux_yuv_frames_t));
this->stream = stream;
this->input = input;
@@ -253,7 +256,7 @@ static void class_dispose (demux_class_t *this_gen) {
static void *init_class (xine_t *xine, void *data) {
demux_yuv_frames_class_t *this;
- this = xine_xmalloc (sizeof (demux_yuv_frames_class_t));
+ this = calloc(1, sizeof(demux_yuv_frames_class_t));
this->demux_class.open_plugin = open_plugin;
this->demux_class.get_description = get_description;
diff --git a/src/demuxers/ebml.c b/src/demuxers/ebml.c
index ac44aecd7..4ce8a549d 100644
--- a/src/demuxers/ebml.c
+++ b/src/demuxers/ebml.c
@@ -318,6 +318,22 @@ int ebml_read_utf8 (ebml_parser_t *ebml, ebml_elem_t *elem, char *str) {
return ebml_read_ascii (ebml, elem, str);
}
+char *ebml_alloc_read_ascii (ebml_parser_t *ebml, ebml_elem_t *elem)
+{
+ char *text;
+ if (elem->len >= 4096)
+ return NULL;
+ text = malloc(elem->len + 1);
+ if (text)
+ {
+ text[elem->len] = '\0';
+ if (ebml_read_ascii (ebml, elem, text))
+ return text;
+ free (text);
+ }
+ return NULL;
+}
+
int ebml_read_date (ebml_parser_t *ebml, ebml_elem_t *elem, int64_t *date) {
return ebml_read_sint (ebml, elem, date);
}
@@ -423,10 +439,8 @@ int ebml_check_header(ebml_parser_t *ebml) {
}
case EBML_ID_DOCTYPE: {
- char *text = malloc(elem.len + 1);
-
- text[elem.len] = '\0';
- if (!ebml_read_ascii (ebml, &elem, text))
+ char *text = ebml_alloc_read_ascii (ebml, &elem);
+ if (!text)
return 0;
lprintf("doctype: %s\n", text);
diff --git a/src/demuxers/ebml.h b/src/demuxers/ebml.h
index 35078c502..9aa471c0b 100644
--- a/src/demuxers/ebml.h
+++ b/src/demuxers/ebml.h
@@ -65,7 +65,7 @@ typedef struct ebml_parser_s {
} ebml_parser_t;
-ebml_parser_t *new_ebml_parser (xine_t *xine, input_plugin_t *input);
+ebml_parser_t *new_ebml_parser (xine_t *xine, input_plugin_t *input) XINE_MALLOC;
void dispose_ebml_parser (ebml_parser_t *ebml);
@@ -91,6 +91,8 @@ int ebml_read_ascii(ebml_parser_t *ebml, ebml_elem_t *elem, char *str);
int ebml_read_utf8(ebml_parser_t *ebml, ebml_elem_t *elem, char *str);
+char *ebml_alloc_read_ascii(ebml_parser_t *ebml, ebml_elem_t *elem);
+
int ebml_read_date(ebml_parser_t *ebml, ebml_elem_t *elem, int64_t *date);
int ebml_read_master(ebml_parser_t *ebml, ebml_elem_t *elem);
diff --git a/src/demuxers/id3.c b/src/demuxers/id3.c
index 6b36cc666..39055a852 100644
--- a/src/demuxers/id3.c
+++ b/src/demuxers/id3.c
@@ -241,7 +241,7 @@ static int id3v2_parse_header(input_plugin_t *input, uint8_t *mp3_frame_header,
lprintf("tag: ID3 v2.%d.%d\n", mp3_frame_header[3], tag_header->revision);
lprintf("flags: %d\n", tag_header->flags);
- lprintf("size: %d\n", tag_header->size);
+ lprintf("size: %zu\n", tag_header->size);
return 1;
} else {
return 0;
@@ -261,7 +261,7 @@ static int id3v22_parse_frame_header(input_plugin_t *input,
frame_header->size = _X_BE_24_synchsafe(&buf[3]);
- lprintf("frame: %c%c%c: size: %d\n", buf[0], buf[1], buf[2],
+ lprintf("frame: %c%c%c: size: %zu\n", buf[0], buf[1], buf[2],
frame_header->size);
return 1;
@@ -275,8 +275,11 @@ static int id3v22_interp_frame(input_plugin_t *input,
id3v22_frame_header_t *frame_header) {
char *buf;
int enc;
+ const size_t bufsize = frame_header->size + 2;
+ if ( bufsize < 3 ) /* frames has to be _at least_ 1 byte */
+ return 0;
- buf = malloc(frame_header->size + 1);
+ buf = malloc(bufsize);
if (buf == NULL) {
lprintf("malloc error");
return 0;
@@ -284,6 +287,7 @@ static int id3v22_interp_frame(input_plugin_t *input,
if (input->read (input, buf, frame_header->size) == frame_header->size) {
buf[frame_header->size] = 0;
+ buf[frame_header->size + 1] = 0;
enc = buf[0];
if( enc >= ID3_ENCODING_COUNT )
enc = 0;
@@ -337,9 +341,9 @@ static int id3v22_interp_frame(input_plugin_t *input,
}
-int id3v22_parse_tag(input_plugin_t *input,
- xine_stream_t *stream,
- int8_t *mp3_frame_header) {
+static int id3v22_parse_tag(input_plugin_t *input,
+ xine_stream_t *stream,
+ int8_t *mp3_frame_header) {
id3v2_header_t tag_header;
id3v22_frame_header_t tag_frame_header;
int pos = 0;
@@ -349,21 +353,21 @@ int id3v22_parse_tag(input_plugin_t *input,
if (tag_header.flags & ID3V22_ZERO_FLAG) {
/* invalid flags */
xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
- "id3: invalid header flags (%02x)\n", tag_header.flags);
+ LOG_MODULE ": invalid header flags (%02x)\n", tag_header.flags);
input->seek (input, tag_header.size - pos, SEEK_CUR);
return 0;
}
if (tag_header.flags & ID3V22_COMPRESS_FLAG) {
/* compressed tag: not supported */
xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
- "id3: compressed tags are not supported\n");
+ LOG_MODULE ": compressed tags are not supported\n");
input->seek (input, tag_header.size - pos, SEEK_CUR);
return 0;
}
if (tag_header.flags & ID3V22_UNSYNCH_FLAG) {
/* unsynchronized tag: not supported */
xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
- "id3: unsynchronized tags are not supported\n");
+ LOG_MODULE ": unsynchronized tags are not supported\n");
input->seek (input, tag_header.size - pos, SEEK_CUR);
return 0;
}
@@ -371,15 +375,15 @@ int id3v22_parse_tag(input_plugin_t *input,
while ((pos + ID3V22_FRAME_HEADER_SIZE) <= tag_header.size) {
if (id3v22_parse_frame_header(input, &tag_frame_header)) {
pos += ID3V22_FRAME_HEADER_SIZE;
- if (tag_frame_header.id && tag_frame_header.size) {
+ if (tag_frame_header.id) {
if ((pos + tag_frame_header.size) <= tag_header.size) {
if (!id3v22_interp_frame(input, stream, &tag_frame_header)) {
xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
- "id3: invalid frame content\n");
+ LOG_MODULE ": invalid frame content\n");
}
} else {
xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
- "id3: invalid frame header\n");
+ LOG_MODULE ": invalid frame header\n");
input->seek (input, tag_header.size - pos, SEEK_CUR);
return 1;
}
@@ -391,13 +395,13 @@ int id3v22_parse_tag(input_plugin_t *input,
}
} else {
xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
- "id3: id3v2_parse_frame_header problem\n");
+ LOG_MODULE ": id3v2_parse_frame_header problem\n");
return 0;
}
}
return 1;
} else {
- xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "id3: id3v2_parse_header problem\n");
+ xprintf(stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": id3v2_parse_header problem\n");
return 0;
}
}
@@ -415,7 +419,7 @@ static int id3v23_parse_frame_header(input_plugin_t *input,
frame_header->size = _X_BE_32(&buf[4]);
frame_header->flags = _X_BE_16(buf + 8);
- lprintf("frame: %c%c%c%c, size: %d, flags: %X\n", buf[0], buf[1], buf[2], buf[3],
+ lprintf("frame: %c%c%c%c, size: %zu, flags: %X\n", buf[0], buf[1], buf[2], buf[3],
frame_header->size, frame_header->flags);
return 1;
@@ -451,11 +455,11 @@ static int id3v23_parse_frame_ext_header(input_plugin_t *input,
}
} else {
- lprintf("invalid ext header size: %d\n", frame_ext_header->size);
+ lprintf("invalid ext header size: %zu\n", frame_ext_header->size);
return 0;
}
- lprintf("ext header: size: %d, flags: %X, padding_size: %d, crc: %d\n",
+ lprintf("ext header: size: %zu, flags: %X, padding_size: %d, crc: %d\n",
frame_ext_header->size, frame_ext_header->flags,
frame_ext_header->padding_size, frame_ext_header->crc);
return 1;
@@ -469,8 +473,11 @@ static int id3v23_interp_frame(input_plugin_t *input,
id3v23_frame_header_t *frame_header) {
char *buf;
int enc;
-
- buf = malloc(frame_header->size + 1);
+ const size_t bufsize = frame_header->size + 2;
+ if ( bufsize < 3 ) /* frames has to be _at least_ 1 byte */
+ return 0;
+
+ buf = malloc(bufsize);
if (buf == NULL) {
lprintf("malloc error");
return 0;
@@ -478,6 +485,7 @@ static int id3v23_interp_frame(input_plugin_t *input,
if (input->read (input, buf, frame_header->size) == frame_header->size) {
buf[frame_header->size] = 0;
+ buf[frame_header->size + 1] = 0;
enc = buf[0];
if( enc >= ID3_ENCODING_COUNT )
enc = 0;
@@ -530,9 +538,9 @@ static int id3v23_interp_frame(input_plugin_t *input,
}
}
-int id3v23_parse_tag(input_plugin_t *input,
- xine_stream_t *stream,
- int8_t *mp3_frame_header) {
+static int id3v23_parse_tag(input_plugin_t *input,
+ xine_stream_t *stream,
+ int8_t *mp3_frame_header) {
id3v2_header_t tag_header;
id3v23_frame_header_t tag_frame_header;
id3v23_frame_ext_header_t tag_frame_ext_header;
@@ -543,14 +551,14 @@ int id3v23_parse_tag(input_plugin_t *input,
if (tag_header.flags & ID3V23_ZERO_FLAG) {
/* invalid flags */
xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
- "id3: invalid header flags (%02x)\n", tag_header.flags);
+ LOG_MODULE ": invalid header flags (%02x)\n", tag_header.flags);
input->seek (input, tag_header.size - pos, SEEK_CUR);
return 0;
}
if (tag_header.flags & ID3V23_UNSYNCH_FLAG) {
/* unsynchronized tag: not supported */
xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
- "id3: unsynchronized tags are not supported\n");
+ LOG_MODULE ": unsynchronized tags are not supported\n");
input->seek (input, tag_header.size - pos, SEEK_CUR);
return 0;
}
@@ -559,38 +567,40 @@ int id3v23_parse_tag(input_plugin_t *input,
if (!id3v23_parse_frame_ext_header(input, &tag_frame_ext_header)) {
return 0;
}
+ pos += tag_frame_ext_header.size;
}
/* frame parsing */
while ((pos + ID3V23_FRAME_HEADER_SIZE) <= tag_header.size) {
if (id3v23_parse_frame_header(input, &tag_frame_header)) {
pos += ID3V23_FRAME_HEADER_SIZE;
- if (tag_frame_header.id && tag_frame_header.size) {
+ if (tag_frame_header.id) {
if ((pos + tag_frame_header.size) <= tag_header.size) {
if (!id3v23_interp_frame(input, stream, &tag_frame_header)) {
xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
- "id3: invalid frame content\n");
+ LOG_MODULE ": invalid frame content\n");
}
} else {
xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
- "id3: invalid frame header\n");
+ LOG_MODULE ": invalid frame header\n");
input->seek (input, tag_header.size - pos, SEEK_CUR);
return 1;
}
pos += tag_frame_header.size;
} else {
/* end of frames, the rest is padding */
- input->seek (input, tag_header.size - pos, SEEK_CUR);
+ lprintf("skipping padding %zu bytes\n", tag_header.size - pos);
+ input->seek (input, tag_header.size - pos, SEEK_CUR);
return 1;
}
} else {
xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
- "id3: id3v2_parse_frame_header problem\n");
+ LOG_MODULE ": id3v2_parse_frame_header problem\n");
return 0;
}
}
return 1;
} else {
- xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "id3v23: id3v2_parse_header problem\n");
+ xprintf(stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": id3v2_parse_header problem\n");
return 0;
}
}
@@ -624,7 +634,7 @@ static int id3v24_parse_frame_header(input_plugin_t *input,
frame_header->size = _X_BE_32_synchsafe(&buf[4]);
frame_header->flags = _X_BE_16(&buf[8]);
- lprintf("frame: %c%c%c%c, size: %d, flags: %X\n", buf[0], buf[1], buf[2], buf[3],
+ lprintf("frame: %c%c%c%c, size: %zu, flags: %X\n", buf[0], buf[1], buf[2], buf[3],
frame_header->size, frame_header->flags);
return 1;
@@ -704,7 +714,7 @@ static int id3v24_parse_ext_header(input_plugin_t *input,
} else {
return 0;
}
- lprintf("ext header: size: %d, flags: %X, crc: %d, restrictions: %8X\n",
+ lprintf("ext header: size: %zu, flags: %X, crc: %d, restrictions: %8X\n",
frame_ext_header->size, frame_ext_header->flags,
frame_ext_header->crc, frame_ext_header->restrictions);
return 1;
@@ -718,8 +728,11 @@ static int id3v24_interp_frame(input_plugin_t *input,
id3v24_frame_header_t *frame_header) {
char *buf;
int enc;
-
- buf = malloc(frame_header->size + 1);
+ const size_t bufsize = frame_header->size + 2;
+ if ( bufsize < 3 ) /* frames has to be _at least_ 1 byte */
+ return 0;
+
+ buf = malloc(bufsize);
if (buf == NULL) {
lprintf("malloc error");
return 0;
@@ -727,6 +740,7 @@ static int id3v24_interp_frame(input_plugin_t *input,
if (input->read (input, buf, frame_header->size) == frame_header->size) {
buf[frame_header->size] = 0;
+ buf[frame_header->size + 1] = 0;
enc = buf[0];
if( enc >= ID3_ENCODING_COUNT )
enc = 0;
@@ -757,6 +771,7 @@ static int id3v24_interp_frame(input_plugin_t *input,
break;
case ( FOURCC_TAG('T', 'Y', 'E', 'R') ):
+ case ( FOURCC_TAG('T', 'D', 'R', 'C') ):
_x_meta_info_set_generic(stream, XINE_META_INFO_YEAR, buf + 1, id3_encoding[enc]);
break;
@@ -781,9 +796,9 @@ static int id3v24_interp_frame(input_plugin_t *input,
}
}
-int id3v24_parse_tag(input_plugin_t *input,
- xine_stream_t *stream,
- int8_t *mp3_frame_header) {
+static int id3v24_parse_tag(input_plugin_t *input,
+ xine_stream_t *stream,
+ int8_t *mp3_frame_header) {
id3v2_header_t tag_header;
id3v24_frame_header_t tag_frame_header;
id3v24_frame_ext_header_t tag_frame_ext_header;
@@ -794,7 +809,7 @@ int id3v24_parse_tag(input_plugin_t *input,
if (tag_header.flags & ID3V24_ZERO_FLAG) {
/* invalid flags */
xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
- "id3: invalid header flags (%02x)\n", tag_header.flags);
+ LOG_MODULE ": invalid header flags (%02x)\n", tag_header.flags);
input->seek (input, tag_header.size - pos, SEEK_CUR);
return 0;
}
@@ -809,20 +824,21 @@ int id3v24_parse_tag(input_plugin_t *input,
if (!id3v24_parse_ext_header(input, &tag_frame_ext_header)) {
return 0;
}
+ pos += tag_frame_ext_header.size;
}
/* frame parsing */
while ((pos + ID3V24_FRAME_HEADER_SIZE) <= tag_header.size) {
if (id3v24_parse_frame_header(input, &tag_frame_header)) {
pos += ID3V24_FRAME_HEADER_SIZE;
- if (tag_frame_header.id && tag_frame_header.size) {
+ if (tag_frame_header.id) {
if ((pos + tag_frame_header.size) <= tag_header.size) {
if (!id3v24_interp_frame(input, stream, &tag_frame_header)) {
xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
- "id3: invalid frame content\n");
+ LOG_MODULE ": invalid frame content\n");
}
} else {
xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
- "id3: invalid frame header\n");
+ LOG_MODULE ": invalid frame header\n");
input->seek (input, tag_header.size - pos, SEEK_CUR);
return 1;
}
@@ -834,7 +850,7 @@ int id3v24_parse_tag(input_plugin_t *input,
}
} else {
xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
- "id3: id3v2_parse_frame_header problem\n");
+ LOG_MODULE ": id3v2_parse_frame_header problem\n");
return 0;
}
}
@@ -844,7 +860,7 @@ int id3v24_parse_tag(input_plugin_t *input,
}
return 1;
} else {
- xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "id3v23: id3v2_parse_header problem\n");
+ xprintf(stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": id3v2_parse_header problem\n");
return 0;
}
}
@@ -858,22 +874,22 @@ int id3v2_parse_tag(input_plugin_t *input,
switch(mp3_frame_header[3]) {
case 2:
- xprintf(stream->xine, XINE_VERBOSITY_LOG, "ID3V2.2 tag\n");
+ xprintf(stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": ID3V2.2 tag\n");
result = id3v22_parse_tag(input, stream, mp3_frame_header);
break;
case 3:
- xprintf(stream->xine, XINE_VERBOSITY_LOG, "ID3V2.3 tag\n");
+ xprintf(stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": ID3V2.3 tag\n");
result = id3v23_parse_tag(input, stream, mp3_frame_header);
break;
case 4:
- xprintf(stream->xine, XINE_VERBOSITY_LOG, "ID3V2.4 tag\n");
+ xprintf(stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": ID3V2.4 tag\n");
result = id3v24_parse_tag(input, stream, mp3_frame_header);
break;
default:
- xprintf(stream->xine, XINE_VERBOSITY_LOG, "Unknown ID3v2 version: 0x%02x.\n", mp3_frame_header[3]);
+ xprintf(stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": Unknown ID3v2 version: 0x%02x.\n", mp3_frame_header[3]);
}
return result;
diff --git a/src/demuxers/id3.h b/src/demuxers/id3.h
index b4ea4b6be..41babe2b4 100644
--- a/src/demuxers/id3.h
+++ b/src/demuxers/id3.h
@@ -103,22 +103,22 @@ typedef struct {
uint32_t id;
uint8_t revision;
uint8_t flags;
- uint32_t size;
+ size_t size;
} id3v2_header_t;
typedef struct {
uint32_t id;
- uint32_t size;
+ size_t size;
} id3v22_frame_header_t;
typedef struct {
uint32_t id;
- uint32_t size;
+ size_t size;
uint16_t flags;
} id3v23_frame_header_t;
typedef struct {
- uint32_t size;
+ size_t size;
uint16_t flags;
uint32_t padding_size;
uint32_t crc;
@@ -128,12 +128,12 @@ typedef id3v2_header_t id3v24_footer_t;
typedef struct {
uint32_t id;
- uint32_t size;
+ size_t size;
uint16_t flags;
} id3v24_frame_header_t;
typedef struct {
- uint32_t size;
+ size_t size;
uint8_t flags;
uint32_t crc;
uint8_t restrictions;
@@ -151,19 +151,16 @@ typedef struct {
int id3v1_parse_tag (input_plugin_t *input, xine_stream_t *stream);
-int id3v22_parse_tag(input_plugin_t *input,
- xine_stream_t *stream,
- int8_t *mp3_frame_header);
-
-int id3v23_parse_tag(input_plugin_t *input,
- xine_stream_t *stream,
- int8_t *mp3_frame_header);
-
-int id3v24_parse_tag(input_plugin_t *input,
- xine_stream_t *stream,
- int8_t *mp3_frame_header);
-
-/* Generic function that switch between the three above */
+/**
+ * @brief Generic function for ID3v2 tags parsing.
+ * @param input Pointer to the input plugin used by the demuxer, used
+ * to access the tag's data.
+ * @param stream Pointer to the xine stream currently being read.
+ * @param mp3_frame_header Header of the MP3 frame carrying the tag.
+ *
+ * @note This function will take care of calling the proper function for
+ * parsing ID3v2.2, ID3v2.3 or ID3v2.4 tags.
+ */
int id3v2_parse_tag(input_plugin_t *input,
xine_stream_t *stream,
int8_t *mp3_frame_header);
diff --git a/src/demuxers/iff.h b/src/demuxers/iff.h
index 94830f69c..8ac24a697 100644
--- a/src/demuxers/iff.h
+++ b/src/demuxers/iff.h
@@ -27,8 +27,8 @@
#define IFFP_IFF_H
#define IFF_OKAY 0L
-#define CLIENT_ERROR 1L
-#define NOFILE 5L
+#define IFF_CLIENT_ERROR 1L
+#define IFF_NOFILE 5L
#define FOURCC_CHUNK BE_FOURCC
#define IFF_16SV_CHUNK FOURCC_CHUNK('1', '6', 'S', 'V')
diff --git a/src/demuxers/matroska.h b/src/demuxers/matroska.h
index 6806c207d..df6e8ad1b 100644
--- a/src/demuxers/matroska.h
+++ b/src/demuxers/matroska.h
@@ -62,6 +62,7 @@
#define MATROSKA_ID_CL_BLOCKGROUP 0xA0
#define MATROSKA_ID_CL_BLOCK 0xA1
#define MATROSKA_ID_CL_BLOCKVIRTUAL 0xA2
+#define MATROSKA_ID_CL_SIMPLEBLOCK 0xA3
#define MATROSKA_ID_CL_BLOCKADDITIONS 0x75A1
#define MATROSKA_ID_CL_BLOCKMORE 0xA6
#define MATROSKA_ID_CL_BLOCKADDID 0xEE
@@ -235,7 +236,7 @@ struct matroska_track_s {
void (*handle_content) (demux_plugin_t *this_gen,
matroska_track_t *track,
int decoder_flags,
- uint8_t *data, int data_len,
+ uint8_t *data, size_t data_len,
int64_t data_pts, int data_duration,
int input_normpos, int input_time);
};
diff --git a/src/demuxers/real_common.h b/src/demuxers/real_common.h
new file mode 100644
index 000000000..4945a65ff
--- /dev/null
+++ b/src/demuxers/real_common.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2008 the xine project
+ *
+ * This file is part of xine, a free video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ */
+
+static inline void demux_real_sipro_swap (char buffer[], int bs)
+{
+ /* bs = nybbles per subpacket */
+ static const unsigned char sipr_swaps[38][2] = {
+ {0, 63}, {1, 22}, {2, 44}, {3, 90}, {5, 81}, {7, 31}, {8, 86}, {9, 58},
+ {10, 36}, {12, 68}, {13, 39}, {14, 73}, {15, 53}, {16, 69}, {17, 57},
+ {19, 88}, {20, 34}, {21, 71}, {24, 46}, {25, 94}, {26, 54}, {28, 75},
+ {29, 50}, {32, 70}, {33, 92}, {35, 74}, {38, 85}, {40, 56}, {42, 87},
+ {43, 65}, {45, 59}, {48, 79}, {49, 93}, {51, 89}, {55, 95}, {61, 76},
+ {67, 83}, {77, 80}
+ };
+ int n;
+
+ for (n = 0; n < 38; ++n)
+ {
+ int j;
+ int i = bs * sipr_swaps[n][0];
+ int o = bs * sipr_swaps[n][1];
+ /* swap nibbles of block 'i' with 'o' TODO: optimize */
+ for (j = 0; j < bs; ++j)
+ {
+ int x = (i & 1) ? (buffer[i >> 1] >> 4) : (buffer[i >> 1] & 0x0F);
+ int y = (o & 1) ? (buffer[o >> 1] >> 4) : (buffer[o >> 1] & 0x0F);
+ if (o & 1)
+ buffer[o >> 1] = (buffer[o >> 1] & 0x0F) | (x << 4);
+ else
+ buffer[o >> 1] = (buffer[o >> 1] & 0xF0) | x;
+ if (i & 1)
+ buffer[i >> 1] = (buffer[i >> 1] & 0x0F) | (y << 4);
+ else
+ buffer[i >> 1] = (buffer[i >> 1] & 0xF0) | y;
+ ++i;
+ ++o;
+ }
+ }
+}
diff --git a/src/dxr3/Makefile.am b/src/dxr3/Makefile.am
index f1a61ce12..3c2cbafbc 100644
--- a/src/dxr3/Makefile.am
+++ b/src/dxr3/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
AM_CFLAGS = $(X_CFLAGS) $(LIBFAME_CFLAGS)
diff --git a/src/dxr3/dxr3_decode_spu.c b/src/dxr3/dxr3_decode_spu.c
index 139939d8e..82c8f8da0 100644
--- a/src/dxr3/dxr3_decode_spu.c
+++ b/src/dxr3/dxr3_decode_spu.c
@@ -17,6 +17,10 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
/* dxr3 spu decoder plugin.
* Accepts the spu data from xine and sends it directly to the
@@ -198,7 +202,7 @@ static void *dxr3_spudec_init_plugin(xine_t *xine, void* data)
{
dxr3_spudec_class_t *this;
- this = (dxr3_spudec_class_t *)xine_xmalloc(sizeof(dxr3_spudec_class_t));
+ this = calloc(1, sizeof(dxr3_spudec_class_t));
if (!this) return NULL;
this->spu_decoder_class.open_plugin = dxr3_spudec_open_plugin;
@@ -221,7 +225,7 @@ static spu_decoder_t *dxr3_spudec_open_plugin(spu_decoder_class_t *class_gen, xi
if (class->instance) return NULL;
if (!dxr3_present(stream)) return NULL;
- this = (dxr3_spudec_t *)xine_xmalloc(sizeof(dxr3_spudec_t));
+ this = calloc(1, sizeof(dxr3_spudec_t));
if (!this) return NULL;
this->spu_decoder.decode_data = dxr3_spudec_decode_data;
@@ -374,7 +378,7 @@ static void dxr3_spudec_decode_data(spu_decoder_t *this_gen, buf_element_t *buf)
printf("dxr3_decode_spu: DEBUG: allocating new PCI node for hli_s_ptm %d\n", pci.hli.hl_gi.hli_s_ptm);
/* append PCI at the end of the list */
while (node->next) node = node->next;
- node->next = (pci_node_t *)xine_xmalloc(sizeof(pci_node_t));
+ node->next = calloc(1, sizeof(pci_node_t));
node->next->vpts = this->stream->metronom->got_spu_packet(this->stream->metronom, pci.hli.hl_gi.hli_s_ptm);
node->next->next = NULL;
xine_fast_memcpy(&node->next->pci, &pci, sizeof(pci_t));
diff --git a/src/dxr3/dxr3_decode_video.c b/src/dxr3/dxr3_decode_video.c
index 3f1c273ff..e68ba2b5c 100644
--- a/src/dxr3/dxr3_decode_video.c
+++ b/src/dxr3/dxr3_decode_video.c
@@ -17,6 +17,10 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
/* dxr3 video decoder plugin.
* Accepts the video data from xine and sends it directly to the
@@ -193,7 +197,7 @@ static void *dxr3_init_plugin(xine_t *xine, void *data)
{
dxr3_decoder_class_t *this;
- this = (dxr3_decoder_class_t *)xine_xmalloc(sizeof (dxr3_decoder_class_t));
+ this = calloc(1, sizeof (dxr3_decoder_class_t));
if (!this) return NULL;
this->video_decoder_class.open_plugin = dxr3_open_plugin;
@@ -220,7 +224,7 @@ static video_decoder_t *dxr3_open_plugin(video_decoder_class_t *class_gen, xine_
if (class->instance) return NULL;
if (!dxr3_present(stream)) return NULL;
- this = (dxr3_decoder_t *)xine_xmalloc(sizeof (dxr3_decoder_t));
+ this = calloc(1, sizeof (dxr3_decoder_t));
if (!this) return NULL;
cfg = stream->xine->config;
diff --git a/src/dxr3/dxr3_mpeg_encoders.c b/src/dxr3/dxr3_mpeg_encoders.c
index 0c59b0b93..0077a465b 100644
--- a/src/dxr3/dxr3_mpeg_encoders.c
+++ b/src/dxr3/dxr3_mpeg_encoders.c
@@ -124,7 +124,7 @@ int dxr3_rte_init(dxr3_driver_t *drv)
return 0;
}
- this = xine_xmalloc(sizeof(rte_data_t));
+ this = calloc(1, sizeof(rte_data_t));
if (!this) return 0;
this->encoder_data.type = ENC_RTE;
@@ -316,7 +316,7 @@ int dxr3_fame_init(dxr3_driver_t *drv)
{
fame_data_t *this;
- this = xine_xmalloc(sizeof(fame_data_t));
+ this = calloc(1, sizeof(fame_data_t));
if (!this) return 0;
this->encoder_data.type = ENC_FAME;
diff --git a/src/dxr3/dxr3_scr.c b/src/dxr3/dxr3_scr.c
index 8fb049656..c95ab00a7 100644
--- a/src/dxr3/dxr3_scr.c
+++ b/src/dxr3/dxr3_scr.c
@@ -70,7 +70,7 @@ dxr3_scr_t *dxr3_scr_init(xine_t *xine)
int devnum;
char tmpstr[128];
- this = (dxr3_scr_t *)xine_xmalloc(sizeof(dxr3_scr_t));
+ this = calloc(1, sizeof(dxr3_scr_t));
devnum = xine->config->register_num(xine->config,
CONF_KEY, 0, CONF_NAME, CONF_HELP, 10, NULL, NULL);
diff --git a/src/dxr3/video_out_dxr3.c b/src/dxr3/video_out_dxr3.c
index c51354157..189824183 100644
--- a/src/dxr3/video_out_dxr3.c
+++ b/src/dxr3/video_out_dxr3.c
@@ -21,7 +21,7 @@
/* mpeg1 encoding video out plugin for the dxr3.
*
* modifications to the original dxr3 video out plugin by
- * Mike Lampard <mike at web2u.com.au>
+ * Mike Lampard <mlampard at users.sourceforge.net>
* this first standalone version by
* Harm van der Heijden <hrm at users.sourceforge.net>
*/
@@ -169,7 +169,7 @@ static dxr3_driver_class_t *dxr3_vo_init_plugin(xine_t *xine, void *visual_gen)
{
dxr3_driver_class_t *this;
- this = (dxr3_driver_class_t *)xine_xmalloc(sizeof(dxr3_driver_class_t));
+ this = calloc(1, sizeof(dxr3_driver_class_t));
if (!this) return NULL;
this->devnum = xine->config->register_num(xine->config,
@@ -232,7 +232,7 @@ static vo_driver_t *dxr3_vo_open_plugin(video_driver_class_t *class_gen, const v
if (class->instance) return NULL;
- this = (dxr3_driver_t *)xine_xmalloc(sizeof(dxr3_driver_t));
+ this = calloc(1, sizeof(dxr3_driver_t));
if (!this) return NULL;
this->vo_driver.get_capabilities = dxr3_get_capabilities;
@@ -536,7 +536,7 @@ static vo_frame_t *dxr3_alloc_frame(vo_driver_t *this_gen)
dxr3_frame_t *frame;
dxr3_driver_t *this = (dxr3_driver_t *)this_gen;
- frame = (dxr3_frame_t *)xine_xmalloc(sizeof(dxr3_frame_t));
+ frame = calloc(1, sizeof(dxr3_frame_t));
pthread_mutex_init(&frame->vo_frame.mutex, NULL);
@@ -1334,7 +1334,7 @@ static int lookup_parameter(struct lut_entry *lut, char *name,
static int dxr3_overlay_read_state(dxr3_overlay_t *this)
{
char *loc;
- char fname[256], tmp[128], line[256];
+ char *fname, line[256];
FILE *fp;
struct lut_entry lut[] = {
{"xoffset", TYPE_INT, &this->xoffset},
@@ -1359,18 +1359,16 @@ static int dxr3_overlay_read_state(dxr3_overlay_t *this)
* (used by .overlay/res file) */
setlocale(LC_NUMERIC, "C");
- snprintf(tmp, sizeof(tmp), "/res_%dx%dx%d",
+ asprintf(&fname, "%s/.overlay/res_%dx%dx%d", getenv("HOME"),
this->screen_xres, this->screen_yres, this->screen_depth);
- strncpy(fname, getenv("HOME"), sizeof(fname) - strlen(tmp) - sizeof("/.overlay"));
- fname[sizeof(fname) - strlen(tmp) - sizeof("/.overlay")] = '\0';
- strcat(fname, "/.overlay");
- strcat(fname, tmp);
llprintf(LOG_OVR, "attempting to open %s\n", fname);
if (!(fp = fopen(fname, "r"))) {
xprintf(this->xine, XINE_VERBOSITY_LOG,
_("video_out_dxr3: ERROR Reading overlay init file. Run autocal!\n"));
+ free(fname);
return -1;
}
+ free(fname);
while (!feof(fp)) {
if (!fgets(line, 256, fp))
diff --git a/src/input/Makefile.am b/src/input/Makefile.am
index 81dd62eca..8e9c9385d 100644
--- a/src/input/Makefile.am
+++ b/src/input/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
EXTRA_DIST = input_dvd.c input_vcd.c input_gnome_vfs.c input_rtp.c
diff --git a/src/input/http_helper.c b/src/input/http_helper.c
index 4883763b0..279d3ff05 100644
--- a/src/input/http_helper.c
+++ b/src/input/http_helper.c
@@ -240,8 +240,7 @@ char *_x_canonicalise_url (const char *base, const char *url) {
++cut;
}
base_length = cut ? (size_t)(cut - base) : strlen (base);
- ret = malloc (base_length + strlen (url) + 1);
- sprintf (ret, "%.*s%s", (int)base_length, base, url);
+ asprintf (&ret, "%.*s%s", (int)base_length, base, url);
return ret;
}
diff --git a/src/input/input_cdda.c b/src/input/input_cdda.c
index fd4dd1fa9..d982909eb 100644
--- a/src/input/input_cdda.c
+++ b/src/input/input_cdda.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2005 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -44,6 +44,7 @@
# include <sys/ioctl.h>
#else
/* for WIN32 */
+# include <windef.h>
# include <winioctl.h>
#endif
@@ -70,6 +71,8 @@
#define DEFAULT_CDDA_DEVICE "/vol/dev/aliases/cdrom0"
#elif defined(WIN32)
#define DEFAULT_CDDA_DEVICE "d:\\"
+#elif defined(__OpenBSD__)
+#define DEFAULT_CDDA_DEVICE "/dev/rcd0c"
#else
#define DEFAULT_CDDA_DEVICE "/dev/cdrom"
#endif
@@ -135,7 +138,7 @@ typedef struct {
char *disc_category;
int fd;
- unsigned long disc_id;
+ uint32_t disc_id;
int disc_length;
trackinfo_t *track;
@@ -370,7 +373,7 @@ static cdrom_toc * init_cdrom_toc(void) {
cdrom_toc *toc;
- toc = (cdrom_toc *) xine_xmalloc(sizeof (cdrom_toc));
+ toc = calloc(1, sizeof (cdrom_toc));
toc->first_track = toc->last_track = toc->total_tracks = 0;
toc->toc_entries = NULL;
@@ -418,10 +421,9 @@ static int read_cdrom_toc(int fd, cdrom_toc *toc) {
toc->total_tracks = toc->last_track - toc->first_track + 1;
/* allocate space for the toc entries */
- toc->toc_entries =
- (cdrom_toc_entry *)malloc(toc->total_tracks * sizeof(cdrom_toc_entry));
+ toc->toc_entries = calloc(toc->total_tracks, sizeof(cdrom_toc_entry));
if (!toc->toc_entries) {
- perror("malloc");
+ perror("calloc");
return -1;
}
@@ -529,10 +531,9 @@ static int read_cdrom_toc(int fd, cdrom_toc *toc) {
toc->total_tracks = toc->last_track - toc->first_track + 1;
/* allocate space for the toc entries */
- toc->toc_entries =
- (cdrom_toc_entry *)malloc(toc->total_tracks * sizeof(cdrom_toc_entry));
+ toc->toc_entries = calloc(toc->total_tracks, sizeof(cdrom_toc_entry));
if (!toc->toc_entries) {
- perror("malloc");
+ perror("calloc");
return -1;
}
@@ -612,7 +613,7 @@ static int read_cdrom_frames(cdda_input_plugin_t *this_gen, int frame, int num_f
return 0;
}
-#elif defined(__FreeBSD_kernel__) || defined(__NetBSD__)
+#elif defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__)
#include <sys/cdio.h>
@@ -625,7 +626,7 @@ static int read_cdrom_toc(int fd, cdrom_toc *toc) {
struct ioc_toc_header tochdr;
#if defined(__FreeBSD_kernel__)
struct ioc_read_toc_single_entry tocentry;
-#elif defined(__NetBSD__)
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
struct ioc_read_toc_entry tocentry;
struct cd_toc_entry data;
#endif
@@ -642,10 +643,9 @@ static int read_cdrom_toc(int fd, cdrom_toc *toc) {
toc->total_tracks = toc->last_track - toc->first_track + 1;
/* allocate space for the toc entries */
- toc->toc_entries =
- (cdrom_toc_entry *)malloc(toc->total_tracks * sizeof(cdrom_toc_entry));
+ toc->toc_entries = calloc(toc->total_tracks, sizeof(cdrom_toc_entry));
if (!toc->toc_entries) {
- perror("malloc");
+ perror("calloc");
return -1;
}
@@ -661,7 +661,7 @@ static int read_cdrom_toc(int fd, cdrom_toc *toc) {
perror("CDIOREADTOCENTRY");
return -1;
}
-#elif defined(__NetBSD__)
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
memset(&data, 0, sizeof(data));
tocentry.data_len = sizeof(data);
tocentry.data = &data;
@@ -682,7 +682,7 @@ static int read_cdrom_toc(int fd, cdrom_toc *toc) {
(tocentry.entry.addr.msf.minute * CD_SECONDS_PER_MINUTE * CD_FRAMES_PER_SECOND) +
(tocentry.entry.addr.msf.second * CD_FRAMES_PER_SECOND) +
tocentry.entry.addr.msf.frame;
-#elif defined(__NetBSD__)
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
toc->toc_entries[i-1].track_mode = (tocentry.data->control & 0x04) ? 1 : 0;
toc->toc_entries[i-1].first_frame_minute = tocentry.data->addr.msf.minute;
toc->toc_entries[i-1].first_frame_second = tocentry.data->addr.msf.second;
@@ -704,7 +704,7 @@ static int read_cdrom_toc(int fd, cdrom_toc *toc) {
perror("CDIOREADTOCENTRY");
return -1;
}
-#elif defined(__NetBSD__)
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
memset(&data, 0, sizeof(data));
tocentry.data_len = sizeof(data);
tocentry.data = &data;
@@ -725,7 +725,7 @@ static int read_cdrom_toc(int fd, cdrom_toc *toc) {
(tocentry.entry.addr.msf.minute * CD_SECONDS_PER_MINUTE * CD_FRAMES_PER_SECOND) +
(tocentry.entry.addr.msf.second * CD_FRAMES_PER_SECOND) +
tocentry.entry.addr.msf.frame;
-#elif defined(__NetBSD__)
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
toc->leadout_track.track_mode = (tocentry.data->control & 0x04) ? 1 : 0;
toc->leadout_track.first_frame_minute = tocentry.data->addr.msf.minute;
toc->leadout_track.first_frame_second = tocentry.data->addr.msf.second;
@@ -763,7 +763,7 @@ static int read_cdrom_frames(cdda_input_plugin_t *this_gen, int frame, int num_f
perror("CDIOCREADAUDIO");
return -1;
}
-#elif defined(__NetBSD__)
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
scsireq_t req;
int nblocks = 1;
@@ -835,10 +835,9 @@ static int read_cdrom_toc(cdda_input_plugin_t *this_gen, cdrom_toc *toc) {
/* allocate space for the toc entries */
- toc->toc_entries =
- (cdrom_toc_entry *)malloc(toc->total_tracks * sizeof(cdrom_toc_entry));
+ toc->toc_entries = calloc(toc->total_tracks, sizeof(cdrom_toc_entry));
if (!toc->toc_entries) {
- perror("malloc");
+ perror("calloc");
return -1;
}
@@ -1036,13 +1035,13 @@ network_command( xine_stream_t *stream, int socket, char *data_buf, char *msg, .
#ifndef WIN32
-static int network_connect(xine_stream_t *stream, char *url )
+static int network_connect(xine_stream_t *stream, const char *got_url )
{
- char *host;
+ char *host, *url;
int port;
int fd;
- url = strdup(url);
+ url = strdup(got_url);
parse_url(url, &host, &port);
if( !host || !strlen(host) || !port )
@@ -1081,10 +1080,9 @@ static int network_read_cdrom_toc(xine_stream_t *stream, int fd, cdrom_toc *toc)
toc->total_tracks = toc->last_track - toc->first_track + 1;
/* allocate space for the toc entries */
- toc->toc_entries =
- (cdrom_toc_entry *)malloc(toc->total_tracks * sizeof(cdrom_toc_entry));
+ toc->toc_entries = calloc(toc->total_tracks, sizeof(cdrom_toc_entry));
if (!toc->toc_entries) {
- perror("malloc");
+ perror("calloc");
return -1;
}
@@ -1312,20 +1310,17 @@ static void _cdda_mkdir_recursive_safe(xine_t *xine, char *path) {
if(p && strlen(p)) {
#ifdef WIN32
- if (*buf2 != '\0') {
+ if (*buf2 != '\0') {
#endif
-
- int size = strlen(buf2);
- snprintf(buf2 + size, sizeof(buf2) - size, "/%s", p);
-
+ size_t size = strlen(buf2);
+ snprintf(buf2 + size, sizeof(buf2) - size, "/%s", p);
#ifdef WIN32
- }
- else {
- snprintf(buf2, sizeof(buf2), "%s", p);
- }
-
+ }
+ else {
+ snprintf(buf2, sizeof(buf2), "%s", p);
+ }
#endif /* WIN32 */
-
+
_cdda_mkdir_safe(xine, buf2);
}
}
@@ -1443,13 +1438,13 @@ static int _cdda_cddb_handle_code(char *buf) {
*/
static int _cdda_load_cached_cddb_infos(cdda_input_plugin_t *this) {
char cdir[XINE_PATH_MAX + XINE_NAME_MAX + 1];
+ size_t cdir_size = 0;
DIR *dir;
if(this == NULL)
return 0;
- memset(&cdir, 0, sizeof(cdir));
- snprintf(cdir, sizeof(cdir), "%s", this->cddb.cache_dir);
+ cdir_size = snprintf(cdir, sizeof(cdir), "%s", this->cddb.cache_dir);
if((dir = opendir(cdir)) != NULL) {
struct dirent *pdir;
@@ -1457,14 +1452,12 @@ static int _cdda_load_cached_cddb_infos(cdda_input_plugin_t *this) {
while((pdir = readdir(dir)) != NULL) {
char discid[9];
- memset(&discid, 0, sizeof(discid));
- snprintf(discid, sizeof(discid), "%08lx", this->cddb.disc_id);
+ snprintf(discid, sizeof(discid), "%08" PRIx32, this->cddb.disc_id);
if(!strcasecmp(pdir->d_name, discid)) {
FILE *fd;
- int size = strlen(cdir);
- snprintf(cdir + size, sizeof(cdir) - size, "/%s", discid);
+ cdir_size += snprintf(cdir + cdir_size, sizeof(cdir) - cdir_size, "/%s", discid);
if((fd = fopen(cdir, "r")) == NULL) {
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
"input_cdda: fopen(%s) failed: %s.\n", cdir, strerror(errno));
@@ -1484,7 +1477,7 @@ static int _cdda_load_cached_cddb_infos(cdda_input_plugin_t *this) {
if (sscanf(buffer, "DTITLE=%s", &buf[0]) == 1) {
char *pt, *artist, *title;
- pt = strrchr(buffer, '=');
+ pt = strchr(buffer, '=');
if (pt) {
pt++;
@@ -1524,7 +1517,7 @@ static int _cdda_load_cached_cddb_infos(cdda_input_plugin_t *this) {
else if (sscanf(buffer, "TTITLE%d=%s", &tnum, &buf[0]) == 2) {
char *pt;
- pt = strrchr(buffer, '=');
+ pt = strchr(buffer, '=');
if (pt)
pt++;
if (this->cddb.track[tnum].title == NULL)
@@ -1542,14 +1535,9 @@ static int _cdda_load_cached_cddb_infos(cdda_input_plugin_t *this) {
int nyear;
y = strstr(buffer, "YEAR:");
- if(y) {
- if (sscanf(y+5, "%4d", &nyear) == 1) {
- char year[5];
-
- snprintf(year, 5, "%d", nyear);
- if (this->cddb.disc_year == NULL)
- this->cddb.disc_year = strdup(year);
- }
+ if (y && this->cddb.disc_year == NULL) {
+ if (sscanf(y+5, "%4d", &nyear) == 1)
+ asprintf(&this->cddb.disc_year, "%d", nyear);
}
}
}
@@ -1563,7 +1551,7 @@ static int _cdda_load_cached_cddb_infos(cdda_input_plugin_t *this) {
}
}
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
- "input_cdda: cached entry for disc ID %08lx not found.\n", this->cddb.disc_id);
+ "input_cdda: cached entry for disc ID %08" PRIx32 " not found.\n", this->cddb.disc_id);
closedir(dir);
}
@@ -1587,7 +1575,7 @@ static void _cdda_save_cached_cddb_infos(cdda_input_plugin_t *this, char *fileco
_cdda_mkdir_recursive_safe(this->stream->xine, cfile);
- snprintf(cfile, sizeof(cfile), "%s/%08lx", this->cddb.cache_dir, this->cddb.disc_id);
+ snprintf(cfile, sizeof(cfile), "%s/%08" PRIx32 , this->cddb.cache_dir, this->cddb.disc_id);
if((fd = fopen(cfile, "w")) == NULL) {
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
@@ -1726,12 +1714,11 @@ static int _cdda_cddb_retrieve(cdda_input_plugin_t *this) {
/* Send query command */
memset(&buffer, 0, sizeof(buffer));
- sprintf(buffer, "cddb query %08lx %d ", this->cddb.disc_id, this->cddb.num_tracks);
+ size_t size = sprintf(buffer, "cddb query %08" PRIx32 " %d ", this->cddb.disc_id, this->cddb.num_tracks);
for (i = 0; i < this->cddb.num_tracks; i++) {
- int size = strlen(buffer);
- snprintf(buffer + size, sizeof(buffer) - size, "%d ", this->cddb.track[i].start);
+ size += snprintf(buffer + size, sizeof(buffer) - size, "%d ", this->cddb.track[i].start);
}
- snprintf(buffer + strlen(buffer), sizeof(buffer) - strlen(buffer), "%d\n", this->cddb.disc_length);
+ snprintf(buffer + strlen(buffer), sizeof(buffer) - size, "%d\n", this->cddb.disc_length);
if ((err = _cdda_cddb_send_command(this, buffer)) <= 0) {
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
"input_cdda: error while sending cddb query command.\n");
@@ -1818,7 +1805,7 @@ static int _cdda_cddb_retrieve(cdda_input_plugin_t *this) {
while (strcmp(buffer, ".")) {
char buf[2048];
int tnum;
- int bufsize = strlen(buffercache);
+ size_t bufsize = strlen(buffercache);
memset(&buffer, 0, sizeof(buffer));
_cdda_cddb_socket_read(this, buffer, sizeof(buffer) - 1);
@@ -1886,14 +1873,9 @@ static int _cdda_cddb_retrieve(cdda_input_plugin_t *this) {
int nyear;
y = strstr(buffer, "YEAR:");
- if (y) {
- if (sscanf(y+5, "%4d", &nyear) == 1) {
- char year[5];
-
- snprintf(year, 5, "%d", nyear);
- if (this->cddb.disc_year == NULL)
- this->cddb.disc_year = strdup(year);
- }
+ if (y && this->cddb.disc_year == NULL) {
+ if (sscanf(y+5, "%4d", &nyear) == 1)
+ asprintf(&this->cddb.disc_year, "%d", nyear);
}
}
}
@@ -1922,7 +1904,7 @@ static unsigned int _cdda_cddb_sum(int n) {
}
return ret;
}
-static unsigned long _cdda_calc_cddb_id(cdda_input_plugin_t *this) {
+static uint32_t _cdda_calc_cddb_id(cdda_input_plugin_t *this) {
int i, tsum = 0;
if(this == NULL || (this->cddb.num_tracks <= 0))
@@ -1979,7 +1961,7 @@ static void _cdda_cdindex(cdda_input_plugin_t *this, cdrom_toc *toc) {
/*
* return cbbd disc id.
*/
-static unsigned long _cdda_get_cddb_id(cdda_input_plugin_t *this) {
+static uint32_t _cdda_get_cddb_id(cdda_input_plugin_t *this) {
if(this == NULL || (this->cddb.num_tracks <= 0))
return 0;
@@ -2024,7 +2006,7 @@ static void _cdda_free_cddb_info(cdda_input_plugin_t *this) {
*/
static int cdda_open(cdda_input_plugin_t *this_gen,
- char *cdda_device, cdrom_toc *toc, int *fdd) {
+ const char *cdda_device, cdrom_toc *toc, int *fdd) {
#ifndef WIN32
int fd = -1;
@@ -2104,9 +2086,9 @@ static int cdda_open(cdda_input_plugin_t *this_gen,
hASPI = LoadLibrary( "wnaspi32.dll" );
if( hASPI != NULL )
{
- (FARPROC) lpGetSupport = GetProcAddress( hASPI,
+ lpGetSupport = GetProcAddress( hASPI,
"GetASPI32SupportInfo" );
- (FARPROC) lpSendCommand = GetProcAddress( hASPI,
+ lpSendCommand = GetProcAddress( hASPI,
"SendASPI32Command" );
}
@@ -2458,7 +2440,7 @@ static int cdda_plugin_open (input_plugin_t *this_gen ) {
if(this->cddb.num_tracks) {
int t;
- this->cddb.track = (trackinfo_t *) xine_xmalloc(sizeof(trackinfo_t) * this->cddb.num_tracks);
+ this->cddb.track = (trackinfo_t *) calloc(this->cddb.num_tracks, sizeof(trackinfo_t));
for(t = 0; t < this->cddb.num_tracks; t++) {
int length = (toc->toc_entries[t].first_frame_minute * CD_SECONDS_PER_MINUTE +
@@ -2485,15 +2467,31 @@ static int cdda_plugin_open (input_plugin_t *this_gen ) {
}
if(this->cddb.track[this->track].title) {
- lprintf("Track %d Title: %s\n", this->track+1, this->cddb.track[this->track].title);
-
- _x_meta_info_set_utf8(this->stream, XINE_META_INFO_TITLE, this->cddb.track[this->track].title);
- }
+ /* Check for track 'titles' of the form <artist> / <title>. */
+ char *pt;
+ pt = strstr(this->cddb.track[this->track].title, " / ");
+ if (pt != NULL) {
+ char *track_artist;
+ track_artist = strdup(this->cddb.track[this->track].title);
+ track_artist[pt - this->cddb.track[this->track].title] = 0;
+ lprintf("Track %d Artist: %s\n", this->track+1, track_artist);
+
+ _x_meta_info_set_utf8(this->stream, XINE_META_INFO_ARTIST, track_artist);
+ free(track_artist);
+ pt += 3;
+ }
+ else {
+ if(this->cddb.disc_artist) {
+ lprintf("Disc Artist: %s\n", this->cddb.disc_artist);
+
+ _x_meta_info_set_utf8(this->stream, XINE_META_INFO_ARTIST, this->cddb.disc_artist);
+ }
- if(this->cddb.disc_artist) {
- lprintf("Disc Artist: %s\n", this->cddb.disc_artist);
+ pt = this->cddb.track[this->track].title;
+ }
+ lprintf("Track %d Title: %s\n", this->track+1, pt);
- _x_meta_info_set_utf8(this->stream, XINE_META_INFO_ARTIST, this->cddb.disc_artist);
+ _x_meta_info_set_utf8(this->stream, XINE_META_INFO_TITLE, pt);
}
if(this->cddb.disc_category) {
@@ -2513,13 +2511,140 @@ static int cdda_plugin_open (input_plugin_t *this_gen ) {
return 1;
}
+static xine_mrl_t** cdda_class_get_dir(input_class_t *this_gen,
+ const char *filename,
+ int *num_files) {
+ cdda_input_class_t *this = (cdda_input_class_t *) this_gen;
+ cdda_input_plugin_t *ip;
+ cdrom_toc *toc;
+ char *base_mrl;
+ int len, frame;
+ const char * device;
+ int fd, i, err = -1;
+ int num_tracks;
+
+ if (filename && *filename) {
+ device = filename;
+ if (strncasecmp(device,"cdda:/",6) == 0) {
+ device += 6;
+ while ('/' == *device)
+ device++;
+ device--;
+ }
+ }
+ else {
+ device = this->cdda_device;
+ }
+ lprintf("cdda_class_get_dir for >%s<\n", device);
+
+ /* get the CD TOC */
+ toc = init_cdrom_toc();
+
+ fd = -1;
+
+ /* we create a new instance because getting a directory of a cd
+ * should not affect another cd that might be playing. */
+ ip = (cdda_input_plugin_t *)xine_xmalloc(sizeof(cdda_input_plugin_t));
+ ip->stream = NULL;
+ ip->fd = -1;
+ ip->net_fd = -1;
+
+#ifndef WIN32
+ if( strchr(device,':') ) {
+ fd = network_connect(ip->stream, device);
+ if( fd != -1 ) {
+ err = network_read_cdrom_toc(ip->stream, fd, toc);
+ }
+ }
+#endif
+
+ if (fd == -1) {
+ if (cdda_open(ip, device, toc, &fd) == -1) {
+ lprintf("cdda_class_get_dir: opening >%s< failed %s\n",
+ device, strerror(errno));
+ free(ip);
+ return NULL;
+ }
+
+#ifndef WIN32
+ err = read_cdrom_toc(fd, toc);
+#else
+ err = read_cdrom_toc(ip, toc);
+#endif /* WIN32 */
+ }
+
+#ifdef LOG
+ print_cdrom_toc(toc);
+#endif
+
+ cdda_close(ip);
+
+ if ( err < 0 ) {
+ free(ip);
+ return NULL;
+ }
+
+ num_tracks = toc->last_track - toc->first_track + 1;
+
+ /* this could be done in read_cdrom_toc, but it seems other code doesn't use it */
+ frame = toc->leadout_track.first_frame;
+ for ( i = num_tracks-1 ; i >= 0 ; i--) {
+ toc->toc_entries[i].total_frames = frame - toc->toc_entries[i].first_frame;
+ frame = toc->toc_entries[i].first_frame;
+ }
+
+ if (toc->ignore_last_track)
+ num_tracks--;
+
+ len = strlen(device) + 5;
+ base_mrl = xine_xmalloc(len+1);
+ sprintf(base_mrl, "cdda:%s", device);
+
+ /* allocate space for the mrls's if needed. */
+ if (num_tracks+1 > this->mrls_allocated_entries) {
+ this->mrls = realloc(this->mrls, (num_tracks+1) * sizeof(xine_mrl_t*));
+ }
+ for (i = 0 ; i < num_tracks ; i++) {
+ if (i < this->mrls_allocated_entries) {
+ if (this->mrls[i]->origin)
+ free(this->mrls[i]->origin);
+ if (this->mrls[i]->mrl)
+ free(this->mrls[i]->mrl);
+ if (this->mrls[i]->link) {
+ free(this->mrls[i]->link);
+ this->mrls[i]->link = NULL;
+ }
+ }
+ else {
+ this->mrls[i] = (xine_mrl_t *) xine_xmalloc(sizeof(xine_mrl_t));
+ this->mrls[i]->link = NULL;
+ this->mrls_allocated_entries++;
+ }
+ this->mrls[i]->origin = strdup(base_mrl);
+ this->mrls[i]->mrl = xine_xmalloc(len+4);
+ sprintf( this->mrls[i]->mrl, "%s/%d", base_mrl, i+toc->first_track);
+ this->mrls[i]->type = mrl_cda | mrl_file_blockdev;
+ this->mrls[i]->size = toc->toc_entries[i].total_frames * CD_RAW_FRAME_SIZE;
+ }
+ /* Clean up */
+ while(this->mrls_allocated_entries > num_tracks) {
+ MRL_ZERO(this->mrls[this->mrls_allocated_entries - 1]);
+ free(this->mrls[this->mrls_allocated_entries--]);
+ }
+ free_cdrom_toc(toc);
+ free(ip);
+
+ this->mrls[num_tracks] = NULL;
+ *num_files = num_tracks;
+ return this->mrls;
+}
+
static char ** cdda_class_get_autoplay_list (input_class_t *this_gen,
int *num_files) {
cdda_input_class_t *this = (cdda_input_class_t *) this_gen;
cdda_input_plugin_t *ip = this->ip;
cdrom_toc *toc;
- char trackmrl[20];
int fd, i, err = -1;
int num_tracks;
@@ -2541,7 +2666,7 @@ static char ** cdda_class_get_autoplay_list (input_class_t *this_gen,
* device we are going to open; but it is possible that this function
* gets called, before a plugin instance has been created;
* let's create a dummy instance in such a condition */
- ip = (cdda_input_plugin_t *)xine_xmalloc(sizeof(cdda_input_plugin_t));
+ ip = calloc(1, sizeof(cdda_input_plugin_t));
ip->stream = NULL;
ip->fd = -1;
ip->net_fd = -1;
@@ -2585,10 +2710,8 @@ static char ** cdda_class_get_autoplay_list (input_class_t *this_gen,
num_tracks = toc->last_track - toc->first_track;
if (toc->ignore_last_track)
num_tracks--;
- for ( i = 0; i <= num_tracks; i++ ) {
- sprintf(trackmrl,"cdda:/%d",i+toc->first_track);
- this->autoplaylist[i] = strdup(trackmrl);
- }
+ for ( i = 0; i <= num_tracks; i++ )
+ asprintf(&this->autoplaylist[i],"cdda:/%d",i+toc->first_track);
*num_files = toc->last_track - toc->first_track + 1;
@@ -2642,7 +2765,7 @@ static input_plugin_t *cdda_class_get_instance (input_class_t *cls_gen, xine_str
} else
return NULL;
- this = (cdda_input_plugin_t *) xine_xmalloc (sizeof (cdda_input_plugin_t));
+ this = calloc(1, sizeof (cdda_input_plugin_t));
class->ip = this;
this->stream = stream;
@@ -2731,7 +2854,7 @@ static void *init_plugin (xine_t *xine, void *data) {
cdda_input_class_t *this;
config_values_t *config;
- this = (cdda_input_class_t *) xine_xmalloc (sizeof (cdda_input_class_t));
+ this = calloc(1, sizeof (cdda_input_class_t));
this->xine = xine;
this->config = xine->config;
@@ -2740,8 +2863,7 @@ static void *init_plugin (xine_t *xine, void *data) {
this->input_class.get_instance = cdda_class_get_instance;
this->input_class.get_identifier = cdda_class_get_identifier;
this->input_class.get_description = cdda_class_get_description;
- /* this->input_class.get_dir = cdda_class_get_dir; */
- this->input_class.get_dir = NULL;
+ this->input_class.get_dir = cdda_class_get_dir;
this->input_class.get_autoplay_list = cdda_class_get_autoplay_list;
this->input_class.dispose = cdda_class_dispose;
this->input_class.eject_media = cdda_class_eject_media;
diff --git a/src/input/input_dvb.c b/src/input/input_dvb.c
index 795b843c5..5060757e4 100644
--- a/src/input/input_dvb.c
+++ b/src/input/input_dvb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2005 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -66,14 +66,14 @@
* OSD - this will allow for filtering/searching of epg data - useful for automatic recording :)
*/
-/* pthread.h must be included first so rest of the headers are imported
- thread safely (on some systems). */
-#include <pthread.h>
-
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+/* pthread.h must be included first so rest of the headers are imported
+ thread safely (on some systems). */
+#include <pthread.h>
+
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
@@ -286,11 +286,12 @@ typedef struct {
xine_t *xine;
- char *mrls[5];
+ char *mrls[6];
int numchannels;
char *autoplaylist[MAX_AUTOCHANNELS];
+ char *default_channels_conf_filename;
} dvb_input_class_t;
typedef struct {
@@ -331,6 +332,9 @@ typedef struct {
/* scratch buffer for forward seeking */
char seek_buf[BUFSIZE];
+ /* Is the GUI enabled at all? */
+ int dvb_gui_enabled;
+
/* simple vcr-like functionality */
int record_fd;
int record_paused;
@@ -369,6 +373,7 @@ static const Param bw_list [] = {
{ "BANDWIDTH_6_MHZ", BANDWIDTH_6_MHZ },
{ "BANDWIDTH_7_MHZ", BANDWIDTH_7_MHZ },
{ "BANDWIDTH_8_MHZ", BANDWIDTH_8_MHZ },
+ { "BANDWIDTH_AUTO", BANDWIDTH_AUTO },
{ NULL, 0 }
};
@@ -391,6 +396,7 @@ static const Param guard_list [] = {
{"GUARD_INTERVAL_1_32", GUARD_INTERVAL_1_32},
{"GUARD_INTERVAL_1_4", GUARD_INTERVAL_1_4},
{"GUARD_INTERVAL_1_8", GUARD_INTERVAL_1_8},
+ {"GUARD_INTERVAL_AUTO", GUARD_INTERVAL_AUTO},
{ NULL, 0 }
};
@@ -399,6 +405,7 @@ static const Param hierarchy_list [] = {
{ "HIERARCHY_2", HIERARCHY_2 },
{ "HIERARCHY_4", HIERARCHY_4 },
{ "HIERARCHY_NONE", HIERARCHY_NONE },
+ { "HIERARCHY_AUTO", HIERARCHY_AUTO },
{ NULL, 0 }
};
@@ -417,12 +424,14 @@ static const Param qam_list [] = {
{ "QAM_256", QAM_256 },
{ "QAM_32", QAM_32 },
{ "QAM_64", QAM_64 },
+ { "QAM_AUTO", QAM_AUTO },
{ NULL, 0 }
};
static const Param transmissionmode_list [] = {
{ "TRANSMISSION_MODE_2K", TRANSMISSION_MODE_2K },
{ "TRANSMISSION_MODE_8K", TRANSMISSION_MODE_8K },
+ { "TRANSMISSION_MODE_AUTO", TRANSMISSION_MODE_AUTO },
{ NULL, 0 }
};
@@ -513,7 +522,7 @@ time_t dvb_mjdtime (char *buf)
int i;
unsigned int year, month, day, hour, min, sec;
unsigned long int mjd;
- struct tm *tma = xine_xmalloc(sizeof(struct tm));
+ struct tm *tma = calloc(1, sizeof(struct tm));
time_t t;
_x_assert(tma != NULL);
@@ -571,24 +580,23 @@ static void tuner_dispose(tuner_t * this)
}
-static tuner_t *tuner_init(xine_t * xine, int adapter)
+static tuner_t *XINE_MALLOC tuner_init(xine_t * xine, int adapter)
{
tuner_t *this;
int x;
int test_video;
- char *video_device=xine_xmalloc(200);
+ char *video_device=malloc(100);
_x_assert(video_device != NULL);
- this = (tuner_t *) xine_xmalloc(sizeof(tuner_t));
+ this = calloc(1, sizeof(tuner_t));
_x_assert(this != NULL);
xprintf(this->xine, XINE_VERBOSITY_DEBUG, "tuner_init adapter=%d\n", adapter);
this->fd_frontend = -1;
- for (x = 0; x < MAX_FILTERS; x++)
- this->fd_pidfilter[x] = 0;
+ memset(this->fd_pidfilter, 0, sizeof(this->fd_pidfilter));
this->xine = xine;
this->adapter_num = adapter;
@@ -881,14 +889,15 @@ static channel_t *load_channels(xine_t *xine, xine_stream_t *stream, int *num_ch
FILE *f;
char str[BUFSIZE];
- char filename[BUFSIZE];
channel_t *channels = NULL;
int num_channels = 0;
int num_alloc = 0;
- int i;
struct stat st;
-
- snprintf(filename, BUFSIZE, "%s/.xine/channels.conf", xine_get_homedir());
+ xine_cfg_entry_t channels_conf;
+ char *filename;
+
+ xine_config_lookup_entry(xine, "media.dvb.channels_conf", &channels_conf);
+ filename = channels_conf.str_value;
f = fopen(filename, "r");
if (!f) {
@@ -910,8 +919,8 @@ static channel_t *load_channels(xine_t *xine, xine_stream_t *stream, int *num_ch
while ( fgets (str, BUFSIZE, f)) {
channel_t channel = {0};
- /* lose trailing spaces & control characters */
- i = strlen (str);
+ /* lose trailing spaces & control characters */
+ size_t i = strlen (str);
while (i && str[i - 1] <= ' ')
--i;
if (i == 0)
@@ -922,7 +931,7 @@ static channel_t *load_channels(xine_t *xine, xine_stream_t *stream, int *num_ch
continue;
if (num_channels >= num_alloc) {
- channel_t *new_channels = xine_xmalloc((num_alloc += 32) * sizeof (channel_t));
+ channel_t *new_channels = calloc((num_alloc += 32), sizeof (channel_t));
_x_assert(new_channels != NULL);
memcpy(new_channels, channels, num_channels * sizeof (channel_t));
free(channels);
@@ -933,8 +942,7 @@ static channel_t *load_channels(xine_t *xine, xine_stream_t *stream, int *num_ch
/* Initially there's no EPG data in the EPG structs. */
channels[num_channels].epg_count = 0;
- for (i = 0; i < MAX_EPG_ENTRIES_PER_CHANNEL; ++i)
- channels[num_channels].epg[i] = NULL;
+ memset(channels[num_channels].epg, 0, sizeof(channels[num_channels].epg));
num_channels++;
}
@@ -1144,6 +1152,8 @@ static void parse_pmt(dvb_input_plugin_t *this, const unsigned char *buf, int se
switch (buf[0]) {
case 0x01:
case 0x02:
+ case 0x10:
+ case 0x1b:
if(!has_video) {
xprintf(this->stream->xine,XINE_VERBOSITY_LOG,"input_dvb: Adding VIDEO : PID 0x%04x\n", elementary_pid);
dvb_set_pidfilter(this, VIDFILTER, elementary_pid, DMX_PES_VIDEO, DMX_OUT_TS_TAP);
@@ -1153,6 +1163,8 @@ static void parse_pmt(dvb_input_plugin_t *this, const unsigned char *buf, int se
case 0x03:
case 0x04:
+ case 0x0f:
+ case 0x11:
if(!has_audio) {
xprintf(this->stream->xine,XINE_VERBOSITY_LOG,"input_dvb: Adding AUDIO : PID 0x%04x\n", elementary_pid);
dvb_set_pidfilter(this, AUDFILTER, elementary_pid, DMX_PES_AUDIO, DMX_OUT_TS_TAP);
@@ -1229,7 +1241,7 @@ static void dvb_parse_si(dvb_input_plugin_t *this) {
struct pollfd pfd;
tuner_t *tuner = this->tuner;
- tmpbuffer = xine_xmalloc (8192);
+ tmpbuffer = calloc(1, 8192);
_x_assert(tmpbuffer != NULL);
@@ -1437,13 +1449,10 @@ static void load_epg_data(dvb_input_plugin_t *this)
already "found" in the stream. This information is used to initialize the
channel's EPG structs when the EPG information for the channel is seen in
the stream the first time. */
- seen_channels = xine_xmalloc(this->num_channels*sizeof(char));
+ seen_channels = calloc(this->num_channels, sizeof(char));
_x_assert(seen_channels != NULL);
- for (i = 0; i < this->num_channels; i++) {
- seen_channels[i] = 0;
- }
- foo = xine_xmalloc(8192);
+ foo = calloc(1, 8192);
_x_assert(foo != NULL);
fd.fd = this->tuner->fd_pidfilter[EITFILTER];
@@ -1493,19 +1502,19 @@ static void load_epg_data(dvb_input_plugin_t *this)
Allocate space for the strings. */
if (current_channel->epg[current_channel->epg_count] == NULL) {
current_channel->epg[current_channel->epg_count] =
- xine_xmalloc(sizeof(epg_entry_t));
+ calloc(1, sizeof(epg_entry_t));
_x_assert(current_channel->epg[current_channel->epg_count] != NULL);
current_channel->epg[current_channel->epg_count]->progname =
- xine_xmalloc((MAX_EPG_PROGRAM_NAME_LENGTH + 1) * sizeof(char));
+ malloc(MAX_EPG_PROGRAM_NAME_LENGTH + 1);
_x_assert(current_channel->epg[current_channel->epg_count]->progname != NULL);
current_channel->epg[current_channel->epg_count]->description =
- xine_xmalloc((MAX_EPG_PROGRAM_DESCRIPTION_LENGTH + 1) * sizeof(char));
+ malloc(MAX_EPG_PROGRAM_DESCRIPTION_LENGTH + 1);
_x_assert(current_channel->epg[current_channel->epg_count]->description != NULL);
current_channel->epg[current_channel->epg_count]->content =
- xine_xmalloc((MAX_EPG_CONTENT_TYPE_LENGTH + 1) * sizeof(char));
+ malloc(MAX_EPG_CONTENT_TYPE_LENGTH + 1);
_x_assert(current_channel->epg[current_channel->epg_count]->content != NULL);
current_channel->epg[current_channel->epg_count]->running = 0;
@@ -1655,21 +1664,22 @@ static void load_epg_data(dvb_input_plugin_t *this)
}
/* Prints text to an area, tries to cut the lines in between words. */
-static void render_text_area(osd_renderer_t* renderer, osd_object_t* osd, char* text,
+static void render_text_area(osd_renderer_t* renderer, osd_object_t* osd, const char* text,
int x, int y, int row_space,
int max_x, int max_y, int* height, int color_base) {
/* The position of the text to be printed. */
- char* cursor = text;
+ const char* cursor = text;
+ const char *const text_end = text + strlen(text);
/* The line to be printed next. */
char text_line[512];
int text_width, text_height;
- int old_line_length, line_cursor;
- char* bound, *old_bound;
+ size_t old_line_length, line_cursor;
+ const char* bound, *old_bound;
*height = 0;
- while (cursor < text + strlen(text)) {
+ while (cursor < text_end) {
bound = cursor;
line_cursor = 0;
text_line[0] = '\0';
@@ -1726,7 +1736,7 @@ static void render_text_area(osd_renderer_t* renderer, osd_object_t* osd, char*
}
/* OK, it did fit, let's try to fit some more. */
- } while (bound < text + strlen(text));
+ } while (bound < text_end);
if (y + text_height + row_space > max_y) {
break;
@@ -1825,7 +1835,7 @@ static void show_program_info(int x, int y, int max_x, int max_y, int* last_y,
if (epg_data == NULL || epg_data->progname == NULL)
return;
- buffer = xine_xmalloc(512);
+ buffer = calloc(1, 512);
_x_assert(buffer != NULL);
@@ -1842,8 +1852,7 @@ static void show_program_info(int x, int y, int max_x, int max_y, int* last_y,
/*Content type and rating, if any. */
if (strlen(epg_data->content) > 3) {
-
- snprintf(buffer, 94, "%s", epg_data->content);
+ strncpy(buffer, epg_data->content, 94-1);
prog_rating = epg_data->rating;
if (prog_rating > 0) {
@@ -1873,7 +1882,7 @@ static void show_program_info(int x, int y, int max_x, int max_y, int* last_y,
/* Print the description. */
if (epg_data->description && strlen(epg_data->description) > 0) {
renderer->set_font(osd, "sans", EPG_DESCRIPTION_FONT_SIZE);
- sprintf(buffer, "%s", epg_data->description);
+ strcpy(buffer, epg_data->description);
/* If the description is not complete (i.e., there is no comma at the end),
add "..." to the end. In my locale they often seem to send incomplete description
texts :( */
@@ -2207,7 +2216,7 @@ static void do_record (dvb_input_plugin_t *this) {
this->stream->osd_renderer->hide (this->paused_osd, 0);
this->record_paused=0;
} else {
- t=xine_xmalloc(sizeof(time_t));
+ t=calloc(1, sizeof(time_t));
_x_assert(t != NULL);
@@ -2499,15 +2508,13 @@ static off_t dvb_plugin_read (input_plugin_t *this_gen,
if (!this->tuned_in)
return 0;
- dvb_event_handler (this);
+ if (this->dvb_gui_enabled)
+ dvb_event_handler (this);
#ifdef LOG_READS
xprintf(this->class->xine,XINE_VERBOSITY_DEBUG,
"input_dvb: reading %" PRIdMAX " bytes...\n", (intmax_t)len);
#endif
-#ifndef DVB_NO_BUFFERING
- nbc_check_buffers (this->nbc);
-#endif
/* protect against channel changes */
have_mutex = pthread_mutex_lock(&this->channel_change_mutex);
total=0;
@@ -2595,6 +2602,12 @@ static buf_element_t *dvb_plugin_read_block (input_plugin_t *this_gen,
buf_element_t *buf = fifo->buffer_pool_alloc (fifo);
int total_bytes;
+ if (todo > buf->max_size)
+ todo = buf->max_size;
+ if (todo < 0) {
+ buf->free_buffer (buf);
+ return NULL;
+ }
buf->content = buf->mem;
buf->type = BUF_DEMUX_BLOCK;
@@ -2764,7 +2777,12 @@ static int dvb_plugin_open(input_plugin_t * this_gen)
xine_cfg_entry_t zoomdvb;
xine_cfg_entry_t adapter;
xine_cfg_entry_t lastchannel;
+ xine_cfg_entry_t gui_enabled;
+ xine_config_lookup_entry(this->stream->xine, "media.dvb.gui_enabled", &gui_enabled);
+ this->dvb_gui_enabled = gui_enabled.num_value;
+ xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("input_dvb: DVB GUI %s\n"), this->dvb_gui_enabled ? "enabled" : "disabled");
+
xine_config_lookup_entry(this->stream->xine, "media.dvb.adapter", &adapter);
if (!(tuner = tuner_init(this->class->xine,adapter.num_value))) {
@@ -2822,7 +2840,7 @@ static int dvb_plugin_open(input_plugin_t * this_gen)
* that the channels have really ugly names, sometimes prefixed
* by numbers...
*/
- int chanlen = strlen(channame);
+ size_t chanlen = strlen(channame);
int offset = 0;
xprintf(this->class->xine, XINE_VERBOSITY_LOG,
@@ -2876,7 +2894,7 @@ static int dvb_plugin_open(input_plugin_t * this_gen)
}
ptr = this->mrl;
ptr += 7;
- channels = xine_xmalloc(sizeof(channel_t));
+ channels = calloc(1, sizeof(channel_t));
_x_assert(channels != NULL);
if (extract_channel_from_string(channels, ptr, tuner->feinfo.type) < 0) {
free(channels);
@@ -2896,7 +2914,7 @@ static int dvb_plugin_open(input_plugin_t * this_gen)
}
ptr = this->mrl;
ptr += 7;
- channels = xine_xmalloc(sizeof(channel_t));
+ channels = calloc(1, sizeof(channel_t));
_x_assert(channels != NULL);
if (extract_channel_from_string(channels, ptr, tuner->feinfo.type) < 0) {
free(channels);
@@ -2919,7 +2937,7 @@ static int dvb_plugin_open(input_plugin_t * this_gen)
}
ptr = this->mrl;
ptr += 7;
- channels = xine_xmalloc(sizeof(channel_t));
+ channels = calloc(1, sizeof(channel_t));
_x_assert(channels != NULL);
if (extract_channel_from_string(channels, ptr, tuner->feinfo.type) < 0)
{
@@ -2945,7 +2963,7 @@ static int dvb_plugin_open(input_plugin_t * this_gen)
}
ptr = this->mrl;
ptr += 7;
- channels = xine_xmalloc(sizeof(channel_t));
+ channels = calloc(1, sizeof(channel_t));
_x_assert(channels != NULL);
if (extract_channel_from_string(channels, ptr, tuner->feinfo.type) < 0)
{
@@ -2990,15 +3008,16 @@ static int dvb_plugin_open(input_plugin_t * this_gen)
this->event_queue = xine_event_new_queue(this->stream);
#ifdef EPG_UPDATE_IN_BACKGROUND
- /* Start the EPG updater thread. */
- this->epg_updater_stop = 0;
- if (pthread_create(&this->epg_updater_thread, NULL,
- epg_data_updater, this) != 0) {
- xprintf(
- this->class->xine, XINE_VERBOSITY_LOG,
- _("input_dvb: cannot create EPG updater thread\n"));
- return 0;
-
+ if (this->dvb_gui_enabled) {
+ /* Start the EPG updater thread. */
+ this->epg_updater_stop = 0;
+ if (pthread_create(&this->epg_updater_thread, NULL,
+ epg_data_updater, this) != 0) {
+ xprintf(
+ this->class->xine, XINE_VERBOSITY_LOG,
+ _("input_dvb: cannot create EPG updater thread\n"));
+ return 0;
+ }
}
#endif
/*
@@ -3109,7 +3128,7 @@ static input_plugin_t *dvb_class_get_instance (input_class_t *class_gen,
fprintf(stderr, "input_dvb: continuing in get_instance\n");
- this = (dvb_input_plugin_t *) xine_xmalloc (sizeof(dvb_input_plugin_t));
+ this = calloc(1, sizeof(dvb_input_plugin_t));
_x_assert(this != NULL);
@@ -3164,6 +3183,8 @@ static void dvb_class_dispose(input_class_t * this_gen)
{
dvb_input_class_t *class = (dvb_input_class_t *) this_gen;
int x;
+
+ free(class->default_channels_conf_filename);
for(x=0;x<class->numchannels;x++)
free(class->autoplaylist[x]);
@@ -3181,7 +3202,6 @@ static char **dvb_class_get_autoplay_list(input_class_t * this_gen,
{
dvb_input_class_t *class = (dvb_input_class_t *) this_gen;
channel_t *channels=NULL;
- char foobuffer[BUFSIZE];
int ch, apch, num_channels = 0;
int default_channel = -1;
xine_cfg_entry_t lastchannel_enable = {0};
@@ -3226,21 +3246,19 @@ static char **dvb_class_get_autoplay_list(input_class_t * this_gen,
for (ch = 0, apch = !!lastchannel_enable.num_value;
ch < num_channels && ch < MAX_AUTOCHANNELS;
++ch, ++apch) {
- snprintf(foobuffer, BUFSIZE, "dvb://%s", channels[ch].name);
- free(class->autoplaylist[apch]);
- class->autoplaylist[apch] = strdup(foobuffer);
- _x_assert(class->autoplaylist[apch] != NULL);
+ free(class->autoplaylist[apch]);
+ asprintf(&(class->autoplaylist[apch]), "dvb://%s", channels[ch].name);
+ _x_assert(class->autoplaylist[apch] != NULL);
}
if (lastchannel_enable.num_value){
+ free(class->autoplaylist[0]);
if (default_channel != -1)
/* plugin has been used before - channel is valid */
- sprintf (foobuffer, "dvb://%s", channels[default_channel].name);
+ asprintf (&(class->autoplaylist[0]), "dvb://%s", channels[default_channel].name);
else
/* set a reasonable default - the first channel */
- sprintf (foobuffer, "dvb://%s", num_channels ? channels[0].name : "0");
- free(class->autoplaylist[0]);
- class->autoplaylist[0]=strdup(foobuffer);
+ asprintf (&(class->autoplaylist[0]), "dvb://%s", num_channels ? channels[0].name : "0");
}
free_channel_list(channels, num_channels);
@@ -3256,7 +3274,7 @@ static void *init_class (xine_t *xine, void *data) {
dvb_input_class_t *this;
config_values_t *config = xine->config;
- this = (dvb_input_class_t *) xine_xmalloc (sizeof (dvb_input_class_t));
+ this = calloc(1, sizeof (dvb_input_class_t));
_x_assert(this != NULL);
this->xine = xine;
@@ -3275,6 +3293,10 @@ static void *init_class (xine_t *xine, void *data) {
this->mrls[3] = "dvbt://";
this->mrls[4] = "dvba://";
this->mrls[5] = 0;
+
+ asprintf(&this->default_channels_conf_filename,
+ "%s/.xine/channels.conf",
+ xine_get_homedir());
xprintf(this->xine,XINE_VERBOSITY_DEBUG,"init class succeeded\n");
@@ -3308,7 +3330,19 @@ static void *init_class (xine_t *xine, void *data) {
"in your system."),
0, NULL, (void *) this);
-
+ /* set to 0 to turn off the GUI built into this input plugin */
+ config->register_bool(config, "media.dvb.gui_enabled",
+ 1,
+ _("Enable the DVB GUI"),
+ _("Enable the DVB GUI, mouse controlled recording and channel switching."),
+ 21, NULL, NULL);
+ /* Override the default channels file */
+ config->register_filename(config, "media.dvb.channels_conf",
+ this->default_channels_conf_filename,
+ XINE_CONFIG_STRING_IS_FILENAME,
+ _("DVB Channels config file"),
+ _("DVB Channels config file to use instead of the ~/.xine/channels.conf file."),
+ 21, NULL, NULL);
return this;
}
diff --git a/src/input/input_dvd.c b/src/input/input_dvd.c
index a891b9877..279f3c64e 100644
--- a/src/input/input_dvd.c
+++ b/src/input/input_dvd.c
@@ -115,6 +115,9 @@
/* There really isn't a default on Windows! */
#define DVD_PATH "d:\\"
#define RDVD_PATH "d:\\"
+#elif defined(__OpenBSD__)
+#define DVD_PATH "/dev/rcd0c"
+#define RDVD_PATH "/dev/rcd0c"
#else
#define DVD_PATH "/dev/dvd"
#define RDVD_PATH "/dev/rdvd"
@@ -352,11 +355,14 @@ static void send_mouse_enter_leave_event(dvd_input_plugin_t *this, int direction
}
static int update_title_display(dvd_input_plugin_t *this) {
- char ui_title[MAX_STR_LEN + 1];
- xine_event_t uevent;
xine_ui_data_t data;
+ xine_event_t uevent = {
+ .type = XINE_EVENT_UI_SET_TITLE,
+ .stream = this->stream,
+ .data = &data,
+ .data_length = sizeof(data)
+ };
int tt=-1, pr=-1;
- size_t ui_str_length=0;
int num_tt = 0;
if(!this || !(this->stream))
@@ -386,15 +392,15 @@ static int update_title_display(dvd_input_plugin_t *this) {
dvdnav_get_number_of_parts(this->dvdnav, tt, &num_part);
dvdnav_get_angle_info(this->dvdnav, &cur_angle, &num_angle);
if(num_angle > 1) {
- snprintf(ui_title, MAX_STR_LEN,
- "Title %i, Chapter %i, Angle %i of %i",
- tt,pr,cur_angle, num_angle);
+ data.str_len = snprintf(data.str, sizeof(data.str),
+ "Title %i, Chapter %i, Angle %i of %i",
+ tt,pr,cur_angle, num_angle);
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_ANGLE_NUMBER,cur_angle);
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_ANGLE_COUNT,num_angle);
} else {
- snprintf(ui_title, MAX_STR_LEN,
- "Title %i, Chapter %i",
- tt,pr);
+ data.str_len = snprintf(data.str, sizeof(data.str),
+ "Title %i, Chapter %i",
+ tt,pr);
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_ANGLE_NUMBER,0);
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_ANGLE_COUNT,0);
}
@@ -403,9 +409,9 @@ static int update_title_display(dvd_input_plugin_t *this) {
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_CHAPTER_NUMBER,pr);
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_CHAPTER_COUNT,num_part);
} else if (tt == 0 && dvdnav_menu_table[pr]) {
- snprintf(ui_title, MAX_STR_LEN,
- "DVD %s Menu",
- dvdnav_menu_table[pr]);
+ data.str_len = snprintf(data.str, sizeof(data.str),
+ "DVD %s Menu",
+ dvdnav_menu_table[pr]);
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_TITLE_NUMBER,tt);
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_TITLE_COUNT,num_tt);
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_CHAPTER_NUMBER,0);
@@ -413,7 +419,8 @@ static int update_title_display(dvd_input_plugin_t *this) {
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_ANGLE_NUMBER,0);
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_ANGLE_COUNT,0);
} else {
- strcpy(ui_title, "DVD Menu");
+ strcpy(data.str, "DVD Menu");
+ data.str_len = strlen(data.str);
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_TITLE_NUMBER,0);
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_TITLE_COUNT,num_tt);
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_CHAPTER_NUMBER,0);
@@ -421,22 +428,15 @@ static int update_title_display(dvd_input_plugin_t *this) {
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_ANGLE_NUMBER,0);
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_ANGLE_COUNT,0);
}
- ui_str_length = strlen(ui_title);
if (this->dvd_name && this->dvd_name[0] &&
- (ui_str_length + strlen(this->dvd_name) < MAX_STR_LEN)) {
- snprintf(ui_title+ui_str_length, MAX_STR_LEN - ui_str_length,
- ", %s", this->dvd_name);
+ (data.str_len + strlen(this->dvd_name) < sizeof(data.str))) {
+ data.str_len += snprintf(data.str+data.str_len, sizeof(data.str) - data.str_len,
+ ", %s", this->dvd_name);
}
#ifdef INPUT_DEBUG
- printf("input_dvd: Changing title to read '%s'\n", ui_title);
+ printf("input_dvd: Changing title to read '%s'\n", data.str);
#endif
- uevent.type = XINE_EVENT_UI_SET_TITLE;
- uevent.stream = this->stream;
- uevent.data = &data;
- uevent.data_length = sizeof(data);;
- memcpy(data.str, ui_title, strlen(ui_title) + 1);
- data.str_len = strlen(ui_title) + 1;
xine_event_send(this->stream, &uevent);
return 1;
@@ -853,6 +853,9 @@ static buf_element_t *dvd_plugin_read_block (input_plugin_t *this_gen,
static off_t dvd_plugin_read (input_plugin_t *this_gen, char *ch_buf, off_t len) {
/* dvd_input_plugin_t *this = (dvd_input_plugin_t*)this_gen; */
+ if (len < 4)
+ return -1;
+
/* FIXME: Tricking the demux_mpeg_block plugin */
ch_buf[0] = 0;
ch_buf[1] = 0;
@@ -1313,7 +1316,7 @@ static int dvd_plugin_get_optional_data (input_plugin_t *this_gen,
if(this && this->stream && this->dvdnav) {
if(!(dvdnav_is_domain_vts(this->dvdnav))) {
- sprintf(data, "%s", "menu");
+ strcpy(data, "menu");
if (channel <= 0)
return INPUT_OPTIONAL_SUCCESS;
else
@@ -1336,7 +1339,7 @@ static int dvd_plugin_get_optional_data (input_plugin_t *this_gen,
return INPUT_OPTIONAL_SUCCESS;
} else {
if(channel == -1) {
- sprintf(data, "%s", "none");
+ strcpy(data, "none");
return INPUT_OPTIONAL_SUCCESS;
}
}
@@ -1369,10 +1372,7 @@ check_solaris_vold_device(dvd_input_class_t *this)
(volume_action = getenv("VOLUME_ACTION")) != NULL &&
strcmp(volume_action, "insert") == 0) {
- device = malloc(strlen(volume_device) + strlen(volume_name) + 2);
- if (device == NULL)
- return;
- sprintf(device, "%s/%s", volume_device, volume_name);
+ asprintf(&device, "%s/%s", volume_device, volume_name);
if (stat(device, &stb) != 0 || !S_ISCHR(stb.st_mode)) {
free(device);
return;
@@ -1625,14 +1625,14 @@ static input_plugin_t *dvd_class_get_instance (input_class_t *class_gen, xine_st
if (strncasecmp (data, handled_mrl, strlen(handled_mrl) ) != 0)
return NULL;
- this = (dvd_input_plugin_t *) xine_xmalloc (sizeof (dvd_input_plugin_t));
+ this = calloc(1, sizeof (dvd_input_plugin_t));
if (!this) {
return NULL;
}
this->mem_stack = 0;
this->mem_stack_max = 1024;
- this->mem = xine_xmalloc(sizeof(unsigned char *) * this->mem_stack_max);
+ this->mem = calloc(this->mem_stack_max, sizeof(unsigned char *));
if (!this->mem) {
free(this);
return NULL;
@@ -1758,7 +1758,7 @@ static void *init_class (xine_t *xine, void *data) {
printf("input_dvd.c: config = %p\n", config);
#endif
- this = (dvd_input_class_t *) xine_xmalloc (sizeof (dvd_input_class_t));
+ this = (dvd_input_class_t *) calloc(1, sizeof (dvd_input_class_t));
if (!this)
return NULL;
@@ -1820,8 +1820,7 @@ static void *init_class (xine_t *xine, void *data) {
"playing scrambled DVDs."), 20, NULL, NULL);
xine_setenv("DVDCSS_METHOD", decrypt_modes[mode], 0);
- css_cache_default = (char *)malloc(strlen(xine_get_homedir()) + 10);
- sprintf(css_cache_default, "%s/.dvdcss/", xine_get_homedir());
+ asprintf(&css_cache_default, "%s/.dvdcss/", xine_get_homedir());
css_cache = config->register_filename(config, "media.dvd.css_cache_path", css_cache_default, XINE_CONFIG_STRING_IS_DIRECTORY_NAME,
_("path to the title key cache"),
_("Since cracking the copy protection of scrambled DVDs can "
diff --git a/src/input/input_file.c b/src/input/input_file.c
index f81103dcd..2187f0007 100644
--- a/src/input/input_file.c
+++ b/src/input/input_file.c
@@ -145,6 +145,9 @@ static int check_mmap_file(file_input_plugin_t *this) {
static off_t file_plugin_read (input_plugin_t *this_gen, char *buf, off_t len) {
file_input_plugin_t *this = (file_input_plugin_t *) this_gen;
+ if (len < 0)
+ return -1;
+
#ifdef HAVE_MMAP
if ( check_mmap_file(this) ) {
off_t l = len;
@@ -166,6 +169,13 @@ static buf_element_t *file_plugin_read_block (input_plugin_t *this_gen, fifo_buf
file_input_plugin_t *this = (file_input_plugin_t *) this_gen;
buf_element_t *buf = fifo->buffer_pool_alloc (fifo);
+ if (todo > buf->max_size)
+ todo = buf->max_size;
+ if (todo < 0) {
+ buf->free_buffer (buf);
+ return NULL;
+ }
+
buf->type = BUF_DEMUX_BLOCK;
#ifdef HAVE_MMAP
@@ -421,7 +431,7 @@ static input_plugin_t *file_class_get_instance (input_class_t *cls_gen, xine_str
return NULL;
}
- this = (file_input_plugin_t *) xine_xmalloc (sizeof (file_input_plugin_t));
+ this = (file_input_plugin_t *) calloc(1, sizeof (file_input_plugin_t));
this->stream = stream;
this->mrl = mrl;
this->fh = -1;
@@ -689,9 +699,9 @@ static xine_mrl_t **file_class_get_dir (input_class_t *this_gen,
return NULL;
}
- dir_files = (xine_mrl_t *) xine_xmalloc(sizeof(xine_mrl_t) * MAXFILES);
- hide_files = (xine_mrl_t *) xine_xmalloc(sizeof(xine_mrl_t) * MAXFILES);
- norm_files = (xine_mrl_t *) xine_xmalloc(sizeof(xine_mrl_t) * MAXFILES);
+ dir_files = (xine_mrl_t *) calloc(MAXFILES, sizeof(xine_mrl_t));
+ hide_files = (xine_mrl_t *) calloc(MAXFILES, sizeof(xine_mrl_t));
+ norm_files = (xine_mrl_t *) calloc(MAXFILES, sizeof(xine_mrl_t));
while((pdirent = readdir(pdir)) != NULL) {
@@ -708,11 +718,8 @@ static xine_mrl_t **file_class_get_dir (input_class_t *this_gen,
}
else {
- dir_files[num_dir_files].mrl = (char *)
- xine_xmalloc(strlen(current_dir_slashed) + 1 + strlen(pdirent->d_name) + 1);
-
dir_files[num_dir_files].origin = strdup(current_dir);
- sprintf(dir_files[num_dir_files].mrl, "%s%s",
+ asprintf(&(dir_files[num_dir_files].mrl), "%s%s",
current_dir_slashed, pdirent->d_name);
dir_files[num_dir_files].link = NULL;
dir_files[num_dir_files].type = get_file_type(fullfilename, current_dir, this->xine);
@@ -730,8 +737,9 @@ static xine_mrl_t **file_class_get_dir (input_class_t *this_gen,
xprintf (this->xine, XINE_VERBOSITY_DEBUG,
"input_file: readlink() failed: %s\n", strerror(errno));
else {
- dir_files[num_dir_files].link = (char *) xine_xmalloc(linksize + 1);
- strncpy(dir_files[num_dir_files].link, linkbuf, linksize);
+ dir_files[num_dir_files].link =
+ strndup(linkbuf, linksize);
+
dir_files[num_dir_files].type |= get_file_type(dir_files[num_dir_files].link, current_dir, this->xine);
}
}
@@ -746,11 +754,8 @@ static xine_mrl_t **file_class_get_dir (input_class_t *this_gen,
/* if user don't want to see hidden files, ignore them */
if(this->show_hidden_files) {
- hide_files[num_hide_files].mrl = (char *)
- xine_xmalloc(strlen(current_dir_slashed) + 1 + strlen(pdirent->d_name) + 1);
-
hide_files[num_hide_files].origin = strdup(current_dir);
- sprintf(hide_files[num_hide_files].mrl, "%s%s",
+ asprintf(&(hide_files[num_hide_files].mrl), "%s%s",
current_dir_slashed, pdirent->d_name);
hide_files[num_hide_files].link = NULL;
hide_files[num_hide_files].type = get_file_type(fullfilename, current_dir, this->xine);
@@ -769,9 +774,8 @@ static xine_mrl_t **file_class_get_dir (input_class_t *this_gen,
"input_file: readlink() failed: %s\n", strerror(errno));
}
else {
- hide_files[num_hide_files].link = (char *)
- xine_xmalloc(linksize + 1);
- strncpy(hide_files[num_hide_files].link, linkbuf, linksize);
+ hide_files[num_hide_files].link =
+ strndup(linkbuf, linksize);
hide_files[num_hide_files].type |= get_file_type(hide_files[num_hide_files].link, current_dir, this->xine);
}
}
@@ -782,11 +786,8 @@ static xine_mrl_t **file_class_get_dir (input_class_t *this_gen,
} /* So a *normal* one. */
else {
- norm_files[num_norm_files].mrl = (char *)
- xine_xmalloc(strlen(current_dir_slashed) + 1 + strlen(pdirent->d_name) + 1);
-
norm_files[num_norm_files].origin = strdup(current_dir);
- sprintf(norm_files[num_norm_files].mrl, "%s%s",
+ asprintf(&(norm_files[num_norm_files].mrl), "%s%s",
current_dir_slashed, pdirent->d_name);
norm_files[num_norm_files].link = NULL;
norm_files[num_norm_files].type = get_file_type(fullfilename, current_dir, this->xine);
@@ -805,9 +806,8 @@ static xine_mrl_t **file_class_get_dir (input_class_t *this_gen,
"input_file: readlink() failed: %s\n", strerror(errno));
}
else {
- norm_files[num_norm_files].link = (char *)
- xine_xmalloc(linksize + 1);
- strncpy(norm_files[num_norm_files].link, linkbuf, linksize);
+ norm_files[num_norm_files].link =
+ strndup(linkbuf, linksize);
norm_files[num_norm_files].type |= get_file_type(norm_files[num_norm_files].link, current_dir, this->xine);
}
}
@@ -849,7 +849,7 @@ static xine_mrl_t **file_class_get_dir (input_class_t *this_gen,
if(num_files >= this->mrls_allocated_entries) {
++this->mrls_allocated_entries;
this->mrls = realloc(this->mrls, (this->mrls_allocated_entries+1) * sizeof(xine_mrl_t*));
- this->mrls[num_files] = (xine_mrl_t *) xine_xmalloc(sizeof(xine_mrl_t));
+ this->mrls[num_files] = calloc(1, sizeof(xine_mrl_t));
}
else
memset(this->mrls[num_files], 0, sizeof(xine_mrl_t));
@@ -867,7 +867,7 @@ static xine_mrl_t **file_class_get_dir (input_class_t *this_gen,
if(num_files >= this->mrls_allocated_entries) {
++this->mrls_allocated_entries;
this->mrls = realloc(this->mrls, (this->mrls_allocated_entries+1) * sizeof(xine_mrl_t*));
- this->mrls[num_files] = (xine_mrl_t *) xine_xmalloc(sizeof(xine_mrl_t));
+ this->mrls[num_files] = calloc(1, sizeof(xine_mrl_t));
}
else
memset(this->mrls[num_files], 0, sizeof(xine_mrl_t));
@@ -885,7 +885,7 @@ static xine_mrl_t **file_class_get_dir (input_class_t *this_gen,
if(num_files >= this->mrls_allocated_entries) {
++this->mrls_allocated_entries;
this->mrls = realloc(this->mrls, (this->mrls_allocated_entries+1) * sizeof(xine_mrl_t*));
- this->mrls[num_files] = (xine_mrl_t *) xine_xmalloc(sizeof(xine_mrl_t));
+ this->mrls[num_files] = calloc(1, sizeof(xine_mrl_t));
}
else
memset(this->mrls[num_files], 0, sizeof(xine_mrl_t));
@@ -965,7 +965,7 @@ static void *init_plugin (xine_t *xine, void *data) {
file_input_class_t *this;
config_values_t *config;
- this = (file_input_class_t *) xine_xmalloc (sizeof (file_input_class_t));
+ this = (file_input_class_t *) calloc(1, sizeof (file_input_class_t));
this->xine = xine;
this->config = xine->config;
@@ -979,7 +979,7 @@ static void *init_plugin (xine_t *xine, void *data) {
this->input_class.dispose = file_class_dispose;
this->input_class.eject_media = NULL;
- this->mrls = (xine_mrl_t **) xine_xmalloc(sizeof(xine_mrl_t*));
+ this->mrls = (xine_mrl_t **) calloc(1, sizeof(xine_mrl_t*));
this->mrls_allocated_entries = 0;
{
diff --git a/src/input/input_gnome_vfs.c b/src/input/input_gnome_vfs.c
index 0848b9206..a3dfafdd5 100644
--- a/src/input/input_gnome_vfs.c
+++ b/src/input/input_gnome_vfs.c
@@ -121,6 +121,13 @@ gnomevfs_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo,
off_t total_bytes;
buf_element_t *buf = fifo->buffer_pool_alloc (fifo);
+ if (todo > buf->max_size)
+ todo = buf->max_size;
+ if (todo < 0) {
+ buf->free_buffer (buf);
+ return NULL;
+ }
+
buf->content = buf->mem;
buf->type = BUF_DEMUX_BLOCK;
diff --git a/src/input/input_http.c b/src/input/input_http.c
index af696ca14..c831dfc59 100644
--- a/src/input/input_http.c
+++ b/src/input/input_http.c
@@ -82,6 +82,8 @@ typedef struct {
char auth[BUFSIZE];
char proxyauth[BUFSIZE];
+
+ char *mime_type;
char *proto;
char *user;
@@ -235,26 +237,16 @@ static int http_plugin_basicauth (const char *user, const char *password, char*
char *tmp;
char *sptr;
char *dptr;
- int totlen;
+ size_t count;
int enclen;
- int count;
-
- totlen = strlen (user) + 1;
- if(password != NULL)
- totlen += strlen (password);
- enclen = ((totlen + 2) / 3 ) * 4 + 1;
+ count = asprintf(&tmp, "%s:%s", user, (password != NULL) ? password : "");
+
+ enclen = ((count + 2) / 3 ) * 4 + 1;
if (len < enclen)
return -1;
-
- tmp = malloc (sizeof(char) * (totlen + 1));
- strcpy (tmp, user);
- strcat (tmp, ":");
- if (password != NULL)
- strcat (tmp, password);
-
- count = strlen(tmp);
+
sptr = tmp;
dptr = dest;
while (count >= 3) {
@@ -429,6 +421,9 @@ static off_t http_plugin_read (input_plugin_t *this_gen,
num_bytes = 0;
+ if (nlen < 0)
+ return -1;
+
if (this->curpos < this->preview_size) {
if (nlen > (this->preview_size - this->curpos))
@@ -445,7 +440,7 @@ static off_t http_plugin_read (input_plugin_t *this_gen,
n = nlen - num_bytes;
- if (n) {
+ if (n > 0) {
int read_bytes;
read_bytes = http_plugin_read_int (this, &buf[num_bytes], n);
@@ -511,6 +506,13 @@ static buf_element_t *http_plugin_read_block (input_plugin_t *this_gen, fifo_buf
off_t total_bytes;
buf_element_t *buf = fifo->buffer_pool_alloc (fifo);
+ if (todo > buf->max_size)
+ todo = buf->max_size;
+ if (todo < 0) {
+ buf->free_buffer (buf);
+ return NULL;
+ }
+
buf->content = buf->mem;
buf->type = BUF_DEMUX_BLOCK;
@@ -562,7 +564,7 @@ static off_t http_plugin_seek(input_plugin_t *this_gen, off_t offset, int origin
if ((origin == SEEK_CUR) && (offset >= 0)) {
for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) {
- if( !this_gen->read (this_gen, this->seek_buf, BUFSIZE) )
+ if( this_gen->read (this_gen, this->seek_buf, BUFSIZE) <= 0 )
return this->curpos;
}
@@ -584,7 +586,7 @@ static off_t http_plugin_seek(input_plugin_t *this_gen, off_t offset, int origin
offset -= this->curpos;
for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) {
- if( !this_gen->read (this_gen, this->seek_buf, BUFSIZE) )
+ if( this_gen->read (this_gen, this->seek_buf, BUFSIZE) <= 0 )
return this->curpos;
}
@@ -602,17 +604,20 @@ static const char* http_plugin_get_mrl (input_plugin_t *this_gen) {
}
static int http_plugin_get_optional_data (input_plugin_t *this_gen,
- void *data, int data_type) {
+ void *const data, int data_type) {
+ void **const ptr = (void **const) data;
http_input_plugin_t *this = (http_input_plugin_t *) this_gen;
switch (data_type) {
case INPUT_OPTIONAL_DATA_PREVIEW:
-
memcpy (data, this->preview, this->preview_size);
return this->preview_size;
- break;
+ case INPUT_OPTIONAL_DATA_MIME_TYPE:
+ *ptr = this->mime_type;
+ case INPUT_OPTIONAL_DATA_DEMUX_MIME_TYPE:
+ return *this->mime_type ? INPUT_OPTIONAL_SUCCESS : INPUT_OPTIONAL_UNSUPPORTED;
}
return INPUT_OPTIONAL_UNSUPPORTED;
@@ -637,6 +642,7 @@ static void http_plugin_dispose (input_plugin_t *this_gen ) {
if (this->user) free(this->user);
if (this->password) free(this->password);
if (this->uri) free(this->uri);
+ if (this->mime_type) free(this->mime_type);
free (this);
}
@@ -661,11 +667,13 @@ static int http_plugin_open (input_plugin_t *this_gen ) {
int done, len, linenum;
int httpcode;
int res;
- int buflen;
+ size_t buflen;
int use_proxy;
int proxyport;
int mpegurl_redirect = 0;
-
+ char mime_type[256];
+
+ mime_type[0] = 0;
use_proxy = this_class->proxyhost && strlen(this_class->proxyhost);
if (use_proxy) {
@@ -753,43 +761,38 @@ static int http_plugin_open (input_plugin_t *this_gen ) {
if (use_proxy) {
if (this->port != DEFAULT_HTTP_PORT) {
- snprintf (this->buf, BUFSIZE, "GET http://%s:%d%s HTTP/1.0\015\012",
- this->host, this->port, this->uri);
+ buflen = snprintf (this->buf, BUFSIZE, "GET http://%s:%d%s HTTP/1.0\015\012",
+ this->host, this->port, this->uri);
} else {
- snprintf (this->buf, BUFSIZE, "GET http://%s%s HTTP/1.0\015\012",
- this->host, this->uri);
+ buflen = snprintf (this->buf, BUFSIZE, "GET http://%s%s HTTP/1.0\015\012",
+ this->host, this->uri);
}
}
else
- snprintf (this->buf, BUFSIZE, "GET %s HTTP/1.0\015\012", this->uri);
+ buflen = snprintf (this->buf, BUFSIZE, "GET %s HTTP/1.0\015\012", this->uri);
- buflen = strlen(this->buf);
if (this->port != DEFAULT_HTTP_PORT)
- snprintf (this->buf + buflen, BUFSIZE - buflen, "Host: %s:%d\015\012",
- this->host, this->port);
+ buflen += snprintf (this->buf + buflen, BUFSIZE - buflen, "Host: %s:%d\015\012",
+ this->host, this->port);
else
- snprintf (this->buf + buflen, BUFSIZE - buflen, "Host: %s\015\012",
- this->host);
+ buflen += snprintf (this->buf + buflen, BUFSIZE - buflen, "Host: %s\015\012",
+ this->host);
- buflen = strlen(this->buf);
if (this_class->proxyuser && strlen(this_class->proxyuser)) {
- snprintf (this->buf + buflen, BUFSIZE - buflen,
- "Proxy-Authorization: Basic %s\015\012", this->proxyauth);
- buflen = strlen(this->buf);
+ buflen += snprintf (this->buf + buflen, BUFSIZE - buflen,
+ "Proxy-Authorization: Basic %s\015\012", this->proxyauth);
}
if (this->user && strlen(this->user)) {
- snprintf (this->buf + buflen, BUFSIZE - buflen,
- "Authorization: Basic %s\015\012", this->auth);
- buflen = strlen(this->buf);
+ buflen += snprintf (this->buf + buflen, BUFSIZE - buflen,
+ "Authorization: Basic %s\015\012", this->auth);
}
- snprintf(this->buf + buflen, BUFSIZE - buflen,
- "User-Agent: xine/%s\015\012"
- "Accept: */*\015\012"
- "Icy-MetaData: 1\015\012"
- "\015\012",
- VERSION);
- buflen = strlen(this->buf);
+ buflen += snprintf(this->buf + buflen, BUFSIZE - buflen,
+ "User-Agent: xine/%s\015\012"
+ "Accept: */*\015\012"
+ "Icy-MetaData: 1\015\012"
+ "\015\012",
+ VERSION);
if (_x_io_tcp_write (this->stream, this->fh, this->buf, buflen) != buflen) {
_x_message(this->stream, XINE_MSG_CONNECTION_REFUSED, "couldn't send request", NULL);
xprintf(this_class->xine, XINE_VERBOSITY_DEBUG, "input_http: couldn't send request\n");
@@ -934,7 +937,11 @@ static int http_plugin_open (input_plugin_t *this_gen ) {
/* content type */
if (!strncasecmp(this->buf, TAG_CONTENT_TYPE, sizeof(TAG_CONTENT_TYPE) - 1)) {
- if (!strncasecmp(this->buf + sizeof(TAG_CONTENT_TYPE) - 1, "video/nsv", 9)) {
+ const char *type = this->buf + sizeof (TAG_CONTENT_TYPE) - 1;
+ while (isspace (*type))
+ ++type;
+ sprintf (mime_type, "%.255s", type);
+ if (!strncasecmp (type, "video/nsv", 9)) {
lprintf("shoutcast nsv detected\n");
this->is_nsv = 1;
}
@@ -999,12 +1006,15 @@ static int http_plugin_open (input_plugin_t *this_gen ) {
this->preview_size = http_plugin_read_int (this, this->preview, MAX_PREVIEW_SIZE);
}
if (this->preview_size < 0) {
+ this->preview_size = 0;
xine_log (this->stream->xine, XINE_LOG_MSG, _("input_http: read error %d\n"), errno);
return -12;
}
lprintf("preview_size=%"PRId64"\n", this->preview_size);
this->curpos = 0;
+ if (*mime_type)
+ this->mime_type = strdup (mime_type);
return 1;
}
@@ -1022,11 +1032,10 @@ static input_plugin_t *http_class_get_instance (input_class_t *cls_gen, xine_str
strncasecmp (mrl, "peercast://pls/", 15)) {
return NULL;
}
- this = (http_input_plugin_t *) xine_xmalloc(sizeof(http_input_plugin_t));
+ this = calloc(1, sizeof(http_input_plugin_t));
if (!strncasecmp (mrl, "peercast://pls/", 15)) {
- this->mrl = xine_xmalloc (30 + strlen(mrl) - 15);
- sprintf (this->mrl, "http://127.0.0.1:7144/stream/%s", mrl+15);
+ asprintf (&this->mrl, "http://127.0.0.1:7144/stream/%s", mrl+15);
} else {
this->mrl = strdup (mrl);
}
@@ -1073,7 +1082,7 @@ static void *init_class (xine_t *xine, void *data) {
config_values_t *config;
char *proxy_env;
- this = (http_input_class_t *) xine_xmalloc (sizeof (http_input_class_t));
+ this = calloc(1, sizeof (http_input_class_t));
this->xine = xine;
this->config = xine->config;
@@ -1090,25 +1099,21 @@ static void *init_class (xine_t *xine, void *data) {
/*
* honour http_proxy envvar
*/
- if((proxy_env = getenv("http_proxy")) && (strlen(proxy_env))) {
+ if((proxy_env = getenv("http_proxy")) && *proxy_env) {
int proxy_port = DEFAULT_HTTP_PORT;
- char *http_proxy = xine_xmalloc(strlen(proxy_env) + 1);
char *p;
if(!strncmp(proxy_env, "http://", 7))
proxy_env += 7;
+
+ this->proxyhost_env = strdup(proxy_env);
- sprintf(http_proxy, "%s", proxy_env);
-
- if((p = strrchr(&http_proxy[0], ':')) && (strlen(p) > 1)) {
+ if((p = strrchr(this->proxyhost_env, ':')) && (strlen(p) > 1)) {
*p++ = '\0';
proxy_port = (int) strtol(p, &p, 10);
}
- this->proxyhost_env = strdup(http_proxy);
this->proxyport_env = proxy_port;
-
- free(http_proxy);
}
else
proxy_env = NULL; /* proxy_env can be "" */
diff --git a/src/input/input_mms.c b/src/input/input_mms.c
index 6a1e729e6..cd88a0609 100644
--- a/src/input/input_mms.c
+++ b/src/input/input_mms.c
@@ -122,6 +122,13 @@ static buf_element_t *mms_plugin_read_block (input_plugin_t *this_gen,
lprintf ("mms_plugin_read_block: %"PRId64" bytes...\n", todo);
+ if (todo > buf->max_size)
+ todo = buf->max_size;
+ if (todo < 0) {
+ buf->free_buffer (buf);
+ return NULL;
+ }
+
buf->content = buf->mem;
buf->type = BUF_DEMUX_BLOCK;
@@ -401,7 +408,7 @@ static input_plugin_t *mms_class_get_instance (input_class_t *cls_gen, xine_stre
return NULL;
}
- this = (mms_input_plugin_t *) xine_xmalloc (sizeof (mms_input_plugin_t));
+ this = calloc(1, sizeof (mms_input_plugin_t));
cls->ip = this;
this->stream = stream;
this->mms = NULL;
@@ -459,7 +466,7 @@ static void *init_class (xine_t *xine, void *data) {
mms_input_class_t *this;
- this = (mms_input_class_t *) xine_xmalloc (sizeof (mms_input_class_t));
+ this = calloc(1, sizeof (mms_input_class_t));
this->xine = xine;
this->ip = NULL;
diff --git a/src/input/input_net.c b/src/input/input_net.c
index fe78c93f4..d9da27b54 100644
--- a/src/input/input_net.c
+++ b/src/input/input_net.c
@@ -253,6 +253,9 @@ static off_t net_plugin_read (input_plugin_t *this_gen,
lprintf("reading %" PRIdMAX " bytes...\n", (intmax_t)len);
+ if (len < 0)
+ return -1;
+
total=0;
if (this->curpos < this->preview_size) {
n = this->preview_size - this->curpos;
@@ -288,6 +291,13 @@ static buf_element_t *net_plugin_read_block (input_plugin_t *this_gen,
buf_element_t *buf = fifo->buffer_pool_alloc (fifo);
off_t total_bytes;
+ if (todo > buf->max_size)
+ todo = buf->max_size;
+ if (todo < 0) {
+ buf->free_buffer (buf);
+ return NULL;
+ }
+
buf->content = buf->mem;
buf->type = BUF_DEMUX_BLOCK;
@@ -331,7 +341,7 @@ static off_t net_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin
if ((origin == SEEK_CUR) && (offset >= 0)) {
for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) {
- if( !this_gen->read (this_gen, this->seek_buf, BUFSIZE) )
+ if( this_gen->read (this_gen, this->seek_buf, BUFSIZE) <= 0 )
return this->curpos;
}
@@ -353,7 +363,7 @@ static off_t net_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin
offset -= this->curpos;
for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) {
- if( !this_gen->read (this_gen, this->seek_buf, BUFSIZE) )
+ if( this_gen->read (this_gen, this->seek_buf, BUFSIZE) <= 0 )
return this->curpos;
}
@@ -480,7 +490,7 @@ static input_plugin_t *net_class_get_instance (input_class_t *cls_gen, xine_stre
return NULL;
}
- this = xine_xmalloc(sizeof(net_input_plugin_t));
+ this = calloc(1, sizeof(net_input_plugin_t));
this->mrl = strdup(mrl);
this->host_port = strdup(filename);
this->stream = stream;
@@ -528,7 +538,7 @@ static void *init_class (xine_t *xine, void *data) {
net_input_class_t *this;
- this = (net_input_class_t *) xine_xmalloc(sizeof(net_input_class_t));
+ this = calloc(1, sizeof(net_input_class_t));
this->config = xine->config;
this->xine = xine;
diff --git a/src/input/input_plugin.h b/src/input/input_plugin.h
index 1d1e5cf53..080e05476 100644
--- a/src/input/input_plugin.h
+++ b/src/input/input_plugin.h
@@ -307,6 +307,13 @@ struct input_plugin_s {
#define INPUT_OPTIONAL_DATA_SPULANG 3
#define INPUT_OPTIONAL_DATA_PREVIEW 7
+/* buffer is a const char **; the string is freed by the input plugin. */
+#define INPUT_OPTIONAL_DATA_MIME_TYPE 8
+/* buffer is unused; true if the demuxer should be determined by the MIME type */
+#define INPUT_OPTIONAL_DATA_DEMUX_MIME_TYPE 9
+/* buffer is a const char **; the string is static or freed by the input plugin. */
+#define INPUT_OPTIONAL_DATA_DEMUXER 10
+
#define MAX_MRL_ENTRIES 255
#define MAX_PREVIEW_SIZE 4096
@@ -333,65 +340,38 @@ struct input_plugin_s {
/*
* Freeing/zeroing all of entries of given mrl.
*/
-#define MRL_ZERO(m) { \
- if((m)) { \
- if((m)->origin) \
- free((m)->origin); \
- if((m)->mrl) \
- free((m)->mrl); \
- if((m)->link) \
- free((m)->link); \
- (m)->origin = NULL; \
- (m)->mrl = NULL; \
- (m)->link = NULL; \
- (m)->type = 0; \
- (m)->size = (off_t) 0; \
- } \
-}
+#define MRL_ZERO(m) { \
+ if((m)) { \
+ free((m)->origin); \
+ free((m)->mrl); \
+ free((m)->link); \
+ (m)->origin = NULL; \
+ (m)->mrl = NULL; \
+ (m)->link = NULL; \
+ (m)->type = 0; \
+ (m)->size = (off_t) 0; \
+ } \
+ }
/*
* Duplicate two mrls entries (s = source, d = destination).
*/
-#define MRL_DUPLICATE(s, d) { \
- _x_assert((s) != NULL); \
- _x_assert((d) != NULL); \
- \
- if((s)->origin) { \
- if((d)->origin) { \
- (d)->origin = (char *) realloc((d)->origin, strlen((s)->origin) + 1); \
- sprintf((d)->origin, "%s", (s)->origin); \
- } \
- else \
- (d)->origin = strdup((s)->origin); \
- } \
- else \
- (d)->origin = NULL; \
- \
- if((s)->mrl) { \
- if((d)->mrl) { \
- (d)->mrl = (char *) realloc((d)->mrl, strlen((s)->mrl) + 1); \
- sprintf((d)->mrl, "%s", (s)->mrl); \
- } \
- else \
- (d)->mrl = strdup((s)->mrl); \
- } \
- else \
- (d)->mrl = NULL; \
- \
- if((s)->link) { \
- if((d)->link) { \
- (d)->link = (char *) realloc((d)->link, strlen((s)->link) + 1); \
- sprintf((d)->link, "%s", (s)->link); \
- } \
- else \
- (d)->link = strdup((s)->link); \
- } \
- else \
- (d)->link = NULL; \
- \
- (d)->type = (s)->type; \
- (d)->size = (s)->size; \
-}
+#define MRL_DUPLICATE(s, d) { \
+ _x_assert((s) != NULL); \
+ _x_assert((d) != NULL); \
+ \
+ free((d)->origin); \
+ (d)->origin = (s)->origin ? strdup((s)->origin) : NULL; \
+ \
+ free((d)->mrl); \
+ (d)->mrl = (s)->mrl ? strdup((s)->mrl) : NULL; \
+ \
+ free((d)->link); \
+ (d)->link = (s)->link ? strdup((s)->link) : NULL; \
+ \
+ (d)->type = (s)->type; \
+ (d)->size = (s)->size; \
+ }
/*
* Duplicate two arrays of mrls (s = source, d = destination).
diff --git a/src/input/input_pnm.c b/src/input/input_pnm.c
index 680c5b1e8..f609695d5 100644
--- a/src/input/input_pnm.c
+++ b/src/input/input_pnm.c
@@ -82,10 +82,9 @@ static off_t pnm_plugin_read (input_plugin_t *this_gen,
lprintf ("pnm_plugin_read: %"PRId64" bytes ...\n", len);
- nbc_check_buffers (this->nbc);
-
n = pnm_read (this->pnm, buf, len);
- this->curpos += n;
+ if (n >= 0)
+ this->curpos += n;
return n;
}
@@ -98,6 +97,13 @@ static buf_element_t *pnm_plugin_read_block (input_plugin_t *this_gen,
lprintf ("pnm_plugin_read_block: %"PRId64" bytes...\n", todo);
+ if (todo > buf->max_size)
+ todo = buf->max_size;
+ if (todo < 0) {
+ buf->free_buffer (buf);
+ return NULL;
+ }
+
buf->content = buf->mem;
buf->type = BUF_DEMUX_BLOCK;
@@ -125,10 +131,16 @@ static off_t pnm_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin
if ((origin == SEEK_CUR) && (offset >= 0)) {
for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) {
- this->curpos += pnm_plugin_read (this_gen, this->scratch, BUFSIZE);
+ off_t n = pnm_plugin_read (this_gen, this->scratch, BUFSIZE);
+ if (n <= 0)
+ return this->curpos;
+ this->curpos += n;
}
- this->curpos += pnm_plugin_read (this_gen, this->scratch, offset);
+ off_t n = pnm_plugin_read (this_gen, this->scratch, offset);
+ if (n <= 0)
+ return this->curpos;
+ this->curpos += n;
}
return this->curpos;
@@ -231,7 +243,7 @@ static input_plugin_t *pnm_class_get_instance (input_class_t *cls_gen, xine_stre
return NULL;
}
- this = (pnm_input_plugin_t *) xine_xmalloc (sizeof (pnm_input_plugin_t));
+ this = calloc(1, sizeof (pnm_input_plugin_t));
this->stream = stream;
this->pnm = NULL;
@@ -276,7 +288,7 @@ static void *init_class (xine_t *xine, void *data) {
pnm_input_class_t *this;
- this = (pnm_input_class_t *) xine_xmalloc (sizeof (pnm_input_class_t));
+ this = calloc(1, sizeof (pnm_input_class_t));
this->xine = xine;
diff --git a/src/input/input_pvr.c b/src/input/input_pvr.c
index 1b8000072..a9c92e42e 100644
--- a/src/input/input_pvr.c
+++ b/src/input/input_pvr.c
@@ -376,10 +376,10 @@ static void pvrscr_exit (scr_plugin_t *scr) {
free(this);
}
-static pvrscr_t* pvrscr_init (void) {
+static pvrscr_t *XINE_MALLOC pvrscr_init (void) {
pvrscr_t *this;
- this = (pvrscr_t *) xine_xmalloc(sizeof(pvrscr_t));
+ this = calloc(1, sizeof(pvrscr_t));
this->scr.interface_version = 3;
this->scr.get_priority = pvrscr_get_priority;
@@ -424,6 +424,9 @@ static uint32_t pvr_plugin_get_capabilities (input_plugin_t *this_gen) {
static off_t pvr_plugin_read (input_plugin_t *this_gen, char *buf, off_t len) {
/*pvr_input_plugin_t *this = (pvr_input_plugin_t *) this_gen;*/
+ if (len < 4)
+ return -1;
+
/* FIXME: Tricking the demux_mpeg_block plugin */
buf[0] = 0;
buf[1] = 0;
@@ -504,34 +507,24 @@ static void pvr_adjust_realtime_speed(pvr_input_plugin_t *this, fifo_buffer_t *f
}
#define PVR_FILENAME "%s%08d_%08d.vob"
-#define PVR_FILENAME_SIZE 1+8+1+8+4+1
static char *make_temp_name(pvr_input_plugin_t *this, int page) {
-
char *filename;
- int size = strlen(this->tmp_prefix)+PVR_FILENAME_SIZE;
- filename = malloc(size);
-
- snprintf(filename, size, PVR_FILENAME, this->tmp_prefix, this->session, page);
+ asprintf(&filename, PVR_FILENAME, this->tmp_prefix, this->session, page);
return filename;
}
#define SAVE_BASE_FILENAME "ch%03d %02d-%02d-%04d %02d:%02d:%02d"
-#define SAVE_BASE_FILENAME_SIZE 2+3+1+2+1+2+1+4+1+2+1+2+1+2+1
static char *make_base_save_name(int channel, time_t tm) {
-
struct tm rec_time;
char *filename;
- int size = SAVE_BASE_FILENAME_SIZE;
- filename = malloc(size);
-
localtime_r(&tm, &rec_time);
- snprintf(filename, size, SAVE_BASE_FILENAME,
+ asprintf(&filename, SAVE_BASE_FILENAME,
channel, rec_time.tm_mon+1, rec_time.tm_mday,
rec_time.tm_year+1900, rec_time.tm_hour, rec_time.tm_min,
rec_time.tm_sec);
@@ -539,16 +532,11 @@ static char *make_base_save_name(int channel, time_t tm) {
}
#define SAVE_FILENAME "%s%s_%04d.vob"
-#define SAVE_FILENAME_SIZE 1+4+4+1
static char *make_save_name(pvr_input_plugin_t *this, char *base, int page) {
-
char *filename;
- int size = strlen(this->save_prefix)+strlen(base)+SAVE_FILENAME_SIZE;
- filename = malloc(size);
-
- snprintf(filename, size, SAVE_FILENAME, this->save_prefix, base, page);
+ asprintf(&filename, SAVE_FILENAME, this->save_prefix, base, page);
return filename;
}
@@ -1219,6 +1207,14 @@ static buf_element_t *pvr_plugin_read_block (input_plugin_t *this_gen, fifo_buff
return NULL;
}
+ buf = fifo->buffer_pool_alloc (fifo);
+ if (todo > buf->max_size)
+ todo = buf->max_size;
+ if (todo < 0) {
+ buf->free_buffer(buf);
+ return NULL;
+ }
+
if( this->scr_tunning == -2 )
speed = this->speed_before_pause;
@@ -1242,7 +1238,6 @@ static buf_element_t *pvr_plugin_read_block (input_plugin_t *this_gen, fifo_buff
pvr_event_handler(this);
- buf = fifo->buffer_pool_alloc (fifo);
buf->content = buf->mem;
pthread_mutex_lock(&this->lock);
@@ -1480,7 +1475,7 @@ static input_plugin_t *pvr_class_get_instance (input_class_t *cls_gen, xine_stre
mrl = strdup(data);
aux = &mrl[5];
- this = (pvr_input_plugin_t *) xine_xmalloc (sizeof (pvr_input_plugin_t));
+ this = calloc(1, sizeof (pvr_input_plugin_t));
this->class = cls;
this->stream = stream;
this->dev_fd = -1;
@@ -1564,7 +1559,7 @@ static void *init_plugin (xine_t *xine, void *data) {
pvr_input_class_t *this;
- this = (pvr_input_class_t *) xine_xmalloc (sizeof (pvr_input_class_t));
+ this = calloc(1, sizeof (pvr_input_class_t));
this->xine = xine;
this->config = xine->config;
diff --git a/src/input/input_rtp.c b/src/input/input_rtp.c
index 25498f289..90bae6670 100644
--- a/src/input/input_rtp.c
+++ b/src/input/input_rtp.c
@@ -453,6 +453,9 @@ static off_t rtp_plugin_read (input_plugin_t *this_gen,
struct timespec timeout;
off_t copied = 0;
+ if (length < 0)
+ return -1;
+
while(length > 0) {
off_t n;
@@ -524,6 +527,12 @@ static buf_element_t *rtp_plugin_read_block (input_plugin_t *this_gen,
buf_element_t *buf = fifo->buffer_pool_alloc (fifo);
int total_bytes;
+ if (todo > buf->max_size)
+ todo = buf->max_size;
+ if (todo < 0) {
+ buf->free_buffer (buf);
+ return NULL;
+ }
buf->content = buf->mem;
buf->type = BUF_DEMUX_BLOCK;
@@ -609,11 +618,14 @@ static int rtp_plugin_get_optional_data (input_plugin_t *this_gen,
if (data_type == INPUT_OPTIONAL_DATA_PREVIEW) {
if (!this->preview_read_done) {
this->preview_size = rtp_plugin_read(this_gen, this->preview, MAX_PREVIEW_SIZE);
+ if (this->preview_size < 0)
+ this->preview_size = 0;
lprintf("Preview data length = %d\n", this->preview_size);
this->preview_read_done = 1;
}
- memcpy(data, this->preview, this->preview_size);
+ if (this->preview_size)
+ memcpy(data, this->preview, this->preview_size);
return this->preview_size;
}
else {
@@ -717,7 +729,7 @@ static input_plugin_t *rtp_class_get_instance (input_class_t *cls_gen,
}
}
- this = (rtp_input_plugin_t *) xine_xmalloc(sizeof(rtp_input_plugin_t));
+ this = calloc(1, sizeof(rtp_input_plugin_t));
this->stream = stream;
this->mrl = mrl;
this->filename = filename;
@@ -784,7 +796,7 @@ static void *init_class (xine_t *xine, void *data) {
rtp_input_class_t *this;
- this = (rtp_input_class_t *) xine_xmalloc(sizeof(rtp_input_class_t));
+ this = calloc(1, sizeof(rtp_input_class_t));
this->config = xine->config;
this->xine = xine;
diff --git a/src/input/input_rtsp.c b/src/input/input_rtsp.c
index 2895edf5d..fad395e0b 100644
--- a/src/input/input_rtsp.c
+++ b/src/input/input_rtsp.c
@@ -83,10 +83,9 @@ static off_t rtsp_plugin_read (input_plugin_t *this_gen,
lprintf ("rtsp_plugin_read: %"PRId64" bytes ...\n", len);
- nbc_check_buffers (this->nbc);
-
n = rtsp_session_read (this->rtsp, buf, len);
- this->curpos += n;
+ if (n > 0)
+ this->curpos += n;
return n;
}
@@ -99,6 +98,13 @@ static buf_element_t *rtsp_plugin_read_block (input_plugin_t *this_gen,
lprintf ("rtsp_plugin_read_block: %"PRId64" bytes...\n", todo);
+ if (todo > buf->max_size)
+ todo = buf->max_size;
+ if (todo < 0) {
+ buf->free_buffer (buf);
+ return NULL;
+ }
+
buf->content = buf->mem;
buf->type = BUF_DEMUX_BLOCK;
@@ -125,10 +131,16 @@ static off_t rtsp_plugin_seek (input_plugin_t *this_gen, off_t offset, int origi
if ((origin == SEEK_CUR) && (offset >= 0)) {
for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) {
- this->curpos += rtsp_plugin_read (this_gen, this->scratch, BUFSIZE);
+ off_t n = rtsp_plugin_read (this_gen, this->scratch, BUFSIZE);
+ if (n <= 0)
+ return this->curpos;
+ this->curpos += n;
}
- this->curpos += rtsp_plugin_read (this_gen, this->scratch, offset);
+ off_t n = rtsp_plugin_read (this_gen, this->scratch, offset);
+ if (n <= 0)
+ return this->curpos;
+ this->curpos += n;
}
return this->curpos;
@@ -246,7 +258,7 @@ static input_plugin_t *rtsp_class_get_instance (input_class_t *cls_gen, xine_str
if (strncasecmp (mrl, "rtsp://", 6))
return NULL;
- this = (rtsp_input_plugin_t *) xine_xmalloc (sizeof (rtsp_input_plugin_t));
+ this = calloc(1, sizeof (rtsp_input_plugin_t));
this->stream = stream;
this->rtsp = NULL;
@@ -254,8 +266,7 @@ static input_plugin_t *rtsp_class_get_instance (input_class_t *cls_gen, xine_str
/* since we handle only real streams yet, we can savely add
* an .rm extention to force handling by demux_real.
*/
- this->public_mrl = xine_xmalloc (sizeof (char)*(strlen(this->mrl)+10));
- sprintf(this->public_mrl, "%s.rm", this->mrl);
+ asprintf(&this->public_mrl, "%s.rm", this->mrl);
this->nbc = nbc_init (stream);
@@ -298,7 +309,7 @@ static void *init_class (xine_t *xine, void *data) {
rtsp_input_class_t *this;
- this = (rtsp_input_class_t *) xine_xmalloc (sizeof (rtsp_input_class_t));
+ this = calloc(1, sizeof (rtsp_input_class_t));
this->xine = xine;
diff --git a/src/input/input_smb.c b/src/input/input_smb.c
index 7da9c1454..e49eaa889 100644
--- a/src/input/input_smb.c
+++ b/src/input/input_smb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 the xine project
+ * Copyright (C) 2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -51,7 +51,7 @@ typedef struct {
xine_stream_t *stream;
/* File */
- char *mrl;
+ const char *mrl;
int fd;
} smb_input_t;
@@ -69,6 +69,8 @@ smb_plugin_read (input_plugin_t *this_gen, char *buf, off_t len)
smb_input_t *this = (smb_input_t *) this_gen;
off_t n, num_bytes;
+ if (len < 0)
+ return -1;
num_bytes = 0;
while (num_bytes < len)
@@ -89,6 +91,13 @@ smb_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo,
off_t total_bytes;
buf_element_t *buf = fifo->buffer_pool_alloc (fifo);
+ if (todo > buf->max_size)
+ todo = buf->max_size;
+ if (todo < 0) {
+ buf->free_buffer (buf);
+ return NULL;
+ }
+
buf->content = buf->mem;
buf->type = BUF_DEMUX_BLOCK;
@@ -138,7 +147,7 @@ smb_plugin_get_length (input_plugin_t *this_gen)
return st.st_size;
}
-static char*
+static const char*
smb_plugin_get_mrl (input_plugin_t *this_gen)
{
smb_input_t *this = (smb_input_t *) this_gen;
@@ -150,7 +159,7 @@ static uint32_t smb_plugin_get_blocksize (input_plugin_t *this_gen) {
return 0;
}
-static char
+static const char
*smb_class_get_description (input_class_t *this_gen)
{
return _("CIFS/SMB input plugin based on libsmbclient");
@@ -256,8 +265,8 @@ static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen,
}
if ((dir = smbc_opendir(current_path_smb)) >= 0){
- xine_mrl_t *dir_files = (xine_mrl_t *) xine_xmalloc(sizeof(xine_mrl_t) * MAXFILES);
- xine_mrl_t *norm_files = (xine_mrl_t *) xine_xmalloc(sizeof(xine_mrl_t) * MAXFILES);
+ xine_mrl_t *dir_files = (xine_mrl_t *) calloc(MAXFILES, sizeof(xine_mrl_t));
+ xine_mrl_t *norm_files = (xine_mrl_t *) calloc(MAXFILES, sizeof(xine_mrl_t));
int num_dir_files=0;
int num_norm_files=0;
while ((pdirent = smbc_readdir(dir)) != NULL){
@@ -265,9 +274,7 @@ static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen,
dir_files[num_dir_files].link = NULL;
dir_files[num_dir_files].type = mrl_file | mrl_file_directory;
dir_files[num_dir_files].origin = strdup(current_path);
- dir_files[num_dir_files].mrl = (char *) xine_xmalloc(
- strlen(current_path) + 1 + strlen(pdirent->name) + 1);
- sprintf(dir_files[num_dir_files].mrl, "%s/%s", current_path, pdirent->name);
+ asprintf(&(dir_files[num_dir_files].mrl), "%s/%s", current_path, pdirent->name);
dir_files[num_dir_files].size = pdirent->dirlen;
num_dir_files ++;
}else if (pdirent->smbc_type == SMBC_SERVER){
@@ -275,17 +282,14 @@ static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen,
dir_files[num_dir_files].link = NULL;
dir_files[num_dir_files].type = mrl_file | mrl_file_directory;
dir_files[num_dir_files].origin = strdup("smb:/");
- dir_files[num_dir_files].mrl = (char *) xine_xmalloc(strlen("smb:/") + 4);
- sprintf(dir_files[num_dir_files].mrl, "%s/%s", "smb:/", "..");
+ asprintf(&(dir_files[num_dir_files].mrl), "%s/%s", "smb:/", "..");
dir_files[num_dir_files].size = pdirent->dirlen;
num_dir_files ++;
}
dir_files[num_dir_files].link = NULL;
dir_files[num_dir_files].type = mrl_file | mrl_file_directory;
dir_files[num_dir_files].origin = strdup("smb:/");
- dir_files[num_dir_files].mrl =
- (char *) xine_xmalloc(strlen("smb:/") + 1 + strlen(pdirent->name) + 1);
- sprintf(dir_files[num_dir_files].mrl, "%s/%s", "smb:/", pdirent->name);
+ asprintf(&(dir_files[num_dir_files].mrl), "%s/%s", "smb:/", pdirent->name);
dir_files[num_dir_files].size = pdirent->dirlen;
num_dir_files ++;
} else if (pdirent->smbc_type == SMBC_FILE_SHARE){
@@ -293,9 +297,7 @@ static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen,
dir_files[num_dir_files].link = NULL;
dir_files[num_dir_files].type = mrl_file | mrl_file_directory;
dir_files[num_dir_files].origin = strdup(current_path);
- dir_files[num_dir_files].mrl = (char *) xine_xmalloc(
- strlen(current_path) + 3);
- sprintf(dir_files[num_dir_files].mrl, "%s/%s", current_path, "..");
+ asprintf(&(dir_files[num_dir_files].mrl), "%s/%s", current_path, "..");
dir_files[num_dir_files].type |= mrl_file_directory;
dir_files[num_dir_files].size = pdirent->dirlen;
num_dir_files ++;
@@ -304,9 +306,7 @@ static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen,
dir_files[num_dir_files].link = NULL;
dir_files[num_dir_files].type = mrl_file | mrl_file_directory;
dir_files[num_dir_files].origin = strdup(current_path);
- dir_files[num_dir_files].mrl = (char *) xine_xmalloc(
- strlen(current_path) + 1 + strlen(pdirent->name) + 1);
- sprintf(dir_files[num_dir_files].mrl, "%s/%s", current_path, pdirent->name);
+ asprintf(&(dir_files[num_dir_files].mrl), "%s/%s", current_path, pdirent->name);
dir_files[num_dir_files].size = pdirent->dirlen;
num_dir_files ++;
}
@@ -314,18 +314,14 @@ static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen,
dir_files[num_dir_files].link = NULL;
dir_files[num_dir_files].type = mrl_file | mrl_file_directory;
dir_files[num_dir_files].origin = strdup(current_path);
- dir_files[num_dir_files].mrl =
- (char *) xine_xmalloc(strlen(current_path) + 1 + strlen(pdirent->name) + 1);
- sprintf(dir_files[num_dir_files].mrl, "%s/%s", current_path, pdirent->name);
+ asprintf(&(dir_files[num_dir_files].mrl), "%s/%s", current_path, pdirent->name);
dir_files[num_dir_files].size = pdirent->dirlen;
num_dir_files ++;
}else if (pdirent->smbc_type == SMBC_FILE){
norm_files[num_norm_files].link = NULL;
norm_files[num_norm_files].type = mrl_file | mrl_file_normal;
norm_files[num_norm_files].origin = strdup(current_path);
- norm_files[num_norm_files].mrl =
- (char *) xine_xmalloc(strlen(current_path) + 1 + strlen(pdirent->name) + 1);
- sprintf(norm_files[num_norm_files].mrl, "%s/%s", current_path, pdirent->name);
+ asprintf(&(norm_files[num_norm_files].mrl), "%s/%s", current_path, pdirent->name);
norm_files[num_norm_files].size = pdirent->dirlen;
num_norm_files ++;
}
@@ -335,8 +331,7 @@ static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen,
if (num_dir_files == 0) {
dir_files[num_dir_files].link = NULL;
dir_files[num_dir_files].origin = strdup(current_path);
- dir_files[num_dir_files].mrl = (char *) xine_xmalloc(strlen(current_path) + 4);
- sprintf(dir_files[num_dir_files].mrl, "%s/%s", current_path, "..");
+ asprintf(&(dir_files[num_dir_files].mrl), "%s/%s", current_path, "..");
dir_files[num_dir_files].type = mrl_file | mrl_file_directory;
dir_files[num_dir_files].size = 0;
num_dir_files ++;
@@ -359,7 +354,7 @@ static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen,
++this->mrls_allocated_entries;
this->mrls = realloc(this->mrls,
(this->mrls_allocated_entries+1) * sizeof(xine_mrl_t*));
- this->mrls[num_files] = (xine_mrl_t *) xine_xmalloc(sizeof(xine_mrl_t));
+ this->mrls[num_files] = calloc(1, sizeof(xine_mrl_t));
}else
memset(this->mrls[num_files], 0, sizeof(xine_mrl_t));
@@ -376,7 +371,7 @@ static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen,
++this->mrls_allocated_entries;
this->mrls = realloc(this->mrls,
(this->mrls_allocated_entries+1) * sizeof(xine_mrl_t*));
- this->mrls[num_files] = (xine_mrl_t *) xine_xmalloc(sizeof(xine_mrl_t));
+ this->mrls[num_files] = calloc(1, sizeof(xine_mrl_t));
}else
memset(this->mrls[num_files], 0, sizeof(xine_mrl_t));
@@ -437,7 +432,7 @@ smb_plugin_dispose (input_plugin_t *this_gen )
if (this->fd>=0)
smbc_close(this->fd);
if (this->mrl)
- free (this->mrl);
+ free ((char *)this->mrl);
free (this);
}
@@ -475,7 +470,7 @@ smb_class_get_instance (input_class_t *class_gen, xine_stream_t *stream,
if (strncmp (mrl, "smb://",6))
return NULL;
- this = (smb_input_t *)xine_xmalloc(sizeof(smb_input_t));
+ this = calloc(1, sizeof(smb_input_t));
this->stream = stream;
this->mrl = strdup (mrl);
this->fd = -1;
@@ -514,7 +509,7 @@ static void
if (smbc_init(smb_auth,(xine->verbosity >= XINE_VERBOSITY_DEBUG)))
goto _exit_error;
- this = (smb_input_class_t *) xine_xmalloc(sizeof(smb_input_class_t));
+ this = calloc(1, sizeof(smb_input_class_t));
this->xine = xine;
this->input_class.get_instance = smb_class_get_instance;
diff --git a/src/input/input_stdin_fifo.c b/src/input/input_stdin_fifo.c
index 465e9c00b..64b8d748c 100644
--- a/src/input/input_stdin_fifo.c
+++ b/src/input/input_stdin_fifo.c
@@ -85,6 +85,8 @@ static off_t stdin_plugin_read (input_plugin_t *this_gen,
off_t n, total;
lprintf ("reading %"PRId64" bytes...\n", len);
+ if (len < 0)
+ return -1;
total=0;
if (this->curpos < this->preview_size) {
@@ -121,6 +123,13 @@ static buf_element_t *stdin_plugin_read_block (input_plugin_t *this_gen, fifo_bu
/* stdin_input_plugin_t *this = (stdin_input_plugin_t *) this_gen; */
buf_element_t *buf = fifo->buffer_pool_alloc (fifo);
+ if (todo > buf->max_size)
+ todo = buf->max_size;
+ if (todo < 0) {
+ buf->free_buffer (buf);
+ return NULL;
+ }
+
buf->content = buf->mem;
buf->type = BUF_DEMUX_BLOCK;
@@ -146,7 +155,7 @@ static off_t stdin_plugin_seek (input_plugin_t *this_gen, off_t offset, int orig
if ((origin == SEEK_CUR) && (offset >= 0)) {
for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) {
- if( !this_gen->read (this_gen, this->seek_buf, BUFSIZE) )
+ if( this_gen->read (this_gen, this->seek_buf, BUFSIZE) <= 0 )
return this->curpos;
}
@@ -168,7 +177,7 @@ static off_t stdin_plugin_seek (input_plugin_t *this_gen, off_t offset, int orig
offset -= this->curpos;
for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) {
- if( !this_gen->read (this_gen, this->seek_buf, BUFSIZE) )
+ if( this_gen->read (this_gen, this->seek_buf, BUFSIZE) <= 0 )
return this->curpos;
}
@@ -270,6 +279,8 @@ static int stdin_plugin_open (input_plugin_t *this_gen ) {
this->preview_size = stdin_plugin_read (&this->input_plugin, this->preview,
MAX_PREVIEW_SIZE);
+ if (this->preview_size < 0)
+ this->preview_size = 0;
this->curpos = 0;
return 1;
@@ -311,7 +322,7 @@ static input_plugin_t *stdin_class_get_instance (input_class_t *class_gen,
* => create plugin instance
*/
- this = (stdin_input_plugin_t *) xine_xmalloc(sizeof(stdin_input_plugin_t));
+ this = calloc(1, sizeof(stdin_input_plugin_t));
this->stream = stream;
this->curpos = 0;
@@ -362,7 +373,7 @@ static void *init_class (xine_t *xine, void *data) {
stdin_input_class_t *this;
- this = (stdin_input_class_t *) xine_xmalloc (sizeof (stdin_input_class_t));
+ this = calloc(1, sizeof (stdin_input_class_t));
this->xine = xine;
diff --git a/src/input/input_v4l.c b/src/input/input_v4l.c
index b43a2684a..3a020bd69 100644
--- a/src/input/input_v4l.c
+++ b/src/input/input_v4l.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2004 the xine project
+ * Copyright (C) 2003-2008 the xine project
* Copyright (C) 2003 J.Asselman <j.asselman@itsec-ps.nl>
*
* This file is part of xine, a free video player.
@@ -91,13 +91,15 @@ static const resolution_t resolutions[] = {
};
#define NUM_RESOLUTIONS (sizeof(resolutions)/sizeof(resolutions[0]))
-#define RADIO_DEV "/dev/v4l/radio0"
-#define VIDEO_DEV "/dev/v4l/video0"
-
-#if !defined(NDELAY) && defined(O_NDELAY)
-#define FNDELAY O_NDELAY
+#define RADIO_DEV "/dev/radio0"
+#define VIDEO_DEV "/dev/video0"
+#ifdef HAVE_ALSA
+#define AUDIO_DEV "plughw:0,0"
#endif
+static char *tv_standard_names[] = { "AUTO", "PAL", "NTSC", "SECAM", "OLD", NULL };
+static int tv_standard_values[] = { VIDEO_MODE_AUTO, VIDEO_MODE_PAL, VIDEO_MODE_NTSC, VIDEO_MODE_SECAM, -1 };
+
typedef struct pvrscr_s pvrscr_t;
typedef struct {
@@ -117,6 +119,10 @@ typedef struct {
int old_zoomx;
int old_zoomy;
int audio_only;
+
+ buf_element_t *frames_base;
+ void *audio_content_base;
+ void *video_content_base;
/* Audio */
buf_element_t *aud_frames;
@@ -342,11 +348,11 @@ static void pvrscr_exit (scr_plugin_t *scr)
free(this);
}
-static pvrscr_t* pvrscr_init (void)
+static pvrscr_t *XINE_MALLOC pvrscr_init (void)
{
pvrscr_t *this;
- this = (pvrscr_t *) xine_xmalloc(sizeof(pvrscr_t));
+ this = calloc(1, sizeof(pvrscr_t));
this->scr.interface_version = 3;
this->scr.get_priority = pvrscr_get_priority;
@@ -539,6 +545,12 @@ static int set_frequency(v4l_input_plugin_t *this, unsigned long frequency)
fd = this->radio_fd;
if (frequency != 0) {
+ /* FIXME: Don't assume tuner 0 ? */
+ this->tuner = 0;
+ ret = ioctl(fd, VIDIOCSTUNER, &this->tuner);
+ lprintf("(%d) Response on set tuner to %d\n", ret, this->tuner);
+ this->video_tuner.tuner = this->tuner;
+
if (this->video_tuner.flags & VIDEO_TUNER_LOW) {
this->calc_frequency = frequency * 16;
} else {
@@ -624,6 +636,7 @@ static int search_by_channel(v4l_input_plugin_t *this, char *input_source)
{
int ret = 0;
int fd = 0;
+ cfg_entry_t *tv_standard_entry;
lprintf("input_source: %s\n", input_source);
@@ -659,20 +672,19 @@ static int search_by_channel(v4l_input_plugin_t *this, char *input_source)
return -1;
}
+ tv_standard_entry = this->stream->xine->config->lookup_entry(this->stream->xine->config,
+ "media.video4linux.tv_standard");
this->tuner_name = input_source;
- ret = ioctl(fd, VIDIOCSCHAN, &this->input);
+ if (tv_standard_entry->num_value != 0) {
+ this->video_channel.norm = tv_standard_values[ tv_standard_entry->num_value ];
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ "input_v4l: TV Standard configured as STD %s (%d)\n",
+ tv_standard_names[ tv_standard_entry->num_value ], this->video_channel.norm );
+ ret = ioctl(fd, VIDIOCSCHAN, &this->video_channel);
+ } else
+ ret = ioctl(fd, VIDIOCSCHAN, &this->input);
lprintf("(%d) Set channel to %d\n", ret, this->input);
-
- /* FIXME: Don't assume tuner 0 ? */
-
- this->tuner = 0;
-
- ret = ioctl(fd, VIDIOCSTUNER, &this->tuner);
-
- lprintf("(%d) Response on set tuner to %d\n", ret, this->tuner);
-
- this->video_tuner.tuner = this->tuner;
} else {
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
"input_v4l: Not setting video source. No source given\n");
@@ -708,23 +720,50 @@ static int search_by_channel(v4l_input_plugin_t *this, char *input_source)
return 1;
}
-static void allocate_audio_frames(v4l_input_plugin_t *this)
+static void allocate_frames(v4l_input_plugin_t *this, unsigned dovideo)
{
+ const size_t framescount = dovideo ? 2*NUM_FRAMES : NUM_FRAMES;
+
+ /* Allocate a single memory area for both audio and video frames */
+ buf_element_t *frames = this->frames_base =
+ calloc(framescount, sizeof(buf_element_t));
+ extra_info_t *infos =
+ calloc(framescount, sizeof(extra_info_t));
+
int i;
-
+
+ uint8_t *audio_content = this->audio_content_base =
+ calloc(NUM_FRAMES, this->periodsize);
+
+ /* Set up audio frames */
for (i = 0; i < NUM_FRAMES; i++) {
- buf_element_t *frame;
-
/* Audio frame */
- frame = xine_xmalloc(sizeof(buf_element_t));
-
- frame->content = xine_xmalloc(this->periodsize);
- frame->type = BUF_AUDIO_LPCM_LE;
- frame->source = this;
- frame->free_buffer = store_aud_frame;
- frame->extra_info = xine_xmalloc(sizeof(extra_info_t));
-
- store_aud_frame(frame);
+ frames[i].content = audio_content;
+ frames[i].type = BUF_AUDIO_LPCM_LE;
+ frames[i].source = this;
+ frames[i].free_buffer = store_aud_frame;
+ frames[i].extra_info = &infos[i];
+
+ audio_content += this->periodsize;
+ store_aud_frame(&frames[i]);
+ }
+
+ if ( dovideo ) {
+ uint8_t *video_content = this->video_content_base =
+ calloc(NUM_FRAMES, this->frame_size);
+
+ /* Set up video frames */
+ for (i = NUM_FRAMES; i < 2*NUM_FRAMES; i++) {
+ /* Video frame */
+ frames[i].content = video_content;
+ frames[i].type = this->frame_format;
+ frames[i].source = this;
+ frames[i].free_buffer = store_vid_frame;
+ frames[i].extra_info = &infos[i];
+
+ video_content += this->frame_size;
+ store_vid_frame(&frames[i]);
+ }
}
}
@@ -775,7 +814,7 @@ static int open_radio_capture_device(v4l_input_plugin_t *this)
/* Pre-allocate some frames for audio so it doesn't have to be done during
* capture */
- allocate_audio_frames(this);
+ allocate_frames(this, 0);
this->audio_only = 1;
@@ -801,7 +840,7 @@ static int open_video_capture_device(v4l_input_plugin_t *this)
{
int found = 0;
int tuner_found = 0;
- int i, ret;
+ int ret;
unsigned int j;
cfg_entry_t *entry;
@@ -845,10 +884,6 @@ static int open_video_capture_device(v4l_input_plugin_t *this)
_x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1);
_x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1);
- /* Pre-allocate some frames for audio and video so it doesn't have to be
- * done during capture */
- allocate_audio_frames(this);
-
/* Unmute audio off video capture device */
unmute_audio(this);
@@ -951,27 +986,17 @@ static int open_video_capture_device(v4l_input_plugin_t *this)
break;
}
- for (i = 0; i < NUM_FRAMES; i++) {
- buf_element_t *frame;
-
- frame = xine_xmalloc (sizeof (buf_element_t));
-
- frame->content = xine_xmalloc (this->frame_size);
- frame->type = this->frame_format;
- frame->source = this;
- frame->free_buffer = store_vid_frame;
- frame->extra_info = xine_xmalloc(sizeof(extra_info_t));
-
- store_vid_frame(frame);
- }
-
/* Strip the vbi / sync signal from the image by zooming in */
this->old_zoomx = xine_get_param(this->stream, XINE_PARAM_VO_ZOOM_X);
this->old_zoomy = xine_get_param(this->stream, XINE_PARAM_VO_ZOOM_Y);
xine_set_param(this->stream, XINE_PARAM_VO_ZOOM_X, 103);
xine_set_param(this->stream, XINE_PARAM_VO_ZOOM_Y, 103);
-
+
+ /* Pre-allocate some frames for audio and video so it doesn't have to be
+ * done during capture */
+ allocate_frames(this, 1);
+
/* If we made it here, everything went ok */
this->audio_only = 0;
if (tuner_found)
@@ -1566,52 +1591,19 @@ static void v4l_plugin_dispose (input_plugin_t *this_gen) {
if (this->event_queue)
xine_event_dispose_queue (this->event_queue);
-
- lprintf("Freeing allocated audio frames");
- if (this->aud_frames) {
- buf_element_t *cur_frame = this->aud_frames;
-
- while (cur_frame != NULL) {
- buf_element_t *next_frame = cur_frame->next;
-#ifdef LOG
- printf(".");
-#endif
- if (cur_frame->content)
- free(cur_frame->content);
-
- if (cur_frame->extra_info)
- free(cur_frame->extra_info);
-
- free(cur_frame);
- cur_frame = next_frame;
- }
- }
-#ifdef LOG
- printf("\n");
-#endif
+ /* All the frames, both video and audio, are allocated in a single
+ memory area pointed by the frames_base pointer. The content of
+ the frames is divided in two areas, one pointed by
+ audio_content_base and the other by video_content_base. The
+ extra_info structures are all allocated in the first frame
+ data. */
+ free(this->audio_content_base);
+ free(this->video_content_base);
+ if (this->frames_base)
+ free(this->frames_base->extra_info);
+ free(this->frames_base);
-
- lprintf("Freeing allocated video frames");
- if (this->vid_frames) {
- buf_element_t *cur_frame = this->vid_frames;
-
- while (cur_frame != NULL) {
- buf_element_t *next_frame = cur_frame->next;
-#ifdef LOG
- printf(".");
-#endif
-
- if (cur_frame->content)
- free(cur_frame->content);
-
- if (cur_frame->extra_info)
- free(cur_frame->extra_info);
-
- free(cur_frame);
- cur_frame = next_frame;
- }
- }
#ifdef LOG
printf("\n");
#endif
@@ -1701,6 +1693,9 @@ static input_plugin_t *v4l_class_get_instance (input_class_t *cls_gen,
{
/* v4l_input_class_t *cls = (v4l_input_class_t *) cls_gen; */
v4l_input_plugin_t *this;
+#ifdef HAVE_ALSA
+ cfg_entry_t *entry;
+#endif
char *mrl = strdup(data);
/* Example mrl: v4l:/Television/62500 */
@@ -1709,7 +1704,7 @@ static input_plugin_t *v4l_class_get_instance (input_class_t *cls_gen,
return NULL;
}
- this = (v4l_input_plugin_t *) xine_xmalloc (sizeof (v4l_input_plugin_t));
+ this = calloc(1, sizeof (v4l_input_plugin_t));
extract_mrl(this, mrl);
@@ -1721,13 +1716,14 @@ static input_plugin_t *v4l_class_get_instance (input_class_t *cls_gen,
this->event_queue = NULL;
this->scr = NULL;
#ifdef HAVE_ALSA
- this->pcm_name = NULL;
this->pcm_data = NULL;
this->pcm_hwparams = NULL;
/* Audio */
this->pcm_stream = SND_PCM_STREAM_CAPTURE;
- this->pcm_name = strdup("plughw:0,0");
+ entry = this->stream->xine->config->lookup_entry(this->stream->xine->config,
+ "media.video4linux.audio_device");
+ this->pcm_name = strdup (entry->str_value);
this->audio_capture = 1;
#endif
this->rate = 44100;
@@ -1870,11 +1866,11 @@ static input_plugin_t *v4l_class_get_radio_instance (input_class_t *cls_gen,
* v4l input plugin class stuff
*/
-static char *v4l_class_get_video_description (input_class_t *this_gen) {
+static const char *v4l_class_get_video_description (input_class_t *this_gen) {
return _("v4l tv input plugin");
}
-static char *v4l_class_get_radio_description (input_class_t *this_gen) {
+static const char *v4l_class_get_radio_description (input_class_t *this_gen) {
return _("v4l radio input plugin");
}
@@ -1893,7 +1889,7 @@ static void *init_video_class (xine_t *xine, void *data)
v4l_input_class_t *this;
config_values_t *config = xine->config;
- this = (v4l_input_class_t *) xine_xmalloc (sizeof (v4l_input_class_t));
+ this = calloc(1, sizeof (v4l_input_class_t));
this->xine = xine;
@@ -1910,7 +1906,19 @@ static void *init_video_class (xine_t *xine, void *data)
_("v4l video device"),
_("The path to your Video4Linux video device."),
10, NULL, NULL);
-
+#ifdef HAVE_ALSA
+ config->register_filename (config, "media.video4linux.audio_device",
+ AUDIO_DEV, 0,
+ _("v4l ALSA audio input device"),
+ _("The name of the audio device which corresponds "
+ "to your Video4Linux video device."),
+ 10, NULL, NULL);
+#endif
+ config->register_enum (config, "media.video4linux.tv_standard", 4 /* old */,
+ tv_standard_names, _("v4l TV standard"),
+ _("Selects the TV standard of the input signals. "
+ "Either: AUTO, PAL, NTSC or SECAM. "), 20, NULL, NULL);
+
return this;
}
@@ -1919,7 +1927,7 @@ static void *init_radio_class (xine_t *xine, void *data)
v4l_input_class_t *this;
config_values_t *config = xine->config;
- this = (v4l_input_class_t *) xine_xmalloc (sizeof (v4l_input_class_t));
+ this = calloc(1, sizeof (v4l_input_class_t));
this->xine = xine;
diff --git a/src/input/input_vcd.c b/src/input/input_vcd.c
index 007fa5946..c99f57f09 100644
--- a/src/input/input_vcd.c
+++ b/src/input/input_vcd.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2006 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -84,7 +84,7 @@ typedef struct {
const char *device;
- char *filelist[100];
+ char **filelist;
int mrls_allocated_entries;
xine_mrl_t **mrls;
@@ -92,7 +92,7 @@ typedef struct {
#if defined (__linux__) || defined(__sun)
struct cdrom_tochdr tochdr;
struct cdrom_tocentry tocent[100];
-#elif defined (__FreeBSD_kernel__)
+#elif defined (__FreeBSD_kernel__) || defined (__OpenBSD__)
struct ioc_toc_header tochdr;
struct cd_toc_entry *tocent;
off_t cur_sec;
@@ -117,7 +117,7 @@ typedef struct {
int cur_track;
-#if defined (__linux__) || defined(__sun) || defined (__FreeBSD_kernel__)
+#if defined (__linux__) || defined(__sun) || defined (__FreeBSD_kernel__) || defined (__OpenBSD__)
uint8_t cur_min, cur_sec, cur_frame;
#endif
@@ -177,7 +177,7 @@ static int input_vcd_read_toc (vcd_input_class_t *this, int fd) {
return 0;
}
-#elif defined (__FreeBSD_kernel__)
+#elif defined (__FreeBSD_kernel__) || defined (__OpenBSD__)
static int input_vcd_read_toc (vcd_input_class_t *this, int fd) {
struct ioc_read_toc_entry te;
@@ -393,7 +393,7 @@ static off_t vcd_plugin_read (input_plugin_t *this_gen,
memcpy (buf, data.data, VCDSECTORSIZE); /* FIXME */
return VCDSECTORSIZE;
}
-#elif defined (__FreeBSD_kernel__)
+#elif defined (__FreeBSD_kernel__) || defined (__OpenBSD__)
static off_t vcd_plugin_read (input_plugin_t *this_gen,
char *buf, off_t nlen) {
vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen;
@@ -531,7 +531,7 @@ static buf_element_t *vcd_plugin_read_block (input_plugin_t *this_gen,
memcpy (buf->mem, data.data, VCDSECTORSIZE); /* FIXME */
return buf;
}
-#elif defined (__FreeBSD_kernel__)
+#elif defined (__FreeBSD_kernel__) || defined (__OpenBSD__)
static buf_element_t *vcd_plugin_read_block (input_plugin_t *this_gen,
fifo_buffer_t *fifo, off_t nlen) {
@@ -690,7 +690,7 @@ static off_t vcd_plugin_seek (input_plugin_t *this_gen,
return offset ; /* FIXME */
}
-#elif defined (__FreeBSD_kernel__)
+#elif defined (__FreeBSD_kernel__) || defined (__OpenBSD__)
static off_t vcd_plugin_seek (input_plugin_t *this_gen,
off_t offset, int origin) {
@@ -764,7 +764,7 @@ static off_t vcd_plugin_get_length (input_plugin_t *this_gen) {
return (off_t) 0;
}
-#elif defined (__FreeBSD_kernel__)
+#elif defined (__FreeBSD_kernel__) || defined (__OpenBSD__)
static off_t vcd_plugin_get_length (input_plugin_t *this_gen) {
vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen;
off_t len ;
@@ -859,6 +859,10 @@ static int vcd_plugin_open (input_plugin_t *this_gen) {
this->cur_min = this->cls->tocent[this->cur_track].cdte_addr.msf.minute;
this->cur_sec = this->cls->tocent[this->cur_track].cdte_addr.msf.second;
this->cur_frame = this->cls->tocent[this->cur_track].cdte_addr.msf.frame;
+#elif defined (__OpenBSD__)
+ this->cur_min = this->cls->tocent[this->cur_track + 1 - this->cls->tochdr.starting_track].addr.msf.minute;
+ this->cur_sec = this->cls->tocent[this->cur_track + 1 - this->cls->tochdr.starting_track].addr.msf.second;
+ this->cur_frame = this->cls->tocent[this->cur_track + 1 - this->cls->tochdr.starting_track].addr.msf.frame;
#elif defined (__FreeBSD_kernel__)
{
int bsize = 2352;
@@ -889,7 +893,7 @@ static input_plugin_t *vcd_class_get_instance (input_class_t *cls_gen, xine_stre
return 0;
}
- this = (vcd_input_plugin_t *) xine_xmalloc(sizeof(vcd_input_plugin_t));
+ this = calloc(1, sizeof(vcd_input_plugin_t));
this->stream = stream;
this->mrl = mrl;
@@ -924,17 +928,26 @@ static const char *vcd_class_get_identifier (input_class_t *this_gen) {
return "vcdo";
}
+static void vcd_filelist_dispose(vcd_input_class_t *this) {
+ if ( this->filelist == NULL ) return;
+
+ char **entry = this->filelist;
+
+ while(*(entry)) {
+ free(*(entry++));
+ }
+
+ free(this->filelist);
+}
+
static void vcd_class_dispose (input_class_t *this_gen) {
vcd_input_class_t *this = (vcd_input_class_t *) this_gen;
- int i;
config_values_t *config = this->xine->config;
config->unregister_callback(config, "media.vcd.device");
- for (i = 0; i < 100; i++)
- free (this->filelist[i]);
-
+ vcd_filelist_dispose(this);
free (this->mrls);
free (this);
}
@@ -982,33 +995,19 @@ static xine_mrl_t **vcd_class_get_dir (input_class_t *this_gen, const char *file
/* printf ("%d tracks\n", this->total_tracks); */
for (i=1; i<this->total_tracks; i++) { /* FIXME: check if track 0 contains valid data */
- char mrl[1024];
-
- memset(&mrl, 0, sizeof (mrl));
- sprintf(mrl, "vcdo:/%d",i);
-
if((i-1) >= this->mrls_allocated_entries) {
++this->mrls_allocated_entries;
/* note: 1 extra pointer for terminating NULL */
this->mrls = realloc(this->mrls, (this->mrls_allocated_entries+1) * sizeof(xine_mrl_t*));
- this->mrls[(i-1)] = (xine_mrl_t *) xine_xmalloc(sizeof(xine_mrl_t));
+ this->mrls[(i-1)] = calloc(1, sizeof(xine_mrl_t));
}
else {
memset(this->mrls[(i-1)], 0, sizeof(xine_mrl_t));
}
- if(this->mrls[(i-1)]->mrl) {
- this->mrls[(i-1)]->mrl = (char *)
- realloc(this->mrls[(i-1)]->mrl, strlen(mrl) + 1);
- }
- else {
- this->mrls[(i-1)]->mrl = (char *) xine_xmalloc(strlen(mrl) + 1);
- }
-
- this->mrls[i-1]->origin = NULL;
- sprintf(this->mrls[i-1]->mrl, "%s", mrl);
- this->mrls[i-1]->link = NULL;
- this->mrls[i-1]->type = (0 | mrl_vcd);
+ asprintf(&(this->mrls[i-1]->mrl), "vcdo:/%d", i);
+
+ this->mrls[i-1]->type = mrl_vcd;
/* hack */
this->mrls[i-1]->size = vcd_plugin_get_length ((input_plugin_t *) this);
@@ -1055,20 +1054,15 @@ static char ** vcd_class_get_autoplay_list (input_class_t *this_gen, int *num_fi
fd = -1;
*num_files = this->total_tracks - 1;
-
- /* printf ("%d tracks\n", this->total_tracks); */
-
- for (i = 1; i < this->total_tracks; i++) { /* FIXME: check if track 0 contains valid data */
- if(this->filelist[i - 1] == NULL)
- this->filelist[i - 1] = (char *) realloc(this->filelist[i - 1], sizeof(char *) * 256);
+ vcd_filelist_dispose(this);
+ this->filelist = calloc(this->total_tracks+1, sizeof(char*));
- sprintf (this->filelist[i - 1], "vcdo:/%d",i);
- /* printf ("list[%d] : %d %s\n", i, this->filelist[i-1], this->filelist[i-1]); */
- }
+ /* FIXME: check if track 0 contains valid data */
+ for (i = 1; i < this->total_tracks; i++)
+ asprintf(&this->filelist[i-1], "vcdo:/%d", i);
- this->filelist[i - 1] = (char *) realloc(this->filelist[i-1], sizeof(char *));
- this->filelist[i - 1] = NULL;
+ /* printf ("%d tracks\n", this->total_tracks); */
return this->filelist;
}
@@ -1077,9 +1071,8 @@ static void *init_class (xine_t *xine, void *data) {
vcd_input_class_t *this;
config_values_t *config = xine->config;
- int i;
- this = (vcd_input_class_t *) xine_xmalloc (sizeof (vcd_input_class_t));
+ this = calloc(1, sizeof (vcd_input_class_t));
this->xine = xine;
@@ -1097,13 +1090,9 @@ static void *init_class (xine_t *xine, void *data) {
"you intend to play your VideoCDs with."),
10, device_change_cb, (void *)this);
- this->mrls = (xine_mrl_t **) xine_xmalloc(sizeof(xine_mrl_t*));
+ this->mrls = calloc(1, sizeof(xine_mrl_t*));
this->mrls_allocated_entries = 0;
- for (i = 0; i < 100; i++) {
- this->filelist[i] = (char *) xine_xmalloc(sizeof(char *) * 256);
- }
-
return this;
}
diff --git a/src/input/libdvdnav/bswap.h b/src/input/libdvdnav/bswap.h
index 2a2d222fe..23f0251d6 100644
--- a/src/input/libdvdnav/bswap.h
+++ b/src/input/libdvdnav/bswap.h
@@ -20,7 +20,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <config.h>
+#include "config.h"
#if defined(WORDS_BIGENDIAN)
/* All bigendian systems are fine, just ignore the swaps. */
diff --git a/src/input/libdvdnav/diff_against_cvs.patch b/src/input/libdvdnav/diff_against_cvs.patch
index 202474fef..6df704e2a 100644
--- a/src/input/libdvdnav/diff_against_cvs.patch
+++ b/src/input/libdvdnav/diff_against_cvs.patch
@@ -323,7 +323,7 @@ diff -u -p -u -r1.5 dvd_reader.h
-#ifdef _MSC_VER
+#ifdef HAVE_CONFIG_H
- #include <config.h>
+ #include "config.h"
+#endif
+#ifdef _MSC_VER
diff --git a/src/input/libdvdnav/dvd_reader.c b/src/input/libdvdnav/dvd_reader.c
index 200a1dbec..eff1977fc 100644
--- a/src/input/libdvdnav/dvd_reader.c
+++ b/src/input/libdvdnav/dvd_reader.c
@@ -1037,6 +1037,28 @@ int32_t DVDFileSeek( dvd_file_t *dvd_file, int32_t offset )
return offset;
}
+int32_t DVDFileSeekForce( dvd_file_t *dvd_file, int offset, int force_size )
+{
+ /* Check arguments. */
+ if( dvd_file == NULL || offset < 0 )
+ return -1;
+
+ if( dvd_file->dvd->isImageFile ) {
+ if( force_size < 0 )
+ force_size = (offset - 1) / DVD_VIDEO_LB_LEN + 1;
+ if( dvd_file->filesize < force_size) {
+ dvd_file->filesize = force_size;
+ fprintf(stderr, "libdvdread: Ignored UDF provided size of file.\n");
+ }
+ }
+
+ if( offset > dvd_file->filesize * DVD_VIDEO_LB_LEN ) {
+ return -1;
+ }
+ dvd_file->seek_pos = (uint32_t) offset;
+ return offset;
+}
+
ssize_t DVDReadBytes( dvd_file_t *dvd_file, void *data, size_t byte_size )
{
unsigned char *secbuf_base, *secbuf;
@@ -1077,7 +1099,7 @@ ssize_t DVDReadBytes( dvd_file_t *dvd_file, void *data, size_t byte_size )
memcpy( data, &(secbuf[ seek_byte ]), byte_size );
free( secbuf_base );
- dvd_file->seek_pos += byte_size;
+ DVDFileSeekForce(dvd_file, dvd_file->seek_pos + byte_size, -1);
return byte_size;
}
diff --git a/src/input/libdvdnav/dvd_reader.h b/src/input/libdvdnav/dvd_reader.h
index bb3f5053b..c7b3f9df8 100644
--- a/src/input/libdvdnav/dvd_reader.h
+++ b/src/input/libdvdnav/dvd_reader.h
@@ -22,7 +22,7 @@
*/
#ifdef HAVE_CONFIG_H
-#include <config.h>
+#include "config.h"
#endif
#ifdef _MSC_VER
@@ -171,6 +171,8 @@ ssize_t DVDReadBlocks( dvd_file_t *, int, size_t, unsigned char * );
*/
int32_t DVDFileSeek( dvd_file_t *, int32_t );
+int32_t DVDFileSeekForce( dvd_file_t *, int, int );
+
/**
* Reads the given number of bytes from the file. This call can only be used
* on the information files, and may not be used for reading from a VOB. This
diff --git a/src/input/libdvdnav/ifo_read.c b/src/input/libdvdnav/ifo_read.c
index 8f47d2a54..bc1ba580b 100644
--- a/src/input/libdvdnav/ifo_read.c
+++ b/src/input/libdvdnav/ifo_read.c
@@ -93,6 +93,10 @@ static inline int DVDFileSeek_( dvd_file_t *dvd_file, uint32_t offset ) {
return (DVDFileSeek(dvd_file, (int)offset) == (int)offset);
}
+static inline int32_t DVDFileSeekForce_( dvd_file_t *dvd_file, uint32_t offset, int force_size ) {
+ return (DVDFileSeekForce(dvd_file, (int)offset, force_size) == (int)offset);
+}
+
ifo_handle_t *ifoOpen(dvd_reader_t *dvd, int title) {
ifo_handle_t *ifofile;
@@ -1507,7 +1511,7 @@ static int ifoRead_VOBU_ADMAP_internal(ifo_handle_t *ifofile,
unsigned int i;
int info_length;
- if(!DVDFileSeek_(ifofile->file, sector * DVD_BLOCK_LEN))
+ if(!DVDFileSeekForce_(ifofile->file, sector * DVD_BLOCK_LEN, sector))
return 0;
if(!(DVDReadBytes(ifofile->file, vobu_admap, VOBU_ADMAP_SIZE)))
diff --git a/src/input/libdvdnav/md5.c b/src/input/libdvdnav/md5.c
index 2bfdddee4..16b7b0690 100644
--- a/src/input/libdvdnav/md5.c
+++ b/src/input/libdvdnav/md5.c
@@ -21,7 +21,7 @@
/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */
#ifdef HAVE_CONFIG_H
-# include <config.h>
+# include "config.h"
#endif
#include <sys/types.h>
diff --git a/src/input/libdvdnav/remap.c b/src/input/libdvdnav/remap.c
index 43c81c66f..df0be29ce 100644
--- a/src/input/libdvdnav/remap.c
+++ b/src/input/libdvdnav/remap.c
@@ -216,6 +216,7 @@ remap_t* remap_loadmap( char *title) {
remap_add_node( map, tmp);
}
}
+ close (fp); /* ignoring errors... */
if (map->nblocks == 0 && map->debug == 0) return NULL;
return map;
diff --git a/src/input/libreal/asmrp.c b/src/input/libreal/asmrp.c
index f7206b583..902c59d42 100644
--- a/src/input/libreal/asmrp.c
+++ b/src/input/libreal/asmrp.c
@@ -32,6 +32,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -95,7 +99,7 @@ typedef struct {
} asmrp_t;
-static asmrp_t *asmrp_new () {
+static asmrp_t *XINE_MALLOC asmrp_new () {
asmrp_t *p;
diff --git a/src/input/libreal/real.c b/src/input/libreal/real.c
index df50f0440..dcb90bcd0 100644
--- a/src/input/libreal/real.c
+++ b/src/input/libreal/real.c
@@ -21,6 +21,10 @@
* adopted from joschkas real tools.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include <string.h>
@@ -48,9 +52,6 @@ static const unsigned char xor_table[] = {
#define _X_BE_32C(x,y) do { *(uint32_t *)(x) = be2me_32((y)); } while(0)
#define _X_LE_32C(x,y) do { *(uint32_t *)(x) = le2me_32((y)); } while(0)
-#define MAX(x,y) ((x>y) ? x : y)
-
-
static void hash(char *field, char *param) {
uint32_t a, b, c, d;
@@ -313,7 +314,7 @@ static void calc_response_string (char *result, char *challenge) {
void real_calc_response_and_checksum (char *response, char *chksum, char *challenge) {
- int ch_len, resp_len;
+ size_t ch_len, resp_len;
int i;
char *ptr;
char buf[128];
@@ -449,7 +450,7 @@ rmff_header_t *real_parse_sdp(char *data, char **stream_rules, uint32_t bandwidt
if (!desc) return NULL;
buf=xine_buffer_init(2048);
- header = xine_xmalloc(sizeof(rmff_header_t));
+ header = calloc(1, sizeof(rmff_header_t));
header->fileheader=rmff_new_fileheader(4+desc->stream_count);
header->cont=rmff_new_cont(
@@ -458,7 +459,7 @@ rmff_header_t *real_parse_sdp(char *data, char **stream_rules, uint32_t bandwidt
desc->copyright,
desc->abstract);
header->data=rmff_new_dataheader(0,0);
- header->streams = xine_xmalloc(sizeof(rmff_mdpr_t*)*(desc->stream_count+1));
+ header->streams = calloc((desc->stream_count+1), sizeof(rmff_mdpr_t*));
lprintf("number of streams: %u\n", desc->stream_count);
for (i=0; i<desc->stream_count; i++) {
@@ -660,7 +661,7 @@ rmff_header_t *real_setup_and_get_header(rtsp_t *rtsp_session, uint32_t bandwid
lprintf("Stream description size: %i\n", size);
- description = malloc(sizeof(char)*(size+1));
+ description = malloc(size+1);
if( rtsp_read_data(rtsp_session, description, size) <= 0) {
xine_buffer_free(buf);
diff --git a/src/input/libreal/rmff.c b/src/input/libreal/rmff.c
index 159b81ee6..2d3fcc613 100644
--- a/src/input/libreal/rmff.c
+++ b/src/input/libreal/rmff.c
@@ -21,6 +21,10 @@
* adopted from joschkas real tools
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#define LOG_MODULE "rmff"
#define LOG_VERBOSE
/*
@@ -35,9 +39,13 @@
* writes header data to a buffer
*/
-static void rmff_dump_fileheader(rmff_fileheader_t *fileheader, char *buffer) {
+static int rmff_dump_fileheader(rmff_fileheader_t *fileheader, uint8_t *buffer, int bufsize) {
+
+ if (!fileheader) return 0;
+
+ if (bufsize < RMFF_FILEHEADER_SIZE)
+ return -1;
- if (!fileheader) return;
fileheader->object_id=_X_BE_32(&fileheader->object_id);
fileheader->size=_X_BE_32(&fileheader->size);
fileheader->object_version=_X_BE_16(&fileheader->object_version);
@@ -53,11 +61,17 @@ static void rmff_dump_fileheader(rmff_fileheader_t *fileheader, char *buffer) {
fileheader->file_version=_X_BE_32(&fileheader->file_version);
fileheader->num_headers=_X_BE_32(&fileheader->num_headers);
fileheader->object_id=_X_BE_32(&fileheader->object_id);
+
+ return RMFF_FILEHEADER_SIZE;
}
-static void rmff_dump_prop(rmff_prop_t *prop, char *buffer) {
+static int rmff_dump_prop(rmff_prop_t *prop, uint8_t *buffer, int bufsize) {
+
+ if (!prop) return 0;
+
+ if (bufsize < RMFF_PROPHEADER_SIZE)
+ return -1;
- if (!prop) return;
prop->object_id=_X_BE_32(&prop->object_id);
prop->size=_X_BE_32(&prop->size);
prop->object_version=_X_BE_16(&prop->object_version);
@@ -93,13 +107,19 @@ static void rmff_dump_prop(rmff_prop_t *prop, char *buffer) {
prop->num_streams=_X_BE_16(&prop->num_streams);
prop->flags=_X_BE_16(&prop->flags);
prop->object_id=_X_BE_32(&prop->object_id);
+
+ return RMFF_PROPHEADER_SIZE;
}
-static void rmff_dump_mdpr(rmff_mdpr_t *mdpr, char *buffer) {
+static int rmff_dump_mdpr(rmff_mdpr_t *mdpr, uint8_t *buffer, int bufsize) {
int s1, s2, s3;
- if (!mdpr) return;
+ if (!mdpr) return 0;
+
+ if (bufsize < RMFF_MDPRHEADER_SIZE + mdpr->type_specific_len + mdpr->stream_name_size + mdpr->mime_type_size)
+ return -1;
+
mdpr->object_id=_X_BE_32(&mdpr->object_id);
mdpr->size=_X_BE_32(&mdpr->size);
mdpr->object_version=_X_BE_16(&mdpr->object_version);
@@ -141,13 +161,19 @@ static void rmff_dump_mdpr(rmff_mdpr_t *mdpr, char *buffer) {
mdpr->duration=_X_BE_32(&mdpr->duration);
mdpr->object_id=_X_BE_32(&mdpr->object_id);
+ return RMFF_MDPRHEADER_SIZE + s1 + s2 + s3;
}
-static void rmff_dump_cont(rmff_cont_t *cont, char *buffer) {
+static int rmff_dump_cont(rmff_cont_t *cont, uint8_t *buffer, int bufsize) {
int p;
- if (!cont) return;
+ if (!cont) return 0;
+
+ if (bufsize < RMFF_CONTHEADER_SIZE + cont->title_len + cont->author_len +
+ cont->copyright_len + cont->comment_len)
+ return -1;
+
cont->object_id=_X_BE_32(&cont->object_id);
cont->size=_X_BE_32(&cont->size);
cont->object_version=_X_BE_16(&cont->object_version);
@@ -181,11 +207,18 @@ static void rmff_dump_cont(rmff_cont_t *cont, char *buffer) {
cont->size=_X_BE_32(&cont->size);
cont->object_version=_X_BE_16(&cont->object_version);
cont->object_id=_X_BE_32(&cont->object_id);
+
+ return RMFF_CONTHEADER_SIZE + cont->title_len + cont->author_len +
+ cont->copyright_len + cont->comment_len;
}
-static void rmff_dump_dataheader(rmff_data_t *data, char *buffer) {
+static int rmff_dump_dataheader(rmff_data_t *data, uint8_t *buffer, int bufsize) {
+
+ if (!data) return 0;
+
+ if (bufsize < RMFF_DATAHEADER_SIZE)
+ return -1;
- if (!data) return;
data->object_id=_X_BE_32(&data->object_id);
data->size=_X_BE_32(&data->size);
data->object_version=_X_BE_16(&data->object_version);
@@ -201,31 +234,43 @@ static void rmff_dump_dataheader(rmff_data_t *data, char *buffer) {
data->size=_X_BE_32(&data->size);
data->object_version=_X_BE_16(&data->object_version);
data->object_id=_X_BE_32(&data->object_id);
+
+ return RMFF_DATAHEADER_SIZE;
}
-int rmff_dump_header(rmff_header_t *h, char *buffer, int max) {
+int rmff_dump_header(rmff_header_t *h, void *buf_gen, int max) {
+ uint8_t *buffer = buf_gen;
- int written=0;
+ int written=0, size;
rmff_mdpr_t **stream=h->streams;
- rmff_dump_fileheader(h->fileheader, &buffer[written]);
- written+=h->fileheader->size;
- rmff_dump_prop(h->prop, &buffer[written]);
- written+=h->prop->size;
- rmff_dump_cont(h->cont, &buffer[written]);
- written+=h->cont->size;
+ if ((size=rmff_dump_fileheader(h->fileheader, &buffer[written], max)) < 0)
+ return -1;
+ written+=size;
+ max -= size;
+ if ((size=rmff_dump_prop(h->prop, &buffer[written], max)) < 0)
+ return -1;
+ written+=size;
+ max -= size;
+ if ((size=rmff_dump_cont(h->cont, &buffer[written], max)) < 0)
+ return -1;
+ written+=size;
+ max -= size;
if (stream)
{
while(*stream)
{
- rmff_dump_mdpr(*stream, &buffer[written]);
- written+=(*stream)->size;
+ if ((size=rmff_dump_mdpr(*stream, &buffer[written], max)) < 0)
+ return -1;
+ written+=size;
+ max -= size;
stream++;
}
}
- rmff_dump_dataheader(h->data, &buffer[written]);
- written+=18;
+ if ((size=rmff_dump_dataheader(h->data, &buffer[written], max)) < 0)
+ return -1;
+ written+=size;
return written;
}
@@ -289,12 +334,14 @@ static rmff_prop_t *rmff_scan_prop(const char *data) {
return prop;
}
-static rmff_mdpr_t *rmff_scan_mdpr(const char *data) {
-
- rmff_mdpr_t *mdpr = malloc(sizeof(rmff_mdpr_t));
+static rmff_mdpr_t *rmff_scan_mdpr(const char *data)
+{
+ rmff_mdpr_t *mdpr = calloc(sizeof(rmff_mdpr_t), 1);
mdpr->object_id=_X_BE_32(data);
mdpr->size=_X_BE_32(&data[4]);
+ if (mdpr->size < 46)
+ goto fail;
mdpr->object_version=_X_BE_16(&data[8]);
if (mdpr->object_version != 0)
{
@@ -310,21 +357,40 @@ static rmff_mdpr_t *rmff_scan_mdpr(const char *data) {
mdpr->duration=_X_BE_32(&data[36]);
mdpr->stream_name_size=data[40];
- mdpr->stream_name = malloc(sizeof(char)*(mdpr->stream_name_size+1));
+ if (mdpr->size < 46 + mdpr->stream_name_size)
+ goto fail;
+ mdpr->stream_name = malloc(mdpr->stream_name_size+1);
+ if (!mdpr->stream_name)
+ goto fail;
memcpy(mdpr->stream_name, &data[41], mdpr->stream_name_size);
mdpr->stream_name[mdpr->stream_name_size]=0;
mdpr->mime_type_size=data[41+mdpr->stream_name_size];
- mdpr->mime_type = malloc(sizeof(char)*(mdpr->mime_type_size+1));
+ if (mdpr->size < 46 + mdpr->stream_name_size + mdpr->mime_type_size)
+ goto fail;
+ mdpr->mime_type = malloc(mdpr->mime_type_size+1);
+ if (!mdpr->mime_type)
+ goto fail;
memcpy(mdpr->mime_type, &data[42+mdpr->stream_name_size], mdpr->mime_type_size);
mdpr->mime_type[mdpr->mime_type_size]=0;
mdpr->type_specific_len=_X_BE_32(&data[42+mdpr->stream_name_size+mdpr->mime_type_size]);
- mdpr->type_specific_data = malloc(sizeof(char)*(mdpr->type_specific_len));
+ if (mdpr->size < 46 + mdpr->stream_name_size + mdpr->mime_type_size + mdpr->type_specific_data)
+ goto fail;
+ mdpr->type_specific_data = malloc(mdpr->type_specific_len);
+ if (!mdpr->type_specific_data)
+ goto fail;
memcpy(mdpr->type_specific_data,
&data[46+mdpr->stream_name_size+mdpr->mime_type_size], mdpr->type_specific_len);
return mdpr;
+
+fail:
+ free (mdpr->stream_name);
+ free (mdpr->mime_type);
+ free (mdpr->type_specific_data);
+ free (mdpr);
+ return NULL;
}
static rmff_cont_t *rmff_scan_cont(const char *data) {
@@ -340,22 +406,22 @@ static rmff_cont_t *rmff_scan_cont(const char *data) {
lprintf("warning: unknown object version in CONT: 0x%04x\n", cont->object_version);
}
cont->title_len=_X_BE_16(&data[10]);
- cont->title = malloc(sizeof(char)*(cont->title_len+1));
+ cont->title = malloc(cont->title_len+1);
memcpy(cont->title, &data[12], cont->title_len);
cont->title[cont->title_len]=0;
pos=cont->title_len+12;
cont->author_len=_X_BE_16(&data[pos]);
- cont->author = malloc(sizeof(char)*(cont->author_len+1));
+ cont->author = malloc(cont->author_len+1);
memcpy(cont->author, &data[pos+2], cont->author_len);
cont->author[cont->author_len]=0;
pos=pos+2+cont->author_len;
cont->copyright_len=_X_BE_16(&data[pos]);
- cont->copyright = malloc(sizeof(char)*(cont->copyright_len+1));
+ cont->copyright = malloc(cont->copyright_len+1);
memcpy(cont->copyright, &data[pos+2], cont->copyright_len);
cont->copyright[cont->copyright_len]=0;
pos=pos+2+cont->copyright_len;
cont->comment_len=_X_BE_16(&data[pos]);
- cont->comment = malloc(sizeof(char)*(cont->comment_len+1));
+ cont->comment = malloc(cont->comment_len+1);
memcpy(cont->comment, &data[pos+2], cont->comment_len);
cont->comment[cont->comment_len]=0;
@@ -403,10 +469,7 @@ rmff_header_t *rmff_scan_header(const char *data) {
header->fileheader=rmff_scan_fileheader(ptr);
ptr += header->fileheader->size;
- header->streams = malloc(sizeof(rmff_mdpr_t*)*(header->fileheader->num_headers));
- for (i=0; i<header->fileheader->num_headers; i++) {
- header->streams[i]=NULL;
- }
+ header->streams = calloc(header->fileheader->num_headers, sizeof(rmff_mdpr_t*));
for (i=1; i<header->fileheader->num_headers; i++) {
chunk_type = _X_BE_32(ptr);
@@ -425,8 +488,11 @@ rmff_header_t *rmff_scan_header(const char *data) {
break;
case MDPR_TAG:
mdpr=rmff_scan_mdpr(ptr);
- chunk_size=mdpr->size;
- header->streams[mdpr->stream_number]=mdpr;
+ if (mdpr) /* FIXME: what to do if NULL? */
+ {
+ chunk_size=mdpr->size;
+ header->streams[mdpr->stream_number]=mdpr;
+ }
break;
case CONT_TAG:
header->cont=rmff_scan_cont(ptr);
@@ -586,7 +652,7 @@ rmff_mdpr_t *rmff_new_mdpr(
mdpr->mime_type_size=strlen(mime_type);
}
mdpr->type_specific_len=type_specific_len;
- mdpr->type_specific_data = malloc(sizeof(char)*type_specific_len);
+ mdpr->type_specific_data = malloc(type_specific_len);
memcpy(mdpr->type_specific_data,type_specific_data,type_specific_len);
mdpr->mlti_data=NULL;
diff --git a/src/input/libreal/rmff.h b/src/input/libreal/rmff.h
index d39942088..50656349d 100644
--- a/src/input/libreal/rmff.h
+++ b/src/input/libreal/rmff.h
@@ -32,13 +32,19 @@
#include <string.h>
#include <inttypes.h>
-
#ifndef HAVE_RMFF_H
#define HAVE_RMFF_H
+#include "attributes.h"
#define RMFF_HEADER_SIZE 0x12
+#define RMFF_FILEHEADER_SIZE 18
+#define RMFF_PROPHEADER_SIZE 50
+#define RMFF_MDPRHEADER_SIZE 46
+#define RMFF_CONTHEADER_SIZE 18
+#define RMFF_DATAHEADER_SIZE 18
+
#define FOURCC_TAG( ch0, ch1, ch2, ch3 ) \
(((long)(unsigned char)(ch3) ) | \
( (long)(unsigned char)(ch2) << 8 ) | \
@@ -214,7 +220,7 @@ rmff_data_t *rmff_new_dataheader(
/*
* reads header infos from data and returns a newly allocated header struct
*/
-rmff_header_t *rmff_scan_header(const char *data);
+rmff_header_t *rmff_scan_header(const char *data) XINE_MALLOC;
/*
* scans a data packet header. Notice, that this function does not allocate
@@ -225,7 +231,7 @@ void rmff_scan_pheader(rmff_pheader_t *h, char *data);
/*
* reads header infos from stream and returns a newly allocated header struct
*/
-rmff_header_t *rmff_scan_header_stream(int fd);
+rmff_header_t *rmff_scan_header_stream(int fd) XINE_MALLOC;
/*
* prints header information in human readible form to stdout
@@ -245,7 +251,7 @@ int rmff_get_header_size(rmff_header_t *h);
/*
* dumps the header <h> to <buffer>. <max> is the size of <buffer>
*/
-int rmff_dump_header(rmff_header_t *h, char *buffer, int max);
+int rmff_dump_header(rmff_header_t *h, void *buf_gen, int max);
/*
* dumps a packet header
diff --git a/src/input/libreal/sdpplin.c b/src/input/libreal/sdpplin.c
index c62b6bbc1..a07cb3360 100644
--- a/src/input/libreal/sdpplin.c
+++ b/src/input/libreal/sdpplin.c
@@ -19,6 +19,10 @@
*
* sdp/sdpplin parser.
*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
#define LOG_MODULE "sdpplin"
#define LOG_VERBOSE
@@ -60,7 +64,8 @@ static char *b64_decode(const char *in, char *out, int *size)
k=0;
/*CONSTANTCONDITION*/
- for (j=0; j<strlen(in); j+=4)
+ const size_t in_len = strlen(in);
+ for (j=0; j<in_len; j+=4)
{
char a[4], b[4];
@@ -99,7 +104,7 @@ static char *nl(char *data) {
static int filter(const char *in, const char *filter, char **out) {
- int flen=strlen(filter);
+ size_t flen=strlen(filter);
size_t len;
if (!in)
@@ -120,9 +125,9 @@ static int filter(const char *in, const char *filter, char **out) {
return 0;
}
-static sdpplin_stream_t *sdpplin_parse_stream(char **data) {
+static sdpplin_stream_t *XINE_MALLOC sdpplin_parse_stream(char **data) {
- sdpplin_stream_t *desc = xine_xmalloc(sizeof(sdpplin_stream_t));
+ sdpplin_stream_t *desc = calloc(1, sizeof(sdpplin_stream_t));
char *buf=xine_buffer_init(32);
char *decoded=xine_buffer_init(32);
int handled;
@@ -143,7 +148,14 @@ static sdpplin_stream_t *sdpplin_parse_stream(char **data) {
handled=0;
if(filter(*data,"a=control:streamid=",&buf)) {
- desc->stream_id=atoi(buf);
+ /* This way negative values are mapped to unfeasibly high
+ * values, and will be discarded afterward
+ */
+ unsigned long tmp = strtoul(buf, NULL, 10);
+ if ( tmp > UINT16_MAX )
+ lprintf("stream id out of bound: %lu\n", tmp);
+ else
+ desc->stream_id=tmp;
handled=1;
*data=nl(*data);
}
@@ -199,7 +211,7 @@ static sdpplin_stream_t *sdpplin_parse_stream(char **data) {
if(filter(*data,"a=OpaqueData:buffer;",&buf)) {
decoded = b64_decode(buf, decoded, &(desc->mlti_data_size));
if ( decoded != NULL ) {
- desc->mlti_data = malloc(sizeof(char)*desc->mlti_data_size);
+ desc->mlti_data = malloc(desc->mlti_data_size);
memcpy(desc->mlti_data, decoded, desc->mlti_data_size);
handled=1;
*data=nl(*data);
@@ -232,7 +244,7 @@ static sdpplin_stream_t *sdpplin_parse_stream(char **data) {
sdpplin_t *sdpplin_parse(char *data) {
- sdpplin_t *desc = xine_xmalloc(sizeof(sdpplin_t));
+ sdpplin_t *desc = calloc(1, sizeof(sdpplin_t));
sdpplin_stream_t *stream;
char *buf=xine_buffer_init(32);
char *decoded=xine_buffer_init(32);
@@ -252,7 +264,10 @@ sdpplin_t *sdpplin_parse(char *data) {
}
stream=sdpplin_parse_stream(&data);
lprintf("got data for stream id %u\n", stream->stream_id);
- desc->stream[stream->stream_id]=stream;
+ if ( stream->stream_id >= desc->stream_count )
+ lprintf("stream id %u is greater than stream count %u\n", stream->stream_id, desc->stream_count);
+ else
+ desc->stream[stream->stream_id]=stream;
continue;
}
@@ -293,8 +308,15 @@ sdpplin_t *sdpplin_parse(char *data) {
}
if(filter(data,"a=StreamCount:integer;",&buf)) {
- desc->stream_count=atoi(buf);
- desc->stream = malloc(sizeof(sdpplin_stream_t*)*desc->stream_count);
+ /* This way negative values are mapped to unfeasibly high
+ * values, and will be discarded afterward
+ */
+ unsigned long tmp = strtoul(buf, NULL, 10);
+ if ( tmp > UINT16_MAX )
+ lprintf("stream count out of bound: %lu\n", tmp);
+ else
+ desc->stream_count = tmp;
+ desc->stream = calloc(desc->stream_count, sizeof(sdpplin_stream_t*));
handled=1;
data=nl(data);
}
diff --git a/src/input/libreal/sdpplin.h b/src/input/libreal/sdpplin.h
index cb3b434d4..1604ee38c 100644
--- a/src/input/libreal/sdpplin.h
+++ b/src/input/libreal/sdpplin.h
@@ -37,7 +37,7 @@ typedef struct {
char *id;
char *bandwidth;
- int stream_id;
+ uint16_t stream_id;
char *range;
char *length;
char *rtpmap;
@@ -81,7 +81,7 @@ typedef struct {
int flags;
int is_real_data_type;
- int stream_count;
+ uint16_t stream_count;
char *title;
char *author;
char *copyright;
@@ -101,7 +101,7 @@ typedef struct {
} sdpplin_t;
-sdpplin_t *sdpplin_parse(char *data);
+sdpplin_t *sdpplin_parse(char *data) XINE_MALLOC;
void sdpplin_free(sdpplin_t *description);
diff --git a/src/input/librtsp/rtsp.c b/src/input/librtsp/rtsp.c
index 530ffc6cf..de4440b1c 100644
--- a/src/input/librtsp/rtsp.c
+++ b/src/input/librtsp/rtsp.c
@@ -21,6 +21,10 @@
* *not* RFC 2326 compilant yet.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <unistd.h>
#include <stdio.h>
#include <assert.h>
@@ -123,7 +127,7 @@ static char *rtsp_get(rtsp_t *s) {
static void rtsp_put(rtsp_t *s, const char *string) {
- int len=strlen(string);
+ size_t len=strlen(string);
char *buf = malloc(sizeof(char)*len+2);
lprintf(">> '%s'", string);
@@ -173,9 +177,7 @@ static void rtsp_send_request(rtsp_t *s, const char *type, const char *what) {
char **payload=s->scheduled;
char *buf;
- buf = malloc(strlen(type)+strlen(what)+strlen(rtsp_protocol_version)+3);
-
- sprintf(buf,"%s %s %s",type, what, rtsp_protocol_version);
+ asprintf(&buf,"%s %s %s",type, what, rtsp_protocol_version);
rtsp_put(s,buf);
free(buf);
if (payload)
@@ -200,8 +202,7 @@ static void rtsp_schedule_standard(rtsp_t *s) {
if (s->session) {
char *buf;
- buf = malloc(strlen(s->session)+15);
- sprintf(buf, "Session: %s", s->session);
+ asprintf(&buf, "Session: %s", s->session);
rtsp_schedule_field(s, buf);
free(buf);
}
@@ -232,38 +233,32 @@ static int rtsp_get_answers(rtsp_t *s) {
if (!answer)
return 0;
- if (!strncasecmp(answer,"Cseq:",5)) {
- sscanf(answer,"%*s %u",&answer_seq);
+ if (!strncasecmp(answer,"Cseq: ",6)) {
+ sscanf(answer+6,"%u",&answer_seq);
if (s->cseq != answer_seq) {
lprintf("warning: Cseq mismatch. got %u, assumed %u", answer_seq, s->cseq);
s->cseq=answer_seq;
}
}
- if (!strncasecmp(answer,"Server:",7)) {
- char *buf = xine_xmalloc(strlen(answer));
- sscanf(answer,"%*s %s",buf);
- if (s->server) free(s->server);
- s->server=strdup(buf);
- free(buf);
+ if (!strncasecmp(answer,"Server: ",8)) {
+ free(s->server);
+ s->server = strdup(answer + 8);
}
- if (!strncasecmp(answer,"Session:",8)) {
- char *buf = xine_xmalloc(strlen(answer));
- sscanf(answer,"%*s %s",buf);
+ if (!strncasecmp(answer,"Session: ",9)) {
+ char *tmp = answer + 9;
if (s->session) {
- if (strcmp(buf, s->session)) {
+ if (strcmp(tmp, s->session)) {
xprintf(s->stream->xine, XINE_VERBOSITY_DEBUG,
- "rtsp: warning: setting NEW session: %s\n", buf);
- free(s->session);
- s->session=strdup(buf);
+ "rtsp: warning: setting NEW session: %s\n", tmp);
+ s->session=strdup(tmp);
}
} else
{
lprintf("setting session id to: %s\n", buf);
- s->session=strdup(buf);
+ s->session=strdup(tmp);
}
- free(buf);
}
*answer_ptr=answer;
answer_ptr++;
@@ -304,8 +299,7 @@ int rtsp_request_options(rtsp_t *s, const char *what) {
buf=strdup(what);
} else
{
- buf = malloc(sizeof(char)*(strlen(s->host)+16));
- sprintf(buf,"rtsp://%s:%i", s->host, s->port);
+ asprintf(&buf,"rtsp://%s:%i", s->host, s->port);
}
rtsp_send_request(s,"OPTIONS",buf);
free(buf);
@@ -321,8 +315,7 @@ int rtsp_request_describe(rtsp_t *s, const char *what) {
buf=strdup(what);
} else
{
- buf = malloc(sizeof(char)*(strlen(s->host)+strlen(s->path)+16));
- sprintf(buf,"rtsp://%s:%i/%s", s->host, s->port, s->path);
+ asprintf(&buf,"rtsp://%s:%i/%s", s->host, s->port, s->path);
}
rtsp_send_request(s,"DESCRIBE",buf);
free(buf);
@@ -345,8 +338,7 @@ int rtsp_request_setparameter(rtsp_t *s, const char *what) {
buf=strdup(what);
} else
{
- buf = malloc(sizeof(char)*(strlen(s->host)+strlen(s->path)+16));
- sprintf(buf,"rtsp://%s:%i/%s", s->host, s->port, s->path);
+ asprintf(&buf,"rtsp://%s:%i/%s", s->host, s->port, s->path);
}
rtsp_send_request(s,"SET_PARAMETER",buf);
free(buf);
@@ -362,8 +354,7 @@ int rtsp_request_play(rtsp_t *s, const char *what) {
buf=strdup(what);
} else
{
- buf = malloc(sizeof(char)*(strlen(s->host)+strlen(s->path)+16));
- sprintf(buf,"rtsp://%s:%i/%s", s->host, s->port, s->path);
+ asprintf(&buf,"rtsp://%s:%i/%s", s->host, s->port, s->path);
}
rtsp_send_request(s,"PLAY",buf);
free(buf);
@@ -412,8 +403,7 @@ int rtsp_read_data(rtsp_t *s, char *buffer, unsigned int size) {
}
/* lets make the server happy */
rtsp_put(s, "RTSP/1.0 451 Parameter Not Understood");
- rest = malloc(sizeof(char)*17);
- sprintf(rest,"CSeq: %u", seq);
+ asprintf(&rest,"CSeq: %u", seq);
rtsp_put(s, rest);
free(rest);
rtsp_put(s, "");
@@ -486,9 +476,7 @@ rtsp_t *rtsp_connect(xine_stream_t *stream, const char *mrl, const char *user_ag
pathbegin=slash-mrl_ptr;
hostend=colon-mrl_ptr;
- s->host = malloc(sizeof(char)*hostend+1);
- strncpy(s->host, mrl_ptr, hostend);
- s->host[hostend]=0;
+ s->host = strndup(mrl_ptr, hostend);
if (pathbegin < strlen(mrl_ptr)) s->path=strdup(mrl_ptr+pathbegin+1);
if (colon != slash) {
diff --git a/src/input/librtsp/rtsp.h b/src/input/librtsp/rtsp.h
index dc2624459..2e1fd6aa0 100644
--- a/src/input/librtsp/rtsp.h
+++ b/src/input/librtsp/rtsp.h
@@ -40,7 +40,7 @@
typedef struct rtsp_s rtsp_t;
-rtsp_t* rtsp_connect (xine_stream_t *stream, const char *mrl, const char *user_agent);
+rtsp_t* rtsp_connect (xine_stream_t *stream, const char *mrl, const char *user_agent) XINE_MALLOC;
int rtsp_request_options(rtsp_t *s, const char *what);
int rtsp_request_describe(rtsp_t *s, const char *what);
diff --git a/src/input/librtsp/rtsp_session.c b/src/input/librtsp/rtsp_session.c
index f3ddb59bc..88103aa7d 100644
--- a/src/input/librtsp/rtsp_session.c
+++ b/src/input/librtsp/rtsp_session.c
@@ -20,6 +20,10 @@
* high level interface to rtsp servers.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
@@ -78,7 +82,7 @@ const char *rtsp_bandwidth_strs[]={"14.4 Kbps (Modem)", "19.2 Kbps (Modem)",
rtsp_session_t *rtsp_session_start(xine_stream_t *stream, char *mrl) {
- rtsp_session_t *rtsp_session = xine_xmalloc(sizeof(rtsp_session_t));
+ rtsp_session_t *rtsp_session = calloc(1, sizeof(rtsp_session_t));
xine_t *xine = stream->xine;
char *server;
char *mrl_line=strdup(mrl);
@@ -148,6 +152,11 @@ connect:
rtsp_session->header_left =
rtsp_session->header_len = rmff_dump_header(h,rtsp_session->header,HEADER_SIZE);
+ if (rtsp_session->header_len < 0) {
+ xprintf (stream->xine, XINE_VERBOSITY_LOG,
+ _("rtsp_session: rtsp server returned overly-large headers, session can not be established.\n"));
+ goto session_abort;
+ }
xine_buffer_copyin(rtsp_session->recv, 0, rtsp_session->header, rtsp_session->header_len);
rtsp_session->recv_size = rtsp_session->header_len;
@@ -157,6 +166,7 @@ connect:
{
xprintf(stream->xine, XINE_VERBOSITY_LOG,
_("rtsp_session: rtsp server type '%s' not supported yet. sorry.\n"), server);
+ session_abort:
rtsp_close(rtsp_session->s);
free(server);
xine_buffer_free(rtsp_session->recv);
diff --git a/src/input/librtsp/rtsp_session.h b/src/input/librtsp/rtsp_session.h
index b47db0730..33ac579e1 100644
--- a/src/input/librtsp/rtsp_session.h
+++ b/src/input/librtsp/rtsp_session.h
@@ -25,7 +25,7 @@
typedef struct rtsp_session_s rtsp_session_t;
-rtsp_session_t *rtsp_session_start(xine_stream_t *stream, char *mrl);
+rtsp_session_t *rtsp_session_start(xine_stream_t *stream, char *mrl) XINE_MALLOC;
void rtsp_session_set_start_time(rtsp_session_t *this, int start_time);
diff --git a/src/input/mms.c b/src/input/mms.c
index f11a89cf3..b2d00a46e 100644
--- a/src/input/mms.c
+++ b/src/input/mms.c
@@ -202,9 +202,9 @@ static void mms_buffer_put_64 (mms_buffer_t *mms_buffer, uint64_t value) {
}
+#ifdef LOG
static void print_command (char *data, int len) {
-#ifdef LOG
int i;
int dir = _X_LE_32 (data + 36) >> 16;
int comm = _X_LE_32 (data + 36) & 0xFFFF;
@@ -240,8 +240,10 @@ static void print_command (char *data, int len) {
if (len > CMD_HEADER_LEN)
printf ("\n");
printf ("----------------------------------------------\n");
+}
+#else
+# define print_command(data, len)
#endif
-}
@@ -288,7 +290,7 @@ static int send_command (mms_t *this, int command,
#ifdef USE_ICONV
static iconv_t string_utf16_open() {
- return iconv_open("UTF-16LE", nl_langinfo(CODESET));
+ return iconv_open("UTF-16LE", "UTF-8");
}
static void string_utf16_close(iconv_t url_conv) {
@@ -678,7 +680,7 @@ mms_t *mms_connect (xine_stream_t *stream, const char *url, int bandwidth) {
if (!url)
return NULL;
- this = (mms_t*) xine_xmalloc (sizeof (mms_t));
+ this = calloc(1, sizeof (mms_t));
this->stream = stream;
this->url = strdup (url);
@@ -769,12 +771,17 @@ mms_t *mms_connect (xine_stream_t *stream, const char *url, int bandwidth) {
/* command 0x5 */
{
mms_buffer_t command_buffer;
- char *path;
- int pathlen;
+ char *path, *unescaped;
+ size_t pathlen;
+
+ unescaped = strdup (this->uri);
+ if (!unescaped)
+ goto fail;
+ _x_mrl_unescape (unescaped);
/* remove the first '/' */
- path = this->uri;
- pathlen = strlen(path);
+ path = unescaped;
+ pathlen = strlen (path);
if (pathlen > 1) {
path++;
pathlen--;
@@ -785,6 +792,7 @@ mms_t *mms_connect (xine_stream_t *stream, const char *url, int bandwidth) {
mms_buffer_put_32 (&command_buffer, 0x00000000); /* ?? */
mms_buffer_put_32 (&command_buffer, 0x00000000); /* ?? */
string_utf16 (url_conv, this->scmd_body + command_buffer.pos, path, pathlen);
+ free (unescaped);
if (!send_command (this, 5, 1, 0xffffffff, pathlen * 2 + 12))
goto fail;
}
diff --git a/src/input/mmsh.c b/src/input/mmsh.c
index ae1c62bc1..4ee7ed07d 100644
--- a/src/input/mmsh.c
+++ b/src/input/mmsh.c
@@ -190,11 +190,9 @@ struct mmsh_s {
};
static int send_command (mmsh_t *this, char *cmd) {
- int length;
-
lprintf ("send_command:\n%s\n", cmd);
- length = strlen(cmd);
+ const size_t length = strlen(cmd);
if (_x_io_tcp_write(this->stream, this->s, cmd, length) != length) {
xprintf (this->stream->xine, XINE_LOG_MSG, _("libmmsh: send error\n"));
return 0;
@@ -636,7 +634,7 @@ mmsh_t *mmsh_connect (xine_stream_t *stream, const char *url, int bandwidth) {
report_progress (stream, 0);
- this = (mmsh_t*) xine_xmalloc (sizeof (mmsh_t));
+ this = calloc(1, sizeof (mmsh_t));
this->stream = stream;
this->url = strdup(url);
diff --git a/src/input/net_buf_ctrl.c b/src/input/net_buf_ctrl.c
index 624af4081..e27ed99f3 100644
--- a/src/input/net_buf_ctrl.c
+++ b/src/input/net_buf_ctrl.c
@@ -118,8 +118,8 @@ void nbc_check_buffers (nbc_t *this) {
}
static void display_stats (nbc_t *this) {
- const char *buffering[2] = {" ", "buf"};
- const char *enabled[2] = {"off", "on "};
+ const char buffering[2][4] = {" ", "buf"};
+ const char enabled[2][4] = {"off", "on "};
printf("bufing: %d, enb: %d\n", this->buffering, this->enabled);
printf("net_buf_ctrl: vid %3d%% %4.1fs %4" PRId64 "kbps %1d, "\
@@ -496,7 +496,7 @@ static void nbc_get_cb (fifo_buffer_t *fifo,
nbc_t *nbc_init (xine_stream_t *stream) {
- nbc_t *this = (nbc_t *) xine_xmalloc (sizeof (nbc_t));
+ nbc_t *this = calloc(1, sizeof (nbc_t));
fifo_buffer_t *video_fifo = stream->video_fifo;
fifo_buffer_t *audio_fifo = stream->audio_fifo;
double video_fifo_factor, audio_fifo_factor;
diff --git a/src/input/net_buf_ctrl.h b/src/input/net_buf_ctrl.h
index 79f698008..7dfb7b0d1 100644
--- a/src/input/net_buf_ctrl.h
+++ b/src/input/net_buf_ctrl.h
@@ -27,14 +27,14 @@
typedef struct nbc_s nbc_t;
-nbc_t *nbc_init (xine_stream_t *xine);
+nbc_t *nbc_init (xine_stream_t *xine) XINE_MALLOC;
-void nbc_check_buffers (nbc_t *this);
+void nbc_check_buffers (nbc_t *this) XINE_DEPRECATED;
void nbc_close (nbc_t *this);
-void nbc_set_high_water_mark(nbc_t *this, int value);
+void nbc_set_high_water_mark(nbc_t *this, int value) XINE_DEPRECATED;
-void nbc_set_low_water_mark(nbc_t *this, int value);
+void nbc_set_low_water_mark(nbc_t *this, int value) XINE_DEPRECATED;
#endif
diff --git a/src/input/pnm.c b/src/input/pnm.c
index 38d65b850..aabdbde96 100644
--- a/src/input/pnm.c
+++ b/src/input/pnm.c
@@ -21,6 +21,10 @@
* based upon code from joschka
*/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
@@ -90,7 +94,7 @@ struct pnm_s {
/* header of rm files */
#define RM_HEADER_SIZE 0x12
-const unsigned char rm_header[]={
+static const unsigned char rm_header[]={
0x2e, 0x52, 0x4d, 0x46, /* object_id ".RMF" */
0x00, 0x00, 0x00, 0x12, /* header_size 0x12 */
0x00, 0x00, /* object_version 0x00 */
@@ -100,7 +104,7 @@ const unsigned char rm_header[]={
/* data chunk header */
#define PNM_DATA_HEADER_SIZE 18
-const unsigned char pnm_data_header[]={
+static const unsigned char pnm_data_header[]={
'D','A','T','A',
0,0,0,0, /* data chunk size */
0,0, /* object version */
@@ -411,8 +415,8 @@ static void pnm_send_request(pnm_t *p, uint32_t bandwidth) {
*/
static void pnm_send_response(pnm_t *p, const char *response) {
-
- int size=strlen(response);
+ /** @TODO should check that sze is always < 256 */
+ size_t size=strlen(response);
p->buffer[0]=0x23;
p->buffer[1]=0;
@@ -627,10 +631,7 @@ static int pnm_get_stream_chunk(pnm_t *p) {
*/
n=0;
while (p->buffer[0] != 0x5a) {
- int i;
- for (i=1; i<8; i++) {
- p->buffer[i-1]=p->buffer[i];
- }
+ memmove(p->buffer, &p->buffer[1], 8);
_x_io_tcp_read (p->stream, p->s, &p->buffer[7], 1);
n++;
}
@@ -716,7 +717,7 @@ pnm_t *pnm_connect(xine_stream_t *stream, const char *mrl) {
mrl_ptr+=6;
- p = xine_xmalloc(sizeof(pnm_t));
+ p = calloc(1, sizeof(pnm_t));
p->stream = stream;
p->port=7070;
p->url=strdup(mrl);
@@ -732,9 +733,7 @@ pnm_t *pnm_connect(xine_stream_t *stream, const char *mrl) {
pathbegin=slash-mrl_ptr;
hostend=colon-mrl_ptr;
- p->host = malloc(sizeof(char)*hostend+1);
- strncpy(p->host, mrl_ptr, hostend);
- p->host[hostend]=0;
+ p->host = strndup(mrl_ptr, hostend);
if (pathbegin < strlen(mrl_ptr)) p->path=strdup(mrl_ptr+pathbegin+1);
if (colon != slash) {
diff --git a/src/input/vcd/Makefile.am b/src/input/vcd/Makefile.am
index 31ec6a44c..61eac753b 100644
--- a/src/input/vcd/Makefile.am
+++ b/src/input/vcd/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
SUBDIRS = libcdio libvcd
diff --git a/src/input/vcd/libcdio/FreeBSD/freebsd.c b/src/input/vcd/libcdio/FreeBSD/freebsd.c
index 5a3443e95..bcfe674a5 100644
--- a/src/input/vcd/libcdio/FreeBSD/freebsd.c
+++ b/src/input/vcd/libcdio/FreeBSD/freebsd.c
@@ -29,11 +29,11 @@
static const char _rcsid[] = "$Id: freebsd.c,v 1.1 2005/01/01 02:43:57 rockyb Exp $";
-#include <arpa/inet.h>
#include "freebsd.h"
#ifdef HAVE_FREEBSD_CDROM
+#include <arpa/inet.h>
#include <cdio/sector.h>
static access_mode_t
diff --git a/src/input/vcd/libcdio/MSWindows/aspi32.c b/src/input/vcd/libcdio/MSWindows/aspi32.c
index 238a4b4e9..e62f8a089 100644
--- a/src/input/vcd/libcdio/MSWindows/aspi32.c
+++ b/src/input/vcd/libcdio/MSWindows/aspi32.c
@@ -162,9 +162,9 @@ have_aspi( HMODULE *hASPI,
return false;
}
- (FARPROC) *lpGetSupport = GetProcAddress( *hASPI,
+ *lpGetSupport = (FARPROC)GetProcAddress( *hASPI,
"GetASPI32SupportInfo" );
- (FARPROC) *lpSendCommand = GetProcAddress( *hASPI,
+ *lpSendCommand = (FARPROC)GetProcAddress( *hASPI,
"SendASPI32Command" );
/* make sure that we've got both function addresses */
diff --git a/src/input/vcd/xine-extra.c b/src/input/vcd/xine-extra.c
index 79c962a79..e3b6da912 100644
--- a/src/input/vcd/xine-extra.c
+++ b/src/input/vcd/xine-extra.c
@@ -45,8 +45,10 @@ static xine_t *my_xine = NULL;
void
xine_vlog_msg(xine_t *this, int buf, const char *format, va_list args)
{
+ va_list copy;
+ va_copy (copy, args);
xine_vlog(this, buf, format, args);
- vfprintf(stdout, format, args);
+ vfprintf(stdout, format, copy);
}
/*! This routine is like xine_log, except it takes a va_list instead
@@ -59,8 +61,10 @@ xine_vlog_msg(xine_t *this, int buf, const char *format, va_list args)
void
xine_vlog_err(xine_t *this, int buf, const char *format, va_list args)
{
+ va_list copy;
+ va_copy (copy, args);
xine_vlog(this, buf, format, args);
- vfprintf(stderr, format, args);
+ vfprintf(stderr, format, copy);
}
/*! Call this before calling any of the xine_log_msg or xine_log_err
@@ -116,8 +120,8 @@ xine_log_err(const char *format, ...)
{
va_list args;
- va_start(args, format);
if (NULL == my_xine) return false;
+ va_start(args, format);
xine_vlog_err(my_xine, XINE_LOG_MSG, format, args);
va_end(args);
return true;
diff --git a/src/input/vcd/xineplug_inp_vcd.c b/src/input/vcd/xineplug_inp_vcd.c
index 2e52ccc0f..50382ee7e 100644
--- a/src/input/vcd/xineplug_inp_vcd.c
+++ b/src/input/vcd/xineplug_inp_vcd.c
@@ -20,7 +20,7 @@
/*
These are plugin routines called by the xine engine. See
Chapter 4. Extending xine's input
- http://xinehq.de/index.php/hackersguide/index.php?resource=5.3&action=default#INPUT
+ http://www.xine-project.org/hackersguide#INPUT
and the comments in input_plugin.h
This is what is referred to below a "the xine plugin spec"
@@ -272,11 +272,9 @@ vcd_add_mrl_slot(vcd_input_class_t *this, const char *mrl, off_t size,
this->mrls[*i]->type = mrl_vcd;
this->mrls[*i]->size = size * M2F2_SECTOR_SIZE;
- this->mrls[*i]->mrl = (char *) malloc(strlen(mrl) + 1);
+ this->mrls[*i]->mrl = strdup(mrl);
if (NULL==this->mrls[*i]->mrl) {
LOG_ERR("Can't malloc %zu bytes for MRL name %s", sizeof(xine_mrl_t), mrl);
- } else {
- sprintf(this->mrls[*i]->mrl, "%s", mrl);
}
(*i)++;
}
@@ -968,7 +966,7 @@ vcd_class_eject_media (input_class_t *this_gen)
* From spec:
* return current MRL
*/
-static char *
+static const char *
vcd_plugin_get_mrl (input_plugin_t *this_gen)
{
vcd_input_plugin_t *t = (vcd_input_plugin_t *) this_gen;
@@ -989,7 +987,7 @@ vcd_plugin_get_mrl (input_plugin_t *this_gen)
/* Bad type. */
LOG_ERR("%s %d", _("Invalid current entry type"),
vcdplayer->play_item.type);
- return strdup("");
+ return "";
} else {
n += offset;
if (n < t->class->num_mrls) {
@@ -997,7 +995,7 @@ vcd_plugin_get_mrl (input_plugin_t *this_gen)
t->class->mrls[n]->mrl);
return t->class->mrls[n]->mrl;
} else {
- return strdup("");
+ return "";
}
}
}
@@ -1007,7 +1005,7 @@ vcd_plugin_get_mrl (input_plugin_t *this_gen)
return human readable (verbose = 1 line) description for this plugin
*/
-static char *
+static const char *
vcd_class_get_description (input_class_t *this_gen)
{
dbg_print((INPUT_DBG_CALL|INPUT_DBG_EXT), "called\n");
@@ -1767,7 +1765,7 @@ vcd_init (xine_t *xine, void *data)
dbg_print(INPUT_DBG_CALL, "Called\n");
- class = (vcd_input_class_t *) xine_xmalloc (sizeof (vcd_input_class_t));
+ class = calloc(1, sizeof (vcd_input_class_t));
class->xine = xine;
class->config = config = xine->config;
diff --git a/src/liba52/Makefile.am b/src/liba52/Makefile.am
index 508ea9c1b..b13170076 100644
--- a/src/liba52/Makefile.am
+++ b/src/liba52/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
if A52
diff --git a/src/liba52/parse.c b/src/liba52/parse.c
index 0bfd02fce..f1adc2f40 100644
--- a/src/liba52/parse.c
+++ b/src/liba52/parse.c
@@ -49,7 +49,7 @@ a52_state_t * a52_init (uint32_t mm_accel)
a52_state_t * state;
int i;
- state = xine_xmalloc (sizeof (a52_state_t));
+ state = calloc(1, sizeof (a52_state_t));
if (state == NULL)
return NULL;
diff --git a/src/liba52/xine_a52_decoder.c b/src/liba52/xine_a52_decoder.c
index b8b500ecd..47babce7a 100644
--- a/src/liba52/xine_a52_decoder.c
+++ b/src/liba52/xine_a52_decoder.c
@@ -27,7 +27,7 @@
/* avoid compiler warnings */
#define _BSD_SOURCE 1
-#include <config.h>
+#include "config.h"
#include <stdlib.h>
#include <unistd.h>
@@ -654,7 +654,7 @@ static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stre
lprintf ("open_plugin called\n");
- this = (a52dec_decoder_t *) xine_xmalloc (sizeof (a52dec_decoder_t));
+ this = calloc(1, sizeof (a52dec_decoder_t));
this->audio_decoder.decode_data = a52dec_decode_data;
this->audio_decoder.reset = a52dec_reset;
@@ -806,7 +806,7 @@ static void *init_plugin (xine_t *xine, void *data) {
a52dec_class_t *this;
config_values_t *cfg;
- this = (a52dec_class_t *) xine_xmalloc (sizeof (a52dec_class_t));
+ this = calloc(1, sizeof (a52dec_class_t));
this->decoder_class.open_plugin = open_plugin;
this->decoder_class.get_identifier = get_identifier;
diff --git a/src/libdts/Makefile.am b/src/libdts/Makefile.am
index 1329dd49c..b7ec60016 100644
--- a/src/libdts/Makefile.am
+++ b/src/libdts/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
if DTS
diff --git a/src/libdts/xine_dts_decoder.c b/src/libdts/xine_dts_decoder.c
index 6573d5ed0..eba750110 100644
--- a/src/libdts/xine_dts_decoder.c
+++ b/src/libdts/xine_dts_decoder.c
@@ -21,6 +21,10 @@
* 09-12-2001 DTS passthrough inprovements (C) James Courtier-Dutton
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#ifndef __sun
/* required for swab() */
#define _XOPEN_SOURCE 500
@@ -207,19 +211,27 @@ static void dts_decode_frame (dts_decoder_t *this, int64_t pts, int preview_mode
audio_buffer->num_frames = this->ac5_pcm_length;
- data_out[0] = 0x72; data_out[1] = 0xf8; /* spdif syncword */
- data_out[2] = 0x1f; data_out[3] = 0x4e; /* .............. */
- data_out[4] = ac5_spdif_type; /* DTS data */
- data_out[5] = 0; /* Unknown */
- data_out[6] = (this->ac5_length << 3) & 0xff; /* ac5_length * 8 */
- data_out[7] = ((this->ac5_length ) >> 5) & 0xff;
-
- if( this->ac5_pcm_length ) {
- if( this->ac5_pcm_length % 2) {
- swab(data_in, &data_out[8], this->ac5_length );
- } else {
- swab(data_in, &data_out[8], this->ac5_length + 1);
+ // Checking if AC5 data plus IEC958 header will fit into frames samples data
+ if ( this->ac5_length + 8 <= this->ac5_pcm_length * 2 * 2 ) {
+ data_out[0] = 0x72; data_out[1] = 0xf8; /* spdif syncword */
+ data_out[2] = 0x1f; data_out[3] = 0x4e; /* .............. */
+ data_out[4] = ac5_spdif_type; /* DTS data */
+ data_out[5] = 0; /* Unknown */
+ data_out[6] = (this->ac5_length << 3) & 0xff; /* ac5_length * 8 */
+ data_out[7] = ((this->ac5_length ) >> 5) & 0xff;
+
+ if( this->ac5_pcm_length ) {
+ if( this->ac5_pcm_length % 2) {
+ swab(data_in, &data_out[8], this->ac5_length );
+ } else {
+ swab(data_in, &data_out[8], this->ac5_length + 1);
+ }
}
+ // Transmit it without header otherwise, receivers will autodetect DTS
+ } else {
+ lprintf("AC5 data is too large (%i > %i), sending without IEC958 header\n",
+ this->ac5_length + 8, this->ac5_pcm_length * 2 * 2);
+ memcpy(data_out, data_in, this->ac5_length);
}
} else {
/* Software decode */
@@ -481,7 +493,7 @@ static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stre
lprintf("open_plugin\n");
- this = (dts_decoder_t *) xine_xmalloc (sizeof (dts_decoder_t));
+ this = calloc(1, sizeof (dts_decoder_t));
this->audio_decoder.decode_data = dts_decode_data;
this->audio_decoder.reset = dts_reset;
@@ -590,7 +602,7 @@ static void *init_plugin (xine_t *xine, void *data) {
lprintf("init_plugin\n");
- this = (dts_class_t *) xine_xmalloc (sizeof (dts_class_t));
+ this = calloc(1, sizeof (dts_class_t));
this->decoder_class.open_plugin = open_plugin;
this->decoder_class.get_identifier = get_identifier;
diff --git a/src/libfaad/Makefile.am b/src/libfaad/Makefile.am
index 729418f1c..92bab83fb 100644
--- a/src/libfaad/Makefile.am
+++ b/src/libfaad/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
SUBDIRS = codebook
@@ -10,8 +11,10 @@ xineplug_LTLIBRARIES = $(faad_module)
VPATH = @srcdir@:@srcdir@/codebook:
-xineplug_decode_faad_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) -fno-strict-aliasing
-xineplug_decode_faad_la_SOURCES = \
+if EXTERNAL_LIBFAAD
+libfaad_sources =
+else
+libfaad_sources = \
bits.c \
cfft.c \
common.c \
@@ -49,11 +52,21 @@ xineplug_decode_faad_la_SOURCES = \
ssr_fb.c \
ssr_ipqf.c \
syntax.c \
- tns.c \
+ tns.c
+endif
+
+xineplug_decode_faad_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) -fno-strict-aliasing
+xineplug_decode_faad_la_SOURCES = \
+ $(libfaad_sources) \
xine_faad_decoder.c
xineplug_decode_faad_la_LDFLAGS = $(xineplug_ldflags)
+if EXTERNAL_LIBFAAD
+xineplug_decode_faad_la_LIBADD = $(XINE_LIB) -lfaad -lm $(LTLIBINTL)
+else
xineplug_decode_faad_la_LIBADD = $(XINE_LIB) -lm $(LTLIBINTL)
+endif
+
noinst_HEADERS = \
analysis.h \
@@ -103,4 +116,17 @@ noinst_HEADERS = \
ssr_win.h \
structs.h \
syntax.h \
- tns.h
+ tns.h \
+ codebook/hcb.h \
+ codebook/hcb_1.h \
+ codebook/hcb_2.h \
+ codebook/hcb_3.h \
+ codebook/hcb_4.h \
+ codebook/hcb_5.h \
+ codebook/hcb_6.h \
+ codebook/hcb_7.h \
+ codebook/hcb_8.h \
+ codebook/hcb_9.h \
+ codebook/hcb_10.h \
+ codebook/hcb_11.h \
+ codebook/hcb_sf.h
diff --git a/src/libfaad/analysis.h b/src/libfaad/analysis.h
index 810a95f3b..50e43fa04 100644
--- a/src/libfaad/analysis.h
+++ b/src/libfaad/analysis.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: analysis.h,v 1.7 2005/10/29 23:57:06 tmmm Exp $
+** $Id: analysis.h,v 1.18 2007/11/01 12:33:29 menno Exp $
**/
#ifndef __ANALYSIS_H__
diff --git a/src/libfaad/bits.c b/src/libfaad/bits.c
index ae273c7d8..dc14d7a03 100644
--- a/src/libfaad/bits.c
+++ b/src/libfaad/bits.c
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,17 +19,19 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: bits.c,v 1.9 2005/10/29 23:57:06 tmmm Exp $
+** $Id: bits.c,v 1.44 2007/11/01 12:33:29 menno Exp $
**/
#include "common.h"
#include "structs.h"
#include <stdlib.h>
-#include <string.h>
#include "bits.h"
/* initialize buffer, call once before first getbits or showbits */
@@ -40,25 +42,38 @@ void faad_initbits(bitfile *ld, const void *_buffer, const uint32_t buffer_size)
if (ld == NULL)
return;
- memset(ld, 0, sizeof(bitfile));
+ // useless
+ //memset(ld, 0, sizeof(bitfile));
if (buffer_size == 0 || _buffer == NULL)
{
ld->error = 1;
- ld->no_more_reading = 1;
return;
}
- ld->buffer = faad_malloc((buffer_size+12)*sizeof(uint8_t));
- memset(ld->buffer, 0, (buffer_size+12)*sizeof(uint8_t));
- memcpy(ld->buffer, _buffer, buffer_size*sizeof(uint8_t));
+ ld->buffer = _buffer;
ld->buffer_size = buffer_size;
+ ld->bytes_left = buffer_size;
- tmp = getdword((uint32_t*)ld->buffer);
+ if (ld->bytes_left >= 4)
+ {
+ tmp = getdword((uint32_t*)ld->buffer);
+ ld->bytes_left -= 4;
+ } else {
+ tmp = getdword_n((uint32_t*)ld->buffer, ld->bytes_left);
+ ld->bytes_left = 0;
+ }
ld->bufa = tmp;
- tmp = getdword((uint32_t*)ld->buffer + 1);
+ if (ld->bytes_left >= 4)
+ {
+ tmp = getdword((uint32_t*)ld->buffer + 1);
+ ld->bytes_left -= 4;
+ } else {
+ tmp = getdword_n((uint32_t*)ld->buffer + 1, ld->bytes_left);
+ ld->bytes_left = 0;
+ }
ld->bufb = tmp;
ld->start = (uint32_t*)ld->buffer;
@@ -66,21 +81,12 @@ void faad_initbits(bitfile *ld, const void *_buffer, const uint32_t buffer_size)
ld->bits_left = 32;
- ld->bytes_used = 0;
- ld->no_more_reading = 0;
ld->error = 0;
}
void faad_endbits(bitfile *ld)
{
- if (ld)
- {
- if (ld->buffer)
- {
- faad_free(ld->buffer);
- ld->buffer = NULL;
- }
- }
+ // void
}
uint32_t faad_get_processed_bits(bitfile *ld)
@@ -90,12 +96,12 @@ uint32_t faad_get_processed_bits(bitfile *ld)
uint8_t faad_byte_align(bitfile *ld)
{
- uint8_t remainder = (uint8_t)((32 - ld->bits_left) % 8);
+ int remainder = (32 - ld->bits_left) & 0x7;
if (remainder)
{
faad_flushbits(ld, 8 - remainder);
- return (8 - remainder);
+ return (uint8_t)(8 - remainder);
}
return 0;
}
@@ -105,20 +111,22 @@ void faad_flushbits_ex(bitfile *ld, uint32_t bits)
uint32_t tmp;
ld->bufa = ld->bufb;
- if (ld->no_more_reading == 0)
+ if (ld->bytes_left >= 4)
{
tmp = getdword(ld->tail);
- ld->tail++;
+ ld->bytes_left -= 4;
} else {
- tmp = 0;
+ tmp = getdword_n(ld->tail, ld->bytes_left);
+ ld->bytes_left = 0;
}
ld->bufb = tmp;
+ ld->tail++;
ld->bits_left += (32 - bits);
- ld->bytes_used += 4;
- if (ld->bytes_used == ld->buffer_size)
- ld->no_more_reading = 1;
- if (ld->bytes_used > ld->buffer_size)
- ld->error = 1;
+ //ld->bytes_left -= 4;
+// if (ld->bytes_left == 0)
+// ld->no_more_reading = 1;
+// if (ld->bytes_left < 0)
+// ld->error = 1;
}
/* rewind to beginning */
@@ -126,30 +134,79 @@ void faad_rewindbits(bitfile *ld)
{
uint32_t tmp;
- tmp = ld->start[0];
-#ifndef ARCH_IS_BIG_ENDIAN
- BSWAP(tmp);
-#endif
+ ld->bytes_left = ld->buffer_size;
+
+ if (ld->bytes_left >= 4)
+ {
+ tmp = getdword((uint32_t*)&ld->start[0]);
+ ld->bytes_left -= 4;
+ } else {
+ tmp = getdword_n((uint32_t*)&ld->start[0], ld->bytes_left);
+ ld->bytes_left = 0;
+ }
ld->bufa = tmp;
- tmp = ld->start[1];
-#ifndef ARCH_IS_BIG_ENDIAN
- BSWAP(tmp);
-#endif
+ if (ld->bytes_left >= 4)
+ {
+ tmp = getdword((uint32_t*)&ld->start[1]);
+ ld->bytes_left -= 4;
+ } else {
+ tmp = getdword_n((uint32_t*)&ld->start[1], ld->bytes_left);
+ ld->bytes_left = 0;
+ }
ld->bufb = tmp;
+
ld->bits_left = 32;
ld->tail = &ld->start[2];
- ld->bytes_used = 0;
- ld->no_more_reading = 0;
+}
+
+/* reset to a certain point */
+void faad_resetbits(bitfile *ld, int bits)
+{
+ uint32_t tmp;
+ int words = bits >> 5;
+ int remainder = bits & 0x1F;
+
+ ld->bytes_left = ld->buffer_size - words*4;
+
+ if (ld->bytes_left >= 4)
+ {
+ tmp = getdword(&ld->start[words]);
+ ld->bytes_left -= 4;
+ } else {
+ tmp = getdword_n(&ld->start[words], ld->bytes_left);
+ ld->bytes_left = 0;
+ }
+ ld->bufa = tmp;
+
+ if (ld->bytes_left >= 4)
+ {
+ tmp = getdword(&ld->start[words+1]);
+ ld->bytes_left -= 4;
+ } else {
+ tmp = getdword_n(&ld->start[words+1], ld->bytes_left);
+ ld->bytes_left = 0;
+ }
+ ld->bufb = tmp;
+
+ ld->bits_left = 32 - remainder;
+ ld->tail = &ld->start[words+2];
+
+ /* recheck for reading too many bytes */
+ ld->error = 0;
+// if (ld->bytes_left == 0)
+// ld->no_more_reading = 1;
+// if (ld->bytes_left < 0)
+// ld->error = 1;
}
uint8_t *faad_getbitbuffer(bitfile *ld, uint32_t bits
DEBUGDEC)
{
- uint16_t i;
- uint8_t temp;
- uint16_t bytes = (uint16_t)bits / 8;
- uint8_t remainder = (uint8_t)bits % 8;
+ int i;
+ unsigned int temp;
+ int bytes = bits >> 3;
+ int remainder = bits & 0x7;
uint8_t *buffer = (uint8_t*)faad_malloc((bytes+1)*sizeof(uint8_t));
@@ -160,9 +217,9 @@ uint8_t *faad_getbitbuffer(bitfile *ld, uint32_t bits
if (remainder)
{
- temp = (uint8_t)faad_getbits(ld, remainder DEBUGVAR(print,var,dbg)) << (8-remainder);
+ temp = faad_getbits(ld, remainder DEBUGVAR(print,var,dbg)) << (8-remainder);
- buffer[bytes] = temp;
+ buffer[bytes] = (uint8_t)temp;
}
return buffer;
@@ -207,7 +264,8 @@ void faad_initbits_rev(bitfile *ld, void *buffer,
if (ld->bits_left == 0)
ld->bits_left = 32;
- ld->bytes_used = 0;
- ld->no_more_reading = 0;
+ ld->bytes_left = ld->buffer_size;
ld->error = 0;
}
+
+/* EOF */
diff --git a/src/libfaad/bits.h b/src/libfaad/bits.h
index 05460f0cc..e303e8e72 100644
--- a/src/libfaad/bits.h
+++ b/src/libfaad/bits.h
@@ -1,28 +1,31 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
+**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
-**
+**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
-**
+**
** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
+** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: bits.h,v 1.11 2005/10/30 01:21:53 tmmm Exp $
+** $Id: bits.h,v 1.45 2007/11/01 12:33:29 menno Exp $
**/
#ifndef __BITS_H__
@@ -37,8 +40,10 @@ extern "C" {
#include <stdio.h>
#endif
-#define BYTE_NUMBIT 8
-#define bit2byte(a) ((a+7)/BYTE_NUMBIT)
+#define BYTE_NUMBIT 8
+#define BYTE_NUMBIT_LD 3
+//#define bit2byte(a) ((a+7)/BYTE_NUMBIT)
+#define bit2byte(a) ((a+7)>>BYTE_NUMBIT_LD)
typedef struct _bitfile
{
@@ -47,25 +52,16 @@ typedef struct _bitfile
uint32_t bufb;
uint32_t bits_left;
uint32_t buffer_size; /* size of the buffer in bytes */
- uint32_t bytes_used;
- uint8_t no_more_reading;
+ uint32_t bytes_left;
uint8_t error;
uint32_t *tail;
uint32_t *start;
- void *buffer;
+ const void *buffer;
} bitfile;
-#if defined(_MSC_VER)
-#define BSWAP(a) __asm mov eax,a __asm bswap eax __asm mov a, eax
-#elif defined(LINUX) || defined(DJGPP) || defined (__MINGW32__) || defined (__CYGWIN__)
-#define BSWAP(a) __asm__ ( "bswapl %0\n" : "=r" (a) : "0" (a) )
-#else
-#define BSWAP(a) \
- ((a) = ( ((a)&0xff)<<24) | (((a)&0xff00)<<8) | (((a)>>8)&0xff00) | (((a)>>24)&0xff))
-#endif
-
-static uint32_t bitmask[] = {
+#if 0
+static uint32_t const bitmask[] = {
0x0, 0x1, 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x1FF,
0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF,
0x1FFFF, 0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF,
@@ -74,6 +70,7 @@ static uint32_t bitmask[] = {
/* added bitmask 32, correct?!?!?! */
, 0xFFFFFFFF
};
+#endif
void faad_initbits(bitfile *ld, const void *buffer, const uint32_t buffer_size);
void faad_endbits(bitfile *ld);
@@ -83,6 +80,7 @@ uint8_t faad_byte_align(bitfile *ld);
uint32_t faad_get_processed_bits(bitfile *ld);
void faad_flushbits_ex(bitfile *ld, uint32_t bits);
void faad_rewindbits(bitfile *ld);
+void faad_resetbits(bitfile *ld, int bits);
uint8_t *faad_getbitbuffer(bitfile *ld, uint32_t bits
DEBUGDEC);
#ifdef DRM
@@ -93,7 +91,6 @@ uint32_t faad_origbitbuffer_size(bitfile *ld);
/* circumvent memory alignment errors on ARM */
static INLINE uint32_t getdword(void *mem)
{
-#ifdef ARM
uint32_t tmp;
#ifndef ARCH_IS_BIG_ENDIAN
((uint8_t*)&tmp)[0] = ((uint8_t*)mem)[3];
@@ -108,25 +105,52 @@ static INLINE uint32_t getdword(void *mem)
#endif
return tmp;
-#else
- uint32_t tmp;
- tmp = *(uint32_t*)mem;
+}
+
+/* reads only n bytes from the stream instead of the standard 4 */
+static /*INLINE*/ uint32_t getdword_n(void *mem, int n)
+{
+ uint32_t tmp = 0;
#ifndef ARCH_IS_BIG_ENDIAN
- BSWAP(tmp);
+ switch (n)
+ {
+ case 3:
+ ((uint8_t*)&tmp)[1] = ((uint8_t*)mem)[2];
+ case 2:
+ ((uint8_t*)&tmp)[2] = ((uint8_t*)mem)[1];
+ case 1:
+ ((uint8_t*)&tmp)[3] = ((uint8_t*)mem)[0];
+ default:
+ break;
+ }
+#else
+ switch (n)
+ {
+ case 3:
+ ((uint8_t*)&tmp)[2] = ((uint8_t*)mem)[2];
+ case 2:
+ ((uint8_t*)&tmp)[1] = ((uint8_t*)mem)[1];
+ case 1:
+ ((uint8_t*)&tmp)[0] = ((uint8_t*)mem)[0];
+ default:
+ break;
+ }
#endif
+
return tmp;
-#endif
}
static INLINE uint32_t faad_showbits(bitfile *ld, uint32_t bits)
{
if (bits <= ld->bits_left)
{
- return (ld->bufa >> (ld->bits_left - bits)) & bitmask[bits];
+ //return (ld->bufa >> (ld->bits_left - bits)) & bitmask[bits];
+ return (ld->bufa << (32 - ld->bits_left)) >> (32 - bits);
}
bits -= ld->bits_left;
- return ((ld->bufa & bitmask[ld->bits_left]) << bits) | (ld->bufb >> (32 - bits));
+ //return ((ld->bufa & bitmask[ld->bits_left]) << bits) | (ld->bufb >> (32 - bits));
+ return ((ld->bufa & ((1<<ld->bits_left)-1)) << bits) | (ld->bufb >> (32 - bits));
}
static INLINE void faad_flushbits(bitfile *ld, uint32_t bits)
@@ -144,11 +168,11 @@ static INLINE void faad_flushbits(bitfile *ld, uint32_t bits)
}
/* return next n bits (right adjusted) */
-static INLINE uint32_t faad_getbits(bitfile *ld, uint32_t n DEBUGDEC)
+static /*INLINE*/ uint32_t faad_getbits(bitfile *ld, uint32_t n DEBUGDEC)
{
uint32_t ret;
- if (ld->no_more_reading || n == 0)
+ if (n == 0)
return 0;
ret = faad_showbits(ld, n);
@@ -230,22 +254,23 @@ static INLINE void faad_flushbits_rev(bitfile *ld, uint32_t bits)
ld->start--;
ld->bits_left += (32 - bits);
- ld->bytes_used += 4;
- if (ld->bytes_used == ld->buffer_size)
- ld->no_more_reading = 1;
- if (ld->bytes_used > ld->buffer_size)
+ if (ld->bytes_left < 4)
+ {
ld->error = 1;
+ ld->bytes_left = 0;
+ } else {
+ ld->bytes_left -= 4;
+ }
+// if (ld->bytes_left == 0)
+// ld->no_more_reading = 1;
}
}
-static INLINE uint32_t faad_getbits_rev(bitfile *ld, uint32_t n
+static /*INLINE*/ uint32_t faad_getbits_rev(bitfile *ld, uint32_t n
DEBUGDEC)
{
uint32_t ret;
- if (ld->no_more_reading)
- return 0;
-
if (n == 0)
return 0;
@@ -261,28 +286,73 @@ static INLINE uint32_t faad_getbits_rev(bitfile *ld, uint32_t n
}
#ifdef DRM
+/* CRC lookup table for G8 polynome in DRM standard */
+static const uint8_t crc_table_G8[256] = {
+ 0x0, 0x1d, 0x3a, 0x27, 0x74, 0x69, 0x4e, 0x53,
+ 0xe8, 0xf5, 0xd2, 0xcf, 0x9c, 0x81, 0xa6, 0xbb,
+ 0xcd, 0xd0, 0xf7, 0xea, 0xb9, 0xa4, 0x83, 0x9e,
+ 0x25, 0x38, 0x1f, 0x2, 0x51, 0x4c, 0x6b, 0x76,
+ 0x87, 0x9a, 0xbd, 0xa0, 0xf3, 0xee, 0xc9, 0xd4,
+ 0x6f, 0x72, 0x55, 0x48, 0x1b, 0x6, 0x21, 0x3c,
+ 0x4a, 0x57, 0x70, 0x6d, 0x3e, 0x23, 0x4, 0x19,
+ 0xa2, 0xbf, 0x98, 0x85, 0xd6, 0xcb, 0xec, 0xf1,
+ 0x13, 0xe, 0x29, 0x34, 0x67, 0x7a, 0x5d, 0x40,
+ 0xfb, 0xe6, 0xc1, 0xdc, 0x8f, 0x92, 0xb5, 0xa8,
+ 0xde, 0xc3, 0xe4, 0xf9, 0xaa, 0xb7, 0x90, 0x8d,
+ 0x36, 0x2b, 0xc, 0x11, 0x42, 0x5f, 0x78, 0x65,
+ 0x94, 0x89, 0xae, 0xb3, 0xe0, 0xfd, 0xda, 0xc7,
+ 0x7c, 0x61, 0x46, 0x5b, 0x8, 0x15, 0x32, 0x2f,
+ 0x59, 0x44, 0x63, 0x7e, 0x2d, 0x30, 0x17, 0xa,
+ 0xb1, 0xac, 0x8b, 0x96, 0xc5, 0xd8, 0xff, 0xe2,
+ 0x26, 0x3b, 0x1c, 0x1, 0x52, 0x4f, 0x68, 0x75,
+ 0xce, 0xd3, 0xf4, 0xe9, 0xba, 0xa7, 0x80, 0x9d,
+ 0xeb, 0xf6, 0xd1, 0xcc, 0x9f, 0x82, 0xa5, 0xb8,
+ 0x3, 0x1e, 0x39, 0x24, 0x77, 0x6a, 0x4d, 0x50,
+ 0xa1, 0xbc, 0x9b, 0x86, 0xd5, 0xc8, 0xef, 0xf2,
+ 0x49, 0x54, 0x73, 0x6e, 0x3d, 0x20, 0x7, 0x1a,
+ 0x6c, 0x71, 0x56, 0x4b, 0x18, 0x5, 0x22, 0x3f,
+ 0x84, 0x99, 0xbe, 0xa3, 0xf0, 0xed, 0xca, 0xd7,
+ 0x35, 0x28, 0xf, 0x12, 0x41, 0x5c, 0x7b, 0x66,
+ 0xdd, 0xc0, 0xe7, 0xfa, 0xa9, 0xb4, 0x93, 0x8e,
+ 0xf8, 0xe5, 0xc2, 0xdf, 0x8c, 0x91, 0xb6, 0xab,
+ 0x10, 0xd, 0x2a, 0x37, 0x64, 0x79, 0x5e, 0x43,
+ 0xb2, 0xaf, 0x88, 0x95, 0xc6, 0xdb, 0xfc, 0xe1,
+ 0x5a, 0x47, 0x60, 0x7d, 0x2e, 0x33, 0x14, 0x9,
+ 0x7f, 0x62, 0x45, 0x58, 0xb, 0x16, 0x31, 0x2c,
+ 0x97, 0x8a, 0xad, 0xb0, 0xe3, 0xfe, 0xd9, 0xc4,
+};
+
static uint8_t faad_check_CRC(bitfile *ld, uint16_t len)
{
- uint8_t CRC;
- uint16_t r=255; /* Initialize to all ones */
+ int bytes, rem;
+ unsigned int CRC;
+ unsigned int r=255; /* Initialize to all ones */
/* CRC polynome used x^8 + x^4 + x^3 + x^2 +1 */
#define GPOLY 0435
faad_rewindbits(ld);
- CRC = (uint8_t) ~faad_getbits(ld, 8
- DEBUGVAR(1,999,"faad_check_CRC(): CRC")); /* CRC is stored inverted */
+ CRC = (unsigned int) ~faad_getbits(ld, 8
+ DEBUGVAR(1,999,"faad_check_CRC(): CRC")) & 0xFF; /* CRC is stored inverted */
+
+ bytes = len >> 3;
+ rem = len & 0x7;
- for (; len>0; len--)
+ for (; bytes > 0; bytes--)
+ {
+ r = crc_table_G8[( r ^ faad_getbits(ld, 8 DEBUGVAR(1,998,"")) ) & 0xFF];
+ }
+ for (; rem > 0; rem--)
{
r = ( (r << 1) ^ (( ( faad_get1bit(ld
DEBUGVAR(1,998,"")) & 1) ^ ((r >> 7) & 1)) * GPOLY )) & 0xFF;
}
if (r != CRC)
+ // if (0)
{
- return 8;
+ return 28;
} else {
return 0;
}
diff --git a/src/libfaad/cfft.c b/src/libfaad/cfft.c
index 61cac2fd5..5b01d75d3 100644
--- a/src/libfaad/cfft.c
+++ b/src/libfaad/cfft.c
@@ -1,28 +1,31 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
+**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
-**
+**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
-**
+**
** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
+** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: cfft.c,v 1.12 2006/09/26 18:00:31 dgp85 Exp $
+** $Id: cfft.c,v 1.35 2007/11/01 12:33:29 menno Exp $
**/
/*
@@ -546,7 +549,7 @@ static void passf5(const uint16_t ido, const uint16_t l1, const complex_t *cc,
ComplexMult(&RE(c4), &RE(c5),
ti12, ti11, RE(t5), RE(t4));
ComplexMult(&IM(c4), &IM(c5),
- ti12, ti12, IM(t5), IM(t4));
+ ti12, ti11, IM(t5), IM(t4));
RE(ch[ah+l1]) = RE(c2) + IM(c5);
IM(ch[ah+l1]) = IM(c2) - RE(c5);
@@ -648,7 +651,7 @@ static void passf5(const uint16_t ido, const uint16_t l1, const complex_t *cc,
ComplexMult(&RE(c4), &RE(c5),
ti12, ti11, RE(t5), RE(t4));
ComplexMult(&IM(c4), &IM(c5),
- ti12, ti12, IM(t5), IM(t4));
+ ti12, ti11, IM(t5), IM(t4));
IM(d2) = IM(c2) - RE(c5);
IM(d3) = IM(c3) - RE(c4);
@@ -992,13 +995,11 @@ cfft_info *cffti(uint16_t n)
void cfftu(cfft_info *cfft)
{
- if ( ! cfft ) return;
-
- faad_free(cfft->work);
+ if (cfft->work) faad_free(cfft->work);
#ifndef FIXED_POINT
- faad_free(cfft->tab);
+ if (cfft->tab) faad_free(cfft->tab);
#endif
- faad_free(cfft);
+ if (cfft) faad_free(cfft);
}
diff --git a/src/libfaad/cfft.h b/src/libfaad/cfft.h
index a29537bed..dc89cdc85 100644
--- a/src/libfaad/cfft.h
+++ b/src/libfaad/cfft.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: cfft.h,v 1.9 2005/10/29 23:57:06 tmmm Exp $
+** $Id: cfft.h,v 1.24 2007/11/01 12:33:29 menno Exp $
**/
#ifndef __CFFT_H__
diff --git a/src/libfaad/cfft_tab.h b/src/libfaad/cfft_tab.h
index 072a991f1..80b1b75be 100644
--- a/src/libfaad/cfft_tab.h
+++ b/src/libfaad/cfft_tab.h
@@ -1,28 +1,31 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
+**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
-**
+**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
-**
+**
** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
+** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: cfft_tab.h,v 1.6 2005/10/29 23:57:06 tmmm Exp $
+** $Id: cfft_tab.h,v 1.21 2007/11/01 12:33:29 menno Exp $
**/
#ifndef __CFFT_TAB_H__
diff --git a/src/libfaad/codebook/hcb.h b/src/libfaad/codebook/hcb.h
index 96093300c..29bbca4f8 100644
--- a/src/libfaad/codebook/hcb.h
+++ b/src/libfaad/codebook/hcb.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: hcb.h,v 1.6 2005/10/29 23:57:08 tmmm Exp $
+** $Id: hcb.h,v 1.8 2007/11/01 12:34:10 menno Exp $
**/
#ifndef __HCB_H__
diff --git a/src/libfaad/codebook/hcb_1.h b/src/libfaad/codebook/hcb_1.h
index 220299c55..f6632c230 100644
--- a/src/libfaad/codebook/hcb_1.h
+++ b/src/libfaad/codebook/hcb_1.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: hcb_1.h,v 1.4 2005/10/29 23:57:08 tmmm Exp $
+** $Id: hcb_1.h,v 1.5 2007/11/01 12:34:11 menno Exp $
**/
/* 2-step huffman table HCB_1 */
diff --git a/src/libfaad/codebook/hcb_10.h b/src/libfaad/codebook/hcb_10.h
index 60bcab90a..87e621df5 100644
--- a/src/libfaad/codebook/hcb_10.h
+++ b/src/libfaad/codebook/hcb_10.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: hcb_10.h,v 1.4 2005/10/29 23:57:08 tmmm Exp $
+** $Id: hcb_10.h,v 1.5 2007/11/01 12:34:11 menno Exp $
**/
/* 2-step huffman table HCB_10 */
diff --git a/src/libfaad/codebook/hcb_11.h b/src/libfaad/codebook/hcb_11.h
index bd4f647e6..509a1d684 100644
--- a/src/libfaad/codebook/hcb_11.h
+++ b/src/libfaad/codebook/hcb_11.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: hcb_11.h,v 1.4 2005/10/29 23:57:08 tmmm Exp $
+** $Id: hcb_11.h,v 1.5 2007/11/01 12:34:11 menno Exp $
**/
/* 2-step huffman table HCB_11 */
diff --git a/src/libfaad/codebook/hcb_2.h b/src/libfaad/codebook/hcb_2.h
index 6aff6b12b..8edfe525d 100644
--- a/src/libfaad/codebook/hcb_2.h
+++ b/src/libfaad/codebook/hcb_2.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: hcb_2.h,v 1.4 2005/10/29 23:57:08 tmmm Exp $
+** $Id: hcb_2.h,v 1.5 2007/11/01 12:34:11 menno Exp $
**/
/* 2-step huffman table HCB_2 */
diff --git a/src/libfaad/codebook/hcb_3.h b/src/libfaad/codebook/hcb_3.h
index 25b54da90..e9481e198 100644
--- a/src/libfaad/codebook/hcb_3.h
+++ b/src/libfaad/codebook/hcb_3.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: hcb_3.h,v 1.4 2005/10/29 23:57:08 tmmm Exp $
+** $Id: hcb_3.h,v 1.5 2007/11/01 12:34:11 menno Exp $
**/
/* Binary search huffman table HCB_3 */
diff --git a/src/libfaad/codebook/hcb_4.h b/src/libfaad/codebook/hcb_4.h
index 9378b0980..c2b43e005 100644
--- a/src/libfaad/codebook/hcb_4.h
+++ b/src/libfaad/codebook/hcb_4.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: hcb_4.h,v 1.4 2005/10/29 23:57:08 tmmm Exp $
+** $Id: hcb_4.h,v 1.5 2007/11/01 12:34:11 menno Exp $
**/
/* 2-step huffman table HCB_4 */
diff --git a/src/libfaad/codebook/hcb_5.h b/src/libfaad/codebook/hcb_5.h
index 7e50207e3..ca7c473bf 100644
--- a/src/libfaad/codebook/hcb_5.h
+++ b/src/libfaad/codebook/hcb_5.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: hcb_5.h,v 1.4 2005/10/29 23:57:08 tmmm Exp $
+** $Id: hcb_5.h,v 1.5 2007/11/01 12:34:11 menno Exp $
**/
/* Binary search huffman table HCB_5 */
diff --git a/src/libfaad/codebook/hcb_6.h b/src/libfaad/codebook/hcb_6.h
index 12417d997..2181d63d5 100644
--- a/src/libfaad/codebook/hcb_6.h
+++ b/src/libfaad/codebook/hcb_6.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: hcb_6.h,v 1.4 2005/10/29 23:57:08 tmmm Exp $
+** $Id: hcb_6.h,v 1.5 2007/11/01 12:34:11 menno Exp $
**/
/* 2-step huffman table HCB_6 */
diff --git a/src/libfaad/codebook/hcb_7.h b/src/libfaad/codebook/hcb_7.h
index e5392326d..54c85c11d 100644
--- a/src/libfaad/codebook/hcb_7.h
+++ b/src/libfaad/codebook/hcb_7.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: hcb_7.h,v 1.4 2005/10/29 23:57:08 tmmm Exp $
+** $Id: hcb_7.h,v 1.5 2007/11/01 12:34:11 menno Exp $
**/
/* Binary search huffman table HCB_7 */
diff --git a/src/libfaad/codebook/hcb_8.h b/src/libfaad/codebook/hcb_8.h
index 951743bed..6e3f1009e 100644
--- a/src/libfaad/codebook/hcb_8.h
+++ b/src/libfaad/codebook/hcb_8.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: hcb_8.h,v 1.4 2005/10/29 23:57:08 tmmm Exp $
+** $Id: hcb_8.h,v 1.5 2007/11/01 12:34:11 menno Exp $
**/
/* 2-step huffman table HCB_8 */
diff --git a/src/libfaad/codebook/hcb_9.h b/src/libfaad/codebook/hcb_9.h
index daccf6197..bdba2c222 100644
--- a/src/libfaad/codebook/hcb_9.h
+++ b/src/libfaad/codebook/hcb_9.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: hcb_9.h,v 1.4 2005/10/29 23:57:08 tmmm Exp $
+** $Id: hcb_9.h,v 1.5 2007/11/01 12:34:11 menno Exp $
**/
/* Binary search huffman table HCB_9 */
diff --git a/src/libfaad/codebook/hcb_sf.h b/src/libfaad/codebook/hcb_sf.h
index 494053177..3c02b3d84 100644
--- a/src/libfaad/codebook/hcb_sf.h
+++ b/src/libfaad/codebook/hcb_sf.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: hcb_sf.h,v 1.4 2005/10/29 23:57:08 tmmm Exp $
+** $Id: hcb_sf.h,v 1.7 2007/11/01 12:34:11 menno Exp $
**/
/* Binary search huffman table HCB_SF */
diff --git a/src/libfaad/common.c b/src/libfaad/common.c
index 8c0d93e95..595605586 100644
--- a/src/libfaad/common.c
+++ b/src/libfaad/common.c
@@ -1,28 +1,31 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
+**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
-**
+**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
-**
+**
** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
+** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: common.c,v 1.8 2005/10/29 23:57:06 tmmm Exp $
+** $Id: common.c,v 1.26 2007/11/01 12:33:30 menno Exp $
**/
/* just some common functions that could be used anywhere */
@@ -229,16 +232,16 @@ static uint32_t __r2 = 1;
* which gives a period of 18.410.713.077.675.721.215. The result is the
* XORed values of both generators.
*/
-uint32_t random_int(void)
+uint32_t ne_rng(uint32_t *__r1, uint32_t *__r2)
{
uint32_t t1, t2, t3, t4;
- t3 = t1 = __r1; t4 = t2 = __r2; // Parity calculation is done via table lookup, this is also available
+ t3 = t1 = *__r1; t4 = t2 = *__r2; // Parity calculation is done via table lookup, this is also available
t1 &= 0xF5; t2 >>= 25; // on CPUs without parity, can be implemented in C and avoid unpredictable
t1 = Parity [t1]; t2 &= 0x63; // jumps and slow rotate through the carry flag operations.
t1 <<= 31; t2 = Parity [t2];
- return (__r1 = (t3 >> 1) | t1 ) ^ (__r2 = (t4 + t4) | t2 );
+ return (*__r1 = (t3 >> 1) | t1 ) ^ (*__r2 = (t4 + t4) | t2 );
}
uint32_t ones32(uint32_t x)
diff --git a/src/libfaad/common.h b/src/libfaad/common.h
index 31f07708a..4419f1eb5 100644
--- a/src/libfaad/common.h
+++ b/src/libfaad/common.h
@@ -1,28 +1,31 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
+**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
-**
+**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
-**
+**
** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
+** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: common.h,v 1.17 2006/06/17 20:43:57 dgp85 Exp $
+** $Id: common.h,v 1.72 2007/11/01 12:33:30 menno Exp $
**/
#ifndef __COMMON_H__
@@ -32,13 +35,16 @@
extern "C" {
#endif
-#ifdef __CYGWIN__
-#define __STRICT_ANSI__
+#ifdef HAVE_CONFIG_H
+# include "config.h"
#endif
-#include "config.h"
-
+#if 1
#define INLINE __inline
+#else
+#define INLINE inline
+#endif
+
#if 0 //defined(_WIN32) && !defined(_WIN32_WCE)
#define ALIGN __declspec(align(16))
#else
@@ -63,10 +69,13 @@ extern "C" {
/* Use if target platform has address generators with autoincrement */
//#define PREFER_POINTERS
-#if defined(_WIN32_WCE) || defined(__arm__)
+#ifdef _WIN32_WCE
#define FIXED_POINT
#endif
+#ifdef __BFIN__
+#define FIXED_POINT
+#endif
#define ERROR_RESILIENCE
@@ -79,8 +88,6 @@ extern "C" {
#define LTP_DEC
/* Allow decoding of LD profile AAC */
#define LD_DEC
-/* Allow decoding of scalable profiles */
-//#define SCALABLE_DEC
/* Allow decoding of Digital Radio Mondiale (DRM) */
//#define DRM
//#define DRM_PS
@@ -114,20 +121,25 @@ extern "C" {
//#define SBR_LOW_POWER
#define PS_DEC
+#ifdef SBR_LOW_POWER
+#undef PS_DEC
+#endif
+
/* FIXED POINT: No MAIN decoding */
#ifdef FIXED_POINT
# ifdef MAIN_DEC
# undef MAIN_DEC
# endif
-# ifdef SBR_DEC
-# undef SBR_DEC
-# endif
#endif // FIXED_POINT
#ifdef DRM
-# ifndef SCALABLE_DEC
-# define SCALABLE_DEC
+# ifndef ALLOW_SMALL_FRAMELENGTH
+# define ALLOW_SMALL_FRAMELENGTH
# endif
+# undef LD_DEC
+# undef LTP_DEC
+# undef MAIN_DEC
+# undef SSR_DEC
#endif
@@ -152,6 +164,23 @@ extern "C" {
/* END COMPILE TIME DEFINITIONS */
+#if defined(_WIN32) && !defined(__MINGW32__)
+
+#include <stdlib.h>
+
+typedef unsigned __int64 uint64_t;
+typedef unsigned __int32 uint32_t;
+typedef unsigned __int16 uint16_t;
+typedef unsigned __int8 uint8_t;
+typedef __int64 int64_t;
+typedef __int32 int32_t;
+typedef __int16 int16_t;
+typedef __int8 int8_t;
+typedef float float32_t;
+
+
+#else
+
#include <stdio.h>
#if HAVE_SYS_TYPES_H
# include <sys/types.h>
@@ -176,8 +205,6 @@ extern "C" {
#if HAVE_STRINGS_H
# include <strings.h>
#endif
-
-/* precedence defining int-types by header files for all platforms */
#if HAVE_INTTYPES_H
# include <inttypes.h>
#else
@@ -185,30 +212,23 @@ extern "C" {
# include <stdint.h>
# else
/* we need these... */
-# ifdef WIN32
-typedef unsigned __int64 uint64_t;
-typedef unsigned __int32 uint32_t;
-typedef unsigned __int16 uint16_t;
-typedef unsigned __int8 uint8_t;
-typedef __int64 int64_t;
-typedef __int32 int32_t;
-typedef __int16 int16_t;
-typedef __int8 int8_t;
-# else /* WIN32 */
-typedef float float32_t;
+#ifndef __TCS__
typedef unsigned long long uint64_t;
+typedef long long int64_t;
+#else
+typedef unsigned long uint64_t;
+typedef long int64_t;
+#endif
typedef unsigned long uint32_t;
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;
-typedef long long int64_t;
typedef long int32_t;
typedef short int16_t;
typedef char int8_t;
-# endif /* WIN32 */
# endif
#endif
#if HAVE_UNISTD_H
-# include <unistd.h>
+//# include <unistd.h>
#endif
#ifndef HAVE_FLOAT32_T
@@ -229,6 +249,8 @@ char *strchr(), *strrchr();
# endif
#endif
+#endif
+
#ifdef WORDS_BIGENDIAN
#define ARCH_IS_BIG_ENDIAN
#endif
@@ -289,7 +311,6 @@ char *strchr(), *strrchr();
}
-#ifndef HAVE_LRINTF
#if defined(_WIN32) && !defined(__MINGW32__)
#define HAS_LRINTF
static INLINE int lrintf(float f)
@@ -302,7 +323,9 @@ char *strchr(), *strrchr();
}
return i;
}
- #elif (defined(__i386__) && defined(__GNUC__))
+ #elif (defined(__i386__) && defined(__GNUC__) && \
+ !defined(__CYGWIN__) && !defined(__MINGW32__))
+ #ifndef HAVE_LRINTF
#define HAS_LRINTF
// from http://www.stereopsis.com/FPU.html
static INLINE int lrintf(float f)
@@ -315,8 +338,9 @@ char *strchr(), *strrchr();
: "m" (f));
return i;
}
+ #endif /* HAVE_LRINTF */
#endif
-#endif
+
#ifdef __ICL /* only Intel C compiler has fmath ??? */
@@ -331,8 +355,6 @@ char *strchr(), *strrchr();
#else
-#include <math.h>
-
#ifdef HAVE_LRINTF
# define HAS_LRINTF
# define _ISOC9X_SOURCE 1
@@ -341,6 +363,8 @@ char *strchr(), *strrchr();
# define __USE_ISOC99 1
#endif
+ #include <math.h>
+
#ifdef HAVE_SINF
# define sin sinf
#error
@@ -380,7 +404,7 @@ typedef real_t complex_t[2];
/* common functions */
uint8_t cpu_has_sse(void);
-uint32_t random_int(void);
+uint32_t ne_rng(uint32_t *__r1, uint32_t *__r2);
uint32_t ones32(uint32_t x);
uint32_t floor_log2(uint32_t x);
uint32_t wl_min_lzc(uint32_t x);
diff --git a/src/libfaad/decoder.c b/src/libfaad/decoder.c
index 33aee247e..7fb4b1965 100644
--- a/src/libfaad/decoder.c
+++ b/src/libfaad/decoder.c
@@ -1,28 +1,31 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
+**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
-**
+**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
-**
+**
** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
+** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: decoder.c,v 1.10 2005/10/29 23:57:06 tmmm Exp $
+** $Id: decoder.c,v 1.111 2007/11/01 12:33:30 menno Exp $
**/
#include "common.h"
@@ -90,6 +93,7 @@ uint32_t NEAACDECAPI NeAACDecGetCapabilities(void)
return cap;
}
+const unsigned char mes[] = { 0x67,0x20,0x61,0x20,0x20,0x20,0x6f,0x20,0x72,0x20,0x65,0x20,0x6e,0x20,0x20,0x20,0x74,0x20,0x68,0x20,0x67,0x20,0x69,0x20,0x72,0x20,0x79,0x20,0x70,0x20,0x6f,0x20,0x63 };
NeAACDecHandle NEAACDECAPI NeAACDecOpen(void)
{
uint8_t i;
@@ -100,6 +104,7 @@ NeAACDecHandle NEAACDECAPI NeAACDecOpen(void)
memset(hDecoder, 0, sizeof(NeAACDecStruct));
+ hDecoder->cmes = mes;
hDecoder->config.outputFormat = FAAD_FMT_16BIT;
hDecoder->config.defObjectType = MAIN;
hDecoder->config.defSampleRate = 44100; /* Default: 44.1kHz */
@@ -116,6 +121,9 @@ NeAACDecHandle NEAACDECAPI NeAACDecOpen(void)
hDecoder->frame = 0;
hDecoder->sample_buffer = NULL;
+ hDecoder->__r1 = 1;
+ hDecoder->__r2 = 1;
+
for (i = 0; i < MAX_CHANNELS; i++)
{
hDecoder->window_shape_prev[i] = 0;
@@ -194,6 +202,7 @@ uint8_t NEAACDECAPI NeAACDecSetConfiguration(NeAACDecHandle hDecoder,
return 0;
}
+
int32_t NEAACDECAPI NeAACDecInit(NeAACDecHandle hDecoder, uint8_t *buffer,
uint32_t buffer_size,
uint32_t *samplerate, uint8_t *channels)
@@ -203,6 +212,7 @@ int32_t NEAACDECAPI NeAACDecInit(NeAACDecHandle hDecoder, uint8_t *buffer,
adif_header adif;
adts_header adts;
+
if ((hDecoder == NULL) || (samplerate == NULL) || (channels == NULL))
return -1;
@@ -257,7 +267,6 @@ int32_t NEAACDECAPI NeAACDecInit(NeAACDecHandle hDecoder, uint8_t *buffer,
}
faad_endbits(&ld);
}
- hDecoder->channelConfiguration = *channels;
#if (defined(PS_DEC) || defined(DRM_PS))
/* check if we have a mono file */
@@ -268,6 +277,8 @@ int32_t NEAACDECAPI NeAACDecInit(NeAACDecHandle hDecoder, uint8_t *buffer,
}
#endif
+ hDecoder->channelConfiguration = *channels;
+
#ifdef SBR_DEC
/* implicit signalling */
if (*samplerate <= 24000 && !(hDecoder->config.dontUpSampleImplicitSBR))
@@ -422,8 +433,8 @@ int8_t NEAACDECAPI NeAACDecInitDRM(NeAACDecHandle *hDecoder, uint32_t samplerate
if ((channels == DRMCH_MONO) || (channels == DRMCH_STEREO))
(*hDecoder)->sbr_present_flag = 0;
else
- (*hDecoder)->sbr_present_flag = 1;
-#endif
+ (*hDecoder)->sbr_present_flag = 1;
+#endif
(*hDecoder)->fb = filter_bank_init((*hDecoder)->frameLength);
@@ -525,8 +536,14 @@ static void create_channel_config(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hI
chdir = hInfo->num_front_channels;
if (chdir & 1)
{
+#if (defined(PS_DEC) || defined(DRM_PS))
+ /* When PS is enabled output is always stereo */
+ hInfo->channel_position[chpos++] = FRONT_CHANNEL_LEFT;
+ hInfo->channel_position[chpos++] = FRONT_CHANNEL_RIGHT;
+#else
hInfo->channel_position[chpos++] = FRONT_CHANNEL_CENTER;
chdir--;
+#endif
}
for (i = 0; i < chdir; i += 2)
{
@@ -565,8 +582,15 @@ static void create_channel_config(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hI
switch (hDecoder->channelConfiguration)
{
case 1:
+#if (defined(PS_DEC) || defined(DRM_PS))
+ /* When PS is enabled output is always stereo */
+ hInfo->num_front_channels = 2;
+ hInfo->channel_position[0] = FRONT_CHANNEL_LEFT;
+ hInfo->channel_position[1] = FRONT_CHANNEL_RIGHT;
+#else
hInfo->num_front_channels = 1;
hInfo->channel_position[0] = FRONT_CHANNEL_CENTER;
+#endif
break;
case 2:
hInfo->num_front_channels = 2;
@@ -722,13 +746,25 @@ void* NEAACDECAPI NeAACDecDecode2(NeAACDecHandle hDecoder,
sample_buffer, sample_buffer_size);
}
+#ifdef DRM
+
+#define ERROR_STATE_INIT 6
+
+static void conceal_output(NeAACDecHandle hDecoder, uint16_t frame_len,
+ uint8_t out_ch, void *sample_buffer)
+{
+ return;
+}
+#endif
+
static void* aac_frame_decode(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo,
uint8_t *buffer, uint32_t buffer_size,
void **sample_buffer2, uint32_t sample_buffer_size)
{
+ uint16_t i;
uint8_t channels = 0;
uint8_t output_channels = 0;
- bitfile ld;
+ bitfile ld = {0};
uint32_t bitsconsumed;
uint16_t frame_len;
void *sample_buffer;
@@ -753,6 +789,33 @@ static void* aac_frame_decode(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo,
memset(hInfo, 0, sizeof(NeAACDecFrameInfo));
memset(hDecoder->internal_channel, 0, MAX_CHANNELS*sizeof(hDecoder->internal_channel[0]));
+#ifdef USE_TIME_LIMIT
+ if ((TIME_LIMIT * get_sample_rate(hDecoder->sf_index)) > hDecoder->TL_count)
+ {
+ hDecoder->TL_count += 1024;
+ } else {
+ hInfo->error = (NUM_ERROR_MESSAGES-1);
+ goto error;
+ }
+#endif
+
+
+ /* check for some common metadata tag types in the bitstream
+ * No need to return an error
+ */
+ /* ID3 */
+ if (buffer_size >= 128)
+ {
+ if (memcmp(buffer, "TAG", 3) == 0)
+ {
+ /* found it */
+ hInfo->bytesconsumed = 128; /* 128 bytes fixed size */
+ /* no error, but no output either */
+ return NULL;
+ }
+ }
+
+
/* initialize the bitstream */
faad_initbits(&ld, buffer, buffer_size);
@@ -780,7 +843,7 @@ static void* aac_frame_decode(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo,
/* We do not support stereo right now */
if (0) //(hDecoder->channelConfiguration == 2)
{
- hInfo->error = 8; // Throw CRC error
+ hInfo->error = 28; // Throw CRC error
goto error;
}
@@ -808,14 +871,14 @@ static void* aac_frame_decode(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo,
#endif
/* decode the complete bitstream */
-#ifdef SCALABLE_DEC
- if ((hDecoder->object_type == 6) || (hDecoder->object_type == DRM_ER_LC))
+#ifdef DRM
+ if (/*(hDecoder->object_type == 6) ||*/ (hDecoder->object_type == DRM_ER_LC))
{
- aac_scalable_main_element(hDecoder, hInfo, &ld, &hDecoder->pce, hDecoder->drc);
+ DRM_aac_scalable_main_element(hDecoder, hInfo, &ld, &hDecoder->pce, hDecoder->drc);
} else {
#endif
raw_data_block(hDecoder, hInfo, &ld, &hDecoder->pce, hDecoder->drc);
-#ifdef SCALABLE_DEC
+#ifdef DRM
}
#endif
@@ -978,10 +1041,16 @@ static void* aac_frame_decode(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo,
}
#endif
+
sample_buffer = output_to_PCM(hDecoder, hDecoder->time_out, sample_buffer,
output_channels, frame_len, hDecoder->config.outputFormat);
+#ifdef DRM
+ //conceal_output(hDecoder, frame_len, output_channels, sample_buffer);
+#endif
+
+
hDecoder->postSeekResetFlag = 0;
hDecoder->frame++;
@@ -1013,6 +1082,30 @@ static void* aac_frame_decode(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo,
error:
+
+#ifdef DRM
+ hDecoder->error_state = ERROR_STATE_INIT;
+#endif
+
+ /* reset filterbank state */
+ for (i = 0; i < MAX_CHANNELS; i++)
+ {
+ if (hDecoder->fb_intermed[i] != NULL)
+ {
+ memset(hDecoder->fb_intermed[i], 0, hDecoder->frameLength*sizeof(real_t));
+ }
+ }
+#ifdef SBR_DEC
+ for (i = 0; i < MAX_SYNTAX_ELEMENTS; i++)
+ {
+ if (hDecoder->sbr[i] != NULL)
+ {
+ sbrReset(hDecoder->sbr[i]);
+ }
+ }
+#endif
+
+
faad_endbits(&ld);
/* cleanup */
diff --git a/src/libfaad/decoder.h b/src/libfaad/decoder.h
index 5a3a2663f..a4cb567d2 100644
--- a/src/libfaad/decoder.h
+++ b/src/libfaad/decoder.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: decoder.h,v 1.9 2005/10/29 23:57:06 tmmm Exp $
+** $Id: decoder.h,v 1.48 2007/11/01 12:33:30 menno Exp $
**/
#ifndef __DECODER_H__
diff --git a/src/libfaad/drc.c b/src/libfaad/drc.c
index ef4b6a96e..3c9ff3ae0 100644
--- a/src/libfaad/drc.c
+++ b/src/libfaad/drc.c
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: drc.c,v 1.7 2005/10/29 23:57:06 tmmm Exp $
+** $Id: drc.c,v 1.28 2007/11/01 12:33:30 menno Exp $
**/
#include "common.h"
diff --git a/src/libfaad/drc.h b/src/libfaad/drc.h
index 046ecbc3e..49118bcd0 100644
--- a/src/libfaad/drc.h
+++ b/src/libfaad/drc.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: drc.h,v 1.7 2005/10/29 23:57:06 tmmm Exp $
+** $Id: drc.h,v 1.22 2007/11/01 12:33:30 menno Exp $
**/
#ifndef __DRC_H__
diff --git a/src/libfaad/drm_dec.c b/src/libfaad/drm_dec.c
index a782b0f22..61cb8180e 100644
--- a/src/libfaad/drm_dec.c
+++ b/src/libfaad/drm_dec.c
@@ -1,28 +1,31 @@
/*
-** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR and PS decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
+** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
+**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
-**
+**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
-**
+**
** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
+** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: drm_dec.c,v 1.1 2005/10/30 00:50:19 tmmm Exp $
+** $Id: drm_dec.c,v 1.9 2007/11/01 12:33:30 menno Exp $
**/
#include <stdlib.h>
@@ -243,17 +246,9 @@ static const real_t sa_sqrt_1_minus[8][2] = {
{ FRAC_CONST(0.929071574), FRAC_CONST(0) }
};
-static const uint8_t sa_freq_scale[9][2] =
+static const uint8_t sa_freq_scale[9] =
{
- { 0, 0},
- { 1, 1},
- { 2, 2},
- { 3, 3},
- { 5, 5},
- { 7, 7},
- {10,10},
- {13,13},
- {46,23}
+ 0, 1, 2, 3, 5, 7, 10, 13, 23
};
static const uint8_t pan_freq_scale[21] =
@@ -290,9 +285,9 @@ static const real_t filter_coeff[] =
FRAC_CONST(0.48954165955695)
};
-static const uint8_t delay_length[][2] =
+static const uint8_t delay_length[3] =
{
- { 1, 3 }, { 2, 4 }, { 3, 5 }
+ 3, 4, 5
};
static const real_t delay_fraction[] =
@@ -300,15 +295,9 @@ static const real_t delay_fraction[] =
FRAC_CONST(0.43), FRAC_CONST(0.75), FRAC_CONST(0.347)
};
-static const real_t peak_decay[2] =
-{
- FRAC_CONST(0.58664621951003), FRAC_CONST(0.76592833836465)
-};
+static const real_t peak_decay = FRAC_CONST(0.76592833836465);
-static const real_t smooth_coeff[2] =
-{
- FRAC_CONST(0.6), FRAC_CONST(0.25)
-};
+static const real_t smooth_coeff = FRAC_CONST(0.25);
/* Please note that these are the same tables as in plain PS */
static const complex_t Q_Fract_allpass_Qmf[][3] = {
@@ -566,25 +555,22 @@ static void drm_ps_delta_decode(drm_ps_info *ps)
{
if (ps->bs_sa_dt_flag && !ps->g_last_had_sa)
{
- for (band = 0; band < DRM_NUM_SA_BANDS; band++)
- {
- ps->g_prev_sa_index[band] = 0;
- }
- }
- if (ps->bs_sa_dt_flag)
- {
+ /* wait until we get a DT frame */
+ ps->bs_enable_sa = 0;
+ } else if (ps->bs_sa_dt_flag) {
+ /* DT frame, we have a last frame, so we can decode */
ps->g_sa_index[0] = sa_delta_clip(ps, ps->g_prev_sa_index[0]+ps->bs_sa_data[0]);
-
} else {
+ /* DF always decodable */
ps->g_sa_index[0] = sa_delta_clip(ps,ps->bs_sa_data[0]);
}
for (band = 1; band < DRM_NUM_SA_BANDS; band++)
{
- if (ps->bs_sa_dt_flag)
+ if (ps->bs_sa_dt_flag && ps->g_last_had_sa)
{
ps->g_sa_index[band] = sa_delta_clip(ps, ps->g_prev_sa_index[band] + ps->bs_sa_data[band]);
- } else {
+ } else if (!ps->bs_sa_dt_flag) {
ps->g_sa_index[band] = sa_delta_clip(ps, ps->g_sa_index[band-1] + ps->bs_sa_data[band]);
}
}
@@ -618,28 +604,19 @@ static void drm_ps_delta_decode(drm_ps_info *ps)
{
if (ps->bs_pan_dt_flag && !ps->g_last_had_pan)
{
-/* The DRM PS spec doesn't say anything about this case. (deltacoded in time without a previous frame)
- AAC PS spec you must tread previous frame as 0, so that's what we try.
-*/
- for (band = 0; band < DRM_NUM_PAN_BANDS; band++)
- {
- ps->g_prev_pan_index[band] = 0;
- }
- }
-
- if (ps->bs_pan_dt_flag)
- {
- ps->g_pan_index[0] = pan_delta_clip(ps, ps->g_prev_pan_index[0]+ps->bs_pan_data[0]);
+ ps->bs_enable_pan = 0;
+ } else if (ps->bs_pan_dt_flag) {
+ ps->g_pan_index[0] = pan_delta_clip(ps, ps->g_prev_pan_index[0]+ps->bs_pan_data[0]);
} else {
- ps->g_pan_index[0] = pan_delta_clip(ps, ps->bs_pan_data[0]);
+ ps->g_pan_index[0] = pan_delta_clip(ps, ps->bs_pan_data[0]);
}
for (band = 1; band < DRM_NUM_PAN_BANDS; band++)
{
- if (ps->bs_pan_dt_flag)
+ if (ps->bs_pan_dt_flag && ps->g_last_had_pan)
{
ps->g_pan_index[band] = pan_delta_clip(ps, ps->g_prev_pan_index[band] + ps->bs_pan_data[band]);
- } else {
+ } else if (!ps->bs_pan_dt_flag) {
ps->g_pan_index[band] = pan_delta_clip(ps, ps->g_pan_index[band-1] + ps->bs_pan_data[band]);
}
}
@@ -658,7 +635,7 @@ static void drm_ps_delta_decode(drm_ps_info *ps)
}
}
-static void drm_calc_sa_side_signal(drm_ps_info *ps, qmf_t X[38][64], uint8_t rateselect)
+static void drm_calc_sa_side_signal(drm_ps_info *ps, qmf_t X[38][64])
{
uint8_t s, b, k;
complex_t qfrac, tmp0, tmp, in, R0;
@@ -673,7 +650,7 @@ static void drm_calc_sa_side_signal(drm_ps_info *ps, qmf_t X[38][64], uint8_t ra
uint32_t in_re, in_im;
#endif
- for (b = 0; b < sa_freq_scale[DRM_NUM_SA_BANDS][rateselect]; b++)
+ for (b = 0; b < sa_freq_scale[DRM_NUM_SA_BANDS]; b++)
{
/* set delay indices */
for (k = 0; k < NUM_OF_LINKS; k++)
@@ -701,16 +678,16 @@ static void drm_calc_sa_side_signal(drm_ps_info *ps, qmf_t X[38][64], uint8_t ra
power = MUL_R(RE(in),RE(in)) + MUL_R(IM(in),IM(in));
#endif
- ps->peakdecay_fast[b] = MUL_F(ps->peakdecay_fast[b], peak_decay[rateselect]);
+ ps->peakdecay_fast[b] = MUL_F(ps->peakdecay_fast[b], peak_decay);
if (ps->peakdecay_fast[b] < power)
ps->peakdecay_fast[b] = power;
peakdiff = ps->prev_peakdiff[b];
- peakdiff += MUL_F((ps->peakdecay_fast[b] - power - ps->prev_peakdiff[b]), smooth_coeff[rateselect]);
+ peakdiff += MUL_F((ps->peakdecay_fast[b] - power - ps->prev_peakdiff[b]), smooth_coeff);
ps->prev_peakdiff[b] = peakdiff;
nrg = ps->prev_nrg[b];
- nrg += MUL_F((power - ps->prev_nrg[b]), smooth_coeff[rateselect]);
+ nrg += MUL_F((power - ps->prev_nrg[b]), smooth_coeff);
ps->prev_nrg[b] = nrg;
if (MUL_R(peakdiff, gamma) <= nrg) {
@@ -763,7 +740,7 @@ static void drm_calc_sa_side_signal(drm_ps_info *ps, qmf_t X[38][64], uint8_t ra
for (k = 0; k < NUM_OF_LINKS; k++)
{
- if (++temp_delay_ser[k] >= delay_length[k][rateselect])
+ if (++temp_delay_ser[k] >= delay_length[k])
temp_delay_ser[k] = 0;
}
}
@@ -773,7 +750,7 @@ static void drm_calc_sa_side_signal(drm_ps_info *ps, qmf_t X[38][64], uint8_t ra
ps->delay_buf_index_ser[k] = temp_delay_ser[k];
}
-static void drm_add_ambiance(drm_ps_info *ps, uint8_t rateselect, qmf_t X_left[38][64], qmf_t X_right[38][64])
+static void drm_add_ambiance(drm_ps_info *ps, qmf_t X_left[38][64], qmf_t X_right[38][64])
{
uint8_t s, b, ifreq, qclass;
real_t sa_map[MAX_SA_BAND], sa_dir_map[MAX_SA_BAND], k_sa_map[MAX_SA_BAND], k_sa_dir_map[MAX_SA_BAND];
@@ -783,7 +760,7 @@ static void drm_add_ambiance(drm_ps_info *ps, uint8_t rateselect, qmf_t X_left[3
{
/* Instead of dequantization and mapping, we use an inverse mapping
to look up all the values we need */
- for (b = 0; b < sa_freq_scale[DRM_NUM_SA_BANDS][rateselect]; b++)
+ for (b = 0; b < sa_freq_scale[DRM_NUM_SA_BANDS]; b++)
{
const real_t inv_f_num_of_subsamples = FRAC_CONST(0.03333333333);
@@ -804,7 +781,7 @@ static void drm_add_ambiance(drm_ps_info *ps, uint8_t rateselect, qmf_t X_left[3
for (s = 0; s < NUM_OF_SUBSAMPLES; s++)
{
- for (b = 0; b < sa_freq_scale[DRM_NUM_SA_BANDS][rateselect]; b++)
+ for (b = 0; b < sa_freq_scale[DRM_NUM_SA_BANDS]; b++)
{
QMF_RE(X_right[s][b]) = MUL_F(QMF_RE(X_left[s][b]), sa_dir_map[b]) - MUL_F(QMF_RE(ps->SA[s][b]), sa_map[b]);
QMF_IM(X_right[s][b]) = MUL_F(QMF_IM(X_left[s][b]), sa_dir_map[b]) - MUL_F(QMF_IM(ps->SA[s][b]), sa_map[b]);
@@ -814,7 +791,7 @@ static void drm_add_ambiance(drm_ps_info *ps, uint8_t rateselect, qmf_t X_left[3
sa_map[b] += k_sa_map[b];
sa_dir_map[b] += k_sa_dir_map[b];
}
- for (b = sa_freq_scale[DRM_NUM_SA_BANDS][rateselect]; b < NUM_OF_QMF_CHANNELS; b++)
+ for (b = sa_freq_scale[DRM_NUM_SA_BANDS]; b < NUM_OF_QMF_CHANNELS; b++)
{
QMF_RE(X_right[s][b]) = QMF_RE(X_left[s][b]);
QMF_IM(X_right[s][b]) = QMF_IM(X_left[s][b]);
@@ -833,7 +810,7 @@ static void drm_add_ambiance(drm_ps_info *ps, uint8_t rateselect, qmf_t X_left[3
}
}
-static void drm_add_pan(drm_ps_info *ps, uint8_t rateselect, qmf_t X_left[38][64], qmf_t X_right[38][64])
+static void drm_add_pan(drm_ps_info *ps, qmf_t X_left[38][64], qmf_t X_right[38][64])
{
uint8_t s, b, qclass, ifreq;
real_t tmp, coeff1, coeff2;
@@ -924,10 +901,8 @@ void drm_ps_free(drm_ps_info *ps)
}
/* main DRM PS decoding function */
-uint8_t drm_ps_decode(drm_ps_info *ps, uint8_t guess, uint32_t samplerate, qmf_t X_left[38][64], qmf_t X_right[38][64])
-{
- uint8_t rateselect = (samplerate >= 24000);
-
+uint8_t drm_ps_decode(drm_ps_info *ps, uint8_t guess, qmf_t X_left[38][64], qmf_t X_right[38][64])
+{
if (ps == NULL)
{
memcpy(X_right, X_left, sizeof(qmf_t)*30*64);
@@ -958,8 +933,8 @@ uint8_t drm_ps_decode(drm_ps_info *ps, uint8_t guess, uint32_t samplerate, qmf_t
ps->drm_ps_data_available = 0;
- drm_calc_sa_side_signal(ps, X_left, rateselect);
- drm_add_ambiance(ps, rateselect, X_left, X_right);
+ drm_calc_sa_side_signal(ps, X_left);
+ drm_add_ambiance(ps, X_left, X_right);
if (ps->bs_enable_sa)
{
@@ -973,7 +948,7 @@ uint8_t drm_ps_decode(drm_ps_info *ps, uint8_t guess, uint32_t samplerate, qmf_t
if (ps->bs_enable_pan)
{
- drm_add_pan(ps, rateselect, X_left, X_right);
+ drm_add_pan(ps, X_left, X_right);
ps->g_last_had_pan = 1;
diff --git a/src/libfaad/drm_dec.h b/src/libfaad/drm_dec.h
index bb7d6dc93..d0ac995e4 100644
--- a/src/libfaad/drm_dec.h
+++ b/src/libfaad/drm_dec.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: drm_dec.h,v 1.1 2005/10/30 00:50:19 tmmm Exp $
+** $Id: drm_dec.h,v 1.8 2007/11/01 12:33:30 menno Exp $
**/
#ifndef __DRM_DEC_H__
@@ -88,7 +91,7 @@ uint16_t drm_ps_data(drm_ps_info *ps, bitfile *ld);
drm_ps_info *drm_ps_init(void);
void drm_ps_free(drm_ps_info *ps);
-uint8_t drm_ps_decode(drm_ps_info *ps, uint8_t guess, uint32_t samplerate, qmf_t X_left[38][64], qmf_t X_right[38][64]);
+uint8_t drm_ps_decode(drm_ps_info *ps, uint8_t guess, qmf_t X_left[38][64], qmf_t X_right[38][64]);
#ifdef __cplusplus
}
diff --git a/src/libfaad/error.c b/src/libfaad/error.c
index 2fbe08fc1..c552e06cd 100644
--- a/src/libfaad/error.c
+++ b/src/libfaad/error.c
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: error.c,v 1.8 2005/10/29 23:57:06 tmmm Exp $
+** $Id: error.c,v 1.32 2007/11/01 12:33:30 menno Exp $
**/
#include "common.h"
@@ -56,6 +59,11 @@ char *err_msg[] = {
"Unexpected fill element with SBR data",
"Not all elements were provided with SBR data",
"LTP decoding not available",
- "Output data buffer too small"
+ "Output data buffer too small",
+ "CRC error in DRM data",
+ "PNS not allowed in DRM data stream",
+ "No standard extension payload allowed in DRM",
+ "PCE shall be the first element in a frame",
+ "Bitstream value not allowed by specification"
};
diff --git a/src/libfaad/error.h b/src/libfaad/error.h
index 1009a9f57..7f750217c 100644
--- a/src/libfaad/error.h
+++ b/src/libfaad/error.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: error.h,v 1.7 2005/10/29 23:57:06 tmmm Exp $
+** $Id: error.h,v 1.26 2007/11/01 12:33:30 menno Exp $
**/
#ifndef __ERROR_H__
@@ -32,7 +35,7 @@
extern "C" {
#endif
-#define NUM_ERROR_MESSAGES 28
+#define NUM_ERROR_MESSAGES 33
extern char *err_msg[];
#ifdef __cplusplus
diff --git a/src/libfaad/faad.h b/src/libfaad/faad.h
deleted file mode 100644
index e46c31d87..000000000
--- a/src/libfaad/faad.h
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
-** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-**
-** Any non-GPL usage of this software or parts of this software is strictly
-** forbidden.
-**
-** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
-**
-** $Id: faad.h,v 1.7 2004/12/03 01:15:30 tmattern Exp $
-**/
-
-#ifndef __AACDEC_H__
-#define __AACDEC_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#ifdef _WIN32
- #pragma pack(push, 8)
- #ifndef FAADAPI
- #define FAADAPI __cdecl
- #endif
-#else
- #ifndef FAADAPI
- #define FAADAPI
- #endif
-#endif
-
-#define FAAD2_VERSION "2.0 "
-
-/* object types for AAC */
-#define MAIN 1
-#define LC 2
-#define SSR 3
-#define LTP 4
-#define HE_AAC 5
-#define ER_LC 17
-#define ER_LTP 19
-#define LD 23
-#define DRM_ER_LC 27 /* special object type for DRM */
-
-/* header types */
-#define RAW 0
-#define ADIF 1
-#define ADTS 2
-
-/* SBR signalling */
-#define NO_SBR 0
-#define SBR_UPSAMPLED 1
-#define SBR_DOWNSAMPLED 2
-#define NO_SBR_UPSAMPLED 3
-
-/* library output formats */
-#define FAAD_FMT_16BIT 1
-#define FAAD_FMT_24BIT 2
-#define FAAD_FMT_32BIT 3
-#define FAAD_FMT_FLOAT 4
-#define FAAD_FMT_DOUBLE 5
-
-/* Capabilities */
-#define LC_DEC_CAP (1<<0) /* Can decode LC */
-#define MAIN_DEC_CAP (1<<1) /* Can decode MAIN */
-#define LTP_DEC_CAP (1<<2) /* Can decode LTP */
-#define LD_DEC_CAP (1<<3) /* Can decode LD */
-#define ERROR_RESILIENCE_CAP (1<<4) /* Can decode ER */
-#define FIXED_POINT_CAP (1<<5) /* Fixed point */
-
-/* Channel definitions */
-#define FRONT_CHANNEL_CENTER (1)
-#define FRONT_CHANNEL_LEFT (2)
-#define FRONT_CHANNEL_RIGHT (3)
-#define SIDE_CHANNEL_LEFT (4)
-#define SIDE_CHANNEL_RIGHT (5)
-#define BACK_CHANNEL_LEFT (6)
-#define BACK_CHANNEL_RIGHT (7)
-#define BACK_CHANNEL_CENTER (8)
-#define LFE_CHANNEL (9)
-#define UNKNOWN_CHANNEL (0)
-
-/* DRM channel definitions */
-#define DRMCH_MONO 1
-#define DRMCH_STEREO 2
-#define DRMCH_SBR_MONO 3
-#define DRMCH_SBR_LC_STEREO 4
-#define DRMCH_SBR_STEREO 5
-
-
-/* A decode call can eat up to FAAD_MIN_STREAMSIZE bytes per decoded channel,
- so at least so much bytes per channel should be available in this stream */
-#define FAAD_MIN_STREAMSIZE 768 /* 6144 bits/channel */
-
-
-typedef void *faacDecHandle;
-
-typedef struct mp4AudioSpecificConfig
-{
- /* Audio Specific Info */
- unsigned char objectTypeIndex;
- unsigned char samplingFrequencyIndex;
- unsigned long samplingFrequency;
- unsigned char channelsConfiguration;
-
- /* GA Specific Info */
- unsigned char frameLengthFlag;
- unsigned char dependsOnCoreCoder;
- unsigned short coreCoderDelay;
- unsigned char extensionFlag;
- unsigned char aacSectionDataResilienceFlag;
- unsigned char aacScalefactorDataResilienceFlag;
- unsigned char aacSpectralDataResilienceFlag;
- unsigned char epConfig;
-
- char sbr_present_flag;
- char forceUpSampling;
-} mp4AudioSpecificConfig;
-
-typedef struct faacDecConfiguration
-{
- unsigned char defObjectType;
- unsigned long defSampleRate;
- unsigned char outputFormat;
- unsigned char downMatrix;
- unsigned char useOldADTSFormat;
- unsigned char dontUpSampleImplicitSBR;
-} faacDecConfiguration, *faacDecConfigurationPtr;
-
-typedef struct faacDecFrameInfo
-{
- unsigned long bytesconsumed;
- unsigned long samples;
- unsigned char channels;
- unsigned char error;
- unsigned long samplerate;
-
- /* SBR: 0: off, 1: on; upsample, 2: on; downsampled, 3: off; upsampled */
- unsigned char sbr;
-
- /* MPEG-4 ObjectType */
- unsigned char object_type;
-
- /* AAC header type; MP4 will be signalled as RAW also */
- unsigned char header_type;
-
- /* multichannel configuration */
- unsigned char num_front_channels;
- unsigned char num_side_channels;
- unsigned char num_back_channels;
- unsigned char num_lfe_channels;
- unsigned char channel_position[64];
-} faacDecFrameInfo;
-
-char* FAADAPI faacDecGetErrorMessage(unsigned char errcode);
-
-unsigned long FAADAPI faacDecGetCapabilities(void);
-
-faacDecHandle FAADAPI faacDecOpen(void);
-
-faacDecConfigurationPtr FAADAPI faacDecGetCurrentConfiguration(faacDecHandle hDecoder);
-
-unsigned char FAADAPI faacDecSetConfiguration(faacDecHandle hDecoder,
- faacDecConfigurationPtr config);
-
-/* Init the library based on info from the AAC file (ADTS/ADIF) */
-long FAADAPI faacDecInit(faacDecHandle hDecoder,
- unsigned char *buffer,
- unsigned long buffer_size,
- unsigned long *samplerate,
- unsigned char *channels);
-
-/* Init the library using a DecoderSpecificInfo */
-char FAADAPI faacDecInit2(faacDecHandle hDecoder, unsigned char *pBuffer,
- unsigned long SizeOfDecoderSpecificInfo,
- unsigned long *samplerate, unsigned char *channels);
-
-/* Init the library for DRM */
-char FAADAPI faacDecInitDRM(faacDecHandle hDecoder, unsigned long samplerate,
- unsigned char channels);
-
-void FAADAPI faacDecPostSeekReset(faacDecHandle hDecoder, long frame);
-
-void FAADAPI faacDecClose(faacDecHandle hDecoder);
-
-void* FAADAPI faacDecDecode(faacDecHandle hDecoder,
- faacDecFrameInfo *hInfo,
- unsigned char *buffer,
- unsigned long buffer_size);
-
-char FAADAPI AudioSpecificConfig(unsigned char *pBuffer,
- unsigned long buffer_size,
- mp4AudioSpecificConfig *mp4ASC);
-
-#ifdef _WIN32
- #pragma pack(pop)
-#endif
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif
diff --git a/src/libfaad/filtbank.c b/src/libfaad/filtbank.c
index 2919b5be3..eaeddcce6 100644
--- a/src/libfaad/filtbank.c
+++ b/src/libfaad/filtbank.c
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: filtbank.c,v 1.10 2005/10/29 23:57:06 tmmm Exp $
+** $Id: filtbank.c,v 1.45 2007/11/01 12:33:30 menno Exp $
**/
#include "common.h"
diff --git a/src/libfaad/filtbank.h b/src/libfaad/filtbank.h
index 54c72c0ef..de0149c97 100644
--- a/src/libfaad/filtbank.h
+++ b/src/libfaad/filtbank.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: filtbank.h,v 1.7 2005/10/29 23:57:06 tmmm Exp $
+** $Id: filtbank.h,v 1.27 2007/11/01 12:33:30 menno Exp $
**/
#ifndef __FILTBANK_H__
diff --git a/src/libfaad/fixed.h b/src/libfaad/fixed.h
index c58ee26cb..531583772 100644
--- a/src/libfaad/fixed.h
+++ b/src/libfaad/fixed.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: fixed.h,v 1.7 2005/10/29 23:57:06 tmmm Exp $
+** $Id: fixed.h,v 1.32 2007/11/01 12:33:30 menno Exp $
**/
#ifndef __FIXED_H__
@@ -36,6 +39,7 @@ extern "C" {
#include <cmnintrin.h>
#endif
+
#define COEF_BITS 28
#define COEF_PRECISION (1 << COEF_BITS)
#define REAL_BITS 14 // MAXIMUM OF 14 FOR FIXED POINT SBR
@@ -240,9 +244,27 @@ static INLINE void ComplexMult(real_t *y1, real_t *y2,
return _MulHigh(A,B) << (32-FRAC_BITS);
}
#else
+#ifdef __BFIN__
+#define _MulHigh(X,Y) ({ int __xxo; \
+ asm ( \
+ "a1 = %2.H * %1.L (IS,M);\n\t" \
+ "a0 = %1.H * %2.H, a1+= %1.H * %2.L (IS,M);\n\t"\
+ "a1 = a1 >>> 16;\n\t" \
+ "%0 = (a0 += a1);\n\t" \
+ : "=d" (__xxo) : "d" (X), "d" (Y) : "A0","A1"); __xxo; })
+
+#define MUL_F(X,Y) ({ int __xxo; \
+ asm ( \
+ "a1 = %2.H * %1.L (M);\n\t" \
+ "a0 = %1.H * %2.H, a1+= %1.H * %2.L (M);\n\t" \
+ "a1 = a1 >>> 16;\n\t" \
+ "%0 = (a0 += a1);\n\t" \
+ : "=d" (__xxo) : "d" (X), "d" (Y) : "A0","A1"); __xxo; })
+#else
#define _MulHigh(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (FRAC_SIZE-1))) >> FRAC_SIZE)
#define MUL_F(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (FRAC_BITS-1))) >> FRAC_BITS)
#endif
+#endif
#define MUL_Q2(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (Q2_BITS-1))) >> Q2_BITS)
#define MUL_SHIFT6(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (6-1))) >> 6)
#define MUL_SHIFT23(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (23-1))) >> 23)
diff --git a/src/libfaad/hcr.c b/src/libfaad/hcr.c
index 94f08fd2a..c76629641 100644
--- a/src/libfaad/hcr.c
+++ b/src/libfaad/hcr.c
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2004 G.C. Pascutto, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: hcr.c,v 1.7 2005/10/29 23:57:06 tmmm Exp $
+** $Id: hcr.c,v 1.24 2007/11/01 12:33:30 menno Exp $
**/
#include "common.h"
@@ -222,6 +225,7 @@ uint8_t reordered_spectral_data(NeAACDecHandle hDecoder, ic_stream *ics,
uint16_t sp_offset[8];
uint16_t g, i, sortloop, set, bitsread;
+ uint16_t bitsleft, codewordsleft;
uint8_t w_idx, sfb, this_CB, last_CB, this_sec_CB;
const uint16_t nshort = hDecoder->frameLength/8;
@@ -236,7 +240,7 @@ uint8_t reordered_spectral_data(NeAACDecHandle hDecoder, ic_stream *ics,
/* since there is spectral data, at least one codeword has nonzero length */
if (ics->length_of_longest_codeword == 0)
return 10;
-
+
if (sp_data_len < ics->length_of_longest_codeword)
return 10;
@@ -272,7 +276,7 @@ uint8_t reordered_spectral_data(NeAACDecHandle hDecoder, ic_stream *ics,
for (sfb = 0; sfb < ics->max_sfb; sfb++)
{
/* loop over all in this sfb, 4 lines per loop */
- for (w_idx = 0; 4*w_idx < (ics->swb_offset[sfb+1] - ics->swb_offset[sfb]); w_idx++)
+ for (w_idx = 0; 4*w_idx < (min(ics->swb_offset[sfb+1], ics->swb_offset_max) - ics->swb_offset[sfb]); w_idx++)
{
for(g = 0; g < ics->num_window_groups; g++)
{
@@ -404,6 +408,25 @@ uint8_t reordered_spectral_data(NeAACDecHandle hDecoder, ic_stream *ics,
rewrev_bits(&segment[i]);
}
+#if 0 // Seems to give false errors
+ bitsleft = 0;
+
+ for (i = 0; i < numberOfSegments && !bitsleft; i++)
+ bitsleft += segment[i].len;
+
+ if (bitsleft) return 10;
+
+ codewordsleft = 0;
+
+ for (i = 0; (i < numberOfCodewords - numberOfSegments) && (!codewordsleft); i++)
+ if (!codeword[i].decoded)
+ codewordsleft++;
+
+ if (codewordsleft) return 10;
+#endif
+
+
return 0;
+
}
#endif
diff --git a/src/libfaad/huffman.c b/src/libfaad/huffman.c
index 6c24a6cec..e2656c089 100644
--- a/src/libfaad/huffman.c
+++ b/src/libfaad/huffman.c
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: huffman.c,v 1.5 2005/10/29 23:57:06 tmmm Exp $
+** $Id: huffman.c,v 1.26 2007/11/01 12:33:30 menno Exp $
**/
#include "common.h"
diff --git a/src/libfaad/huffman.h b/src/libfaad/huffman.h
index cffe23093..f8bcb237e 100644
--- a/src/libfaad/huffman.h
+++ b/src/libfaad/huffman.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: huffman.h,v 1.7 2005/10/29 23:57:06 tmmm Exp $
+** $Id: huffman.h,v 1.28 2007/11/01 12:33:30 menno Exp $
**/
#ifndef __HUFFMAN_H__
diff --git a/src/libfaad/ic_predict.c b/src/libfaad/ic_predict.c
index 82753a9f2..70027ba2f 100644
--- a/src/libfaad/ic_predict.c
+++ b/src/libfaad/ic_predict.c
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: ic_predict.c,v 1.7 2005/10/29 23:57:06 tmmm Exp $
+** $Id: ic_predict.c,v 1.28 2007/11/01 12:33:31 menno Exp $
**/
#include "common.h"
@@ -81,7 +84,8 @@ static void ic_predict(pred_state *state, real_t input, real_t *output, uint8_t
{
uint16_t tmp;
int16_t i, j;
- real_t dr1, predictedvalue;
+ real_t dr1;
+ float32_t predictedvalue;
real_t e0, e1;
real_t k1, k2;
@@ -114,7 +118,7 @@ static void ic_predict(pred_state *state, real_t input, real_t *output, uint8_t
#define B 0.953125
real_t c = COR[0];
real_t v = VAR[0];
- real_t tmp;
+ float32_t tmp;
if (c == 0 || v <= 1)
{
k1 = 0;
@@ -144,7 +148,7 @@ static void ic_predict(pred_state *state, real_t input, real_t *output, uint8_t
#define B 0.953125
real_t c = COR[1];
real_t v = VAR[1];
- real_t tmp;
+ float32_t tmp;
if (c == 0 || v <= 1)
{
k2 = 0;
@@ -209,7 +213,7 @@ void pns_reset_pred_state(ic_stream *ics, pred_state *state)
if (is_noise(ics, g, sfb))
{
offs = ics->swb_offset[sfb];
- offs2 = ics->swb_offset[sfb+1];
+ offs2 = min(ics->swb_offset[sfb+1], ics->swb_offset_max);
for (i = offs; i < offs2; i++)
reset_pred_state(&state[i]);
@@ -241,7 +245,7 @@ void ic_prediction(ic_stream *ics, real_t *spec, pred_state *state,
for (sfb = 0; sfb < max_pred_sfb(sf_index); sfb++)
{
uint16_t low = ics->swb_offset[sfb];
- uint16_t high = ics->swb_offset[sfb+1];
+ uint16_t high = min(ics->swb_offset[sfb+1], ics->swb_offset_max);
for (bin = low; bin < high; bin++)
{
diff --git a/src/libfaad/ic_predict.h b/src/libfaad/ic_predict.h
index 233992b96..e69cd114e 100644
--- a/src/libfaad/ic_predict.h
+++ b/src/libfaad/ic_predict.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: ic_predict.h,v 1.7 2005/10/29 23:57:06 tmmm Exp $
+** $Id: ic_predict.h,v 1.23 2007/11/01 12:33:31 menno Exp $
**/
#ifdef MAIN_DEC
diff --git a/src/libfaad/iq_table.h b/src/libfaad/iq_table.h
index 9002e15d7..3cc2b8061 100644
--- a/src/libfaad/iq_table.h
+++ b/src/libfaad/iq_table.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: iq_table.h,v 1.6 2005/10/29 23:57:06 tmmm Exp $
+** $Id: iq_table.h,v 1.20 2007/11/01 12:33:31 menno Exp $
**/
#ifndef IQ_TABLE_H__
diff --git a/src/libfaad/is.c b/src/libfaad/is.c
index 9fcdbcbb5..5236db077 100644
--- a/src/libfaad/is.c
+++ b/src/libfaad/is.c
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: is.c,v 1.7 2005/10/29 23:57:06 tmmm Exp $
+** $Id: is.c,v 1.28 2007/11/01 12:33:31 menno Exp $
**/
#include "common.h"
@@ -84,7 +87,7 @@ void is_decode(ic_stream *ics, ic_stream *icsr, real_t *l_spec, real_t *r_spec,
/* Scale from left to right channel,
do not touch left channel */
- for (i = icsr->swb_offset[sfb]; i < icsr->swb_offset[sfb+1]; i++)
+ for (i = icsr->swb_offset[sfb]; i < min(icsr->swb_offset[sfb+1], ics->swb_offset_max); i++)
{
#ifndef FIXED_POINT
r_spec[(group*nshort)+i] = MUL_R(l_spec[(group*nshort)+i], scale);
diff --git a/src/libfaad/is.h b/src/libfaad/is.h
index 0786f7258..3e3b750ab 100644
--- a/src/libfaad/is.h
+++ b/src/libfaad/is.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: is.h,v 1.7 2005/10/29 23:57:06 tmmm Exp $
+** $Id: is.h,v 1.20 2007/11/01 12:33:31 menno Exp $
**/
#ifndef __IS_H__
diff --git a/src/libfaad/kbd_win.h b/src/libfaad/kbd_win.h
index 046b6b995..de404c7ea 100644
--- a/src/libfaad/kbd_win.h
+++ b/src/libfaad/kbd_win.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: kbd_win.h,v 1.7 2005/10/29 23:57:06 tmmm Exp $
+** $Id: kbd_win.h,v 1.21 2007/11/01 12:33:31 menno Exp $
**/
#ifndef __KBD_WIN_H__
diff --git a/src/libfaad/lt_predict.c b/src/libfaad/lt_predict.c
index 3aab00426..2be18ae9f 100644
--- a/src/libfaad/lt_predict.c
+++ b/src/libfaad/lt_predict.c
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: lt_predict.c,v 1.7 2005/10/29 23:57:07 tmmm Exp $
+** $Id: lt_predict.c,v 1.27 2007/11/01 12:33:31 menno Exp $
**/
@@ -53,9 +56,6 @@ uint8_t is_ltp_ot(uint8_t object_type)
#ifdef LD_DEC
|| (object_type == LD)
#endif
-#ifdef SCALABLE_DEC
- || (object_type == 6) /* TODO */
-#endif
)
{
return 1;
@@ -120,7 +120,7 @@ void lt_prediction(ic_stream *ics, ltp_info *ltp, real_t *spec,
if (ltp->long_used[sfb])
{
uint16_t low = ics->swb_offset[sfb];
- uint16_t high = ics->swb_offset[sfb+1];
+ uint16_t high = min(ics->swb_offset[sfb+1], ics->swb_offset_max);
for (bin = low; bin < high; bin++)
{
diff --git a/src/libfaad/lt_predict.h b/src/libfaad/lt_predict.h
index faa2fbca7..117f83424 100644
--- a/src/libfaad/lt_predict.h
+++ b/src/libfaad/lt_predict.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: lt_predict.h,v 1.7 2005/10/29 23:57:07 tmmm Exp $
+** $Id: lt_predict.h,v 1.20 2007/11/01 12:33:31 menno Exp $
**/
#ifdef LTP_DEC
diff --git a/src/libfaad/mdct.c b/src/libfaad/mdct.c
index 0df3d6aae..247691e40 100644
--- a/src/libfaad/mdct.c
+++ b/src/libfaad/mdct.c
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: mdct.c,v 1.11 2005/10/29 23:57:07 tmmm Exp $
+** $Id: mdct.c,v 1.47 2007/11/01 12:33:31 menno Exp $
**/
/*
@@ -33,7 +36,7 @@
* As described in:
* P. Duhamel, Y. Mahieux, and J.P. Petit, "A Fast Algorithm for the
* Implementation of Filter Banks Based on 'Time Domain Aliasing
- * Cancellation'," IEEE Proc. on ICASSP'91, 1991, pp. 2209-2212.
+ * Cancellation’," IEEE Proc. on ICASSP‘91, 1991, pp. 2209-2212.
*
*
* As of April 6th 2002 completely rewritten.
diff --git a/src/libfaad/mdct.h b/src/libfaad/mdct.h
index c2b738795..736180ead 100644
--- a/src/libfaad/mdct.h
+++ b/src/libfaad/mdct.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: mdct.h,v 1.8 2005/10/29 23:57:07 tmmm Exp $
+** $Id: mdct.h,v 1.30 2007/11/01 12:33:31 menno Exp $
**/
#ifndef __MDCT_H__
diff --git a/src/libfaad/mdct_tab.h b/src/libfaad/mdct_tab.h
index 7dd17166b..eea285b67 100644
--- a/src/libfaad/mdct_tab.h
+++ b/src/libfaad/mdct_tab.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: mdct_tab.h,v 1.1 2005/10/30 00:50:19 tmmm Exp $
+** $Id: mdct_tab.h,v 1.7 2007/11/01 12:33:32 menno Exp $
**/
#ifndef __MDCT_TAB_H__
diff --git a/src/libfaad/mp4.c b/src/libfaad/mp4.c
index 651280805..ef3f8a9c9 100644
--- a/src/libfaad/mp4.c
+++ b/src/libfaad/mp4.c
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: mp4.c,v 1.9 2005/10/29 23:57:07 tmmm Exp $
+** $Id: mp4.c,v 1.38 2007/11/01 12:33:32 menno Exp $
**/
#include "common.h"
@@ -58,11 +61,7 @@ static uint8_t ObjectTypesTable[32] = {
#else
0, /* 5 SBR */
#endif
-#ifdef SCALABLE_DEC
- 1, /* 6 AAC Scalable */
-#else
0, /* 6 AAC Scalable */
-#endif
0, /* 7 TwinVQ */
0, /* 8 CELP */
0, /* 9 HVXC */
@@ -83,11 +82,7 @@ static uint8_t ObjectTypesTable[32] = {
#else
0, /* 19 ER AAC LTP */
#endif
-#ifdef SCALABLE_DEC
- 1, /* 20 ER AAC scalable */
-#else
0, /* 20 ER AAC scalable */
-#endif
0, /* 21 ER TwinVQ */
0, /* 22 ER BSAC */
#ifdef LD_DEC
@@ -248,10 +243,10 @@ int8_t AudioSpecificConfig2(uint8_t *pBuffer,
if (syncExtensionType == 0x2b7)
{
- mp4ASC->objectTypeIndex = (uint8_t)faad_getbits(&ld, 5
+ uint8_t tmp_OTi = (uint8_t)faad_getbits(&ld, 5
DEBUGVAR(1,10,"parse_audio_decoder_specific_info(): extensionAudioObjectType"));
- if (mp4ASC->objectTypeIndex == 5)
+ if (tmp_OTi == 5)
{
mp4ASC->sbr_present_flag = (uint8_t)faad_get1bit(&ld
DEBUGVAR(1,11,"parse_audio_decoder_specific_info(): sbr_present_flag"));
@@ -259,6 +254,10 @@ int8_t AudioSpecificConfig2(uint8_t *pBuffer,
if (mp4ASC->sbr_present_flag)
{
uint8_t tmp;
+
+ /* Don't set OT to SBR until checked that it is actually there */
+ mp4ASC->objectTypeIndex = tmp_OTi;
+
tmp = (uint8_t)faad_getbits(&ld, 4
DEBUGVAR(1,12,"parse_audio_decoder_specific_info(): extensionSamplingFrequencyIndex"));
diff --git a/src/libfaad/mp4.h b/src/libfaad/mp4.h
index 478c9b9be..532ba3524 100644
--- a/src/libfaad/mp4.h
+++ b/src/libfaad/mp4.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: mp4.h,v 1.8 2005/10/29 23:57:07 tmmm Exp $
+** $Id: mp4.h,v 1.25 2007/11/01 12:33:32 menno Exp $
**/
#ifndef __MP4_H__
diff --git a/src/libfaad/ms.c b/src/libfaad/ms.c
index 93b0a2051..97c8fb198 100644
--- a/src/libfaad/ms.c
+++ b/src/libfaad/ms.c
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: ms.c,v 1.7 2005/10/29 23:57:07 tmmm Exp $
+** $Id: ms.c,v 1.21 2007/11/01 12:33:32 menno Exp $
**/
#include "common.h"
@@ -58,7 +61,7 @@ void ms_decode(ic_stream *ics, ic_stream *icsr, real_t *l_spec, real_t *r_spec,
if ((ics->ms_used[g][sfb] || ics->ms_mask_present == 2) &&
!is_intensity(icsr, g, sfb) && !is_noise(ics, g, sfb))
{
- for (i = ics->swb_offset[sfb]; i < ics->swb_offset[sfb+1]; i++)
+ for (i = ics->swb_offset[sfb]; i < min(ics->swb_offset[sfb+1], ics->swb_offset_max); i++)
{
k = (group*nshort) + i;
tmp = l_spec[k] - r_spec[k];
diff --git a/src/libfaad/ms.h b/src/libfaad/ms.h
index 4bc7c8175..30cfadaf6 100644
--- a/src/libfaad/ms.h
+++ b/src/libfaad/ms.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: ms.h,v 1.7 2005/10/29 23:57:07 tmmm Exp $
+** $Id: ms.h,v 1.19 2007/11/01 12:33:32 menno Exp $
**/
#ifndef __MS_H__
diff --git a/src/libfaad/output.c b/src/libfaad/output.c
index 33ebed39c..a96ebd983 100644
--- a/src/libfaad/output.c
+++ b/src/libfaad/output.c
@@ -1,28 +1,31 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
-**
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
+**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
-**
+**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
-**
+**
** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
+** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: output.c,v 1.9 2006/06/30 21:36:27 dgp85 Exp $
+** $Id: output.c,v 1.46 2007/11/01 12:33:32 menno Exp $
**/
#include "common.h"
@@ -463,7 +466,7 @@ static INLINE real_t get_sample(real_t **input, uint8_t channel, uint16_t sample
}
}
-static void* output_to_PCM_orig(NeAACDecHandle hDecoder,
+void* output_to_PCM(NeAACDecHandle hDecoder,
real_t **input, void *sample_buffer, uint8_t channels,
uint16_t frame_len, uint8_t format)
{
@@ -554,56 +557,4 @@ static void* output_to_PCM_orig(NeAACDecHandle hDecoder,
return sample_buffer;
}
-void *output_to_PCM(NeAACDecHandle hDecoder,
- real_t **input, void *sample_buffer, uint8_t channels,
- uint16_t frame_len, uint8_t format)
-{
- int ch, i;
- int16_t *short_sample_buffer;
- real_t *ch0, *ch1, *ch2, *ch3, *ch4;
-
- if (format != FAAD_FMT_16BIT)
- return output_to_PCM_orig(hDecoder, input, sample_buffer, channels, frame_len, format);
-
- short_sample_buffer = (int16_t *)sample_buffer;
- ch0 = input[hDecoder->internal_channel[0]];
- ch1 = input[hDecoder->internal_channel[1]];
- ch2 = input[hDecoder->internal_channel[2]];
- ch3 = input[hDecoder->internal_channel[3]];
- ch4 = input[hDecoder->internal_channel[4]];
-
- if (hDecoder->downMatrix)
- {
- for (i = 0; i < frame_len; ++i)
- {
- int32_t tmp = (ch1[i] + ((ch0[i] + ch3[i]) >> 1) + ((ch0[i] + ch3[i]) >> 2) + (1 << (REAL_BITS))) >> (REAL_BITS + 1);
- if ((tmp + 0x8000) & ~0xffff)
- tmp = ~(tmp >> 31) - 0x8000;
- short_sample_buffer[0] = tmp;
- tmp = (ch2[i] + ((ch0[i] + ch4[i]) >> 1) + ((ch0[i] + ch4[i]) >> 2) + (1 << (REAL_BITS))) >> (REAL_BITS + 1);
- if ((tmp + 0x8000) & ~0xffff)
- tmp = ~(tmp >> 31) - 0x8000;
- short_sample_buffer[1] = tmp;
- short_sample_buffer += channels;
- }
- return sample_buffer;
- }
-
- /* Copy output to a standard PCM buffer */
- for (i = 0; i < frame_len; ++i)
- {
- for (ch = 0; ch < channels; ++ch)
- {
- int32_t tmp = input[hDecoder->internal_channel[ch]][i];
- tmp += (1 << (REAL_BITS - 1));
- tmp >>= REAL_BITS;
- if ((tmp + 0x8000) & ~0xffff)
- tmp = ~(tmp >> 31) - 0x8000;
- *(short_sample_buffer++) = tmp;
- }
- }
-
- return sample_buffer;
-}
-
#endif
diff --git a/src/libfaad/output.h b/src/libfaad/output.h
index 1b15dae58..0451d8b73 100644
--- a/src/libfaad/output.h
+++ b/src/libfaad/output.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: output.h,v 1.7 2005/10/29 23:57:07 tmmm Exp $
+** $Id: output.h,v 1.25 2007/11/01 12:33:32 menno Exp $
**/
#ifndef __OUTPUT_H__
diff --git a/src/libfaad/pns.c b/src/libfaad/pns.c
index 5266d8eef..248fd05ef 100644
--- a/src/libfaad/pns.c
+++ b/src/libfaad/pns.c
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: pns.c,v 1.8 2005/10/29 23:57:07 tmmm Exp $
+** $Id: pns.c,v 1.38 2007/11/01 12:33:32 menno Exp $
**/
#include "common.h"
@@ -33,7 +36,8 @@
/* static function declarations */
static void gen_rand_vector(real_t *spec, int16_t scale_factor, uint16_t size,
- uint8_t sub);
+ uint8_t sub,
+ /* RNG states */ uint32_t *__r1, uint32_t *__r2);
#ifdef FIXED_POINT
@@ -68,7 +72,7 @@ real_t fp_sqrt(real_t value)
return root;
}
-static real_t pow2_table[] =
+static real_t const pow2_table[] =
{
COEF_CONST(1.0),
COEF_CONST(1.18920711500272),
@@ -83,7 +87,8 @@ static real_t pow2_table[] =
multiplication/accumulation per random value.
*/
static INLINE void gen_rand_vector(real_t *spec, int16_t scale_factor, uint16_t size,
- uint8_t sub)
+ uint8_t sub,
+ /* RNG states */ uint32_t *__r1, uint32_t *__r2)
{
#ifndef FIXED_POINT
uint16_t i;
@@ -93,7 +98,7 @@ static INLINE void gen_rand_vector(real_t *spec, int16_t scale_factor, uint16_t
for (i = 0; i < size; i++)
{
- real_t tmp = scale*(real_t)(int32_t)random_int();
+ real_t tmp = scale*(real_t)(int32_t)ne_rng(__r1, __r2);
spec[i] = tmp;
energy += tmp*tmp;
}
@@ -112,7 +117,7 @@ static INLINE void gen_rand_vector(real_t *spec, int16_t scale_factor, uint16_t
for (i = 0; i < size; i++)
{
/* this can be replaced by a 16 bit random generator!!!! */
- real_t tmp = (int32_t)random_int();
+ real_t tmp = (int32_t)ne_rng(__r1, __r2);
if (tmp < 0)
tmp = -(tmp & ((1<<(REAL_BITS-1))-1));
else
@@ -152,7 +157,8 @@ static INLINE void gen_rand_vector(real_t *spec, int16_t scale_factor, uint16_t
void pns_decode(ic_stream *ics_left, ic_stream *ics_right,
real_t *spec_left, real_t *spec_right, uint16_t frame_len,
- uint8_t channel_pair, uint8_t object_type)
+ uint8_t channel_pair, uint8_t object_type,
+ /* RNG states */ uint32_t *__r1, uint32_t *__r2)
{
uint8_t g, sfb, b;
uint16_t size, offs;
@@ -202,11 +208,11 @@ void pns_decode(ic_stream *ics_left, ic_stream *ics_right,
#endif
offs = ics_left->swb_offset[sfb];
- size = ics_left->swb_offset[sfb+1] - offs;
+ size = min(ics_left->swb_offset[sfb+1], ics_left->swb_offset_max) - offs;
/* Generate random vector */
gen_rand_vector(&spec_left[(group*nshort)+offs],
- ics_left->scale_factors[g][sfb], size, sub);
+ ics_left->scale_factors[g][sfb], size, sub, __r1, __r2);
}
/* From the spec:
@@ -233,7 +239,7 @@ void pns_decode(ic_stream *ics_left, ic_stream *ics_right,
uint16_t c;
offs = ics_right->swb_offset[sfb];
- size = ics_right->swb_offset[sfb+1] - offs;
+ size = min(ics_right->swb_offset[sfb+1], ics_right->swb_offset_max) - offs;
for (c = 0; c < size; c++)
{
@@ -250,11 +256,11 @@ void pns_decode(ic_stream *ics_left, ic_stream *ics_right,
#endif
offs = ics_right->swb_offset[sfb];
- size = ics_right->swb_offset[sfb+1] - offs;
+ size = min(ics_right->swb_offset[sfb+1], ics_right->swb_offset_max) - offs;
/* Generate random vector */
gen_rand_vector(&spec_right[(group*nshort)+offs],
- ics_right->scale_factors[g][sfb], size, sub);
+ ics_right->scale_factors[g][sfb], size, sub, __r1, __r2);
}
}
}
diff --git a/src/libfaad/pns.h b/src/libfaad/pns.h
index 2f246cc4f..38ced252d 100644
--- a/src/libfaad/pns.h
+++ b/src/libfaad/pns.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: pns.h,v 1.7 2005/10/29 23:57:07 tmmm Exp $
+** $Id: pns.h,v 1.27 2007/11/01 12:33:33 menno Exp $
**/
#ifndef __PNS_H__
@@ -38,7 +41,8 @@ extern "C" {
void pns_decode(ic_stream *ics_left, ic_stream *ics_right,
real_t *spec_left, real_t *spec_right, uint16_t frame_len,
- uint8_t channel_pair, uint8_t object_type);
+ uint8_t channel_pair, uint8_t object_type,
+ /* RNG states */ uint32_t *__r1, uint32_t *__r2);
static INLINE uint8_t is_noise(ic_stream *ics, uint8_t group, uint8_t sfb)
{
diff --git a/src/libfaad/ps_dec.c b/src/libfaad/ps_dec.c
index 3b957bfda..aebfe0a48 100644
--- a/src/libfaad/ps_dec.c
+++ b/src/libfaad/ps_dec.c
@@ -1,28 +1,31 @@
/*
-** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR and PS decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
+** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
+**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
-**
+**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
-**
+**
** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
+** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: ps_dec.c,v 1.3 2006/09/26 17:55:59 dgp85 Exp $
+** $Id: ps_dec.c,v 1.14 2007/11/01 12:33:33 menno Exp $
**/
#include "common.h"
@@ -159,7 +162,7 @@ typedef struct
/* static function declarations */
static void ps_data_decode(ps_info *ps);
-static hyb_info *hybrid_init(void);
+static hyb_info *hybrid_init();
static void channel_filter2(hyb_info *hyb, uint8_t frame_len, const real_t *filter,
qmf_t *buffer, qmf_t **X_hybrid);
static void INLINE DCT3_4_unscaled(real_t *y, real_t *x);
@@ -175,7 +178,7 @@ static void delta_decode(uint8_t enable, int8_t *index, int8_t *index_prev,
int8_t min_index, int8_t max_index);
static void delta_modulo_decode(uint8_t enable, int8_t *index, int8_t *index_prev,
uint8_t dt_flag, uint8_t nr_par, uint8_t stride,
- int8_t log2modulo);
+ int8_t and_modulo);
static void map20indexto34(int8_t *index, uint8_t bins);
#ifdef PS_LOW_POWER
static void map34indexto20(int8_t *index, uint8_t bins);
@@ -189,7 +192,7 @@ static void ps_mix_phase(ps_info *ps, qmf_t X_left[38][64], qmf_t X_right[38][64
/* */
-static hyb_info *hybrid_init(void)
+static hyb_info *hybrid_init()
{
uint8_t i;
@@ -230,16 +233,24 @@ static void hybrid_free(hyb_info *hyb)
{
uint8_t i;
- faad_free(hyb->work);
+ if (hyb->work)
+ faad_free(hyb->work);
for (i = 0; i < 5; i++)
- faad_free(hyb->buffer[i]);
- faad_free(hyb->buffer);
+ {
+ if (hyb->buffer[i])
+ faad_free(hyb->buffer[i]);
+ }
+ if (hyb->buffer)
+ faad_free(hyb->buffer);
for (i = 0; i < hyb->frame_len; i++)
- faad_free(hyb->temp[i]);
-
- faad_free(hyb->temp);
+ {
+ if (hyb->temp[i])
+ faad_free(hyb->temp[i]);
+ }
+ if (hyb->temp)
+ faad_free(hyb->temp);
}
/* real filter, size 2 */
@@ -666,7 +677,7 @@ static void delta_decode(uint8_t enable, int8_t *index, int8_t *index_prev,
/* in: log2 value of the modulo value to allow using AND instead of MOD */
static void delta_modulo_decode(uint8_t enable, int8_t *index, int8_t *index_prev,
uint8_t dt_flag, uint8_t nr_par, uint8_t stride,
- int8_t log2modulo)
+ int8_t and_modulo)
{
int8_t i;
@@ -676,19 +687,19 @@ static void delta_modulo_decode(uint8_t enable, int8_t *index, int8_t *index_pre
{
/* delta coded in frequency direction */
index[0] = 0 + index[0];
- index[0] &= log2modulo;
+ index[0] &= and_modulo;
for (i = 1; i < nr_par; i++)
{
index[i] = index[i-1] + index[i];
- index[i] &= log2modulo;
+ index[i] &= and_modulo;
}
} else {
/* delta coded in time direction */
for (i = 0; i < nr_par; i++)
{
index[i] = index_prev[i*stride] + index[i];
- index[i] &= log2modulo;
+ index[i] &= and_modulo;
}
}
} else {
@@ -833,11 +844,11 @@ static void ps_data_decode(ps_info *ps)
/* delta modulo decode ipd parameters */
delta_modulo_decode(ps->enable_ipdopd, ps->ipd_index[env], ipd_index_prev,
- ps->ipd_dt[env], ps->nr_ipdopd_par, 1, /*log2(8)*/ 3);
+ ps->ipd_dt[env], ps->nr_ipdopd_par, 1, 7);
/* delta modulo decode opd parameters */
delta_modulo_decode(ps->enable_ipdopd, ps->opd_index[env], opd_index_prev,
- ps->opd_dt[env], ps->nr_ipdopd_par, 1, /*log2(8)*/ 3);
+ ps->opd_dt[env], ps->nr_ipdopd_par, 1, 7);
}
/* handle error case */
@@ -906,8 +917,6 @@ static void ps_data_decode(ps_info *ps)
if (ps->border_position[ps->num_env] < 32 /* 30 for 960? */)
{
- ps->num_env++;
- ps->border_position[ps->num_env] = 32 /* 30 for 960? */;
for (bin = 0; bin < 34; bin++)
{
ps->iid_index[ps->num_env][bin] = ps->iid_index[ps->num_env-1][bin];
@@ -918,6 +927,8 @@ static void ps_data_decode(ps_info *ps)
ps->ipd_index[ps->num_env][bin] = ps->ipd_index[ps->num_env-1][bin];
ps->opd_index[ps->num_env][bin] = ps->opd_index[ps->num_env-1][bin];
}
+ ps->num_env++;
+ ps->border_position[ps->num_env] = 32 /* 30 for 960? */;
}
for (env = 1; env < ps->num_env; env++)
@@ -1410,6 +1421,26 @@ static const real_t ipdopd_sin_tab[] = {
FRAC_CONST(-0.000000000000000)
};
+static real_t magnitude_c(complex_t c)
+{
+#ifdef FIXED_POINT
+#define ps_abs(A) (((A) > 0) ? (A) : (-(A)))
+#define ALPHA FRAC_CONST(0.948059448969)
+#define BETA FRAC_CONST(0.392699081699)
+
+ real_t abs_inphase = ps_abs(RE(c));
+ real_t abs_quadrature = ps_abs(IM(c));
+
+ if (abs_inphase > abs_quadrature) {
+ return MUL_F(abs_inphase, ALPHA) + MUL_F(abs_quadrature, BETA);
+ } else {
+ return MUL_F(abs_quadrature, ALPHA) + MUL_F(abs_inphase, BETA);
+ }
+#else
+ return sqrt(RE(c)*RE(c) + IM(c)*IM(c));
+#endif
+}
+
static void ps_mix_phase(ps_info *ps, qmf_t X_left[38][64], qmf_t X_right[38][64],
qmf_t X_hybrid_left[32][32], qmf_t X_hybrid_right[32][32])
{
@@ -1580,8 +1611,7 @@ static void ps_mix_phase(ps_info *ps, qmf_t X_left[38][64], qmf_t X_right[38][64
if ((ps->enable_ipdopd) && (bk < nr_ipdopd_par))
{
int8_t i;
- real_t xxyy, ppqq;
- real_t yq, xp, xq, py, tmp;
+ real_t xy, pq, xypq;
/* ringbuffer index */
i = ps->phase_hist;
@@ -1614,7 +1644,7 @@ static void ps_mix_phase(ps_info *ps, qmf_t X_left[38][64], qmf_t X_right[38][64
/* ringbuffer index */
if (i == 0)
- {
+ {
i = 2;
}
i--;
@@ -1644,53 +1674,54 @@ static void ps_mix_phase(ps_info *ps, qmf_t X_left[38][64], qmf_t X_right[38][64
RE(phaseRight) = (float)cos(opd);
IM(phaseRight) = (float)sin(opd);
#else
+
// x = IM(tempLeft)
// y = RE(tempLeft)
// p = IM(tempRight)
// q = RE(tempRight)
- // cos(atan2(x,y)) = 1/sqrt(1 + (x*x)/(y*y))
- // sin(atan2(x,y)) = x/(y*sqrt(1 + (x*x)/(y*y)))
- // cos(atan2(x,y)-atan2(p,q)) = (y*q+x*p)/(y*q * sqrt(1 + (x*x)/(y*y)) * sqrt(1 + (p*p)/(q*q)));
- // sin(atan2(x,y)-atan2(p,q)) = (x*q-p*y)/(y*q * sqrt(1 + (x*x)/(y*y)) * sqrt(1 + (p*p)/(q*q)));
+ // cos(atan2(x,y)) = y/sqrt((x*x) + (y*y))
+ // sin(atan2(x,y)) = x/sqrt((x*x) + (y*y))
+ // cos(atan2(x,y)-atan2(p,q)) = (y*q + x*p) / ( sqrt((x*x) + (y*y)) * sqrt((p*p) + (q*q)) );
+ // sin(atan2(x,y)-atan2(p,q)) = (x*q - y*p) / ( sqrt((x*x) + (y*y)) * sqrt((p*p) + (q*q)) );
- /* (x*x)/(y*y) (REAL > 0) */
- xxyy = DIV_R(MUL_C(IM(tempLeft),IM(tempLeft)), MUL_C(RE(tempLeft),RE(tempLeft)));
- ppqq = DIV_R(MUL_C(IM(tempRight),IM(tempRight)), MUL_C(RE(tempRight),RE(tempRight)));
+ xy = magnitude_c(tempRight);
+ pq = magnitude_c(tempLeft);
- /* 1 + (x*x)/(y*y) (REAL > 1) */
- xxyy += REAL_CONST(1);
- ppqq += REAL_CONST(1);
-
- /* 1 / sqrt(1 + (x*x)/(y*y)) (FRAC <= 1) */
- xxyy = DIV_R(FRAC_CONST(1), ps_sqrt(xxyy));
- ppqq = DIV_R(FRAC_CONST(1), ps_sqrt(ppqq));
+ if (xy != 0)
+ {
+ RE(phaseLeft) = DIV_R(RE(tempRight), xy);
+ IM(phaseLeft) = DIV_R(IM(tempRight), xy);
+ } else {
+ RE(phaseLeft) = 0;
+ IM(phaseLeft) = 0;
+ }
- /* COEF */
- yq = MUL_C(RE(tempLeft), RE(tempRight));
- xp = MUL_C(IM(tempLeft), IM(tempRight));
- xq = MUL_C(IM(tempLeft), RE(tempRight));
- py = MUL_C(RE(tempLeft), IM(tempRight));
+ xypq = MUL_R(xy, pq);
- RE(phaseLeft) = xxyy;
- IM(phaseLeft) = MUL_R(xxyy, (DIV_R(IM(tempLeft), RE(tempLeft))));
+ if (xypq != 0)
+ {
+ real_t tmp1 = MUL_R(RE(tempRight), RE(tempLeft)) + MUL_R(IM(tempRight), IM(tempLeft));
+ real_t tmp2 = MUL_R(IM(tempRight), RE(tempLeft)) - MUL_R(RE(tempRight), IM(tempLeft));
- tmp = DIV_C(MUL_F(xxyy, ppqq), yq);
+ RE(phaseRight) = DIV_R(tmp1, xypq);
+ IM(phaseRight) = DIV_R(tmp2, xypq);
+ } else {
+ RE(phaseRight) = 0;
+ IM(phaseRight) = 0;
+ }
- /* MUL_C(FRAC,COEF) = FRAC */
- RE(phaseRight) = MUL_C(tmp, (yq+xp));
- IM(phaseRight) = MUL_C(tmp, (xq-py));
#endif
- /* MUL_F(COEF, FRAC) = COEF */
- IM(h11) = MUL_F(RE(h11), IM(phaseLeft));
- IM(h12) = MUL_F(RE(h12), IM(phaseRight));
- IM(h21) = MUL_F(RE(h21), IM(phaseLeft));
- IM(h22) = MUL_F(RE(h22), IM(phaseRight));
+ /* MUL_F(COEF, REAL) = COEF */
+ IM(h11) = MUL_R(RE(h11), IM(phaseLeft));
+ IM(h12) = MUL_R(RE(h12), IM(phaseRight));
+ IM(h21) = MUL_R(RE(h21), IM(phaseLeft));
+ IM(h22) = MUL_R(RE(h22), IM(phaseRight));
- RE(h11) = MUL_F(RE(h11), RE(phaseLeft));
- RE(h12) = MUL_F(RE(h12), RE(phaseRight));
- RE(h21) = MUL_F(RE(h21), RE(phaseLeft));
- RE(h22) = MUL_F(RE(h22), RE(phaseRight));
+ RE(h11) = MUL_R(RE(h11), RE(phaseLeft));
+ RE(h12) = MUL_R(RE(h12), RE(phaseRight));
+ RE(h21) = MUL_R(RE(h21), RE(phaseLeft));
+ RE(h22) = MUL_R(RE(h22), RE(phaseRight));
}
/* length of the envelope n_e+1 - n_e (in time samples) */
@@ -1927,8 +1958,8 @@ ps_info *ps_init(uint8_t sr_index)
/* main Parametric Stereo decoding function */
uint8_t ps_decode(ps_info *ps, qmf_t X_left[38][64], qmf_t X_right[38][64])
{
- qmf_t X_hybrid_left[32][32] = {{{0}}};
- qmf_t X_hybrid_right[32][32] = {{{0}}};
+ qmf_t X_hybrid_left[32][32] = {{0}};
+ qmf_t X_hybrid_right[32][32] = {{0}};
/* delta decoding of the bitstream data */
ps_data_decode(ps);
diff --git a/src/libfaad/ps_dec.h b/src/libfaad/ps_dec.h
index 978161fff..d96561404 100644
--- a/src/libfaad/ps_dec.h
+++ b/src/libfaad/ps_dec.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: ps_dec.h,v 1.1 2005/10/30 00:50:19 tmmm Exp $
+** $Id: ps_dec.h,v 1.12 2007/11/01 12:33:33 menno Exp $
**/
#ifndef __PS_DEC_H__
diff --git a/src/libfaad/ps_syntax.c b/src/libfaad/ps_syntax.c
index fc2f9e7f2..50253d459 100644
--- a/src/libfaad/ps_syntax.c
+++ b/src/libfaad/ps_syntax.c
@@ -1,6 +1,6 @@
/*
-** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR and PS decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: ps_syntax.c,v 1.1 2005/10/30 00:50:19 tmmm Exp $
+** $Id: ps_syntax.c,v 1.11 2007/11/01 12:33:33 menno Exp $
**/
#include "common.h"
@@ -308,9 +311,9 @@ static const int8_t t_huff_opd[][2] = {
{ 2, 3 }, /* index 1: 2 bits: 0x */
{ 4, 5 }, /* index 2: 3 bits: 00x */
{ /*1*/ -30, /*7*/ -24 }, /* index 3: 3 bits: 01x */
- { /*5*/ -26, 6 }, /* index 4: 4 bits: 000x */
- { /*2*/ -29, /*6*/ -25 }, /* index 5: 4 bits: 001x */
- { /*4*/ -27, /*3*/ -28 } /* index 6: 5 bits: 0001x */
+ { /*5*/ -26, /*2*/ -29 }, /* index 4: 4 bits: 000x */
+ { /*6*/ -25, 6 }, /* index 5: 4 bits: 001x */
+ { /*4*/ -27, /*3*/ -28 } /* index 6: 5 bits: 0011x */
};
/* static function declarations */
@@ -380,7 +383,10 @@ uint16_t ps_data(ps_info *ps, bitfile *ld, uint8_t *header)
/* we are here, but no header has been read yet */
if (ps->header_read == 0)
+ {
+ ps->ps_data_available = 0;
return 1;
+ }
ps->frame_class = (uint8_t)faad_get1bit(ld
DEBUGVAR(1,1006,"ps_data(): frame_class"));
@@ -394,7 +400,7 @@ uint16_t ps_data(ps_info *ps, bitfile *ld, uint8_t *header)
for (n = 1; n < ps->num_env+1; n++)
{
ps->border_position[n] = (uint8_t)faad_getbits(ld, 5
- DEBUGVAR(1,1008,"ps_data(): border_position"));
+ DEBUGVAR(1,1008,"ps_data(): border_position")) + 1;
}
}
diff --git a/src/libfaad/ps_tables.h b/src/libfaad/ps_tables.h
index c71489617..f3370be9d 100644
--- a/src/libfaad/ps_tables.h
+++ b/src/libfaad/ps_tables.h
@@ -1,28 +1,31 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
+**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
-**
+**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
-**
+**
** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
+** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: ps_tables.h,v 1.1 2005/10/30 00:50:19 tmmm Exp $
+** $Id: ps_tables.h,v 1.8 2007/11/01 12:33:33 menno Exp $
**/
#ifndef __PS_TABLES_H__
@@ -541,7 +544,7 @@ static const real_t sf_iid_fine[] = {
};
#ifdef __cplusplus
-
+}
#endif
#endif
diff --git a/src/libfaad/pulse.c b/src/libfaad/pulse.c
index 9e0a705e6..3dd973abf 100644
--- a/src/libfaad/pulse.c
+++ b/src/libfaad/pulse.c
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,12 +19,14 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: pulse.c,v 1.8 2005/10/29 23:57:07 tmmm Exp $
+** $Id: pulse.c,v 1.21 2007/11/01 12:33:34 menno Exp $
**/
-
#include "common.h"
#include "structs.h"
@@ -37,7 +39,7 @@ uint8_t pulse_decode(ic_stream *ics, int16_t *spec_data, uint16_t framelen)
uint16_t k;
pulse_info *pul = &(ics->pul);
- k = ics->swb_offset[pul->pulse_start_sfb];
+ k = min(ics->swb_offset[pul->pulse_start_sfb], ics->swb_offset_max);
for (i = 0; i <= pul->number_pulse; i++)
{
diff --git a/src/libfaad/pulse.h b/src/libfaad/pulse.h
index a057c0d3b..f7676cd89 100644
--- a/src/libfaad/pulse.h
+++ b/src/libfaad/pulse.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: pulse.h,v 1.8 2005/10/29 23:57:07 tmmm Exp $
+** $Id: pulse.h,v 1.20 2007/11/01 12:33:34 menno Exp $
**/
#ifndef __PULSE_H__
diff --git a/src/libfaad/rvlc.c b/src/libfaad/rvlc.c
index bad49a0c6..73619c6d1 100644
--- a/src/libfaad/rvlc.c
+++ b/src/libfaad/rvlc.c
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: rvlc.c,v 1.7 2005/10/29 23:57:07 tmmm Exp $
+** $Id: rvlc.c,v 1.21 2007/11/01 12:33:34 menno Exp $
**/
/* RVLC scalefactor decoding
diff --git a/src/libfaad/rvlc.h b/src/libfaad/rvlc.h
index 867468580..56f630fa4 100644
--- a/src/libfaad/rvlc.h
+++ b/src/libfaad/rvlc.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: rvlc.h,v 1.6 2005/10/29 23:57:07 tmmm Exp $
+** $Id: rvlc.h,v 1.17 2007/11/01 12:33:34 menno Exp $
**/
#ifndef __RVLC_SCF_H__
diff --git a/src/libfaad/sbr_dct.c b/src/libfaad/sbr_dct.c
index ba8bbaf9b..16e7128ea 100644
--- a/src/libfaad/sbr_dct.c
+++ b/src/libfaad/sbr_dct.c
@@ -1,30 +1,38 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
+**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
-**
+**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
-**
+**
** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
+** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: sbr_dct.c,v 1.5 2005/10/29 23:57:07 tmmm Exp $
+** $Id: sbr_dct.c,v 1.20 2007/11/01 12:33:34 menno Exp $
**/
+
+/* Most of the DCT/DST codes here are generated using Spiral which is GPL
+ * For more info see: http://www.spiral.net/
+ */
+
#include "common.h"
#ifdef SBR_DEC
@@ -479,6 +487,413 @@ void DCT4_32(real_t *y, real_t *x)
y[1] = f397 - f396;
}
+void DST4_32(real_t *y, real_t *x)
+{
+ real_t f0, f1, f2, f3, f4, f5, f6, f7, f8, f9;
+ real_t f10, f11, f12, f13, f14, f15, f16, f17, f18, f19;
+ real_t f20, f21, f22, f23, f24, f25, f26, f27, f28, f29;
+ real_t f30, f31, f32, f33, f34, f35, f36, f37, f38, f39;
+ real_t f40, f41, f42, f43, f44, f45, f46, f47, f48, f49;
+ real_t f50, f51, f52, f53, f54, f55, f56, f57, f58, f59;
+ real_t f60, f61, f62, f63, f64, f65, f66, f67, f68, f69;
+ real_t f70, f71, f72, f73, f74, f75, f76, f77, f78, f79;
+ real_t f80, f81, f82, f83, f84, f85, f86, f87, f88, f89;
+ real_t f90, f91, f92, f93, f94, f95, f96, f97, f98, f99;
+ real_t f100, f101, f102, f103, f104, f105, f106, f107, f108, f109;
+ real_t f110, f111, f112, f113, f114, f115, f116, f117, f118, f119;
+ real_t f120, f121, f122, f123, f124, f125, f126, f127, f128, f129;
+ real_t f130, f131, f132, f133, f134, f135, f136, f137, f138, f139;
+ real_t f140, f141, f142, f143, f144, f145, f146, f147, f148, f149;
+ real_t f150, f151, f152, f153, f154, f155, f156, f157, f158, f159;
+ real_t f160, f161, f162, f163, f164, f165, f166, f167, f168, f169;
+ real_t f170, f171, f172, f173, f174, f175, f176, f177, f178, f179;
+ real_t f180, f181, f182, f183, f184, f185, f186, f187, f188, f189;
+ real_t f190, f191, f192, f193, f194, f195, f196, f197, f198, f199;
+ real_t f200, f201, f202, f203, f204, f205, f206, f207, f208, f209;
+ real_t f210, f211, f212, f213, f214, f215, f216, f217, f218, f219;
+ real_t f220, f221, f222, f223, f224, f225, f226, f227, f228, f229;
+ real_t f230, f231, f232, f233, f234, f235, f236, f237, f238, f239;
+ real_t f240, f241, f242, f243, f244, f245, f246, f247, f248, f249;
+ real_t f250, f251, f252, f253, f254, f255, f256, f257, f258, f259;
+ real_t f260, f261, f262, f263, f264, f265, f266, f267, f268, f269;
+ real_t f270, f271, f272, f273, f274, f275, f276, f277, f278, f279;
+ real_t f280, f281, f282, f283, f284, f285, f286, f287, f288, f289;
+ real_t f290, f291, f292, f293, f294, f295, f296, f297, f298, f299;
+ real_t f300, f301, f302, f303, f304, f305, f306, f307, f308, f309;
+ real_t f310, f311, f312, f313, f314, f315, f316, f317, f318, f319;
+ real_t f320, f321, f322, f323, f324, f325, f326, f327, f328, f329;
+ real_t f330, f331, f332, f333, f334, f335;
+
+ f0 = x[0] - x[1];
+ f1 = x[2] - x[1];
+ f2 = x[2] - x[3];
+ f3 = x[4] - x[3];
+ f4 = x[4] - x[5];
+ f5 = x[6] - x[5];
+ f6 = x[6] - x[7];
+ f7 = x[8] - x[7];
+ f8 = x[8] - x[9];
+ f9 = x[10] - x[9];
+ f10 = x[10] - x[11];
+ f11 = x[12] - x[11];
+ f12 = x[12] - x[13];
+ f13 = x[14] - x[13];
+ f14 = x[14] - x[15];
+ f15 = x[16] - x[15];
+ f16 = x[16] - x[17];
+ f17 = x[18] - x[17];
+ f18 = x[18] - x[19];
+ f19 = x[20] - x[19];
+ f20 = x[20] - x[21];
+ f21 = x[22] - x[21];
+ f22 = x[22] - x[23];
+ f23 = x[24] - x[23];
+ f24 = x[24] - x[25];
+ f25 = x[26] - x[25];
+ f26 = x[26] - x[27];
+ f27 = x[28] - x[27];
+ f28 = x[28] - x[29];
+ f29 = x[30] - x[29];
+ f30 = x[30] - x[31];
+ f31 = MUL_F(FRAC_CONST(0.7071067811865476), f15);
+ f32 = x[0] - f31;
+ f33 = x[0] + f31;
+ f34 = f7 + f23;
+ f35 = MUL_C(COEF_CONST(1.3065629648763766), f7);
+ f36 = MUL_F(FRAC_CONST(-0.9238795325112866), f34);
+ f37 = MUL_F(FRAC_CONST(-0.5411961001461967), f23);
+ f38 = f35 + f36;
+ f39 = f37 - f36;
+ f40 = f33 - f39;
+ f41 = f33 + f39;
+ f42 = f32 - f38;
+ f43 = f32 + f38;
+ f44 = f11 - f19;
+ f45 = f11 + f19;
+ f46 = MUL_F(FRAC_CONST(0.7071067811865476), f45);
+ f47 = f3 - f46;
+ f48 = f3 + f46;
+ f49 = MUL_F(FRAC_CONST(0.7071067811865476), f44);
+ f50 = f49 - f27;
+ f51 = f49 + f27;
+ f52 = f51 + f48;
+ f53 = MUL_F(FRAC_CONST(-0.7856949583871021), f51);
+ f54 = MUL_F(FRAC_CONST(0.9807852804032304), f52);
+ f55 = MUL_C(COEF_CONST(1.1758756024193588), f48);
+ f56 = f53 + f54;
+ f57 = f55 - f54;
+ f58 = f50 + f47;
+ f59 = MUL_F(FRAC_CONST(-0.2758993792829430), f50);
+ f60 = MUL_F(FRAC_CONST(0.8314696123025452), f58);
+ f61 = MUL_C(COEF_CONST(1.3870398453221475), f47);
+ f62 = f59 + f60;
+ f63 = f61 - f60;
+ f64 = f41 - f56;
+ f65 = f41 + f56;
+ f66 = f43 - f62;
+ f67 = f43 + f62;
+ f68 = f42 - f63;
+ f69 = f42 + f63;
+ f70 = f40 - f57;
+ f71 = f40 + f57;
+ f72 = f5 - f9;
+ f73 = f5 + f9;
+ f74 = f13 - f17;
+ f75 = f13 + f17;
+ f76 = f21 - f25;
+ f77 = f21 + f25;
+ f78 = MUL_F(FRAC_CONST(0.7071067811865476), f75);
+ f79 = f1 - f78;
+ f80 = f1 + f78;
+ f81 = f73 + f77;
+ f82 = MUL_C(COEF_CONST(1.3065629648763766), f73);
+ f83 = MUL_F(FRAC_CONST(-0.9238795325112866), f81);
+ f84 = MUL_F(FRAC_CONST(-0.5411961001461967), f77);
+ f85 = f82 + f83;
+ f86 = f84 - f83;
+ f87 = f80 - f86;
+ f88 = f80 + f86;
+ f89 = f79 - f85;
+ f90 = f79 + f85;
+ f91 = MUL_F(FRAC_CONST(0.7071067811865476), f74);
+ f92 = f29 - f91;
+ f93 = f29 + f91;
+ f94 = f76 + f72;
+ f95 = MUL_C(COEF_CONST(1.3065629648763766), f76);
+ f96 = MUL_F(FRAC_CONST(-0.9238795325112866), f94);
+ f97 = MUL_F(FRAC_CONST(-0.5411961001461967), f72);
+ f98 = f95 + f96;
+ f99 = f97 - f96;
+ f100 = f93 - f99;
+ f101 = f93 + f99;
+ f102 = f92 - f98;
+ f103 = f92 + f98;
+ f104 = f101 + f88;
+ f105 = MUL_F(FRAC_CONST(-0.8971675863426361), f101);
+ f106 = MUL_F(FRAC_CONST(0.9951847266721968), f104);
+ f107 = MUL_C(COEF_CONST(1.0932018670017576), f88);
+ f108 = f105 + f106;
+ f109 = f107 - f106;
+ f110 = f90 - f103;
+ f111 = MUL_F(FRAC_CONST(-0.6666556584777466), f103);
+ f112 = MUL_F(FRAC_CONST(0.9569403357322089), f110);
+ f113 = MUL_C(COEF_CONST(1.2472250129866713), f90);
+ f114 = f112 - f111;
+ f115 = f113 - f112;
+ f116 = f102 + f89;
+ f117 = MUL_F(FRAC_CONST(-0.4105245275223571), f102);
+ f118 = MUL_F(FRAC_CONST(0.8819212643483549), f116);
+ f119 = MUL_C(COEF_CONST(1.3533180011743529), f89);
+ f120 = f117 + f118;
+ f121 = f119 - f118;
+ f122 = f87 - f100;
+ f123 = MUL_F(FRAC_CONST(-0.1386171691990915), f100);
+ f124 = MUL_F(FRAC_CONST(0.7730104533627370), f122);
+ f125 = MUL_C(COEF_CONST(1.4074037375263826), f87);
+ f126 = f124 - f123;
+ f127 = f125 - f124;
+ f128 = f65 - f108;
+ f129 = f65 + f108;
+ f130 = f67 - f114;
+ f131 = f67 + f114;
+ f132 = f69 - f120;
+ f133 = f69 + f120;
+ f134 = f71 - f126;
+ f135 = f71 + f126;
+ f136 = f70 - f127;
+ f137 = f70 + f127;
+ f138 = f68 - f121;
+ f139 = f68 + f121;
+ f140 = f66 - f115;
+ f141 = f66 + f115;
+ f142 = f64 - f109;
+ f143 = f64 + f109;
+ f144 = f0 + f30;
+ f145 = MUL_C(COEF_CONST(1.0478631305325901), f0);
+ f146 = MUL_F(FRAC_CONST(-0.9987954562051724), f144);
+ f147 = MUL_F(FRAC_CONST(-0.9497277818777548), f30);
+ f148 = f145 + f146;
+ f149 = f147 - f146;
+ f150 = f4 + f26;
+ f151 = MUL_F(FRAC_CONST(1.2130114330978077), f4);
+ f152 = MUL_F(FRAC_CONST(-0.9700312531945440), f150);
+ f153 = MUL_F(FRAC_CONST(-0.7270510732912803), f26);
+ f154 = f151 + f152;
+ f155 = f153 - f152;
+ f156 = f8 + f22;
+ f157 = MUL_C(COEF_CONST(1.3315443865537255), f8);
+ f158 = MUL_F(FRAC_CONST(-0.9039892931234433), f156);
+ f159 = MUL_F(FRAC_CONST(-0.4764341996931612), f22);
+ f160 = f157 + f158;
+ f161 = f159 - f158;
+ f162 = f12 + f18;
+ f163 = MUL_C(COEF_CONST(1.3989068359730781), f12);
+ f164 = MUL_F(FRAC_CONST(-0.8032075314806453), f162);
+ f165 = MUL_F(FRAC_CONST(-0.2075082269882124), f18);
+ f166 = f163 + f164;
+ f167 = f165 - f164;
+ f168 = f16 + f14;
+ f169 = MUL_C(COEF_CONST(1.4125100802019777), f16);
+ f170 = MUL_F(FRAC_CONST(-0.6715589548470187), f168);
+ f171 = MUL_F(FRAC_CONST(0.0693921705079402), f14);
+ f172 = f169 + f170;
+ f173 = f171 - f170;
+ f174 = f20 + f10;
+ f175 = MUL_C(COEF_CONST(1.3718313541934939), f20);
+ f176 = MUL_F(FRAC_CONST(-0.5141027441932219), f174);
+ f177 = MUL_F(FRAC_CONST(0.3436258658070501), f10);
+ f178 = f175 + f176;
+ f179 = f177 - f176;
+ f180 = f24 + f6;
+ f181 = MUL_C(COEF_CONST(1.2784339185752409), f24);
+ f182 = MUL_F(FRAC_CONST(-0.3368898533922200), f180);
+ f183 = MUL_F(FRAC_CONST(0.6046542117908008), f6);
+ f184 = f181 + f182;
+ f185 = f183 - f182;
+ f186 = f28 + f2;
+ f187 = MUL_C(COEF_CONST(1.1359069844201433), f28);
+ f188 = MUL_F(FRAC_CONST(-0.1467304744553624), f186);
+ f189 = MUL_F(FRAC_CONST(0.8424460355094185), f2);
+ f190 = f187 + f188;
+ f191 = f189 - f188;
+ f192 = f149 - f173;
+ f193 = f149 + f173;
+ f194 = f148 - f172;
+ f195 = f148 + f172;
+ f196 = f155 - f179;
+ f197 = f155 + f179;
+ f198 = f154 - f178;
+ f199 = f154 + f178;
+ f200 = f161 - f185;
+ f201 = f161 + f185;
+ f202 = f160 - f184;
+ f203 = f160 + f184;
+ f204 = f167 - f191;
+ f205 = f167 + f191;
+ f206 = f166 - f190;
+ f207 = f166 + f190;
+ f208 = f192 + f194;
+ f209 = MUL_C(COEF_CONST(1.1758756024193588), f192);
+ f210 = MUL_F(FRAC_CONST(-0.9807852804032304), f208);
+ f211 = MUL_F(FRAC_CONST(-0.7856949583871021), f194);
+ f212 = f209 + f210;
+ f213 = f211 - f210;
+ f214 = f196 + f198;
+ f215 = MUL_C(COEF_CONST(1.3870398453221475), f196);
+ f216 = MUL_F(FRAC_CONST(-0.5555702330196022), f214);
+ f217 = MUL_F(FRAC_CONST(0.2758993792829431), f198);
+ f218 = f215 + f216;
+ f219 = f217 - f216;
+ f220 = f200 + f202;
+ f221 = MUL_F(FRAC_CONST(0.7856949583871022), f200);
+ f222 = MUL_F(FRAC_CONST(0.1950903220161283), f220);
+ f223 = MUL_C(COEF_CONST(1.1758756024193586), f202);
+ f224 = f221 + f222;
+ f225 = f223 - f222;
+ f226 = f204 + f206;
+ f227 = MUL_F(FRAC_CONST(-0.2758993792829430), f204);
+ f228 = MUL_F(FRAC_CONST(0.8314696123025452), f226);
+ f229 = MUL_C(COEF_CONST(1.3870398453221475), f206);
+ f230 = f227 + f228;
+ f231 = f229 - f228;
+ f232 = f193 - f201;
+ f233 = f193 + f201;
+ f234 = f195 - f203;
+ f235 = f195 + f203;
+ f236 = f197 - f205;
+ f237 = f197 + f205;
+ f238 = f199 - f207;
+ f239 = f199 + f207;
+ f240 = f213 - f225;
+ f241 = f213 + f225;
+ f242 = f212 - f224;
+ f243 = f212 + f224;
+ f244 = f219 - f231;
+ f245 = f219 + f231;
+ f246 = f218 - f230;
+ f247 = f218 + f230;
+ f248 = f232 + f234;
+ f249 = MUL_C(COEF_CONST(1.3065629648763766), f232);
+ f250 = MUL_F(FRAC_CONST(-0.9238795325112866), f248);
+ f251 = MUL_F(FRAC_CONST(-0.5411961001461967), f234);
+ f252 = f249 + f250;
+ f253 = f251 - f250;
+ f254 = f236 + f238;
+ f255 = MUL_F(FRAC_CONST(0.5411961001461969), f236);
+ f256 = MUL_F(FRAC_CONST(0.3826834323650898), f254);
+ f257 = MUL_C(COEF_CONST(1.3065629648763766), f238);
+ f258 = f255 + f256;
+ f259 = f257 - f256;
+ f260 = f240 + f242;
+ f261 = MUL_C(COEF_CONST(1.3065629648763766), f240);
+ f262 = MUL_F(FRAC_CONST(-0.9238795325112866), f260);
+ f263 = MUL_F(FRAC_CONST(-0.5411961001461967), f242);
+ f264 = f261 + f262;
+ f265 = f263 - f262;
+ f266 = f244 + f246;
+ f267 = MUL_F(FRAC_CONST(0.5411961001461969), f244);
+ f268 = MUL_F(FRAC_CONST(0.3826834323650898), f266);
+ f269 = MUL_C(COEF_CONST(1.3065629648763766), f246);
+ f270 = f267 + f268;
+ f271 = f269 - f268;
+ f272 = f233 - f237;
+ f273 = f233 + f237;
+ f274 = f235 - f239;
+ f275 = f235 + f239;
+ f276 = f253 - f259;
+ f277 = f253 + f259;
+ f278 = f252 - f258;
+ f279 = f252 + f258;
+ f280 = f241 - f245;
+ f281 = f241 + f245;
+ f282 = f243 - f247;
+ f283 = f243 + f247;
+ f284 = f265 - f271;
+ f285 = f265 + f271;
+ f286 = f264 - f270;
+ f287 = f264 + f270;
+ f288 = f272 - f274;
+ f289 = f272 + f274;
+ f290 = MUL_F(FRAC_CONST(0.7071067811865474), f288);
+ f291 = MUL_F(FRAC_CONST(0.7071067811865474), f289);
+ f292 = f276 - f278;
+ f293 = f276 + f278;
+ f294 = MUL_F(FRAC_CONST(0.7071067811865474), f292);
+ f295 = MUL_F(FRAC_CONST(0.7071067811865474), f293);
+ f296 = f280 - f282;
+ f297 = f280 + f282;
+ f298 = MUL_F(FRAC_CONST(0.7071067811865474), f296);
+ f299 = MUL_F(FRAC_CONST(0.7071067811865474), f297);
+ f300 = f284 - f286;
+ f301 = f284 + f286;
+ f302 = MUL_F(FRAC_CONST(0.7071067811865474), f300);
+ f303 = MUL_F(FRAC_CONST(0.7071067811865474), f301);
+ f304 = f129 - f273;
+ f305 = f129 + f273;
+ f306 = f131 - f281;
+ f307 = f131 + f281;
+ f308 = f133 - f285;
+ f309 = f133 + f285;
+ f310 = f135 - f277;
+ f311 = f135 + f277;
+ f312 = f137 - f295;
+ f313 = f137 + f295;
+ f314 = f139 - f303;
+ f315 = f139 + f303;
+ f316 = f141 - f299;
+ f317 = f141 + f299;
+ f318 = f143 - f291;
+ f319 = f143 + f291;
+ f320 = f142 - f290;
+ f321 = f142 + f290;
+ f322 = f140 - f298;
+ f323 = f140 + f298;
+ f324 = f138 - f302;
+ f325 = f138 + f302;
+ f326 = f136 - f294;
+ f327 = f136 + f294;
+ f328 = f134 - f279;
+ f329 = f134 + f279;
+ f330 = f132 - f287;
+ f331 = f132 + f287;
+ f332 = f130 - f283;
+ f333 = f130 + f283;
+ f334 = f128 - f275;
+ f335 = f128 + f275;
+ y[31] = MUL_F(FRAC_CONST(0.5001506360206510), f305);
+ y[30] = MUL_F(FRAC_CONST(0.5013584524464084), f307);
+ y[29] = MUL_F(FRAC_CONST(0.5037887256810443), f309);
+ y[28] = MUL_F(FRAC_CONST(0.5074711720725553), f311);
+ y[27] = MUL_F(FRAC_CONST(0.5124514794082247), f313);
+ y[26] = MUL_F(FRAC_CONST(0.5187927131053328), f315);
+ y[25] = MUL_F(FRAC_CONST(0.5265773151542700), f317);
+ y[24] = MUL_F(FRAC_CONST(0.5359098169079920), f319);
+ y[23] = MUL_F(FRAC_CONST(0.5469204379855088), f321);
+ y[22] = MUL_F(FRAC_CONST(0.5597698129470802), f323);
+ y[21] = MUL_F(FRAC_CONST(0.5746551840326600), f325);
+ y[20] = MUL_F(FRAC_CONST(0.5918185358574165), f327);
+ y[19] = MUL_F(FRAC_CONST(0.6115573478825099), f329);
+ y[18] = MUL_F(FRAC_CONST(0.6342389366884031), f331);
+ y[17] = MUL_F(FRAC_CONST(0.6603198078137061), f333);
+ y[16] = MUL_F(FRAC_CONST(0.6903721282002123), f335);
+ y[15] = MUL_F(FRAC_CONST(0.7251205223771985), f334);
+ y[14] = MUL_F(FRAC_CONST(0.7654941649730891), f332);
+ y[13] = MUL_F(FRAC_CONST(0.8127020908144905), f330);
+ y[12] = MUL_F(FRAC_CONST(0.8683447152233481), f328);
+ y[11] = MUL_F(FRAC_CONST(0.9345835970364075), f326);
+ y[10] = MUL_C(COEF_CONST(1.0144082649970547), f324);
+ y[9] = MUL_C(COEF_CONST(1.1120716205797176), f322);
+ y[8] = MUL_C(COEF_CONST(1.2338327379765710), f320);
+ y[7] = MUL_C(COEF_CONST(1.3892939586328277), f318);
+ y[6] = MUL_C(COEF_CONST(1.5939722833856311), f316);
+ y[5] = MUL_C(COEF_CONST(1.8746759800084078), f314);
+ y[4] = MUL_C(COEF_CONST(2.2820500680051619), f312);
+ y[3] = MUL_C(COEF_CONST(2.9246284281582162), f310);
+ y[2] = MUL_C(COEF_CONST(4.0846110781292477), f308);
+ y[1] = MUL_C(COEF_CONST(6.7967507116736332), f306);
+ y[0] = MUL_R(REAL_CONST(20.3738781672314530), f304);
+}
+
#ifdef SBR_LOW_POWER
void DCT2_16_unscaled(real_t *y, real_t *x)
@@ -1811,7 +2226,7 @@ void dct4_kernel(real_t * in_real, real_t * in_imag, real_t * out_real, real_t *
{
// Tables with bit reverse values for 5 bits, bit reverse of i at i-th position
const uint8_t bit_rev_tab[32] = { 0,16,8,24,4,20,12,28,2,18,10,26,6,22,14,30,1,17,9,25,5,21,13,29,3,19,11,27,7,23,15,31 };
- uint16_t i, i_rev;
+ uint32_t i, i_rev;
/* Step 2: modulate */
// 3*32=96 multiplications
@@ -1859,413 +2274,6 @@ void dct4_kernel(real_t * in_real, real_t * in_imag, real_t * out_real, real_t *
}
-void DST4_32(real_t *y, real_t *x)
-{
- real_t f0, f1, f2, f3, f4, f5, f6, f7, f8, f9;
- real_t f10, f11, f12, f13, f14, f15, f16, f17, f18, f19;
- real_t f20, f21, f22, f23, f24, f25, f26, f27, f28, f29;
- real_t f30, f31, f32, f33, f34, f35, f36, f37, f38, f39;
- real_t f40, f41, f42, f43, f44, f45, f46, f47, f48, f49;
- real_t f50, f51, f52, f53, f54, f55, f56, f57, f58, f59;
- real_t f60, f61, f62, f63, f64, f65, f66, f67, f68, f69;
- real_t f70, f71, f72, f73, f74, f75, f76, f77, f78, f79;
- real_t f80, f81, f82, f83, f84, f85, f86, f87, f88, f89;
- real_t f90, f91, f92, f93, f94, f95, f96, f97, f98, f99;
- real_t f100, f101, f102, f103, f104, f105, f106, f107, f108, f109;
- real_t f110, f111, f112, f113, f114, f115, f116, f117, f118, f119;
- real_t f120, f121, f122, f123, f124, f125, f126, f127, f128, f129;
- real_t f130, f131, f132, f133, f134, f135, f136, f137, f138, f139;
- real_t f140, f141, f142, f143, f144, f145, f146, f147, f148, f149;
- real_t f150, f151, f152, f153, f154, f155, f156, f157, f158, f159;
- real_t f160, f161, f162, f163, f164, f165, f166, f167, f168, f169;
- real_t f170, f171, f172, f173, f174, f175, f176, f177, f178, f179;
- real_t f180, f181, f182, f183, f184, f185, f186, f187, f188, f189;
- real_t f190, f191, f192, f193, f194, f195, f196, f197, f198, f199;
- real_t f200, f201, f202, f203, f204, f205, f206, f207, f208, f209;
- real_t f210, f211, f212, f213, f214, f215, f216, f217, f218, f219;
- real_t f220, f221, f222, f223, f224, f225, f226, f227, f228, f229;
- real_t f230, f231, f232, f233, f234, f235, f236, f237, f238, f239;
- real_t f240, f241, f242, f243, f244, f245, f246, f247, f248, f249;
- real_t f250, f251, f252, f253, f254, f255, f256, f257, f258, f259;
- real_t f260, f261, f262, f263, f264, f265, f266, f267, f268, f269;
- real_t f270, f271, f272, f273, f274, f275, f276, f277, f278, f279;
- real_t f280, f281, f282, f283, f284, f285, f286, f287, f288, f289;
- real_t f290, f291, f292, f293, f294, f295, f296, f297, f298, f299;
- real_t f300, f301, f302, f303, f304, f305, f306, f307, f308, f309;
- real_t f310, f311, f312, f313, f314, f315, f316, f317, f318, f319;
- real_t f320, f321, f322, f323, f324, f325, f326, f327, f328, f329;
- real_t f330, f331, f332, f333, f334, f335;
-
- f0 = x[0] - x[1];
- f1 = x[2] - x[1];
- f2 = x[2] - x[3];
- f3 = x[4] - x[3];
- f4 = x[4] - x[5];
- f5 = x[6] - x[5];
- f6 = x[6] - x[7];
- f7 = x[8] - x[7];
- f8 = x[8] - x[9];
- f9 = x[10] - x[9];
- f10 = x[10] - x[11];
- f11 = x[12] - x[11];
- f12 = x[12] - x[13];
- f13 = x[14] - x[13];
- f14 = x[14] - x[15];
- f15 = x[16] - x[15];
- f16 = x[16] - x[17];
- f17 = x[18] - x[17];
- f18 = x[18] - x[19];
- f19 = x[20] - x[19];
- f20 = x[20] - x[21];
- f21 = x[22] - x[21];
- f22 = x[22] - x[23];
- f23 = x[24] - x[23];
- f24 = x[24] - x[25];
- f25 = x[26] - x[25];
- f26 = x[26] - x[27];
- f27 = x[28] - x[27];
- f28 = x[28] - x[29];
- f29 = x[30] - x[29];
- f30 = x[30] - x[31];
- f31 = MUL_F(FRAC_CONST(0.7071067811865476), f15);
- f32 = x[0] - f31;
- f33 = x[0] + f31;
- f34 = f7 + f23;
- f35 = MUL_C(COEF_CONST(1.3065629648763766), f7);
- f36 = MUL_F(FRAC_CONST(-0.9238795325112866), f34);
- f37 = MUL_F(FRAC_CONST(-0.5411961001461967), f23);
- f38 = f35 + f36;
- f39 = f37 - f36;
- f40 = f33 - f39;
- f41 = f33 + f39;
- f42 = f32 - f38;
- f43 = f32 + f38;
- f44 = f11 - f19;
- f45 = f11 + f19;
- f46 = MUL_F(FRAC_CONST(0.7071067811865476), f45);
- f47 = f3 - f46;
- f48 = f3 + f46;
- f49 = MUL_F(FRAC_CONST(0.7071067811865476), f44);
- f50 = f49 - f27;
- f51 = f49 + f27;
- f52 = f51 + f48;
- f53 = MUL_F(FRAC_CONST(-0.7856949583871021), f51);
- f54 = MUL_F(FRAC_CONST(0.9807852804032304), f52);
- f55 = MUL_C(COEF_CONST(1.1758756024193588), f48);
- f56 = f53 + f54;
- f57 = f55 - f54;
- f58 = f50 + f47;
- f59 = MUL_F(FRAC_CONST(-0.2758993792829430), f50);
- f60 = MUL_F(FRAC_CONST(0.8314696123025452), f58);
- f61 = MUL_C(COEF_CONST(1.3870398453221475), f47);
- f62 = f59 + f60;
- f63 = f61 - f60;
- f64 = f41 - f56;
- f65 = f41 + f56;
- f66 = f43 - f62;
- f67 = f43 + f62;
- f68 = f42 - f63;
- f69 = f42 + f63;
- f70 = f40 - f57;
- f71 = f40 + f57;
- f72 = f5 - f9;
- f73 = f5 + f9;
- f74 = f13 - f17;
- f75 = f13 + f17;
- f76 = f21 - f25;
- f77 = f21 + f25;
- f78 = MUL_F(FRAC_CONST(0.7071067811865476), f75);
- f79 = f1 - f78;
- f80 = f1 + f78;
- f81 = f73 + f77;
- f82 = MUL_C(COEF_CONST(1.3065629648763766), f73);
- f83 = MUL_F(FRAC_CONST(-0.9238795325112866), f81);
- f84 = MUL_F(FRAC_CONST(-0.5411961001461967), f77);
- f85 = f82 + f83;
- f86 = f84 - f83;
- f87 = f80 - f86;
- f88 = f80 + f86;
- f89 = f79 - f85;
- f90 = f79 + f85;
- f91 = MUL_F(FRAC_CONST(0.7071067811865476), f74);
- f92 = f29 - f91;
- f93 = f29 + f91;
- f94 = f76 + f72;
- f95 = MUL_C(COEF_CONST(1.3065629648763766), f76);
- f96 = MUL_F(FRAC_CONST(-0.9238795325112866), f94);
- f97 = MUL_F(FRAC_CONST(-0.5411961001461967), f72);
- f98 = f95 + f96;
- f99 = f97 - f96;
- f100 = f93 - f99;
- f101 = f93 + f99;
- f102 = f92 - f98;
- f103 = f92 + f98;
- f104 = f101 + f88;
- f105 = MUL_F(FRAC_CONST(-0.8971675863426361), f101);
- f106 = MUL_F(FRAC_CONST(0.9951847266721968), f104);
- f107 = MUL_C(COEF_CONST(1.0932018670017576), f88);
- f108 = f105 + f106;
- f109 = f107 - f106;
- f110 = f90 - f103;
- f111 = MUL_F(FRAC_CONST(-0.6666556584777466), f103);
- f112 = MUL_F(FRAC_CONST(0.9569403357322089), f110);
- f113 = MUL_C(COEF_CONST(1.2472250129866713), f90);
- f114 = f112 - f111;
- f115 = f113 - f112;
- f116 = f102 + f89;
- f117 = MUL_F(FRAC_CONST(-0.4105245275223571), f102);
- f118 = MUL_F(FRAC_CONST(0.8819212643483549), f116);
- f119 = MUL_C(COEF_CONST(1.3533180011743529), f89);
- f120 = f117 + f118;
- f121 = f119 - f118;
- f122 = f87 - f100;
- f123 = MUL_F(FRAC_CONST(-0.1386171691990915), f100);
- f124 = MUL_F(FRAC_CONST(0.7730104533627370), f122);
- f125 = MUL_C(COEF_CONST(1.4074037375263826), f87);
- f126 = f124 - f123;
- f127 = f125 - f124;
- f128 = f65 - f108;
- f129 = f65 + f108;
- f130 = f67 - f114;
- f131 = f67 + f114;
- f132 = f69 - f120;
- f133 = f69 + f120;
- f134 = f71 - f126;
- f135 = f71 + f126;
- f136 = f70 - f127;
- f137 = f70 + f127;
- f138 = f68 - f121;
- f139 = f68 + f121;
- f140 = f66 - f115;
- f141 = f66 + f115;
- f142 = f64 - f109;
- f143 = f64 + f109;
- f144 = f0 + f30;
- f145 = MUL_C(COEF_CONST(1.0478631305325901), f0);
- f146 = MUL_F(FRAC_CONST(-0.9987954562051724), f144);
- f147 = MUL_F(FRAC_CONST(-0.9497277818777548), f30);
- f148 = f145 + f146;
- f149 = f147 - f146;
- f150 = f4 + f26;
- f151 = MUL_F(FRAC_CONST(1.2130114330978077), f4);
- f152 = MUL_F(FRAC_CONST(-0.9700312531945440), f150);
- f153 = MUL_F(FRAC_CONST(-0.7270510732912803), f26);
- f154 = f151 + f152;
- f155 = f153 - f152;
- f156 = f8 + f22;
- f157 = MUL_C(COEF_CONST(1.3315443865537255), f8);
- f158 = MUL_F(FRAC_CONST(-0.9039892931234433), f156);
- f159 = MUL_F(FRAC_CONST(-0.4764341996931612), f22);
- f160 = f157 + f158;
- f161 = f159 - f158;
- f162 = f12 + f18;
- f163 = MUL_C(COEF_CONST(1.3989068359730781), f12);
- f164 = MUL_F(FRAC_CONST(-0.8032075314806453), f162);
- f165 = MUL_F(FRAC_CONST(-0.2075082269882124), f18);
- f166 = f163 + f164;
- f167 = f165 - f164;
- f168 = f16 + f14;
- f169 = MUL_C(COEF_CONST(1.4125100802019777), f16);
- f170 = MUL_F(FRAC_CONST(-0.6715589548470187), f168);
- f171 = MUL_F(FRAC_CONST(0.0693921705079402), f14);
- f172 = f169 + f170;
- f173 = f171 - f170;
- f174 = f20 + f10;
- f175 = MUL_C(COEF_CONST(1.3718313541934939), f20);
- f176 = MUL_F(FRAC_CONST(-0.5141027441932219), f174);
- f177 = MUL_F(FRAC_CONST(0.3436258658070501), f10);
- f178 = f175 + f176;
- f179 = f177 - f176;
- f180 = f24 + f6;
- f181 = MUL_C(COEF_CONST(1.2784339185752409), f24);
- f182 = MUL_F(FRAC_CONST(-0.3368898533922200), f180);
- f183 = MUL_F(FRAC_CONST(0.6046542117908008), f6);
- f184 = f181 + f182;
- f185 = f183 - f182;
- f186 = f28 + f2;
- f187 = MUL_C(COEF_CONST(1.1359069844201433), f28);
- f188 = MUL_F(FRAC_CONST(-0.1467304744553624), f186);
- f189 = MUL_F(FRAC_CONST(0.8424460355094185), f2);
- f190 = f187 + f188;
- f191 = f189 - f188;
- f192 = f149 - f173;
- f193 = f149 + f173;
- f194 = f148 - f172;
- f195 = f148 + f172;
- f196 = f155 - f179;
- f197 = f155 + f179;
- f198 = f154 - f178;
- f199 = f154 + f178;
- f200 = f161 - f185;
- f201 = f161 + f185;
- f202 = f160 - f184;
- f203 = f160 + f184;
- f204 = f167 - f191;
- f205 = f167 + f191;
- f206 = f166 - f190;
- f207 = f166 + f190;
- f208 = f192 + f194;
- f209 = MUL_C(COEF_CONST(1.1758756024193588), f192);
- f210 = MUL_F(FRAC_CONST(-0.9807852804032304), f208);
- f211 = MUL_F(FRAC_CONST(-0.7856949583871021), f194);
- f212 = f209 + f210;
- f213 = f211 - f210;
- f214 = f196 + f198;
- f215 = MUL_C(COEF_CONST(1.3870398453221475), f196);
- f216 = MUL_F(FRAC_CONST(-0.5555702330196022), f214);
- f217 = MUL_F(FRAC_CONST(0.2758993792829431), f198);
- f218 = f215 + f216;
- f219 = f217 - f216;
- f220 = f200 + f202;
- f221 = MUL_F(FRAC_CONST(0.7856949583871022), f200);
- f222 = MUL_F(FRAC_CONST(0.1950903220161283), f220);
- f223 = MUL_C(COEF_CONST(1.1758756024193586), f202);
- f224 = f221 + f222;
- f225 = f223 - f222;
- f226 = f204 + f206;
- f227 = MUL_F(FRAC_CONST(-0.2758993792829430), f204);
- f228 = MUL_F(FRAC_CONST(0.8314696123025452), f226);
- f229 = MUL_C(COEF_CONST(1.3870398453221475), f206);
- f230 = f227 + f228;
- f231 = f229 - f228;
- f232 = f193 - f201;
- f233 = f193 + f201;
- f234 = f195 - f203;
- f235 = f195 + f203;
- f236 = f197 - f205;
- f237 = f197 + f205;
- f238 = f199 - f207;
- f239 = f199 + f207;
- f240 = f213 - f225;
- f241 = f213 + f225;
- f242 = f212 - f224;
- f243 = f212 + f224;
- f244 = f219 - f231;
- f245 = f219 + f231;
- f246 = f218 - f230;
- f247 = f218 + f230;
- f248 = f232 + f234;
- f249 = MUL_C(COEF_CONST(1.3065629648763766), f232);
- f250 = MUL_F(FRAC_CONST(-0.9238795325112866), f248);
- f251 = MUL_F(FRAC_CONST(-0.5411961001461967), f234);
- f252 = f249 + f250;
- f253 = f251 - f250;
- f254 = f236 + f238;
- f255 = MUL_F(FRAC_CONST(0.5411961001461969), f236);
- f256 = MUL_F(FRAC_CONST(0.3826834323650898), f254);
- f257 = MUL_C(COEF_CONST(1.3065629648763766), f238);
- f258 = f255 + f256;
- f259 = f257 - f256;
- f260 = f240 + f242;
- f261 = MUL_C(COEF_CONST(1.3065629648763766), f240);
- f262 = MUL_F(FRAC_CONST(-0.9238795325112866), f260);
- f263 = MUL_F(FRAC_CONST(-0.5411961001461967), f242);
- f264 = f261 + f262;
- f265 = f263 - f262;
- f266 = f244 + f246;
- f267 = MUL_F(FRAC_CONST(0.5411961001461969), f244);
- f268 = MUL_F(FRAC_CONST(0.3826834323650898), f266);
- f269 = MUL_C(COEF_CONST(1.3065629648763766), f246);
- f270 = f267 + f268;
- f271 = f269 - f268;
- f272 = f233 - f237;
- f273 = f233 + f237;
- f274 = f235 - f239;
- f275 = f235 + f239;
- f276 = f253 - f259;
- f277 = f253 + f259;
- f278 = f252 - f258;
- f279 = f252 + f258;
- f280 = f241 - f245;
- f281 = f241 + f245;
- f282 = f243 - f247;
- f283 = f243 + f247;
- f284 = f265 - f271;
- f285 = f265 + f271;
- f286 = f264 - f270;
- f287 = f264 + f270;
- f288 = f272 - f274;
- f289 = f272 + f274;
- f290 = MUL_F(FRAC_CONST(0.7071067811865474), f288);
- f291 = MUL_F(FRAC_CONST(0.7071067811865474), f289);
- f292 = f276 - f278;
- f293 = f276 + f278;
- f294 = MUL_F(FRAC_CONST(0.7071067811865474), f292);
- f295 = MUL_F(FRAC_CONST(0.7071067811865474), f293);
- f296 = f280 - f282;
- f297 = f280 + f282;
- f298 = MUL_F(FRAC_CONST(0.7071067811865474), f296);
- f299 = MUL_F(FRAC_CONST(0.7071067811865474), f297);
- f300 = f284 - f286;
- f301 = f284 + f286;
- f302 = MUL_F(FRAC_CONST(0.7071067811865474), f300);
- f303 = MUL_F(FRAC_CONST(0.7071067811865474), f301);
- f304 = f129 - f273;
- f305 = f129 + f273;
- f306 = f131 - f281;
- f307 = f131 + f281;
- f308 = f133 - f285;
- f309 = f133 + f285;
- f310 = f135 - f277;
- f311 = f135 + f277;
- f312 = f137 - f295;
- f313 = f137 + f295;
- f314 = f139 - f303;
- f315 = f139 + f303;
- f316 = f141 - f299;
- f317 = f141 + f299;
- f318 = f143 - f291;
- f319 = f143 + f291;
- f320 = f142 - f290;
- f321 = f142 + f290;
- f322 = f140 - f298;
- f323 = f140 + f298;
- f324 = f138 - f302;
- f325 = f138 + f302;
- f326 = f136 - f294;
- f327 = f136 + f294;
- f328 = f134 - f279;
- f329 = f134 + f279;
- f330 = f132 - f287;
- f331 = f132 + f287;
- f332 = f130 - f283;
- f333 = f130 + f283;
- f334 = f128 - f275;
- f335 = f128 + f275;
- y[31] = MUL_F(FRAC_CONST(0.5001506360206510), f305);
- y[30] = MUL_F(FRAC_CONST(0.5013584524464084), f307);
- y[29] = MUL_F(FRAC_CONST(0.5037887256810443), f309);
- y[28] = MUL_F(FRAC_CONST(0.5074711720725553), f311);
- y[27] = MUL_F(FRAC_CONST(0.5124514794082247), f313);
- y[26] = MUL_F(FRAC_CONST(0.5187927131053328), f315);
- y[25] = MUL_F(FRAC_CONST(0.5265773151542700), f317);
- y[24] = MUL_F(FRAC_CONST(0.5359098169079920), f319);
- y[23] = MUL_F(FRAC_CONST(0.5469204379855088), f321);
- y[22] = MUL_F(FRAC_CONST(0.5597698129470802), f323);
- y[21] = MUL_F(FRAC_CONST(0.5746551840326600), f325);
- y[20] = MUL_F(FRAC_CONST(0.5918185358574165), f327);
- y[19] = MUL_F(FRAC_CONST(0.6115573478825099), f329);
- y[18] = MUL_F(FRAC_CONST(0.6342389366884031), f331);
- y[17] = MUL_F(FRAC_CONST(0.6603198078137061), f333);
- y[16] = MUL_F(FRAC_CONST(0.6903721282002123), f335);
- y[15] = MUL_F(FRAC_CONST(0.7251205223771985), f334);
- y[14] = MUL_F(FRAC_CONST(0.7654941649730891), f332);
- y[13] = MUL_F(FRAC_CONST(0.8127020908144905), f330);
- y[12] = MUL_F(FRAC_CONST(0.8683447152233481), f328);
- y[11] = MUL_F(FRAC_CONST(0.9345835970364075), f326);
- y[10] = MUL_C(COEF_CONST(1.0144082649970547), f324);
- y[9] = MUL_C(COEF_CONST(1.1120716205797176), f322);
- y[8] = MUL_C(COEF_CONST(1.2338327379765710), f320);
- y[7] = MUL_C(COEF_CONST(1.3892939586328277), f318);
- y[6] = MUL_C(COEF_CONST(1.5939722833856311), f316);
- y[5] = MUL_C(COEF_CONST(1.8746759800084078), f314);
- y[4] = MUL_C(COEF_CONST(2.2820500680051619), f312);
- y[3] = MUL_C(COEF_CONST(2.9246284281582162), f310);
- y[2] = MUL_C(COEF_CONST(4.0846110781292477), f308);
- y[1] = MUL_C(COEF_CONST(6.7967507116736332), f306);
- y[0] = MUL_R(REAL_CONST(20.3738781672314530), f304);
-}
-
#endif
#endif
diff --git a/src/libfaad/sbr_dct.h b/src/libfaad/sbr_dct.h
index 6293486c7..ce44fd7ef 100644
--- a/src/libfaad/sbr_dct.h
+++ b/src/libfaad/sbr_dct.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: sbr_dct.h,v 1.5 2005/10/29 23:57:07 tmmm Exp $
+** $Id: sbr_dct.h,v 1.19 2007/11/01 12:33:34 menno Exp $
**/
#ifndef __SBR_DCT_H__
diff --git a/src/libfaad/sbr_dec.c b/src/libfaad/sbr_dec.c
index 24c1f5031..f87d0106c 100644
--- a/src/libfaad/sbr_dec.c
+++ b/src/libfaad/sbr_dec.c
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: sbr_dec.c,v 1.9 2006/06/17 20:43:57 dgp85 Exp $
+** $Id: sbr_dec.c,v 1.43 2007/11/01 12:33:34 menno Exp $
**/
@@ -176,6 +179,72 @@ void sbrDecodeEnd(sbr_info *sbr)
}
}
+void sbrReset(sbr_info *sbr)
+{
+ uint8_t j;
+ if (sbr->qmfa[0] != NULL)
+ memset(sbr->qmfa[0]->x, 0, 2 * sbr->qmfa[0]->channels * 10 * sizeof(real_t));
+ if (sbr->qmfa[1] != NULL)
+ memset(sbr->qmfa[1]->x, 0, 2 * sbr->qmfa[1]->channels * 10 * sizeof(real_t));
+ if (sbr->qmfs[0] != NULL)
+ memset(sbr->qmfs[0]->v, 0, 2 * sbr->qmfs[0]->channels * 20 * sizeof(real_t));
+ if (sbr->qmfs[1] != NULL)
+ memset(sbr->qmfs[1]->v, 0, 2 * sbr->qmfs[1]->channels * 20 * sizeof(real_t));
+
+ for (j = 0; j < 5; j++)
+ {
+ if (sbr->G_temp_prev[0][j] != NULL)
+ memset(sbr->G_temp_prev[0][j], 0, 64*sizeof(real_t));
+ if (sbr->G_temp_prev[1][j] != NULL)
+ memset(sbr->G_temp_prev[1][j], 0, 64*sizeof(real_t));
+ if (sbr->Q_temp_prev[0][j] != NULL)
+ memset(sbr->Q_temp_prev[0][j], 0, 64*sizeof(real_t));
+ if (sbr->Q_temp_prev[1][j] != NULL)
+ memset(sbr->Q_temp_prev[1][j], 0, 64*sizeof(real_t));
+ }
+
+ memset(sbr->Xsbr[0], 0, (sbr->numTimeSlotsRate+sbr->tHFGen)*64 * sizeof(qmf_t));
+ memset(sbr->Xsbr[1], 0, (sbr->numTimeSlotsRate+sbr->tHFGen)*64 * sizeof(qmf_t));
+
+ sbr->GQ_ringbuf_index[0] = 0;
+ sbr->GQ_ringbuf_index[1] = 0;
+ sbr->header_count = 0;
+ sbr->Reset = 1;
+
+ sbr->L_E_prev[0] = 0;
+ sbr->L_E_prev[1] = 0;
+ sbr->bs_freq_scale = 2;
+ sbr->bs_alter_scale = 1;
+ sbr->bs_noise_bands = 2;
+ sbr->bs_limiter_bands = 2;
+ sbr->bs_limiter_gains = 2;
+ sbr->bs_interpol_freq = 1;
+ sbr->bs_smoothing_mode = 1;
+ sbr->bs_start_freq = 5;
+ sbr->bs_amp_res = 1;
+ sbr->bs_samplerate_mode = 1;
+ sbr->prevEnvIsShort[0] = -1;
+ sbr->prevEnvIsShort[1] = -1;
+ sbr->bsco = 0;
+ sbr->bsco_prev = 0;
+ sbr->M_prev = 0;
+ sbr->bs_start_freq_prev = -1;
+
+ sbr->f_prev[0] = 0;
+ sbr->f_prev[1] = 0;
+ for (j = 0; j < MAX_M; j++)
+ {
+ sbr->E_prev[0][j] = 0;
+ sbr->Q_prev[0][j] = 0;
+ sbr->E_prev[1][j] = 0;
+ sbr->Q_prev[1][j] = 0;
+ sbr->bs_add_harmonic_prev[0][j] = 0;
+ sbr->bs_add_harmonic_prev[1][j] = 0;
+ }
+ sbr->bs_add_harmonic_flag_prev[0] = 0;
+ sbr->bs_add_harmonic_flag_prev[1] = 0;
+}
+
static uint8_t sbr_save_prev_data(sbr_info *sbr, uint8_t ch)
{
uint8_t i;
@@ -226,11 +295,12 @@ static void sbr_save_matrix(sbr_info *sbr, uint8_t ch)
}
}
-static void sbr_process_channel(sbr_info *sbr, real_t *channel_buf, qmf_t X[MAX_NTSR][64],
- uint8_t ch, uint8_t dont_process,
- const uint8_t downSampledSBR)
+static uint8_t sbr_process_channel(sbr_info *sbr, real_t *channel_buf, qmf_t X[MAX_NTSR][64],
+ uint8_t ch, uint8_t dont_process,
+ const uint8_t downSampledSBR)
{
int16_t k, l;
+ uint8_t ret = 0;
#ifdef SBR_LOW_POWER
ALIGN real_t deg[64];
@@ -278,7 +348,7 @@ static void sbr_process_channel(sbr_info *sbr, real_t *channel_buf, qmf_t X[MAX_
,ch);
#endif
-#ifdef SBR_LOW_POWER
+#if 0 //def SBR_LOW_POWER
for (l = sbr->t_E[ch][0]; l < sbr->t_E[ch][sbr->L_E[ch]]; l++)
{
for (k = 0; k < sbr->kx; k++)
@@ -290,12 +360,16 @@ static void sbr_process_channel(sbr_info *sbr, real_t *channel_buf, qmf_t X[MAX_
#if 1
/* hf adjustment */
- hf_adjustment(sbr, sbr->Xsbr[ch]
+ ret = hf_adjustment(sbr, sbr->Xsbr[ch]
#ifdef SBR_LOW_POWER
,deg
#endif
,ch);
#endif
+ if (ret > 0)
+ {
+ dont_process = 1;
+ }
}
if ((sbr->just_seeked != 0) || dont_process)
@@ -367,6 +441,8 @@ static void sbr_process_channel(sbr_info *sbr, real_t *channel_buf, qmf_t X[MAX_
#endif
}
}
+
+ return ret;
}
uint8_t sbrDecodeCoupleFrame(sbr_info *sbr, real_t *left_chan, real_t *right_chan,
@@ -400,7 +476,7 @@ uint8_t sbrDecodeCoupleFrame(sbr_info *sbr, real_t *left_chan, real_t *right_cha
sbr->just_seeked = 0;
}
- sbr_process_channel(sbr, left_chan, X, 0, dont_process, downSampledSBR);
+ sbr->ret += sbr_process_channel(sbr, left_chan, X, 0, dont_process, downSampledSBR);
/* subband synthesis */
if (downSampledSBR)
{
@@ -409,7 +485,7 @@ uint8_t sbrDecodeCoupleFrame(sbr_info *sbr, real_t *left_chan, real_t *right_cha
sbr_qmf_synthesis_64(sbr, sbr->qmfs[0], X, left_chan);
}
- sbr_process_channel(sbr, right_chan, X, 1, dont_process, downSampledSBR);
+ sbr->ret += sbr_process_channel(sbr, right_chan, X, 1, dont_process, downSampledSBR);
/* subband synthesis */
if (downSampledSBR)
{
@@ -483,7 +559,7 @@ uint8_t sbrDecodeSingleFrame(sbr_info *sbr, real_t *channel,
sbr->just_seeked = 0;
}
- sbr_process_channel(sbr, channel, X, 0, dont_process, downSampledSBR);
+ sbr->ret += sbr_process_channel(sbr, channel, X, 0, dont_process, downSampledSBR);
/* subband synthesis */
if (downSampledSBR)
{
@@ -526,8 +602,8 @@ uint8_t sbrDecodeSingleFramePS(sbr_info *sbr, real_t *left_channel, real_t *righ
uint8_t l, k;
uint8_t dont_process = 0;
uint8_t ret = 0;
- ALIGN qmf_t X_left[38][64] = {{{0}}};
- ALIGN qmf_t X_right[38][64] = {{{0}}}; /* must set this to 0 */
+ ALIGN qmf_t X_left[38][64] = {{0}};
+ ALIGN qmf_t X_right[38][64] = {{0}}; /* must set this to 0 */
if (sbr == NULL)
return 20;
@@ -558,7 +634,7 @@ uint8_t sbrDecodeSingleFramePS(sbr_info *sbr, real_t *left_channel, real_t *righ
sbr->qmfs[1] = qmfs_init((downSampledSBR)?32:64);
}
- sbr_process_channel(sbr, left_channel, X_left, 0, dont_process, downSampledSBR);
+ sbr->ret += sbr_process_channel(sbr, left_channel, X_left, 0, dont_process, downSampledSBR);
/* copy some extra data for PS */
for (l = 32; l < 38; l++)
@@ -574,7 +650,7 @@ uint8_t sbrDecodeSingleFramePS(sbr_info *sbr, real_t *left_channel, real_t *righ
#ifdef DRM_PS
if (sbr->Is_DRM_SBR)
{
- drm_ps_decode(sbr->drm_ps, (sbr->ret > 0), sbr->sample_rate, X_left, X_right);
+ drm_ps_decode(sbr->drm_ps, (sbr->ret > 0), X_left, X_right);
} else {
#endif
#ifdef PS_DEC
diff --git a/src/libfaad/sbr_dec.h b/src/libfaad/sbr_dec.h
index 5efd5c5e0..40c1d5388 100644
--- a/src/libfaad/sbr_dec.h
+++ b/src/libfaad/sbr_dec.h
@@ -1,28 +1,31 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
+**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
-**
+**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
-**
+**
** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
+** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: sbr_dec.h,v 1.7 2005/10/29 23:57:07 tmmm Exp $
+** $Id: sbr_dec.h,v 1.39 2007/11/01 12:33:34 menno Exp $
**/
#ifndef __SBR_DEC_H__
@@ -183,6 +186,7 @@ typedef struct
#endif
#if (defined(PS_DEC) || defined(DRM_PS))
uint8_t ps_used;
+ uint8_t psResetFlag;
#endif
/* to get it compiling */
@@ -231,6 +235,7 @@ sbr_info *sbrDecodeInit(uint16_t framelength, uint8_t id_aac,
#endif
);
void sbrDecodeEnd(sbr_info *sbr);
+void sbrReset(sbr_info *sbr);
uint8_t sbrDecodeCoupleFrame(sbr_info *sbr, real_t *left_chan, real_t *right_chan,
const uint8_t just_seeked, const uint8_t downSampledSBR);
diff --git a/src/libfaad/sbr_e_nf.c b/src/libfaad/sbr_e_nf.c
index 2d2bf4f85..14ba1e4a5 100644
--- a/src/libfaad/sbr_e_nf.c
+++ b/src/libfaad/sbr_e_nf.c
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: sbr_e_nf.c,v 1.5 2005/10/29 23:57:07 tmmm Exp $
+** $Id: sbr_e_nf.c,v 1.21 2007/11/01 12:33:35 menno Exp $
**/
#include "common.h"
diff --git a/src/libfaad/sbr_e_nf.h b/src/libfaad/sbr_e_nf.h
index 48874c125..59017a906 100644
--- a/src/libfaad/sbr_e_nf.h
+++ b/src/libfaad/sbr_e_nf.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: sbr_e_nf.h,v 1.5 2005/10/29 23:57:07 tmmm Exp $
+** $Id: sbr_e_nf.h,v 1.18 2007/11/01 12:33:35 menno Exp $
**/
#ifndef __SBR_E_NF_H__
diff --git a/src/libfaad/sbr_fbt.c b/src/libfaad/sbr_fbt.c
index 511235863..5919c7b56 100644
--- a/src/libfaad/sbr_fbt.c
+++ b/src/libfaad/sbr_fbt.c
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: sbr_fbt.c,v 1.5 2005/10/29 23:57:07 tmmm Exp $
+** $Id: sbr_fbt.c,v 1.21 2007/11/01 12:33:35 menno Exp $
**/
/* Calculate frequency band tables */
diff --git a/src/libfaad/sbr_fbt.h b/src/libfaad/sbr_fbt.h
index 26c580efe..d24a25e27 100644
--- a/src/libfaad/sbr_fbt.h
+++ b/src/libfaad/sbr_fbt.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: sbr_fbt.h,v 1.5 2005/10/29 23:57:07 tmmm Exp $
+** $Id: sbr_fbt.h,v 1.18 2007/11/01 12:33:35 menno Exp $
**/
#ifndef __SBR_FBT_H__
diff --git a/src/libfaad/sbr_hfadj.c b/src/libfaad/sbr_hfadj.c
index 081f731e9..efac06502 100644
--- a/src/libfaad/sbr_hfadj.c
+++ b/src/libfaad/sbr_hfadj.c
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: sbr_hfadj.c,v 1.5 2005/10/29 23:57:07 tmmm Exp $
+** $Id: sbr_hfadj.c,v 1.22 2007/11/01 12:33:35 menno Exp $
**/
/* High Frequency adjustment */
@@ -39,8 +42,8 @@
/* static function declarations */
-static void estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj,
- qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch);
+static uint8_t estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj,
+ qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch);
static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch);
#ifdef SBR_LOW_POWER
static void calc_gain_groups(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch);
@@ -49,13 +52,14 @@ static void aliasing_reduction(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg,
static void hf_assembly(sbr_info *sbr, sbr_hfadj_info *adj, qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch);
-void hf_adjustment(sbr_info *sbr, qmf_t Xsbr[MAX_NTSRHFG][64]
+uint8_t hf_adjustment(sbr_info *sbr, qmf_t Xsbr[MAX_NTSRHFG][64]
#ifdef SBR_LOW_POWER
- ,real_t *deg /* aliasing degree */
+ ,real_t *deg /* aliasing degree */
#endif
- ,uint8_t ch)
+ ,uint8_t ch)
{
ALIGN sbr_hfadj_info adj = {{{0}}};
+ uint8_t ret = 0;
if (sbr->bs_frame_class[ch] == FIXFIX)
{
@@ -72,7 +76,9 @@ void hf_adjustment(sbr_info *sbr, qmf_t Xsbr[MAX_NTSRHFG][64]
sbr->l_A[ch] = sbr->L_E[ch] + 1 - sbr->bs_pointer[ch];
}
- estimate_current_envelope(sbr, &adj, Xsbr, ch);
+ ret = estimate_current_envelope(sbr, &adj, Xsbr, ch);
+ if (ret > 0)
+ return 1;
calculate_gain(sbr, &adj, ch);
@@ -82,6 +88,8 @@ void hf_adjustment(sbr_info *sbr, qmf_t Xsbr[MAX_NTSRHFG][64]
#endif
hf_assembly(sbr, &adj, Xsbr, ch);
+
+ return 0;
}
static uint8_t get_S_mapped(sbr_info *sbr, uint8_t ch, uint8_t l, uint8_t current_band)
@@ -125,8 +133,8 @@ static uint8_t get_S_mapped(sbr_info *sbr, uint8_t ch, uint8_t l, uint8_t curren
return 0;
}
-static void estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj,
- qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch)
+static uint8_t estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj,
+ qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch)
{
uint8_t m, l, j, k, k_l, k_h, p;
real_t nrg, div;
@@ -142,6 +150,9 @@ static void estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj,
div = (real_t)(u_i - l_i);
+ if (div == 0)
+ div = 1;
+
for (m = 0; m < sbr->M; m++)
{
nrg = 0;
@@ -192,6 +203,9 @@ static void estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj,
div = (real_t)((u_i - l_i)*(k_h - k_l));
+ if (div == 0)
+ div = 1;
+
for (i = l_i + sbr->tHFAdj; i < u_i + sbr->tHFAdj; i++)
{
for (j = k_l; j < k_h; j++)
@@ -225,6 +239,8 @@ static void estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj,
}
}
}
+
+ return 0;
}
#ifdef FIXED_POINT
@@ -1342,15 +1358,27 @@ static void calc_gain_groups(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, ui
{
uint8_t l, k, i;
uint8_t grouping;
+ uint8_t S_mapped;
for (l = 0; l < sbr->L_E[ch]; l++)
{
+ uint8_t current_res_band = 0;
i = 0;
grouping = 0;
+ S_mapped = get_S_mapped(sbr, ch, l, current_res_band);
+
for (k = sbr->kx; k < sbr->kx + sbr->M - 1; k++)
{
- if (deg[k + 1] && adj->S_mapped[l][k-sbr->kx] == 0)
+ if (k == sbr->f_table_res[sbr->f[ch][l]][current_res_band+1])
+ {
+ /* step to next resolution band */
+ current_res_band++;
+
+ S_mapped = get_S_mapped(sbr, ch, l, current_res_band);
+ }
+
+ if (deg[k + 1] && S_mapped == 0)
{
if (grouping == 0)
{
@@ -1361,7 +1389,7 @@ static void calc_gain_groups(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, ui
} else {
if (grouping)
{
- if (adj->S_mapped[l][k-sbr->kx])
+ if (S_mapped)
{
sbr->f_group[l][i] = k;
} else {
diff --git a/src/libfaad/sbr_hfadj.h b/src/libfaad/sbr_hfadj.h
index aeaba32e8..03ef71a0c 100644
--- a/src/libfaad/sbr_hfadj.h
+++ b/src/libfaad/sbr_hfadj.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: sbr_hfadj.h,v 1.5 2005/10/29 23:57:07 tmmm Exp $
+** $Id: sbr_hfadj.h,v 1.19 2007/11/01 12:33:35 menno Exp $
**/
#ifndef __SBR_HFADJ_H__
@@ -40,11 +43,11 @@ typedef struct
} sbr_hfadj_info;
-void hf_adjustment(sbr_info *sbr, qmf_t Xsbr[MAX_NTSRHFG][64]
+uint8_t hf_adjustment(sbr_info *sbr, qmf_t Xsbr[MAX_NTSRHFG][64]
#ifdef SBR_LOW_POWER
- ,real_t *deg
+ ,real_t *deg
#endif
- ,uint8_t ch);
+ ,uint8_t ch);
#ifdef __cplusplus
diff --git a/src/libfaad/sbr_hfgen.c b/src/libfaad/sbr_hfgen.c
index 688b9a0ea..b0f3219c3 100644
--- a/src/libfaad/sbr_hfgen.c
+++ b/src/libfaad/sbr_hfgen.c
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: sbr_hfgen.c,v 1.5 2005/10/29 23:57:07 tmmm Exp $
+** $Id: sbr_hfgen.c,v 1.26 2007/11/01 12:33:35 menno Exp $
**/
/* High Frequency generation */
@@ -36,7 +39,6 @@
#include "sbr_hfgen.h"
#include "sbr_fbt.h"
-
/* static function declarations */
#ifdef SBR_LOW_POWER
static void calc_prediction_coef_lp(sbr_info *sbr, qmf_t Xlow[MAX_NTSRHFG][64],
diff --git a/src/libfaad/sbr_hfgen.h b/src/libfaad/sbr_hfgen.h
index 27a58be61..a7c842494 100644
--- a/src/libfaad/sbr_hfgen.h
+++ b/src/libfaad/sbr_hfgen.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: sbr_hfgen.h,v 1.5 2005/10/29 23:57:07 tmmm Exp $
+** $Id: sbr_hfgen.h,v 1.20 2007/11/01 12:33:35 menno Exp $
**/
#ifndef __SBR_HFGEN_H__
diff --git a/src/libfaad/sbr_huff.c b/src/libfaad/sbr_huff.c
index 39ae32b9b..6ba878640 100644
--- a/src/libfaad/sbr_huff.c
+++ b/src/libfaad/sbr_huff.c
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: sbr_huff.c,v 1.7 2005/10/29 23:57:07 tmmm Exp $
+** $Id: sbr_huff.c,v 1.21 2007/11/01 12:33:35 menno Exp $
**/
#include "common.h"
diff --git a/src/libfaad/sbr_huff.h b/src/libfaad/sbr_huff.h
index 631a43a8d..f749f2e08 100644
--- a/src/libfaad/sbr_huff.h
+++ b/src/libfaad/sbr_huff.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: sbr_huff.h,v 1.7 2005/10/29 23:57:07 tmmm Exp $
+** $Id: sbr_huff.h,v 1.21 2007/11/01 12:33:35 menno Exp $
**/
#ifndef __SBR_HUFF_H__
diff --git a/src/libfaad/sbr_noise.h b/src/libfaad/sbr_noise.h
index a25fbf3cd..1cf7190de 100644
--- a/src/libfaad/sbr_noise.h
+++ b/src/libfaad/sbr_noise.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: sbr_noise.h,v 1.5 2005/10/29 23:57:07 tmmm Exp $
+** $Id: sbr_noise.h,v 1.17 2007/11/01 12:33:35 menno Exp $
**/
#ifndef __SBR_NOISE_H__
diff --git a/src/libfaad/sbr_qmf.c b/src/libfaad/sbr_qmf.c
index d534a0442..68f408916 100644
--- a/src/libfaad/sbr_qmf.c
+++ b/src/libfaad/sbr_qmf.c
@@ -1,28 +1,31 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
+**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
-**
+**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
-**
+**
** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
+** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: sbr_qmf.c,v 1.7 2005/10/29 23:57:07 tmmm Exp $
+** $Id: sbr_qmf.c,v 1.32 2007/11/01 12:33:36 menno Exp $
**/
#include "common.h"
@@ -72,7 +75,7 @@ void sbr_qmf_analysis_32(sbr_info *sbr, qmfa_info *qmfa, const real_t *input,
#else
ALIGN real_t y[32];
#endif
- uint16_t in = 0;
+ uint32_t in = 0;
uint8_t l;
/* qmf subsample l */
@@ -251,7 +254,7 @@ void sbr_qmf_synthesis_32(sbr_info *sbr, qmfs_info *qmfs, qmf_t X[MAX_NTSRHFG][6
{
ALIGN real_t x[16];
ALIGN real_t y[16];
- int16_t n, k, out = 0;
+ int32_t n, k, out = 0;
uint8_t l;
/* qmf subsample l */
@@ -320,7 +323,7 @@ void sbr_qmf_synthesis_64(sbr_info *sbr, qmfs_info *qmfs, qmf_t X[MAX_NTSRHFG][6
{
ALIGN real_t x[64];
ALIGN real_t y[64];
- int16_t n, k, out = 0;
+ int32_t n, k, out = 0;
uint8_t l;
@@ -392,7 +395,7 @@ void sbr_qmf_synthesis_32(sbr_info *sbr, qmfs_info *qmfs, qmf_t X[MAX_NTSRHFG][6
#ifndef FIXED_POINT
real_t scale = 1.f/64.f;
#endif
- int16_t n, k, out = 0;
+ int32_t n, k, out = 0;
uint8_t l;
@@ -475,7 +478,7 @@ void sbr_qmf_synthesis_64(sbr_info *sbr, qmfs_info *qmfs, qmf_t X[MAX_NTSRHFG][6
#ifndef FIXED_POINT
real_t scale = 1.f/64.f;
#endif
- int16_t n, k, out = 0;
+ int32_t n, k, out = 0;
uint8_t l;
diff --git a/src/libfaad/sbr_qmf.h b/src/libfaad/sbr_qmf.h
index b1d673d9c..efb167be9 100644
--- a/src/libfaad/sbr_qmf.h
+++ b/src/libfaad/sbr_qmf.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: sbr_qmf.h,v 1.7 2005/10/29 23:57:07 tmmm Exp $
+** $Id: sbr_qmf.h,v 1.25 2007/11/01 12:33:36 menno Exp $
**/
#ifndef __SBR_QMF_H__
diff --git a/src/libfaad/sbr_qmf_c.h b/src/libfaad/sbr_qmf_c.h
index d9c079520..c2fcd2739 100644
--- a/src/libfaad/sbr_qmf_c.h
+++ b/src/libfaad/sbr_qmf_c.h
@@ -1,28 +1,31 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
+**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
-**
+**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
-**
+**
** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
+** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: sbr_qmf_c.h,v 1.5 2005/10/29 23:57:07 tmmm Exp $
+** $Id: sbr_qmf_c.h,v 1.17 2007/11/01 12:33:36 menno Exp $
**/
#ifndef __SBR_QMF_C_H__
diff --git a/src/libfaad/sbr_syntax.c b/src/libfaad/sbr_syntax.c
index 19cb1b5c2..216c2e9e1 100644
--- a/src/libfaad/sbr_syntax.c
+++ b/src/libfaad/sbr_syntax.c
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: sbr_syntax.c,v 1.7 2005/10/29 23:57:07 tmmm Exp $
+** $Id: sbr_syntax.c,v 1.38 2007/11/01 12:33:36 menno Exp $
**/
#include "common.h"
@@ -46,6 +49,7 @@
#include "analysis.h"
/* static function declarations */
+/* static function declarations */
static void sbr_header(bitfile *ld, sbr_info *sbr);
static uint8_t calc_sbr_tables(sbr_info *sbr, uint8_t start_freq, uint8_t stop_freq,
uint8_t samplerate_mode, uint8_t freq_scale,
@@ -131,16 +135,23 @@ static uint8_t calc_sbr_tables(sbr_info *sbr, uint8_t start_freq, uint8_t stop_f
}
/* table 2 */
-uint8_t sbr_extension_data(bitfile *ld, sbr_info *sbr, uint16_t cnt)
+uint8_t sbr_extension_data(bitfile *ld, sbr_info *sbr, uint16_t cnt,
+ uint8_t psResetFlag)
{
uint8_t result = 0;
uint16_t num_align_bits = 0;
- uint16_t num_sbr_bits = (uint16_t)faad_get_processed_bits(ld);
+ uint16_t num_sbr_bits1 = (uint16_t)faad_get_processed_bits(ld);
+ uint16_t num_sbr_bits2;
uint8_t saved_start_freq, saved_samplerate_mode;
uint8_t saved_stop_freq, saved_freq_scale;
uint8_t saved_alter_scale, saved_xover_band;
+#if (defined(PS_DEC) || defined(DRM_PS))
+ if (psResetFlag)
+ sbr->psResetFlag = psResetFlag;
+#endif
+
#ifdef DRM
if (!sbr->Is_DRM_SBR)
#endif
@@ -206,28 +217,40 @@ uint8_t sbr_extension_data(bitfile *ld, sbr_info *sbr, uint16_t cnt)
{
calc_sbr_tables(sbr, saved_start_freq, saved_stop_freq,
saved_samplerate_mode, saved_freq_scale,
- saved_alter_scale, saved_xover_band);
+ saved_alter_scale, saved_xover_band);
}
- /* we should be able to safely set result to 0 now */
- result = 0;
+ /* we should be able to safely set result to 0 now, */
+ /* but practise indicates this doesn't work well */
}
} else {
result = 1;
}
-#ifdef DRM
- if (!sbr->Is_DRM_SBR)
-#endif
+ num_sbr_bits2 = (uint16_t)faad_get_processed_bits(ld) - num_sbr_bits1;
+
+ /* check if we read more bits then were available for sbr */
+ if (8*cnt < num_sbr_bits2)
{
- num_sbr_bits = (uint16_t)faad_get_processed_bits(ld) - num_sbr_bits;
+ faad_resetbits(ld, num_sbr_bits1 + 8*cnt);
+ num_sbr_bits2 = 8*cnt;
- /* check if we read more bits then were available for sbr */
- if (8*cnt < num_sbr_bits)
- return 1;
+#ifdef PS_DEC
+ /* turn off PS for the unfortunate case that we randomly read some
+ * PS data that looks correct */
+ sbr->ps_used = 0;
+#endif
+
+ /* Make sure it doesn't decode SBR in this frame, or we'll get glitches */
+ return 1;
+ }
+#ifdef DRM
+ if (!sbr->Is_DRM_SBR)
+#endif
+ {
/* -4 does not apply, bs_extension_type is re-read in this function */
- num_align_bits = 8*cnt /*- 4*/ - num_sbr_bits;
+ num_align_bits = 8*cnt /*- 4*/ - num_sbr_bits2;
while (num_align_bits > 7)
{
@@ -364,11 +387,14 @@ static uint8_t sbr_single_channel_element(bitfile *ld, sbr_info *sbr)
#ifdef DRM
/* bs_coupling, from sbr_channel_pair_base_element(bs_amp_res) */
if (sbr->Is_DRM_SBR)
+ {
faad_get1bit(ld);
+ }
#endif
if ((result = sbr_grid(ld, sbr, 0)) > 0)
return result;
+
sbr_dtdf(ld, sbr, 0);
invf_mode(ld, sbr, 0);
sbr_envelope(ld, sbr, 0);
@@ -431,7 +457,11 @@ static uint8_t sbr_single_channel_element(bitfile *ld, sbr_info *sbr)
} else {
/* to be safe make it 3, will switch to "default"
* in sbr_extension() */
+#ifdef DRM
+ return 1;
+#else
sbr->bs_extension_id = 3;
+#endif
}
}
#endif
@@ -829,6 +859,10 @@ static uint16_t sbr_extension(bitfile *ld, sbr_info *sbr,
{
sbr->ps = ps_init(get_sr_index(sbr->sample_rate));
}
+ if (sbr->psResetFlag)
+ {
+ sbr->ps->header_read = 0;
+ }
ret = ps_data(sbr->ps, ld, &header);
/* enable PS if and only if: a header has been decoded */
@@ -837,6 +871,11 @@ static uint16_t sbr_extension(bitfile *ld, sbr_info *sbr,
sbr->ps_used = 1;
}
+ if (header == 1)
+ {
+ sbr->psResetFlag = 0;
+ }
+
return ret;
#endif
#ifdef DRM_PS
diff --git a/src/libfaad/sbr_syntax.h b/src/libfaad/sbr_syntax.h
index 1baa5fec3..a13b2708f 100644
--- a/src/libfaad/sbr_syntax.h
+++ b/src/libfaad/sbr_syntax.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: sbr_syntax.h,v 1.7 2005/10/29 23:57:07 tmmm Exp $
+** $Id: sbr_syntax.h,v 1.23 2007/11/01 12:33:36 menno Exp $
**/
#ifndef __SBR_SYNTAX_H__
@@ -55,7 +58,8 @@ extern "C" {
#define NOISE_FLOOR_OFFSET 6
-uint8_t sbr_extension_data(bitfile *ld, sbr_info *sbr, uint16_t cnt);
+uint8_t sbr_extension_data(bitfile *ld, sbr_info *sbr, uint16_t cnt,
+ uint8_t resetFlag);
#ifdef __cplusplus
}
diff --git a/src/libfaad/sbr_tf_grid.c b/src/libfaad/sbr_tf_grid.c
index ae741c256..b3b24fd16 100644
--- a/src/libfaad/sbr_tf_grid.c
+++ b/src/libfaad/sbr_tf_grid.c
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: sbr_tf_grid.c,v 1.5 2005/10/29 23:57:07 tmmm Exp $
+** $Id: sbr_tf_grid.c,v 1.19 2007/11/01 12:33:36 menno Exp $
**/
/* Time/Frequency grid */
diff --git a/src/libfaad/sbr_tf_grid.h b/src/libfaad/sbr_tf_grid.h
index 8772a384a..27a8f908e 100644
--- a/src/libfaad/sbr_tf_grid.h
+++ b/src/libfaad/sbr_tf_grid.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: sbr_tf_grid.h,v 1.5 2005/10/29 23:57:07 tmmm Exp $
+** $Id: sbr_tf_grid.h,v 1.17 2007/11/01 12:33:36 menno Exp $
**/
#ifndef __SBR_TF_GRID_H__
diff --git a/src/libfaad/sine_win.h b/src/libfaad/sine_win.h
index c7e6ecd6e..e4198da3a 100644
--- a/src/libfaad/sine_win.h
+++ b/src/libfaad/sine_win.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: sine_win.h,v 1.6 2005/10/29 23:57:07 tmmm Exp $
+** $Id: sine_win.h,v 1.19 2007/11/01 12:33:36 menno Exp $
**/
#ifndef __SINE_WIN_H__
diff --git a/src/libfaad/specrec.c b/src/libfaad/specrec.c
index fd4b0653c..ea6ca94b9 100644
--- a/src/libfaad/specrec.c
+++ b/src/libfaad/specrec.c
@@ -1,28 +1,31 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
+**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
-**
+**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
-**
+**
** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
+** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: specrec.c,v 1.10 2006/06/17 20:43:57 dgp85 Exp $
+** $Id: specrec.c,v 1.60 2007/11/01 12:33:36 menno Exp $
**/
/*
@@ -327,6 +330,11 @@ uint8_t window_grouping_info(NeAACDecHandle hDecoder, ic_stream *ics)
}
#endif
+ if (ics->max_sfb > ics->num_swb)
+ {
+ return 32;
+ }
+
/* preparation of sect_sfb_offset for long blocks */
/* also copy the last value! */
#ifdef LD_DEC
@@ -348,6 +356,7 @@ uint8_t window_grouping_info(NeAACDecHandle hDecoder, ic_stream *ics)
}
ics->sect_sfb_offset[0][ics->num_swb] = hDecoder->frameLength;
ics->swb_offset[ics->num_swb] = hDecoder->frameLength;
+ ics->swb_offset_max = hDecoder->frameLength;
} else {
#endif
for (i = 0; i < ics->num_swb; i++)
@@ -357,6 +366,7 @@ uint8_t window_grouping_info(NeAACDecHandle hDecoder, ic_stream *ics)
}
ics->sect_sfb_offset[0][ics->num_swb] = hDecoder->frameLength;
ics->swb_offset[ics->num_swb] = hDecoder->frameLength;
+ ics->swb_offset_max = hDecoder->frameLength;
#ifdef LD_DEC
}
#endif
@@ -367,9 +377,15 @@ uint8_t window_grouping_info(NeAACDecHandle hDecoder, ic_stream *ics)
ics->window_group_length[ics->num_window_groups-1] = 1;
ics->num_swb = num_swb_128_window[sf_index];
+ if (ics->max_sfb > ics->num_swb)
+ {
+ return 32;
+ }
+
for (i = 0; i < ics->num_swb; i++)
ics->swb_offset[i] = swb_offset_128_window[sf_index][i];
ics->swb_offset[ics->num_swb] = hDecoder->frameLength/8;
+ ics->swb_offset_max = hDecoder->frameLength/8;
for (i = 0; i < ics->num_windows-1; i++) {
if (bit_set(ics->scale_factor_grouping, 6-i) == 0)
@@ -405,7 +421,7 @@ uint8_t window_grouping_info(NeAACDecHandle hDecoder, ic_stream *ics)
}
return 0;
default:
- return 1;
+ return 32;
}
}
@@ -667,25 +683,46 @@ static uint8_t quant_to_spec(NeAACDecHandle hDecoder,
static uint8_t allocate_single_channel(NeAACDecHandle hDecoder, uint8_t channel,
uint8_t output_channels)
{
- uint8_t mul = 1;
+ int mul = 1;
#ifdef MAIN_DEC
/* MAIN object type prediction */
if (hDecoder->object_type == MAIN)
{
- hDecoder->pred_stat[channel] = (pred_state*)realloc(hDecoder->pred_stat[channel], hDecoder->frameLength * sizeof(pred_state));
- reset_all_predictors(hDecoder->pred_stat[channel], hDecoder->frameLength);
+ /* allocate the state only when needed */
+ if (hDecoder->pred_stat[channel] != NULL)
+ {
+ faad_free(hDecoder->pred_stat[channel]);
+ hDecoder->pred_stat[channel] = NULL;
+ }
+
+ hDecoder->pred_stat[channel] = (pred_state*)faad_malloc(hDecoder->frameLength * sizeof(pred_state));
+ reset_all_predictors(hDecoder->pred_stat[channel], hDecoder->frameLength);
}
#endif
#ifdef LTP_DEC
if (is_ltp_ot(hDecoder->object_type))
{
- hDecoder->lt_pred_stat[channel] = (int16_t*)realloc(hDecoder->lt_pred_stat[channel], hDecoder->frameLength*4 * sizeof(int16_t));
- memset(hDecoder->lt_pred_stat[channel], 0, hDecoder->frameLength*4 * sizeof(int16_t));
+ /* allocate the state only when needed */
+ if (hDecoder->lt_pred_stat[channel] != NULL)
+ {
+ faad_free(hDecoder->lt_pred_stat[channel]);
+ hDecoder->lt_pred_stat[channel] = NULL;
+ }
+
+ hDecoder->lt_pred_stat[channel] = (int16_t*)faad_malloc(hDecoder->frameLength*4 * sizeof(int16_t));
+ memset(hDecoder->lt_pred_stat[channel], 0, hDecoder->frameLength*4 * sizeof(int16_t));
}
#endif
+ if (hDecoder->time_out[channel] != NULL)
+ {
+ faad_free(hDecoder->time_out[channel]);
+ hDecoder->time_out[channel] = NULL;
+ }
+
+ {
mul = 1;
#ifdef SBR_DEC
hDecoder->sbr_alloced[hDecoder->fr_ch_ele] = 0;
@@ -696,28 +733,48 @@ static uint8_t allocate_single_channel(NeAACDecHandle hDecoder, uint8_t channel,
hDecoder->sbr_alloced[hDecoder->fr_ch_ele] = 1;
}
#endif
- hDecoder->time_out[channel] = (real_t*)realloc(hDecoder->time_out[channel], mul*hDecoder->frameLength*sizeof(real_t));
+ hDecoder->time_out[channel] = (real_t*)faad_malloc(mul*hDecoder->frameLength*sizeof(real_t));
memset(hDecoder->time_out[channel], 0, mul*hDecoder->frameLength*sizeof(real_t));
+ }
+
#if (defined(PS_DEC) || defined(DRM_PS))
if (output_channels == 2)
{
- hDecoder->time_out[channel+1] = (real_t*)realloc(hDecoder->time_out[channel+1], mul*hDecoder->frameLength*sizeof(real_t));
- memset(hDecoder->time_out[channel+1], 0, mul*hDecoder->frameLength*sizeof(real_t));
+ if (hDecoder->time_out[channel+1] != NULL)
+ {
+ faad_free(hDecoder->time_out[channel+1]);
+ hDecoder->time_out[channel+1] = NULL;
+ }
+
+ hDecoder->time_out[channel+1] = (real_t*)faad_malloc(mul*hDecoder->frameLength*sizeof(real_t));
+ memset(hDecoder->time_out[channel+1], 0, mul*hDecoder->frameLength*sizeof(real_t));
}
#endif
- hDecoder->fb_intermed[channel] = (real_t*)realloc(hDecoder->fb_intermed[channel], hDecoder->frameLength*sizeof(real_t));
- memset(hDecoder->fb_intermed[channel], 0, hDecoder->frameLength*sizeof(real_t));
+ if (hDecoder->fb_intermed[channel] != NULL)
+ {
+ faad_free(hDecoder->fb_intermed[channel]);
+ hDecoder->fb_intermed[channel] = NULL;
+ }
+
+ hDecoder->fb_intermed[channel] = (real_t*)faad_malloc(hDecoder->frameLength*sizeof(real_t));
+ memset(hDecoder->fb_intermed[channel], 0, hDecoder->frameLength*sizeof(real_t));
#ifdef SSR_DEC
if (hDecoder->object_type == SSR)
{
- uint16_t k;
- hDecoder->ssr_overlap[channel] = (real_t*)realloc(hDecoder->ssr_overlap[channel], 2*hDecoder->frameLength*sizeof(real_t));
+ if (hDecoder->ssr_overlap[channel] == NULL)
+ {
+ hDecoder->ssr_overlap[channel] = (real_t*)faad_malloc(2*hDecoder->frameLength*sizeof(real_t));
memset(hDecoder->ssr_overlap[channel], 0, 2*hDecoder->frameLength*sizeof(real_t));
- hDecoder->prev_fmd[channel] = (real_t*)realloc(hDecoder->prev_fmd[channel], 2*hDecoder->frameLength*sizeof(real_t));
+ }
+ if (hDecoder->prev_fmd[channel] == NULL)
+ {
+ uint16_t k;
+ hDecoder->prev_fmd[channel] = (real_t*)faad_malloc(2*hDecoder->frameLength*sizeof(real_t));
for (k = 0; k < 2*hDecoder->frameLength; k++)
hDecoder->prev_fmd[channel][k] = REAL_CONST(-1);
+ }
}
#endif
@@ -727,7 +784,7 @@ static uint8_t allocate_single_channel(NeAACDecHandle hDecoder, uint8_t channel,
static uint8_t allocate_channel_pair(NeAACDecHandle hDecoder,
uint8_t channel, uint8_t paired_channel)
{
- uint8_t mul = 1;
+ int mul = 1;
#ifdef MAIN_DEC
/* MAIN object type prediction */
@@ -832,7 +889,8 @@ static uint8_t allocate_channel_pair(NeAACDecHandle hDecoder,
uint8_t reconstruct_single_channel(NeAACDecHandle hDecoder, ic_stream *ics,
element *sce, int16_t *spec_data)
{
- uint8_t retval, output_channels;
+ uint8_t retval;
+ int output_channels;
ALIGN real_t spec_coef[1024];
#ifdef PROFILE
@@ -841,15 +899,38 @@ uint8_t reconstruct_single_channel(NeAACDecHandle hDecoder, ic_stream *ics,
/* always allocate 2 channels, PS can always "suddenly" turn up */
-#if (defined(PS_DEC) || defined(DRM_PS))
- output_channels = hDecoder->ps_used[hDecoder->fr_ch_ele] ? 2 : 1;
+#if ( (defined(DRM) && defined(DRM_PS)) )
+ output_channels = 2;
+#elif defined(PS_DEC)
+ if (hDecoder->ps_used[hDecoder->fr_ch_ele])
+ output_channels = 2;
+ else
+ output_channels = 1;
#else
output_channels = 1;
#endif
- if (hDecoder->element_output_channels[hDecoder->fr_ch_ele] < output_channels)
+ if (hDecoder->element_output_channels[hDecoder->fr_ch_ele] == 0)
{
+ /* element_output_channels not set yet */
hDecoder->element_output_channels[hDecoder->fr_ch_ele] = output_channels;
+ } else if (hDecoder->element_output_channels[hDecoder->fr_ch_ele] != output_channels) {
+ /* element inconsistency */
+
+ /* this only happens if PS is actually found but not in the first frame
+ * this means that there is only 1 bitstream element!
+ */
+
+ /* reset the allocation */
+ hDecoder->element_alloced[hDecoder->fr_ch_ele] = 0;
+
+ hDecoder->element_output_channels[hDecoder->fr_ch_ele] = output_channels;
+
+ //return 21;
+ }
+
+ if (hDecoder->element_alloced[hDecoder->fr_ch_ele] == 0)
+ {
retval = allocate_single_channel(hDecoder, sce->channel, output_channels);
if (retval > 0)
return retval;
@@ -870,7 +951,8 @@ uint8_t reconstruct_single_channel(NeAACDecHandle hDecoder, ic_stream *ics,
/* pns decoding */
- pns_decode(ics, NULL, spec_coef, NULL, hDecoder->frameLength, 0, hDecoder->object_type);
+ pns_decode(ics, NULL, spec_coef, NULL, hDecoder->frameLength, 0, hDecoder->object_type,
+ &(hDecoder->__r1), &(hDecoder->__r2));
#ifdef MAIN_DEC
/* MAIN object type prediction */
@@ -954,8 +1036,8 @@ uint8_t reconstruct_single_channel(NeAACDecHandle hDecoder, ic_stream *ics,
if (((hDecoder->sbr_present_flag == 1) || (hDecoder->forceUpSampling == 1))
&& hDecoder->sbr_alloced[hDecoder->fr_ch_ele])
{
- uint8_t ele = hDecoder->fr_ch_ele;
- uint8_t ch = sce->channel;
+ int ele = hDecoder->fr_ch_ele;
+ int ch = sce->channel;
/* following case can happen when forceUpSampling == 1 */
if (hDecoder->sbr[ele] == NULL)
@@ -970,9 +1052,9 @@ uint8_t reconstruct_single_channel(NeAACDecHandle hDecoder, ic_stream *ics,
}
if (sce->ics1.window_sequence == EIGHT_SHORT_SEQUENCE)
- hDecoder->sbr[ele]->maxAACLine = 8*sce->ics1.swb_offset[max(sce->ics1.max_sfb-1, 0)];
+ hDecoder->sbr[ele]->maxAACLine = 8*min(sce->ics1.swb_offset[max(sce->ics1.max_sfb-1, 0)], sce->ics1.swb_offset_max);
else
- hDecoder->sbr[ele]->maxAACLine = sce->ics1.swb_offset[max(sce->ics1.max_sfb-1, 0)];
+ hDecoder->sbr[ele]->maxAACLine = min(sce->ics1.swb_offset[max(sce->ics1.max_sfb-1, 0)], sce->ics1.swb_offset_max);
/* check if any of the PS tools is used */
#if (defined(PS_DEC) || defined(DRM_PS))
@@ -995,20 +1077,21 @@ uint8_t reconstruct_single_channel(NeAACDecHandle hDecoder, ic_stream *ics,
{
return 23;
}
+#endif
/* copy L to R when no PS is used */
#if (defined(PS_DEC) || defined(DRM_PS))
- if ((hDecoder->ps_used[hDecoder->fr_ch_ele] == 0) && (output_channels == 2))
+ if ((hDecoder->ps_used[hDecoder->fr_ch_ele] == 0) &&
+ (hDecoder->element_output_channels[hDecoder->fr_ch_ele] == 2))
{
- uint8_t ele = hDecoder->fr_ch_ele;
- uint8_t ch = sce->channel;
- uint16_t frame_size = (hDecoder->sbr_alloced[ele]) ? 2 : 1;
+ int ele = hDecoder->fr_ch_ele;
+ int ch = sce->channel;
+ int frame_size = (hDecoder->sbr_alloced[ele]) ? 2 : 1;
frame_size *= hDecoder->frameLength*sizeof(real_t);
memcpy(hDecoder->time_out[ch+1], hDecoder->time_out[ch], frame_size);
}
#endif
-#endif
return 0;
}
@@ -1049,10 +1132,13 @@ uint8_t reconstruct_channel_pair(NeAACDecHandle hDecoder, ic_stream *ics1, ic_st
/* pns decoding */
if (ics1->ms_mask_present)
{
- pns_decode(ics1, ics2, spec_coef1, spec_coef2, hDecoder->frameLength, 1, hDecoder->object_type);
+ pns_decode(ics1, ics2, spec_coef1, spec_coef2, hDecoder->frameLength, 1, hDecoder->object_type,
+ &(hDecoder->__r1), &(hDecoder->__r2));
} else {
- pns_decode(ics1, NULL, spec_coef1, NULL, hDecoder->frameLength, 0, hDecoder->object_type);
- pns_decode(ics2, NULL, spec_coef2, NULL, hDecoder->frameLength, 0, hDecoder->object_type);
+ pns_decode(ics1, NULL, spec_coef1, NULL, hDecoder->frameLength, 0, hDecoder->object_type,
+ &(hDecoder->__r1), &(hDecoder->__r2));
+ pns_decode(ics2, NULL, spec_coef2, NULL, hDecoder->frameLength, 0, hDecoder->object_type,
+ &(hDecoder->__r1), &(hDecoder->__r2));
}
/* mid/side decoding */
@@ -1204,9 +1290,9 @@ uint8_t reconstruct_channel_pair(NeAACDecHandle hDecoder, ic_stream *ics1, ic_st
if (((hDecoder->sbr_present_flag == 1) || (hDecoder->forceUpSampling == 1))
&& hDecoder->sbr_alloced[hDecoder->fr_ch_ele])
{
- uint8_t ele = hDecoder->fr_ch_ele;
- uint8_t ch0 = cpe->channel;
- uint8_t ch1 = cpe->paired_channel;
+ int ele = hDecoder->fr_ch_ele;
+ int ch0 = cpe->channel;
+ int ch1 = cpe->paired_channel;
/* following case can happen when forceUpSampling == 1 */
if (hDecoder->sbr[ele] == NULL)
@@ -1221,9 +1307,9 @@ uint8_t reconstruct_channel_pair(NeAACDecHandle hDecoder, ic_stream *ics1, ic_st
}
if (cpe->ics1.window_sequence == EIGHT_SHORT_SEQUENCE)
- hDecoder->sbr[ele]->maxAACLine = 8*cpe->ics1.swb_offset[max(cpe->ics1.max_sfb-1, 0)];
+ hDecoder->sbr[ele]->maxAACLine = 8*min(cpe->ics1.swb_offset[max(cpe->ics1.max_sfb-1, 0)], cpe->ics1.swb_offset_max);
else
- hDecoder->sbr[ele]->maxAACLine = cpe->ics1.swb_offset[max(cpe->ics1.max_sfb-1, 0)];
+ hDecoder->sbr[ele]->maxAACLine = min(cpe->ics1.swb_offset[max(cpe->ics1.max_sfb-1, 0)], cpe->ics1.swb_offset_max);
retval = sbrDecodeCoupleFrame(hDecoder->sbr[ele],
hDecoder->time_out[ch0], hDecoder->time_out[ch1],
diff --git a/src/libfaad/specrec.h b/src/libfaad/specrec.h
index da174abe8..f58094cf4 100644
--- a/src/libfaad/specrec.h
+++ b/src/libfaad/specrec.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: specrec.h,v 1.7 2005/10/29 23:57:07 tmmm Exp $
+** $Id: specrec.h,v 1.32 2007/11/01 12:33:36 menno Exp $
**/
#ifndef __SPECREC_H__
diff --git a/src/libfaad/ssr.c b/src/libfaad/ssr.c
index 46517d0c8..368112407 100644
--- a/src/libfaad/ssr.c
+++ b/src/libfaad/ssr.c
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: ssr.c,v 1.6 2005/10/29 23:57:07 tmmm Exp $
+** $Id: ssr.c,v 1.19 2007/11/01 12:33:36 menno Exp $
**/
#include "common.h"
diff --git a/src/libfaad/ssr.h b/src/libfaad/ssr.h
index d1defdc45..7adcf2a11 100644
--- a/src/libfaad/ssr.h
+++ b/src/libfaad/ssr.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: ssr.h,v 1.6 2005/10/29 23:57:07 tmmm Exp $
+** $Id: ssr.h,v 1.19 2007/11/01 12:33:36 menno Exp $
**/
#ifndef __SSR_H__
diff --git a/src/libfaad/ssr_fb.c b/src/libfaad/ssr_fb.c
index fb62c90c6..a977c9411 100644
--- a/src/libfaad/ssr_fb.c
+++ b/src/libfaad/ssr_fb.c
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: ssr_fb.c,v 1.6 2005/10/29 23:57:07 tmmm Exp $
+** $Id: ssr_fb.c,v 1.17 2007/11/01 12:33:36 menno Exp $
**/
#include "common.h"
diff --git a/src/libfaad/ssr_fb.h b/src/libfaad/ssr_fb.h
index 739a4dfbb..3ae4eb04b 100644
--- a/src/libfaad/ssr_fb.h
+++ b/src/libfaad/ssr_fb.h
@@ -1,6 +1,6 @@
/*
-** FAAD - Freeware Advanced Audio Decoder
-** Copyright (C) 2002 M. Bakker
+** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
+** Copyright (C) 2003-2005 M. Bakker, Ahead Software AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -16,7 +16,16 @@
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
-** $Id: ssr_fb.h,v 1.5 2005/10/29 23:57:07 tmmm Exp $
+** Any non-GPL usage of this software or parts of this software is strictly
+** forbidden.
+**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
+** Commercial non-GPL licensing of this software is possible.
+** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+**
+** $Id: ssr_fb.h,v 1.16 2007/11/01 12:33:36 menno Exp $
**/
#ifndef __SSR_FB_H__
diff --git a/src/libfaad/ssr_ipqf.c b/src/libfaad/ssr_ipqf.c
index 3064285de..6963427c9 100644
--- a/src/libfaad/ssr_ipqf.c
+++ b/src/libfaad/ssr_ipqf.c
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: ssr_ipqf.c,v 1.6 2005/10/29 23:57:07 tmmm Exp $
+** $Id: ssr_ipqf.c,v 1.18 2007/11/01 12:33:39 menno Exp $
**/
#include "common.h"
diff --git a/src/libfaad/ssr_ipqf.h b/src/libfaad/ssr_ipqf.h
index 360db978b..47299219c 100644
--- a/src/libfaad/ssr_ipqf.h
+++ b/src/libfaad/ssr_ipqf.h
@@ -1,6 +1,6 @@
/*
-** FAAD - Freeware Advanced Audio Decoder
-** Copyright (C) 2002 M. Bakker
+** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
+** Copyright (C) 2003-2005 M. Bakker, Ahead Software AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -16,7 +16,16 @@
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
-** $Id: ssr_ipqf.h,v 1.5 2005/10/29 23:57:07 tmmm Exp $
+** Any non-GPL usage of this software or parts of this software is strictly
+** forbidden.
+**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
+** Commercial non-GPL licensing of this software is possible.
+** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+**
+** $Id: ssr_ipqf.h,v 1.17 2007/11/01 12:33:39 menno Exp $
**/
#ifndef __SSR_IPQF_H__
diff --git a/src/libfaad/ssr_win.h b/src/libfaad/ssr_win.h
index ddbb3086e..64b0f98bf 100644
--- a/src/libfaad/ssr_win.h
+++ b/src/libfaad/ssr_win.h
@@ -1,6 +1,6 @@
/*
-** FAAD - Freeware Advanced Audio Decoder
-** Copyright (C) 2002 M. Bakker
+** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
+** Copyright (C) 2003-2005 M. Bakker, Ahead Software AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -16,7 +16,16 @@
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
-** $Id: ssr_win.h,v 1.5 2005/10/29 23:57:07 tmmm Exp $
+** Any non-GPL usage of this software or parts of this software is strictly
+** forbidden.
+**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
+** Commercial non-GPL licensing of this software is possible.
+** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+**
+** $Id: ssr_win.h,v 1.16 2007/11/01 12:33:39 menno Exp $
**/
#ifndef __SSR_WIN_H__
diff --git a/src/libfaad/structs.h b/src/libfaad/structs.h
index db6361a5c..5d957c59e 100644
--- a/src/libfaad/structs.h
+++ b/src/libfaad/structs.h
@@ -1,28 +1,31 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
+**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
-**
+**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
-**
+**
** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
+** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: structs.h,v 1.7 2005/10/29 23:57:07 tmmm Exp $
+** $Id: structs.h,v 1.46 2007/11/01 12:33:40 menno Exp $
**/
#ifndef __STRUCTS_H__
@@ -247,6 +250,7 @@ typedef struct
uint8_t scale_factor_grouping;
uint16_t sect_sfb_offset[8][15*8];
uint16_t swb_offset[52];
+ uint16_t swb_offset_max;
uint8_t sect_cb[8][15*8];
uint16_t sect_start[8][15*8];
@@ -261,6 +265,7 @@ typedef struct
uint8_t ms_used[MAX_WINDOW_GROUPS][MAX_SFB];
uint8_t noise_used;
+ uint8_t is_used;
uint8_t pulse_data_present;
uint8_t tns_data_present;
@@ -447,6 +452,14 @@ typedef struct
int16_t *lt_pred_stat[MAX_CHANNELS];
#endif
+#ifdef DRM
+ uint8_t error_state;
+#endif
+
+ /* RNG states */
+ uint32_t __r1;
+ uint32_t __r2;
+
/* Program Config Element */
uint8_t pce_set;
program_config pce;
@@ -463,6 +476,7 @@ typedef struct
int64_t scalefac_cycles;
int64_t requant_cycles;
#endif
+ const unsigned char *cmes;
} NeAACDecStruct, *NeAACDecHandle;
diff --git a/src/libfaad/syntax.c b/src/libfaad/syntax.c
index 6dc9fc57d..373582b7f 100644
--- a/src/libfaad/syntax.c
+++ b/src/libfaad/syntax.c
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: syntax.c,v 1.10 2006/09/26 17:48:24 dgp85 Exp $
+** $Id: syntax.c,v 1.89 2007/11/01 12:33:40 menno Exp $
**/
/*
@@ -93,9 +96,11 @@ static void adts_variable_header(adts_header *adts, bitfile *ld);
static void adts_error_check(adts_header *adts, bitfile *ld);
static uint8_t dynamic_range_info(bitfile *ld, drc_info *drc);
static uint8_t excluded_channels(bitfile *ld, drc_info *drc);
-#ifdef SCALABLE_DEC
-static int8_t aac_scalable_main_header(NeAACDecHandle hDecoder, ic_stream *ics1, ic_stream *ics2,
- bitfile *ld, uint8_t this_layer_stereo);
+static uint8_t side_info(NeAACDecHandle hDecoder, element *ele,
+ bitfile *ld, ic_stream *ics, uint8_t scal_flag);
+#ifdef DRM
+static int8_t DRM_aac_scalable_main_header(NeAACDecHandle hDecoder, ic_stream *ics1, ic_stream *ics2,
+ bitfile *ld, uint8_t this_layer_stereo);
#endif
@@ -323,7 +328,7 @@ static void decode_sce_lfe(NeAACDecHandle hDecoder,
uint8_t channels = hDecoder->fr_channels;
uint8_t tag = 0;
- if (channels+1 >= MAX_CHANNELS)
+ if (channels+1 > MAX_CHANNELS)
{
hInfo->error = 12;
return;
@@ -413,6 +418,7 @@ void raw_data_block(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo,
bitfile *ld, program_config *pce, drc_info *drc)
{
uint8_t id_syn_ele;
+ uint8_t ele_this_frame = 0;
hDecoder->fr_channels = 0;
hDecoder->fr_ch_ele = 0;
@@ -429,36 +435,55 @@ void raw_data_block(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo,
{
switch (id_syn_ele) {
case ID_SCE:
+ ele_this_frame++;
if (hDecoder->first_syn_ele == 25) hDecoder->first_syn_ele = id_syn_ele;
decode_sce_lfe(hDecoder, hInfo, ld, id_syn_ele);
if (hInfo->error > 0)
return;
break;
case ID_CPE:
+ ele_this_frame++;
if (hDecoder->first_syn_ele == 25) hDecoder->first_syn_ele = id_syn_ele;
decode_cpe(hDecoder, hInfo, ld, id_syn_ele);
if (hInfo->error > 0)
return;
break;
case ID_LFE:
+#ifdef DRM
+ hInfo->error = 32;
+#else
+ ele_this_frame++;
hDecoder->has_lfe++;
decode_sce_lfe(hDecoder, hInfo, ld, id_syn_ele);
+#endif
if (hInfo->error > 0)
return;
break;
case ID_CCE: /* not implemented yet, but skip the bits */
+#ifdef DRM
+ hInfo->error = 32;
+#else
+ ele_this_frame++;
#ifdef COUPLING_DEC
hInfo->error = coupling_channel_element(hDecoder, ld);
#else
hInfo->error = 6;
#endif
+#endif
if (hInfo->error > 0)
return;
break;
case ID_DSE:
+ ele_this_frame++;
data_stream_element(hDecoder, ld);
break;
case ID_PCE:
+ if (ele_this_frame != 0)
+ {
+ hInfo->error = 31;
+ return;
+ }
+ ele_this_frame++;
/* 14496-4: 5.6.4.1.2.1.3: */
/* program_configuration_element()'s in access units shall be ignored */
program_config_element(pce, ld);
@@ -467,6 +492,7 @@ void raw_data_block(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo,
//hDecoder->pce_set = 1;
break;
case ID_FIL:
+ ele_this_frame++;
/* one sbr_info describes a channel_element not a channel! */
/* if we encounter SBR data here: error */
/* SBR data will be read directly in the SCE/LFE/CPE element */
@@ -577,6 +603,10 @@ static uint8_t single_lfe_channel_element(NeAACDecHandle hDecoder, bitfile *ld,
if (retval > 0)
return retval;
+ /* IS not allowed in single channel */
+ if (ics->is_used)
+ return 32;
+
#ifdef SBR_DEC
/* check if next bitstream element is a fill element */
/* if so, read it now so SBR decoding can be done in case of a file with SBR */
@@ -627,6 +657,11 @@ static uint8_t channel_pair_element(NeAACDecHandle hDecoder, bitfile *ld,
ics1->ms_mask_present = (uint8_t)faad_getbits(ld, 2
DEBUGVAR(1,41,"channel_pair_element(): ms_mask_present"));
+ if (ics1->ms_mask_present == 3)
+ {
+ /* bitstream error */
+ return 32;
+ }
if (ics1->ms_mask_present == 1)
{
uint8_t g, sfb;
@@ -730,14 +765,23 @@ static uint8_t ics_info(NeAACDecHandle hDecoder, ic_stream *ics, bitfile *ld,
uint8_t common_window)
{
uint8_t retval = 0;
+ uint8_t ics_reserved_bit;
- /* ics->ics_reserved_bit = */ faad_get1bit(ld
+ ics_reserved_bit = faad_get1bit(ld
DEBUGVAR(1,43,"ics_info(): ics_reserved_bit"));
+ if (ics_reserved_bit != 0)
+ return 32;
ics->window_sequence = (uint8_t)faad_getbits(ld, 2
DEBUGVAR(1,44,"ics_info(): window_sequence"));
ics->window_shape = faad_get1bit(ld
DEBUGVAR(1,45,"ics_info(): window_shape"));
+#ifdef LD_DEC
+ /* No block switching in LD */
+ if ((hDecoder->object_type == LD) && (ics->window_sequence != ONLY_LONG_SEQUENCE))
+ return 32;
+#endif
+
if (ics->window_sequence == EIGHT_SHORT_SEQUENCE)
{
ics->max_sfb = (uint8_t)faad_getbits(ld, 4
@@ -753,6 +797,7 @@ static uint8_t ics_info(NeAACDecHandle hDecoder, ic_stream *ics, bitfile *ld,
if ((retval = window_grouping_info(hDecoder, ics)) > 0)
return retval;
+
/* should be an error */
/* check the range of max_sfb */
if (ics->max_sfb > ics->num_swb)
@@ -922,6 +967,10 @@ static uint8_t coupling_channel_element(NeAACDecHandle hDecoder, bitfile *ld)
return result;
}
+ /* IS not allowed in single channel */
+ if (ics->is_used)
+ return 32;
+
for (c = 1; c < num_gain_element_lists; c++)
{
uint8_t cge;
@@ -1029,7 +1078,8 @@ static uint8_t fill_element(NeAACDecHandle hDecoder, bitfile *ld, drc_info *drc
hDecoder->sbr_present_flag = 1;
/* parse the SBR data */
- hDecoder->sbr[sbr_ele]->ret = sbr_extension_data(ld, hDecoder->sbr[sbr_ele], count);
+ hDecoder->sbr[sbr_ele]->ret = sbr_extension_data(ld, hDecoder->sbr[sbr_ele], count,
+ hDecoder->postSeekResetFlag);
#if 0
if (hDecoder->sbr[sbr_ele]->ret > 0)
@@ -1049,10 +1099,14 @@ static uint8_t fill_element(NeAACDecHandle hDecoder, bitfile *ld, drc_info *drc
#endif
} else {
#endif
+#ifndef DRM
while (count > 0)
{
count -= extension_payload(ld, drc, count);
}
+#else
+ return 30;
+#endif
#ifdef SBR_DEC
}
#endif
@@ -1157,10 +1211,10 @@ static void gain_control_data(bitfile *ld, ic_stream *ics)
}
#endif
-#ifdef SCALABLE_DEC
+#ifdef DRM
/* Table 4.4.13 ASME */
-void aac_scalable_main_element(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo,
- bitfile *ld, program_config *pce, drc_info *drc)
+void DRM_aac_scalable_main_element(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo,
+ bitfile *ld, program_config *pce, drc_info *drc)
{
uint8_t retval = 0;
uint8_t channels = hDecoder->fr_channels = 0;
@@ -1175,7 +1229,7 @@ void aac_scalable_main_element(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo
hDecoder->fr_ch_ele = 0;
- hInfo->error = aac_scalable_main_header(hDecoder, ics1, ics2, ld, this_layer_stereo);
+ hInfo->error = DRM_aac_scalable_main_header(hDecoder, ics1, ics2, ld, this_layer_stereo);
if (hInfo->error > 0)
return;
@@ -1189,22 +1243,77 @@ void aac_scalable_main_element(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo
hDecoder->element_id[0] = ID_SCE;
}
- for (ch = 0; ch < (this_layer_stereo ? 2 : 1); ch++)
+ if (this_layer_stereo)
{
- ic_stream *ics;
- if (ch == 0)
- {
- ics = ics1;
- spec_data = spec_data1;
- } else {
- ics = ics2;
- spec_data = spec_data2;
- }
+ cpe.channel = 0;
+ cpe.paired_channel = 1;
+ }
+
+
+ /* Stereo2 / Mono1 */
+ ics1->tns_data_present = faad_get1bit(ld);
- hInfo->error = individual_channel_stream(hDecoder, &cpe, ld, ics, 1, spec_data);
+#if defined(LTP_DEC)
+ ics1->ltp.data_present = faad_get1bit(ld);
+#elif defined (DRM)
+ if(faad_get1bit(ld)) {
+ hInfo->error = 26;
+ return;
+ }
+#else
+ faad_get1bit(ld);
+#endif
+
+ hInfo->error = side_info(hDecoder, &cpe, ld, ics1, 1);
+ if (hInfo->error > 0)
+ return;
+ if (this_layer_stereo)
+ {
+ /* Stereo3 */
+ ics2->tns_data_present = faad_get1bit(ld);
+#ifdef LTP_DEC
+ ics1->ltp.data_present =
+#endif
+ faad_get1bit(ld);
+ hInfo->error = side_info(hDecoder, &cpe, ld, ics2, 1);
if (hInfo->error > 0)
return;
}
+ /* Stereo4 / Mono2 */
+ if (ics1->tns_data_present)
+ tns_data(ics1, &(ics1->tns), ld);
+ if (this_layer_stereo)
+ {
+ /* Stereo5 */
+ if (ics2->tns_data_present)
+ tns_data(ics2, &(ics2->tns), ld);
+ }
+
+#ifdef DRM
+ /* CRC check */
+ if (hDecoder->object_type == DRM_ER_LC)
+ {
+ if ((hInfo->error = (uint8_t)faad_check_CRC(ld, (uint16_t)faad_get_processed_bits(ld) - 8)) > 0)
+ return;
+ }
+#endif
+
+ /* Stereo6 / Mono3 */
+ /* error resilient spectral data decoding */
+ if ((hInfo->error = reordered_spectral_data(hDecoder, ics1, ld, spec_data1)) > 0)
+ {
+ return;
+ }
+ if (this_layer_stereo)
+ {
+ /* Stereo7 */
+ /* error resilient spectral data decoding */
+ if ((hInfo->error = reordered_spectral_data(hDecoder, ics2, ld, spec_data2)) > 0)
+ {
+ return;
+ }
+ }
+
#ifdef DRM
#ifdef SBR_DEC
@@ -1244,6 +1353,7 @@ void aac_scalable_main_element(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo
/* Set SBR data */
/* consider 8 bits from AAC-CRC */
+ /* SBR buffer size is original buffer size minus AAC buffer size */
count = (uint16_t)bit2byte(buffer_size*8 - bitsconsumed);
faad_initbits(&ld_sbr, revbuffer, count);
@@ -1252,7 +1362,7 @@ void aac_scalable_main_element(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo
faad_getbits(&ld_sbr, 8); /* Skip 8-bit CRC */
- hDecoder->sbr[0]->ret = sbr_extension_data(&ld_sbr, hDecoder->sbr[0], count);
+ hDecoder->sbr[0]->ret = sbr_extension_data(&ld_sbr, hDecoder->sbr[0], count, hDecoder->postSeekResetFlag);
#if (defined(PS_DEC) || defined(DRM_PS))
if (hDecoder->sbr[0]->ps_used)
{
@@ -1261,6 +1371,11 @@ void aac_scalable_main_element(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo
}
#endif
+ if (ld_sbr.error)
+ {
+ hDecoder->sbr[0]->ret = 1;
+ }
+
/* check CRC */
/* no need to check it if there was already an error */
if (hDecoder->sbr[0]->ret == 0)
@@ -1269,7 +1384,7 @@ void aac_scalable_main_element(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo
/* SBR data was corrupted, disable it until the next header */
if (hDecoder->sbr[0]->ret != 0)
{
- hDecoder->sbr[0]->header_count = 0;
+ hDecoder->sbr[0]->header_count = 0;
}
faad_endbits(&ld_sbr);
@@ -1308,15 +1423,18 @@ void aac_scalable_main_element(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo
}
/* Table 4.4.15 */
-static int8_t aac_scalable_main_header(NeAACDecHandle hDecoder, ic_stream *ics1, ic_stream *ics2,
- bitfile *ld, uint8_t this_layer_stereo)
+static int8_t DRM_aac_scalable_main_header(NeAACDecHandle hDecoder, ic_stream *ics1, ic_stream *ics2,
+ bitfile *ld, uint8_t this_layer_stereo)
{
uint8_t retval = 0;
uint8_t ch;
ic_stream *ics;
+ uint8_t ics_reserved_bit;
- /* ics1->ics_reserved_bit = */ faad_get1bit(ld
+ ics_reserved_bit = faad_get1bit(ld
DEBUGVAR(1,300,"aac_scalable_main_header(): ics_reserved_bits"));
+ if (ics_reserved_bit != 0)
+ return 32;
ics1->window_sequence = (uint8_t)faad_getbits(ld, 2
DEBUGVAR(1,301,"aac_scalable_main_header(): window_sequence"));
ics1->window_shape = faad_get1bit(ld
@@ -1346,6 +1464,11 @@ static int8_t aac_scalable_main_header(NeAACDecHandle hDecoder, ic_stream *ics1,
{
ics1->ms_mask_present = (uint8_t)faad_getbits(ld, 2
DEBUGVAR(1,306,"aac_scalable_main_header(): ms_mask_present"));
+ if (ics1->ms_mask_present == 3)
+ {
+ /* bitstream error */
+ return 32;
+ }
if (ics1->ms_mask_present == 1)
{
uint8_t g, sfb;
@@ -1364,70 +1487,12 @@ static int8_t aac_scalable_main_header(NeAACDecHandle hDecoder, ic_stream *ics1,
ics1->ms_mask_present = 0;
}
- if (0)
- {
- faad_get1bit(ld
- DEBUGVAR(1,308,"aac_scalable_main_header(): tns_channel_mono_layer"));
- }
-
- for (ch = 0; ch < (this_layer_stereo ? 2 : 1); ch++)
- {
- if (ch == 0)
- ics = ics1;
- else
- ics = ics2;
-
- if ( 1 /*!tvq_layer_pesent || (tns_aac_tvq_en[ch] == 1)*/)
- {
- if ((ics->tns_data_present = faad_get1bit(ld
- DEBUGVAR(1,309,"aac_scalable_main_header(): tns_data_present"))) & 1)
- {
-#ifdef DRM
- /* different order of data units in DRM */
- if (hDecoder->object_type != DRM_ER_LC)
-#endif
- {
- tns_data(ics, &(ics->tns), ld);
- }
- }
- }
-#if 0
- if (0 /*core_flag || tvq_layer_pesent*/)
- {
- if ((ch==0) || ((ch==1) && (core_stereo || tvq_stereo))
- diff_control_data();
- if (mono_stereo_flag)
- diff_control_data_lr();
- } else {
-#endif
- if ((
-#ifdef LTP_DEC
- ics->ltp.data_present =
-#endif
- faad_get1bit(ld DEBUGVAR(1,310,"aac_scalable_main_header(): ltp.data_present"))) & 1)
- {
-#ifdef LTP_DEC
- if ((retval = ltp_data(hDecoder, ics, &(ics->ltp), ld)) > 0)
- {
- return retval;
- }
-#else
- return 26;
-#endif
- }
-#if 0
- }
-#endif
- }
-
return 0;
}
#endif
-/* Table 4.4.24 */
-static uint8_t individual_channel_stream(NeAACDecHandle hDecoder, element *ele,
- bitfile *ld, ic_stream *ics, uint8_t scal_flag,
- int16_t *spec_data)
+static uint8_t side_info(NeAACDecHandle hDecoder, element *ele,
+ bitfile *ld, ic_stream *ics, uint8_t scal_flag)
{
uint8_t result;
@@ -1513,6 +1578,21 @@ static uint8_t individual_channel_stream(NeAACDecHandle hDecoder, element *ele,
if ((result = rvlc_decode_scale_factors(ics, ld)) > 0)
return result;
}
+#endif
+
+ return 0;
+}
+
+/* Table 4.4.24 */
+static uint8_t individual_channel_stream(NeAACDecHandle hDecoder, element *ele,
+ bitfile *ld, ic_stream *ics, uint8_t scal_flag,
+ int16_t *spec_data)
+{
+ uint8_t result;
+
+ result = side_info(hDecoder, ele, ld, ics, scal_flag);
+ if (result > 0)
+ return result;
if (hDecoder->object_type >= ER_OBJECT_START)
{
@@ -1523,10 +1603,13 @@ static uint8_t individual_channel_stream(NeAACDecHandle hDecoder, element *ele,
#ifdef DRM
/* CRC check */
if (hDecoder->object_type == DRM_ER_LC)
+ {
if ((result = (uint8_t)faad_check_CRC(ld, (uint16_t)faad_get_processed_bits(ld) - 8)) > 0)
return result;
+ }
#endif
+#ifdef ERROR_RESILIENCE
if (hDecoder->aacSpectralDataResilienceFlag)
{
/* error resilient spectral data decoding */
@@ -1594,7 +1677,7 @@ static uint8_t section_data(NeAACDecHandle hDecoder, ic_stream *ics, bitfile *ld
/* if "faad_getbits" detects error and returns "0", "k" is never
incremented and we cannot leave the while loop */
- if ((ld->error != 0) || (ld->no_more_reading))
+ if (ld->error != 0)
return 14;
#ifdef ERROR_RESILIENCE
@@ -1605,12 +1688,23 @@ static uint8_t section_data(NeAACDecHandle hDecoder, ic_stream *ics, bitfile *ld
ics->sect_cb[g][i] = (uint8_t)faad_getbits(ld, sect_cb_bits
DEBUGVAR(1,71,"section_data(): sect_cb"));
+ if (ics->sect_cb[g][i] == 12)
+ return 32;
+
#if 0
printf("%d\n", ics->sect_cb[g][i]);
#endif
+#ifndef DRM
if (ics->sect_cb[g][i] == NOISE_HCB)
ics->noise_used = 1;
+#else
+ /* PNS not allowed in DRM */
+ if (ics->sect_cb[g][i] == NOISE_HCB)
+ return 29;
+#endif
+ if (ics->sect_cb[g][i] == INTENSITY_HCB2 || ics->sect_cb[g][i] == INTENSITY_HCB)
+ ics->is_used = 1;
#ifdef ERROR_RESILIENCE
if (hDecoder->aacSectionDataResilienceFlag)
@@ -1651,10 +1745,18 @@ static uint8_t section_data(NeAACDecHandle hDecoder, ic_stream *ics, bitfile *ld
printf("%d\n", ics->sect_end[g][i]);
#endif
- if (k + sect_len >= 8*15)
- return 15;
- if (i >= 8*15)
- return 15;
+ if (ics->window_sequence == EIGHT_SHORT_SEQUENCE)
+ {
+ if (k + sect_len > 8*15)
+ return 15;
+ if (i >= 8*15)
+ return 15;
+ } else {
+ if (k + sect_len > MAX_SFB)
+ return 15;
+ if (i >= MAX_SFB)
+ return 15;
+ }
for (sfb = k; sfb < k + sect_len; sfb++)
{
@@ -1675,6 +1777,13 @@ static uint8_t section_data(NeAACDecHandle hDecoder, ic_stream *ics, bitfile *ld
i++;
}
ics->num_sec[g] = i;
+
+ /* the sum of all sect_len_incr elements for a given window
+ * group shall equal max_sfb */
+ if (k != ics->max_sfb)
+ {
+ return 32;
+ }
#if 0
printf("%d\n", ics->num_sec[g]);
#endif
@@ -1735,6 +1844,7 @@ static uint8_t decode_scale_factors(ic_stream *ics, bitfile *ld)
break;
case NOISE_HCB: /* noise books */
+#ifndef DRM
/* decode noise energy */
if (noise_pcm_flag)
{
@@ -1750,6 +1860,10 @@ static uint8_t decode_scale_factors(ic_stream *ics, bitfile *ld)
#ifdef SF_PRINT
printf("%d\n", ics->scale_factors[g][sfb]);
#endif
+#else
+ /* PNS not allowed in DRM */
+ return 29;
+#endif
break;
default: /* spectral books */
@@ -2048,11 +2162,11 @@ static uint16_t extension_payload(bitfile *ld, drc_info *drc, uint16_t count)
return n;
case EXT_FILL_DATA:
/* fill_nibble = */ faad_getbits(ld, 4
- DEBUGVAR(1,136,"extension_payload(): fill_nibble")); /* must be '0000' */
+ DEBUGVAR(1,136,"extension_payload(): fill_nibble")); /* must be ‘0000’ */
for (i = 0; i < count-1; i++)
{
/* fill_byte[i] = */ faad_getbits(ld, 8
- DEBUGVAR(1,88,"extension_payload(): fill_byte")); /* must be '10100101' */
+ DEBUGVAR(1,88,"extension_payload(): fill_byte")); /* must be ‘10100101’ */
}
return count;
case EXT_DATA_ELEMENT:
@@ -2127,7 +2241,7 @@ static uint8_t dynamic_range_info(bitfile *ld, drc_info *drc)
n++;
drc->num_bands += band_incr;
- for (i = 0; i < drc->num_bands; i++);
+ for (i = 0; i < drc->num_bands; i++)
{
drc->band_top[i] = (uint8_t)faad_getbits(ld, 8
DEBUGVAR(1,97,"dynamic_range_info(): band_top"));
diff --git a/src/libfaad/syntax.h b/src/libfaad/syntax.h
index a047dd644..123c4573f 100644
--- a/src/libfaad/syntax.h
+++ b/src/libfaad/syntax.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: syntax.h,v 1.10 2005/10/29 23:57:07 tmmm Exp $
+** $Id: syntax.h,v 1.58 2007/11/01 12:33:40 menno Exp $
**/
#ifndef __SYNTAX_H__
@@ -114,9 +117,10 @@ void raw_data_block(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo,
bitfile *ld, program_config *pce, drc_info *drc);
uint8_t reordered_spectral_data(NeAACDecHandle hDecoder, ic_stream *ics, bitfile *ld,
int16_t *spectral_data);
-void aac_scalable_main_element(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo,
- bitfile *ld, program_config *pce, drc_info *drc);
-
+#ifdef DRM
+void DRM_aac_scalable_main_element(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo,
+ bitfile *ld, program_config *pce, drc_info *drc);
+#endif
#ifdef __cplusplus
}
diff --git a/src/libfaad/tns.c b/src/libfaad/tns.c
index bb4db731a..611865204 100644
--- a/src/libfaad/tns.c
+++ b/src/libfaad/tns.c
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: tns.c,v 1.8 2005/10/29 23:57:07 tmmm Exp $
+** $Id: tns.c,v 1.40 2007/11/01 12:33:40 menno Exp $
**/
#include "common.h"
@@ -106,11 +109,11 @@ void tns_decode_frame(ic_stream *ics, tns_info *tns, uint8_t sr_index,
start = min(bottom, max_tns_sfb(sr_index, object_type, (ics->window_sequence == EIGHT_SHORT_SEQUENCE)));
start = min(start, ics->max_sfb);
- start = ics->swb_offset[start];
+ start = min(ics->swb_offset[start], ics->swb_offset_max);
end = min(top, max_tns_sfb(sr_index, object_type, (ics->window_sequence == EIGHT_SHORT_SEQUENCE)));
end = min(end, ics->max_sfb);
- end = ics->swb_offset[end];
+ end = min(ics->swb_offset[end], ics->swb_offset_max);
size = end - start;
if (size <= 0)
@@ -160,11 +163,11 @@ void tns_encode_frame(ic_stream *ics, tns_info *tns, uint8_t sr_index,
start = min(bottom, max_tns_sfb(sr_index, object_type, (ics->window_sequence == EIGHT_SHORT_SEQUENCE)));
start = min(start, ics->max_sfb);
- start = ics->swb_offset[start];
+ start = min(ics->swb_offset[start], ics->swb_offset_max);
end = min(top, max_tns_sfb(sr_index, object_type, (ics->window_sequence == EIGHT_SHORT_SEQUENCE)));
end = min(end, ics->max_sfb);
- end = ics->swb_offset[end];
+ end = min(ics->swb_offset[end], ics->swb_offset_max);
size = end - start;
if (size <= 0)
@@ -292,7 +295,7 @@ static void tns_ma_filter(real_t *spectrum, uint16_t size, int8_t inc, real_t *l
y = *spectrum;
for (j = 0; j < order; j++)
- y += MUL_C(state[j], lpc[j+1]);
+ y += MUL_C(state[state_index+j], lpc[j+1]);
/* double ringbuffer state */
state_index--;
diff --git a/src/libfaad/tns.h b/src/libfaad/tns.h
index fc77894d8..8848c3f2d 100644
--- a/src/libfaad/tns.h
+++ b/src/libfaad/tns.h
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@@ -19,10 +19,13 @@
** Any non-GPL usage of this software or parts of this software is strictly
** forbidden.
**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
**
-** $Id: tns.h,v 1.8 2005/10/29 23:57:07 tmmm Exp $
+** $Id: tns.h,v 1.23 2007/11/01 12:33:41 menno Exp $
**/
#ifndef __TNS_H__
diff --git a/src/libfaad/xine_faad_decoder.c b/src/libfaad/xine_faad_decoder.c
index 934140a32..b90bc701f 100644
--- a/src/libfaad/xine_faad_decoder.c
+++ b/src/libfaad/xine_faad_decoder.c
@@ -18,6 +18,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
@@ -35,10 +39,14 @@
#include "audio_out.h"
#include "buffer.h"
#include "xineutils.h"
+#ifdef HAVE_FAAD_H
+#include <faad.h>
+#else
#include "common.h"
#include "structs.h"
#include "decoder.h"
#include "syntax.h"
+#endif
#define FAAD_MIN_STREAMSIZE 768 /* 6144 bits/channel */
@@ -271,7 +279,32 @@ static void faad_decode_audio ( faad_decoder_t *this, int end_frame ) {
lprintf("decoded %d/%d output %ld\n",
used, this->size, this->faac_finfo.samples );
-
+
+ /* Performing necessary channel reordering because aac uses a different
+ * layout than alsa:
+ *
+ * aac 5.1 channel layout: c l r ls rs lfe
+ * alsa 5.1 channel layout: l r ls rs c lfe
+ *
+ * Reordering is only necessary for 5.0 and above. Currently only 5.0
+ * and 5.1 is being taken care of, the rest will stay in the wrong order
+ * for now.
+ *
+ * WARNING: the following needs a output format of 16 bits per sample.
+ * TODO: - reorder while copying (in the while() loop) and optimizing
+ */
+ if(this->num_channels == 5 || this->num_channels == 6)
+ {
+ int i = 0;
+ uint16_t* buf = (uint16_t*)(sample_buffer);
+
+ for(; i < this->faac_finfo.samples; i += this->num_channels) {
+ uint16_t center = buf[i];
+ *((uint64_t*)(buf + i)) = *((uint64_t*)(buf + i + 1));
+ buf[i + 4] = center;
+ }
+ }
+
while( decoded ) {
audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out);
@@ -320,7 +353,7 @@ static void faad_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
if( !this->faac_dec && (buf->decoder_flags & BUF_FLAG_SPECIAL) &&
buf->decoder_info[1] == BUF_SPECIAL_DECODER_CONFIG ) {
- this->dec_config = xine_xmalloc(buf->decoder_info[2]);
+ this->dec_config = malloc(buf->decoder_info[2]);
this->dec_config_size = buf->decoder_info[2];
memcpy(this->dec_config, buf->decoder_info_ptr[2], buf->decoder_info[2]);
@@ -341,7 +374,7 @@ static void faad_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
xine_waveformatex *wavex = (xine_waveformatex *) buf->content;
if( wavex->cbSize > 0 ) {
- this->dec_config = xine_xmalloc(wavex->cbSize);
+ this->dec_config = malloc(wavex->cbSize);
this->dec_config_size = wavex->cbSize;
memcpy(this->dec_config, buf->content + sizeof(xine_waveformatex),
wavex->cbSize);
@@ -417,7 +450,7 @@ static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stre
faad_decoder_t *this ;
- this = (faad_decoder_t *) xine_xmalloc (sizeof (faad_decoder_t));
+ this = calloc(1, sizeof (faad_decoder_t));
this->audio_decoder.decode_data = faad_decode_data;
this->audio_decoder.reset = faad_reset;
@@ -458,7 +491,7 @@ static void *init_plugin (xine_t *xine, void *data) {
faad_class_t *this ;
- this = (faad_class_t *) xine_xmalloc (sizeof (faad_class_t));
+ this = calloc(1, sizeof (faad_class_t));
this->decoder_class.open_plugin = open_plugin;
this->decoder_class.get_identifier = get_identifier;
diff --git a/src/libffmpeg/Makefile.am b/src/libffmpeg/Makefile.am
index 61acdd0d1..9af34df26 100644
--- a/src/libffmpeg/Makefile.am
+++ b/src/libffmpeg/Makefile.am
@@ -1,45 +1,12 @@
include $(top_srcdir)/misc/Makefile.common
+DEFAULT_INCLUDES = -I.
+
if HAVE_FFMPEG
-AM_CFLAGS = $(FFMPEG_CFLAGS) $(FFMPEG_POSTPROC_CFLAGS)
-link_ffmpeg = $(FFMPEG_LIBS) $(FFMPEG_POSTPROC_LIBS)
else
-ff_cppflags = -I$(top_srcdir)/src/libffmpeg/libavutil
-link_ffmpeg = \
- $(top_builddir)/src/libffmpeg/libavcodec/libavcodec.la \
- $(top_builddir)/src/libffmpeg/libavutil/libavutil.la \
- $(top_builddir)/src/libffmpeg/libavcodec/libpostproc/libpostprocess.la
SUBDIRS = libavcodec libavutil
endif
-# ffmpeg_config.h is generated by configure
-DISTCLEANFILES = ffmpeg_config.h
-
-# this must always be included, even if the current machine has no DXR3...
-EXTRA_DIST = ffmpeg_encoder.c diff_to_ffmpeg_cvs.txt
+EXTRA_DIST = diff_to_ffmpeg_cvs.txt
INTERNAL_DOCS = diff_to_ffmpeg_cvs.txt
-
-xineplug_LTLIBRARIES = xineplug_decode_ff.la xineplug_decode_dvaudio.la
-
-if HAVE_DXR3
-AM_CPPFLAGS = -I$(top_srcdir)/src/dxr3 $(X_CFLAGS) $(ff_cppflags) \
- $(ZLIB_CPPFLAGS)
-xineplug_decode_ff_la_SOURCES = ffmpeg_decoder.c ff_audio_decoder.c ff_video_decoder.c \
- ffmpeg_encoder.c ff_mpeg_parser.c ffmpeg_decoder.h \
- ff_mpeg_parser.h
-else
-AM_CPPFLAGS = $(ff_cppflags) $(ZLIB_CPPFLAGS)
-xineplug_decode_ff_la_SOURCES = ffmpeg_decoder.c ff_audio_decoder.c ff_video_decoder.c \
- ff_mpeg_parser.c ffmpeg_decoder.h ff_mpeg_parser.h
-endif
-
-xineplug_decode_ff_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS)
-xineplug_decode_ff_la_LDFLAGS = $(xineplug_ldflags) $(IMPURE_TEXT_LDFLAGS)
-xineplug_decode_ff_la_LIBADD = $(XINE_LIB) $(MLIB_LIBS) -lm $(ZLIB_LIBS) \
- $(link_ffmpeg) $(PTHREAD_LIBS) $(LTLIBINTL)
-
-xineplug_decode_dvaudio_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS)
-xineplug_decode_dvaudio_la_LDFLAGS = $(xineplug_ldflags)
-xineplug_decode_dvaudio_la_SOURCES = ff_dvaudio_decoder.c
-xineplug_decode_dvaudio_la_LIBADD = $(XINE_LIB) $(LTLIBINTL)
diff --git a/src/libffmpeg/libavcodec/i386/Makefile.am b/src/libffmpeg/libavcodec/i386/Makefile.am
index b9d33c3a7..039c50d61 100644
--- a/src/libffmpeg/libavcodec/i386/Makefile.am
+++ b/src/libffmpeg/libavcodec/i386/Makefile.am
@@ -10,6 +10,9 @@ AM_CPPFLAGS = $(LIBFFMPEG_CPPFLAGS) -I$(top_srcdir)/src/libffmpeg/libavutil -I$(
# Avoid "can't find register" failures with -O1 and higher
dsputil_mmx.o dsputil_mmx.lo: CFLAGS=$(shell echo @CFLAGS@ | sed -e 's/-funroll-loops//g; s/$$/ -Os/')
+if ARCH_X86_32
+dsputil_mmx.o dsputil_mmx.lo: CFLAGS+=-prefer-non-pic
+endif
# Avoid errors on (at least) amd64 with -O0
fdct_mmx.o fdct_mmx.lo: CFLAGS=`echo @CFLAGS@ | sed -e 's/^/-Os /; s/-O0\?\s/-Os /g'`
diff --git a/src/libmad/Makefile.am b/src/libmad/Makefile.am
index c879645c5..56339cc72 100644
--- a/src/libmad/Makefile.am
+++ b/src/libmad/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
AM_CFLAGS = -DOPT_SPEED
diff --git a/src/libmad/bit.c b/src/libmad/bit.c
index 8d9571e8f..cd0fe4904 100644
--- a/src/libmad/bit.c
+++ b/src/libmad/bit.c
@@ -27,7 +27,8 @@
# ifdef HAVE_LIMITS_H
# include <limits.h>
-# else
+# endif
+# ifndef CHAR_BIT
# define CHAR_BIT 8
# endif
diff --git a/src/libmad/layer12.c b/src/libmad/layer12.c
index 25fd04d70..76def1189 100644
--- a/src/libmad/layer12.c
+++ b/src/libmad/layer12.c
@@ -27,7 +27,8 @@
# ifdef HAVE_LIMITS_H
# include <limits.h>
-# else
+# endif
+#ifndef CHAR_BIT
# define CHAR_BIT 8
# endif
diff --git a/src/libmad/layer3.c b/src/libmad/layer3.c
index c5d46e8d1..899102e0d 100644
--- a/src/libmad/layer3.c
+++ b/src/libmad/layer3.c
@@ -34,7 +34,8 @@
# ifdef HAVE_LIMITS_H
# include <limits.h>
-# else
+#endif
+# ifndef CHAR_BIT
# define CHAR_BIT 8
# endif
diff --git a/src/libmad/xine_mad_decoder.c b/src/libmad/xine_mad_decoder.c
index bb4ba1f7a..cb8c52831 100644
--- a/src/libmad/xine_mad_decoder.c
+++ b/src/libmad/xine_mad_decoder.c
@@ -22,7 +22,7 @@
#include <stdlib.h>
#include <string.h>
-#include <config.h>
+#include "config.h"
#ifdef HAVE_MAD_H
#include <mad.h>
@@ -48,6 +48,20 @@
#define INPUT_BUF_SIZE 16384
+/* According to Rob Leslie (libmad author) :
+ * The absolute theoretical maximum frame size is 2881 bytes: MPEG 2.5 Layer II,
+ * 8000 Hz @ 160 kbps, with a padding slot. (Such a frame is unlikely, but it was
+ * a useful exercise to compute all possible frame sizes.) Add to this an 8 byte
+ * MAD_BUFFER_GUARD, and the minimum buffer size you should be streaming to
+ * libmad in the general case is 2889 bytes.
+
+ * Theoretical frame sizes for Layer III range from 24 to 1441 bytes, but there
+ * is a "soft" limit imposed by the standard of 960 bytes. Nonetheless MAD can
+ * decode frames of any size as long as they fit entirely in the buffer you pass,
+ * not including the MAD_BUFFER_GUARD bytes.
+ */
+#define MAD_MIN_SIZE 2889
+
typedef struct {
audio_decoder_class_t decoder_class;
} mad_class_t;
@@ -101,7 +115,7 @@ static void mad_reset (audio_decoder_t *this_gen) {
static void mad_discontinuity (audio_decoder_t *this_gen) {
mad_decoder_t *this = (mad_decoder_t *) this_gen;
-
+
this->pts = 0;
}
@@ -141,16 +155,17 @@ static int head_check(mad_decoder_t *this) {
static void mad_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
mad_decoder_t *this = (mad_decoder_t *) this_gen;
+ int bytes_in_buffer_at_pts;
+
+ lprintf ("decode data, size: %d, decoder_flags: %d\n", buf->size, buf->decoder_flags);
- lprintf ("decode data, decoder_flags: 0x%08X\n", buf->decoder_flags);
-
if (buf->size>(INPUT_BUF_SIZE-this->bytes_in_buffer)) {
xprintf (this->xstream->xine, XINE_VERBOSITY_DEBUG,
"libmad: ALERT input buffer too small (%d bytes, %d avail)!\n",
buf->size, INPUT_BUF_SIZE-this->bytes_in_buffer);
buf->size = INPUT_BUF_SIZE-this->bytes_in_buffer;
}
-
+
if ((buf->decoder_flags & BUF_FLAG_HEADER) == 0) {
/* reset decoder on leaving preview mode */
@@ -162,6 +177,8 @@ static void mad_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
this->preview_mode = 1;
}
+ bytes_in_buffer_at_pts = this->bytes_in_buffer;
+
xine_fast_memcpy (&this->buffer[this->bytes_in_buffer],
buf->content, buf->size);
this->bytes_in_buffer += buf->size;
@@ -173,6 +190,9 @@ static void mad_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
mad_stream_buffer (&this->stream, this->buffer,
this->bytes_in_buffer);
+ if (this->bytes_in_buffer < MAD_MIN_SIZE)
+ return;
+
if (!this->needs_more_data) {
this->pts = buf->pts;
if (buf->decoder_flags & BUF_FLAG_AUDIO_PADDING) {
@@ -206,6 +226,7 @@ static void mad_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
return;
default:
+ lprintf ("error 0x%04X, mad_stream_buffer %d bytes\n", this->stream.error, this->bytes_in_buffer);
mad_stream_buffer (&this->stream, this->buffer,
this->bytes_in_buffer);
}
@@ -266,13 +287,14 @@ static void mad_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
mad_synth_frame (&this->synth, &this->frame);
if ( (buf->decoder_flags & BUF_FLAG_PREVIEW) == 0 ) {
-
+
unsigned int nchannels, nsamples;
mad_fixed_t const *left_ch, *right_ch;
struct mad_pcm *pcm = &this->synth.pcm;
audio_buffer_t *audio_buffer;
uint16_t *output;
-
+ int bitrate;
+ int pts_offset;
audio_buffer = this->xstream->audio_out->get_buffer (this->xstream->audio_out);
output = audio_buffer->mem;
@@ -281,7 +303,7 @@ static void mad_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
nsamples = pcm->length;
left_ch = pcm->samples[0];
right_ch = pcm->samples[1];
-
+
/* padding */
if (this->start_padding || this->end_padding) {
/* check padding validity */
@@ -298,7 +320,7 @@ static void mad_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
}
audio_buffer->num_frames = nsamples;
audio_buffer->vpts = this->pts;
-
+
while (nsamples--) {
/* output sample(s) in 16-bit signed little-endian PCM */
@@ -309,8 +331,24 @@ static void mad_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
}
+ audio_buffer->num_frames = pcm->length;
+
+ /* pts computing */
+ if (this->frame.header.bitrate > 0) {
+ bitrate = this->frame.header.bitrate;
+ } else {
+ bitrate = _x_stream_info_get(this->xstream, XINE_STREAM_INFO_AUDIO_BITRATE);
+ lprintf("offset %d bps\n", bitrate);
+ }
+ audio_buffer->vpts = buf->pts;
+ if (audio_buffer->vpts && (bitrate > 0)) {
+ pts_offset = (bytes_in_buffer_at_pts * 8 * 90) / (bitrate / 1000);
+ lprintf("pts: %"PRId64", offset: %d pts, %d bytes\n", buf->pts, pts_offset, bytes_in_buffer_at_pts);
+ if (audio_buffer->vpts < pts_offset)
+ pts_offset = audio_buffer->vpts;
+ audio_buffer->vpts -= pts_offset;
+ }
- lprintf ("audio_out->put_buffer, samples=%d, pts=%"PRId64"\n", audio_buffer->num_frames, audio_buffer->vpts);
this->xstream->audio_out->put_buffer (this->xstream->audio_out, audio_buffer, this->xstream);
this->pts = buf->pts;
@@ -351,7 +389,7 @@ static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stre
mad_decoder_t *this ;
- this = (mad_decoder_t *) xine_xmalloc (sizeof (mad_decoder_t));
+ this = (mad_decoder_t *) calloc(1, sizeof(mad_decoder_t));
this->audio_decoder.decode_data = mad_decode_data;
this->audio_decoder.reset = mad_reset;
@@ -395,7 +433,7 @@ static void *init_plugin (xine_t *xine, void *data) {
mad_class_t *this;
- this = (mad_class_t *) xine_xmalloc (sizeof (mad_class_t));
+ this = (mad_class_t *) calloc(1, sizeof(mad_class_t));
this->decoder_class.open_plugin = open_plugin;
this->decoder_class.get_identifier = get_identifier;
@@ -411,7 +449,7 @@ static uint32_t audio_types[] = {
static const decoder_info_t dec_info_audio = {
audio_types, /* supported types */
- 7 /* priority */
+ 8 /* priority */
};
const plugin_info_t xine_plugin_info[] EXPORTED = {
diff --git a/src/libmpeg2/Makefile.am b/src/libmpeg2/Makefile.am
index 9895aa5d7..849e56363 100644
--- a/src/libmpeg2/Makefile.am
+++ b/src/libmpeg2/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
xineplug_LTLIBRARIES = xineplug_decode_mpeg2.la
@@ -22,7 +23,7 @@ xineplug_decode_mpeg2_la_SOURCES = \
xine_mpeg2_decoder.c \
libmpeg2_accel.c
-xineplug_decode_mpeg2_la_LIBADD = $(XINE_LIB) $(MLIB_LIBS) -lm
+xineplug_decode_mpeg2_la_LIBADD = $(XINE_LIB) $(MLIB_LIBS) $(LTLIBINTL) -lm
xineplug_decode_mpeg2_la_CFLAGS = $(VISIBILITY_FLAG) $(LIBMPEG2_CFLAGS)
xineplug_decode_mpeg2_la_LDFLAGS = $(xineplug_ldflags)
diff --git a/src/libmpeg2/decode.c b/src/libmpeg2/decode.c
index 58f34ccbc..c66b18691 100644
--- a/src/libmpeg2/decode.c
+++ b/src/libmpeg2/decode.c
@@ -461,9 +461,10 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
break;
case 0xb7: /* sequence end code */
-#ifdef LOG_PAN_SCAN
- printf ("libmpeg2: sequence end code not handled\n");
-#endif
+ mpeg2_flush(mpeg2dec);
+ mpeg2dec->is_sequence_needed = 1;
+ break;
+
case 0xb8: /* group of pictures start code */
if (mpeg2_header_group_of_pictures (picture, buffer)) {
printf ("libmpeg2: bad group of pictures\n");
diff --git a/src/libmpeg2/motion_comp.c b/src/libmpeg2/motion_comp.c
index 8779c1296..f8faa3ee5 100644
--- a/src/libmpeg2/motion_comp.c
+++ b/src/libmpeg2/motion_comp.c
@@ -68,7 +68,7 @@ void mpeg2_mc_init (uint32_t mm_accel)
mpeg2_mc = mpeg2_mc_altivec;
} else
#endif
-#ifdef ARCH_SPARC
+#if defined(ARCH_SPARC) && defined(ENABLE_VIS)
if (mm_accel & MM_ACCEL_SPARC_VIS) {
#ifdef LOG
fprintf (stderr, "Using VIS for motion compensation\n");
diff --git a/src/libmpeg2/mpeg2.h b/src/libmpeg2/mpeg2.h
index 253f300a2..ae69688f5 100644
--- a/src/libmpeg2/mpeg2.h
+++ b/src/libmpeg2/mpeg2.h
@@ -31,7 +31,8 @@ typedef struct mpeg2dec_s {
uint32_t frame_format;
/* this is where we keep the state of the decoder */
- struct picture_s * picture, *picture_base;
+ struct picture_s * picture;
+ void *picture_base;
uint32_t shift;
int new_sequence;
@@ -45,7 +46,8 @@ typedef struct mpeg2dec_s {
/* which is 224K for MP@ML streams. */
/* (we make no pretenses of decoding anything more than that) */
/* allocated in init - gcc has problems allocating such big structures */
- uint8_t * chunk_buffer, *chunk_base;
+ uint8_t * chunk_buffer;
+ void *chunk_base;
/* pointer to current position in chunk_buffer */
uint8_t * chunk_ptr;
/* last start code ? */
diff --git a/src/libmpeg2/slice_xvmc_vld.c b/src/libmpeg2/slice_xvmc_vld.c
index 7e370a519..cd4eca0a2 100644
--- a/src/libmpeg2/slice_xvmc_vld.c
+++ b/src/libmpeg2/slice_xvmc_vld.c
@@ -17,6 +17,10 @@
*
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "xine_internal.h"
#include "video_out.h"
#include "mpeg2.h"
diff --git a/src/libmpeg2/xine_mpeg2_decoder.c b/src/libmpeg2/xine_mpeg2_decoder.c
index 4c4cc8654..b136ee861 100644
--- a/src/libmpeg2/xine_mpeg2_decoder.c
+++ b/src/libmpeg2/xine_mpeg2_decoder.c
@@ -20,6 +20,10 @@
* stuff needed to turn libmpeg2 into a xine decoder plugin
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <string.h>
@@ -117,7 +121,7 @@ static void mpeg2dec_dispose (video_decoder_t *this_gen) {
static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) {
mpeg2dec_decoder_t *this ;
- this = (mpeg2dec_decoder_t *) xine_xmalloc (sizeof (mpeg2dec_decoder_t));
+ this = (mpeg2dec_decoder_t *) calloc(1, sizeof(mpeg2dec_decoder_t));
this->video_decoder.decode_data = mpeg2dec_decode_data;
this->video_decoder.flush = mpeg2dec_flush;
@@ -155,7 +159,7 @@ static void *init_plugin (xine_t *xine, void *data) {
mpeg2_class_t *this;
- this = (mpeg2_class_t *) xine_xmalloc (sizeof (mpeg2_class_t));
+ this = (mpeg2_class_t *) calloc(1, sizeof(mpeg2_class_t));
this->decoder_class.open_plugin = open_plugin;
this->decoder_class.get_identifier = get_identifier;
diff --git a/src/libmpeg2new/Makefile.am b/src/libmpeg2new/Makefile.am
index 49959da86..8b05a5444 100644
--- a/src/libmpeg2new/Makefile.am
+++ b/src/libmpeg2new/Makefile.am
@@ -1,13 +1,18 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
-SUBDIRS = libmpeg2
+SUBDIRS = include libmpeg2
-xineplug_LTLIBRARIES = xineplug_decode_mpeg2.la
+if ENABLE_MPEG2NEW
+mpeg2new_module = xineplug_decode_mpeg2new.la
+endif
-xineplug_decode_mpeg2_la_SOURCES = \
- xine_mpeg2_decoder.c
+xineplug_LTLIBRARIES = $(mpeg2new_module)
-xineplug_decode_mpeg2_la_CFLAGS = $(VISIBILITY_FLAG) $(LIBMPEG2_CFLAGS)
-xineplug_decode_mpeg2_la_LIBADD = $(XINE_LIB) ./libmpeg2/libmpeg2.la
-xineplug_decode_mpeg2_la_LDFLAGS = $(xineplug_ldflags)
+xineplug_decode_mpeg2new_la_SOURCES = \
+ xine_mpeg2new_decoder.c
+
+xineplug_decode_mpeg2new_la_CFLAGS = $(VISIBILITY_FLAG) $(LIBMPEG2_CFLAGS)
+xineplug_decode_mpeg2new_la_LIBADD = $(XINE_LIB) libmpeg2/libmpeg2.la
+xineplug_decode_mpeg2new_la_LDFLAGS = $(xineplug_ldflags)
diff --git a/src/libmpeg2new/include/Makefile.am b/src/libmpeg2new/include/Makefile.am
index 302d01cb1..91d5575ee 100644
--- a/src/libmpeg2new/include/Makefile.am
+++ b/src/libmpeg2new/include/Makefile.am
@@ -1,3 +1,4 @@
-pkginclude_HEADERS = mpeg2.h mpeg2convert.h
+include $(top_builddir)/misc/Makefile.plugins
+include $(top_srcdir)/misc/Makefile.common
-EXTRA_DIST = video_out.h mmx.h alpha_asm.h vis.h attributes.h tendra.h
+EXTRA_DIST = video_out.h mmx.h alpha_asm.h vis.h attributes.h tendra.h mpeg2.h mpeg2convert.h
diff --git a/src/libmpeg2new/include/attributes.h b/src/libmpeg2new/include/attributes.h
index eefbc0dd1..92db86e7e 100644
--- a/src/libmpeg2new/include/attributes.h
+++ b/src/libmpeg2new/include/attributes.h
@@ -22,11 +22,7 @@
*/
/* use gcc attribs to align critical data structures */
-#ifdef ATTRIBUTE_ALIGNED_MAX
-#define ATTR_ALIGN(align) __attribute__ ((__aligned__ ((ATTRIBUTE_ALIGNED_MAX < align) ? ATTRIBUTE_ALIGNED_MAX : align)))
-#else
-#define ATTR_ALIGN(align)
-#endif
+#include "../../xine-utils/attributes.h"
#ifdef HAVE_BUILTIN_EXPECT
#define likely(x) __builtin_expect ((x) != 0, 1)
diff --git a/src/libmpeg2new/libmpeg2/Makefile.am b/src/libmpeg2new/libmpeg2/Makefile.am
index f99894f12..0bfeda1ce 100644
--- a/src/libmpeg2new/libmpeg2/Makefile.am
+++ b/src/libmpeg2new/libmpeg2/Makefile.am
@@ -1,13 +1,20 @@
include $(top_srcdir)/misc/Makefile.common
-noinst_LTLIBRARIES = libmpeg2.la libmpeg2arch.la
+if ENABLE_MPEG2NEW
+mpeg2new_libs = libmpeg2.la libmpeg2arch.la
+endif
+
+noinst_LTLIBRARIES = $(mpeg2new_libs)
libmpeg2_la_SOURCES = alloc.c header.c decode.c slice.c motion_comp.c idct.c
libmpeg2_la_LIBADD = libmpeg2arch.la
+AM_CPPFLAGS = -I$(srcdir)/../include
+
libmpeg2arch_la_SOURCES = motion_comp_mmx.c idct_mmx.c \
motion_comp_altivec.c idct_altivec.c \
motion_comp_alpha.c idct_alpha.c \
motion_comp_vis.c \
cpu_accel.c cpu_state.c
+EXTRA_DIST = mpeg2_internal.h vlc.h
diff --git a/src/libmpeg2new/libmpeg2/motion_comp_alpha.c b/src/libmpeg2new/libmpeg2/motion_comp_alpha.c
index 05cd55084..73f6625d2 100644
--- a/src/libmpeg2new/libmpeg2/motion_comp_alpha.c
+++ b/src/libmpeg2new/libmpeg2/motion_comp_alpha.c
@@ -26,10 +26,10 @@
#include <inttypes.h>
-#include "mpeg2.h"
-#include "attributes.h"
+#include "../include/mpeg2.h"
+#include "../include/attributes.h"
#include "mpeg2_internal.h"
-#include "alpha_asm.h"
+#include "../include/alpha_asm.h"
static inline uint64_t avg2 (uint64_t a, uint64_t b)
{
diff --git a/src/libmpeg2new/libmpeg2/motion_comp_altivec.c b/src/libmpeg2new/libmpeg2/motion_comp_altivec.c
index 4356aa6e7..cc1b72f56 100644
--- a/src/libmpeg2new/libmpeg2/motion_comp_altivec.c
+++ b/src/libmpeg2new/libmpeg2/motion_comp_altivec.c
@@ -30,8 +30,8 @@
#endif
#include <inttypes.h>
-#include "mpeg2.h"
-#include "attributes.h"
+#include "../include/mpeg2.h"
+#include "../include/attributes.h"
#include "mpeg2_internal.h"
typedef vector signed char vector_s8_t;
diff --git a/src/libmpeg2new/libmpeg2/motion_comp_vis.c b/src/libmpeg2new/libmpeg2/motion_comp_vis.c
index 54c0f7e75..e4b61aaa7 100644
--- a/src/libmpeg2new/libmpeg2/motion_comp_vis.c
+++ b/src/libmpeg2new/libmpeg2/motion_comp_vis.c
@@ -22,14 +22,14 @@
#include "config.h"
-#ifdef ARCH_SPARC
+#if defined(ARCH_SPARC) && defined(ENABLE_VIS)
#include <inttypes.h>
-#include "mpeg2.h"
-#include "attributes.h"
+#include "../include/mpeg2.h"
+#include "../include/attributes.h"
#include "mpeg2_internal.h"
-#include "vis.h"
+#include "../include/vis.h"
/* The trick used in some of this file is the formula from the MMX
* motion comp code, which is:
@@ -2058,4 +2058,4 @@ static void MC_avg_xy_8_vis (uint8_t * dest, const uint8_t * _ref,
MPEG2_MC_EXTERN(vis);
-#endif /* !(ARCH_SPARC) */
+#endif /* defined(ARCH_SPARC) && defined(ENABLE_VIS) */
diff --git a/src/libmpeg2new/xine_mpeg2new_decoder.c b/src/libmpeg2new/xine_mpeg2new_decoder.c
index 7ceac9178..8c16c441b 100644
--- a/src/libmpeg2new/xine_mpeg2new_decoder.c
+++ b/src/libmpeg2new/xine_mpeg2new_decoder.c
@@ -20,6 +20,10 @@
* stuff needed to turn libmpeg2 into a xine decoder plugin
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <string.h>
@@ -35,13 +39,14 @@
#include "video_out.h"
#include "buffer.h"
-
-
+/*
#define LOG
#define LOG_FRAME_ALLOC_FREE
#define LOG_ENTRY
#define LOG_FRAME_COUNTER
+*/
+#define _x_abort() do {} while (0)
typedef struct {
video_decoder_class_t decoder_class;
@@ -66,7 +71,9 @@ typedef struct mpeg2_video_decoder_s {
} mpeg2_video_decoder_t;
-
+#ifndef LOG_FRAME_ALLOC_FREE
+inline static void mpeg2_video_print_bad_state(img_state_t * img_state) {}
+#else
static void mpeg2_video_print_bad_state(img_state_t * img_state) {
int32_t n,m;
m=0;
@@ -79,6 +86,7 @@ static void mpeg2_video_print_bad_state(img_state_t * img_state) {
if (m > 3) _x_abort();
if (m == 0) printf("NO FRAMES\n");
}
+#endif
static void mpeg2_video_free_all(img_state_t * img_state) {
int32_t n,m;
@@ -153,7 +161,7 @@ static void mpeg2_video_decode_data (video_decoder_t *this_gen, buf_element_t *b
_x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, info->sequence->picture_width);
_x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, info->sequence->picture_height);
_x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, info->sequence->frame_period / 300);
- if (this->force_aspect) info->sequence->pixel_width = this->force_aspect;
+ if (this->force_aspect) ((mpeg2_sequence_t *)info->sequence)->pixel_width = this->force_aspect; /* ugly... */
switch (info->sequence->pixel_width) {
case 3:
this->ratio = 16.0 / 9.0;
@@ -449,7 +457,7 @@ static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stre
mpeg2_video_decoder_t *this ;
int32_t n;
- this = (mpeg2_video_decoder_t *) xine_xmalloc (sizeof (mpeg2_video_decoder_t));
+ this = (mpeg2_video_decoder_t *) calloc(1, sizeof(mpeg2_video_decoder_t));
this->video_decoder.decode_data = mpeg2_video_decode_data;
this->video_decoder.flush = mpeg2_video_flush;
@@ -490,7 +498,7 @@ static void *init_plugin (xine_t *xine, void *data) {
mpeg2_class_t *this;
- this = (mpeg2_class_t *) xine_xmalloc (sizeof (mpeg2_class_t));
+ this = (mpeg2_class_t *) calloc(1, sizeof(mpeg2_class_t));
this->decoder_class.open_plugin = open_plugin;
this->decoder_class.get_identifier = get_identifier;
@@ -503,14 +511,14 @@ static void *init_plugin (xine_t *xine, void *data) {
* exported plugin catalog entry
*/
-static uint32_t supported_types[] = { BUF_VIDEO_MPEG, 0 };
+static const uint32_t supported_types[] = { BUF_VIDEO_MPEG, 0 };
-static decoder_info_t dec_info_mpeg2 = {
+static const decoder_info_t dec_info_mpeg2 = {
supported_types, /* supported types */
6 /* priority */
};
-plugin_info_t xine_plugin_info[] = {
+const plugin_info_t xine_plugin_info[] EXPORTED = {
/* type, API, "name", version, special_info, init_function */
{ PLUGIN_VIDEO_DECODER, 18, "mpeg2new", XINE_VERSION_CODE, &dec_info_mpeg2, init_plugin },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
diff --git a/src/libmusepack/Makefile.am b/src/libmusepack/Makefile.am
index 01875bdad..11344c3c2 100644
--- a/src/libmusepack/Makefile.am
+++ b/src/libmusepack/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
SUBDIRS = musepack
diff --git a/src/libmusepack/xine_musepack_decoder.c b/src/libmusepack/xine_musepack_decoder.c
index 7a2d30a06..1454b32f9 100644
--- a/src/libmusepack/xine_musepack_decoder.c
+++ b/src/libmusepack/xine_musepack_decoder.c
@@ -24,6 +24,10 @@
* Seeking??
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -214,7 +218,7 @@ static void mpc_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
this->file_size = buf->decoder_info[0];
/* Initialise the data accumulation buffer */
- this->buf = xine_xmalloc(INIT_BUFSIZE);
+ this->buf = calloc(1, INIT_BUFSIZE);
this->buf_max = INIT_BUFSIZE;
this->read = 0;
this->size = 0;
@@ -396,7 +400,7 @@ static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stre
mpc_decoder_t *this ;
- this = (mpc_decoder_t *) xine_xmalloc (sizeof (mpc_decoder_t));
+ this = (mpc_decoder_t *) calloc(1, sizeof(mpc_decoder_t));
/* connect the member functions */
this->audio_decoder.decode_data = mpc_decode_data;
@@ -441,7 +445,7 @@ static void *init_plugin (xine_t *xine, void *data) {
mpc_class_t *this ;
- this = (mpc_class_t *) xine_xmalloc (sizeof (mpc_class_t));
+ this = (mpc_class_t *) calloc(1, sizeof(mpc_class_t));
this->decoder_class.open_plugin = open_plugin;
this->decoder_class.get_identifier = get_identifier;
diff --git a/src/libreal/Makefile.am b/src/libreal/Makefile.am
index 6e76d6279..90e47a63c 100644
--- a/src/libreal/Makefile.am
+++ b/src/libreal/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
if ENABLE_REAL
diff --git a/src/libreal/real_common.c b/src/libreal/real_common.c
index fcd0fac8f..6fda4ddbe 100644
--- a/src/libreal/real_common.c
+++ b/src/libreal/real_common.c
@@ -77,8 +77,8 @@ void _x_real_codecs_init(xine_t *const xine) {
default_real_codecs_path[0] = 0;
-#define UL64 0x05 /* /usr/{,local/}lib64 */
-#define UL 0x0A /* /usr/{,local/}lib */
+#define UL64 0x03 /* /usr/{,local/}lib64 */
+#define UL 0x0C /* /usr/{,local/}lib */
#define O 0x10 /* /opt */
#define OL64 0x20 /* /opt/lib64 */
#define OL 0x40 /* /opt/lib */
diff --git a/src/libreal/xine_real_audio_decoder.c b/src/libreal/xine_real_audio_decoder.c
index 1b21de2d0..4187477e1 100644
--- a/src/libreal/xine_real_audio_decoder.c
+++ b/src/libreal/xine_real_audio_decoder.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2003 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -22,6 +22,10 @@
* code inspired by work from Florian Schneider for the MPlayer Project
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <string.h>
@@ -51,6 +55,8 @@ typedef struct {
/* empty so far */
} real_class_t;
+typedef void * ra_codec_t;
+
typedef struct realdec_decoder_s {
audio_decoder_t audio_decoder;
@@ -60,18 +66,18 @@ typedef struct realdec_decoder_s {
void *ra_handle;
- unsigned long (*raCloseCodec)(void*);
- unsigned long (*raDecode)(void*, char*,unsigned long,char*,unsigned int*,long);
- unsigned long (*raFlush)(unsigned long,unsigned long,unsigned long);
- unsigned long (*raFreeDecoder)(void*);
- void* (*raGetFlavorProperty)(void*,unsigned long,unsigned long,int*);
- unsigned long (*raInitDecoder)(void*, void*);
- unsigned long (*raOpenCodec2)(void*);
- unsigned long (*raSetFlavor)(void*,unsigned long);
- void (*raSetDLLAccessPath)(char*);
- void (*raSetPwd)(char*,char*);
+ uint32_t (*raCloseCodec)(ra_codec_t);
+ uint32_t (*raDecode)(ra_codec_t, char *, uint32_t, char *, uint32_t *, uint32_t);
+ uint32_t (*raFlush)(ra_codec_t, char *, uint32_t *);
+ uint32_t (*raFreeDecoder)(ra_codec_t);
+ void * (*raGetFlavorProperty)(ra_codec_t, uint16_t, uint16_t, uint16_t *);
+ uint32_t (*raInitDecoder)(ra_codec_t, void *);
+ uint32_t (*raOpenCodec2)(ra_codec_t *, const char *);
+ uint32_t (*raSetFlavor)(ra_codec_t, uint16_t);
+ void (*raSetDLLAccessPath)(char *);
+ void (*raSetPwd)(ra_codec_t, char *);
- void *context;
+ ra_codec_t context;
int sps, w, h;
int block_align;
@@ -92,14 +98,14 @@ typedef struct realdec_decoder_s {
} realdec_decoder_t;
typedef struct {
- int samplerate;
- short bits;
- short channels;
- int unk1;
- int subpacket_size;
- int coded_frame_size;
- int codec_data_length;
- void *extras;
+ uint32_t samplerate;
+ uint16_t bits;
+ uint16_t channels;
+ uint16_t quality;
+ uint32_t subpacket_size;
+ uint32_t coded_frame_size;
+ uint32_t codec_data_length;
+ void *extras;
} ra_init_t;
static int load_syms_linux (realdec_decoder_t *this, const char *const codec_name, const char *const codec_alternate) {
@@ -216,13 +222,14 @@ static int init_codec (realdec_decoder_t *this, buf_element_t *buf) {
_x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "Cook");
if (!load_syms_linux (this, "cook.so", "cook.so.6.0"))
return 0;
+ this->block_align = subpacket_size;
break;
case BUF_AUDIO_ATRK:
_x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "Atrac");
if (!load_syms_linux (this, "atrc.so", "atrc.so.6.0"))
return 0;
- this->block_align = 384;
+ this->block_align = subpacket_size;
break;
case BUF_AUDIO_14_4:
@@ -254,7 +261,7 @@ static int init_codec (realdec_decoder_t *this, buf_element_t *buf) {
* init codec
*/
- result = this->raOpenCodec2 (&this->context);
+ result = this->raOpenCodec2 (&this->context, NULL);
if (result) {
xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libareal: error in raOpenCodec2: %d\n", result);
return 0;
@@ -266,7 +273,7 @@ static int init_codec (realdec_decoder_t *this, buf_element_t *buf) {
init_data.samplerate = samples_per_sec;
init_data.bits = bits_per_sample;
init_data.channels = num_channels;
- init_data.unk1 = 100; /* ??? */
+ init_data.quality = 100; /* ??? */
init_data.subpacket_size = subpacket_size; /* subpacket size */
init_data.coded_frame_size = coded_frame_size; /* coded frame size */
init_data.codec_data_length = data_len; /* codec data length */
@@ -307,14 +314,14 @@ static int init_codec (realdec_decoder_t *this, buf_element_t *buf) {
if (this->sps) {
this->frame_size = this->w/this->sps*this->h*this->sps;
- this->frame_buffer = xine_xmalloc (this->frame_size);
- this->frame_reordered = xine_xmalloc (this->frame_size);
+ this->frame_buffer = calloc (1, this->frame_size);
+ this->frame_reordered = calloc (1, this->frame_size);
this->frame_num_bytes = 0;
} else {
this->frame_size = this->w*this->h;
- this->frame_buffer = xine_xmalloc (this->frame_size);
+ this->frame_buffer = calloc (this->w, this->h);
this->frame_reordered = this->frame_buffer;
this->frame_num_bytes = 0;
@@ -350,13 +357,6 @@ static int init_codec (realdec_decoder_t *this, buf_element_t *buf) {
return 1;
}
-static unsigned char sipr_swaps[38][2]={
- {0,63},{1,22},{2,44},{3,90},{5,81},{7,31},{8,86},{9,58},{10,36},{12,68},
- {13,39},{14,73},{15,53},{16,69},{17,57},{19,88},{20,34},{21,71},{24,46},
- {25,94},{26,54},{28,75},{29,50},{32,70},{33,92},{35,74},{38,85},{40,56},
- {42,87},{43,65},{45,59},{48,79},{49,93},{51,89},{55,95},{61,76},{67,83},
- {77,80} };
-
static void realdec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
realdec_decoder_t *this = (realdec_decoder_t *) this_gen;
@@ -383,116 +383,32 @@ static void realdec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
this->pts = buf->pts;
size = buf->size;
-
while (size) {
+ int need;
- int needed;
-
- needed = this->frame_size - this->frame_num_bytes;
-
- if (needed>size) {
-
- memcpy (this->frame_buffer+this->frame_num_bytes, buf->content, size);
+ need = this->frame_size - this->frame_num_bytes;
+ if (size < need) {
+ memcpy (this->frame_buffer + this->frame_num_bytes,
+ buf->content + buf->size - size, size);
this->frame_num_bytes += size;
-
- lprintf ("buffering %d/%d bytes\n", this->frame_num_bytes, this->frame_size);
-
size = 0;
-
} else {
-
- int result;
- int len =-1;
- int n;
- int sps = this->sps;
- int w = this->w;
- int h = this->h;
audio_buffer_t *audio_buffer;
+ int n, len;
+ int result;
- lprintf ("buffering %d bytes\n", needed);
-
- memcpy (this->frame_buffer+this->frame_num_bytes, buf->content, needed);
-
- size -= needed;
+ memcpy (this->frame_buffer + this->frame_num_bytes,
+ buf->content + buf->size - size, need);
+ size -= need;
this->frame_num_bytes = 0;
- lprintf ("frame completed. reordering...\n");
- lprintf ("bs=%d sps=%d w=%d h=%d \n",/*sh->wf->nBlockAlign*/-1,sps,w,h);
-
- if (!sps) {
-
- int j,n;
- int bs=h*w*2/96; /* nibbles per subpacket */
- unsigned char *p=this->frame_buffer;
-
- /* 'sipr' way */
- /* demux_read_data(sh->ds, p, h*w); */
- for (n=0;n<38;n++){
- int i=bs*sipr_swaps[n][0];
- int o=bs*sipr_swaps[n][1];
- /* swap nibbles of block 'i' with 'o' TODO: optimize */
- for (j=0;j<bs;j++) {
- int x=(i&1) ? (p[(i>>1)]>>4) : (p[(i>>1)]&15);
- int y=(o&1) ? (p[(o>>1)]>>4) : (p[(o>>1)]&15);
- if (o&1)
- p[(o>>1)]=(p[(o>>1)]&0x0F)|(x<<4);
- else
- p[(o>>1)]=(p[(o>>1)]&0xF0)|x;
-
- if (i&1)
- p[(i>>1)]=(p[(i>>1)]&0x0F)|(y<<4);
- else
- p[(i>>1)]=(p[(i>>1)]&0xF0)|y;
-
- ++i;
- ++o;
- }
- }
- /*
- sh->a_in_buffer_size=
- sh->a_in_buffer_len=w*h;
- */
-
- } else {
- int x, y;
- uint8_t *s;
-
- /* 'cook' way */
-
- w /= sps; s = this->frame_buffer;
-
- for (y=0; y<h; y++)
-
- for (x=0; x<w; x++) {
-
- lprintf ("x=%d, y=%d, off %d\n",
- x, y, sps*(h*x+((h+1)/2)*(y&1)+(y>>1)));
-
- memcpy (this->frame_reordered+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)),
- s, sps);
- s+=sps;
-
- /* demux_read_data(sh->ds, sh->a_in_buffer+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)),
- sps); */
-
- }
- /*
- sh->a_in_buffer_size=
- sh->a_in_buffer_len=w*h*sps;
- */
- }
-
-#ifdef LOG
- xine_hexdump (this->frame_reordered, buf->size);
-#endif
-
n = 0;
- while (n<this->frame_size) {
+ while (n < this->frame_size) {
audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out);
result = this->raDecode (this->context,
- this->frame_reordered+n,
+ this->frame_buffer + n,
this->block_align,
(char *) audio_buffer->mem, &len, -1);
@@ -506,7 +422,7 @@ static void realdec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
this->stream->audio_out->put_buffer (this->stream->audio_out,
audio_buffer, this->stream);
- n+=this->block_align;
+ n += this->block_align;
}
}
}
@@ -565,7 +481,7 @@ static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen,
real_class_t *cls = (real_class_t *) class_gen;
realdec_decoder_t *this ;
- this = (realdec_decoder_t *) xine_xmalloc (sizeof (realdec_decoder_t));
+ this = (realdec_decoder_t *) calloc(1, sizeof(realdec_decoder_t));
this->audio_decoder.decode_data = realdec_decode_data;
this->audio_decoder.reset = realdec_reset;
@@ -598,9 +514,8 @@ static void dispose_class (audio_decoder_class_t *this) {
void *init_realadec (xine_t *xine, void *data) {
real_class_t *this;
- config_values_t *config = xine->config;
- this = (real_class_t *) xine_xmalloc (sizeof (real_class_t));
+ this = (real_class_t *) calloc(1, sizeof(real_class_t));
this->decoder_class.open_plugin = open_plugin;
this->decoder_class.get_identifier = get_identifier;
@@ -622,5 +537,5 @@ static uint32_t audio_types[] = {
const decoder_info_t dec_info_realaudio = {
audio_types, /* supported types */
- 7 /* priority */
+ 6 /* priority */
};
diff --git a/src/libreal/xine_real_video_decoder.c b/src/libreal/xine_real_video_decoder.c
index d68c7390e..314edc489 100644
--- a/src/libreal/xine_real_video_decoder.c
+++ b/src/libreal/xine_real_video_decoder.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2004 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -22,6 +22,10 @@
* code inspired by work from Florian Schneider for the MPlayer Project
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <string.h>
@@ -63,9 +67,9 @@ typedef struct realdec_decoder_s {
uint32_t (*rvyuv_custom_message)(void*, void*);
uint32_t (*rvyuv_free)(void*);
- uint32_t (*rvyuv_hive_message)(uint32_t, uint32_t);
+ uint32_t (*rvyuv_hive_message)(uint32_t, void*);
uint32_t (*rvyuv_init)(void*, void*); /* initdata,context */
- uint32_t (*rvyuv_transform)(char*, char*, void*, uint32_t*,void*);
+ uint32_t (*rvyuv_transform)(char*, char*, void*, void*, void*);
void *context;
@@ -113,13 +117,21 @@ typedef struct cmsg_data_s {
typedef struct transform_in_s {
uint32_t len;
- uint32_t unknown1;
- uint32_t chunks;
- uint32_t* extra;
- uint32_t unknown2;
+ uint32_t interpolate;
+ uint32_t nsegments;
+ void *segments;
+ uint32_t flags;
uint32_t timestamp;
} transform_in_t;
+typedef struct {
+ uint32_t frames;
+ uint32_t notes;
+ uint32_t timestamp;
+ uint32_t width;
+ uint32_t height;
+} transform_out_t;
+
/*
* real codec loader
*/
@@ -169,7 +181,6 @@ static int init_codec (realdec_decoder_t *this, buf_element_t *buf) {
int result;
rv_init_t init_data = {11, 0, 0, 0, 0, 0, 1, 0}; /* rv30 */
-
switch (buf->type) {
case BUF_VIDEO_RV20:
_x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Real Video 2.0");
@@ -258,7 +269,7 @@ static int init_codec (realdec_decoder_t *this, buf_element_t *buf) {
#ifdef LOG
printf ("libreal: CustomMessage cmsg_data:\n");
- xine_hexdump ((uint8_t *) cmsg_data, sizeof (cmsg_data));
+ xine_hexdump ((uint8_t *) &cmsg_data, sizeof (cmsg_data));
printf ("libreal: cmsg24:\n");
xine_hexdump ((uint8_t *) cmsg24, (buf->size - 34 + 2) * sizeof(uint32_t));
#endif
@@ -271,7 +282,7 @@ static int init_codec (realdec_decoder_t *this, buf_element_t *buf) {
this->frame_size = this->width * this->height;
this->frame_buffer = xine_xmalloc (this->width * this->height * 3 / 2);
- this->chunk_buffer = xine_xmalloc (BUF_SIZE);
+ this->chunk_buffer = calloc(1, BUF_SIZE);
this->chunk_buffer_max = BUF_SIZE;
return 1;
@@ -342,7 +353,7 @@ static void realdec_decode_data (video_decoder_t *this_gen, buf_element_t *buf)
int result;
vo_frame_t *img;
- uint32_t transform_out[5];
+ transform_out_t transform_out;
transform_in_t transform_in = {
this->chunk_buffer_size,
/* length of the packet (sub-packets appended) */
@@ -369,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, 6 * 4);
+ xine_hexdump ((uint8_t *) &transform_in, sizeof(rv_xform_in_t));
printf ("libreal: chunk_table:\n");
xine_hexdump ((uint8_t *) buf->decoder_info_ptr[2],
@@ -379,21 +390,21 @@ static void realdec_decode_data (video_decoder_t *this_gen, buf_element_t *buf)
result = this->rvyuv_transform (this->chunk_buffer,
this->frame_buffer,
&transform_in,
- transform_out,
+ &transform_out,
this->context);
lprintf ("transform result: %08x\n", result);
lprintf ("transform_out:\n");
- #ifdef LOG
- xine_hexdump ((uint8_t *) transform_out, 5 * 4);
- #endif
+#ifdef LOG
+ xine_hexdump ((uint8_t *) &transform_out, 5 * 4);
+#endif
/* Sometimes the stream contains video of a different size
* to that specified in the realmedia header */
- if(transform_out[0] && ((transform_out[3] != this->width) ||
- (transform_out[4] != this->height))) {
- this->width = transform_out[3];
- this->height = transform_out[4];
+ if(transform_out.frames && ((transform_out.width != this->width) ||
+ (transform_out.height != this->height))) {
+ this->width = transform_out.width;
+ this->height = transform_out.height;
this->frame_size = this->width * this->height;
@@ -489,7 +500,7 @@ static video_decoder_t *open_plugin (video_decoder_class_t *class_gen,
real_class_t *cls = (real_class_t *) class_gen;
realdec_decoder_t *this ;
- this = (realdec_decoder_t *) xine_xmalloc (sizeof (realdec_decoder_t));
+ this = (realdec_decoder_t *) calloc(1, sizeof(realdec_decoder_t));
this->video_decoder.decode_data = realdec_decode_data;
this->video_decoder.flush = realdec_flush;
@@ -526,9 +537,8 @@ static void dispose_class (video_decoder_class_t *this) {
void *init_realvdec (xine_t *xine, void *data) {
real_class_t *this;
- config_values_t *config = xine->config;
- this = (real_class_t *) xine_xmalloc (sizeof (real_class_t));
+ this = (real_class_t *) calloc(1, sizeof(real_class_t));
this->decoder_class.open_plugin = open_plugin;
this->decoder_class.get_identifier = get_identifier;
@@ -544,8 +554,7 @@ void *init_realvdec (xine_t *xine, void *data) {
* exported plugin catalog entry
*/
-static uint32_t supported_types[] = { BUF_VIDEO_RV20,
- BUF_VIDEO_RV30,
+static uint32_t supported_types[] = { BUF_VIDEO_RV30,
BUF_VIDEO_RV40,
0 };
diff --git a/src/libspucc/Makefile.am b/src/libspucc/Makefile.am
index a8af8632e..1e170cdd5 100644
--- a/src/libspucc/Makefile.am
+++ b/src/libspucc/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
xineplug_LTLIBRARIES = xineplug_decode_spucc.la
diff --git a/src/libspucc/cc_decoder.c b/src/libspucc/cc_decoder.c
index 8d666e847..98c7319b6 100644
--- a/src/libspucc/cc_decoder.c
+++ b/src/libspucc/cc_decoder.c
@@ -27,6 +27,10 @@
* available at http://sourceforge.net/projects/ccdecoder/.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -216,8 +220,6 @@ static const uint8_t *const cc_alpha_palettes[NUM_CC_PALETTES] = {
#define TRANSP_SPACE 0x19 /* code for transparent space, essentially
arbitrary */
-#define MAX(a, b) ((a) > (b)? (a) : (b))
-
/* mapping from PAC row code to actual CC row */
static const int rowdata[] = {10, -1, 0, 1, 2, 3, 11, 12, 13, 14, 4, 5, 6,
7, 8, 9};
@@ -922,7 +924,7 @@ cc_renderer_t *cc_renderer_open(osd_renderer_t *osd_renderer,
metronom_t *metronom, cc_state_t *cc_state,
int video_width, int video_height)
{
- cc_renderer_t *this = (cc_renderer_t *) xine_xmalloc(sizeof (cc_renderer_t));
+ cc_renderer_t *this = calloc(1, sizeof (cc_renderer_t));
this->osd_renderer = osd_renderer;
this->metronom = metronom;
@@ -1439,7 +1441,7 @@ void decode_cc(cc_decoder_t *this, uint8_t *buffer, uint32_t buf_len,
cc_decoder_t *cc_decoder_open(cc_state_t *cc_state)
{
- cc_decoder_t *this = (cc_decoder_t *) xine_xmalloc(sizeof (cc_decoder_t));
+ cc_decoder_t *this = calloc(1, sizeof (cc_decoder_t));
/* configfile stuff */
this->cc_state = cc_state;
diff --git a/src/libspucc/cc_decoder.h b/src/libspucc/cc_decoder.h
index 8698189a6..47703b6d1 100644
--- a/src/libspucc/cc_decoder.h
+++ b/src/libspucc/cc_decoder.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2003 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* Copyright (C) Christian Vogler
* cvogler@gradient.cis.upenn.edu - December 2001
@@ -31,11 +31,7 @@ typedef struct cc_decoder_s cc_decoder_t;
typedef struct cc_renderer_s cc_renderer_t;
#define NUM_CC_PALETTES 2
-static const char *cc_schemes[NUM_CC_PALETTES + 1] = {
- "White/Gray/Translucent",
- "White/Black/Solid",
- NULL
-};
+extern const char *cc_schemes[];
#define CC_FONT_MAX 256
diff --git a/src/libspucc/xine_cc_decoder.c b/src/libspucc/xine_cc_decoder.c
index 9cdb4c4ea..12a5e7132 100644
--- a/src/libspucc/xine_cc_decoder.c
+++ b/src/libspucc/xine_cc_decoder.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2003 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -20,6 +20,10 @@
* closed caption spu decoder. receive data by events.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -33,6 +37,12 @@
#define LOG_DEBUG 1
*/
+const char *cc_schemes[NUM_CC_PALETTES + 1] = {
+ "White/Gray/Translucent",
+ "White/Black/Solid",
+ NULL
+};
+
typedef struct spucc_decoder_s {
spu_decoder_t spu_decoder;
@@ -193,7 +203,7 @@ static void spucc_register_cfg_vars(spucc_class_t *this,
cc_vars->cc_scheme = xine_cfg->register_enum(xine_cfg,
"subtitles.closedcaption.scheme", 0,
- cc_schemes,
+ (char **)cc_schemes,
_("closed-captioning foreground/background scheme"),
_("Choose your favourite rendering of the closed "
"captions."),
@@ -301,7 +311,7 @@ static spu_decoder_t *spudec_open_plugin (spu_decoder_class_t *class, xine_strea
spucc_decoder_t *this ;
- this = (spucc_decoder_t *) xine_xmalloc (sizeof (spucc_decoder_t));
+ this = (spucc_decoder_t *) calloc(1, sizeof(spucc_decoder_t));
this->spu_decoder.decode_data = spudec_decode_data;
this->spu_decoder.reset = spudec_reset;
@@ -338,7 +348,7 @@ static void *init_spu_decoder_plugin (xine_t *xine, void *data) {
spucc_class_t *this ;
- this = (spucc_class_t *) xine_xmalloc (sizeof (spucc_class_t));
+ this = (spucc_class_t *) calloc(1, sizeof(spucc_class_t));
this->spu_class.open_plugin = spudec_open_plugin;
this->spu_class.get_identifier = spudec_get_identifier;
diff --git a/src/libspucmml/Makefile.am b/src/libspucmml/Makefile.am
index 81e8d3623..53a980b57 100644
--- a/src/libspucmml/Makefile.am
+++ b/src/libspucmml/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
xineplug_LTLIBRARIES = xineplug_decode_spucmml.la
diff --git a/src/libspucmml/xine_cmml_decoder.c b/src/libspucmml/xine_cmml_decoder.c
index b684d21cb..c3da1b0fd 100644
--- a/src/libspucmml/xine_cmml_decoder.c
+++ b/src/libspucmml/xine_cmml_decoder.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2003 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -88,14 +88,13 @@ static void video_frame_format_change_callback (void *user_data, const xine_even
static void update_font_size (spucmml_decoder_t *this) {
- static int sizes[SUBTITLE_SIZE_NUM][4] = {
+ static const int sizes[SUBTITLE_SIZE_NUM][4] = {
{ 16, 16, 16, 20 }, /* SUBTITLE_SIZE_SMALL */
{ 16, 16, 20, 24 }, /* SUBTITLE_SIZE_NORMAL */
{ 16, 20, 24, 32 }, /* SUBTITLE_SIZE_LARGE */
};
- int *vec = sizes[this->subtitle_size];
- int y;
+ const int *const vec = sizes[this->subtitle_size];
if( this->cached_width >= 512 )
this->font_size = vec[3];
@@ -108,7 +107,7 @@ static void update_font_size (spucmml_decoder_t *this) {
this->line_height = this->font_size + 10;
- y = this->cached_height - (SUB_MAX_TEXT * this->line_height) - 5;
+ int y = this->cached_height - (SUB_MAX_TEXT * this->line_height) - 5;
if(((y - this->vertical_offset) >= 0) && ((y - this->vertical_offset) <= this->cached_height))
y -= this->vertical_offset;
@@ -137,83 +136,80 @@ static void update_font_size (spucmml_decoder_t *this) {
}
static int get_width(spucmml_decoder_t *this, char* text) {
- size_t i=0;
- int width=0,w,dummy;
- char letter[2]={0, 0};
+ int width=0;
+
+ while (1)
+ switch (*text) {
+ case '\0':
+ llprintf(LOG_WIDTH, "get_width returning width of %d\n", width);
+ return width;
- while (i<=strlen(text)) {
- switch (text[i]) {
case '<':
- if (!strncmp("<b>", text+i, 3)) {
+ if (!strncmp("<b>", text, 3)) {
/*Do somethink to enable BOLD typeface*/
- i=i+3;
+ text += 3;
break;
- } else if (!strncmp("</b>", text+i, 3)) {
+ } else if (!strncmp("</b>", text, 3)) {
/*Do somethink to disable BOLD typeface*/
- i=i+4;
+ text += 4;
break;
- } else if (!strncmp("<i>", text+i, 3)) {
+ } else if (!strncmp("<i>", text, 3)) {
/*Do somethink to enable italics typeface*/
- i=i+3;
+ text += 3;
break;
- } else if (!strncmp("</i>", text+i, 3)) {
+ } else if (!strncmp("</i>", text, 3)) {
/*Do somethink to disable italics typeface*/
- i=i+4;
+ text += 4;
break;
- } else if (!strncmp("<font>", text+i, 3)) {
+ } else if (!strncmp("<font>", text, 3)) {
/*Do somethink to disable typing
fixme - no teststreams*/
- i=i+6;
+ text += 6;
break;
- } else if (!strncmp("</font>", text+i, 3)) {
+ } else if (!strncmp("</font>", text, 3)) {
/*Do somethink to enable typing
fixme - no teststreams*/
- i=i+7;
+ text += 7;
break;
}
default:
- letter[0]=text[i];
- this->stream->osd_renderer->get_text_size(this->osd, letter, &w, &dummy);
- width=width+w;
- i++;
+ {
+ int w, dummy;
+ const char letter[2] = { *text, '\0' };
+ this->stream->osd_renderer->get_text_size(this->osd, letter, &w, &dummy);
+ width += w;
+ text++;
+ }
}
- }
-
- llprintf(LOG_WIDTH, "get_width returning width of %d\n", width);
-
- return width;
}
static void render_line(spucmml_decoder_t *this, int x, int y, char* text) {
- size_t i=0;
- int w,dummy;
- char letter[2]={0,0};
+ while (*text != '\0') {
+ int w, dummy;
+ const char letter[2] = { *text, '\0' };
- while (i<=strlen(text)) {
- letter[0]=text[i];
this->stream->osd_renderer->render_text(this->osd, x, y, letter, OSD_TEXT1);
this->stream->osd_renderer->get_text_size(this->osd, letter, &w, &dummy);
- x=x+w;
- i++;
+ x += w;
+ text++;
}
}
static void draw_subtitle(spucmml_decoder_t *this, int64_t sub_start) {
- int line, y;
- int font_size;
-
this->stream->osd_renderer->filled_rect (this->osd, 0, 0,
this->cached_width-1, this->line_height * SUB_MAX_TEXT - 1, 0);
- y = (SUB_MAX_TEXT - this->lines) * this->line_height;
- font_size = this->font_size;
+ const int y = (SUB_MAX_TEXT - this->lines) * this->line_height;
+ int font_size = this->font_size;
this->stream->osd_renderer->set_encoding(this->osd, this->class->src_encoding);
+ int line;
+
for (line=0; line<this->lines; line++) {
- int w,x;
+ int x;
while(1) {
- w=get_width( this, this->text[line]);
+ const int w = get_width( this, this->text[line]);
x = (this->cached_width - w) / 2;
if( w > this->cached_width && font_size > 16 ) {
@@ -242,14 +238,13 @@ static void draw_subtitle(spucmml_decoder_t *this, int64_t sub_start) {
static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {
spucmml_decoder_t *this = (spucmml_decoder_t *) this_gen;
- char *str;
xml_node_t *packet_xml_root;
char * anchor_text = NULL;
lprintf("CMML packet seen\n");
- str = (char *) buf->content;
+ char *str = (char *) buf->content;
/* parse the CMML */
@@ -268,36 +263,30 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {
for (title_node = packet_xml_root->child; title_node != NULL; title_node = title_node->next) {
- if (strcasecmp (title_node->name, "title") == 0) {
+ if (title_node->data &&
+ strcasecmp (title_node->name, "title") == 0) {
/* found a title node */
- xine_event_t uevent;
- char *title;
- int title_len;
-
- title = title_node->data;
-
- if (title)
- {
- xine_ui_data_t data;
- /* found a non-empty title */
- lprintf ("found title: \"%s\"\n", title);
-
- /* set xine meta-info */
- _x_meta_info_set(this->stream, XINE_META_INFO_TITLE, strdup(title));
-
- /* and push out a new event signifying the title update on the event
- * queue */
- title_len = strlen(title) + 1;
- memcpy(data.str, title, title_len);
- data.str_len = title_len;
-
- uevent.type = XINE_EVENT_UI_SET_TITLE;
- uevent.stream = this->stream;
- uevent.data = &data;
- uevent.data_length = sizeof(data);
- xine_event_send(this->stream, &uevent);
- }
+ xine_ui_data_t data = {
+ .str_len = strlen(title_node->data) + 1
+ };
+ xine_event_t uevent = {
+ .type = XINE_EVENT_UI_SET_TITLE,
+ .stream = this->stream,
+ .data = &data,
+ .data_length = sizeof(data),
+ };
+ strncpy(data.str, title_node->data, sizeof(data.str)-1);
+
+ /* found a non-empty title */
+ lprintf ("found title: \"%s\"\n", data.str);
+
+ /* set xine meta-info */
+ _x_meta_info_set(this->stream, XINE_META_INFO_TITLE, strdup(data.str));
+
+ /* and push out a new event signifying the title update on the event
+ * queue */
+ xine_event_send(this->stream, &uevent);
}
}
} else if (strcasecmp(packet_xml_root->name, "clip") == 0) {
@@ -446,11 +435,8 @@ static void update_osd_font(void *this_gen, xine_cfg_entry_t *entry)
}
static spu_decoder_t *spucmml_class_open_plugin (spu_decoder_class_t *class_gen, xine_stream_t *stream) {
-
spucmml_class_t *class = (spucmml_class_t *)class_gen;
- spucmml_decoder_t *this ;
-
- this = (spucmml_decoder_t *) xine_xmalloc (sizeof (spucmml_decoder_t));
+ spucmml_decoder_t *this = (spucmml_decoder_t *) calloc(1, sizeof(spucmml_decoder_t));
this->spu_decoder.decode_data = spudec_decode_data;
this->spu_decoder.reset = spudec_reset;
@@ -511,10 +497,7 @@ static void update_src_encoding(void *this_gen, xine_cfg_entry_t *entry)
}
static void *init_spu_decoder_plugin (xine_t *xine, void *data) {
-
- spucmml_class_t *this ;
-
- this = (spucmml_class_t *) xine_xmalloc (sizeof (spucmml_class_t));
+ spucmml_class_t *this = (spucmml_class_t *) calloc(1, sizeof(spucmml_class_t));
this->class.open_plugin = spucmml_class_open_plugin;
this->class.get_identifier = spucmml_class_get_identifier;
diff --git a/src/libspudec/Makefile.am b/src/libspudec/Makefile.am
index 208d994f5..061bd7731 100644
--- a/src/libspudec/Makefile.am
+++ b/src/libspudec/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
xineplug_LTLIBRARIES = xineplug_decode_spu.la
@@ -7,7 +8,7 @@ if HAVE_DVDNAV
xineplug_decode_spu_la_SOURCES = \
spu.c \
xine_spu_decoder.c
-xineplug_decode_spu_la_LIBADD = $(XINE_LIB) $(DVDNAV_LIBS) $(PTHREAD_LIBS)
+xineplug_decode_spu_la_LIBADD = $(XINE_LIB) $(DVDNAV_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL)
else
@@ -16,7 +17,7 @@ xineplug_decode_spu_la_SOURCES = \
spu.c \
xine_spu_decoder.c
AM_CPPFLAGS = -I$(top_srcdir)/src/input/libdvdnav
-xineplug_decode_spu_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS)
+xineplug_decode_spu_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL)
endif
diff --git a/src/libspudec/spu.c b/src/libspudec/spu.c
index ce3497ef0..e91cafbc1 100644
--- a/src/libspudec/spu.c
+++ b/src/libspudec/spu.c
@@ -37,6 +37,10 @@
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
@@ -209,7 +213,7 @@ void spudec_decode_nav(spudec_decoder_t *this, buf_element_t *buf) {
#endif
/* append PCI at the end of the list */
while (node->next) node = node->next;
- node->next = (pci_node_t *)xine_xmalloc(sizeof(pci_node_t));
+ node->next = malloc(sizeof(pci_node_t));
node->next->vpts = this->stream->metronom->got_spu_packet(this->stream->metronom, pci.hli.hl_gi.hli_s_ptm);
node->next->next = NULL;
xine_fast_memcpy(&node->next->pci, &pci, sizeof(pci_t));
diff --git a/src/libspudec/spu.h b/src/libspudec/spu.h
index 8d92146f0..464f77438 100644
--- a/src/libspudec/spu.h
+++ b/src/libspudec/spu.h
@@ -26,7 +26,7 @@
#define __SPU_H__
#ifdef HAVE_CONFIG_H
-#include <config.h>
+#include "config.h"
#endif
#include <inttypes.h>
diff --git a/src/libspudec/xine_spu_decoder.c b/src/libspudec/xine_spu_decoder.c
index 0ab91d906..b6c06ca05 100644
--- a/src/libspudec/xine_spu_decoder.c
+++ b/src/libspudec/xine_spu_decoder.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2004 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* Copyright (C) James Courtier-Dutton James@superbug.demon.co.uk - July 2001
*
@@ -22,6 +22,10 @@
* stuff needed to turn libspu into a xine decoder plugin
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
@@ -68,11 +72,8 @@ static const clut_t default_clut[] = {
};
static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {
- uint32_t stream_id;
- spudec_seq_t *cur_seq;
spudec_decoder_t *this = (spudec_decoder_t *) this_gen;
- stream_id = buf->type & 0x1f ;
- cur_seq = &this->spudec_stream_state[stream_id].ra_seq;
+ const uint8_t stream_id = buf->type & 0x1f ;
#ifdef LOG_DEBUG
printf("libspudec:got buffer type = %x\n", buf->type);
@@ -177,7 +178,6 @@ static void spudec_discontinuity (spu_decoder_t *this_gen) {
static void spudec_dispose (spu_decoder_t *this_gen) {
spudec_decoder_t *this = (spudec_decoder_t *) this_gen;
- int i;
video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out);
if( this->menu_handle >= 0 )
@@ -185,6 +185,7 @@ static void spudec_dispose (spu_decoder_t *this_gen) {
this->menu_handle);
this->menu_handle = -1;
+ int i;
for (i=0; i < MAX_STREAMS; i++) {
if( this->spudec_stream_state[i].overlay_handle >= 0 )
ovl_manager->free_handle(ovl_manager,
@@ -225,11 +226,9 @@ static void spudec_set_button (spu_decoder_t *this_gen, int32_t button, int32_t
* when video_overlay does menus */
video_overlay_manager_t *ovl_manager;
- video_overlay_event_t *overlay_event = NULL;
- vo_overlay_t *overlay = NULL;
- overlay_event = xine_xmalloc (sizeof(video_overlay_event_t));
+ video_overlay_event_t *overlay_event = calloc(1, sizeof(video_overlay_event_t));
+ vo_overlay_t *overlay = calloc(1, sizeof(vo_overlay_t));
- overlay = xine_xmalloc (sizeof(vo_overlay_t));
/* FIXME: Watch out for threads. We should really put a lock on this
* because events is a different thread than decode_data */
@@ -313,9 +312,8 @@ static void spudec_set_button (spu_decoder_t *this_gen, int32_t button, int32_t
static spu_decoder_t *open_plugin (spu_decoder_class_t *class_gen, xine_stream_t *stream) {
spudec_decoder_t *this ;
- int i;
- this = (spudec_decoder_t *) xine_xmalloc (sizeof (spudec_decoder_t));
+ this = (spudec_decoder_t *) calloc(1, sizeof (spudec_decoder_t));
this->spu_decoder.decode_data = spudec_decode_data;
this->spu_decoder.reset = spudec_reset;
@@ -328,7 +326,7 @@ static spu_decoder_t *open_plugin (spu_decoder_class_t *class_gen, xine_stream_t
this->menu_handle = -1;
this->buttonN = 1;
- this->event.object.overlay = xine_xmalloc(sizeof(vo_overlay_t));
+ this->event.object.overlay = calloc(1, sizeof(vo_overlay_t));
pthread_mutex_init(&this->nav_pci_lock, NULL);
this->pci_cur.pci.hli.hl_gi.hli_ss = 0;
@@ -337,6 +335,8 @@ static spu_decoder_t *open_plugin (spu_decoder_class_t *class_gen, xine_stream_t
this->ovl_caps = stream->video_out->get_capabilities(stream->video_out);
this->output_open = 0;
this->last_event_vpts = 0;
+
+ int i;
for (i=0; i < MAX_STREAMS; i++) {
this->spudec_stream_state[i].ra_seq.complete = 1;
this->spudec_stream_state[i].overlay_handle = -1;
@@ -376,7 +376,7 @@ static void *init_plugin (xine_t *xine, void *data) {
spudec_class_t *this;
- this = (spudec_class_t *) xine_xmalloc (sizeof (spudec_class_t));
+ this = calloc(1, sizeof (spudec_class_t));
this->decoder_class.open_plugin = open_plugin;
this->decoder_class.get_identifier = get_identifier;
diff --git a/src/libspudvb/Makefile.am b/src/libspudvb/Makefile.am
index 310c02f0b..8187346aa 100644
--- a/src/libspudvb/Makefile.am
+++ b/src/libspudvb/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
xineplug_LTLIBRARIES = xineplug_decode_spudvb.la
diff --git a/src/libspudvb/xine_spudvb_decoder.c b/src/libspudvb/xine_spudvb_decoder.c
index 602723fcb..bcb0cbf96 100644
--- a/src/libspudvb/xine_spudvb_decoder.c
+++ b/src/libspudvb/xine_spudvb_decoder.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 the xine project
+ * Copyright (C) 2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -28,6 +28,7 @@
#include "pthread.h"
#include <errno.h>
#include "xine_internal.h"
+#include "bswap.h"
#include "osd.h"
#define MAX_REGIONS 7
@@ -47,6 +48,7 @@ typedef struct {
} page_t;
typedef struct {
+ int version_number;
int width, height;
int empty;
int depth;
@@ -140,58 +142,50 @@ static void update_region (dvb_spu_decoder_t * this, int region_id, int region_w
dvbsub_func_t *dvbsub = this->dvbsub;
region_t *reg = &dvbsub->regions[region_id];
- page_t *page = &dvbsub->page;
/* reject invalid sizes and set some limits ! */
if ( region_width<=0 || region_height<=0 || region_width>720 || region_height>576 ) {
- if ( reg->img ) {
- free( reg->img );
- reg->img = NULL;
- }
+ free( reg->img );
+ reg->img = NULL;
#ifdef LOG
printf("SPUDVB: rejected region %d = %dx%d\n", region_id, region_width, region_height );
#endif
return;
}
- if ( reg->width*reg->height<region_width*region_height ) {
+ if ( (reg->width*reg->height) < (region_width*region_height) ) {
#ifdef LOG
printf("SPUDVB: update size of region %d = %dx%d\n", region_id, region_width, region_height);
#endif
- if ( reg->img ) {
- free( reg->img );
- reg->img = NULL;
- }
+ free( reg->img );
+ reg->img = NULL;
}
if ( !reg->img ) {
- if ( !(reg->img=xine_xmalloc(region_width*region_height)) ) {
+ if ( !(reg->img=malloc(region_width*region_height)) ) {
lprintf( "can't allocate mem for region %d\n", region_id );
return;
}
- fill_color = 15;
fill = 1;
}
-
+
if ( fill ) {
memset( reg->img, fill_color, region_width*region_height );
reg->empty = 1;
#ifdef LOG
- printf("SPUDVB : FILL REGION %d\n", region_id);
+ printf("SPUDVB : FILL REGION %d\n", region_id);
#endif
}
reg->width = region_width;
reg->height = region_height;
- page->regions[region_id].is_visible = 1;
}
static void do_plot (dvb_spu_decoder_t * this, int r, int x, int y, unsigned char pixel)
{
- int i;
- dvbsub_func_t *dvbsub = this->dvbsub;
+ dvbsub_func_t *const dvbsub = this->dvbsub;
- i = (y * dvbsub->regions[r].width) + x;
+ const int i = (y * dvbsub->regions[r].width) + x;
/* do some clipping */
if ( i<(dvbsub->regions[r].width*dvbsub->regions[r].height) ) {
dvbsub->regions[r].img[i] = pixel;
@@ -204,7 +198,7 @@ static void plot (dvb_spu_decoder_t * this, int r, int run_length, unsigned char
dvbsub_func_t *dvbsub = this->dvbsub;
- int x2 = dvbsub->x + run_length;
+ const int x2 = dvbsub->x + run_length;
while (dvbsub->x < x2) {
do_plot (this, r, dvbsub->x, dvbsub->y, pixel);
@@ -212,97 +206,90 @@ static void plot (dvb_spu_decoder_t * this, int r, int run_length, unsigned char
}
}
-static unsigned char next_nibble (dvb_spu_decoder_t * this)
+static uint8_t next_nibble (dvb_spu_decoder_t * this)
{
- unsigned char x;
dvbsub_func_t *dvbsub = this->dvbsub;
- if (dvbsub->nibble_flag == 0) {
- x = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4;
- dvbsub->nibble_flag = 1;
- }
- else {
- x = (dvbsub->buf[dvbsub->i++] & 0x0f);
- dvbsub->nibble_flag = 0;
- }
- return (x);
+ dvbsub->nibble_flag = !dvbsub->nibble_flag;
+
+ if (dvbsub->nibble_flag) /* Inverted! */
+ return (dvbsub->buf[dvbsub->i] & 0xf0) >> 4;
+ else
+ return (dvbsub->buf[dvbsub->i++] & 0x0f);
}
static void decode_4bit_pixel_code_string (dvb_spu_decoder_t * this, int r, int object_id, int ofs, int n)
{
- int next_bits, switch_1, switch_2, switch_3, run_length, pixel_code;
-
- dvbsub_func_t *dvbsub = this->dvbsub;
-
- int bits;
- unsigned int data;
- int j;
+ dvbsub_func_t *const dvbsub = this->dvbsub;
if (dvbsub->in_scanline == 0) {
dvbsub->in_scanline = 1;
}
dvbsub->nibble_flag = 0;
- j = dvbsub->i + n;
+ const int j = dvbsub->i + n;
while (dvbsub->i < j) {
- bits = 0;
- pixel_code = 0;
- next_bits = next_nibble (this);
+ int bits = 0;
+ const uint8_t next_bits = next_nibble (this);
if (next_bits != 0) {
- pixel_code = next_bits;
+ const uint8_t pixel_code = next_bits;
plot (this, r, 1, pixel_code);
bits += 4;
}
else {
bits += 4;
- data = next_nibble (this);
- switch_1 = (data & 0x08) >> 3;
+ const uint8_t data = next_nibble (this);
+ const uint8_t switch_1 = (data & 0x08) >> 3;
bits++;
if (switch_1 == 0) {
- run_length = (data & 0x07);
+ const uint8_t run_length = (data & 0x07);
bits += 3;
if (run_length != 0) {
- plot (this, r, run_length + 2, pixel_code);
+ plot (this, r, run_length + 2, 0);
}
else {
break;
}
}
else {
- switch_2 = (data & 0x04) >> 2;
+ const uint8_t switch_2 = (data & 0x04) >> 2;
bits++;
if (switch_2 == 0) {
- run_length = (data & 0x03);
+ const uint8_t run_length = (data & 0x03);
bits += 2;
- pixel_code = next_nibble (this);
+ const uint8_t pixel_code = next_nibble (this);
bits += 4;
plot (this, r, run_length + 4, pixel_code);
}
else {
- switch_3 = (data & 0x03);
+ const uint8_t switch_3 = (data & 0x03);
bits += 2;
switch (switch_3) {
case 0:
- plot (this, r, 1, pixel_code);
+ plot (this, r, 1, 0);
break;
case 1:
- plot (this, r, 2, pixel_code);
+ plot (this, r, 2, 0);
break;
case 2:
- run_length = next_nibble (this);
- bits += 4;
- pixel_code = next_nibble (this);
- bits += 4;
- plot (this, r, run_length + 9, pixel_code);
+ {
+ const uint8_t run_length = next_nibble (this);
+ bits += 4;
+ const uint8_t pixel_code = next_nibble (this);
+ bits += 4;
+ plot (this, r, run_length + 9, pixel_code);
+ }
break;
case 3:
- run_length = next_nibble (this);
- run_length = (run_length << 4) | next_nibble (this);
- bits += 8;
- pixel_code = next_nibble (this);
- bits += 4;
- plot (this, r, run_length + 25, pixel_code);
+ {
+ uint8_t run_length = next_nibble (this);
+ run_length = (run_length << 4) | next_nibble (this);
+ bits += 8;
+ const uint8_t pixel_code = next_nibble (this);
+ bits += 4;
+ plot (this, r, run_length + 25, pixel_code);
+ }
}
}
}
@@ -337,41 +324,36 @@ static void set_clut(dvb_spu_decoder_t *this,int CLUT_id,int CLUT_entry_id,int Y
}
static void process_CLUT_definition_segment(dvb_spu_decoder_t *this) {
- int page_id,
- segment_length,
- CLUT_id,
- CLUT_version_number;
-
- int CLUT_entry_id,
- CLUT_flag_8_bit,
- CLUT_flag_4_bit,
- CLUT_flag_2_bit,
- full_range_flag,
- Y_value,
- Cr_value,
- Cb_value,
- T_value;
dvbsub_func_t *dvbsub = this->dvbsub;
- int j;
-
- page_id=(dvbsub->buf[dvbsub->i]<<8)|dvbsub->buf[dvbsub->i+1]; dvbsub->i+=2;
- segment_length=(dvbsub->buf[dvbsub->i]<<8)|dvbsub->buf[dvbsub->i+1]; dvbsub->i+=2;
- j=dvbsub->i+segment_length;
-
- CLUT_id=dvbsub->buf[dvbsub->i++];
- CLUT_version_number=(dvbsub->buf[dvbsub->i]&0xf0)>>4;
+ /*
+ const uint16_t page_id= _X_BE_16(&dvbsub->buf[dvbsub->i]);
+ */
+ dvbsub->i+=2;
+ const uint16_t segment_length= _X_BE_16(&dvbsub->buf[dvbsub->i]);
+ dvbsub->i+=2;
+ const int j=dvbsub->i+segment_length;
+
+ const uint8_t CLUT_id=dvbsub->buf[dvbsub->i++];
+ /*
+ const uint8_t CLUT_version_number=(dvbsub->buf[dvbsub->i]&0xf0)>>4;
+ */
dvbsub->i++;
while (dvbsub->i < j) {
- CLUT_entry_id=dvbsub->buf[dvbsub->i++];
-
- CLUT_flag_2_bit=(dvbsub->buf[dvbsub->i]&0x80)>>7;
- CLUT_flag_4_bit=(dvbsub->buf[dvbsub->i]&0x40)>>6;
- CLUT_flag_8_bit=(dvbsub->buf[dvbsub->i]&0x20)>>5;
- full_range_flag=dvbsub->buf[dvbsub->i]&1;
+ const uint8_t CLUT_entry_id=dvbsub->buf[dvbsub->i++];
+ /*
+ const uint8_t CLUT_flag_2_bit=(dvbsub->buf[dvbsub->i]&0x80)>>7;
+ const uint8_t CLUT_flag_4_bit=(dvbsub->buf[dvbsub->i]&0x40)>>6;
+ const uint8_t CLUT_flag_8_bit=(dvbsub->buf[dvbsub->i]&0x20)>>5;
+ */
+ const uint8_t full_range_flag=dvbsub->buf[dvbsub->i]&1;
dvbsub->i++;
+ int Y_value,
+ Cr_value,
+ Cb_value,
+ T_value;
if (full_range_flag==1) {
Y_value=dvbsub->buf[dvbsub->i++];
Cr_value=dvbsub->buf[dvbsub->i++];
@@ -390,17 +372,14 @@ static void process_CLUT_definition_segment(dvb_spu_decoder_t *this) {
static void process_pixel_data_sub_block (dvb_spu_decoder_t * this, int r, int o, int ofs, int n)
{
- int data_type;
- int j;
-
dvbsub_func_t *dvbsub = this->dvbsub;
- j = dvbsub->i + n;
+ const int j = dvbsub->i + n;
dvbsub->x = (dvbsub->regions[r].object_pos[o]) >> 16;
dvbsub->y = ((dvbsub->regions[r].object_pos[o]) & 0xffff) + ofs;
while (dvbsub->i < j) {
- data_type = dvbsub->buf[dvbsub->i++];
+ const uint8_t data_type = dvbsub->buf[dvbsub->i++];
switch (data_type) {
case 0:
@@ -423,82 +402,86 @@ static void process_pixel_data_sub_block (dvb_spu_decoder_t * this, int r, int o
static void process_page_composition_segment (dvb_spu_decoder_t * this)
{
- int segment_length;
- int region_id, region_x, region_y;
- int j;
- int r;
dvbsub_func_t *dvbsub = this->dvbsub;
- dvbsub->page.page_id = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1];
+ dvbsub->page.page_id = _X_BE_16(&dvbsub->buf[dvbsub->i]);
dvbsub->i += 2;
- segment_length = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1];
+ const uint16_t segment_length = _X_BE_16(&dvbsub->buf[dvbsub->i]);
dvbsub->i += 2;
- j = dvbsub->i + segment_length;
+ const int j = dvbsub->i + segment_length;
dvbsub->page.page_time_out = dvbsub->buf[dvbsub->i++];
+ if ( dvbsub->page.page_time_out>6 ) /* some timeout are insane, e.g. 65s ! */
+ dvbsub->page.page_time_out = 6;
- dvbsub->page.page_version_number = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4;
+ int version = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4;
+ if ( version == dvbsub->page.page_version_number )
+ return;
+ dvbsub->page.page_version_number = version;
dvbsub->page.page_state = (dvbsub->buf[dvbsub->i] & 0x0c) >> 2;
dvbsub->i++;
- if (dvbsub->page.page_state==2) {
- for (r=0; r<MAX_REGIONS; r++)
- dvbsub->page.regions[r].is_visible = 0;
- }
- else if ( dvbsub->page.page_state!=0 && dvbsub->page.page_state!=1 ) {
- return;
+ int r;
+ for (r=0; r<MAX_REGIONS; r++) { /* reset */
+ dvbsub->page.regions[r].is_visible = 0;
}
while (dvbsub->i < j) {
- region_id = dvbsub->buf[dvbsub->i++];
+ const uint8_t region_id = dvbsub->buf[dvbsub->i++];
dvbsub->i++; /* reserved */
- region_x = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1];
+ const uint16_t region_x = _X_BE_16(&dvbsub->buf[dvbsub->i]);
dvbsub->i += 2;
- region_y = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1];
+ const uint16_t region_y = _X_BE_16(&dvbsub->buf[dvbsub->i]);
dvbsub->i += 2;
dvbsub->page.regions[region_id].x = region_x;
dvbsub->page.regions[region_id].y = region_y;
+ dvbsub->page.regions[region_id].is_visible = 1;
}
}
static void process_region_composition_segment (dvb_spu_decoder_t * this)
{
- int segment_length,
- region_id,
- region_version_number,
- region_fill_flag, region_width, region_height, region_level_of_compatibility, region_depth, CLUT_id, region_8_bit_pixel_code, region_4_bit_pixel_code, region_2_bit_pixel_code;
- int object_id, object_type, object_provider_flag, object_x, object_y, foreground_pixel_code, background_pixel_code;
- int j;
- int o;
dvbsub_func_t *dvbsub = this->dvbsub;
- dvbsub->page.page_id = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1];
+ dvbsub->page.page_id = _X_BE_16(&dvbsub->buf[dvbsub->i]);
dvbsub->i += 2;
- segment_length = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1];
+ const uint16_t segment_length = _X_BE_16(&dvbsub->buf[dvbsub->i]);
dvbsub->i += 2;
- j = dvbsub->i + segment_length;
+ const int j = dvbsub->i + segment_length;
- region_id = dvbsub->buf[dvbsub->i++];
- region_version_number = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4;
- region_fill_flag = (dvbsub->buf[dvbsub->i] & 0x08) >> 3;
+ const uint8_t region_id = dvbsub->buf[dvbsub->i++];
+ const uint8_t region_version_number = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4;
+ const uint8_t region_fill_flag = (dvbsub->buf[dvbsub->i] & 0x08) >> 3;
dvbsub->i++;
- region_width = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1];
+ const uint16_t region_width = _X_BE_16(&dvbsub->buf[dvbsub->i]);
dvbsub->i += 2;
- region_height = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1];
+ const uint16_t region_height = _X_BE_16(&dvbsub->buf[dvbsub->i]);
dvbsub->i += 2;
- region_level_of_compatibility = (dvbsub->buf[dvbsub->i] & 0xe0) >> 5;
- region_depth = (dvbsub->buf[dvbsub->i] & 0x1c) >> 2;
+ /*
+ const uint8_t region_level_of_compatibility = (dvbsub->buf[dvbsub->i] & 0xe0) >> 5;
+ const uint8_t region_depth = (dvbsub->buf[dvbsub->i] & 0x1c) >> 2;
+ */
+ dvbsub->i++;
+ const uint8_t CLUT_id = dvbsub->buf[dvbsub->i++];
+ /*
+ const uint8_t region_8_bit_pixel_code = dvbsub->buf[dvbsub->i];
+ */
dvbsub->i++;
- CLUT_id = dvbsub->buf[dvbsub->i++];
- region_8_bit_pixel_code = dvbsub->buf[dvbsub->i++];
- region_4_bit_pixel_code = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4;
- region_2_bit_pixel_code = (dvbsub->buf[dvbsub->i] & 0x0c) >> 2;
+ const uint8_t region_4_bit_pixel_code = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4;
+ /*
+ const uint8_t region_2_bit_pixel_code = (dvbsub->buf[dvbsub->i] & 0x0c) >> 2;
+ */
dvbsub->i++;
if(region_id>=MAX_REGIONS)
return;
+
+ if ( dvbsub->regions[region_id].version_number == region_version_number )
+ return;
+
+ dvbsub->regions[region_id].version_number = region_version_number;
/* Check if region size has changed and fill background. */
update_region (this, region_id, region_width, region_height, region_fill_flag, region_4_bit_pixel_code);
@@ -508,25 +491,33 @@ static void process_region_composition_segment (dvb_spu_decoder_t * this)
dvbsub->regions[region_id].objects_start = dvbsub->i;
dvbsub->regions[region_id].objects_end = j;
- for (o = 0; o < 65536; o++) {
- dvbsub->regions[region_id].object_pos[o] = 0xffffffff;
+ {
+ int o;
+ for (o = 0; o < 65536; o++) {
+ dvbsub->regions[region_id].object_pos[o] = 0xffffffff;
+ }
}
while (dvbsub->i < j) {
- object_id = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1];
+ const uint16_t object_id = _X_BE_16(&dvbsub->buf[dvbsub->i]);
dvbsub->i += 2;
- object_type = (dvbsub->buf[dvbsub->i] & 0xc0) >> 6;
- object_provider_flag = (dvbsub->buf[dvbsub->i] & 0x30) >> 4;
- object_x = ((dvbsub->buf[dvbsub->i] & 0x0f) << 8) | dvbsub->buf[dvbsub->i + 1];
+ const uint8_t object_type = (dvbsub->buf[dvbsub->i] & 0xc0) >> 6;
+ /*
+ const uint8_t object_provider_flag = (dvbsub->buf[dvbsub->i] & 0x30) >> 4;
+ */
+ const uint16_t object_x = ((dvbsub->buf[dvbsub->i] & 0x0f) << 8) | dvbsub->buf[dvbsub->i + 1];
dvbsub->i += 2;
- object_y = ((dvbsub->buf[dvbsub->i] & 0x0f) << 8) | dvbsub->buf[dvbsub->i + 1];
+ const uint16_t object_y = ((dvbsub->buf[dvbsub->i] & 0x0f) << 8) | dvbsub->buf[dvbsub->i + 1];
dvbsub->i += 2;
dvbsub->regions[region_id].object_pos[object_id] = (object_x << 16) | object_y;
if ((object_type == 0x01) || (object_type == 0x02)) {
- foreground_pixel_code = dvbsub->buf[dvbsub->i++];
- background_pixel_code = dvbsub->buf[dvbsub->i++];
+ /*
+ const uint8_t foreground_pixel_code = dvbsub->buf[dvbsub->i];
+ const uint8_t background_pixel_code = dvbsub->buf[dvbsub->i+1];
+ */
+ dvbsub->i += 2;
}
}
@@ -534,49 +525,48 @@ static void process_region_composition_segment (dvb_spu_decoder_t * this)
static void process_object_data_segment (dvb_spu_decoder_t * this)
{
- int segment_length, object_id, object_version_number, object_coding_method, non_modifying_colour_flag;
-
- int top_field_data_block_length, bottom_field_data_block_length;
-
dvbsub_func_t *dvbsub = this->dvbsub;
- int j;
- int old_i;
- int r;
-
dvbsub->page.page_id = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1];
dvbsub->i += 2;
- segment_length = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1];
+ /*
+ const uint16_t segment_length = _X_BE_16(&dvbsub->buf[dvbsub->i]);
+ */
dvbsub->i += 2;
- j = dvbsub->i + segment_length;
- object_id = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1];
+ const uint16_t object_id = _X_BE_16(&dvbsub->buf[dvbsub->i]);
dvbsub->i += 2;
dvbsub->curr_obj = object_id;
- object_version_number = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4;
- object_coding_method = (dvbsub->buf[dvbsub->i] & 0x0c) >> 2;
- non_modifying_colour_flag = (dvbsub->buf[dvbsub->i] & 0x02) >> 1;
+ const uint8_t object_coding_method = (dvbsub->buf[dvbsub->i] & 0x0c) >> 2;
+ /*
+ const uint8_t object_version_number = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4;
+ const uint8_t non_modifying_colour_flag = (dvbsub->buf[dvbsub->i] & 0x02) >> 1;
+ */
dvbsub->i++;
- old_i = dvbsub->i;
+ if ( object_coding_method != 0 )
+ return;
+
+ const int old_i = dvbsub->i;
+ int r;
for (r = 0; r < MAX_REGIONS; r++) {
/* If this object is in this region... */
- if (dvbsub->regions[r].img) {
- if (dvbsub->regions[r].object_pos[object_id] != 0xffffffff) {
- dvbsub->i = old_i;
- if (object_coding_method == 0) {
- top_field_data_block_length = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1];
- dvbsub->i += 2;
- bottom_field_data_block_length = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1];
- dvbsub->i += 2;
-
- process_pixel_data_sub_block (this, r, object_id, 0, top_field_data_block_length);
-
- process_pixel_data_sub_block (this, r, object_id, 1, bottom_field_data_block_length);
- }
- }
- }
+ if (!dvbsub->regions[r].img)
+ continue;
+
+ if (dvbsub->regions[r].object_pos[object_id] == 0xffffffff)
+ continue;
+
+ dvbsub->i = old_i;
+
+ const uint16_t top_field_data_block_length = _X_BE_16(&dvbsub->buf[dvbsub->i]);
+ dvbsub->i += 2;
+ const uint16_t bottom_field_data_block_length = _X_BE_16(&dvbsub->buf[dvbsub->i]);
+ dvbsub->i += 2;
+
+ process_pixel_data_sub_block (this, r, object_id, 0, top_field_data_block_length);
+ process_pixel_data_sub_block (this, r, object_id, 1, bottom_field_data_block_length);
}
}
@@ -603,38 +593,37 @@ static void* dvbsub_timer_func(void *this_gen)
{
dvb_spu_decoder_t *this = (dvb_spu_decoder_t *) this_gen;
pthread_mutex_lock(&this->dvbsub_osd_mutex);
- int i;
/* If we're cancelled via pthread_cancel, unlock the mutex */
pthread_cleanup_push(unlock_mutex_cancellation_func, &this->dvbsub_osd_mutex);
- while(1)
- {
+ while(1) {
/* Record the current timeout, and wait - note that pthread_cond_timedwait
will unlock the mutex on entry, and lock it on exit */
struct timespec timeout = this->dvbsub_hide_timeout;
- int result = pthread_cond_timedwait(&this->dvbsub_restart_timeout,
- &this->dvbsub_osd_mutex,
- &this->dvbsub_hide_timeout);
- if(result == ETIMEDOUT &&
- timeout.tv_sec == this->dvbsub_hide_timeout.tv_sec &&
- timeout.tv_nsec == this->dvbsub_hide_timeout.tv_nsec)
- {
- /* We timed out, and no-one changed the timeout underneath us.
- Hide the OSD, then wait until we're signalled. */
- if(this && this->stream && this->stream->osd_renderer)
- {
- for ( i=0; i<MAX_REGIONS; i++ ) {
- if ( this->dvbsub->regions[i].osd ) {
- this->stream->osd_renderer->hide( this->dvbsub->regions[i].osd, 0 );
+ const int result = pthread_cond_timedwait(&this->dvbsub_restart_timeout,
+ &this->dvbsub_osd_mutex,
+ &this->dvbsub_hide_timeout);
+ if(result != ETIMEDOUT ||
+ timeout.tv_sec != this->dvbsub_hide_timeout.tv_sec ||
+ timeout.tv_nsec != this->dvbsub_hide_timeout.tv_nsec)
+ continue;
+
+ /* We timed out, and no-one changed the timeout underneath us.
+ Hide the OSD, then wait until we're signalled. */
+ if(this && this->stream && this->stream->osd_renderer) {
+ int i;
+ for ( i=0; i<MAX_REGIONS; i++ ) {
+ if ( !this->dvbsub->regions[i].osd )
+ continue;
+
+ this->stream->osd_renderer->hide( this->dvbsub->regions[i].osd, 0 );
#ifdef LOG
- printf("SPUDVB: thread hiding = %d\n",i);
+ printf("SPUDVB: thread hiding = %d\n",i);
#endif
- }
- }
}
- pthread_cond_wait(&this->dvbsub_restart_timeout, &this->dvbsub_osd_mutex);
}
+ pthread_cond_wait(&this->dvbsub_restart_timeout, &this->dvbsub_osd_mutex);
}
pthread_cleanup_pop(1);
@@ -654,26 +643,29 @@ static void downscale_region_image( region_t *reg, unsigned char *dest, int dest
static void draw_subtitles (dvb_spu_decoder_t * this)
{
- int r;
- int display=0;
int64_t dum;
- int dest_width=0, dest_height, reg_width;
+ int dest_width=0, dest_height;
this->stream->video_out->status(this->stream->video_out, NULL, &dest_width, &dest_height, &dum);
- unsigned char tmp[dest_width*576];
- unsigned char *reg;
if ( !dest_width )
return;
/* render all regions onto the page */
- for ( r=0; r<MAX_REGIONS; r++ ) {
- if ( this->dvbsub->page.regions[r].is_visible )
- display++;
+ {
+ int r;
+ int display = 0;
+ for ( r=0; r<MAX_REGIONS; r++ ) {
+ if ( this->dvbsub->page.regions[r].is_visible ) {
+ display = 1;
+ break;
+ }
+ }
+ if ( !display )
+ return;
}
- if ( !display )
- return;
+ int r;
for (r = 0; r < MAX_REGIONS; r++) {
if (this->dvbsub->regions[r].img) {
if (this->dvbsub->page.regions[r].is_visible && !this->dvbsub->regions[r].empty) {
@@ -682,6 +674,10 @@ static void draw_subtitles (dvb_spu_decoder_t * this)
continue;
/* clear osd */
this->stream->osd_renderer->clear( this->dvbsub->regions[r].osd );
+
+ uint8_t *reg;
+ int reg_width;
+ uint8_t tmp[dest_width*576];
if (this->dvbsub->regions[r].width>dest_width) {
downscale_region_image(&this->dvbsub->regions[r], tmp, dest_width);
reg = tmp;
@@ -702,6 +698,9 @@ static void draw_subtitles (dvb_spu_decoder_t * this)
printf("SPUDVB: this->vpts=%llu\n",this->vpts);
#endif
for ( r=0; r<MAX_REGIONS; r++ ) {
+#ifdef LOG
+ printf("SPUDVB : region=%d, visible=%d, osd=%d, empty=%d\n", r, this->dvbsub->page.regions[r].is_visible, this->dvbsub->regions[r].osd?1:0, this->dvbsub->regions[r].empty );
+#endif
if ( this->dvbsub->page.regions[r].is_visible && this->dvbsub->regions[r].osd && !this->dvbsub->regions[r].empty ) {
this->stream->osd_renderer->set_position( this->dvbsub->regions[r].osd, this->dvbsub->page.regions[r].x, this->dvbsub->page.regions[r].y );
this->stream->osd_renderer->show( this->dvbsub->regions[r].osd, this->vpts );
@@ -731,12 +730,6 @@ static void draw_subtitles (dvb_spu_decoder_t * this)
static void spudec_decode_data (spu_decoder_t * this_gen, buf_element_t * buf)
{
dvb_spu_decoder_t *this = (dvb_spu_decoder_t *) this_gen;
- int new_i;
- int data_identifier, subtitle_stream_id;
- int segment_length, segment_type;
- int PES_header_data_length;
- int PES_packet_length;
- int i;
if((buf->type & 0xffff0000)!=BUF_SPU_DVB)
return;
@@ -746,6 +739,7 @@ static void spudec_decode_data (spu_decoder_t * this_gen, buf_element_t * buf)
if (buf->decoder_info[2] == 0) {
/* Hide the osd - note that if the timeout thread times out, it'll rehide, which is harmless */
pthread_mutex_lock(&this->dvbsub_osd_mutex);
+ int i;
for ( i=0; i<MAX_REGIONS; i++ ) {
if ( this->dvbsub->regions[i].osd )
this->stream->osd_renderer->hide( this->dvbsub->regions[i].osd, 0 );
@@ -779,12 +773,12 @@ static void spudec_decode_data (spu_decoder_t * this_gen, buf_element_t * buf)
* because buf->pts could be too far in future and metronom won't accept
* further backwards pts (see metronom_got_spu_packet) */
if (buf->pts) {
- metronom_t *metronom = this->stream->metronom;
- int64_t vpts_offset = metronom->get_option( metronom, METRONOM_VPTS_OFFSET );
- int64_t spu_offset = metronom->get_option( metronom, METRONOM_SPU_OFFSET );
- int64_t vpts = (int64_t)(buf->pts)+vpts_offset+spu_offset;
- metronom_clock_t *clock = this->stream->xine->clock;
- int64_t curvpts = clock->get_current_time( clock );
+ metronom_t *const metronom = this->stream->metronom;
+ const int64_t vpts_offset = metronom->get_option( metronom, METRONOM_VPTS_OFFSET );
+ const int64_t spu_offset = metronom->get_option( metronom, METRONOM_SPU_OFFSET );
+ const int64_t vpts = (int64_t)(buf->pts)+vpts_offset+spu_offset;
+ metronom_clock_t *const clock = this->stream->xine->clock;
+ const int64_t curvpts = clock->get_current_time( clock );
/* if buf->pts is unreliable, show page asap (better than nothing) */
#ifdef LOG
printf("SPUDVB: spu_vpts=%lld - current_vpts=%lld\n", vpts, curvpts);
@@ -795,58 +789,62 @@ static void spudec_decode_data (spu_decoder_t * this_gen, buf_element_t * buf)
this->vpts = vpts;
}
+ /* completely ignore pts since it makes a lot of problems with various providers */
+ this->vpts = 0;
+
/* process the pes section */
- PES_packet_length = this->pes_pkt_size;
+ const int PES_packet_length = this->pes_pkt_size;
- this->dvbsub->buf = this->pes_pkt;
+ this->dvbsub->buf = this->pes_pkt;
- PES_header_data_length = 0;
- this->dvbsub->i = 0;
+ this->dvbsub->i = 0;
- data_identifier = this->dvbsub->buf[this->dvbsub->i++];
- subtitle_stream_id = this->dvbsub->buf[this->dvbsub->i++];
+ /*
+ const uint8_t data_identifier = this->dvbsub->buf[this->dvbsub->i];
+ const uint8_t subtitle_stream_id = this->dvbsub->buf[this->dvbsub->i+1];
+ */
+ this->dvbsub->i += 2;
- while (this->dvbsub->i <= (PES_packet_length)) {
- /* SUBTITLING SEGMENT */
- this->dvbsub->i++;
- segment_type = this->dvbsub->buf[this->dvbsub->i++];
+ while (this->dvbsub->i <= (PES_packet_length)) {
+ /* SUBTITLING SEGMENT */
+ this->dvbsub->i++;
+ const uint8_t segment_type = this->dvbsub->buf[this->dvbsub->i++];
- this->dvbsub->page.page_id = (this->dvbsub->buf[this->dvbsub->i] << 8) | this->dvbsub->buf[this->dvbsub->i + 1];
- segment_length = (this->dvbsub->buf[this->dvbsub->i + 2] << 8) | this->dvbsub->buf[this->dvbsub->i + 3];
- new_i = this->dvbsub->i + segment_length + 4;
+ this->dvbsub->page.page_id = (this->dvbsub->buf[this->dvbsub->i] << 8) | this->dvbsub->buf[this->dvbsub->i + 1];
+ const uint16_t segment_length = _X_BE_16(&this->dvbsub->buf[this->dvbsub->i + 2]);
+ const int new_i = this->dvbsub->i + segment_length + 4;
- /* only process complete segments */
- if(new_i > (this->pes_pkt_wrptr - this->pes_pkt))
- break;
- /* verify we've the right segment */
- if(this->dvbsub->page.page_id==this->spu_descriptor->comp_page_id){
- /* SEGMENT_DATA_FIELD */
- switch (segment_type & 0xff) {
- case 0x10:
- process_page_composition_segment (this);
- break;
- case 0x11:
- process_region_composition_segment (this);
- break;
- case 0x12:
- process_CLUT_definition_segment(this);
- break;
- case 0x13:
- process_object_data_segment (this);
- break;
- case 0x80: /* Page is now completely rendered */
- draw_subtitles( this );
- break;
- default:
- return;
- break;
- }
- }
- this->dvbsub->i = new_i;
- }
+ /* only process complete segments */
+ if(new_i > (this->pes_pkt_wrptr - this->pes_pkt))
+ break;
- return;
+ /* verify we've the right segment */
+ if(this->dvbsub->page.page_id==this->spu_descriptor->comp_page_id){
+ /* SEGMENT_DATA_FIELD */
+ switch (segment_type) {
+ case 0x10:
+ process_page_composition_segment(this);
+ break;
+ case 0x11:
+ process_region_composition_segment(this);
+ break;
+ case 0x12:
+ process_CLUT_definition_segment(this);
+ break;
+ case 0x13:
+ process_object_data_segment (this);
+ break;
+ case 0x80:
+ draw_subtitles( this ); /* Page is now completely rendered */
+ break;
+ default:
+ return;
+ break;
+ }
+ }
+ this->dvbsub->i = new_i;
+ }
}
static void spudec_reset (spu_decoder_t * this_gen)
@@ -859,7 +857,9 @@ static void spudec_reset (spu_decoder_t * this_gen)
for ( i=0; i<MAX_REGIONS; i++ ) {
if ( this->dvbsub->regions[i].osd )
this->stream->osd_renderer->hide(this->dvbsub->regions[i].osd, 0);
+ this->dvbsub->regions[i].version_number = -1;
}
+ this->dvbsub->page.page_version_number = -1;
pthread_mutex_unlock(&this->dvbsub_osd_mutex);
}
@@ -872,42 +872,31 @@ static void spudec_discontinuity (spu_decoder_t * this_gen)
static void spudec_dispose (spu_decoder_t * this_gen)
{
dvb_spu_decoder_t *this = (dvb_spu_decoder_t *) this_gen;
- int i;
pthread_cancel(this->dvbsub_timer_thread);
pthread_join(this->dvbsub_timer_thread, NULL);
pthread_mutex_destroy(&this->dvbsub_osd_mutex);
pthread_cond_destroy(&this->dvbsub_restart_timeout);
- if(this->spu_descriptor){
- free(this->spu_descriptor);
- this->spu_descriptor=NULL;
- }
+ free(this->spu_descriptor);
+ this->spu_descriptor=NULL;
+ int i;
for ( i=0; i<MAX_REGIONS; i++ ) {
- if ( this->dvbsub->regions[i].img )
- free( this->dvbsub->regions[i].img );
+ free( this->dvbsub->regions[i].img );
if ( this->dvbsub->regions[i].osd )
this->stream->osd_renderer->free_object( this->dvbsub->regions[i].osd );
}
- if (this->pes_pkt)
- free (this->pes_pkt);
-
- if (this->dvbsub)
- free (this->dvbsub);
-
+ free (this->pes_pkt);
+ free (this->dvbsub);
free (this);
}
static spu_decoder_t *dvb_spu_class_open_plugin (spu_decoder_class_t * class_gen, xine_stream_t * stream)
{
-
- int i;
- dvb_spu_decoder_t *this;
- dvb_spu_class_t *class = (dvb_spu_class_t *) class_gen;
-
- this = (dvb_spu_decoder_t *) xine_xmalloc (sizeof (dvb_spu_decoder_t));
+ dvb_spu_decoder_t *this = calloc(1, sizeof (dvb_spu_decoder_t));
+ dvb_spu_class_t *class = (dvb_spu_class_t *)class_gen;
this->spu_decoder.decode_data = spudec_decode_data;
this->spu_decoder.reset = spudec_reset;
@@ -919,17 +908,10 @@ static spu_decoder_t *dvb_spu_class_open_plugin (spu_decoder_class_t * class_gen
this->class = class;
this->stream = stream;
- this->pes_pkt = xine_xmalloc (1024*65);
- this->spu_descriptor = xine_xmalloc(sizeof(spu_dvb_descriptor_t));
+ this->pes_pkt = calloc(65, 1024);
+ this->spu_descriptor = calloc(1, sizeof(spu_dvb_descriptor_t));
- this->dvbsub = xine_xmalloc (sizeof (dvbsub_func_t));
-
- for (i = 0; i < MAX_REGIONS; i++) {
- this->dvbsub->page.regions[i].is_visible = 0;
- this->dvbsub->regions[i].img = NULL;
- this->dvbsub->regions[i].osd = NULL;
- this->dvbsub->regions[i].CLUT_id = 0;
- }
+ this->dvbsub = calloc(1, sizeof (dvbsub_func_t));
pthread_mutex_init(&this->dvbsub_osd_mutex, NULL);
pthread_cond_init(&this->dvbsub_restart_timeout, NULL);
@@ -957,9 +939,7 @@ static char *dvb_spu_class_get_description (spu_decoder_class_t * this)
static void *init_spu_decoder_plugin (xine_t * xine, void *data)
{
-
- dvb_spu_class_t *this;
- this = (dvb_spu_class_t *) xine_xmalloc (sizeof (dvb_spu_class_t));
+ dvb_spu_class_t *this = calloc(1, sizeof (dvb_spu_class_t));
this->class.open_plugin = dvb_spu_class_open_plugin;
this->class.get_identifier = dvb_spu_class_get_identifier;
diff --git a/src/libsputext/Makefile.am b/src/libsputext/Makefile.am
index 4f03d7fa9..62258933d 100644
--- a/src/libsputext/Makefile.am
+++ b/src/libsputext/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
AM_LDFLAGS = $(xineplug_ldflags)
diff --git a/src/libsputext/demux_sputext.c b/src/libsputext/demux_sputext.c
index acf8e10f6..198c30498 100644
--- a/src/libsputext/demux_sputext.c
+++ b/src/libsputext/demux_sputext.c
@@ -129,7 +129,6 @@ static int eol(char p) {
}
static inline void trail_space(char *s) {
- int i;
while (isspace(*s)) {
char *copy = s;
do {
@@ -137,7 +136,7 @@ static inline void trail_space(char *s) {
copy++;
} while(*copy);
}
- i = strlen(s) - 1;
+ size_t i = strlen(s) - 1;
while (i > 0 && isspace(s[i]))
s[i--] = '\0';
}
@@ -147,10 +146,8 @@ static inline void trail_space(char *s) {
*/
static char *read_line_from_input(demux_sputext_t *this, char *line, off_t len) {
off_t nread = 0;
- char *s;
- int linelen;
- if ((len - this->buflen) > 512) {
+ if ((len - this->buflen) > 512 && len < SUB_BUFSIZE) {
if((nread = this->input->read(this->input,
&this->buf[this->buflen], len - this->buflen)) < 0) {
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "read failed.\n");
@@ -161,11 +158,11 @@ static char *read_line_from_input(demux_sputext_t *this, char *line, off_t len)
this->buflen += nread;
this->buf[this->buflen] = '\0';
- s = strchr(this->buf, '\n');
+ char *s = strchr(this->buf, '\n');
if (line && (s || this->buflen)) {
- linelen = s ? (s - this->buf) + 1 : this->buflen;
+ size_t linelen = s ? (s - this->buf) + 1 : this->buflen;
memcpy(line, this->buf, linelen);
line[linelen] = '\0';
@@ -184,13 +181,12 @@ static subtitle_t *sub_read_line_sami(demux_sputext_t *this, subtitle_t *current
static char line[LINE_LEN + 1];
static char *s = NULL;
- char text[LINE_LEN + 1], *p, *q;
- int state;
+ char text[LINE_LEN + 1];
- p = NULL;
+ char *p = NULL;
current->lines = current->start = 0;
current->end = -1;
- state = 0;
+ int state = 0;
/* read the first line */
if (!s)
@@ -230,14 +226,16 @@ static subtitle_t *sub_read_line_sami(demux_sputext_t *this, subtitle_t *current
continue;
case 4: /* get current->end or skip <TAG> */
- q = strstr (s, "Start=");
- if (q) {
- current->end = strtol (q + 6, &q, 0) / 10 - 1;
- *p = '\0'; trail_space (text);
- if (text[0] != '\0')
- current->text[current->lines++] = strdup (text);
- if (current->lines > 0) { state = 99; break; }
- state = 0; continue;
+ {
+ char *q = strstr (s, "Start=");
+ if (q) {
+ current->end = strtol (q + 6, &q, 0) / 10 - 1;
+ *p = '\0'; trail_space (text);
+ if (text[0] != '\0')
+ current->text[current->lines++] = strdup (text);
+ if (current->lines > 0) { state = 99; break; }
+ state = 0; continue;
+ }
}
s = strchr (s, '>');
if (s) { s++; state = 3; continue; }
@@ -255,19 +253,14 @@ static subtitle_t *sub_read_line_sami(demux_sputext_t *this, subtitle_t *current
static char *sub_readtext(char *source, char **dest) {
- int len=0;
+ size_t len=0;
char *p=source;
while ( !eol(*p) && *p!= '|' ) {
p++,len++;
}
- *dest= (char *)xine_xmalloc (len+1);
- if (!dest)
- return ERR;
-
- strncpy(*dest, source, len);
- (*dest)[len]=0;
+ *dest = strndup(source, len);
while (*p=='\r' || *p=='\n' || *p=='|')
p++;
@@ -280,8 +273,6 @@ static subtitle_t *sub_read_line_microdvd(demux_sputext_t *this, subtitle_t *cur
char line[LINE_LEN + 1];
char line2[LINE_LEN + 1];
- char *p, *next;
- int i;
memset (current, 0, sizeof(subtitle_t));
@@ -292,9 +283,10 @@ static subtitle_t *sub_read_line_microdvd(demux_sputext_t *this, subtitle_t *cur
(sscanf (line, "{%ld}{%ld}%" LINE_LEN_QUOT "[^\r\n]", &(current->start), &(current->end),line2) !=3)
);
- p=line2;
+ char *p=line2;
- next=p, i=0;
+ char *next=p;
+ size_t i=0;
while ((next =sub_readtext (next, &(current->text[i])))) {
if (current->text[i]==ERR) return ERR;
i++;
@@ -310,33 +302,33 @@ static subtitle_t *sub_read_line_microdvd(demux_sputext_t *this, subtitle_t *cur
}
static subtitle_t *sub_read_line_subviewer(demux_sputext_t *this, subtitle_t *current) {
-
char line[LINE_LEN + 1];
- int a1,a2,a3,a4,b1,b2,b3,b4;
- char *p=NULL, *q=NULL;
- int len;
memset (current, 0, sizeof(subtitle_t));
while (1) {
if (!read_line_from_input(this, line, LINE_LEN)) return NULL;
- if (sscanf (line, "%d:%d:%d.%d,%d:%d:%d.%d",&a1,&a2,&a3,&a4,&b1,&b2,&b3,&b4) < 8) {
- if (sscanf (line, "%d:%d:%d,%d,%d:%d:%d,%d",&a1,&a2,&a3,&a4,&b1,&b2,&b3,&b4) < 8)
- continue;
+
+ {
+ int a1,a2,a3,a4,b1,b2,b3,b4;
+ if (sscanf (line, "%d:%d:%d.%d,%d:%d:%d.%d",&a1,&a2,&a3,&a4,&b1,&b2,&b3,&b4) < 8) {
+ if (sscanf (line, "%d:%d:%d,%d,%d:%d:%d,%d",&a1,&a2,&a3,&a4,&b1,&b2,&b3,&b4) < 8)
+ continue;
+ }
+
+ current->start = a1*360000+a2*6000+a3*100+a4;
+ current->end = b1*360000+b2*6000+b3*100+b4;
}
- current->start = a1*360000+a2*6000+a3*100+a4;
- current->end = b1*360000+b2*6000+b3*100+b4;
-
+
if (!read_line_from_input(this, line, LINE_LEN))
return NULL;
- p=q=line;
+ char *p = line, *q = line;
for (current->lines=1; current->lines <= SUB_MAX_TEXT; current->lines++) {
+ size_t len;
for (q=p,len=0; *p && *p!='\r' && *p!='\n' && *p!='|' && strncasecmp(p,"[br]",4); p++,len++);
- current->text[current->lines-1]=(char *)xine_xmalloc (len+1);
+ current->text[current->lines-1] = strndup(q, len);
if (!current->text[current->lines-1]) return ERR;
- strncpy (current->text[current->lines-1], q, len);
- current->text[current->lines-1][len]='\0';
if (!*p || *p=='\r' || *p=='\n') break;
if (*p=='[') while (*p++!=']');
if (*p=='|') p++;
@@ -348,25 +340,27 @@ static subtitle_t *sub_read_line_subviewer(demux_sputext_t *this, subtitle_t *cu
}
static subtitle_t *sub_read_line_subrip(demux_sputext_t *this,subtitle_t *current) {
- char line[LINE_LEN + 1];
- int a1,a2,a3,a4,b1,b2,b3,b4;
- int i,end_sub;
-
memset(current,0,sizeof(subtitle_t));
- do {
- if(!read_line_from_input(this,line,LINE_LEN))
- return NULL;
- i = sscanf(line,"%d:%d:%d%*[,.]%d --> %d:%d:%d%*[,.]%d",&a1,&a2,&a3,&a4,&b1,&b2,&b3,&b4);
- } while(i < 8);
- current->start = a1*360000+a2*6000+a3*100+a4/10;
- current->end = b1*360000+b2*6000+b3*100+b4/10;
- i=0;
- end_sub=0;
+
+ {
+ int a1,a2,a3,a4,b1,b2,b3,b4,i;
+ do {
+ char line[LINE_LEN + 1];
+ if(!read_line_from_input(this,line,LINE_LEN))
+ return NULL;
+ i = sscanf(line,"%d:%d:%d%*[,.]%d --> %d:%d:%d%*[,.]%d",&a1,&a2,&a3,&a4,&b1,&b2,&b3,&b4);
+ } while(i < 8);
+ current->start = a1*360000+a2*6000+a3*100+a4/10;
+ current->end = b1*360000+b2*6000+b3*100+b4/10;
+ }
+
+ int i=0;
+ int end_sub=0;
do {
char *p; /* pointer to the curently read char */
- char temp_line[SUB_BUFSIZE]; /* subtitle line that will be transfered to current->text[i] */
- int temp_index; /* ... and its index wich 'points' to the first EMPTY place -> last read char is at temp_index-1 if temp_index>0 */
- temp_line[SUB_BUFSIZE-1]='\0'; /* just in case... */
+ char line[LINE_LEN + 1];
+ char temp_line[SUB_BUFSIZE] = { 0, }; /* subtitle line that will be transfered to current->text[i] */
+ size_t temp_index; /* ... and its index wich 'points' to the first EMPTY place -> last read char is at temp_index-1 if temp_index>0 */
if(!read_line_from_input(this,line,LINE_LEN)) {
if(i)
break; /* if something was read, transmit it */
@@ -396,10 +390,10 @@ static subtitle_t *sub_read_line_subrip(demux_sputext_t *this,subtitle_t *curren
xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "Too many characters in a subtitle line\n");
if(temp_line[temp_index-1]=='\0' || temp_index==SUB_BUFSIZE) {
if(temp_index>1) { /* more than 1 char (including '\0') -> that is a valid one */
- current->text[i]=(char *)xine_xmalloc(temp_index);
+ /* temp_index<=SUB_BUFSIZE is always true here */
+ current->text[i] = strndup(temp_line, temp_index);
if(!current->text[i])
return ERR;
- strncpy(current->text[i],temp_line,temp_index); /* temp_index<=SUB_BUFSIZE is always true here */
i++;
temp_index=0;
} else
@@ -416,9 +410,6 @@ static subtitle_t *sub_read_line_subrip(demux_sputext_t *this,subtitle_t *curren
static subtitle_t *sub_read_line_vplayer(demux_sputext_t *this,subtitle_t *current) {
char line[LINE_LEN + 1];
- int a1,a2,a3,b1,b2,b3;
- char *p=NULL, *next, *p2;
- int i;
memset (current, 0, sizeof(subtitle_t));
@@ -436,24 +427,32 @@ static subtitle_t *sub_read_line_vplayer(demux_sputext_t *this,subtitle_t *curre
this->next_line[0] = '\0';
return NULL;
}
- if( (sscanf( line, "%d:%d:%d:", &a1, &a2, &a3) < 3) ||
- (sscanf( this->next_line, "%d:%d:%d:", &b1, &b2, &b3) < 3) )
- continue;
- current->start = a1*360000+a2*6000+a3*100;
- current->end = b1*360000+b2*6000+b3*100;
+
+ {
+ int a1,a2,a3,b1,b2,b3;
+ if( (sscanf( line, "%d:%d:%d:", &a1, &a2, &a3) < 3) ||
+ (sscanf( this->next_line, "%d:%d:%d:", &b1, &b2, &b3) < 3) )
+ continue;
+ current->start = a1*360000+a2*6000+a3*100;
+ current->end = b1*360000+b2*6000+b3*100;
+ }
+
if ((current->end - current->start) > LINE_LEN)
current->end = current->start + LINE_LEN; /* not too long though. */
/* teraz czas na wkopiowanie stringu */
- p=line;
+ char *p=line;
/* finds the body of the subtitle_t */
- for (i=0; i<3; i++){
- p2=strchr( p, ':');
- if( p2 == NULL ) break;
- p=p2+1;
- }
+ {
+ int i;
+ for (i=0; i<3; i++){
+ char *p2=strchr( p, ':');
+ if( p2 == NULL ) break;
+ p=p2+1;
+ }
+ }
- next=p;
- i=0;
+ char *next=p;
+ int i=0;
while( (next = sub_readtext( next, &(current->text[i]))) ) {
if (current->text[i]==ERR)
return ERR;
@@ -475,35 +474,40 @@ static subtitle_t *sub_read_line_rt(demux_sputext_t *this,subtitle_t *current) {
* I couldn't check it since DTD is not included.
* WARNING: full XML parses can be required for proper parsing
*/
- char line[LINE_LEN + 1];
- int a1,a2,a3,a4,b1,b2,b3,b4;
- char *p=NULL,*next=NULL;
- int i,len,plen;
-
memset (current, 0, sizeof(subtitle_t));
while (!current->text[0]) {
+ char line[LINE_LEN + 1];
if (!read_line_from_input(this, line, LINE_LEN)) return NULL;
+
+ char *p = line;
/*
* TODO: it seems that format of time is not easily determined, it may be 1:12, 1:12.0 or 0:1:12.0
* to describe the same moment in time. Maybe there are even more formats in use.
*/
- if ((len=sscanf (line, "<Time Begin=\"%d:%d:%d.%d\" End=\"%d:%d:%d.%d\"",&a1,&a2,&a3,&a4,&b1,&b2,&b3,&b4)) < 8)
-
- plen=a1=a2=a3=a4=b1=b2=b3=b4=0;
- if (
- ((len=sscanf (line, "<%*[tT]ime %*[bB]egin=\"%d:%d\" %*[Ee]nd=\"%d:%d\"%*[^<]<clear/>%n",&a2,&a3,&b2,&b3,&plen)) < 4) &&
- ((len=sscanf (line, "<%*[tT]ime %*[bB]egin=\"%d:%d\" %*[Ee]nd=\"%d:%d.%d\"%*[^<]<clear/>%n",&a2,&a3,&b2,&b3,&b4,&plen)) < 5) &&
- /* ((len=sscanf (line, "<%*[tT]ime %*[bB]egin=\"%d:%d.%d\" %*[Ee]nd=\"%d:%d\"%*[^<]<clear/>%n",&a2,&a3,&a4,&b2,&b3,&plen)) < 5) && */
- ((len=sscanf (line, "<%*[tT]ime %*[bB]egin=\"%d:%d.%d\" %*[Ee]nd=\"%d:%d.%d\"%*[^<]<clear/>%n",&a2,&a3,&a4,&b2,&b3,&b4,&plen)) < 6) &&
- ((len=sscanf (line, "<%*[tT]ime %*[bB]egin=\"%d:%d:%d.%d\" %*[Ee]nd=\"%d:%d:%d.%d\"%*[^<]<clear/>%n",&a1,&a2,&a3,&a4,&b1,&b2,&b3,&b4,&plen)) < 8)
- )
- continue;
- current->start = a1*360000+a2*6000+a3*100+a4/10;
- current->end = b1*360000+b2*6000+b3*100+b4/10;
- p=line; p+=plen;i=0;
+ {
+ int a1,a2,a3,a4,b1,b2,b3,b4,len,plen;
+ if ((len=sscanf (line, "<Time Begin=\"%d:%d:%d.%d\" End=\"%d:%d:%d.%d\"",&a1,&a2,&a3,&a4,&b1,&b2,&b3,&b4)) < 8)
+
+ a1=a2=a3=a4=b1=b2=b3=b4=0;
+ if (
+ ((len=sscanf (line, "<%*[tT]ime %*[bB]egin=\"%d:%d\" %*[Ee]nd=\"%d:%d\"%*[^<]<clear/>%n",&a2,&a3,&b2,&b3,&plen)) < 4) &&
+ ((len=sscanf (line, "<%*[tT]ime %*[bB]egin=\"%d:%d\" %*[Ee]nd=\"%d:%d.%d\"%*[^<]<clear/>%n",&a2,&a3,&b2,&b3,&b4,&plen)) < 5) &&
+ /* ((len=sscanf (line, "<%*[tT]ime %*[bB]egin=\"%d:%d.%d\" %*[Ee]nd=\"%d:%d\"%*[^<]<clear/>%n",&a2,&a3,&a4,&b2,&b3,&plen)) < 5) && */
+ ((len=sscanf (line, "<%*[tT]ime %*[bB]egin=\"%d:%d.%d\" %*[Ee]nd=\"%d:%d.%d\"%*[^<]<clear/>%n",&a2,&a3,&a4,&b2,&b3,&b4,&plen)) < 6) &&
+ ((len=sscanf (line, "<%*[tT]ime %*[bB]egin=\"%d:%d:%d.%d\" %*[Ee]nd=\"%d:%d:%d.%d\"%*[^<]<clear/>%n",&a1,&a2,&a3,&a4,&b1,&b2,&b3,&b4,&plen)) < 8)
+ )
+ continue;
+
+ current->start = a1*360000+a2*6000+a3*100+a4/10;
+ current->end = b1*360000+b2*6000+b3*100+b4/10;
+
+ p += plen;
+ }
+
+ int i=0;
/* TODO: I don't know what kind of convention is here for marking multiline subs, maybe <br/> like in xml? */
- next = strstr(line,"<clear/>")+8;i=0;
+ char *next = strstr(line,"<clear/>")+8;i=0;
while ((next =sub_readtext (next, &(current->text[i])))) {
if (current->text[i]==ERR)
return ERR;
@@ -520,52 +524,54 @@ static subtitle_t *sub_read_line_rt(demux_sputext_t *this,subtitle_t *current) {
}
static subtitle_t *sub_read_line_ssa(demux_sputext_t *this,subtitle_t *current) {
- int comma;
static int max_comma = 32; /* let's use 32 for the case that the */
/* amount of commas increase with newer SSA versions */
int hour1, min1, sec1, hunsec1, hour2, min2, sec2, hunsec2, nothing;
- int num;
- char line[LINE_LEN + 1], line3[LINE_LEN + 1], *line2;
- char *tmp;
+ char line3[LINE_LEN + 1];
- do {
- if (!read_line_from_input(this, line, LINE_LEN)) return NULL;
- } while (sscanf (line, "Dialogue: Marked=%d,%d:%d:%d.%d,%d:%d:%d.%d,"
- "%[^\n\r]", &nothing,
- &hour1, &min1, &sec1, &hunsec1,
- &hour2, &min2, &sec2, &hunsec2,
- line3) < 9
- &&
- sscanf (line, "Dialogue: %d,%d:%d:%d.%d,%d:%d:%d.%d,"
- "%[^\n\r]", &nothing,
- &hour1, &min1, &sec1, &hunsec1,
- &hour2, &min2, &sec2, &hunsec2,
- line3) < 9 );
+ {
+ char line[LINE_LEN + 1];
+ do {
+ if (!read_line_from_input(this, line, LINE_LEN)) return NULL;
+ } while (sscanf (line, "Dialogue: Marked=%d,%d:%d:%d.%d,%d:%d:%d.%d,"
+ "%[^\n\r]", &nothing,
+ &hour1, &min1, &sec1, &hunsec1,
+ &hour2, &min2, &sec2, &hunsec2,
+ line3) < 9
+ &&
+ sscanf (line, "Dialogue: %d,%d:%d:%d.%d,%d:%d:%d.%d,"
+ "%[^\n\r]", &nothing,
+ &hour1, &min1, &sec1, &hunsec1,
+ &hour2, &min2, &sec2, &hunsec2,
+ line3) < 9 );
+ }
- line2=strchr(line3, ',');
+ char *line2=strchr(line3, ',');
+ if (!line2)
+ return NULL;
- for (comma = 4; comma < max_comma; comma ++)
- {
- tmp = line2;
- if(!(tmp=strchr(++tmp, ','))) break;
- if(*(++tmp) == ' ') break;
- /* a space after a comma means we're already in a sentence */
- line2 = tmp;
- }
+ int comma;
+ for (comma = 4; comma < max_comma; comma ++) {
+ char *tmp = line2;
+ if(!(tmp=strchr(++tmp, ','))) break;
+ if(*(++tmp) == ' ') break;
+ /* a space after a comma means we're already in a sentence */
+ line2 = tmp;
+ }
if(comma < max_comma)max_comma = comma;
/* eliminate the trailing comma */
if(*line2 == ',') line2++;
- current->lines=0;num=0;
+ current->lines=0;
current->start = 360000*hour1 + 6000*min1 + 100*sec1 + hunsec1;
current->end = 360000*hour2 + 6000*min2 + 100*sec2 + hunsec2;
+ int num=0;
+ char *tmp;
while (((tmp=strstr(line2, "\\n")) != NULL) || ((tmp=strstr(line2, "\\N")) != NULL) ){
- current->text[num]=(char *)malloc(tmp-line2+1);
- strncpy (current->text[num], line2, tmp-line2);
- current->text[num][tmp-line2]='\0';
+ current->text[num] = strndup(line2, tmp-line2);
line2=tmp+2;
num++;
current->lines++;
@@ -591,8 +597,7 @@ static subtitle_t *sub_read_line_ssa(demux_sputext_t *this,subtitle_t *current)
static subtitle_t *sub_read_line_pjs (demux_sputext_t *this, subtitle_t *current) {
char line[LINE_LEN + 1];
- char text[LINE_LEN + 1];
- char *s, *d;
+ char *s;
memset (current, 0, sizeof(subtitle_t));
@@ -618,6 +623,8 @@ static subtitle_t *sub_read_line_pjs (demux_sputext_t *this, subtitle_t *current
return ERR;
}
/* copy the string to the text buffer */
+ char text[LINE_LEN + 1];
+ char *d = NULL;
for (s++, d=text; *s && *s!='"'; s++, d++)
*d=*s;
*d=0;
@@ -629,25 +636,26 @@ static subtitle_t *sub_read_line_pjs (demux_sputext_t *this, subtitle_t *current
static subtitle_t *sub_read_line_mpsub (demux_sputext_t *this, subtitle_t *current) {
char line[LINE_LEN + 1];
- float a,b;
- int num=0;
- char *p, *q;
- do {
- if (!read_line_from_input(this, line, LINE_LEN))
- return NULL;
- } while (sscanf (line, "%f %f", &a, &b) !=2);
-
- this->mpsub_position += (a*100.0);
- current->start = (int) this->mpsub_position;
- this->mpsub_position += (b*100.0);
- current->end = (int) this->mpsub_position;
+ {
+ float a,b;
+ do {
+ if (!read_line_from_input(this, line, LINE_LEN))
+ return NULL;
+ } while (sscanf (line, "%f %f", &a, &b) !=2);
+
+ this->mpsub_position += (a*100.0);
+ current->start = (int) this->mpsub_position;
+ this->mpsub_position += (b*100.0);
+ current->end = (int) this->mpsub_position;
+ }
+ int num = 0;
while (num < SUB_MAX_TEXT) {
if (!read_line_from_input(this, line, LINE_LEN))
return NULL;
- p=line;
+ char *p=line;
while (isspace(*p))
p++;
@@ -657,17 +665,15 @@ static subtitle_t *sub_read_line_mpsub (demux_sputext_t *this, subtitle_t *curre
if (eol(*p))
return NULL;
+ char *q;
for (q=p; !eol(*q); q++);
*q='\0';
- if (strlen(p)) {
+ if (*p) {
current->text[num]=strdup(p);
xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, ">%s<\n",p);
current->lines = ++num;
} else {
- if (num)
- return current;
- else
- return NULL;
+ return num ? current : NULL;
}
}
@@ -675,11 +681,10 @@ static subtitle_t *sub_read_line_mpsub (demux_sputext_t *this, subtitle_t *curre
}
static subtitle_t *sub_read_line_aqt (demux_sputext_t *this, subtitle_t *current) {
- char line[LINE_LEN + 1];
-
memset (current, 0, sizeof(subtitle_t));
while (1) {
+ char line[LINE_LEN + 1];
/* try to locate next subtitle_t */
if (!read_line_from_input(this, line, LINE_LEN))
return NULL;
@@ -687,6 +692,7 @@ static subtitle_t *sub_read_line_aqt (demux_sputext_t *this, subtitle_t *current
break;
}
+ char line[LINE_LEN + 1];
if (!read_line_from_input(this, line, LINE_LEN))
return NULL;
@@ -708,255 +714,252 @@ static subtitle_t *sub_read_line_aqt (demux_sputext_t *this, subtitle_t *current
}
static subtitle_t *sub_read_line_jacobsub(demux_sputext_t *this, subtitle_t *current) {
- char line1[LINE_LEN], line2[LINE_LEN], directive[LINE_LEN], *p, *q;
- unsigned a1, a2, a3, a4, b1, b2, b3, b4, comment = 0;
- static unsigned jacoTimeres = 30;
- static int jacoShift = 0;
-
- memset(current, 0, sizeof(subtitle_t));
- memset(line1, 0, LINE_LEN);
- memset(line2, 0, LINE_LEN);
- memset(directive, 0, LINE_LEN);
- while (!current->text[0]) {
- if (!read_line_from_input(this, line1, LINE_LEN)) {
- return NULL;
- }
- if (sscanf
- (line1, "%u:%u:%u.%u %u:%u:%u.%u %" LINE_LEN_QUOT "[^\n\r]", &a1, &a2, &a3, &a4,
- &b1, &b2, &b3, &b4, line2) < 9) {
- if (sscanf(line1, "@%u @%u %" LINE_LEN_QUOT "[^\n\r]", &a4, &b4, line2) < 3) {
- if (line1[0] == '#') {
- int hours = 0, minutes = 0, seconds, delta, inverter =
- 1;
- unsigned units = jacoShift;
- switch (toupper(line1[1])) {
- case 'S':
- if (isalpha(line1[2])) {
- delta = 6;
- } else {
- delta = 2;
- }
- if (sscanf(&line1[delta], "%d", &hours)) {
- if (hours < 0) {
- hours *= -1;
- inverter = -1;
- }
- if (sscanf(&line1[delta], "%*d:%d", &minutes)) {
- if (sscanf
- (&line1[delta], "%*d:%*d:%d",
- &seconds)) {
- sscanf(&line1[delta], "%*d:%*d:%*d.%d",
- &units);
- } else {
- hours = 0;
- sscanf(&line1[delta], "%d:%d.%d",
- &minutes, &seconds, &units);
- minutes *= inverter;
- }
- } else {
- hours = minutes = 0;
- sscanf(&line1[delta], "%d.%d", &seconds,
- &units);
- seconds *= inverter;
- }
- jacoShift =
- ((hours * 3600 + minutes * 60 +
- seconds) * jacoTimeres +
- units) * inverter;
- }
- break;
- case 'T':
- if (isalpha(line1[2])) {
- delta = 8;
- } else {
- delta = 2;
- }
- sscanf(&line1[delta], "%u", &jacoTimeres);
- break;
- }
- }
- continue;
+ char line1[LINE_LEN] = { 0, }, line2[LINE_LEN] = { 0, }, directive[LINE_LEN] = { 0, }, *p, *q;
+ unsigned a1, a2, a3, a4, b1, b2, b3, b4, comment = 0;
+ static unsigned jacoTimeres = 30;
+ static int jacoShift = 0;
+
+ memset(current, 0, sizeof(subtitle_t));
+ while (!current->text[0]) {
+ if (!read_line_from_input(this, line1, LINE_LEN)) {
+ return NULL;
+ }
+ if (sscanf
+ (line1, "%u:%u:%u.%u %u:%u:%u.%u %" LINE_LEN_QUOT "[^\n\r]", &a1, &a2, &a3, &a4,
+ &b1, &b2, &b3, &b4, line2) < 9) {
+ if (sscanf(line1, "@%u @%u %" LINE_LEN_QUOT "[^\n\r]", &a4, &b4, line2) < 3) {
+ if (line1[0] == '#') {
+ int hours = 0, minutes = 0, seconds, delta, inverter =
+ 1;
+ unsigned units = jacoShift;
+ switch (toupper(line1[1])) {
+ case 'S':
+ if (isalpha(line1[2])) {
+ delta = 6;
} else {
- current->start =
- (unsigned long) ((a4 + jacoShift) * 100.0 /
- jacoTimeres);
- current->end =
- (unsigned long) ((b4 + jacoShift) * 100.0 /
- jacoTimeres);
+ delta = 2;
}
- } else {
- current->start =
- (unsigned
- long) (((a1 * 3600 + a2 * 60 + a3) * jacoTimeres + a4 +
- jacoShift) * 100.0 / jacoTimeres);
- current->end =
- (unsigned
- long) (((b1 * 3600 + b2 * 60 + b3) * jacoTimeres + b4 +
- jacoShift) * 100.0 / jacoTimeres);
- }
- current->lines = 0;
- p = line2;
- while ((*p == ' ') || (*p == '\t')) {
- ++p;
- }
- if (isalpha(*p)||*p == '[') {
- int cont, jLength;
-
- if (sscanf(p, "%s %" LINE_LEN_QUOT "[^\n\r]", directive, line1) < 2)
- return ERR;
- jLength = strlen(directive);
- for (cont = 0; cont < jLength; ++cont) {
- if (isalpha(*(directive + cont)))
- *(directive + cont) = toupper(*(directive + cont));
- }
- if ((strstr(directive, "RDB") != NULL)
- || (strstr(directive, "RDC") != NULL)
- || (strstr(directive, "RLB") != NULL)
- || (strstr(directive, "RLG") != NULL)) {
- continue;
+ if (sscanf(&line1[delta], "%d", &hours)) {
+ if (hours < 0) {
+ hours *= -1;
+ inverter = -1;
+ }
+ if (sscanf(&line1[delta], "%*d:%d", &minutes)) {
+ if (sscanf
+ (&line1[delta], "%*d:%*d:%d",
+ &seconds)) {
+ sscanf(&line1[delta], "%*d:%*d:%*d.%d",
+ &units);
+ } else {
+ hours = 0;
+ sscanf(&line1[delta], "%d:%d.%d",
+ &minutes, &seconds, &units);
+ minutes *= inverter;
+ }
+ } else {
+ hours = minutes = 0;
+ sscanf(&line1[delta], "%d.%d", &seconds,
+ &units);
+ seconds *= inverter;
+ }
+ jacoShift =
+ ((hours * 3600 + minutes * 60 +
+ seconds) * jacoTimeres +
+ units) * inverter;
}
- /* no alignment */
-#if 0
- if (strstr(directive, "JL") != NULL) {
- current->alignment = SUB_ALIGNMENT_HLEFT;
- } else if (strstr(directive, "JR") != NULL) {
- current->alignment = SUB_ALIGNMENT_HRIGHT;
+ break;
+ case 'T':
+ if (isalpha(line1[2])) {
+ delta = 8;
} else {
- current->alignment = SUB_ALIGNMENT_HCENTER;
+ delta = 2;
}
+ sscanf(&line1[delta], "%u", &jacoTimeres);
+ break;
+ }
+ }
+ continue;
+ } else {
+ current->start =
+ (unsigned long) ((a4 + jacoShift) * 100.0 /
+ jacoTimeres);
+ current->end =
+ (unsigned long) ((b4 + jacoShift) * 100.0 /
+ jacoTimeres);
+ }
+ } else {
+ current->start =
+ (unsigned
+ long) (((a1 * 3600 + a2 * 60 + a3) * jacoTimeres + a4 +
+ jacoShift) * 100.0 / jacoTimeres);
+ current->end =
+ (unsigned
+ long) (((b1 * 3600 + b2 * 60 + b3) * jacoTimeres + b4 +
+ jacoShift) * 100.0 / jacoTimeres);
+ }
+ current->lines = 0;
+ p = line2;
+ while ((*p == ' ') || (*p == '\t')) {
+ ++p;
+ }
+ if (isalpha(*p)||*p == '[') {
+ if (sscanf(p, "%s %" LINE_LEN_QUOT "[^\n\r]", directive, line1) < 2)
+ return ERR;
+ if ((strcasestr(directive, "RDB") != NULL)
+ || (strcasestr(directive, "RDC") != NULL)
+ || (strcasestr(directive, "RLB") != NULL)
+ || (strcasestr(directive, "RLG") != NULL)) {
+ continue;
+ }
+ /* no alignment */
+#if 0
+ if (strcasestr(directive, "JL") != NULL) {
+ current->alignment = SUB_ALIGNMENT_HLEFT;
+ } else if (strcasestr(directive, "JR") != NULL) {
+ current->alignment = SUB_ALIGNMENT_HRIGHT;
+ } else {
+ current->alignment = SUB_ALIGNMENT_HCENTER;
+ }
#endif
- strcpy(line2, line1);
- p = line2;
+ strcpy(line2, line1);
+ p = line2;
+ }
+ for (q = line1; (!eol(*p)) && (current->lines < SUB_MAX_TEXT); ++p) {
+ switch (*p) {
+ case '{':
+ comment++;
+ break;
+ case '}':
+ if (comment) {
+ --comment;
+ /* the next line to get rid of a blank after the comment */
+ if ((*(p + 1)) == ' ')
+ p++;
}
- for (q = line1; (!eol(*p)) && (current->lines < SUB_MAX_TEXT); ++p) {
- switch (*p) {
- case '{':
- comment++;
- break;
- case '}':
- if (comment) {
- --comment;
- /* the next line to get rid of a blank after the comment */
- if ((*(p + 1)) == ' ')
- p++;
- }
- break;
- case '~':
- if (!comment) {
- *q = ' ';
- ++q;
- }
- break;
- case ' ':
- case '\t':
- if ((*(p + 1) == ' ') || (*(p + 1) == '\t'))
- break;
- if (!comment) {
- *q = ' ';
- ++q;
- }
- break;
- case '\\':
- if (*(p + 1) == 'n') {
- *q = '\0';
- q = line1;
- current->text[current->lines++] = strdup(line1);
- ++p;
- break;
- }
- if ((toupper(*(p + 1)) == 'C')
- || (toupper(*(p + 1)) == 'F')) {
- ++p,++p;
- break;
- }
- if ((*(p + 1) == 'B') || (*(p + 1) == 'b') ||
- /* actually this means "insert current date here" */
- (*(p + 1) == 'D') ||
- (*(p + 1) == 'I') || (*(p + 1) == 'i') ||
- (*(p + 1) == 'N') ||
- /* actually this means "insert current time here" */
- (*(p + 1) == 'T') ||
- (*(p + 1) == 'U') || (*(p + 1) == 'u')) {
- ++p;
- break;
- }
- if ((*(p + 1) == '\\') ||
- (*(p + 1) == '~') || (*(p + 1) == '{')) {
- ++p;
- } else if (eol(*(p + 1))) {
- if (!read_line_from_input(this, directive, LINE_LEN))
- return NULL;
- trail_space(directive);
- strncat(line2, directive,
- ((LINE_LEN > 511) ? LINE_LEN-1 : 511)
- - strlen(line2));
- break;
- }
- default:
- if (!comment) {
- *q = *p;
- ++q;
- }
- }
+ break;
+ case '~':
+ if (!comment) {
+ *q = ' ';
+ ++q;
+ }
+ break;
+ case ' ':
+ case '\t':
+ if ((*(p + 1) == ' ') || (*(p + 1) == '\t'))
+ break;
+ if (!comment) {
+ *q = ' ';
+ ++q;
}
- *q = '\0';
- current->text[current->lines] = strdup(line1);
+ break;
+ case '\\':
+ if (*(p + 1) == 'n') {
+ *q = '\0';
+ q = line1;
+ current->text[current->lines++] = strdup(line1);
+ ++p;
+ break;
+ }
+ if ((toupper(*(p + 1)) == 'C')
+ || (toupper(*(p + 1)) == 'F')) {
+ ++p,++p;
+ break;
+ }
+ if ((*(p + 1) == 'B') || (*(p + 1) == 'b') ||
+ /* actually this means "insert current date here" */
+ (*(p + 1) == 'D') ||
+ (*(p + 1) == 'I') || (*(p + 1) == 'i') ||
+ (*(p + 1) == 'N') ||
+ /* actually this means "insert current time here" */
+ (*(p + 1) == 'T') ||
+ (*(p + 1) == 'U') || (*(p + 1) == 'u')) {
+ ++p;
+ break;
+ }
+ if ((*(p + 1) == '\\') ||
+ (*(p + 1) == '~') || (*(p + 1) == '{')) {
+ ++p;
+ } else if (eol(*(p + 1))) {
+ if (!read_line_from_input(this, directive, LINE_LEN))
+ return NULL;
+ trail_space(directive);
+ strncat(line2, directive,
+ ((LINE_LEN > 511) ? LINE_LEN-1 : 511)
+ - strlen(line2));
+ break;
+ }
+ default:
+ if (!comment) {
+ *q = *p;
+ ++q;
+ }
+ }
}
- current->lines++;
- return current;
+ *q = '\0';
+ if (current->lines < SUB_MAX_TEXT)
+ current->text[current->lines] = strdup(line1);
+ else
+ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "Too many lines in a subtitle\n");
+ }
+ current->lines++;
+ return current;
}
static subtitle_t *sub_read_line_subviewer2(demux_sputext_t *this, subtitle_t *current) {
+ char *p=NULL;
+
+ while (!current->text[0]) {
char line[LINE_LEN+1];
- int a1,a2,a3,a4;
- char *p=NULL;
- int i,len;
-
- while (!current->text[0]) {
- if (!read_line_from_input(this, line, LINE_LEN)) return NULL;
- if (line[0]!='{')
- continue;
- if ((len=sscanf (line, "{T %d:%d:%d:%d",&a1,&a2,&a3,&a4)) < 4)
- continue;
- current->start = a1*360000+a2*6000+a3*100+a4/10;
- for (i=0; i<SUB_MAX_TEXT;) {
- if (!read_line_from_input(this, line, LINE_LEN)) break;
- if (line[0]=='}') break;
- len=0;
- for (p=line; *p!='\n' && *p!='\r' && *p; ++p,++len);
- if (len) {
- current->text[i]=(char *)malloc (len+1);
- if (!current->text[i]) return ERR;
- strncpy (current->text[i], line, len); current->text[i][len]='\0';
- ++i;
- } else {
- break;
- }
- }
- current->lines=i;
+ if (!read_line_from_input(this, line, LINE_LEN)) return NULL;
+ if (line[0]!='{')
+ continue;
+
+ {
+ int a1,a2,a3,a4;
+ const int len = sscanf (line, "{T %d:%d:%d:%d",&a1,&a2,&a3,&a4);
+ if (len < 4)
+ continue;
+ current->start = a1*360000+a2*6000+a3*100+a4/10;
}
- return current;
+
+ int i;
+ for (i=0; i<SUB_MAX_TEXT;) {
+ if (!read_line_from_input(this, line, LINE_LEN)) break;
+ if (line[0]=='}') break;
+ size_t len=0;
+ for (p=line; *p!='\n' && *p!='\r' && *p; ++p,++len);
+ if (len) {
+ current->text[i] = strndup(line, len);
+ if (!current->text[i]) return ERR;
+ ++i;
+ } else {
+ break;
+ }
+ }
+ current->lines=i;
+ }
+ return current;
}
static subtitle_t *sub_read_line_subrip09 (demux_sputext_t *this, subtitle_t *current) {
- char line[LINE_LEN + 1];
- char *next;
- int h, m, s;
- int i;
-
memset (current, 0, sizeof(subtitle_t));
-
- do {
- if (!read_line_from_input (this, line, LINE_LEN)) return NULL;
- } while (sscanf (line, "[%d:%d:%d]", &h, &m, &s) != 3);
+ int h, m, s;
+ {
+ char line[LINE_LEN + 1];
+ do {
+ if (!read_line_from_input (this, line, LINE_LEN)) return NULL;
+ } while (sscanf (line, "[%d:%d:%d]", &h, &m, &s) != 3);
+ }
+
+ char line[LINE_LEN + 1];
if (!read_line_from_input (this, line, LINE_LEN)) return NULL;
current->start = 360000 * h + 6000 * m + 100 * s;
current->end = -1;
- next=line;
- i=0;
+ char *next = line;
+ int i=0;
while ((next = sub_readtext (next, &(current->text[i])))) {
if (current->text[i]==ERR) return ERR;
i++;
@@ -976,22 +979,27 @@ static subtitle_t *sub_read_line_subrip09 (demux_sputext_t *this, subtitle_t *cu
*/
static subtitle_t *sub_read_line_mpl2(demux_sputext_t *this, subtitle_t *current) {
- char line[LINE_LEN+1];
char line2[LINE_LEN+1];
- char *p, *next;
- int i;
memset (current, 0, sizeof(subtitle_t));
- do {
- if (!read_line_from_input (this, line, LINE_LEN)) return NULL;
- } while ((sscanf (line,
+
+ {
+ char line[LINE_LEN+1];
+ long start, end;
+
+ do {
+ if (!read_line_from_input (this, line, LINE_LEN)) return NULL;
+ } while ((sscanf (line,
"[%ld][%ld]%[^\r\n]",
- &(current->start), &(current->end), line2) < 3));
- current->start *= 10;
- current->end *= 10;
- p=line2;
+ &start, &end, line2) < 3));
+
+ current->start = start * 10;
+ current->end = end * 10;
+ }
+
+ char *p = line2, *next = p;
+ int i = 0;
- next=p, i=0;
while ((next = sub_readtext (next, &(current->text[i])))) {
if (current->text[i] == ERR) {return ERR;}
i++;
@@ -1009,16 +1017,13 @@ static subtitle_t *sub_read_line_mpl2(demux_sputext_t *this, subtitle_t *current
static int sub_autodetect (demux_sputext_t *this) {
-
- char line[LINE_LEN + 1];
- int i, j=0;
- char p;
-
- while (j < 100) {
- j++;
+ int j;
+ for(j = 1; j < 100; j++) {
+ char line[LINE_LEN + 1];
if (!read_line_from_input(this, line, LINE_LEN))
return FORMAT_UNKNOWN;
+ int i;
if ((sscanf (line, "{%d}{}", &i)==1) ||
(sscanf (line, "{%d}{%d}", &i, &i)==2)) {
this->uses_time=0;
@@ -1078,11 +1083,14 @@ static int sub_autodetect (demux_sputext_t *this) {
xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "mpsub subtitle format detected\n");
return FORMAT_MPSUB;
}
+
+ char p;
if (sscanf (line, "FORMAT=TIM%c", &p)==1 && p=='E') {
this->uses_time=1;
xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "mpsub subtitle format detected\n");
return FORMAT_MPSUB;
}
+
if (strstr (line, "-->>")) {
this->uses_time=0;
xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "aqtitle subtitle format detected\n");
@@ -1116,9 +1124,6 @@ static int sub_autodetect (demux_sputext_t *this) {
static subtitle_t *sub_read_file (demux_sputext_t *this) {
- int n_max;
- int timeout;
- subtitle_t *first;
subtitle_t * (*func[])(demux_sputext_t *this,subtitle_t *dest)=
{
sub_read_line_microdvd,
@@ -1159,23 +1164,23 @@ static subtitle_t *sub_read_file (demux_sputext_t *this) {
}
this->buflen = 0;
- this->num=0;n_max=32;
- first = (subtitle_t *) xine_xmalloc(n_max*sizeof(subtitle_t));
+ this->num=0;
+ int n_max=32;
+ subtitle_t *first = calloc(n_max, sizeof(subtitle_t));
if(!first) return NULL;
- timeout = ((demux_sputext_class_t *)
- (this->demux_plugin.demux_class))->max_timeout;
- if (this->uses_time) timeout *= 100;
- else timeout *= 10;
- while(1) {
- subtitle_t *sub;
+ const int timeout =
+ (((demux_sputext_class_t *)
+ (this->demux_plugin.demux_class))->max_timeout) *
+ (this->uses_time ? 100 : 10);
+ while(1) {
if(this->num>=n_max){
n_max+=16;
first=realloc(first,n_max*sizeof(subtitle_t));
}
- sub = func[this->format] (this, &first[this->num]);
+ subtitle_t *sub = func[this->format] (this, &first[this->num]);
if (!sub)
break; /* EOF */
@@ -1223,31 +1228,29 @@ static subtitle_t *sub_read_file (demux_sputext_t *this) {
static int demux_sputext_next (demux_sputext_t *this_gen) {
demux_sputext_t *this = (demux_sputext_t *) this_gen;
- buf_element_t *buf;
- uint32_t *val;
- char *str;
- subtitle_t *sub;
- int line;
if (this->cur >= this->num)
return 0;
- sub = &this->subtitles[this->cur];
+ subtitle_t *sub = &this->subtitles[this->cur];
- buf = this->stream->video_fifo->buffer_pool_alloc(this->stream->video_fifo);
+ buf_element_t *buf = this->stream->video_fifo->buffer_pool_alloc(this->stream->video_fifo);
buf->type = BUF_SPU_TEXT;
buf->pts = 0;
- val = (uint32_t * )buf->content;
+ uint32_t *val = (uint32_t * )buf->content;
*val++ = sub->lines;
*val++ = this->uses_time;
*val++ = (this->uses_time) ? sub->start * 10 : sub->start;
*val++ = (this->uses_time) ? sub->end * 10 : sub->end;
- str = (char *)val;
+ char *str = (char *)val;
+
+ /** @FIXME The way this works seems wrong, SUB_BUFSIZE-1 is not the
+ right maximum, I think. */
+ int line;
for (line = 0; line < sub->lines; line++, str+=strlen(str)+1) {
- if( strlen(sub->text[line]) > SUB_BUFSIZE )
- sub->text[line][SUB_BUFSIZE] = '\0';
- strcpy(str, sub->text[line]);
+ strncpy(str, sub->text[line], SUB_BUFSIZE-1);
+ str[SUB_BUFSIZE-1] = '\0';
}
this->stream->video_fifo->put(this->stream->video_fifo, buf);
@@ -1258,9 +1261,10 @@ static int demux_sputext_next (demux_sputext_t *this_gen) {
static void demux_sputext_dispose (demux_plugin_t *this_gen) {
demux_sputext_t *this = (demux_sputext_t *) this_gen;
- int i, l;
-
+
+ int i;
for (i = 0; i < this->num; i++) {
+ int l;
for (l = 0; l < this->subtitles[i].lines; l++)
free(this->subtitles[i].text[l]);
}
@@ -1276,11 +1280,9 @@ static int demux_sputext_get_status (demux_plugin_t *this_gen) {
static int demux_sputext_get_stream_length (demux_plugin_t *this_gen) {
demux_sputext_t *this = (demux_sputext_t *) this_gen;
- if( this->uses_time && this->num ) {
- return this->subtitles[this->num-1].end * 10;
- } else {
- return 0;
- }
+ return ( this->uses_time && this->num ) ?
+ this->subtitles[this->num-1].end * 10 :
+ 0;
}
static int demux_sputext_send_chunk (demux_plugin_t *this_gen) {
@@ -1313,8 +1315,6 @@ static int demux_sputext_seek (demux_plugin_t *this_gen,
static void demux_sputext_send_headers(demux_plugin_t *this_gen) {
demux_sputext_t *this = (demux_sputext_t*)this_gen;
- buf_element_t *buf;
-
lprintf("send_headers() called\n");
@@ -1323,7 +1323,7 @@ static void demux_sputext_send_headers(demux_plugin_t *this_gen) {
_x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 0);
/* enable the SPU channel */
- buf = this->stream->video_fifo->buffer_pool_alloc(this->stream->video_fifo);
+ buf_element_t *buf = this->stream->video_fifo->buffer_pool_alloc(this->stream->video_fifo);
buf->type = BUF_CONTROL_SPU_CHANNEL;
buf->decoder_info[0] = buf->decoder_info[1] = buf->decoder_info[2] = 0;
this->stream->video_fifo->put(this->stream->video_fifo, buf);
@@ -1358,7 +1358,7 @@ static demux_plugin_t *open_demux_plugin (demux_class_t *class_gen, xine_stream_
lprintf("open_plugin() called\n");
- this = xine_xmalloc (sizeof (demux_sputext_t));
+ this = calloc(1, sizeof (demux_sputext_t));
this->stream = stream;
this->input = input;
@@ -1460,7 +1460,7 @@ static void *init_sputext_demux_class (xine_t *xine, void *data) {
lprintf("initializing\n");
- this = xine_xmalloc (sizeof (demux_sputext_class_t));
+ this = calloc(1, sizeof (demux_sputext_class_t));
this->demux_class.open_plugin = open_demux_plugin;
this->demux_class.get_description = get_demux_description;
diff --git a/src/libsputext/xine_sputext_decoder.c b/src/libsputext/xine_sputext_decoder.c
index d0cab9cbf..7d5e73ce9 100644
--- a/src/libsputext/xine_sputext_decoder.c
+++ b/src/libsputext/xine_sputext_decoder.c
@@ -18,6 +18,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
@@ -63,7 +67,7 @@
#define rgb2yuv(R,G,B) ((((((66*R+129*G+25*B+128)>>8)+16)<<8)|(((112*R-94*G-18*B+128)>>8)+128))<<8|(((-38*R-74*G+112*B+128)>>8)+128))
-static uint32_t sub_palette[22]={
+static const uint32_t sub_palette[22]={
/* RED */
rgb2yuv(0,0,0),
rgb2yuv(0,0,0),
@@ -90,7 +94,7 @@ static uint32_t sub_palette[22]={
rgb2yuv(0,170,255)
};
-static uint8_t sub_trans[22]={
+static const uint8_t sub_trans[22]={
0, 0, 3, 6, 8, 10, 12, 14, 15, 15, 15,
0, 0, 3, 6, 8, 10, 12, 14, 15, 15, 15
};
@@ -185,7 +189,7 @@ static inline char *get_font (sputext_class_t *class)
}
static void update_font_size (sputext_decoder_t *this, int force_update) {
- static int sizes[SUBTITLE_SIZE_NUM] = { 16, 20, 24, 32, 48, 64 };
+ static const int sizes[SUBTITLE_SIZE_NUM] = { 16, 20, 24, 32, 48, 64 };
if ((this->subtitle_size != this->class->subtitle_size) ||
(this->vertical_offset != this->class->vertical_offset) ||
@@ -214,11 +218,9 @@ static void update_font_size (sputext_decoder_t *this, int force_update) {
}
static void update_output_size (sputext_decoder_t *this) {
- int unscaled;
-
- unscaled = this->class->use_unscaled &&
- (this->stream->video_out->get_capabilities(this->stream->video_out) &
- VO_CAP_UNSCALED_OVERLAY);
+ const int unscaled = this->class->use_unscaled &&
+ (this->stream->video_out->get_capabilities(this->stream->video_out) &
+ VO_CAP_UNSCALED_OVERLAY);
if( unscaled != this->unscaled ) {
this->unscaled = unscaled;
@@ -303,7 +305,7 @@ static void update_output_size (sputext_decoder_t *this) {
}
}
-static int parse_utf8_size(unsigned char *c)
+static int parse_utf8_size(const uint8_t *c)
{
if ( c[0]<0x80 )
return 1;
@@ -329,13 +331,8 @@ static int parse_utf8_size(unsigned char *c)
static int ogm_render_line_internal(sputext_decoder_t *this, int x, int y, const char *text, int render)
{
- int i = 0, w, value;
- char* end;
- char letter[5]={0, 0, 0, 0, 0};
- const char *encoding = this->buf_encoding ? this->buf_encoding
- : this->class->src_encoding;
- int shift, isutf8 = !strcmp(encoding, "utf-8");
- size_t length = strlen (text);
+ const size_t length = strlen (text);
+ size_t i = 0;
while (i <= length) {
@@ -379,6 +376,7 @@ static int ogm_render_line_internal(sputext_decoder_t *this, int x, int y, const
if (text[i] == '{') {
if (!strncmp("{\\", text+i, 2)) {
+ int value;
if (sscanf(text+i, "{\\b%d}", &value) == 1) {
if (render) {
@@ -395,7 +393,7 @@ static int ogm_render_line_internal(sputext_decoder_t *this, int x, int y, const
this->current_osd_text = OSD_TEXT1;
}
}
- end = strstr(text+i+2, "}");
+ char *const end = strstr(text+i+2, "}");
if (end) {
i=end-text+1;
continue;
@@ -403,15 +401,20 @@ static int ogm_render_line_internal(sputext_decoder_t *this, int x, int y, const
}
}
- shift = isutf8 ? parse_utf8_size (&text[i]) : 1;
+ char letter[5];
+ const char *const encoding = this->buf_encoding ? : this->class->src_encoding;
+ const int isutf8 = !strcmp(encoding, "utf-8");
+ const size_t shift = isutf8 ? parse_utf8_size (&text[i]) : 1;
memcpy(letter,&text[i],shift);
letter[shift]=0;
if (render)
this->renderer->render_text(this->osd, x, y, letter, this->current_osd_text);
- this->renderer->get_text_size(this->osd, letter, &w, &value);
- x=x+w;
- i+=shift;
+
+ int w, dummy;
+ this->renderer->get_text_size(this->osd, letter, &w, &dummy);
+ x += w;
+ i += shift;
}
return x;
@@ -547,15 +550,9 @@ static int is_cjk_encoding(const char *enc) {
static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t sub_end ) {
- int line, y;
- int font_size;
- char *font;
- const char *encoding = (this->buf_encoding)?this->buf_encoding:
- this->class->src_encoding;
+ int y;
int sub_x, sub_y, max_width;
int alignment;
- int rebuild_all;
-
_x_assert(this->renderer != NULL);
if ( ! this->renderer )
@@ -565,21 +562,20 @@ static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t su
update_font_size(this, 0);
- font = get_font (this->class);
+ const char *const font = get_font (this->class);
if( strcmp(this->font, font) ) {
strncpy(this->font, font, FILENAME_MAX);
this->font[FILENAME_MAX - 1] = '\0';
this->renderer->set_font (this->osd, font, this->font_size);
}
- font_size = this->font_size;
- if (this->buf_encoding)
- this->renderer->set_encoding(this->osd, this->buf_encoding);
- else
- this->renderer->set_encoding(this->osd, this->class->src_encoding);
+ int font_size = this->font_size;
+ const char *const encoding = this->buf_encoding ? : this->class->src_encoding;
+ this->renderer->set_encoding(this->osd, encoding);
- rebuild_all = 0;
+ int rebuild_all = 0;
+ int line;
for (line = 0; line < this->lines; line++) {
int line_width = ogm_get_width(this, this->text[line]);
@@ -637,30 +633,27 @@ static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t su
/* regenerate all the lines to find something that better fits */
if (rebuild_all) {
- int line, line_width;
- char *stream, *current_cut, *best_cut;
- char buf[SUB_BUFSIZE * SUB_MAX_TEXT];
+ char buf[SUB_BUFSIZE * SUB_MAX_TEXT] = { 0, };
- buf[0] = 0;
+ int line;
for(line = 0; line < this->lines; line++) {
- int len = strlen(buf);
- if (len) {
+ const size_t len = strlen(buf);
+ if (len)
buf[len] = ' ';
- len++;
- }
- strncpy(buf + len, this->text[line], SUB_BUFSIZE);
- *(buf + len + SUB_BUFSIZE) = 0;
+
+ strncat(buf, this->text[line], SUB_BUFSIZE-len-1);
}
- stream = buf;
+ char *stream = buf;
this->lines = 0;
+ char *current_cut, *best_cut;
do {
if (this->lines + 1 < SUB_MAX_TEXT) {
/* find the longest sequence witch fit */
- line_width = 0;
+ int line_width = 0;
current_cut = stream;
best_cut = NULL;
while (line_width < max_width) {
@@ -1081,7 +1074,7 @@ static spu_decoder_t *sputext_class_open_plugin (spu_decoder_class_t *class_gen,
sputext_class_t *class = (sputext_class_t *)class_gen;
sputext_decoder_t *this ;
- this = (sputext_decoder_t *) xine_xmalloc (sizeof (sputext_decoder_t));
+ this = (sputext_decoder_t *) calloc(1, sizeof(sputext_decoder_t));
this->spu_decoder.decode_data = spudec_decode_data;
this->spu_decoder.reset = spudec_reset;
@@ -1135,7 +1128,7 @@ static void *init_spu_decoder_plugin (xine_t *xine, void *data) {
lprintf("init class\n");
- this = (sputext_class_t *) xine_xmalloc (sizeof (sputext_class_t));
+ this = (sputext_class_t *) calloc(1, sizeof(sputext_class_t));
this->class.open_plugin = sputext_class_open_plugin;
this->class.get_identifier = sputext_class_get_identifier;
diff --git a/src/libw32dll/Makefile.am b/src/libw32dll/Makefile.am
index e7f655888..5036851a3 100644
--- a/src/libw32dll/Makefile.am
+++ b/src/libw32dll/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
AM_CFLAGS = -I$(srcdir)/wine -DWIN32_PATH=\"@w32_path@\" $(VISIBILITY_FLAG)
diff --git a/src/libw32dll/qt_decoder.c b/src/libw32dll/qt_decoder.c
index 3053b2b68..99e2ba9d4 100644
--- a/src/libw32dll/qt_decoder.c
+++ b/src/libw32dll/qt_decoder.c
@@ -553,7 +553,7 @@ static audio_decoder_t *qta_open_plugin (audio_decoder_class_t *class_gen,
qta_decoder_t *this ;
- this = (qta_decoder_t *) xine_xmalloc (sizeof (qta_decoder_t));
+ this = (qta_decoder_t *) calloc(1, sizeof(qta_decoder_t));
this->audio_decoder.decode_data = qta_decode_data;
this->audio_decoder.reset = qta_reset;
@@ -592,7 +592,7 @@ static void *qta_init_class (xine_t *xine, void *data) {
pthread_once (&once_control, init_routine);
- this = (qta_class_t *) xine_xmalloc (sizeof (qta_class_t));
+ this = (qta_class_t *) calloc(1, sizeof(qta_class_t));
this->decoder_class.open_plugin = qta_open_plugin;
this->decoder_class.get_identifier = qta_get_identifier;
@@ -1063,7 +1063,7 @@ static video_decoder_t *qtv_open_plugin (video_decoder_class_t *class_gen,
qtv_class_t *cls = (qtv_class_t *) class_gen;
qtv_decoder_t *this ;
- this = (qtv_decoder_t *) xine_xmalloc (sizeof (qtv_decoder_t));
+ this = (qtv_decoder_t *) calloc(1, sizeof(qtv_decoder_t));
this->video_decoder.decode_data = qtv_decode_data;
this->video_decoder.flush = qtv_flush;
@@ -1116,7 +1116,7 @@ static void *qtv_init_class (xine_t *xine, void *data) {
pthread_once (&once_control, init_routine);
- this = (qtv_class_t *) xine_xmalloc (sizeof (qtv_class_t));
+ this = (qtv_class_t *) calloc(1, sizeof(qtv_class_t));
this->decoder_class.open_plugin = qtv_open_plugin;
this->decoder_class.get_identifier = qtv_get_identifier;
diff --git a/src/libw32dll/w32codec.c b/src/libw32dll/w32codec.c
index 88790ebc7..e61ebcb82 100644
--- a/src/libw32dll/w32codec.c
+++ b/src/libw32dll/w32codec.c
@@ -21,6 +21,10 @@
* DirectShow support by Miguel Freitas (Nov/2001)
* DMO support (Dez/2002)
*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
#include <stdlib.h>
#include <stdio.h>
@@ -1550,7 +1554,7 @@ static video_decoder_t *open_video_decoder_plugin (video_decoder_class_t *class_
w32v_decoder_t *this ;
- this = (w32v_decoder_t *) xine_xmalloc (sizeof (w32v_decoder_t));
+ this = (w32v_decoder_t *) calloc(1, sizeof(w32v_decoder_t));
this->video_decoder.decode_data = w32v_decode_data;
this->video_decoder.flush = w32v_flush;
@@ -1593,7 +1597,7 @@ static void *init_video_decoder_class (xine_t *xine, void *data) {
cfg = xine->config;
if ((win32_def_path = get_win32_codecs_path(cfg)) == NULL) return NULL;
- this = (w32v_class_t *) xine_xmalloc (sizeof (w32v_class_t));
+ this = (w32v_class_t *) calloc(1, sizeof(w32v_class_t));
this->decoder_class.open_plugin = open_video_decoder_plugin;
this->decoder_class.get_identifier = get_video_identifier;
@@ -1614,7 +1618,7 @@ static audio_decoder_t *open_audio_decoder_plugin (audio_decoder_class_t *class_
w32a_decoder_t *this ;
- this = (w32a_decoder_t *) xine_xmalloc (sizeof (w32a_decoder_t));
+ this = (w32a_decoder_t *) calloc(1, sizeof(w32a_decoder_t));
this->audio_decoder.decode_data = w32a_decode_data;
this->audio_decoder.reset = w32a_reset;
@@ -1655,7 +1659,7 @@ static void *init_audio_decoder_class (xine_t *xine, void *data) {
cfg = xine->config;
if ((win32_def_path = get_win32_codecs_path(cfg)) == NULL) return NULL;
- this = (w32a_class_t *) xine_xmalloc (sizeof (w32a_class_t));
+ this = (w32a_class_t *) calloc(1, sizeof(w32a_class_t));
this->decoder_class.open_plugin = open_audio_decoder_plugin;
this->decoder_class.get_identifier = get_identifier;
diff --git a/src/libw32dll/wine/Makefile.am b/src/libw32dll/wine/Makefile.am
index 63da4068e..70341a502 100644
--- a/src/libw32dll/wine/Makefile.am
+++ b/src/libw32dll/wine/Makefile.am
@@ -9,7 +9,8 @@ noinst_LTLIBRARIES = $(wine_lib)
AM_CFLAGS = $(X_CFLAGS) @W32_NO_OPTIMIZE@ \
-Wmissing-prototypes -Wimplicit-function-declaration \
-DWIN32_PATH=\"@w32_path@\" -I$(srcdir)/.. -D__WINE__ \
- -Ddbg_printf=__vprintf -DTRACE=__vprintf
+ -Ddbg_printf=__vprintf -DTRACE=__vprintf \
+ -I$(top_srcdir)/src/xine-utils
# CFLAGS is here to filter out -fomit-frame-pointer,
# -finline-functions and -frename-registers because they cause bad
diff --git a/src/libw32dll/wine/driver.c b/src/libw32dll/wine/driver.c
index ef8761628..296fcd25a 100644
--- a/src/libw32dll/wine/driver.c
+++ b/src/libw32dll/wine/driver.c
@@ -1,4 +1,4 @@
-#include <config.h>
+#include "config.h"
#include <stdio.h>
#ifdef HAVE_MALLOC_H
#include <malloc.h>
diff --git a/src/libw32dll/wine/elfdll.c b/src/libw32dll/wine/elfdll.c
index 7853ffe71..e81467b5a 100644
--- a/src/libw32dll/wine/elfdll.c
+++ b/src/libw32dll/wine/elfdll.c
@@ -3,7 +3,7 @@
*
* Copyright 1999 Bertho A. Stultiens
*/
-#include <config.h>
+#include "config.h"
#ifdef HAVE_LIBDL
diff --git a/src/libw32dll/wine/pe_image.c b/src/libw32dll/wine/pe_image.c
index c99bbaed0..1366cc396 100644
--- a/src/libw32dll/wine/pe_image.c
+++ b/src/libw32dll/wine/pe_image.c
@@ -900,7 +900,7 @@ void PE_UnloadLibrary(WINE_MODREF *wm)
*/
static void extend_stack_for_dll_alloca(void)
{
-#ifndef __FreeBSD__
+#if !defined(__FreeBSD__) && !defined(__OpenBSD__)
void* mem=alloca(0x20000);
*(int*)mem=0x1234;
#endif
diff --git a/src/libw32dll/wine/pe_resource.c b/src/libw32dll/wine/pe_resource.c
index 6acfef2f0..16dc85389 100644
--- a/src/libw32dll/wine/pe_resource.c
+++ b/src/libw32dll/wine/pe_resource.c
@@ -9,7 +9,7 @@
* Copyright 1995 Alexandre Julliard
* Copyright 1997 Marcus Meissner
*/
-#include <config.h>
+#include "config.h"
#include <stdlib.h>
#include <sys/types.h>
diff --git a/src/libw32dll/wine/registry.c b/src/libw32dll/wine/registry.c
index 0f91499b3..0ccf3de9b 100644
--- a/src/libw32dll/wine/registry.c
+++ b/src/libw32dll/wine/registry.c
@@ -311,8 +311,7 @@ static void init_registry(void)
localregpathname = regpathname;
#else
#ifdef XINE_MAJOR
- localregpathname = (char *)malloc(strlen(xine_get_homedir()) + 21);
- sprintf(localregpathname, "%s/.xine/win32registry", xine_get_homedir());
+ asprintf(&localregpathname, "%s/.xine/win32registry", xine_get_homedir());
#else
// regpathname is an external pointer
//
diff --git a/src/libw32dll/wine/resource.c b/src/libw32dll/wine/resource.c
index 9d4fa80bb..a38c1dd1e 100644
--- a/src/libw32dll/wine/resource.c
+++ b/src/libw32dll/wine/resource.c
@@ -4,7 +4,7 @@
* Copyright 1993 Robert J. Amstadt
* Copyright 1995 Alexandre Julliard
*/
-#include <config.h>
+#include "config.h"
#include <assert.h>
#include <stdio.h>
diff --git a/src/libw32dll/wine/vfl.c b/src/libw32dll/wine/vfl.c
index e8eb7969f..f509995de 100644
--- a/src/libw32dll/wine/vfl.c
+++ b/src/libw32dll/wine/vfl.c
@@ -1,7 +1,7 @@
/*
* Copyright 1998 Marcus Meissner
*/
-#include <config.h>
+#include "config.h"
#include <stdio.h>
#include <stdlib.h>
diff --git a/src/libw32dll/wine/win32.c b/src/libw32dll/wine/win32.c
index 3b0941391..d9744ae35 100644
--- a/src/libw32dll/wine/win32.c
+++ b/src/libw32dll/wine/win32.c
@@ -1430,7 +1430,7 @@ static void WINAPI expDeleteCriticalSection(CRITICAL_SECTION *c)
}
static int WINAPI expGetCurrentThreadId()
{
- dbgprintf("GetCurrentThreadId() => %ld\n", pthread_self());
+ dbgprintf("GetCurrentThreadId() => %ld\n", (long int)pthread_self());
return (int)pthread_self();
}
static int WINAPI expGetCurrentProcess()
@@ -2134,7 +2134,6 @@ static const char* WINAPI expGetCommandLineA()
dbgprintf("GetCommandLineA() => \"c:\\aviplay.exe\"\n");
return "c:\\aviplay.exe";
}
-static short envs[]={'p', 'a', 't', 'h', ' ', 'c', ':', '\\', 0, 0};
static LPWSTR WINAPI expGetEnvironmentStringsW()
{
dbgprintf("GetEnvironmentStringsW() => 0\n");
@@ -3491,9 +3490,9 @@ static HANDLE WINAPI expCreateFileA(LPCSTR cs1,DWORD i1,DWORD i2,
if(strstr(cs1, ".qtx"))
{
int result;
- char* tmp=(char*)malloc(strlen(win32_def_path)+250);
char* x=strrchr(cs1,'\\');
- sprintf(tmp,"%s/%s",win32_def_path,x?(x+1):cs1);
+ char* tmp;
+ asprintf(&tmp,"%s/%s",win32_def_path,x?(x+1):cs1);
// printf("### Open: %s -> %s\n",cs1,tmp);
result=open(tmp, O_RDONLY);
free(tmp);
@@ -3998,7 +3997,7 @@ static int XINE_FORMAT_PRINTF(2, 3) expsprintf(char* str, const char* format, ..
va_end(args);
return r;
}
-static int XINE_FORMAT_PRINTF(2, 3) expsscanf(const char* str, const char* format, ...)
+static int XINE_FORMAT_SCANF(2, 3) expsscanf(const char* str, const char* format, ...)
{
va_list args;
int r;
@@ -4162,7 +4161,7 @@ static void* expmemset(void* dest, int c, size_t n)
static time_t exptime(time_t* t)
{
time_t result = time(t);
- dbgprintf("time(%p) => %ld\n", t, result);
+ dbgprintf("time(%p) => %ld\n", t, (long int)result);
return result;
}
@@ -5058,11 +5057,9 @@ struct libs libraries[]={
LL(ddraw)
#endif
};
-#if defined(__CYGWIN__) || defined(__OS2__) || defined (__OpenBSD__)
-#define MANGLE(a) "_" #a
-#else
-#define MANGLE(a) #a
-#endif
+
+#include "mangle.h"
+
static void ext_stubs(void)
{
// expects:
diff --git a/src/libxineadec/Makefile.am b/src/libxineadec/Makefile.am
index d502b7955..ae261e60c 100644
--- a/src/libxineadec/Makefile.am
+++ b/src/libxineadec/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
EXTRA_DIST = fooaudio.c
@@ -39,7 +40,7 @@ xineplug_decode_lpcm_la_CFLAGS = $(VISIBILITY_FLAG)
xineplug_decode_lpcm_la_LIBADD = $(XINE_LIB)
xineplug_decode_vorbis_la_SOURCES = xine_vorbis_decoder.c
-xineplug_decode_vorbis_la_LIBADD = $(XINE_LIB) $(VORBIS_LIBS) $(OGG_LIBS)
+xineplug_decode_vorbis_la_LIBADD = $(XINE_LIB) $(VORBIS_LIBS) $(OGG_LIBS) $(LTLIBINTL)
xineplug_decode_vorbis_la_CFLAGS = $(VISIBILITY_FLAG) $(VORBIS_CFLAGS)
xineplug_decode_speex_la_SOURCES = xine_speex_decoder.c
diff --git a/src/libxineadec/fooaudio.c b/src/libxineadec/fooaudio.c
index 5ab4fa1f6..53fcef801 100644
--- a/src/libxineadec/fooaudio.c
+++ b/src/libxineadec/fooaudio.c
@@ -22,6 +22,10 @@
* place of the data it should actually send.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -91,7 +95,7 @@ static void fooaudio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
this->channels = buf->decoder_info[3];
/* initialize the data accumulation buffer */
- this->buf = xine_xmalloc(AUDIOBUFSIZE);
+ this->buf = calloc(1, AUDIOBUFSIZE);
this->bufsize = AUDIOBUFSIZE;
this->size = 0;
@@ -255,7 +259,7 @@ static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stre
fooaudio_decoder_t *this ;
- this = (fooaudio_decoder_t *) xine_xmalloc (sizeof (fooaudio_decoder_t));
+ this = (fooaudio_decoder_t *) calloc(1, sizeof(fooaudio_decoder_t));
/* connect the member functions */
this->audio_decoder.decode_data = fooaudio_decode_data;
diff --git a/src/libxineadec/gsm610.c b/src/libxineadec/gsm610.c
index 23c0d2104..c67382bc5 100644
--- a/src/libxineadec/gsm610.c
+++ b/src/libxineadec/gsm610.c
@@ -101,7 +101,7 @@ static void gsm610_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
if (buf->decoder_flags & BUF_FLAG_STDHEADER) {
this->sample_rate = buf->decoder_info[1];
- this->buf = xine_xmalloc(AUDIOBUFSIZE);
+ this->buf = calloc(1, AUDIOBUFSIZE);
this->bufsize = AUDIOBUFSIZE;
this->size = 0;
@@ -233,7 +233,7 @@ static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stre
gsm610_decoder_t *this ;
- this = (gsm610_decoder_t *) xine_xmalloc (sizeof (gsm610_decoder_t));
+ this = (gsm610_decoder_t *) calloc(1, sizeof(gsm610_decoder_t));
this->audio_decoder.decode_data = gsm610_decode_data;
this->audio_decoder.reset = gsm610_reset;
@@ -265,7 +265,7 @@ static void *init_plugin (xine_t *xine, void *data) {
gsm610_class_t *this ;
- this = (gsm610_class_t *) xine_xmalloc (sizeof (gsm610_class_t));
+ this = (gsm610_class_t *) calloc(1, sizeof(gsm610_class_t));
this->decoder_class.open_plugin = open_plugin;
this->decoder_class.get_identifier = get_identifier;
diff --git a/src/libxineadec/gsm610/long_term.c b/src/libxineadec/gsm610/long_term.c
index 625662e1f..d3ef1b63d 100644
--- a/src/libxineadec/gsm610/long_term.c
+++ b/src/libxineadec/gsm610/long_term.c
@@ -6,6 +6,10 @@
/* $Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/long_term.c,v 1.3 2003/12/07 15:34:30 f1rmb Exp $ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include "xineutils.h"
diff --git a/src/libxineadec/gsm610/lpc.c b/src/libxineadec/gsm610/lpc.c
index 0f51fa55f..7a8a8e2bc 100644
--- a/src/libxineadec/gsm610/lpc.c
+++ b/src/libxineadec/gsm610/lpc.c
@@ -6,6 +6,10 @@
/* $Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/lpc.c,v 1.3 2003/12/07 15:34:30 f1rmb Exp $ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include "xineutils.h"
diff --git a/src/libxineadec/gsm610/rpe.c b/src/libxineadec/gsm610/rpe.c
index 67d94d30e..be1b1529b 100644
--- a/src/libxineadec/gsm610/rpe.c
+++ b/src/libxineadec/gsm610/rpe.c
@@ -6,6 +6,10 @@
/* $Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/rpe.c,v 1.3 2003/12/07 15:34:30 f1rmb Exp $ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include "xineutils.h"
#include "private.h"
diff --git a/src/libxineadec/gsm610/short_term.c b/src/libxineadec/gsm610/short_term.c
index 8222b2caa..c2d64853b 100644
--- a/src/libxineadec/gsm610/short_term.c
+++ b/src/libxineadec/gsm610/short_term.c
@@ -6,6 +6,10 @@
/* $Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/short_term.c,v 1.3 2003/12/07 15:34:30 f1rmb Exp $ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include "xineutils.h"
#include "private.h"
diff --git a/src/libxineadec/nsf.c b/src/libxineadec/nsf.c
index bdf523f1d..d4841ec6e 100644
--- a/src/libxineadec/nsf.c
+++ b/src/libxineadec/nsf.c
@@ -21,6 +21,10 @@
* http://www.baisoku.org/
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -90,7 +94,7 @@ static void nsf_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
this->song_number = buf->content[4];
/* allocate a buffer for the file */
this->nsf_size = _X_BE_32(&buf->content[0]);
- this->nsf_file = xine_xmalloc(this->nsf_size);
+ this->nsf_file = calloc(1, this->nsf_size);
this->nsf_index = 0;
/* peform any other required initialization */
@@ -205,7 +209,7 @@ static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stre
nsf_decoder_t *this ;
- this = (nsf_decoder_t *) xine_xmalloc (sizeof (nsf_decoder_t));
+ this = (nsf_decoder_t *) calloc(1, sizeof(nsf_decoder_t));
/* connect the member functions */
this->audio_decoder.decode_data = nsf_decode_data;
@@ -255,7 +259,7 @@ static void *init_plugin (xine_t *xine, void *data) {
nsf_class_t *this ;
- this = (nsf_class_t *) xine_xmalloc (sizeof (nsf_class_t));
+ this = (nsf_class_t *) calloc(1, sizeof(nsf_class_t));
this->decoder_class.open_plugin = open_plugin;
this->decoder_class.get_identifier = get_identifier;
diff --git a/src/libxineadec/xine_lpcm_decoder.c b/src/libxineadec/xine_lpcm_decoder.c
index 8d8f23a05..435545d56 100644
--- a/src/libxineadec/xine_lpcm_decoder.c
+++ b/src/libxineadec/xine_lpcm_decoder.c
@@ -20,6 +20,11 @@
* 31-8-2001 Added LPCM rate sensing.
* (c) 2001 James Courtier-Dutton James@superbug.demon.co.uk
*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#ifndef __sun
#define _XOPEN_SOURCE 500
#endif
@@ -187,18 +192,34 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
uint8_t *d = (uint8_t *)audio_buffer->mem;
int n = buf->size;
- while (n >= 0) {
+ while (n >= 3) {
if ( stream_be ) {
- *d++ = s[0];
- *d++ = s[1];
+ if ( stream_be == this->cpu_be ) {
+ *d++ = s[0];
+ *d++ = s[1];
+ } else {
+ *d++ = s[1];
+ *d++ = s[0];
+ }
} else {
- *d++ = s[1];
- *d++ = s[2];
+ if ( stream_be == this->cpu_be ) {
+ *d++ = s[1];
+ *d++ = s[2];
+ }
+ else
+ {
+ *d++ = s[2];
+ *d++ = s[1];
+ }
}
s += 3;
n -= 3;
}
+
+ if ( (d - (uint8_t*)audio_buffer->mem)/2*3 < buf->size )
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "lpcm_decoder: lost %i bytes\n", (int)(buf->size - (d - (uint8_t*)audio_buffer->mem))/2*3);
+
} else {
memcpy (audio_buffer->mem, sample_buffer, buf->size);
}
@@ -224,7 +245,7 @@ static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stre
lpcm_decoder_t *this ;
- this = (lpcm_decoder_t *) xine_xmalloc (sizeof (lpcm_decoder_t));
+ this = (lpcm_decoder_t *) calloc(1, sizeof(lpcm_decoder_t));
this->audio_decoder.decode_data = lpcm_decode_data;
this->audio_decoder.reset = lpcm_reset;
@@ -259,7 +280,7 @@ static void *init_plugin (xine_t *xine, void *data) {
lpcm_class_t *this ;
- this = (lpcm_class_t *) xine_xmalloc (sizeof (lpcm_class_t));
+ this = (lpcm_class_t *) calloc(1, sizeof(lpcm_class_t));
this->decoder_class.open_plugin = open_plugin;
this->decoder_class.get_identifier = get_identifier;
diff --git a/src/libxineadec/xine_speex_decoder.c b/src/libxineadec/xine_speex_decoder.c
index aa8234385..46ea3a9f9 100644
--- a/src/libxineadec/xine_speex_decoder.c
+++ b/src/libxineadec/xine_speex_decoder.c
@@ -170,16 +170,16 @@ void read_metadata (speex_decoder_t *this, char * comments, int length)
#endif
for (i = 0; speex_comment_keys[i].key != NULL; i++) {
+ size_t keylen = strlen(speex_comment_keys[i].key);
if ( !strncasecmp (speex_comment_keys[i].key, c,
- strlen(speex_comment_keys[i].key)) ) {
- int keylen = strlen(speex_comment_keys[i].key);
+ keylen) ) {
char meta_info[(len - keylen) + 1];
lprintf ("known metadata %d %d\n",
i, speex_comment_keys[i].xine_metainfo_index);
- snprintf(meta_info, (len - keylen), "%s", c + keylen);
+ strncpy(meta_info, &c[keylen], len-keylen);
_x_meta_info_set_utf8(this->stream, speex_comment_keys[i].xine_metainfo_index, meta_info);
}
}
@@ -204,7 +204,7 @@ static void speex_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
if (!this->st) {
SpeexMode * spx_mode;
SpeexHeader * spx_header;
- int modeID;
+ unsigned int modeID;
int bitrate;
speex_bits_init (&this->bits);
@@ -216,7 +216,12 @@ static void speex_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
return;
}
- modeID = spx_header->mode;
+ modeID = (unsigned int)spx_header->mode;
+ if (modeID >= SPEEX_NB_MODES) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": invalid mode ID %u\n", modeID);
+ return;
+ }
+
spx_mode = (SpeexMode *) speex_mode_list[modeID];
if (spx_mode->bitstream_version != spx_header->mode_bitstream_version) {
@@ -280,7 +285,7 @@ static void speex_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
}
} else if (this->output_open) {
- int i, j;
+ int j;
audio_buffer_t *audio_buffer;
@@ -350,7 +355,7 @@ static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen,
speex_decoder_t *this ;
static SpeexStereoState init_stereo = SPEEX_STEREO_STATE_INIT;
- this = (speex_decoder_t *) xine_xmalloc (sizeof (speex_decoder_t));
+ this = (speex_decoder_t *) calloc(1, sizeof(speex_decoder_t));
this->audio_decoder.decode_data = speex_decode_data;
this->audio_decoder.reset = speex_reset;
@@ -391,7 +396,7 @@ static void *init_plugin (xine_t *xine, void *data) {
speex_class_t *this;
- this = (speex_class_t *) xine_xmalloc (sizeof (speex_class_t));
+ this = (speex_class_t *) calloc(1, sizeof(speex_class_t));
this->decoder_class.open_plugin = open_plugin;
this->decoder_class.get_identifier = get_identifier;
diff --git a/src/libxineadec/xine_vorbis_decoder.c b/src/libxineadec/xine_vorbis_decoder.c
index 4b7a6c15d..218c26033 100644
--- a/src/libxineadec/xine_vorbis_decoder.c
+++ b/src/libxineadec/xine_vorbis_decoder.c
@@ -41,6 +41,7 @@
#include <vorbis/codec.h>
#define MAX_NUM_SAMPLES 4096
+#define INIT_BUFSIZE 8192
typedef struct {
audio_decoder_class_t decoder_class;
@@ -70,6 +71,11 @@ typedef struct vorbis_decoder_s {
xine_stream_t *stream;
+ /* data accumulation stuff */
+ unsigned char *buf;
+ int bufsize;
+ int size;
+
} vorbis_decoder_t;
@@ -78,6 +84,7 @@ static void vorbis_reset (audio_decoder_t *this_gen) {
vorbis_decoder_t *this = (vorbis_decoder_t *) this_gen;
if( this->header_count ) return;
+ this->size = 0;
/* clear block first, as it might contain allocated data */
vorbis_block_clear(&this->vb);
@@ -136,126 +143,147 @@ static void get_metadata (vorbis_decoder_t *this) {
_x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "vorbis");
}
+static void vorbis_check_bufsize (vorbis_decoder_t *this, int size) {
+ if (size > this->bufsize) {
+ this->bufsize = size + size / 2;
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ _("vorbis: increasing buffer to %d to avoid overflow.\n"),
+ this->bufsize);
+ this->buf = realloc(this->buf, this->bufsize);
+ }
+}
+
static void vorbis_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
vorbis_decoder_t *this = (vorbis_decoder_t *) this_gen;
memset( &this->op, 0, sizeof(this->op) );
- this->op.packet = buf->content;
- this->op.bytes = buf->size;
-
- if ( (buf->decoder_flags & BUF_FLAG_HEADER) &&
- !(buf->decoder_flags & BUF_FLAG_STDHEADER) ) {
- lprintf ("%d headers to go\n", this->header_count);
- if (this->header_count) {
- int res = 0;
+ /* data accumulation */
+ vorbis_check_bufsize(this, this->size + buf->size);
+ xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size);
+ this->size += buf->size;
- if (this->header_count == 3)
- this->op.b_o_s = 1;
+ if (buf->decoder_flags & BUF_FLAG_FRAME_END) {
+ this->op.packet = this->buf;
+ this->op.bytes = this->size;
-
- if( (res = vorbis_synthesis_headerin(&this->vi,&this->vc,&this->op)) < 0 ){
- /* error case; not a vorbis header */
- xine_log(this->stream->xine, XINE_LOG_MSG, "libvorbis: this bitstream does not contain vorbis audio data. Following first 64 bytes (return: %d).\n", res);
- xine_hexdump((char *)this->op.packet, this->op.bytes < 64 ? this->op.bytes : 64);
- return;
- }
-
- this->header_count--;
-
- if (!this->header_count) {
-
- int mode = AO_CAP_MODE_MONO;
-
- get_metadata (this);
-
- mode = _x_ao_channels2mode(this->vi.channels);
-
- this->convsize=MAX_NUM_SAMPLES/this->vi.channels;
-
- if (!this->output_open) {
- this->output_open = (this->stream->audio_out->open) (this->stream->audio_out,
- this->stream,
- 16,
- this->vi.rate,
- mode) ;
-
- _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE,
- this->vi.bitrate_nominal);
-
- }
-
- /* OK, got and parsed all three headers. Initialize the Vorbis
- * packet->PCM decoder. */
- lprintf("all three headers parsed. initializing decoder.\n");
- /* initialize central decode state */
- vorbis_synthesis_init(&this->vd,&this->vi);
- /* initialize local state for most of the decode so multiple
- * block decodes can proceed in parallel. We could init
- * multiple vorbis_block structures for vd here */
- vorbis_block_init(&this->vd,&this->vb);
+ /* reset accumultaion buffer */
+ this->size = 0;
+
+ if ( (buf->decoder_flags & BUF_FLAG_HEADER) &&
+ !(buf->decoder_flags & BUF_FLAG_STDHEADER) ) {
+
+ lprintf ("%d headers to go\n", this->header_count);
+
+ if (this->header_count) {
+ int res = 0;
+
+ if (this->header_count == 3)
+ this->op.b_o_s = 1;
+
+ if ( (res = vorbis_synthesis_headerin(&this->vi,&this->vc,&this->op)) < 0 ) {
+ /* error case; not a vorbis header */
+ xine_log(this->stream->xine, XINE_LOG_MSG, "libvorbis: this bitstream does not contain vorbis audio data. Following first 64 bytes (return: %d).\n", res);
+ xine_hexdump((char *)this->op.packet, this->op.bytes < 64 ? this->op.bytes : 64);
+ return;
+ }
+
+ this->header_count--;
+
+ if (!this->header_count) {
+
+ int mode = AO_CAP_MODE_MONO;
+
+ get_metadata (this);
+
+ mode = _x_ao_channels2mode(this->vi.channels);
+
+ this->convsize=MAX_NUM_SAMPLES/this->vi.channels;
+
+ if (!this->output_open) {
+ this->output_open = (this->stream->audio_out->open) (this->stream->audio_out,
+ this->stream,
+ 16,
+ this->vi.rate,
+ mode) ;
+
+ _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE,
+ this->vi.bitrate_nominal);
+
+ }
+
+ /* OK, got and parsed all three headers. Initialize the Vorbis
+ * packet->PCM decoder. */
+ lprintf("all three headers parsed. initializing decoder.\n");
+ /* initialize central decode state */
+ vorbis_synthesis_init(&this->vd,&this->vi);
+ /* initialize local state for most of the decode so multiple
+ * block decodes can proceed in parallel. We could init
+ * multiple vorbis_block structures for vd here */
+ vorbis_block_init(&this->vd,&this->vb);
+ }
}
- }
-
- } else if (this->output_open) {
-
- float **pcm;
- int samples;
-
- if(vorbis_synthesis(&this->vb,&this->op)==0)
- vorbis_synthesis_blockin(&this->vd,&this->vb);
-
- if (buf->pts!=0)
- this->pts=buf->pts;
-
- while ((samples=vorbis_synthesis_pcmout(&this->vd,&pcm))>0){
-
- /* **pcm is a multichannel float vector. In stereo, for
- * example, pcm[0][...] is left, and pcm[1][...] is right.
- * samples is the size of each channel. Convert the float
- * values (-1.<=range<=1.) to whatever PCM format and write
- * it out
- */
-
- int i,j;
- int bout=(samples<this->convsize?samples:this->convsize);
- audio_buffer_t *audio_buffer;
-
- audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out);
-
- /* convert floats to 16 bit signed ints (host order) and
- interleave */
- for(i=0;i<this->vi.channels;i++){
- ogg_int16_t *ptr=audio_buffer->mem+i;
- float *mono=pcm[i];
- for(j=0;j<bout;j++){
- int val=(mono[j] + 1.0f) * 32768.f;
- val -= 32768;
- /* might as well guard against clipping */
- if(val>32767){
- val=32767;
- } else if(val<-32768){
- val=-32768;
- }
- *ptr=val;
- ptr+=this->vi.channels;
- }
+
+ } else if (this->output_open) {
+
+ float **pcm;
+ int samples;
+
+ if(vorbis_synthesis(&this->vb,&this->op)==0)
+ vorbis_synthesis_blockin(&this->vd,&this->vb);
+
+ if (buf->pts!=0)
+ this->pts=buf->pts;
+
+ while ((samples=vorbis_synthesis_pcmout(&this->vd,&pcm))>0){
+
+ /* **pcm is a multichannel float vector. In stereo, for
+ * example, pcm[0][...] is left, and pcm[1][...] is right.
+ * samples is the size of each channel. Convert the float
+ * values (-1.<=range<=1.) to whatever PCM format and write
+ * it out
+ */
+
+ int i,j;
+ int bout=(samples<this->convsize?samples:this->convsize);
+ audio_buffer_t *audio_buffer;
+
+ audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out);
+
+ /* convert floats to 16 bit signed ints (host order) and
+ interleave */
+ for(i=0;i<this->vi.channels;i++){
+ ogg_int16_t *ptr=audio_buffer->mem+i;
+ float *mono=pcm[i];
+ for(j=0;j<bout;j++){
+ int val=(mono[j] + 1.0f) * 32768.f;
+ val -= 32768;
+ /* might as well guard against clipping */
+ if(val>32767){
+ val=32767;
+ } else if(val<-32768){
+ val=-32768;
+ }
+ *ptr=val;
+ ptr+=this->vi.channels;
+ }
+ }
+
+ audio_buffer->vpts = this->pts;
+ this->pts=0;
+ audio_buffer->num_frames = bout;
+
+ this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream);
+
+ buf->pts=0;
+
+ /* tell libvorbis how many samples we actually consumed */
+ vorbis_synthesis_read(&this->vd,bout);
}
-
- audio_buffer->vpts = this->pts;
- this->pts=0;
- audio_buffer->num_frames = bout;
-
- this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream);
-
- buf->pts=0;
-
- /* tell libvorbis how many samples we actually consumed */
- vorbis_synthesis_read(&this->vd,bout);
+ } else {
+ lprintf("output not open\n");
}
- } else {
- lprintf("output not open\n");
}
}
@@ -287,7 +315,7 @@ static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen,
vorbis_decoder_t *this ;
- this = (vorbis_decoder_t *) xine_xmalloc (sizeof (vorbis_decoder_t));
+ this = (vorbis_decoder_t *) calloc(1, sizeof(vorbis_decoder_t));
this->audio_decoder.decode_data = vorbis_decode_data;
this->audio_decoder.reset = vorbis_reset;
@@ -299,6 +327,10 @@ static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen,
this->header_count = 3;
this->convsize = 0;
+ this->bufsize = INIT_BUFSIZE;
+ this->buf = calloc(1, INIT_BUFSIZE);
+ this->size = 0;
+
vorbis_info_init(&this->vi);
vorbis_comment_init(&this->vc);
@@ -327,7 +359,7 @@ static void *init_plugin (xine_t *xine, void *data) {
vorbis_class_t *this;
- this = (vorbis_class_t *) xine_xmalloc (sizeof (vorbis_class_t));
+ this = (vorbis_class_t *) calloc(1, sizeof(vorbis_class_t));
this->decoder_class.open_plugin = open_plugin;
this->decoder_class.get_identifier = get_identifier;
diff --git a/src/libxinevdec/Makefile.am b/src/libxinevdec/Makefile.am
index 9805eb09e..b7dbe1db1 100644
--- a/src/libxinevdec/Makefile.am
+++ b/src/libxinevdec/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
AM_CFLAGS = $(VISIBILITY_FLAG)
@@ -43,4 +44,4 @@ xineplug_decode_gdk_pixbuf_la_LIBADD = $(XINE_LIB) $(DYNAMIC_LD_LIBS) $(GDK_PIXB
xineplug_decode_theora_la_SOURCES = xine_theora_decoder.c
xineplug_decode_theora_la_CFLAGS = $(AM_CFLAGS) $(OGG_CFLAGS) $(THEORA_CFLAGS)
-xineplug_decode_theora_la_LIBADD = $(XINE_LIB) $(OGG_LIBS) $(THEORA_LIBS)
+xineplug_decode_theora_la_LIBADD = $(XINE_LIB) $(OGG_LIBS) $(THEORA_LIBS) $(LTLIBINTL)
diff --git a/src/libxinevdec/bitplane.c b/src/libxinevdec/bitplane.c
index bf868ad2a..76b7c8a89 100644
--- a/src/libxinevdec/bitplane.c
+++ b/src/libxinevdec/bitplane.c
@@ -29,6 +29,10 @@
* - untested (found no testfiles) IFF-ANIM OPT 3, 4 and 6
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -252,7 +256,7 @@ static uint8_t *bitplane_decode_byterun1 (uint8_t *compressed,
int i = 0;
int j = 0;
- uint8_t *uncompressed = xine_xmalloc( size_uncompressed );
+ uint8_t *uncompressed = calloc(1, size_uncompressed );
while ( i < size_compressed &&
pixel_ptr < size_uncompressed ) {
@@ -1158,8 +1162,8 @@ static void bitplane_decode_data (video_decoder_t *this_gen,
this->bytes_per_pixel = 1;
/* New Buffer for indexes (palette based formats) */
- this->index_buf = xine_xmalloc( this->num_pixel * this->bytes_per_pixel );
- this->index_buf_hist = xine_xmalloc( this->num_pixel * this->bytes_per_pixel );
+ this->index_buf = calloc( this->num_pixel, this->bytes_per_pixel );
+ this->index_buf_hist = calloc( this->num_pixel, this->bytes_per_pixel );
this->num_bitplanes = bih->biPlanes;
this->camg_mode = bih->biCompression;
@@ -1189,7 +1193,7 @@ static void bitplane_decode_data (video_decoder_t *this_gen,
if (this->buf)
free (this->buf);
this->bufsize = VIDEOBUFSIZE;
- this->buf = xine_xmalloc(this->bufsize);
+ this->buf = calloc(1, this->bufsize);
this->size = 0;
this->framenumber = 0;
@@ -1255,7 +1259,7 @@ static void bitplane_decode_data (video_decoder_t *this_gen,
case BUF_VIDEO_BITPLANE:
/* uncompressed Buffer, set decoded_buf pointer direct to input stream */
if( this->buf_uk == NULL )
- this->buf_uk = xine_xmalloc( (this->size) );
+ this->buf_uk = malloc(this->size);
xine_fast_memcpy (this->buf_uk, this->buf, this->size);
break;
case BUF_VIDEO_BITPLANE_BR1:
@@ -1294,7 +1298,7 @@ static void bitplane_decode_data (video_decoder_t *this_gen,
}
}
if( this->buf_uk_hist == NULL ) {
- this->buf_uk_hist = xine_xmalloc( (this->size_uk) );
+ this->buf_uk_hist = malloc(this->size_uk);
xine_fast_memcpy (this->buf_uk_hist, this->buf_uk, this->size_uk);
xine_fast_memcpy (this->index_buf_hist, this->index_buf,
(this->num_pixel * this->bytes_per_pixel));
@@ -1306,20 +1310,12 @@ static void bitplane_decode_data (video_decoder_t *this_gen,
/* when no start-picture is given, create a empty one */
if( this->buf_uk_hist == NULL ) {
this->size_uk = (((this->num_pixel) / 8) * this->num_bitplanes);
- this->buf_uk = xine_xmalloc( (this->size_uk) );
- this->buf_uk_hist = xine_xmalloc( (this->size_uk) );
- for (i = 0; i < this->size_uk; i++) {
- this->buf_uk[i] = 0;
- this->buf_uk_hist[i] = 0;
- }
+ this->buf_uk = calloc(this->num_bitplanes, ((this->num_pixel) / 8));
+ this->buf_uk_hist = calloc(this->num_bitplanes, ((this->num_pixel) / 8));
}
if( this->index_buf == NULL ) {
- this->index_buf = xine_xmalloc( (this->num_pixel * this->bytes_per_pixel) );
- this->index_buf_hist = xine_xmalloc( (this->num_pixel * this->bytes_per_pixel) );
- for (i = 0; i < (this->num_pixel * this->bytes_per_pixel); i++) {
- this->index_buf[i] = 0;
- this->index_buf_hist[i] = 0;
- }
+ this->index_buf = calloc( this->num_pixel, this->bytes_per_pixel );
+ this->index_buf_hist = calloc( this->num_pixel, this->bytes_per_pixel );
}
switch( anhd->operation ) {
@@ -1523,7 +1519,7 @@ static void bitplane_dispose (video_decoder_t *this_gen) {
static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) {
- bitplane_decoder_t *this = (bitplane_decoder_t *) xine_xmalloc (sizeof (bitplane_decoder_t));
+ bitplane_decoder_t *this = (bitplane_decoder_t *) calloc(1, sizeof(bitplane_decoder_t));
this->video_decoder.decode_data = bitplane_decode_data;
this->video_decoder.flush = bitplane_flush;
@@ -1558,7 +1554,7 @@ static void dispose_class (video_decoder_class_t *this) {
static void *init_plugin (xine_t *xine, void *data) {
- bitplane_class_t *this = (bitplane_class_t *) xine_xmalloc (sizeof (bitplane_class_t));
+ bitplane_class_t *this = (bitplane_class_t *) calloc(1, sizeof(bitplane_class_t));
this->decoder_class.open_plugin = open_plugin;
this->decoder_class.get_identifier = get_identifier;
diff --git a/src/libxinevdec/foovideo.c b/src/libxinevdec/foovideo.c
index 98e0ebc0b..7a80c7c66 100644
--- a/src/libxinevdec/foovideo.c
+++ b/src/libxinevdec/foovideo.c
@@ -24,6 +24,10 @@
* frame when the frames are played in succession.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -206,7 +210,7 @@ static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stre
foovideo_decoder_t *this ;
- this = (foovideo_decoder_t *) xine_xmalloc (sizeof (foovideo_decoder_t));
+ this = (foovideo_decoder_t *) calloc(1, sizeof(foovideo_decoder_t));
this->video_decoder.decode_data = foovideo_decode_data;
this->video_decoder.flush = foovideo_flush;
@@ -256,7 +260,7 @@ static void *init_plugin (xine_t *xine, void *data) {
foovideo_class_t *this;
- this = (foovideo_class_t *) xine_xmalloc (sizeof (foovideo_class_t));
+ this = (foovideo_class_t *) calloc(1, sizeof(foovideo_class_t));
this->decoder_class.open_plugin = open_plugin;
this->decoder_class.get_identifier = get_identifier;
diff --git a/src/libxinevdec/gdkpixbuf.c b/src/libxinevdec/gdkpixbuf.c
index b5acdfa42..de4c2271e 100644
--- a/src/libxinevdec/gdkpixbuf.c
+++ b/src/libxinevdec/gdkpixbuf.c
@@ -20,6 +20,11 @@
* a gdk-pixbuf-based image video decoder
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
#include <stdlib.h>
#include <string.h>
@@ -236,7 +241,7 @@ static video_decoder_t *open_plugin (video_decoder_class_t *class_gen,
g_type_init ();
- this = (image_decoder_t *) xine_xmalloc (sizeof (image_decoder_t));
+ this = (image_decoder_t *) calloc(1, sizeof(image_decoder_t));
this->video_decoder.decode_data = image_decode_data;
this->video_decoder.flush = image_flush;
@@ -277,7 +282,7 @@ static void *init_class (xine_t *xine, void *data) {
image_class_t *this;
- this = (image_class_t *) xine_xmalloc (sizeof (image_class_t));
+ this = (image_class_t *) calloc(1, sizeof(image_class_t));
this->decoder_class.open_plugin = open_plugin;
this->decoder_class.get_identifier = get_identifier;
diff --git a/src/libxinevdec/image.c b/src/libxinevdec/image.c
index a338e3cab..bd749be8e 100644
--- a/src/libxinevdec/image.c
+++ b/src/libxinevdec/image.c
@@ -20,6 +20,10 @@
* a image video decoder
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <string.h>
@@ -88,7 +92,7 @@ static void image_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
if (buf->decoder_flags & BUF_FLAG_FRAME_END) {
int width, height, i;
- MagickBooleanType status;
+ int status;
MagickWand *wand;
uint8_t *img_buf, *img_buf_ptr;
yuv_planes_t yuv_planes;
@@ -101,7 +105,7 @@ static void image_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
status = MagickReadImageBlob(wand, this->image, this->index);
this->index = 0;
- if (status == MagickFalse) {
+ if (!status) {
DestroyMagickWand(wand);
lprintf("error loading image\n");
return;
@@ -212,7 +216,7 @@ static video_decoder_t *open_plugin (video_decoder_class_t *class_gen,
lprintf("opened\n");
- this = (image_decoder_t *) xine_xmalloc (sizeof (image_decoder_t));
+ this = (image_decoder_t *) calloc(1, sizeof(image_decoder_t));
this->video_decoder.decode_data = image_decode_data;
this->video_decoder.flush = image_flush;
@@ -255,7 +259,7 @@ static void *init_class (xine_t *xine, void *data) {
image_class_t *this;
- this = (image_class_t *) xine_xmalloc (sizeof (image_class_t));
+ this = (image_class_t *) calloc(1, sizeof(image_class_t));
this->decoder_class.open_plugin = open_plugin;
this->decoder_class.get_identifier = get_identifier;
diff --git a/src/libxinevdec/rgb.c b/src/libxinevdec/rgb.c
index 0e7be4c18..fc206a0ce 100644
--- a/src/libxinevdec/rgb.c
+++ b/src/libxinevdec/rgb.c
@@ -31,6 +31,10 @@
* indicated by a negative height parameter.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -145,7 +149,7 @@ static void rgb_decode_data (video_decoder_t *this_gen,
/* minimal buffer size */
this->bufsize = this->width * this->height * this->bytes_per_pixel;
- this->buf = xine_xmalloc(this->bufsize);
+ this->buf = calloc(1, this->bufsize);
this->size = 0;
init_yuv_planes(&this->yuv_planes, this->width, this->height);
@@ -398,7 +402,7 @@ static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stre
rgb_decoder_t *this ;
- this = (rgb_decoder_t *) xine_xmalloc (sizeof (rgb_decoder_t));
+ this = (rgb_decoder_t *) calloc(1, sizeof(rgb_decoder_t));
this->video_decoder.decode_data = rgb_decode_data;
this->video_decoder.flush = rgb_flush;
@@ -432,7 +436,7 @@ static void *init_plugin (xine_t *xine, void *data) {
rgb_class_t *this;
- this = (rgb_class_t *) xine_xmalloc (sizeof (rgb_class_t));
+ this = (rgb_class_t *) calloc(1, sizeof(rgb_class_t));
this->decoder_class.open_plugin = open_plugin;
this->decoder_class.get_identifier = get_identifier;
diff --git a/src/libxinevdec/xine_theora_decoder.c b/src/libxinevdec/xine_theora_decoder.c
index c71ce7559..d15625812 100644
--- a/src/libxinevdec/xine_theora_decoder.c
+++ b/src/libxinevdec/xine_theora_decoder.c
@@ -312,7 +312,7 @@ static video_decoder_t *theora_open_plugin (video_decoder_class_t *class_gen, xi
theora_decoder_t *this ;
- this = (theora_decoder_t *) xine_xmalloc (sizeof (theora_decoder_t));
+ this = (theora_decoder_t *) calloc(1, sizeof(theora_decoder_t));
this->theora_decoder.decode_data = theora_decode_data;
this->theora_decoder.flush = theora_flush;
@@ -370,7 +370,7 @@ static void *init_plugin (xine_t *xine, void *data) {
/*initialize our plugin*/
theora_class_t *this;
- this = (theora_class_t *) xine_xmalloc (sizeof (theora_class_t));
+ this = (theora_class_t *) calloc(1, sizeof(theora_class_t));
this->decoder_class.open_plugin = theora_open_plugin;
this->decoder_class.get_identifier = theora_get_identifier;
diff --git a/src/libxinevdec/yuv.c b/src/libxinevdec/yuv.c
index 2b8657685..b1a69cd65 100644
--- a/src/libxinevdec/yuv.c
+++ b/src/libxinevdec/yuv.c
@@ -22,6 +22,10 @@
* a way that xine can display them.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -321,7 +325,7 @@ static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stre
yuv_decoder_t *this ;
- this = (yuv_decoder_t *) xine_xmalloc (sizeof (yuv_decoder_t));
+ this = (yuv_decoder_t *) calloc(1, sizeof(yuv_decoder_t));
this->video_decoder.decode_data = yuv_decode_data;
this->video_decoder.flush = yuv_flush;
@@ -355,7 +359,7 @@ static void *init_plugin (xine_t *xine, void *data) {
yuv_class_t *this;
- this = (yuv_class_t *) xine_xmalloc (sizeof (yuv_class_t));
+ this = (yuv_class_t *) calloc(1, sizeof(yuv_class_t));
this->decoder_class.open_plugin = open_plugin;
this->decoder_class.get_identifier = get_identifier;
diff --git a/src/post/audio/Makefile.am b/src/post/audio/Makefile.am
index 41a364d0d..5e587ef2f 100644
--- a/src/post/audio/Makefile.am
+++ b/src/post/audio/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
noinst_HEADERS = dsp.h filter.h window.h audio_filters.h
diff --git a/src/post/audio/audio_filters.c b/src/post/audio/audio_filters.c
index 8200db51b..12d48784c 100644
--- a/src/post/audio/audio_filters.c
+++ b/src/post/audio/audio_filters.c
@@ -20,6 +20,9 @@
* catalog for audio filter plugins
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
#include "xine_internal.h"
#include "xineutils.h"
diff --git a/src/post/audio/filter.c b/src/post/audio/filter.c
index c5602736c..55d75e1e4 100644
--- a/src/post/audio/filter.c
+++ b/src/post/audio/filter.c
@@ -414,7 +414,7 @@ void bilinear(_ftype_t* a, _ftype_t* b, _ftype_t* k, _ftype_t fs, _ftype_t *coef
*
* return -1 if fail 0 if success.
*/
-int szxform(_ftype_t* a, _ftype_t* b, _ftype_t Q, _ftype_t fc, _ftype_t fs, _ftype_t *k, _ftype_t *coef)
+int szxform(const _ftype_t* a, const _ftype_t* b, _ftype_t Q, _ftype_t fc, _ftype_t fs, _ftype_t *k, _ftype_t *coef)
{
_ftype_t at[3];
_ftype_t bt[3];
diff --git a/src/post/audio/filter.h b/src/post/audio/filter.h
index 0b0ce1c1b..0e08aa2b9 100644
--- a/src/post/audio/filter.h
+++ b/src/post/audio/filter.h
@@ -55,7 +55,7 @@ extern int design_pfir(unsigned int n, unsigned int k, _ftype_t* w, _ftype_t** p
extern void prewarp(_ftype_t* a, _ftype_t fc, _ftype_t fs);
void bilinear(_ftype_t* a, _ftype_t* b, _ftype_t* k, _ftype_t fs, _ftype_t *coef);
-extern int szxform(_ftype_t* a, _ftype_t* b, _ftype_t Q, _ftype_t fc, _ftype_t fs, _ftype_t *k, _ftype_t *coef);
+extern int szxform(const _ftype_t* a, const _ftype_t* b, _ftype_t Q, _ftype_t fc, _ftype_t fs, _ftype_t *k, _ftype_t *coef);
/* Add new data to circular queue designed to be used with a FIR
* filter. xq is the circular queue, in pointing at the new sample, xi
diff --git a/src/post/audio/stretch.c b/src/post/audio/stretch.c
index 5aa7a0617..d4621a800 100644
--- a/src/post/audio/stretch.c
+++ b/src/post/audio/stretch.c
@@ -20,6 +20,10 @@
* Time stretch by a given factor, optionally preserving pitch
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include "xine_internal.h"
@@ -152,10 +156,10 @@ static void stretchscr_exit (scr_plugin_t *scr) {
free(this);
}
-static stretchscr_t* stretchscr_init (double *stretch_factor) {
+static stretchscr_t *XINE_MALLOC stretchscr_init (double *stretch_factor) {
stretchscr_t *this;
- this = (stretchscr_t *) xine_xmalloc(sizeof(stretchscr_t));
+ this = calloc(1, sizeof(stretchscr_t));
this->scr.interface_version = 3;
this->scr.get_priority = stretchscr_get_priority;
@@ -620,7 +624,7 @@ static post_plugin_t *stretch_open_plugin(post_class_t *class_gen, int inputs,
xine_audio_port_t **audio_target,
xine_video_port_t **video_target)
{
- post_plugin_stretch_t *this = (post_plugin_stretch_t *)xine_xmalloc(sizeof(post_plugin_stretch_t));
+ post_plugin_stretch_t *this = calloc(1, sizeof(post_plugin_stretch_t));
post_in_t *input;
post_out_t *output;
xine_post_in_t *input_api;
diff --git a/src/post/audio/upmix.c b/src/post/audio/upmix.c
index e1b2afbe3..e753f4a2a 100644
--- a/src/post/audio/upmix.c
+++ b/src/post/audio/upmix.c
@@ -24,6 +24,10 @@
* E.g. Converts Stereo into Surround 5.1
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include "xine_internal.h"
@@ -181,7 +185,7 @@ static int upmix_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream,
}
pthread_mutex_lock (&this->lock);
- this->sub = xine_xmalloc(sizeof(af_sub_t));
+ this->sub = calloc(1, sizeof(af_sub_t));
if (!this->sub) {
pthread_mutex_unlock (&this->lock);
return 0;
@@ -379,7 +383,7 @@ static post_plugin_t *upmix_open_plugin(post_class_t *class_gen, int inputs,
xine_audio_port_t **audio_target,
xine_video_port_t **video_target)
{
- post_plugin_upmix_t *this = (post_plugin_upmix_t *)xine_xmalloc(sizeof(post_plugin_upmix_t));
+ post_plugin_upmix_t *this = calloc(1, sizeof(post_plugin_upmix_t));
post_in_t *input;
post_out_t *output;
xine_post_in_t *input_api;
diff --git a/src/post/audio/upmix_mono.c b/src/post/audio/upmix_mono.c
index 195831123..52b5f497b 100644
--- a/src/post/audio/upmix_mono.c
+++ b/src/post/audio/upmix_mono.c
@@ -23,6 +23,10 @@
* It simply converts Mono into Stereo.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#define LOG_MODULE "upmix_mono"
@@ -192,32 +196,32 @@ static void upmix_mono_port_put_buffer(xine_audio_port_t *port_gen,
_x_extra_info_merge(buf1->extra_info, buf->extra_info);
{
- int step = buf->format.bits / 8;
+ const size_t step = buf->format.bits / 8;
uint8_t *src = (uint8_t *)buf->mem;
uint8_t *dst0 = (uint8_t *)buf0->mem;
uint8_t *dst1 = (uint8_t *)buf1->mem;
- int i, k;
+ int i;
for (i = 0; i < buf->num_frames / 2; i++)
{
- for (k = 0; k < step; k++)
- *dst0++ = *src++;
+ memcpy(dst0, src, step);
+ dst0 += step;
- src -= step;
+ memcpy(dst0, src, step);
+ dst0 += step;
- for (k = 0; k < step; k++)
- *dst0++ = *src++;
+ src += step;
}
for (i = buf->num_frames / 2; i < buf->num_frames; i++)
{
- for (k = 0; k < step; k++)
- *dst1++ = *src++;
+ memcpy(dst1, src, step);
+ dst1 += step;
- src -= step;
+ memcpy(dst1, src, step);
+ dst1 += step;
- for (k = 0; k < step; k++)
- *dst1++ = *src++;
+ src += step;
}
}
@@ -244,11 +248,11 @@ static void upmix_mono_port_put_buffer(xine_audio_port_t *port_gen,
_x_extra_info_merge(buf0->extra_info, buf->extra_info);
{
- int step = buf->format.bits / 8;
+ const size_t step = buf->format.bits / 8;
uint8_t *src = (uint8_t *)buf->mem;
uint8_t *dst0 = (uint8_t *)buf0->mem;
int cur_channel = this->params.channel;
- int i, j, k;
+ int i, j;
if( cur_channel >= this->channels )
cur_channel = this->channels-1;
@@ -259,8 +263,8 @@ static void upmix_mono_port_put_buffer(xine_audio_port_t *port_gen,
{
for (j = 0; j < this->channels; j++ )
{
- for (k = 0; k < step; k++)
- *dst0++ = *(src+k);
+ memcpy(dst0, src, step);
+ dst0 += step;
}
src += this->channels * step;
}
@@ -293,7 +297,7 @@ static post_plugin_t *upmix_mono_open_plugin(post_class_t *class_gen, int inputs
xine_audio_port_t **audio_target,
xine_video_port_t **video_target)
{
- post_plugin_upmix_mono_t *this = (post_plugin_upmix_mono_t *)xine_xmalloc(sizeof(post_plugin_upmix_mono_t));
+ post_plugin_upmix_mono_t *this = calloc(1, sizeof(post_plugin_upmix_mono_t));
post_in_t *input;
post_out_t *output;
xine_post_in_t *input_api;
diff --git a/src/post/audio/volnorm.c b/src/post/audio/volnorm.c
index 783c1e26d..158705ef7 100644
--- a/src/post/audio/volnorm.c
+++ b/src/post/audio/volnorm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2005 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -22,6 +22,10 @@
* & Pierre Lombard.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include <math.h>
@@ -407,12 +411,11 @@ static post_plugin_t *volnorm_open_plugin(post_class_t *class_gen, int inputs,
xine_audio_port_t **audio_target,
xine_video_port_t **video_target)
{
- post_plugin_volnorm_t *this = (post_plugin_volnorm_t *)xine_xmalloc(sizeof(post_plugin_volnorm_t));
+ post_plugin_volnorm_t *this = calloc(1, sizeof(post_plugin_volnorm_t));
post_in_t *input;
post_out_t *output;
xine_post_in_t *input_api;
post_audio_port_t *port;
- int i;
if (!this || !audio_target || !audio_target[0] ) {
free(this);
@@ -426,9 +429,8 @@ static post_plugin_t *volnorm_open_plugin(post_class_t *class_gen, int inputs,
this->mul = MUL_INIT;
this->lastavg = MID_S16;
this->idx = 0;
- for (i = 0; i < NSAMPLES; i++)
- this->mem[i].len = this->mem[i].avg = 0;
-
+ memset(this->mem, 0, sizeof(this->mem));
+
port = _x_post_intercept_audio_port(&this->post, audio_target[0], &input, &output);
port->new_port.open = volnorm_port_open;
port->new_port.close = volnorm_port_close;
diff --git a/src/post/deinterlace/Makefile.am b/src/post/deinterlace/Makefile.am
index d382a2e98..bac6bac33 100644
--- a/src/post/deinterlace/Makefile.am
+++ b/src/post/deinterlace/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
SUBDIRS = plugins
@@ -8,7 +9,7 @@ xinepost_LTLIBRARIES = xineplug_post_tvtime.la
xineplug_post_tvtime_la_SOURCES = xine_plugin.c \
deinterlace.c pulldown.c speedy.c tvtime.c
-xineplug_post_tvtime_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) \
+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)
diff --git a/src/post/deinterlace/plugins/Makefile.am b/src/post/deinterlace/plugins/Makefile.am
index 17d170127..5f0997eb8 100644
--- a/src/post/deinterlace/plugins/Makefile.am
+++ b/src/post/deinterlace/plugins/Makefile.am
@@ -30,7 +30,10 @@ EXTRA_DIST = greedy2frame_template.c greedyh.asm \
# libpostproc is here so we can use their nice mangle.h
AM_CFLAGS = -I$(top_srcdir)/src/post/deinterlace \
- -I$(top_srcdir)/src/libffmpeg/libavcodec/libpostproc
+ -I$(top_srcdir)/src/xine-utils
+
+# Avoid "can't find register" failures with -O0, -O2, -O3 (gcc 4.0)
+libdeinterlaceplugins_la-kdetv_greedyh.o libdeinterlaceplugins_la-kdetv_greedyh.lo: CFLAGS=$(shell echo @CFLAGS@ | sed -e 's/$$/ -O1/')
noinst_LTLIBRARIES = libdeinterlaceplugins.la
@@ -45,7 +48,6 @@ libdeinterlaceplugins_la_SOURCES = \
scalerbob.c \
kdetv_greedyh.c \
kdetv_tomsmocomp.c
-libdeinterlaceplugins_la_LIBADD = $(XINE_LIB)
libdeinterlaceplugins_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS)
libdeinterlaceplugins_la_LDFLAGS = -avoid-version -module
diff --git a/src/post/deinterlace/plugins/tomsmocomp/tomsmocompmacros.h b/src/post/deinterlace/plugins/tomsmocomp/tomsmocompmacros.h
index a3b92a51c..a0136fd44 100644
--- a/src/post/deinterlace/plugins/tomsmocomp/tomsmocompmacros.h
+++ b/src/post/deinterlace/plugins/tomsmocomp/tomsmocompmacros.h
@@ -2,6 +2,8 @@
#include <math.h>
#include <stdlib.h>
+#include "mangle.h"
+
#define USE_FOR_DSCALER
#define MyMemCopy xine_fast_memcpy
diff --git a/src/post/deinterlace/tvtime.c b/src/post/deinterlace/tvtime.c
index eff43d5e8..97da6543e 100644
--- a/src/post/deinterlace/tvtime.c
+++ b/src/post/deinterlace/tvtime.c
@@ -38,14 +38,6 @@
#include "tvtime.h"
/**
- * This is how many frames to wait until deciding if the pulldown phase
- * has changed or if we've really found a pulldown sequence. This is
- * currently set to about 1 second, that is, we won't go into film mode
- * until we've seen a pulldown sequence successfully for 1 second.
- */
-#define PULLDOWN_ERROR_WAIT 60
-
-/**
* This is how many predictions have to be incorrect before we fall back to
* video mode. Right now, if we mess up, we jump to video mode immediately.
*/
@@ -192,13 +184,13 @@ int tvtime_build_deinterlaced_frame( tvtime_t *tvtime, uint8_t *output,
if( !tvtime->pdoffset ) {
/* No pulldown offset applies, drop out of pulldown immediately. */
tvtime->pdlastbusted = 0;
- tvtime->pderror = PULLDOWN_ERROR_WAIT;
+ tvtime->pderror = tvtime->pulldown_error_wait;
} else if( tvtime->pdoffset != predicted ) {
if( tvtime->pdlastbusted ) {
tvtime->pdlastbusted--;
tvtime->pdoffset = predicted;
} else {
- tvtime->pderror = PULLDOWN_ERROR_WAIT;
+ tvtime->pderror = tvtime->pulldown_error_wait;
}
} else {
if( tvtime->pderror ) {
@@ -437,7 +429,7 @@ void tvtime_reset_context( tvtime_t *tvtime )
tvtime->last_botdiff = 0;
tvtime->pdoffset = PULLDOWN_SEQ_AA;
- tvtime->pderror = PULLDOWN_ERROR_WAIT;
+ tvtime->pderror = tvtime->pulldown_error_wait;
tvtime->pdlastbusted = 0;
tvtime->filmmode = 0;
}
diff --git a/src/post/deinterlace/tvtime.h b/src/post/deinterlace/tvtime.h
index 8e4c5abc2..2253f264e 100644
--- a/src/post/deinterlace/tvtime.h
+++ b/src/post/deinterlace/tvtime.h
@@ -56,6 +56,11 @@ typedef struct {
*/
deinterlace_method_t *curmethod;
+ /**
+ * This is how many frames to wait until deciding if the pulldown phase
+ * has changed or if we've really found a pulldown sequence.
+ */
+ unsigned int pulldown_error_wait;
/* internal data */
int last_topdiff;
diff --git a/src/post/deinterlace/xine_plugin.c b/src/post/deinterlace/xine_plugin.c
index 477e6812b..7149f2bdb 100644
--- a/src/post/deinterlace/xine_plugin.c
+++ b/src/post/deinterlace/xine_plugin.c
@@ -23,6 +23,10 @@
* heavily based on tvtime.sf.net by Billy Biggs
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
/*
#define LOG
*/
@@ -69,6 +73,7 @@ typedef struct deinterlace_parameters_s {
int method;
int enabled;
int pulldown;
+ int pulldown_error_wait;
int framerate_mode;
int judder_correction;
int use_progressive_frame_flag;
@@ -87,6 +92,8 @@ PARAM_ITEM( POST_PARAM_TYPE_BOOL, enabled, NULL, 0, 1, 0,
"enable/disable" )
PARAM_ITEM( POST_PARAM_TYPE_INT, pulldown, enum_pulldown, 0, 0, 0,
"pulldown algorithm" )
+PARAM_ITEM( POST_PARAM_TYPE_INT, pulldown_error_wait, NULL, 0, 0, 0,
+ "number of frames of telecine pattern sync required before mode change" )
PARAM_ITEM( POST_PARAM_TYPE_INT, framerate_mode, enum_framerate, 0, 0, 0,
"framerate output mode" )
PARAM_ITEM( POST_PARAM_TYPE_BOOL, judder_correction, NULL, 0, 1, 0,
@@ -165,6 +172,7 @@ static int set_parameters (xine_post_t *this_gen, void *param_gen) {
this->enabled = param->enabled;
this->pulldown = param->pulldown;
+ this->tvtime->pulldown_error_wait = param->pulldown_error_wait;
this->framerate_mode = param->framerate_mode;
this->judder_correction = param->judder_correction;
this->use_progressive_frame_flag = param->use_progressive_frame_flag;
@@ -185,6 +193,7 @@ static int get_parameters (xine_post_t *this_gen, void *param_gen) {
param->method = this->cur_method;
param->enabled = this->enabled;
param->pulldown = this->pulldown;
+ param->pulldown_error_wait = this->tvtime->pulldown_error_wait;
param->framerate_mode = this->framerate_mode;
param->judder_correction = this->judder_correction;
param->use_progressive_frame_flag = this->use_progressive_frame_flag;
@@ -212,6 +221,9 @@ static char * get_static_help (void) {
"\n"
" Enabled: Enable/disable the plugin.\n"
"\n"
+ " Pulldown_error_wait: Ensures that the telecine pattern has been "
+ "locked for this many frames before changing to filmmode.\n"
+ "\n"
" Pulldown: Choose the 2-3 pulldown detection algorithm. 24 FPS films "
"that have being converted to NTSC can be detected and intelligently "
"reconstructed to their original (non-interlaced) frames.\n"
@@ -291,7 +303,7 @@ static int deinterlace_draw(vo_frame_t *frame, xine_stream_t *stream)
static void *deinterlace_init_plugin(xine_t *xine, void *data)
{
- post_class_deinterlace_t *class = (post_class_deinterlace_t *)xine_xmalloc(sizeof(post_class_deinterlace_t));
+ post_class_deinterlace_t *class = calloc(1, sizeof(post_class_deinterlace_t));
uint32_t config_flags = xine_mm_accel();
int i;
@@ -350,6 +362,7 @@ static void *deinterlace_init_plugin(xine_t *xine, void *data)
class->init_param.method = 1; /* First (plugin) method available */
class->init_param.enabled = 1;
class->init_param.pulldown = 1; /* vektor */
+ class->init_param.pulldown_error_wait = 60; /* about one second */
class->init_param.framerate_mode = 0; /* full */
class->init_param.judder_correction = 1;
class->init_param.use_progressive_frame_flag = 1;
@@ -364,7 +377,7 @@ static post_plugin_t *deinterlace_open_plugin(post_class_t *class_gen, int input
xine_audio_port_t **audio_target,
xine_video_port_t **video_target)
{
- post_plugin_deinterlace_t *this = (post_plugin_deinterlace_t *)xine_xmalloc(sizeof(post_plugin_deinterlace_t));
+ post_plugin_deinterlace_t *this = calloc(1, sizeof(post_plugin_deinterlace_t));
post_in_t *input;
xine_post_in_t *input_api;
post_out_t *output;
diff --git a/src/post/goom/Makefile.am b/src/post/goom/Makefile.am
index c01482917..cd022c9b0 100644
--- a/src/post/goom/Makefile.am
+++ b/src/post/goom/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
EXTRA_DIST = mmx.c xmmx.c ppc_drawings.s ppc_zoom_ultimate.s diff_against_release.patch \
diff --git a/src/post/goom/convolve_fx.c b/src/post/goom/convolve_fx.c
index e86bb3723..ee36dfd0b 100644
--- a/src/post/goom/convolve_fx.c
+++ b/src/post/goom/convolve_fx.c
@@ -20,7 +20,7 @@ typedef char Motif[CONV_MOTIF_W][CONV_MOTIF_W];
#define NB_THETA 512
-#define MAX 2.0f
+//#define MAX 2.0f
typedef struct _CONV_DATA{
PluginParam light;
@@ -73,7 +73,7 @@ static void set_motif(ConvData *data, Motif motif)
static void convolve_init(VisualFX *_this, PluginInfo *info) {
ConvData *data;
- data = (ConvData*)malloc(sizeof(ConvData));
+ data = (ConvData*)calloc(1, sizeof(ConvData));
_this->fx_data = (void*)data;
data->light = secure_f_param("Screen Brightness");
diff --git a/src/post/goom/diff_against_release.patch b/src/post/goom/diff_against_release.patch
index bde85c285..a5e84b8d1 100644
--- a/src/post/goom/diff_against_release.patch
+++ b/src/post/goom/diff_against_release.patch
@@ -653,3 +653,40 @@ diff -u -p -r1.2 -r1.3
#endif
+diff -r 96c7f8460d61 src/post/goom/convolve_fx.c
+--- convolve_fx.c Mon Nov 10 16:33:51 2008 +0100
++++ convolve_fx.c Sun Nov 16 21:14:29 2008 +0100
+@@ -73,7 +73,7 @@ static void set_motif(ConvData *data, Mo
+
+ static void convolve_init(VisualFX *_this, PluginInfo *info) {
+ ConvData *data;
+- data = (ConvData*)malloc(sizeof(ConvData));
++ data = (ConvData*)calloc(1, sizeof(ConvData));
+ _this->fx_data = (void*)data;
+
+ data->light = secure_f_param("Screen Brightness");
+diff -r 96c7f8460d61 src/post/goom/goom_core.c
+--- goom_core.c Mon Nov 10 16:33:51 2008 +0100
++++ goom_core.c Sun Nov 16 21:14:29 2008 +0100
+@@ -76,6 +76,10 @@ PluginInfo *goom_init (guint32 resx, gui
+ goomInfo->tentacles_fx = tentacle_fx_create();
+ goomInfo->tentacles_fx.init(&goomInfo->tentacles_fx, goomInfo);
+
++ goomInfo->screen.width = resx;
++ goomInfo->screen.height = resy;
++ goomInfo->screen.size = resx * resy;
++
+ goomInfo->convolve_fx = convolve_create();
+ goomInfo->convolve_fx.init(&goomInfo->convolve_fx, goomInfo);
+
+@@ -83,10 +87,6 @@ PluginInfo *goom_init (guint32 resx, gui
+ plugin_info_add_visual (goomInfo, 1, &goomInfo->tentacles_fx);
+ plugin_info_add_visual (goomInfo, 2, &goomInfo->star_fx);
+ plugin_info_add_visual (goomInfo, 3, &goomInfo->convolve_fx);
+-
+- goomInfo->screen.width = resx;
+- goomInfo->screen.height = resy;
+- goomInfo->screen.size = resx * resy;
+
+ init_buffers(goomInfo, goomInfo->screen.size);
+ goomInfo->gRandom = goom_random_init((uintptr_t)goomInfo->pixel);
diff --git a/src/post/goom/goom_core.c b/src/post/goom/goom_core.c
index b24f2f496..62d9a27b6 100644
--- a/src/post/goom/goom_core.c
+++ b/src/post/goom/goom_core.c
@@ -76,6 +76,10 @@ PluginInfo *goom_init (guint32 resx, guint32 resy)
goomInfo->tentacles_fx = tentacle_fx_create();
goomInfo->tentacles_fx.init(&goomInfo->tentacles_fx, goomInfo);
+ goomInfo->screen.width = resx;
+ goomInfo->screen.height = resy;
+ goomInfo->screen.size = resx * resy;
+
goomInfo->convolve_fx = convolve_create();
goomInfo->convolve_fx.init(&goomInfo->convolve_fx, goomInfo);
@@ -84,10 +88,6 @@ PluginInfo *goom_init (guint32 resx, guint32 resy)
plugin_info_add_visual (goomInfo, 2, &goomInfo->star_fx);
plugin_info_add_visual (goomInfo, 3, &goomInfo->convolve_fx);
- goomInfo->screen.width = resx;
- goomInfo->screen.height = resy;
- goomInfo->screen.size = resx * resy;
-
init_buffers(goomInfo, goomInfo->screen.size);
goomInfo->gRandom = goom_random_init((uintptr_t)goomInfo->pixel);
@@ -841,7 +841,7 @@ void update_message (PluginInfo *goomInfo, char *message) {
if (message) {
int i=1,j=0;
- sprintf (goomInfo->update_message.message, "%s", message);
+ strcpy(goomInfo->update_message.message, message);
for (j=0;goomInfo->update_message.message[j];j++)
if (goomInfo->update_message.message[j]=='\n')
i++;
@@ -855,8 +855,8 @@ void update_message (PluginInfo *goomInfo, char *message) {
char *ptr = msg;
int pos;
float ecart;
+ strncpy(msg, goomInfo->update_message.message, goomInfo->update_message.longueur);
message = msg;
- sprintf (msg, "%s", goomInfo->update_message.message);
while (!fin) {
while (1) {
diff --git a/src/post/goom/ppc_zoom_ultimate.h b/src/post/goom/ppc_zoom_ultimate.h
index d6932e7e6..d070071c9 100644
--- a/src/post/goom/ppc_zoom_ultimate.h
+++ b/src/post/goom/ppc_zoom_ultimate.h
@@ -11,4 +11,4 @@
void ppc_zoom_generic (int sizeX, int sizeY, Pixel *src, Pixel *dest, int *brutS, int *brutD, int buffratio, int precalCoef[16][16]);
/* G4 Specific PowerPC Code (Possible use of Altivec and Data Streams) */
-void ppc_zoom_G4 (int sizeX, int sizeY, Pixel *src, Pixel *dest, int *brutS, int *brutD, int buffratio, int precalCoef[16][16]); \ No newline at end of file
+void ppc_zoom_G4 (int sizeX, int sizeY, Pixel *src, Pixel *dest, int *brutS, int *brutD, int buffratio, int precalCoef[16][16]);
diff --git a/src/post/goom/xine_goom.c b/src/post/goom/xine_goom.c
index 8cd06dbd6..db7079423 100644
--- a/src/post/goom/xine_goom.c
+++ b/src/post/goom/xine_goom.c
@@ -48,7 +48,7 @@
#define GOOM_HEIGHT 240
/* colorspace conversion methods */
-static const char const * goom_csc_methods[]={
+static const char* goom_csc_methods[]={
"Fast but not photorealistic",
"Slow but looks better",
NULL
@@ -187,7 +187,7 @@ static void csc_method_changed_cb(void *data, xine_cfg_entry_t *cfg) {
static void *goom_init_plugin(xine_t *xine, void *data)
{
- post_class_goom_t *this = (post_class_goom_t *)xine_xmalloc(sizeof(post_class_goom_t));
+ post_class_goom_t *this = calloc(1, sizeof(post_class_goom_t));
config_values_t *cfg;
if (!this)
@@ -234,7 +234,7 @@ static post_plugin_t *goom_open_plugin(post_class_t *class_gen, int inputs,
xine_audio_port_t **audio_target,
xine_video_port_t **video_target)
{
- post_plugin_goom_t *this = (post_plugin_goom_t *)xine_xmalloc(sizeof(post_plugin_goom_t));
+ post_plugin_goom_t *this = calloc(1, sizeof(post_plugin_goom_t));
post_class_goom_t *class = (post_class_goom_t*) class_gen;
post_in_t *input;
post_out_t *output;
diff --git a/src/post/mosaico/Makefile.am b/src/post/mosaico/Makefile.am
index af027b6e6..56426c711 100644
--- a/src/post/mosaico/Makefile.am
+++ b/src/post/mosaico/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
xinepost_LTLIBRARIES = xineplug_post_mosaico.la xineplug_post_switch.la
diff --git a/src/post/mosaico/mosaico.c b/src/post/mosaico/mosaico.c
index 50b1cfcdf..c9ac9ab4c 100644
--- a/src/post/mosaico/mosaico.c
+++ b/src/post/mosaico/mosaico.c
@@ -22,6 +22,10 @@
* simple video mosaico plugin
*/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#define LOG_MODULE "mosaico"
#define LOG_VERBOSE
/*
@@ -122,7 +126,7 @@ static int mosaico_draw(vo_frame_t *frame, xine_stream_t *stream);
static void *mosaico_init_plugin(xine_t *xine, void *data)
{
- post_class_mosaico_t *this = (post_class_mosaico_t *)xine_xmalloc(sizeof(post_class_mosaico_t));
+ post_class_mosaico_t *this = calloc(1, sizeof(post_class_mosaico_t));
if (!this)
return NULL;
@@ -140,7 +144,7 @@ static post_plugin_t *mosaico_open_plugin(post_class_t *class_gen, int inputs,
xine_audio_port_t **audio_target,
xine_video_port_t **video_target)
{
- post_mosaico_t *this = (post_mosaico_t *)xine_xmalloc(sizeof(post_mosaico_t));
+ post_mosaico_t *this = calloc(1, sizeof(post_mosaico_t));
post_in_t *input;
xine_post_in_t *input_api;
post_out_t *output;
@@ -158,7 +162,7 @@ static post_plugin_t *mosaico_open_plugin(post_class_t *class_gen, int inputs,
_x_post_init(&this->post, 0, inputs);
- this->pip = (mosaico_pip_t *)xine_xmalloc(sizeof(mosaico_pip_t) * (inputs - 1));
+ this->pip = (mosaico_pip_t *)calloc((inputs - 1), sizeof(mosaico_pip_t));
this->pip_count = inputs - 1;
pthread_cond_init(&this->vpts_limit_changed, NULL);
@@ -178,8 +182,7 @@ static post_plugin_t *mosaico_open_plugin(post_class_t *class_gen, int inputs,
this->pip[i].y = 50;
this->pip[i].w = 150;
this->pip[i].h = 150;
- this->pip[i].input_name = (char *)xine_xmalloc(sizeof("video in ") + 10);
- snprintf(this->pip[i].input_name, sizeof("video in ") + 10, "video in %d", i+1);
+ asprintf(&(this->pip[i].input_name), "video in %d", i+1);
port = _x_post_intercept_video_port(&this->post, video_target[0], &input, NULL);
port->new_port.close = mosaico_close;
diff --git a/src/post/mosaico/switch.c b/src/post/mosaico/switch.c
index 8fec5ee77..a01c821b2 100644
--- a/src/post/mosaico/switch.c
+++ b/src/post/mosaico/switch.c
@@ -101,7 +101,7 @@ static int switch_draw(vo_frame_t *frame, xine_stream_t *stream);
static void *switch_init_plugin(xine_t *xine, void *data)
{
- post_class_switch_t *this = (post_class_switch_t *)xine_xmalloc(sizeof(post_class_switch_t));
+ post_class_switch_t *this = calloc(1, sizeof(post_class_switch_t));
if (!this)
return NULL;
@@ -119,7 +119,7 @@ static post_plugin_t *switch_open_plugin(post_class_t *class_gen, int inputs,
xine_audio_port_t **audio_target,
xine_video_port_t **video_target)
{
- post_switch_t *this = (post_switch_t *)xine_xmalloc(sizeof(post_switch_t));
+ post_switch_t *this = calloc(1, sizeof(post_switch_t));
post_in_t *input;
xine_post_in_t *input_api;
post_out_t *output;
diff --git a/src/post/planar/Makefile.am b/src/post/planar/Makefile.am
index 4ba6bfa41..751ea390a 100644
--- a/src/post/planar/Makefile.am
+++ b/src/post/planar/Makefile.am
@@ -1,12 +1,13 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
POSTPROC_INT_LIB = $(top_builddir)/src/libffmpeg/libavcodec/libpostproc/libpostprocess.la
if HAVE_FFMPEG
postproc_lib = $(FFMPEG_POSTPROC_LIBS)
-ff_cflags = $(FFMPEG_POSTPROC_CFLAGS)
+ff_cflags = $(FFMPEG_CFLAGS) $(FFMPEG_POSTPROC_CFLAGS)
else
-ff_cflags = -I$(top_srcdir)/src/libffmpeg/libavcodec/libpostproc
+ff_cflags = -I$(top_srcdir)/src/libffmpeg/libavcodec
postproc_lib = $(POSTPROC_INT_LIB)
postproc_dep = $(postproc_lib)
endif
diff --git a/src/post/planar/boxblur.c b/src/post/planar/boxblur.c
index b7a6f524f..517cec489 100644
--- a/src/post/planar/boxblur.c
+++ b/src/post/planar/boxblur.c
@@ -21,6 +21,10 @@
* Copyright (C) 2002 Michael Niedermayer <michaelni@gmx.at>
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "xine_internal.h"
#include "post.h"
#include "xineutils.h"
@@ -154,7 +158,7 @@ static post_plugin_t *boxblur_open_plugin(post_class_t *class_gen, int inputs,
xine_audio_port_t **audio_target,
xine_video_port_t **video_target)
{
- post_plugin_boxblur_t *this = (post_plugin_boxblur_t *)xine_xmalloc(sizeof(post_plugin_boxblur_t));
+ post_plugin_boxblur_t *this = calloc(1, sizeof(post_plugin_boxblur_t));
post_in_t *input;
xine_post_in_t *input_api;
post_out_t *output;
diff --git a/src/post/planar/denoise3d.c b/src/post/planar/denoise3d.c
index fb3c1102b..21b58dbf9 100644
--- a/src/post/planar/denoise3d.c
+++ b/src/post/planar/denoise3d.c
@@ -21,6 +21,10 @@
* Copyright (C) 2003 Daniel Moreno <comac@comac.darktech.org>
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "xine_internal.h"
#include "post.h"
#include "xineutils.h"
@@ -194,7 +198,7 @@ static post_plugin_t *denoise3d_open_plugin(post_class_t *class_gen, int inputs,
xine_audio_port_t **audio_target,
xine_video_port_t **video_target)
{
- post_plugin_denoise3d_t *this = (post_plugin_denoise3d_t *)xine_xmalloc(sizeof(post_plugin_denoise3d_t));
+ post_plugin_denoise3d_t *this = calloc(1, sizeof(post_plugin_denoise3d_t));
post_in_t *input;
xine_post_in_t *input_api;
post_out_t *output;
diff --git a/src/post/planar/eq.c b/src/post/planar/eq.c
index b2cf6e50f..45bc43463 100644
--- a/src/post/planar/eq.c
+++ b/src/post/planar/eq.c
@@ -21,6 +21,10 @@
* Copyright (C) Richard Felker
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "xine_internal.h"
#include "post.h"
#include "xineutils.h"
@@ -246,7 +250,7 @@ static post_plugin_t *eq_open_plugin(post_class_t *class_gen, int inputs,
xine_audio_port_t **audio_target,
xine_video_port_t **video_target)
{
- post_plugin_eq_t *this = (post_plugin_eq_t *)xine_xmalloc(sizeof(post_plugin_eq_t));
+ post_plugin_eq_t *this = calloc(1, sizeof(post_plugin_eq_t));
post_in_t *input;
xine_post_in_t *input_api;
post_out_t *output;
diff --git a/src/post/planar/eq2.c b/src/post/planar/eq2.c
index 6b277c347..1a301fdab 100644
--- a/src/post/planar/eq2.c
+++ b/src/post/planar/eq2.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2006 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -25,6 +25,10 @@
* Richard Felker (original MMX contrast/brightness code (vf_eq.c))
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "xine_internal.h"
#include "post.h"
#include "xineutils.h"
@@ -427,13 +431,11 @@ static post_plugin_t *eq2_open_plugin(post_class_t *class_gen, int inputs,
xine_audio_port_t **audio_target,
xine_video_port_t **video_target)
{
- post_plugin_eq2_t *this = (post_plugin_eq2_t *)xine_xmalloc(sizeof(post_plugin_eq2_t));
+ post_plugin_eq2_t *this = calloc(1, sizeof(post_plugin_eq2_t));
post_in_t *input;
xine_post_in_t *input_api;
post_out_t *output;
post_video_port_t *port;
- vf_eq2_t *eq2;
- int i;
if (!this || !video_target || !video_target[0]) {
free(this);
@@ -442,26 +444,15 @@ static post_plugin_t *eq2_open_plugin(post_class_t *class_gen, int inputs,
_x_post_init(&this->post, 0, 1);
- eq2 = &this->eq2;
- for (i = 0; i < 3; i++) {
- eq2->buf[i] = NULL;
- eq2->buf_w[i] = 0;
- eq2->buf_h[i] = 0;
-
- eq2->param[i].adjust = NULL;
- eq2->param[i].c = 1.0;
- eq2->param[i].b = 0.0;
- eq2->param[i].g = 1.0;
- eq2->param[i].lut_clean = 0;
- }
+ memset(&this->eq2, 0, sizeof(this->eq2));
- eq2->gamma = this->params.gamma = 1.0;
- eq2->contrast = this->params.contrast = 1.0;
- eq2->brightness = this->params.brightness = 0.0;
- eq2->saturation = this->params.saturation = 1.0;
- eq2->rgamma = this->params.rgamma = 1.0;
- eq2->ggamma = this->params.ggamma = 1.0;
- eq2->bgamma = this->params.bgamma = 1.0;
+ this->eq2.gamma = this->params.gamma = 1.0;
+ this->eq2.contrast = this->params.contrast = 1.0;
+ this->eq2.brightness = this->params.brightness = 0.0;
+ this->eq2.saturation = this->params.saturation = 1.0;
+ this->eq2.rgamma = this->params.rgamma = 1.0;
+ this->eq2.ggamma = this->params.ggamma = 1.0;
+ this->eq2.bgamma = this->params.bgamma = 1.0;
pthread_mutex_init(&this->lock, NULL);
diff --git a/src/post/planar/expand.c b/src/post/planar/expand.c
index 67d449153..52bc2b37a 100644
--- a/src/post/planar/expand.c
+++ b/src/post/planar/expand.c
@@ -148,7 +148,7 @@ static post_plugin_t *expand_open_plugin(post_class_t *class_gen, int inputs,
xine_audio_port_t **audio_target,
xine_video_port_t **video_target)
{
- post_expand_t *this = (post_expand_t *)xine_xmalloc(sizeof(post_expand_t));
+ post_expand_t *this = calloc(1, sizeof(post_expand_t));
post_in_t *input;
xine_post_in_t *input_param;
post_out_t *output;
diff --git a/src/post/planar/fill.c b/src/post/planar/fill.c
index 32a9d5dfb..98c572777 100644
--- a/src/post/planar/fill.c
+++ b/src/post/planar/fill.c
@@ -66,7 +66,7 @@ static post_plugin_t *fill_open_plugin(post_class_t *class_gen, int inputs,
xine_audio_port_t **audio_target,
xine_video_port_t **video_target)
{
- post_plugin_t *this = (post_plugin_t *)xine_xmalloc(sizeof(post_plugin_t));
+ post_plugin_t *this = calloc(1, sizeof(post_plugin_t));
post_in_t *input;
post_out_t *output;
post_video_port_t *port;
diff --git a/src/post/planar/invert.c b/src/post/planar/invert.c
index 1aa5c2a2e..d1f0c8d4e 100644
--- a/src/post/planar/invert.c
+++ b/src/post/planar/invert.c
@@ -67,7 +67,7 @@ static post_plugin_t *invert_open_plugin(post_class_t *class_gen, int inputs,
xine_audio_port_t **audio_target,
xine_video_port_t **video_target)
{
- post_plugin_t *this = (post_plugin_t *)xine_xmalloc(sizeof(post_plugin_t));
+ post_plugin_t *this = calloc(1, sizeof(post_plugin_t));
post_in_t *input;
post_out_t *output;
post_video_port_t *port;
diff --git a/src/post/planar/noise.c b/src/post/planar/noise.c
index 8c04f2e72..f639fce76 100644
--- a/src/post/planar/noise.c
+++ b/src/post/planar/noise.c
@@ -21,6 +21,10 @@
* is copyright 2002 Michael Niedermayer <michaelni@gmx.at>
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "xine_internal.h"
#include "post.h"
#include "xineutils.h"
@@ -471,7 +475,7 @@ static post_plugin_t *noise_open_plugin(post_class_t *class_gen, int inputs,
xine_audio_port_t **audio_target,
xine_video_port_t **video_target)
{
- post_plugin_noise_t *this = (post_plugin_noise_t *)xine_xmalloc(sizeof(post_plugin_noise_t));
+ post_plugin_noise_t *this = calloc(1, sizeof(post_plugin_noise_t));
post_in_t *input;
xine_post_in_t *input_api;
post_out_t *output;
diff --git a/src/post/planar/planar.c b/src/post/planar/planar.c
index 5907d58e5..e1c9681ab 100644
--- a/src/post/planar/planar.c
+++ b/src/post/planar/planar.c
@@ -20,6 +20,10 @@
* catalog for planar post plugins
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "xine_internal.h"
#include "post.h"
#include "xineutils.h"
diff --git a/src/post/planar/pp.c b/src/post/planar/pp.c
index e13119311..1ce45e381 100644
--- a/src/post/planar/pp.c
+++ b/src/post/planar/pp.c
@@ -20,12 +20,21 @@
* plugin for ffmpeg libpostprocess
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "xine_internal.h"
#include "post.h"
#include "xineutils.h"
-#include "postprocess.h"
#include <pthread.h>
+#ifdef HAVE_FFMPEG_AVUTIL_H
+# include <postprocess.h>
+#else
+# include <libpostproc/postprocess.h>
+#endif
+
#define PP_STRING_SIZE 256 /* size of pp mode string (including all options) */
/* plugin class initialization function */
@@ -114,12 +123,9 @@ static char * get_help (void) {
);
static char *help = NULL;
- if( !help ) {
- help = malloc( strlen(help1) + strlen(help2) + strlen(pp_help) + 1);
- strcpy(help, help1);
- strcat(help, pp_help);
- strcat(help, help2);
- }
+ if( !help )
+ asprintf(&help, "%s%s%s", help1, help2, pp_help);
+
return help;
}
@@ -169,7 +175,7 @@ static post_plugin_t *pp_open_plugin(post_class_t *class_gen, int inputs,
xine_audio_port_t **audio_target,
xine_video_port_t **video_target)
{
- post_plugin_pp_t *this = (post_plugin_pp_t *)xine_xmalloc(sizeof(post_plugin_pp_t));
+ post_plugin_pp_t *this = calloc(1, sizeof(post_plugin_pp_t));
post_in_t *input;
xine_post_in_t *input_api;
post_out_t *output;
diff --git a/src/post/planar/unsharp.c b/src/post/planar/unsharp.c
index b9b791a8e..6fac727ce 100644
--- a/src/post/planar/unsharp.c
+++ b/src/post/planar/unsharp.c
@@ -21,18 +21,15 @@
* Copyright (C) 2002 Rémi Guyomarch <rguyom@pobox.com>
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "xine_internal.h"
#include "post.h"
#include "xineutils.h"
#include <pthread.h>
-#ifndef MIN
-#define MIN(a,b) (((a)<(b))?(a):(b))
-#endif
-#ifndef MAX
-#define MAX(a,b) (((a)>(b))?(a):(b))
-#endif
-
/*===========================================================================*/
#define MIN_MATRIX_SIZE 3
@@ -287,7 +284,7 @@ static post_plugin_t *unsharp_open_plugin(post_class_t *class_gen, int inputs,
xine_audio_port_t **audio_target,
xine_video_port_t **video_target)
{
- post_plugin_unsharp_t *this = (post_plugin_unsharp_t *)xine_xmalloc(sizeof(post_plugin_unsharp_t));
+ post_plugin_unsharp_t *this = calloc(1, sizeof(post_plugin_unsharp_t));
post_in_t *input;
xine_post_in_t *input_api;
post_out_t *output;
diff --git a/src/post/visualizations/Makefile.am b/src/post/visualizations/Makefile.am
index f42598d9c..a766bc10a 100644
--- a/src/post/visualizations/Makefile.am
+++ b/src/post/visualizations/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
EXTRA_DIST = fooviz.c
diff --git a/src/post/visualizations/fftgraph.c b/src/post/visualizations/fftgraph.c
index 5068bd37a..8bd30ed5c 100644
--- a/src/post/visualizations/fftgraph.c
+++ b/src/post/visualizations/fftgraph.c
@@ -21,6 +21,10 @@
* by Thibaut Mattern (tmattern@noos.fr)
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include <math.h>
@@ -415,7 +419,7 @@ static post_plugin_t *fftgraph_open_plugin(post_class_t *class_gen, int inputs,
xine_video_port_t **video_target)
{
post_class_fftgraph_t *class = (post_class_fftgraph_t *)class_gen;
- post_plugin_fftgraph_t *this = (post_plugin_fftgraph_t *)xine_xmalloc(sizeof(post_plugin_fftgraph_t));
+ post_plugin_fftgraph_t *this = calloc(1, sizeof(post_plugin_fftgraph_t));
post_in_t *input;
post_out_t *output;
post_out_t *outputv;
diff --git a/src/post/visualizations/fftscope.c b/src/post/visualizations/fftscope.c
index ba34437f5..ccff59634 100644
--- a/src/post/visualizations/fftscope.c
+++ b/src/post/visualizations/fftscope.c
@@ -23,6 +23,10 @@
* FFT code by Steve Haehnichen, originally licensed under GPL v1
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include <math.h>
@@ -435,7 +439,7 @@ static post_plugin_t *fftscope_open_plugin(post_class_t *class_gen, int inputs,
xine_audio_port_t **audio_target,
xine_video_port_t **video_target)
{
- post_plugin_fftscope_t *this = (post_plugin_fftscope_t *)xine_xmalloc(sizeof(post_plugin_fftscope_t));
+ post_plugin_fftscope_t *this = calloc(1, sizeof(post_plugin_fftscope_t));
post_class_fftscope_t *class = (post_class_fftscope_t *)class_gen;
post_in_t *input;
post_out_t *output;
diff --git a/src/post/visualizations/fooviz.c b/src/post/visualizations/fooviz.c
index 21854afc6..c645601fc 100644
--- a/src/post/visualizations/fooviz.c
+++ b/src/post/visualizations/fooviz.c
@@ -24,6 +24,10 @@
* colors on each iteration.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include "xine_internal.h"
@@ -247,7 +251,7 @@ static post_plugin_t *fooviz_open_plugin(post_class_t *class_gen, int inputs,
xine_video_port_t **video_target)
{
post_class_fooviz_t *class = (post_class_fooviz_t *)class_gen;
- post_plugin_fooviz_t *this = (post_plugin_fooviz_t *)xine_xmalloc(sizeof(post_plugin_fooviz_t));
+ post_plugin_fooviz_t *this = calloc(1, sizeof(post_plugin_fooviz_t));
post_in_t *input;
post_out_t *output;
post_out_t *outputv;
diff --git a/src/post/visualizations/oscope.c b/src/post/visualizations/oscope.c
index a435604d4..a2c9c6961 100644
--- a/src/post/visualizations/oscope.c
+++ b/src/post/visualizations/oscope.c
@@ -21,6 +21,10 @@
* by Mike Melanson (melanson@pcisys.net)
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include "xine_internal.h"
@@ -318,7 +322,7 @@ static post_plugin_t *oscope_open_plugin(post_class_t *class_gen, int inputs,
xine_video_port_t **video_target)
{
post_class_oscope_t *class = (post_class_oscope_t *)class_gen;
- post_plugin_oscope_t *this = (post_plugin_oscope_t *)xine_xmalloc(sizeof(post_plugin_oscope_t));
+ post_plugin_oscope_t *this = calloc(1, sizeof(post_plugin_oscope_t));
post_in_t *input;
post_out_t *output;
post_out_t *outputv;
diff --git a/src/video_out/Makefile.am b/src/video_out/Makefile.am
index d447417c5..3e182fc14 100644
--- a/src/video_out/Makefile.am
+++ b/src/video_out/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
AM_CPPFLAGS = -DXINE_COMPILE
@@ -100,6 +101,7 @@ xineplug_LTLIBRARIES = $(xshm_module) $(xv_module) $(xvmc_module) \
$(xxmc_module) \
$(xcbshm_module) \
$(xcbxv_module) \
+ xineplug_vo_out_raw.la \
xineplug_vo_out_none.la
xineplug_vo_out_xcbshm_la_SOURCES = yuv2rgb.c yuv2rgb_mmx.c yuv2rgb_mlib.c video_out_xcbshm.c $(XCBOSD)
@@ -130,11 +132,11 @@ xineplug_vo_out_xxmc_la_CFLAGS = $(VISIBILITY_FLAG) $(X_CFLAGS) $(XV_CFLAGS) -fn
xineplug_vo_out_opengl_la_SOURCES = yuv2rgb.c yuv2rgb_mmx.c yuv2rgb_mlib.c \
video_out_opengl.c myglext.h $(X11OSD)
-xineplug_vo_out_opengl_la_LIBADD = $(MLIB_LIBS) $(OPENGL_LIBS) $(GLUT_LIBS) \
- $(GLU_LIBS) $(X_LIBS) $(XINE_LIB) $(PTHREAD_LIBS) $(DYNAMIC_LD_LIBS) $(LTLIBINTL)
+xineplug_vo_out_opengl_la_LIBADD = $(XINE_LIB) $(MLIB_LIBS) $(OPENGL_LIBS) \
+ $(GLUT_LIBS) $(GLU_LIBS) $(X_LIBS) $(PTHREAD_LIBS) $(DYNAMIC_LD_LIBS) $(LTLIBINTL)
xineplug_vo_out_opengl_la_CFLAGS = $(VISIBILITY_FLAG) $(X_CFLAGS) $(MLIB_CFLAGS) -fno-strict-aliasing
-xineplug_vo_out_syncfb_la_SOURCES = video_out_syncfb.c
+xineplug_vo_out_syncfb_la_SOURCES = video_out_syncfb.c
xineplug_vo_out_syncfb_la_LIBADD = $(XINE_LIB) $(X_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL)
xineplug_vo_out_syncfb_la_CFLAGS = $(VISIBILITY_FLAG) $(X_CFLAGS)
@@ -177,28 +179,32 @@ xineplug_vo_out_sdl_la_SOURCES = video_out_sdl.c
xineplug_vo_out_sdl_la_LIBADD = $(XINE_LIB) $(SDL_LIBS) $(X_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL)
xineplug_vo_out_sdl_la_CFLAGS = $(VISIBILITY_FLAG) $(X_CFLAGS) $(SDL_CFLAGS)
-xineplug_vo_out_stk_la_SOURCES = video_out_stk.c
+xineplug_vo_out_stk_la_SOURCES = video_out_stk.c
xineplug_vo_out_stk_la_LIBADD = $(XINE_LIB) $(LIBSTK_LIBS) $(PTHREAD_LIBS)
xineplug_vo_out_stk_la_CFLAGS = $(VISIBILITY_FLAG) $(LIBSTK_CFLAGS)
-xineplug_vo_out_directx_la_SOURCES = yuv2rgb.c yuv2rgb_mmx.c video_out_directx.c
+xineplug_vo_out_directx_la_SOURCES = yuv2rgb.c yuv2rgb_mmx.c video_out_directx.c
xineplug_vo_out_directx_la_CPPFLAGS = $(AM_CPPFLAGS) $(DIRECTX_CPPFLAGS)
-xineplug_vo_out_directx_la_LIBADD = $(XINE_LIB) $(DIRECTX_VIDEO_LIBS) $(PTHREAD_LIBS)
+xineplug_vo_out_directx_la_LIBADD = $(XINE_LIB) $(DIRECTX_VIDEO_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL)
xineplug_vo_out_directx_la_CFLAGS = $(VISIBILITY_FLAG)
xineplug_vo_out_none_la_SOURCES = video_out_none.c
xineplug_vo_out_none_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL)
xineplug_vo_out_none_la_CFLAGS = $(VISIBILITY_FLAG)
+xineplug_vo_out_raw_la_SOURCES = yuv2rgb.c yuv2rgb_mmx.c yuv2rgb_mlib.c video_out_raw.c
+xineplug_vo_out_raw_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL)
+xineplug_vo_out_raw_la_CFLAGS = $(VISIBILITY_FLAG)
+
xineplug_vo_out_macosx_la_SOURCES = video_out_macosx.m
xineplug_vo_out_macosx_la_CPPFLAGS = $(AM_CPPFLAGS) $(X_CFLAGS) $(MLIB_CFLAGS)
xineplug_vo_out_macosx_la_OBJCFLAGS = $(VISIBILITY_FLAG)
-xineplug_vo_out_macosx_la_LIBADD = $(MLIB_LIBS) $(OPENGL_LIBS) $(GLUT_LIBS) \
- $(GLU_LIBS) $(X_LIBS) $(XINE_LIB) $(PTHREAD_LIBS)
+xineplug_vo_out_macosx_la_LIBADD = $(XINE_LIB) $(MLIB_LIBS) $(OPENGL_LIBS) \
+ $(GLUT_LIBS) $(GLU_LIBS) $(X_LIBS) $(PTHREAD_LIBS)
# The "-Wl,-framework -Wl,Cocoa" 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_vo_out_macosx_la_LDFLAGS = $(AM_LDFLAGS) \
-Wl,-framework -Wl,Cocoa -framework Cocoa -framework OpenGL
noinst_HEADERS = deinterlace.h video_out_syncfb.h \
- yuv2rgb.h x11osd.h xcbosd.h
+ yuv2rgb.h x11osd.h xcbosd.h xv_common.h
diff --git a/src/video_out/deinterlace.c b/src/video_out/deinterlace.c
index 8ba161ebb..712e9a83e 100644
--- a/src/video_out/deinterlace.c
+++ b/src/video_out/deinterlace.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2001 the xine project
+ * Copyright (C) 2001-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -30,6 +30,10 @@
*
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include <string.h>
#include "xine_internal.h"
@@ -37,6 +41,18 @@
#include "xineutils.h"
+const char *deinterlace_methods[] = {
+ "none",
+ "bob",
+ "weave",
+ "greedy",
+ "onefield",
+ "onefield_xv",
+ "linearblend",
+ NULL
+};
+
+
/*
DeinterlaceFieldBob algorithm
Based on Virtual Dub plugin by Gunnar Thalin
diff --git a/src/video_out/deinterlace.h b/src/video_out/deinterlace.h
index 2ebbf53d9..d7712f581 100644
--- a/src/video_out/deinterlace.h
+++ b/src/video_out/deinterlace.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2001 the xine project
+ * Copyright (C) 2001-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -41,15 +41,6 @@ void deinterlace_yuv( uint8_t *pdst, uint8_t *psrc[],
#define DEINTERLACE_ONEFIELDXV 5
#define DEINTERLACE_LINEARBLEND 6
-static const char *deinterlace_methods[] = {
- "none",
- "bob",
- "weave",
- "greedy",
- "onefield",
- "onefield_xv",
- "linearblend",
- NULL
-};
+extern const char *deinterlace_methods[];
#endif
diff --git a/src/video_out/macosx/XineOpenGLView.m b/src/video_out/macosx/XineOpenGLView.m
index a9ffee00f..1f947ca16 100644
--- a/src/video_out/macosx/XineOpenGLView.m
+++ b/src/video_out/macosx/XineOpenGLView.m
@@ -340,7 +340,7 @@ NSColorToYUV(NSColor *color)
// http://developer.apple.com/samplecode/Sample_Code/Graphics_3D/TextureRange/MainOpenGLView.m.htm
glTexSubImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0,
videoSize.width, videoSize.height, GL_YCBCR_422_APPLE,
-#if WORDS_BIG_ENDIAN
+#if WORDS_BIGENDIAN
GL_UNSIGNED_SHORT_8_8_APPLE,
#else
GL_UNSIGNED_SHORT_8_8_REV_APPLE,
diff --git a/src/video_out/video_out_aa.c b/src/video_out/video_out_aa.c
index 012db9665..770b75a10 100644
--- a/src/video_out/video_out_aa.c
+++ b/src/video_out/video_out_aa.c
@@ -106,7 +106,7 @@ static vo_frame_t *aa_alloc_frame(vo_driver_t *this_gen) {
/* aa_driver_t *this = (aa_driver_t*) this_gen; */
aa_frame_t *frame;
- frame = (aa_frame_t *) xine_xmalloc (sizeof (aa_frame_t));
+ frame = calloc(1, sizeof (aa_frame_t));
if (!frame)
return NULL;
@@ -276,7 +276,7 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi
aa_class_t *class = (aa_class_t *) class_gen;
aa_driver_t *this;
- this = (aa_driver_t*) xine_xmalloc (sizeof (aa_driver_t));
+ this = (aa_driver_t*) calloc(1, sizeof(aa_driver_t));
this->context = (aa_context*) visual_gen;
@@ -316,7 +316,7 @@ static void *init_class (xine_t *xine, void *visual_gen) {
/* aa_context *context = (aa_context*) visual_gen; */
aa_class_t *this;
- this = (aa_class_t *) xine_xmalloc(sizeof(aa_class_t));
+ this = calloc(1, sizeof(aa_class_t));
this->driver_class.open_plugin = open_plugin;
this->driver_class.get_identifier = get_identifier;
diff --git a/src/video_out/video_out_caca.c b/src/video_out/video_out_caca.c
index 866eabcd8..65ebf707e 100644
--- a/src/video_out/video_out_caca.c
+++ b/src/video_out/video_out_caca.c
@@ -120,7 +120,7 @@ static vo_frame_t *caca_alloc_frame(vo_driver_t *this_gen) {
caca_driver_t *this = (caca_driver_t*) this_gen;
caca_frame_t *frame;
- frame = (caca_frame_t *) xine_xmalloc (sizeof (caca_frame_t));
+ frame = calloc(1, sizeof (caca_frame_t));
if (!frame)
return NULL;
@@ -276,9 +276,10 @@ static int caca_redraw_needed (vo_driver_t *this_gen) {
static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *visual_gen) {
caca_class_t *class = (caca_class_t *) class_gen;
+ caca_display_t *dp = (caca_display_t *)visual_gen;
caca_driver_t *this;
- this = (caca_driver_t*) xine_xmalloc (sizeof (caca_driver_t));
+ this = calloc(1, sizeof (caca_driver_t));
this->config = class->config;
this->xine = class->xine;
@@ -300,8 +301,13 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi
this->yuv2rgb_factory = yuv2rgb_factory_init(MODE_32_RGB, 0, NULL);
this->yuv2rgb_factory->set_csc_levels(this->yuv2rgb_factory, 0, 128, 128);
- this->cv = cucul_create_canvas(0, 0);
- this->dp = caca_create_display(this->cv);
+ if (dp) {
+ this->cv = caca_get_canvas(dp);
+ this->dp = dp;
+ } else {
+ this->cv = cucul_create_canvas(0, 0);
+ this->dp = caca_create_display(this->cv);
+ }
caca_refresh_display(this->dp);
return &this->vo_driver;
@@ -322,7 +328,7 @@ static void dispose_class (video_driver_class_t *this_gen) {
static void *init_class (xine_t *xine, void *visual_gen) {
caca_class_t *this;
- this = (caca_class_t *) xine_xmalloc(sizeof(caca_class_t));
+ this = calloc(1, sizeof(caca_class_t));
this->driver_class.open_plugin = open_plugin;
this->driver_class.get_identifier = get_identifier;
diff --git a/src/video_out/video_out_directfb.c b/src/video_out/video_out_directfb.c
index e6e333a0c..2e9874cc0 100644
--- a/src/video_out/video_out_directfb.c
+++ b/src/video_out/video_out_directfb.c
@@ -168,10 +168,6 @@ typedef struct {
"no-deinit-check"
-#ifndef MAX
-# define MAX( a, b ) (((a) > (b)) ? (a) : (b))
-#endif
-
#define YCBCR_TO_RGB( y, cb, cr, r, g, b ) \
do { \
int _y, _cb, _cr, _r, _g, _b; \
@@ -232,7 +228,7 @@ static vo_frame_t *directfb_alloc_frame (vo_driver_t *this_gen) {
directfb_driver_t *this = (directfb_driver_t *) this_gen;
directfb_frame_t *frame;
- frame = (directfb_frame_t *) xine_xmalloc (sizeof (directfb_frame_t));
+ frame = (directfb_frame_t *) calloc(1, sizeof(directfb_frame_t));
if (!frame) {
xprintf (this->xine, XINE_VERBOSITY_DEBUG,
"video_out_directfb: directfb_alloc_frame: out of memory\n");
@@ -1753,7 +1749,7 @@ static vo_driver_t *open_plugin_fb (video_driver_class_t *class_gen, const void
DFBDisplayLayerID id;
DFBResult ret;
- this = xine_xmalloc (sizeof (directfb_driver_t));
+ this = calloc(1, sizeof(directfb_driver_t));
if (!this)
return NULL;
@@ -1908,7 +1904,7 @@ static void *init_class_fb (xine_t *xine, void *visual_gen) {
return NULL;
}
- this = (directfb_class_t *) xine_xmalloc (sizeof (directfb_class_t));
+ this = (directfb_class_t *) calloc(1, sizeof(directfb_class_t));
this->driver_class.open_plugin = open_plugin_fb;
this->driver_class.get_identifier = get_identifier_fb;
this->driver_class.get_description = get_description_fb;
@@ -1939,7 +1935,7 @@ static vo_driver_t *open_plugin_x11 (video_driver_class_t *class_gen, const void
DFBDisplayLayerID id = DLID_PRIMARY;
DFBResult ret;
- this = xine_xmalloc (sizeof (directfb_driver_t));
+ this = calloc(1, sizeof(directfb_driver_t));
if (!this)
return NULL;
@@ -2127,7 +2123,7 @@ static void *init_class_x11 (xine_t *xine, void *visual_gen) {
if (strcmp (XServerVendor (visual->display), "Denis Oliver Kropp"))
return NULL;
- this = (directfb_class_t *) xine_xmalloc (sizeof (directfb_class_t));
+ this = (directfb_class_t *) calloc(1, sizeof(directfb_class_t));
this->driver_class.open_plugin = open_plugin_x11;
this->driver_class.get_identifier = get_identifier_x11;
this->driver_class.get_description = get_description_x11;
diff --git a/src/video_out/video_out_directx.c b/src/video_out/video_out_directx.c
index 11ee709e1..3c6f6e784 100644
--- a/src/video_out/video_out_directx.c
+++ b/src/video_out/video_out_directx.c
@@ -21,6 +21,10 @@
* by Matthew Grooms <elon@altavista.com>
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
typedef unsigned char boolean;
#include <windows.h>
@@ -55,21 +59,33 @@ typedef unsigned char boolean;
* the linking stage.
*****************************************************************************/
#if 1
-static const GUID IID_IDirectDraw = {
+static const GUID xine_IID_IDirectDraw = {
0x6C14DB80,0xA733,0x11CE,{0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60}
};
+#ifdef IID_IDirectDraw
+# undef IID_IDirectDraw
+#endif
+#define IID_IDirectDraw xine_IID_IDirectDraw
#endif
#if 0
static const GUID IID_IDirectDraw2 = {
0xB3A6F3E0,0x2B43,0x11CF,{0xA2,0xDE,0x00,0xAA,0x00,0xB9,0x33,0x56}
};
+#ifdef IID_IDirectDraw2
+# undef IID_IDirectDraw2
+#endif
+#define IID_IDirectDraw2 xine_IID_IDirectDraw2
#endif
#if 0
static const GUID IID_IDirectDraw4 = {
0x9C59509A,0x39BD,0x11D1,{0x8C,0x4A,0x00,0xC0,0x4F,0xD9,0x30,0xC5}
};
+#ifdef IID_IDirectDraw4
+# undef IID_IDirectDraw4
+#endif
+#define IID_IDirectDraw4 xine_IID_IDirectDraw4
#endif
/* -----------------------------------------
@@ -117,7 +133,8 @@ typedef struct {
yuv2rgb_t *yuv2rgb; /* used for format conversion */
int mode; /* rgb mode */
int bytespp; /* rgb bits per pixel */
-
+ DDPIXELFORMAT primary_pixel_format;
+ DDSURFACEDESC ddsd; /* set by Lock(), used during display_frame */
alphablend_t alphablend_extra_data;
} win32_driver_t;
@@ -367,8 +384,9 @@ static boolean CreateSecondary( win32_driver_t * win32_driver, int width, int he
lprintf("CreateSecondary() - Falling back to back buffer same as primary\n");
lprintf("CreateSecondary() - act_format = (NATIVE) %d\n", IMGFMT_NATIVE);
- ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+ ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
+ ddsd.ddpfPixelFormat = win32_driver->primary_pixel_format;
win32_driver->act_format = IMGFMT_NATIVE;
if( IDirectDraw_CreateSurface( win32_driver->ddobj, &ddsd, &win32_driver->secondary, 0 ) == DD_OK )
@@ -429,6 +447,10 @@ static boolean CheckPixelFormat( win32_driver_t * win32_driver )
Error( 0, "IDirectDrawSurface_GetPixelFormat ( CheckPixelFormat ) : error 0x%lx", result );
return 0;
}
+
+ /* store pixel format for CreateSecondary */
+
+ win32_driver->primary_pixel_format = ddpf;
/* TODO : support paletized video modes */
@@ -478,9 +500,11 @@ static boolean CheckPixelFormat( win32_driver_t * win32_driver )
win32_driver->mode = MODE_15_BGR;
}
+ lprintf("win32 mode: %u\n", win32_driver->mode);
return TRUE;
}
+#if 0
/* Create a Direct draw surface from
* a bitmap resource..
*
@@ -546,6 +570,7 @@ static LPDIRECTDRAWSURFACE CreateBMP( win32_driver_t * win32_driver, int resourc
return bmp_surf;
}
+#endif
/* Merge overlay with the current primary
* surface. This funtion is only used when
@@ -755,23 +780,22 @@ static boolean DisplayFrame( win32_driver_t * win32_driver )
/* Lock our back buffer to update its contents. */
-static void * Lock( void * surface )
+static void * Lock( win32_driver_t * win32_driver, void * surface )
{
LPDIRECTDRAWSURFACE lock_surface = ( LPDIRECTDRAWSURFACE ) surface;
- DDSURFACEDESC ddsd;
HRESULT result;
if( !surface )
return 0;
- memset( &ddsd, 0, sizeof( ddsd ) );
- ddsd.dwSize = sizeof( ddsd );
+ memset( &win32_driver->ddsd, 0, sizeof( win32_driver->ddsd ) );
+ win32_driver->ddsd.dwSize = sizeof( win32_driver->ddsd );
- result = IDirectDrawSurface_Lock( lock_surface, 0, &ddsd, DDLOCK_WAIT | DDLOCK_NOSYSLOCK, 0 );
+ result = IDirectDrawSurface_Lock( lock_surface, 0, &win32_driver->ddsd, DDLOCK_WAIT | DDLOCK_NOSYSLOCK, 0 );
if( result == DDERR_SURFACELOST )
{
IDirectDrawSurface_Restore( lock_surface );
- result = IDirectDrawSurface_Lock( lock_surface, 0, &ddsd, DDLOCK_WAIT | DDLOCK_NOSYSLOCK, 0 );
+ result = IDirectDrawSurface_Lock( lock_surface, 0, &win32_driver->ddsd, DDLOCK_WAIT | DDLOCK_NOSYSLOCK, 0 );
if( result != DD_OK )
return 0;
@@ -786,7 +810,7 @@ static void * Lock( void * surface )
}
}
- return ddsd.lpSurface;
+ return win32_driver->ddsd.lpSurface;
}
/* Unlock our back buffer to prepair for display. */
@@ -863,7 +887,7 @@ static vo_frame_t * win32_alloc_frame( vo_driver_t * vo_driver )
{
win32_frame_t *win32_frame;
- win32_frame = ( win32_frame_t * ) xine_xmalloc( sizeof( win32_frame_t ) );
+ win32_frame = calloc(1, sizeof(win32_frame_t));
if (!win32_frame)
return NULL;
@@ -946,8 +970,6 @@ static void win32_display_frame( vo_driver_t * vo_driver, vo_frame_t * vo_frame
{
win32_driver_t *win32_driver = ( win32_driver_t * ) vo_driver;
win32_frame_t *win32_frame = ( win32_frame_t * ) vo_frame;
- int offset;
- int size;
/* if the required width, height or format has changed
@@ -966,7 +988,7 @@ static void win32_display_frame( vo_driver_t * vo_driver, vo_frame_t * vo_frame
/* lock our surface to update its contents */
- win32_driver->contents = Lock( win32_driver->secondary );
+ win32_driver->contents = Lock( win32_driver, win32_driver->secondary );
/* surface unavailable, skip frame render */
@@ -1051,37 +1073,47 @@ static void win32_display_frame( vo_driver_t * vo_driver, vo_frame_t * vo_frame
/* the actual format is identical to our
* stream format. we just need to copy it */
- switch(win32_frame->format)
+ int line;
+ uint8_t * src;
+ vo_frame_t * frame = vo_frame;
+ uint8_t * dst = (uint8_t *)win32_driver->contents;
+
+ switch(win32_frame->format)
{
- case XINE_IMGFMT_YV12:
- {
- vo_frame_t *frame;
- uint8_t *img;
-
- frame = vo_frame;
- img = (uint8_t *)win32_driver->contents;
-
- offset = 0;
- size = frame->pitches[0] * frame->height;
- xine_fast_memcpy( img+offset, frame->base[0], size);
-
- offset += size;
- size = frame->pitches[2]* frame->height / 2;
- xine_fast_memcpy( img+offset, frame->base[2], size);
-
- offset += size;
- size = frame->pitches[1] * frame->height / 2;
- xine_fast_memcpy( img+offset, frame->base[1], size);
- }
+ case XINE_IMGFMT_YV12:
+ src = frame->base[0];
+ for (line = 0; line < frame->height ; line++){
+ xine_fast_memcpy( dst, src, frame->width);
+ src += vo_frame->pitches[0];
+ dst += win32_driver->ddsd.lPitch;
+ }
+
+ src = frame->base[2];
+ for (line = 0; line < frame->height/2 ; line++){
+ xine_fast_memcpy( dst, src, frame->width/2);
+ src += vo_frame->pitches[2];
+ dst += win32_driver->ddsd.lPitch/2;
+ }
+
+ src = frame->base[1];
+ for (line = 0; line < frame->height/2 ; line++){
+ xine_fast_memcpy( dst, src, frame->width/2);
+ src += vo_frame->pitches[1];
+ dst += win32_driver->ddsd.lPitch/2;
+ }
break;
+
case XINE_IMGFMT_YUY2:
- xine_fast_memcpy( win32_driver->contents, win32_frame->vo_frame.base[0], win32_frame->vo_frame.pitches[0] * win32_frame->vo_frame.height * 2);
- break;
default:
- xine_fast_memcpy( win32_driver->contents, win32_frame->vo_frame.base[0], win32_frame->vo_frame.pitches[0] * win32_frame->vo_frame.height * 2);
+ src = frame->base[0];
+ for (line = 0; line < frame->height ; line++){
+ xine_fast_memcpy( dst, src, frame->width*2);
+ src += vo_frame->pitches[0];
+ dst += win32_driver->ddsd.lPitch;
+ }
break;
}
- }
+ }
/* unlock the surface */
@@ -1143,11 +1175,38 @@ static int win32_gui_data_exchange( vo_driver_t * vo_driver, int data_type, void
switch( data_type )
{
+
case GUI_WIN32_MOVED_OR_RESIZED:
UpdateRect( win32_driver->win32_visual );
DisplayFrame( win32_driver );
break;
+ case XINE_GUI_SEND_DRAWABLE_CHANGED:
+ {
+ HRESULT result;
+ HWND newWndHnd = (HWND) data;
+
+ /* set cooperative level */
+ result = IDirectDraw_SetCooperativeLevel( win32_driver->ddobj, newWndHnd, DDSCL_NORMAL );
+ if( result != DD_OK )
+ {
+ Error( 0, "SetCooperativeLevel : error 0x%lx", result );
+ return 0;
+ }
+ /* associate our clipper with new window */
+ result = IDirectDrawClipper_SetHWnd( win32_driver->ddclipper, 0, newWndHnd );
+ if( result != DD_OK )
+ {
+ Error( 0, "ddclipper->SetHWnd : error 0x%lx", result );
+ return 0;
+ }
+ /* store our objects in our visual struct */
+ win32_driver->win32_visual->WndHnd = newWndHnd;
+ /* update video area and redraw current frame */
+ UpdateRect( win32_driver->win32_visual );
+ DisplayFrame( win32_driver );
+ break;
}
+ }
return 0;
}
@@ -1183,7 +1242,7 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *wi
/*vo_driver_t *init_video_out_plugin( config_values_t * config, void * win32_visual )*/
{
directx_class_t *class = (directx_class_t *)class_gen;
- win32_driver_t *win32_driver = ( win32_driver_t * ) xine_xmalloc ( sizeof( win32_driver_t ) );
+ win32_driver_t *win32_driver = calloc(1, sizeof(win32_driver_t));
_x_alphablend_init(&win32_driver->alphablend_extra_data, class->xine);
@@ -1249,7 +1308,7 @@ static void *init_class (xine_t *xine, void *visual_gen) {
/*
* from this point on, nothing should go wrong anymore
*/
- directx = (directx_class_t *) xine_xmalloc (sizeof (directx_class_t));
+ directx = calloc(1, sizeof (directx_class_t));
directx->driver_class.open_plugin = open_plugin;
directx->driver_class.get_identifier = get_identifier;
diff --git a/src/video_out/video_out_fb.c b/src/video_out/video_out_fb.c
index 95060a4d8..d67b0870d 100644
--- a/src/video_out/video_out_fb.c
+++ b/src/video_out/video_out_fb.c
@@ -221,7 +221,7 @@ static vo_frame_t *fb_alloc_frame(vo_driver_t *this_gen)
this->total_num_native_buffers <= this->used_num_buffers)
return 0;
- frame = (fb_frame_t *)xine_xmalloc(sizeof(fb_frame_t));
+ frame = calloc(1, sizeof(fb_frame_t));
if(!frame)
return NULL;
@@ -324,21 +324,10 @@ static void setup_colorspace_converter(fb_frame_t *frame, int flags)
static void frame_reallocate(fb_driver_t *this, fb_frame_t *frame,
uint32_t width, uint32_t height, int format)
{
- if(frame->chunk[0])
- {
- free(frame->chunk[0]);
- frame->chunk[0] = NULL;
- }
- if(frame->chunk[1])
- {
- free(frame->chunk[1]);
- frame->chunk[1] = NULL;
- }
- if(frame->chunk[2])
- {
- free(frame->chunk[2]);
- frame->chunk[2] = NULL;
- }
+ free(frame->chunk[0]);
+ free(frame->chunk[1]);
+ free(frame->chunk[2]);
+ memset(frame->chunk, 0, sizeof(frame->chunk[0])*3);
if(this->use_zero_copy)
{
@@ -348,10 +337,9 @@ static void frame_reallocate(fb_driver_t *this, fb_frame_t *frame,
}
else
{
- if(frame->data)
- free(frame->data);
- frame->data = xine_xmalloc(frame->sc.output_width *
- frame->sc.output_height *
+ free(frame->data);
+ frame->data = calloc(frame->sc.output_width *
+ frame->sc.output_height,
this->bytes_per_pixel);
}
@@ -1004,7 +992,7 @@ static vo_driver_t *fb_open_plugin(video_driver_class_t *class_gen,
config = class->config;
/* allocate plugin struct */
- this = (fb_driver_t *) xine_xmalloc(sizeof(fb_driver_t));
+ this = calloc(1, sizeof(fb_driver_t));
if(!this)
return NULL;
@@ -1087,7 +1075,7 @@ static void fb_dispose_class(video_driver_class_t *this_gen)
static void *fb_init_class(xine_t *xine, void *visual_gen)
{
- fb_class_t *this = (fb_class_t *)xine_xmalloc(sizeof(fb_class_t));
+ fb_class_t *this = calloc(1, sizeof(fb_class_t));
this->driver_class.open_plugin = fb_open_plugin;
this->driver_class.get_identifier = fb_get_identifier;
diff --git a/src/video_out/video_out_macosx.m b/src/video_out/video_out_macosx.m
index 4621d31b9..b5b4d731c 100644
--- a/src/video_out/video_out_macosx.m
+++ b/src/video_out/video_out_macosx.m
@@ -97,7 +97,7 @@ static vo_frame_t *macosx_alloc_frame(vo_driver_t *vo_driver) {
/* macosx_driver_t *this = (macosx_driver_t *) vo_driver; */
macosx_frame_t *frame;
- frame = (macosx_frame_t *) xine_xmalloc(sizeof(macosx_frame_t));
+ frame = calloc(1, sizeof(macosx_frame_t));
if(!frame)
return NULL;
@@ -207,7 +207,7 @@ static void macosx_display_frame(vo_driver_t *vo_driver, vo_frame_t *vo_frame) {
break;
case XINE_IMGFMT_YUY2:
xine_fast_memcpy (texture_buffer, vo_frame->base[0],
- vo_frame->pitches[0] * vo_frame->height * 2);
+ vo_frame->pitches[0] * vo_frame->height);
[driver->view updateTexture];
break;
default:
@@ -320,7 +320,7 @@ static vo_driver_t *open_plugin(video_driver_class_t *driver_class, const void *
macosx_driver_t *driver;
XineOpenGLView *view = (XineOpenGLView *) visual;
- driver = (macosx_driver_t *) xine_xmalloc(sizeof(macosx_driver_t));
+ driver = calloc(1, sizeof(macosx_driver_t));
driver->config = class->config;
driver->xine = class->xine;
@@ -366,7 +366,7 @@ static void dispose_class (video_driver_class_t *driver_class) {
static void *init_class (xine_t *xine, void *visual) {
macosx_class_t *this;
- this = (macosx_class_t *) xine_xmalloc(sizeof(macosx_class_t));
+ this = calloc(1, sizeof(macosx_class_t));
this->driver_class.open_plugin = open_plugin;
this->driver_class.get_identifier = get_identifier;
diff --git a/src/video_out/video_out_none.c b/src/video_out/video_out_none.c
index 5f2424a60..0de6e34e8 100644
--- a/src/video_out/video_out_none.c
+++ b/src/video_out/video_out_none.c
@@ -88,7 +88,7 @@ static vo_frame_t *none_alloc_frame(vo_driver_t *vo_driver) {
/* none_driver_t *this = (none_driver_t *) vo_driver; */
none_frame_t *frame;
- frame = (none_frame_t *) xine_xmalloc(sizeof(none_frame_t));
+ frame = calloc(1, sizeof(none_frame_t));
if(!frame)
return NULL;
@@ -243,7 +243,7 @@ static vo_driver_t *open_plugin(video_driver_class_t *driver_class, const void *
none_class_t *class = (none_class_t *) driver_class;
none_driver_t *driver;
- driver = (none_driver_t *) xine_xmalloc(sizeof(none_driver_t));
+ driver = calloc(1, sizeof(none_driver_t));
driver->config = class->config;
driver->xine = class->xine;
@@ -286,7 +286,7 @@ static void dispose_class (video_driver_class_t *driver_class) {
static void *init_class (xine_t *xine, void *visual) {
none_class_t *this;
- this = (none_class_t *) xine_xmalloc(sizeof(none_class_t));
+ this = calloc(1, sizeof(none_class_t));
this->driver_class.open_plugin = open_plugin;
this->driver_class.get_identifier = get_identifier;
diff --git a/src/video_out/video_out_opengl.c b/src/video_out/video_out_opengl.c
index 54696f452..a8f11db2f 100644
--- a/src/video_out/video_out_opengl.c
+++ b/src/video_out/video_out_opengl.c
@@ -669,8 +669,8 @@ static int render_image_envtex (opengl_driver_t *this, opengl_frame_t *frame) {
* Render setup functions
*/
static int render_help_verify_ext (opengl_driver_t *this, char *ext) {
- int ret = 0;
- int l = strlen (ext);
+ int ret = 0;
+ const size_t l = strlen (ext);
const char *e;
for (e = (char *) this->gl_exts; e && *e; e = strchr (e, ' ')) {
while (isspace (*e))
@@ -694,10 +694,9 @@ static void *getdladdr (const GLubyte *_funcName) {
return NULL;
#elif defined(__APPLE__)
- char *temp = xine_xmalloc (strlen (funcName) + 2);
+ char *temp;
+ asprintf(&temp, "_%s", funcName);
void *res = NULL;
- temp[0] = '_'; /* Mac OS X prepends an underscore on function names */
- strcpy (temp+1, funcName);
if (NSIsSymbolNameDefined (temp)) {
NSSymbol symbol = NSLookupAndBindSymbol (temp);
res = NSAddressOfSymbol (symbol);
@@ -1281,7 +1280,7 @@ static vo_frame_t *opengl_alloc_frame (vo_driver_t *this_gen) {
opengl_frame_t *frame;
opengl_driver_t *this = (opengl_driver_t *) this_gen;
- frame = (opengl_frame_t *) xine_xmalloc (sizeof (opengl_frame_t));
+ frame = (opengl_frame_t *) calloc(1, sizeof(opengl_frame_t));
if (!frame)
return NULL;
@@ -1820,7 +1819,7 @@ static vo_driver_t *opengl_open_plugin (video_driver_class_t *class_gen, const v
char **render_fun_names;
int i;
- this = (opengl_driver_t *) xine_xmalloc (sizeof (opengl_driver_t));
+ this = (opengl_driver_t *) calloc(1, sizeof(opengl_driver_t));
if (!this)
return NULL;
@@ -1876,8 +1875,7 @@ static vo_driver_t *opengl_open_plugin (video_driver_class_t *class_gen, const v
this->drawable, X11OSD_SHAPED);
XUnlockDisplay (this->display);
- render_fun_names = xine_xmalloc ((sizeof(opengl_rb)/sizeof(opengl_render_t)+1)
- * sizeof (const char *));
+ render_fun_names = calloc((sizeof(opengl_rb)/sizeof(opengl_render_t)+1), sizeof(const char*));
for (i = 0; i < sizeof (opengl_rb) / sizeof (opengl_render_t); i++)
render_fun_names[i] = opengl_rb[i].name;
render_fun_names[i] = NULL;
@@ -1955,6 +1953,52 @@ static vo_driver_t *opengl_open_plugin (video_driver_class_t *class_gen, const v
* class functions
*/
+static int opengl_verify_direct (x11_visual_t *vis) {
+ int attribs[] = {
+ GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ None
+ };
+ Window root, win;
+ XVisualInfo *visinfo;
+ GLXContext ctx;
+ XSetWindowAttributes xattr;
+ int ret = 0;
+
+ if (!vis || !vis->display ||
+ ! (root = RootWindow (vis->display, vis->screen))) {
+ fprintf (stderr, "[videoout_opengl]: Don't have a root window to verify\n");
+ return 0;
+ }
+ if (! (visinfo = glXChooseVisual (vis->display, vis->screen, attribs)))
+ return 0;
+ if (! (ctx = glXCreateContext (vis->display, visinfo, NULL, 1)))
+ return 0;
+ memset (&xattr, 0, sizeof (xattr));
+ xattr.colormap = XCreateColormap(vis->display, root, visinfo->visual, AllocNone);
+ xattr.event_mask = StructureNotifyMask | ExposureMask;
+ if ( (win = XCreateWindow (vis->display, root, 0, 0, 1, 1, 0, visinfo->depth,
+ InputOutput, visinfo->visual,
+ CWBackPixel | CWBorderPixel | CWColormap | CWEventMask,
+ &xattr))) {
+ if (glXMakeCurrent (vis->display, win, ctx)) {
+ const char *renderer = (const char *) glGetString(GL_RENDERER);
+ if (glXIsDirect (vis->display, ctx) &&
+ ! strstr (renderer, "Software") &&
+ ! strstr (renderer, "Indirect"))
+ ret = 1;
+ glXMakeCurrent (vis->display, None, NULL);
+ }
+ XDestroyWindow (vis->display, win);
+ }
+ glXDestroyContext (vis->display, ctx);
+ XFreeColormap (vis->display, xattr.colormap);
+
+ return ret;
+}
+
static char* opengl_get_identifier (video_driver_class_t *this_gen) {
return "opengl";
}
@@ -1970,7 +2014,18 @@ static void opengl_dispose_class (video_driver_class_t *this_gen) {
}
static void *opengl_init_class (xine_t *xine, void *visual_gen) {
- opengl_class_t *this = (opengl_class_t *) xine_xmalloc (sizeof (opengl_class_t));
+
+ opengl_class_t *this;
+
+ xprintf (xine, XINE_VERBOSITY_LOG,
+ "video_out_opengl: Testing for hardware accelerated direct rendering visual\n");
+ if (! opengl_verify_direct ((x11_visual_t *)visual_gen)) {
+ xprintf (xine, XINE_VERBOSITY_LOG,
+ "video_out_opengl: Didn't find any\n");
+ return NULL;
+ }
+
+ this = (opengl_class_t *) calloc (1, sizeof(opengl_class_t));
this->driver_class.open_plugin = opengl_open_plugin;
this->driver_class.get_identifier = opengl_get_identifier;
diff --git a/src/video_out/video_out_pgx32.c b/src/video_out/video_out_pgx32.c
index d903efc89..45a54cc76 100644
--- a/src/video_out/video_out_pgx32.c
+++ b/src/video_out/video_out_pgx32.c
@@ -386,7 +386,7 @@ static vo_frame_t *pgx32_alloc_frame(vo_driver_t *this_gen)
/*pgx32_driver_t *this = (pgx32_driver_t *)(void *)this_gen;*/
pgx32_frame_t *frame;
- frame = (pgx32_frame_t *) xine_xmalloc(sizeof(pgx32_frame_t));
+ frame = calloc(1, sizeof(pgx32_frame_t));
if (!frame) {
return NULL;
}
@@ -800,7 +800,7 @@ static vo_driver_t *pgx32_init_driver(video_driver_class_t *class_gen, const voi
pgx32_driver_class_t *class = (pgx32_driver_class_t *)(void *)class_gen;
pgx32_driver_t *this;
- this = (pgx32_driver_t *)xine_xmalloc(sizeof(pgx32_driver_t));
+ this = calloc(1, sizeof(pgx32_driver_t));
if (!this) {
return NULL;
}
@@ -869,7 +869,7 @@ static void *pgx32_init_class(xine_t *xine, void *visual_gen)
{
pgx32_driver_class_t *class;
- class = (pgx32_driver_class_t *)xine_xmalloc(sizeof(pgx32_driver_class_t));
+ class = calloc(1, sizeof(pgx32_driver_class_t));
if (!class) {
return NULL;
}
diff --git a/src/video_out/video_out_pgx64.c b/src/video_out/video_out_pgx64.c
index 4abb794d7..abda51e2b 100644
--- a/src/video_out/video_out_pgx64.c
+++ b/src/video_out/video_out_pgx64.c
@@ -561,7 +561,7 @@ static vo_frame_t *pgx64_alloc_frame(vo_driver_t *this_gen)
/*pgx64_driver_t *this = (pgx64_driver_t *)(void *)this_gen;*/
pgx64_frame_t *frame;
- frame = (pgx64_frame_t *) xine_xmalloc(sizeof(pgx64_frame_t));
+ frame = calloc(1, sizeof(pgx64_frame_t));
if (!frame) {
return NULL;
}
@@ -1352,7 +1352,7 @@ static vo_driver_t *pgx64_init_driver(video_driver_class_t *class_gen, const voi
struct fbgattr attr;
long page_size;
- this = (pgx64_driver_t *)xine_xmalloc(sizeof(pgx64_driver_t));
+ this = calloc(1, sizeof(pgx64_driver_t));
if (!this) {
return NULL;
}
@@ -1493,7 +1493,7 @@ static void *pgx64_init_class(xine_t *xine, void *visual_gen)
{
pgx64_driver_class_t *class;
- class = (pgx64_driver_class_t *)xine_xmalloc(sizeof(pgx64_driver_class_t));
+ class = calloc(1, sizeof(pgx64_driver_class_t));
if (!class) {
return NULL;
}
diff --git a/src/video_out/video_out_raw.c b/src/video_out/video_out_raw.c
new file mode 100644
index 000000000..99e2c0004
--- /dev/null
+++ b/src/video_out/video_out_raw.c
@@ -0,0 +1,610 @@
+/*
+ * Copyright (C) 2007-2008 the xine project
+ *
+ * This file is part of xine, a free video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ *
+ * video_out_raw.c, a video output plugin to pass raw data to frontend
+ *
+ * Written by Christophe Thommeret <hftom@free.fr>,
+ * based on others' video output plugins.
+ *
+ */
+
+/* #define LOG */
+#define LOG_MODULE "video_out_raw"
+
+/* Allow frontend some time to render frames
+* However, frontends are strongly advised to render synchronously */
+#define NUM_FRAMES_BACKLOG 4
+#define BYTES_PER_PIXEL 3
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <math.h>
+#include <errno.h>
+#include <ctype.h>
+#include <pthread.h>
+
+#include "xine.h"
+#include "video_out.h"
+
+#include "xine_internal.h"
+#include "yuv2rgb.h"
+#include "xineutils.h"
+
+
+
+typedef struct {
+ vo_frame_t vo_frame;
+
+ int width, height, format, flags;
+ double ratio;
+ uint8_t *chunk[4]; /* mem alloc by xmalloc_aligned */
+ uint8_t *rgb, *rgb_dst;
+ yuv2rgb_t *yuv2rgb; /* yuv2rgb converter set up for this frame */
+
+} raw_frame_t;
+
+typedef struct {
+ vo_driver_t vo_driver;
+
+ void *user_data;
+
+ void (*raw_output_cb) (void *user_data, int format,
+ int frame_width, int frame_height, double frame_aspect,
+ void *data0, void *data1, void *data2);
+
+ void (*raw_overlay_cb) (void *user_data, int num_ovl,
+ raw_overlay_t *overlays_p);
+
+ int ovl_changed;
+ raw_overlay_t overlays[XINE_VORAW_MAX_OVL];
+ yuv2rgb_t *ovl_yuv2rgb;
+
+ int doYV12;
+ int doYUY2;
+ yuv2rgb_factory_t *yuv2rgb_factory;
+ /* Frame state */
+ raw_frame_t *frame[NUM_FRAMES_BACKLOG];
+ xine_t *xine;
+} raw_driver_t;
+
+
+typedef struct {
+ video_driver_class_t driver_class;
+ xine_t *xine;
+} raw_class_t;
+
+
+
+static void raw_overlay_clut_yuv2rgb(raw_driver_t *this, vo_overlay_t *overlay, raw_frame_t *frame)
+{
+ int i;
+ clut_t* clut = (clut_t*) overlay->color;
+
+ if (!overlay->rgb_clut) {
+ for ( i=0; i<sizeof(overlay->color)/sizeof(overlay->color[0]); i++ ) {
+ *((uint32_t *)&clut[i]) = this->ovl_yuv2rgb->yuv2rgb_single_pixel_fun(frame->yuv2rgb, clut[i].y, clut[i].cb, clut[i].cr);
+ }
+ overlay->rgb_clut++;
+ }
+ if (!overlay->hili_rgb_clut) {
+ clut = (clut_t*) overlay->hili_color;
+ for ( i=0; i<sizeof(overlay->color)/sizeof(overlay->color[0]); i++) {
+ *((uint32_t *)&clut[i]) = this->ovl_yuv2rgb->yuv2rgb_single_pixel_fun(frame->yuv2rgb, clut[i].y, clut[i].cb, clut[i].cr);
+ }
+ overlay->hili_rgb_clut++;
+ }
+}
+
+
+static int raw_process_ovl( raw_driver_t *this_gen, vo_overlay_t *overlay )
+{
+ raw_overlay_t *ovl = &this_gen->overlays[this_gen->ovl_changed-1];
+
+ if ( overlay->width<=0 || overlay->height<=0 )
+ return 0;
+
+ if ( (overlay->width*overlay->height)!=(ovl->ovl_w*ovl->ovl_h) )
+ ovl->ovl_rgba = (uint8_t*)realloc( ovl->ovl_rgba, overlay->width*overlay->height*4 );
+ ovl->ovl_w = overlay->width;
+ ovl->ovl_h = overlay->height;
+ ovl->ovl_x = overlay->x;
+ ovl->ovl_y = overlay->y;
+
+ int num_rle = overlay->num_rle;
+ rle_elem_t *rle = overlay->rle;
+ uint8_t *rgba = ovl->ovl_rgba;
+ clut_t *low_colors = (clut_t*)overlay->color;
+ clut_t *hili_colors = (clut_t*)overlay->hili_color;
+ uint8_t *low_trans = overlay->trans;
+ uint8_t *hili_trans = overlay->hili_trans;
+ clut_t *colors;
+ uint8_t *trans;
+ uint8_t alpha;
+ int rlelen = 0;
+ uint8_t clr = 0;
+ int i, pos=0, x, y;
+
+ while ( num_rle>0 ) {
+ x = pos%ovl->ovl_w;
+ y = pos/ovl->ovl_w;
+ if ( (x>=overlay->hili_left && x<=overlay->hili_right) && (y>=overlay->hili_top && y<=overlay->hili_bottom) ) {
+ colors = hili_colors;
+ trans = hili_trans;
+ }
+ else {
+ colors = low_colors;
+ trans = low_trans;
+ }
+ rlelen = rle->len;
+ clr = rle->color;
+ alpha = trans[clr];
+ for ( i=0; i<rlelen; ++i ) {
+ rgba[0] = colors[clr].y;
+ rgba[1] = colors[clr].cr;
+ rgba[2] = colors[clr].cb;
+ rgba[3] = alpha*255/15;
+ rgba+= 4;
+ ++pos;
+ }
+ ++rle;
+ --num_rle;
+ }
+ return 1;
+}
+
+
+static void raw_overlay_begin (vo_driver_t *this_gen, vo_frame_t *frame_gen, int changed)
+{
+ raw_driver_t *this = (raw_driver_t *) this_gen;
+
+ if ( !changed )
+ return;
+
+ ++this->ovl_changed;
+}
+
+
+static void raw_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay)
+{
+ raw_driver_t *this = (raw_driver_t *) this_gen;
+ raw_frame_t *frame = (raw_frame_t *) frame_gen;
+
+ if ( !this->ovl_changed || this->ovl_changed>XINE_VORAW_MAX_OVL )
+ return;
+
+ if (overlay->rle) {
+ if (!overlay->rgb_clut || !overlay->hili_rgb_clut)
+ raw_overlay_clut_yuv2rgb (this, overlay, frame);
+ if ( raw_process_ovl( this, overlay ) )
+ ++this->ovl_changed;
+ }
+}
+
+
+static void raw_overlay_end (vo_driver_t *this_gen, vo_frame_t *vo_img)
+{
+ raw_driver_t *this = (raw_driver_t *) this_gen;
+
+ if ( !this->ovl_changed )
+ return;
+
+ this->raw_overlay_cb( this->user_data, this->ovl_changed-1, this->overlays );
+
+ this->ovl_changed = 0;
+}
+
+
+static void raw_frame_proc_slice (vo_frame_t *vo_img, uint8_t **src)
+{
+ raw_frame_t *frame = (raw_frame_t *) vo_img ;
+
+ vo_img->proc_called = 1;
+ if (! frame->rgb_dst)
+ return;
+
+ if( frame->vo_frame.crop_left || frame->vo_frame.crop_top ||
+ frame->vo_frame.crop_right || frame->vo_frame.crop_bottom )
+ {
+ /* TODO: ?!? */
+ return;
+ }
+
+ if (frame->format == XINE_IMGFMT_YV12)
+ frame->yuv2rgb->yuv2rgb_fun (frame->yuv2rgb, frame->rgb_dst, src[0], src[1], src[2]);
+ else
+ frame->yuv2rgb->yuy22rgb_fun (frame->yuv2rgb, frame->rgb_dst, src[0]);
+}
+
+
+
+static void raw_frame_field (vo_frame_t *vo_img, int which_field)
+{
+ raw_frame_t *frame = (raw_frame_t *) vo_img ;
+ raw_driver_t *this = (raw_driver_t *) vo_img->driver;
+
+ if ( frame->format==XINE_IMGFMT_YV12 && this->doYV12 ) {
+ frame->rgb_dst = 0;
+ return;
+ }
+ else if ( frame->format==XINE_IMGFMT_YUY2 && this->doYUY2 ) {
+ frame->rgb_dst = 0;
+ return;
+ }
+
+ switch (which_field) {
+ case VO_TOP_FIELD:
+ frame->rgb_dst = (uint8_t *)frame->rgb;
+ break;
+ case VO_BOTTOM_FIELD:
+ frame->rgb_dst = (uint8_t *)frame->rgb + frame->width * BYTES_PER_PIXEL;
+ break;
+ case VO_BOTH_FIELDS:
+ frame->rgb_dst = (uint8_t *)frame->rgb;
+ break;
+ }
+
+ frame->yuv2rgb->next_slice (frame->yuv2rgb, NULL);
+}
+
+
+
+static void raw_frame_dispose (vo_frame_t *vo_img)
+{
+ raw_frame_t *frame = (raw_frame_t *) vo_img ;
+
+ frame->yuv2rgb->dispose (frame->yuv2rgb);
+
+ free (frame->chunk[0]);
+ free (frame->chunk[1]);
+ free (frame->chunk[2]);
+ free (frame->chunk[3]);
+ free (frame);
+}
+
+
+
+static vo_frame_t *raw_alloc_frame (vo_driver_t *this_gen)
+{
+ raw_frame_t *frame;
+ raw_driver_t *this = (raw_driver_t *) this_gen;
+
+ frame = (raw_frame_t *) calloc(1, sizeof(raw_frame_t));
+
+ if (!frame)
+ return NULL;
+
+ pthread_mutex_init (&frame->vo_frame.mutex, NULL);
+
+ /*
+ * supply required functions/fields
+ */
+ frame->vo_frame.proc_slice = raw_frame_proc_slice;
+ frame->vo_frame.proc_frame = NULL;
+ frame->vo_frame.field = raw_frame_field;
+ frame->vo_frame.dispose = raw_frame_dispose;
+ frame->vo_frame.driver = this_gen;
+
+ /*
+ * colorspace converter for this frame
+ */
+ frame->yuv2rgb = this->yuv2rgb_factory->create_converter (this->yuv2rgb_factory);
+
+ return (vo_frame_t *) frame;
+}
+
+
+
+static void raw_update_frame_format (vo_driver_t *this_gen, vo_frame_t *frame_gen,
+ uint32_t width, uint32_t height, double ratio, int format, int flags)
+{
+ raw_frame_t *frame = (raw_frame_t *) frame_gen;
+
+ /* Check frame size and format and reallocate if necessary */
+ if ((frame->width != width)
+ || (frame->height != height)
+ || (frame->format != format)
+ || (frame->flags != flags)) {
+/* lprintf ("updating frame to %d x %d (ratio=%g, format=%08x)\n", width, height, ratio, format); */
+
+ flags &= VO_BOTH_FIELDS;
+
+ /* (re-) allocate render space */
+ free (frame->chunk[0]);
+ free (frame->chunk[1]);
+ free (frame->chunk[2]);
+ free (frame->chunk[3]);
+
+ if (format == XINE_IMGFMT_YV12) {
+ frame->vo_frame.pitches[0] = 8*((width + 7) / 8);
+ frame->vo_frame.pitches[1] = 8*((width + 15) / 16);
+ frame->vo_frame.pitches[2] = 8*((width + 15) / 16);
+ frame->vo_frame.base[0] = xine_xmalloc_aligned (16, frame->vo_frame.pitches[0] * height, (void **) &frame->chunk[0]);
+ frame->vo_frame.base[1] = xine_xmalloc_aligned (16, frame->vo_frame.pitches[1] * ((height+1)/2), (void **) &frame->chunk[1]);
+ frame->vo_frame.base[2] = xine_xmalloc_aligned (16, frame->vo_frame.pitches[2] * ((height+1)/2), (void **) &frame->chunk[2]);
+ } else {
+ frame->vo_frame.pitches[0] = 8*((width + 3) / 4);
+ frame->vo_frame.base[0] = xine_xmalloc_aligned (16, frame->vo_frame.pitches[0] * height, (void **) &frame->chunk[0]);
+ frame->chunk[1] = NULL;
+ frame->chunk[2] = NULL;
+ }
+ frame->rgb = xine_xmalloc_aligned (16, BYTES_PER_PIXEL*width*height,
+ (void **) &frame->chunk[3]);
+
+ /* set up colorspace converter */
+ switch (flags) {
+ case VO_TOP_FIELD:
+ case VO_BOTTOM_FIELD:
+ frame->yuv2rgb->configure (frame->yuv2rgb,
+ width,
+ height,
+ 2*frame->vo_frame.pitches[0],
+ 2*frame->vo_frame.pitches[1],
+ width,
+ height,
+ BYTES_PER_PIXEL*width * 2);
+ break;
+ case VO_BOTH_FIELDS:
+ frame->yuv2rgb->configure (frame->yuv2rgb,
+ width,
+ height,
+ frame->vo_frame.pitches[0],
+ frame->vo_frame.pitches[1],
+ width,
+ height,
+ BYTES_PER_PIXEL*width);
+ break;
+ }
+
+ frame->width = width;
+ frame->height = height;
+ frame->format = format;
+
+ raw_frame_field ((vo_frame_t *)frame, flags);
+ }
+
+ frame->ratio = ratio;
+}
+
+
+
+static int raw_redraw_needed (vo_driver_t *this_gen)
+{
+ return 0;
+}
+
+
+
+static void raw_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen)
+{
+ raw_driver_t *this = (raw_driver_t *) this_gen;
+ raw_frame_t *frame = (raw_frame_t *) frame_gen;
+ int i;
+
+ if (this->frame[NUM_FRAMES_BACKLOG-1]) {
+ this->frame[NUM_FRAMES_BACKLOG-1]->vo_frame.free (&this->frame[NUM_FRAMES_BACKLOG-1]->vo_frame);
+ }
+ for (i = NUM_FRAMES_BACKLOG-1; i > 0; i--)
+ this->frame[i] = this->frame[i-1];
+ this->frame[0] = frame;
+
+ if ( frame->rgb_dst ) {
+ this->raw_output_cb( this->user_data, XINE_VORAW_RGB, frame->width, frame->height, frame->ratio, frame->rgb, 0, 0 );
+ }
+ else if ( frame->format==XINE_IMGFMT_YV12 ) {
+ this->raw_output_cb( this->user_data, XINE_VORAW_YV12, frame->width, frame->height, frame->ratio, frame->vo_frame.base[0],
+ frame->vo_frame.base[1], frame->vo_frame.base[2] );
+ }
+ else {
+ this->raw_output_cb( this->user_data, XINE_VORAW_YUY2, frame->width, frame->height, frame->ratio, frame->vo_frame.base[0], 0, 0 );
+ }
+}
+
+
+
+static int raw_get_property (vo_driver_t *this_gen, int property)
+{
+ switch (property) {
+ case VO_PROP_ASPECT_RATIO:
+ return XINE_VO_ASPECT_AUTO;
+ case VO_PROP_MAX_NUM_FRAMES:
+ return 15;
+ case VO_PROP_BRIGHTNESS:
+ return 0;
+ case VO_PROP_CONTRAST:
+ return 128;
+ case VO_PROP_SATURATION:
+ return 128;
+ case VO_PROP_WINDOW_WIDTH:
+ return 0;
+ case VO_PROP_WINDOW_HEIGHT:
+ return 0;
+ default:
+ return 0;
+ }
+}
+
+
+
+static int raw_set_property (vo_driver_t *this_gen, int property, int value)
+{
+ return value;
+}
+
+
+
+static void raw_get_property_min_max (vo_driver_t *this_gen, int property, int *min, int *max)
+{
+ *min = 0;
+ *max = 0;
+}
+
+
+
+static int raw_gui_data_exchange (vo_driver_t *this_gen, int data_type, void *data)
+{
+ return 0;
+}
+
+
+
+static uint32_t raw_get_capabilities (vo_driver_t *this_gen)
+{
+ uint32_t capabilities = VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_CROP;
+ return capabilities;
+}
+
+
+
+static void raw_dispose (vo_driver_t *this_gen)
+{
+ raw_driver_t *this = (raw_driver_t *) this_gen;
+ int i;
+
+ for (i = 0; i < NUM_FRAMES_BACKLOG; i++)
+ if (this->frame[i])
+ this->frame[i]->vo_frame.dispose (&this->frame[i]->vo_frame);
+
+ this->yuv2rgb_factory->dispose (this->yuv2rgb_factory);
+
+ for ( i=0; i<XINE_VORAW_MAX_OVL; ++i )
+ free( this->overlays[i].ovl_rgba );
+
+ free (this);
+}
+
+
+
+static vo_driver_t *raw_open_plugin (video_driver_class_t *class_gen, const void *visual_gen)
+{
+ raw_class_t *class = (raw_class_t *) class_gen;
+ raw_visual_t *visual = (raw_visual_t *) visual_gen;
+ raw_driver_t *this;
+ int i;
+
+ this = (raw_driver_t *) calloc(1, sizeof(raw_driver_t));
+
+ if (!this)
+ return NULL;
+
+ this->raw_output_cb = visual->raw_output_cb;
+ this->user_data = visual->user_data;
+ this->xine = class->xine;
+ this->raw_overlay_cb = visual->raw_overlay_cb;
+ this->doYV12 = visual->supported_formats&XINE_VORAW_YV12;
+ this->doYUY2 = visual->supported_formats&XINE_VORAW_YUY2;
+
+ this->vo_driver.get_capabilities = raw_get_capabilities;
+ this->vo_driver.alloc_frame = raw_alloc_frame;
+ this->vo_driver.update_frame_format = raw_update_frame_format;
+ this->vo_driver.overlay_begin = raw_overlay_begin;
+ this->vo_driver.overlay_blend = raw_overlay_blend;
+ this->vo_driver.overlay_end = raw_overlay_end;
+ this->vo_driver.display_frame = raw_display_frame;
+ this->vo_driver.get_property = raw_get_property;
+ this->vo_driver.set_property = raw_set_property;
+ this->vo_driver.get_property_min_max = raw_get_property_min_max;
+ this->vo_driver.gui_data_exchange = raw_gui_data_exchange;
+ this->vo_driver.dispose = raw_dispose;
+ this->vo_driver.redraw_needed = raw_redraw_needed;
+
+ this->yuv2rgb_factory = yuv2rgb_factory_init (MODE_24_BGR, 1, NULL); /* converts to rgb */
+
+ for (i = 0; i < NUM_FRAMES_BACKLOG; i++)
+ this->frame[i] = 0;
+
+ for ( i=0; i<XINE_VORAW_MAX_OVL; ++i ) {
+ this->overlays[i].ovl_w = this->overlays[i].ovl_h = 2;
+ this->overlays[i].ovl_rgba = (uint8_t*)malloc(2*2*4);
+ this->overlays[i].ovl_x = this->overlays[i].ovl_y = 0;
+ }
+ this->ovl_changed = 0;
+
+ /* we have to use a second converter for overlays
+ * because "MODE_24_BGR, 1 (swap)" breaks overlays conversion */
+ yuv2rgb_factory_t *factory = yuv2rgb_factory_init (MODE_24_BGR, 0, NULL);
+ this->ovl_yuv2rgb = factory->create_converter( factory );
+ factory->dispose( factory );
+
+ return &this->vo_driver;
+}
+
+/*
+ * class functions
+ */
+
+static char* raw_get_identifier (video_driver_class_t *this_gen)
+{
+ return "raw";
+}
+
+
+
+static char* raw_get_description (video_driver_class_t *this_gen)
+{
+ return _("xine video output plugin passing raw data to supplied callback");
+}
+
+
+
+static void raw_dispose_class (video_driver_class_t *this_gen)
+{
+ raw_class_t *this = (raw_class_t *) this_gen;
+ free (this);
+}
+
+
+
+static void *raw_init_class (xine_t *xine, void *visual_gen)
+{
+ raw_class_t *this = (raw_class_t *) calloc(1, sizeof(raw_class_t));
+
+ this->driver_class.open_plugin = raw_open_plugin;
+ this->driver_class.get_identifier = raw_get_identifier;
+ this->driver_class.get_description = raw_get_description;
+ this->driver_class.dispose = raw_dispose_class;
+ this->xine = xine;
+
+ return this;
+}
+
+
+
+static const vo_info_t vo_info_raw = {
+ 7, /* priority */
+ XINE_VISUAL_TYPE_RAW /* visual type */
+};
+
+
+/*
+ * exported plugin catalog entry
+ */
+
+const plugin_info_t xine_plugin_info[] EXPORTED = {
+ /* type, API, "name", version, special_info, init_function */
+ { PLUGIN_VIDEO_OUT, 21, "raw", XINE_VERSION_CODE, &vo_info_raw, raw_init_class },
+ { PLUGIN_NONE, 0, "", 0, NULL, NULL }
+};
diff --git a/src/video_out/video_out_sdl.c b/src/video_out/video_out_sdl.c
index 6705b4176..89150f5d0 100644
--- a/src/video_out/video_out_sdl.c
+++ b/src/video_out/video_out_sdl.c
@@ -138,7 +138,7 @@ static vo_frame_t *sdl_alloc_frame (vo_driver_t *this_gen) {
/* sdl_driver_t *this = (sdl_driver_t *) this_gen; */
sdl_frame_t *frame ;
- frame = (sdl_frame_t *) xine_xmalloc (sizeof (sdl_frame_t));
+ frame = (sdl_frame_t *) calloc(1, sizeof(sdl_frame_t));
if (!frame)
return NULL;
@@ -469,13 +469,15 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi
sdl_driver_t *this;
const SDL_VideoInfo *vidInfo;
-#ifdef HAVE_X11
+#if defined(HAVE_X11) || defined(WIN32)
static char SDL_windowhack[32];
x11_visual_t *visual = (x11_visual_t *) visual_gen;
+#endif
+#ifdef HAVE_X11
XWindowAttributes window_attributes;
#endif
- this = (sdl_driver_t *) xine_xmalloc (sizeof (sdl_driver_t));
+ this = (sdl_driver_t *) calloc(1, sizeof(sdl_driver_t));
if (!this)
return NULL;
@@ -502,14 +504,18 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi
_x_vo_scale_init( &this->sc, 0, 0, config);
this->sc.frame_output_cb = visual->frame_output_cb;
this->sc.user_data = visual->user_data;
-
- /* set SDL to use our existing X11 window */
- sprintf(SDL_windowhack,"SDL_WINDOWID=0x%x", (uint32_t) this->drawable );
- putenv(SDL_windowhack);
#else
_x_vo_scale_init( &this->sc, 0, 0, config );
#endif
+#if defined(HAVE_X11) || defined(WIN32)
+ /* set SDL to use our existing X11/win32 window */
+ if (visual->d){
+ sprintf(SDL_windowhack,"SDL_WINDOWID=0x%x", (uint32_t) visual->d);
+ putenv(SDL_windowhack);
+ }
+#endif
+
if ((SDL_Init (SDL_INIT_VIDEO)) < 0) {
xprintf (this->xine, XINE_VERBOSITY_DEBUG, "video_out_sdl: open_plugin - sdl video initialization failed.\n");
return NULL;
@@ -596,7 +602,7 @@ static void *init_class (xine_t *xine, void *visual_gen) {
}
SDL_QuitSubSystem (SDL_INIT_VIDEO);
- this = (sdl_class_t*) xine_xmalloc (sizeof (sdl_class_t));
+ this = (sdl_class_t*) calloc(1, sizeof(sdl_class_t));
this->driver_class.open_plugin = open_plugin;
this->driver_class.get_identifier = get_identifier;
diff --git a/src/video_out/video_out_stk.c b/src/video_out/video_out_stk.c
index dfc4ae385..00dd80251 100644
--- a/src/video_out/video_out_stk.c
+++ b/src/video_out/video_out_stk.c
@@ -133,7 +133,7 @@ static vo_frame_t *stk_alloc_frame(vo_driver_t *this_gen) {
stk_frame_t* frame;
//printf("video_out_stk: alloc_frame()\n");
- frame = (stk_frame_t *) xine_xmalloc(sizeof(stk_frame_t));
+ frame = calloc(1, sizeof(stk_frame_t));
if (!frame)
return NULL;
@@ -389,7 +389,7 @@ static vo_driver_t *open_plugin(video_driver_class_t *class_gen, const void *vis
//printf("video_out_stk: open_plugin()\n");
- this = (stk_driver_t *) xine_xmalloc (sizeof (stk_driver_t));
+ this = calloc(1, sizeof (stk_driver_t));
if (!this)
return NULL;
@@ -463,7 +463,7 @@ static void *init_class (xine_t *xine, void *visual_gen) {
//printf("video_out_stk: init_class()\n");
- this = (stk_class_t *) xine_xmalloc(sizeof(stk_class_t));
+ this = calloc(1, sizeof(stk_class_t));
this->driver_class.open_plugin = open_plugin;
this->driver_class.get_identifier = get_identifier;
diff --git a/src/video_out/video_out_syncfb.c b/src/video_out/video_out_syncfb.c
index b1fadbd58..f66817f36 100644
--- a/src/video_out/video_out_syncfb.c
+++ b/src/video_out/video_out_syncfb.c
@@ -478,7 +478,7 @@ static vo_frame_t* syncfb_alloc_frame(vo_driver_t* this_gen)
/* syncfb_driver_t *this = (syncfb_driver_t *) this_gen; */
syncfb_frame_t *frame;
- frame = (syncfb_frame_t *) xine_xmalloc(sizeof(syncfb_frame_t));
+ frame = calloc(1, sizeof(syncfb_frame_t));
if(!frame)
return NULL;
@@ -882,7 +882,7 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi
display = visual->display;
- if(!(this = xine_xmalloc(sizeof (syncfb_driver_t))))
+ if(!(this = calloc(1, sizeof (syncfb_driver_t))))
return NULL;
_x_alphablend_init(&this->alphablend_extra_data, class->xine);
@@ -1105,7 +1105,7 @@ static void *init_class (xine_t *xine, void *visual_gen) {
/*
* from this point on, nothing should go wrong anymore
*/
- this = (syncfb_class_t *) xine_xmalloc (sizeof (syncfb_class_t));
+ this = calloc(1, sizeof (syncfb_class_t));
this->driver_class.open_plugin = open_plugin;
this->driver_class.get_identifier = get_identifier;
diff --git a/src/video_out/video_out_vidix.c b/src/video_out/video_out_vidix.c
index 9e3f870b1..482841a09 100644
--- a/src/video_out/video_out_vidix.c
+++ b/src/video_out/video_out_vidix.c
@@ -370,7 +370,7 @@ static vo_frame_t *vidix_alloc_frame (vo_driver_t *this_gen) {
/* vidix_driver_t *this = (vidix_driver_t *) this_gen; */
vidix_frame_t *frame ;
- frame = (vidix_frame_t *) xine_xmalloc (sizeof (vidix_frame_t));
+ frame = (vidix_frame_t *) calloc(1, sizeof(vidix_frame_t));
if (!frame)
return NULL;
@@ -947,7 +947,7 @@ static vidix_driver_t *open_plugin (video_driver_class_t *class_gen) {
vidix_driver_t *this;
int err;
- this = (vidix_driver_t *) xine_xmalloc (sizeof (vidix_driver_t));
+ this = (vidix_driver_t *) calloc(1, sizeof(vidix_driver_t));
if (!this)
return NULL;
@@ -1089,7 +1089,7 @@ static void *init_class (xine_t *xine, void *visual_gen) {
vidix_class_t *this;
int err;
- this = (vidix_class_t *) xine_xmalloc (sizeof (vidix_class_t));
+ this = (vidix_class_t *) calloc(1, sizeof(vidix_class_t));
if (!this)
return NULL;
diff --git a/src/video_out/video_out_xcbshm.c b/src/video_out/video_out_xcbshm.c
index 2ac579555..a5282a24f 100644
--- a/src/video_out/video_out_xcbshm.c
+++ b/src/video_out/video_out_xcbshm.c
@@ -295,7 +295,7 @@ static vo_frame_t *xshm_alloc_frame (vo_driver_t *this_gen) {
xshm_frame_t *frame;
xshm_driver_t *this = (xshm_driver_t *) this_gen;
- frame = (xshm_frame_t *) xine_xmalloc (sizeof (xshm_frame_t));
+ frame = (xshm_frame_t *) calloc(1, sizeof(xshm_frame_t));
if (!frame)
return NULL;
@@ -1015,7 +1015,7 @@ static vo_driver_t *xshm_open_plugin(video_driver_class_t *class_gen, const void
const xcb_query_extension_reply_t *query_extension_reply;
- this = (xshm_driver_t *) xine_xmalloc (sizeof (xshm_driver_t));
+ this = (xshm_driver_t *) calloc(1, sizeof(xshm_driver_t));
if (!this)
return NULL;
@@ -1250,7 +1250,7 @@ static void xshm_dispose_class (video_driver_class_t *this_gen) {
}
static void *xshm_init_class (xine_t *xine, void *visual_gen) {
- xshm_class_t *this = (xshm_class_t *) xine_xmalloc (sizeof (xshm_class_t));
+ xshm_class_t *this = (xshm_class_t *) calloc(1, sizeof(xshm_class_t));
this->driver_class.open_plugin = xshm_open_plugin;
this->driver_class.get_identifier = xshm_get_identifier;
diff --git a/src/video_out/video_out_xcbxv.c b/src/video_out/video_out_xcbxv.c
index 18ab5c6fb..1e6e2b663 100644
--- a/src/video_out/video_out_xcbxv.c
+++ b/src/video_out/video_out_xcbxv.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2004, 2007 the xine project
+ * Copyright (C) 2000-2004, 2007-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -65,6 +65,7 @@
#include "xineutils.h"
#include "vo_scale.h"
#include "xcbosd.h"
+#include "xv_common.h"
typedef struct xv_driver_s xv_driver_t;
@@ -137,6 +138,8 @@ struct xv_driver_s {
int use_colorkey;
uint32_t colorkey;
+ int sync_is_vsync;
+
/* hold initial port attributes values to restore on exit */
xine_list_t *port_attributes;
@@ -155,6 +158,10 @@ typedef struct {
xine_t *xine;
} xv_class_t;
+VIDEO_DEVICE_XV_DECL_BICUBIC_TYPES;
+VIDEO_DEVICE_XV_DECL_PREFER_TYPES;
+VIDEO_DEVICE_XV_DECL_SYNC_ATOMS;
+
static uint32_t xv_get_capabilities (vo_driver_t *this_gen) {
xv_driver_t *this = (xv_driver_t *) this_gen;
@@ -186,7 +193,7 @@ static vo_frame_t *xv_alloc_frame (vo_driver_t *this_gen) {
/* xv_driver_t *this = (xv_driver_t *) this_gen; */
xv_frame_t *frame ;
- frame = (xv_frame_t *) xine_xmalloc (sizeof (xv_frame_t));
+ frame = (xv_frame_t *) calloc(1, sizeof(xv_frame_t));
if (!frame)
return NULL;
@@ -432,7 +439,7 @@ static void xv_deinterlace_frame (xv_driver_t *this) {
for( i = 0; i < VO_NUM_RECENT_FRAMES; i++ )
if( this->recent_frames[i] && this->recent_frames[i]->width == frame->width &&
this->recent_frames[i]->height == frame->height )
- recent_bitmaps[i] = this->recent_frames[i]->image + frame->width*frame->height;
+ recent_bitmaps[i] = this->recent_frames[i]->image + this->deinterlace_frame.xv_width*frame->height;
else
recent_bitmaps[i] = NULL;
@@ -1101,6 +1108,8 @@ static int xv_check_yv12(xcb_connection_t *connection, xcb_xv_port_t port) {
list_formats_cookie = xcb_xv_list_image_formats(connection, port);
list_formats_reply = xcb_xv_list_image_formats_reply(connection, list_formats_cookie, NULL);
+ if (!list_formats_reply)
+ return 1; /* no formats listed; probably due to an invalid port no. */
format_it = xcb_xv_list_image_formats_format_iterator(list_formats_reply);
for (; format_it.rem; xcb_xv_image_format_info_next(&format_it))
@@ -1122,7 +1131,7 @@ static void xv_check_capability (xv_driver_t *this,
char *config_help) {
int int_default;
cfg_entry_t *entry;
- char *str_prop = xcb_xv_attribute_info_name(attr);
+ const char *str_prop = xcb_xv_attribute_info_name(attr);
xcb_xv_get_port_attribute_cookie_t get_attribute_cookie;
xcb_xv_get_port_attribute_reply_t *get_attribute_reply;
@@ -1207,44 +1216,42 @@ static void xv_update_deinterlace(void *this_gen, xine_cfg_entry_t *entry) {
this->deinterlace_method = entry->num_value;
}
-static void xv_update_XV_FILTER(void *this_gen, xine_cfg_entry_t *entry) {
+static void xv_update_attr (void *this_gen, xine_cfg_entry_t *entry,
+ const char *atomstr, const char *debugstr)
+{
xv_driver_t *this = (xv_driver_t *) this_gen;
- int xv_filter;
xcb_intern_atom_cookie_t atom_cookie;
xcb_intern_atom_reply_t *atom_reply;
- xv_filter = entry->num_value;
-
pthread_mutex_lock(&this->main_mutex);
- atom_cookie = xcb_intern_atom(this->connection, 0, sizeof("XV_FILTER"), "XV_FILTER");
+ atom_cookie = xcb_intern_atom(this->connection, 0, strlen (atomstr), atomstr);
atom_reply = xcb_intern_atom_reply(this->connection, atom_cookie, NULL);
- xcb_xv_set_port_attribute(this->connection, this->xv_port, atom_reply->atom, xv_filter);
+ xcb_xv_set_port_attribute(this->connection, this->xv_port, atom_reply->atom, entry->num_value);
free(atom_reply);
pthread_mutex_unlock(&this->main_mutex);
xprintf(this->xine, XINE_VERBOSITY_DEBUG,
- "video_out_xcbxv: bilinear scaling mode (XV_FILTER) = %d\n",xv_filter);
+ LOG_MODULE ": %s = %d\n", debugstr, entry->num_value);
}
-static void xv_update_XV_DOUBLE_BUFFER(void *this_gen, xine_cfg_entry_t *entry) {
- xv_driver_t *this = (xv_driver_t *) this_gen;
- int xv_double_buffer;
-
- xcb_intern_atom_cookie_t atom_cookie;
- xcb_intern_atom_reply_t *atom_reply;
+static void xv_update_XV_FILTER(void *this_gen, xine_cfg_entry_t *entry) {
+ xv_update_attr (this_gen, entry, "XV_FILTER", "bilinear scaling mode");
+}
- xv_double_buffer = entry->num_value;
+static void xv_update_XV_DOUBLE_BUFFER(void *this_gen, xine_cfg_entry_t *entry) {
+ xv_update_attr (this_gen, entry, "XV_DOUBLE_BUFFER", "double buffering mode");
+}
- pthread_mutex_lock(&this->main_mutex);
- atom_cookie = xcb_intern_atom(this->connection, 0, sizeof("XV_DOUBLE_BUFFER"), "XV_DOUBLE_BUFFER");
- atom_reply = xcb_intern_atom_reply(this->connection, atom_cookie, NULL);
- xcb_xv_set_port_attribute(this->connection, this->xv_port, atom_reply->atom, xv_double_buffer);
- free(atom_reply);
- pthread_mutex_unlock(&this->main_mutex);
+static void xv_update_XV_SYNC_TO_VBLANK(void *this_gen, xine_cfg_entry_t *entry) {
+ xv_update_attr (this_gen, entry,
+ sync_atoms[((xv_driver_t *)this_gen)->sync_is_vsync],
+ "sync to vblank");
+}
- xprintf(this->xine, XINE_VERBOSITY_DEBUG,
- "video_out_xcbxv: double buffering mode = %d\n", xv_double_buffer);
+static void xv_update_XV_BICUBIC(void *this_gen, xine_cfg_entry_t *entry)
+{
+ xv_update_attr (this_gen, entry, "XV_BICUBIC", "bicubic filtering mode");
}
static void xv_update_xv_pitch_alignment(void *this_gen, xine_cfg_entry_t *entry) {
@@ -1253,14 +1260,65 @@ static void xv_update_xv_pitch_alignment(void *this_gen, xine_cfg_entry_t *entry
this->use_pitch_alignment = entry->num_value;
}
+static xcb_xv_port_t xv_open_port (xv_driver_t *this, xcb_xv_port_t port) {
+ xcb_xv_grab_port_cookie_t grab_port_cookie;
+ xcb_xv_grab_port_reply_t *grab_port_reply;
+
+ if (xv_check_yv12 (this->connection, port))
+ return 0;
+
+ grab_port_cookie = xcb_xv_grab_port (this->connection, port, XCB_CURRENT_TIME);
+ grab_port_reply = xcb_xv_grab_port_reply (this->connection, grab_port_cookie, NULL);
+
+ if (grab_port_reply && (grab_port_reply->result == XCB_GRAB_STATUS_SUCCESS))
+ {
+ free (grab_port_reply);
+ return port;
+ }
+ free (grab_port_reply);
+ return 0;
+}
+
+static xcb_xv_adaptor_info_iterator_t *
+xv_find_adaptor_by_port (int port, xcb_xv_adaptor_info_iterator_t *adaptor_it)
+{
+ for (; adaptor_it->rem; xcb_xv_adaptor_info_next(adaptor_it))
+ if (adaptor_it->data->type & XCB_XV_TYPE_IMAGE_MASK)
+ if (port >= adaptor_it->data->base_id &&
+ port < adaptor_it->data->base_id + adaptor_it->data->num_ports)
+ return adaptor_it;
+ return NULL; /* shouldn't happen */
+}
+
+static xcb_xv_port_t xv_autodetect_port(xv_driver_t *this,
+ xcb_xv_adaptor_info_iterator_t *adaptor_it,
+ xcb_xv_port_t base,
+ xv_prefertype prefer_type)
+{
+ for (; adaptor_it->rem; xcb_xv_adaptor_info_next(adaptor_it))
+ if (adaptor_it->data->type & XCB_XV_TYPE_IMAGE_MASK &&
+ (prefer_type == xv_prefer_none ||
+ strcasestr (xcb_xv_adaptor_info_name (adaptor_it->data), prefer_substrings[prefer_type])))
+ {
+ int j;
+ for (j = 0; j < adaptor_it->data->num_ports; ++j)
+ {
+ xcb_xv_port_t port = adaptor_it->data->base_id + j;
+ if (port >= base && xv_open_port (this, port))
+ return port;
+ }
+ }
+ return 0;
+}
+
static vo_driver_t *open_plugin(video_driver_class_t *class_gen, const void *visual_gen) {
xv_class_t *class = (xv_class_t *) class_gen;
config_values_t *config = class->config;
xv_driver_t *this;
int i;
xcb_visual_t *visual = (xcb_visual_t *) visual_gen;
- unsigned int j;
xcb_xv_port_t xv_port;
+ xv_prefertype prefer_type;
const xcb_query_extension_reply_t *query_extension_reply;
@@ -1271,10 +1329,10 @@ static vo_driver_t *open_plugin(video_driver_class_t *class_gen, const void *vis
xcb_xv_list_image_formats_cookie_t list_formats_cookie;
xcb_xv_list_image_formats_reply_t *list_formats_reply;
- xcb_xv_adaptor_info_iterator_t adaptor_it;
+ xcb_xv_adaptor_info_iterator_t adaptor_it, adaptor_first;
xcb_xv_image_format_info_iterator_t format_it;
- this = (xv_driver_t *) xine_xmalloc (sizeof (xv_driver_t));
+ this = (xv_driver_t *) calloc(1, sizeof(xv_driver_t));
if (!this)
return NULL;
@@ -1309,28 +1367,37 @@ static vo_driver_t *open_plugin(video_driver_class_t *class_gen, const void *vis
return NULL;
}
- adaptor_it = xcb_xv_query_adaptors_info_iterator(query_adaptors_reply);
-
- xv_port = 0;
-
- for (; adaptor_it.rem && !xv_port; xcb_xv_adaptor_info_next(&adaptor_it)) {
-
- if (adaptor_it.data->type & XCB_XV_TYPE_IMAGE_MASK) {
-
- for (j = 0; j < adaptor_it.data->num_ports; j++)
- if (!xv_check_yv12(this->connection, adaptor_it.data->base_id + j)) {
- xcb_xv_grab_port_cookie_t grab_port_cookie;
- xcb_xv_grab_port_reply_t *grab_port_reply;
- grab_port_cookie = xcb_xv_grab_port(this->connection, adaptor_it.data->base_id + j, XCB_CURRENT_TIME);
- grab_port_reply = xcb_xv_grab_port_reply(this->connection, grab_port_cookie, NULL);
- if (grab_port_reply && (grab_port_reply->result == XCB_GRAB_STATUS_SUCCESS)) {
- free(grab_port_reply);
- xv_port = adaptor_it.data->base_id + j;
- break;
- }
- free(grab_port_reply);
- }
- }
+ adaptor_first = xcb_xv_query_adaptors_info_iterator(query_adaptors_reply);
+ xv_port = config->register_num (config, "video.device.xv_port", 0,
+ VIDEO_DEVICE_XV_PORT_HELP,
+ 20, NULL, NULL);
+ prefer_type = config->register_enum (config, "video.device.xv_preferred_method", 0,
+ prefer_labels, VIDEO_DEVICE_XV_PREFER_TYPE_HELP,
+ 10, NULL, NULL);
+
+ if (xv_port != 0) {
+ if (! xv_open_port(this, xv_port)) {
+ xprintf(class->xine, XINE_VERBOSITY_NONE,
+ _("%s: could not open Xv port %d - autodetecting\n"),
+ LOG_MODULE, xv_port);
+ adaptor_it = adaptor_first;
+ xv_port = xv_autodetect_port (this, &adaptor_it, xv_port, prefer_type);
+ } else
+ xv_find_adaptor_by_port (xv_port, &adaptor_it);
+ }
+ if (!xv_port)
+ {
+ adaptor_it = adaptor_first;
+ xv_port = xv_autodetect_port (this, &adaptor_it, 0, prefer_type);
+ }
+ if (!xv_port)
+ {
+ if (prefer_type)
+ xprintf(class->xine, XINE_VERBOSITY_NONE,
+ _("%s: no available ports of type \"%s\", defaulting...\n"),
+ LOG_MODULE, prefer_labels[prefer_type]);
+ adaptor_it = adaptor_first;
+ xv_port = xv_autodetect_port (this, &adaptor_it, 0, xv_prefer_none);
}
if (!xv_port) {
@@ -1411,10 +1478,11 @@ static vo_driver_t *open_plugin(video_driver_class_t *class_gen, const void *vis
for (; attribute_it.rem; xcb_xv_attribute_info_next(&attribute_it)) {
if ((attribute_it.data->flags & XCB_XV_ATTRIBUTE_FLAG_SETTABLE) && (attribute_it.data->flags & XCB_XV_ATTRIBUTE_FLAG_GETTABLE)) {
+ const char *const name = xcb_xv_attribute_info_name(attribute_it.data);
/* store initial port attribute value */
- xv_store_port_attribute(this, xcb_xv_attribute_info_name(attribute_it.data));
-
- if(!strcmp(xcb_xv_attribute_info_name(attribute_it.data), "XV_HUE")) {
+ xv_store_port_attribute(this, name);
+
+ if(!strcmp(name, "XV_HUE")) {
if (!strncmp(xcb_xv_adaptor_info_name(adaptor_it.data), "NV", 2)) {
xprintf (this->xine, XINE_VERBOSITY_NONE, "video_out_xcbxv: ignoring broken XV_HUE settings on NVidia cards\n");
} else {
@@ -1422,64 +1490,61 @@ static vo_driver_t *open_plugin(video_driver_class_t *class_gen, const void *vis
adaptor_it.data->base_id,
NULL, NULL, NULL);
}
- } else if(!strcmp(xcb_xv_attribute_info_name(attribute_it.data), "XV_SATURATION")) {
+ } else if(!strcmp(name, "XV_SATURATION")) {
xv_check_capability (this, VO_PROP_SATURATION, attribute_it.data,
adaptor_it.data->base_id,
NULL, NULL, NULL);
-
- } else if(!strcmp(xcb_xv_attribute_info_name(attribute_it.data), "XV_BRIGHTNESS")) {
+ } else if(!strcmp(name, "XV_BRIGHTNESS")) {
xv_check_capability (this, VO_PROP_BRIGHTNESS, attribute_it.data,
adaptor_it.data->base_id,
NULL, NULL, NULL);
-
- } else if(!strcmp(xcb_xv_attribute_info_name(attribute_it.data), "XV_CONTRAST")) {
+ } else if(!strcmp(name, "XV_CONTRAST")) {
xv_check_capability (this, VO_PROP_CONTRAST, attribute_it.data,
adaptor_it.data->base_id,
NULL, NULL, NULL);
-
- } else if(!strcmp(xcb_xv_attribute_info_name(attribute_it.data), "XV_COLORKEY")) {
+ } else if(!strcmp(name, "XV_COLORKEY")) {
xv_check_capability (this, VO_PROP_COLORKEY, attribute_it.data,
adaptor_it.data->base_id,
"video.device.xv_colorkey",
- _("video overlay colour key"),
- _("The colour key is used to tell the graphics card where to "
- "overlay the video image. Try different values, if you experience "
- "windows becoming transparent."));
-
- } else if(!strcmp(xcb_xv_attribute_info_name(attribute_it.data), "XV_AUTOPAINT_COLORKEY")) {
+ VIDEO_DEVICE_XV_COLORKEY_HELP);
+ } else if(!strcmp(name, "XV_AUTOPAINT_COLORKEY")) {
xv_check_capability (this, VO_PROP_AUTOPAINT_COLORKEY, attribute_it.data,
adaptor_it.data->base_id,
"video.device.xv_autopaint_colorkey",
- _("autopaint colour key"),
- _("Make Xv autopaint its colour key."));
-
- } else if(!strcmp(xcb_xv_attribute_info_name(attribute_it.data), "XV_FILTER")) {
+ VIDEO_DEVICE_XV_AUTOPAINT_COLORKEY_HELP);
+ } else if(!strcmp(name, "XV_FILTER")) {
int xv_filter;
/* This setting is specific to Permedia 2/3 cards. */
xv_filter = config->register_range (config, "video.device.xv_filter", 0,
attribute_it.data->min, attribute_it.data->max,
- _("bilinear scaling mode"),
- _("Selects the bilinear scaling mode for Permedia cards. "
- "The individual values are:\n\n"
- "Permedia 2\n"
- "0 - disable bilinear filtering\n"
- "1 - enable bilinear filtering\n\n"
- "Permedia 3\n"
- "0 - disable bilinear filtering\n"
- "1 - horizontal linear filtering\n"
- "2 - enable full bilinear filtering"),
+ VIDEO_DEVICE_XV_FILTER_HELP,
20, xv_update_XV_FILTER, this);
config->update_num(config,"video.device.xv_filter",xv_filter);
- } else if(!strcmp(xcb_xv_attribute_info_name(attribute_it.data), "XV_DOUBLE_BUFFER")) {
- int xv_double_buffer;
- xv_double_buffer =
+ } else if(!strcmp(name, "XV_DOUBLE_BUFFER")) {
+ int xv_double_buffer =
config->register_bool (config, "video.device.xv_double_buffer", 1,
- _("enable double buffering"),
- _("Double buffering will synchronize the update of the video image to the "
- "repainting of the entire screen (\"vertical retrace\"). This eliminates "
- "flickering and tearing artifacts, but will use more graphics memory."),
- 20, xv_update_XV_DOUBLE_BUFFER, this);
+ VIDEO_DEVICE_XV_DOUBLE_BUFFER_HELP,
+ 20, xv_update_XV_DOUBLE_BUFFER, this);
config->update_num(config,"video.device.xv_double_buffer",xv_double_buffer);
+ } else if(!strcmp(name, sync_atoms[this->sync_is_vsync = 0]) ||
+ !strcmp(name, sync_atoms[this->sync_is_vsync = 1])) {
+ int xv_sync_to_vblank;
+ xv_sync_to_vblank =
+ config->register_bool (config, "video.device.xv_sync_to_vblank", 1,
+ _("enable vblank sync"),
+ _("This option will synchronize the update of the video image to the "
+ "repainting of the entire screen (\"vertical retrace\"). This eliminates "
+ "flickering and tearing artifacts. On nvidia cards one may also "
+ "need to run \"nvidia-settings\" and choose which display device to "
+ "sync to under the XVideo Settings tab"),
+ 20, xv_update_XV_SYNC_TO_VBLANK, this);
+ config->update_num(config,"video.device.xv_sync_to_vblank",xv_sync_to_vblank);
+ } else if(!strcmp(name, "XV_BICUBIC")) {
+ int xv_bicubic =
+ config->register_enum (config, "video.device.xv_bicubic", 2,
+ bicubic_types, VIDEO_DEVICE_XV_BICUBIC_HELP,
+ 20, xv_update_XV_BICUBIC, this);
+ config->update_num(config,"video.device.xv_bicubic",xv_bicubic);
}
}
}
@@ -1524,8 +1589,7 @@ static vo_driver_t *open_plugin(video_driver_class_t *class_gen, const void *vis
this->use_pitch_alignment =
config->register_bool (config, "video.device.xv_pitch_alignment", 0,
- _("pitch alignment workaround"),
- _("Some buggy video drivers need a workaround to function properly."),
+ VIDEO_DEVICE_XV_PITCH_ALIGNMENT_HELP,
10, xv_update_xv_pitch_alignment, this);
this->deinterlace_method =
@@ -1596,7 +1660,7 @@ static void dispose_class (video_driver_class_t *this_gen) {
}
static void *init_class (xine_t *xine, void *visual_gen) {
- xv_class_t *this = (xv_class_t *) xine_xmalloc (sizeof (xv_class_t));
+ xv_class_t *this = (xv_class_t *) calloc(1, sizeof(xv_class_t));
this->driver_class.open_plugin = open_plugin;
this->driver_class.get_identifier = get_identifier;
diff --git a/src/video_out/video_out_xshm.c b/src/video_out/video_out_xshm.c
index 9e901821a..74791f145 100644
--- a/src/video_out/video_out_xshm.c
+++ b/src/video_out/video_out_xshm.c
@@ -276,7 +276,7 @@ static XImage *create_ximage (xshm_driver_t *this, XShmSegmentInfo *shminfo,
this->bytes_per_pixel = this->bpp / 8;
this->image_byte_order = myimage->byte_order;
- myimage->data = xine_xmalloc (width * this->bytes_per_pixel * height);
+ myimage->data = calloc (width * height, this->bytes_per_pixel);
}
return myimage;
@@ -387,7 +387,7 @@ static vo_frame_t *xshm_alloc_frame (vo_driver_t *this_gen) {
xshm_frame_t *frame;
xshm_driver_t *this = (xshm_driver_t *) this_gen;
- frame = (xshm_frame_t *) xine_xmalloc (sizeof (xshm_frame_t));
+ frame = (xshm_frame_t *) calloc(1, sizeof(xshm_frame_t));
if (!frame)
return NULL;
@@ -1083,7 +1083,7 @@ static vo_driver_t *xshm_open_plugin_2 (video_driver_class_t *class_gen, const v
int cpu_byte_order;
XColor dummy;
- this = (xshm_driver_t *) xine_xmalloc (sizeof (xshm_driver_t));
+ this = (xshm_driver_t *) calloc(1, sizeof(xshm_driver_t));
if (!this)
return NULL;
@@ -1310,7 +1310,7 @@ static void xshm_dispose_class (video_driver_class_t *this_gen) {
}
static void *xshm_init_class (xine_t *xine, void *visual_gen) {
- xshm_class_t *this = (xshm_class_t *) xine_xmalloc (sizeof (xshm_class_t));
+ xshm_class_t *this = (xshm_class_t *) calloc(1, sizeof(xshm_class_t));
this->driver_class.open_plugin = xshm_open_plugin_old;
this->driver_class.get_identifier = xshm_get_identifier;
diff --git a/src/video_out/video_out_xv.c b/src/video_out/video_out_xv.c
index 3bb0a93dc..f2c47ef7e 100644
--- a/src/video_out/video_out_xv.c
+++ b/src/video_out/video_out_xv.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2004 the xine project
+ * Copyright (C) 2000-2004, 2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -70,6 +70,7 @@
#include "xineutils.h"
#include "vo_scale.h"
#include "x11osd.h"
+#include "xv_common.h"
#define LOCK_DISPLAY(this) {if(this->lock_display) this->lock_display(this->user_data); \
else XLockDisplay(this->display);}
@@ -142,6 +143,8 @@ struct xv_driver_s {
int use_colorkey;
uint32_t colorkey;
+ int sync_is_vsync;
+
/* hold initial port attributes values to restore on exit */
xine_list_t *port_attributes;
@@ -168,6 +171,10 @@ typedef struct {
static int gX11Fail;
+VIDEO_DEVICE_XV_DECL_BICUBIC_TYPES;
+VIDEO_DEVICE_XV_DECL_PREFER_TYPES;
+VIDEO_DEVICE_XV_DECL_SYNC_ATOMS;
+
static uint32_t xv_get_capabilities (vo_driver_t *this_gen) {
xv_driver_t *this = (xv_driver_t *) this_gen;
@@ -208,7 +215,7 @@ static vo_frame_t *xv_alloc_frame (vo_driver_t *this_gen) {
/* xv_driver_t *this = (xv_driver_t *) this_gen; */
xv_frame_t *frame ;
- frame = (xv_frame_t *) xine_xmalloc (sizeof (xv_frame_t));
+ frame = (xv_frame_t *) calloc(1, sizeof(xv_frame_t));
if (!frame)
return NULL;
@@ -521,7 +528,7 @@ static void xv_deinterlace_frame (xv_driver_t *this) {
for( i = 0; i < VO_NUM_RECENT_FRAMES; i++ )
if( this->recent_frames[i] && this->recent_frames[i]->width == frame->width &&
this->recent_frames[i]->height == frame->height )
- recent_bitmaps[i] = this->recent_frames[i]->image->data + frame->width*frame->height;
+ recent_bitmaps[i] = this->recent_frames[i]->image->data + this->deinterlace_frame.image->width*frame->height;
else
recent_bitmaps[i] = NULL;
@@ -851,8 +858,8 @@ static void xv_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) {
if( factor > 1 )
{
- lprintf( "%s PutImage %dX interval (%fs)\n",
- log_line_prefix(), factor, elapse_time );
+ lprintf( "%s PutImage %dX interval (%fs)\n",
+ LOG_MODULE, factor, elapse_time );
}
}
@@ -1090,7 +1097,7 @@ static int xv_gui_data_exchange (vo_driver_t *this_gen,
return 0;
}
-static void xv_store_port_attribute(xv_driver_t *this, char *name) {
+static void xv_store_port_attribute(xv_driver_t *this, const char *name) {
Atom atom;
xv_portattribute_t *attr;
@@ -1190,14 +1197,13 @@ static int xv_check_yv12 (Display *display, XvPortID port) {
/* called xlocked */
static void xv_check_capability (xv_driver_t *this,
- int property, XvAttribute attr,
- int base_id,
+ int property, XvAttribute attr, int base_id,
char *config_name,
char *config_desc,
char *config_help) {
int int_default;
cfg_entry_t *entry;
- char *str_prop = attr.name;
+ const char *str_prop = attr.name;
/*
* some Xv drivers (Gatos ATI) report some ~0 as max values, this is confusing.
@@ -1267,36 +1273,38 @@ static void xv_update_deinterlace(void *this_gen, xine_cfg_entry_t *entry) {
this->deinterlace_method = entry->num_value;
}
-static void xv_update_XV_FILTER(void *this_gen, xine_cfg_entry_t *entry) {
+static void xv_update_attr (void *this_gen, xine_cfg_entry_t *entry,
+ const char *atomstr, const char *debugstr)
+{
xv_driver_t *this = (xv_driver_t *) this_gen;
Atom atom;
- int xv_filter;
-
- xv_filter = entry->num_value;
LOCK_DISPLAY(this);
- atom = XInternAtom (this->display, "XV_FILTER", False);
- XvSetPortAttribute (this->display, this->xv_port, atom, xv_filter);
+ atom = XInternAtom (this->display, atomstr, False);
+ XvSetPortAttribute (this->display, this->xv_port, atom, entry->num_value);
UNLOCK_DISPLAY(this);
xprintf(this->xine, XINE_VERBOSITY_DEBUG,
- "video_out_xv: bilinear scaling mode (XV_FILTER) = %d\n",xv_filter);
+ LOG_MODULE ": %s = %d\n", debugstr, entry->num_value);
}
-static void xv_update_XV_DOUBLE_BUFFER(void *this_gen, xine_cfg_entry_t *entry) {
- xv_driver_t *this = (xv_driver_t *) this_gen;
- Atom atom;
- int xv_double_buffer;
+static void xv_update_XV_FILTER(void *this_gen, xine_cfg_entry_t *entry) {
+ xv_update_attr (this_gen, entry, "XV_FILTER", "bilinear scaling mode");
+}
- xv_double_buffer = entry->num_value;
+static void xv_update_XV_DOUBLE_BUFFER(void *this_gen, xine_cfg_entry_t *entry) {
+ xv_update_attr (this_gen, entry, "XV_DOUBLE_BUFFER", "double buffering mode");
+}
- LOCK_DISPLAY(this);
- atom = XInternAtom (this->display, "XV_DOUBLE_BUFFER", False);
- XvSetPortAttribute (this->display, this->xv_port, atom, xv_double_buffer);
- UNLOCK_DISPLAY(this);
+static void xv_update_XV_SYNC_TO_VBLANK(void *this_gen, xine_cfg_entry_t *entry) {
+ xv_update_attr (this_gen, entry,
+ sync_atoms[((xv_driver_t *)this_gen)->sync_is_vsync],
+ "sync to vblank");
+}
- xprintf(this->xine, XINE_VERBOSITY_DEBUG,
- "video_out_xv: double buffering mode = %d\n", xv_double_buffer);
+static void xv_update_XV_BICUBIC(void *this_gen, xine_cfg_entry_t *entry)
+{
+ xv_update_attr (this_gen, entry, "XV_BICUBIC", "bicubic filtering mode");
}
static void xv_update_xv_pitch_alignment(void *this_gen, xine_cfg_entry_t *entry) {
@@ -1305,6 +1313,52 @@ static void xv_update_xv_pitch_alignment(void *this_gen, xine_cfg_entry_t *entry
this->use_pitch_alignment = entry->num_value;
}
+static int xv_open_port (xv_driver_t *this, XvPortID port) {
+ int ret;
+ x11_InstallXErrorHandler (this);
+ ret = ! xv_check_yv12(this->display, port)
+ && XvGrabPort(this->display, port, 0) == Success;
+ x11_DeInstallXErrorHandler (this);
+ return ret;
+}
+
+static unsigned int
+xv_find_adaptor_by_port (int port, unsigned int adaptors,
+ XvAdaptorInfo *adaptor_info)
+{
+ unsigned int an;
+ for (an = 0; an < adaptors; an++)
+ if (adaptor_info[an].type & XvImageMask)
+ if (port >= adaptor_info[an].base_id &&
+ port < adaptor_info[an].base_id + adaptor_info[an].num_ports)
+ return an;
+ return 0; /* shouldn't happen */
+}
+
+static XvPortID xv_autodetect_port(xv_driver_t *this,
+ unsigned int adaptors,
+ XvAdaptorInfo *adaptor_info,
+ unsigned int *adaptor_num,
+ XvPortID base,
+ xv_prefertype prefer_type)
+{
+ unsigned int an, j;
+
+ for (an = 0; an < adaptors; an++)
+ if (adaptor_info[an].type & XvImageMask &&
+ (prefer_type == xv_prefer_none ||
+ strcasestr (adaptor_info[an].name, prefer_substrings[prefer_type])))
+ for (j = 0; j < adaptor_info[an].num_ports; j++) {
+ XvPortID port = adaptor_info[an].base_id + j;
+ if (port >= base && xv_open_port(this, port)) {
+ *adaptor_num = an;
+ return port;
+ }
+ }
+
+ return 0;
+}
+
/* expects XINE_VISUAL_TYPE_X11_2 with configurable locking */
static vo_driver_t *open_plugin_2 (video_driver_class_t *class_gen, const void *visual_gen) {
xv_class_t *class = (xv_class_t *) class_gen;
@@ -1317,14 +1371,15 @@ static vo_driver_t *open_plugin_2 (video_driver_class_t *class_gen, const void *
x11_visual_t *visual = (x11_visual_t *) visual_gen;
XColor dummy;
XvImage *myimage;
- unsigned int adaptors, j;
+ unsigned int adaptors;
unsigned int ver,rel,req,ev,err;
XShmSegmentInfo myshminfo;
XvPortID xv_port;
XvAdaptorInfo *adaptor_info;
unsigned int adaptor_num;
+ xv_prefertype prefer_type;
- this = (xv_driver_t *) xine_xmalloc (sizeof (xv_driver_t));
+ this = (xv_driver_t *) calloc(1, sizeof(xv_driver_t));
if (!this)
return NULL;
@@ -1360,24 +1415,31 @@ static vo_driver_t *open_plugin_2 (video_driver_class_t *class_gen, const void *
return NULL;
}
- xv_port = 0;
-
- for ( adaptor_num = 0; (adaptor_num < adaptors) && !xv_port; adaptor_num++ ) {
-
- if (adaptor_info[adaptor_num].type & XvImageMask) {
-
- for (j = 0; j < adaptor_info[adaptor_num].num_ports && !xv_port; j++)
- if (( !(xv_check_yv12 (this->display,
- adaptor_info[adaptor_num].base_id + j)))
- && (XvGrabPort (this->display,
- adaptor_info[adaptor_num].base_id + j,
- 0) == Success)) {
- xv_port = adaptor_info[adaptor_num].base_id + j;
- }
-
- if( xv_port )
- break;
- }
+ xv_port = config->register_num (config, "video.device.xv_port", 0,
+ VIDEO_DEVICE_XV_PORT_HELP,
+ 20, NULL, NULL);
+ prefer_type = config->register_enum (config, "video.device.xv_preferred_method", 0,
+ prefer_labels, VIDEO_DEVICE_XV_PREFER_TYPE_HELP,
+ 10, NULL, NULL);
+
+ if (xv_port != 0) {
+ if (! xv_open_port(this, xv_port)) {
+ xprintf(class->xine, XINE_VERBOSITY_NONE,
+ _("%s: could not open Xv port %"PRId32" - autodetecting\n"),
+ LOG_MODULE, xv_port);
+ xv_port = xv_autodetect_port(this, adaptors, adaptor_info, &adaptor_num, xv_port, prefer_type);
+ } else
+ adaptor_num = xv_find_adaptor_by_port (xv_port, adaptors, adaptor_info);
+ }
+ if (!xv_port)
+ xv_port = xv_autodetect_port(this, adaptors, adaptor_info, &adaptor_num, 0, prefer_type);
+ if (!xv_port)
+ {
+ if (prefer_type)
+ xprintf(class->xine, XINE_VERBOSITY_NONE,
+ _("%s: no available ports of type \"%s\", defaulting...\n"),
+ LOG_MODULE, prefer_labels[prefer_type]);
+ xv_port = xv_autodetect_port(this, adaptors, adaptor_info, &adaptor_num, 0, xv_prefer_none);
}
if (!xv_port) {
@@ -1469,10 +1531,11 @@ static vo_driver_t *open_plugin_2 (video_driver_class_t *class_gen, const void *
for(k = 0; k < nattr; k++) {
if((attr[k].flags & XvSettable) && (attr[k].flags & XvGettable)) {
+ const char *const name = attr[k].name;
/* store initial port attribute value */
- xv_store_port_attribute(this, attr[k].name);
+ xv_store_port_attribute(this, name);
- if(!strcmp(attr[k].name, "XV_HUE")) {
+ if(!strcmp(name, "XV_HUE")) {
if (!strncmp(adaptor_info[adaptor_num].name, "NV", 2)) {
xprintf (this->xine, XINE_VERBOSITY_NONE, "video_out_xv: ignoring broken XV_HUE settings on NVidia cards\n");
} else {
@@ -1480,64 +1543,61 @@ static vo_driver_t *open_plugin_2 (video_driver_class_t *class_gen, const void *
adaptor_info[adaptor_num].base_id,
NULL, NULL, NULL);
}
- } else if(!strcmp(attr[k].name, "XV_SATURATION")) {
+ } else if(!strcmp(name, "XV_SATURATION")) {
xv_check_capability (this, VO_PROP_SATURATION, attr[k],
adaptor_info[adaptor_num].base_id,
NULL, NULL, NULL);
-
- } else if(!strcmp(attr[k].name, "XV_BRIGHTNESS")) {
+ } else if(!strcmp(name, "XV_BRIGHTNESS")) {
xv_check_capability (this, VO_PROP_BRIGHTNESS, attr[k],
adaptor_info[adaptor_num].base_id,
NULL, NULL, NULL);
-
- } else if(!strcmp(attr[k].name, "XV_CONTRAST")) {
+ } else if(!strcmp(name, "XV_CONTRAST")) {
xv_check_capability (this, VO_PROP_CONTRAST, attr[k],
adaptor_info[adaptor_num].base_id,
NULL, NULL, NULL);
-
- } else if(!strcmp(attr[k].name, "XV_COLORKEY")) {
+ } else if(!strcmp(name, "XV_COLORKEY")) {
xv_check_capability (this, VO_PROP_COLORKEY, attr[k],
adaptor_info[adaptor_num].base_id,
"video.device.xv_colorkey",
- _("video overlay colour key"),
- _("The colour key is used to tell the graphics card where to "
- "overlay the video image. Try different values, if you experience "
- "windows becoming transparent."));
-
- } else if(!strcmp(attr[k].name, "XV_AUTOPAINT_COLORKEY")) {
+ VIDEO_DEVICE_XV_COLORKEY_HELP);
+ } else if(!strcmp(name, "XV_AUTOPAINT_COLORKEY")) {
xv_check_capability (this, VO_PROP_AUTOPAINT_COLORKEY, attr[k],
adaptor_info[adaptor_num].base_id,
"video.device.xv_autopaint_colorkey",
- _("autopaint colour key"),
- _("Make Xv autopaint its colour key."));
-
- } else if(!strcmp(attr[k].name, "XV_FILTER")) {
+ VIDEO_DEVICE_XV_AUTOPAINT_COLORKEY_HELP);
+ } else if(!strcmp(name, "XV_FILTER")) {
int xv_filter;
/* This setting is specific to Permedia 2/3 cards. */
xv_filter = config->register_range (config, "video.device.xv_filter", 0,
attr[k].min_value, attr[k].max_value,
- _("bilinear scaling mode"),
- _("Selects the bilinear scaling mode for Permedia cards. "
- "The individual values are:\n\n"
- "Permedia 2\n"
- "0 - disable bilinear filtering\n"
- "1 - enable bilinear filtering\n\n"
- "Permedia 3\n"
- "0 - disable bilinear filtering\n"
- "1 - horizontal linear filtering\n"
- "2 - enable full bilinear filtering"),
+ VIDEO_DEVICE_XV_FILTER_HELP,
20, xv_update_XV_FILTER, this);
config->update_num(config,"video.device.xv_filter",xv_filter);
- } else if(!strcmp(attr[k].name, "XV_DOUBLE_BUFFER")) {
- int xv_double_buffer;
- xv_double_buffer =
+ } else if(!strcmp(name, "XV_DOUBLE_BUFFER")) {
+ int xv_double_buffer =
config->register_bool (config, "video.device.xv_double_buffer", 1,
- _("enable double buffering"),
- _("Double buffering will synchronize the update of the video image to the "
- "repainting of the entire screen (\"vertical retrace\"). This eliminates "
- "flickering and tearing artifacts, but will use more graphics memory."),
- 20, xv_update_XV_DOUBLE_BUFFER, this);
+ VIDEO_DEVICE_XV_DOUBLE_BUFFER_HELP,
+ 20, xv_update_XV_DOUBLE_BUFFER, this);
config->update_num(config,"video.device.xv_double_buffer",xv_double_buffer);
+ } else if(((this->sync_is_vsync = 0), !strcmp(name, sync_atoms[0])) ||
+ ((this->sync_is_vsync = 1), !strcmp(name, sync_atoms[1]))) {
+ int xv_sync_to_vblank;
+ xv_sync_to_vblank =
+ config->register_bool (config, "video.device.xv_sync_to_vblank", 1,
+ _("enable vblank sync"),
+ _("This option will synchronize the update of the video image to the "
+ "repainting of the entire screen (\"vertical retrace\"). This eliminates "
+ "flickering and tearing artifacts. On nvidia cards one may also "
+ "need to run \"nvidia-settings\" and choose which display device to "
+ "sync to under the XVideo Settings tab"),
+ 20, xv_update_XV_SYNC_TO_VBLANK, this);
+ config->update_num(config,"video.device.xv_sync_to_vblank",xv_sync_to_vblank);
+ } else if(!strcmp(name, "XV_BICUBIC")) {
+ int xv_bicubic =
+ config->register_enum (config, "video.device.xv_bicubic", 2,
+ bicubic_types, VIDEO_DEVICE_XV_BICUBIC_HELP,
+ 20, xv_update_XV_BICUBIC, this);
+ config->update_num(config,"video.device.xv_bicubic",xv_bicubic);
}
}
}
@@ -1593,8 +1653,7 @@ static vo_driver_t *open_plugin_2 (video_driver_class_t *class_gen, const void *
this->use_pitch_alignment =
config->register_bool (config, "video.device.xv_pitch_alignment", 0,
- _("pitch alignment workaround"),
- _("Some buggy video drivers need a workaround to function properly."),
+ VIDEO_DEVICE_XV_PITCH_ALIGNMENT_HELP,
10, xv_update_xv_pitch_alignment, this);
this->deinterlace_method =
@@ -1684,7 +1743,7 @@ static void dispose_class (video_driver_class_t *this_gen) {
}
static void *init_class (xine_t *xine, void *visual_gen) {
- xv_class_t *this = (xv_class_t *) xine_xmalloc (sizeof (xv_class_t));
+ xv_class_t *this = (xv_class_t *) calloc(1, sizeof(xv_class_t));
this->driver_class.open_plugin = open_plugin_old;
this->driver_class.get_identifier = get_identifier;
diff --git a/src/video_out/video_out_xvmc.c b/src/video_out/video_out_xvmc.c
index a17e4d6a0..c2560ccc0 100644
--- a/src/video_out/video_out_xvmc.c
+++ b/src/video_out/video_out_xvmc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2004 the xine project
+ * Copyright (C) 2000-2004, 2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -75,6 +75,7 @@
#include "xineutils.h"
#include "vo_scale.h"
+#include "xv_common.h"
/* #define LOG1 */
/* #define DLOG */
@@ -225,8 +226,6 @@ typedef struct {
Display *display;
config_values_t *config;
XvPortID xv_port;
- XvAdaptorInfo *adaptor_info;
- unsigned int adaptor_num;
int surface_type_id;
unsigned int max_surface_width;
@@ -556,7 +555,7 @@ static vo_frame_t *xvmc_alloc_frame (vo_driver_t *this_gen) {
lprintf ("xvmc_alloc_frame\n");
- frame = (xvmc_frame_t *) xine_xmalloc (sizeof (xvmc_frame_t));
+ frame = calloc(1, sizeof (xvmc_frame_t));
if (!frame)
return NULL;
@@ -595,8 +594,8 @@ static cxid_t *xvmc_set_context (xvmc_driver_t *this,
/* initialize block & macro block pointers first time */
if(macroblocks->blocks == NULL || macroblocks->macro_blocks == NULL) {
- macroblocks->blocks = xine_xmalloc(sizeof(XvMCBlockArray));
- macroblocks->macro_blocks = xine_xmalloc(sizeof(XvMCMacroBlockArray));
+ macroblocks->blocks = calloc(1, sizeof(XvMCBlockArray));
+ macroblocks->macro_blocks = calloc(1, sizeof(XvMCMacroBlockArray));
lprintf("macroblocks->blocks %lx ->macro_blocks %lx\n",
macroblocks->blocks,macroblocks->macro_blocks);
@@ -700,6 +699,7 @@ static cxid_t *xvmc_set_context (xvmc_driver_t *this,
return NULL;
}
+#if 0
static XvImage *create_ximage (xvmc_driver_t *this, XShmSegmentInfo *shminfo,
int width, int height, int format) {
unsigned int xvmc_format;
@@ -755,6 +755,7 @@ static void dispose_ximage (xvmc_driver_t *this,
lprintf ("dispose_ximage\n");
XFree(myimage);
}
+#endif
static void xvmc_update_frame_format (vo_driver_t *this_gen,
vo_frame_t *frame_gen,
@@ -1252,13 +1253,13 @@ static void xvmc_dispose (vo_driver_t *this_gen) {
/* called xlocked */
static void xvmc_check_capability (xvmc_driver_t *this,
- int property, XvAttribute attr,
- int base_id, char *str_prop,
- char *config_name,
- char *config_desc,
- char *config_help) {
+ int property, XvAttribute attr, int base_id,
+ const char *config_name,
+ const char *config_desc,
+ const char *config_help) {
int int_default;
cfg_entry_t *entry;
+ const char *str_prop = attr.name;
/*
* some Xv drivers (Gatos ATI) report some ~0 as max values, this is confusing.
@@ -1281,13 +1282,13 @@ static void xvmc_check_capability (xvmc_driver_t *this,
if ((attr.min_value == 0) && (attr.max_value == 1)) {
this->config->register_bool (this->config, config_name, int_default,
config_desc,
- NULL, 20, xvmc_property_callback, &this->props[property]);
+ config_help, 20, xvmc_property_callback, &this->props[property]);
} else {
this->config->register_range (this->config, config_name, int_default,
this->props[property].min, this->props[property].max,
config_desc,
- NULL, 20, xvmc_property_callback, &this->props[property]);
+ config_help, 20, xvmc_property_callback, &this->props[property]);
}
entry = this->config->lookup_entry (this->config, config_name);
@@ -1333,7 +1334,6 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi
xvmc_class_t *class = (xvmc_class_t *) class_gen;
config_values_t *config = class->config;
xvmc_driver_t *this = NULL;
- Display *display = NULL;
unsigned int i, formats;
XvPortID xv_port = class->xv_port;
XvAttribute *attr;
@@ -1341,14 +1341,13 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi
int nattr;
x11_visual_t *visual = (x11_visual_t *) visual_gen;
XColor dummy;
+ XvAdaptorInfo *adaptor_info;
+ unsigned int adaptor_num;
/* XvImage *myimage; */
lprintf ("open_plugin\n");
- display = visual->display;
-
- /* TODO ??? */
- this = (xvmc_driver_t *) xine_xmalloc (sizeof (xvmc_driver_t));
+ this = calloc(1, sizeof (xvmc_driver_t));
if (!this)
return NULL;
@@ -1430,56 +1429,47 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi
this->capabilities |= VO_CAP_XVMC_IDCT;
XLockDisplay(this->display);
- attr = XvQueryPortAttributes(display, xv_port, &nattr);
+ attr = XvQueryPortAttributes(this->display, xv_port, &nattr);
if(attr && nattr) {
int k;
for(k = 0; k < nattr; k++) {
if((attr[k].flags & XvSettable) && (attr[k].flags & XvGettable)) {
- if(!strcmp(attr[k].name, "XV_HUE")) {
- xvmc_check_capability (this, VO_PROP_HUE, attr[k],
- class->adaptor_info[class->adaptor_num].base_id, "XV_HUE",
- NULL, NULL, NULL);
-
- } else if(!strcmp(attr[k].name, "XV_SATURATION")) {
+ const char *const name = attr[k].name;
+ if(!strcmp(name, "XV_HUE")) {
+ if (!strncmp(adaptor_info[adaptor_num].name, "NV", 2)) {
+ xprintf (this->xine, XINE_VERBOSITY_NONE, LOG_MODULE ": ignoring broken XV_HUE settings on NVidia cards\n");
+ } else {
+ xvmc_check_capability (this, VO_PROP_HUE, attr[k],
+ adaptor_info[adaptor_num].base_id,
+ NULL, NULL, NULL);
+ }
+ } else if(!strcmp(name, "XV_SATURATION")) {
xvmc_check_capability (this, VO_PROP_SATURATION, attr[k],
- class->adaptor_info[class->adaptor_num].base_id, "XV_SATURATION",
+ adaptor_info[adaptor_num].base_id,
NULL, NULL, NULL);
-
} else if(!strcmp(attr[k].name, "XV_BRIGHTNESS")) {
xvmc_check_capability (this, VO_PROP_BRIGHTNESS, attr[k],
- class->adaptor_info[class->adaptor_num].base_id, "XV_BRIGHTNESS",
+ adaptor_info[adaptor_num].base_id,
NULL, NULL, NULL);
-
- } else if(!strcmp(attr[k].name, "XV_CONTRAST")) {
+ } else if(!strcmp(name, "XV_CONTRAST")) {
xvmc_check_capability (this, VO_PROP_CONTRAST, attr[k],
- class->adaptor_info[class->adaptor_num].base_id, "XV_CONTRAST",
+ adaptor_info[adaptor_num].base_id,
NULL, NULL, NULL);
-
- } else if(!strcmp(attr[k].name, "XV_COLORKEY")) {
+ } else if(!strcmp(name, "XV_COLORKEY")) {
xvmc_check_capability (this, VO_PROP_COLORKEY, attr[k],
- class->adaptor_info[class->adaptor_num].base_id, "XV_COLORKEY",
+ adaptor_info[adaptor_num].base_id,
"video.device.xv_colorkey",
- _("video overlay colour key"),
- _("The colour key is used to tell the graphics card where to "
- "overlay the video image. Try different values, if you experience "
- "windows becoming transparent."));
-
- } else if(!strcmp(attr[k].name, "XV_AUTOPAINT_COLORKEY")) {
+ VIDEO_DEVICE_XV_COLORKEY_HELP);
+ } else if(!strcmp(name, "XV_AUTOPAINT_COLORKEY")) {
xvmc_check_capability (this, VO_PROP_AUTOPAINT_COLORKEY, attr[k],
- class->adaptor_info[class->adaptor_num].base_id, "XV_AUTOPAINT_COLORKEY",
+ adaptor_info[adaptor_num].base_id,
"video.device.xv_autopaint_colorkey",
- _("autopaint colour key"),
- _("Make Xv autopaint its colour key."));
-
- } else if(!strcmp(attr[k].name, "XV_DOUBLE_BUFFER")) {
- int xvmc_double_buffer;
- xvmc_double_buffer = config->register_bool (config, "video.device.xv_double_buffer", 1,
- _("enable double buffering"),
- _("Double buffering will synchronize the update of the video image to the "
- "repainting of the entire screen (\"vertical retrace\"). This eliminates "
- "flickering and tearing artifacts, but will use more graphics memory."),
- 20, xvmc_update_XV_DOUBLE_BUFFER, this);
+ VIDEO_DEVICE_XV_AUTOPAINT_COLORKEY_HELP);
+ } else if(!strcmp(name, "XV_DOUBLE_BUFFER")) {
+ int xvmc_double_buffer = config->register_bool (config, "video.device.xv_double_buffer", 1,
+ VIDEO_DEVICE_XV_DOUBLE_BUFFER_HELP,
+ 20, xvmc_update_XV_DOUBLE_BUFFER, this);
config->update_num(config,"video.device.xv_double_buffer",xvmc_double_buffer);
}
}
@@ -1494,7 +1484,7 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi
/*
* check supported image formats
*/
- fo = XvListImageFormats(display, this->xv_port, (int*)&formats);
+ fo = XvListImageFormats(this->display, this->xv_port, (int*)&formats);
XUnlockDisplay(this->display);
this->xvmc_format_yv12 = 0;
@@ -1613,10 +1603,6 @@ static char* get_description (video_driver_class_t *this_gen) {
static void dispose_class (video_driver_class_t *this_gen) {
xvmc_class_t *this = (xvmc_class_t *) this_gen;
- XLockDisplay(this->display);
- XvFreeAdaptorInfo (this->adaptor_info);
- XUnlockDisplay(this->display);
-
free (this);
}
@@ -1789,8 +1775,6 @@ static void *init_class (xine_t *xine, void *visual_gen) {
this->display = display;
this->config = xine->config;
this->xv_port = xv_port;
- this->adaptor_info = adaptor_info;
- this->adaptor_num = adaptor_num;
this->surface_type_id = surface_type;
this->max_surface_width = max_width;
this->max_surface_height = max_height;
diff --git a/src/video_out/video_out_xxmc.c b/src/video_out/video_out_xxmc.c
index 28679e95d..61e0139e3 100644
--- a/src/video_out/video_out_xxmc.c
+++ b/src/video_out/video_out_xxmc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2004 the xine project
+ * Copyright (C) 2000-2004, 2008 the xine project
* Copyright (C) 2004 the Unichrome project
*
* This file is part of xine, a free video player.
@@ -34,9 +34,9 @@
*/
-
#include "xxmc.h"
#include <unistd.h>
+#include "xv_common.h"
static int gX11Fail;
@@ -45,6 +45,8 @@ static void xxmc_frame_updates(xxmc_driver_t *driver, xxmc_frame_t *frame,
static void dispose_ximage (xxmc_driver_t *this, XShmSegmentInfo *shminfo,
XvImage *myimage);
+VIDEO_DEVICE_XV_DECL_BICUBIC_TYPES;
+VIDEO_DEVICE_XV_DECL_PREFER_TYPES;
/*
* Acceleration level priority. Static for now. It may well turn out that IDCT
@@ -158,18 +160,13 @@ static void xxmc_xvmc_dump_subpictures(xxmc_driver_t *this)
static void xxmc_xvmc_surface_handler_construct(xxmc_driver_t *this)
{
- int i;
xvmc_surface_handler_t *handler = &this->xvmc_surf_handler;
pthread_mutex_init(&handler->mutex,NULL);
- for (i=0; i<XVMC_MAX_SURFACES; ++i) {
- handler->surfInUse[i] = 0;
- handler->surfValid[i] = 0;
- }
- for (i=0; i<XVMC_MAX_SUBPICTURES; ++i) {
- handler->subInUse[i] = 0;
- handler->subValid[i] = 0;
- }
+ memset(handler->surfInUse, 0, sizeof(handler->surfInUse));
+ memset(handler->surfValid, 0, sizeof(handler->surfValid));
+ memset(handler->subInUse, 0, sizeof(handler->subInUse));
+ memset(handler->subValid, 0, sizeof(handler->subValid));
}
static void xxmc_xvmc_destroy_surfaces(xxmc_driver_t *this)
@@ -550,7 +547,7 @@ static vo_frame_t *xxmc_alloc_frame (vo_driver_t *this_gen) {
xxmc_driver_t *this = (xxmc_driver_t *) this_gen;
xxmc_frame_t *frame ;
- frame = (xxmc_frame_t *) xine_xmalloc (sizeof (xxmc_frame_t));
+ frame = calloc(1, sizeof (xxmc_frame_t));
if (!frame)
return NULL;
@@ -1611,8 +1608,8 @@ static void xxmc_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen)
* other than 100 %, so let's disable deinterlacing at all for this frame
*/
if (this->deinterlace_enabled && this->bob) {
- disable_deinterlace = this->disable_bob_for_progressive_frames && frame->vo_frame.progressive_frame
- || this->disable_bob_for_scaled_osd && this->scaled_osd_active
+ disable_deinterlace = (this->disable_bob_for_progressive_frames && frame->vo_frame.progressive_frame)
+ || (this->disable_bob_for_scaled_osd && this->scaled_osd_active)
|| !frame->vo_frame.stream
|| xine_get_param(frame->vo_frame.stream, XINE_PARAM_FINE_SPEED) != XINE_FINE_SPEED_NORMAL;
if (!disable_deinterlace) {
@@ -2065,13 +2062,13 @@ static int xxmc_check_yv12 (Display *display, XvPortID port) {
/* called xlocked */
static void xxmc_check_capability (xxmc_driver_t *this,
- int property, XvAttribute attr,
- int base_id, char *str_prop,
- char *config_name,
- char *config_desc,
- char *config_help) {
+ int property, XvAttribute attr, int base_id,
+ const char *config_name,
+ const char *config_desc,
+ const char *config_help) {
int int_default;
cfg_entry_t *entry;
+ const char *str_prop = attr.name;
if (VO_PROP_COLORKEY && (attr.max_value == ~0))
attr.max_value = 2147483615;
@@ -2133,36 +2130,32 @@ static void xxmc_check_capability (xxmc_driver_t *this,
this->props[property].value = int_default;
}
-static void xxmc_update_XV_FILTER(void *this_gen, xine_cfg_entry_t *entry) {
+static void xxmc_update_attr (void *this_gen, xine_cfg_entry_t *entry,
+ const char *atomstr, const char *debugstr)
+{
xxmc_driver_t *this = (xxmc_driver_t *) this_gen;
Atom atom;
- int xv_filter;
-
- xv_filter = entry->num_value;
XLockDisplay(this->display);
- atom = XInternAtom (this->display, "XV_FILTER", False);
- XvSetPortAttribute (this->display, this->xv_port, atom, xv_filter);
+ atom = XInternAtom (this->display, atomstr, False);
+ XvSetPortAttribute (this->display, this->xv_port, atom, entry->num_value);
XUnlockDisplay(this->display);
xprintf(this->xine, XINE_VERBOSITY_DEBUG,
- "video_out_xxmc: bilinear scaling mode (XV_FILTER) = %d\n",xv_filter);
+ LOG_MODULE ": %s = %d\n", debugstr, entry->num_value);
}
-static void xxmc_update_XV_DOUBLE_BUFFER(void *this_gen, xine_cfg_entry_t *entry) {
- xxmc_driver_t *this = (xxmc_driver_t *) this_gen;
- Atom atom;
- int xv_double_buffer;
-
- xv_double_buffer = entry->num_value;
+static void xxmc_update_XV_FILTER(void *this_gen, xine_cfg_entry_t *entry) {
+ xxmc_update_attr (this_gen, entry, "XV_FILTER", "bilinear scaling mode");
+}
- XLockDisplay(this->display);
- atom = XInternAtom (this->display, "XV_DOUBLE_BUFFER", False);
- XvSetPortAttribute (this->display, this->xv_port, atom, xv_double_buffer);
- XUnlockDisplay(this->display);
+static void xxmc_update_XV_DOUBLE_BUFFER(void *this_gen, xine_cfg_entry_t *entry) {
+ xxmc_update_attr (this_gen, entry, "XV_DOUBLE_BUFFER", "double buffering mode");
+}
- xprintf(this->xine, XINE_VERBOSITY_DEBUG,
- "video_out_xxmc: double buffering mode = %d\n", xv_double_buffer);
+static void xxmc_update_XV_BICUBIC(void *this_gen, xine_cfg_entry_t *entry)
+{
+ xxmc_update_attr (this_gen, entry, "XV_BICUBIC", "bicubic filtering mode");
}
static void xxmc_update_xv_pitch_alignment(void *this_gen, xine_cfg_entry_t *entry) {
@@ -2201,6 +2194,52 @@ static void xxmc_update_disable_bob_for_scaled_osd(void *this_gen, xine_cfg_entr
this->disable_bob_for_scaled_osd = entry->num_value;
}
+static int xxmc_open_port (xxmc_driver_t *this, XvPortID port) {
+ int ret;
+ x11_InstallXErrorHandler (this);
+ ret = ! xxmc_check_yv12(this->display, port)
+ && XvGrabPort(this->display, port, 0) == Success;
+ x11_DeInstallXErrorHandler (this);
+ return ret;
+}
+
+static unsigned int
+xxmc_find_adaptor_by_port (int port, unsigned int adaptors,
+ XvAdaptorInfo *adaptor_info)
+{
+ unsigned int an;
+ for (an = 0; an < adaptors; an++)
+ if (adaptor_info[an].type & XvImageMask)
+ if (port >= adaptor_info[an].base_id &&
+ port < adaptor_info[an].base_id + adaptor_info[an].num_ports)
+ return an;
+ return 0; /* shouldn't happen */
+}
+
+static XvPortID xxmc_autodetect_port(xxmc_driver_t *this,
+ unsigned int adaptors,
+ XvAdaptorInfo *adaptor_info,
+ unsigned int *adaptor_num,
+ XvPortID base,
+ xv_prefertype prefer_type)
+{
+ unsigned int an, j;
+
+ for (an = 0; an < adaptors; an++)
+ if (adaptor_info[an].type & XvImageMask &&
+ (prefer_type == xv_prefer_none ||
+ strcasestr (adaptor_info[an].name, prefer_substrings[prefer_type])))
+ for (j = 0; j < adaptor_info[an].num_ports; j++) {
+ XvPortID port = adaptor_info[an].base_id + j;
+ if (port >= base && xxmc_open_port(this, port)) {
+ *adaptor_num = an;
+ return port;
+ }
+ }
+
+ return 0;
+}
+
static void checkXvMCCap( xxmc_driver_t *this, XvPortID xv_port)
{
@@ -2363,17 +2402,18 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi
x11_visual_t *visual = (x11_visual_t *) visual_gen;
XColor dummy;
XvImage *myimage;
- unsigned int adaptors, j;
+ unsigned int adaptors;
unsigned int ver,rel,req,ev,err;
XShmSegmentInfo myshminfo;
XvPortID xv_port;
XvAdaptorInfo *adaptor_info;
unsigned int adaptor_num;
+ xv_prefertype prefer_type;
cfg_entry_t *entry;
int use_more_frames;
int use_unscaled;
- this = (xxmc_driver_t *) xine_xmalloc (sizeof (xxmc_driver_t));
+ this = calloc(1, sizeof (xxmc_driver_t));
if (!this)
return NULL;
@@ -2404,24 +2444,31 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi
return NULL;
}
- xv_port = 0;
-
- for ( adaptor_num = 0; (adaptor_num < adaptors) && !xv_port; adaptor_num++ ) {
-
- if (adaptor_info[adaptor_num].type & XvImageMask) {
-
- for (j = 0; j < adaptor_info[adaptor_num].num_ports && !xv_port; j++)
- if (( !(xxmc_check_yv12 (this->display,
- adaptor_info[adaptor_num].base_id + j)))
- && (XvGrabPort (this->display,
- adaptor_info[adaptor_num].base_id + j,
- 0) == Success)) {
- xv_port = adaptor_info[adaptor_num].base_id + j;
- }
-
- if( xv_port )
- break;
- }
+ xv_port = config->register_num (config, "video.device.xv_port", 0,
+ VIDEO_DEVICE_XV_PORT_HELP,
+ 20, NULL, NULL);
+ prefer_type = config->register_enum (config, "video.device.xv_preferred_method", 0,
+ prefer_labels, VIDEO_DEVICE_XV_PREFER_TYPE_HELP,
+ 10, NULL, NULL);
+
+ if (xv_port != 0) {
+ if (! xxmc_open_port(this, xv_port)) {
+ xprintf(class->xine, XINE_VERBOSITY_NONE,
+ _("%s: could not open Xv port %d - autodetecting\n"),
+ LOG_MODULE, xv_port);
+ xv_port = xxmc_autodetect_port(this, adaptors, adaptor_info, &adaptor_num, xv_port, prefer_type);
+ } else
+ adaptor_num = xxmc_find_adaptor_by_port (xv_port, adaptors, adaptor_info);
+ }
+ if (!xv_port)
+ xv_port = xxmc_autodetect_port(this, adaptors, adaptor_info, &adaptor_num, 0, prefer_type);
+ if (!xv_port)
+ {
+ if (prefer_type)
+ xprintf(class->xine, XINE_VERBOSITY_NONE,
+ _("%s: no available ports of type \"%s\", defaulting...\n"),
+ LOG_MODULE, prefer_labels[prefer_type]);
+ xv_port = xxmc_autodetect_port(this, adaptors, adaptor_info, &adaptor_num, 0, xv_prefer_none);
}
if (!xv_port) {
@@ -2510,72 +2557,60 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi
for(k = 0; k < nattr; k++) {
if((attr[k].flags & XvSettable) && (attr[k].flags & XvGettable)) {
- if(!strcmp(attr[k].name, "XV_HUE")) {
+ const char *const name = attr[k].name;
+ if(!strcmp(name, "XV_HUE")) {
if (!strncmp(adaptor_info[adaptor_num].name, "NV", 2)) {
xprintf (this->xine, XINE_VERBOSITY_NONE, "video_out_xxmc: ignoring broken XV_HUE settings on NVidia cards\n");
} else {
xxmc_check_capability (this, VO_PROP_HUE, attr[k],
- adaptor_info[adaptor_num].base_id, "XV_HUE",
+ adaptor_info[adaptor_num].base_id,
NULL, NULL, NULL);
}
- } else if(!strcmp(attr[k].name, "XV_SATURATION")) {
+ } else if(!strcmp(name, "XV_SATURATION")) {
xxmc_check_capability (this, VO_PROP_SATURATION, attr[k],
- adaptor_info[adaptor_num].base_id, "XV_SATURATION",
+ adaptor_info[adaptor_num].base_id,
NULL, NULL, NULL);
- } else if(!strcmp(attr[k].name, "XV_BRIGHTNESS")) {
+ } else if(!strcmp(name, "XV_BRIGHTNESS")) {
xxmc_check_capability (this, VO_PROP_BRIGHTNESS, attr[k],
- adaptor_info[adaptor_num].base_id, "XV_BRIGHTNESS",
+ adaptor_info[adaptor_num].base_id,
NULL, NULL, NULL);
- } else if(!strcmp(attr[k].name, "XV_CONTRAST")) {
+ } else if(!strcmp(name, "XV_CONTRAST")) {
xxmc_check_capability (this, VO_PROP_CONTRAST, attr[k],
- adaptor_info[adaptor_num].base_id, "XV_CONTRAST",
+ adaptor_info[adaptor_num].base_id,
NULL, NULL, NULL);
- } else if(!strcmp(attr[k].name, "XV_COLORKEY")) {
+ } else if(!strcmp(name, "XV_COLORKEY")) {
xxmc_check_capability (this, VO_PROP_COLORKEY, attr[k],
- adaptor_info[adaptor_num].base_id, "XV_COLORKEY",
+ adaptor_info[adaptor_num].base_id,
"video.device.xv_colorkey",
- _("video overlay colour key"),
- _("The colour key is used to tell the graphics card where to "
- "overlay the video image. Try different values, if you experience "
- "windows becoming transparent."));
-
- } else if(!strcmp(attr[k].name, "XV_AUTOPAINT_COLORKEY")) {
+ VIDEO_DEVICE_XV_COLORKEY_HELP);
+ } else if(!strcmp(name, "XV_AUTOPAINT_COLORKEY")) {
xxmc_check_capability (this, VO_PROP_AUTOPAINT_COLORKEY, attr[k],
- adaptor_info[adaptor_num].base_id, "XV_AUTOPAINT_COLORKEY",
+ adaptor_info[adaptor_num].base_id,
"video.device.xv_autopaint_colorkey",
- _("autopaint colour key"),
- _("Make Xv autopaint its colour key."));
-
- } else if(!strcmp(attr[k].name, "XV_FILTER")) {
+ VIDEO_DEVICE_XV_AUTOPAINT_COLORKEY_HELP);
+ } else if(!strcmp(name, "XV_FILTER")) {
int xv_filter;
/* This setting is specific to Permedia 2/3 cards. */
xv_filter = config->register_range (config, "video.device.xv_filter", 0,
attr[k].min_value, attr[k].max_value,
- _("bilinear scaling mode"),
- _("Selects the bilinear scaling mode for Permedia cards. "
- "The individual values are:\n\n"
- "Permedia 2\n"
- "0 - disable bilinear filtering\n"
- "1 - enable bilinear filtering\n\n"
- "Permedia 3\n"
- "0 - disable bilinear filtering\n"
- "1 - horizontal linear filtering\n"
- "2 - enable full bilinear filtering"),
+ VIDEO_DEVICE_XV_FILTER_HELP,
20, xxmc_update_XV_FILTER, this);
config->update_num(config,"video.device.xv_filter",xv_filter);
- } else if(!strcmp(attr[k].name, "XV_DOUBLE_BUFFER")) {
- int xv_double_buffer;
- xv_double_buffer =
+ } else if(!strcmp(name, "XV_DOUBLE_BUFFER")) {
+ int xv_double_buffer =
config->register_bool (config, "video.device.xv_double_buffer", 1,
- _("enable double buffering"),
- _("Double buffering will synchronize the update of the video image to the "
- "repainting of the entire screen (\"vertical retrace\"). This eliminates "
- "flickering and tearing artifacts, but will use more graphics memory."),
+ VIDEO_DEVICE_XV_DOUBLE_BUFFER_HELP,
20, xxmc_update_XV_DOUBLE_BUFFER, this);
config->update_num(config,"video.device.xv_double_buffer",xv_double_buffer);
+ } else if(!strcmp(name, "XV_BICUBIC")) {
+ int xv_bicubic =
+ config->register_enum (config, "video.device.xv_bicubic", 2,
+ bicubic_types, VIDEO_DEVICE_XV_BICUBIC_HELP,
+ 20, xxmc_update_XV_BICUBIC, this);
+ config->update_num(config,"video.device.xv_bicubic",xv_bicubic);
}
}
}
@@ -2639,8 +2674,7 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi
this->use_pitch_alignment =
config->register_bool (config, "video.device.xv_pitch_alignment", 0,
- _("pitch alignment workaround"),
- _("Some buggy video drivers need a workaround to function properly."),
+ VIDEO_DEVICE_XV_PITCH_ALIGNMENT_HELP,
10, xxmc_update_xv_pitch_alignment, this);
use_more_frames=
@@ -2744,7 +2778,7 @@ static void dispose_class (video_driver_class_t *this_gen) {
}
static void *init_class (xine_t *xine, void *visual_gen) {
- xxmc_class_t *this = (xxmc_class_t *) xine_xmalloc (sizeof (xxmc_class_t));
+ xxmc_class_t *this = calloc(1, sizeof (xxmc_class_t));
this->driver_class.open_plugin = open_plugin;
this->driver_class.get_identifier = get_identifier;
diff --git a/src/video_out/x11osd.c b/src/video_out/x11osd.c
index e0cb6f1f6..4d0e46287 100644
--- a/src/video_out/x11osd.c
+++ b/src/video_out/x11osd.c
@@ -245,7 +245,7 @@ x11osd_create (xine_t *xine, Display *display, int screen, Window window, enum x
XSetWindowAttributes attr;
XWindowAttributes getattr;
- osd = xine_xmalloc (sizeof (x11osd));
+ osd = calloc(1, sizeof(x11osd));
if (!osd)
return NULL;
diff --git a/src/video_out/xcbosd.c b/src/video_out/xcbosd.c
index 4bb2b60af..d8cf119a2 100644
--- a/src/video_out/xcbosd.c
+++ b/src/video_out/xcbosd.c
@@ -238,7 +238,7 @@ xcbosd *xcbosd_create(xine_t *xine, xcb_connection_t *connection, xcb_screen_t *
xcb_void_cookie_t generic_cookie;
xcb_generic_error_t *generic_error;
- osd = xine_xmalloc (sizeof (xcbosd));
+ osd = calloc(1, sizeof(xcbosd));
if (!osd)
return NULL;
diff --git a/src/video_out/xv_common.h b/src/video_out/xv_common.h
new file mode 100644
index 000000000..ff49286f0
--- /dev/null
+++ b/src/video_out/xv_common.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2008 the xine project
+ *
+ * This file is part of xine, a free video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * xv_common.h: X11 Xv common bits
+ */
+
+#define VIDEO_DEVICE_XV_COLORKEY_HELP \
+ _("video overlay colour key"), \
+ _("The colour key is used to tell the graphics card where to " \
+ "overlay the video image. Try different values, if you "\
+ "experience windows becoming transparent.")
+
+#define VIDEO_DEVICE_XV_AUTOPAINT_COLORKEY_HELP \
+ _("autopaint colour key"), \
+ _("Make Xv autopaint its colour key.")
+
+#define VIDEO_DEVICE_XV_FILTER_HELP \
+ _("bilinear scaling mode"), \
+ _("Selects the bilinear scaling mode for Permedia cards. " \
+ "The individual values are:\n\n" \
+ "Permedia 2\n" \
+ "0 - disable bilinear filtering\n" \
+ "1 - enable bilinear filtering\n\n" \
+ "Permedia 3\n" \
+ "0 - disable bilinear filtering\n" \
+ "1 - horizontal linear filtering\n" \
+ "2 - enable full bilinear filtering")
+
+#define VIDEO_DEVICE_XV_DOUBLE_BUFFER_HELP \
+ _("enable double buffering"), \
+ _("Double buffering will synchronize the update of the video " \
+ "image to the repainting of the entire screen (\"vertical " \
+ "retrace\"). This eliminates flickering and tearing artifacts, " \
+ "but will use more graphics memory.")
+
+#define VIDEO_DEVICE_XV_PORT_HELP \
+ _("Xv port number"), \
+ _("Selects the Xv port number to use (0 to autodetect).")
+
+#define VIDEO_DEVICE_XV_PITCH_ALIGNMENT_HELP \
+ _("pitch alignment workaround"), \
+ _("Some buggy video drivers need a workaround to function properly.")
+
+#define VIDEO_DEVICE_XV_DECL_SYNC_ATOMS \
+ static const char *const sync_atoms[] = \
+ { "XV_SYNC_TO_VBLANK", "XV_VSYNC" };
+
+#define VIDEO_DEVICE_XV_DECL_PREFER_TYPES \
+ typedef enum { \
+ xv_prefer_none, xv_prefer_overlay, xv_prefer_textured, xv_prefer_blitter, \
+ } xv_prefertype; \
+ static const char *const prefer_labels[] = \
+ { "Any", "Overlay", "Textured Video", "Blitter", NULL }; \
+ static const char prefer_substrings[][8] = \
+ { "", "Overlay", "Texture", "Blitter" };
+#define VIDEO_DEVICE_XV_PREFER_TYPE_HELP \
+ _("video display method preference"), \
+ _("Selects which video output method is preferred. " \
+ "Detection is done using the reported Xv adaptor names.\n" \
+ "(Only applies when auto-detecting which Xv port to use.)")
+
+#define VIDEO_DEVICE_XV_DECL_BICUBIC_TYPES \
+ static const char *const bicubic_types[] = { "Off", "On", "Auto", NULL };
+#define VIDEO_DEVICE_XV_BICUBIC_HELP \
+ _("bicubic filtering"), \
+ _("This option controls bicubic filtering of the video image. " \
+ "It may be used instead of, or as well as, xine's deinterlacers.")
diff --git a/src/video_out/xxmc.h b/src/video_out/xxmc.h
index 1c24991be..03b12c15b 100644
--- a/src/video_out/xxmc.h
+++ b/src/video_out/xxmc.h
@@ -37,6 +37,14 @@
#define XVMC_THREAD_SAFE
+/*
+ * some implementations are not aware of the display having been locked
+ * already before calling the xvmc function and may therefore deadlock.
+ */
+/*
+#define XVMC_LOCKDISPLAY_SAFE
+*/
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@@ -171,7 +179,7 @@ typedef struct context_lock_s {
return; \
}
-#ifdef XVMC_THREAD_SAFE
+#if defined(XVMC_THREAD_SAFE) && defined(XVMC_LOCKDISPLAY_SAFE)
#define XVMCLOCKDISPLAY(display)
#define XVMCUNLOCKDISPLAY(display)
#else
diff --git a/src/video_out/yuv2rgb.c b/src/video_out/yuv2rgb.c
index c98dd518f..fb2d63e6c 100644
--- a/src/video_out/yuv2rgb.c
+++ b/src/video_out/yuv2rgb.c
@@ -3144,7 +3144,7 @@ static void yuy22rgb_c_init (yuv2rgb_factory_t *this)
static yuv2rgb_t *yuv2rgb_create_converter (yuv2rgb_factory_t *factory) {
- yuv2rgb_t *this = xine_xmalloc (sizeof (yuv2rgb_t));
+ yuv2rgb_t *this = calloc(1, sizeof(yuv2rgb_t));
this->swapped = factory->swapped;
this->cmap = factory->cmap;
diff --git a/src/video_out/yuv2rgb_mlib.c b/src/video_out/yuv2rgb_mlib.c
index 8635526ed..22e67efa8 100644
--- a/src/video_out/yuv2rgb_mlib.c
+++ b/src/video_out/yuv2rgb_mlib.c
@@ -38,8 +38,6 @@
#include "xineutils.h"
#include "yuv2rgb.h"
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-
static void mlib_yuv420_rgb24(yuv2rgb_t *this,
uint8_t * image, uint8_t * py,
uint8_t * pu, uint8_t * pv)
diff --git a/src/xine-engine/alphablend.c b/src/xine-engine/alphablend.c
index a7ab33cf8..a9b015209 100644
--- a/src/xine-engine/alphablend.c
+++ b/src/xine-engine/alphablend.c
@@ -23,6 +23,10 @@
*
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
/*
#define LOG_BLEND_YUV
#define LOG_BLEND_RGB16
@@ -1110,12 +1114,12 @@ static uint8_t *(*blend_yuv_grow_extra_data(alphablend_t *extra_data, int osd_wi
uint8_t *data[ 3 ][ 2 ];
} *header = (struct header_s *)extra_data->buffer;
- int needed_buffer_size = sizeof (*header) + osd_width * sizeof (uint8_t[ 3 ][ 2 ]);
+ size_t needed_buffer_size = sizeof (*header) + osd_width * sizeof (uint8_t[ 3 ][ 2 ]);
if (extra_data->buffer_size < needed_buffer_size) {
free(extra_data->buffer);
- header = xine_xmalloc(needed_buffer_size);
+ header = calloc(1, needed_buffer_size);
if (!header) {
extra_data->buffer_size = 0;
return 0;
@@ -1552,12 +1556,12 @@ static uint8_t *(*blend_yuy2_grow_extra_data(alphablend_t *extra_data, int osd_w
uint8_t *data[ 3 ];
} *header = (struct header_s *)extra_data->buffer;
- int needed_buffer_size = sizeof (*header) + osd_width * sizeof (uint8_t[ 3 ]);
+ size_t needed_buffer_size = sizeof (*header) + osd_width * sizeof (uint8_t[ 3 ]);
if (extra_data->buffer_size < needed_buffer_size) {
free(extra_data->buffer);
- header = xine_xmalloc(needed_buffer_size);
+ header = calloc(1, needed_buffer_size);
if (!header) {
extra_data->buffer_size = 0;
return 0;
diff --git a/src/xine-engine/alphablend.h b/src/xine-engine/alphablend.h
index 3c9a693d9..7aa63b306 100644
--- a/src/xine-engine/alphablend.h
+++ b/src/xine-engine/alphablend.h
@@ -39,22 +39,7 @@ typedef struct {
void _x_alphablend_init(alphablend_t *extra_data, xine_t *xine) XINE_PROTECTED;
void _x_alphablend_free(alphablend_t *extra_data) XINE_PROTECTED;
-/* _MSC_VER port changes */
-#undef ATTRIBUTE_PACKED
-#undef PRAGMA_PACK_BEGIN
-#undef PRAGMA_PACK_END
-
-#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) || defined(__ICC)
-#define ATTRIBUTE_PACKED __attribute__ ((packed))
-#define PRAGMA_PACK 0
-#endif
-
-#if !defined(ATTRIBUTE_PACKED)
-#define ATTRIBUTE_PACKED
-#define PRAGMA_PACK 1
-#endif
-
-#if PRAGMA_PACK
+#if !SUPPORT_ATTRIBUTE_PACKED
#pragma pack(8)
#endif
@@ -63,10 +48,10 @@ typedef struct { /* CLUT == Color LookUp Table */
uint8_t cr;
uint8_t y;
uint8_t foo;
-} ATTRIBUTE_PACKED clut_t;
+} XINE_PACKED clut_t;
-#if PRAGMA_PACK
+#if !SUPPORT_ATTRIBUTE_PACKED
#pragma pack()
#endif
diff --git a/src/xine-engine/audio_decoder.c b/src/xine-engine/audio_decoder.c
index 5476262d9..855dee372 100644
--- a/src/xine-engine/audio_decoder.c
+++ b/src/xine-engine/audio_decoder.c
@@ -89,16 +89,18 @@ static void *audio_decoder_loop (void *stream_gen) {
if (stream->audio_decoder_plugin) {
lprintf ("close old decoder\n");
-
+
+ stream->keep_ao_driver_open = !!(buf->decoder_flags & BUF_FLAG_GAPLESS_SW);
_x_free_audio_decoder (stream, stream->audio_decoder_plugin);
stream->audio_decoder_plugin = NULL;
stream->audio_track_map_entries = 0;
stream->audio_type = 0;
+ stream->keep_ao_driver_open = 0;
}
running_ticket->release(running_ticket, 0);
- if( !stream->gapless_switch )
+ if( !(buf->decoder_flags & BUF_FLAG_GAPLESS_SW) )
stream->metronom->handle_audio_discontinuity (stream->metronom, DISC_STREAMSTART, 0);
buftype_unknown = 0;
diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c
index 7fe92d9fe..a6f83dc9d 100644
--- a/src/xine-engine/audio_out.c
+++ b/src/xine-engine/audio_out.c
@@ -215,6 +215,7 @@ typedef struct {
int num_driver_actions; /* number of threads, that wish to call
* functions needing driver_lock */
pthread_mutex_t driver_action_lock; /* protects num_driver_actions */
+ pthread_cond_t driver_action_cond; /* informs about num_driver_actions-- */
metronom_clock_t *clock;
xine_t *xine;
@@ -243,6 +244,7 @@ typedef struct {
audio_fifo_t *free_fifo;
audio_fifo_t *out_fifo;
int64_t last_audio_vpts;
+ pthread_mutex_t current_speed_lock;
uint32_t current_speed; /* the current playback speed */
/* FIXME: replace all this->clock->speed with this->current_speed. we should make
* sure nobody will change speed without going through xine.c:set_speed_internal */
@@ -287,13 +289,14 @@ struct audio_fifo_s {
int num_buffers;
};
+static int ao_get_property (xine_audio_port_t *this_gen, int property);
static int ao_set_property (xine_audio_port_t *this_gen, int property, int value);
-static audio_fifo_t *fifo_new (xine_t *xine) {
+static audio_fifo_t *XINE_MALLOC fifo_new (xine_t *xine) {
audio_fifo_t *fifo;
- fifo = (audio_fifo_t *) xine_xmalloc (sizeof (audio_fifo_t));
+ fifo = (audio_fifo_t *) calloc(1, sizeof(audio_fifo_t));
if (!fifo)
return NULL;
@@ -1039,6 +1042,7 @@ static void *ao_loop (void *this_gen) {
* we must process/free buffers otherwise the entire engine will stop.
*/
+ pthread_mutex_lock(&this->current_speed_lock);
if ( this->audio_loop_running &&
(this->clock->speed == XINE_SPEED_PAUSE ||
(this->clock->speed != XINE_FINE_SPEED_NORMAL &&
@@ -1054,6 +1058,7 @@ static void *ao_loop (void *this_gen) {
_x_refcounter_dec(in_buf->stream->refcounter);
fifo_append (this->free_fifo, in_buf);
in_buf = NULL;
+ pthread_mutex_unlock(&this->current_speed_lock);
continue;
}
@@ -1064,6 +1069,7 @@ static void *ao_loop (void *this_gen) {
}
lprintf ("loop:pause: I feel sleepy (%d buffers).\n", this->out_fifo->num_buffers);
+ pthread_mutex_unlock(&this->current_speed_lock);
xine_usec_sleep (10000);
lprintf ("loop:pause: I wake up.\n");
continue;
@@ -1273,12 +1279,20 @@ static void *ao_loop (void *this_gen) {
fifo_append (this->free_fifo, in_buf);
in_buf = NULL;
}
+ pthread_mutex_unlock(&this->current_speed_lock);
/* Give other threads a chance to use functions which require this->driver_lock to
* be available. This is needed when using NPTL on Linux (and probably PThreads
* on Solaris as well). */
- if (this->num_driver_actions > 0)
- sched_yield();
+ if (this->num_driver_actions > 0) {
+ /* calling sched_yield() is not sufficient on multicore systems */
+ /* sched_yield(); */
+ /* instead wait for the other thread to acquire this->driver_lock */
+ pthread_mutex_lock(&this->driver_action_lock);
+ if (this->num_driver_actions > 0)
+ pthread_cond_wait(&this->driver_action_cond, &this->driver_action_lock);
+ pthread_mutex_unlock(&this->driver_action_lock);
+ }
}
if (in_buf) {
@@ -1469,6 +1483,8 @@ static inline void dec_num_driver_actions(aos_t *this) {
pthread_mutex_lock(&this->driver_action_lock);
this->num_driver_actions--;
+ /* indicate the change to ao_loop() */
+ pthread_cond_broadcast(&this->driver_action_cond);
pthread_mutex_unlock(&this->driver_action_lock);
}
@@ -1608,17 +1624,21 @@ static void ao_close(xine_audio_port_t *this_gen, xine_stream_t *stream) {
pthread_mutex_unlock(&this->streams_lock);
/* close driver if no streams left */
- if (!ite && !this->grab_only && !stream->gapless_switch) {
+ if (!ite && !this->grab_only && !stream->keep_ao_driver_open) {
xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_out: no streams left, closing driver\n");
if (this->audio_loop_running) {
+ /* make sure there are no more buffers on queue */
if (this->clock->speed == XINE_SPEED_PAUSE ||
(this->clock->speed != XINE_FINE_SPEED_NORMAL && !this->slow_fast_audio)) {
- /* discard buffers, otherwise we'll wait forever */
+ int discard = ao_get_property(this_gen, AO_PROP_DISCARD_BUFFERS);
+ /* discard buffers while waiting, otherwise we'll wait forever */
ao_set_property(this_gen, AO_PROP_DISCARD_BUFFERS, 1);
+ fifo_wait_empty(this->out_fifo);
+ ao_set_property(this_gen, AO_PROP_DISCARD_BUFFERS, discard);
}
- /* make sure there are no more buffers on queue */
- fifo_wait_empty(this->out_fifo);
+ else
+ fifo_wait_empty(this->out_fifo);
}
pthread_mutex_lock( &this->driver_lock );
@@ -1667,6 +1687,7 @@ static void ao_exit(xine_audio_port_t *this_gen) {
}
pthread_mutex_destroy(&this->driver_lock);
+ pthread_cond_destroy(&this->driver_action_cond);
pthread_mutex_destroy(&this->driver_action_lock);
pthread_mutex_destroy(&this->streams_lock);
xine_list_delete(this->streams);
@@ -1679,6 +1700,7 @@ static void ao_exit(xine_audio_port_t *this_gen) {
free (this->frame_buf[1]);
free (this->zero_space);
+ pthread_mutex_destroy(&this->current_speed_lock);
pthread_mutex_destroy(&this->flush_audio_driver_lock);
pthread_cond_destroy(&this->flush_audio_driver_reached);
@@ -1905,8 +1927,15 @@ static int ao_set_property (xine_audio_port_t *this_gen, int property, int value
if (value != XINE_FINE_SPEED_NORMAL && value != XINE_SPEED_PAUSE && !this->slow_fast_audio )
this->ao.control(&this->ao, AO_CTRL_FLUSH_BUFFERS, NULL);
- this->ao.control(&this->ao,
- (value == XINE_SPEED_PAUSE) ? AO_CTRL_PLAY_PAUSE : AO_CTRL_PLAY_RESUME, NULL);
+ if( value == XINE_SPEED_PAUSE ) {
+ /* current_speed_lock is here to make sure the ao_loop will pause in a safe place.
+ * that is, we cannot pause writing to device, filling gaps etc. */
+ pthread_mutex_lock(&this->current_speed_lock);
+ this->ao.control(&this->ao, AO_CTRL_PLAY_PAUSE, NULL);
+ pthread_mutex_unlock(&this->current_speed_lock);
+ } else {
+ this->ao.control(&this->ao, AO_CTRL_PLAY_RESUME, NULL);
+ }
this->current_speed = value;
if( this->slow_fast_audio )
ao_update_resample_factor(this);
@@ -2046,11 +2075,12 @@ xine_audio_port_t *_x_ao_new_port (xine_t *xine, ao_driver_t *driver,
static const char* resample_modes[] = {"auto", "off", "on", NULL};
static const char* av_sync_methods[] = {"metronom feedback", "resample", NULL};
- this = xine_xmalloc (sizeof (aos_t)) ;
+ this = calloc(1, sizeof(aos_t)) ;
this->driver = driver;
this->xine = xine;
this->clock = xine->clock;
+ this->current_speed = xine->clock->speed;
this->streams = xine_list_new();
/* warning: driver_lock is a recursive mutex. it must NOT be
@@ -2062,6 +2092,7 @@ xine_audio_port_t *_x_ao_new_port (xine_t *xine, ao_driver_t *driver,
pthread_mutex_init( &this->streams_lock, NULL );
pthread_mutex_init( &this->driver_lock, &attr );
pthread_mutex_init( &this->driver_action_lock, NULL );
+ pthread_cond_init( &this->driver_action_cond, NULL );
this->ao.open = ao_open;
this->ao.get_buffer = ao_get_buffer;
@@ -2080,8 +2111,9 @@ xine_audio_port_t *_x_ao_new_port (xine_t *xine, ao_driver_t *driver,
this->grab_only = grab_only;
this->flush_audio_driver = 0;
this->discard_buffers = 0;
- this->zero_space = xine_xmalloc (ZERO_BUF_SIZE * 4 * 6); /* MAX as 32bit, 6 channels. */
+ this->zero_space = calloc (1, ZERO_BUF_SIZE * 4 * 6); /* MAX as 32bit, 6 channels. */
+ pthread_mutex_init( &this->current_speed_lock, NULL );
pthread_mutex_init( &this->flush_audio_driver_lock, NULL );
pthread_cond_init( &this->flush_audio_driver_reached, NULL );
@@ -2191,8 +2223,8 @@ xine_audio_port_t *_x_ao_new_port (xine_t *xine, ao_driver_t *driver,
audio_buffer_t *buf;
- buf = (audio_buffer_t *) xine_xmalloc (sizeof (audio_buffer_t));
- buf->mem = xine_xmalloc (AUDIO_BUF_SIZE);
+ buf = (audio_buffer_t *) calloc(1, sizeof(audio_buffer_t));
+ buf->mem = calloc (1, AUDIO_BUF_SIZE);
buf->mem_size = AUDIO_BUF_SIZE;
buf->extra_info = malloc(sizeof(extra_info_t));
@@ -2206,8 +2238,8 @@ xine_audio_port_t *_x_ao_new_port (xine_t *xine, ao_driver_t *driver,
audio_buffer_t *buf;
- buf = (audio_buffer_t *) xine_xmalloc (sizeof (audio_buffer_t));
- buf->mem = xine_xmalloc (4*AUDIO_BUF_SIZE);
+ buf = (audio_buffer_t *) calloc(1, sizeof(audio_buffer_t));
+ buf->mem = calloc(4, AUDIO_BUF_SIZE);
buf->mem_size = 4*AUDIO_BUF_SIZE;
buf->extra_info = malloc(sizeof(extra_info_t));
diff --git a/src/xine-engine/audio_out.h b/src/xine-engine/audio_out.h
index c4581ec24..5f4420363 100644
--- a/src/xine-engine/audio_out.h
+++ b/src/xine-engine/audio_out.h
@@ -259,7 +259,7 @@ struct audio_driver_class_s {
* this initiates the audio_out sync routines
* found in ./src/xine-engine/audio_out.c
*/
-xine_audio_port_t *_x_ao_new_port (xine_t *xine, ao_driver_t *driver, int grab_only) XINE_PROTECTED;
+xine_audio_port_t *_x_ao_new_port (xine_t *xine, ao_driver_t *driver, int grab_only) XINE_MALLOC XINE_PROTECTED;
/*
* audio output modes + capabilities
diff --git a/src/xine-engine/broadcaster.c b/src/xine-engine/broadcaster.c
index 1d2f01366..81711de49 100644
--- a/src/xine-engine/broadcaster.c
+++ b/src/xine-engine/broadcaster.c
@@ -32,6 +32,10 @@
* 'xine -V none -A none'
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -323,7 +327,7 @@ broadcaster_t *_x_init_broadcaster(xine_stream_t *stream, int port)
signal( SIGPIPE, SIG_IGN );
- this = xine_xmalloc(sizeof(broadcaster_t));
+ this = calloc(1, sizeof(broadcaster_t));
this->port = port;
this->stream = stream;
this->msock = msock;
diff --git a/src/xine-engine/broadcaster.h b/src/xine-engine/broadcaster.h
index 093fb4af0..b59d33349 100644
--- a/src/xine-engine/broadcaster.h
+++ b/src/xine-engine/broadcaster.h
@@ -27,13 +27,9 @@
extern "C" {
#endif
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
typedef struct broadcaster_s broadcaster_t;
-broadcaster_t *_x_init_broadcaster(xine_stream_t *stream, int port) XINE_PROTECTED;
+broadcaster_t *_x_init_broadcaster(xine_stream_t *stream, int port) XINE_MALLOC XINE_PROTECTED;
void _x_close_broadcaster(broadcaster_t *this) XINE_PROTECTED;
int _x_get_broadcaster_port(broadcaster_t *this) XINE_PROTECTED;
diff --git a/src/xine-engine/buffer.c b/src/xine-engine/buffer.c
index 93ad75ba0..417fee745 100644
--- a/src/xine-engine/buffer.c
+++ b/src/xine-engine/buffer.c
@@ -500,7 +500,7 @@ fifo_buffer_t *_x_fifo_buffer_new (int num_buffers, uint32_t buf_size) {
int alignment = 2048;
unsigned char *multi_buffer = NULL;
- this = xine_xmalloc (sizeof (fifo_buffer_t));
+ this = calloc(1, sizeof(fifo_buffer_t));
this->first = NULL;
this->last = NULL;
@@ -551,7 +551,7 @@ fifo_buffer_t *_x_fifo_buffer_new (int num_buffers, uint32_t buf_size) {
for (i = 0; i<num_buffers; i++) {
buf_element_t *buf;
- buf = xine_xmalloc (sizeof (buf_element_t));
+ buf = calloc(1, sizeof(buf_element_t));
buf->mem = multi_buffer;
multi_buffer += buf_size;
diff --git a/src/xine-engine/buffer.h b/src/xine-engine/buffer.h
index 3a3f06e9b..6928ebd96 100644
--- a/src/xine-engine/buffer.h
+++ b/src/xine-engine/buffer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2004 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -35,10 +35,7 @@
extern "C" {
#endif
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
+#include <string.h>
#include <stdio.h>
#include <pthread.h>
#include <sys/types.h>
@@ -191,6 +188,7 @@ extern "C" {
#define BUF_VIDEO_THEORA_RAW 0x02640000
#define BUF_VIDEO_VC1 0x02650000
#define BUF_VIDEO_VMNC 0x02660000
+#define BUF_VIDEO_SNOW 0x02670000
/* audio buffer types: (please keep in sync with buffer_types.c) */
@@ -258,6 +256,9 @@ extern "C" {
#define BUF_AUDIO_SMACKER 0x033B0000
#define BUF_AUDIO_FLVADPCM 0x033C0000
#define BUF_AUDIO_WAVPACK 0x033D0000
+#define BUF_AUDIO_MP3ADU 0x033E0000
+#define BUF_AUDIO_AMR_NB 0x033F0000
+#define BUF_AUDIO_AMR_WB 0x03400000
/* spu buffer types: */
@@ -373,13 +374,16 @@ struct buf_element_s {
* decoder_info[2] carries denominator for display aspect ratio */
#define BUF_FLAG_ASPECT 0x0800
+/* represent the state of gapless_switch at the time buf was enqueued */
+#define BUF_FLAG_GAPLESS_SW 0x1000
+
/* Amount of audio padding added by encoder (mp3, aac). These empty
* audio frames are causing a gap when switching between mp3 files.
* decoder_info[1] carries amount of audio frames padded at the
* beginning of the buffer
* decoder_info[2] carries amount of audio frames padded at the end of
* the buffer */
-#define BUF_FLAG_AUDIO_PADDING 0x1000
+#define BUF_FLAG_AUDIO_PADDING 0x2000
/* Special buffer types:
* Sometimes there is a need to relay special information from a demuxer
@@ -613,8 +617,8 @@ struct fifo_buffer_s
* allocate num_buffers of buf_size bytes each
*/
-fifo_buffer_t *_x_fifo_buffer_new (int num_buffers, uint32_t buf_size) XINE_PROTECTED;
-fifo_buffer_t *_x_dummy_fifo_buffer_new (int num_buffers, uint32_t buf_size) XINE_PROTECTED;
+fifo_buffer_t *_x_fifo_buffer_new (int num_buffers, uint32_t buf_size) XINE_MALLOC XINE_PROTECTED;
+fifo_buffer_t *_x_dummy_fifo_buffer_new (int num_buffers, uint32_t buf_size) XINE_MALLOC XINE_PROTECTED;
/* return BUF_VIDEO_xxx given the fourcc
@@ -624,16 +628,16 @@ fifo_buffer_t *_x_dummy_fifo_buffer_new (int num_buffers, uint32_t buf_size) XIN
uint32_t _x_fourcc_to_buf_video( uint32_t fourcc_int ) XINE_PROTECTED;
/* return codec name given BUF_VIDEO_xxx */
-char * _x_buf_video_name( uint32_t buf_type ) XINE_PROTECTED;
+const char * _x_buf_video_name( uint32_t buf_type ) XINE_PROTECTED;
/* return BUF_AUDIO_xxx given the formattag */
uint32_t _x_formattag_to_buf_audio( uint32_t formattag ) XINE_PROTECTED;
/* return codec name given BUF_AUDIO_xxx */
-char * _x_buf_audio_name( uint32_t buf_type ) XINE_PROTECTED;
+const char * _x_buf_audio_name( uint32_t buf_type ) XINE_PROTECTED;
-#ifndef ATTRIBUTE_PACKED
+#ifndef SUPPORT_ATTRIBUTE_PACKED
/* no attribute packed? let's try with pragma pack as a last resort */
#pragma pack(2)
#endif
@@ -642,7 +646,7 @@ char * _x_buf_audio_name( uint32_t buf_type ) XINE_PROTECTED;
* - will always use machine endian format, so demuxers reading
* stuff from win32 formats must use the function below.
*/
-typedef struct __attribute__((__packed__)) {
+typedef struct XINE_PACKED {
int32_t biSize;
int32_t biWidth;
int32_t biHeight;
@@ -659,7 +663,7 @@ typedef struct __attribute__((__packed__)) {
/* this is xine version of WAVEFORMATEX
* (the same comments from xine_bmiheader)
*/
-typedef struct __attribute__((__packed__)) {
+typedef struct XINE_PACKED {
int16_t wFormatTag;
int16_t nChannels;
int32_t nSamplesPerSec;
@@ -668,7 +672,7 @@ typedef struct __attribute__((__packed__)) {
int16_t wBitsPerSample;
int16_t cbSize;
} xine_waveformatex;
-#ifndef ATTRIBUTE_PACKED
+#ifndef SUPPORT_ATTRIBUTE_PACKED
#pragma pack()
#endif
@@ -678,6 +682,10 @@ void _x_bmiheader_le2me( xine_bmiheader *bih ) XINE_PROTECTED;
/* convert xine_waveformatex struct from little endian */
void _x_waveformatex_le2me( xine_waveformatex *wavex ) XINE_PROTECTED;
+static __inline int _x_is_fourcc(void *ptr, void *tag) {
+ return memcmp(ptr, tag, 4) == 0;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/src/xine-engine/buffer_types.c b/src/xine-engine/buffer_types.c
index 7242738e1..b7571d1d7 100644
--- a/src/xine-engine/buffer_types.c
+++ b/src/xine-engine/buffer_types.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2005 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -659,6 +659,8 @@ static const video_db_t video_db[] = {
ME_FOURCC('a','v','c','1'),
ME_FOURCC('h','2','6','4'),
ME_FOURCC('H','2','6','4'),
+ ME_FOURCC('x','2','6','4'),
+ ME_FOURCC('X','2','6','4'),
0
},
BUF_VIDEO_H264,
@@ -779,6 +781,14 @@ static const video_db_t video_db[] = {
BUF_VIDEO_VMNC,
"VMware Screen Codec"
},
+{
+ {
+ ME_FOURCC('S','N','O','W'),
+ 0
+ },
+ BUF_VIDEO_SNOW,
+ "Snow"
+},
{ { 0 }, 0, "last entry" }
};
@@ -806,6 +816,14 @@ static const audio_db_t audio_db[] = {
},
{
{
+ ME_FOURCC('a', 'd', 'u', 0x55),
+ 0
+ },
+ BUF_AUDIO_MP3ADU,
+ "MPEG layer-3 adu"
+},
+{
+ {
ME_FOURCC('t','w','o','s'),
ME_FOURCC('i','n','2','4'),
0
@@ -1132,11 +1150,32 @@ static const audio_db_t audio_db[] = {
},
{
{
- 0
+ ME_FOURCC('W', 'V', 'P', 'K'),
},
BUF_AUDIO_WAVPACK,
"Wavpack"
},
+{
+ {
+ ME_FOURCC('s', 'a', 'm', 'r'),
+ },
+ BUF_AUDIO_AMR_NB,
+ "AMR narrow band"
+},
+{
+ {
+ ME_FOURCC('s', 'a', 'w', 'b'),
+ },
+ BUF_AUDIO_AMR_WB,
+ "AMR wide band"
+},
+{
+ {
+ ME_FOURCC('T', 'T', 'A', '1'),
+ },
+ BUF_AUDIO_TTA,
+ "True Audio Lossless"
+},
{ { 0 }, 0, "last entry" }
};
@@ -1161,7 +1200,7 @@ static uint32_t cached_buf_type=0;
return 0;
}
-char * _x_buf_video_name( uint32_t buf_type ) {
+const char * _x_buf_video_name( uint32_t buf_type ) {
int i;
buf_type &= 0xffff0000;
@@ -1195,7 +1234,7 @@ static uint32_t cached_buf_type=0;
return 0;
}
-char * _x_buf_audio_name( uint32_t buf_type ) {
+const char * _x_buf_audio_name( uint32_t buf_type ) {
int i;
buf_type &= 0xffff0000;
diff --git a/src/xine-engine/configfile.c b/src/xine-engine/configfile.c
index 2dc89f0af..81acab348 100644
--- a/src/xine-engine/configfile.c
+++ b/src/xine-engine/configfile.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2004 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -319,11 +319,11 @@ static void config_insert(config_values_t *this, cfg_entry_t *new_entry) {
this->first = new_entry;
}
-static cfg_entry_t *config_add (config_values_t *this, const char *key, int exp_level) {
+static cfg_entry_t *XINE_MALLOC config_add (config_values_t *this, const char *key, int exp_level) {
cfg_entry_t *entry;
- entry = (cfg_entry_t *) xine_xmalloc (sizeof (cfg_entry_t));
+ entry = calloc (1, sizeof (cfg_entry_t));
entry->config = this;
entry->key = strdup(key);
entry->type = XINE_CONFIG_TYPE_UNKNOWN;
@@ -356,22 +356,22 @@ static const char *config_xlate_internal (const char *key, const xine_config_ent
return NULL;
}
-static const char *config_translate_key (const char *key) {
+static const char *config_translate_key (const char *key, char **tmp) {
/* Returns translated key or, if no translation found, NULL.
* Translated key may be in a static buffer allocated within this function.
* NOT re-entrant; assumes that config_lock is held.
*/
unsigned trans;
- static char *newkey = NULL;
+ const char *newkey = NULL;
/* first, special-case the decoder entries (so that new ones can be added
* without requiring modification of the translation table)
*/
+ *tmp = NULL;
if (!strncmp (key, "decoder.", 8) &&
!strcmp (key + (trans = strlen (key)) - 9, "_priority")) {
- newkey = realloc (newkey, trans + 27 - 17); /* diff. in string lengths */
- sprintf (newkey, "engine.decoder_priorities.%.*s", trans - 17, key + 8);
- return newkey;
+ asprintf (tmp, "engine.decoder_priorities.%.*s", trans - 17, key + 8);
+ return *tmp;
}
/* search the translation table... */
@@ -386,6 +386,7 @@ static void config_lookup_entry_int (config_values_t *this, const char *key,
cfg_entry_t **entry, cfg_entry_t **prev) {
int trans;
+ char *tmp = NULL;
/* try twice at most (second time with translation from old key name) */
for (trans = 2; trans; --trans) {
@@ -397,14 +398,18 @@ static void config_lookup_entry_int (config_values_t *this, const char *key,
*entry = (*entry)->next;
}
- if (*entry)
+ if (*entry) {
+ free(tmp);
return;
+ }
/* we did not find a match, maybe this is an old config entry name
* trying to translate */
- key = config_translate_key(key);
- if (!key)
+ key = config_translate_key(key, &tmp);
+ if (!key) {
+ free(tmp);
return;
+ }
}
}
@@ -748,7 +753,7 @@ static int config_register_enum (config_values_t *this,
entry->type = XINE_CONFIG_TYPE_ENUM;
if (entry->unknown_value)
- entry->num_value = config_parse_enum (entry->unknown_value, values);
+ entry->num_value = config_parse_enum (entry->unknown_value, (const char **)values);
else
entry->num_value = def_value;
@@ -756,14 +761,14 @@ static int config_register_enum (config_values_t *this,
entry->num_default = def_value;
/* allocate and copy the enum values */
- value_src = values;
+ value_src = (const char **)values;
value_count = 0;
while (*value_src) {
value_src++;
value_count++;
}
entry->enum_values = malloc (sizeof(char*) * (value_count + 1));
- value_src = values;
+ value_src = (const char **)values;
value_dest = entry->enum_values;
while (*value_src) {
*value_dest = strdup(*value_src);
@@ -862,7 +867,7 @@ static void config_update_string (config_values_t *this,
/* if an enum is updated with a string, we convert the string to
* its index and use update number */
if (entry->type == XINE_CONFIG_TYPE_ENUM) {
- config_update_num(this, key, config_parse_enum(value, entry->enum_values));
+ config_update_num(this, key, config_parse_enum(value, (const char **)entry->enum_values));
return;
}
@@ -944,15 +949,17 @@ void xine_config_load (xine_t *xine, const char *filename) {
if (!(entry = config_lookup_entry(this, line))) {
const char *key = line;
+ char *tmp = NULL;
pthread_mutex_lock(&this->config_lock);
if (this->current_version < CONFIG_FILE_VERSION) {
/* old config file -> let's see if we have to rename this one */
- key = config_translate_key(key);
+ key = config_translate_key(key, &tmp);
if (!key)
key = line; /* no translation? fall back on untranslated key */
}
entry = config_add (this, key, 50);
entry->unknown_value = strdup(value);
+ free(tmp);
pthread_mutex_unlock(&this->config_lock);
} else {
switch (entry->type) {
@@ -1005,7 +1012,7 @@ void xine_config_save (xine_t *xine, const char *filename) {
char *buf = NULL;
size_t rlen;
- buf = (char *) xine_xmalloc(config_stat.st_size + 1);
+ buf = (char *) malloc(config_stat.st_size + 1);
if((rlen = fread(buf, 1, config_stat.st_size, f_config)) && ((off_t)rlen == config_stat.st_size)) {
(void) fwrite(buf, 1, rlen, f_backup);
}
@@ -1204,7 +1211,7 @@ config_values_t *_x_config_init (void) {
config_values_t *this;
pthread_mutexattr_t attr;
- if (!(this = xine_xmalloc(sizeof(config_values_t)))) {
+ if (!(this = calloc(1, sizeof(config_values_t)))) {
printf ("configfile: could not allocate config object\n");
_x_abort();
diff --git a/src/xine-engine/configfile.h b/src/xine-engine/configfile.h
index e21b08db0..e1dca7b18 100644
--- a/src/xine-engine/configfile.h
+++ b/src/xine-engine/configfile.h
@@ -200,7 +200,7 @@ struct config_values_s {
/*
* allocate and init a new xine config object
*/
-config_values_t *_x_config_init (void) XINE_PROTECTED;
+config_values_t *_x_config_init (void) XINE_MALLOC XINE_PROTECTED;
/*
* interpret stream_setup part of mrls for config value changes
diff --git a/src/xine-engine/demux.c b/src/xine-engine/demux.c
index f33397256..698b44988 100644
--- a/src/xine-engine/demux.c
+++ b/src/xine-engine/demux.c
@@ -21,6 +21,9 @@
* hide some xine engine details from demuxers and reduce code duplication
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
#include <stdio.h>
#include <string.h>
@@ -47,11 +50,6 @@
#include <winsock.h>
#endif
-#ifdef MIN
-#undef MIN
-#endif
-#define MIN(a,b) ( (a) < (b) ) ? (a) : (b)
-
/*
* Flush audio and video buffers. It is called from demuxers on
* seek/stop, and may be useful when user input changes a stream and
@@ -122,6 +120,16 @@ void _x_demux_flush_engine (xine_stream_t *stream) {
}
+static struct timespec _x_compute_interval(unsigned int millisecs) {
+ struct timespec ts;
+ clock_gettime(CLOCK_REALTIME, &ts);
+ uint64_t ttimer = (uint64_t)ts.tv_sec*1000 + ts.tv_nsec/1000000 + millisecs;
+ ts.tv_sec = ttimer/1000;
+ ts.tv_nsec = (ttimer%1000)*1000000;
+ return ts;
+}
+
+
void _x_demux_control_newpts( xine_stream_t *stream, int64_t pts, uint32_t flags ) {
buf_element_t *buf;
@@ -143,6 +151,29 @@ void _x_demux_control_newpts( xine_stream_t *stream, int64_t pts, uint32_t flags
pthread_mutex_unlock(&stream->demux_mutex);
}
+/* avoid ao_loop being stuck in a pthread_cond_wait, waiting for data;
+ * return 1 if the stream is stopped
+ * (better fix wanted!)
+ */
+static int demux_unstick_ao_loop (xine_stream_t *stream)
+{
+/* if (!stream->audio_thread_created)
+ return 0;
+*/
+ int status = xine_get_status (stream);
+ if (status != XINE_STATUS_QUIT && status != XINE_STATUS_STOP && stream->demux_plugin->get_status(stream->demux_plugin) != DEMUX_FINISHED)
+ return 0;
+#if 0
+ /* right, stream is stopped... */
+ audio_buffer_t *buf = stream->audio_out->get_buffer (stream->audio_out);
+ buf->num_frames = 0;
+ buf->stream = NULL;
+ stream->audio_out->put_buffer (stream->audio_out, buf, stream);
+#endif
+ lprintf("stuck\n");
+ return 1;
+}
+
/* sync with decoder fifos, making sure everything gets processed */
void _x_demux_control_headers_done (xine_stream_t *stream) {
@@ -180,24 +211,31 @@ void _x_demux_control_headers_done (xine_stream_t *stream) {
stream->audio_fifo->put (stream->audio_fifo, buf_audio);
pthread_mutex_unlock(&stream->demux_mutex);
+ unsigned int max_iterations = 0;
while ((stream->header_count_audio < header_count_audio) ||
(stream->header_count_video < header_count_video)) {
- struct timeval tv;
- struct timespec ts;
lprintf ("waiting for headers. v:%d %d a:%d %d\n",
stream->header_count_video, header_count_video,
stream->header_count_audio, header_count_audio);
+
+ struct timespec ts = _x_compute_interval(1000);
+ int ret_wait;
- gettimeofday(&tv, NULL);
- ts.tv_sec = tv.tv_sec + 1;
- ts.tv_nsec = tv.tv_usec * 1000;
/* use timedwait to workaround buggy pthread broadcast implementations */
- pthread_cond_timedwait (&stream->counter_changed, &stream->counter_lock, &ts);
+ ret_wait = pthread_cond_timedwait (&stream->counter_changed, &stream->counter_lock, &ts);
+
+ if (ret_wait == ETIMEDOUT && demux_unstick_ao_loop (stream) && ++max_iterations > 4) {
+ xine_log(stream->xine,
+ XINE_LOG_MSG,_("Stuck in _x_demux_control_headers_done(). Taking the emergency exit\n"));
+ stream->emergency_brake = 1;
+ break;
+ }
}
stream->demux_action_pending = 0;
+ pthread_cond_signal(&stream->demux_resume);
lprintf ("headers processed.\n");
@@ -207,15 +245,18 @@ void _x_demux_control_headers_done (xine_stream_t *stream) {
void _x_demux_control_start( xine_stream_t *stream ) {
buf_element_t *buf;
+ uint32_t flags = (stream->gapless_switch) ? BUF_FLAG_GAPLESS_SW : 0;
pthread_mutex_lock(&stream->demux_mutex);
buf = stream->video_fifo->buffer_pool_alloc (stream->video_fifo);
buf->type = BUF_CONTROL_START;
+ buf->decoder_flags = flags;
stream->video_fifo->put (stream->video_fifo, buf);
buf = stream->audio_fifo->buffer_pool_alloc (stream->audio_fifo);
buf->type = BUF_CONTROL_START;
+ buf->decoder_flags = flags;
stream->audio_fifo->put (stream->audio_fifo, buf);
pthread_mutex_unlock(&stream->demux_mutex);
@@ -284,12 +325,14 @@ static void *demux_loop (void *stream_gen) {
/* someone may want to interrupt us */
if( stream->demux_action_pending ) {
- pthread_mutex_unlock( &stream->demux_lock );
-
- lprintf ("sched_yield\n");
+ struct timeval tv;
+ struct timespec ts;
- sched_yield();
- pthread_mutex_lock( &stream->demux_lock );
+ gettimeofday(&tv, NULL);
+ ts.tv_sec = tv.tv_sec;
+ ts.tv_nsec = (tv.tv_usec + 100000) * 1000;
+
+ pthread_cond_timedwait (&stream->demux_resume, &stream->demux_lock, &ts);
}
}
@@ -345,10 +388,21 @@ static void *demux_loop (void *stream_gen) {
pthread_mutex_unlock( &stream->demux_lock );
pthread_mutex_lock (&stream->counter_lock);
+ struct timespec ts;
+ unsigned int max_iterations = 0;
+ int ret_wait;
while ((stream->finished_count_audio < finished_count_audio) ||
(stream->finished_count_video < finished_count_video)) {
lprintf ("waiting for finisheds.\n");
- pthread_cond_wait (&stream->counter_changed, &stream->counter_lock);
+ ts = _x_compute_interval(1000);
+ ret_wait = pthread_cond_timedwait (&stream->counter_changed, &stream->counter_lock, &ts);
+
+ if (ret_wait == ETIMEDOUT && demux_unstick_ao_loop (stream) && ++max_iterations > 4) {
+ xine_log(stream->xine,
+ XINE_LOG_MSG,_("Stuck in demux_loop(). Taking the emergency exit\n"));
+ stream->emergency_brake = 1;
+ break;
+ }
}
pthread_mutex_unlock (&stream->counter_lock);
@@ -365,6 +419,7 @@ int _x_demux_start_thread (xine_stream_t *stream) {
stream->demux_action_pending = 1;
pthread_mutex_lock( &stream->demux_lock );
stream->demux_action_pending = 0;
+ pthread_cond_signal(&stream->demux_resume);
if( !stream->demux_thread_running ) {
@@ -396,6 +451,7 @@ int _x_demux_stop_thread (xine_stream_t *stream) {
pthread_mutex_lock( &stream->demux_lock );
stream->demux_thread_running = 0;
stream->demux_action_pending = 0;
+ pthread_cond_signal(&stream->demux_resume);
/* At that point, the demuxer has sent the last audio/video buffer,
* so it's a safe place to flush the engine.
@@ -435,7 +491,7 @@ int _x_demux_read_header( input_plugin_t *input, unsigned char *buffer, off_t si
read_size = input->read(input, buffer, size);
input->seek(input, 0, SEEK_SET);
} else if (input->get_capabilities(input) & INPUT_CAP_PREVIEW) {
- buf = xine_xmalloc(MAX_PREVIEW_SIZE);
+ buf = malloc(MAX_PREVIEW_SIZE);
read_size = input->get_optional_data(input, buf, INPUT_OPTIONAL_DATA_PREVIEW);
read_size = MIN (read_size, size);
memcpy(buffer, buf, read_size);
@@ -652,7 +708,7 @@ void _x_demux_send_mrl_reference (xine_stream_t *stream, int alternative,
xine_mrl_reference_data_ext_t *e;
xine_mrl_reference_data_t *b;
} data;
- int mrl_len = strlen (mrl);
+ const size_t mrl_len = strlen (mrl);
if (!title)
title = "";
diff --git a/src/xine-engine/info_helper.c b/src/xine-engine/info_helper.c
index 1ac4ed982..6ce9bcd38 100644
--- a/src/xine-engine/info_helper.c
+++ b/src/xine-engine/info_helper.c
@@ -131,7 +131,7 @@ uint32_t _x_stream_info_get_public(xine_stream_t *stream, int info) {
* at the end of the string
*/
static void meta_info_chomp(char *str) {
- int i, len;
+ ssize_t i, len;
len = strlen(str);
if (!len)
@@ -251,7 +251,15 @@ static void meta_info_set_unlocked_encoding(xine_stream_t *stream, int info, con
size_t inbytesleft, outbytesleft;
inbuf = (ICONV_CONST char *)value;
- inbytesleft = strlen(value);
+ if (!strncmp (enc, "UTF-16", 6) || !strncmp (enc, "UCS-2", 5))
+ {
+ /* strlen() won't work with UTF-16* or UCS-2* */
+ inbytesleft = 0;
+ while (value[inbytesleft] || value[inbytesleft + 1])
+ inbytesleft += 2;
+ } /* ... do we need to handle UCS-4? Probably not. */
+ else
+ inbytesleft = strlen(value);
outbytesleft = 4 * inbytesleft; /* estimative (max) */
outbuf = utf8_value = malloc(outbytesleft+1);
@@ -340,11 +348,10 @@ void _x_meta_info_set_utf8(xine_stream_t *stream, int info, const char *str) {
void _x_meta_info_n_set(xine_stream_t *stream, int info, const char *buf, int len) {
pthread_mutex_lock(&stream->meta_mutex);
if(meta_valid(info) && len) {
- char *str = xine_xmalloc(len + 1);
+ char *str = strndup(buf, len);
- snprintf(str, len + 1 , "%s", buf);
- meta_info_set_unlocked(stream, info, (const char *) &str[0]);
- free(str);
+ meta_info_set_unlocked(stream, info, str);
+ free(str);
}
pthread_mutex_unlock(&stream->meta_mutex);
}
@@ -359,7 +366,7 @@ void _x_meta_info_set_multi(xine_stream_t *stream, int info, ...) {
va_list ap;
char *args[1025];
char *buf;
- int n, len;
+ size_t n, len;
len = n = 0;
@@ -376,7 +383,7 @@ void _x_meta_info_set_multi(xine_stream_t *stream, int info, ...) {
if(len) {
char *p, *meta;
- p = meta = (char *) xine_xmalloc(len + 1);
+ p = meta = (char *) malloc(len + 1);
n = 0;
while(args[n]) {
diff --git a/src/xine-engine/input_cache.c b/src/xine-engine/input_cache.c
index 30b1ba4aa..4eb524af6 100644
--- a/src/xine-engine/input_cache.c
+++ b/src/xine-engine/input_cache.c
@@ -356,7 +356,7 @@ input_plugin_t *_x_cache_plugin_get_instance (xine_stream_t *stream, int readahe
lprintf("mrl: %s\n", main_plugin->get_mrl(main_plugin));
- this = (cache_input_plugin_t *)xine_xmalloc(sizeof(cache_input_plugin_t));
+ this = calloc(1, sizeof(cache_input_plugin_t));
if (!this)
return NULL;
@@ -386,7 +386,7 @@ input_plugin_t *_x_cache_plugin_get_instance (xine_stream_t *stream, int readahe
this->buf_size = DEFAULT_BUFFER_SIZE;
}
- this->buf = (char *)xine_xmalloc(this->buf_size);
+ this->buf = calloc(1, this->buf_size);
if (!this->buf) {
free (this);
return NULL;
diff --git a/src/xine-engine/input_rip.c b/src/xine-engine/input_rip.c
index 0c185aa1b..8db7eaaf5 100644
--- a/src/xine-engine/input_rip.c
+++ b/src/xine-engine/input_rip.c
@@ -517,10 +517,9 @@ static void rip_plugin_dispose(input_plugin_t *this_gen) {
* returns non-zero, if there was enough space
*/
static int dir_file_concat(char *target, size_t maxlen, const char *dir, const char *name) {
- size_t len_dir, len_name, pos_name = 0;
-
- len_name = strlen(name);
- len_dir = strlen(dir);
+ size_t len_name = strlen(name);
+ size_t len_dir = strlen(dir);
+ size_t pos_name = 0;
/* remove slashes */
if (dir[len_dir - 1] == '/') len_dir--;
@@ -585,7 +584,7 @@ input_plugin_t *_x_rip_plugin_get_instance (xine_stream_t *stream, const char *f
return NULL;
}
- this = (rip_input_plugin_t *)xine_xmalloc(sizeof(rip_input_plugin_t));
+ this = calloc(1, sizeof(rip_input_plugin_t));
this->main_input_plugin = main_plugin;
this->stream = stream;
this->curpos = 0;
diff --git a/src/xine-engine/load_plugins.c b/src/xine-engine/load_plugins.c
index 71cb19d3b..5128644da 100644
--- a/src/xine-engine/load_plugins.c
+++ b/src/xine-engine/load_plugins.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2006 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -313,7 +313,6 @@ static void _insert_node (xine_t *this,
const input_info_t *input_old;
uint32_t *types;
char key[80];
- char desc[100];
int i;
_x_assert(list);
@@ -325,8 +324,8 @@ static void _insert_node (xine_t *this,
return;
}
- entry = xine_xmalloc(sizeof(plugin_node_t));
- entry->info = xine_xmalloc(sizeof(plugin_info_t));
+ entry = calloc(1, sizeof(plugin_node_t));
+ entry->info = calloc(1, sizeof(plugin_info_t));
*(entry->info) = *info;
entry->info->id = strdup(info->id);
entry->info->init = info->init;
@@ -339,7 +338,7 @@ static void _insert_node (xine_t *this,
case PLUGIN_VIDEO_OUT:
vo_old = info->special_info;
- vo_new = xine_xmalloc(sizeof(vo_info_t));
+ vo_new = calloc(1, sizeof(vo_info_t));
entry->priority = vo_new->priority = vo_old->priority;
vo_new->visual_type = vo_old->visual_type;
entry->info->special_info = vo_new;
@@ -347,7 +346,7 @@ static void _insert_node (xine_t *this,
case PLUGIN_AUDIO_OUT:
ao_old = info->special_info;
- ao_new = xine_xmalloc(sizeof(ao_info_t));
+ ao_new = calloc(1, sizeof(ao_info_t));
entry->priority = ao_new->priority = ao_old->priority;
entry->info->special_info = ao_new;
break;
@@ -356,7 +355,7 @@ static void _insert_node (xine_t *this,
case PLUGIN_VIDEO_DECODER:
case PLUGIN_SPU_DECODER:
decoder_old = info->special_info;
- decoder_new = xine_xmalloc(sizeof(decoder_info_t));
+ decoder_new = calloc(1, sizeof(decoder_info_t));
if (decoder_old == NULL) {
if (file)
xprintf (this, XINE_VERBOSITY_DEBUG,
@@ -368,22 +367,21 @@ static void _insert_node (xine_t *this,
info->id);
_x_abort();
}
- for (i=0; decoder_old->supported_types[i] != 0; ++i);
- types = xine_xmalloc((i+1)*sizeof(uint32_t));
- for (i=0; decoder_old->supported_types[i] != 0; ++i){
- types[i] = decoder_old->supported_types[i];
+ {
+ size_t supported_types_size;
+ for (supported_types_size=0; decoder_old->supported_types[supported_types_size] != 0; ++supported_types_size);
+ types = calloc((supported_types_size+1), sizeof(uint32_t));
+ memcpy(types, decoder_old->supported_types, supported_types_size*sizeof(uint32_t));
+ decoder_new->supported_types = types;
}
- decoder_new->supported_types = types;
entry->priority = decoder_new->priority = decoder_old->priority;
snprintf(key, sizeof(key), "engine.decoder_priorities.%s", info->id);
- snprintf(desc, sizeof(desc), _("priority for %s decoder"), info->id);
/* write the description on the heap because the config system
* does not strdup() it, so we have to provide a different pointer
* for each decoder */
for (i = 0; catalog->prio_desc[i]; i++);
- catalog->prio_desc[i] = malloc(strlen(desc) + 1);
- strcpy(catalog->prio_desc[i], desc);
+ asprintf(&catalog->prio_desc[i], _("priority for %s decoder"), info->id);
this->config->register_num (this->config,
key,
0,
@@ -402,14 +400,14 @@ static void _insert_node (xine_t *this,
case PLUGIN_POST:
post_old = info->special_info;
- post_new = xine_xmalloc(sizeof(post_info_t));
+ post_new = calloc(1, sizeof(post_info_t));
post_new->type = post_old->type;
entry->info->special_info = post_new;
break;
case PLUGIN_DEMUX:
demux_old = info->special_info;
- demux_new = xine_xmalloc(sizeof(demuxer_info_t));
+ demux_new = calloc(1, sizeof(demuxer_info_t));
if (demux_old) {
entry->priority = demux_new->priority = demux_old->priority;
@@ -426,7 +424,7 @@ static void _insert_node (xine_t *this,
case PLUGIN_INPUT:
input_old = info->special_info;
- input_new = xine_xmalloc(sizeof(input_info_t));
+ input_new = calloc(1, sizeof(input_info_t));
if (input_old) {
entry->priority = input_new->priority = input_old->priority;
@@ -463,12 +461,12 @@ static int _plugin_node_comparator(void *a, void *b) {
}
}
-static plugin_catalog_t *_new_catalog(void){
+static plugin_catalog_t *XINE_MALLOC _new_catalog(void){
plugin_catalog_t *catalog;
int i;
- catalog = xine_xmalloc(sizeof(plugin_catalog_t));
+ catalog = calloc(1, sizeof(plugin_catalog_t));
for (i = 0; i < PLUGIN_TYPE_MAX; i++) {
catalog->plugin_lists[i] = xine_sarray_new(0, _plugin_node_comparator);
@@ -487,7 +485,7 @@ static void _register_plugins_internal(xine_t *this, plugin_file_t *file, plugin
while ( info && info->type != PLUGIN_NONE ) {
- if (file)
+ if (file && file->filename)
xine_log (this, XINE_LOG_PLUGIN,
_("load_plugins: plugin %s found\n"), file->filename);
else
@@ -556,25 +554,20 @@ static void collect_plugins(xine_t *this, char *path){
dir = opendir(path);
if (dir) {
struct dirent *pEntry;
- size_t path_len, str_size;
- char *str = NULL;
- path_len = strlen(path);
- str_size = path_len * 2 + 2; /* +2 for '/' and '\0' */
- str = malloc(str_size);
- xine_fast_memcpy(str, path, path_len);
- str[path_len] = '/';
- str[path_len + 1] = '\0';
+ size_t path_len = strlen(path);
+ size_t str_size = path_len * 2 + 2; /* +2 for '/' and '\0' */
+ char *str = malloc(str_size);
+ sprintf(str, "%s/", path);
while ((pEntry = readdir (dir)) != NULL) {
- size_t new_str_size, d_len;
void *lib = NULL;
plugin_info_t *info = NULL;
struct stat statbuffer;
- d_len = strlen(pEntry->d_name);
- new_str_size = path_len + d_len + 2;
+ size_t d_len = strlen(pEntry->d_name);
+ size_t new_str_size = path_len + d_len + 2;
if (str_size < new_str_size) {
str_size = new_str_size + new_str_size / 2;
str = realloc(str, str_size);
@@ -599,7 +592,7 @@ static void collect_plugins(xine_t *this, char *path){
#if defined(__hpux)
if(!strstr(str, ".sl")
#elif defined(__CYGWIN__) || defined(WIN32)
- if(!strstr(str, ".dll")
+ if(!strstr(str, ".dll") || strstr(str, ".dll.a")
#else
if(!strstr(str, ".so")
#endif
@@ -941,11 +934,11 @@ static void load_plugin_list(FILE *fp, xine_sarray_t *plugins) {
if( node ) {
xine_sarray_add (plugins, node);
}
- node = xine_xmalloc(sizeof(plugin_node_t));
- file = xine_xmalloc(sizeof(plugin_file_t));
+ node = calloc(1, sizeof(plugin_node_t));
+ file = calloc(1, sizeof(plugin_file_t));
node->file = file;
file->filename = strdup(line+1);
- node->info = xine_xmalloc(2*sizeof(plugin_info_t));
+ node->info = calloc(2, sizeof(plugin_info_t));
node->info[1].type = PLUGIN_NONE;
decoder_info = NULL;
vo_info = NULL;
@@ -981,34 +974,34 @@ static void load_plugin_list(FILE *fp, xine_sarray_t *plugins) {
case PLUGIN_VIDEO_OUT:
node->info->special_info = vo_info =
- xine_xmalloc(sizeof(vo_info_t));
+ calloc(1, sizeof(vo_info_t));
break;
case PLUGIN_AUDIO_OUT:
node->info->special_info = ao_info =
- xine_xmalloc(sizeof(ao_info_t));
+ calloc(1, sizeof(ao_info_t));
break;
case PLUGIN_DEMUX:
node->info->special_info = demuxer_info =
- xine_xmalloc(sizeof(demuxer_info_t));
+ calloc(1, sizeof(demuxer_info_t));
break;
case PLUGIN_INPUT:
node->info->special_info = input_info =
- xine_xmalloc(sizeof(input_info_t));
+ calloc(1, sizeof(input_info_t));
break;
case PLUGIN_AUDIO_DECODER:
case PLUGIN_VIDEO_DECODER:
case PLUGIN_SPU_DECODER:
node->info->special_info = decoder_info =
- xine_xmalloc(sizeof(decoder_info_t));
+ calloc(1, sizeof(decoder_info_t));
break;
case PLUGIN_POST:
node->info->special_info = post_info =
- xine_xmalloc(sizeof(post_info_t));
+ calloc(1, sizeof(post_info_t));
break;
}
@@ -1029,7 +1022,7 @@ static void load_plugin_list(FILE *fp, xine_sarray_t *plugins) {
for( s = value, i = 0; s && sscanf(s," %lu",&lu) > 0; i++ ) {
s = strchr(s+1, ' ');
}
- decoder_info->supported_types = xine_xmalloc((i+1)*sizeof(uint32_t));
+ decoder_info->supported_types = calloc((i+1), sizeof(uint32_t));
for( s = value, i = 0; s && sscanf(s," %lu",&lu) > 0; i++ ) {
decoder_info->supported_types[i] = lu;
s = strchr(s+1, ' ');
@@ -1069,22 +1062,21 @@ static void load_plugin_list(FILE *fp, xine_sarray_t *plugins) {
static void save_catalog (xine_t *this) {
FILE *fp;
- char *cachefile, *dirfile;
+ char *cachefile, *cachefile_new, *dirfile;
const char *relname = CACHE_CATALOG_FILE;
const char *dirname = CACHE_CATALOG_DIR;
+
+ const char *const homedir = xine_get_homedir();
- cachefile = (char *) xine_xmalloc(strlen(xine_get_homedir()) +
- strlen(relname) + 2);
- sprintf(cachefile, "%s/%s", xine_get_homedir(), relname);
+ asprintf(&cachefile, "%s/%s", homedir, relname);
+ asprintf(&cachefile_new, "%s.new", cachefile);
/* make sure homedir (~/.xine) exists */
- dirfile = (char *) xine_xmalloc(strlen(xine_get_homedir()) +
- strlen(dirname) + 2);
- sprintf(dirfile, "%s/%s", xine_get_homedir(), dirname);
+ asprintf(&dirfile, "%s/%s", homedir, dirname);
mkdir (dirfile, 0755);
free (dirfile);
- if( (fp = fopen(cachefile,"w")) != NULL ) {
+ if( (fp = fopen(cachefile_new,"w")) != NULL ) {
int i;
fprintf(fp, "# this file is automatically created by xine, do not edit.\n\n");
@@ -1093,9 +1085,29 @@ static void save_catalog (xine_t *this) {
for (i = 0; i < PLUGIN_TYPE_MAX; i++) {
save_plugin_list (fp, this->plugin_catalog->plugin_lists[i]);
}
- fclose(fp);
+ if (fclose(fp))
+ {
+ const char *err = strerror (errno);
+ xine_log (this, XINE_LOG_MSG,
+ _("failed to save catalogue cache: %s\n"), err);
+ goto do_unlink;
+ }
+ else if (rename (cachefile_new, cachefile))
+ {
+ const char *err = strerror (errno);
+ xine_log (this, XINE_LOG_MSG,
+ _("failed to replace catalogue cache: %s\n"), err);
+ do_unlink:
+ if (unlink (cachefile_new) && errno != ENOENT)
+ {
+ err = strerror (errno);
+ xine_log (this, XINE_LOG_MSG,
+ _("failed to remove new catalogue cache: %s\n"), err);
+ }
+ }
}
free(cachefile);
+ free(cachefile_new);
}
/*
@@ -1107,9 +1119,7 @@ static void load_cached_catalog (xine_t *this) {
char *cachefile;
const char *relname = CACHE_CATALOG_FILE;
- cachefile = (char *) xine_xmalloc(strlen(xine_get_homedir()) +
- strlen(relname) + 2);
- sprintf(cachefile, "%s/%s", xine_get_homedir(), relname);
+ asprintf(&cachefile, "%s/%s", xine_get_homedir(), relname);
if( (fp = fopen(cachefile,"r")) != NULL ) {
load_plugin_list (fp, this->plugin_catalog->cache_list);
@@ -1119,14 +1129,24 @@ static void load_cached_catalog (xine_t *this) {
}
+/* helper function for _x_scan_plugins */
+static void push_if_dir (xine_list_t *plugindirs, void *path)
+{
+ struct stat st;
+ if (!stat (path, &st) && S_ISDIR (st.st_mode))
+ xine_list_push_back (plugindirs, path);
+ else
+ free (path);
+}
+
/*
* initialize catalog, load all plugins into new catalog
*/
void _x_scan_plugins (xine_t *this) {
-
- char *homedir, *plugindir, *pluginpath;
- int i,j;
- int lenpluginpath;
+
+ char *homedir, *pluginpath;
+ xine_list_t *plugindirs = xine_list_new ();
+ xine_list_iterator_t iter;
lprintf("_x_scan_plugins()\n");
@@ -1140,41 +1160,45 @@ void _x_scan_plugins (xine_t *this) {
this->plugin_catalog = _new_catalog();
load_cached_catalog (this);
- if ((pluginpath = getenv("XINE_PLUGIN_PATH")) != NULL) {
- pluginpath = strdup(pluginpath);
+ if ((pluginpath = getenv("XINE_PLUGIN_PATH")) != NULL && *pluginpath) {
+ char *p = pluginpath;
+ while (p && p[0])
+ {
+ size_t len;
+ char *dir, *q;
+
+ q = p;
+ p = strchr (p, XINE_PATH_SEPARATOR_CHAR);
+ if (p) {
+ p++;
+ len = p - q;
+ } else
+ len = strlen(q);
+ if (q[0] == '~' && q[1] == '/')
+ asprintf (&dir, "%s%.*s", homedir, (int)(len - 1), q + 1);
+ else
+ dir = strndup (q, len);
+ push_if_dir (plugindirs, dir); /* store or free it */
+ }
} else {
- const char *str1, *str2;
- int len;
-
- str1 = "~/.xine/plugins";
- str2 = XINE_PLUGINDIR;
- len = strlen(str1) + strlen(str2) + 2;
- pluginpath = xine_xmalloc(len);
- snprintf(pluginpath, len, "%s" XINE_PATH_SEPARATOR_STRING "%s", str1, str2);
- }
- plugindir = xine_xmalloc(strlen(pluginpath)+strlen(homedir)+2);
- j=0;
- lenpluginpath = strlen(pluginpath);
- for (i=0; i <= lenpluginpath; ++i){
- switch (pluginpath[i]){
- case XINE_PATH_SEPARATOR_CHAR:
- case '\0':
- plugindir[j] = '\0';
- collect_plugins(this, plugindir);
- j = 0;
- break;
- case '~':
- if (j == 0){
- strcpy(plugindir, homedir);
- j = strlen(plugindir);
- break;
- }
- default:
- plugindir[j++] = pluginpath[i];
+ char *dir;
+ int i;
+ asprintf (&dir, "%s/.xine/plugins", homedir);
+ push_if_dir (plugindirs, dir);
+ for (i = 0; i <= XINE_LT_AGE; ++i)
+ {
+ asprintf (&dir, "%s.%d", XINE_PLUGINROOT, XINE_LT_AGE - i);
+ push_if_dir (plugindirs, dir);
}
}
- free(plugindir);
- free(pluginpath);
+ for (iter = xine_list_front (plugindirs); iter;
+ iter = xine_list_next (plugindirs, iter))
+ {
+ char *dir = xine_list_get_value (plugindirs, iter);
+ collect_plugins(this, dir);
+ free (dir);
+ }
+ xine_list_delete (plugindirs);
free(homedir);
save_catalog (this);
@@ -1229,6 +1253,26 @@ void _x_free_input_plugin (xine_stream_t *stream, input_plugin_t *input) {
}
}
+static int probe_mime_type (xine_t *self, plugin_node_t *node, const char *mime_type)
+{
+ /* catalog->lock is expected to be locked */
+ if (node->plugin_class || _load_plugin_class(self, node, NULL))
+ {
+ const unsigned int mime_type_len = strlen (mime_type);
+ demux_class_t *cls = (demux_class_t *)node->plugin_class;
+ const char *mime = cls->get_mimetypes (cls);
+ while (mime)
+ {
+ while (*mime == ';' || isspace (*mime))
+ ++mime;
+ if (!strncasecmp (mime, mime_type, mime_type_len) &&
+ (!mime[mime_type_len] || mime[mime_type_len] == ':' || mime[mime_type_len] == ';'))
+ return 1;
+ mime = strchr (mime, ';');
+ }
+ }
+ return 0;
+}
static demux_plugin_t *probe_demux (xine_stream_t *stream, int method1, int method2,
input_plugin_t *input) {
@@ -1251,8 +1295,6 @@ static demux_plugin_t *probe_demux (xine_stream_t *stream, int method1, int meth
while (methods[i] != -1 && !plugin) {
int list_id, list_size;
- stream->content_detection_method = methods[i];
-
pthread_mutex_lock (&catalog->lock);
list_size = xine_sarray_size(catalog->plugin_lists[PLUGIN_DEMUX - 1]);
@@ -1264,6 +1306,25 @@ static demux_plugin_t *probe_demux (xine_stream_t *stream, int method1, int meth
xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "load_plugins: probing demux '%s'\n", node->info->id);
if (node->plugin_class || _load_plugin_class(stream->xine, node, NULL)) {
+ const char *mime_type;
+
+ /* If detecting by MRL, try the MIME type first (but not text/plain)... */
+ stream->content_detection_method = METHOD_EXPLICIT;
+ if (methods[i] == METHOD_BY_EXTENSION &&
+ stream->input_plugin->get_optional_data &&
+ stream->input_plugin->get_optional_data (stream->input_plugin, NULL, INPUT_OPTIONAL_DATA_DEMUX_MIME_TYPE) != INPUT_OPTIONAL_UNSUPPORTED &&
+ stream->input_plugin->get_optional_data (stream->input_plugin, &mime_type, INPUT_OPTIONAL_DATA_MIME_TYPE) != INPUT_OPTIONAL_UNSUPPORTED &&
+ mime_type && strcasecmp (mime_type, "text/plain") &&
+ probe_mime_type (stream->xine, node, mime_type) &&
+ (plugin = ((demux_class_t *)node->plugin_class)->open_plugin (node->plugin_class, stream, input)))
+ {
+ inc_node_ref(node);
+ plugin->node = node;
+ break;
+ }
+
+ /* ... then try the extension */
+ stream->content_detection_method = methods[i];
if ((plugin = ((demux_class_t *)node->plugin_class)->open_plugin(node->plugin_class, stream, input))) {
inc_node_ref(node);
plugin->node = node;
@@ -1659,6 +1720,36 @@ const char *const *xine_list_video_output_plugins (xine_t *xine) {
return catalog->ids;
}
+const char *const *xine_list_video_output_plugins_typed(xine_t *xine, uint64_t typemask)
+{
+ plugin_catalog_t *catalog = xine->plugin_catalog;
+ plugin_node_t *node;
+ int list_id, list_size, i;
+
+ pthread_mutex_lock (&catalog->lock);
+
+ list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_VIDEO_OUT - 1]);
+
+ for (list_id = i = 0; list_id < list_size; list_id++)
+ {
+ node = xine_sarray_get (catalog->plugin_lists[PLUGIN_VIDEO_OUT - 1], list_id);
+ if (typemask & (1ULL << ((vo_info_t *)node->info->special_info)->visual_type))
+ {
+ const char *id = node->info->id;
+ int j = i;
+ while (--j >= 0)
+ if (!strcmp (catalog->ids[j], id))
+ goto ignore; /* already listed */
+ catalog->ids[i++] = id;
+ }
+ ignore: ;
+ }
+ catalog->ids[i] = NULL;
+
+ pthread_mutex_unlock (&catalog->lock);
+ return catalog->ids;
+}
+
static ao_driver_t *_load_audio_driver (xine_t *this, plugin_node_t *node,
void *data) {
@@ -2384,6 +2475,31 @@ void xine_post_dispose(xine_t *xine, xine_post_t *post_gen) {
* their disposal if they are still in use => post.c handles the counting for us */
}
+/**
+ * @brief Concantenates an array of strings into a single
+ * string separated with a given string.
+ *
+ * @param strings Array of strings to concatenate.
+ * @param count Number of elements in the @p strings array.
+ * @param joining String to use to join the various strings together.
+ * @param final_length The pre-calculated final length of the string.
+ */
+static char *_x_concatenate_with_string(char const **strings, size_t count, char *joining, size_t final_length) {
+ size_t i;
+ char *const result = malloc(final_length+1); /* Better be safe */
+ char *str = result;
+
+ for(i = 0; i < count; i++, strings++) {
+ if ( *strings ) {
+ int offset = snprintf(str, final_length, "%s%s", *strings, joining);
+ str += offset;
+ final_length -= offset;
+ }
+ }
+
+ return result;
+}
+
/* get a list of file extensions for file types supported by xine
* the list is separated by spaces
*
@@ -2391,66 +2507,35 @@ void xine_post_dispose(xine_t *xine, xine_post_t *post_gen) {
char *xine_get_file_extensions (xine_t *self) {
plugin_catalog_t *catalog = self->plugin_catalog;
- int len, pos;
- plugin_node_t *node;
- char *str;
- int list_id, list_size;
+ int list_id;
pthread_mutex_lock (&catalog->lock);
- /* calc length of output */
-
- len = 0;
- list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_DEMUX - 1]);
- for (list_id = 0; list_id < list_size; list_id++) {
- demux_class_t *cls;
- const char *exts;
-
- node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id);
- if (node->plugin_class || _load_plugin_class(self, node, NULL)) {
-
- cls = (demux_class_t *)node->plugin_class;
-
- if((exts = cls->get_extensions(cls)) && *exts)
- len += strlen(exts) + 1;
- }
- }
-
- /* create output */
- str = malloc (len); /* '\0' space is already counted in the previous loop */
- pos = 0;
+ /* calc length of output string and create an array of strings to
+ concatenate */
+ size_t len = 0;
+ const int list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_DEMUX - 1]);
+ const char **extensions = calloc(list_size, sizeof(char*));
- list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_DEMUX - 1]);
for (list_id = 0; list_id < list_size; list_id++) {
- demux_class_t *cls;
- const char *e;
- int l;
-
- node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id);
+ plugin_node_t *const node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id);
if (node->plugin_class || _load_plugin_class(self, node, NULL)) {
-
- cls = (demux_class_t *)node->plugin_class;
-
- if((e = cls->get_extensions (cls)) && *e) {
- l = strlen(e);
- memcpy (&str[pos], e, l);
-
- pos += l;
-
- /* Don't add ' ' char at the end of str */
- if((pos + 1) < len) {
- str[pos] = ' ';
- pos++;
- }
- }
+ demux_class_t *const cls = (demux_class_t *)node->plugin_class;
+ if( (extensions[list_id] = cls->get_extensions(cls)) != NULL )
+ len += strlen(extensions[list_id]) +1;
}
}
- str[pos] = 0;
+ /* create output string */
+ char *const result = _x_concatenate_with_string(extensions, list_size, " ", len);
+ free(extensions);
+ /* Drop the last whitespace */
+ result[len-1] = '\0';
+
pthread_mutex_unlock (&catalog->lock);
- return str;
+ return result;
}
/* get a list of mime types supported by xine
@@ -2459,65 +2544,34 @@ char *xine_get_file_extensions (xine_t *self) {
char *xine_get_mime_types (xine_t *self) {
plugin_catalog_t *catalog = self->plugin_catalog;
- int len, pos;
- plugin_node_t *node;
- char *str;
- int list_id, list_size;
+ int list_id;
pthread_mutex_lock (&catalog->lock);
/* calc length of output */
- len = 0;
- list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_DEMUX - 1]);
+ /* calc length of output string and create an array of strings to
+ concatenate */
+ size_t len = 0;
+ const int list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_DEMUX - 1]);
+ const char **mimetypes = calloc(list_size, sizeof(char*));
for (list_id = 0; list_id < list_size; list_id++) {
- demux_class_t *cls;
- const char *s;
-
- node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id);
+ plugin_node_t *const node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id);
if (node->plugin_class || _load_plugin_class(self, node, NULL)) {
-
- cls = (demux_class_t *)node->plugin_class;
-
- s = cls->get_mimetypes (cls);
- if (s)
- len += strlen(s);
+ demux_class_t *const cls = (demux_class_t *)node->plugin_class;
+ if( (mimetypes[list_id] = cls->get_mimetypes(cls)) != NULL )
+ len += strlen(mimetypes[list_id]);
}
}
- /* create output */
-
- str = malloc (len+1);
- pos = 0;
-
- list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_DEMUX - 1]);
-
- for (list_id = 0; list_id < list_size; list_id++) {
- demux_class_t *cls;
- const char *s;
- int l;
-
- node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id);
- if (node->plugin_class || _load_plugin_class(self, node, NULL)) {
+ /* create output string */
+ char *const result = _x_concatenate_with_string(mimetypes, list_size, "", len);
+ free(mimetypes);
- cls = (demux_class_t *)node->plugin_class;
-
- s = cls->get_mimetypes (cls);
- if (s) {
- l = strlen(s);
- memcpy (&str[pos], s, l);
-
- pos += l;
- }
- }
- }
-
- str[pos] = 0;
-
pthread_mutex_unlock (&catalog->lock);
- return str;
+ return result;
}
@@ -2530,47 +2584,24 @@ char *xine_get_demux_for_mime_type (xine_t *self, const char *mime_type) {
plugin_catalog_t *catalog = self->plugin_catalog;
plugin_node_t *node;
char *id = NULL;
- char *mime_arg, *mime_demux;
- char *s;
- const char *mt;
int list_id, list_size;
- /* create a copy and convert to lower case */
- mime_arg = strdup(mime_type);
- for(s=mime_arg; *s; s++)
- *s = tolower(*s);
-
pthread_mutex_lock (&catalog->lock);
list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_DEMUX - 1]);
for (list_id = 0; (list_id < list_size) && !id; list_id++) {
- demux_class_t *cls;
node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id);
- if (node->plugin_class || _load_plugin_class(self, node, NULL)) {
-
- cls = (demux_class_t *)node->plugin_class;
-
- mt = cls->get_mimetypes (cls);
- if (mt) {
- mime_demux = strdup(mt);
-
- for(s=mime_demux; *s; s++)
- *s = tolower(*s);
-
- if( strstr(mime_demux, mime_arg) )
- id = strdup(node->info->id);
-
- free(mime_demux);
- }
+ if (probe_mime_type (self, node, mime_type))
+ {
+ free (id);
+ id = strdup(node->info->id);
}
}
pthread_mutex_unlock (&catalog->lock);
- free(mime_arg);
-
return id;
}
diff --git a/src/xine-engine/lrb.c b/src/xine-engine/lrb.c
index 6da846a7c..6f8ac8479 100644
--- a/src/xine-engine/lrb.c
+++ b/src/xine-engine/lrb.c
@@ -30,7 +30,7 @@ lrb_t *lrb_new (int max_num_entries,
lrb_t *this;
- this = xine_xmalloc (sizeof (lrb_t));
+ this = calloc(1, sizeof(lrb_t));
this->max_num_entries = max_num_entries;
this->cur_num_entries = 0;
diff --git a/src/xine-engine/metronom.c b/src/xine-engine/metronom.c
index 73f36d541..eb9abb84a 100644
--- a/src/xine-engine/metronom.c
+++ b/src/xine-engine/metronom.c
@@ -172,11 +172,10 @@ static void unixscr_exit (scr_plugin_t *scr) {
free(this);
}
-static scr_plugin_t* unixscr_init () {
+static scr_plugin_t *XINE_MALLOC unixscr_init () {
unixscr_t *this;
- this = (unixscr_t *) xine_xmalloc(sizeof(unixscr_t));
- memset(this, 0, sizeof(*this));
+ this = calloc(1, sizeof(unixscr_t));
this->scr.interface_version = 3;
this->scr.get_priority = unixscr_get_priority;
@@ -890,7 +889,7 @@ static void metronom_clock_exit (metronom_clock_t *this) {
metronom_t * _x_metronom_init (int have_video, int have_audio, xine_t *xine) {
- metronom_t *this = xine_xmalloc (sizeof (metronom_t));
+ metronom_t *this = calloc(1, sizeof (metronom_t));
this->set_audio_rate = metronom_set_audio_rate;
this->got_video_frame = metronom_got_video_frame;
@@ -943,7 +942,7 @@ metronom_t * _x_metronom_init (int have_video, int have_audio, xine_t *xine) {
metronom_clock_t *_x_metronom_clock_init(xine_t *xine)
{
- metronom_clock_t *this = (metronom_clock_t *) xine_xmalloc(sizeof(metronom_clock_t));
+ metronom_clock_t *this = calloc(1, sizeof(metronom_clock_t));
int err;
this->set_option = metronom_clock_set_option;
diff --git a/src/xine-engine/metronom.h b/src/xine-engine/metronom.h
index 20e31117c..c7a594d89 100644
--- a/src/xine-engine/metronom.h
+++ b/src/xine-engine/metronom.h
@@ -223,7 +223,7 @@ struct metronom_s {
#define METRONOM_VPTS_OFFSET 6
#define METRONOM_PREBUFFER 7
-metronom_t *_x_metronom_init (int have_video, int have_audio, xine_t *xine) XINE_PROTECTED;
+metronom_t *_x_metronom_init (int have_video, int have_audio, xine_t *xine) XINE_MALLOC XINE_PROTECTED;
/* FIXME: reorder this structure on the next cleanup to remove the dummies */
struct metronom_clock_s {
@@ -319,7 +319,7 @@ struct metronom_clock_s {
#endif
};
-metronom_clock_t *_x_metronom_clock_init(xine_t *xine) XINE_PROTECTED;
+metronom_clock_t *_x_metronom_clock_init(xine_t *xine) XINE_MALLOC XINE_PROTECTED;
/*
* clock options
diff --git a/src/xine-engine/osd.c b/src/xine-engine/osd.c
index ef888e7a4..af8286831 100644
--- a/src/xine-engine/osd.c
+++ b/src/xine-engine/osd.c
@@ -83,17 +83,6 @@
# define UCS2_ENCODING "UCS-2LE"
#endif
-#ifdef MAX
-#undef MAX
-#endif
-#define MAX(a,b) ( (a) > (b) ) ? (a) : (b)
-
-#ifdef MIN
-#undef MIN
-#endif
-#define MIN(a,b) ( (a) < (b) ) ? (a) : (b)
-
-
#if (FREETYPE_MAJOR > 2) || \
(FREETYPE_MAJOR == 2 && FREETYPE_MINOR > 1) || \
(FREETYPE_MAJOR == 2 && FREETYPE_MINOR == 1 && FREETYPE_PATCH >= 3)
@@ -132,6 +121,20 @@ struct osd_ft2context_s {
FT_Face face;
int size;
};
+
+static void osd_free_ft2 (osd_object_t *osd)
+{
+ if( osd->ft2 ) {
+ if ( osd->ft2->face )
+ FT_Done_Face (osd->ft2->face);
+ if ( osd->ft2->library )
+ FT_Done_FreeType(osd->ft2->library);
+ free( osd->ft2 );
+ osd->ft2 = NULL;
+ }
+}
+#else
+static inline void osd_free_ft2 (osd_object_t *osd __attr_unused) {}
#endif
/*
@@ -143,20 +146,20 @@ struct osd_ft2context_s {
* for the sake of simplicity)
*/
-static osd_object_t *osd_new_object (osd_renderer_t *this, int width, int height) {
+static osd_object_t *XINE_MALLOC osd_new_object (osd_renderer_t *this, int width, int height) {
osd_object_t *osd;
pthread_mutex_lock (&this->osd_mutex);
- osd = xine_xmalloc( sizeof(osd_object_t) );
+ osd = calloc(1, sizeof(osd_object_t));
osd->renderer = this;
osd->next = this->osds;
this->osds = osd;
osd->width = width;
osd->height = height;
- osd->area = xine_xmalloc( width * height );
+ osd->area = calloc(width, height);
osd->x1 = width;
osd->y1 = height;
@@ -670,7 +673,7 @@ static int osd_renderer_load_font(osd_renderer_t *this, char *filename) {
/* fixme: check for all read errors... */
if( (fp = gzopen(filename,"rb")) != NULL ) {
- font = xine_xmalloc( sizeof(osd_font_t) );
+ font = calloc(1, sizeof(osd_font_t));
gzread(fp, font->name, sizeof(font->name) );
font->version = gzread_i16(fp);
@@ -818,7 +821,7 @@ static int osd_renderer_unload_font(osd_renderer_t *this, char *fontname ) {
#ifdef HAVE_FT2
static int osd_set_font_freetype2( osd_object_t *osd, const char *fontname, int size ) {
if (!osd->ft2) {
- osd->ft2 = xine_xmalloc(sizeof(osd_ft2context_t));
+ osd->ft2 = calloc(1, sizeof(osd_ft2context_t));
if(FT_Init_FreeType( &osd->ft2->library )) {
xprintf(osd->renderer->stream->xine, XINE_VERBOSITY_LOG,
_("osd: cannot initialize ft2 library\n"));
@@ -827,6 +830,11 @@ static int osd_set_font_freetype2( osd_object_t *osd, const char *fontname, int
return 0;
}
}
+
+ if (osd->ft2->face) {
+ FT_Done_Face (osd->ft2->face);
+ osd->ft2->face = NULL;
+ }
#ifdef HAVE_FONTCONFIG
do {
@@ -885,16 +893,14 @@ static int osd_set_font_freetype2( osd_object_t *osd, const char *fontname, int
_("osd: error loading font %s with ft2\n"), fontname);
}
- free(osd->ft2);
- osd->ft2 = NULL;
+ osd_free_ft2 (osd);
return 0;
end:
if (FT_Set_Pixel_Sizes(osd->ft2->face, 0, size)) {
xprintf(osd->renderer->stream->xine, XINE_VERBOSITY_LOG,
_("osd: error setting font size (no scalable font?)\n"));
- free(osd->ft2);
- osd->ft2 = NULL;
+ osd_free_ft2 (osd);
return 0;
}
@@ -1410,10 +1416,9 @@ static void osd_preload_fonts (osd_renderer_t *this, char *path) {
if( p ) {
osd_font_t *font;
- char *pathname;
*p++ = '\0';
- font = xine_xmalloc( sizeof(osd_font_t) );
+ font = calloc(1, sizeof(osd_font_t) );
strncpy(font->name, s, sizeof(font->name));
font->size = atoi(p);
@@ -1421,9 +1426,7 @@ static void osd_preload_fonts (osd_renderer_t *this, char *path) {
lprintf("font '%s' size %d is preloaded\n",
font->name, font->size);
- pathname = (char *) xine_xmalloc(strlen(path) + strlen(entry->d_name) + 2);
- sprintf (pathname, "%s/%s", path, entry->d_name);
- font->filename = pathname;
+ asprintf (&font->filename, "%s/%s", path, entry->d_name);
font->next = this->fonts;
this->fonts = font;
@@ -1472,15 +1475,7 @@ static void osd_free_object (osd_object_t *osd_to_close) {
if ( osd == osd_to_close ) {
free( osd->area );
-#ifdef HAVE_FT2
- if( osd->ft2 ) {
- if ( osd->ft2->library )
- FT_Done_FreeType(osd->ft2->library);
-
- free( osd->ft2 );
- }
-#endif
-
+ osd_free_ft2 (osd);
osd_free_encoding(osd);
if( last )
@@ -1579,9 +1574,9 @@ osd_renderer_t *_x_osd_renderer_init( xine_stream_t *stream ) {
osd_renderer_t *this;
char str[1024];
- this = xine_xmalloc(sizeof(osd_renderer_t));
+ this = calloc(1, sizeof(osd_renderer_t));
this->stream = stream;
- this->event.object.overlay = xine_xmalloc( sizeof(vo_overlay_t) );
+ this->event.object.overlay = calloc(1, sizeof(vo_overlay_t));
pthread_mutex_init (&this->osd_mutex, NULL);
diff --git a/src/xine-engine/osd.h b/src/xine-engine/osd.h
index 38b5d1fdd..70193a2ea 100644
--- a/src/xine-engine/osd.h
+++ b/src/xine-engine/osd.h
@@ -226,7 +226,7 @@ struct osd_renderer_s {
/*
* initialize the osd rendering engine
*/
-osd_renderer_t *_x_osd_renderer_init( xine_stream_t *stream );
+osd_renderer_t *_x_osd_renderer_init( xine_stream_t *stream ) XINE_MALLOC;
/*
diff --git a/src/xine-engine/post.c b/src/xine-engine/post.c
index 5d8d67037..aa182d627 100644
--- a/src/xine-engine/post.c
+++ b/src/xine-engine/post.c
@@ -30,13 +30,10 @@
void _x_post_init(post_plugin_t *post, int num_audio_inputs, int num_video_inputs) {
- int audio_inputs_size = (num_audio_inputs + 1) * sizeof(xine_audio_port_t *);
- int video_inputs_size = (num_video_inputs + 1) * sizeof(xine_video_port_t *);
-
post->input = xine_list_new();
post->output = xine_list_new();
- post->xine_post.audio_input = (xine_audio_port_t **)xine_xmalloc(audio_inputs_size);
- post->xine_post.video_input = (xine_video_port_t **)xine_xmalloc(video_inputs_size);
+ post->xine_post.audio_input = calloc(num_audio_inputs + 1, sizeof(xine_audio_port_t *));
+ post->xine_post.video_input = calloc(num_video_inputs + 1, sizeof(xine_video_port_t *));
}
@@ -207,7 +204,7 @@ static int post_video_rewire(xine_post_out_t *output_gen, void *data) {
post_video_port_t *_x_post_intercept_video_port(post_plugin_t *post, xine_video_port_t *original,
post_in_t **input, post_out_t **output) {
- post_video_port_t *port = (post_video_port_t *)xine_xmalloc(sizeof(post_video_port_t));
+ post_video_port_t *port = calloc(1, sizeof(post_video_port_t));
if (!port)
return NULL;
@@ -235,7 +232,7 @@ post_video_port_t *_x_post_intercept_video_port(post_plugin_t *post, xine_video_
pthread_mutex_init(&port->free_frames_lock, NULL);
if (input) {
- *input = (post_in_t *)xine_xmalloc(sizeof(post_in_t));
+ *input = calloc(1, sizeof(post_in_t));
if (!*input) return port;
(*input)->xine_in.name = "video in";
(*input)->xine_in.type = XINE_POST_DATA_VIDEO;
@@ -245,7 +242,7 @@ post_video_port_t *_x_post_intercept_video_port(post_plugin_t *post, xine_video_
}
if (output) {
- *output = (post_out_t *)xine_xmalloc(sizeof(post_out_t));
+ *output = calloc(1, sizeof(post_out_t));
if (!*output) return port;
(*output)->xine_out.name = "video out";
(*output)->xine_out.type = XINE_POST_DATA_VIDEO;
@@ -353,7 +350,7 @@ vo_frame_t *_x_post_intercept_video_frame(vo_frame_t *frame, post_video_port_t *
new_frame = port->free_frame_slots;
port->free_frame_slots = new_frame->next;
} else {
- new_frame = (vo_frame_t *)xine_xmalloc(sizeof(vo_frame_t));
+ new_frame = calloc(1, sizeof(vo_frame_t));
}
pthread_mutex_unlock(&port->free_frames_lock);
@@ -716,7 +713,7 @@ static int post_audio_rewire(xine_post_out_t *output_gen, void *data) {
post_audio_port_t *_x_post_intercept_audio_port(post_plugin_t *post, xine_audio_port_t *original,
post_in_t **input, post_out_t **output) {
- post_audio_port_t *port = (post_audio_port_t *)xine_xmalloc(sizeof(post_audio_port_t));
+ post_audio_port_t *port = calloc(1, sizeof(post_audio_port_t));
if (!port)
return NULL;
@@ -739,7 +736,7 @@ post_audio_port_t *_x_post_intercept_audio_port(post_plugin_t *post, xine_audio_
pthread_mutex_init(&port->usage_lock, NULL);
if (input) {
- *input = (post_in_t *)xine_xmalloc(sizeof(post_in_t));
+ *input = calloc(1, sizeof(post_in_t));
if (!*input) return port;
(*input)->xine_in.name = "audio in";
(*input)->xine_in.type = XINE_POST_DATA_AUDIO;
@@ -749,7 +746,7 @@ post_audio_port_t *_x_post_intercept_audio_port(post_plugin_t *post, xine_audio_
}
if (output) {
- *output = (post_out_t *)xine_xmalloc(sizeof(post_out_t));
+ *output = calloc(1, sizeof(post_out_t));
if (!*output) return port;
(*output)->xine_out.name = "audio out";
(*output)->xine_out.type = XINE_POST_DATA_AUDIO;
diff --git a/src/xine-engine/refcounter.c b/src/xine-engine/refcounter.c
index 539abf3ed..384bdf5ed 100644
--- a/src/xine-engine/refcounter.c
+++ b/src/xine-engine/refcounter.c
@@ -17,6 +17,11 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#define LOG_MODULE "refcounter"
#define LOG_VERBOSE
/*
@@ -30,7 +35,7 @@ refcounter_t* _x_new_refcounter(void *object, void (*destructor)(void *))
{
refcounter_t *new_refcounter;
- new_refcounter = (refcounter_t *) xine_xmalloc (sizeof (refcounter_t));
+ new_refcounter = (refcounter_t *) calloc(1, sizeof(refcounter_t));
new_refcounter->count = 1;
new_refcounter->object = object;
new_refcounter->destructor = destructor;
diff --git a/src/xine-engine/refcounter.h b/src/xine-engine/refcounter.h
index 87abd6321..b3ddd71fc 100644
--- a/src/xine-engine/refcounter.h
+++ b/src/xine-engine/refcounter.h
@@ -20,10 +20,6 @@
#ifndef HAVE_REFCOUNTER_H
#define HAVE_REFCOUNTER_H
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <pthread.h>
typedef struct {
@@ -35,7 +31,7 @@ typedef struct {
typedef void (*refcounter_destructor)(void*);
-refcounter_t* _x_new_refcounter(void *object, refcounter_destructor destructor) XINE_PROTECTED;
+refcounter_t* _x_new_refcounter(void *object, refcounter_destructor destructor) XINE_MALLOC XINE_PROTECTED;
int _x_refcounter_inc(refcounter_t *refcounter) XINE_PROTECTED;
diff --git a/src/xine-engine/scratch.c b/src/xine-engine/scratch.c
index 38b606b84..696e99ffb 100644
--- a/src/xine-engine/scratch.c
+++ b/src/xine-engine/scratch.c
@@ -50,12 +50,11 @@ static void __attribute__((__format__(__printf__, 2, 0)))
localtime_r (&t, &tm);
if ( ! this->lines[this->cur] )
- this->lines[this->cur] = xine_xmalloc(SCRATCH_LINE_LEN_MAX+1);
+ this->lines[this->cur] = malloc(SCRATCH_LINE_LEN_MAX+1);
if ( ! this->lines[this->cur] )
return;
- strftime (this->lines[this->cur], SCRATCH_LINE_LEN_MAX, "%X: ", &tm);
- l = strlen (this->lines[this->cur]);
+ l = strftime (this->lines[this->cur], SCRATCH_LINE_LEN_MAX, "%X: ", &tm);
vsnprintf (this->lines[this->cur] + l, SCRATCH_LINE_LEN_MAX - l, format, argp);
lprintf ("printing format %s to line %d\n", format, this->cur);
@@ -105,15 +104,11 @@ static void scratch_dispose (scratch_buffer_t *this) {
scratch_buffer_t *_x_new_scratch_buffer (int num_lines) {
scratch_buffer_t *this;
- int i;
- this = xine_xmalloc (sizeof (scratch_buffer_t));
+ this = calloc(1, sizeof(scratch_buffer_t));
- this->lines = xine_xmalloc (sizeof (char *) * (num_lines + 1));
- this->ordered = xine_xmalloc (sizeof (char *) * (num_lines + 1));
-
- for (i = 0; i <= num_lines; i++)
- this->lines[i] = this->ordered[i] = NULL;
+ this->lines = calloc ((num_lines + 1), sizeof(char*));
+ this->ordered = calloc ((num_lines + 1), sizeof(char*));
this->scratch_printf = scratch_printf;
this->get_content = scratch_get_content;
diff --git a/src/xine-engine/scratch.h b/src/xine-engine/scratch.h
index c0e591d31..1029276e3 100644
--- a/src/xine-engine/scratch.h
+++ b/src/xine-engine/scratch.h
@@ -51,6 +51,6 @@ struct scratch_buffer_s {
pthread_mutex_t lock;
};
-scratch_buffer_t *_x_new_scratch_buffer (int num_lines) XINE_PROTECTED;
+scratch_buffer_t *_x_new_scratch_buffer (int num_lines) XINE_MALLOC XINE_PROTECTED;
#endif
diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c
index c88e01714..d3c9e0d34 100644
--- a/src/xine-engine/video_decoder.c
+++ b/src/xine-engine/video_decoder.c
@@ -160,7 +160,7 @@ static void *video_decoder_loop (void *stream_gen) {
running_ticket->release(running_ticket, 0);
- if( !stream->gapless_switch )
+ if( !(buf->decoder_flags & BUF_FLAG_GAPLESS_SW) )
stream->metronom->handle_video_discontinuity (stream->metronom,
DISC_STREAMSTART, 0);
diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c
index a8464ac40..be062cc5d 100644
--- a/src/xine-engine/video_out.c
+++ b/src/xine-engine/video_out.c
@@ -139,11 +139,11 @@ typedef struct {
* frame queue (fifo) util functions
*/
-static img_buf_fifo_t *vo_new_img_buf_queue () {
+static img_buf_fifo_t *XINE_MALLOC vo_new_img_buf_queue () {
img_buf_fifo_t *queue;
- queue = (img_buf_fifo_t *) xine_xmalloc (sizeof (img_buf_fifo_t));
+ queue = (img_buf_fifo_t *) calloc(1, sizeof(img_buf_fifo_t));
if( queue ) {
queue->first = NULL;
queue->last = NULL;
@@ -1771,7 +1771,7 @@ xine_video_port_t *_x_vo_new_port (xine_t *xine, vo_driver_t *driver, int grabon
int num_frame_buffers;
- this = xine_xmalloc (sizeof (vos_t)) ;
+ this = calloc(1, sizeof(vos_t)) ;
this->xine = xine;
this->clock = xine->clock;
diff --git a/src/xine-engine/video_out.h b/src/xine-engine/video_out.h
index 4d9c80565..9a2ba06c6 100644
--- a/src/xine-engine/video_out.h
+++ b/src/xine-engine/video_out.h
@@ -36,10 +36,6 @@
extern "C" {
#endif
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <pthread.h>
#ifdef XINE_COMPILE
@@ -448,7 +444,7 @@ struct video_overlay_manager_s {
* build a video_out_port from
* a given video driver
*/
-xine_video_port_t *_x_vo_new_port (xine_t *xine, vo_driver_t *driver, int grabonly) XINE_PROTECTED;
+xine_video_port_t *_x_vo_new_port (xine_t *xine, vo_driver_t *driver, int grabonly) XINE_MALLOC XINE_PROTECTED;
#ifdef __cplusplus
}
diff --git a/src/xine-engine/video_overlay.c b/src/xine-engine/video_overlay.c
index c189fa56b..b88f10c11 100644
--- a/src/xine-engine/video_overlay.c
+++ b/src/xine-engine/video_overlay.c
@@ -18,6 +18,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
@@ -199,7 +203,7 @@ static void video_overlay_reset (video_overlay_t *this) {
pthread_mutex_lock (&this->events_mutex);
for (i=0; i < MAX_EVENTS; i++) {
if (this->events[i].event == NULL) {
- this->events[i].event = xine_xmalloc (sizeof(video_overlay_event_t));
+ this->events[i].event = calloc(1, sizeof(video_overlay_event_t));
#ifdef LOG_DEBUG
printf ("video_overlay: MALLOC2: this->events[%d].event %p, len=%d\n",
i,
@@ -293,7 +297,7 @@ static int32_t video_overlay_add_event(video_overlay_manager_t *this_gen, void
event->object.overlay->hili_trans[i] = OVL_MAX_OPACITY;
}
- this->events[new_event].event->object.overlay = xine_xmalloc (sizeof(vo_overlay_t));
+ this->events[new_event].event->object.overlay = calloc(1, sizeof(vo_overlay_t));
xine_fast_memcpy(this->events[new_event].event->object.overlay,
event->object.overlay, sizeof(vo_overlay_t));
@@ -587,7 +591,7 @@ video_overlay_manager_t *_x_video_overlay_new_manager (xine_t *xine) {
video_overlay_t *this;
- this = (video_overlay_t *) xine_xmalloc (sizeof (video_overlay_t));
+ this = (video_overlay_t *) calloc(1, sizeof(video_overlay_t));
this->xine = xine;
this->video_overlay.init = video_overlay_init;
diff --git a/src/xine-engine/video_overlay.h b/src/xine-engine/video_overlay.h
index d580a1e83..01f3a2a3a 100644
--- a/src/xine-engine/video_overlay.h
+++ b/src/xine-engine/video_overlay.h
@@ -98,6 +98,6 @@ typedef struct video_overlay_event_s {
video_overlay_object_t object; /* The image data. */
} video_overlay_event_t;
-video_overlay_manager_t *_x_video_overlay_new_manager(xine_t *) XINE_PROTECTED;
+video_overlay_manager_t *_x_video_overlay_new_manager(xine_t *) XINE_MALLOC XINE_PROTECTED;
#endif
diff --git a/src/xine-engine/vo_scale.c b/src/xine-engine/vo_scale.c
index ff30c47a6..8d84c32da 100644
--- a/src/xine-engine/vo_scale.c
+++ b/src/xine-engine/vo_scale.c
@@ -22,6 +22,10 @@
* Takes into account aspect ratio correction and zooming.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include <string.h>
#include <math.h>
diff --git a/src/xine-engine/vo_scale.h b/src/xine-engine/vo_scale.h
index 829405162..eb2607024 100644
--- a/src/xine-engine/vo_scale.h
+++ b/src/xine-engine/vo_scale.h
@@ -29,10 +29,6 @@
extern "C" {
#endif
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#ifdef XINE_COMPILE
# include "configfile.h"
#else
diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c
index eae13bec9..aebbffb39 100644
--- a/src/xine-engine/xine.c
+++ b/src/xine-engine/xine.c
@@ -36,6 +36,7 @@
#include <stdarg.h>
#include <stdio.h>
#include <ctype.h>
+#include <unistd.h>
#if defined (__linux__) || defined (__GLIBC__)
#include <endian.h>
#elif defined (__FreeBSD__)
@@ -132,7 +133,7 @@ static int acquire_allowed_to_block(xine_ticket_t *this) {
unsigned new_size;
for(entry = 0; entry < this->holder_thread_count; ++entry) {
- if(this->holder_threads[entry].holder == own_id) {
+ if(pthread_equal(this->holder_threads[entry].holder, own_id)) {
/* This thread may already hold this ticket */
this->holder_threads[entry].count++;
return (this->holder_threads[entry].count == 1);
@@ -203,7 +204,7 @@ static int release_allowed_to_block(xine_ticket_t *this) {
unsigned entry;
for(entry = 0; entry < this->holder_thread_count; ++entry) {
- if(this->holder_threads[entry].holder == own_id) {
+ if(pthread_equal(this->holder_threads[entry].holder, own_id)) {
this->holder_threads[entry].count--;
return this->holder_threads[entry].count == 0;
}
@@ -303,10 +304,10 @@ static void ticket_dispose(xine_ticket_t *this) {
free(this);
}
-static xine_ticket_t *ticket_init(void) {
+static xine_ticket_t *XINE_MALLOC ticket_init(void) {
xine_ticket_t *port_ticket;
- port_ticket = (xine_ticket_t *) xine_xmalloc(sizeof(xine_ticket_t));
+ port_ticket = calloc(1, sizeof(xine_ticket_t));
port_ticket->acquire_nonblocking = ticket_acquire_nonblocking;
port_ticket->acquire = ticket_acquire;
@@ -329,17 +330,20 @@ static xine_ticket_t *ticket_init(void) {
static void set_speed_internal (xine_stream_t *stream, int speed) {
xine_t *xine = stream->xine;
+ int old_speed = xine->clock->speed;
- if (xine->clock->speed != XINE_SPEED_PAUSE && speed == XINE_SPEED_PAUSE)
+ if (old_speed != XINE_SPEED_PAUSE && speed == XINE_SPEED_PAUSE)
/* get all decoder and post threads in a state where they agree to be blocked */
xine->port_ticket->revoke(xine->port_ticket, 0);
- if (xine->clock->speed == XINE_SPEED_PAUSE && speed != XINE_SPEED_PAUSE)
+ if (old_speed == XINE_SPEED_PAUSE && speed != XINE_SPEED_PAUSE)
/* all decoder and post threads may continue now */
xine->port_ticket->issue(xine->port_ticket, 0);
- stream->xine->clock->set_fine_speed (stream->xine->clock, speed);
-
+ if (old_speed != XINE_SPEED_PAUSE && speed == XINE_SPEED_PAUSE)
+ /* set master clock so audio_out loop can pause in a safe place */
+ stream->xine->clock->set_fine_speed (stream->xine->clock, speed);
+
/* see coment on audio_out loop about audio_paused */
if( stream->audio_out ) {
xine->port_ticket->acquire(xine->port_ticket, 1);
@@ -349,6 +353,10 @@ static void set_speed_internal (xine_stream_t *stream, int speed) {
xine->port_ticket->release(xine->port_ticket, 1);
}
+
+ if (old_speed == XINE_SPEED_PAUSE || speed != XINE_SPEED_PAUSE)
+ /* master clock is set after resuming the audio device (audio_out loop may continue) */
+ stream->xine->clock->set_fine_speed (stream->xine->clock, speed);
}
@@ -418,6 +426,7 @@ void xine_stop (xine_stream_t *stream) {
static void close_internal (xine_stream_t *stream) {
int i ;
+ int gapless_switch = stream->gapless_switch;
if( stream->slave ) {
xine_close( stream->slave );
@@ -428,7 +437,7 @@ static void close_internal (xine_stream_t *stream) {
}
}
- if( !stream->gapless_switch ) {
+ if( !gapless_switch ) {
/* make sure that other threads cannot change the speed, especially pauseing the stream */
pthread_mutex_lock(&stream->speed_change_lock);
stream->ignore_speed_change = 1;
@@ -444,7 +453,7 @@ static void close_internal (xine_stream_t *stream) {
stop_internal( stream );
- if( !stream->gapless_switch ) {
+ if( !gapless_switch ) {
if (stream->video_out)
stream->video_out->set_property(stream->video_out, VO_PROP_DISCARD_FRAMES, 0);
if (stream->audio_out)
@@ -552,7 +561,7 @@ static int stream_rewire_video(xine_post_out_t *output, void *data)
return 1;
}
-void xine_dispose_internal (xine_stream_t *stream);
+static void xine_dispose_internal (xine_stream_t *stream);
xine_stream_t *xine_stream_new (xine_t *this,
xine_audio_port_t *ao, xine_video_port_t *vo) {
@@ -569,7 +578,7 @@ xine_stream_t *xine_stream_new (xine_t *this,
pthread_mutex_lock (&this->streams_lock);
- stream = (xine_stream_t *) xine_xmalloc (sizeof (xine_stream_t)) ;
+ stream = (xine_stream_t *) calloc (1, sizeof (xine_stream_t)) ;
stream->current_extra_info = malloc( sizeof( extra_info_t ) );
stream->audio_decoder_extra_info = malloc( sizeof( extra_info_t ) );
stream->video_decoder_extra_info = malloc( sizeof( extra_info_t ) );
@@ -595,6 +604,7 @@ xine_stream_t *xine_stream_new (xine_t *this,
stream->early_finish_event = 0;
stream->delay_finish_event = 0;
stream->gapless_switch = 0;
+ stream->keep_ao_driver_open = 0;
stream->video_out = vo;
if (vo)
@@ -628,6 +638,7 @@ xine_stream_t *xine_stream_new (xine_t *this,
pthread_mutex_init (&stream->meta_mutex, NULL);
pthread_mutex_init (&stream->demux_lock, NULL);
pthread_mutex_init (&stream->demux_mutex, NULL);
+ pthread_cond_init (&stream->demux_resume, NULL);
pthread_mutex_init (&stream->event_queues_lock, NULL);
pthread_mutex_init (&stream->counter_lock, NULL);
pthread_cond_init (&stream->counter_changed, NULL);
@@ -733,7 +744,7 @@ xine_stream_t *xine_stream_new (xine_t *this,
}
void _x_mrl_unescape(char *mrl) {
- int i, len = strlen(mrl);
+ size_t i, len = strlen(mrl);
for (i = 0; i < len; i++) {
if ((mrl[i]=='%') && (i<(len-2))) {
@@ -780,9 +791,23 @@ void _x_flush_events_queues (xine_stream_t *stream) {
pthread_mutex_unlock (&stream->event_queues_lock);
}
-/*static*/ int open_internal (xine_stream_t *stream, const char *mrl) {
+static inline int _x_path_looks_like_mrl (const char *path)
+{
+ if ((*path & 0xDF) < 'A' || (*path & 0xDF) > 'Z')
+ return 0;
+
+ for (++path; *path; ++path)
+ if ((*path != '-' && *path < '0') || (*path > '9' && *path < 'A') ||
+ (*path > 'Z' && *path < 'a') || *path > 'z')
+ break;
+
+ return path[0] == ':' && path[1] == '/';
+}
+
+static int open_internal (xine_stream_t *stream, const char *mrl) {
const char *stream_setup = NULL;
+ const char *mrl_proto = NULL;
int no_cache = 0;
if (!mrl) {
@@ -806,16 +831,31 @@ void _x_flush_events_queues (xine_stream_t *stream) {
/*
* look for a stream_setup in MRL and try finding an input plugin
*/
+ stream_setup = strchr (mrl, '#');
if (isalpha (*mrl))
{
- stream_setup = mrl + 1;
- while (isalnum (*stream_setup) || *stream_setup == '+' || *stream_setup == '-' || *stream_setup == '.')
- ++stream_setup;
- if (stream_setup[0] == ':' && stream_setup[1] == '/')
- stream_setup = strchr (mrl, '#');
- else
- stream_setup = NULL;
+ mrl_proto = mrl + 1;
+ while (isalnum (*mrl_proto) || *mrl_proto == '+' || *mrl_proto == '-' || *mrl_proto == '.')
+ ++mrl_proto;
+ if (!mrl_proto[0] || mrl_proto[0] != ':' || mrl_proto[1] != '/')
+ mrl_proto = NULL;
+ }
+
+ /* for raw filenames we must try every '#' checking if it is part of the filename */
+ if( !mrl_proto && stream_setup) {
+ struct stat stat_buf;
+ int res;
+
+ while( stream_setup ) {
+ char *raw_filename = strndup (mrl, stream_setup - mrl);
+
+ res = stat(raw_filename, &stat_buf);
+ free(raw_filename);
+ if( !res )
+ break;
+ stream_setup = strchr(stream_setup + 1, '#');
+ }
}
{
@@ -824,8 +864,10 @@ void _x_flush_events_queues (xine_stream_t *stream) {
/*
* find an input plugin
*/
-
- if ((stream->input_plugin = _x_find_input_plugin (stream, input_source))) {
+ stream->input_plugin = _x_find_input_plugin (stream, input_source);
+ free(input_source);
+
+ if ( stream->input_plugin ) {
int res;
xine_log (stream->xine, XINE_LOG_MSG, _("xine: found input plugin : %s\n"),
@@ -840,7 +882,6 @@ void _x_flush_events_queues (xine_stream_t *stream) {
case 1: /* Open successfull */
break;
case -1: /* Open unsuccessfull, but correct plugin */
- free(input_source);
stream->err = XINE_ERROR_INPUT_FAILED;
_x_flush_events_queues (stream);
return 0;
@@ -851,8 +892,6 @@ void _x_flush_events_queues (xine_stream_t *stream) {
stream->err = XINE_ERROR_INPUT_FAILED;
}
}
-
- free(input_source);
}
if (!stream->input_plugin) {
@@ -917,6 +956,7 @@ void _x_flush_events_queues (xine_stream_t *stream) {
memcpy(filename, tmp, strlen(tmp));
filename[strlen(tmp)] = '\0';
}
+ _x_mrl_unescape(filename);
xine_log(stream->xine, XINE_LOG_MSG, _("xine: join rip input plugin\n"));
input_saver = _x_rip_plugin_get_instance (stream, filename);
@@ -1091,7 +1131,9 @@ void _x_flush_events_queues (xine_stream_t *stream) {
memcpy(subtitle_mrl, tmp, strlen(tmp));
subtitle_mrl[strlen(tmp)] = '\0';
}
- _x_mrl_unescape(subtitle_mrl);
+ /* unescape for xine_open() if the MRL looks like a raw pathname */
+ if (!_x_path_looks_like_mrl(subtitle_mrl))
+ _x_mrl_unescape(subtitle_mrl);
stream->slave = xine_stream_new (stream->xine, NULL, stream->video_out );
stream->slave_affection = XINE_MASTER_SLAVE_PLAY | XINE_MASTER_SLAVE_STOP;
if( xine_open( stream->slave, subtitle_mrl ) ) {
@@ -1152,6 +1194,27 @@ void _x_flush_events_queues (xine_stream_t *stream) {
/* enable buffered input plugin (request optimizer) */
stream->input_plugin = _x_cache_plugin_get_instance(stream, 0);
+ /* Let the plugin request a specific demuxer (if the user hasn't).
+ * This overrides find-by-content & find-by-extension.
+ */
+ if (!stream->demux_plugin)
+ {
+ char *default_demux = NULL;
+ stream->input_plugin->get_optional_data (stream->input_plugin, &default_demux, INPUT_OPTIONAL_DATA_DEMUXER);
+ if (default_demux)
+ {
+ stream->demux_plugin = _x_find_demux_plugin_by_name (stream, default_demux, stream->input_plugin);
+ if (stream->demux_plugin)
+ {
+ lprintf ("demux and input plugin found\n");
+ _x_meta_info_set_utf8 (stream, XINE_META_INFO_SYSTEMLAYER,
+ stream->demux_plugin->demux_class->get_identifier (stream->demux_plugin->demux_class));
+ }
+ else
+ xine_log (stream->xine, XINE_LOG_MSG, _("xine: couldn't load plugin-specified demux %s for >%s<\n"), default_demux, mrl);
+ }
+ }
+
if (!stream->demux_plugin) {
/*
@@ -1290,6 +1353,7 @@ static int play_internal (xine_stream_t *stream, int start_pos, int start_time)
pthread_mutex_lock( &stream->demux_lock );
/* demux_lock taken. now demuxer is suspended */
stream->demux_action_pending = 0;
+ pthread_cond_signal(&stream->demux_resume);
/* set normal speed again (now that demuxer/input pair is suspended)
* some input plugin may have changed speed by itself, we must ensure
@@ -1403,7 +1467,7 @@ int xine_eject (xine_stream_t *stream) {
return status;
}
-void xine_dispose_internal (xine_stream_t *stream) {
+static void xine_dispose_internal (xine_stream_t *stream) {
xine_list_iterator_t *ite;
@@ -1416,6 +1480,7 @@ void xine_dispose_internal (xine_stream_t *stream) {
pthread_mutex_destroy (&stream->current_extra_info_lock);
pthread_cond_destroy (&stream->counter_changed);
pthread_mutex_destroy (&stream->demux_mutex);
+ pthread_cond_destroy (&stream->demux_resume);
pthread_mutex_destroy (&stream->demux_lock);
pthread_mutex_destroy (&stream->first_frame_lock);
pthread_cond_destroy (&stream->first_frame_reached);
@@ -1510,7 +1575,7 @@ xine_t *xine_new (void) {
int i_err;
#endif
- this = xine_xmalloc (sizeof (xine_t));
+ this = calloc(1, sizeof (xine_t));
if (!this)
_x_abort();
@@ -1599,8 +1664,7 @@ static void config_save_cb (void *this_gen, xine_cfg_entry_t *entry) {
xine_t *this = (xine_t *)this_gen;
char *homedir_trail_slash;
- homedir_trail_slash = (char *)malloc(strlen(xine_get_homedir()) + 2);
- sprintf(homedir_trail_slash, "%s/", xine_get_homedir());
+ asprintf(&homedir_trail_slash, "%s/", xine_get_homedir());
if (entry->str_value[0] &&
(entry->str_value[0] != '/' || strstr(entry->str_value, "/.") ||
strcmp(entry->str_value, xine_get_homedir()) == 0 ||
@@ -1627,6 +1691,12 @@ void xine_init (xine_t *this) {
static const char *demux_strategies[] = {"default", "reverse", "content",
"extension", NULL};
+ /*
+ * locks
+ */
+ pthread_mutex_init (&this->streams_lock, NULL);
+ pthread_mutex_init (&this->log_lock, NULL);
+
/* initialize color conversion tables and functions */
init_yuv_conversion();
@@ -1708,12 +1778,6 @@ void xine_init (xine_t *this) {
this->streams = xine_list_new();
/*
- * locks
- */
- pthread_mutex_init (&this->streams_lock, NULL);
- pthread_mutex_init (&this->log_lock, NULL);
-
- /*
* start metronom clock
*/
@@ -1899,50 +1963,98 @@ int xine_get_pos_length (xine_stream_t *stream, int *pos_stream,
return 1;
}
-int xine_get_current_frame (xine_stream_t *stream, int *width, int *height,
- int *ratio_code, int *format,
- uint8_t *img) {
+static int _x_get_current_frame_data (xine_stream_t *stream,
+ xine_current_frame_data_t *data,
+ int flags, int img_size_unknown) {
vo_frame_t *frame;
+ size_t required_size;
stream->xine->port_ticket->acquire(stream->xine->port_ticket, 0);
frame = stream->video_out->get_last_frame (stream->video_out);
stream->xine->port_ticket->release(stream->xine->port_ticket, 0);
- if (!frame)
+ if (!frame) {
+ data->img_size = 0;
return 0;
+ }
- *width = frame->width;
- *height = frame->height;
+ data->width = frame->width;
+ data->height = frame->height;
+ data->crop_left = frame->crop_left;
+ data->crop_right = frame->crop_right;
+ data->crop_top = frame->crop_top;
+ data->crop_bottom = frame->crop_bottom;
- *ratio_code = 10000.0 * frame->ratio;
+ data->ratio_code = 10000.0 * frame->ratio;
/* make ratio_code backward compatible */
#define RATIO_LIKE(a, b) ((b) - 1 <= (a) && (a) <= 1 + (b))
- if (RATIO_LIKE(*ratio_code, 10000))
- *ratio_code = XINE_VO_ASPECT_SQUARE;
- else if (RATIO_LIKE(*ratio_code, 13333))
- *ratio_code = XINE_VO_ASPECT_4_3;
- else if (RATIO_LIKE(*ratio_code, 17778))
- *ratio_code = XINE_VO_ASPECT_ANAMORPHIC;
- else if (RATIO_LIKE(*ratio_code, 21100))
- *ratio_code = XINE_VO_ASPECT_DVB;
-
- *format = frame->format;
-
- if (img){
+ if (RATIO_LIKE(data->ratio_code, 10000))
+ data->ratio_code = XINE_VO_ASPECT_SQUARE;
+ else if (RATIO_LIKE(data->ratio_code, 13333))
+ data->ratio_code = XINE_VO_ASPECT_4_3;
+ else if (RATIO_LIKE(data->ratio_code, 17778))
+ data->ratio_code = XINE_VO_ASPECT_ANAMORPHIC;
+ else if (RATIO_LIKE(data->ratio_code, 21100))
+ data->ratio_code = XINE_VO_ASPECT_DVB;
+
+ data->format = frame->format;
+ data->interlaced = frame->progressive_frame ? 0 : (2 - frame->top_field_first);
+
+ switch (frame->format) {
+
+ case XINE_IMGFMT_YV12:
+ required_size = frame->width * frame->height
+ + ((frame->width + 1) / 2) * ((frame->height + 1) / 2)
+ + ((frame->width + 1) / 2) * ((frame->height + 1) / 2);
+ break;
+
+ case XINE_IMGFMT_YUY2:
+ required_size = frame->width * frame->height
+ + ((frame->width + 1) / 2) * frame->height
+ + ((frame->width + 1) / 2) * frame->height;
+ break;
+
+ default:
+ if (data->img || (flags & XINE_FRAME_DATA_ALLOCATE_IMG)) {
+ xprintf (stream->xine, XINE_VERBOSITY_DEBUG,
+ "xine: error, snapshot function not implemented for format 0x%x\n", frame->format);
+ _x_abort ();
+ }
+
+ required_size = 0;
+ }
+
+ if (flags & XINE_FRAME_DATA_ALLOCATE_IMG) {
+ /* return allocated buffer size */
+ data->img_size = required_size;
+ /* allocate img or fail */
+ if (!(data->img = calloc(1, required_size)))
+ return 0;
+ } else {
+ /* fail if supplied buffer is to small */
+ if (data->img && !img_size_unknown && data->img_size < required_size) {
+ data->img_size = required_size;
+ return 0;
+ }
+ /* return used buffer size */
+ data->img_size = required_size;
+ }
+
+ if (data->img) {
switch (frame->format) {
case XINE_IMGFMT_YV12:
yv12_to_yv12(
/* Y */
frame->base[0], frame->pitches[0],
- img, frame->width,
+ data->img, frame->width,
/* U */
frame->base[1], frame->pitches[1],
- img+frame->width*frame->height, frame->width/2,
+ data->img+frame->width*frame->height, frame->width/2,
/* V */
frame->base[2], frame->pitches[2],
- img+frame->width*frame->height+frame->width*frame->height/4, frame->width/2,
+ data->img+frame->width*frame->height+frame->width*frame->height/4, frame->width/2,
/* width x height */
frame->width, frame->height);
break;
@@ -1952,7 +2064,7 @@ int xine_get_current_frame (xine_stream_t *stream, int *width, int *height,
/* src */
frame->base[0], frame->pitches[0],
/* dst */
- img, frame->width*2,
+ data->img, frame->width*2,
/* width x height */
frame->width, frame->height);
break;
@@ -1966,6 +2078,69 @@ int xine_get_current_frame (xine_stream_t *stream, int *width, int *height,
return 1;
}
+int xine_get_current_frame_data (xine_stream_t *stream,
+ xine_current_frame_data_t *data,
+ int flags) {
+
+ return _x_get_current_frame_data(stream, data, flags, 0);
+}
+
+int xine_get_current_frame_alloc (xine_stream_t *stream, int *width, int *height,
+ int *ratio_code, int *format,
+ uint8_t **img, int *img_size) {
+
+ int result;
+ xine_current_frame_data_t data;
+
+ memset(&data, 0, sizeof (data));
+
+ result = _x_get_current_frame_data(stream, &data, img ? XINE_FRAME_DATA_ALLOCATE_IMG : 0, 0);
+ if (width) *width = data.width;
+ if (height) *height = data.height;
+ if (ratio_code) *ratio_code = data.ratio_code;
+ if (format) *format = data.format;
+ if (img_size) *img_size = data.img_size;
+ if (img) *img = data.img;
+ return result;
+}
+
+int xine_get_current_frame_s (xine_stream_t *stream, int *width, int *height,
+ int *ratio_code, int *format,
+ uint8_t *img, int *img_size) {
+ int result;
+ xine_current_frame_data_t data;
+
+ memset(&data, 0, sizeof (data));
+ data.img = img;
+ if (img_size)
+ data.img_size = *img_size;
+
+ result = _x_get_current_frame_data(stream, &data, 0, 0);
+ if (width) *width = data.width;
+ if (height) *height = data.height;
+ if (ratio_code) *ratio_code = data.ratio_code;
+ if (format) *format = data.format;
+ if (img_size) *img_size = data.img_size;
+ return result;
+}
+
+int xine_get_current_frame (xine_stream_t *stream, int *width, int *height,
+ int *ratio_code, int *format,
+ uint8_t *img) {
+ int result;
+ xine_current_frame_data_t data;
+
+ memset(&data, 0, sizeof (data));
+ data.img = img;
+
+ result = _x_get_current_frame_data(stream, &data, 0, 1);
+ if (width) *width = data.width;
+ if (height) *height = data.height;
+ if (ratio_code) *ratio_code = data.ratio_code;
+ if (format) *format = data.format;
+ return result;
+}
+
int xine_get_video_frame (xine_stream_t *stream,
int timestamp, /* msec */
int *width, int *height,
@@ -2084,7 +2259,10 @@ void xine_log (xine_t *this, int buf, const char *format, ...) {
vsnprintf(buffer, SCRATCH_LINE_LEN_MAX, format, argp);
printf("%s", buffer);
va_end (argp);
- }
+ }
+
+ if (this->log_cb)
+ this->log_cb (this->log_cb_user_data, buf);
}
void xine_vlog(xine_t *this, int buf, const char *format,
@@ -2093,6 +2271,9 @@ void xine_vlog(xine_t *this, int buf, const char *format,
check_log_alloc (this, buf);
this->log_buffers[buf]->scratch_printf(this->log_buffers[buf], format, args);
+
+ if (this->log_cb)
+ this->log_cb (this->log_cb_user_data, buf);
}
char *const *xine_get_log (xine_t *this, int buf) {
@@ -2107,12 +2288,10 @@ char *const *xine_get_log (xine_t *this, int buf) {
}
void xine_register_log_cb (xine_t *this, xine_log_cb_t cb, void *user_data) {
-
- printf ("xine: xine_register_log_cb: not implemented yet.\n");
- _x_abort();
+ this->log_cb = cb;
+ this->log_cb_user_data = user_data;
}
-
int xine_get_error (xine_stream_t *stream) {
return stream->err;
}
diff --git a/src/xine-engine/xine_interface.c b/src/xine-engine/xine_interface.c
index 50d8796e8..0438aedfa 100644
--- a/src/xine-engine/xine_interface.c
+++ b/src/xine-engine/xine_interface.c
@@ -527,6 +527,9 @@ void xine_set_param (xine_stream_t *stream, int param, int value) {
case XINE_PARAM_GAPLESS_SWITCH:
stream->gapless_switch = !!value;
+ if( stream->gapless_switch && !stream->early_finish_event ) {
+ xprintf (stream->xine, XINE_VERBOSITY_DEBUG, "frontend possibly buggy: gapless_switch without early_finish_event\n");
+ }
break;
default:
@@ -739,6 +742,8 @@ uint32_t xine_get_stream_info (xine_stream_t *stream, int info) {
case XINE_STREAM_INFO_IGNORE_AUDIO:
case XINE_STREAM_INFO_IGNORE_SPU:
case XINE_STREAM_INFO_VIDEO_HAS_STILL:
+ case XINE_STREAM_INFO_SKIPPED_FRAMES:
+ case XINE_STREAM_INFO_DISCARDED_FRAMES:
case XINE_STREAM_INFO_VIDEO_AFD:
case XINE_STREAM_INFO_DVD_TITLE_NUMBER:
case XINE_STREAM_INFO_DVD_TITLE_COUNT:
@@ -945,7 +950,7 @@ int _x_message(xine_stream_t *stream, int type, ...) {
xine_ui_message_data_t *data;
xine_event_t event;
const char *explanation;
- int size;
+ size_t size;
int n;
va_list ap;
char *s, *params;
@@ -990,7 +995,7 @@ int _x_message(xine_stream_t *stream, int type, ...) {
args[n] = NULL;
size += sizeof(xine_ui_message_data_t) + 1;
- data = xine_xmalloc( size );
+ data = calloc(1, size );
strcpy(data->compatibility.str, "Upgrade your frontend to see the error messages");
data->type = type;
diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h
index 9b69f16f1..945157fc2 100644
--- a/src/xine-engine/xine_internal.h
+++ b/src/xine-engine/xine_internal.h
@@ -117,6 +117,9 @@ struct xine_s {
#ifdef XINE_ENGINE_INTERNAL
xine_ticket_t *port_ticket;
pthread_mutex_t log_lock;
+
+ xine_log_cb_t log_cb;
+ void *log_cb_user_data;
#endif
};
@@ -333,6 +336,7 @@ struct xine_stream_s {
int demux_thread_running;
pthread_mutex_t demux_lock;
int demux_action_pending;
+ pthread_cond_t demux_resume;
pthread_mutex_t demux_mutex; /* used in _x_demux_... functions to synchronize order of pairwise A/V buffer operations */
extra_info_t *current_extra_info;
@@ -357,6 +361,7 @@ struct xine_stream_s {
int early_finish_event; /* do not wait fifos get empty before sending event */
int gapless_switch; /* next stream switch will be gapless */
int delay_finish_event; /* delay event in 1/10 sec units. 0=>no delay, -1=>forever */
+ int keep_ao_driver_open;
#endif
};
@@ -388,8 +393,8 @@ input_plugin_t *_x_find_input_plugin (xine_stream_t *stream, const char *mrl) XI
demux_plugin_t *_x_find_demux_plugin (xine_stream_t *stream, input_plugin_t *input) XINE_PROTECTED;
demux_plugin_t *_x_find_demux_plugin_by_name (xine_stream_t *stream, const char *name, input_plugin_t *input) XINE_PROTECTED;
demux_plugin_t *_x_find_demux_plugin_last_probe(xine_stream_t *stream, const char *last_demux_name, input_plugin_t *input) XINE_PROTECTED;
-input_plugin_t *_x_rip_plugin_get_instance (xine_stream_t *stream, const char *filename) XINE_PROTECTED;
-input_plugin_t *_x_cache_plugin_get_instance (xine_stream_t *stream, int readahead_size) XINE_PROTECTED;
+input_plugin_t *_x_rip_plugin_get_instance (xine_stream_t *stream, const char *filename) XINE_MALLOC XINE_PROTECTED;
+input_plugin_t *_x_cache_plugin_get_instance (xine_stream_t *stream, int readahead_size) XINE_MALLOC XINE_PROTECTED;
void _x_free_input_plugin (xine_stream_t *stream, input_plugin_t *input) XINE_PROTECTED;
void _x_free_demux_plugin (xine_stream_t *stream, demux_plugin_t *demux) XINE_PROTECTED;
diff --git a/src/xine-utils/Makefile.am b/src/xine-utils/Makefile.am
index 95de06b9e..501f489fe 100644
--- a/src/xine-utils/Makefile.am
+++ b/src/xine-utils/Makefile.am
@@ -12,7 +12,7 @@ endif
endif
AM_CFLAGS = $(X_CFLAGS) $(VISIBILITY_FLAG)
-AM_CPPFLAGS=-DXINE_LIBRARY_COMPILE
+AM_CPPFLAGS= -DXINE_LIBRARY_COMPILE
libxineutils_la_SOURCES = $(pppc_files) \
cpu_accel.c \
@@ -37,6 +37,7 @@ xineinclude_HEADERS = \
compat.h \
xine_buffer.h \
xineutils.h \
+ xine_mmx.h \
xmllexer.h \
xmlparser.h \
list.h \
@@ -46,5 +47,5 @@ xineinclude_HEADERS = \
ring_buffer.h
-noinst_HEADERS = ppcasm_string.h xine_check.h
+noinst_HEADERS = ppcasm_string.h mangle.h
diff --git a/src/xine-utils/array.c b/src/xine-utils/array.c
index 6c226c7ef..f6989fbb6 100644
--- a/src/xine-utils/array.c
+++ b/src/xine-utils/array.c
@@ -56,7 +56,7 @@ xine_array_t *xine_array_new(size_t initial_size) {
if (initial_size < MIN_CHUNK_SIZE)
initial_size = MIN_CHUNK_SIZE;
- new_array->chunk = (void**)malloc(sizeof(void*) * initial_size);
+ new_array->chunk = (void**)calloc(initial_size, sizeof(void*));
if (!new_array->chunk) {
free(new_array);
return NULL;
diff --git a/src/xine-utils/array.h b/src/xine-utils/array.h
index ae2093823..44f3c7632 100644
--- a/src/xine-utils/array.h
+++ b/src/xine-utils/array.h
@@ -27,7 +27,7 @@
typedef struct xine_array_s xine_array_t;
/* Constructor */
-xine_array_t *xine_array_new(size_t initial_size) XINE_PROTECTED;
+xine_array_t *xine_array_new(size_t initial_size) XINE_MALLOC XINE_PROTECTED;
/* Destructor */
void xine_array_delete(xine_array_t *array) XINE_PROTECTED;
diff --git a/src/xine-utils/attributes.h b/src/xine-utils/attributes.h
index 563832e5c..d7a0e2f1e 100644
--- a/src/xine-utils/attributes.h
+++ b/src/xine-utils/attributes.h
@@ -1,7 +1,7 @@
/*
* attributes.h
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
- * Copyright (C) 2001-2007 xine developers
+ * Copyright (C) 2001-2008 xine developers
*
* This file was originally part of mpeg2dec, a free MPEG-2 video stream
* decoder.
@@ -32,20 +32,29 @@
#define ATTR_ALIGN(align)
#endif
-/* disable GNU __attribute__ extension, when not compiling with GNU C */
-#if defined(__GNUC__) || defined (__ICC)
-#ifndef ATTRIBUTE_PACKED
-#define ATTRIBUTE_PACKED 1
-#endif
-#else
-#undef ATTRIBUTE_PACKED
-#ifndef __attribute__
-#define __attribute__(x) /**/
-#endif /* __attribute __*/
-#endif
-
#ifdef XINE_COMPILE
# include "configure.h"
+#else
+# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95 )
+# define SUPPORT_ATTRIBUTE_PACKED 1
+# endif
+
+# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3 )
+# define SUPPORT_ATTRIBUTE_DEPRECATED 1
+# define SUPPORT_ATTRIBUTE_FORMAT 1
+# define SUPPORT_ATTRIBUTE_FORMAT_ARG 1
+# define SUPPORT_ATTRIBUTE_MALLOC 1
+# define SUPPORT_ATTRIBUTE_UNUSED 1
+# define SUPPORT_ATTRIBUTE_CONST 1
+# endif
+
+# if __GNUC__ >= 4
+# define SUPPORT_ATTRIBUTE_VISIBILITY_DEFAULT 1
+# if __ELF__
+# define SUPPORT_ATTRIBUTE_VISIBILITY_PROTECTED 1
+# endif
+# define SUPPORT_ATTRIBUTE_SENTINEL 1
+# endif
#endif
/* Export protected only for libxine functions */
@@ -63,6 +72,12 @@
# define XINE_SENTINEL
#endif
+#if defined(SUPPORT_ATTRIBUTE_DEPRECATED) && !defined(XINE_COMPILE)
+# define XINE_DEPRECATED __attribute__((__deprecated__))
+#else
+# define XINE_DEPRECATED
+#endif
+
#ifndef __attr_unused
# ifdef SUPPORT_ATTRIBUTE_UNUSED
# define __attr_unused __attribute__((__unused__))
@@ -74,8 +89,10 @@
/* Format attributes */
#ifdef SUPPORT_ATTRIBUTE_FORMAT
# define XINE_FORMAT_PRINTF(fmt,var) __attribute__((__format__(__printf__, fmt, var)))
+# define XINE_FORMAT_SCANF(fmt,var) __attribute__((__format__(__scanf__, fmt, var)))
#else
# define XINE_FORMAT_PRINTF(fmt,var)
+# define XINE_FORMAT_SCANF(fmt,var)
#endif
#ifdef SUPPORT_ATTRIBUTE_FORMAT_ARG
# define XINE_FORMAT_PRINTF_ARG(fmt) __attribute__((__format_arg__(fmt)))
@@ -83,4 +100,22 @@
# define XINE_FORMAT_PRINTF_ARG(fmt)
#endif
+#ifdef SUPPORT_ATTRIBUTE_MALLOC
+# define XINE_MALLOC __attribute__((__malloc__))
+#else
+# define XINE_MALLOC
+#endif
+
+#ifdef SUPPORT_ATTRIBUTE_PACKED
+# define XINE_PACKED __attribute__((__packed__))
+#else
+# define XINE_PACKED
+#endif
+
+#ifdef SUPPORT_ATTRIBUTE_CONST
+# define XINE_CONST __attribute__((__const__))
+#else
+# define XINE_CONST
+#endif
+
#endif /* ATTRIBUTE_H_ */
diff --git a/src/xine-utils/color.c b/src/xine-utils/color.c
index 0b9cf0188..f5ebf6c00 100644
--- a/src/xine-utils/color.c
+++ b/src/xine-utils/color.c
@@ -159,18 +159,14 @@ void (*yuy2_to_yv12)
* and height passed to it. The width must be divisible by 2.
*/
void init_yuv_planes(yuv_planes_t *yuv_planes, int width, int height) {
-
- int plane_size;
-
memset (yuv_planes, 0, sizeof (yuv_planes));
yuv_planes->row_width = width;
yuv_planes->row_count = height;
- plane_size = yuv_planes->row_width * yuv_planes->row_count;
- yuv_planes->y = xine_xmalloc(plane_size);
- yuv_planes->u = xine_xmalloc(plane_size);
- yuv_planes->v = xine_xmalloc(plane_size);
+ yuv_planes->y = calloc(width, height);
+ yuv_planes->u = calloc(width, height);
+ yuv_planes->v = calloc(width, height);
}
/*
diff --git a/src/xine-utils/cpu_accel.c b/src/xine-utils/cpu_accel.c
index c241dd7ef..d6c4bd9a8 100644
--- a/src/xine-utils/cpu_accel.c
+++ b/src/xine-utils/cpu_accel.c
@@ -40,6 +40,10 @@
#include "xineutils.h"
+#if defined(PIC) && ! defined(__PIC__)
+#define __PIC__
+#endif
+
#if defined(ARCH_X86) || defined(ARCH_X86_64)
static jmp_buf sigill_return;
diff --git a/src/xine-utils/list.c b/src/xine-utils/list.c
index 65bdaec26..eb654a3e3 100644
--- a/src/xine-utils/list.c
+++ b/src/xine-utils/list.c
@@ -67,9 +67,9 @@ struct xine_list_s {
/* Allocates a new chunk of n elements
* One malloc call is used to allocate the struct and the elements.
*/
-static xine_list_chunk_t *xine_list_alloc_chunk(size_t size) {
+static xine_list_chunk_t *XINE_MALLOC xine_list_alloc_chunk(size_t size) {
xine_list_chunk_t *new_chunk;
- size_t chunk_mem_size;;
+ size_t chunk_mem_size;
chunk_mem_size = sizeof(xine_list_chunk_t);
chunk_mem_size += sizeof(xine_list_elem_t) * size;
diff --git a/src/xine-utils/list.h b/src/xine-utils/list.h
index e00e30d6c..f05ed2b0e 100644
--- a/src/xine-utils/list.h
+++ b/src/xine-utils/list.h
@@ -48,7 +48,7 @@ typedef struct xine_list_s xine_list_t;
typedef void* xine_list_iterator_t;
/* Constructor */
-xine_list_t *xine_list_new(void) XINE_PROTECTED;
+xine_list_t *xine_list_new(void) XINE_MALLOC XINE_PROTECTED;
/* Destructor */
void xine_list_delete(xine_list_t *list) XINE_PROTECTED;
diff --git a/src/xine-utils/mangle.h b/src/xine-utils/mangle.h
new file mode 100644
index 000000000..746317fa5
--- /dev/null
+++ b/src/xine-utils/mangle.h
@@ -0,0 +1,54 @@
+/*
+ * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
+ * copyright (c) 2008 the xine-project
+ *
+ * This file is part of FFmpeg.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ */
+
+/**
+ * @file
+ *
+ * @brief MANGLE definition from FFmpeg project, until the code is ported
+ * not to require this (considered an hack by the FFmpeg project.
+ */
+
+#ifndef _XINE_MANGLE_H
+#define _XINE_MANGLE_H
+
+#if defined(PIC) && ! defined(__PIC__)
+#define __PIC__
+#endif
+
+// 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(__x86_64__) && defined(__PIC__)
+# define MANGLE(a) "_" #a"(%%rip)"
+# else
+# define MANGLE(a) "_" #a
+# endif
+#else
+# if defined(__x86_64__) && defined(__PIC__)
+# define MANGLE(a) #a"(%%rip)"
+# elif defined(__APPLE__)
+# define MANGLE(a) "_" #a
+# else
+# define MANGLE(a) #a
+# endif
+#endif
+
+#endif
diff --git a/src/xine-utils/monitor.c b/src/xine-utils/monitor.c
index fb323055c..650c10f99 100644
--- a/src/xine-utils/monitor.c
+++ b/src/xine-utils/monitor.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2003 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -38,13 +38,10 @@ static long profiler_calls[MAX_ID] ;
static const char *profiler_label[MAX_ID] ;
void xine_profiler_init () {
- int i;
- for (i=0; i<MAX_ID; i++) {
- profiler_times[i] = 0;
- profiler_start[i] = 0;
- profiler_calls[i] = 0;
- profiler_label[i] = NULL;
- }
+ memset(profiler_times, 0, sizeof(profiler_times));
+ memset(profiler_start, 0, sizeof(profiler_start));
+ memset(profiler_calls, 0, sizeof(profiler_calls));
+ memset(profiler_label, 0, sizeof(profiler_label));
}
int xine_profiler_allocate_slot (const char *label) {
diff --git a/src/xine-utils/pool.c b/src/xine-utils/pool.c
index a1fddadd9..1b7fd63f3 100644
--- a/src/xine-utils/pool.c
+++ b/src/xine-utils/pool.c
@@ -55,7 +55,7 @@ struct xine_pool_s {
/* Allocates a new chunk of n elements
* One malloc call is used to allocate the struct and the elements.
*/
-static xine_pool_chunk_t *xine_pool_alloc_chunk(size_t object_size, size_t object_count) {
+static xine_pool_chunk_t *XINE_MALLOC xine_pool_alloc_chunk(size_t object_size, size_t object_count) {
xine_pool_chunk_t *new_chunk;
size_t chunk_mem_size;;
diff --git a/src/xine-utils/pool.h b/src/xine-utils/pool.h
index 918da82a2..2667b7fdc 100644
--- a/src/xine-utils/pool.h
+++ b/src/xine-utils/pool.h
@@ -36,7 +36,7 @@ xine_pool_t *xine_pool_new(size_t object_size,
void (create_object)(void *object),
void (prepare_object)(void *object),
void (return_object)(void *object),
- void (delete_object)(void *object)) XINE_PROTECTED;
+ void (delete_object)(void *object)) XINE_MALLOC XINE_PROTECTED;
/* Deletes a pool */
void xine_pool_delete(xine_pool_t *pool) XINE_PROTECTED;
diff --git a/src/xine-utils/ring_buffer.h b/src/xine-utils/ring_buffer.h
index efcffd3b7..5f104dc77 100644
--- a/src/xine-utils/ring_buffer.h
+++ b/src/xine-utils/ring_buffer.h
@@ -22,7 +22,7 @@
typedef struct xine_ring_buffer_s xine_ring_buffer_t;
/* Creates a new ring buffer */
-xine_ring_buffer_t *xine_ring_buffer_new(size_t size) XINE_PROTECTED;
+xine_ring_buffer_t *xine_ring_buffer_new(size_t size) XINE_MALLOC XINE_PROTECTED;
/* Deletes a ring buffer */
void xine_ring_buffer_delete(xine_ring_buffer_t *ring_buffer) XINE_PROTECTED;
diff --git a/src/xine-utils/sorted_array.h b/src/xine-utils/sorted_array.h
index a1894eca3..c6fdd1c25 100644
--- a/src/xine-utils/sorted_array.h
+++ b/src/xine-utils/sorted_array.h
@@ -63,7 +63,7 @@ typedef struct xine_sarray_s xine_sarray_t;
typedef int (*xine_sarray_comparator_t)(void*, void*);
/* Constructor */
-xine_sarray_t *xine_sarray_new(size_t initial_size, xine_sarray_comparator_t comparator) XINE_PROTECTED;
+xine_sarray_t *xine_sarray_new(size_t initial_size, xine_sarray_comparator_t comparator) XINE_MALLOC XINE_PROTECTED;
/* Destructor */
void xine_sarray_delete(xine_sarray_t *sarray) XINE_PROTECTED;
diff --git a/src/xine-utils/utils.c b/src/xine-utils/utils.c
index c5f18a699..689b68502 100644
--- a/src/xine-utils/utils.c
+++ b/src/xine-utils/utils.c
@@ -236,7 +236,25 @@ static const lang_locale_t lang_locales[] = {
{ NULL, NULL, NULL, NULL }
};
-
+/**
+ * @brief Allocate and clean memory size_t 'size', then return the
+ * pointer to the allocated memory.
+ * @param size Size of the memory area to allocate.
+ *
+ * @return A pointer to the allocated memory area, or NULL in case of
+ * error.
+ *
+ * The behaviour of this function differs from standard malloc() as
+ * xine_xmalloc(0) will not return a NULL pointer, but rather a
+ * pointer to a memory area of size 1 byte.
+ *
+ * The NULL value is only ever returned in case of an error in
+ * malloc(), and is reported to stderr stream.
+ *
+ * @deprecated This function has been deprecated, as the behaviour of
+ * allocating a 1 byte memory area on zero size is almost
+ * never desired, and the function is thus mostly misused.
+ */
void *xine_xmalloc(size_t size) {
void *ptr;
@@ -257,7 +275,7 @@ void *xine_xmalloc_aligned(size_t alignment, size_t size, void **base) {
char *ptr;
- *base = ptr = xine_xmalloc (size+alignment);
+ *base = ptr = calloc(1, size+alignment);
while ((size_t) ptr % alignment)
ptr++;
@@ -324,22 +342,18 @@ const char *xine_get_homedir(void) {
char *s;
int len;
- if (!homedir[0]) {
- len = xine_strcpy_command(GetCommandLine(), homedir, sizeof(homedir));
- s = strdup(homedir);
- GetFullPathName(s, sizeof(homedir), homedir, NULL);
- free(s);
- if ((s = strrchr(homedir, '\\'))) *s = '\0';
- }
+ len = xine_strcpy_command(GetCommandLine(), homedir, sizeof(homedir));
+ s = strdup(homedir);
+ GetFullPathName(s, sizeof(homedir), homedir, NULL);
+ free(s);
+ if ((s = strrchr(homedir, '\\')))
+ *s = '\0';
return homedir;
#else
struct passwd pwd, *pw = NULL;
static char homedir[BUFSIZ] = {0,};
- if(homedir[0])
- return homedir;
-
#ifdef HAVE_GETPWUID_R
if(getpwuid_r(getuid(), &pwd, homedir, sizeof(homedir), &pw) != 0 || pw == NULL) {
#else
@@ -375,6 +389,17 @@ static void xine_get_rootdir(char *rootdir, size_t maxlen) {
if ((s = strrchr(rootdir, XINE_DIRECTORY_SEPARATOR_CHAR))) *s = '\0';
}
+const char *xine_get_pluginroot(void) {
+ static char pluginroot[1024] = {0, };
+
+ if (!pluginroot[0]) {
+ xine_get_rootdir(pluginroot, sizeof(pluginroot) - strlen(XINE_REL_PLUGINROOT) - 1);
+ strcat(pluginroot, XINE_DIRECTORY_SEPARATOR_STRING XINE_REL_PLUGINROOT);
+ }
+
+ return pluginroot;
+}
+
const char *xine_get_plugindir(void) {
static char plugindir[1024] = {0, };
@@ -431,23 +456,22 @@ char *xine_chomp(char *str) {
* a thread-safe usecond sleep
*/
void xine_usec_sleep(unsigned usec) {
-#if 0
-#if HAVE_NANOSLEEP
+#ifdef WIN32
+ /* select does not work on win32 */
+ Sleep(usec / 1000);
+#else
+# if 0
+# if HAVE_NANOSLEEP
/* nanosleep is prefered on solaris, because it's mt-safe */
struct timespec ts, remaining;
-
ts.tv_sec = usec / 1000000;
ts.tv_nsec = (usec % 1000000) * 1000;
while (nanosleep (&ts, &remaining) == -1 && errno == EINTR)
ts = remaining;
-#else
-# if WIN32
- Sleep(usec / 1000);
-# else
+# else
usleep(usec);
-# endif
-#endif
-#else
+# endif
+# else
if (usec < 10000) {
usec = 10000;
}
@@ -455,6 +479,7 @@ void xine_usec_sleep(unsigned usec) {
tm.tv_sec = usec / 1000000;
tm.tv_usec = usec % 1000000;
select(0, 0, 0, 0, &tm);
+# endif
#endif
}
@@ -497,7 +522,7 @@ void xine_hexdump (const char *buf, int length) {
static const lang_locale_t *_get_first_lang_locale(const char *lcal) {
const lang_locale_t *llocale;
- int lang_len;
+ size_t lang_len;
char *mod;
if(lcal && *lcal) {
@@ -664,3 +689,11 @@ int xine_monotonic_clock(struct timeval *tv, struct timezone *tz)
#endif
}
+
+char *xine_strcat_realloc (char **dest, char *append)
+{
+ char *newstr = realloc (*dest, (*dest ? strlen (*dest) : 0) + strlen (append) + 1);
+ if (newstr)
+ strcat (*dest = newstr, append);
+ return newstr;
+}
diff --git a/src/xine-utils/xine_buffer.c b/src/xine-utils/xine_buffer.c
index 190ab5197..44d0acbab 100644
--- a/src/xine-utils/xine_buffer.c
+++ b/src/xine-utils/xine_buffer.c
@@ -47,6 +47,10 @@
* (eg during reallocation). The user must respect that.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -117,7 +121,7 @@ typedef struct {
*/
void *xine_buffer_init(int chunk_size) {
- uint8_t *data=xine_xmalloc(chunk_size+XINE_BUFFER_HEADER_SIZE);
+ uint8_t *data=calloc(1, chunk_size+XINE_BUFFER_HEADER_SIZE);
xine_buffer_header_t *header=(xine_buffer_header_t*)data;
header->size=chunk_size;
@@ -162,7 +166,7 @@ void *xine_buffer_dup(const void *buf) {
CHECK_MAGIC(buf);
#endif
-new=xine_xmalloc(GET_HEADER(buf)->size+XINE_BUFFER_HEADER_SIZE);
+ new = malloc(GET_HEADER(buf)->size+XINE_BUFFER_HEADER_SIZE);
xine_fast_memcpy(new, ((uint8_t*)buf)-XINE_BUFFER_HEADER_SIZE,
GET_HEADER(buf)->size+XINE_BUFFER_HEADER_SIZE);
diff --git a/src/xine-utils/xine_check.c b/src/xine-utils/xine_check.c
index f00a23832..b8465f3f8 100644
--- a/src/xine-utils/xine_check.c
+++ b/src/xine-utils/xine_check.c
@@ -44,7 +44,6 @@
#include <fcntl.h>
#include <unistd.h>
-#include "xine_check.h"
#include "xineutils.h"
#if defined(__linux__)
@@ -102,38 +101,7 @@ set_hc_result(xine_health_check_t* hc, int state, const char *format, ...)
#if defined(__linux__)
-xine_health_check_t* xine_health_check (xine_health_check_t* hc, int check_num) {
-
- switch(check_num) {
- case CHECK_KERNEL:
- hc = _x_health_check_kernel (hc);
- break;
- case CHECK_MTRR:
- hc = _x_health_check_mtrr (hc);
- break;
- case CHECK_CDROM:
- hc = _x_health_check_cdrom (hc);
- break;
- case CHECK_DVDROM:
- hc = _x_health_check_dvdrom (hc);
- break;
- case CHECK_DMA:
- hc = _x_health_check_dma (hc);
- break;
- case CHECK_X:
- hc = _x_health_check_x (hc);
- break;
- case CHECK_XV:
- hc = _x_health_check_xv (hc);
- break;
- default:
- hc->status = XINE_HEALTH_CHECK_NO_SUCH_CHECK;
- }
-
- return hc;
-}
-
-xine_health_check_t* _x_health_check_kernel (xine_health_check_t* hc) {
+static xine_health_check_t* _x_health_check_kernel (xine_health_check_t* hc) {
struct utsname kernel;
hc->title = "Check for kernel version";
@@ -153,7 +121,7 @@ xine_health_check_t* _x_health_check_kernel (xine_health_check_t* hc) {
}
#if defined(ARCH_X86) || defined(ARCH_X86_64)
-xine_health_check_t* _x_health_check_mtrr (xine_health_check_t* hc) {
+static xine_health_check_t* _x_health_check_mtrr (xine_health_check_t* hc) {
FILE *fd;
hc->title = "Check for MTRR support";
@@ -170,7 +138,7 @@ xine_health_check_t* _x_health_check_mtrr (xine_health_check_t* hc) {
return hc;
}
#else
-xine_health_check_t* _x_health_check_mtrr (xine_health_check_t* hc) {
+static xine_health_check_t* _x_health_check_mtrr (xine_health_check_t* hc) {
hc->title = "Check for MTRR support";
hc->explanation = "Don't worry about this one";
@@ -181,7 +149,7 @@ xine_health_check_t* _x_health_check_mtrr (xine_health_check_t* hc) {
}
#endif
-xine_health_check_t* _x_health_check_cdrom (xine_health_check_t* hc) {
+static xine_health_check_t* _x_health_check_cdrom (xine_health_check_t* hc) {
struct stat cdrom_st;
int fd;
@@ -217,7 +185,7 @@ xine_health_check_t* _x_health_check_cdrom (xine_health_check_t* hc) {
return hc;
}
-xine_health_check_t* _x_health_check_dvdrom(xine_health_check_t* hc) {
+static xine_health_check_t* _x_health_check_dvdrom(xine_health_check_t* hc) {
struct stat dvdrom_st;
int fd;
@@ -253,7 +221,7 @@ xine_health_check_t* _x_health_check_dvdrom(xine_health_check_t* hc) {
return hc;
}
-xine_health_check_t* _x_health_check_dma (xine_health_check_t* hc) {
+static xine_health_check_t* _x_health_check_dma (xine_health_check_t* hc) {
int is_scsi_dev = 0;
int fd = 0;
@@ -307,7 +275,7 @@ xine_health_check_t* _x_health_check_dma (xine_health_check_t* hc) {
}
-xine_health_check_t* _x_health_check_x (xine_health_check_t* hc) {
+static xine_health_check_t* _x_health_check_x (xine_health_check_t* hc) {
char* env_display = getenv("DISPLAY");
hc->title = "Check for X11 environment";
@@ -323,7 +291,7 @@ xine_health_check_t* _x_health_check_x (xine_health_check_t* hc) {
return hc;
}
-xine_health_check_t* _x_health_check_xv (xine_health_check_t* hc) {
+static xine_health_check_t* _x_health_check_xv (xine_health_check_t* hc) {
#ifdef HAVE_X11
#ifdef HAVE_XV
@@ -497,6 +465,37 @@ xine_health_check_t* _x_health_check_xv (xine_health_check_t* hc) {
#endif /* ! HAVE_X11 */
}
+xine_health_check_t* xine_health_check (xine_health_check_t* hc, int check_num) {
+
+ switch(check_num) {
+ case CHECK_KERNEL:
+ hc = _x_health_check_kernel (hc);
+ break;
+ case CHECK_MTRR:
+ hc = _x_health_check_mtrr (hc);
+ break;
+ case CHECK_CDROM:
+ hc = _x_health_check_cdrom (hc);
+ break;
+ case CHECK_DVDROM:
+ hc = _x_health_check_dvdrom (hc);
+ break;
+ case CHECK_DMA:
+ hc = _x_health_check_dma (hc);
+ break;
+ case CHECK_X:
+ hc = _x_health_check_x (hc);
+ break;
+ case CHECK_XV:
+ hc = _x_health_check_xv (hc);
+ break;
+ default:
+ hc->status = XINE_HEALTH_CHECK_NO_SUCH_CHECK;
+ }
+
+ return hc;
+}
+
#else /* !__linux__ */
xine_health_check_t* xine_health_check (xine_health_check_t* hc, int check_num) {
hc->title = "xine health check not supported on this platform";
diff --git a/src/xine-utils/xine_check.h b/src/xine-utils/xine_check.h
deleted file mode 100644
index 4b21bf74e..000000000
--- a/src/xine-utils/xine_check.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef XINE_CHECK_H
-#define XINE_CHECK_H
-#include <stdio.h>
-
-#ifdef XINE_COMPILE
-# include "xine.h"
-#else
-# include <xine.h>
-#endif
-
-/*
- * Start checking xine setup here
- *
- * cdrom_dev = Name of the device link for the cdrom drive (e.g. /dev/cdrom)
- * dvd_dev = Name of the device link for the dvd drive (e.g. /dev/dvd)
- */
-
-/* Get Kernel information */
-xine_health_check_t* _x_health_check_kernel(xine_health_check_t*);
-
-/* health_check MTRR */
-xine_health_check_t* _x_health_check_mtrr(xine_health_check_t*);
-
-/* health_check CDROM */
-xine_health_check_t* _x_health_check_cdrom(xine_health_check_t*);
-
-/* health_check DVDROM */
-xine_health_check_t* _x_health_check_dvdrom(xine_health_check_t*);
-
-/* health_check DMA settings of DVD drive*/
-xine_health_check_t* _x_health_check_dma(xine_health_check_t*);
-
-/* health_check X */
-xine_health_check_t* _x_health_check_x(xine_health_check_t*);
-
-/* health_check Xv extension */
-xine_health_check_t* _x_health_check_xv(xine_health_check_t*);
-
-#endif
diff --git a/src/xine-utils/xine_mmx.h b/src/xine-utils/xine_mmx.h
new file mode 100644
index 000000000..440d1efcc
--- /dev/null
+++ b/src/xine-utils/xine_mmx.h
@@ -0,0 +1,490 @@
+/*
+ * Copyright (C) 2000-2006 the xine project
+ *
+ * This file is part of xine, a free video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ */
+#ifndef XINE_MMX_H
+#define XINE_MMX_H
+
+#if defined(ARCH_X86) || defined(ARCH_X86_64)
+
+typedef union {
+ int64_t q; /* Quadword (64-bit) value */
+ uint64_t uq; /* Unsigned Quadword */
+ int d[2]; /* 2 Doubleword (32-bit) values */
+ unsigned int ud[2]; /* 2 Unsigned Doubleword */
+ short w[4]; /* 4 Word (16-bit) values */
+ unsigned short uw[4]; /* 4 Unsigned Word */
+ char b[8]; /* 8 Byte (8-bit) values */
+ unsigned char ub[8]; /* 8 Unsigned Byte */
+ float s[2]; /* Single-precision (32-bit) value */
+} ATTR_ALIGN(8) mmx_t; /* On an 8-byte (64-bit) boundary */
+
+
+
+#define mmx_i2r(op,imm,reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "i" (imm) )
+
+#define mmx_m2r(op,mem,reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "m" (mem))
+
+#define mmx_r2m(op,reg,mem) \
+ __asm__ __volatile__ (#op " %%" #reg ", %0" \
+ : "=m" (mem) \
+ : /* nothing */ )
+
+#define mmx_r2r(op,regs,regd) \
+ __asm__ __volatile__ (#op " %" #regs ", %" #regd)
+
+
+#define emms() __asm__ __volatile__ ("emms")
+
+#define movd_m2r(var,reg) mmx_m2r (movd, var, reg)
+#define movd_r2m(reg,var) mmx_r2m (movd, reg, var)
+#define movd_r2r(regs,regd) mmx_r2r (movd, regs, regd)
+
+#define movq_m2r(var,reg) mmx_m2r (movq, var, reg)
+#define movq_r2m(reg,var) mmx_r2m (movq, reg, var)
+#define movq_r2r(regs,regd) mmx_r2r (movq, regs, regd)
+
+#define packssdw_m2r(var,reg) mmx_m2r (packssdw, var, reg)
+#define packssdw_r2r(regs,regd) mmx_r2r (packssdw, regs, regd)
+#define packsswb_m2r(var,reg) mmx_m2r (packsswb, var, reg)
+#define packsswb_r2r(regs,regd) mmx_r2r (packsswb, regs, regd)
+
+#define packuswb_m2r(var,reg) mmx_m2r (packuswb, var, reg)
+#define packuswb_r2r(regs,regd) mmx_r2r (packuswb, regs, regd)
+
+#define paddb_m2r(var,reg) mmx_m2r (paddb, var, reg)
+#define paddb_r2r(regs,regd) mmx_r2r (paddb, regs, regd)
+#define paddd_m2r(var,reg) mmx_m2r (paddd, var, reg)
+#define paddd_r2r(regs,regd) mmx_r2r (paddd, regs, regd)
+#define paddw_m2r(var,reg) mmx_m2r (paddw, var, reg)
+#define paddw_r2r(regs,regd) mmx_r2r (paddw, regs, regd)
+
+#define paddsb_m2r(var,reg) mmx_m2r (paddsb, var, reg)
+#define paddsb_r2r(regs,regd) mmx_r2r (paddsb, regs, regd)
+#define paddsw_m2r(var,reg) mmx_m2r (paddsw, var, reg)
+#define paddsw_r2r(regs,regd) mmx_r2r (paddsw, regs, regd)
+
+#define paddusb_m2r(var,reg) mmx_m2r (paddusb, var, reg)
+#define paddusb_r2r(regs,regd) mmx_r2r (paddusb, regs, regd)
+#define paddusw_m2r(var,reg) mmx_m2r (paddusw, var, reg)
+#define paddusw_r2r(regs,regd) mmx_r2r (paddusw, regs, regd)
+
+#define pand_m2r(var,reg) mmx_m2r (pand, var, reg)
+#define pand_r2r(regs,regd) mmx_r2r (pand, regs, regd)
+
+#define pandn_m2r(var,reg) mmx_m2r (pandn, var, reg)
+#define pandn_r2r(regs,regd) mmx_r2r (pandn, regs, regd)
+
+#define pcmpeqb_m2r(var,reg) mmx_m2r (pcmpeqb, var, reg)
+#define pcmpeqb_r2r(regs,regd) mmx_r2r (pcmpeqb, regs, regd)
+#define pcmpeqd_m2r(var,reg) mmx_m2r (pcmpeqd, var, reg)
+#define pcmpeqd_r2r(regs,regd) mmx_r2r (pcmpeqd, regs, regd)
+#define pcmpeqw_m2r(var,reg) mmx_m2r (pcmpeqw, var, reg)
+#define pcmpeqw_r2r(regs,regd) mmx_r2r (pcmpeqw, regs, regd)
+
+#define pcmpgtb_m2r(var,reg) mmx_m2r (pcmpgtb, var, reg)
+#define pcmpgtb_r2r(regs,regd) mmx_r2r (pcmpgtb, regs, regd)
+#define pcmpgtd_m2r(var,reg) mmx_m2r (pcmpgtd, var, reg)
+#define pcmpgtd_r2r(regs,regd) mmx_r2r (pcmpgtd, regs, regd)
+#define pcmpgtw_m2r(var,reg) mmx_m2r (pcmpgtw, var, reg)
+#define pcmpgtw_r2r(regs,regd) mmx_r2r (pcmpgtw, regs, regd)
+
+#define pmaddwd_m2r(var,reg) mmx_m2r (pmaddwd, var, reg)
+#define pmaddwd_r2r(regs,regd) mmx_r2r (pmaddwd, regs, regd)
+
+#define pmulhw_m2r(var,reg) mmx_m2r (pmulhw, var, reg)
+#define pmulhw_r2r(regs,regd) mmx_r2r (pmulhw, regs, regd)
+
+#define pmullw_m2r(var,reg) mmx_m2r (pmullw, var, reg)
+#define pmullw_r2r(regs,regd) mmx_r2r (pmullw, regs, regd)
+
+#define por_m2r(var,reg) mmx_m2r (por, var, reg)
+#define por_r2r(regs,regd) mmx_r2r (por, regs, regd)
+
+#define pslld_i2r(imm,reg) mmx_i2r (pslld, imm, reg)
+#define pslld_m2r(var,reg) mmx_m2r (pslld, var, reg)
+#define pslld_r2r(regs,regd) mmx_r2r (pslld, regs, regd)
+#define psllq_i2r(imm,reg) mmx_i2r (psllq, imm, reg)
+#define psllq_m2r(var,reg) mmx_m2r (psllq, var, reg)
+#define psllq_r2r(regs,regd) mmx_r2r (psllq, regs, regd)
+#define psllw_i2r(imm,reg) mmx_i2r (psllw, imm, reg)
+#define psllw_m2r(var,reg) mmx_m2r (psllw, var, reg)
+#define psllw_r2r(regs,regd) mmx_r2r (psllw, regs, regd)
+
+#define psrad_i2r(imm,reg) mmx_i2r (psrad, imm, reg)
+#define psrad_m2r(var,reg) mmx_m2r (psrad, var, reg)
+#define psrad_r2r(regs,regd) mmx_r2r (psrad, regs, regd)
+#define psraw_i2r(imm,reg) mmx_i2r (psraw, imm, reg)
+#define psraw_m2r(var,reg) mmx_m2r (psraw, var, reg)
+#define psraw_r2r(regs,regd) mmx_r2r (psraw, regs, regd)
+
+#define psrld_i2r(imm,reg) mmx_i2r (psrld, imm, reg)
+#define psrld_m2r(var,reg) mmx_m2r (psrld, var, reg)
+#define psrld_r2r(regs,regd) mmx_r2r (psrld, regs, regd)
+#define psrlq_i2r(imm,reg) mmx_i2r (psrlq, imm, reg)
+#define psrlq_m2r(var,reg) mmx_m2r (psrlq, var, reg)
+#define psrlq_r2r(regs,regd) mmx_r2r (psrlq, regs, regd)
+#define psrlw_i2r(imm,reg) mmx_i2r (psrlw, imm, reg)
+#define psrlw_m2r(var,reg) mmx_m2r (psrlw, var, reg)
+#define psrlw_r2r(regs,regd) mmx_r2r (psrlw, regs, regd)
+
+#define psubb_m2r(var,reg) mmx_m2r (psubb, var, reg)
+#define psubb_r2r(regs,regd) mmx_r2r (psubb, regs, regd)
+#define psubd_m2r(var,reg) mmx_m2r (psubd, var, reg)
+#define psubd_r2r(regs,regd) mmx_r2r (psubd, regs, regd)
+#define psubw_m2r(var,reg) mmx_m2r (psubw, var, reg)
+#define psubw_r2r(regs,regd) mmx_r2r (psubw, regs, regd)
+
+#define psubsb_m2r(var,reg) mmx_m2r (psubsb, var, reg)
+#define psubsb_r2r(regs,regd) mmx_r2r (psubsb, regs, regd)
+#define psubsw_m2r(var,reg) mmx_m2r (psubsw, var, reg)
+#define psubsw_r2r(regs,regd) mmx_r2r (psubsw, regs, regd)
+
+#define psubusb_m2r(var,reg) mmx_m2r (psubusb, var, reg)
+#define psubusb_r2r(regs,regd) mmx_r2r (psubusb, regs, regd)
+#define psubusw_m2r(var,reg) mmx_m2r (psubusw, var, reg)
+#define psubusw_r2r(regs,regd) mmx_r2r (psubusw, regs, regd)
+
+#define punpckhbw_m2r(var,reg) mmx_m2r (punpckhbw, var, reg)
+#define punpckhbw_r2r(regs,regd) mmx_r2r (punpckhbw, regs, regd)
+#define punpckhdq_m2r(var,reg) mmx_m2r (punpckhdq, var, reg)
+#define punpckhdq_r2r(regs,regd) mmx_r2r (punpckhdq, regs, regd)
+#define punpckhwd_m2r(var,reg) mmx_m2r (punpckhwd, var, reg)
+#define punpckhwd_r2r(regs,regd) mmx_r2r (punpckhwd, regs, regd)
+
+#define punpcklbw_m2r(var,reg) mmx_m2r (punpcklbw, var, reg)
+#define punpcklbw_r2r(regs,regd) mmx_r2r (punpcklbw, regs, regd)
+#define punpckldq_m2r(var,reg) mmx_m2r (punpckldq, var, reg)
+#define punpckldq_r2r(regs,regd) mmx_r2r (punpckldq, regs, regd)
+#define punpcklwd_m2r(var,reg) mmx_m2r (punpcklwd, var, reg)
+#define punpcklwd_r2r(regs,regd) mmx_r2r (punpcklwd, regs, regd)
+
+#define pxor_m2r(var,reg) mmx_m2r (pxor, var, reg)
+#define pxor_r2r(regs,regd) mmx_r2r (pxor, regs, regd)
+
+
+/* 3DNOW extensions */
+
+#define pavgusb_m2r(var,reg) mmx_m2r (pavgusb, var, reg)
+#define pavgusb_r2r(regs,regd) mmx_r2r (pavgusb, regs, regd)
+
+
+/* AMD MMX extensions - also available in intel SSE */
+
+
+#define mmx_m2ri(op,mem,reg,imm) \
+ __asm__ __volatile__ (#op " %1, %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (mem), "X" (imm))
+#define mmx_r2ri(op,regs,regd,imm) \
+ __asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \
+ : /* nothing */ \
+ : "X" (imm) )
+
+#define mmx_fetch(mem,hint) \
+ __asm__ __volatile__ ("prefetch" #hint " %0" \
+ : /* nothing */ \
+ : "X" (mem))
+
+
+#define maskmovq(regs,maskreg) mmx_r2ri (maskmovq, regs, maskreg)
+
+#define movntq_r2m(mmreg,var) mmx_r2m (movntq, mmreg, var)
+
+#define pavgb_m2r(var,reg) mmx_m2r (pavgb, var, reg)
+#define pavgb_r2r(regs,regd) mmx_r2r (pavgb, regs, regd)
+#define pavgw_m2r(var,reg) mmx_m2r (pavgw, var, reg)
+#define pavgw_r2r(regs,regd) mmx_r2r (pavgw, regs, regd)
+
+#define pextrw_r2r(mmreg,reg,imm) mmx_r2ri (pextrw, mmreg, reg, imm)
+
+#define pinsrw_r2r(reg,mmreg,imm) mmx_r2ri (pinsrw, reg, mmreg, imm)
+
+#define pmaxsw_m2r(var,reg) mmx_m2r (pmaxsw, var, reg)
+#define pmaxsw_r2r(regs,regd) mmx_r2r (pmaxsw, regs, regd)
+
+#define pmaxub_m2r(var,reg) mmx_m2r (pmaxub, var, reg)
+#define pmaxub_r2r(regs,regd) mmx_r2r (pmaxub, regs, regd)
+
+#define pminsw_m2r(var,reg) mmx_m2r (pminsw, var, reg)
+#define pminsw_r2r(regs,regd) mmx_r2r (pminsw, regs, regd)
+
+#define pminub_m2r(var,reg) mmx_m2r (pminub, var, reg)
+#define pminub_r2r(regs,regd) mmx_r2r (pminub, regs, regd)
+
+#define pmovmskb(mmreg,reg) \
+ __asm__ __volatile__ ("movmskps %" #mmreg ", %" #reg)
+
+#define pmulhuw_m2r(var,reg) mmx_m2r (pmulhuw, var, reg)
+#define pmulhuw_r2r(regs,regd) mmx_r2r (pmulhuw, regs, regd)
+
+#define prefetcht0(mem) mmx_fetch (mem, t0)
+#define prefetcht1(mem) mmx_fetch (mem, t1)
+#define prefetcht2(mem) mmx_fetch (mem, t2)
+#define prefetchnta(mem) mmx_fetch (mem, nta)
+
+#define psadbw_m2r(var,reg) mmx_m2r (psadbw, var, reg)
+#define psadbw_r2r(regs,regd) mmx_r2r (psadbw, regs, regd)
+
+#define pshufw_m2r(var,reg,imm) mmx_m2ri(pshufw, var, reg, imm)
+#define pshufw_r2r(regs,regd,imm) mmx_r2ri(pshufw, regs, regd, imm)
+
+#define sfence() __asm__ __volatile__ ("sfence\n\t")
+
+typedef union {
+ float sf[4]; /* Single-precision (32-bit) value */
+} ATTR_ALIGN(16) sse_t; /* On a 16 byte (128-bit) boundary */
+
+
+#define sse_i2r(op, imm, reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (imm) )
+
+#define sse_m2r(op, mem, reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (mem))
+
+#define sse_r2m(op, reg, mem) \
+ __asm__ __volatile__ (#op " %%" #reg ", %0" \
+ : "=X" (mem) \
+ : /* nothing */ )
+
+#define sse_r2r(op, regs, regd) \
+ __asm__ __volatile__ (#op " %" #regs ", %" #regd)
+
+#define sse_r2ri(op, regs, regd, imm) \
+ __asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \
+ : /* nothing */ \
+ : "X" (imm) )
+
+#define sse_m2ri(op, mem, reg, subop) \
+ __asm__ __volatile__ (#op " %0, %%" #reg ", " #subop \
+ : /* nothing */ \
+ : "X" (mem))
+
+
+#define movaps_m2r(var, reg) sse_m2r(movaps, var, reg)
+#define movaps_r2m(reg, var) sse_r2m(movaps, reg, var)
+#define movaps_r2r(regs, regd) sse_r2r(movaps, regs, regd)
+
+#define movntps_r2m(xmmreg, var) sse_r2m(movntps, xmmreg, var)
+
+#define movups_m2r(var, reg) sse_m2r(movups, var, reg)
+#define movups_r2m(reg, var) sse_r2m(movups, reg, var)
+#define movups_r2r(regs, regd) sse_r2r(movups, regs, regd)
+
+#define movhlps_r2r(regs, regd) sse_r2r(movhlps, regs, regd)
+
+#define movlhps_r2r(regs, regd) sse_r2r(movlhps, regs, regd)
+
+#define movhps_m2r(var, reg) sse_m2r(movhps, var, reg)
+#define movhps_r2m(reg, var) sse_r2m(movhps, reg, var)
+
+#define movlps_m2r(var, reg) sse_m2r(movlps, var, reg)
+#define movlps_r2m(reg, var) sse_r2m(movlps, reg, var)
+
+#define movss_m2r(var, reg) sse_m2r(movss, var, reg)
+#define movss_r2m(reg, var) sse_r2m(movss, reg, var)
+#define movss_r2r(regs, regd) sse_r2r(movss, regs, regd)
+
+#define shufps_m2r(var, reg, index) sse_m2ri(shufps, var, reg, index)
+#define shufps_r2r(regs, regd, index) sse_r2ri(shufps, regs, regd, index)
+
+#define cvtpi2ps_m2r(var, xmmreg) sse_m2r(cvtpi2ps, var, xmmreg)
+#define cvtpi2ps_r2r(mmreg, xmmreg) sse_r2r(cvtpi2ps, mmreg, xmmreg)
+
+#define cvtps2pi_m2r(var, mmreg) sse_m2r(cvtps2pi, var, mmreg)
+#define cvtps2pi_r2r(xmmreg, mmreg) sse_r2r(cvtps2pi, mmreg, xmmreg)
+
+#define cvttps2pi_m2r(var, mmreg) sse_m2r(cvttps2pi, var, mmreg)
+#define cvttps2pi_r2r(xmmreg, mmreg) sse_r2r(cvttps2pi, mmreg, xmmreg)
+
+#define cvtsi2ss_m2r(var, xmmreg) sse_m2r(cvtsi2ss, var, xmmreg)
+#define cvtsi2ss_r2r(reg, xmmreg) sse_r2r(cvtsi2ss, reg, xmmreg)
+
+#define cvtss2si_m2r(var, reg) sse_m2r(cvtss2si, var, reg)
+#define cvtss2si_r2r(xmmreg, reg) sse_r2r(cvtss2si, xmmreg, reg)
+
+#define cvttss2si_m2r(var, reg) sse_m2r(cvtss2si, var, reg)
+#define cvttss2si_r2r(xmmreg, reg) sse_r2r(cvtss2si, xmmreg, reg)
+
+#define movmskps(xmmreg, reg) \
+ __asm__ __volatile__ ("movmskps %" #xmmreg ", %" #reg)
+
+#define addps_m2r(var, reg) sse_m2r(addps, var, reg)
+#define addps_r2r(regs, regd) sse_r2r(addps, regs, regd)
+
+#define addss_m2r(var, reg) sse_m2r(addss, var, reg)
+#define addss_r2r(regs, regd) sse_r2r(addss, regs, regd)
+
+#define subps_m2r(var, reg) sse_m2r(subps, var, reg)
+#define subps_r2r(regs, regd) sse_r2r(subps, regs, regd)
+
+#define subss_m2r(var, reg) sse_m2r(subss, var, reg)
+#define subss_r2r(regs, regd) sse_r2r(subss, regs, regd)
+
+#define mulps_m2r(var, reg) sse_m2r(mulps, var, reg)
+#define mulps_r2r(regs, regd) sse_r2r(mulps, regs, regd)
+
+#define mulss_m2r(var, reg) sse_m2r(mulss, var, reg)
+#define mulss_r2r(regs, regd) sse_r2r(mulss, regs, regd)
+
+#define divps_m2r(var, reg) sse_m2r(divps, var, reg)
+#define divps_r2r(regs, regd) sse_r2r(divps, regs, regd)
+
+#define divss_m2r(var, reg) sse_m2r(divss, var, reg)
+#define divss_r2r(regs, regd) sse_r2r(divss, regs, regd)
+
+#define rcpps_m2r(var, reg) sse_m2r(rcpps, var, reg)
+#define rcpps_r2r(regs, regd) sse_r2r(rcpps, regs, regd)
+
+#define rcpss_m2r(var, reg) sse_m2r(rcpss, var, reg)
+#define rcpss_r2r(regs, regd) sse_r2r(rcpss, regs, regd)
+
+#define rsqrtps_m2r(var, reg) sse_m2r(rsqrtps, var, reg)
+#define rsqrtps_r2r(regs, regd) sse_r2r(rsqrtps, regs, regd)
+
+#define rsqrtss_m2r(var, reg) sse_m2r(rsqrtss, var, reg)
+#define rsqrtss_r2r(regs, regd) sse_r2r(rsqrtss, regs, regd)
+
+#define sqrtps_m2r(var, reg) sse_m2r(sqrtps, var, reg)
+#define sqrtps_r2r(regs, regd) sse_r2r(sqrtps, regs, regd)
+
+#define sqrtss_m2r(var, reg) sse_m2r(sqrtss, var, reg)
+#define sqrtss_r2r(regs, regd) sse_r2r(sqrtss, regs, regd)
+
+#define andps_m2r(var, reg) sse_m2r(andps, var, reg)
+#define andps_r2r(regs, regd) sse_r2r(andps, regs, regd)
+
+#define andnps_m2r(var, reg) sse_m2r(andnps, var, reg)
+#define andnps_r2r(regs, regd) sse_r2r(andnps, regs, regd)
+
+#define orps_m2r(var, reg) sse_m2r(orps, var, reg)
+#define orps_r2r(regs, regd) sse_r2r(orps, regs, regd)
+
+#define xorps_m2r(var, reg) sse_m2r(xorps, var, reg)
+#define xorps_r2r(regs, regd) sse_r2r(xorps, regs, regd)
+
+#define maxps_m2r(var, reg) sse_m2r(maxps, var, reg)
+#define maxps_r2r(regs, regd) sse_r2r(maxps, regs, regd)
+
+#define maxss_m2r(var, reg) sse_m2r(maxss, var, reg)
+#define maxss_r2r(regs, regd) sse_r2r(maxss, regs, regd)
+
+#define minps_m2r(var, reg) sse_m2r(minps, var, reg)
+#define minps_r2r(regs, regd) sse_r2r(minps, regs, regd)
+
+#define minss_m2r(var, reg) sse_m2r(minss, var, reg)
+#define minss_r2r(regs, regd) sse_r2r(minss, regs, regd)
+
+#define cmpps_m2r(var, reg, op) sse_m2ri(cmpps, var, reg, op)
+#define cmpps_r2r(regs, regd, op) sse_r2ri(cmpps, regs, regd, op)
+
+#define cmpeqps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 0)
+#define cmpeqps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 0)
+
+#define cmpltps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 1)
+#define cmpltps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 1)
+
+#define cmpleps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 2)
+#define cmpleps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 2)
+
+#define cmpunordps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 3)
+#define cmpunordps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 3)
+
+#define cmpneqps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 4)
+#define cmpneqps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 4)
+
+#define cmpnltps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 5)
+#define cmpnltps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 5)
+
+#define cmpnleps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 6)
+#define cmpnleps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 6)
+
+#define cmpordps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 7)
+#define cmpordps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 7)
+
+#define cmpss_m2r(var, reg, op) sse_m2ri(cmpss, var, reg, op)
+#define cmpss_r2r(regs, regd, op) sse_r2ri(cmpss, regs, regd, op)
+
+#define cmpeqss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 0)
+#define cmpeqss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 0)
+
+#define cmpltss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 1)
+#define cmpltss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 1)
+
+#define cmpless_m2r(var, reg) sse_m2ri(cmpss, var, reg, 2)
+#define cmpless_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 2)
+
+#define cmpunordss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 3)
+#define cmpunordss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 3)
+
+#define cmpneqss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 4)
+#define cmpneqss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 4)
+
+#define cmpnltss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 5)
+#define cmpnltss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 5)
+
+#define cmpnless_m2r(var, reg) sse_m2ri(cmpss, var, reg, 6)
+#define cmpnless_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 6)
+
+#define cmpordss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 7)
+#define cmpordss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 7)
+
+#define comiss_m2r(var, reg) sse_m2r(comiss, var, reg)
+#define comiss_r2r(regs, regd) sse_r2r(comiss, regs, regd)
+
+#define ucomiss_m2r(var, reg) sse_m2r(ucomiss, var, reg)
+#define ucomiss_r2r(regs, regd) sse_r2r(ucomiss, regs, regd)
+
+#define unpcklps_m2r(var, reg) sse_m2r(unpcklps, var, reg)
+#define unpcklps_r2r(regs, regd) sse_r2r(unpcklps, regs, regd)
+
+#define unpckhps_m2r(var, reg) sse_m2r(unpckhps, var, reg)
+#define unpckhps_r2r(regs, regd) sse_r2r(unpckhps, regs, regd)
+
+#define fxrstor(mem) \
+ __asm__ __volatile__ ("fxrstor %0" \
+ : /* nothing */ \
+ : "X" (mem))
+
+#define fxsave(mem) \
+ __asm__ __volatile__ ("fxsave %0" \
+ : /* nothing */ \
+ : "X" (mem))
+
+#define stmxcsr(mem) \
+ __asm__ __volatile__ ("stmxcsr %0" \
+ : /* nothing */ \
+ : "X" (mem))
+
+#define ldmxcsr(mem) \
+ __asm__ __volatile__ ("ldmxcsr %0" \
+ : /* nothing */ \
+ : "X" (mem))
+#endif /*ARCH_X86 */
+
+#endif /*XINE_MMX_H*/
diff --git a/src/xine-utils/xineutils.h b/src/xine-utils/xineutils.h
index 120cb3578..581932cee 100644
--- a/src/xine-utils/xineutils.h
+++ b/src/xine-utils/xineutils.h
@@ -24,10 +24,6 @@
extern "C" {
#endif
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
@@ -43,6 +39,7 @@ extern "C" {
# include "list.h"
# include "array.h"
# include "sorted_array.h"
+# include "xine_mmx.h"
#else
# ifdef WIN32
# include <winsock.h>
@@ -58,6 +55,7 @@ extern "C" {
# include <xine/list.h>
# include <xine/array.h>
# include <xine/sorted_array.h>
+# include <xine/xine_mmx.h>
#endif
#include <stdio.h>
@@ -125,474 +123,8 @@ extern "C" {
#define MM_SSE MM_ACCEL_X86_SSE
#define MM_SSE2 MM_ACCEL_X86_SSE2
-uint32_t xine_mm_accel (void) XINE_PROTECTED;
-
-#if defined(ARCH_X86) || defined(ARCH_X86_64)
-
-typedef union {
- int64_t q; /* Quadword (64-bit) value */
- uint64_t uq; /* Unsigned Quadword */
- int d[2]; /* 2 Doubleword (32-bit) values */
- unsigned int ud[2]; /* 2 Unsigned Doubleword */
- short w[4]; /* 4 Word (16-bit) values */
- unsigned short uw[4]; /* 4 Unsigned Word */
- char b[8]; /* 8 Byte (8-bit) values */
- unsigned char ub[8]; /* 8 Unsigned Byte */
- float s[2]; /* Single-precision (32-bit) value */
-} ATTR_ALIGN(8) mmx_t; /* On an 8-byte (64-bit) boundary */
-
-
-
-#define mmx_i2r(op,imm,reg) \
- __asm__ __volatile__ (#op " %0, %%" #reg \
- : /* nothing */ \
- : "i" (imm) )
-
-#define mmx_m2r(op,mem,reg) \
- __asm__ __volatile__ (#op " %0, %%" #reg \
- : /* nothing */ \
- : "m" (mem))
-
-#define mmx_r2m(op,reg,mem) \
- __asm__ __volatile__ (#op " %%" #reg ", %0" \
- : "=m" (mem) \
- : /* nothing */ )
-
-#define mmx_r2r(op,regs,regd) \
- __asm__ __volatile__ (#op " %" #regs ", %" #regd)
-
-
-#define emms() __asm__ __volatile__ ("emms")
-
-#define movd_m2r(var,reg) mmx_m2r (movd, var, reg)
-#define movd_r2m(reg,var) mmx_r2m (movd, reg, var)
-#define movd_r2r(regs,regd) mmx_r2r (movd, regs, regd)
-
-#define movq_m2r(var,reg) mmx_m2r (movq, var, reg)
-#define movq_r2m(reg,var) mmx_r2m (movq, reg, var)
-#define movq_r2r(regs,regd) mmx_r2r (movq, regs, regd)
-
-#define packssdw_m2r(var,reg) mmx_m2r (packssdw, var, reg)
-#define packssdw_r2r(regs,regd) mmx_r2r (packssdw, regs, regd)
-#define packsswb_m2r(var,reg) mmx_m2r (packsswb, var, reg)
-#define packsswb_r2r(regs,regd) mmx_r2r (packsswb, regs, regd)
-
-#define packuswb_m2r(var,reg) mmx_m2r (packuswb, var, reg)
-#define packuswb_r2r(regs,regd) mmx_r2r (packuswb, regs, regd)
-
-#define paddb_m2r(var,reg) mmx_m2r (paddb, var, reg)
-#define paddb_r2r(regs,regd) mmx_r2r (paddb, regs, regd)
-#define paddd_m2r(var,reg) mmx_m2r (paddd, var, reg)
-#define paddd_r2r(regs,regd) mmx_r2r (paddd, regs, regd)
-#define paddw_m2r(var,reg) mmx_m2r (paddw, var, reg)
-#define paddw_r2r(regs,regd) mmx_r2r (paddw, regs, regd)
-
-#define paddsb_m2r(var,reg) mmx_m2r (paddsb, var, reg)
-#define paddsb_r2r(regs,regd) mmx_r2r (paddsb, regs, regd)
-#define paddsw_m2r(var,reg) mmx_m2r (paddsw, var, reg)
-#define paddsw_r2r(regs,regd) mmx_r2r (paddsw, regs, regd)
-
-#define paddusb_m2r(var,reg) mmx_m2r (paddusb, var, reg)
-#define paddusb_r2r(regs,regd) mmx_r2r (paddusb, regs, regd)
-#define paddusw_m2r(var,reg) mmx_m2r (paddusw, var, reg)
-#define paddusw_r2r(regs,regd) mmx_r2r (paddusw, regs, regd)
-
-#define pand_m2r(var,reg) mmx_m2r (pand, var, reg)
-#define pand_r2r(regs,regd) mmx_r2r (pand, regs, regd)
-
-#define pandn_m2r(var,reg) mmx_m2r (pandn, var, reg)
-#define pandn_r2r(regs,regd) mmx_r2r (pandn, regs, regd)
-
-#define pcmpeqb_m2r(var,reg) mmx_m2r (pcmpeqb, var, reg)
-#define pcmpeqb_r2r(regs,regd) mmx_r2r (pcmpeqb, regs, regd)
-#define pcmpeqd_m2r(var,reg) mmx_m2r (pcmpeqd, var, reg)
-#define pcmpeqd_r2r(regs,regd) mmx_r2r (pcmpeqd, regs, regd)
-#define pcmpeqw_m2r(var,reg) mmx_m2r (pcmpeqw, var, reg)
-#define pcmpeqw_r2r(regs,regd) mmx_r2r (pcmpeqw, regs, regd)
-
-#define pcmpgtb_m2r(var,reg) mmx_m2r (pcmpgtb, var, reg)
-#define pcmpgtb_r2r(regs,regd) mmx_r2r (pcmpgtb, regs, regd)
-#define pcmpgtd_m2r(var,reg) mmx_m2r (pcmpgtd, var, reg)
-#define pcmpgtd_r2r(regs,regd) mmx_r2r (pcmpgtd, regs, regd)
-#define pcmpgtw_m2r(var,reg) mmx_m2r (pcmpgtw, var, reg)
-#define pcmpgtw_r2r(regs,regd) mmx_r2r (pcmpgtw, regs, regd)
-
-#define pmaddwd_m2r(var,reg) mmx_m2r (pmaddwd, var, reg)
-#define pmaddwd_r2r(regs,regd) mmx_r2r (pmaddwd, regs, regd)
-
-#define pmulhw_m2r(var,reg) mmx_m2r (pmulhw, var, reg)
-#define pmulhw_r2r(regs,regd) mmx_r2r (pmulhw, regs, regd)
-
-#define pmullw_m2r(var,reg) mmx_m2r (pmullw, var, reg)
-#define pmullw_r2r(regs,regd) mmx_r2r (pmullw, regs, regd)
-
-#define por_m2r(var,reg) mmx_m2r (por, var, reg)
-#define por_r2r(regs,regd) mmx_r2r (por, regs, regd)
-
-#define pslld_i2r(imm,reg) mmx_i2r (pslld, imm, reg)
-#define pslld_m2r(var,reg) mmx_m2r (pslld, var, reg)
-#define pslld_r2r(regs,regd) mmx_r2r (pslld, regs, regd)
-#define psllq_i2r(imm,reg) mmx_i2r (psllq, imm, reg)
-#define psllq_m2r(var,reg) mmx_m2r (psllq, var, reg)
-#define psllq_r2r(regs,regd) mmx_r2r (psllq, regs, regd)
-#define psllw_i2r(imm,reg) mmx_i2r (psllw, imm, reg)
-#define psllw_m2r(var,reg) mmx_m2r (psllw, var, reg)
-#define psllw_r2r(regs,regd) mmx_r2r (psllw, regs, regd)
-
-#define psrad_i2r(imm,reg) mmx_i2r (psrad, imm, reg)
-#define psrad_m2r(var,reg) mmx_m2r (psrad, var, reg)
-#define psrad_r2r(regs,regd) mmx_r2r (psrad, regs, regd)
-#define psraw_i2r(imm,reg) mmx_i2r (psraw, imm, reg)
-#define psraw_m2r(var,reg) mmx_m2r (psraw, var, reg)
-#define psraw_r2r(regs,regd) mmx_r2r (psraw, regs, regd)
-
-#define psrld_i2r(imm,reg) mmx_i2r (psrld, imm, reg)
-#define psrld_m2r(var,reg) mmx_m2r (psrld, var, reg)
-#define psrld_r2r(regs,regd) mmx_r2r (psrld, regs, regd)
-#define psrlq_i2r(imm,reg) mmx_i2r (psrlq, imm, reg)
-#define psrlq_m2r(var,reg) mmx_m2r (psrlq, var, reg)
-#define psrlq_r2r(regs,regd) mmx_r2r (psrlq, regs, regd)
-#define psrlw_i2r(imm,reg) mmx_i2r (psrlw, imm, reg)
-#define psrlw_m2r(var,reg) mmx_m2r (psrlw, var, reg)
-#define psrlw_r2r(regs,regd) mmx_r2r (psrlw, regs, regd)
-
-#define psubb_m2r(var,reg) mmx_m2r (psubb, var, reg)
-#define psubb_r2r(regs,regd) mmx_r2r (psubb, regs, regd)
-#define psubd_m2r(var,reg) mmx_m2r (psubd, var, reg)
-#define psubd_r2r(regs,regd) mmx_r2r (psubd, regs, regd)
-#define psubw_m2r(var,reg) mmx_m2r (psubw, var, reg)
-#define psubw_r2r(regs,regd) mmx_r2r (psubw, regs, regd)
-
-#define psubsb_m2r(var,reg) mmx_m2r (psubsb, var, reg)
-#define psubsb_r2r(regs,regd) mmx_r2r (psubsb, regs, regd)
-#define psubsw_m2r(var,reg) mmx_m2r (psubsw, var, reg)
-#define psubsw_r2r(regs,regd) mmx_r2r (psubsw, regs, regd)
-
-#define psubusb_m2r(var,reg) mmx_m2r (psubusb, var, reg)
-#define psubusb_r2r(regs,regd) mmx_r2r (psubusb, regs, regd)
-#define psubusw_m2r(var,reg) mmx_m2r (psubusw, var, reg)
-#define psubusw_r2r(regs,regd) mmx_r2r (psubusw, regs, regd)
-
-#define punpckhbw_m2r(var,reg) mmx_m2r (punpckhbw, var, reg)
-#define punpckhbw_r2r(regs,regd) mmx_r2r (punpckhbw, regs, regd)
-#define punpckhdq_m2r(var,reg) mmx_m2r (punpckhdq, var, reg)
-#define punpckhdq_r2r(regs,regd) mmx_r2r (punpckhdq, regs, regd)
-#define punpckhwd_m2r(var,reg) mmx_m2r (punpckhwd, var, reg)
-#define punpckhwd_r2r(regs,regd) mmx_r2r (punpckhwd, regs, regd)
-
-#define punpcklbw_m2r(var,reg) mmx_m2r (punpcklbw, var, reg)
-#define punpcklbw_r2r(regs,regd) mmx_r2r (punpcklbw, regs, regd)
-#define punpckldq_m2r(var,reg) mmx_m2r (punpckldq, var, reg)
-#define punpckldq_r2r(regs,regd) mmx_r2r (punpckldq, regs, regd)
-#define punpcklwd_m2r(var,reg) mmx_m2r (punpcklwd, var, reg)
-#define punpcklwd_r2r(regs,regd) mmx_r2r (punpcklwd, regs, regd)
-
-#define pxor_m2r(var,reg) mmx_m2r (pxor, var, reg)
-#define pxor_r2r(regs,regd) mmx_r2r (pxor, regs, regd)
-
-
-/* 3DNOW extensions */
-
-#define pavgusb_m2r(var,reg) mmx_m2r (pavgusb, var, reg)
-#define pavgusb_r2r(regs,regd) mmx_r2r (pavgusb, regs, regd)
-
-
-/* AMD MMX extensions - also available in intel SSE */
-
-
-#define mmx_m2ri(op,mem,reg,imm) \
- __asm__ __volatile__ (#op " %1, %0, %%" #reg \
- : /* nothing */ \
- : "X" (mem), "X" (imm))
-#define mmx_r2ri(op,regs,regd,imm) \
- __asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \
- : /* nothing */ \
- : "X" (imm) )
-
-#define mmx_fetch(mem,hint) \
- __asm__ __volatile__ ("prefetch" #hint " %0" \
- : /* nothing */ \
- : "X" (mem))
-
-
-#define maskmovq(regs,maskreg) mmx_r2ri (maskmovq, regs, maskreg)
-
-#define movntq_r2m(mmreg,var) mmx_r2m (movntq, mmreg, var)
-
-#define pavgb_m2r(var,reg) mmx_m2r (pavgb, var, reg)
-#define pavgb_r2r(regs,regd) mmx_r2r (pavgb, regs, regd)
-#define pavgw_m2r(var,reg) mmx_m2r (pavgw, var, reg)
-#define pavgw_r2r(regs,regd) mmx_r2r (pavgw, regs, regd)
-
-#define pextrw_r2r(mmreg,reg,imm) mmx_r2ri (pextrw, mmreg, reg, imm)
-
-#define pinsrw_r2r(reg,mmreg,imm) mmx_r2ri (pinsrw, reg, mmreg, imm)
-
-#define pmaxsw_m2r(var,reg) mmx_m2r (pmaxsw, var, reg)
-#define pmaxsw_r2r(regs,regd) mmx_r2r (pmaxsw, regs, regd)
-
-#define pmaxub_m2r(var,reg) mmx_m2r (pmaxub, var, reg)
-#define pmaxub_r2r(regs,regd) mmx_r2r (pmaxub, regs, regd)
-
-#define pminsw_m2r(var,reg) mmx_m2r (pminsw, var, reg)
-#define pminsw_r2r(regs,regd) mmx_r2r (pminsw, regs, regd)
-
-#define pminub_m2r(var,reg) mmx_m2r (pminub, var, reg)
-#define pminub_r2r(regs,regd) mmx_r2r (pminub, regs, regd)
-
-#define pmovmskb(mmreg,reg) \
- __asm__ __volatile__ ("movmskps %" #mmreg ", %" #reg)
-
-#define pmulhuw_m2r(var,reg) mmx_m2r (pmulhuw, var, reg)
-#define pmulhuw_r2r(regs,regd) mmx_r2r (pmulhuw, regs, regd)
-
-#define prefetcht0(mem) mmx_fetch (mem, t0)
-#define prefetcht1(mem) mmx_fetch (mem, t1)
-#define prefetcht2(mem) mmx_fetch (mem, t2)
-#define prefetchnta(mem) mmx_fetch (mem, nta)
-
-#define psadbw_m2r(var,reg) mmx_m2r (psadbw, var, reg)
-#define psadbw_r2r(regs,regd) mmx_r2r (psadbw, regs, regd)
-
-#define pshufw_m2r(var,reg,imm) mmx_m2ri(pshufw, var, reg, imm)
-#define pshufw_r2r(regs,regd,imm) mmx_r2ri(pshufw, regs, regd, imm)
-
-#define sfence() __asm__ __volatile__ ("sfence\n\t")
-
-typedef union {
- float sf[4]; /* Single-precision (32-bit) value */
-} ATTR_ALIGN(16) sse_t; /* On a 16 byte (128-bit) boundary */
-
-
-#define sse_i2r(op, imm, reg) \
- __asm__ __volatile__ (#op " %0, %%" #reg \
- : /* nothing */ \
- : "X" (imm) )
-
-#define sse_m2r(op, mem, reg) \
- __asm__ __volatile__ (#op " %0, %%" #reg \
- : /* nothing */ \
- : "X" (mem))
-
-#define sse_r2m(op, reg, mem) \
- __asm__ __volatile__ (#op " %%" #reg ", %0" \
- : "=X" (mem) \
- : /* nothing */ )
-
-#define sse_r2r(op, regs, regd) \
- __asm__ __volatile__ (#op " %" #regs ", %" #regd)
-
-#define sse_r2ri(op, regs, regd, imm) \
- __asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \
- : /* nothing */ \
- : "X" (imm) )
-
-#define sse_m2ri(op, mem, reg, subop) \
- __asm__ __volatile__ (#op " %0, %%" #reg ", " #subop \
- : /* nothing */ \
- : "X" (mem))
-
-
-#define movaps_m2r(var, reg) sse_m2r(movaps, var, reg)
-#define movaps_r2m(reg, var) sse_r2m(movaps, reg, var)
-#define movaps_r2r(regs, regd) sse_r2r(movaps, regs, regd)
-
-#define movntps_r2m(xmmreg, var) sse_r2m(movntps, xmmreg, var)
-
-#define movups_m2r(var, reg) sse_m2r(movups, var, reg)
-#define movups_r2m(reg, var) sse_r2m(movups, reg, var)
-#define movups_r2r(regs, regd) sse_r2r(movups, regs, regd)
-
-#define movhlps_r2r(regs, regd) sse_r2r(movhlps, regs, regd)
-
-#define movlhps_r2r(regs, regd) sse_r2r(movlhps, regs, regd)
-
-#define movhps_m2r(var, reg) sse_m2r(movhps, var, reg)
-#define movhps_r2m(reg, var) sse_r2m(movhps, reg, var)
-
-#define movlps_m2r(var, reg) sse_m2r(movlps, var, reg)
-#define movlps_r2m(reg, var) sse_r2m(movlps, reg, var)
-
-#define movss_m2r(var, reg) sse_m2r(movss, var, reg)
-#define movss_r2m(reg, var) sse_r2m(movss, reg, var)
-#define movss_r2r(regs, regd) sse_r2r(movss, regs, regd)
-
-#define shufps_m2r(var, reg, index) sse_m2ri(shufps, var, reg, index)
-#define shufps_r2r(regs, regd, index) sse_r2ri(shufps, regs, regd, index)
-
-#define cvtpi2ps_m2r(var, xmmreg) sse_m2r(cvtpi2ps, var, xmmreg)
-#define cvtpi2ps_r2r(mmreg, xmmreg) sse_r2r(cvtpi2ps, mmreg, xmmreg)
-
-#define cvtps2pi_m2r(var, mmreg) sse_m2r(cvtps2pi, var, mmreg)
-#define cvtps2pi_r2r(xmmreg, mmreg) sse_r2r(cvtps2pi, mmreg, xmmreg)
-
-#define cvttps2pi_m2r(var, mmreg) sse_m2r(cvttps2pi, var, mmreg)
-#define cvttps2pi_r2r(xmmreg, mmreg) sse_r2r(cvttps2pi, mmreg, xmmreg)
-
-#define cvtsi2ss_m2r(var, xmmreg) sse_m2r(cvtsi2ss, var, xmmreg)
-#define cvtsi2ss_r2r(reg, xmmreg) sse_r2r(cvtsi2ss, reg, xmmreg)
+uint32_t xine_mm_accel (void) XINE_CONST XINE_PROTECTED;
-#define cvtss2si_m2r(var, reg) sse_m2r(cvtss2si, var, reg)
-#define cvtss2si_r2r(xmmreg, reg) sse_r2r(cvtss2si, xmmreg, reg)
-
-#define cvttss2si_m2r(var, reg) sse_m2r(cvtss2si, var, reg)
-#define cvttss2si_r2r(xmmreg, reg) sse_r2r(cvtss2si, xmmreg, reg)
-
-#define movmskps(xmmreg, reg) \
- __asm__ __volatile__ ("movmskps %" #xmmreg ", %" #reg)
-
-#define addps_m2r(var, reg) sse_m2r(addps, var, reg)
-#define addps_r2r(regs, regd) sse_r2r(addps, regs, regd)
-
-#define addss_m2r(var, reg) sse_m2r(addss, var, reg)
-#define addss_r2r(regs, regd) sse_r2r(addss, regs, regd)
-
-#define subps_m2r(var, reg) sse_m2r(subps, var, reg)
-#define subps_r2r(regs, regd) sse_r2r(subps, regs, regd)
-
-#define subss_m2r(var, reg) sse_m2r(subss, var, reg)
-#define subss_r2r(regs, regd) sse_r2r(subss, regs, regd)
-
-#define mulps_m2r(var, reg) sse_m2r(mulps, var, reg)
-#define mulps_r2r(regs, regd) sse_r2r(mulps, regs, regd)
-
-#define mulss_m2r(var, reg) sse_m2r(mulss, var, reg)
-#define mulss_r2r(regs, regd) sse_r2r(mulss, regs, regd)
-
-#define divps_m2r(var, reg) sse_m2r(divps, var, reg)
-#define divps_r2r(regs, regd) sse_r2r(divps, regs, regd)
-
-#define divss_m2r(var, reg) sse_m2r(divss, var, reg)
-#define divss_r2r(regs, regd) sse_r2r(divss, regs, regd)
-
-#define rcpps_m2r(var, reg) sse_m2r(rcpps, var, reg)
-#define rcpps_r2r(regs, regd) sse_r2r(rcpps, regs, regd)
-
-#define rcpss_m2r(var, reg) sse_m2r(rcpss, var, reg)
-#define rcpss_r2r(regs, regd) sse_r2r(rcpss, regs, regd)
-
-#define rsqrtps_m2r(var, reg) sse_m2r(rsqrtps, var, reg)
-#define rsqrtps_r2r(regs, regd) sse_r2r(rsqrtps, regs, regd)
-
-#define rsqrtss_m2r(var, reg) sse_m2r(rsqrtss, var, reg)
-#define rsqrtss_r2r(regs, regd) sse_r2r(rsqrtss, regs, regd)
-
-#define sqrtps_m2r(var, reg) sse_m2r(sqrtps, var, reg)
-#define sqrtps_r2r(regs, regd) sse_r2r(sqrtps, regs, regd)
-
-#define sqrtss_m2r(var, reg) sse_m2r(sqrtss, var, reg)
-#define sqrtss_r2r(regs, regd) sse_r2r(sqrtss, regs, regd)
-
-#define andps_m2r(var, reg) sse_m2r(andps, var, reg)
-#define andps_r2r(regs, regd) sse_r2r(andps, regs, regd)
-
-#define andnps_m2r(var, reg) sse_m2r(andnps, var, reg)
-#define andnps_r2r(regs, regd) sse_r2r(andnps, regs, regd)
-
-#define orps_m2r(var, reg) sse_m2r(orps, var, reg)
-#define orps_r2r(regs, regd) sse_r2r(orps, regs, regd)
-
-#define xorps_m2r(var, reg) sse_m2r(xorps, var, reg)
-#define xorps_r2r(regs, regd) sse_r2r(xorps, regs, regd)
-
-#define maxps_m2r(var, reg) sse_m2r(maxps, var, reg)
-#define maxps_r2r(regs, regd) sse_r2r(maxps, regs, regd)
-
-#define maxss_m2r(var, reg) sse_m2r(maxss, var, reg)
-#define maxss_r2r(regs, regd) sse_r2r(maxss, regs, regd)
-
-#define minps_m2r(var, reg) sse_m2r(minps, var, reg)
-#define minps_r2r(regs, regd) sse_r2r(minps, regs, regd)
-
-#define minss_m2r(var, reg) sse_m2r(minss, var, reg)
-#define minss_r2r(regs, regd) sse_r2r(minss, regs, regd)
-
-#define cmpps_m2r(var, reg, op) sse_m2ri(cmpps, var, reg, op)
-#define cmpps_r2r(regs, regd, op) sse_r2ri(cmpps, regs, regd, op)
-
-#define cmpeqps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 0)
-#define cmpeqps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 0)
-
-#define cmpltps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 1)
-#define cmpltps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 1)
-
-#define cmpleps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 2)
-#define cmpleps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 2)
-
-#define cmpunordps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 3)
-#define cmpunordps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 3)
-
-#define cmpneqps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 4)
-#define cmpneqps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 4)
-
-#define cmpnltps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 5)
-#define cmpnltps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 5)
-
-#define cmpnleps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 6)
-#define cmpnleps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 6)
-
-#define cmpordps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 7)
-#define cmpordps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 7)
-
-#define cmpss_m2r(var, reg, op) sse_m2ri(cmpss, var, reg, op)
-#define cmpss_r2r(regs, regd, op) sse_r2ri(cmpss, regs, regd, op)
-
-#define cmpeqss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 0)
-#define cmpeqss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 0)
-
-#define cmpltss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 1)
-#define cmpltss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 1)
-
-#define cmpless_m2r(var, reg) sse_m2ri(cmpss, var, reg, 2)
-#define cmpless_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 2)
-
-#define cmpunordss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 3)
-#define cmpunordss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 3)
-
-#define cmpneqss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 4)
-#define cmpneqss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 4)
-
-#define cmpnltss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 5)
-#define cmpnltss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 5)
-
-#define cmpnless_m2r(var, reg) sse_m2ri(cmpss, var, reg, 6)
-#define cmpnless_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 6)
-
-#define cmpordss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 7)
-#define cmpordss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 7)
-
-#define comiss_m2r(var, reg) sse_m2r(comiss, var, reg)
-#define comiss_r2r(regs, regd) sse_r2r(comiss, regs, regd)
-
-#define ucomiss_m2r(var, reg) sse_m2r(ucomiss, var, reg)
-#define ucomiss_r2r(regs, regd) sse_r2r(ucomiss, regs, regd)
-
-#define unpcklps_m2r(var, reg) sse_m2r(unpcklps, var, reg)
-#define unpcklps_r2r(regs, regd) sse_r2r(unpcklps, regs, regd)
-
-#define unpckhps_m2r(var, reg) sse_m2r(unpckhps, var, reg)
-#define unpckhps_r2r(regs, regd) sse_r2r(unpckhps, regs, regd)
-
-#define fxrstor(mem) \
- __asm__ __volatile__ ("fxrstor %0" \
- : /* nothing */ \
- : "X" (mem))
-
-#define fxsave(mem) \
- __asm__ __volatile__ ("fxsave %0" \
- : /* nothing */ \
- : "X" (mem))
-
-#define stmxcsr(mem) \
- __asm__ __volatile__ ("stmxcsr %0" \
- : /* nothing */ \
- : "X" (mem))
-
-#define ldmxcsr(mem) \
- __asm__ __volatile__ ("ldmxcsr %0" \
- : /* nothing */ \
- : "X" (mem))
-#endif /*ARCH_X86 */
/* Optimized/fast memcpy */
@@ -621,11 +153,7 @@ void xine_profiler_print_results (void) XINE_PROTECTED;
* Allocate and clean memory size_t 'size', then return the pointer
* to the allocated memory.
*/
-#if !defined(__GNUC__) || __GNUC__ < 3
-void *xine_xmalloc(size_t size) XINE_PROTECTED;
-#else
-void *xine_xmalloc(size_t size) __attribute__ ((__malloc__)) XINE_PROTECTED;
-#endif
+void *xine_xmalloc(size_t size) XINE_MALLOC XINE_DEPRECATED XINE_PROTECTED;
/*
* Same as above, but memory is aligned to 'alignement'.
@@ -643,6 +171,7 @@ const char *xine_get_homedir(void) XINE_PROTECTED;
/*
* Get other xine directories.
*/
+const char *xine_get_pluginroot(void) XINE_PROTECTED;
const char *xine_get_plugindir(void) XINE_PROTECTED;
const char *xine_get_fontdir(void) XINE_PROTECTED;
const char *xine_get_localedir(void) XINE_PROTECTED;
@@ -665,7 +194,7 @@ void xine_usec_sleep(unsigned usec) XINE_PROTECTED;
*/
-void xine_strdupa(char *dest, char *src) XINE_PROTECTED;
+void xine_strdupa(char *dest, char *src) XINE_PROTECTED XINE_DEPRECATED;
#define xine_strdupa(d, s) do { \
(d) = NULL; \
if((s) != NULL) { \
@@ -679,6 +208,13 @@ void xine_strdupa(char *dest, char *src) XINE_PROTECTED;
#define xine_strsep(STRINGP, DELIM) strsep((STRINGP), (DELIM))
#define xine_setenv(NAME, VAL, XX) setenv((NAME), (VAL), (XX))
+/**
+ * append to a string, reallocating
+ * normally, updates & returns *dest
+ * on error, *dest is unchanged & NULL is returned.
+ */
+char *xine_strcat_realloc (char **dest, char *append) XINE_PROTECTED;
+
/*
* Color Conversion Utility Functions
* The following data structures and functions facilitate the conversion
@@ -959,7 +495,7 @@ void xine_xprintf(xine_t *xine, int verbose, const char *fmt, ...);
/**
* get encoding of current locale
*/
-char *xine_get_system_encoding(void) XINE_PROTECTED;
+char *xine_get_system_encoding(void) XINE_MALLOC XINE_PROTECTED;
/*
* guess default encoding for the subtitles
diff --git a/src/xine-utils/xmllexer.c b/src/xine-utils/xmllexer.c
index be3bdd248..08c56e88e 100644
--- a/src/xine-utils/xmllexer.c
+++ b/src/xine-utils/xmllexer.c
@@ -25,11 +25,14 @@
#define LOG
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#ifdef XINE_COMPILE
#include "xineutils.h"
#else
#define lprintf(...)
-#define xine_xmalloc malloc
#endif
#include "xmllexer.h"
#include <stdio.h>
@@ -411,6 +414,8 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
case '\"': /* " */
case ' ':
case '\t':
+ case '\n':
+ case '\r':
case '=':
case '/':
tok[tok_pos] = '\0';
@@ -532,7 +537,7 @@ static struct {
char *lexer_decode_entities (const char *tok)
{
- char *buf = xine_xmalloc (strlen (tok) + 1);
+ char *buf = calloc (strlen (tok) + 1, sizeof(char));
char *bp = buf;
char c;
diff --git a/src/xine-utils/xmlparser.c b/src/xine-utils/xmlparser.c
index 14ce35c54..93a707993 100644
--- a/src/xine-utils/xmlparser.c
+++ b/src/xine-utils/xmlparser.c
@@ -19,6 +19,10 @@
* Floor, Boston, MA 02110, USA
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
@@ -36,7 +40,7 @@
#include "xineutils.h"
#else
#define lprintf(...)
-#define xine_xmalloc malloc
+#define XINE_MALLOC
#endif
#include "xmllexer.h"
#include "xmlparser.h"
@@ -79,7 +83,7 @@ static void free_xml_node(xml_node_t * node) {
free(node);
}
-static xml_property_t * new_xml_property(void) {
+static xml_property_t *XINE_MALLOC new_xml_property(void) {
xml_property_t * new_property;
new_property = (xml_property_t*) malloc(sizeof(xml_property_t));
@@ -476,9 +480,9 @@ static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int r
int token_buffer_size = TOKEN_SIZE;
int pname_buffer_size = TOKEN_SIZE;
int nname_buffer_size = TOKEN_SIZE;
- char *token_buffer = xine_xmalloc (token_buffer_size);
- char *pname_buffer = xine_xmalloc (pname_buffer_size);
- char *nname_buffer = xine_xmalloc (nname_buffer_size);
+ char *token_buffer = calloc(1, token_buffer_size);
+ char *pname_buffer = calloc(1, pname_buffer_size);
+ char *nname_buffer = calloc(1, nname_buffer_size);
res = _xml_parser_get_node(&token_buffer, &token_buffer_size,
&pname_buffer, &pname_buffer_size,
@@ -590,7 +594,7 @@ static int xml_escape_string_internal (char *buf, const char *s,
char *xml_escape_string (const char *s, xml_escape_quote_t quote_type)
{
- char *buf = xine_xmalloc (xml_escape_string_internal (NULL, s, quote_type));
+ char *buf = calloc (1, xml_escape_string_internal (NULL, s, quote_type));
return buf ? (xml_escape_string_internal (buf, s, quote_type), buf) : NULL;
}
@@ -598,11 +602,10 @@ static void xml_parser_dump_node (const xml_node_t *node, int indent) {
xml_property_t *p;
xml_node_t *n;
- int l;
printf ("%*s<%s ", indent, "", node->name);
- l = strlen (node->name);
+ size_t l = strlen (node->name);
p = node->props;
while (p) {