From 0112143fdaae0a6264d9e02355e9dc0ca4f7741c Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 17 Dec 2013 02:39:45 +0100 Subject: Split mpvcore/ into common/, misc/, bstr/ --- audio/audio.c | 2 +- audio/audio_buffer.c | 2 +- audio/chmap.c | 2 +- audio/chmap.h | 2 +- audio/decode/ad.h | 2 +- audio/decode/ad_lavc.c | 8 +- audio/decode/ad_mpg123.c | 2 +- audio/decode/ad_spdif.c | 4 +- audio/decode/dec_audio.c | 6 +- audio/filter/af.h | 2 +- audio/filter/af_center.c | 2 +- audio/filter/af_channels.c | 2 +- audio/filter/af_delay.c | 2 +- audio/filter/af_drc.c | 2 +- audio/filter/af_equalizer.c | 2 +- audio/filter/af_extrastereo.c | 2 +- audio/filter/af_lavfi.c | 2 +- audio/filter/af_lavrresample.c | 4 +- audio/filter/af_pan.c | 2 +- audio/filter/af_scaletempo.c | 2 +- audio/filter/af_sub.c | 2 +- audio/filter/af_volume.c | 2 +- audio/filter/tools.c | 2 +- audio/fmt-conversion.c | 2 +- audio/format.c | 2 +- audio/format.h | 2 +- audio/mixer.c | 2 +- audio/out/ao.c | 4 +- audio/out/ao.h | 4 +- audio/out/ao_alsa.c | 2 +- audio/out/ao_coreaudio.c | 4 +- audio/out/ao_coreaudio_utils.h | 2 +- audio/out/ao_dsound.c | 2 +- audio/out/ao_jack.c | 4 +- audio/out/ao_lavc.c | 6 +- audio/out/ao_null.c | 2 +- audio/out/ao_openal.c | 2 +- audio/out/ao_oss.c | 2 +- audio/out/ao_pcm.c | 2 +- audio/out/ao_portaudio.c | 4 +- audio/out/ao_pulse.c | 2 +- audio/out/ao_sdl.c | 2 +- audio/out/ao_sndio.c | 2 +- audio/out/ao_wasapi.c | 6 +- bstr/bstr.c | 385 ++++++++++++++ bstr/bstr.h | 200 +++++++ common/asxparser.c | 581 +++++++++++++++++++++ common/asxparser.h | 27 + common/av_common.c | 178 +++++++ common/av_common.h | 39 ++ common/av_log.c | 176 +++++++ common/av_log.h | 2 + common/av_opts.c | 55 ++ common/av_opts.h | 30 ++ common/codecs.c | 147 ++++++ common/codecs.h | 43 ++ common/common.c | 163 ++++++ common/common.h | 81 +++ common/cpudetect.c | 56 ++ common/cpudetect.h | 40 ++ common/encode.h | 21 + common/encode_lavc.c | 1115 ++++++++++++++++++++++++++++++++++++++++ common/encode_lavc.h | 101 ++++ common/global.h | 12 + common/msg.c | 389 ++++++++++++++ common/msg.h | 180 +++++++ common/playlist.c | 241 +++++++++ common/playlist.h | 82 +++ common/playlist_parser.c | 566 ++++++++++++++++++++ common/playlist_parser.h | 29 ++ common/version.c | 26 + compat/atomics.h | 23 + demux/codec_tags.c | 2 +- demux/demux.c | 4 +- demux/demux.h | 4 +- demux/demux_cue.c | 2 +- demux/demux_lavf.c | 8 +- demux/demux_libass.c | 4 +- demux/demux_mf.c | 2 +- demux/demux_mkv.c | 4 +- demux/demux_playlist.c | 6 +- demux/demux_subreader.c | 4 +- demux/ebml.c | 2 +- demux/ebml.h | 2 +- demux/mf.c | 2 +- demux/stheader.h | 2 +- input/input.c | 8 +- input/input.h | 2 +- input/joystick.c | 2 +- input/lirc.c | 2 +- misc/charset_conv.c | 287 +++++++++++ misc/charset_conv.h | 19 + misc/ring.c | 138 +++++ misc/ring.h | 108 ++++ mpvcore/asxparser.c | 581 --------------------- mpvcore/asxparser.h | 27 - mpvcore/av_common.c | 178 ------- mpvcore/av_common.h | 39 -- mpvcore/av_log.c | 176 ------- mpvcore/av_log.h | 2 - mpvcore/av_opts.c | 55 -- mpvcore/av_opts.h | 30 -- mpvcore/bstr.c | 385 -------------- mpvcore/bstr.h | 200 ------- mpvcore/charset_conv.c | 287 ----------- mpvcore/charset_conv.h | 19 - mpvcore/codecs.c | 147 ------ mpvcore/codecs.h | 43 -- mpvcore/cpudetect.c | 56 -- mpvcore/cpudetect.h | 40 -- mpvcore/encode.h | 21 - mpvcore/encode_lavc.c | 1115 ---------------------------------------- mpvcore/encode_lavc.h | 101 ---- mpvcore/mp_common.c | 163 ------ mpvcore/mp_common.h | 81 --- mpvcore/mp_memory_barrier.h | 23 - mpvcore/mp_msg.c | 389 -------------- mpvcore/mp_msg.h | 180 ------- mpvcore/mp_ring.c | 138 ----- mpvcore/mp_ring.h | 108 ---- mpvcore/mpv_global.h | 12 - mpvcore/playlist.c | 241 --------- mpvcore/playlist.h | 82 --- mpvcore/playlist_parser.c | 566 -------------------- mpvcore/playlist_parser.h | 29 -- mpvcore/version.c | 26 - old-makefile | 30 +- options/m_config.c | 2 +- options/m_config.h | 2 +- options/m_option.c | 4 +- options/m_option.h | 2 +- options/m_property.c | 4 +- options/parse_commandline.c | 6 +- options/parse_configfile.c | 2 +- options/path.c | 2 +- options/path.h | 2 +- osdep/getch2.c | 4 +- osdep/priority.c | 2 +- osdep/timer-darwin.c | 2 +- player/audio.c | 4 +- player/command.c | 6 +- player/configfiles.c | 4 +- player/core.h | 2 +- player/dvdnav.c | 4 +- player/loadfile.c | 8 +- player/lua.c | 6 +- player/main.c | 18 +- player/misc.c | 8 +- player/osd.c | 6 +- player/playloop.c | 8 +- player/screenshot.c | 4 +- player/sub.c | 4 +- player/timeline/tl_cue.c | 6 +- player/timeline/tl_matroska.c | 10 +- player/timeline/tl_mpv_edl.c | 6 +- player/video.c | 6 +- stream/ai_alsa1x.c | 2 +- stream/ai_oss.c | 2 +- stream/ai_sndio.c | 2 +- stream/audio_in.c | 2 +- stream/cache.c | 4 +- stream/cdinfo.c | 2 +- stream/cookies.c | 2 +- stream/dvb_tune.c | 2 +- stream/rar.c | 2 +- stream/resolve/resolve_quvi.c | 2 +- stream/resolve/resolve_quvi9.c | 4 +- stream/stream.c | 6 +- stream/stream.h | 4 +- stream/stream_bluray.c | 2 +- stream/stream_cdda.c | 2 +- stream/stream_dvd.c | 2 +- stream/stream_dvd_common.c | 2 +- stream/stream_dvdnav.c | 2 +- stream/stream_file.c | 2 +- stream/stream_lavf.c | 4 +- stream/stream_pvr.c | 2 +- stream/stream_radio.c | 2 +- stream/stream_rar.c | 2 +- stream/stream_smb.c | 2 +- stream/stream_vcd.c | 2 +- stream/tv.c | 2 +- stream/tvi_v4l2.c | 2 +- stream/vcd_read.h | 2 +- stream/vcd_read_darwin.h | 2 +- stream/vcd_read_fbsd.h | 2 +- stream/vcd_read_win32.h | 2 +- sub/ass_mp.c | 2 +- sub/dec_sub.c | 4 +- sub/draw_bmp.c | 2 +- sub/find_subfiles.c | 4 +- sub/osd.c | 4 +- sub/osd_libass.c | 4 +- sub/sd_ass.c | 4 +- sub/sd_lavc.c | 4 +- sub/sd_lavc_conv.c | 6 +- sub/sd_lavf_srt.c | 2 +- sub/sd_microdvd.c | 4 +- sub/sd_srt.c | 4 +- sub/spudec.c | 4 +- video/decode/dec_video.c | 4 +- video/decode/vaapi.c | 4 +- video/decode/vd_lavc.c | 10 +- video/decode/vda.c | 4 +- video/decode/vdpau.c | 4 +- video/filter/pullup.c | 4 +- video/filter/vf.c | 2 +- video/filter/vf.h | 2 +- video/filter/vf_crop.c | 2 +- video/filter/vf_delogo.c | 4 +- video/filter/vf_divtc.c | 4 +- video/filter/vf_dlopen.c | 2 +- video/filter/vf_dsize.c | 2 +- video/filter/vf_eq.c | 4 +- video/filter/vf_expand.c | 2 +- video/filter/vf_flip.c | 2 +- video/filter/vf_format.c | 2 +- video/filter/vf_gradfun.c | 2 +- video/filter/vf_hqdn3d.c | 2 +- video/filter/vf_ilpack.c | 4 +- video/filter/vf_lavfi.c | 4 +- video/filter/vf_lavfi.h | 2 +- video/filter/vf_mirror.c | 2 +- video/filter/vf_noformat.c | 2 +- video/filter/vf_noise.c | 4 +- video/filter/vf_phase.c | 2 +- video/filter/vf_pp.c | 4 +- video/filter/vf_pullup.c | 4 +- video/filter/vf_rotate.c | 2 +- video/filter/vf_scale.c | 2 +- video/filter/vf_softpulldown.c | 2 +- video/filter/vf_stereo3d.c | 2 +- video/filter/vf_sub.c | 2 +- video/filter/vf_swapuv.c | 2 +- video/filter/vf_unsharp.c | 4 +- video/filter/vf_yadif.c | 4 +- video/fmt-conversion.c | 2 +- video/img_format.h | 2 +- video/mp_image.h | 2 +- video/mp_image_pool.c | 2 +- video/out/aspect.c | 2 +- video/out/bitmap_packer.c | 4 +- video/out/gl_common.h | 4 +- video/out/gl_lcms.c | 6 +- video/out/gl_video.c | 2 +- video/out/vo.c | 6 +- video/out/vo.h | 2 +- video/out/vo_caca.c | 2 +- video/out/vo_direct3d.c | 2 +- video/out/vo_image.c | 4 +- video/out/vo_lavc.c | 4 +- video/out/vo_null.c | 2 +- video/out/vo_opengl.c | 6 +- video/out/vo_opengl_old.c | 2 +- video/out/vo_sdl.c | 2 +- video/out/vo_vaapi.c | 2 +- video/out/vo_vdpau.c | 2 +- video/out/vo_wayland.c | 2 +- video/out/vo_x11.c | 2 +- video/out/vo_xv.c | 2 +- video/out/w32_common.c | 4 +- video/out/wayland_common.c | 4 +- video/out/x11_common.c | 4 +- video/sws_utils.c | 4 +- video/vaapi.c | 4 +- video/vdpau.h | 2 +- wscript_build.py | 34 +- 267 files changed, 5898 insertions(+), 5894 deletions(-) create mode 100644 bstr/bstr.c create mode 100644 bstr/bstr.h create mode 100644 common/asxparser.c create mode 100644 common/asxparser.h create mode 100644 common/av_common.c create mode 100644 common/av_common.h create mode 100644 common/av_log.c create mode 100644 common/av_log.h create mode 100644 common/av_opts.c create mode 100644 common/av_opts.h create mode 100644 common/codecs.c create mode 100644 common/codecs.h create mode 100644 common/common.c create mode 100644 common/common.h create mode 100644 common/cpudetect.c create mode 100644 common/cpudetect.h create mode 100644 common/encode.h create mode 100644 common/encode_lavc.c create mode 100644 common/encode_lavc.h create mode 100644 common/global.h create mode 100644 common/msg.c create mode 100644 common/msg.h create mode 100644 common/playlist.c create mode 100644 common/playlist.h create mode 100644 common/playlist_parser.c create mode 100644 common/playlist_parser.h create mode 100644 common/version.c create mode 100644 compat/atomics.h create mode 100644 misc/charset_conv.c create mode 100644 misc/charset_conv.h create mode 100644 misc/ring.c create mode 100644 misc/ring.h delete mode 100644 mpvcore/asxparser.c delete mode 100644 mpvcore/asxparser.h delete mode 100644 mpvcore/av_common.c delete mode 100644 mpvcore/av_common.h delete mode 100644 mpvcore/av_log.c delete mode 100644 mpvcore/av_log.h delete mode 100644 mpvcore/av_opts.c delete mode 100644 mpvcore/av_opts.h delete mode 100644 mpvcore/bstr.c delete mode 100644 mpvcore/bstr.h delete mode 100644 mpvcore/charset_conv.c delete mode 100644 mpvcore/charset_conv.h delete mode 100644 mpvcore/codecs.c delete mode 100644 mpvcore/codecs.h delete mode 100644 mpvcore/cpudetect.c delete mode 100644 mpvcore/cpudetect.h delete mode 100644 mpvcore/encode.h delete mode 100644 mpvcore/encode_lavc.c delete mode 100644 mpvcore/encode_lavc.h delete mode 100644 mpvcore/mp_common.c delete mode 100644 mpvcore/mp_common.h delete mode 100644 mpvcore/mp_memory_barrier.h delete mode 100644 mpvcore/mp_msg.c delete mode 100644 mpvcore/mp_msg.h delete mode 100644 mpvcore/mp_ring.c delete mode 100644 mpvcore/mp_ring.h delete mode 100644 mpvcore/mpv_global.h delete mode 100644 mpvcore/playlist.c delete mode 100644 mpvcore/playlist.h delete mode 100644 mpvcore/playlist_parser.c delete mode 100644 mpvcore/playlist_parser.h delete mode 100644 mpvcore/version.c diff --git a/audio/audio.c b/audio/audio.c index a5cf52f5b3..950d25be75 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -20,7 +20,7 @@ #include #include "talloc.h" -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "audio.h" static void update_redundant_info(struct mp_audio *mpa) diff --git a/audio/audio_buffer.c b/audio/audio_buffer.c index 53563f90c6..2bd546a532 100644 --- a/audio/audio_buffer.c +++ b/audio/audio_buffer.c @@ -19,7 +19,7 @@ #include #include -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "audio_buffer.h" #include "audio.h" diff --git a/audio/chmap.c b/audio/chmap.c index 0e714f3c83..ce301b6565 100644 --- a/audio/chmap.c +++ b/audio/chmap.c @@ -18,7 +18,7 @@ #include #include -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "chmap.h" // Names taken from libavutil/channel_layout.c (Not accessible by API.) diff --git a/audio/chmap.h b/audio/chmap.h index cd6c49f716..ca1e6c2508 100644 --- a/audio/chmap.h +++ b/audio/chmap.h @@ -20,7 +20,7 @@ #include #include -#include "mpvcore/bstr.h" +#include "bstr/bstr.h" #define MP_NUM_CHANNELS 8 diff --git a/audio/decode/ad.h b/audio/decode/ad.h index 56f8944120..2ac9fb21f6 100644 --- a/audio/decode/ad.h +++ b/audio/decode/ad.h @@ -19,7 +19,7 @@ #ifndef MPLAYER_AD_H #define MPLAYER_AD_H -#include "mpvcore/codecs.h" +#include "common/codecs.h" #include "demux/stheader.h" #include "demux/demux.h" diff --git a/audio/decode/ad_lavc.c b/audio/decode/ad_lavc.c index 8b2c2d1727..9e1ba49fc1 100644 --- a/audio/decode/ad_lavc.c +++ b/audio/decode/ad_lavc.c @@ -29,11 +29,11 @@ #include "talloc.h" #include "config.h" -#include "mpvcore/av_common.h" -#include "mpvcore/codecs.h" -#include "mpvcore/mp_msg.h" +#include "common/av_common.h" +#include "common/codecs.h" +#include "common/msg.h" #include "options/options.h" -#include "mpvcore/av_opts.h" +#include "common/av_opts.h" #include "ad.h" #include "audio/fmt-conversion.h" diff --git a/audio/decode/ad_mpg123.c b/audio/decode/ad_mpg123.c index f65553bd77..57f84e136f 100644 --- a/audio/decode/ad_mpg123.c +++ b/audio/decode/ad_mpg123.c @@ -25,7 +25,7 @@ #include "config.h" #include "ad.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include diff --git a/audio/decode/ad_spdif.c b/audio/decode/ad_spdif.c index fdc12772b8..5532d6b5a8 100644 --- a/audio/decode/ad_spdif.c +++ b/audio/decode/ad_spdif.c @@ -26,8 +26,8 @@ #include #include "config.h" -#include "mpvcore/mp_msg.h" -#include "mpvcore/av_common.h" +#include "common/msg.h" +#include "common/av_common.h" #include "options/options.h" #include "ad.h" diff --git a/audio/decode/dec_audio.c b/audio/decode/dec_audio.c index 1c34c6abe9..51966a7cc6 100644 --- a/audio/decode/dec_audio.c +++ b/audio/decode/dec_audio.c @@ -26,9 +26,9 @@ #include "demux/codec_tags.h" #include "config.h" -#include "mpvcore/codecs.h" -#include "mpvcore/mp_msg.h" -#include "mpvcore/bstr.h" +#include "common/codecs.h" +#include "common/msg.h" +#include "bstr/bstr.h" #include "stream/stream.h" #include "demux/demux.h" diff --git a/audio/filter/af.h b/audio/filter/af.h index 260d4dae7e..1e78c01718 100644 --- a/audio/filter/af.h +++ b/audio/filter/af.h @@ -29,7 +29,7 @@ #include "audio/format.h" #include "audio/chmap.h" #include "audio/audio.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" struct af_instance; diff --git a/audio/filter/af_center.c b/audio/filter/af_center.c index d1095e611c..2e626bffb6 100644 --- a/audio/filter/af_center.c +++ b/audio/filter/af_center.c @@ -29,7 +29,7 @@ #include #include -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "af.h" // Data for specific instances of this filter diff --git a/audio/filter/af_channels.c b/audio/filter/af_channels.c index 8edaa4285a..7bbf952ffe 100644 --- a/audio/filter/af_channels.c +++ b/audio/filter/af_channels.c @@ -27,7 +27,7 @@ #include #include -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "af.h" #define FR 0 diff --git a/audio/filter/af_delay.c b/audio/filter/af_delay.c index b2c03697fd..f29d065427 100644 --- a/audio/filter/af_delay.c +++ b/audio/filter/af_delay.c @@ -27,7 +27,7 @@ #include #include -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "af.h" #define L 65536 diff --git a/audio/filter/af_drc.c b/audio/filter/af_drc.c index 0edb99f469..fad34ba500 100644 --- a/audio/filter/af_drc.c +++ b/audio/filter/af_drc.c @@ -26,7 +26,7 @@ #include #include -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "af.h" // Methods: diff --git a/audio/filter/af_equalizer.c b/audio/filter/af_equalizer.c index c14fc8451d..7f79dab8ca 100644 --- a/audio/filter/af_equalizer.c +++ b/audio/filter/af_equalizer.c @@ -29,7 +29,7 @@ #include #include -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "af.h" #define L 2 // Storage for filter taps diff --git a/audio/filter/af_extrastereo.c b/audio/filter/af_extrastereo.c index 92cc4dd216..1e814e8351 100644 --- a/audio/filter/af_extrastereo.c +++ b/audio/filter/af_extrastereo.c @@ -26,7 +26,7 @@ #include #include -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "af.h" // Data for specific instances of this filter diff --git a/audio/filter/af_lavfi.c b/audio/filter/af_lavfi.c index e764d4fae8..6fee39afea 100644 --- a/audio/filter/af_lavfi.c +++ b/audio/filter/af_lavfi.c @@ -39,7 +39,7 @@ #include "af.h" #include "options/m_option.h" -#include "mpvcore/av_opts.h" +#include "common/av_opts.h" #define IS_LIBAV_FORK (LIBAVFILTER_VERSION_MICRO < 100) diff --git a/audio/filter/af_lavrresample.c b/audio/filter/af_lavrresample.c index 65d380e873..ee453cc1de 100644 --- a/audio/filter/af_lavrresample.c +++ b/audio/filter/af_lavrresample.c @@ -54,9 +54,9 @@ #error "config.h broken or no resampler found" #endif -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/m_option.h" -#include "mpvcore/av_opts.h" +#include "common/av_opts.h" #include "audio/filter/af.h" #include "audio/fmt-conversion.h" #include "audio/reorder_ch.h" diff --git a/audio/filter/af_pan.c b/audio/filter/af_pan.c index 800221e4bf..accea8026d 100644 --- a/audio/filter/af_pan.c +++ b/audio/filter/af_pan.c @@ -25,7 +25,7 @@ #include #include -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "af.h" // Data for specific instances of this filter diff --git a/audio/filter/af_scaletempo.c b/audio/filter/af_scaletempo.c index c54fe44e36..5b93914851 100644 --- a/audio/filter/af_scaletempo.c +++ b/audio/filter/af_scaletempo.c @@ -36,7 +36,7 @@ #include #include -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "af.h" #include "options/m_option.h" diff --git a/audio/filter/af_sub.c b/audio/filter/af_sub.c index ff88272b34..7012e1e129 100644 --- a/audio/filter/af_sub.c +++ b/audio/filter/af_sub.c @@ -32,7 +32,7 @@ #include #include -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "af.h" #include "dsp.h" diff --git a/audio/filter/af_volume.c b/audio/filter/af_volume.c index 06a1f7dd3c..6a27081b28 100644 --- a/audio/filter/af_volume.c +++ b/audio/filter/af_volume.c @@ -26,7 +26,7 @@ #include #include -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "af.h" struct priv { diff --git a/audio/filter/tools.c b/audio/filter/tools.c index c5f423ebf9..217224150e 100644 --- a/audio/filter/tools.c +++ b/audio/filter/tools.c @@ -19,7 +19,7 @@ #include #include -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "af.h" /* Convert to gain value from dB. Returns AF_OK if of and AF_ERROR if diff --git a/audio/fmt-conversion.c b/audio/fmt-conversion.c index da770a8eda..65f84945c1 100644 --- a/audio/fmt-conversion.c +++ b/audio/fmt-conversion.c @@ -16,7 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include #include #include "format.h" diff --git a/audio/format.c b/audio/format.c index 1f6b0cac20..e343ca36db 100644 --- a/audio/format.c +++ b/audio/format.c @@ -25,7 +25,7 @@ #include #include -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "audio/filter/af.h" int af_fmt2bits(int format) diff --git a/audio/format.h b/audio/format.h index b318d4cdca..d21707e677 100644 --- a/audio/format.h +++ b/audio/format.h @@ -26,7 +26,7 @@ #include #include #include "config.h" -#include "mpvcore/bstr.h" +#include "bstr/bstr.h" #if BYTE_ORDER == BIG_ENDIAN #define AF_SELECT_LE_BE(LE, BE) BE diff --git a/audio/mixer.c b/audio/mixer.c index 0972b80533..b3ba9c3a58 100644 --- a/audio/mixer.c +++ b/audio/mixer.c @@ -24,7 +24,7 @@ #include "config.h" #include "audio/out/ao.h" #include "audio/filter/af.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "talloc.h" #include "mixer.h" diff --git a/audio/out/ao.c b/audio/out/ao.c index 6434949cd9..ddd177400d 100644 --- a/audio/out/ao.c +++ b/audio/out/ao.c @@ -29,8 +29,8 @@ #include "options/options.h" #include "options/m_config.h" -#include "mpvcore/mp_msg.h" -#include "mpvcore/mpv_global.h" +#include "common/msg.h" +#include "common/global.h" extern const struct ao_driver audio_out_oss; extern const struct ao_driver audio_out_coreaudio; diff --git a/audio/out/ao.h b/audio/out/ao.h index dff9ad6a8b..81737e094d 100644 --- a/audio/out/ao.h +++ b/audio/out/ao.h @@ -21,8 +21,8 @@ #include -#include "mpvcore/bstr.h" -#include "mpvcore/mp_common.h" +#include "bstr/bstr.h" +#include "common/common.h" #include "audio/chmap.h" #include "audio/chmap_sel.h" diff --git a/audio/out/ao_alsa.c b/audio/out/ao_alsa.c index 372b490e9f..a65b9b05ec 100644 --- a/audio/out/ao_alsa.c +++ b/audio/out/ao_alsa.c @@ -38,7 +38,7 @@ #include "config.h" #include "options/options.h" #include "options/m_option.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #define ALSA_PCM_NEW_HW_PARAMS_API #define ALSA_PCM_NEW_SW_PARAMS_API diff --git a/audio/out/ao_coreaudio.c b/audio/out/ao_coreaudio.c index 2fb7976c67..4a4091daf9 100644 --- a/audio/out/ao_coreaudio.c +++ b/audio/out/ao_coreaudio.c @@ -40,8 +40,8 @@ #include "audio/format.h" #include "osdep/timer.h" #include "options/m_option.h" -#include "mpvcore/mp_ring.h" -#include "mpvcore/mp_msg.h" +#include "misc/ring.h" +#include "common/msg.h" #include "audio/out/ao_coreaudio_properties.h" #include "audio/out/ao_coreaudio_utils.h" diff --git a/audio/out/ao_coreaudio_utils.h b/audio/out/ao_coreaudio_utils.h index 296f1d2497..cf69248b47 100644 --- a/audio/out/ao_coreaudio_utils.h +++ b/audio/out/ao_coreaudio_utils.h @@ -22,7 +22,7 @@ #include #include #include -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "audio/out/ao.h" #define CA_CFSTR_ENCODING kCFStringEncodingASCII diff --git a/audio/out/ao_dsound.c b/audio/out/ao_dsound.c index 1ace4093b4..26c7bb83ed 100644 --- a/audio/out/ao_dsound.c +++ b/audio/out/ao_dsound.c @@ -39,7 +39,7 @@ #include "audio/format.h" #include "ao.h" #include "audio/reorder_ch.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "osdep/timer.h" #include "options/m_option.h" diff --git a/audio/out/ao_jack.c b/audio/out/ao_jack.c index 8c54796e2b..f4cb5c475e 100644 --- a/audio/out/ao_jack.c +++ b/audio/out/ao_jack.c @@ -29,14 +29,14 @@ #include #include "config.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "ao.h" #include "audio/format.h" #include "osdep/timer.h" #include "options/m_option.h" -#include "mpvcore/mp_ring.h" +#include "misc/ring.h" #include diff --git a/audio/out/ao_lavc.c b/audio/out/ao_lavc.c index 713b952229..3e4ba01105 100644 --- a/audio/out/ao_lavc.c +++ b/audio/out/ao_lavc.c @@ -31,14 +31,14 @@ #include "compat/libav.h" #include "config.h" #include "options/options.h" -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "audio/format.h" #include "audio/fmt-conversion.h" #include "talloc.h" #include "ao.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" -#include "mpvcore/encode_lavc.h" +#include "common/encode_lavc.h" struct priv { uint8_t *buffer; diff --git a/audio/out/ao_null.c b/audio/out/ao_null.c index 282511ae40..7c912d94a4 100644 --- a/audio/out/ao_null.c +++ b/audio/out/ao_null.c @@ -31,7 +31,7 @@ #include "config.h" #include "osdep/timer.h" #include "options/m_option.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "audio/format.h" #include "ao.h" diff --git a/audio/out/ao_openal.c b/audio/out/ao_openal.c index c6c2e9e8b8..d613b74208 100644 --- a/audio/out/ao_openal.c +++ b/audio/out/ao_openal.c @@ -35,7 +35,7 @@ #include #endif -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "ao.h" #include "audio/format.h" diff --git a/audio/out/ao_oss.c b/audio/out/ao_oss.c index 9ff7d1a165..574fcf6beb 100644 --- a/audio/out/ao_oss.c +++ b/audio/out/ao_oss.c @@ -36,7 +36,7 @@ #include "config.h" #include "options/options.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #if HAVE_SYS_SOUNDCARD_H #include diff --git a/audio/out/ao_pcm.c b/audio/out/ao_pcm.c index 2a086c549f..14548d3be3 100644 --- a/audio/out/ao_pcm.c +++ b/audio/out/ao_pcm.c @@ -34,7 +34,7 @@ #include "audio/format.h" #include "audio/reorder_ch.h" #include "ao.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #ifdef __MINGW32__ // for GetFileType to detect pipes diff --git a/audio/out/ao_portaudio.c b/audio/out/ao_portaudio.c index 6e3d9680fd..8b4efe7944 100644 --- a/audio/out/ao_portaudio.c +++ b/audio/out/ao_portaudio.c @@ -28,8 +28,8 @@ #include "config.h" #include "options/m_option.h" #include "audio/format.h" -#include "mpvcore/mp_msg.h" -#include "mpvcore/mp_ring.h" +#include "common/msg.h" +#include "misc/ring.h" #include "ao.h" struct priv { diff --git a/audio/out/ao_pulse.c b/audio/out/ao_pulse.c index 651589c34f..f3bce40574 100644 --- a/audio/out/ao_pulse.c +++ b/audio/out/ao_pulse.c @@ -28,7 +28,7 @@ #include "config.h" #include "audio/format.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "ao.h" #include "input/input.h" diff --git a/audio/out/ao_sdl.c b/audio/out/ao_sdl.c index dd2fb894be..ac1fd6febb 100644 --- a/audio/out/ao_sdl.c +++ b/audio/out/ao_sdl.c @@ -23,7 +23,7 @@ #include "audio/format.h" #include "talloc.h" #include "ao.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/m_option.h" #include "osdep/timer.h" diff --git a/audio/out/ao_sndio.c b/audio/out/ao_sndio.c index 6cf08cd095..75ea5d095b 100644 --- a/audio/out/ao_sndio.c +++ b/audio/out/ao_sndio.c @@ -23,7 +23,7 @@ #include #include "options/m_option.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "audio/format.h" #include "ao.h" diff --git a/audio/out/ao_wasapi.c b/audio/out/ao_wasapi.c index b2ac1f2343..d70b66a493 100644 --- a/audio/out/ao_wasapi.c +++ b/audio/out/ao_wasapi.c @@ -31,10 +31,10 @@ #include "config.h" #include "options/m_option.h" -#include "mpvcore/m_config.h" +#include "common/m_config.h" #include "audio/format.h" -#include "mpvcore/mp_msg.h" -#include "mpvcore/mp_ring.h" +#include "common/msg.h" +#include "common/mp_ring.h" #include "ao.h" #ifndef BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE diff --git a/bstr/bstr.c b/bstr/bstr.c new file mode 100644 index 0000000000..65ae928d31 --- /dev/null +++ b/bstr/bstr.c @@ -0,0 +1,385 @@ +/* + * This file is part of MPlayer. + * + * MPlayer 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. + * + * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include + +#include + +#include "talloc.h" + +#include "bstr/bstr.h" + +int bstrcmp(struct bstr str1, struct bstr str2) +{ + int ret = memcmp(str1.start, str2.start, FFMIN(str1.len, str2.len)); + + if (!ret) { + if (str1.len == str2.len) + return 0; + else if (str1.len > str2.len) + return 1; + else + return -1; + } + return ret; +} + +int bstrcasecmp(struct bstr str1, struct bstr str2) +{ + int ret = strncasecmp(str1.start, str2.start, FFMIN(str1.len, str2.len)); + + if (!ret) { + if (str1.len == str2.len) + return 0; + else if (str1.len > str2.len) + return 1; + else + return -1; + } + return ret; +} + +int bstrchr(struct bstr str, int c) +{ + for (int i = 0; i < str.len; i++) + if (str.start[i] == c) + return i; + return -1; +} + +int bstrrchr(struct bstr str, int c) +{ + for (int i = str.len - 1; i >= 0; i--) + if (str.start[i] == c) + return i; + return -1; +} + +int bstrcspn(struct bstr str, const char *reject) +{ + int i; + for (i = 0; i < str.len; i++) + if (strchr(reject, str.start[i])) + break; + return i; +} + +int bstrspn(struct bstr str, const char *accept) +{ + int i; + for (i = 0; i < str.len; i++) + if (!strchr(accept, str.start[i])) + break; + return i; +} + +int bstr_find(struct bstr haystack, struct bstr needle) +{ + for (int i = 0; i < haystack.len; i++) + if (bstr_startswith(bstr_splice(haystack, i, haystack.len), needle)) + return i; + return -1; +} + +struct bstr bstr_lstrip(struct bstr str) +{ + while (str.len && isspace(*str.start)) { + str.start++; + str.len--; + } + return str; +} + +struct bstr bstr_strip(struct bstr str) +{ + str = bstr_lstrip(str); + while (str.len && isspace(str.start[str.len - 1])) + str.len--; + return str; +} + +struct bstr bstr_split(struct bstr str, const char *sep, struct bstr *rest) +{ + int start; + for (start = 0; start < str.len; start++) + if (!strchr(sep, str.start[start])) + break; + str = bstr_cut(str, start); + int end = bstrcspn(str, sep); + if (rest) { + *rest = bstr_cut(str, end); + } + return bstr_splice(str, 0, end); +} + +// Unlike with bstr_split(), tok is a string, and not a set of char. +// If tok is in str, return true, and: concat(out_left, tok, out_right) == str +// Otherwise, return false, and set out_left==str, out_right=="" +bool bstr_split_tok(bstr str, const char *tok, bstr *out_left, bstr *out_right) +{ + bstr bsep = bstr0(tok); + int pos = bstr_find(str, bsep); + if (pos < 0) + pos = str.len; + *out_left = bstr_splice(str, 0, pos); + *out_right = bstr_cut(str, pos + bsep.len); + return pos != str.len; +} + +struct bstr bstr_splice(struct bstr str, int start, int end) +{ + if (start < 0) + start += str.len; + if (end < 0) + end += str.len; + end = FFMIN(end, str.len); + start = FFMAX(start, 0); + end = FFMAX(end, start); + str.start += start; + str.len = end - start; + return str; +} + +long long bstrtoll(struct bstr str, struct bstr *rest, int base) +{ + str = bstr_lstrip(str); + char buf[51]; + int len = FFMIN(str.len, 50); + memcpy(buf, str.start, len); + buf[len] = 0; + char *endptr; + long long r = strtoll(buf, &endptr, base); + if (rest) + *rest = bstr_cut(str, endptr - buf); + return r; +} + +double bstrtod(struct bstr str, struct bstr *rest) +{ + str = bstr_lstrip(str); + char buf[101]; + int len = FFMIN(str.len, 100); + memcpy(buf, str.start, len); + buf[len] = 0; + char *endptr; + double r = strtod(buf, &endptr); + if (rest) + *rest = bstr_cut(str, endptr - buf); + return r; +} + +struct bstr *bstr_splitlines(void *talloc_ctx, struct bstr str) +{ + if (str.len == 0) + return NULL; + int count = 0; + for (int i = 0; i < str.len; i++) + if (str.start[i] == '\n') + count++; + if (str.start[str.len - 1] != '\n') + count++; + struct bstr *r = talloc_array_ptrtype(talloc_ctx, r, count); + unsigned char *p = str.start; + for (int i = 0; i < count - 1; i++) { + r[i].start = p; + while (*p++ != '\n'); + r[i].len = p - r[i].start; + } + r[count - 1].start = p; + r[count - 1].len = str.start + str.len - p; + return r; +} + +struct bstr bstr_getline(struct bstr str, struct bstr *rest) +{ + int pos = bstrchr(str, '\n'); + if (pos < 0) + pos = str.len; + if (rest) + *rest = bstr_cut(str, pos + 1); + return bstr_splice(str, 0, pos + 1); +} + +struct bstr bstr_strip_linebreaks(struct bstr str) +{ + if (bstr_endswith0(str, "\r\n")) { + str = bstr_splice(str, 0, str.len - 2); + } else if (bstr_endswith0(str, "\n")) { + str = bstr_splice(str, 0, str.len - 1); + } + return str; +} + +bool bstr_eatstart(struct bstr *s, struct bstr prefix) +{ + if (!bstr_startswith(*s, prefix)) + return false; + *s = bstr_cut(*s, prefix.len); + return true; +} + +void bstr_lower(struct bstr str) +{ + for (int i = 0; i < str.len; i++) + str.start[i] = tolower(str.start[i]); +} + +int bstr_sscanf(struct bstr str, const char *format, ...) +{ + char *ptr = bstrdup0(NULL, str); + va_list va; + va_start(va, format); + int ret = vsscanf(ptr, format, va); + va_end(va); + talloc_free(ptr); + return ret; +} + +int bstr_parse_utf8_code_length(unsigned char b) +{ + if (b < 128) + return 1; + int bytes = 7 - av_log2(b ^ 255); + return (bytes >= 2 && bytes <= 4) ? bytes : -1; +} + +int bstr_decode_utf8(struct bstr s, struct bstr *out_next) +{ + if (s.len == 0) + return -1; + unsigned int codepoint = s.start[0]; + s.start++; s.len--; + if (codepoint >= 128) { + int bytes = bstr_parse_utf8_code_length(codepoint); + if (bytes < 0 || s.len < bytes - 1) + return -1; + codepoint &= 127 >> bytes; + for (int n = 1; n < bytes; n++) { + int tmp = (unsigned char)s.start[0]; + if ((tmp & 0xC0) != 0x80) + return -1; + codepoint = (codepoint << 6) | (tmp & ~0xC0); + s.start++; s.len--; + } + if (codepoint > 0x10FFFF || (codepoint >= 0xD800 && codepoint <= 0xDFFF)) + return -1; + // Overlong sequences - check taken from libavcodec. + // (The only reason we even bother with this is to make libavcodec's + // retarded subtitle utf-8 check happy.) + unsigned int min = bytes == 2 ? 0x80 : 1 << (5 * bytes - 4); + if (codepoint < min) + return -1; + } + if (out_next) + *out_next = s; + return codepoint; +} + +int bstr_validate_utf8(struct bstr s) +{ + while (s.len) { + if (bstr_decode_utf8(s, &s) < 0) { + // Try to guess whether the sequence was just cut-off. + unsigned int codepoint = (unsigned char)s.start[0]; + int bytes = bstr_parse_utf8_code_length(codepoint); + if (bytes > 1 && s.len < 6) { + // Manually check validity of left bytes + for (int n = 1; n < bytes; n++) { + if (n >= s.len) { + // Everything valid until now - just cut off. + return -(bytes - s.len); + } + int tmp = (unsigned char)s.start[n]; + if ((tmp & 0xC0) != 0x80) + break; + } + } + return -8; + } + } + return 0; +} + +static void append_bstr(bstr *buf, bstr s) +{ + buf->start = talloc_realloc(NULL, buf->start, unsigned char, buf->len + s.len); + memcpy(buf->start + buf->len, s.start, s.len); + buf->len += s.len; +} + +struct bstr bstr_sanitize_utf8_latin1(void *talloc_ctx, struct bstr s) +{ + bstr new = {0}; + bstr left = s; + unsigned char *first_ok = s.start; + while (left.len) { + int r = bstr_decode_utf8(left, &left); + if (r < 0) { + append_bstr(&new, (bstr){first_ok, left.start - first_ok}); + uint32_t codepoint = (unsigned char)left.start[0]; + char data[8]; + uint8_t tmp; + char *output = data; + PUT_UTF8(codepoint, tmp, *output++ = tmp;); + append_bstr(&new, (bstr){data, output - data}); + left.start += 1; + left.len -= 1; + first_ok = left.start; + } + } + if (!new.start) + return s; + if (first_ok != left.start) + append_bstr(&new, (bstr){first_ok, left.start - first_ok}); + // For convenience + append_bstr(&new, (bstr){"\0", 1}); + new.len -= 1; + talloc_steal(talloc_ctx, new.start); + return new; +} + +bool bstr_case_startswith(struct bstr s, struct bstr prefix) +{ + struct bstr start = bstr_splice(s, 0, prefix.len); + return start.len == prefix.len && bstrcasecmp(start, prefix) == 0; +} + +bool bstr_case_endswith(struct bstr s, struct bstr suffix) +{ + struct bstr end = bstr_cut(s, -suffix.len); + return end.len == suffix.len && bstrcasecmp(end, suffix) == 0; +} + +struct bstr bstr_strip_ext(struct bstr str) +{ + int dotpos = bstrrchr(str, '.'); + if (dotpos < 0) + return str; + return (struct bstr){str.start, dotpos}; +} + +struct bstr bstr_get_ext(struct bstr s) +{ + int dotpos = bstrrchr(s, '.'); + if (dotpos < 0) + return (struct bstr){NULL, 0}; + return bstr_splice(s, dotpos + 1, s.len); +} diff --git a/bstr/bstr.h b/bstr/bstr.h new file mode 100644 index 0000000000..67e85655c4 --- /dev/null +++ b/bstr/bstr.h @@ -0,0 +1,200 @@ +/* + * This file is part of MPlayer. + * + * MPlayer 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. + * + * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPLAYER_BSTR_H +#define MPLAYER_BSTR_H + +#include +#include +#include +#include + +#include "talloc.h" + +/* NOTE: 'len' is size_t, but most string-handling functions below assume + * that input size has been sanity checked and len fits in an int. + */ +typedef struct bstr { + unsigned char *start; + size_t len; +} bstr; + +// If str.start is NULL, return NULL. +static inline char *bstrdup0(void *talloc_ctx, struct bstr str) +{ + return talloc_strndup(talloc_ctx, (char *)str.start, str.len); +} + +// Like bstrdup0(), but always return a valid C-string. +static inline char *bstrto0(void *talloc_ctx, struct bstr str) +{ + return str.start ? bstrdup0(talloc_ctx, str) : talloc_strdup(talloc_ctx, ""); +} + +// Return start = NULL iff that is true for the original. +static inline struct bstr bstrdup(void *talloc_ctx, struct bstr str) +{ + struct bstr r = { NULL, str.len }; + if (str.start) + r.start = (unsigned char *)talloc_memdup(talloc_ctx, str.start, str.len); + return r; +} + +static inline struct bstr bstr0(const char *s) +{ + return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0}; +} + +int bstrcmp(struct bstr str1, struct bstr str2); +int bstrcasecmp(struct bstr str1, struct bstr str2); +int bstrchr(struct bstr str, int c); +int bstrrchr(struct bstr str, int c); +int bstrspn(struct bstr str, const char *accept); +int bstrcspn(struct bstr str, const char *reject); + +int bstr_find(struct bstr haystack, struct bstr needle); +struct bstr *bstr_splitlines(void *talloc_ctx, struct bstr str); +struct bstr bstr_lstrip(struct bstr str); +struct bstr bstr_strip(struct bstr str); +struct bstr bstr_split(struct bstr str, const char *sep, struct bstr *rest); +bool bstr_split_tok(bstr str, const char *tok, bstr *out_left, bstr *out_right); +struct bstr bstr_splice(struct bstr str, int start, int end); +long long bstrtoll(struct bstr str, struct bstr *rest, int base); +double bstrtod(struct bstr str, struct bstr *rest); +void bstr_lower(struct bstr str); +int bstr_sscanf(struct bstr str, const char *format, ...); + +// Decode the UTF-8 code point at the start of the string,, and return the +// character. +// After calling this function, *out_next will point to the next character. +// out_next can be NULL. +// On error, -1 is returned, and *out_next is not modified. +int bstr_decode_utf8(struct bstr str, struct bstr *out_next); + +// Return the length of the UTF-8 sequence that starts with the given byte. +// Given a string char *s, the next UTF-8 code point is to be expected at +// s + bstr_parse_utf8_code_length(s[0]) +// On error, -1 is returned. On success, it returns a value in the range [1, 4]. +int bstr_parse_utf8_code_length(unsigned char b); + +// Return >= 0 if the string is valid UTF-8, otherwise negative error code. +// Embedded \0 bytes are considered valid. +// This returns -N if the UTF-8 string was likely just cut-off in the middle of +// an UTF-8 sequence: -1 means 1 byte was missing, -5 5 bytes missing. +// If the string was likely not cut off, -8 is returned. +// Use (return_value > -8) to check whether the string is valid UTF-8 or valid +// but cut-off UTF-8. +int bstr_validate_utf8(struct bstr s); + +// Force the input string to valid UTF-8. If invalid UTF-8 encoding is +// encountered, the invalid bytes are interpreted as Latin-1. +// Embedded \0 bytes are considered valid. +// If replacement happens, a newly allocated string is returned (with a \0 +// byte added past its end for convenience). The string is allocated via +// talloc, with talloc_ctx as parent. +struct bstr bstr_sanitize_utf8_latin1(void *talloc_ctx, struct bstr s); + +// Return the text before the next line break, and return it. Change *rest to +// point to the text following this line break. (rest can be NULL.) +// Line break characters are not stripped. +struct bstr bstr_getline(struct bstr str, struct bstr *rest); + +// Strip one trailing line break. This is intended for use with bstr_getline, +// and will remove the trailing \n or \r\n sequence. +struct bstr bstr_strip_linebreaks(struct bstr str); + +// If s starts with prefix, return true and return the rest of the string in s. +bool bstr_eatstart(struct bstr *s, struct bstr prefix); + +bool bstr_case_startswith(struct bstr s, struct bstr prefix); +bool bstr_case_endswith(struct bstr s, struct bstr suffix); +struct bstr bstr_strip_ext(struct bstr str); +struct bstr bstr_get_ext(struct bstr s); + +static inline struct bstr bstr_cut(struct bstr str, int n) +{ + if (n < 0) { + n += str.len; + if (n < 0) + n = 0; + } + if (((size_t)n) > str.len) + n = str.len; + return (struct bstr){str.start + n, str.len - n}; +} + +static inline bool bstr_startswith(struct bstr str, struct bstr prefix) +{ + if (str.len < prefix.len) + return false; + return !memcmp(str.start, prefix.start, prefix.len); +} + +static inline bool bstr_startswith0(struct bstr str, const char *prefix) +{ + return bstr_startswith(str, bstr0(prefix)); +} + +static inline bool bstr_endswith(struct bstr str, struct bstr suffix) +{ + if (str.len < suffix.len) + return false; + return !memcmp(str.start + str.len - suffix.len, suffix.start, suffix.len); +} + +static inline bool bstr_endswith0(struct bstr str, const char *suffix) +{ + return bstr_endswith(str, bstr0(suffix)); +} + +static inline int bstrcmp0(struct bstr str1, const char *str2) +{ + return bstrcmp(str1, bstr0(str2)); +} + +static inline bool bstr_equals(struct bstr str1, struct bstr str2) +{ + return bstrcmp(str1, str2) == 0; +} + +static inline bool bstr_equals0(struct bstr str1, const char *str2) +{ + return bstrcmp(str1, bstr0(str2)) == 0; +} + +static inline int bstrcasecmp0(struct bstr str1, const char *str2) +{ + return bstrcasecmp(str1, bstr0(str2)); +} + +static inline int bstr_find0(struct bstr haystack, const char *needle) +{ + return bstr_find(haystack, bstr0(needle)); +} + +static inline int bstr_eatstart0(struct bstr *s, const char *prefix) +{ + return bstr_eatstart(s, bstr0(prefix)); +} + +// create a pair (not single value!) for "%.*s" printf syntax +#define BSTR_P(bstr) (int)((bstr).len), (bstr).start + +#define WHITESPACE " \f\n\r\t\v" + +#endif /* MPLAYER_BSTR_H */ diff --git a/common/asxparser.c b/common/asxparser.c new file mode 100644 index 0000000000..5b1d5652a3 --- /dev/null +++ b/common/asxparser.c @@ -0,0 +1,581 @@ +/* + * This file is part of MPlayer. + * + * MPlayer 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. + * + * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "playlist.h" +#include "playlist_parser.h" +#include "stream/stream.h" +#include "asxparser.h" +#include "common/msg.h" + + +typedef struct ASX_Parser_t ASX_Parser_t; + +typedef struct { + char* buffer; + int line; +} ASX_LineSave_t; + +struct ASX_Parser_t { + int line; // Curent line + ASX_LineSave_t *ret_stack; + int ret_stack_size; + char* last_body; + int deep; + struct playlist *pl; +}; + +ASX_Parser_t *asx_parser_new(struct playlist *pl); + +void +asx_parser_free(ASX_Parser_t* parser); + +/* + * Return -1 on error, 0 when nothing is found, 1 on sucess + */ +int +asx_get_element(ASX_Parser_t* parser,char** _buffer, + char** _element,char** _body,char*** _attribs); + +int +asx_parse_attribs(ASX_Parser_t* parser,char* buffer,char*** _attribs); + +/////// Attribs utils + +char* +asx_get_attrib(const char* attrib,char** attribs); + +#define asx_free_attribs(a) asx_list_free(&a,free) + +////// List utils + +typedef void (*ASX_FreeFunc)(void* arg); + +void +asx_list_free(void* list_ptr,ASX_FreeFunc free_func); + + +////// List utils + +void +asx_list_free(void* list_ptr,ASX_FreeFunc free_func) { + void** ptr = *(void***)list_ptr; + if(ptr == NULL) return; + if(free_func != NULL) { + for( ; *ptr != NULL ; ptr++) + free_func(*ptr); + } + free(*(void**)list_ptr); + *(void**)list_ptr = NULL; +} + +/////// Attribs utils + +char* +asx_get_attrib(const char* attrib,char** attribs) { + char** ptr; + + if(attrib == NULL || attribs == NULL) return NULL; + for(ptr = attribs; ptr[0] != NULL; ptr += 2){ + if(strcasecmp(ptr[0],attrib) == 0) + return strdup(ptr[1]); + } + return NULL; +} + +#define asx_warning_attrib_required(p,e,a) mp_msg(MSGT_PLAYTREE,MSGL_WARN,"At line %d : element %s don't have the required attribute %s",p->line,e,a) +#define asx_warning_body_parse_error(p,e) mp_msg(MSGT_PLAYTREE,MSGL_WARN,"At line %d : error while parsing %s body",p->line,e) + +ASX_Parser_t *asx_parser_new(struct playlist *pl) +{ + ASX_Parser_t* parser = calloc(1,sizeof(ASX_Parser_t)); + parser->pl = pl; + return parser; +} + +void +asx_parser_free(ASX_Parser_t* parser) { + if(!parser) return; + free(parser->ret_stack); + free(parser); + +} + +#define LETTER "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" +#define SPACE " \n\t\r" + +int +asx_parse_attribs(ASX_Parser_t* parser,char* buffer,char*** _attribs) { + char *ptr1, *ptr2, *ptr3; + int n_attrib = 0; + char **attribs = NULL; + char *attrib, *val; + + ptr1 = buffer; + while(1) { + for( ; strchr(SPACE,*ptr1) != NULL; ptr1++) { // Skip space + if(*ptr1 == '\0') break; + } + ptr3 = strchr(ptr1,'='); + if(ptr3 == NULL) break; + for(ptr2 = ptr3-1; strchr(SPACE,*ptr2) != NULL; ptr2--) { + if (ptr2 == ptr1) { + mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : this should never append, back to attribute begin while skipping end space",parser->line); + break; + } + } + attrib = malloc(ptr2-ptr1+2); + strncpy(attrib,ptr1,ptr2-ptr1+1); + attrib[ptr2-ptr1+1] = '\0'; + + ptr1 = strchr(ptr3,'"'); + if(ptr1 == NULL || ptr1[1] == '\0') ptr1 = strchr(ptr3,'\''); + if(ptr1 == NULL || ptr1[1] == '\0') { + mp_msg(MSGT_PLAYTREE,MSGL_WARN,"At line %d : can't find attribute %s value",parser->line,attrib); + free(attrib); + break; + } + ptr2 = strchr(ptr1+1,ptr1[0]); + if (ptr2 == NULL) { + mp_msg(MSGT_PLAYTREE,MSGL_WARN,"At line %d : value of attribute %s isn't finished",parser->line,attrib); + free(attrib); + break; + } + ptr1++; + val = malloc(ptr2-ptr1+1); + strncpy(val,ptr1,ptr2-ptr1); + val[ptr2-ptr1] = '\0'; + n_attrib++; + + attribs = realloc(attribs, (2 * n_attrib + 1) * sizeof(char*)); + attribs[n_attrib*2-2] = attrib; + attribs[n_attrib*2-1] = val; + + ptr1 = ptr2+1; + } + + if(n_attrib > 0) + attribs[n_attrib*2] = NULL; + + *_attribs = attribs; + + return n_attrib; +} + +/* + * Return -1 on error, 0 when nothing is found, 1 on sucess + */ +int +asx_get_element(ASX_Parser_t* parser,char** _buffer, + char** _element,char** _body,char*** _attribs) { + char *ptr1,*ptr2, *ptr3, *ptr4; + char *attribs = NULL; + char *element = NULL, *body = NULL, *ret = NULL, *buffer; + int n_attrib = 0; + int body_line = 0,attrib_line,ret_line,in = 0; + int quotes = 0; + + if(_buffer == NULL || _element == NULL || _body == NULL || _attribs == NULL) { + mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : asx_get_element called with invalid value",parser->line); + return -1; + } + + *_body = *_element = NULL; + *_attribs = NULL; + buffer = *_buffer; + + if(buffer == NULL) return 0; + + if(parser->ret_stack && /*parser->last_body && */buffer != parser->last_body) { + ASX_LineSave_t* ls = parser->ret_stack; + int i; + for(i = 0 ; i < parser->ret_stack_size ; i++) { + if(buffer == ls[i].buffer) { + parser->line = ls[i].line; + break; + } + + } + if( i < parser->ret_stack_size) { + i++; + if( i < parser->ret_stack_size) + memmove(parser->ret_stack,parser->ret_stack+i, (parser->ret_stack_size - i)*sizeof(ASX_LineSave_t)); + parser->ret_stack_size -= i; + if(parser->ret_stack_size > 0) + parser->ret_stack = realloc(parser->ret_stack,parser->ret_stack_size*sizeof(ASX_LineSave_t)); + else { + free(parser->ret_stack); + parser->ret_stack = NULL; + } + } + } + + ptr1 = buffer; + while(1) { + for( ; ptr1[0] != '<' ; ptr1++) { + if(ptr1[0] == '\0') { + ptr1 = NULL; + break; + } + if(ptr1[0] == '\n') parser->line++; + } + //ptr1 = strchr(ptr1,'<'); + if(!ptr1 || ptr1[1] == '\0') return 0; // Nothing found + + if(strncmp(ptr1,"",3) != 0 ; ptr1++) { + if(ptr1[0] == '\0') { + ptr1 = NULL; + break; + } + if(ptr1[0] == '\n') parser->line++; + } + //ptr1 = strstr(ptr1,"-->"); + if(!ptr1) { + mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : unfinished comment",parser->line); + return -1; + } + } else { + break; + } + } + + // Is this space skip very useful ?? + for(ptr1++; strchr(SPACE,ptr1[0]) != NULL; ptr1++) { // Skip space + if(ptr1[0] == '\0') { + mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : EOB reached while parsing element start",parser->line); + return -1; + } + if(ptr1[0] == '\n') parser->line++; + } + + for(ptr2 = ptr1; strchr(LETTER,*ptr2) != NULL;ptr2++) { // Go to end of name + if(*ptr2 == '\0'){ + mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : EOB reached while parsing element start",parser->line); + return -1; + } + if(ptr2[0] == '\n') parser->line++; + } + + element = malloc(ptr2-ptr1+1); + strncpy(element,ptr1,ptr2-ptr1); + element[ptr2-ptr1] = '\0'; + + for( ; strchr(SPACE,*ptr2) != NULL; ptr2++) { // Skip space + if(ptr2[0] == '\0') { + mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : EOB reached while parsing element start",parser->line); + free(element); + return -1; + } + if(ptr2[0] == '\n') parser->line++; + } + attrib_line = parser->line; + + + + for(ptr3 = ptr2; ptr3[0] != '\0'; ptr3++) { // Go to element end + if(ptr3[0] == '"') quotes ^= 1; + if(!quotes && (ptr3[0] == '>' || strncmp(ptr3,"/>",2) == 0)) + break; + if(ptr3[0] == '\n') parser->line++; + } + if(ptr3[0] == '\0' || ptr3[1] == '\0') { // End of file + mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : EOB reached while parsing element start",parser->line); + free(element); + return -1; + } + + // Save attribs string + if(ptr3-ptr2 > 0) { + attribs = malloc(ptr3-ptr2+1); + strncpy(attribs,ptr2,ptr3-ptr2); + attribs[ptr3-ptr2] = '\0'; + } + //bs_line = parser->line; + if(ptr3[0] != '/') { // Not Self closed element + ptr3++; + for( ; strchr(SPACE,*ptr3) != NULL; ptr3++) { // Skip space on body begin + if(*ptr3 == '\0') { + mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : EOB reached while parsing %s element body",parser->line,element); + free(element); + free(attribs); + return -1; + } + if(ptr3[0] == '\n') parser->line++; + } + ptr4 = ptr3; + body_line = parser->line; + while(1) { // Find closing element + for( ; ptr4[0] != '<' ; ptr4++) { + if(ptr4[0] == '\0') { + ptr4 = NULL; + break; + } + if(ptr4[0] == '\n') parser->line++; + } + if(ptr4 && strncmp(ptr4,"",3) != 0 ; ptr4++) { + if(ptr4[0] == '\0') { + ptr4 = NULL; + break; + } + if(ptr1[0] == '\n') parser->line++; + } + continue; + } + if(ptr4 == NULL || ptr4[1] == '\0') { + mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : EOB reached while parsing %s element body",parser->line,element); + free(element); + free(attribs); + return -1; + } + if(ptr4[1] != '/' && strncasecmp(element,ptr4+1,strlen(element)) == 0) { + in++; + ptr4+=2; + continue; + } else if(strncasecmp(element,ptr4+2,strlen(element)) == 0) { // Extract body + if(in > 0) { + in--; + ptr4 += 2+strlen(element); + continue; + } + ret = ptr4+strlen(element)+3; + if(ptr4 != ptr3) { + ptr4--; + for( ; ptr4 != ptr3 && strchr(SPACE,*ptr4) != NULL; ptr4--) ;// Skip space on body end + // if(ptr4[0] == '\0') parser->line--; + //} + ptr4++; + body = malloc(ptr4-ptr3+1); + strncpy(body,ptr3,ptr4-ptr3); + body[ptr4-ptr3] = '\0'; + } + break; + } else { + ptr4 += 2; + } + } + } else { + ret = ptr3 + 2; // 2 is for /> + } + + for( ; ret[0] != '\0' && strchr(SPACE,ret[0]) != NULL; ret++) { // Skip space + if(ret[0] == '\n') parser->line++; + } + + ret_line = parser->line; + + if(attribs) { + parser->line = attrib_line; + n_attrib = asx_parse_attribs(parser,attribs,_attribs); + free(attribs); + if(n_attrib < 0) { + mp_msg(MSGT_PLAYTREE,MSGL_WARN,"At line %d : error while parsing element %s attributes",parser->line,element); + free(element); + free(body); + return -1; + } + } else + *_attribs = NULL; + + *_element = element; + *_body = body; + + parser->last_body = body; + parser->ret_stack_size++; + parser->ret_stack = realloc(parser->ret_stack,parser->ret_stack_size*sizeof(ASX_LineSave_t)); + if(parser->ret_stack_size > 1) + memmove(parser->ret_stack+1,parser->ret_stack,(parser->ret_stack_size-1)*sizeof(ASX_LineSave_t)); + parser->ret_stack[0].buffer = ret; + parser->ret_stack[0].line = ret_line; + parser->line = body ? body_line : ret_line; + + *_buffer = ret; + return 1; + +} + +static void +asx_parse_ref(ASX_Parser_t* parser, char** attribs) { + char *href; + + href = asx_get_attrib("HREF",attribs); + if(href == NULL) { + asx_warning_attrib_required(parser,"REF" ,"HREF" ); + return; + } +#if 0 + // replace http my mmshttp to avoid infinite loops + // disabled since some playlists for e.g. WinAMP use asx as well + // "-user-agent NSPlayer/4.1.0.3856" is a possible workaround + if (strncmp(href, "http://", 7) == 0) { + char *newref = malloc(3 + strlen(href) + 1); + strcpy(newref, "mms"); + strcpy(newref + 3, href); + free(href); + href = newref; + } +#endif + + playlist_add_file(parser->pl, href); + + mp_msg(MSGT_PLAYTREE,MSGL_V,"Adding file %s to element entry\n",href); + + free(href); + +} + +static void asx_parse_entryref(ASX_Parser_t* parser,char* buffer,char** _attribs) { + char *href; + + if(parser->deep > 0) + return; + + href = asx_get_attrib("HREF",_attribs); + if(href == NULL) { + asx_warning_attrib_required(parser,"ENTRYREF" ,"HREF" ); + return; + } + mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Recursive playlist %s\n", href); + playlist_add_file(parser->pl, href); + free(href); + //mp_msg(MSGT_PLAYTREE,MSGL_INFO,"Need to implement entryref\n"); +} + +static void asx_parse_entry(ASX_Parser_t* parser,char* buffer,char** _attribs) { + char *element,*body,**attribs; + int r; + + while(buffer && buffer[0] != '\0') { + r = asx_get_element(parser,&buffer,&element,&body,&attribs); + if(r < 0) { + asx_warning_body_parse_error(parser,"ENTRY"); + return; + } else if (r == 0) { // No more element + break; + } + if(strcasecmp(element,"REF") == 0) { + asx_parse_ref(parser,attribs); + mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Adding element %s to entry\n",element); + } else + mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Ignoring element %s\n",element); + free(body); + asx_free_attribs(attribs); + } + +} + + +static void asx_parse_repeat(ASX_Parser_t* parser,char* buffer,char** _attribs) { + char *element,*body,**attribs; + int r; + + asx_get_attrib("COUNT",_attribs); + mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Ignoring repeated playlist entries\n"); + + while(buffer && buffer[0] != '\0') { + r = asx_get_element(parser,&buffer,&element,&body,&attribs); + if(r < 0) { + asx_warning_body_parse_error(parser,"REPEAT"); + return; + } else if (r == 0) { // No more element + break; + } + if(strcasecmp(element,"ENTRY") == 0) { + asx_parse_entry(parser,body,attribs); + } else if(strcasecmp(element,"ENTRYREF") == 0) { + asx_parse_entryref(parser,body,attribs); + } else if(strcasecmp(element,"REPEAT") == 0) { + asx_parse_repeat(parser,body,attribs); + } else + mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Ignoring element %s\n",element); + free(body); + asx_free_attribs(attribs); + } + +} + + +bool asx_parse(char* buffer, struct playlist *pl) +{ + char *element,*asx_body,**asx_attribs,*body = NULL, **attribs; + int r; + ASX_Parser_t* parser = asx_parser_new(pl); + + parser->line = 1; + parser->deep = 0; + + r = asx_get_element(parser,&buffer,&element,&asx_body,&asx_attribs); + if(r < 0) { + mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : Syntax error ???",parser->line); + asx_parser_free(parser); + return false; + } else if(r == 0) { // No contents + mp_msg(MSGT_PLAYTREE,MSGL_ERR,"empty asx element"); + asx_parser_free(parser); + return false; + } + + if(strcasecmp(element,"ASX") != 0) { + mp_msg(MSGT_PLAYTREE,MSGL_ERR,"first element isn't ASX, it's %s\n",element); + asx_free_attribs(asx_attribs); + asx_parser_free(parser); + return false; + } + + if(!asx_body) { + mp_msg(MSGT_PLAYTREE,MSGL_ERR,"ASX element is empty"); + asx_free_attribs(asx_attribs); + asx_parser_free(parser); + return false; + } + + buffer = asx_body; + while(buffer && buffer[0] != '\0') { + r = asx_get_element(parser,&buffer,&element,&body,&attribs); + if(r < 0) { + asx_warning_body_parse_error(parser,"ASX"); + asx_parser_free(parser); + return false; + } else if (r == 0) { // No more element + break; + } + if(strcasecmp(element,"ENTRY") == 0) { + asx_parse_entry(parser,body,attribs); + } else if(strcasecmp(element,"ENTRYREF") == 0) { + asx_parse_entryref(parser,body,attribs); + } else if(strcasecmp(element,"REPEAT") == 0) { + asx_parse_repeat(parser,body,attribs); + } else + mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Ignoring element %s\n",element); + free(body); + asx_free_attribs(attribs); + } + + free(asx_body); + asx_free_attribs(asx_attribs); + asx_parser_free(parser); + return true; +} diff --git a/common/asxparser.h b/common/asxparser.h new file mode 100644 index 0000000000..e49a2cedc0 --- /dev/null +++ b/common/asxparser.h @@ -0,0 +1,27 @@ +/* + * This file is part of MPlayer. + * + * MPlayer 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. + * + * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPLAYER_ASXPARSER_H +#define MPLAYER_ASXPARSER_H + +#include + +struct playlist; +bool asx_parse(char* buffer, struct playlist *pl); + +#endif /* MPLAYER_ASXPARSER_H */ diff --git a/common/av_common.c b/common/av_common.c new file mode 100644 index 0000000000..cccb0f755e --- /dev/null +++ b/common/av_common.c @@ -0,0 +1,178 @@ +/* + * This file is part of mpv. + * + * mpv 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. + * + * mpv 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 mpv. If not, see . + */ + +#include + +#include +#include + +#include "common/common.h" +#include "common/msg.h" +#include "demux/packet.h" +#include "av_common.h" +#include "codecs.h" + +#include "osdep/numcores.h" + + +// Copy the codec-related fields from st into avctx. This does not set the +// codec itself, only codec related header data provided by libavformat. +// The goal is to initialize a new decoder with the header data provided by +// libavformat, and unlike avcodec_copy_context(), allow the user to create +// a clean AVCodecContext for a manually selected AVCodec. +// This is strictly for decoding only. +void mp_copy_lav_codec_headers(AVCodecContext *avctx, AVCodecContext *st) +{ + if (st->extradata_size) { + av_free(avctx->extradata); + avctx->extradata_size = 0; + avctx->extradata = + av_mallocz(st->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); + if (avctx->extradata) { + avctx->extradata_size = st->extradata_size; + memcpy(avctx->extradata, st->extradata, st->extradata_size); + } + } + avctx->codec_tag = st->codec_tag; + avctx->stream_codec_tag = st->stream_codec_tag; + avctx->bit_rate = st->bit_rate; + avctx->width = st->width; + avctx->height = st->height; + avctx->pix_fmt = st->pix_fmt; + avctx->sample_aspect_ratio = st->sample_aspect_ratio; + avctx->chroma_sample_location = st->chroma_sample_location; + avctx->sample_rate = st->sample_rate; + avctx->channels = st->channels; + avctx->block_align = st->block_align; + avctx->channel_layout = st->channel_layout; + avctx->audio_service_type = st->audio_service_type; + avctx->bits_per_coded_sample = st->bits_per_coded_sample; +} + +// We merely pass-through our PTS/DTS as an int64_t; libavcodec won't use it. +union pts { int64_t i; double d; }; + +// Convert the mpv style timestamp (seconds as double) to a libavcodec style +// timestamp (integer units in a given timebase). +// +// If the given timebase is NULL or invalid, pass through the mpv timestamp by +// reinterpret casting them to int64_t. In this case, the timestamps will be +// non-sense for libavcodec, but we expect that it doesn't interpret them, +// and treats them as opaque. +int64_t mp_pts_to_av(double mp_pts, AVRational *tb) +{ + assert(sizeof(int64_t) >= sizeof(double)); + if (tb && tb->num > 0 && tb->den > 0) + return mp_pts == MP_NOPTS_VALUE ? AV_NOPTS_VALUE : mp_pts / av_q2d(*tb); + // The + 0.0 is to squash possible negative zero mp_pts, which would + // happen to end up as AV_NOPTS_VALUE. + return (union pts){.d = mp_pts + 0.0}.i; +} + +// Inverse of mp_pts_to_av(). (The timebases must be exactly the same.) +double mp_pts_from_av(int64_t av_pts, AVRational *tb) +{ + assert(sizeof(int64_t) >= sizeof(double)); + if (tb && tb->num > 0 && tb->den > 0) + return av_pts == AV_NOPTS_VALUE ? MP_NOPTS_VALUE : av_pts * av_q2d(*tb); + // Should libavcodec set the PTS to AV_NOPTS_VALUE, it would end up as + // non-sense (usually negative zero) when unwrapped to double. + return av_pts == AV_NOPTS_VALUE ? MP_NOPTS_VALUE : (union pts){.i = av_pts}.d; +} + +// Set dst from mpkt. Note that dst is not refcountable. +// mpkt can be NULL to generate empty packets (used to flush delayed data). +// Sets pts/dts using mp_pts_to_av(ts, tb). (Be aware of the implications.) +// Set duration field only if tb is set. +void mp_set_av_packet(AVPacket *dst, struct demux_packet *mpkt, AVRational *tb) +{ + av_init_packet(dst); + dst->data = mpkt ? mpkt->buffer : NULL; + dst->size = mpkt ? mpkt->len : 0; + /* Some codecs (ZeroCodec, some cases of PNG) may want keyframe info + * from demuxer. */ + if (mpkt && mpkt->keyframe) + dst->flags |= AV_PKT_FLAG_KEY; + if (mpkt && mpkt->avpacket) { + dst->side_data = mpkt->avpacket->side_data; + dst->side_data_elems = mpkt->avpacket->side_data_elems; + } + if (mpkt && tb && tb->num > 0 && tb->den > 0) + dst->duration = mpkt->duration / av_q2d(*tb); + dst->pts = mp_pts_to_av(mpkt ? mpkt->pts : MP_NOPTS_VALUE, tb); + dst->dts = mp_pts_to_av(mpkt ? mpkt->dts : MP_NOPTS_VALUE, tb); +} + +void mp_set_avcodec_threads(AVCodecContext *avctx, int threads) +{ + if (threads == 0) { + threads = default_thread_count(); + if (threads < 1) { + mp_msg(MSGT_GLOBAL, MSGL_WARN, "Could not determine " + "thread count to use, defaulting to 1.\n"); + threads = 1; + } + // Apparently some libavcodec versions have or had trouble with more + // than 16 threads, and/or print a warning when using > 16. + threads = MPMIN(threads, 16); + } + avctx->thread_count = threads; +} + +void mp_add_lavc_decoders(struct mp_decoder_list *list, enum AVMediaType type) +{ + AVCodec *cur = NULL; + for (;;) { + cur = av_codec_next(cur); + if (!cur) + break; + if (av_codec_is_decoder(cur) && cur->type == type) { + mp_add_decoder(list, "lavc", mp_codec_from_av_codec_id(cur->id), + cur->name, cur->long_name); + } + } +} + +int mp_codec_to_av_codec_id(const char *codec) +{ + int id = AV_CODEC_ID_NONE; + if (codec) { + const AVCodecDescriptor *desc = avcodec_descriptor_get_by_name(codec); + if (desc) + id = desc->id; + if (id == AV_CODEC_ID_NONE) { + AVCodec *avcodec = avcodec_find_decoder_by_name(codec); + if (avcodec) + id = avcodec->id; + } + } + return id; +} + +const char *mp_codec_from_av_codec_id(int codec_id) +{ + const char *name = NULL; + const AVCodecDescriptor *desc = avcodec_descriptor_get(codec_id); + if (desc) + name = desc->name; + if (!name) { + AVCodec *avcodec = avcodec_find_decoder(codec_id); + if (avcodec) + name = avcodec->name; + } + return name; +} diff --git a/common/av_common.h b/common/av_common.h new file mode 100644 index 0000000000..7bf2d64d9e --- /dev/null +++ b/common/av_common.h @@ -0,0 +1,39 @@ +/* + * This file is part of mpv. + * + * mpv 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. + * + * mpv 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 mpv. If not, see . + */ + +#ifndef MP_AVCOMMON_H +#define MP_AVCOMMON_H + +#include + +#include +#include +#include + +struct mp_decoder_list; +struct demux_packet; + +void mp_copy_lav_codec_headers(AVCodecContext *avctx, AVCodecContext *st); +void mp_set_av_packet(AVPacket *dst, struct demux_packet *mpkt, AVRational *tb); +int64_t mp_pts_to_av(double mp_pts, AVRational *tb); +double mp_pts_from_av(int64_t av_pts, AVRational *tb); +void mp_set_avcodec_threads(AVCodecContext *avctx, int threads); +void mp_add_lavc_decoders(struct mp_decoder_list *list, enum AVMediaType type); +int mp_codec_to_av_codec_id(const char *codec); +const char *mp_codec_from_av_codec_id(int codec_id); + +#endif diff --git a/common/av_log.c b/common/av_log.c new file mode 100644 index 0000000000..ba47500572 --- /dev/null +++ b/common/av_log.c @@ -0,0 +1,176 @@ +/* + * av_log to mp_msg converter + * Copyright (C) 2006 Michael Niedermayer + * Copyright (C) 2009 Uoti Urpala + * + * This file is part of MPlayer. + * + * MPlayer 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. + * + * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include + +#include "av_log.h" +#include "config.h" +#include "common/msg.h" +#include +#include + +#include +#include +#include + +#if HAVE_LIBAVDEVICE +#include +#endif + +#if HAVE_LIBAVFILTER +#include +#endif + +#if HAVE_LIBAVRESAMPLE +#include +#endif +#if HAVE_LIBSWRESAMPLE +#include +#endif + +static int av_log_level_to_mp_level(int av_level) +{ + if (av_level > AV_LOG_VERBOSE) + return MSGL_DBG2; + if (av_level > AV_LOG_INFO) + return MSGL_V; + if (av_level > AV_LOG_WARNING) + return MSGL_V; + if (av_level > AV_LOG_ERROR) + return MSGL_WARN; + if (av_level > AV_LOG_FATAL) + return MSGL_ERR; + return MSGL_FATAL; +} + +static int extract_msg_type_from_ctx(void *ptr) +{ + if (!ptr) + return MSGT_FIXME; + + AVClass *avc = *(AVClass **)ptr; + if (!avc) { + mp_msg(MSGT_FIXME, MSGL_WARN, + "av_log callback called with bad parameters (NULL AVClass).\n" + "This is a bug in one of Libav/FFmpeg libraries used.\n"); + return MSGT_FIXME; + } + + if (!strcmp(avc->class_name, "AVCodecContext")) { + AVCodecContext *s = ptr; + if (s->codec) { + if (s->codec->type == AVMEDIA_TYPE_AUDIO) { + if (s->codec->decode) + return MSGT_DECAUDIO; + } else if (s->codec->type == AVMEDIA_TYPE_VIDEO) { + if (s->codec->decode) + return MSGT_DECVIDEO; + } + // FIXME subtitles, encoders + // What msgt for them? There is nothing appropriate... + } + return MSGT_FIXME; + } + + if (!strcmp(avc->class_name, "AVFormatContext")) { + AVFormatContext *s = ptr; + if (s->iformat) + return MSGT_DEMUXER; + else if (s->oformat) + return MSGT_MUXER; + return MSGT_FIXME; + } + + return MSGT_FIXME; +} + +#if LIBAVCODEC_VERSION_MICRO >= 100 +#define LIB_PREFIX "ffmpeg" +#else +#define LIB_PREFIX "libav" +#endif + +static bool print_prefix = true; + +static void mp_msg_av_log_callback(void *ptr, int level, const char *fmt, + va_list vl) +{ + AVClass *avc = ptr ? *(AVClass **)ptr : NULL; + int mp_level = av_log_level_to_mp_level(level); + int type = extract_msg_type_from_ctx(ptr); + + if (!mp_msg_test(type, mp_level)) + return; + + if (print_prefix) { + mp_msg(type, mp_level, "[%s/%s] ", LIB_PREFIX, + avc ? avc->item_name(ptr) : "?"); + } + print_prefix = fmt[strlen(fmt) - 1] == '\n'; + + mp_msg_va(type, mp_level, fmt, vl); +} + +void init_libav(void) +{ + av_log_set_callback(mp_msg_av_log_callback); + avcodec_register_all(); + av_register_all(); + avformat_network_init(); + +#if HAVE_LIBAVFILTER + avfilter_register_all(); +#endif +#if HAVE_LIBAVDEVICE + avdevice_register_all(); +#endif +} + +#define V(x) (x)>>16, (x)>>8 & 255, (x) & 255 +static void print_version(int v, char *name, unsigned buildv, unsigned runv) +{ + mp_msg(MSGT_CPLAYER, v, " %-15s %d.%d.%d", name, V(buildv)); + if (buildv != runv) + mp_msg(MSGT_CPLAYER, v, " (runtime %d.%d.%d)", V(runv)); + mp_msg(MSGT_CPLAYER, v, "\n"); +} +#undef V + +void print_libav_versions(int v) +{ + mp_msg(MSGT_CPLAYER, v, "%s library versions:\n", LIB_PREFIX); + + print_version(v, "libavutil", LIBAVUTIL_VERSION_INT, avutil_version()); + print_version(v, "libavcodec", LIBAVCODEC_VERSION_INT, avcodec_version()); + print_version(v, "libavformat", LIBAVFORMAT_VERSION_INT, avformat_version()); + print_version(v, "libswscale", LIBSWSCALE_VERSION_INT, swscale_version()); +#if HAVE_LIBAVFILTER + print_version(v, "libavfilter", LIBAVFILTER_VERSION_INT, avfilter_version()); +#endif +#if HAVE_LIBAVRESAMPLE + print_version(v, "libavresample", LIBAVRESAMPLE_VERSION_INT, avresample_version()); +#endif +#if HAVE_LIBSWRESAMPLE + print_version(v, "libswresample", LIBSWRESAMPLE_VERSION_INT, swresample_version()); +#endif +} diff --git a/common/av_log.h b/common/av_log.h new file mode 100644 index 0000000000..d5c57b0aeb --- /dev/null +++ b/common/av_log.h @@ -0,0 +1,2 @@ +void init_libav(void); +void print_libav_versions(int v); diff --git a/common/av_opts.c b/common/av_opts.c new file mode 100644 index 0000000000..777a1eec5a --- /dev/null +++ b/common/av_opts.c @@ -0,0 +1,55 @@ +/* + * AVOption parsing helper + * Copyright (C) 2008 Michael Niedermayer + * + * This file is part of MPlayer. + * + * MPlayer 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. + * + * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include + +#include + +#include "av_opts.h" + +int parse_avopts(void *v, char *str){ + char *start; + + if (!str) + return 0; + + start= str= strdup(str); + + while(str && *str){ + char *next_opt, *arg; + + next_opt= strchr(str, ','); + if(next_opt) *next_opt++= 0; + + arg = strchr(str, '='); + if(arg) *arg++= 0; + + if (av_opt_set(v, str, arg, AV_OPT_SEARCH_CHILDREN) < 0) { + free(start); + return -1; + } + str= next_opt; + } + + free(start); + return 0; +} diff --git a/common/av_opts.h b/common/av_opts.h new file mode 100644 index 0000000000..640443a352 --- /dev/null +++ b/common/av_opts.h @@ -0,0 +1,30 @@ +/* + * AVOption parsing helper + * Copyright (C) 2008 Michael Niedermayer + * + * This file is part of MPlayer. + * + * MPlayer 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. + * + * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPLAYER_AV_OPTS_H +#define MPLAYER_AV_OPTS_H + +/** + * Parses str and sets AVOptions in v accordingly. + */ +int parse_avopts(void *v, char *str); + +#endif /* MPLAYER_AV_OPTS_H */ diff --git a/common/codecs.c b/common/codecs.c new file mode 100644 index 0000000000..b7639a4576 --- /dev/null +++ b/common/codecs.c @@ -0,0 +1,147 @@ +/* + * This file is part of mpv. + * + * mpv 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. + * + * mpv 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 mpv. If not, see . + */ + +#include +#include "talloc.h" +#include "bstr/bstr.h" +#include "common/msg.h" +#include "codecs.h" + +void mp_add_decoder(struct mp_decoder_list *list, const char *family, + const char *codec, const char *decoder, const char *desc) +{ + struct mp_decoder_entry entry = { + .family = talloc_strdup(list, family), + .codec = talloc_strdup(list, codec), + .decoder = talloc_strdup(list, decoder), + .desc = talloc_strdup(list, desc), + }; + MP_TARRAY_APPEND(list, list->entries, list->num_entries, entry); +} + +static void mp_add_decoder_entry(struct mp_decoder_list *list, + struct mp_decoder_entry *entry) +{ + mp_add_decoder(list, entry->family, entry->codec, entry->decoder, + entry->desc); +} + +static struct mp_decoder_entry *find_decoder(struct mp_decoder_list *list, + bstr family, bstr decoder) +{ + for (int n = 0; n < list->num_entries; n++) { + struct mp_decoder_entry *cur = &list->entries[n]; + if (bstr_equals0(decoder, cur->decoder) && + bstr_equals0(family, cur->family)) + return cur; + } + return NULL; +} + +// Add entry, but only if it's not yet on the list, and if the codec matches. +// If codec == NULL, don't compare codecs. +static void add_new(struct mp_decoder_list *to, struct mp_decoder_entry *entry, + const char *codec) +{ + if (!entry || (codec && strcmp(entry->codec, codec) != 0)) + return; + if (!find_decoder(to, bstr0(entry->family), bstr0(entry->decoder))) + mp_add_decoder_entry(to, entry); +} + +// Select a decoder from the given list for the given codec. The selection +// can be influenced by the selection string, which can specify a priority +// list of preferred decoders. +// This returns a list of decoders to try, with the preferred decoders first. +// The selection string corresponds to --vd/--ad directly, and has the +// following syntax: +// selection = [ ("," )*] +// entry = ":" // prefer decoder +// entry = ":*" // prefer all decoders +// entry = "+" ":" // force a decoder +// entry = "-" ":" // exclude a decoder +// entry = "-" // don't add fallback decoders +// Forcing a decoder means it's added even if the codec mismatches. +struct mp_decoder_list *mp_select_decoders(struct mp_decoder_list *all, + const char *codec, + const char *selection) +{ + struct mp_decoder_list *list = talloc_zero(NULL, struct mp_decoder_list); + struct mp_decoder_list *remove = talloc_zero(NULL, struct mp_decoder_list); + if (!codec) + codec = "unknown"; + bool stop = false; + bstr sel = bstr0(selection); + while (sel.len) { + bstr entry; + bstr_split_tok(sel, ",", &entry, &sel); + if (bstr_equals0(entry, "-")) { + stop = true; + break; + } + bool force = bstr_eatstart0(&entry, "+"); + bool exclude = !force && bstr_eatstart0(&entry, "-"); + struct mp_decoder_list *dest = exclude ? remove : list; + bstr family, decoder; + if (!bstr_split_tok(entry, ":", &family, &decoder)) { + mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Decoders must be specified as " + "'family:decoder' for the --ad/--vd options.\n"); + break; + } + if (bstr_equals0(decoder, "*")) { + for (int n = 0; n < all->num_entries; n++) { + struct mp_decoder_entry *cur = &all->entries[n]; + if (bstr_equals0(family, cur->family)) + add_new(dest, cur, codec); + } + } else { + add_new(dest, find_decoder(all, family, decoder), + force ? NULL : codec); + } + } + if (!stop) { + // Add the remaining codecs which haven't been added yet + for (int n = 0; n < all->num_entries; n++) + add_new(list, &all->entries[n], codec); + } + for (int n = 0; n < remove->num_entries; n++) { + struct mp_decoder_entry *ex = &remove->entries[n]; + struct mp_decoder_entry *del = + find_decoder(list, bstr0(ex->family), bstr0(ex->decoder)); + if (del) { + int index = del - &list->entries[0]; + MP_TARRAY_REMOVE_AT(list->entries, list->num_entries, index); + } + } + talloc_free(remove); + return list; +} + +void mp_print_decoders(int msgt, int msgl, const char *header, + struct mp_decoder_list *list) +{ + mp_msg(msgt, msgl, "%s\n", header); + for (int n = 0; n < list->num_entries; n++) { + struct mp_decoder_entry *entry = &list->entries[n]; + mp_msg(msgt, msgl, " %s:%s", entry->family, entry->decoder); + if (strcmp(entry->decoder, entry->codec) != 0) + mp_msg(msgt, msgl, " (%s)", entry->codec); + mp_msg(msgt, msgl, " - %s\n", entry->desc); + } + if (list->num_entries == 0) + mp_msg(msgt, msgl, " (no decoders)\n"); +} diff --git a/common/codecs.h b/common/codecs.h new file mode 100644 index 0000000000..21ff284617 --- /dev/null +++ b/common/codecs.h @@ -0,0 +1,43 @@ +/* + * This file is part of mpv. + * + * mpv 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. + * + * mpv 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 mpv. If not, see . + */ + +#ifndef MP_CODECS_H +#define MP_CODECS_H + +struct mp_decoder_entry { + const char *family; // decoder module (e.g. ad_lavc => "lavc") + const char *codec; // name of the codec (e.g. "mp3") + const char *decoder; // decoder name (e.g. "mp3float") + const char *desc; // human readable description +}; + +struct mp_decoder_list { + struct mp_decoder_entry *entries; + int num_entries; +}; + +void mp_add_decoder(struct mp_decoder_list *list, const char *family, + const char *codec, const char *decoder, const char *desc); + +struct mp_decoder_list *mp_select_decoders(struct mp_decoder_list *all, + const char *codec, + const char *selection); + +void mp_print_decoders(int msgt, int msgl, const char *header, + struct mp_decoder_list *list); + +#endif diff --git a/common/common.c b/common/common.c new file mode 100644 index 0000000000..365a369425 --- /dev/null +++ b/common/common.c @@ -0,0 +1,163 @@ +/* + * This file is part of MPlayer. + * + * MPlayer 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. + * + * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include + +#include "talloc.h" +#include "bstr/bstr.h" +#include "common/common.h" + +#define appendf(ptr, ...) \ + do {(*(ptr)) = talloc_asprintf_append_buffer(*(ptr), __VA_ARGS__);} while(0) + +// Return a talloc'ed string formatted according to the format string in fmt. +// On error, return NULL. +// Valid formats: +// %H, %h: hour (%H is padded with 0 to two digits) +// %M: minutes from 00-59 (hours are subtracted) +// %m: total minutes (includes hours, unlike %M) +// %S: seconds from 00-59 (minutes and hours are subtracted) +// %s: total seconds (includes hours and minutes) +// %f: like %s, but as float +// %T: milliseconds (000-999) +char *mp_format_time_fmt(const char *fmt, double time) +{ + if (time == MP_NOPTS_VALUE) + return talloc_strdup(NULL, "unknown"); + char *sign = time < 0 ? "-" : ""; + time = time < 0 ? -time : time; + long long int itime = time; + long long int h, m, tm, s; + int ms; + s = itime; + tm = s / 60; + h = s / 3600; + s -= h * 3600; + m = s / 60; + s -= m * 60; + ms = (time - itime) * 1000; + char *res = talloc_strdup(NULL, ""); + while (*fmt) { + if (fmt[0] == '%') { + fmt++; + switch (fmt[0]) { + case 'h': appendf(&res, "%s%lld", sign, h); break; + case 'H': appendf(&res, "%s%02lld", sign, h); break; + case 'm': appendf(&res, "%s%lld", sign, tm); break; + case 'M': appendf(&res, "%02lld", m); break; + case 's': appendf(&res, "%s%lld", sign, itime); break; + case 'S': appendf(&res, "%02lld", s); break; + case 'T': appendf(&res, "%03d", ms); break; + case '%': appendf(&res, "%s", "%"); break; + default: goto error; + } + fmt++; + } else { + appendf(&res, "%c", *fmt); + fmt++; + } + } + return res; +error: + talloc_free(res); + return NULL; +} + +char *mp_format_time(double time, bool fractions) +{ + return mp_format_time_fmt(fractions ? "%H:%M:%S.%T" : "%H:%M:%S", time); +} + +// Set rc to the union of rc and rc2 +void mp_rect_union(struct mp_rect *rc, const struct mp_rect *rc2) +{ + rc->x0 = FFMIN(rc->x0, rc2->x0); + rc->y0 = FFMIN(rc->y0, rc2->y0); + rc->x1 = FFMAX(rc->x1, rc2->x1); + rc->y1 = FFMAX(rc->y1, rc2->y1); +} + +// Set rc to the intersection of rc and src. +// Return false if the result is empty. +bool mp_rect_intersection(struct mp_rect *rc, const struct mp_rect *rc2) +{ + rc->x0 = FFMAX(rc->x0, rc2->x0); + rc->y0 = FFMAX(rc->y0, rc2->y0); + rc->x1 = FFMIN(rc->x1, rc2->x1); + rc->y1 = FFMIN(rc->y1, rc2->y1); + + return rc->x1 > rc->x0 && rc->y1 > rc->y0; +} + +// Encode the unicode codepoint as UTF-8, and append to the end of the +// talloc'ed buffer. +char *mp_append_utf8_buffer(char *buffer, uint32_t codepoint) +{ + char data[8]; + uint8_t tmp; + char *output = data; + PUT_UTF8(codepoint, tmp, *output++ = tmp;); + return talloc_strndup_append_buffer(buffer, data, output - data); +} + +// Parse a C-style escape beginning at code, and append the result to *str +// using talloc. The input string (*code) must point to the first character +// after the initial '\', and after parsing *code is set to the first character +// after the current escape. +// On error, false is returned, and all input remains unchanged. +bool mp_parse_escape(bstr *code, char **str) +{ + if (code->len < 1) + return false; + char replace = 0; + switch (code->start[0]) { + case '"': replace = '"'; break; + case '\\': replace = '\\'; break; + case 'b': replace = '\b'; break; + case 'f': replace = '\f'; break; + case 'n': replace = '\n'; break; + case 'r': replace = '\r'; break; + case 't': replace = '\t'; break; + case 'e': replace = '\x1b'; break; + case '\'': replace = '\''; break; + } + if (replace) { + *str = talloc_strndup_append_buffer(*str, &replace, 1); + *code = bstr_cut(*code, 1); + return true; + } + if (code->start[0] == 'x' && code->len >= 3) { + bstr num = bstr_splice(*code, 1, 3); + char c = bstrtoll(num, &num, 16); + if (!num.len) + return false; + *str = talloc_strndup_append_buffer(*str, &c, 1); + *code = bstr_cut(*code, 3); + return true; + } + if (code->start[0] == 'u' && code->len >= 5) { + bstr num = bstr_splice(*code, 1, 5); + int c = bstrtoll(num, &num, 16); + if (num.len) + return false; + *str = mp_append_utf8_buffer(*str, c); + *code = bstr_cut(*code, 5); + return true; + } + return false; +} diff --git a/common/common.h b/common/common.h new file mode 100644 index 0000000000..9e751ee851 --- /dev/null +++ b/common/common.h @@ -0,0 +1,81 @@ +/* + * This file is part of MPlayer. + * + * MPlayer 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. + * + * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPLAYER_MPCOMMON_H +#define MPLAYER_MPCOMMON_H + +#include +#include +#include + +#include "compat/compiler.h" +#include "talloc.h" + +// both int64_t and double should be able to represent this exactly +#define MP_NOPTS_VALUE (-1LL<<63) + +#define MP_CONCAT_(a, b) a ## b +#define MP_CONCAT(a, b) MP_CONCAT_(a, b) + +#define ROUND(x) ((int)((x) < 0 ? (x) - 0.5 : (x) + 0.5)) + +#define MPMAX(a, b) ((a) > (b) ? (a) : (b)) +#define MPMIN(a, b) ((a) > (b) ? (b) : (a)) +#define MPCLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a))) +#define MPSWAP(type, a, b) \ + do { type SWAP_tmp = b; b = a; a = SWAP_tmp; } while (0) +#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0])) + +// align must be a power of two (align >= 1), x >= 0 +#define MP_ALIGN_UP(x, align) (((x) + (align) - 1) & ~((align) - 1)) +#define MP_ALIGN_DOWN(x, align) ((x) & ~((align) - 1)) + +#define CONTROL_OK 1 +#define CONTROL_TRUE 1 +#define CONTROL_FALSE 0 +#define CONTROL_UNKNOWN -1 +#define CONTROL_ERROR -2 +#define CONTROL_NA -3 + +enum stream_type { + STREAM_VIDEO, + STREAM_AUDIO, + STREAM_SUB, + STREAM_TYPE_COUNT, +}; + +extern const char *mplayer_version; +extern const char *mplayer_builddate; + +char *mp_format_time(double time, bool fractions); +char *mp_format_time_fmt(const char *fmt, double time); + +struct mp_rect { + int x0, y0; + int x1, y1; +}; + +void mp_rect_union(struct mp_rect *rc, const struct mp_rect *src); +bool mp_rect_intersection(struct mp_rect *rc, const struct mp_rect *rc2); + +char *mp_append_utf8_buffer(char *buffer, uint32_t codepoint); + +struct bstr; +bool mp_parse_escape(struct bstr *code, char **str); + +#endif /* MPLAYER_MPCOMMON_H */ diff --git a/common/cpudetect.c b/common/cpudetect.c new file mode 100644 index 0000000000..ea28cf4dd4 --- /dev/null +++ b/common/cpudetect.c @@ -0,0 +1,56 @@ +/* + * This file is part of MPlayer. + * + * MPlayer 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. + * + * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include + +#include +#include "compat/libav.h" + +#include "config.h" +#include "common/cpudetect.h" +#include "common/msg.h" + +CpuCaps gCpuCaps; + +static void dump_flag(const char *name, bool val) +{ + mp_msg(MSGT_CPUDETECT, MSGL_V, "CPU: %s: %s\n", name, + val ? "enabled" : "disabled"); +} + +void GetCpuCaps(CpuCaps *c) +{ + memset(c, 0, sizeof(*c)); + int flags = av_get_cpu_flags(); +#if ARCH_X86 + c->hasMMX = flags & AV_CPU_FLAG_MMX; + c->hasMMX2 = flags & AV_CPU_FLAG_MMX2; + c->hasSSE = flags & AV_CPU_FLAG_SSE; + c->hasSSE2 = (flags & AV_CPU_FLAG_SSE2) && !(flags & AV_CPU_FLAG_SSE2SLOW); + c->hasSSE3 = (flags & AV_CPU_FLAG_SSE3) && !(flags & AV_CPU_FLAG_SSE3SLOW); + c->hasSSSE3 = flags & AV_CPU_FLAG_SSSE3; +#endif + dump_flag("MMX", c->hasMMX); + dump_flag("MMX2", c->hasMMX2); + dump_flag("SSE", c->hasSSE); + dump_flag("SSE2", c->hasSSE2); + dump_flag("SSE3", c->hasSSE3); + dump_flag("SSSE3", c->hasSSSE3); +} diff --git a/common/cpudetect.h b/common/cpudetect.h new file mode 100644 index 0000000000..d3d9206c65 --- /dev/null +++ b/common/cpudetect.h @@ -0,0 +1,40 @@ +/* + * This file is part of MPlayer. + * + * MPlayer 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. + * + * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPLAYER_CPUDETECT_H +#define MPLAYER_CPUDETECT_H + +#include +#include "config.h" + +#include "compat/x86_cpu.h" + +typedef struct cpucaps_s { + bool hasMMX; + bool hasMMX2; + bool hasSSE; + bool hasSSE2; + bool hasSSE3; + bool hasSSSE3; +} CpuCaps; + +extern CpuCaps gCpuCaps; + +void GetCpuCaps(CpuCaps *caps); + +#endif /* MPLAYER_CPUDETECT_H */ diff --git a/common/encode.h b/common/encode.h new file mode 100644 index 0000000000..fec14045ed --- /dev/null +++ b/common/encode.h @@ -0,0 +1,21 @@ +#ifndef MPLAYER_ENCODE_H +#define MPLAYER_ENCODE_H + +#include + +struct MPOpts; +struct encode_lavc_context; +struct encode_output_conf; + +// interface for mplayer.c +struct encode_lavc_context *encode_lavc_init(struct encode_output_conf *options); +void encode_lavc_finish(struct encode_lavc_context *ctx); +void encode_lavc_free(struct encode_lavc_context *ctx); +void encode_lavc_discontinuity(struct encode_lavc_context *ctx); +bool encode_lavc_showhelp(struct MPOpts *opts); +int encode_lavc_getstatus(struct encode_lavc_context *ctx, char *buf, int bufsize, float relative_position); +void encode_lavc_expect_stream(struct encode_lavc_context *ctx, int mt); +void encode_lavc_set_video_fps(struct encode_lavc_context *ctx, float fps); +bool encode_lavc_didfail(struct encode_lavc_context *ctx); // check if encoding failed + +#endif diff --git a/common/encode_lavc.c b/common/encode_lavc.c new file mode 100644 index 0000000000..97a45ccbbe --- /dev/null +++ b/common/encode_lavc.c @@ -0,0 +1,1115 @@ +/* + * muxing using libavformat + * Copyright (C) 2010 Nicolas George + * Copyright (C) 2011-2012 Rudolf Polzer + * + * This file is part of mpv. + * + * MPlayer 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. + * + * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include + +#include "encode_lavc.h" +#include "common/msg.h" +#include "video/vfcap.h" +#include "options/options.h" +#include "osdep/timer.h" +#include "video/out/vo.h" +#include "talloc.h" +#include "stream/stream.h" + +static int set_to_avdictionary(AVDictionary **dictp, const char *key, + const char *val) +{ + char keybuf[1024]; + char valuebuf[1024]; + + if (key == NULL) { + // we need to split at equals sign + const char *equals = strchr(val, '='); + if (!equals || equals - val >= sizeof(keybuf)) { + mp_msg(MSGT_ENCODE, MSGL_WARN, + "encode-lavc: option '%s' does not contain an equals sign\n", + val); + return 0; + } + memcpy(keybuf, val, equals - val); + keybuf[equals - val] = 0; + key = keybuf; + val = equals + 1; + } + + // hack: support "qscale" key as virtual "global_quality" key that multiplies by QP2LAMBDA + if (!strcmp(key, "qscale")) { + key = "global_quality"; + snprintf(valuebuf, sizeof(valuebuf), + "%.1s(%s)*QP2LAMBDA", + (val[0] == '+' || val[0] == '-') ? val : "", + (val[0] == '+' || val[0] == '-') ? val + 1 : val); + valuebuf[sizeof(valuebuf) - 1] = 0; + val = valuebuf; + } + + mp_msg(MSGT_ENCODE, MSGL_V, + "encode-lavc: setting value '%s' for key '%s'\n", + val, + key); + + if (av_dict_set(dictp, key, *val ? val : NULL, + (val[0] == '+' || val[0] == '-') ? AV_DICT_APPEND : 0) >= 0) + return 1; + + return 0; +} + +static bool value_has_flag(const char *value, const char *flag) +{ + bool state = true; + bool ret = false; + while (*value) { + size_t l = strcspn(value, "+-"); + if (l == 0) { + state = (*value == '+'); + ++value; + } else { + if (l == strlen(flag)) + if (!memcmp(value, flag, l)) + ret = state; + value += l; + } + } + return ret; +} + +#define CHECK_FAIL(ctx, val) \ + if (ctx && (ctx->failed || ctx->finished)) { \ + mp_msg(MSGT_ENCODE, MSGL_ERR, \ + "Called a function on a %s encoding context. Bailing out.\n", \ + ctx->failed ? "failed" : "finished"); \ + return val; \ + } + +int encode_lavc_available(struct encode_lavc_context *ctx) +{ + CHECK_FAIL(ctx, 0); + return ctx && ctx->avc; +} + +int encode_lavc_oformat_flags(struct encode_lavc_context *ctx) +{ + CHECK_FAIL(ctx, 0); + return ctx->avc ? ctx->avc->oformat->flags : 0; +} + +struct encode_lavc_context *encode_lavc_init(struct encode_output_conf *options) +{ + struct encode_lavc_context *ctx; + const char *filename = options->file; + + // STUPID STUPID STUPID STUPID avio + // does not support "-" as file name to mean stdin/stdout + // ffmpeg.c works around this too, the same way + if (!strcmp(filename, "-")) + filename = "pipe:1"; + + if (filename && ( + !strcmp(filename, "/dev/stdout") || + !strcmp(filename, "pipe:") || + !strcmp(filename, "pipe:1"))) + mp_msg_stdout_in_use = 1; + + ctx = talloc_zero(NULL, struct encode_lavc_context); + encode_lavc_discontinuity(ctx); + ctx->options = options; + + ctx->avc = avformat_alloc_context(); + + if (ctx->options->format) { + char *tok; + const char *in = ctx->options->format; + while (*in) { + tok = av_get_token(&in, ","); + ctx->avc->oformat = av_guess_format(tok, filename, NULL); + av_free(tok); + if (ctx->avc->oformat) + break; + if (*in) + ++in; + } + } else + ctx->avc->oformat = av_guess_format(NULL, filename, NULL); + + if (!ctx->avc->oformat) { + encode_lavc_fail(ctx, "encode-lavc: format not found\n"); + return NULL; + } + + av_strlcpy(ctx->avc->filename, filename, + sizeof(ctx->avc->filename)); + + ctx->foptions = NULL; + if (ctx->options->fopts) { + char **p; + for (p = ctx->options->fopts; *p; ++p) { + if (!set_to_avdictionary(&ctx->foptions, NULL, *p)) + mp_msg(MSGT_ENCODE, MSGL_WARN, + "encode-lavc: could not set option %s\n", *p); + } + } + + if (ctx->options->vcodec) { + char *tok; + const char *in = ctx->options->vcodec; + while (*in) { + tok = av_get_token(&in, ","); + ctx->vc = avcodec_find_encoder_by_name(tok); + av_free(tok); + if (ctx->vc && ctx->vc->type != AVMEDIA_TYPE_VIDEO) + ctx->vc = NULL; + if (ctx->vc) + break; + if (*in) + ++in; + } + } else + ctx->vc = avcodec_find_encoder(av_guess_codec(ctx->avc->oformat, NULL, + ctx->avc->filename, NULL, + AVMEDIA_TYPE_VIDEO)); + + if (ctx->options->acodec) { + char *tok; + const char *in = ctx->options->acodec; + while (*in) { + tok = av_get_token(&in, ","); + ctx->ac = avcodec_find_encoder_by_name(tok); + av_free(tok); + if (ctx->ac && ctx->ac->type != AVMEDIA_TYPE_AUDIO) + ctx->ac = NULL; + if (ctx->ac) + break; + if (*in) + ++in; + } + } else + ctx->ac = avcodec_find_encoder(av_guess_codec(ctx->avc->oformat, NULL, + ctx->avc->filename, NULL, + AVMEDIA_TYPE_AUDIO)); + + if (!ctx->vc && !ctx->ac) { + encode_lavc_fail( + ctx, "encode-lavc: neither audio nor video codec was found\n"); + return NULL; + } + + /* taken from ffmpeg unchanged + * TODO turn this into an option if anyone needs this */ + + ctx->avc->max_delay = 0.7 * AV_TIME_BASE; + + ctx->abytes = 0; + ctx->vbytes = 0; + ctx->frames = 0; + + if (options->video_first) + ctx->video_first = true; + if (options->audio_first) + ctx->audio_first = true; + + return ctx; +} + +int encode_lavc_start(struct encode_lavc_context *ctx) +{ + AVDictionaryEntry *de; + unsigned i; + + if (ctx->header_written < 0) + return 0; + if (ctx->header_written > 0) + return 1; + + CHECK_FAIL(ctx, 0); + + if (ctx->expect_video) { + for (i = 0; i < ctx->avc->nb_streams; ++i) + if (ctx->avc->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) + break; + if (i >= ctx->avc->nb_streams) { + encode_lavc_fail(ctx, + "encode-lavc: video stream missing, invalid codec?\n"); + return 0; + } + } + if (ctx->expect_audio) { + for (i = 0; i < ctx->avc->nb_streams; ++i) + if (ctx->avc->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) + break; + if (i >= ctx->avc->nb_streams) { + encode_lavc_fail(ctx, + "encode-lavc: audio stream missing, invalid codec?\n"); + return 0; + } + } + + ctx->header_written = -1; + + if (!(ctx->avc->oformat->flags & AVFMT_NOFILE)) { + mp_msg(MSGT_ENCODE, MSGL_INFO, "Opening output file: %s\n", + ctx->avc->filename); + + if (avio_open(&ctx->avc->pb, ctx->avc->filename, + AVIO_FLAG_WRITE) < 0) { + encode_lavc_fail(ctx, "encode-lavc: could not open '%s'\n", + ctx->avc->filename); + return 0; + } + } + + ctx->t0 = mp_time_sec(); + + mp_msg(MSGT_ENCODE, MSGL_INFO, "Opening muxer: %s [%s]\n", + ctx->avc->oformat->long_name, ctx->avc->oformat->name); + + if (avformat_write_header(ctx->avc, &ctx->foptions) < 0) { + encode_lavc_fail(ctx, "encode-lavc: could not write header\n"); + return 0; + } + + for (de = NULL; (de = av_dict_get(ctx->foptions, "", de, + AV_DICT_IGNORE_SUFFIX));) + mp_msg(MSGT_ENCODE, MSGL_WARN, "ofopts: key '%s' not found.\n", de->key); + av_dict_free(&ctx->foptions); + + ctx->header_written = 1; + return 1; +} + +void encode_lavc_free(struct encode_lavc_context *ctx) +{ + if (!ctx) + return; + + if (!ctx->finished) + encode_lavc_fail(ctx, + "called encode_lavc_free without encode_lavc_finish\n"); + + talloc_free(ctx); +} + +void encode_lavc_finish(struct encode_lavc_context *ctx) +{ + unsigned i; + + if (!ctx) + return; + + if (ctx->finished) + return; + + if (ctx->avc) { + if (ctx->header_written > 0) + av_write_trailer(ctx->avc); // this is allowed to fail + + for (i = 0; i < ctx->avc->nb_streams; i++) { + switch (ctx->avc->streams[i]->codec->codec_type) { + case AVMEDIA_TYPE_VIDEO: + if (ctx->twopass_bytebuffer_v) { + char *stats = ctx->avc->streams[i]->codec->stats_out; + if (stats) + stream_write_buffer(ctx->twopass_bytebuffer_v, + stats, strlen(stats)); + } + break; + case AVMEDIA_TYPE_AUDIO: + if (ctx->twopass_bytebuffer_a) { + char *stats = ctx->avc->streams[i]->codec->stats_out; + if (stats) + stream_write_buffer(ctx->twopass_bytebuffer_a, + stats, strlen(stats)); + } + break; + default: + break; + } + avcodec_close(ctx->avc->streams[i]->codec); + talloc_free(ctx->avc->streams[i]->codec->stats_in); + av_free(ctx->avc->streams[i]->codec); + av_free(ctx->avc->streams[i]->info); + av_free(ctx->avc->streams[i]); + } + + if (ctx->twopass_bytebuffer_v) { + free_stream(ctx->twopass_bytebuffer_v); + ctx->twopass_bytebuffer_v = NULL; + } + + if (ctx->twopass_bytebuffer_a) { + free_stream(ctx->twopass_bytebuffer_a); + ctx->twopass_bytebuffer_a = NULL; + } + + mp_msg(MSGT_ENCODE, MSGL_INFO, "vo-lavc: encoded %lld bytes\n", + ctx->vbytes); + mp_msg(MSGT_ENCODE, MSGL_INFO, "ao-lavc: encoded %lld bytes\n", + ctx->abytes); + if (ctx->avc->pb) { + mp_msg(MSGT_ENCODE, MSGL_INFO, + "encode-lavc: muxing overhead %lld bytes\n", + (long long) (avio_size(ctx->avc->pb) - ctx->vbytes + - ctx->abytes)); + avio_close(ctx->avc->pb); + } + + av_free(ctx->avc); + } + + ctx->finished = true; +} + +void encode_lavc_set_video_fps(struct encode_lavc_context *ctx, float fps) +{ + ctx->vo_fps = fps; +} + +static void encode_2pass_prepare(struct encode_lavc_context *ctx, + AVDictionary **dictp, + AVStream *stream, struct stream **bytebuf, + const char *prefix) +{ + if (!*bytebuf) { + char buf[sizeof(ctx->avc->filename) + 12]; + AVDictionaryEntry *de = av_dict_get(ctx->voptions, "flags", NULL, 0); + + snprintf(buf, sizeof(buf), "%s-%s-pass1.log", ctx->avc->filename, + prefix); + buf[sizeof(buf) - 1] = 0; + + if (value_has_flag(de ? de->value : "", "pass2")) { + if (!(*bytebuf = stream_open(buf, NULL))) { + mp_msg(MSGT_ENCODE, MSGL_WARN, "%s: could not open '%s', " + "disabling 2-pass encoding at pass 2\n", prefix, buf); + stream->codec->flags &= ~CODEC_FLAG_PASS2; + set_to_avdictionary(dictp, "flags", "-pass2"); + } else { + struct bstr content = stream_read_complete(*bytebuf, NULL, + 1000000000); + if (content.start == NULL) { + mp_msg(MSGT_ENCODE, MSGL_WARN, "%s: could not read '%s', " + "disabling 2-pass encoding at pass 1\n", + prefix, ctx->avc->filename); + } else { + content.start[content.len] = 0; + stream->codec->stats_in = content.start; + } + free_stream(*bytebuf); + *bytebuf = NULL; + } + } + + if (value_has_flag(de ? de->value : "", "pass1")) { + if (!(*bytebuf = open_output_stream(buf, NULL))) { + mp_msg( + MSGT_ENCODE, MSGL_WARN, + "%s: could not open '%s', disabling " + "2-pass encoding at pass 1\n", + prefix, ctx->avc->filename); + set_to_avdictionary(dictp, "flags", "-pass1"); + } + } + } +} + +AVStream *encode_lavc_alloc_stream(struct encode_lavc_context *ctx, + enum AVMediaType mt) +{ + AVDictionaryEntry *de; + AVStream *stream = NULL; + char **p; + int i; + + CHECK_FAIL(ctx, NULL); + + if (ctx->header_written) + return NULL; + + for (i = 0; i < ctx->avc->nb_streams; ++i) + if (ctx->avc->streams[i]->codec->codec_type == mt) + // already have a stream of that type, this cannot really happen + return NULL; + + if (ctx->avc->nb_streams == 0) { + // if this stream isn't stream #0, allocate a dummy stream first for + // the next loop to use + if (mt == AVMEDIA_TYPE_VIDEO && ctx->audio_first) { + mp_msg(MSGT_ENCODE, MSGL_INFO, + "vo-lavc: preallocated audio stream for later use\n"); + avformat_new_stream(ctx->avc, NULL); // this one is AVMEDIA_TYPE_UNKNOWN for now + } + if (mt == AVMEDIA_TYPE_AUDIO && ctx->video_first) { + mp_msg(MSGT_ENCODE, MSGL_INFO, + "ao-lavc: preallocated video stream for later use\n"); + avformat_new_stream(ctx->avc, NULL); // this one is AVMEDIA_TYPE_UNKNOWN for now + } + } else { + // find possibly preallocated stream + for (i = 0; i < ctx->avc->nb_streams; ++i) + if (ctx->avc->streams[i]->codec->codec_type == AVMEDIA_TYPE_UNKNOWN) // preallocated stream + stream = ctx->avc->streams[i]; + } + if (!stream) + stream = avformat_new_stream(ctx->avc, NULL); + + if (ctx->timebase.den == 0) { + AVRational r; + + if (ctx->options->fps > 0) + r = av_d2q(ctx->options->fps, ctx->options->fps * 1001 + 2); + else if (ctx->options->autofps && ctx->vo_fps > 0) { + r = av_d2q(ctx->vo_fps, ctx->vo_fps * 1001 + 2); + mp_msg( + MSGT_ENCODE, MSGL_INFO, "vo-lavc: option --ofps not specified " + "but --oautofps is active, using guess of %u/%u\n", + (unsigned)r.num, (unsigned)r.den); + } else { + // we want to handle: + // 1/25 + // 1001/24000 + // 1001/30000 + // for this we would need 120000fps... + // however, mpeg-4 only allows 16bit values + // so let's take 1001/30000 out + r.num = 24000; + r.den = 1; + mp_msg( + MSGT_ENCODE, MSGL_INFO, "vo-lavc: option --ofps not specified " + "and fps could not be inferred, using guess of %u/%u\n", + (unsigned)r.num, (unsigned)r.den); + } + + if (ctx->vc && ctx->vc->supported_framerates) + r = ctx->vc->supported_framerates[av_find_nearest_q_idx(r, + ctx->vc->supported_framerates)]; + + ctx->timebase.num = r.den; + ctx->timebase.den = r.num; + } + + switch (mt) { + case AVMEDIA_TYPE_VIDEO: + if (!ctx->vc) { + encode_lavc_fail(ctx, "vo-lavc: encoder not found\n"); + return NULL; + } + avcodec_get_context_defaults3(stream->codec, ctx->vc); + + // stream->time_base = ctx->timebase; + // doing this breaks mpeg2ts in ffmpeg + // which doesn't properly force the time base to be 90000 + // furthermore, ffmpeg.c doesn't do this either and works + + stream->codec->time_base = ctx->timebase; + + ctx->voptions = NULL; + + if (ctx->options->vopts) + for (p = ctx->options->vopts; *p; ++p) + if (!set_to_avdictionary(&ctx->voptions, NULL, *p)) + mp_msg(MSGT_ENCODE, MSGL_WARN, + "vo-lavc: could not set option %s\n", *p); + + de = av_dict_get(ctx->voptions, "global_quality", NULL, 0); + if (de) + set_to_avdictionary(&ctx->voptions, "flags", "+qscale"); + + if (ctx->avc->oformat->flags & AVFMT_GLOBALHEADER) + set_to_avdictionary(&ctx->voptions, "flags", "+global_header"); + + encode_2pass_prepare(ctx, &ctx->voptions, stream, + &ctx->twopass_bytebuffer_v, + "vo-lavc"); + break; + + case AVMEDIA_TYPE_AUDIO: + if (!ctx->ac) { + encode_lavc_fail(ctx, "ao-lavc: encoder not found\n"); + return NULL; + } + avcodec_get_context_defaults3(stream->codec, ctx->ac); + + stream->codec->time_base = ctx->timebase; + + ctx->aoptions = NULL; + + if (ctx->options->aopts) + for (p = ctx->options->aopts; *p; ++p) + if (!set_to_avdictionary(&ctx->aoptions, NULL, *p)) + mp_msg(MSGT_ENCODE, MSGL_WARN, + "ao-lavc: could not set option %s\n", *p); + + de = av_dict_get(ctx->aoptions, "global_quality", NULL, 0); + if (de) + set_to_avdictionary(&ctx->aoptions, "flags", "+qscale"); + + if (ctx->avc->oformat->flags & AVFMT_GLOBALHEADER) + set_to_avdictionary(&ctx->aoptions, "flags", "+global_header"); + + encode_2pass_prepare(ctx, &ctx->aoptions, stream, + &ctx->twopass_bytebuffer_a, + "ao-lavc"); + break; + + default: + encode_lavc_fail(ctx, "encode-lavc: requested invalid stream type\n"); + return NULL; + } + + return stream; +} + +AVCodec *encode_lavc_get_codec(struct encode_lavc_context *ctx, + AVStream *stream) +{ + CHECK_FAIL(ctx, NULL); + + switch (stream->codec->codec_type) { + case AVMEDIA_TYPE_VIDEO: + return ctx->vc; + case AVMEDIA_TYPE_AUDIO: + return ctx->ac; + default: + break; + } + return NULL; +} + +int encode_lavc_open_codec(struct encode_lavc_context *ctx, AVStream *stream) +{ + AVDictionaryEntry *de; + int ret; + + CHECK_FAIL(ctx, -1); + + switch (stream->codec->codec_type) { + case AVMEDIA_TYPE_VIDEO: + mp_msg(MSGT_ENCODE, MSGL_INFO, "Opening video encoder: %s [%s]\n", + ctx->vc->long_name, ctx->vc->name); + + if (ctx->vc->capabilities & CODEC_CAP_EXPERIMENTAL) { + stream->codec->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; + mp_msg(MSGT_ENCODE, MSGL_WARN, _( + "\n\n" + " ********************************************\n" + " **** Experimental VIDEO codec selected! ****\n" + " ********************************************\n\n" + "This means the output file may be broken or bad.\n" + "Possible reasons, problems, workarounds:\n" + "- Codec implementation in ffmpeg/libav is not finished yet.\n" + " Try updating ffmpeg or libav.\n" + "- Bad picture quality, blocks, blurriness.\n" + " Experiment with codec settings (--ovcopts) to maybe still get the\n" + " desired quality output at the expense of bitrate.\n" + "- Slow compression.\n" + " Bear with it.\n" + "- Crashes.\n" + " Happens. Try varying options to work around.\n" + "If none of this helps you, try another codec in place of %s.\n\n"), + ctx->vc->name); + } + + ret = avcodec_open2(stream->codec, ctx->vc, &ctx->voptions); + + // complain about all remaining options, then free the dict + for (de = NULL; (de = av_dict_get(ctx->voptions, "", de, + AV_DICT_IGNORE_SUFFIX));) + mp_msg(MSGT_ENCODE, MSGL_WARN, "ovcopts: key '%s' not found.\n", + de->key); + av_dict_free(&ctx->voptions); + + break; + case AVMEDIA_TYPE_AUDIO: + mp_msg(MSGT_ENCODE, MSGL_INFO, "Opening audio encoder: %s [%s]\n", + ctx->ac->long_name, ctx->ac->name); + + if (ctx->ac->capabilities & CODEC_CAP_EXPERIMENTAL) { + stream->codec->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; + mp_msg(MSGT_ENCODE, MSGL_WARN, _( + "\n\n" + " ********************************************\n" + " **** Experimental AUDIO codec selected! ****\n" + " ********************************************\n\n" + "This means the output file may be broken or bad.\n" + "Possible reasons, problems, workarounds:\n" + "- Codec implementation in ffmpeg/libav is not finished yet.\n" + " Try updating ffmpeg or libav.\n" + "- Bad sound quality, noise, clicking, whistles, choppiness.\n" + " Experiment with codec settings (--oacopts) to maybe still get the\n" + " desired quality output at the expense of bitrate.\n" + "- Slow compression.\n" + " Bear with it.\n" + "- Crashes.\n" + " Happens. Try varying options to work around.\n" + "If none of this helps you, try another codec in place of %s.\n\n"), + ctx->ac->name); + } + ret = avcodec_open2(stream->codec, ctx->ac, &ctx->aoptions); + + // complain about all remaining options, then free the dict + for (de = NULL; (de = av_dict_get(ctx->aoptions, "", de, + AV_DICT_IGNORE_SUFFIX));) + mp_msg(MSGT_ENCODE, MSGL_WARN, "oacopts: key '%s' not found.\n", + de->key); + av_dict_free(&ctx->aoptions); + + break; + default: + ret = -1; + break; + } + + if (ret < 0) + encode_lavc_fail(ctx, + "unable to open encoder (see above for the cause)\n"); + + return ret; +} + +void encode_lavc_write_stats(struct encode_lavc_context *ctx, AVStream *stream) +{ + CHECK_FAIL(ctx, ); + + switch (stream->codec->codec_type) { + case AVMEDIA_TYPE_VIDEO: + if (ctx->twopass_bytebuffer_v) + if (stream->codec->stats_out) + stream_write_buffer(ctx->twopass_bytebuffer_v, + stream->codec->stats_out, + strlen(stream->codec->stats_out)); + break; + case AVMEDIA_TYPE_AUDIO: + if (ctx->twopass_bytebuffer_a) + if (stream->codec->stats_out) + stream_write_buffer(ctx->twopass_bytebuffer_a, + stream->codec->stats_out, + strlen(stream->codec->stats_out)); + break; + default: + break; + } +} + +int encode_lavc_write_frame(struct encode_lavc_context *ctx, AVPacket *packet) +{ + int r; + + CHECK_FAIL(ctx, -1); + + if (ctx->header_written <= 0) + return -1; + + mp_msg( + MSGT_ENCODE, MSGL_DBG2, + "encode-lavc: write frame: stream %d ptsi %d (%f) dtsi %d (%f) size %d\n", + (int)packet->stream_index, + (int)packet->pts, + packet->pts + * (double)ctx->avc->streams[packet->stream_index]->time_base.num + / (double)ctx->avc->streams[packet->stream_index]->time_base.den, + (int)packet->dts, + packet->dts + * (double)ctx->avc->streams[packet->stream_index]->time_base.num + / (double)ctx->avc->streams[packet->stream_index]->time_base.den, + (int)packet->size); + + switch (ctx->avc->streams[packet->stream_index]->codec->codec_type) { + case AVMEDIA_TYPE_VIDEO: + ctx->vbytes += packet->size; + ++ctx->frames; + break; + case AVMEDIA_TYPE_AUDIO: + ctx->abytes += packet->size; + ctx->audioseconds += packet->duration + * (double)ctx->avc->streams[packet->stream_index]->time_base.num + / (double)ctx->avc->streams[packet->stream_index]->time_base.den; + break; + default: + break; + } + + r = av_interleaved_write_frame(ctx->avc, packet); + + return r; +} + +int encode_lavc_supports_pixfmt(struct encode_lavc_context *ctx, + enum AVPixelFormat pix_fmt) +{ + CHECK_FAIL(ctx, 0); + + if (!ctx->vc) + return 0; + if (pix_fmt == AV_PIX_FMT_NONE) + return 0; + + if (!ctx->vc->pix_fmts) + return VFCAP_CSP_SUPPORTED; + else { + const enum AVPixelFormat *p; + for (p = ctx->vc->pix_fmts; *p >= 0; ++p) { + if (pix_fmt == *p) + return VFCAP_CSP_SUPPORTED; + } + } + return 0; +} + +void encode_lavc_discontinuity(struct encode_lavc_context *ctx) +{ + if (!ctx) + return; + + CHECK_FAIL(ctx, ); + + ctx->audio_pts_offset = MP_NOPTS_VALUE; + ctx->last_video_in_pts = MP_NOPTS_VALUE; + ctx->discontinuity_pts_offset = MP_NOPTS_VALUE; +} + +static void encode_lavc_printoptions(void *obj, const char *indent, + const char *subindent, const char *unit, + int filter_and, int filter_eq) +{ + const AVOption *opt = NULL; + char optbuf[32]; + while ((opt = av_opt_next(obj, opt))) { + // if flags are 0, it simply hasn't been filled in yet and may be + // potentially useful + if (opt->flags) + if ((opt->flags & filter_and) != filter_eq) + continue; + /* Don't print CONST's on level one. + * Don't print anything but CONST's on level two. + * Only print items from the requested unit. + */ + if (!unit && opt->type == AV_OPT_TYPE_CONST) + continue; + else if (unit && opt->type != AV_OPT_TYPE_CONST) + continue; + else if (unit && opt->type == AV_OPT_TYPE_CONST + && strcmp(unit, opt->unit)) + continue; + else if (unit && opt->type == AV_OPT_TYPE_CONST) + mp_msg(MSGT_ENCODE, MSGL_INFO, "%s", subindent); + else + mp_msg(MSGT_ENCODE, MSGL_INFO, "%s", indent); + + switch (opt->type) { + case AV_OPT_TYPE_FLAGS: + snprintf(optbuf, sizeof(optbuf), "%s=", opt->name); + break; + case AV_OPT_TYPE_INT: + snprintf(optbuf, sizeof(optbuf), "%s=", opt->name); + break; + case AV_OPT_TYPE_INT64: + snprintf(optbuf, sizeof(optbuf), "%s=", opt->name); + break; + case AV_OPT_TYPE_DOUBLE: + snprintf(optbuf, sizeof(optbuf), "%s=", opt->name); + break; + case AV_OPT_TYPE_FLOAT: + snprintf(optbuf, sizeof(optbuf), "%s=", opt->name); + break; + case AV_OPT_TYPE_STRING: + snprintf(optbuf, sizeof(optbuf), "%s=", opt->name); + break; + case AV_OPT_TYPE_RATIONAL: + snprintf(optbuf, sizeof(optbuf), "%s=", opt->name); + break; + case AV_OPT_TYPE_BINARY: + snprintf(optbuf, sizeof(optbuf), "%s=", opt->name); + break; + case AV_OPT_TYPE_CONST: + snprintf(optbuf, sizeof(optbuf), " [+-]%s", opt->name); + break; + default: + snprintf(optbuf, sizeof(optbuf), "%s", opt->name); + break; + } + optbuf[sizeof(optbuf) - 1] = 0; + mp_msg(MSGT_ENCODE, MSGL_INFO, "%-32s ", optbuf); + if (opt->help) + mp_msg(MSGT_ENCODE, MSGL_INFO, " %s", opt->help); + mp_msg(MSGT_ENCODE, MSGL_INFO, "\n"); + if (opt->unit && opt->type != AV_OPT_TYPE_CONST) + encode_lavc_printoptions(obj, indent, subindent, opt->unit, + filter_and, filter_eq); + } +} + +bool encode_lavc_showhelp(struct MPOpts *opts) +{ + bool help_output = false; + if (av_codec_next(NULL) == NULL) + mp_msg(MSGT_ENCODE, MSGL_ERR, "NO CODECS\n"); +#define CHECKS(str) ((str) && \ + strcmp((str), "help") == 0 ? (help_output |= 1) : 0) +#define CHECKV(strv) ((strv) && (strv)[0] && \ + strcmp((strv)[0], "help") == 0 ? (help_output |= 1) : 0) + if (CHECKS(opts->encode_output.format)) { + AVOutputFormat *c = NULL; + mp_msg(MSGT_ENCODE, MSGL_INFO, "Available output formats:\n"); + while ((c = av_oformat_next(c))) + mp_msg(MSGT_ENCODE, MSGL_INFO, " --of=%-13s %s\n", c->name, + c->long_name ? c->long_name : ""); + av_free(c); + } + if (CHECKV(opts->encode_output.fopts)) { + AVFormatContext *c = avformat_alloc_context(); + AVOutputFormat *format = NULL; + mp_msg(MSGT_ENCODE, MSGL_INFO, + "Available output format ctx->options:\n"); + encode_lavc_printoptions(c, " --ofopts=", " ", NULL, + AV_OPT_FLAG_ENCODING_PARAM, + AV_OPT_FLAG_ENCODING_PARAM); + av_free(c); + while ((format = av_oformat_next(format))) { + if (format->priv_class) { + mp_msg(MSGT_ENCODE, MSGL_INFO, "Additionally, for --of=%s:\n", + format->name); + encode_lavc_printoptions(&format->priv_class, " --ofopts=", + " ", NULL, + AV_OPT_FLAG_ENCODING_PARAM, + AV_OPT_FLAG_ENCODING_PARAM); + } + } + } + if (CHECKV(opts->encode_output.vopts)) { + AVCodecContext *c = avcodec_alloc_context3(NULL); + AVCodec *codec = NULL; + mp_msg(MSGT_ENCODE, MSGL_INFO, + "Available output video codec ctx->options:\n"); + encode_lavc_printoptions( + c, " --ovcopts=", " ", NULL, + AV_OPT_FLAG_ENCODING_PARAM | + AV_OPT_FLAG_VIDEO_PARAM, + AV_OPT_FLAG_ENCODING_PARAM | + AV_OPT_FLAG_VIDEO_PARAM); + av_free(c); + while ((codec = av_codec_next(codec))) { + if (!av_codec_is_encoder(codec)) + continue; + if (codec->type != AVMEDIA_TYPE_VIDEO) + continue; + if (opts->encode_output.vcodec && opts->encode_output.vcodec[0] && + strcmp(opts->encode_output.vcodec, codec->name) != 0) + continue; + if (codec->priv_class) { + mp_msg(MSGT_ENCODE, MSGL_INFO, "Additionally, for --ovc=%s:\n", + codec->name); + encode_lavc_printoptions( + &codec->priv_class, " --ovcopts=", + " ", NULL, + AV_OPT_FLAG_ENCODING_PARAM | + AV_OPT_FLAG_VIDEO_PARAM, + AV_OPT_FLAG_ENCODING_PARAM | + AV_OPT_FLAG_VIDEO_PARAM); + } + } + } + if (CHECKV(opts->encode_output.aopts)) { + AVCodecContext *c = avcodec_alloc_context3(NULL); + AVCodec *codec = NULL; + mp_msg(MSGT_ENCODE, MSGL_INFO, + "Available output audio codec ctx->options:\n"); + encode_lavc_printoptions( + c, " --oacopts=", " ", NULL, + AV_OPT_FLAG_ENCODING_PARAM | + AV_OPT_FLAG_AUDIO_PARAM, + AV_OPT_FLAG_ENCODING_PARAM | + AV_OPT_FLAG_AUDIO_PARAM); + av_free(c); + while ((codec = av_codec_next(codec))) { + if (!av_codec_is_encoder(codec)) + continue; + if (codec->type != AVMEDIA_TYPE_AUDIO) + continue; + if (opts->encode_output.acodec && opts->encode_output.acodec[0] && + strcmp(opts->encode_output.acodec, codec->name) != 0) + continue; + if (codec->priv_class) { + mp_msg(MSGT_ENCODE, MSGL_INFO, "Additionally, for --oac=%s:\n", + codec->name); + encode_lavc_printoptions( + &codec->priv_class, " --oacopts=", + " ", NULL, + AV_OPT_FLAG_ENCODING_PARAM | + AV_OPT_FLAG_AUDIO_PARAM, + AV_OPT_FLAG_ENCODING_PARAM | + AV_OPT_FLAG_AUDIO_PARAM); + } + } + } + if (CHECKS(opts->encode_output.vcodec)) { + AVCodec *c = NULL; + mp_msg(MSGT_ENCODE, MSGL_INFO, "Available output video codecs:\n"); + while ((c = av_codec_next(c))) { + if (!av_codec_is_encoder(c)) + continue; + if (c->type != AVMEDIA_TYPE_VIDEO) + continue; + mp_msg(MSGT_ENCODE, MSGL_INFO, " --ovc=%-12s %s\n", c->name, + c->long_name ? c->long_name : ""); + } + av_free(c); + } + if (CHECKS(opts->encode_output.acodec)) { + AVCodec *c = NULL; + mp_msg(MSGT_ENCODE, MSGL_INFO, "Available output audio codecs:\n"); + while ((c = av_codec_next(c))) { + if (!av_codec_is_encoder(c)) + continue; + if (c->type != AVMEDIA_TYPE_AUDIO) + continue; + mp_msg(MSGT_ENCODE, MSGL_INFO, " --oac=%-12s %s\n", c->name, + c->long_name ? c->long_name : ""); + } + av_free(c); + } + return help_output; +} + +double encode_lavc_getoffset(struct encode_lavc_context *ctx, AVStream *stream) +{ + CHECK_FAIL(ctx, 0); + + switch (stream->codec->codec_type) { + case AVMEDIA_TYPE_VIDEO: + return ctx->options->voffset; + case AVMEDIA_TYPE_AUDIO: + return ctx->options->aoffset; + default: + break; + } + return 0; +} + +int encode_lavc_getstatus(struct encode_lavc_context *ctx, + char *buf, int bufsize, + float relative_position) +{ + double now = mp_time_sec(); + float minutes, megabytes, fps, x; + float f = FFMAX(0.0001, relative_position); + if (!ctx) + return -1; + + CHECK_FAIL(ctx, -1); + + minutes = (now - ctx->t0) / 60.0 * (1 - f) / f; + megabytes = ctx->avc->pb ? (avio_size(ctx->avc->pb) / 1048576.0 / f) : 0; + fps = ctx->frames / (now - ctx->t0); + x = ctx->audioseconds / (now - ctx->t0); + if (ctx->frames) + snprintf(buf, bufsize, "{%.1fmin %.1ffps %.1fMB}", + minutes, fps, megabytes); + else if (ctx->audioseconds) + snprintf(buf, bufsize, "{%.1fmin %.2fx %.1fMB}", + minutes, x, megabytes); + else + snprintf(buf, bufsize, "{%.1fmin %.1fMB}", + minutes, megabytes); + buf[bufsize - 1] = 0; + return 0; +} + +void encode_lavc_expect_stream(struct encode_lavc_context *ctx, int mt) +{ + CHECK_FAIL(ctx, ); + + switch (mt) { + case AVMEDIA_TYPE_VIDEO: + ctx->expect_video = true; + break; + case AVMEDIA_TYPE_AUDIO: + ctx->expect_audio = true; + break; + } +} + +bool encode_lavc_didfail(struct encode_lavc_context *ctx) +{ + return ctx && ctx->failed; +} + +void encode_lavc_fail(struct encode_lavc_context *ctx, const char *format, ...) +{ + va_list va; + va_start(va, format); + mp_msg_va(MSGT_ENCODE, MSGL_ERR, format, va); + if (ctx->failed) + return; + ctx->failed = true; + encode_lavc_finish(ctx); +} + +bool encode_lavc_set_csp(struct encode_lavc_context *ctx, + AVStream *stream, enum mp_csp csp) +{ + CHECK_FAIL(ctx, NULL); + + if (ctx->header_written) { + if (stream->codec->colorspace != mp_csp_to_avcol_spc(csp)) + mp_msg(MSGT_ENCODE, MSGL_WARN, + "encode-lavc: can not change color space during encoding\n"); + return false; + } + + stream->codec->colorspace = mp_csp_to_avcol_spc(csp); + return true; +} + +bool encode_lavc_set_csp_levels(struct encode_lavc_context *ctx, + AVStream *stream, enum mp_csp_levels lev) +{ + CHECK_FAIL(ctx, NULL); + + if (ctx->header_written) { + if (stream->codec->color_range != mp_csp_levels_to_avcol_range(lev)) + mp_msg(MSGT_ENCODE, MSGL_WARN, + "encode-lavc: can not change color space during encoding\n"); + return false; + } + + stream->codec->color_range = mp_csp_levels_to_avcol_range(lev); + return true; +} + +enum mp_csp encode_lavc_get_csp(struct encode_lavc_context *ctx, + AVStream *stream) +{ + CHECK_FAIL(ctx, 0); + + return avcol_spc_to_mp_csp(stream->codec->colorspace); +} + +enum mp_csp_levels encode_lavc_get_csp_levels(struct encode_lavc_context *ctx, + AVStream *stream) +{ + CHECK_FAIL(ctx, 0); + + return avcol_range_to_mp_csp_levels(stream->codec->color_range); +} + +// vim: ts=4 sw=4 et diff --git a/common/encode_lavc.h b/common/encode_lavc.h new file mode 100644 index 0000000000..15e0a5c7f2 --- /dev/null +++ b/common/encode_lavc.h @@ -0,0 +1,101 @@ +/* + * muxing using libavformat + * Copyright (C) 2011 Rudolf Polzer + * + * This file is part of mpv. + * + * MPlayer 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. + * + * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPLAYER_ENCODE_LAVC_H +#define MPLAYER_ENCODE_LAVC_H + +#include +#include +#include +#include +#include +#include + +#include "encode.h" +#include "video/csputils.h" + +struct encode_lavc_context { + struct encode_output_conf *options; + + float vo_fps; + + // these are processed from the options + AVFormatContext *avc; + AVRational timebase; + AVCodec *vc; + AVCodec *ac; + AVDictionary *foptions; + AVDictionary *aoptions; + AVDictionary *voptions; + + // values created during encoding + int header_written; // -1 means currently writing + + // sync to audio mode + double audio_pts_offset; + double last_video_in_pts; + + // anti discontinuity mode + double next_in_pts; + double discontinuity_pts_offset; + + long long abytes; + long long vbytes; + struct stream *twopass_bytebuffer_a; + struct stream *twopass_bytebuffer_v; + double t0; + unsigned int frames; + double audioseconds; + + bool expect_video; + bool expect_audio; + bool video_first; + bool audio_first; + + // has encoding failed? + bool failed; + bool finished; +}; + +// interface for vo/ao drivers +AVStream *encode_lavc_alloc_stream(struct encode_lavc_context *ctx, enum AVMediaType mt); +void encode_lavc_write_stats(struct encode_lavc_context *ctx, AVStream *stream); +int encode_lavc_write_frame(struct encode_lavc_context *ctx, AVPacket *packet); +int encode_lavc_supports_pixfmt(struct encode_lavc_context *ctx, enum AVPixelFormat format); +AVCodec *encode_lavc_get_codec(struct encode_lavc_context *ctx, AVStream *stream); +int encode_lavc_open_codec(struct encode_lavc_context *ctx, AVStream *stream); +int encode_lavc_available(struct encode_lavc_context *ctx); +int encode_lavc_timesyncfailed(struct encode_lavc_context *ctx); +int encode_lavc_start(struct encode_lavc_context *ctx); // returns 1 on success +int encode_lavc_oformat_flags(struct encode_lavc_context *ctx); +double encode_lavc_getoffset(struct encode_lavc_context *ctx, AVStream *stream); +void encode_lavc_fail(struct encode_lavc_context *ctx, const char *format, ...); // report failure of encoding + +bool encode_lavc_set_csp(struct encode_lavc_context *ctx, + AVStream *stream, enum mp_csp csp); +bool encode_lavc_set_csp_levels(struct encode_lavc_context *ctx, + AVStream *stream, enum mp_csp_levels lev); +enum mp_csp encode_lavc_get_csp(struct encode_lavc_context *ctx, + AVStream *stream); +enum mp_csp_levels encode_lavc_get_csp_levels(struct encode_lavc_context *ctx, + AVStream *stream); + +#endif diff --git a/common/global.h b/common/global.h new file mode 100644 index 0000000000..546c585294 --- /dev/null +++ b/common/global.h @@ -0,0 +1,12 @@ +#ifndef MPV_MPV_H +#define MPV_MPV_H + +// This should be accessed by glue code only, never normal code. +// The only purpose of this is to make mpv library-safe. +// Think hard before adding new members. +struct mpv_global { + struct MPOpts *opts; + struct mp_log *log; +}; + +#endif diff --git a/common/msg.c b/common/msg.c new file mode 100644 index 0000000000..dd03be0f73 --- /dev/null +++ b/common/msg.c @@ -0,0 +1,389 @@ +/* + * This file is part of MPlayer. + * + * MPlayer 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. + * + * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include +#include + +#include "talloc.h" + +#include "config.h" +#include "common/global.h" +#include "osdep/getch2.h" +#include "osdep/io.h" + +#ifndef __MINGW32__ +#include +#endif + +#include "common/msg.h" + +bool mp_msg_stdout_in_use = 0; + +struct mp_log_root { + /* This should, at some point, contain all mp_msg related state, instead + * of having global variables (at least as long as we don't want to + * control the terminal, which is global anyway). But for now, there is + * not much. */ + struct mpv_global *global; +}; + +struct mp_log { + struct mp_log_root *root; + const char *prefix; + const char *verbose_prefix; + int legacy_mod; +}; + +// should not exist +static bool initialized; +static struct mp_log *legacy_logs[MSGT_MAX]; + +/* maximum message length of mp_msg */ +#define MSGSIZE_MAX 6144 + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#include +#define hSTDOUT GetStdHandle(STD_OUTPUT_HANDLE) +#define hSTDERR GetStdHandle(STD_ERROR_HANDLE) +static short stdoutAttrs = 0; +static const unsigned char ansi2win32[10] = { + 0, + FOREGROUND_RED, + FOREGROUND_GREEN, + FOREGROUND_GREEN | FOREGROUND_RED, + FOREGROUND_BLUE, + FOREGROUND_BLUE | FOREGROUND_RED, + FOREGROUND_BLUE | FOREGROUND_GREEN, + FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED, + FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED, + FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED +}; +#endif + +int mp_msg_levels[MSGT_MAX]; // verbose level of this module. initialized to -2 +int mp_msg_level_all = MSGL_STATUS; +int verbose = 0; +int mp_msg_color = 1; +int mp_msg_module = 0; +int mp_msg_cancolor = 0; + +static int mp_msg_docolor(void) { + return mp_msg_cancolor && mp_msg_color; +} + +static void mp_msg_do_init(void){ +#ifdef _WIN32 + CONSOLE_SCREEN_BUFFER_INFO cinfo; + DWORD cmode = 0; + GetConsoleMode(hSTDOUT, &cmode); + cmode |= (ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT); + SetConsoleMode(hSTDOUT, cmode); + SetConsoleMode(hSTDERR, cmode); + GetConsoleScreenBufferInfo(hSTDOUT, &cinfo); + stdoutAttrs = cinfo.wAttributes; +#endif +#ifndef __MINGW32__ + struct sigaction sa; + sa.sa_handler = SIG_IGN; + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); + sigaction(SIGTTOU, &sa, NULL); // just write to stdout if you have to +#endif + int i; + char *env = getenv("MPV_VERBOSE"); + if (env) + verbose = atoi(env); + for(i=0;ilegacy_mod, lev); +} + +static void set_msg_color(FILE* stream, int lev) +{ + static const int v_colors[10] = {9, 1, 3, 3, -1, -1, 2, 8, 8, 8}; + int c = v_colors[lev]; +#ifdef MP_ANNOY_ME + /* that's only a silly color test */ + { + int c; + static int flag = 1; + if (flag) + for(c = 0; c < 24; c++) + printf("\033[%d;3%dm*** COLOR TEST %d ***\n", c>7, c&7, c); + flag = 0; + } +#endif + if (mp_msg_docolor()) + { +#if defined(_WIN32) && !defined(__CYGWIN__) + HANDLE *wstream = stream == stderr ? hSTDERR : hSTDOUT; + if (c == -1) + c = 7; + SetConsoleTextAttribute(wstream, ansi2win32[c] | FOREGROUND_INTENSITY); +#else + if (c == -1) { + fprintf(stream, "\033[0m"); + } else { + fprintf(stream, "\033[%d;3%dm", c >> 3, c & 7); + } +#endif + } +} + +static void print_msg_module(FILE* stream, struct mp_log *log) +{ + int mod = log->legacy_mod; + int c2 = (mod + 1) % 15 + 1; + +#ifdef _WIN32 + HANDLE *wstream = stream == stderr ? hSTDERR : hSTDOUT; + if (mp_msg_docolor()) + SetConsoleTextAttribute(wstream, ansi2win32[c2&7] | FOREGROUND_INTENSITY); + fprintf(stream, "%9s", log->verbose_prefix); + if (mp_msg_docolor()) + SetConsoleTextAttribute(wstream, stdoutAttrs); +#else + if (mp_msg_docolor()) + fprintf(stream, "\033[%d;3%dm", c2 >> 3, c2 & 7); + fprintf(stream, "%9s", log->verbose_prefix); + if (mp_msg_docolor()) + fprintf(stream, "\033[0;37m"); +#endif + fprintf(stream, ": "); +} + +static void mp_msg_log_va(struct mp_log *log, int lev, const char *format, + va_list va) +{ + char tmp[MSGSIZE_MAX]; + FILE *stream = + (mp_msg_stdout_in_use || (lev == MSGL_STATUS)) ? stderr : stdout; + static int header = 1; + // indicates if last line printed was a status line + static int statusline; + + if (!mp_msg_test_log(log, lev)) return; // do not display + vsnprintf(tmp, MSGSIZE_MAX, format, va); + tmp[MSGSIZE_MAX-2] = '\n'; + tmp[MSGSIZE_MAX-1] = 0; + + /* A status line is normally intended to be overwritten by the next + * status line, and does not end with a '\n'. If we're printing a normal + * line instead after the status one print '\n' to change line. */ + if (statusline && lev != MSGL_STATUS) + fprintf(stderr, "\n"); + statusline = lev == MSGL_STATUS; + + set_msg_color(stream, lev); + if (header) { + if (mp_msg_module) { + print_msg_module(stream, log); + set_msg_color(stream, lev); + } else if (lev >= MSGL_V || verbose) { + fprintf(stream, "[%s] ", log->verbose_prefix); + } else if (log->prefix) { + fprintf(stream, "[%s] ", log->prefix); + } + } + + size_t len = strlen(tmp); + header = len && (tmp[len-1] == '\n' || tmp[len-1] == '\r'); + + fprintf(stream, "%s", tmp); + + if (mp_msg_docolor()) + { +#ifdef _WIN32 + HANDLE *wstream = lev <= MSGL_WARN ? hSTDERR : hSTDOUT; + SetConsoleTextAttribute(wstream, stdoutAttrs); +#else + fprintf(stream, "\033[0m"); +#endif + } + fflush(stream); +} + +void mp_msg_va(int mod, int lev, const char *format, va_list va) +{ + assert(initialized); + assert(mod >= 0 && mod < MSGT_MAX); + mp_msg_log_va(legacy_logs[mod], lev, format, va); +} + +void mp_msg(int mod, int lev, const char *format, ...) +{ + va_list va; + va_start(va, format); + mp_msg_va(mod, lev, format, va); + va_end(va); +} + +// legacy names +static const char *module_text[MSGT_MAX] = { + "global", + "cplayer", + "gplayer", + "vo", + "ao", + "demuxer", + "ds", + "demux", + "header", + "avsync", + "autoq", + "cfgparser", + "decaudio", + "decvideo", + "seek", + "win32", + "open", + "dvd", + "parsees", + "lirc", + "stream", + "cache", + "mencoder", + "xacodec", + "tv", + "osdep", + "spudec", + "playtree", + "input", + "vf", + "osd", + "network", + "cpudetect", + "codeccfg", + "sws", + "vobsub", + "subreader", + "af", + "netst", + "muxer", + "osdmenu", + "identify", + "radio", + "ass", + "loader", + "statusline", + "teletext", +}; + +// Create a new log context, which uses talloc_ctx as talloc parent, and parent +// as logical parent. +// The name is the prefix put before the output. It's usually prefixed by the +// parent's name. If the name starts with "/", the parent's name is not +// prefixed (except in verbose mode), and if it starts with "!", the name is +// not printed at all (except in verbose mode). +struct mp_log *mp_log_new(void *talloc_ctx, struct mp_log *parent, + const char *name) +{ + assert(parent); + assert(name); + struct mp_log *log = talloc_zero(talloc_ctx, struct mp_log); + log->root = parent->root; + if (name[0] == '!') { + name = &name[1]; + } else if (name[0] == '/') { + name = &name[1]; + log->prefix = talloc_strdup(log, name); + } else { + log->prefix = parent->prefix + ? talloc_asprintf(log, "%s/%s", parent->prefix, name) + : talloc_strdup(log, name); + } + log->verbose_prefix = parent->prefix + ? talloc_asprintf(log, "%s/%s", parent->prefix, name) + : talloc_strdup(log, name); + if (log->prefix && !log->prefix[0]) + log->prefix = NULL; + if (!log->verbose_prefix[0]) + log->verbose_prefix = "global"; + log->legacy_mod = parent->legacy_mod; + for (int n = 0; n < MSGT_MAX; n++) { + if (module_text[n] && strcmp(name, module_text[n]) == 0) { + log->legacy_mod = n; + break; + } + } + return log; +} + +void mp_msg_init(struct mpv_global *global) +{ + assert(!initialized); + assert(!global->log); + + struct mp_log_root *root = talloc_zero(NULL, struct mp_log_root); + root->global = global; + + struct mp_log dummy = { .root = root }; + struct mp_log *log = mp_log_new(root, &dummy, ""); + for (int n = 0; n < MSGT_MAX; n++) { + char name[80]; + snprintf(name, sizeof(name), "!%s", module_text[n]); + legacy_logs[n] = mp_log_new(root, log, name); + } + mp_msg_do_init(); + + global->log = log; + initialized = true; +} + +struct mpv_global *mp_log_get_global(struct mp_log *log) +{ + return log->root->global; +} + +void mp_msg_uninit(struct mpv_global *global) +{ + talloc_free(global->log->root); + global->log = NULL; + initialized = false; +} + +void mp_msg_log(struct mp_log *log, int lev, const char *format, ...) +{ + va_list va; + va_start(va, format); + mp_msg_log_va(log, lev, format, va); + va_end(va); +} diff --git a/common/msg.h b/common/msg.h new file mode 100644 index 0000000000..889d99ae62 --- /dev/null +++ b/common/msg.h @@ -0,0 +1,180 @@ +/* + * This file is part of MPlayer. + * + * MPlayer 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. + * + * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPLAYER_MP_MSG_H +#define MPLAYER_MP_MSG_H + +#include +#include + +struct mp_log; + +// defined in mplayer.c +extern int verbose; + +/* No-op macro to mark translated strings in the sources */ +#define _(x) x + +// verbosity elevel: + +/* Only messages level MSGL_FATAL-MSGL_STATUS should be translated, + * messages level MSGL_V and above should not be translated. */ + +#define MSGL_FATAL 0 // will exit/abort +#define MSGL_ERR 1 // continues +#define MSGL_WARN 2 // only warning +#define MSGL_HINT 3 // short help message +#define MSGL_INFO 4 // -quiet +#define MSGL_STATUS 5 // v=0 +#define MSGL_V 6 // v=1 +#define MSGL_DBG2 7 // v=2 +#define MSGL_DBG3 8 // v=3 +#define MSGL_DBG4 9 // v=4 +#define MSGL_DBG5 10 // v=5 + +#define MSGL_FIXME 1 // for conversions from printf where the appropriate MSGL is not known; set equal to ERR for obtrusiveness +#define MSGT_FIXME 0 // for conversions from printf where the appropriate MSGT is not known; set equal to GLOBAL for obtrusiveness + +// code/module: + +#define MSGT_GLOBAL 0 // common player stuff errors +#define MSGT_CPLAYER 1 // console player (mplayer.c) + +#define MSGT_VO 3 // libvo +#define MSGT_AO 4 // libao + +#define MSGT_DEMUXER 5 // demuxer.c (general stuff) +#define MSGT_DS 6 // demux stream (add/read packet etc) +#define MSGT_DEMUX 7 // fileformat-specific stuff (demux_*.c) +#define MSGT_HEADER 8 // fileformat-specific header (*header.c) + +#define MSGT_AVSYNC 9 // mplayer.c timer stuff +#define MSGT_AUTOQ 10 // mplayer.c auto-quality stuff + +#define MSGT_CFGPARSER 11 // cfgparser.c + +#define MSGT_DECAUDIO 12 // av decoder +#define MSGT_DECVIDEO 13 + +#define MSGT_SEEK 14 // seeking code +#define MSGT_WIN32 15 // win32 dll stuff +#define MSGT_OPEN 16 // open.c (stream opening) +#define MSGT_DVD 17 // open.c (DVD init/read/seek) + +#define MSGT_PARSEES 18 // parse_es.c (mpeg stream parser) +#define MSGT_LIRC 19 // lirc_mp.c and input lirc driver + +#define MSGT_STREAM 20 // stream.c +#define MSGT_CACHE 21 // cache2.c + +#define MSGT_ENCODE 22 // now encode_lavc.c + +#define MSGT_XACODEC 23 // XAnim codecs + +#define MSGT_TV 24 // TV input subsystem + +#define MSGT_OSDEP 25 // OS-dependent parts + +#define MSGT_SPUDEC 26 // spudec.c + +#define MSGT_PLAYTREE 27 // Playtree handeling (playtree.c, playtreeparser.c) + +#define MSGT_INPUT 28 + +#define MSGT_VFILTER 29 + +#define MSGT_OSD 30 + +#define MSGT_NETWORK 31 + +#define MSGT_CPUDETECT 32 + +#define MSGT_CODECCFG 33 + +#define MSGT_SWS 34 + +#define MSGT_VOBSUB 35 +#define MSGT_SUBREADER 36 + +#define MSGT_AFILTER 37 // Audio filter messages + +#define MSGT_NETST 38 // Netstream + +#define MSGT_MUXER 39 // muxer layer + +#define MSGT_IDENTIFY 41 // -identify output + +#define MSGT_RADIO 42 + +#define MSGT_ASS 43 // libass messages + +#define MSGT_LOADER 44 // dll loader messages + +#define MSGT_STATUSLINE 45 // playback/encoding status line + +#define MSGT_TELETEXT 46 // Teletext decoder + +#define MSGT_MAX 47 + +int mp_msg_test(int mod, int lev); +bool mp_msg_test_log(struct mp_log *log, int lev); + +#include "config.h" +#include "common/common.h" + +// Note: using mp_msg_log or the MP_ERR/... macros is preferred. +void mp_msg_va(int mod, int lev, const char *format, va_list va); +void mp_msg(int mod, int lev, const char *format, ... ) PRINTF_ATTRIBUTE(3, 4); + +struct mp_log *mp_log_new(void *talloc_ctx, struct mp_log *parent, + const char *name); + +void mp_msg_log(struct mp_log *log, int lev, const char *format, ...) + PRINTF_ATTRIBUTE(3, 4); + +// Convenience macros, typically called with a pointer to a context struct +// as first argument, which has a "struct mp_log log;" member. + +#define MP_MSG(obj, lev, ...) mp_msg_log((obj)->log, lev, __VA_ARGS__) +#define MP_MSGT(obj, lev, ...) mp_msgt_log((obj)->log, lev, __VA_ARGS__) + +#define MP_FATAL(obj, ...) MP_MSG(obj, MSGL_FATAL, __VA_ARGS__) +#define MP_ERR(obj, ...) MP_MSG(obj, MSGL_ERR, __VA_ARGS__) +#define MP_WARN(obj, ...) MP_MSG(obj, MSGL_WARN, __VA_ARGS__) +#define MP_INFO(obj, ...) MP_MSG(obj, MSGL_INFO, __VA_ARGS__) +#define MP_VERBOSE(obj, ...) MP_MSG(obj, MSGL_V, __VA_ARGS__) +#define MP_DBG(obj, ...) MP_MSG(obj, MSGL_DBG2, __VA_ARGS__) +#define MP_TRACE(obj, ...) MP_MSG(obj, MSGL_DBG5, __VA_ARGS__) + +#define mp_fatal(log, ...) mp_msg_log(log, MSGL_FATAL, __VA_ARGS__) +#define mp_err(log, ...) mp_msg_log(log, MSGL_ERR, __VA_ARGS__) +#define mp_warn(log, ...) mp_msg_log(log, MSGL_WARN, __VA_ARGS__) +#define mp_info(log, ...) mp_msg_log(log, MSGL_INFO, __VA_ARGS__) +#define mp_verbose(log, ...) mp_msg_log(log, MSGL_V, __VA_ARGS__) +#define mp_dbg(log, ...) mp_msg_log(log, MSGL_DBG2, __VA_ARGS__) +#define mp_trace(log, ...) mp_msg_log(log, MSGL_DBG5, __VA_ARGS__) + +struct mpv_global; +void mp_msg_init(struct mpv_global *global); +void mp_msg_uninit(struct mpv_global *global); + +struct mpv_global *mp_log_get_global(struct mp_log *log); + +extern bool mp_msg_stdout_in_use; + +#endif /* MPLAYER_MP_MSG_H */ diff --git a/common/playlist.c b/common/playlist.c new file mode 100644 index 0000000000..297cb4d379 --- /dev/null +++ b/common/playlist.c @@ -0,0 +1,241 @@ +/* + * This file is part of mplayer. + * + * mplayer 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. + * + * mplayer 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 mplayer. If not, see . + */ + +#include +#include "config.h" +#include "playlist.h" +#include "common/common.h" +#include "talloc.h" +#include "options/path.h" + +struct playlist_entry *playlist_entry_new(const char *filename) +{ + struct playlist_entry *e = talloc_zero(NULL, struct playlist_entry); + e->filename = talloc_strdup(e, filename); + return e; +} + +void playlist_entry_add_param(struct playlist_entry *e, bstr name, bstr value) +{ + struct playlist_param p = {bstrdup(e, name), bstrdup(e, value)}; + MP_TARRAY_APPEND(e, e->params, e->num_params, p); +} + +void playlist_entry_add_params(struct playlist_entry *e, + struct playlist_param *params, + int num_params) +{ + for (int n = 0; n < num_params; n++) + playlist_entry_add_param(e, params[n].name, params[n].value); +} + +// Add entry "add" after entry "after". +// If "after" is NULL, add as first entry. +// Post condition: add->prev == after +void playlist_insert(struct playlist *pl, struct playlist_entry *after, + struct playlist_entry *add) +{ + assert(pl && add->pl == NULL && add->next == NULL && add->prev == NULL); + if (after) { + assert(after->pl == pl); + assert(pl->first && pl->last); + } + add->prev = after; + if (after) { + add->next = after->next; + after->next = add; + } else { + add->next = pl->first; + pl->first = add; + } + if (add->next) { + add->next->prev = add; + } else { + pl->last = add; + } + add->pl = pl; + talloc_steal(pl, add); +} + +void playlist_add(struct playlist *pl, struct playlist_entry *add) +{ + playlist_insert(pl, pl->last, add); +} + +static void playlist_unlink(struct playlist *pl, struct playlist_entry *entry) +{ + assert(pl && entry->pl == pl); + + if (pl->current == entry) { + pl->current = entry->next; + pl->current_was_replaced = true; + } + + if (entry->next) { + entry->next->prev = entry->prev; + } else { + pl->last = entry->prev; + } + if (entry->prev) { + entry->prev->next = entry->next; + } else { + pl->first = entry->next; + } + entry->next = entry->prev = NULL; + // xxx: we'd want to reset the talloc parent of entry + entry->pl = NULL; +} + +void playlist_remove(struct playlist *pl, struct playlist_entry *entry) +{ + playlist_unlink(pl, entry); + talloc_free(entry); +} + +void playlist_clear(struct playlist *pl) +{ + while (pl->first) + playlist_remove(pl, pl->first); + assert(!pl->current); + pl->current_was_replaced = false; +} + +// Moves entry such that entry->prev = at (even if at is NULL) +void playlist_move(struct playlist *pl, struct playlist_entry *entry, + struct playlist_entry *at) +{ + struct playlist_entry *save_current = pl->current; + bool save_replaced = pl->current_was_replaced; + + playlist_unlink(pl, entry); + playlist_insert(pl, at ? at->prev : pl->last, entry); + + pl->current = save_current; + pl->current_was_replaced = save_replaced; +} + +void playlist_add_file(struct playlist *pl, const char *filename) +{ + playlist_add(pl, playlist_entry_new(filename)); +} + +static int playlist_count(struct playlist *pl) +{ + int c = 0; + for (struct playlist_entry *e = pl->first; e; e = e->next) + c++; + return c; +} + +void playlist_shuffle(struct playlist *pl) +{ + struct playlist_entry *save_current = pl->current; + bool save_replaced = pl->current_was_replaced; + int count = playlist_count(pl); + struct playlist_entry **arr = talloc_array(NULL, struct playlist_entry *, + count); + for (int n = 0; n < count; n++) { + arr[n] = pl->first; + playlist_unlink(pl, pl->first); + } + for (int n = 0; n < count; n++) { + int other = (int)((double)(count) * rand() / (RAND_MAX + 1.0)); + struct playlist_entry *tmp = arr[n]; + arr[n] = arr[other]; + arr[other] = tmp; + } + for (int n = 0; n < count; n++) + playlist_add(pl, arr[n]); + talloc_free(arr); + pl->current = save_current; + pl->current_was_replaced = save_replaced; +} + +struct playlist_entry *playlist_get_next(struct playlist *pl, int direction) +{ + assert(direction == -1 || direction == +1); + if (!pl->current) + return NULL; + assert(pl->current->pl == pl); + if (direction < 0) + return pl->current->prev; + return pl->current_was_replaced ? pl->current : pl->current->next; +} + +void playlist_add_base_path(struct playlist *pl, bstr base_path) +{ + if (base_path.len == 0 || bstrcmp0(base_path, ".") == 0) + return; + for (struct playlist_entry *e = pl->first; e; e = e->next) { + if (!mp_is_url(bstr0(e->filename))) { + char *new_file = mp_path_join(e, base_path, bstr0(e->filename)); + talloc_free(e->filename); + e->filename = new_file; + } + } +} + +// Move all entries from source_pl to pl, appending them after the current entry +// of pl. source_pl will be empty, and all entries have changed ownership to pl. +void playlist_transfer_entries(struct playlist *pl, struct playlist *source_pl) +{ + struct playlist_entry *add_after = pl->current; + if (pl->current && pl->current_was_replaced) + add_after = pl->current->next; + if (!add_after) + add_after = pl->last; + + while (source_pl->first) { + struct playlist_entry *e = source_pl->first; + playlist_unlink(source_pl, e); + playlist_insert(pl, add_after, e); + add_after = e; + } +} + +// Return number of entries between list start and e. +// Return -1 if e is not on the list, or if e is NULL. +int playlist_entry_to_index(struct playlist *pl, struct playlist_entry *e) +{ + struct playlist_entry *cur = pl->first; + int pos = 0; + if (!e) + return -1; + while (cur && cur != e) { + cur = cur->next; + pos++; + } + return cur == e ? pos : -1; +} + +int playlist_entry_count(struct playlist *pl) +{ + return playlist_entry_to_index(pl, pl->last) + 1; +} + +// Return entry for which playlist_entry_to_index() would return index. +// Return NULL if not found. +struct playlist_entry *playlist_entry_from_index(struct playlist *pl, int index) +{ + struct playlist_entry *e = pl->first; + for (int n = 0; ; n++) { + if (!e || n == index) + return e; + e = e->next; + } +} + diff --git a/common/playlist.h b/common/playlist.h new file mode 100644 index 0000000000..f383a85fea --- /dev/null +++ b/common/playlist.h @@ -0,0 +1,82 @@ +/* + * This file is part of mplayer. + * + * mplayer 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. + * + * mplayer 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 mplayer. If not, see . + */ + +#ifndef MPLAYER_PLAYLIST_H +#define MPLAYER_PLAYLIST_H + +#include +#include "bstr/bstr.h" + +struct playlist_param { + bstr name, value; +}; + +struct playlist_entry { + struct playlist_entry *prev, *next; + struct playlist *pl; + + char *filename; + + struct playlist_param *params; + int num_params; + + // Set to true if playback didn't seem to work, or if the file could be + // played only for a very short time. This is used to make playlist + // navigation just work in case the user has unplayable files in the + // playlist. + bool playback_short : 1; + // Set to true if not at least 1 frame (audio or video) could be played. + bool init_failed : 1; +}; + +struct playlist { + struct playlist_entry *first, *last; + + // This provides some sort of stable iterator. If this entry is removed from + // the playlist, current is set to the next element (or NULL), and + // current_was_replaced is set to true. + struct playlist_entry *current; + bool current_was_replaced; +}; + +void playlist_entry_add_param(struct playlist_entry *e, bstr name, bstr value); +void playlist_entry_add_params(struct playlist_entry *e, + struct playlist_param *params, + int params_count); + +struct playlist_entry *playlist_entry_new(const char *filename); + +void playlist_insert(struct playlist *pl, struct playlist_entry *after, + struct playlist_entry *add); +void playlist_add(struct playlist *pl, struct playlist_entry *add); +void playlist_remove(struct playlist *pl, struct playlist_entry *entry); +void playlist_clear(struct playlist *pl); + +void playlist_move(struct playlist *pl, struct playlist_entry *entry, + struct playlist_entry *at); + +void playlist_add_file(struct playlist *pl, const char *filename); +void playlist_shuffle(struct playlist *pl); +struct playlist_entry *playlist_get_next(struct playlist *pl, int direction); +void playlist_add_base_path(struct playlist *pl, bstr base_path); +void playlist_transfer_entries(struct playlist *pl, struct playlist *source_pl); + +int playlist_entry_to_index(struct playlist *pl, struct playlist_entry *e); +int playlist_entry_count(struct playlist *pl); +struct playlist_entry *playlist_entry_from_index(struct playlist *pl, int index); + +#endif diff --git a/common/playlist_parser.c b/common/playlist_parser.c new file mode 100644 index 0000000000..af249f4aa5 --- /dev/null +++ b/common/playlist_parser.c @@ -0,0 +1,566 @@ +/* + * This file is part of MPlayer. + * + * MPlayer 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. + * + * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* + * Warning: this is outdated, crappy code. It is used only for --playlist. + * New or cleaned up code should be added to demux_playlist.c instead. + */ + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "talloc.h" +#include "asxparser.h" +#include "playlist.h" +#include "playlist_parser.h" +#include "stream/stream.h" +#include "demux/demux.h" +#include "common/msg.h" +#include "options/path.h" + + +#define BUF_STEP 1024 + +#define WHITES " \n\r\t" + +typedef struct play_tree_parser { + struct stream *stream; + char *buffer,*iter,*line; + int buffer_size , buffer_end; + int keep; + struct playlist *pl; +} play_tree_parser_t; + +static void +strstrip(char* str) { + char* i; + + if (str==NULL) + return; + for(i = str ; i[0] != '\0' && strchr(WHITES,i[0]) != NULL; i++) + /* NOTHING */; + if(i[0] != '\0') { + memmove(str,i,strlen(i) + 1); + for(i = str + strlen(str) - 1 ; strchr(WHITES,i[0]) != NULL; i--) + /* NOTHING */; + i[1] = '\0'; + } else + str[0] = '\0'; +} + +static char* +play_tree_parser_get_line(play_tree_parser_t* p) { + char *end,*line_end; + int r,resize = 0; + + if(p->buffer == NULL) { + p->buffer = malloc(BUF_STEP); + p->buffer_size = BUF_STEP; + p->buffer[0] = 0; + p->iter = p->buffer; + } + + if(p->stream->eof && (p->buffer_end == 0 || p->iter[0] == '\0')) + return NULL; + + assert(p->buffer_end < p->buffer_size); + assert(!p->buffer[p->buffer_end]); + while(1) { + + if(resize) { + char *tmp; + r = p->iter - p->buffer; + end = p->buffer + p->buffer_end; + if (p->buffer_size > INT_MAX - BUF_STEP) + break; + tmp = realloc(p->buffer, p->buffer_size + BUF_STEP); + if (!tmp) + break; + p->buffer = tmp; + p->iter = p->buffer + r; + p->buffer_size += BUF_STEP; + resize = 0; + } + + if(p->buffer_size - p->buffer_end > 1 && ! p->stream->eof) { + r = stream_read(p->stream,p->buffer + p->buffer_end,p->buffer_size - p->buffer_end - 1); + if(r > 0) { + p->buffer_end += r; + assert(p->buffer_end < p->buffer_size); + p->buffer[p->buffer_end] = '\0'; + while(strlen(p->buffer + p->buffer_end - r) != r) + p->buffer[p->buffer_end - r + strlen(p->buffer + p->buffer_end - r)] = '\n'; + } + assert(!p->buffer[p->buffer_end]); + } + + end = strchr(p->iter,'\n'); + if(!end) { + if(p->stream->eof) { + end = p->buffer + p->buffer_end; + break; + } + resize = 1; + continue; + } + break; + } + + line_end = (end > p->iter && *(end-1) == '\r') ? end-1 : end; + if(line_end - p->iter >= 0) + p->line = realloc(p->line, line_end - p->iter + 1); + else + return NULL; + if(line_end - p->iter > 0) + strncpy(p->line,p->iter,line_end - p->iter); + p->line[line_end - p->iter] = '\0'; + if(end[0] != '\0') + end++; + + if(!p->keep) { + if(end[0] != '\0') { + p->buffer_end -= end-p->iter; + memmove(p->buffer,end,p->buffer_end); + } else + p->buffer_end = 0; + p->buffer[p->buffer_end] = '\0'; + p->iter = p->buffer; + } else + p->iter = end; + + return p->line; +} + +static void +play_tree_parser_reset(play_tree_parser_t* p) { + p->iter = p->buffer; +} + +static void +play_tree_parser_stop_keeping(play_tree_parser_t* p) { + p->keep = 0; + if(p->iter && p->iter != p->buffer) { + p->buffer_end -= p->iter -p->buffer; + if(p->buffer_end) + memmove(p->buffer,p->iter,p->buffer_end); + p->buffer[p->buffer_end] = 0; + p->iter = p->buffer; + } +} + + +static bool parse_asx(play_tree_parser_t* p) { + int comments = 0,get_line = 1; + char* line = NULL; + + mp_msg(MSGT_PLAYTREE,MSGL_V,"Trying asx...\n"); + + while(1) { + if(get_line) { + line = play_tree_parser_get_line(p); + if(!line) + return false; + strstrip(line); + if(line[0] == '\0') + continue; + } + if(!comments) { + if(line[0] != '<') { + mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"First char isn't '<' but '%c'\n",line[0]); + mp_msg(MSGT_PLAYTREE,MSGL_DBG3,"Buffer = [%s]\n",p->buffer); + return false; + } else if(strncmp(line,"",4) == 0) { // End of comments + comments = 0; + line = c+4; + if(line[0] != '\0') // There is some more data on this line : keep it + get_line = 0; + + } else { + line = c+1; // Jump the - + if(line[0] != '\0') // Some more data + get_line = 0; + else // End of line + get_line = 1; + } + } else // No - on this line (or rest of line) : get next one + get_line = 1; + } + } + + mp_msg(MSGT_PLAYTREE,MSGL_V,"Detected asx format\n"); + + // We have an asx : load it in memory and parse + + while((line = play_tree_parser_get_line(p)) != NULL) + /* NOTHING */; + + mp_msg(MSGT_PLAYTREE,MSGL_DBG3,"Parsing asx file: [%s]\n",p->buffer); + return asx_parse(p->buffer,p->pl); +} + +static bool parse_smil(play_tree_parser_t* p) { + int entrymode=0; + char* line,source[512],*pos,*s_start,*s_end,*src_line; + int is_rmsmil = 0; + unsigned int npkt, ttlpkt; + + mp_msg(MSGT_PLAYTREE,MSGL_V,"Trying smil playlist...\n"); + + // Check if smil + while((line = play_tree_parser_get_line(p)) != NULL) { + strstrip(line); + if(line[0] == '\0') // Ignore empties + continue; + if (strncasecmp(line," ttlpkt) { + mp_msg(MSGT_PLAYTREE,MSGL_WARN,"smil-over-realrtsp: bad packet counters (npkk = %u, ttlpkt = %u), assuming single packet.\n", + npkt, ttlpkt); + npkt = ttlpkt = 1; + } + } + + //Get entries from smil + src_line = line; + line = NULL; + do { + strstrip(src_line); + free(line); + line = NULL; + /* If we're parsing smil over realrtsp and this is not the last packet and + * this is the last line in the packet (terminating with ") ) we must get + * the next line, strip the header, and concatenate it to the current line. + */ + if (is_rmsmil && npkt != ttlpkt && strstr(src_line,"\")")) { + char *payload; + + line = strdup(src_line); + if(!(src_line = play_tree_parser_get_line(p))) { + mp_msg(MSGT_PLAYTREE,MSGL_WARN,"smil-over-realrtsp: can't get line from packet %u/%u.\n", npkt, ttlpkt); + break; + } + strstrip(src_line); + // Skip header, packet starts after " + if(!(payload = strchr(src_line,'\"'))) { + mp_msg(MSGT_PLAYTREE,MSGL_WARN,"smil-over-realrtsp: can't find start of packet, using complete line.\n"); + payload = src_line; + } else + payload++; + // Skip ") at the end of the last line from the current packet + line[strlen(line)-2] = 0; + line = realloc(line, strlen(line)+strlen(payload)+1); + strcat (line, payload); + npkt++; + } else + line = strdup(src_line); + /* Unescape \" to " for smil-over-rtsp */ + if (is_rmsmil && line[0] != '\0') { + int i, j; + + for (i = 0; i < strlen(line); i++) + if (line[i] == '\\' && line[i+1] == '"') + for (j = i; line[j]; j++) + line[j] = line[j+1]; + } + pos = line; + while (pos) { + if (!entrymode) { // all entries filled so far + while ((pos=strchr(pos, '<'))) { + if (strncasecmp(pos," 511) { + mp_msg(MSGT_PLAYTREE,MSGL_V,"Cannot store such a large source %s\n",line); + break; + } + strncpy(source,s_start,s_end-s_start); + source[(s_end-s_start)]='\0'; // Null terminate + playlist_add_file(p->pl, source); + pos = s_end; + } + } + } + } while((src_line = play_tree_parser_get_line(p)) != NULL); + + free(line); + return true; +} + +static bool parse_textplain(play_tree_parser_t* p) { + char* line; + + mp_msg(MSGT_PLAYTREE,MSGL_V,"Trying plaintext playlist...\n"); + play_tree_parser_stop_keeping(p); + + while((line = play_tree_parser_get_line(p)) != NULL) { + strstrip(line); + if(line[0] == '\0' || line[0] == '#' || (line[0] == '/' && line[1] == '/')) + continue; + + playlist_add_file(p->pl,line); + } + + return true; +} + +/** + * \brief decode the base64 used in nsc files + * \param in input string, 0-terminated + * \param buf output buffer, must point to memory suitable for realloc, + * will be NULL on failure. + * \return decoded length in bytes + */ +static int decode_nsc_base64(char *in, char **buf) { + int i, j, n; + if (in[0] != '0' || in[1] != '2') + goto err_out; + in += 2; // skip prefix + if (strlen(in) < 16) // error out if nothing to decode + goto err_out; + in += 12; // skip encoded string length + n = strlen(in) / 4; + *buf = realloc(*buf, n * 3); + for (i = 0; i < n; i++) { + uint8_t c[4]; + for (j = 0; j < 4; j++) { + c[j] = in[4 * i + j]; + if (c[j] >= '0' && c[j] <= '9') c[j] += 0 - '0'; + else if (c[j] >= 'A' && c[j] <= 'Z') c[j] += 10 - 'A'; + else if (c[j] >= 'a' && c[j] <= 'z') c[j] += 36 - 'a'; + else if (c[j] == '{') c[j] = 62; + else if (c[j] == '}') c[j] = 63; + else { + mp_msg(MSGT_PLAYTREE, MSGL_ERR, "Invalid character %c (0x%02"PRIx8")\n", c[j], c[j]); + goto err_out; + } + } + (*buf)[3 * i] = (c[0] << 2) | (c[1] >> 4); + (*buf)[3 * i + 1] = (c[1] << 4) | (c[2] >> 2); + (*buf)[3 * i + 2] = (c[2] << 6) | c[3]; + } + return 3 * n; +err_out: + free(*buf); + *buf = NULL; + return 0; +} + +/** + * \brief "converts" utf16 to ascii by just discarding every second byte + * \param buf buffer to convert + * \param len lenght of buffer, must be > 0 + */ +static void utf16_to_ascii(char *buf, int len) { + int i; + if (len <= 0) return; + for (i = 0; i < len / 2; i++) + buf[i] = buf[i * 2]; + buf[i] = 0; // just in case +} + +static bool parse_nsc(play_tree_parser_t* p) { + char *line, *addr = NULL, *url, *unicast_url = NULL; + int port = 0; + + mp_msg(MSGT_PLAYTREE,MSGL_V,"Trying nsc playlist...\n"); + while((line = play_tree_parser_get_line(p)) != NULL) { + strstrip(line); + if(!line[0]) // Ignore empties + continue; + if (strncasecmp(line,"[Address]", 9) == 0) + break; // nsc header found + else + return false; + } + mp_msg(MSGT_PLAYTREE,MSGL_V,"Detected nsc playlist format\n"); + play_tree_parser_stop_keeping(p); + while ((line = play_tree_parser_get_line(p)) != NULL) { + strstrip(line); + if (!line[0]) + continue; + if (strncasecmp(line, "Unicast URL=", 12) == 0) { + int len = decode_nsc_base64(&line[12], &unicast_url); + if (len <= 0) + mp_msg(MSGT_PLAYTREE, MSGL_WARN, "[nsc] Unsupported Unicast URL encoding\n"); + else + utf16_to_ascii(unicast_url, len); + } else if (strncasecmp(line, "IP Address=", 11) == 0) { + int len = decode_nsc_base64(&line[11], &addr); + if (len <= 0) + mp_msg(MSGT_PLAYTREE, MSGL_WARN, "[nsc] Unsupported IP Address encoding\n"); + else + utf16_to_ascii(addr, len); + } else if (strncasecmp(line, "IP Port=", 8) == 0) { + port = strtol(&line[8], NULL, 0); + } + } + + bool success = false; + + if (unicast_url) + url = strdup(unicast_url); + else if (addr && port) { + url = malloc(strlen(addr) + 7 + 20 + 1); + sprintf(url, "http://%s:%i", addr, port); + } else + goto err_out; + + playlist_add_file(p->pl, url); + free(url); + success = true; +err_out: + free(addr); + free(unicast_url); + return success; +} + +static struct playlist *do_parse(struct stream* stream, bool forced); + +struct playlist *playlist_parse_file(const char *file, struct MPOpts *opts) +{ + stream_t *stream = stream_open(file, opts); + if(!stream) { + mp_msg(MSGT_PLAYTREE,MSGL_ERR, + "Error while opening playlist file %s: %s\n", + file, strerror(errno)); + return false; + } + + mp_msg(MSGT_PLAYTREE, MSGL_V, + "Parsing playlist file %s...\n", file); + + struct playlist *ret = do_parse(stream, true); + free_stream(stream); + + if (ret) + playlist_add_base_path(ret, mp_dirname(file)); + + return ret; + +} + +typedef bool (*parser_fn)(play_tree_parser_t *); +static const parser_fn pl_parsers[] = { + parse_asx, + parse_smil, + parse_nsc, + parse_textplain +}; + + +static struct playlist *do_parse(struct stream* stream, bool forced) +{ + play_tree_parser_t p = { + .stream = stream, + .pl = talloc_zero(NULL, struct playlist), + .keep = 1, + }; + + bool success = false; + struct demuxer *pl_demux = demux_open(stream, "playlist", NULL, stream->opts); + if (pl_demux && pl_demux->playlist) { + playlist_transfer_entries(p.pl, pl_demux->playlist); + success = true; + } + free_demuxer(pl_demux); + if (!success && play_tree_parser_get_line(&p) != NULL) { + for (int n = 0; n < sizeof(pl_parsers) / sizeof(pl_parsers[0]); n++) { + play_tree_parser_reset(&p); + if (pl_parsers[n] == parse_textplain && !forced) + break; + if (pl_parsers[n](&p)) { + success = true; + break; + } + } + } + + if(success) + mp_msg(MSGT_PLAYTREE,MSGL_V,"Playlist successfully parsed\n"); + else { + mp_msg(MSGT_PLAYTREE,((forced==1)?MSGL_ERR:MSGL_V),"Error while parsing playlist\n"); + talloc_free(p.pl); + p.pl = NULL; + } + + if (p.pl && !p.pl->first) + mp_msg(MSGT_PLAYTREE,((forced==1)?MSGL_WARN:MSGL_V),"Warning: empty playlist\n"); + + return p.pl; +} diff --git a/common/playlist_parser.h b/common/playlist_parser.h new file mode 100644 index 0000000000..a541aa2cb4 --- /dev/null +++ b/common/playlist_parser.h @@ -0,0 +1,29 @@ +/* + * This file is part of MPlayer. + * + * MPlayer 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. + * + * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPLAYER_PLAYLISTPARSER_H +#define MPLAYER_PLAYLISTPARSER_H + +#include + +struct MPOpts; +struct playlist; + +struct playlist *playlist_parse_file(const char *file, struct MPOpts *opts); + +#endif diff --git a/common/version.c b/common/version.c new file mode 100644 index 0000000000..23a0c59bc3 --- /dev/null +++ b/common/version.c @@ -0,0 +1,26 @@ +/* + * This file is part of MPlayer. + * + * MPlayer 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. + * + * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "version.h" +#ifdef NO_BUILD_TIMESTAMPS +#undef BUILDDATE +#define BUILDDATE "UNKNOWN" +#endif + +const char *mplayer_version = "mpv " VERSION; +const char *mplayer_builddate = BUILDDATE; diff --git a/compat/atomics.h b/compat/atomics.h new file mode 100644 index 0000000000..e27825de8f --- /dev/null +++ b/compat/atomics.h @@ -0,0 +1,23 @@ +/* + * This file is part of mpv. + * Copyright (c) 2013 Stefano Pigozzi + * + * mpv 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. + * + * mpv 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 mpv. If not, see . + */ + +// At this point both gcc and clang had __sync_synchronize support for some +// time. We only support a full memory barrier. + +#define mp_memory_barrier() __sync_synchronize() +#define mp_atomic_add_and_fetch(a, b) __sync_add_and_fetch(a, b) diff --git a/demux/codec_tags.c b/demux/codec_tags.c index e63f1e7134..299249a2cf 100644 --- a/demux/codec_tags.c +++ b/demux/codec_tags.c @@ -20,7 +20,7 @@ #include #include "codec_tags.h" #include "stheader.h" -#include "mpvcore/av_common.h" +#include "common/av_common.h" /* The following tables map FourCCs to codec names (as defined by libavcodec). * However, this includes only names that are not defined by libavformat's diff --git a/demux/demux.c b/demux/demux.c index 626804fcef..c5cbe392af 100644 --- a/demux/demux.c +++ b/demux/demux.c @@ -30,9 +30,9 @@ #include "config.h" #include "options/options.h" -#include "mpvcore/av_common.h" +#include "common/av_common.h" #include "talloc.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "stream/stream.h" #include "demux.h" diff --git a/demux/demux.h b/demux/demux.h index 6b08b84e4c..6d5253786f 100644 --- a/demux/demux.h +++ b/demux/demux.h @@ -25,8 +25,8 @@ #include #include -#include "mpvcore/bstr.h" -#include "mpvcore/mp_common.h" +#include "bstr/bstr.h" +#include "common/common.h" #include "packet.h" #include "stheader.h" diff --git a/demux/demux_cue.c b/demux/demux_cue.c index 7c94850899..bfca04dcad 100644 --- a/demux/demux_cue.c +++ b/demux/demux_cue.c @@ -22,7 +22,7 @@ #include #include -#include "mpvcore/bstr.h" +#include "bstr/bstr.h" #include "demux.h" #include "stream/stream.h" diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c index c541f345e1..9057284c1e 100644 --- a/demux/demux_lavf.c +++ b/demux/demux_lavf.c @@ -36,10 +36,10 @@ #include "config.h" #include "options/options.h" -#include "mpvcore/mp_msg.h" -#include "mpvcore/av_opts.h" -#include "mpvcore/av_common.h" -#include "mpvcore/bstr.h" +#include "common/msg.h" +#include "common/av_opts.h" +#include "common/av_common.h" +#include "bstr/bstr.h" #include "stream/stream.h" #include "demux.h" diff --git a/demux/demux_libass.c b/demux/demux_libass.c index 15e149212b..f01b999d9e 100644 --- a/demux/demux_libass.c +++ b/demux/demux_libass.c @@ -22,8 +22,8 @@ #include #include "options/options.h" -#include "mpvcore/mp_msg.h" -#include "mpvcore/charset_conv.h" +#include "common/msg.h" +#include "misc/charset_conv.h" #include "stream/stream.h" #include "demux.h" diff --git a/demux/demux_mf.c b/demux/demux_mf.c index 1eea59a058..876b17a025 100644 --- a/demux/demux_mf.c +++ b/demux/demux_mf.c @@ -27,7 +27,7 @@ #include "talloc.h" #include "config.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "stream/stream.h" #include "demux.h" diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c index b3cf253be5..52ab592eb0 100644 --- a/demux/demux_mkv.c +++ b/demux/demux_mkv.c @@ -43,7 +43,7 @@ #include "talloc.h" #include "options/options.h" -#include "mpvcore/bstr.h" +#include "bstr/bstr.h" #include "stream/stream.h" #include "demux.h" #include "stheader.h" @@ -51,7 +51,7 @@ #include "matroska.h" #include "codec_tags.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" 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}, diff --git a/demux/demux_playlist.c b/demux/demux_playlist.c index 1a4882f92b..38011f80b7 100644 --- a/demux/demux_playlist.c +++ b/demux/demux_playlist.c @@ -15,10 +15,10 @@ * with mpv. If not, see . */ -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "options/options.h" -#include "mpvcore/mp_msg.h" -#include "mpvcore/playlist.h" +#include "common/msg.h" +#include "common/playlist.h" #include "options/path.h" #include "stream/stream.h" #include "demux.h" diff --git a/demux/demux_subreader.c b/demux/demux_subreader.c index a3cee1794b..e2b4c1cac4 100644 --- a/demux/demux_subreader.c +++ b/demux/demux_subreader.c @@ -32,8 +32,8 @@ #include #include "config.h" -#include "mpvcore/mp_msg.h" -#include "mpvcore/mp_common.h" +#include "common/msg.h" +#include "common/common.h" #include "options/options.h" #include "stream/stream.h" #include "demux/demux.h" diff --git a/demux/ebml.c b/demux/ebml.c index 06ef85b742..dabdebb9ea 100644 --- a/demux/ebml.c +++ b/demux/ebml.c @@ -35,7 +35,7 @@ #include "ebml.h" #include "stream/stream.h" #include "compat/mpbswap.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #ifndef SIZE_MAX #define SIZE_MAX ((size_t)-1) diff --git a/demux/ebml.h b/demux/ebml.h index 715e9ff85d..8652746e48 100644 --- a/demux/ebml.h +++ b/demux/ebml.h @@ -24,7 +24,7 @@ #include #include "stream/stream.h" -#include "mpvcore/bstr.h" +#include "bstr/bstr.h" /* EBML version supported */ diff --git a/demux/mf.c b/demux/mf.c index e50e10b43c..02a576c51d 100644 --- a/demux/mf.c +++ b/demux/mf.c @@ -37,7 +37,7 @@ #endif #include "talloc.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "stream/stream.h" #include "options/path.h" diff --git a/demux/stheader.h b/demux/stheader.h index 92bb404b6d..25f60ba032 100644 --- a/demux/stheader.h +++ b/demux/stheader.h @@ -21,7 +21,7 @@ #include -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "audio/chmap.h" #include "ms_hdr.h" struct MPOpts; diff --git a/input/input.c b/input/input.c index 4d2c873211..16f3b3c71a 100644 --- a/input/input.c +++ b/input/input.c @@ -41,15 +41,15 @@ #include "input.h" #include "keycodes.h" #include "osdep/timer.h" -#include "mpvcore/mp_msg.h" -#include "mpvcore/mpv_global.h" +#include "common/msg.h" +#include "common/global.h" #include "options/m_option.h" #include "options/path.h" #include "talloc.h" #include "options/options.h" -#include "mpvcore/bstr.h" +#include "bstr/bstr.h" #include "stream/stream.h" -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "joystick.h" diff --git a/input/input.h b/input/input.h index 43c5742cf6..4020c3d276 100644 --- a/input/input.h +++ b/input/input.h @@ -20,7 +20,7 @@ #define MPLAYER_INPUT_H #include -#include "mpvcore/bstr.h" +#include "bstr/bstr.h" #include "options/m_option.h" // All command IDs diff --git a/input/joystick.c b/input/joystick.c index d8e9d13423..f2be6c3f93 100644 --- a/input/joystick.c +++ b/input/joystick.c @@ -30,7 +30,7 @@ #include #include -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "keycodes.h" #ifndef JOY_AXIS_DELTA diff --git a/input/lirc.c b/input/lirc.c index 052fffbd74..f3b63468e0 100644 --- a/input/lirc.c +++ b/input/lirc.c @@ -26,7 +26,7 @@ #include #include -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "input.h" #include "lirc.h" diff --git a/misc/charset_conv.c b/misc/charset_conv.c new file mode 100644 index 0000000000..fe396e8ef5 --- /dev/null +++ b/misc/charset_conv.c @@ -0,0 +1,287 @@ +/* + * This file is part of mpv. + * + * Based on code taken from libass (ISC license), which was originally part + * of MPlayer (GPL). + * Copyright (C) 2006 Evgeniy Stepanov + * + * mpv 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. + * + * mpv 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 mpv. If not, see . + */ + +#include +#include +#include + +#include "config.h" + +#include "common/msg.h" + +#if HAVE_ENCA +#include +#endif + +#if HAVE_LIBGUESS +#include +#endif + +#if HAVE_ICONV +#include +#endif + +#include "charset_conv.h" + +bool mp_charset_is_utf8(const char *user_cp) +{ + return user_cp && (strcasecmp(user_cp, "utf8") == 0 || + strcasecmp(user_cp, "utf-8") == 0); +} + +// Split the string on ':' into components. +// out_arr is at least max entries long. +// Return number of out_arr entries filled. +static int split_colon(const char *user_cp, int max, bstr *out_arr) +{ + if (!user_cp || max < 1) + return 0; + + int count = 0; + while (1) { + const char *next = strchr(user_cp, ':'); + if (next && max - count > 1) { + out_arr[count++] = (bstr){(char *)user_cp, next - user_cp}; + user_cp = next + 1; + } else { + out_arr[count++] = (bstr){(char *)user_cp, strlen(user_cp)}; + break; + } + } + return count; +} + +// Returns true if user_cp implies that calling mp_charset_guess() on the +// input data is required to determine the real codepage. This is the case +// if user_cp is not a real iconv codepage, but a magic value that requests +// for example ENCA charset auto-detection. +bool mp_charset_requires_guess(const char *user_cp) +{ + bstr res[2] = {{0}}; + int r = split_colon(user_cp, 2, res); + // Note that "utf8" is the UTF-8 codepage, while "utf8:..." specifies UTF-8 + // by default, plus a codepage that is used if the input is not UTF-8. + return bstrcasecmp0(res[0], "enca") == 0 || + bstrcasecmp0(res[0], "guess") == 0 || + (r > 1 && bstrcasecmp0(res[0], "utf-8") == 0) || + (r > 1 && bstrcasecmp0(res[0], "utf8") == 0); +} + +#if HAVE_ENCA +static const char *enca_guess(bstr buf, const char *language) +{ + if (!language || !language[0]) + language = "__"; // neutral language + + const char *detected_cp = NULL; + + EncaAnalyser analyser = enca_analyser_alloc(language); + if (analyser) { + enca_set_termination_strictness(analyser, 0); + EncaEncoding enc = enca_analyse_const(analyser, buf.start, buf.len); + const char *tmp = enca_charset_name(enc.charset, ENCA_NAME_STYLE_ICONV); + if (tmp && enc.charset != ENCA_CS_UNKNOWN) + detected_cp = tmp; + enca_analyser_free(analyser); + } else { + mp_msg(MSGT_SUBREADER, MSGL_ERR, "ENCA doesn't know language '%s'\n", + language); + size_t langcnt; + const char **languages = enca_get_languages(&langcnt); + mp_msg(MSGT_SUBREADER, MSGL_ERR, "ENCA supported languages:"); + for (int i = 0; i < langcnt; i++) + mp_msg(MSGT_SUBREADER, MSGL_ERR, " %s", languages[i]); + mp_msg(MSGT_SUBREADER, MSGL_ERR, "\n"); + free(languages); + } + + return detected_cp; +} +#endif + +#if HAVE_LIBGUESS +static const char *libguess_guess(bstr buf, const char *language) +{ + if (!language || !language[0] || strcmp(language, "help") == 0) { + mp_msg(MSGT_SUBREADER, MSGL_ERR, "libguess needs a language: " + "japanese taiwanese chinese korean russian arabic turkish " + "greek hebrew polish baltic\n"); + return NULL; + } + + return libguess_determine_encoding(buf.start, buf.len, language); +} +#endif + +// Runs charset auto-detection on the input buffer, and returns the result. +// If auto-detection fails, NULL is returned. +// If user_cp doesn't refer to any known auto-detection (for example because +// it's a real iconv codepage), user_cp is returned without even looking at +// the buf data. +const char *mp_charset_guess(bstr buf, const char *user_cp, int flags) +{ + if (!mp_charset_requires_guess(user_cp)) + return user_cp; + + // Do our own UTF-8 detection, because at least ENCA seems to get it + // wrong sometimes (suggested by divVerent). + int r = bstr_validate_utf8(buf); + if (r >= 0 || (r > -8 && (flags & MP_ICONV_ALLOW_CUTOFF))) + return "UTF-8"; + + bstr params[3] = {{0}}; + split_colon(user_cp, 3, params); + + bstr type = params[0]; + char lang[100]; + snprintf(lang, sizeof(lang), "%.*s", BSTR_P(params[1])); + const char *fallback = params[2].start; // last item, already 0-terminated + + const char *res = NULL; + +#if HAVE_ENCA + if (bstrcasecmp0(type, "enca") == 0) + res = enca_guess(buf, lang); +#endif +#if HAVE_LIBGUESS + if (bstrcasecmp0(type, "guess") == 0) + res = libguess_guess(buf, lang); +#endif + if (bstrcasecmp0(type, "utf8") == 0 || bstrcasecmp0(type, "utf-8") == 0) { + if (!fallback) + fallback = params[1].start; // must be already 0-terminated + } + + if (res) { + mp_msg(MSGT_SUBREADER, MSGL_DBG2, "%.*s detected charset: '%s'\n", + BSTR_P(type), res); + } else { + res = fallback; + mp_msg(MSGT_SUBREADER, MSGL_DBG2, + "Detection with %.*s failed: fallback to %s\n", + BSTR_P(type), res && res[0] ? res : "broken UTF-8/Latin1"); + } + + if (!res && !(flags & MP_STRICT_UTF8)) + res = "UTF-8-BROKEN"; + + return res; +} + +// Convert the data in buf to UTF-8. The charset argument can be an iconv +// codepage, a value returned by mp_charset_conv_guess(), or a special value +// that triggers autodetection of the charset (e.g. using ENCA). +// The auto-detection is the only difference to mp_iconv_to_utf8(). +// buf: same as mp_iconv_to_utf8() +// user_cp: iconv codepage, special value, NULL +// flags: same as mp_iconv_to_utf8() +// returns: same as mp_iconv_to_utf8() +bstr mp_charset_guess_and_conv_to_utf8(bstr buf, const char *user_cp, int flags) +{ + return mp_iconv_to_utf8(buf, mp_charset_guess(buf, user_cp, flags), flags); +} + +// Use iconv to convert buf to UTF-8. +// Returns buf.start==NULL on error. Returns buf if cp is NULL, or if there is +// obviously no conversion required (e.g. if cp is "UTF-8"). +// Returns a newly allocated buffer if conversion is done and succeeds. The +// buffer will be terminated with 0 for convenience (the terminating 0 is not +// included in the returned length). +// Free the returned buffer with talloc_free(). +// buf: input data +// cp: iconv codepage (or NULL) +// flags: combination of MP_ICONV_* flags +// returns: buf (no conversion), .start==NULL (error), or allocated buffer +bstr mp_iconv_to_utf8(bstr buf, const char *cp, int flags) +{ +#if HAVE_ICONV + if (!cp || !cp[0] || mp_charset_is_utf8(cp)) + return buf; + + if (strcasecmp(cp, "ASCII") == 0) + return buf; + + if (strcasecmp(cp, "UTF-8-BROKEN") == 0) + return bstr_sanitize_utf8_latin1(NULL, buf); + + iconv_t icdsc; + if ((icdsc = iconv_open("UTF-8", cp)) == (iconv_t) (-1)) { + if (flags & MP_ICONV_VERBOSE) + mp_msg(MSGT_SUBREADER, MSGL_ERR, + "Error opening iconv with codepage '%s'\n", cp); + goto failure; + } + + size_t size = buf.len; + size_t osize = size; + size_t ileft = size; + size_t oleft = size - 1; + + char *outbuf = talloc_size(NULL, osize); + char *ip = buf.start; + char *op = outbuf; + + while (1) { + int clear = 0; + size_t rc; + if (ileft) + rc = iconv(icdsc, &ip, &ileft, &op, &oleft); + else { + clear = 1; // clear the conversion state and leave + rc = iconv(icdsc, NULL, NULL, &op, &oleft); + } + if (rc == (size_t) (-1)) { + if (errno == E2BIG) { + size_t offset = op - outbuf; + outbuf = talloc_realloc_size(NULL, outbuf, osize + size); + op = outbuf + offset; + osize += size; + oleft += size; + } else { + if (errno == EINVAL && (flags & MP_ICONV_ALLOW_CUTOFF)) { + // This is intended for cases where the input buffer is cut + // at a random byte position. If this happens in the middle + // of the buffer, it should still be an error. We say it's + // fine if the error is within 10 bytes of the end. + if (ileft <= 10) + break; + } + if (flags & MP_ICONV_VERBOSE) { + mp_msg(MSGT_SUBREADER, MSGL_ERR, + "Error recoding text with codepage '%s'\n", cp); + } + talloc_free(outbuf); + iconv_close(icdsc); + goto failure; + } + } else if (clear) + break; + } + + iconv_close(icdsc); + + outbuf[osize - oleft - 1] = 0; + return (bstr){outbuf, osize - oleft - 1}; +#endif + +failure: + return (bstr){0}; +} diff --git a/misc/charset_conv.h b/misc/charset_conv.h new file mode 100644 index 0000000000..c216ede2be --- /dev/null +++ b/misc/charset_conv.h @@ -0,0 +1,19 @@ +#ifndef MP_CHARSET_CONV_H +#define MP_CHARSET_CONV_H + +#include +#include "bstr/bstr.h" + +enum { + MP_ICONV_VERBOSE = 1, // print errors instead of failing silently + MP_ICONV_ALLOW_CUTOFF = 2, // allow partial input data + MP_STRICT_UTF8 = 4, // don't fall back to UTF-8-BROKEN when guessing +}; + +bool mp_charset_is_utf8(const char *user_cp); +bool mp_charset_requires_guess(const char *user_cp); +const char *mp_charset_guess(bstr buf, const char *user_cp, int flags); +bstr mp_charset_guess_and_conv_to_utf8(bstr buf, const char *user_cp, int flags); +bstr mp_iconv_to_utf8(bstr buf, const char *cp, int flags); + +#endif diff --git a/misc/ring.c b/misc/ring.c new file mode 100644 index 0000000000..eb139c2cab --- /dev/null +++ b/misc/ring.c @@ -0,0 +1,138 @@ +/* + * This file is part of mpv. + * Copyright (c) 2012 wm4 + * Copyright (c) 2013 Stefano Pigozzi + * + * mpv 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. + * + * mpv 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 mpv. If not, see . + */ + +#include +#include +#include +#include "talloc.h" +#include "compat/atomics.h" +#include "ring.h" + +struct mp_ring { + uint8_t *buffer; + + /* Positions of the first readable/writeable chunks. Do not read this + * fields but use the atomic private accessors `mp_ring_get_wpos` + * and `mp_ring_get_rpos`. */ + uint32_t rpos, wpos; +}; + +static uint32_t mp_ring_get_wpos(struct mp_ring *buffer) +{ + mp_memory_barrier(); + return buffer->wpos; +} + +static uint32_t mp_ring_get_rpos(struct mp_ring *buffer) +{ + mp_memory_barrier(); + return buffer->rpos; +} + +struct mp_ring *mp_ring_new(void *talloc_ctx, int size) +{ + struct mp_ring *ringbuffer = + talloc_zero(talloc_ctx, struct mp_ring); + + *ringbuffer = (struct mp_ring) { + .buffer = talloc_size(talloc_ctx, size), + }; + + return ringbuffer; +} + +int mp_ring_drain(struct mp_ring *buffer, int len) +{ + int buffered = mp_ring_buffered(buffer); + int drain_len = FFMIN(len, buffered); + mp_atomic_add_and_fetch(&buffer->rpos, drain_len); + mp_memory_barrier(); + return drain_len; +} + +int mp_ring_read(struct mp_ring *buffer, unsigned char *dest, int len) +{ + if (!dest) return mp_ring_drain(buffer, len); + + int size = mp_ring_size(buffer); + int buffered = mp_ring_buffered(buffer); + int read_len = FFMIN(len, buffered); + int read_ptr = mp_ring_get_rpos(buffer) % size; + + int len1 = FFMIN(size - read_ptr, read_len); + int len2 = read_len - len1; + + memcpy(dest, buffer->buffer + read_ptr, len1); + memcpy(dest + len1, buffer->buffer, len2); + + mp_atomic_add_and_fetch(&buffer->rpos, read_len); + mp_memory_barrier(); + + return read_len; +} + +int mp_ring_write(struct mp_ring *buffer, unsigned char *src, int len) +{ + int size = mp_ring_size(buffer); + int free = mp_ring_available(buffer); + int write_len = FFMIN(len, free); + int write_ptr = mp_ring_get_wpos(buffer) % size; + + int len1 = FFMIN(size - write_ptr, write_len); + int len2 = write_len - len1; + + memcpy(buffer->buffer + write_ptr, src, len1); + memcpy(buffer->buffer, src + len1, len2); + + mp_atomic_add_and_fetch(&buffer->wpos, write_len); + mp_memory_barrier(); + + return write_len; +} + +void mp_ring_reset(struct mp_ring *buffer) +{ + buffer->wpos = buffer->rpos = 0; + mp_memory_barrier(); +} + +int mp_ring_available(struct mp_ring *buffer) +{ + return mp_ring_size(buffer) - mp_ring_buffered(buffer); +} + +int mp_ring_size(struct mp_ring *buffer) +{ + return talloc_get_size(buffer->buffer); +} + +int mp_ring_buffered(struct mp_ring *buffer) +{ + return (mp_ring_get_wpos(buffer) - mp_ring_get_rpos(buffer)); +} + +char *mp_ring_repr(struct mp_ring *buffer, void *talloc_ctx) +{ + return talloc_asprintf( + talloc_ctx, + "Ringbuffer { .size = %dB, .buffered = %dB, .available = %dB }", + mp_ring_size(buffer), + mp_ring_buffered(buffer), + mp_ring_available(buffer)); +} diff --git a/misc/ring.h b/misc/ring.h new file mode 100644 index 0000000000..e93baea97e --- /dev/null +++ b/misc/ring.h @@ -0,0 +1,108 @@ +/* + * This file is part of mpv. + * Copyright (c) 2012 wm4 + * Copyright (c) 2013 Stefano Pigozzi + * + * mpv 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. + * + * mpv 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 mpv. If not, see . + */ + +#ifndef MPV_MP_RING_H +#define MPV_MP_RING_H + +/** + * A simple non-blocking SPSC (single producer, single consumer) ringbuffer + * implementation. Thread safety is accomplished through atomic operations. + */ + +struct mp_ring; + +/** + * Instantiate a new ringbuffer + * + * talloc_ctx: talloc context of the newly created object + * size: total size in bytes + * return: the newly created ringbuffer + */ +struct mp_ring *mp_ring_new(void *talloc_ctx, int size); + +/** + * Read data from the ringbuffer + * + * buffer: target ringbuffer instance + * dest: destination buffer for the read data. If NULL read data is discarded. + * len: maximum number of bytes to read + * return: number of bytes read + */ +int mp_ring_read(struct mp_ring *buffer, unsigned char *dest, int len); + +/** + * Write data to the ringbuffer + * + * buffer: target ringbuffer instance + * src: source buffer for the write data + * len: maximum number of bytes to write + * return: number of bytes written + */ +int mp_ring_write(struct mp_ring *buffer, unsigned char *src, int len); + +/** + * Drain data from the ringbuffer + * + * buffer: target ringbuffer instance + * len: maximum number of bytes to drain + * return: number of bytes drained + */ +int mp_ring_drain(struct mp_ring *buffer, int len); + +/** + * Reset the ringbuffer discarding any content + * + * buffer: target ringbuffer instance + */ +void mp_ring_reset(struct mp_ring *buffer); + +/** + * Get the available size for writing + * + * buffer: target ringbuffer instance + * return: number of bytes that can be written + */ +int mp_ring_available(struct mp_ring *buffer); + +/** + * Get the total size + * + * buffer: target ringbuffer instance + * return: total ringbuffer size in bytes + */ +int mp_ring_size(struct mp_ring *buffer); + +/** + * Get the available size for reading + * + * buffer: target ringbuffer instance + * return: number of bytes ready for reading + */ +int mp_ring_buffered(struct mp_ring *buffer); + +/** + * Get a string representation of the ringbuffer + * + * buffer: target ringbuffer instance + * talloc_ctx: talloc context of the newly created string + * return: string representing the ringbuffer + */ +char *mp_ring_repr(struct mp_ring *buffer, void *talloc_ctx); + +#endif diff --git a/mpvcore/asxparser.c b/mpvcore/asxparser.c deleted file mode 100644 index 16646b9347..0000000000 --- a/mpvcore/asxparser.c +++ /dev/null @@ -1,581 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "config.h" - -#include -#include -#include -#include -#include - -#include "playlist.h" -#include "playlist_parser.h" -#include "stream/stream.h" -#include "asxparser.h" -#include "mpvcore/mp_msg.h" - - -typedef struct ASX_Parser_t ASX_Parser_t; - -typedef struct { - char* buffer; - int line; -} ASX_LineSave_t; - -struct ASX_Parser_t { - int line; // Curent line - ASX_LineSave_t *ret_stack; - int ret_stack_size; - char* last_body; - int deep; - struct playlist *pl; -}; - -ASX_Parser_t *asx_parser_new(struct playlist *pl); - -void -asx_parser_free(ASX_Parser_t* parser); - -/* - * Return -1 on error, 0 when nothing is found, 1 on sucess - */ -int -asx_get_element(ASX_Parser_t* parser,char** _buffer, - char** _element,char** _body,char*** _attribs); - -int -asx_parse_attribs(ASX_Parser_t* parser,char* buffer,char*** _attribs); - -/////// Attribs utils - -char* -asx_get_attrib(const char* attrib,char** attribs); - -#define asx_free_attribs(a) asx_list_free(&a,free) - -////// List utils - -typedef void (*ASX_FreeFunc)(void* arg); - -void -asx_list_free(void* list_ptr,ASX_FreeFunc free_func); - - -////// List utils - -void -asx_list_free(void* list_ptr,ASX_FreeFunc free_func) { - void** ptr = *(void***)list_ptr; - if(ptr == NULL) return; - if(free_func != NULL) { - for( ; *ptr != NULL ; ptr++) - free_func(*ptr); - } - free(*(void**)list_ptr); - *(void**)list_ptr = NULL; -} - -/////// Attribs utils - -char* -asx_get_attrib(const char* attrib,char** attribs) { - char** ptr; - - if(attrib == NULL || attribs == NULL) return NULL; - for(ptr = attribs; ptr[0] != NULL; ptr += 2){ - if(strcasecmp(ptr[0],attrib) == 0) - return strdup(ptr[1]); - } - return NULL; -} - -#define asx_warning_attrib_required(p,e,a) mp_msg(MSGT_PLAYTREE,MSGL_WARN,"At line %d : element %s don't have the required attribute %s",p->line,e,a) -#define asx_warning_body_parse_error(p,e) mp_msg(MSGT_PLAYTREE,MSGL_WARN,"At line %d : error while parsing %s body",p->line,e) - -ASX_Parser_t *asx_parser_new(struct playlist *pl) -{ - ASX_Parser_t* parser = calloc(1,sizeof(ASX_Parser_t)); - parser->pl = pl; - return parser; -} - -void -asx_parser_free(ASX_Parser_t* parser) { - if(!parser) return; - free(parser->ret_stack); - free(parser); - -} - -#define LETTER "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" -#define SPACE " \n\t\r" - -int -asx_parse_attribs(ASX_Parser_t* parser,char* buffer,char*** _attribs) { - char *ptr1, *ptr2, *ptr3; - int n_attrib = 0; - char **attribs = NULL; - char *attrib, *val; - - ptr1 = buffer; - while(1) { - for( ; strchr(SPACE,*ptr1) != NULL; ptr1++) { // Skip space - if(*ptr1 == '\0') break; - } - ptr3 = strchr(ptr1,'='); - if(ptr3 == NULL) break; - for(ptr2 = ptr3-1; strchr(SPACE,*ptr2) != NULL; ptr2--) { - if (ptr2 == ptr1) { - mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : this should never append, back to attribute begin while skipping end space",parser->line); - break; - } - } - attrib = malloc(ptr2-ptr1+2); - strncpy(attrib,ptr1,ptr2-ptr1+1); - attrib[ptr2-ptr1+1] = '\0'; - - ptr1 = strchr(ptr3,'"'); - if(ptr1 == NULL || ptr1[1] == '\0') ptr1 = strchr(ptr3,'\''); - if(ptr1 == NULL || ptr1[1] == '\0') { - mp_msg(MSGT_PLAYTREE,MSGL_WARN,"At line %d : can't find attribute %s value",parser->line,attrib); - free(attrib); - break; - } - ptr2 = strchr(ptr1+1,ptr1[0]); - if (ptr2 == NULL) { - mp_msg(MSGT_PLAYTREE,MSGL_WARN,"At line %d : value of attribute %s isn't finished",parser->line,attrib); - free(attrib); - break; - } - ptr1++; - val = malloc(ptr2-ptr1+1); - strncpy(val,ptr1,ptr2-ptr1); - val[ptr2-ptr1] = '\0'; - n_attrib++; - - attribs = realloc(attribs, (2 * n_attrib + 1) * sizeof(char*)); - attribs[n_attrib*2-2] = attrib; - attribs[n_attrib*2-1] = val; - - ptr1 = ptr2+1; - } - - if(n_attrib > 0) - attribs[n_attrib*2] = NULL; - - *_attribs = attribs; - - return n_attrib; -} - -/* - * Return -1 on error, 0 when nothing is found, 1 on sucess - */ -int -asx_get_element(ASX_Parser_t* parser,char** _buffer, - char** _element,char** _body,char*** _attribs) { - char *ptr1,*ptr2, *ptr3, *ptr4; - char *attribs = NULL; - char *element = NULL, *body = NULL, *ret = NULL, *buffer; - int n_attrib = 0; - int body_line = 0,attrib_line,ret_line,in = 0; - int quotes = 0; - - if(_buffer == NULL || _element == NULL || _body == NULL || _attribs == NULL) { - mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : asx_get_element called with invalid value",parser->line); - return -1; - } - - *_body = *_element = NULL; - *_attribs = NULL; - buffer = *_buffer; - - if(buffer == NULL) return 0; - - if(parser->ret_stack && /*parser->last_body && */buffer != parser->last_body) { - ASX_LineSave_t* ls = parser->ret_stack; - int i; - for(i = 0 ; i < parser->ret_stack_size ; i++) { - if(buffer == ls[i].buffer) { - parser->line = ls[i].line; - break; - } - - } - if( i < parser->ret_stack_size) { - i++; - if( i < parser->ret_stack_size) - memmove(parser->ret_stack,parser->ret_stack+i, (parser->ret_stack_size - i)*sizeof(ASX_LineSave_t)); - parser->ret_stack_size -= i; - if(parser->ret_stack_size > 0) - parser->ret_stack = realloc(parser->ret_stack,parser->ret_stack_size*sizeof(ASX_LineSave_t)); - else { - free(parser->ret_stack); - parser->ret_stack = NULL; - } - } - } - - ptr1 = buffer; - while(1) { - for( ; ptr1[0] != '<' ; ptr1++) { - if(ptr1[0] == '\0') { - ptr1 = NULL; - break; - } - if(ptr1[0] == '\n') parser->line++; - } - //ptr1 = strchr(ptr1,'<'); - if(!ptr1 || ptr1[1] == '\0') return 0; // Nothing found - - if(strncmp(ptr1,"",3) != 0 ; ptr1++) { - if(ptr1[0] == '\0') { - ptr1 = NULL; - break; - } - if(ptr1[0] == '\n') parser->line++; - } - //ptr1 = strstr(ptr1,"-->"); - if(!ptr1) { - mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : unfinished comment",parser->line); - return -1; - } - } else { - break; - } - } - - // Is this space skip very useful ?? - for(ptr1++; strchr(SPACE,ptr1[0]) != NULL; ptr1++) { // Skip space - if(ptr1[0] == '\0') { - mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : EOB reached while parsing element start",parser->line); - return -1; - } - if(ptr1[0] == '\n') parser->line++; - } - - for(ptr2 = ptr1; strchr(LETTER,*ptr2) != NULL;ptr2++) { // Go to end of name - if(*ptr2 == '\0'){ - mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : EOB reached while parsing element start",parser->line); - return -1; - } - if(ptr2[0] == '\n') parser->line++; - } - - element = malloc(ptr2-ptr1+1); - strncpy(element,ptr1,ptr2-ptr1); - element[ptr2-ptr1] = '\0'; - - for( ; strchr(SPACE,*ptr2) != NULL; ptr2++) { // Skip space - if(ptr2[0] == '\0') { - mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : EOB reached while parsing element start",parser->line); - free(element); - return -1; - } - if(ptr2[0] == '\n') parser->line++; - } - attrib_line = parser->line; - - - - for(ptr3 = ptr2; ptr3[0] != '\0'; ptr3++) { // Go to element end - if(ptr3[0] == '"') quotes ^= 1; - if(!quotes && (ptr3[0] == '>' || strncmp(ptr3,"/>",2) == 0)) - break; - if(ptr3[0] == '\n') parser->line++; - } - if(ptr3[0] == '\0' || ptr3[1] == '\0') { // End of file - mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : EOB reached while parsing element start",parser->line); - free(element); - return -1; - } - - // Save attribs string - if(ptr3-ptr2 > 0) { - attribs = malloc(ptr3-ptr2+1); - strncpy(attribs,ptr2,ptr3-ptr2); - attribs[ptr3-ptr2] = '\0'; - } - //bs_line = parser->line; - if(ptr3[0] != '/') { // Not Self closed element - ptr3++; - for( ; strchr(SPACE,*ptr3) != NULL; ptr3++) { // Skip space on body begin - if(*ptr3 == '\0') { - mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : EOB reached while parsing %s element body",parser->line,element); - free(element); - free(attribs); - return -1; - } - if(ptr3[0] == '\n') parser->line++; - } - ptr4 = ptr3; - body_line = parser->line; - while(1) { // Find closing element - for( ; ptr4[0] != '<' ; ptr4++) { - if(ptr4[0] == '\0') { - ptr4 = NULL; - break; - } - if(ptr4[0] == '\n') parser->line++; - } - if(ptr4 && strncmp(ptr4,"",3) != 0 ; ptr4++) { - if(ptr4[0] == '\0') { - ptr4 = NULL; - break; - } - if(ptr1[0] == '\n') parser->line++; - } - continue; - } - if(ptr4 == NULL || ptr4[1] == '\0') { - mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : EOB reached while parsing %s element body",parser->line,element); - free(element); - free(attribs); - return -1; - } - if(ptr4[1] != '/' && strncasecmp(element,ptr4+1,strlen(element)) == 0) { - in++; - ptr4+=2; - continue; - } else if(strncasecmp(element,ptr4+2,strlen(element)) == 0) { // Extract body - if(in > 0) { - in--; - ptr4 += 2+strlen(element); - continue; - } - ret = ptr4+strlen(element)+3; - if(ptr4 != ptr3) { - ptr4--; - for( ; ptr4 != ptr3 && strchr(SPACE,*ptr4) != NULL; ptr4--) ;// Skip space on body end - // if(ptr4[0] == '\0') parser->line--; - //} - ptr4++; - body = malloc(ptr4-ptr3+1); - strncpy(body,ptr3,ptr4-ptr3); - body[ptr4-ptr3] = '\0'; - } - break; - } else { - ptr4 += 2; - } - } - } else { - ret = ptr3 + 2; // 2 is for /> - } - - for( ; ret[0] != '\0' && strchr(SPACE,ret[0]) != NULL; ret++) { // Skip space - if(ret[0] == '\n') parser->line++; - } - - ret_line = parser->line; - - if(attribs) { - parser->line = attrib_line; - n_attrib = asx_parse_attribs(parser,attribs,_attribs); - free(attribs); - if(n_attrib < 0) { - mp_msg(MSGT_PLAYTREE,MSGL_WARN,"At line %d : error while parsing element %s attributes",parser->line,element); - free(element); - free(body); - return -1; - } - } else - *_attribs = NULL; - - *_element = element; - *_body = body; - - parser->last_body = body; - parser->ret_stack_size++; - parser->ret_stack = realloc(parser->ret_stack,parser->ret_stack_size*sizeof(ASX_LineSave_t)); - if(parser->ret_stack_size > 1) - memmove(parser->ret_stack+1,parser->ret_stack,(parser->ret_stack_size-1)*sizeof(ASX_LineSave_t)); - parser->ret_stack[0].buffer = ret; - parser->ret_stack[0].line = ret_line; - parser->line = body ? body_line : ret_line; - - *_buffer = ret; - return 1; - -} - -static void -asx_parse_ref(ASX_Parser_t* parser, char** attribs) { - char *href; - - href = asx_get_attrib("HREF",attribs); - if(href == NULL) { - asx_warning_attrib_required(parser,"REF" ,"HREF" ); - return; - } -#if 0 - // replace http my mmshttp to avoid infinite loops - // disabled since some playlists for e.g. WinAMP use asx as well - // "-user-agent NSPlayer/4.1.0.3856" is a possible workaround - if (strncmp(href, "http://", 7) == 0) { - char *newref = malloc(3 + strlen(href) + 1); - strcpy(newref, "mms"); - strcpy(newref + 3, href); - free(href); - href = newref; - } -#endif - - playlist_add_file(parser->pl, href); - - mp_msg(MSGT_PLAYTREE,MSGL_V,"Adding file %s to element entry\n",href); - - free(href); - -} - -static void asx_parse_entryref(ASX_Parser_t* parser,char* buffer,char** _attribs) { - char *href; - - if(parser->deep > 0) - return; - - href = asx_get_attrib("HREF",_attribs); - if(href == NULL) { - asx_warning_attrib_required(parser,"ENTRYREF" ,"HREF" ); - return; - } - mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Recursive playlist %s\n", href); - playlist_add_file(parser->pl, href); - free(href); - //mp_msg(MSGT_PLAYTREE,MSGL_INFO,"Need to implement entryref\n"); -} - -static void asx_parse_entry(ASX_Parser_t* parser,char* buffer,char** _attribs) { - char *element,*body,**attribs; - int r; - - while(buffer && buffer[0] != '\0') { - r = asx_get_element(parser,&buffer,&element,&body,&attribs); - if(r < 0) { - asx_warning_body_parse_error(parser,"ENTRY"); - return; - } else if (r == 0) { // No more element - break; - } - if(strcasecmp(element,"REF") == 0) { - asx_parse_ref(parser,attribs); - mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Adding element %s to entry\n",element); - } else - mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Ignoring element %s\n",element); - free(body); - asx_free_attribs(attribs); - } - -} - - -static void asx_parse_repeat(ASX_Parser_t* parser,char* buffer,char** _attribs) { - char *element,*body,**attribs; - int r; - - asx_get_attrib("COUNT",_attribs); - mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Ignoring repeated playlist entries\n"); - - while(buffer && buffer[0] != '\0') { - r = asx_get_element(parser,&buffer,&element,&body,&attribs); - if(r < 0) { - asx_warning_body_parse_error(parser,"REPEAT"); - return; - } else if (r == 0) { // No more element - break; - } - if(strcasecmp(element,"ENTRY") == 0) { - asx_parse_entry(parser,body,attribs); - } else if(strcasecmp(element,"ENTRYREF") == 0) { - asx_parse_entryref(parser,body,attribs); - } else if(strcasecmp(element,"REPEAT") == 0) { - asx_parse_repeat(parser,body,attribs); - } else - mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Ignoring element %s\n",element); - free(body); - asx_free_attribs(attribs); - } - -} - - -bool asx_parse(char* buffer, struct playlist *pl) -{ - char *element,*asx_body,**asx_attribs,*body = NULL, **attribs; - int r; - ASX_Parser_t* parser = asx_parser_new(pl); - - parser->line = 1; - parser->deep = 0; - - r = asx_get_element(parser,&buffer,&element,&asx_body,&asx_attribs); - if(r < 0) { - mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : Syntax error ???",parser->line); - asx_parser_free(parser); - return false; - } else if(r == 0) { // No contents - mp_msg(MSGT_PLAYTREE,MSGL_ERR,"empty asx element"); - asx_parser_free(parser); - return false; - } - - if(strcasecmp(element,"ASX") != 0) { - mp_msg(MSGT_PLAYTREE,MSGL_ERR,"first element isn't ASX, it's %s\n",element); - asx_free_attribs(asx_attribs); - asx_parser_free(parser); - return false; - } - - if(!asx_body) { - mp_msg(MSGT_PLAYTREE,MSGL_ERR,"ASX element is empty"); - asx_free_attribs(asx_attribs); - asx_parser_free(parser); - return false; - } - - buffer = asx_body; - while(buffer && buffer[0] != '\0') { - r = asx_get_element(parser,&buffer,&element,&body,&attribs); - if(r < 0) { - asx_warning_body_parse_error(parser,"ASX"); - asx_parser_free(parser); - return false; - } else if (r == 0) { // No more element - break; - } - if(strcasecmp(element,"ENTRY") == 0) { - asx_parse_entry(parser,body,attribs); - } else if(strcasecmp(element,"ENTRYREF") == 0) { - asx_parse_entryref(parser,body,attribs); - } else if(strcasecmp(element,"REPEAT") == 0) { - asx_parse_repeat(parser,body,attribs); - } else - mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Ignoring element %s\n",element); - free(body); - asx_free_attribs(attribs); - } - - free(asx_body); - asx_free_attribs(asx_attribs); - asx_parser_free(parser); - return true; -} diff --git a/mpvcore/asxparser.h b/mpvcore/asxparser.h deleted file mode 100644 index e49a2cedc0..0000000000 --- a/mpvcore/asxparser.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MPLAYER_ASXPARSER_H -#define MPLAYER_ASXPARSER_H - -#include - -struct playlist; -bool asx_parse(char* buffer, struct playlist *pl); - -#endif /* MPLAYER_ASXPARSER_H */ diff --git a/mpvcore/av_common.c b/mpvcore/av_common.c deleted file mode 100644 index 823c825517..0000000000 --- a/mpvcore/av_common.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * This file is part of mpv. - * - * mpv 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. - * - * mpv 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 mpv. If not, see . - */ - -#include - -#include -#include - -#include "mpvcore/mp_common.h" -#include "mpvcore/mp_msg.h" -#include "demux/packet.h" -#include "av_common.h" -#include "codecs.h" - -#include "osdep/numcores.h" - - -// Copy the codec-related fields from st into avctx. This does not set the -// codec itself, only codec related header data provided by libavformat. -// The goal is to initialize a new decoder with the header data provided by -// libavformat, and unlike avcodec_copy_context(), allow the user to create -// a clean AVCodecContext for a manually selected AVCodec. -// This is strictly for decoding only. -void mp_copy_lav_codec_headers(AVCodecContext *avctx, AVCodecContext *st) -{ - if (st->extradata_size) { - av_free(avctx->extradata); - avctx->extradata_size = 0; - avctx->extradata = - av_mallocz(st->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (avctx->extradata) { - avctx->extradata_size = st->extradata_size; - memcpy(avctx->extradata, st->extradata, st->extradata_size); - } - } - avctx->codec_tag = st->codec_tag; - avctx->stream_codec_tag = st->stream_codec_tag; - avctx->bit_rate = st->bit_rate; - avctx->width = st->width; - avctx->height = st->height; - avctx->pix_fmt = st->pix_fmt; - avctx->sample_aspect_ratio = st->sample_aspect_ratio; - avctx->chroma_sample_location = st->chroma_sample_location; - avctx->sample_rate = st->sample_rate; - avctx->channels = st->channels; - avctx->block_align = st->block_align; - avctx->channel_layout = st->channel_layout; - avctx->audio_service_type = st->audio_service_type; - avctx->bits_per_coded_sample = st->bits_per_coded_sample; -} - -// We merely pass-through our PTS/DTS as an int64_t; libavcodec won't use it. -union pts { int64_t i; double d; }; - -// Convert the mpv style timestamp (seconds as double) to a libavcodec style -// timestamp (integer units in a given timebase). -// -// If the given timebase is NULL or invalid, pass through the mpv timestamp by -// reinterpret casting them to int64_t. In this case, the timestamps will be -// non-sense for libavcodec, but we expect that it doesn't interpret them, -// and treats them as opaque. -int64_t mp_pts_to_av(double mp_pts, AVRational *tb) -{ - assert(sizeof(int64_t) >= sizeof(double)); - if (tb && tb->num > 0 && tb->den > 0) - return mp_pts == MP_NOPTS_VALUE ? AV_NOPTS_VALUE : mp_pts / av_q2d(*tb); - // The + 0.0 is to squash possible negative zero mp_pts, which would - // happen to end up as AV_NOPTS_VALUE. - return (union pts){.d = mp_pts + 0.0}.i; -} - -// Inverse of mp_pts_to_av(). (The timebases must be exactly the same.) -double mp_pts_from_av(int64_t av_pts, AVRational *tb) -{ - assert(sizeof(int64_t) >= sizeof(double)); - if (tb && tb->num > 0 && tb->den > 0) - return av_pts == AV_NOPTS_VALUE ? MP_NOPTS_VALUE : av_pts * av_q2d(*tb); - // Should libavcodec set the PTS to AV_NOPTS_VALUE, it would end up as - // non-sense (usually negative zero) when unwrapped to double. - return av_pts == AV_NOPTS_VALUE ? MP_NOPTS_VALUE : (union pts){.i = av_pts}.d; -} - -// Set dst from mpkt. Note that dst is not refcountable. -// mpkt can be NULL to generate empty packets (used to flush delayed data). -// Sets pts/dts using mp_pts_to_av(ts, tb). (Be aware of the implications.) -// Set duration field only if tb is set. -void mp_set_av_packet(AVPacket *dst, struct demux_packet *mpkt, AVRational *tb) -{ - av_init_packet(dst); - dst->data = mpkt ? mpkt->buffer : NULL; - dst->size = mpkt ? mpkt->len : 0; - /* Some codecs (ZeroCodec, some cases of PNG) may want keyframe info - * from demuxer. */ - if (mpkt && mpkt->keyframe) - dst->flags |= AV_PKT_FLAG_KEY; - if (mpkt && mpkt->avpacket) { - dst->side_data = mpkt->avpacket->side_data; - dst->side_data_elems = mpkt->avpacket->side_data_elems; - } - if (mpkt && tb && tb->num > 0 && tb->den > 0) - dst->duration = mpkt->duration / av_q2d(*tb); - dst->pts = mp_pts_to_av(mpkt ? mpkt->pts : MP_NOPTS_VALUE, tb); - dst->dts = mp_pts_to_av(mpkt ? mpkt->dts : MP_NOPTS_VALUE, tb); -} - -void mp_set_avcodec_threads(AVCodecContext *avctx, int threads) -{ - if (threads == 0) { - threads = default_thread_count(); - if (threads < 1) { - mp_msg(MSGT_GLOBAL, MSGL_WARN, "Could not determine " - "thread count to use, defaulting to 1.\n"); - threads = 1; - } - // Apparently some libavcodec versions have or had trouble with more - // than 16 threads, and/or print a warning when using > 16. - threads = MPMIN(threads, 16); - } - avctx->thread_count = threads; -} - -void mp_add_lavc_decoders(struct mp_decoder_list *list, enum AVMediaType type) -{ - AVCodec *cur = NULL; - for (;;) { - cur = av_codec_next(cur); - if (!cur) - break; - if (av_codec_is_decoder(cur) && cur->type == type) { - mp_add_decoder(list, "lavc", mp_codec_from_av_codec_id(cur->id), - cur->name, cur->long_name); - } - } -} - -int mp_codec_to_av_codec_id(const char *codec) -{ - int id = AV_CODEC_ID_NONE; - if (codec) { - const AVCodecDescriptor *desc = avcodec_descriptor_get_by_name(codec); - if (desc) - id = desc->id; - if (id == AV_CODEC_ID_NONE) { - AVCodec *avcodec = avcodec_find_decoder_by_name(codec); - if (avcodec) - id = avcodec->id; - } - } - return id; -} - -const char *mp_codec_from_av_codec_id(int codec_id) -{ - const char *name = NULL; - const AVCodecDescriptor *desc = avcodec_descriptor_get(codec_id); - if (desc) - name = desc->name; - if (!name) { - AVCodec *avcodec = avcodec_find_decoder(codec_id); - if (avcodec) - name = avcodec->name; - } - return name; -} diff --git a/mpvcore/av_common.h b/mpvcore/av_common.h deleted file mode 100644 index 7bf2d64d9e..0000000000 --- a/mpvcore/av_common.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of mpv. - * - * mpv 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. - * - * mpv 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 mpv. If not, see . - */ - -#ifndef MP_AVCOMMON_H -#define MP_AVCOMMON_H - -#include - -#include -#include -#include - -struct mp_decoder_list; -struct demux_packet; - -void mp_copy_lav_codec_headers(AVCodecContext *avctx, AVCodecContext *st); -void mp_set_av_packet(AVPacket *dst, struct demux_packet *mpkt, AVRational *tb); -int64_t mp_pts_to_av(double mp_pts, AVRational *tb); -double mp_pts_from_av(int64_t av_pts, AVRational *tb); -void mp_set_avcodec_threads(AVCodecContext *avctx, int threads); -void mp_add_lavc_decoders(struct mp_decoder_list *list, enum AVMediaType type); -int mp_codec_to_av_codec_id(const char *codec); -const char *mp_codec_from_av_codec_id(int codec_id); - -#endif diff --git a/mpvcore/av_log.c b/mpvcore/av_log.c deleted file mode 100644 index ca3ef70747..0000000000 --- a/mpvcore/av_log.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * av_log to mp_msg converter - * Copyright (C) 2006 Michael Niedermayer - * Copyright (C) 2009 Uoti Urpala - * - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include - -#include "av_log.h" -#include "config.h" -#include "mpvcore/mp_msg.h" -#include -#include - -#include -#include -#include - -#if HAVE_LIBAVDEVICE -#include -#endif - -#if HAVE_LIBAVFILTER -#include -#endif - -#if HAVE_LIBAVRESAMPLE -#include -#endif -#if HAVE_LIBSWRESAMPLE -#include -#endif - -static int av_log_level_to_mp_level(int av_level) -{ - if (av_level > AV_LOG_VERBOSE) - return MSGL_DBG2; - if (av_level > AV_LOG_INFO) - return MSGL_V; - if (av_level > AV_LOG_WARNING) - return MSGL_V; - if (av_level > AV_LOG_ERROR) - return MSGL_WARN; - if (av_level > AV_LOG_FATAL) - return MSGL_ERR; - return MSGL_FATAL; -} - -static int extract_msg_type_from_ctx(void *ptr) -{ - if (!ptr) - return MSGT_FIXME; - - AVClass *avc = *(AVClass **)ptr; - if (!avc) { - mp_msg(MSGT_FIXME, MSGL_WARN, - "av_log callback called with bad parameters (NULL AVClass).\n" - "This is a bug in one of Libav/FFmpeg libraries used.\n"); - return MSGT_FIXME; - } - - if (!strcmp(avc->class_name, "AVCodecContext")) { - AVCodecContext *s = ptr; - if (s->codec) { - if (s->codec->type == AVMEDIA_TYPE_AUDIO) { - if (s->codec->decode) - return MSGT_DECAUDIO; - } else if (s->codec->type == AVMEDIA_TYPE_VIDEO) { - if (s->codec->decode) - return MSGT_DECVIDEO; - } - // FIXME subtitles, encoders - // What msgt for them? There is nothing appropriate... - } - return MSGT_FIXME; - } - - if (!strcmp(avc->class_name, "AVFormatContext")) { - AVFormatContext *s = ptr; - if (s->iformat) - return MSGT_DEMUXER; - else if (s->oformat) - return MSGT_MUXER; - return MSGT_FIXME; - } - - return MSGT_FIXME; -} - -#if LIBAVCODEC_VERSION_MICRO >= 100 -#define LIB_PREFIX "ffmpeg" -#else -#define LIB_PREFIX "libav" -#endif - -static bool print_prefix = true; - -static void mp_msg_av_log_callback(void *ptr, int level, const char *fmt, - va_list vl) -{ - AVClass *avc = ptr ? *(AVClass **)ptr : NULL; - int mp_level = av_log_level_to_mp_level(level); - int type = extract_msg_type_from_ctx(ptr); - - if (!mp_msg_test(type, mp_level)) - return; - - if (print_prefix) { - mp_msg(type, mp_level, "[%s/%s] ", LIB_PREFIX, - avc ? avc->item_name(ptr) : "?"); - } - print_prefix = fmt[strlen(fmt) - 1] == '\n'; - - mp_msg_va(type, mp_level, fmt, vl); -} - -void init_libav(void) -{ - av_log_set_callback(mp_msg_av_log_callback); - avcodec_register_all(); - av_register_all(); - avformat_network_init(); - -#if HAVE_LIBAVFILTER - avfilter_register_all(); -#endif -#if HAVE_LIBAVDEVICE - avdevice_register_all(); -#endif -} - -#define V(x) (x)>>16, (x)>>8 & 255, (x) & 255 -static void print_version(int v, char *name, unsigned buildv, unsigned runv) -{ - mp_msg(MSGT_CPLAYER, v, " %-15s %d.%d.%d", name, V(buildv)); - if (buildv != runv) - mp_msg(MSGT_CPLAYER, v, " (runtime %d.%d.%d)", V(runv)); - mp_msg(MSGT_CPLAYER, v, "\n"); -} -#undef V - -void print_libav_versions(int v) -{ - mp_msg(MSGT_CPLAYER, v, "%s library versions:\n", LIB_PREFIX); - - print_version(v, "libavutil", LIBAVUTIL_VERSION_INT, avutil_version()); - print_version(v, "libavcodec", LIBAVCODEC_VERSION_INT, avcodec_version()); - print_version(v, "libavformat", LIBAVFORMAT_VERSION_INT, avformat_version()); - print_version(v, "libswscale", LIBSWSCALE_VERSION_INT, swscale_version()); -#if HAVE_LIBAVFILTER - print_version(v, "libavfilter", LIBAVFILTER_VERSION_INT, avfilter_version()); -#endif -#if HAVE_LIBAVRESAMPLE - print_version(v, "libavresample", LIBAVRESAMPLE_VERSION_INT, avresample_version()); -#endif -#if HAVE_LIBSWRESAMPLE - print_version(v, "libswresample", LIBSWRESAMPLE_VERSION_INT, swresample_version()); -#endif -} diff --git a/mpvcore/av_log.h b/mpvcore/av_log.h deleted file mode 100644 index d5c57b0aeb..0000000000 --- a/mpvcore/av_log.h +++ /dev/null @@ -1,2 +0,0 @@ -void init_libav(void); -void print_libav_versions(int v); diff --git a/mpvcore/av_opts.c b/mpvcore/av_opts.c deleted file mode 100644 index 777a1eec5a..0000000000 --- a/mpvcore/av_opts.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * AVOption parsing helper - * Copyright (C) 2008 Michael Niedermayer - * - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include - -#include - -#include "av_opts.h" - -int parse_avopts(void *v, char *str){ - char *start; - - if (!str) - return 0; - - start= str= strdup(str); - - while(str && *str){ - char *next_opt, *arg; - - next_opt= strchr(str, ','); - if(next_opt) *next_opt++= 0; - - arg = strchr(str, '='); - if(arg) *arg++= 0; - - if (av_opt_set(v, str, arg, AV_OPT_SEARCH_CHILDREN) < 0) { - free(start); - return -1; - } - str= next_opt; - } - - free(start); - return 0; -} diff --git a/mpvcore/av_opts.h b/mpvcore/av_opts.h deleted file mode 100644 index 640443a352..0000000000 --- a/mpvcore/av_opts.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * AVOption parsing helper - * Copyright (C) 2008 Michael Niedermayer - * - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MPLAYER_AV_OPTS_H -#define MPLAYER_AV_OPTS_H - -/** - * Parses str and sets AVOptions in v accordingly. - */ -int parse_avopts(void *v, char *str); - -#endif /* MPLAYER_AV_OPTS_H */ diff --git a/mpvcore/bstr.c b/mpvcore/bstr.c deleted file mode 100644 index 996edb7dfe..0000000000 --- a/mpvcore/bstr.c +++ /dev/null @@ -1,385 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include -#include -#include - -#include - -#include "talloc.h" - -#include "mpvcore/bstr.h" - -int bstrcmp(struct bstr str1, struct bstr str2) -{ - int ret = memcmp(str1.start, str2.start, FFMIN(str1.len, str2.len)); - - if (!ret) { - if (str1.len == str2.len) - return 0; - else if (str1.len > str2.len) - return 1; - else - return -1; - } - return ret; -} - -int bstrcasecmp(struct bstr str1, struct bstr str2) -{ - int ret = strncasecmp(str1.start, str2.start, FFMIN(str1.len, str2.len)); - - if (!ret) { - if (str1.len == str2.len) - return 0; - else if (str1.len > str2.len) - return 1; - else - return -1; - } - return ret; -} - -int bstrchr(struct bstr str, int c) -{ - for (int i = 0; i < str.len; i++) - if (str.start[i] == c) - return i; - return -1; -} - -int bstrrchr(struct bstr str, int c) -{ - for (int i = str.len - 1; i >= 0; i--) - if (str.start[i] == c) - return i; - return -1; -} - -int bstrcspn(struct bstr str, const char *reject) -{ - int i; - for (i = 0; i < str.len; i++) - if (strchr(reject, str.start[i])) - break; - return i; -} - -int bstrspn(struct bstr str, const char *accept) -{ - int i; - for (i = 0; i < str.len; i++) - if (!strchr(accept, str.start[i])) - break; - return i; -} - -int bstr_find(struct bstr haystack, struct bstr needle) -{ - for (int i = 0; i < haystack.len; i++) - if (bstr_startswith(bstr_splice(haystack, i, haystack.len), needle)) - return i; - return -1; -} - -struct bstr bstr_lstrip(struct bstr str) -{ - while (str.len && isspace(*str.start)) { - str.start++; - str.len--; - } - return str; -} - -struct bstr bstr_strip(struct bstr str) -{ - str = bstr_lstrip(str); - while (str.len && isspace(str.start[str.len - 1])) - str.len--; - return str; -} - -struct bstr bstr_split(struct bstr str, const char *sep, struct bstr *rest) -{ - int start; - for (start = 0; start < str.len; start++) - if (!strchr(sep, str.start[start])) - break; - str = bstr_cut(str, start); - int end = bstrcspn(str, sep); - if (rest) { - *rest = bstr_cut(str, end); - } - return bstr_splice(str, 0, end); -} - -// Unlike with bstr_split(), tok is a string, and not a set of char. -// If tok is in str, return true, and: concat(out_left, tok, out_right) == str -// Otherwise, return false, and set out_left==str, out_right=="" -bool bstr_split_tok(bstr str, const char *tok, bstr *out_left, bstr *out_right) -{ - bstr bsep = bstr0(tok); - int pos = bstr_find(str, bsep); - if (pos < 0) - pos = str.len; - *out_left = bstr_splice(str, 0, pos); - *out_right = bstr_cut(str, pos + bsep.len); - return pos != str.len; -} - -struct bstr bstr_splice(struct bstr str, int start, int end) -{ - if (start < 0) - start += str.len; - if (end < 0) - end += str.len; - end = FFMIN(end, str.len); - start = FFMAX(start, 0); - end = FFMAX(end, start); - str.start += start; - str.len = end - start; - return str; -} - -long long bstrtoll(struct bstr str, struct bstr *rest, int base) -{ - str = bstr_lstrip(str); - char buf[51]; - int len = FFMIN(str.len, 50); - memcpy(buf, str.start, len); - buf[len] = 0; - char *endptr; - long long r = strtoll(buf, &endptr, base); - if (rest) - *rest = bstr_cut(str, endptr - buf); - return r; -} - -double bstrtod(struct bstr str, struct bstr *rest) -{ - str = bstr_lstrip(str); - char buf[101]; - int len = FFMIN(str.len, 100); - memcpy(buf, str.start, len); - buf[len] = 0; - char *endptr; - double r = strtod(buf, &endptr); - if (rest) - *rest = bstr_cut(str, endptr - buf); - return r; -} - -struct bstr *bstr_splitlines(void *talloc_ctx, struct bstr str) -{ - if (str.len == 0) - return NULL; - int count = 0; - for (int i = 0; i < str.len; i++) - if (str.start[i] == '\n') - count++; - if (str.start[str.len - 1] != '\n') - count++; - struct bstr *r = talloc_array_ptrtype(talloc_ctx, r, count); - unsigned char *p = str.start; - for (int i = 0; i < count - 1; i++) { - r[i].start = p; - while (*p++ != '\n'); - r[i].len = p - r[i].start; - } - r[count - 1].start = p; - r[count - 1].len = str.start + str.len - p; - return r; -} - -struct bstr bstr_getline(struct bstr str, struct bstr *rest) -{ - int pos = bstrchr(str, '\n'); - if (pos < 0) - pos = str.len; - if (rest) - *rest = bstr_cut(str, pos + 1); - return bstr_splice(str, 0, pos + 1); -} - -struct bstr bstr_strip_linebreaks(struct bstr str) -{ - if (bstr_endswith0(str, "\r\n")) { - str = bstr_splice(str, 0, str.len - 2); - } else if (bstr_endswith0(str, "\n")) { - str = bstr_splice(str, 0, str.len - 1); - } - return str; -} - -bool bstr_eatstart(struct bstr *s, struct bstr prefix) -{ - if (!bstr_startswith(*s, prefix)) - return false; - *s = bstr_cut(*s, prefix.len); - return true; -} - -void bstr_lower(struct bstr str) -{ - for (int i = 0; i < str.len; i++) - str.start[i] = tolower(str.start[i]); -} - -int bstr_sscanf(struct bstr str, const char *format, ...) -{ - char *ptr = bstrdup0(NULL, str); - va_list va; - va_start(va, format); - int ret = vsscanf(ptr, format, va); - va_end(va); - talloc_free(ptr); - return ret; -} - -int bstr_parse_utf8_code_length(unsigned char b) -{ - if (b < 128) - return 1; - int bytes = 7 - av_log2(b ^ 255); - return (bytes >= 2 && bytes <= 4) ? bytes : -1; -} - -int bstr_decode_utf8(struct bstr s, struct bstr *out_next) -{ - if (s.len == 0) - return -1; - unsigned int codepoint = s.start[0]; - s.start++; s.len--; - if (codepoint >= 128) { - int bytes = bstr_parse_utf8_code_length(codepoint); - if (bytes < 0 || s.len < bytes - 1) - return -1; - codepoint &= 127 >> bytes; - for (int n = 1; n < bytes; n++) { - int tmp = (unsigned char)s.start[0]; - if ((tmp & 0xC0) != 0x80) - return -1; - codepoint = (codepoint << 6) | (tmp & ~0xC0); - s.start++; s.len--; - } - if (codepoint > 0x10FFFF || (codepoint >= 0xD800 && codepoint <= 0xDFFF)) - return -1; - // Overlong sequences - check taken from libavcodec. - // (The only reason we even bother with this is to make libavcodec's - // retarded subtitle utf-8 check happy.) - unsigned int min = bytes == 2 ? 0x80 : 1 << (5 * bytes - 4); - if (codepoint < min) - return -1; - } - if (out_next) - *out_next = s; - return codepoint; -} - -int bstr_validate_utf8(struct bstr s) -{ - while (s.len) { - if (bstr_decode_utf8(s, &s) < 0) { - // Try to guess whether the sequence was just cut-off. - unsigned int codepoint = (unsigned char)s.start[0]; - int bytes = bstr_parse_utf8_code_length(codepoint); - if (bytes > 1 && s.len < 6) { - // Manually check validity of left bytes - for (int n = 1; n < bytes; n++) { - if (n >= s.len) { - // Everything valid until now - just cut off. - return -(bytes - s.len); - } - int tmp = (unsigned char)s.start[n]; - if ((tmp & 0xC0) != 0x80) - break; - } - } - return -8; - } - } - return 0; -} - -static void append_bstr(bstr *buf, bstr s) -{ - buf->start = talloc_realloc(NULL, buf->start, unsigned char, buf->len + s.len); - memcpy(buf->start + buf->len, s.start, s.len); - buf->len += s.len; -} - -struct bstr bstr_sanitize_utf8_latin1(void *talloc_ctx, struct bstr s) -{ - bstr new = {0}; - bstr left = s; - unsigned char *first_ok = s.start; - while (left.len) { - int r = bstr_decode_utf8(left, &left); - if (r < 0) { - append_bstr(&new, (bstr){first_ok, left.start - first_ok}); - uint32_t codepoint = (unsigned char)left.start[0]; - char data[8]; - uint8_t tmp; - char *output = data; - PUT_UTF8(codepoint, tmp, *output++ = tmp;); - append_bstr(&new, (bstr){data, output - data}); - left.start += 1; - left.len -= 1; - first_ok = left.start; - } - } - if (!new.start) - return s; - if (first_ok != left.start) - append_bstr(&new, (bstr){first_ok, left.start - first_ok}); - // For convenience - append_bstr(&new, (bstr){"\0", 1}); - new.len -= 1; - talloc_steal(talloc_ctx, new.start); - return new; -} - -bool bstr_case_startswith(struct bstr s, struct bstr prefix) -{ - struct bstr start = bstr_splice(s, 0, prefix.len); - return start.len == prefix.len && bstrcasecmp(start, prefix) == 0; -} - -bool bstr_case_endswith(struct bstr s, struct bstr suffix) -{ - struct bstr end = bstr_cut(s, -suffix.len); - return end.len == suffix.len && bstrcasecmp(end, suffix) == 0; -} - -struct bstr bstr_strip_ext(struct bstr str) -{ - int dotpos = bstrrchr(str, '.'); - if (dotpos < 0) - return str; - return (struct bstr){str.start, dotpos}; -} - -struct bstr bstr_get_ext(struct bstr s) -{ - int dotpos = bstrrchr(s, '.'); - if (dotpos < 0) - return (struct bstr){NULL, 0}; - return bstr_splice(s, dotpos + 1, s.len); -} diff --git a/mpvcore/bstr.h b/mpvcore/bstr.h deleted file mode 100644 index 67e85655c4..0000000000 --- a/mpvcore/bstr.h +++ /dev/null @@ -1,200 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MPLAYER_BSTR_H -#define MPLAYER_BSTR_H - -#include -#include -#include -#include - -#include "talloc.h" - -/* NOTE: 'len' is size_t, but most string-handling functions below assume - * that input size has been sanity checked and len fits in an int. - */ -typedef struct bstr { - unsigned char *start; - size_t len; -} bstr; - -// If str.start is NULL, return NULL. -static inline char *bstrdup0(void *talloc_ctx, struct bstr str) -{ - return talloc_strndup(talloc_ctx, (char *)str.start, str.len); -} - -// Like bstrdup0(), but always return a valid C-string. -static inline char *bstrto0(void *talloc_ctx, struct bstr str) -{ - return str.start ? bstrdup0(talloc_ctx, str) : talloc_strdup(talloc_ctx, ""); -} - -// Return start = NULL iff that is true for the original. -static inline struct bstr bstrdup(void *talloc_ctx, struct bstr str) -{ - struct bstr r = { NULL, str.len }; - if (str.start) - r.start = (unsigned char *)talloc_memdup(talloc_ctx, str.start, str.len); - return r; -} - -static inline struct bstr bstr0(const char *s) -{ - return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0}; -} - -int bstrcmp(struct bstr str1, struct bstr str2); -int bstrcasecmp(struct bstr str1, struct bstr str2); -int bstrchr(struct bstr str, int c); -int bstrrchr(struct bstr str, int c); -int bstrspn(struct bstr str, const char *accept); -int bstrcspn(struct bstr str, const char *reject); - -int bstr_find(struct bstr haystack, struct bstr needle); -struct bstr *bstr_splitlines(void *talloc_ctx, struct bstr str); -struct bstr bstr_lstrip(struct bstr str); -struct bstr bstr_strip(struct bstr str); -struct bstr bstr_split(struct bstr str, const char *sep, struct bstr *rest); -bool bstr_split_tok(bstr str, const char *tok, bstr *out_left, bstr *out_right); -struct bstr bstr_splice(struct bstr str, int start, int end); -long long bstrtoll(struct bstr str, struct bstr *rest, int base); -double bstrtod(struct bstr str, struct bstr *rest); -void bstr_lower(struct bstr str); -int bstr_sscanf(struct bstr str, const char *format, ...); - -// Decode the UTF-8 code point at the start of the string,, and return the -// character. -// After calling this function, *out_next will point to the next character. -// out_next can be NULL. -// On error, -1 is returned, and *out_next is not modified. -int bstr_decode_utf8(struct bstr str, struct bstr *out_next); - -// Return the length of the UTF-8 sequence that starts with the given byte. -// Given a string char *s, the next UTF-8 code point is to be expected at -// s + bstr_parse_utf8_code_length(s[0]) -// On error, -1 is returned. On success, it returns a value in the range [1, 4]. -int bstr_parse_utf8_code_length(unsigned char b); - -// Return >= 0 if the string is valid UTF-8, otherwise negative error code. -// Embedded \0 bytes are considered valid. -// This returns -N if the UTF-8 string was likely just cut-off in the middle of -// an UTF-8 sequence: -1 means 1 byte was missing, -5 5 bytes missing. -// If the string was likely not cut off, -8 is returned. -// Use (return_value > -8) to check whether the string is valid UTF-8 or valid -// but cut-off UTF-8. -int bstr_validate_utf8(struct bstr s); - -// Force the input string to valid UTF-8. If invalid UTF-8 encoding is -// encountered, the invalid bytes are interpreted as Latin-1. -// Embedded \0 bytes are considered valid. -// If replacement happens, a newly allocated string is returned (with a \0 -// byte added past its end for convenience). The string is allocated via -// talloc, with talloc_ctx as parent. -struct bstr bstr_sanitize_utf8_latin1(void *talloc_ctx, struct bstr s); - -// Return the text before the next line break, and return it. Change *rest to -// point to the text following this line break. (rest can be NULL.) -// Line break characters are not stripped. -struct bstr bstr_getline(struct bstr str, struct bstr *rest); - -// Strip one trailing line break. This is intended for use with bstr_getline, -// and will remove the trailing \n or \r\n sequence. -struct bstr bstr_strip_linebreaks(struct bstr str); - -// If s starts with prefix, return true and return the rest of the string in s. -bool bstr_eatstart(struct bstr *s, struct bstr prefix); - -bool bstr_case_startswith(struct bstr s, struct bstr prefix); -bool bstr_case_endswith(struct bstr s, struct bstr suffix); -struct bstr bstr_strip_ext(struct bstr str); -struct bstr bstr_get_ext(struct bstr s); - -static inline struct bstr bstr_cut(struct bstr str, int n) -{ - if (n < 0) { - n += str.len; - if (n < 0) - n = 0; - } - if (((size_t)n) > str.len) - n = str.len; - return (struct bstr){str.start + n, str.len - n}; -} - -static inline bool bstr_startswith(struct bstr str, struct bstr prefix) -{ - if (str.len < prefix.len) - return false; - return !memcmp(str.start, prefix.start, prefix.len); -} - -static inline bool bstr_startswith0(struct bstr str, const char *prefix) -{ - return bstr_startswith(str, bstr0(prefix)); -} - -static inline bool bstr_endswith(struct bstr str, struct bstr suffix) -{ - if (str.len < suffix.len) - return false; - return !memcmp(str.start + str.len - suffix.len, suffix.start, suffix.len); -} - -static inline bool bstr_endswith0(struct bstr str, const char *suffix) -{ - return bstr_endswith(str, bstr0(suffix)); -} - -static inline int bstrcmp0(struct bstr str1, const char *str2) -{ - return bstrcmp(str1, bstr0(str2)); -} - -static inline bool bstr_equals(struct bstr str1, struct bstr str2) -{ - return bstrcmp(str1, str2) == 0; -} - -static inline bool bstr_equals0(struct bstr str1, const char *str2) -{ - return bstrcmp(str1, bstr0(str2)) == 0; -} - -static inline int bstrcasecmp0(struct bstr str1, const char *str2) -{ - return bstrcasecmp(str1, bstr0(str2)); -} - -static inline int bstr_find0(struct bstr haystack, const char *needle) -{ - return bstr_find(haystack, bstr0(needle)); -} - -static inline int bstr_eatstart0(struct bstr *s, const char *prefix) -{ - return bstr_eatstart(s, bstr0(prefix)); -} - -// create a pair (not single value!) for "%.*s" printf syntax -#define BSTR_P(bstr) (int)((bstr).len), (bstr).start - -#define WHITESPACE " \f\n\r\t\v" - -#endif /* MPLAYER_BSTR_H */ diff --git a/mpvcore/charset_conv.c b/mpvcore/charset_conv.c deleted file mode 100644 index 3a6ff67330..0000000000 --- a/mpvcore/charset_conv.c +++ /dev/null @@ -1,287 +0,0 @@ -/* - * This file is part of mpv. - * - * Based on code taken from libass (ISC license), which was originally part - * of MPlayer (GPL). - * Copyright (C) 2006 Evgeniy Stepanov - * - * mpv 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. - * - * mpv 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 mpv. If not, see . - */ - -#include -#include -#include - -#include "config.h" - -#include "mpvcore/mp_msg.h" - -#if HAVE_ENCA -#include -#endif - -#if HAVE_LIBGUESS -#include -#endif - -#if HAVE_ICONV -#include -#endif - -#include "charset_conv.h" - -bool mp_charset_is_utf8(const char *user_cp) -{ - return user_cp && (strcasecmp(user_cp, "utf8") == 0 || - strcasecmp(user_cp, "utf-8") == 0); -} - -// Split the string on ':' into components. -// out_arr is at least max entries long. -// Return number of out_arr entries filled. -static int split_colon(const char *user_cp, int max, bstr *out_arr) -{ - if (!user_cp || max < 1) - return 0; - - int count = 0; - while (1) { - const char *next = strchr(user_cp, ':'); - if (next && max - count > 1) { - out_arr[count++] = (bstr){(char *)user_cp, next - user_cp}; - user_cp = next + 1; - } else { - out_arr[count++] = (bstr){(char *)user_cp, strlen(user_cp)}; - break; - } - } - return count; -} - -// Returns true if user_cp implies that calling mp_charset_guess() on the -// input data is required to determine the real codepage. This is the case -// if user_cp is not a real iconv codepage, but a magic value that requests -// for example ENCA charset auto-detection. -bool mp_charset_requires_guess(const char *user_cp) -{ - bstr res[2] = {{0}}; - int r = split_colon(user_cp, 2, res); - // Note that "utf8" is the UTF-8 codepage, while "utf8:..." specifies UTF-8 - // by default, plus a codepage that is used if the input is not UTF-8. - return bstrcasecmp0(res[0], "enca") == 0 || - bstrcasecmp0(res[0], "guess") == 0 || - (r > 1 && bstrcasecmp0(res[0], "utf-8") == 0) || - (r > 1 && bstrcasecmp0(res[0], "utf8") == 0); -} - -#if HAVE_ENCA -static const char *enca_guess(bstr buf, const char *language) -{ - if (!language || !language[0]) - language = "__"; // neutral language - - const char *detected_cp = NULL; - - EncaAnalyser analyser = enca_analyser_alloc(language); - if (analyser) { - enca_set_termination_strictness(analyser, 0); - EncaEncoding enc = enca_analyse_const(analyser, buf.start, buf.len); - const char *tmp = enca_charset_name(enc.charset, ENCA_NAME_STYLE_ICONV); - if (tmp && enc.charset != ENCA_CS_UNKNOWN) - detected_cp = tmp; - enca_analyser_free(analyser); - } else { - mp_msg(MSGT_SUBREADER, MSGL_ERR, "ENCA doesn't know language '%s'\n", - language); - size_t langcnt; - const char **languages = enca_get_languages(&langcnt); - mp_msg(MSGT_SUBREADER, MSGL_ERR, "ENCA supported languages:"); - for (int i = 0; i < langcnt; i++) - mp_msg(MSGT_SUBREADER, MSGL_ERR, " %s", languages[i]); - mp_msg(MSGT_SUBREADER, MSGL_ERR, "\n"); - free(languages); - } - - return detected_cp; -} -#endif - -#if HAVE_LIBGUESS -static const char *libguess_guess(bstr buf, const char *language) -{ - if (!language || !language[0] || strcmp(language, "help") == 0) { - mp_msg(MSGT_SUBREADER, MSGL_ERR, "libguess needs a language: " - "japanese taiwanese chinese korean russian arabic turkish " - "greek hebrew polish baltic\n"); - return NULL; - } - - return libguess_determine_encoding(buf.start, buf.len, language); -} -#endif - -// Runs charset auto-detection on the input buffer, and returns the result. -// If auto-detection fails, NULL is returned. -// If user_cp doesn't refer to any known auto-detection (for example because -// it's a real iconv codepage), user_cp is returned without even looking at -// the buf data. -const char *mp_charset_guess(bstr buf, const char *user_cp, int flags) -{ - if (!mp_charset_requires_guess(user_cp)) - return user_cp; - - // Do our own UTF-8 detection, because at least ENCA seems to get it - // wrong sometimes (suggested by divVerent). - int r = bstr_validate_utf8(buf); - if (r >= 0 || (r > -8 && (flags & MP_ICONV_ALLOW_CUTOFF))) - return "UTF-8"; - - bstr params[3] = {{0}}; - split_colon(user_cp, 3, params); - - bstr type = params[0]; - char lang[100]; - snprintf(lang, sizeof(lang), "%.*s", BSTR_P(params[1])); - const char *fallback = params[2].start; // last item, already 0-terminated - - const char *res = NULL; - -#if HAVE_ENCA - if (bstrcasecmp0(type, "enca") == 0) - res = enca_guess(buf, lang); -#endif -#if HAVE_LIBGUESS - if (bstrcasecmp0(type, "guess") == 0) - res = libguess_guess(buf, lang); -#endif - if (bstrcasecmp0(type, "utf8") == 0 || bstrcasecmp0(type, "utf-8") == 0) { - if (!fallback) - fallback = params[1].start; // must be already 0-terminated - } - - if (res) { - mp_msg(MSGT_SUBREADER, MSGL_DBG2, "%.*s detected charset: '%s'\n", - BSTR_P(type), res); - } else { - res = fallback; - mp_msg(MSGT_SUBREADER, MSGL_DBG2, - "Detection with %.*s failed: fallback to %s\n", - BSTR_P(type), res && res[0] ? res : "broken UTF-8/Latin1"); - } - - if (!res && !(flags & MP_STRICT_UTF8)) - res = "UTF-8-BROKEN"; - - return res; -} - -// Convert the data in buf to UTF-8. The charset argument can be an iconv -// codepage, a value returned by mp_charset_conv_guess(), or a special value -// that triggers autodetection of the charset (e.g. using ENCA). -// The auto-detection is the only difference to mp_iconv_to_utf8(). -// buf: same as mp_iconv_to_utf8() -// user_cp: iconv codepage, special value, NULL -// flags: same as mp_iconv_to_utf8() -// returns: same as mp_iconv_to_utf8() -bstr mp_charset_guess_and_conv_to_utf8(bstr buf, const char *user_cp, int flags) -{ - return mp_iconv_to_utf8(buf, mp_charset_guess(buf, user_cp, flags), flags); -} - -// Use iconv to convert buf to UTF-8. -// Returns buf.start==NULL on error. Returns buf if cp is NULL, or if there is -// obviously no conversion required (e.g. if cp is "UTF-8"). -// Returns a newly allocated buffer if conversion is done and succeeds. The -// buffer will be terminated with 0 for convenience (the terminating 0 is not -// included in the returned length). -// Free the returned buffer with talloc_free(). -// buf: input data -// cp: iconv codepage (or NULL) -// flags: combination of MP_ICONV_* flags -// returns: buf (no conversion), .start==NULL (error), or allocated buffer -bstr mp_iconv_to_utf8(bstr buf, const char *cp, int flags) -{ -#if HAVE_ICONV - if (!cp || !cp[0] || mp_charset_is_utf8(cp)) - return buf; - - if (strcasecmp(cp, "ASCII") == 0) - return buf; - - if (strcasecmp(cp, "UTF-8-BROKEN") == 0) - return bstr_sanitize_utf8_latin1(NULL, buf); - - iconv_t icdsc; - if ((icdsc = iconv_open("UTF-8", cp)) == (iconv_t) (-1)) { - if (flags & MP_ICONV_VERBOSE) - mp_msg(MSGT_SUBREADER, MSGL_ERR, - "Error opening iconv with codepage '%s'\n", cp); - goto failure; - } - - size_t size = buf.len; - size_t osize = size; - size_t ileft = size; - size_t oleft = size - 1; - - char *outbuf = talloc_size(NULL, osize); - char *ip = buf.start; - char *op = outbuf; - - while (1) { - int clear = 0; - size_t rc; - if (ileft) - rc = iconv(icdsc, &ip, &ileft, &op, &oleft); - else { - clear = 1; // clear the conversion state and leave - rc = iconv(icdsc, NULL, NULL, &op, &oleft); - } - if (rc == (size_t) (-1)) { - if (errno == E2BIG) { - size_t offset = op - outbuf; - outbuf = talloc_realloc_size(NULL, outbuf, osize + size); - op = outbuf + offset; - osize += size; - oleft += size; - } else { - if (errno == EINVAL && (flags & MP_ICONV_ALLOW_CUTOFF)) { - // This is intended for cases where the input buffer is cut - // at a random byte position. If this happens in the middle - // of the buffer, it should still be an error. We say it's - // fine if the error is within 10 bytes of the end. - if (ileft <= 10) - break; - } - if (flags & MP_ICONV_VERBOSE) { - mp_msg(MSGT_SUBREADER, MSGL_ERR, - "Error recoding text with codepage '%s'\n", cp); - } - talloc_free(outbuf); - iconv_close(icdsc); - goto failure; - } - } else if (clear) - break; - } - - iconv_close(icdsc); - - outbuf[osize - oleft - 1] = 0; - return (bstr){outbuf, osize - oleft - 1}; -#endif - -failure: - return (bstr){0}; -} diff --git a/mpvcore/charset_conv.h b/mpvcore/charset_conv.h deleted file mode 100644 index 0b2874f0ec..0000000000 --- a/mpvcore/charset_conv.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef MP_CHARSET_CONV_H -#define MP_CHARSET_CONV_H - -#include -#include "mpvcore/bstr.h" - -enum { - MP_ICONV_VERBOSE = 1, // print errors instead of failing silently - MP_ICONV_ALLOW_CUTOFF = 2, // allow partial input data - MP_STRICT_UTF8 = 4, // don't fall back to UTF-8-BROKEN when guessing -}; - -bool mp_charset_is_utf8(const char *user_cp); -bool mp_charset_requires_guess(const char *user_cp); -const char *mp_charset_guess(bstr buf, const char *user_cp, int flags); -bstr mp_charset_guess_and_conv_to_utf8(bstr buf, const char *user_cp, int flags); -bstr mp_iconv_to_utf8(bstr buf, const char *cp, int flags); - -#endif diff --git a/mpvcore/codecs.c b/mpvcore/codecs.c deleted file mode 100644 index b5a07cf999..0000000000 --- a/mpvcore/codecs.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * This file is part of mpv. - * - * mpv 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. - * - * mpv 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 mpv. If not, see . - */ - -#include -#include "talloc.h" -#include "mpvcore/bstr.h" -#include "mpvcore/mp_msg.h" -#include "codecs.h" - -void mp_add_decoder(struct mp_decoder_list *list, const char *family, - const char *codec, const char *decoder, const char *desc) -{ - struct mp_decoder_entry entry = { - .family = talloc_strdup(list, family), - .codec = talloc_strdup(list, codec), - .decoder = talloc_strdup(list, decoder), - .desc = talloc_strdup(list, desc), - }; - MP_TARRAY_APPEND(list, list->entries, list->num_entries, entry); -} - -static void mp_add_decoder_entry(struct mp_decoder_list *list, - struct mp_decoder_entry *entry) -{ - mp_add_decoder(list, entry->family, entry->codec, entry->decoder, - entry->desc); -} - -static struct mp_decoder_entry *find_decoder(struct mp_decoder_list *list, - bstr family, bstr decoder) -{ - for (int n = 0; n < list->num_entries; n++) { - struct mp_decoder_entry *cur = &list->entries[n]; - if (bstr_equals0(decoder, cur->decoder) && - bstr_equals0(family, cur->family)) - return cur; - } - return NULL; -} - -// Add entry, but only if it's not yet on the list, and if the codec matches. -// If codec == NULL, don't compare codecs. -static void add_new(struct mp_decoder_list *to, struct mp_decoder_entry *entry, - const char *codec) -{ - if (!entry || (codec && strcmp(entry->codec, codec) != 0)) - return; - if (!find_decoder(to, bstr0(entry->family), bstr0(entry->decoder))) - mp_add_decoder_entry(to, entry); -} - -// Select a decoder from the given list for the given codec. The selection -// can be influenced by the selection string, which can specify a priority -// list of preferred decoders. -// This returns a list of decoders to try, with the preferred decoders first. -// The selection string corresponds to --vd/--ad directly, and has the -// following syntax: -// selection = [ ("," )*] -// entry = ":" // prefer decoder -// entry = ":*" // prefer all decoders -// entry = "+" ":" // force a decoder -// entry = "-" ":" // exclude a decoder -// entry = "-" // don't add fallback decoders -// Forcing a decoder means it's added even if the codec mismatches. -struct mp_decoder_list *mp_select_decoders(struct mp_decoder_list *all, - const char *codec, - const char *selection) -{ - struct mp_decoder_list *list = talloc_zero(NULL, struct mp_decoder_list); - struct mp_decoder_list *remove = talloc_zero(NULL, struct mp_decoder_list); - if (!codec) - codec = "unknown"; - bool stop = false; - bstr sel = bstr0(selection); - while (sel.len) { - bstr entry; - bstr_split_tok(sel, ",", &entry, &sel); - if (bstr_equals0(entry, "-")) { - stop = true; - break; - } - bool force = bstr_eatstart0(&entry, "+"); - bool exclude = !force && bstr_eatstart0(&entry, "-"); - struct mp_decoder_list *dest = exclude ? remove : list; - bstr family, decoder; - if (!bstr_split_tok(entry, ":", &family, &decoder)) { - mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Decoders must be specified as " - "'family:decoder' for the --ad/--vd options.\n"); - break; - } - if (bstr_equals0(decoder, "*")) { - for (int n = 0; n < all->num_entries; n++) { - struct mp_decoder_entry *cur = &all->entries[n]; - if (bstr_equals0(family, cur->family)) - add_new(dest, cur, codec); - } - } else { - add_new(dest, find_decoder(all, family, decoder), - force ? NULL : codec); - } - } - if (!stop) { - // Add the remaining codecs which haven't been added yet - for (int n = 0; n < all->num_entries; n++) - add_new(list, &all->entries[n], codec); - } - for (int n = 0; n < remove->num_entries; n++) { - struct mp_decoder_entry *ex = &remove->entries[n]; - struct mp_decoder_entry *del = - find_decoder(list, bstr0(ex->family), bstr0(ex->decoder)); - if (del) { - int index = del - &list->entries[0]; - MP_TARRAY_REMOVE_AT(list->entries, list->num_entries, index); - } - } - talloc_free(remove); - return list; -} - -void mp_print_decoders(int msgt, int msgl, const char *header, - struct mp_decoder_list *list) -{ - mp_msg(msgt, msgl, "%s\n", header); - for (int n = 0; n < list->num_entries; n++) { - struct mp_decoder_entry *entry = &list->entries[n]; - mp_msg(msgt, msgl, " %s:%s", entry->family, entry->decoder); - if (strcmp(entry->decoder, entry->codec) != 0) - mp_msg(msgt, msgl, " (%s)", entry->codec); - mp_msg(msgt, msgl, " - %s\n", entry->desc); - } - if (list->num_entries == 0) - mp_msg(msgt, msgl, " (no decoders)\n"); -} diff --git a/mpvcore/codecs.h b/mpvcore/codecs.h deleted file mode 100644 index 21ff284617..0000000000 --- a/mpvcore/codecs.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of mpv. - * - * mpv 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. - * - * mpv 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 mpv. If not, see . - */ - -#ifndef MP_CODECS_H -#define MP_CODECS_H - -struct mp_decoder_entry { - const char *family; // decoder module (e.g. ad_lavc => "lavc") - const char *codec; // name of the codec (e.g. "mp3") - const char *decoder; // decoder name (e.g. "mp3float") - const char *desc; // human readable description -}; - -struct mp_decoder_list { - struct mp_decoder_entry *entries; - int num_entries; -}; - -void mp_add_decoder(struct mp_decoder_list *list, const char *family, - const char *codec, const char *decoder, const char *desc); - -struct mp_decoder_list *mp_select_decoders(struct mp_decoder_list *all, - const char *codec, - const char *selection); - -void mp_print_decoders(int msgt, int msgl, const char *header, - struct mp_decoder_list *list); - -#endif diff --git a/mpvcore/cpudetect.c b/mpvcore/cpudetect.c deleted file mode 100644 index d670de0f98..0000000000 --- a/mpvcore/cpudetect.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include -#include - -#include -#include "compat/libav.h" - -#include "config.h" -#include "mpvcore/cpudetect.h" -#include "mpvcore/mp_msg.h" - -CpuCaps gCpuCaps; - -static void dump_flag(const char *name, bool val) -{ - mp_msg(MSGT_CPUDETECT, MSGL_V, "CPU: %s: %s\n", name, - val ? "enabled" : "disabled"); -} - -void GetCpuCaps(CpuCaps *c) -{ - memset(c, 0, sizeof(*c)); - int flags = av_get_cpu_flags(); -#if ARCH_X86 - c->hasMMX = flags & AV_CPU_FLAG_MMX; - c->hasMMX2 = flags & AV_CPU_FLAG_MMX2; - c->hasSSE = flags & AV_CPU_FLAG_SSE; - c->hasSSE2 = (flags & AV_CPU_FLAG_SSE2) && !(flags & AV_CPU_FLAG_SSE2SLOW); - c->hasSSE3 = (flags & AV_CPU_FLAG_SSE3) && !(flags & AV_CPU_FLAG_SSE3SLOW); - c->hasSSSE3 = flags & AV_CPU_FLAG_SSSE3; -#endif - dump_flag("MMX", c->hasMMX); - dump_flag("MMX2", c->hasMMX2); - dump_flag("SSE", c->hasSSE); - dump_flag("SSE2", c->hasSSE2); - dump_flag("SSE3", c->hasSSE3); - dump_flag("SSSE3", c->hasSSSE3); -} diff --git a/mpvcore/cpudetect.h b/mpvcore/cpudetect.h deleted file mode 100644 index d3d9206c65..0000000000 --- a/mpvcore/cpudetect.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MPLAYER_CPUDETECT_H -#define MPLAYER_CPUDETECT_H - -#include -#include "config.h" - -#include "compat/x86_cpu.h" - -typedef struct cpucaps_s { - bool hasMMX; - bool hasMMX2; - bool hasSSE; - bool hasSSE2; - bool hasSSE3; - bool hasSSSE3; -} CpuCaps; - -extern CpuCaps gCpuCaps; - -void GetCpuCaps(CpuCaps *caps); - -#endif /* MPLAYER_CPUDETECT_H */ diff --git a/mpvcore/encode.h b/mpvcore/encode.h deleted file mode 100644 index fec14045ed..0000000000 --- a/mpvcore/encode.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef MPLAYER_ENCODE_H -#define MPLAYER_ENCODE_H - -#include - -struct MPOpts; -struct encode_lavc_context; -struct encode_output_conf; - -// interface for mplayer.c -struct encode_lavc_context *encode_lavc_init(struct encode_output_conf *options); -void encode_lavc_finish(struct encode_lavc_context *ctx); -void encode_lavc_free(struct encode_lavc_context *ctx); -void encode_lavc_discontinuity(struct encode_lavc_context *ctx); -bool encode_lavc_showhelp(struct MPOpts *opts); -int encode_lavc_getstatus(struct encode_lavc_context *ctx, char *buf, int bufsize, float relative_position); -void encode_lavc_expect_stream(struct encode_lavc_context *ctx, int mt); -void encode_lavc_set_video_fps(struct encode_lavc_context *ctx, float fps); -bool encode_lavc_didfail(struct encode_lavc_context *ctx); // check if encoding failed - -#endif diff --git a/mpvcore/encode_lavc.c b/mpvcore/encode_lavc.c deleted file mode 100644 index 0ea4be486a..0000000000 --- a/mpvcore/encode_lavc.c +++ /dev/null @@ -1,1115 +0,0 @@ -/* - * muxing using libavformat - * Copyright (C) 2010 Nicolas George - * Copyright (C) 2011-2012 Rudolf Polzer - * - * This file is part of mpv. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include - -#include "encode_lavc.h" -#include "mpvcore/mp_msg.h" -#include "video/vfcap.h" -#include "options/options.h" -#include "osdep/timer.h" -#include "video/out/vo.h" -#include "talloc.h" -#include "stream/stream.h" - -static int set_to_avdictionary(AVDictionary **dictp, const char *key, - const char *val) -{ - char keybuf[1024]; - char valuebuf[1024]; - - if (key == NULL) { - // we need to split at equals sign - const char *equals = strchr(val, '='); - if (!equals || equals - val >= sizeof(keybuf)) { - mp_msg(MSGT_ENCODE, MSGL_WARN, - "encode-lavc: option '%s' does not contain an equals sign\n", - val); - return 0; - } - memcpy(keybuf, val, equals - val); - keybuf[equals - val] = 0; - key = keybuf; - val = equals + 1; - } - - // hack: support "qscale" key as virtual "global_quality" key that multiplies by QP2LAMBDA - if (!strcmp(key, "qscale")) { - key = "global_quality"; - snprintf(valuebuf, sizeof(valuebuf), - "%.1s(%s)*QP2LAMBDA", - (val[0] == '+' || val[0] == '-') ? val : "", - (val[0] == '+' || val[0] == '-') ? val + 1 : val); - valuebuf[sizeof(valuebuf) - 1] = 0; - val = valuebuf; - } - - mp_msg(MSGT_ENCODE, MSGL_V, - "encode-lavc: setting value '%s' for key '%s'\n", - val, - key); - - if (av_dict_set(dictp, key, *val ? val : NULL, - (val[0] == '+' || val[0] == '-') ? AV_DICT_APPEND : 0) >= 0) - return 1; - - return 0; -} - -static bool value_has_flag(const char *value, const char *flag) -{ - bool state = true; - bool ret = false; - while (*value) { - size_t l = strcspn(value, "+-"); - if (l == 0) { - state = (*value == '+'); - ++value; - } else { - if (l == strlen(flag)) - if (!memcmp(value, flag, l)) - ret = state; - value += l; - } - } - return ret; -} - -#define CHECK_FAIL(ctx, val) \ - if (ctx && (ctx->failed || ctx->finished)) { \ - mp_msg(MSGT_ENCODE, MSGL_ERR, \ - "Called a function on a %s encoding context. Bailing out.\n", \ - ctx->failed ? "failed" : "finished"); \ - return val; \ - } - -int encode_lavc_available(struct encode_lavc_context *ctx) -{ - CHECK_FAIL(ctx, 0); - return ctx && ctx->avc; -} - -int encode_lavc_oformat_flags(struct encode_lavc_context *ctx) -{ - CHECK_FAIL(ctx, 0); - return ctx->avc ? ctx->avc->oformat->flags : 0; -} - -struct encode_lavc_context *encode_lavc_init(struct encode_output_conf *options) -{ - struct encode_lavc_context *ctx; - const char *filename = options->file; - - // STUPID STUPID STUPID STUPID avio - // does not support "-" as file name to mean stdin/stdout - // ffmpeg.c works around this too, the same way - if (!strcmp(filename, "-")) - filename = "pipe:1"; - - if (filename && ( - !strcmp(filename, "/dev/stdout") || - !strcmp(filename, "pipe:") || - !strcmp(filename, "pipe:1"))) - mp_msg_stdout_in_use = 1; - - ctx = talloc_zero(NULL, struct encode_lavc_context); - encode_lavc_discontinuity(ctx); - ctx->options = options; - - ctx->avc = avformat_alloc_context(); - - if (ctx->options->format) { - char *tok; - const char *in = ctx->options->format; - while (*in) { - tok = av_get_token(&in, ","); - ctx->avc->oformat = av_guess_format(tok, filename, NULL); - av_free(tok); - if (ctx->avc->oformat) - break; - if (*in) - ++in; - } - } else - ctx->avc->oformat = av_guess_format(NULL, filename, NULL); - - if (!ctx->avc->oformat) { - encode_lavc_fail(ctx, "encode-lavc: format not found\n"); - return NULL; - } - - av_strlcpy(ctx->avc->filename, filename, - sizeof(ctx->avc->filename)); - - ctx->foptions = NULL; - if (ctx->options->fopts) { - char **p; - for (p = ctx->options->fopts; *p; ++p) { - if (!set_to_avdictionary(&ctx->foptions, NULL, *p)) - mp_msg(MSGT_ENCODE, MSGL_WARN, - "encode-lavc: could not set option %s\n", *p); - } - } - - if (ctx->options->vcodec) { - char *tok; - const char *in = ctx->options->vcodec; - while (*in) { - tok = av_get_token(&in, ","); - ctx->vc = avcodec_find_encoder_by_name(tok); - av_free(tok); - if (ctx->vc && ctx->vc->type != AVMEDIA_TYPE_VIDEO) - ctx->vc = NULL; - if (ctx->vc) - break; - if (*in) - ++in; - } - } else - ctx->vc = avcodec_find_encoder(av_guess_codec(ctx->avc->oformat, NULL, - ctx->avc->filename, NULL, - AVMEDIA_TYPE_VIDEO)); - - if (ctx->options->acodec) { - char *tok; - const char *in = ctx->options->acodec; - while (*in) { - tok = av_get_token(&in, ","); - ctx->ac = avcodec_find_encoder_by_name(tok); - av_free(tok); - if (ctx->ac && ctx->ac->type != AVMEDIA_TYPE_AUDIO) - ctx->ac = NULL; - if (ctx->ac) - break; - if (*in) - ++in; - } - } else - ctx->ac = avcodec_find_encoder(av_guess_codec(ctx->avc->oformat, NULL, - ctx->avc->filename, NULL, - AVMEDIA_TYPE_AUDIO)); - - if (!ctx->vc && !ctx->ac) { - encode_lavc_fail( - ctx, "encode-lavc: neither audio nor video codec was found\n"); - return NULL; - } - - /* taken from ffmpeg unchanged - * TODO turn this into an option if anyone needs this */ - - ctx->avc->max_delay = 0.7 * AV_TIME_BASE; - - ctx->abytes = 0; - ctx->vbytes = 0; - ctx->frames = 0; - - if (options->video_first) - ctx->video_first = true; - if (options->audio_first) - ctx->audio_first = true; - - return ctx; -} - -int encode_lavc_start(struct encode_lavc_context *ctx) -{ - AVDictionaryEntry *de; - unsigned i; - - if (ctx->header_written < 0) - return 0; - if (ctx->header_written > 0) - return 1; - - CHECK_FAIL(ctx, 0); - - if (ctx->expect_video) { - for (i = 0; i < ctx->avc->nb_streams; ++i) - if (ctx->avc->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) - break; - if (i >= ctx->avc->nb_streams) { - encode_lavc_fail(ctx, - "encode-lavc: video stream missing, invalid codec?\n"); - return 0; - } - } - if (ctx->expect_audio) { - for (i = 0; i < ctx->avc->nb_streams; ++i) - if (ctx->avc->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) - break; - if (i >= ctx->avc->nb_streams) { - encode_lavc_fail(ctx, - "encode-lavc: audio stream missing, invalid codec?\n"); - return 0; - } - } - - ctx->header_written = -1; - - if (!(ctx->avc->oformat->flags & AVFMT_NOFILE)) { - mp_msg(MSGT_ENCODE, MSGL_INFO, "Opening output file: %s\n", - ctx->avc->filename); - - if (avio_open(&ctx->avc->pb, ctx->avc->filename, - AVIO_FLAG_WRITE) < 0) { - encode_lavc_fail(ctx, "encode-lavc: could not open '%s'\n", - ctx->avc->filename); - return 0; - } - } - - ctx->t0 = mp_time_sec(); - - mp_msg(MSGT_ENCODE, MSGL_INFO, "Opening muxer: %s [%s]\n", - ctx->avc->oformat->long_name, ctx->avc->oformat->name); - - if (avformat_write_header(ctx->avc, &ctx->foptions) < 0) { - encode_lavc_fail(ctx, "encode-lavc: could not write header\n"); - return 0; - } - - for (de = NULL; (de = av_dict_get(ctx->foptions, "", de, - AV_DICT_IGNORE_SUFFIX));) - mp_msg(MSGT_ENCODE, MSGL_WARN, "ofopts: key '%s' not found.\n", de->key); - av_dict_free(&ctx->foptions); - - ctx->header_written = 1; - return 1; -} - -void encode_lavc_free(struct encode_lavc_context *ctx) -{ - if (!ctx) - return; - - if (!ctx->finished) - encode_lavc_fail(ctx, - "called encode_lavc_free without encode_lavc_finish\n"); - - talloc_free(ctx); -} - -void encode_lavc_finish(struct encode_lavc_context *ctx) -{ - unsigned i; - - if (!ctx) - return; - - if (ctx->finished) - return; - - if (ctx->avc) { - if (ctx->header_written > 0) - av_write_trailer(ctx->avc); // this is allowed to fail - - for (i = 0; i < ctx->avc->nb_streams; i++) { - switch (ctx->avc->streams[i]->codec->codec_type) { - case AVMEDIA_TYPE_VIDEO: - if (ctx->twopass_bytebuffer_v) { - char *stats = ctx->avc->streams[i]->codec->stats_out; - if (stats) - stream_write_buffer(ctx->twopass_bytebuffer_v, - stats, strlen(stats)); - } - break; - case AVMEDIA_TYPE_AUDIO: - if (ctx->twopass_bytebuffer_a) { - char *stats = ctx->avc->streams[i]->codec->stats_out; - if (stats) - stream_write_buffer(ctx->twopass_bytebuffer_a, - stats, strlen(stats)); - } - break; - default: - break; - } - avcodec_close(ctx->avc->streams[i]->codec); - talloc_free(ctx->avc->streams[i]->codec->stats_in); - av_free(ctx->avc->streams[i]->codec); - av_free(ctx->avc->streams[i]->info); - av_free(ctx->avc->streams[i]); - } - - if (ctx->twopass_bytebuffer_v) { - free_stream(ctx->twopass_bytebuffer_v); - ctx->twopass_bytebuffer_v = NULL; - } - - if (ctx->twopass_bytebuffer_a) { - free_stream(ctx->twopass_bytebuffer_a); - ctx->twopass_bytebuffer_a = NULL; - } - - mp_msg(MSGT_ENCODE, MSGL_INFO, "vo-lavc: encoded %lld bytes\n", - ctx->vbytes); - mp_msg(MSGT_ENCODE, MSGL_INFO, "ao-lavc: encoded %lld bytes\n", - ctx->abytes); - if (ctx->avc->pb) { - mp_msg(MSGT_ENCODE, MSGL_INFO, - "encode-lavc: muxing overhead %lld bytes\n", - (long long) (avio_size(ctx->avc->pb) - ctx->vbytes - - ctx->abytes)); - avio_close(ctx->avc->pb); - } - - av_free(ctx->avc); - } - - ctx->finished = true; -} - -void encode_lavc_set_video_fps(struct encode_lavc_context *ctx, float fps) -{ - ctx->vo_fps = fps; -} - -static void encode_2pass_prepare(struct encode_lavc_context *ctx, - AVDictionary **dictp, - AVStream *stream, struct stream **bytebuf, - const char *prefix) -{ - if (!*bytebuf) { - char buf[sizeof(ctx->avc->filename) + 12]; - AVDictionaryEntry *de = av_dict_get(ctx->voptions, "flags", NULL, 0); - - snprintf(buf, sizeof(buf), "%s-%s-pass1.log", ctx->avc->filename, - prefix); - buf[sizeof(buf) - 1] = 0; - - if (value_has_flag(de ? de->value : "", "pass2")) { - if (!(*bytebuf = stream_open(buf, NULL))) { - mp_msg(MSGT_ENCODE, MSGL_WARN, "%s: could not open '%s', " - "disabling 2-pass encoding at pass 2\n", prefix, buf); - stream->codec->flags &= ~CODEC_FLAG_PASS2; - set_to_avdictionary(dictp, "flags", "-pass2"); - } else { - struct bstr content = stream_read_complete(*bytebuf, NULL, - 1000000000); - if (content.start == NULL) { - mp_msg(MSGT_ENCODE, MSGL_WARN, "%s: could not read '%s', " - "disabling 2-pass encoding at pass 1\n", - prefix, ctx->avc->filename); - } else { - content.start[content.len] = 0; - stream->codec->stats_in = content.start; - } - free_stream(*bytebuf); - *bytebuf = NULL; - } - } - - if (value_has_flag(de ? de->value : "", "pass1")) { - if (!(*bytebuf = open_output_stream(buf, NULL))) { - mp_msg( - MSGT_ENCODE, MSGL_WARN, - "%s: could not open '%s', disabling " - "2-pass encoding at pass 1\n", - prefix, ctx->avc->filename); - set_to_avdictionary(dictp, "flags", "-pass1"); - } - } - } -} - -AVStream *encode_lavc_alloc_stream(struct encode_lavc_context *ctx, - enum AVMediaType mt) -{ - AVDictionaryEntry *de; - AVStream *stream = NULL; - char **p; - int i; - - CHECK_FAIL(ctx, NULL); - - if (ctx->header_written) - return NULL; - - for (i = 0; i < ctx->avc->nb_streams; ++i) - if (ctx->avc->streams[i]->codec->codec_type == mt) - // already have a stream of that type, this cannot really happen - return NULL; - - if (ctx->avc->nb_streams == 0) { - // if this stream isn't stream #0, allocate a dummy stream first for - // the next loop to use - if (mt == AVMEDIA_TYPE_VIDEO && ctx->audio_first) { - mp_msg(MSGT_ENCODE, MSGL_INFO, - "vo-lavc: preallocated audio stream for later use\n"); - avformat_new_stream(ctx->avc, NULL); // this one is AVMEDIA_TYPE_UNKNOWN for now - } - if (mt == AVMEDIA_TYPE_AUDIO && ctx->video_first) { - mp_msg(MSGT_ENCODE, MSGL_INFO, - "ao-lavc: preallocated video stream for later use\n"); - avformat_new_stream(ctx->avc, NULL); // this one is AVMEDIA_TYPE_UNKNOWN for now - } - } else { - // find possibly preallocated stream - for (i = 0; i < ctx->avc->nb_streams; ++i) - if (ctx->avc->streams[i]->codec->codec_type == AVMEDIA_TYPE_UNKNOWN) // preallocated stream - stream = ctx->avc->streams[i]; - } - if (!stream) - stream = avformat_new_stream(ctx->avc, NULL); - - if (ctx->timebase.den == 0) { - AVRational r; - - if (ctx->options->fps > 0) - r = av_d2q(ctx->options->fps, ctx->options->fps * 1001 + 2); - else if (ctx->options->autofps && ctx->vo_fps > 0) { - r = av_d2q(ctx->vo_fps, ctx->vo_fps * 1001 + 2); - mp_msg( - MSGT_ENCODE, MSGL_INFO, "vo-lavc: option --ofps not specified " - "but --oautofps is active, using guess of %u/%u\n", - (unsigned)r.num, (unsigned)r.den); - } else { - // we want to handle: - // 1/25 - // 1001/24000 - // 1001/30000 - // for this we would need 120000fps... - // however, mpeg-4 only allows 16bit values - // so let's take 1001/30000 out - r.num = 24000; - r.den = 1; - mp_msg( - MSGT_ENCODE, MSGL_INFO, "vo-lavc: option --ofps not specified " - "and fps could not be inferred, using guess of %u/%u\n", - (unsigned)r.num, (unsigned)r.den); - } - - if (ctx->vc && ctx->vc->supported_framerates) - r = ctx->vc->supported_framerates[av_find_nearest_q_idx(r, - ctx->vc->supported_framerates)]; - - ctx->timebase.num = r.den; - ctx->timebase.den = r.num; - } - - switch (mt) { - case AVMEDIA_TYPE_VIDEO: - if (!ctx->vc) { - encode_lavc_fail(ctx, "vo-lavc: encoder not found\n"); - return NULL; - } - avcodec_get_context_defaults3(stream->codec, ctx->vc); - - // stream->time_base = ctx->timebase; - // doing this breaks mpeg2ts in ffmpeg - // which doesn't properly force the time base to be 90000 - // furthermore, ffmpeg.c doesn't do this either and works - - stream->codec->time_base = ctx->timebase; - - ctx->voptions = NULL; - - if (ctx->options->vopts) - for (p = ctx->options->vopts; *p; ++p) - if (!set_to_avdictionary(&ctx->voptions, NULL, *p)) - mp_msg(MSGT_ENCODE, MSGL_WARN, - "vo-lavc: could not set option %s\n", *p); - - de = av_dict_get(ctx->voptions, "global_quality", NULL, 0); - if (de) - set_to_avdictionary(&ctx->voptions, "flags", "+qscale"); - - if (ctx->avc->oformat->flags & AVFMT_GLOBALHEADER) - set_to_avdictionary(&ctx->voptions, "flags", "+global_header"); - - encode_2pass_prepare(ctx, &ctx->voptions, stream, - &ctx->twopass_bytebuffer_v, - "vo-lavc"); - break; - - case AVMEDIA_TYPE_AUDIO: - if (!ctx->ac) { - encode_lavc_fail(ctx, "ao-lavc: encoder not found\n"); - return NULL; - } - avcodec_get_context_defaults3(stream->codec, ctx->ac); - - stream->codec->time_base = ctx->timebase; - - ctx->aoptions = NULL; - - if (ctx->options->aopts) - for (p = ctx->options->aopts; *p; ++p) - if (!set_to_avdictionary(&ctx->aoptions, NULL, *p)) - mp_msg(MSGT_ENCODE, MSGL_WARN, - "ao-lavc: could not set option %s\n", *p); - - de = av_dict_get(ctx->aoptions, "global_quality", NULL, 0); - if (de) - set_to_avdictionary(&ctx->aoptions, "flags", "+qscale"); - - if (ctx->avc->oformat->flags & AVFMT_GLOBALHEADER) - set_to_avdictionary(&ctx->aoptions, "flags", "+global_header"); - - encode_2pass_prepare(ctx, &ctx->aoptions, stream, - &ctx->twopass_bytebuffer_a, - "ao-lavc"); - break; - - default: - encode_lavc_fail(ctx, "encode-lavc: requested invalid stream type\n"); - return NULL; - } - - return stream; -} - -AVCodec *encode_lavc_get_codec(struct encode_lavc_context *ctx, - AVStream *stream) -{ - CHECK_FAIL(ctx, NULL); - - switch (stream->codec->codec_type) { - case AVMEDIA_TYPE_VIDEO: - return ctx->vc; - case AVMEDIA_TYPE_AUDIO: - return ctx->ac; - default: - break; - } - return NULL; -} - -int encode_lavc_open_codec(struct encode_lavc_context *ctx, AVStream *stream) -{ - AVDictionaryEntry *de; - int ret; - - CHECK_FAIL(ctx, -1); - - switch (stream->codec->codec_type) { - case AVMEDIA_TYPE_VIDEO: - mp_msg(MSGT_ENCODE, MSGL_INFO, "Opening video encoder: %s [%s]\n", - ctx->vc->long_name, ctx->vc->name); - - if (ctx->vc->capabilities & CODEC_CAP_EXPERIMENTAL) { - stream->codec->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; - mp_msg(MSGT_ENCODE, MSGL_WARN, _( - "\n\n" - " ********************************************\n" - " **** Experimental VIDEO codec selected! ****\n" - " ********************************************\n\n" - "This means the output file may be broken or bad.\n" - "Possible reasons, problems, workarounds:\n" - "- Codec implementation in ffmpeg/libav is not finished yet.\n" - " Try updating ffmpeg or libav.\n" - "- Bad picture quality, blocks, blurriness.\n" - " Experiment with codec settings (--ovcopts) to maybe still get the\n" - " desired quality output at the expense of bitrate.\n" - "- Slow compression.\n" - " Bear with it.\n" - "- Crashes.\n" - " Happens. Try varying options to work around.\n" - "If none of this helps you, try another codec in place of %s.\n\n"), - ctx->vc->name); - } - - ret = avcodec_open2(stream->codec, ctx->vc, &ctx->voptions); - - // complain about all remaining options, then free the dict - for (de = NULL; (de = av_dict_get(ctx->voptions, "", de, - AV_DICT_IGNORE_SUFFIX));) - mp_msg(MSGT_ENCODE, MSGL_WARN, "ovcopts: key '%s' not found.\n", - de->key); - av_dict_free(&ctx->voptions); - - break; - case AVMEDIA_TYPE_AUDIO: - mp_msg(MSGT_ENCODE, MSGL_INFO, "Opening audio encoder: %s [%s]\n", - ctx->ac->long_name, ctx->ac->name); - - if (ctx->ac->capabilities & CODEC_CAP_EXPERIMENTAL) { - stream->codec->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; - mp_msg(MSGT_ENCODE, MSGL_WARN, _( - "\n\n" - " ********************************************\n" - " **** Experimental AUDIO codec selected! ****\n" - " ********************************************\n\n" - "This means the output file may be broken or bad.\n" - "Possible reasons, problems, workarounds:\n" - "- Codec implementation in ffmpeg/libav is not finished yet.\n" - " Try updating ffmpeg or libav.\n" - "- Bad sound quality, noise, clicking, whistles, choppiness.\n" - " Experiment with codec settings (--oacopts) to maybe still get the\n" - " desired quality output at the expense of bitrate.\n" - "- Slow compression.\n" - " Bear with it.\n" - "- Crashes.\n" - " Happens. Try varying options to work around.\n" - "If none of this helps you, try another codec in place of %s.\n\n"), - ctx->ac->name); - } - ret = avcodec_open2(stream->codec, ctx->ac, &ctx->aoptions); - - // complain about all remaining options, then free the dict - for (de = NULL; (de = av_dict_get(ctx->aoptions, "", de, - AV_DICT_IGNORE_SUFFIX));) - mp_msg(MSGT_ENCODE, MSGL_WARN, "oacopts: key '%s' not found.\n", - de->key); - av_dict_free(&ctx->aoptions); - - break; - default: - ret = -1; - break; - } - - if (ret < 0) - encode_lavc_fail(ctx, - "unable to open encoder (see above for the cause)\n"); - - return ret; -} - -void encode_lavc_write_stats(struct encode_lavc_context *ctx, AVStream *stream) -{ - CHECK_FAIL(ctx, ); - - switch (stream->codec->codec_type) { - case AVMEDIA_TYPE_VIDEO: - if (ctx->twopass_bytebuffer_v) - if (stream->codec->stats_out) - stream_write_buffer(ctx->twopass_bytebuffer_v, - stream->codec->stats_out, - strlen(stream->codec->stats_out)); - break; - case AVMEDIA_TYPE_AUDIO: - if (ctx->twopass_bytebuffer_a) - if (stream->codec->stats_out) - stream_write_buffer(ctx->twopass_bytebuffer_a, - stream->codec->stats_out, - strlen(stream->codec->stats_out)); - break; - default: - break; - } -} - -int encode_lavc_write_frame(struct encode_lavc_context *ctx, AVPacket *packet) -{ - int r; - - CHECK_FAIL(ctx, -1); - - if (ctx->header_written <= 0) - return -1; - - mp_msg( - MSGT_ENCODE, MSGL_DBG2, - "encode-lavc: write frame: stream %d ptsi %d (%f) dtsi %d (%f) size %d\n", - (int)packet->stream_index, - (int)packet->pts, - packet->pts - * (double)ctx->avc->streams[packet->stream_index]->time_base.num - / (double)ctx->avc->streams[packet->stream_index]->time_base.den, - (int)packet->dts, - packet->dts - * (double)ctx->avc->streams[packet->stream_index]->time_base.num - / (double)ctx->avc->streams[packet->stream_index]->time_base.den, - (int)packet->size); - - switch (ctx->avc->streams[packet->stream_index]->codec->codec_type) { - case AVMEDIA_TYPE_VIDEO: - ctx->vbytes += packet->size; - ++ctx->frames; - break; - case AVMEDIA_TYPE_AUDIO: - ctx->abytes += packet->size; - ctx->audioseconds += packet->duration - * (double)ctx->avc->streams[packet->stream_index]->time_base.num - / (double)ctx->avc->streams[packet->stream_index]->time_base.den; - break; - default: - break; - } - - r = av_interleaved_write_frame(ctx->avc, packet); - - return r; -} - -int encode_lavc_supports_pixfmt(struct encode_lavc_context *ctx, - enum AVPixelFormat pix_fmt) -{ - CHECK_FAIL(ctx, 0); - - if (!ctx->vc) - return 0; - if (pix_fmt == AV_PIX_FMT_NONE) - return 0; - - if (!ctx->vc->pix_fmts) - return VFCAP_CSP_SUPPORTED; - else { - const enum AVPixelFormat *p; - for (p = ctx->vc->pix_fmts; *p >= 0; ++p) { - if (pix_fmt == *p) - return VFCAP_CSP_SUPPORTED; - } - } - return 0; -} - -void encode_lavc_discontinuity(struct encode_lavc_context *ctx) -{ - if (!ctx) - return; - - CHECK_FAIL(ctx, ); - - ctx->audio_pts_offset = MP_NOPTS_VALUE; - ctx->last_video_in_pts = MP_NOPTS_VALUE; - ctx->discontinuity_pts_offset = MP_NOPTS_VALUE; -} - -static void encode_lavc_printoptions(void *obj, const char *indent, - const char *subindent, const char *unit, - int filter_and, int filter_eq) -{ - const AVOption *opt = NULL; - char optbuf[32]; - while ((opt = av_opt_next(obj, opt))) { - // if flags are 0, it simply hasn't been filled in yet and may be - // potentially useful - if (opt->flags) - if ((opt->flags & filter_and) != filter_eq) - continue; - /* Don't print CONST's on level one. - * Don't print anything but CONST's on level two. - * Only print items from the requested unit. - */ - if (!unit && opt->type == AV_OPT_TYPE_CONST) - continue; - else if (unit && opt->type != AV_OPT_TYPE_CONST) - continue; - else if (unit && opt->type == AV_OPT_TYPE_CONST - && strcmp(unit, opt->unit)) - continue; - else if (unit && opt->type == AV_OPT_TYPE_CONST) - mp_msg(MSGT_ENCODE, MSGL_INFO, "%s", subindent); - else - mp_msg(MSGT_ENCODE, MSGL_INFO, "%s", indent); - - switch (opt->type) { - case AV_OPT_TYPE_FLAGS: - snprintf(optbuf, sizeof(optbuf), "%s=", opt->name); - break; - case AV_OPT_TYPE_INT: - snprintf(optbuf, sizeof(optbuf), "%s=", opt->name); - break; - case AV_OPT_TYPE_INT64: - snprintf(optbuf, sizeof(optbuf), "%s=", opt->name); - break; - case AV_OPT_TYPE_DOUBLE: - snprintf(optbuf, sizeof(optbuf), "%s=", opt->name); - break; - case AV_OPT_TYPE_FLOAT: - snprintf(optbuf, sizeof(optbuf), "%s=", opt->name); - break; - case AV_OPT_TYPE_STRING: - snprintf(optbuf, sizeof(optbuf), "%s=", opt->name); - break; - case AV_OPT_TYPE_RATIONAL: - snprintf(optbuf, sizeof(optbuf), "%s=", opt->name); - break; - case AV_OPT_TYPE_BINARY: - snprintf(optbuf, sizeof(optbuf), "%s=", opt->name); - break; - case AV_OPT_TYPE_CONST: - snprintf(optbuf, sizeof(optbuf), " [+-]%s", opt->name); - break; - default: - snprintf(optbuf, sizeof(optbuf), "%s", opt->name); - break; - } - optbuf[sizeof(optbuf) - 1] = 0; - mp_msg(MSGT_ENCODE, MSGL_INFO, "%-32s ", optbuf); - if (opt->help) - mp_msg(MSGT_ENCODE, MSGL_INFO, " %s", opt->help); - mp_msg(MSGT_ENCODE, MSGL_INFO, "\n"); - if (opt->unit && opt->type != AV_OPT_TYPE_CONST) - encode_lavc_printoptions(obj, indent, subindent, opt->unit, - filter_and, filter_eq); - } -} - -bool encode_lavc_showhelp(struct MPOpts *opts) -{ - bool help_output = false; - if (av_codec_next(NULL) == NULL) - mp_msg(MSGT_ENCODE, MSGL_ERR, "NO CODECS\n"); -#define CHECKS(str) ((str) && \ - strcmp((str), "help") == 0 ? (help_output |= 1) : 0) -#define CHECKV(strv) ((strv) && (strv)[0] && \ - strcmp((strv)[0], "help") == 0 ? (help_output |= 1) : 0) - if (CHECKS(opts->encode_output.format)) { - AVOutputFormat *c = NULL; - mp_msg(MSGT_ENCODE, MSGL_INFO, "Available output formats:\n"); - while ((c = av_oformat_next(c))) - mp_msg(MSGT_ENCODE, MSGL_INFO, " --of=%-13s %s\n", c->name, - c->long_name ? c->long_name : ""); - av_free(c); - } - if (CHECKV(opts->encode_output.fopts)) { - AVFormatContext *c = avformat_alloc_context(); - AVOutputFormat *format = NULL; - mp_msg(MSGT_ENCODE, MSGL_INFO, - "Available output format ctx->options:\n"); - encode_lavc_printoptions(c, " --ofopts=", " ", NULL, - AV_OPT_FLAG_ENCODING_PARAM, - AV_OPT_FLAG_ENCODING_PARAM); - av_free(c); - while ((format = av_oformat_next(format))) { - if (format->priv_class) { - mp_msg(MSGT_ENCODE, MSGL_INFO, "Additionally, for --of=%s:\n", - format->name); - encode_lavc_printoptions(&format->priv_class, " --ofopts=", - " ", NULL, - AV_OPT_FLAG_ENCODING_PARAM, - AV_OPT_FLAG_ENCODING_PARAM); - } - } - } - if (CHECKV(opts->encode_output.vopts)) { - AVCodecContext *c = avcodec_alloc_context3(NULL); - AVCodec *codec = NULL; - mp_msg(MSGT_ENCODE, MSGL_INFO, - "Available output video codec ctx->options:\n"); - encode_lavc_printoptions( - c, " --ovcopts=", " ", NULL, - AV_OPT_FLAG_ENCODING_PARAM | - AV_OPT_FLAG_VIDEO_PARAM, - AV_OPT_FLAG_ENCODING_PARAM | - AV_OPT_FLAG_VIDEO_PARAM); - av_free(c); - while ((codec = av_codec_next(codec))) { - if (!av_codec_is_encoder(codec)) - continue; - if (codec->type != AVMEDIA_TYPE_VIDEO) - continue; - if (opts->encode_output.vcodec && opts->encode_output.vcodec[0] && - strcmp(opts->encode_output.vcodec, codec->name) != 0) - continue; - if (codec->priv_class) { - mp_msg(MSGT_ENCODE, MSGL_INFO, "Additionally, for --ovc=%s:\n", - codec->name); - encode_lavc_printoptions( - &codec->priv_class, " --ovcopts=", - " ", NULL, - AV_OPT_FLAG_ENCODING_PARAM | - AV_OPT_FLAG_VIDEO_PARAM, - AV_OPT_FLAG_ENCODING_PARAM | - AV_OPT_FLAG_VIDEO_PARAM); - } - } - } - if (CHECKV(opts->encode_output.aopts)) { - AVCodecContext *c = avcodec_alloc_context3(NULL); - AVCodec *codec = NULL; - mp_msg(MSGT_ENCODE, MSGL_INFO, - "Available output audio codec ctx->options:\n"); - encode_lavc_printoptions( - c, " --oacopts=", " ", NULL, - AV_OPT_FLAG_ENCODING_PARAM | - AV_OPT_FLAG_AUDIO_PARAM, - AV_OPT_FLAG_ENCODING_PARAM | - AV_OPT_FLAG_AUDIO_PARAM); - av_free(c); - while ((codec = av_codec_next(codec))) { - if (!av_codec_is_encoder(codec)) - continue; - if (codec->type != AVMEDIA_TYPE_AUDIO) - continue; - if (opts->encode_output.acodec && opts->encode_output.acodec[0] && - strcmp(opts->encode_output.acodec, codec->name) != 0) - continue; - if (codec->priv_class) { - mp_msg(MSGT_ENCODE, MSGL_INFO, "Additionally, for --oac=%s:\n", - codec->name); - encode_lavc_printoptions( - &codec->priv_class, " --oacopts=", - " ", NULL, - AV_OPT_FLAG_ENCODING_PARAM | - AV_OPT_FLAG_AUDIO_PARAM, - AV_OPT_FLAG_ENCODING_PARAM | - AV_OPT_FLAG_AUDIO_PARAM); - } - } - } - if (CHECKS(opts->encode_output.vcodec)) { - AVCodec *c = NULL; - mp_msg(MSGT_ENCODE, MSGL_INFO, "Available output video codecs:\n"); - while ((c = av_codec_next(c))) { - if (!av_codec_is_encoder(c)) - continue; - if (c->type != AVMEDIA_TYPE_VIDEO) - continue; - mp_msg(MSGT_ENCODE, MSGL_INFO, " --ovc=%-12s %s\n", c->name, - c->long_name ? c->long_name : ""); - } - av_free(c); - } - if (CHECKS(opts->encode_output.acodec)) { - AVCodec *c = NULL; - mp_msg(MSGT_ENCODE, MSGL_INFO, "Available output audio codecs:\n"); - while ((c = av_codec_next(c))) { - if (!av_codec_is_encoder(c)) - continue; - if (c->type != AVMEDIA_TYPE_AUDIO) - continue; - mp_msg(MSGT_ENCODE, MSGL_INFO, " --oac=%-12s %s\n", c->name, - c->long_name ? c->long_name : ""); - } - av_free(c); - } - return help_output; -} - -double encode_lavc_getoffset(struct encode_lavc_context *ctx, AVStream *stream) -{ - CHECK_FAIL(ctx, 0); - - switch (stream->codec->codec_type) { - case AVMEDIA_TYPE_VIDEO: - return ctx->options->voffset; - case AVMEDIA_TYPE_AUDIO: - return ctx->options->aoffset; - default: - break; - } - return 0; -} - -int encode_lavc_getstatus(struct encode_lavc_context *ctx, - char *buf, int bufsize, - float relative_position) -{ - double now = mp_time_sec(); - float minutes, megabytes, fps, x; - float f = FFMAX(0.0001, relative_position); - if (!ctx) - return -1; - - CHECK_FAIL(ctx, -1); - - minutes = (now - ctx->t0) / 60.0 * (1 - f) / f; - megabytes = ctx->avc->pb ? (avio_size(ctx->avc->pb) / 1048576.0 / f) : 0; - fps = ctx->frames / (now - ctx->t0); - x = ctx->audioseconds / (now - ctx->t0); - if (ctx->frames) - snprintf(buf, bufsize, "{%.1fmin %.1ffps %.1fMB}", - minutes, fps, megabytes); - else if (ctx->audioseconds) - snprintf(buf, bufsize, "{%.1fmin %.2fx %.1fMB}", - minutes, x, megabytes); - else - snprintf(buf, bufsize, "{%.1fmin %.1fMB}", - minutes, megabytes); - buf[bufsize - 1] = 0; - return 0; -} - -void encode_lavc_expect_stream(struct encode_lavc_context *ctx, int mt) -{ - CHECK_FAIL(ctx, ); - - switch (mt) { - case AVMEDIA_TYPE_VIDEO: - ctx->expect_video = true; - break; - case AVMEDIA_TYPE_AUDIO: - ctx->expect_audio = true; - break; - } -} - -bool encode_lavc_didfail(struct encode_lavc_context *ctx) -{ - return ctx && ctx->failed; -} - -void encode_lavc_fail(struct encode_lavc_context *ctx, const char *format, ...) -{ - va_list va; - va_start(va, format); - mp_msg_va(MSGT_ENCODE, MSGL_ERR, format, va); - if (ctx->failed) - return; - ctx->failed = true; - encode_lavc_finish(ctx); -} - -bool encode_lavc_set_csp(struct encode_lavc_context *ctx, - AVStream *stream, enum mp_csp csp) -{ - CHECK_FAIL(ctx, NULL); - - if (ctx->header_written) { - if (stream->codec->colorspace != mp_csp_to_avcol_spc(csp)) - mp_msg(MSGT_ENCODE, MSGL_WARN, - "encode-lavc: can not change color space during encoding\n"); - return false; - } - - stream->codec->colorspace = mp_csp_to_avcol_spc(csp); - return true; -} - -bool encode_lavc_set_csp_levels(struct encode_lavc_context *ctx, - AVStream *stream, enum mp_csp_levels lev) -{ - CHECK_FAIL(ctx, NULL); - - if (ctx->header_written) { - if (stream->codec->color_range != mp_csp_levels_to_avcol_range(lev)) - mp_msg(MSGT_ENCODE, MSGL_WARN, - "encode-lavc: can not change color space during encoding\n"); - return false; - } - - stream->codec->color_range = mp_csp_levels_to_avcol_range(lev); - return true; -} - -enum mp_csp encode_lavc_get_csp(struct encode_lavc_context *ctx, - AVStream *stream) -{ - CHECK_FAIL(ctx, 0); - - return avcol_spc_to_mp_csp(stream->codec->colorspace); -} - -enum mp_csp_levels encode_lavc_get_csp_levels(struct encode_lavc_context *ctx, - AVStream *stream) -{ - CHECK_FAIL(ctx, 0); - - return avcol_range_to_mp_csp_levels(stream->codec->color_range); -} - -// vim: ts=4 sw=4 et diff --git a/mpvcore/encode_lavc.h b/mpvcore/encode_lavc.h deleted file mode 100644 index 15e0a5c7f2..0000000000 --- a/mpvcore/encode_lavc.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * muxing using libavformat - * Copyright (C) 2011 Rudolf Polzer - * - * This file is part of mpv. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MPLAYER_ENCODE_LAVC_H -#define MPLAYER_ENCODE_LAVC_H - -#include -#include -#include -#include -#include -#include - -#include "encode.h" -#include "video/csputils.h" - -struct encode_lavc_context { - struct encode_output_conf *options; - - float vo_fps; - - // these are processed from the options - AVFormatContext *avc; - AVRational timebase; - AVCodec *vc; - AVCodec *ac; - AVDictionary *foptions; - AVDictionary *aoptions; - AVDictionary *voptions; - - // values created during encoding - int header_written; // -1 means currently writing - - // sync to audio mode - double audio_pts_offset; - double last_video_in_pts; - - // anti discontinuity mode - double next_in_pts; - double discontinuity_pts_offset; - - long long abytes; - long long vbytes; - struct stream *twopass_bytebuffer_a; - struct stream *twopass_bytebuffer_v; - double t0; - unsigned int frames; - double audioseconds; - - bool expect_video; - bool expect_audio; - bool video_first; - bool audio_first; - - // has encoding failed? - bool failed; - bool finished; -}; - -// interface for vo/ao drivers -AVStream *encode_lavc_alloc_stream(struct encode_lavc_context *ctx, enum AVMediaType mt); -void encode_lavc_write_stats(struct encode_lavc_context *ctx, AVStream *stream); -int encode_lavc_write_frame(struct encode_lavc_context *ctx, AVPacket *packet); -int encode_lavc_supports_pixfmt(struct encode_lavc_context *ctx, enum AVPixelFormat format); -AVCodec *encode_lavc_get_codec(struct encode_lavc_context *ctx, AVStream *stream); -int encode_lavc_open_codec(struct encode_lavc_context *ctx, AVStream *stream); -int encode_lavc_available(struct encode_lavc_context *ctx); -int encode_lavc_timesyncfailed(struct encode_lavc_context *ctx); -int encode_lavc_start(struct encode_lavc_context *ctx); // returns 1 on success -int encode_lavc_oformat_flags(struct encode_lavc_context *ctx); -double encode_lavc_getoffset(struct encode_lavc_context *ctx, AVStream *stream); -void encode_lavc_fail(struct encode_lavc_context *ctx, const char *format, ...); // report failure of encoding - -bool encode_lavc_set_csp(struct encode_lavc_context *ctx, - AVStream *stream, enum mp_csp csp); -bool encode_lavc_set_csp_levels(struct encode_lavc_context *ctx, - AVStream *stream, enum mp_csp_levels lev); -enum mp_csp encode_lavc_get_csp(struct encode_lavc_context *ctx, - AVStream *stream); -enum mp_csp_levels encode_lavc_get_csp_levels(struct encode_lavc_context *ctx, - AVStream *stream); - -#endif diff --git a/mpvcore/mp_common.c b/mpvcore/mp_common.c deleted file mode 100644 index d4947f442f..0000000000 --- a/mpvcore/mp_common.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include - -#include "talloc.h" -#include "mpvcore/bstr.h" -#include "mpvcore/mp_common.h" - -#define appendf(ptr, ...) \ - do {(*(ptr)) = talloc_asprintf_append_buffer(*(ptr), __VA_ARGS__);} while(0) - -// Return a talloc'ed string formatted according to the format string in fmt. -// On error, return NULL. -// Valid formats: -// %H, %h: hour (%H is padded with 0 to two digits) -// %M: minutes from 00-59 (hours are subtracted) -// %m: total minutes (includes hours, unlike %M) -// %S: seconds from 00-59 (minutes and hours are subtracted) -// %s: total seconds (includes hours and minutes) -// %f: like %s, but as float -// %T: milliseconds (000-999) -char *mp_format_time_fmt(const char *fmt, double time) -{ - if (time == MP_NOPTS_VALUE) - return talloc_strdup(NULL, "unknown"); - char *sign = time < 0 ? "-" : ""; - time = time < 0 ? -time : time; - long long int itime = time; - long long int h, m, tm, s; - int ms; - s = itime; - tm = s / 60; - h = s / 3600; - s -= h * 3600; - m = s / 60; - s -= m * 60; - ms = (time - itime) * 1000; - char *res = talloc_strdup(NULL, ""); - while (*fmt) { - if (fmt[0] == '%') { - fmt++; - switch (fmt[0]) { - case 'h': appendf(&res, "%s%lld", sign, h); break; - case 'H': appendf(&res, "%s%02lld", sign, h); break; - case 'm': appendf(&res, "%s%lld", sign, tm); break; - case 'M': appendf(&res, "%02lld", m); break; - case 's': appendf(&res, "%s%lld", sign, itime); break; - case 'S': appendf(&res, "%02lld", s); break; - case 'T': appendf(&res, "%03d", ms); break; - case '%': appendf(&res, "%s", "%"); break; - default: goto error; - } - fmt++; - } else { - appendf(&res, "%c", *fmt); - fmt++; - } - } - return res; -error: - talloc_free(res); - return NULL; -} - -char *mp_format_time(double time, bool fractions) -{ - return mp_format_time_fmt(fractions ? "%H:%M:%S.%T" : "%H:%M:%S", time); -} - -// Set rc to the union of rc and rc2 -void mp_rect_union(struct mp_rect *rc, const struct mp_rect *rc2) -{ - rc->x0 = FFMIN(rc->x0, rc2->x0); - rc->y0 = FFMIN(rc->y0, rc2->y0); - rc->x1 = FFMAX(rc->x1, rc2->x1); - rc->y1 = FFMAX(rc->y1, rc2->y1); -} - -// Set rc to the intersection of rc and src. -// Return false if the result is empty. -bool mp_rect_intersection(struct mp_rect *rc, const struct mp_rect *rc2) -{ - rc->x0 = FFMAX(rc->x0, rc2->x0); - rc->y0 = FFMAX(rc->y0, rc2->y0); - rc->x1 = FFMIN(rc->x1, rc2->x1); - rc->y1 = FFMIN(rc->y1, rc2->y1); - - return rc->x1 > rc->x0 && rc->y1 > rc->y0; -} - -// Encode the unicode codepoint as UTF-8, and append to the end of the -// talloc'ed buffer. -char *mp_append_utf8_buffer(char *buffer, uint32_t codepoint) -{ - char data[8]; - uint8_t tmp; - char *output = data; - PUT_UTF8(codepoint, tmp, *output++ = tmp;); - return talloc_strndup_append_buffer(buffer, data, output - data); -} - -// Parse a C-style escape beginning at code, and append the result to *str -// using talloc. The input string (*code) must point to the first character -// after the initial '\', and after parsing *code is set to the first character -// after the current escape. -// On error, false is returned, and all input remains unchanged. -bool mp_parse_escape(bstr *code, char **str) -{ - if (code->len < 1) - return false; - char replace = 0; - switch (code->start[0]) { - case '"': replace = '"'; break; - case '\\': replace = '\\'; break; - case 'b': replace = '\b'; break; - case 'f': replace = '\f'; break; - case 'n': replace = '\n'; break; - case 'r': replace = '\r'; break; - case 't': replace = '\t'; break; - case 'e': replace = '\x1b'; break; - case '\'': replace = '\''; break; - } - if (replace) { - *str = talloc_strndup_append_buffer(*str, &replace, 1); - *code = bstr_cut(*code, 1); - return true; - } - if (code->start[0] == 'x' && code->len >= 3) { - bstr num = bstr_splice(*code, 1, 3); - char c = bstrtoll(num, &num, 16); - if (!num.len) - return false; - *str = talloc_strndup_append_buffer(*str, &c, 1); - *code = bstr_cut(*code, 3); - return true; - } - if (code->start[0] == 'u' && code->len >= 5) { - bstr num = bstr_splice(*code, 1, 5); - int c = bstrtoll(num, &num, 16); - if (num.len) - return false; - *str = mp_append_utf8_buffer(*str, c); - *code = bstr_cut(*code, 5); - return true; - } - return false; -} diff --git a/mpvcore/mp_common.h b/mpvcore/mp_common.h deleted file mode 100644 index 9e751ee851..0000000000 --- a/mpvcore/mp_common.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MPLAYER_MPCOMMON_H -#define MPLAYER_MPCOMMON_H - -#include -#include -#include - -#include "compat/compiler.h" -#include "talloc.h" - -// both int64_t and double should be able to represent this exactly -#define MP_NOPTS_VALUE (-1LL<<63) - -#define MP_CONCAT_(a, b) a ## b -#define MP_CONCAT(a, b) MP_CONCAT_(a, b) - -#define ROUND(x) ((int)((x) < 0 ? (x) - 0.5 : (x) + 0.5)) - -#define MPMAX(a, b) ((a) > (b) ? (a) : (b)) -#define MPMIN(a, b) ((a) > (b) ? (b) : (a)) -#define MPCLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a))) -#define MPSWAP(type, a, b) \ - do { type SWAP_tmp = b; b = a; a = SWAP_tmp; } while (0) -#define MP_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0])) - -// align must be a power of two (align >= 1), x >= 0 -#define MP_ALIGN_UP(x, align) (((x) + (align) - 1) & ~((align) - 1)) -#define MP_ALIGN_DOWN(x, align) ((x) & ~((align) - 1)) - -#define CONTROL_OK 1 -#define CONTROL_TRUE 1 -#define CONTROL_FALSE 0 -#define CONTROL_UNKNOWN -1 -#define CONTROL_ERROR -2 -#define CONTROL_NA -3 - -enum stream_type { - STREAM_VIDEO, - STREAM_AUDIO, - STREAM_SUB, - STREAM_TYPE_COUNT, -}; - -extern const char *mplayer_version; -extern const char *mplayer_builddate; - -char *mp_format_time(double time, bool fractions); -char *mp_format_time_fmt(const char *fmt, double time); - -struct mp_rect { - int x0, y0; - int x1, y1; -}; - -void mp_rect_union(struct mp_rect *rc, const struct mp_rect *src); -bool mp_rect_intersection(struct mp_rect *rc, const struct mp_rect *rc2); - -char *mp_append_utf8_buffer(char *buffer, uint32_t codepoint); - -struct bstr; -bool mp_parse_escape(struct bstr *code, char **str); - -#endif /* MPLAYER_MPCOMMON_H */ diff --git a/mpvcore/mp_memory_barrier.h b/mpvcore/mp_memory_barrier.h deleted file mode 100644 index e27825de8f..0000000000 --- a/mpvcore/mp_memory_barrier.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * This file is part of mpv. - * Copyright (c) 2013 Stefano Pigozzi - * - * mpv 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. - * - * mpv 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 mpv. If not, see . - */ - -// At this point both gcc and clang had __sync_synchronize support for some -// time. We only support a full memory barrier. - -#define mp_memory_barrier() __sync_synchronize() -#define mp_atomic_add_and_fetch(a, b) __sync_add_and_fetch(a, b) diff --git a/mpvcore/mp_msg.c b/mpvcore/mp_msg.c deleted file mode 100644 index 0284f2a2cb..0000000000 --- a/mpvcore/mp_msg.c +++ /dev/null @@ -1,389 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include -#include -#include -#include -#include - -#include "talloc.h" - -#include "config.h" -#include "mpvcore/mpv_global.h" -#include "osdep/getch2.h" -#include "osdep/io.h" - -#ifndef __MINGW32__ -#include -#endif - -#include "mpvcore/mp_msg.h" - -bool mp_msg_stdout_in_use = 0; - -struct mp_log_root { - /* This should, at some point, contain all mp_msg related state, instead - * of having global variables (at least as long as we don't want to - * control the terminal, which is global anyway). But for now, there is - * not much. */ - struct mpv_global *global; -}; - -struct mp_log { - struct mp_log_root *root; - const char *prefix; - const char *verbose_prefix; - int legacy_mod; -}; - -// should not exist -static bool initialized; -static struct mp_log *legacy_logs[MSGT_MAX]; - -/* maximum message length of mp_msg */ -#define MSGSIZE_MAX 6144 - -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#include -#define hSTDOUT GetStdHandle(STD_OUTPUT_HANDLE) -#define hSTDERR GetStdHandle(STD_ERROR_HANDLE) -static short stdoutAttrs = 0; -static const unsigned char ansi2win32[10] = { - 0, - FOREGROUND_RED, - FOREGROUND_GREEN, - FOREGROUND_GREEN | FOREGROUND_RED, - FOREGROUND_BLUE, - FOREGROUND_BLUE | FOREGROUND_RED, - FOREGROUND_BLUE | FOREGROUND_GREEN, - FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED, - FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED, - FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED -}; -#endif - -int mp_msg_levels[MSGT_MAX]; // verbose level of this module. initialized to -2 -int mp_msg_level_all = MSGL_STATUS; -int verbose = 0; -int mp_msg_color = 1; -int mp_msg_module = 0; -int mp_msg_cancolor = 0; - -static int mp_msg_docolor(void) { - return mp_msg_cancolor && mp_msg_color; -} - -static void mp_msg_do_init(void){ -#ifdef _WIN32 - CONSOLE_SCREEN_BUFFER_INFO cinfo; - DWORD cmode = 0; - GetConsoleMode(hSTDOUT, &cmode); - cmode |= (ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT); - SetConsoleMode(hSTDOUT, cmode); - SetConsoleMode(hSTDERR, cmode); - GetConsoleScreenBufferInfo(hSTDOUT, &cinfo); - stdoutAttrs = cinfo.wAttributes; -#endif -#ifndef __MINGW32__ - struct sigaction sa; - sa.sa_handler = SIG_IGN; - sa.sa_flags = 0; - sigemptyset(&sa.sa_mask); - sigaction(SIGTTOU, &sa, NULL); // just write to stdout if you have to -#endif - int i; - char *env = getenv("MPV_VERBOSE"); - if (env) - verbose = atoi(env); - for(i=0;ilegacy_mod, lev); -} - -static void set_msg_color(FILE* stream, int lev) -{ - static const int v_colors[10] = {9, 1, 3, 3, -1, -1, 2, 8, 8, 8}; - int c = v_colors[lev]; -#ifdef MP_ANNOY_ME - /* that's only a silly color test */ - { - int c; - static int flag = 1; - if (flag) - for(c = 0; c < 24; c++) - printf("\033[%d;3%dm*** COLOR TEST %d ***\n", c>7, c&7, c); - flag = 0; - } -#endif - if (mp_msg_docolor()) - { -#if defined(_WIN32) && !defined(__CYGWIN__) - HANDLE *wstream = stream == stderr ? hSTDERR : hSTDOUT; - if (c == -1) - c = 7; - SetConsoleTextAttribute(wstream, ansi2win32[c] | FOREGROUND_INTENSITY); -#else - if (c == -1) { - fprintf(stream, "\033[0m"); - } else { - fprintf(stream, "\033[%d;3%dm", c >> 3, c & 7); - } -#endif - } -} - -static void print_msg_module(FILE* stream, struct mp_log *log) -{ - int mod = log->legacy_mod; - int c2 = (mod + 1) % 15 + 1; - -#ifdef _WIN32 - HANDLE *wstream = stream == stderr ? hSTDERR : hSTDOUT; - if (mp_msg_docolor()) - SetConsoleTextAttribute(wstream, ansi2win32[c2&7] | FOREGROUND_INTENSITY); - fprintf(stream, "%9s", log->verbose_prefix); - if (mp_msg_docolor()) - SetConsoleTextAttribute(wstream, stdoutAttrs); -#else - if (mp_msg_docolor()) - fprintf(stream, "\033[%d;3%dm", c2 >> 3, c2 & 7); - fprintf(stream, "%9s", log->verbose_prefix); - if (mp_msg_docolor()) - fprintf(stream, "\033[0;37m"); -#endif - fprintf(stream, ": "); -} - -static void mp_msg_log_va(struct mp_log *log, int lev, const char *format, - va_list va) -{ - char tmp[MSGSIZE_MAX]; - FILE *stream = - (mp_msg_stdout_in_use || (lev == MSGL_STATUS)) ? stderr : stdout; - static int header = 1; - // indicates if last line printed was a status line - static int statusline; - - if (!mp_msg_test_log(log, lev)) return; // do not display - vsnprintf(tmp, MSGSIZE_MAX, format, va); - tmp[MSGSIZE_MAX-2] = '\n'; - tmp[MSGSIZE_MAX-1] = 0; - - /* A status line is normally intended to be overwritten by the next - * status line, and does not end with a '\n'. If we're printing a normal - * line instead after the status one print '\n' to change line. */ - if (statusline && lev != MSGL_STATUS) - fprintf(stderr, "\n"); - statusline = lev == MSGL_STATUS; - - set_msg_color(stream, lev); - if (header) { - if (mp_msg_module) { - print_msg_module(stream, log); - set_msg_color(stream, lev); - } else if (lev >= MSGL_V || verbose) { - fprintf(stream, "[%s] ", log->verbose_prefix); - } else if (log->prefix) { - fprintf(stream, "[%s] ", log->prefix); - } - } - - size_t len = strlen(tmp); - header = len && (tmp[len-1] == '\n' || tmp[len-1] == '\r'); - - fprintf(stream, "%s", tmp); - - if (mp_msg_docolor()) - { -#ifdef _WIN32 - HANDLE *wstream = lev <= MSGL_WARN ? hSTDERR : hSTDOUT; - SetConsoleTextAttribute(wstream, stdoutAttrs); -#else - fprintf(stream, "\033[0m"); -#endif - } - fflush(stream); -} - -void mp_msg_va(int mod, int lev, const char *format, va_list va) -{ - assert(initialized); - assert(mod >= 0 && mod < MSGT_MAX); - mp_msg_log_va(legacy_logs[mod], lev, format, va); -} - -void mp_msg(int mod, int lev, const char *format, ...) -{ - va_list va; - va_start(va, format); - mp_msg_va(mod, lev, format, va); - va_end(va); -} - -// legacy names -static const char *module_text[MSGT_MAX] = { - "global", - "cplayer", - "gplayer", - "vo", - "ao", - "demuxer", - "ds", - "demux", - "header", - "avsync", - "autoq", - "cfgparser", - "decaudio", - "decvideo", - "seek", - "win32", - "open", - "dvd", - "parsees", - "lirc", - "stream", - "cache", - "mencoder", - "xacodec", - "tv", - "osdep", - "spudec", - "playtree", - "input", - "vf", - "osd", - "network", - "cpudetect", - "codeccfg", - "sws", - "vobsub", - "subreader", - "af", - "netst", - "muxer", - "osdmenu", - "identify", - "radio", - "ass", - "loader", - "statusline", - "teletext", -}; - -// Create a new log context, which uses talloc_ctx as talloc parent, and parent -// as logical parent. -// The name is the prefix put before the output. It's usually prefixed by the -// parent's name. If the name starts with "/", the parent's name is not -// prefixed (except in verbose mode), and if it starts with "!", the name is -// not printed at all (except in verbose mode). -struct mp_log *mp_log_new(void *talloc_ctx, struct mp_log *parent, - const char *name) -{ - assert(parent); - assert(name); - struct mp_log *log = talloc_zero(talloc_ctx, struct mp_log); - log->root = parent->root; - if (name[0] == '!') { - name = &name[1]; - } else if (name[0] == '/') { - name = &name[1]; - log->prefix = talloc_strdup(log, name); - } else { - log->prefix = parent->prefix - ? talloc_asprintf(log, "%s/%s", parent->prefix, name) - : talloc_strdup(log, name); - } - log->verbose_prefix = parent->prefix - ? talloc_asprintf(log, "%s/%s", parent->prefix, name) - : talloc_strdup(log, name); - if (log->prefix && !log->prefix[0]) - log->prefix = NULL; - if (!log->verbose_prefix[0]) - log->verbose_prefix = "global"; - log->legacy_mod = parent->legacy_mod; - for (int n = 0; n < MSGT_MAX; n++) { - if (module_text[n] && strcmp(name, module_text[n]) == 0) { - log->legacy_mod = n; - break; - } - } - return log; -} - -void mp_msg_init(struct mpv_global *global) -{ - assert(!initialized); - assert(!global->log); - - struct mp_log_root *root = talloc_zero(NULL, struct mp_log_root); - root->global = global; - - struct mp_log dummy = { .root = root }; - struct mp_log *log = mp_log_new(root, &dummy, ""); - for (int n = 0; n < MSGT_MAX; n++) { - char name[80]; - snprintf(name, sizeof(name), "!%s", module_text[n]); - legacy_logs[n] = mp_log_new(root, log, name); - } - mp_msg_do_init(); - - global->log = log; - initialized = true; -} - -struct mpv_global *mp_log_get_global(struct mp_log *log) -{ - return log->root->global; -} - -void mp_msg_uninit(struct mpv_global *global) -{ - talloc_free(global->log->root); - global->log = NULL; - initialized = false; -} - -void mp_msg_log(struct mp_log *log, int lev, const char *format, ...) -{ - va_list va; - va_start(va, format); - mp_msg_log_va(log, lev, format, va); - va_end(va); -} diff --git a/mpvcore/mp_msg.h b/mpvcore/mp_msg.h deleted file mode 100644 index 976ed5e3f8..0000000000 --- a/mpvcore/mp_msg.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MPLAYER_MP_MSG_H -#define MPLAYER_MP_MSG_H - -#include -#include - -struct mp_log; - -// defined in mplayer.c -extern int verbose; - -/* No-op macro to mark translated strings in the sources */ -#define _(x) x - -// verbosity elevel: - -/* Only messages level MSGL_FATAL-MSGL_STATUS should be translated, - * messages level MSGL_V and above should not be translated. */ - -#define MSGL_FATAL 0 // will exit/abort -#define MSGL_ERR 1 // continues -#define MSGL_WARN 2 // only warning -#define MSGL_HINT 3 // short help message -#define MSGL_INFO 4 // -quiet -#define MSGL_STATUS 5 // v=0 -#define MSGL_V 6 // v=1 -#define MSGL_DBG2 7 // v=2 -#define MSGL_DBG3 8 // v=3 -#define MSGL_DBG4 9 // v=4 -#define MSGL_DBG5 10 // v=5 - -#define MSGL_FIXME 1 // for conversions from printf where the appropriate MSGL is not known; set equal to ERR for obtrusiveness -#define MSGT_FIXME 0 // for conversions from printf where the appropriate MSGT is not known; set equal to GLOBAL for obtrusiveness - -// code/module: - -#define MSGT_GLOBAL 0 // common player stuff errors -#define MSGT_CPLAYER 1 // console player (mplayer.c) - -#define MSGT_VO 3 // libvo -#define MSGT_AO 4 // libao - -#define MSGT_DEMUXER 5 // demuxer.c (general stuff) -#define MSGT_DS 6 // demux stream (add/read packet etc) -#define MSGT_DEMUX 7 // fileformat-specific stuff (demux_*.c) -#define MSGT_HEADER 8 // fileformat-specific header (*header.c) - -#define MSGT_AVSYNC 9 // mplayer.c timer stuff -#define MSGT_AUTOQ 10 // mplayer.c auto-quality stuff - -#define MSGT_CFGPARSER 11 // cfgparser.c - -#define MSGT_DECAUDIO 12 // av decoder -#define MSGT_DECVIDEO 13 - -#define MSGT_SEEK 14 // seeking code -#define MSGT_WIN32 15 // win32 dll stuff -#define MSGT_OPEN 16 // open.c (stream opening) -#define MSGT_DVD 17 // open.c (DVD init/read/seek) - -#define MSGT_PARSEES 18 // parse_es.c (mpeg stream parser) -#define MSGT_LIRC 19 // lirc_mp.c and input lirc driver - -#define MSGT_STREAM 20 // stream.c -#define MSGT_CACHE 21 // cache2.c - -#define MSGT_ENCODE 22 // now encode_lavc.c - -#define MSGT_XACODEC 23 // XAnim codecs - -#define MSGT_TV 24 // TV input subsystem - -#define MSGT_OSDEP 25 // OS-dependent parts - -#define MSGT_SPUDEC 26 // spudec.c - -#define MSGT_PLAYTREE 27 // Playtree handeling (playtree.c, playtreeparser.c) - -#define MSGT_INPUT 28 - -#define MSGT_VFILTER 29 - -#define MSGT_OSD 30 - -#define MSGT_NETWORK 31 - -#define MSGT_CPUDETECT 32 - -#define MSGT_CODECCFG 33 - -#define MSGT_SWS 34 - -#define MSGT_VOBSUB 35 -#define MSGT_SUBREADER 36 - -#define MSGT_AFILTER 37 // Audio filter messages - -#define MSGT_NETST 38 // Netstream - -#define MSGT_MUXER 39 // muxer layer - -#define MSGT_IDENTIFY 41 // -identify output - -#define MSGT_RADIO 42 - -#define MSGT_ASS 43 // libass messages - -#define MSGT_LOADER 44 // dll loader messages - -#define MSGT_STATUSLINE 45 // playback/encoding status line - -#define MSGT_TELETEXT 46 // Teletext decoder - -#define MSGT_MAX 47 - -int mp_msg_test(int mod, int lev); -bool mp_msg_test_log(struct mp_log *log, int lev); - -#include "config.h" -#include "mpvcore/mp_common.h" - -// Note: using mp_msg_log or the MP_ERR/... macros is preferred. -void mp_msg_va(int mod, int lev, const char *format, va_list va); -void mp_msg(int mod, int lev, const char *format, ... ) PRINTF_ATTRIBUTE(3, 4); - -struct mp_log *mp_log_new(void *talloc_ctx, struct mp_log *parent, - const char *name); - -void mp_msg_log(struct mp_log *log, int lev, const char *format, ...) - PRINTF_ATTRIBUTE(3, 4); - -// Convenience macros, typically called with a pointer to a context struct -// as first argument, which has a "struct mp_log log;" member. - -#define MP_MSG(obj, lev, ...) mp_msg_log((obj)->log, lev, __VA_ARGS__) -#define MP_MSGT(obj, lev, ...) mp_msgt_log((obj)->log, lev, __VA_ARGS__) - -#define MP_FATAL(obj, ...) MP_MSG(obj, MSGL_FATAL, __VA_ARGS__) -#define MP_ERR(obj, ...) MP_MSG(obj, MSGL_ERR, __VA_ARGS__) -#define MP_WARN(obj, ...) MP_MSG(obj, MSGL_WARN, __VA_ARGS__) -#define MP_INFO(obj, ...) MP_MSG(obj, MSGL_INFO, __VA_ARGS__) -#define MP_VERBOSE(obj, ...) MP_MSG(obj, MSGL_V, __VA_ARGS__) -#define MP_DBG(obj, ...) MP_MSG(obj, MSGL_DBG2, __VA_ARGS__) -#define MP_TRACE(obj, ...) MP_MSG(obj, MSGL_DBG5, __VA_ARGS__) - -#define mp_fatal(log, ...) mp_msg_log(log, MSGL_FATAL, __VA_ARGS__) -#define mp_err(log, ...) mp_msg_log(log, MSGL_ERR, __VA_ARGS__) -#define mp_warn(log, ...) mp_msg_log(log, MSGL_WARN, __VA_ARGS__) -#define mp_info(log, ...) mp_msg_log(log, MSGL_INFO, __VA_ARGS__) -#define mp_verbose(log, ...) mp_msg_log(log, MSGL_V, __VA_ARGS__) -#define mp_dbg(log, ...) mp_msg_log(log, MSGL_DBG2, __VA_ARGS__) -#define mp_trace(log, ...) mp_msg_log(log, MSGL_DBG5, __VA_ARGS__) - -struct mpv_global; -void mp_msg_init(struct mpv_global *global); -void mp_msg_uninit(struct mpv_global *global); - -struct mpv_global *mp_log_get_global(struct mp_log *log); - -extern bool mp_msg_stdout_in_use; - -#endif /* MPLAYER_MP_MSG_H */ diff --git a/mpvcore/mp_ring.c b/mpvcore/mp_ring.c deleted file mode 100644 index d310aa4f46..0000000000 --- a/mpvcore/mp_ring.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * This file is part of mpv. - * Copyright (c) 2012 wm4 - * Copyright (c) 2013 Stefano Pigozzi - * - * mpv 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. - * - * mpv 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 mpv. If not, see . - */ - -#include -#include -#include -#include "talloc.h" -#include "mpvcore/mp_memory_barrier.h" -#include "mpvcore/mp_ring.h" - -struct mp_ring { - uint8_t *buffer; - - /* Positions of the first readable/writeable chunks. Do not read this - * fields but use the atomic private accessors `mp_ring_get_wpos` - * and `mp_ring_get_rpos`. */ - uint32_t rpos, wpos; -}; - -static uint32_t mp_ring_get_wpos(struct mp_ring *buffer) -{ - mp_memory_barrier(); - return buffer->wpos; -} - -static uint32_t mp_ring_get_rpos(struct mp_ring *buffer) -{ - mp_memory_barrier(); - return buffer->rpos; -} - -struct mp_ring *mp_ring_new(void *talloc_ctx, int size) -{ - struct mp_ring *ringbuffer = - talloc_zero(talloc_ctx, struct mp_ring); - - *ringbuffer = (struct mp_ring) { - .buffer = talloc_size(talloc_ctx, size), - }; - - return ringbuffer; -} - -int mp_ring_drain(struct mp_ring *buffer, int len) -{ - int buffered = mp_ring_buffered(buffer); - int drain_len = FFMIN(len, buffered); - mp_atomic_add_and_fetch(&buffer->rpos, drain_len); - mp_memory_barrier(); - return drain_len; -} - -int mp_ring_read(struct mp_ring *buffer, unsigned char *dest, int len) -{ - if (!dest) return mp_ring_drain(buffer, len); - - int size = mp_ring_size(buffer); - int buffered = mp_ring_buffered(buffer); - int read_len = FFMIN(len, buffered); - int read_ptr = mp_ring_get_rpos(buffer) % size; - - int len1 = FFMIN(size - read_ptr, read_len); - int len2 = read_len - len1; - - memcpy(dest, buffer->buffer + read_ptr, len1); - memcpy(dest + len1, buffer->buffer, len2); - - mp_atomic_add_and_fetch(&buffer->rpos, read_len); - mp_memory_barrier(); - - return read_len; -} - -int mp_ring_write(struct mp_ring *buffer, unsigned char *src, int len) -{ - int size = mp_ring_size(buffer); - int free = mp_ring_available(buffer); - int write_len = FFMIN(len, free); - int write_ptr = mp_ring_get_wpos(buffer) % size; - - int len1 = FFMIN(size - write_ptr, write_len); - int len2 = write_len - len1; - - memcpy(buffer->buffer + write_ptr, src, len1); - memcpy(buffer->buffer, src + len1, len2); - - mp_atomic_add_and_fetch(&buffer->wpos, write_len); - mp_memory_barrier(); - - return write_len; -} - -void mp_ring_reset(struct mp_ring *buffer) -{ - buffer->wpos = buffer->rpos = 0; - mp_memory_barrier(); -} - -int mp_ring_available(struct mp_ring *buffer) -{ - return mp_ring_size(buffer) - mp_ring_buffered(buffer); -} - -int mp_ring_size(struct mp_ring *buffer) -{ - return talloc_get_size(buffer->buffer); -} - -int mp_ring_buffered(struct mp_ring *buffer) -{ - return (mp_ring_get_wpos(buffer) - mp_ring_get_rpos(buffer)); -} - -char *mp_ring_repr(struct mp_ring *buffer, void *talloc_ctx) -{ - return talloc_asprintf( - talloc_ctx, - "Ringbuffer { .size = %dB, .buffered = %dB, .available = %dB }", - mp_ring_size(buffer), - mp_ring_buffered(buffer), - mp_ring_available(buffer)); -} diff --git a/mpvcore/mp_ring.h b/mpvcore/mp_ring.h deleted file mode 100644 index e93baea97e..0000000000 --- a/mpvcore/mp_ring.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * This file is part of mpv. - * Copyright (c) 2012 wm4 - * Copyright (c) 2013 Stefano Pigozzi - * - * mpv 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. - * - * mpv 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 mpv. If not, see . - */ - -#ifndef MPV_MP_RING_H -#define MPV_MP_RING_H - -/** - * A simple non-blocking SPSC (single producer, single consumer) ringbuffer - * implementation. Thread safety is accomplished through atomic operations. - */ - -struct mp_ring; - -/** - * Instantiate a new ringbuffer - * - * talloc_ctx: talloc context of the newly created object - * size: total size in bytes - * return: the newly created ringbuffer - */ -struct mp_ring *mp_ring_new(void *talloc_ctx, int size); - -/** - * Read data from the ringbuffer - * - * buffer: target ringbuffer instance - * dest: destination buffer for the read data. If NULL read data is discarded. - * len: maximum number of bytes to read - * return: number of bytes read - */ -int mp_ring_read(struct mp_ring *buffer, unsigned char *dest, int len); - -/** - * Write data to the ringbuffer - * - * buffer: target ringbuffer instance - * src: source buffer for the write data - * len: maximum number of bytes to write - * return: number of bytes written - */ -int mp_ring_write(struct mp_ring *buffer, unsigned char *src, int len); - -/** - * Drain data from the ringbuffer - * - * buffer: target ringbuffer instance - * len: maximum number of bytes to drain - * return: number of bytes drained - */ -int mp_ring_drain(struct mp_ring *buffer, int len); - -/** - * Reset the ringbuffer discarding any content - * - * buffer: target ringbuffer instance - */ -void mp_ring_reset(struct mp_ring *buffer); - -/** - * Get the available size for writing - * - * buffer: target ringbuffer instance - * return: number of bytes that can be written - */ -int mp_ring_available(struct mp_ring *buffer); - -/** - * Get the total size - * - * buffer: target ringbuffer instance - * return: total ringbuffer size in bytes - */ -int mp_ring_size(struct mp_ring *buffer); - -/** - * Get the available size for reading - * - * buffer: target ringbuffer instance - * return: number of bytes ready for reading - */ -int mp_ring_buffered(struct mp_ring *buffer); - -/** - * Get a string representation of the ringbuffer - * - * buffer: target ringbuffer instance - * talloc_ctx: talloc context of the newly created string - * return: string representing the ringbuffer - */ -char *mp_ring_repr(struct mp_ring *buffer, void *talloc_ctx); - -#endif diff --git a/mpvcore/mpv_global.h b/mpvcore/mpv_global.h deleted file mode 100644 index 546c585294..0000000000 --- a/mpvcore/mpv_global.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef MPV_MPV_H -#define MPV_MPV_H - -// This should be accessed by glue code only, never normal code. -// The only purpose of this is to make mpv library-safe. -// Think hard before adding new members. -struct mpv_global { - struct MPOpts *opts; - struct mp_log *log; -}; - -#endif diff --git a/mpvcore/playlist.c b/mpvcore/playlist.c deleted file mode 100644 index e88838fde2..0000000000 --- a/mpvcore/playlist.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * This file is part of mplayer. - * - * mplayer 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. - * - * mplayer 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 mplayer. If not, see . - */ - -#include -#include "config.h" -#include "playlist.h" -#include "mpvcore/mp_common.h" -#include "talloc.h" -#include "options/path.h" - -struct playlist_entry *playlist_entry_new(const char *filename) -{ - struct playlist_entry *e = talloc_zero(NULL, struct playlist_entry); - e->filename = talloc_strdup(e, filename); - return e; -} - -void playlist_entry_add_param(struct playlist_entry *e, bstr name, bstr value) -{ - struct playlist_param p = {bstrdup(e, name), bstrdup(e, value)}; - MP_TARRAY_APPEND(e, e->params, e->num_params, p); -} - -void playlist_entry_add_params(struct playlist_entry *e, - struct playlist_param *params, - int num_params) -{ - for (int n = 0; n < num_params; n++) - playlist_entry_add_param(e, params[n].name, params[n].value); -} - -// Add entry "add" after entry "after". -// If "after" is NULL, add as first entry. -// Post condition: add->prev == after -void playlist_insert(struct playlist *pl, struct playlist_entry *after, - struct playlist_entry *add) -{ - assert(pl && add->pl == NULL && add->next == NULL && add->prev == NULL); - if (after) { - assert(after->pl == pl); - assert(pl->first && pl->last); - } - add->prev = after; - if (after) { - add->next = after->next; - after->next = add; - } else { - add->next = pl->first; - pl->first = add; - } - if (add->next) { - add->next->prev = add; - } else { - pl->last = add; - } - add->pl = pl; - talloc_steal(pl, add); -} - -void playlist_add(struct playlist *pl, struct playlist_entry *add) -{ - playlist_insert(pl, pl->last, add); -} - -static void playlist_unlink(struct playlist *pl, struct playlist_entry *entry) -{ - assert(pl && entry->pl == pl); - - if (pl->current == entry) { - pl->current = entry->next; - pl->current_was_replaced = true; - } - - if (entry->next) { - entry->next->prev = entry->prev; - } else { - pl->last = entry->prev; - } - if (entry->prev) { - entry->prev->next = entry->next; - } else { - pl->first = entry->next; - } - entry->next = entry->prev = NULL; - // xxx: we'd want to reset the talloc parent of entry - entry->pl = NULL; -} - -void playlist_remove(struct playlist *pl, struct playlist_entry *entry) -{ - playlist_unlink(pl, entry); - talloc_free(entry); -} - -void playlist_clear(struct playlist *pl) -{ - while (pl->first) - playlist_remove(pl, pl->first); - assert(!pl->current); - pl->current_was_replaced = false; -} - -// Moves entry such that entry->prev = at (even if at is NULL) -void playlist_move(struct playlist *pl, struct playlist_entry *entry, - struct playlist_entry *at) -{ - struct playlist_entry *save_current = pl->current; - bool save_replaced = pl->current_was_replaced; - - playlist_unlink(pl, entry); - playlist_insert(pl, at ? at->prev : pl->last, entry); - - pl->current = save_current; - pl->current_was_replaced = save_replaced; -} - -void playlist_add_file(struct playlist *pl, const char *filename) -{ - playlist_add(pl, playlist_entry_new(filename)); -} - -static int playlist_count(struct playlist *pl) -{ - int c = 0; - for (struct playlist_entry *e = pl->first; e; e = e->next) - c++; - return c; -} - -void playlist_shuffle(struct playlist *pl) -{ - struct playlist_entry *save_current = pl->current; - bool save_replaced = pl->current_was_replaced; - int count = playlist_count(pl); - struct playlist_entry **arr = talloc_array(NULL, struct playlist_entry *, - count); - for (int n = 0; n < count; n++) { - arr[n] = pl->first; - playlist_unlink(pl, pl->first); - } - for (int n = 0; n < count; n++) { - int other = (int)((double)(count) * rand() / (RAND_MAX + 1.0)); - struct playlist_entry *tmp = arr[n]; - arr[n] = arr[other]; - arr[other] = tmp; - } - for (int n = 0; n < count; n++) - playlist_add(pl, arr[n]); - talloc_free(arr); - pl->current = save_current; - pl->current_was_replaced = save_replaced; -} - -struct playlist_entry *playlist_get_next(struct playlist *pl, int direction) -{ - assert(direction == -1 || direction == +1); - if (!pl->current) - return NULL; - assert(pl->current->pl == pl); - if (direction < 0) - return pl->current->prev; - return pl->current_was_replaced ? pl->current : pl->current->next; -} - -void playlist_add_base_path(struct playlist *pl, bstr base_path) -{ - if (base_path.len == 0 || bstrcmp0(base_path, ".") == 0) - return; - for (struct playlist_entry *e = pl->first; e; e = e->next) { - if (!mp_is_url(bstr0(e->filename))) { - char *new_file = mp_path_join(e, base_path, bstr0(e->filename)); - talloc_free(e->filename); - e->filename = new_file; - } - } -} - -// Move all entries from source_pl to pl, appending them after the current entry -// of pl. source_pl will be empty, and all entries have changed ownership to pl. -void playlist_transfer_entries(struct playlist *pl, struct playlist *source_pl) -{ - struct playlist_entry *add_after = pl->current; - if (pl->current && pl->current_was_replaced) - add_after = pl->current->next; - if (!add_after) - add_after = pl->last; - - while (source_pl->first) { - struct playlist_entry *e = source_pl->first; - playlist_unlink(source_pl, e); - playlist_insert(pl, add_after, e); - add_after = e; - } -} - -// Return number of entries between list start and e. -// Return -1 if e is not on the list, or if e is NULL. -int playlist_entry_to_index(struct playlist *pl, struct playlist_entry *e) -{ - struct playlist_entry *cur = pl->first; - int pos = 0; - if (!e) - return -1; - while (cur && cur != e) { - cur = cur->next; - pos++; - } - return cur == e ? pos : -1; -} - -int playlist_entry_count(struct playlist *pl) -{ - return playlist_entry_to_index(pl, pl->last) + 1; -} - -// Return entry for which playlist_entry_to_index() would return index. -// Return NULL if not found. -struct playlist_entry *playlist_entry_from_index(struct playlist *pl, int index) -{ - struct playlist_entry *e = pl->first; - for (int n = 0; ; n++) { - if (!e || n == index) - return e; - e = e->next; - } -} - diff --git a/mpvcore/playlist.h b/mpvcore/playlist.h deleted file mode 100644 index 35d9dab701..0000000000 --- a/mpvcore/playlist.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * This file is part of mplayer. - * - * mplayer 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. - * - * mplayer 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 mplayer. If not, see . - */ - -#ifndef MPLAYER_PLAYLIST_H -#define MPLAYER_PLAYLIST_H - -#include -#include "mpvcore/bstr.h" - -struct playlist_param { - bstr name, value; -}; - -struct playlist_entry { - struct playlist_entry *prev, *next; - struct playlist *pl; - - char *filename; - - struct playlist_param *params; - int num_params; - - // Set to true if playback didn't seem to work, or if the file could be - // played only for a very short time. This is used to make playlist - // navigation just work in case the user has unplayable files in the - // playlist. - bool playback_short : 1; - // Set to true if not at least 1 frame (audio or video) could be played. - bool init_failed : 1; -}; - -struct playlist { - struct playlist_entry *first, *last; - - // This provides some sort of stable iterator. If this entry is removed from - // the playlist, current is set to the next element (or NULL), and - // current_was_replaced is set to true. - struct playlist_entry *current; - bool current_was_replaced; -}; - -void playlist_entry_add_param(struct playlist_entry *e, bstr name, bstr value); -void playlist_entry_add_params(struct playlist_entry *e, - struct playlist_param *params, - int params_count); - -struct playlist_entry *playlist_entry_new(const char *filename); - -void playlist_insert(struct playlist *pl, struct playlist_entry *after, - struct playlist_entry *add); -void playlist_add(struct playlist *pl, struct playlist_entry *add); -void playlist_remove(struct playlist *pl, struct playlist_entry *entry); -void playlist_clear(struct playlist *pl); - -void playlist_move(struct playlist *pl, struct playlist_entry *entry, - struct playlist_entry *at); - -void playlist_add_file(struct playlist *pl, const char *filename); -void playlist_shuffle(struct playlist *pl); -struct playlist_entry *playlist_get_next(struct playlist *pl, int direction); -void playlist_add_base_path(struct playlist *pl, bstr base_path); -void playlist_transfer_entries(struct playlist *pl, struct playlist *source_pl); - -int playlist_entry_to_index(struct playlist *pl, struct playlist_entry *e); -int playlist_entry_count(struct playlist *pl); -struct playlist_entry *playlist_entry_from_index(struct playlist *pl, int index); - -#endif diff --git a/mpvcore/playlist_parser.c b/mpvcore/playlist_parser.c deleted file mode 100644 index 17679ddf1f..0000000000 --- a/mpvcore/playlist_parser.c +++ /dev/null @@ -1,566 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -/* - * Warning: this is outdated, crappy code. It is used only for --playlist. - * New or cleaned up code should be added to demux_playlist.c instead. - */ - -#include "config.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "talloc.h" -#include "asxparser.h" -#include "playlist.h" -#include "playlist_parser.h" -#include "stream/stream.h" -#include "demux/demux.h" -#include "mpvcore/mp_msg.h" -#include "options/path.h" - - -#define BUF_STEP 1024 - -#define WHITES " \n\r\t" - -typedef struct play_tree_parser { - struct stream *stream; - char *buffer,*iter,*line; - int buffer_size , buffer_end; - int keep; - struct playlist *pl; -} play_tree_parser_t; - -static void -strstrip(char* str) { - char* i; - - if (str==NULL) - return; - for(i = str ; i[0] != '\0' && strchr(WHITES,i[0]) != NULL; i++) - /* NOTHING */; - if(i[0] != '\0') { - memmove(str,i,strlen(i) + 1); - for(i = str + strlen(str) - 1 ; strchr(WHITES,i[0]) != NULL; i--) - /* NOTHING */; - i[1] = '\0'; - } else - str[0] = '\0'; -} - -static char* -play_tree_parser_get_line(play_tree_parser_t* p) { - char *end,*line_end; - int r,resize = 0; - - if(p->buffer == NULL) { - p->buffer = malloc(BUF_STEP); - p->buffer_size = BUF_STEP; - p->buffer[0] = 0; - p->iter = p->buffer; - } - - if(p->stream->eof && (p->buffer_end == 0 || p->iter[0] == '\0')) - return NULL; - - assert(p->buffer_end < p->buffer_size); - assert(!p->buffer[p->buffer_end]); - while(1) { - - if(resize) { - char *tmp; - r = p->iter - p->buffer; - end = p->buffer + p->buffer_end; - if (p->buffer_size > INT_MAX - BUF_STEP) - break; - tmp = realloc(p->buffer, p->buffer_size + BUF_STEP); - if (!tmp) - break; - p->buffer = tmp; - p->iter = p->buffer + r; - p->buffer_size += BUF_STEP; - resize = 0; - } - - if(p->buffer_size - p->buffer_end > 1 && ! p->stream->eof) { - r = stream_read(p->stream,p->buffer + p->buffer_end,p->buffer_size - p->buffer_end - 1); - if(r > 0) { - p->buffer_end += r; - assert(p->buffer_end < p->buffer_size); - p->buffer[p->buffer_end] = '\0'; - while(strlen(p->buffer + p->buffer_end - r) != r) - p->buffer[p->buffer_end - r + strlen(p->buffer + p->buffer_end - r)] = '\n'; - } - assert(!p->buffer[p->buffer_end]); - } - - end = strchr(p->iter,'\n'); - if(!end) { - if(p->stream->eof) { - end = p->buffer + p->buffer_end; - break; - } - resize = 1; - continue; - } - break; - } - - line_end = (end > p->iter && *(end-1) == '\r') ? end-1 : end; - if(line_end - p->iter >= 0) - p->line = realloc(p->line, line_end - p->iter + 1); - else - return NULL; - if(line_end - p->iter > 0) - strncpy(p->line,p->iter,line_end - p->iter); - p->line[line_end - p->iter] = '\0'; - if(end[0] != '\0') - end++; - - if(!p->keep) { - if(end[0] != '\0') { - p->buffer_end -= end-p->iter; - memmove(p->buffer,end,p->buffer_end); - } else - p->buffer_end = 0; - p->buffer[p->buffer_end] = '\0'; - p->iter = p->buffer; - } else - p->iter = end; - - return p->line; -} - -static void -play_tree_parser_reset(play_tree_parser_t* p) { - p->iter = p->buffer; -} - -static void -play_tree_parser_stop_keeping(play_tree_parser_t* p) { - p->keep = 0; - if(p->iter && p->iter != p->buffer) { - p->buffer_end -= p->iter -p->buffer; - if(p->buffer_end) - memmove(p->buffer,p->iter,p->buffer_end); - p->buffer[p->buffer_end] = 0; - p->iter = p->buffer; - } -} - - -static bool parse_asx(play_tree_parser_t* p) { - int comments = 0,get_line = 1; - char* line = NULL; - - mp_msg(MSGT_PLAYTREE,MSGL_V,"Trying asx...\n"); - - while(1) { - if(get_line) { - line = play_tree_parser_get_line(p); - if(!line) - return false; - strstrip(line); - if(line[0] == '\0') - continue; - } - if(!comments) { - if(line[0] != '<') { - mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"First char isn't '<' but '%c'\n",line[0]); - mp_msg(MSGT_PLAYTREE,MSGL_DBG3,"Buffer = [%s]\n",p->buffer); - return false; - } else if(strncmp(line,"",4) == 0) { // End of comments - comments = 0; - line = c+4; - if(line[0] != '\0') // There is some more data on this line : keep it - get_line = 0; - - } else { - line = c+1; // Jump the - - if(line[0] != '\0') // Some more data - get_line = 0; - else // End of line - get_line = 1; - } - } else // No - on this line (or rest of line) : get next one - get_line = 1; - } - } - - mp_msg(MSGT_PLAYTREE,MSGL_V,"Detected asx format\n"); - - // We have an asx : load it in memory and parse - - while((line = play_tree_parser_get_line(p)) != NULL) - /* NOTHING */; - - mp_msg(MSGT_PLAYTREE,MSGL_DBG3,"Parsing asx file: [%s]\n",p->buffer); - return asx_parse(p->buffer,p->pl); -} - -static bool parse_smil(play_tree_parser_t* p) { - int entrymode=0; - char* line,source[512],*pos,*s_start,*s_end,*src_line; - int is_rmsmil = 0; - unsigned int npkt, ttlpkt; - - mp_msg(MSGT_PLAYTREE,MSGL_V,"Trying smil playlist...\n"); - - // Check if smil - while((line = play_tree_parser_get_line(p)) != NULL) { - strstrip(line); - if(line[0] == '\0') // Ignore empties - continue; - if (strncasecmp(line," ttlpkt) { - mp_msg(MSGT_PLAYTREE,MSGL_WARN,"smil-over-realrtsp: bad packet counters (npkk = %u, ttlpkt = %u), assuming single packet.\n", - npkt, ttlpkt); - npkt = ttlpkt = 1; - } - } - - //Get entries from smil - src_line = line; - line = NULL; - do { - strstrip(src_line); - free(line); - line = NULL; - /* If we're parsing smil over realrtsp and this is not the last packet and - * this is the last line in the packet (terminating with ") ) we must get - * the next line, strip the header, and concatenate it to the current line. - */ - if (is_rmsmil && npkt != ttlpkt && strstr(src_line,"\")")) { - char *payload; - - line = strdup(src_line); - if(!(src_line = play_tree_parser_get_line(p))) { - mp_msg(MSGT_PLAYTREE,MSGL_WARN,"smil-over-realrtsp: can't get line from packet %u/%u.\n", npkt, ttlpkt); - break; - } - strstrip(src_line); - // Skip header, packet starts after " - if(!(payload = strchr(src_line,'\"'))) { - mp_msg(MSGT_PLAYTREE,MSGL_WARN,"smil-over-realrtsp: can't find start of packet, using complete line.\n"); - payload = src_line; - } else - payload++; - // Skip ") at the end of the last line from the current packet - line[strlen(line)-2] = 0; - line = realloc(line, strlen(line)+strlen(payload)+1); - strcat (line, payload); - npkt++; - } else - line = strdup(src_line); - /* Unescape \" to " for smil-over-rtsp */ - if (is_rmsmil && line[0] != '\0') { - int i, j; - - for (i = 0; i < strlen(line); i++) - if (line[i] == '\\' && line[i+1] == '"') - for (j = i; line[j]; j++) - line[j] = line[j+1]; - } - pos = line; - while (pos) { - if (!entrymode) { // all entries filled so far - while ((pos=strchr(pos, '<'))) { - if (strncasecmp(pos," 511) { - mp_msg(MSGT_PLAYTREE,MSGL_V,"Cannot store such a large source %s\n",line); - break; - } - strncpy(source,s_start,s_end-s_start); - source[(s_end-s_start)]='\0'; // Null terminate - playlist_add_file(p->pl, source); - pos = s_end; - } - } - } - } while((src_line = play_tree_parser_get_line(p)) != NULL); - - free(line); - return true; -} - -static bool parse_textplain(play_tree_parser_t* p) { - char* line; - - mp_msg(MSGT_PLAYTREE,MSGL_V,"Trying plaintext playlist...\n"); - play_tree_parser_stop_keeping(p); - - while((line = play_tree_parser_get_line(p)) != NULL) { - strstrip(line); - if(line[0] == '\0' || line[0] == '#' || (line[0] == '/' && line[1] == '/')) - continue; - - playlist_add_file(p->pl,line); - } - - return true; -} - -/** - * \brief decode the base64 used in nsc files - * \param in input string, 0-terminated - * \param buf output buffer, must point to memory suitable for realloc, - * will be NULL on failure. - * \return decoded length in bytes - */ -static int decode_nsc_base64(char *in, char **buf) { - int i, j, n; - if (in[0] != '0' || in[1] != '2') - goto err_out; - in += 2; // skip prefix - if (strlen(in) < 16) // error out if nothing to decode - goto err_out; - in += 12; // skip encoded string length - n = strlen(in) / 4; - *buf = realloc(*buf, n * 3); - for (i = 0; i < n; i++) { - uint8_t c[4]; - for (j = 0; j < 4; j++) { - c[j] = in[4 * i + j]; - if (c[j] >= '0' && c[j] <= '9') c[j] += 0 - '0'; - else if (c[j] >= 'A' && c[j] <= 'Z') c[j] += 10 - 'A'; - else if (c[j] >= 'a' && c[j] <= 'z') c[j] += 36 - 'a'; - else if (c[j] == '{') c[j] = 62; - else if (c[j] == '}') c[j] = 63; - else { - mp_msg(MSGT_PLAYTREE, MSGL_ERR, "Invalid character %c (0x%02"PRIx8")\n", c[j], c[j]); - goto err_out; - } - } - (*buf)[3 * i] = (c[0] << 2) | (c[1] >> 4); - (*buf)[3 * i + 1] = (c[1] << 4) | (c[2] >> 2); - (*buf)[3 * i + 2] = (c[2] << 6) | c[3]; - } - return 3 * n; -err_out: - free(*buf); - *buf = NULL; - return 0; -} - -/** - * \brief "converts" utf16 to ascii by just discarding every second byte - * \param buf buffer to convert - * \param len lenght of buffer, must be > 0 - */ -static void utf16_to_ascii(char *buf, int len) { - int i; - if (len <= 0) return; - for (i = 0; i < len / 2; i++) - buf[i] = buf[i * 2]; - buf[i] = 0; // just in case -} - -static bool parse_nsc(play_tree_parser_t* p) { - char *line, *addr = NULL, *url, *unicast_url = NULL; - int port = 0; - - mp_msg(MSGT_PLAYTREE,MSGL_V,"Trying nsc playlist...\n"); - while((line = play_tree_parser_get_line(p)) != NULL) { - strstrip(line); - if(!line[0]) // Ignore empties - continue; - if (strncasecmp(line,"[Address]", 9) == 0) - break; // nsc header found - else - return false; - } - mp_msg(MSGT_PLAYTREE,MSGL_V,"Detected nsc playlist format\n"); - play_tree_parser_stop_keeping(p); - while ((line = play_tree_parser_get_line(p)) != NULL) { - strstrip(line); - if (!line[0]) - continue; - if (strncasecmp(line, "Unicast URL=", 12) == 0) { - int len = decode_nsc_base64(&line[12], &unicast_url); - if (len <= 0) - mp_msg(MSGT_PLAYTREE, MSGL_WARN, "[nsc] Unsupported Unicast URL encoding\n"); - else - utf16_to_ascii(unicast_url, len); - } else if (strncasecmp(line, "IP Address=", 11) == 0) { - int len = decode_nsc_base64(&line[11], &addr); - if (len <= 0) - mp_msg(MSGT_PLAYTREE, MSGL_WARN, "[nsc] Unsupported IP Address encoding\n"); - else - utf16_to_ascii(addr, len); - } else if (strncasecmp(line, "IP Port=", 8) == 0) { - port = strtol(&line[8], NULL, 0); - } - } - - bool success = false; - - if (unicast_url) - url = strdup(unicast_url); - else if (addr && port) { - url = malloc(strlen(addr) + 7 + 20 + 1); - sprintf(url, "http://%s:%i", addr, port); - } else - goto err_out; - - playlist_add_file(p->pl, url); - free(url); - success = true; -err_out: - free(addr); - free(unicast_url); - return success; -} - -static struct playlist *do_parse(struct stream* stream, bool forced); - -struct playlist *playlist_parse_file(const char *file, struct MPOpts *opts) -{ - stream_t *stream = stream_open(file, opts); - if(!stream) { - mp_msg(MSGT_PLAYTREE,MSGL_ERR, - "Error while opening playlist file %s: %s\n", - file, strerror(errno)); - return false; - } - - mp_msg(MSGT_PLAYTREE, MSGL_V, - "Parsing playlist file %s...\n", file); - - struct playlist *ret = do_parse(stream, true); - free_stream(stream); - - if (ret) - playlist_add_base_path(ret, mp_dirname(file)); - - return ret; - -} - -typedef bool (*parser_fn)(play_tree_parser_t *); -static const parser_fn pl_parsers[] = { - parse_asx, - parse_smil, - parse_nsc, - parse_textplain -}; - - -static struct playlist *do_parse(struct stream* stream, bool forced) -{ - play_tree_parser_t p = { - .stream = stream, - .pl = talloc_zero(NULL, struct playlist), - .keep = 1, - }; - - bool success = false; - struct demuxer *pl_demux = demux_open(stream, "playlist", NULL, stream->opts); - if (pl_demux && pl_demux->playlist) { - playlist_transfer_entries(p.pl, pl_demux->playlist); - success = true; - } - free_demuxer(pl_demux); - if (!success && play_tree_parser_get_line(&p) != NULL) { - for (int n = 0; n < sizeof(pl_parsers) / sizeof(pl_parsers[0]); n++) { - play_tree_parser_reset(&p); - if (pl_parsers[n] == parse_textplain && !forced) - break; - if (pl_parsers[n](&p)) { - success = true; - break; - } - } - } - - if(success) - mp_msg(MSGT_PLAYTREE,MSGL_V,"Playlist successfully parsed\n"); - else { - mp_msg(MSGT_PLAYTREE,((forced==1)?MSGL_ERR:MSGL_V),"Error while parsing playlist\n"); - talloc_free(p.pl); - p.pl = NULL; - } - - if (p.pl && !p.pl->first) - mp_msg(MSGT_PLAYTREE,((forced==1)?MSGL_WARN:MSGL_V),"Warning: empty playlist\n"); - - return p.pl; -} diff --git a/mpvcore/playlist_parser.h b/mpvcore/playlist_parser.h deleted file mode 100644 index a541aa2cb4..0000000000 --- a/mpvcore/playlist_parser.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MPLAYER_PLAYLISTPARSER_H -#define MPLAYER_PLAYLISTPARSER_H - -#include - -struct MPOpts; -struct playlist; - -struct playlist *playlist_parse_file(const char *file, struct MPOpts *opts); - -#endif diff --git a/mpvcore/version.c b/mpvcore/version.c deleted file mode 100644 index 23a0c59bc3..0000000000 --- a/mpvcore/version.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "version.h" -#ifdef NO_BUILD_TIMESTAMPS -#undef BUILDDATE -#define BUILDDATE "UNKNOWN" -#endif - -const char *mplayer_version = "mpv " VERSION; -const char *mplayer_builddate = BUILDDATE; diff --git a/old-makefile b/old-makefile index 4241955581..6756a18e18 100644 --- a/old-makefile +++ b/old-makefile @@ -95,7 +95,7 @@ SOURCES-$(GL) += video/out/gl_common.c video/out/gl_osd.c \ video/out/pnm_loader.c SOURCES-$(ENCODING) += video/out/vo_lavc.c audio/out/ao_lavc.c \ - mpvcore/encode_lavc.c + common/encode_lavc.c SOURCES-$(GL_WIN32) += video/out/w32_common.c video/out/gl_w32.c SOURCES-$(GL_X11) += video/out/x11_common.c video/out/gl_x11.c @@ -180,6 +180,18 @@ SOURCES = audio/audio.c \ audio/out/ao.c \ audio/out/ao_null.c \ audio/out/ao_pcm.c \ + bstr/bstr.c \ + common/asxparser.c \ + common/av_common.c \ + common/av_log.c \ + common/av_opts.c \ + common/codecs.c \ + common/cpudetect.c \ + common/common.c \ + common/msg.c \ + common/playlist.c \ + common/playlist_parser.c \ + common/version.c \ demux/codec_tags.c \ demux/demux.c \ demux/demux_edl.c \ @@ -193,20 +205,8 @@ SOURCES = audio/audio.c \ demux/ebml.c \ demux/mf.c \ input/input.c \ - mpvcore/asxparser.c \ - mpvcore/av_common.c \ - mpvcore/av_log.c \ - mpvcore/av_opts.c \ - mpvcore/bstr.c \ - mpvcore/charset_conv.c \ - mpvcore/codecs.c \ - mpvcore/cpudetect.c \ - mpvcore/mp_common.c \ - mpvcore/mp_msg.c \ - mpvcore/mp_ring.c \ - mpvcore/playlist.c \ - mpvcore/playlist_parser.c \ - mpvcore/version.c \ + misc/charset_conv.c \ + misc/ring.c \ options/m_config.c \ options/m_option.c \ options/m_property.c \ diff --git a/options/m_config.c b/options/m_config.c index 5040482c84..d9a3343ab7 100644 --- a/options/m_config.c +++ b/options/m_config.c @@ -32,7 +32,7 @@ #include "m_config.h" #include "options/m_option.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" static const union m_option_value default_value; diff --git a/options/m_config.h b/options/m_config.h index 8a8865d68e..1f03a9abea 100644 --- a/options/m_config.h +++ b/options/m_config.h @@ -22,7 +22,7 @@ #include #include -#include "mpvcore/bstr.h" +#include "bstr/bstr.h" // m_config provides an API to manipulate the config variables in MPlayer. // It makes use of the Options API to provide a context stack that diff --git a/options/m_option.c b/options/m_option.c index b4bd50a23f..d93c18ee52 100644 --- a/options/m_option.c +++ b/options/m_option.c @@ -36,8 +36,8 @@ #include #include "talloc.h" -#include "mpvcore/mp_common.h" -#include "mpvcore/mp_msg.h" +#include "common/common.h" +#include "common/msg.h" #include "m_option.h" #include "m_config.h" diff --git a/options/m_option.h b/options/m_option.h index dfc9e28a9b..041915bbc1 100644 --- a/options/m_option.h +++ b/options/m_option.h @@ -24,7 +24,7 @@ #include #include "config.h" -#include "mpvcore/bstr.h" +#include "bstr/bstr.h" #include "audio/chmap.h" // m_option allows to parse, print and copy data of various types. diff --git a/options/m_property.c b/options/m_property.c index 38f6a742c9..d01a2cabd7 100644 --- a/options/m_property.c +++ b/options/m_property.c @@ -32,8 +32,8 @@ #include "talloc.h" #include "m_option.h" #include "m_property.h" -#include "mpvcore/mp_msg.h" -#include "mpvcore/mp_common.h" +#include "common/msg.h" +#include "common/common.h" const struct m_option_type m_option_type_dummy = { .name = "Unknown", diff --git a/options/parse_commandline.c b/options/parse_commandline.c index a6feee82c3..182844ccc9 100644 --- a/options/parse_commandline.c +++ b/options/parse_commandline.c @@ -25,11 +25,11 @@ #include #include -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "m_option.h" #include "m_config.h" -#include "mpvcore/playlist.h" -#include "mpvcore/playlist_parser.h" +#include "common/playlist.h" +#include "common/playlist_parser.h" #include "parse_commandline.h" #define GLOBAL 0 diff --git a/options/parse_configfile.c b/options/parse_configfile.c index f82e740df9..af88d1aa62 100644 --- a/options/parse_configfile.c +++ b/options/parse_configfile.c @@ -28,7 +28,7 @@ #include "osdep/io.h" #include "parse_configfile.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "m_option.h" #include "m_config.h" diff --git a/options/path.c b/options/path.c index a2b2f135c5..43c2c0fb80 100644 --- a/options/path.c +++ b/options/path.c @@ -33,7 +33,7 @@ #include #include #include "config.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/path.h" #include "talloc.h" #include "osdep/io.h" diff --git a/options/path.h b/options/path.h index e0c61321d2..e3de212ef3 100644 --- a/options/path.h +++ b/options/path.h @@ -22,7 +22,7 @@ #define MPLAYER_PATH_H #include -#include "mpvcore/bstr.h" +#include "bstr/bstr.h" // Search for the input filename in several paths. These include user and global diff --git a/osdep/getch2.c b/osdep/getch2.c index e07594170a..054b9bf63f 100644 --- a/osdep/getch2.c +++ b/osdep/getch2.c @@ -41,8 +41,8 @@ #include -#include "mpvcore/mp_common.h" -#include "mpvcore/bstr.h" +#include "common/common.h" +#include "bstr/bstr.h" #include "input/input.h" #include "input/keycodes.h" #include "getch2.h" diff --git a/osdep/priority.c b/osdep/priority.c index 211ab8bd31..3868f09078 100644 --- a/osdep/priority.c +++ b/osdep/priority.c @@ -26,7 +26,7 @@ #include -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "priority.h" diff --git a/osdep/timer-darwin.c b/osdep/timer-darwin.c index 72b96675c7..802e0e52a1 100644 --- a/osdep/timer-darwin.c +++ b/osdep/timer-darwin.c @@ -24,7 +24,7 @@ #include #include "config.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "timer.h" static double timebase_ratio; diff --git a/player/audio.c b/player/audio.c index 32f93d869a..ab91834aa8 100644 --- a/player/audio.c +++ b/player/audio.c @@ -25,9 +25,9 @@ #include "config.h" #include "talloc.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/options.h" -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "audio/mixer.h" #include "audio/audio.h" diff --git a/player/command.c b/player/command.c index 532372e3ca..3199bd4137 100644 --- a/player/command.c +++ b/player/command.c @@ -32,14 +32,14 @@ #include "talloc.h" #include "command.h" #include "osdep/timer.h" -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "input/input.h" #include "stream/stream.h" #include "demux/demux.h" #include "demux/stheader.h" #include "stream/resolve/resolve.h" -#include "mpvcore/playlist.h" -#include "mpvcore/playlist_parser.h" +#include "common/playlist.h" +#include "common/playlist_parser.h" #include "sub/osd.h" #include "sub/dec_sub.h" #include "options/m_option.h" diff --git a/player/configfiles.c b/player/configfiles.c index 01b05ec6bc..37d081b953 100644 --- a/player/configfiles.c +++ b/player/configfiles.c @@ -31,11 +31,11 @@ #include "osdep/io.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/path.h" #include "options/m_config.h" #include "options/parse_configfile.h" -#include "mpvcore/playlist.h" +#include "common/playlist.h" #include "options/options.h" #include "options/m_property.h" diff --git a/player/core.h b/player/core.h index 551b902f9d..a344b92ac3 100644 --- a/player/core.h +++ b/player/core.h @@ -21,7 +21,7 @@ #include -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "options/options.h" // definitions used internally by the core player code diff --git a/player/dvdnav.c b/player/dvdnav.c index 6aad6f77ac..e90a65e035 100644 --- a/player/dvdnav.c +++ b/player/dvdnav.c @@ -20,8 +20,8 @@ #include "core.h" -#include "mpvcore/mp_msg.h" -#include "mpvcore/mp_common.h" +#include "common/msg.h" +#include "common/common.h" #include "input/input.h" #include "stream/stream_dvdnav.h" diff --git a/player/loadfile.c b/player/loadfile.c index 7132ca972e..12a8568973 100644 --- a/player/loadfile.c +++ b/player/loadfile.c @@ -30,15 +30,15 @@ #include "osdep/io.h" #include "osdep/timer.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/path.h" #include "options/m_config.h" #include "options/parse_configfile.h" -#include "mpvcore/playlist.h" +#include "common/playlist.h" #include "options/options.h" #include "options/m_property.h" -#include "mpvcore/mp_common.h" -#include "mpvcore/encode.h" +#include "common/common.h" +#include "common/encode.h" #include "input/input.h" #include "audio/mixer.h" diff --git a/player/lua.c b/player/lua.c index 56a9d74332..f75bc96531 100644 --- a/player/lua.c +++ b/player/lua.c @@ -7,13 +7,13 @@ #include "talloc.h" -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "options/m_property.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/m_option.h" #include "input/input.h" #include "options/path.h" -#include "mpvcore/bstr.h" +#include "bstr/bstr.h" #include "osdep/timer.h" #include "sub/osd.h" #include "core.h" diff --git a/player/main.c b/player/main.c index dfab92eefc..b421f2791a 100644 --- a/player/main.c +++ b/player/main.c @@ -32,20 +32,20 @@ #include "osdep/priority.h" #include "osdep/timer.h" -#include "mpvcore/av_log.h" -#include "mpvcore/codecs.h" -#include "mpvcore/cpudetect.h" -#include "mpvcore/encode.h" +#include "common/av_log.h" +#include "common/codecs.h" +#include "common/cpudetect.h" +#include "common/encode.h" #include "options/m_config.h" #include "options/m_option.h" #include "options/m_property.h" -#include "mpvcore/mp_common.h" -#include "mpvcore/mp_msg.h" -#include "mpvcore/mpv_global.h" +#include "common/common.h" +#include "common/msg.h" +#include "common/global.h" #include "options/parse_configfile.h" #include "options/parse_commandline.h" -#include "mpvcore/playlist.h" -#include "mpvcore/playlist_parser.h" +#include "common/playlist.h" +#include "common/playlist_parser.h" #include "options/options.h" #include "input/input.h" diff --git a/player/misc.c b/player/misc.c index f57695dae1..eb8c0c147e 100644 --- a/player/misc.c +++ b/player/misc.c @@ -26,12 +26,12 @@ #include "osdep/io.h" #include "osdep/timer.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/options.h" #include "options/m_property.h" -#include "mpvcore/mp_common.h" -#include "mpvcore/encode.h" -#include "mpvcore/playlist.h" +#include "common/common.h" +#include "common/encode.h" +#include "common/playlist.h" #include "input/input.h" #include "audio/out/ao.h" diff --git a/player/osd.c b/player/osd.c index 1ee8c52aa5..6f73ea9bc3 100644 --- a/player/osd.c +++ b/player/osd.c @@ -26,11 +26,11 @@ #include "config.h" #include "talloc.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/options.h" -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "options/m_property.h" -#include "mpvcore/encode.h" +#include "common/encode.h" #include "osdep/getch2.h" #include "osdep/timer.h" diff --git a/player/playloop.c b/player/playloop.c index cb6b72f710..777d86e974 100644 --- a/player/playloop.c +++ b/player/playloop.c @@ -25,12 +25,12 @@ #include "config.h" #include "talloc.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/options.h" -#include "mpvcore/mp_common.h" -#include "mpvcore/encode.h" +#include "common/common.h" +#include "common/encode.h" #include "options/m_property.h" -#include "mpvcore/playlist.h" +#include "common/playlist.h" #include "input/input.h" #include "osdep/timer.h" diff --git a/player/screenshot.c b/player/screenshot.c index fd09474904..94fc25f563 100644 --- a/player/screenshot.c +++ b/player/screenshot.c @@ -28,8 +28,8 @@ #include "screenshot.h" #include "core.h" #include "command.h" -#include "mpvcore/bstr.h" -#include "mpvcore/mp_msg.h" +#include "bstr/bstr.h" +#include "common/msg.h" #include "options/path.h" #include "video/mp_image.h" #include "video/decode/dec_video.h" diff --git a/player/sub.c b/player/sub.c index ea6eaee89a..69ab7e3584 100644 --- a/player/sub.c +++ b/player/sub.c @@ -25,9 +25,9 @@ #include "config.h" #include "talloc.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/options.h" -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "stream/stream.h" #include "sub/dec_sub.h" diff --git a/player/timeline/tl_cue.c b/player/timeline/tl_cue.c index 48336ed467..48b35d5b04 100644 --- a/player/timeline/tl_cue.c +++ b/player/timeline/tl_cue.c @@ -25,11 +25,11 @@ #include "talloc.h" #include "player/core.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "demux/demux.h" #include "options/path.h" -#include "mpvcore/bstr.h" -#include "mpvcore/mp_common.h" +#include "bstr/bstr.h" +#include "common/common.h" #include "stream/stream.h" // used by demuxer_cue.c diff --git a/player/timeline/tl_matroska.c b/player/timeline/tl_matroska.c index 4b52ad834f..8f793006d6 100644 --- a/player/timeline/tl_matroska.c +++ b/player/timeline/tl_matroska.c @@ -31,13 +31,13 @@ #include "talloc.h" #include "player/core.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "demux/demux.h" #include "options/path.h" -#include "mpvcore/bstr.h" -#include "mpvcore/mp_common.h" -#include "mpvcore/playlist.h" -#include "mpvcore/playlist_parser.h" +#include "bstr/bstr.h" +#include "common/common.h" +#include "common/playlist.h" +#include "common/playlist_parser.h" #include "stream/stream.h" struct find_entry { diff --git a/player/timeline/tl_mpv_edl.c b/player/timeline/tl_mpv_edl.c index 6a41bcb3c3..95bb03e2d8 100644 --- a/player/timeline/tl_mpv_edl.c +++ b/player/timeline/tl_mpv_edl.c @@ -25,11 +25,11 @@ #include "talloc.h" #include "player/core.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "demux/demux.h" #include "options/path.h" -#include "mpvcore/bstr.h" -#include "mpvcore/mp_common.h" +#include "bstr/bstr.h" +#include "common/common.h" #include "stream/stream.h" struct tl_part { diff --git a/player/video.c b/player/video.c index fd3f4ed658..7f4f7a6795 100644 --- a/player/video.c +++ b/player/video.c @@ -25,10 +25,10 @@ #include "config.h" #include "talloc.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/options.h" -#include "mpvcore/mp_common.h" -#include "mpvcore/encode.h" +#include "common/common.h" +#include "common/encode.h" #include "options/m_property.h" #include "audio/out/ao.h" diff --git a/stream/ai_alsa1x.c b/stream/ai_alsa1x.c index 2cf0382150..880817a94e 100644 --- a/stream/ai_alsa1x.c +++ b/stream/ai_alsa1x.c @@ -24,7 +24,7 @@ #include #include "audio_in.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" int ai_alsa_setup(audio_in_t *ai) { diff --git a/stream/ai_oss.c b/stream/ai_oss.c index b5829ea07a..bf57ec4198 100644 --- a/stream/ai_oss.c +++ b/stream/ai_oss.c @@ -39,7 +39,7 @@ #include "osdep/io.h" #include "audio_in.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" int ai_oss_set_samplerate(audio_in_t *ai) { diff --git a/stream/ai_sndio.c b/stream/ai_sndio.c index b486bb9210..08ddac1e03 100644 --- a/stream/ai_sndio.c +++ b/stream/ai_sndio.c @@ -5,7 +5,7 @@ #include #include "audio_in.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" int ai_sndio_setup(audio_in_t *ai) { diff --git a/stream/audio_in.c b/stream/audio_in.c index 605e144f71..1d80ab762b 100644 --- a/stream/audio_in.c +++ b/stream/audio_in.c @@ -23,7 +23,7 @@ #include "config.h" #include "audio_in.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include #include diff --git a/stream/cache.c b/stream/cache.c index 1884dcfb18..5f01275674 100644 --- a/stream/cache.c +++ b/stream/cache.c @@ -52,10 +52,10 @@ #include "osdep/timer.h" #include "osdep/threads.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "stream.h" -#include "mpvcore/mp_common.h" +#include "common/common.h" // Note: (struct priv*)(cache->priv)->cache == cache diff --git a/stream/cdinfo.c b/stream/cdinfo.c index 43180448a3..6398809a0a 100644 --- a/stream/cdinfo.c +++ b/stream/cdinfo.c @@ -25,7 +25,7 @@ #include #include #include -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "cdd.h" /******************************************************************************************************************* diff --git a/stream/cookies.c b/stream/cookies.c index f4d5b863f4..3fcf11b68f 100644 --- a/stream/cookies.c +++ b/stream/cookies.c @@ -35,7 +35,7 @@ #include "options/options.h" #include "cookies.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #define MAX_COOKIES 20 diff --git a/stream/dvb_tune.c b/stream/dvb_tune.c index ddeabd2385..0e40ea088f 100644 --- a/stream/dvb_tune.c +++ b/stream/dvb_tune.c @@ -39,7 +39,7 @@ #include "osdep/io.h" #include "dvbin.h" #include "dvb_tune.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" diff --git a/stream/rar.c b/stream/rar.c index 00c5c16725..cb54c6ebbb 100644 --- a/stream/rar.c +++ b/stream/rar.c @@ -32,7 +32,7 @@ #include #include "talloc.h" -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "stream.h" #include "rar.h" diff --git a/stream/resolve/resolve_quvi.c b/stream/resolve/resolve_quvi.c index b45995dad8..4baaca2528 100644 --- a/stream/resolve/resolve_quvi.c +++ b/stream/resolve/resolve_quvi.c @@ -19,7 +19,7 @@ #include #include "talloc.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/options.h" #include "resolve.h" diff --git a/stream/resolve/resolve_quvi9.c b/stream/resolve/resolve_quvi9.c index 62464be0b5..ed8a95502c 100644 --- a/stream/resolve/resolve_quvi9.c +++ b/stream/resolve/resolve_quvi9.c @@ -22,9 +22,9 @@ #include #include "talloc.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/options.h" -#include "mpvcore/playlist.h" +#include "common/playlist.h" #include "resolve.h" static bool mp_quvi_ok(quvi_t q) diff --git a/stream/stream.c b/stream/stream.c index 7ceecf390e..e0694d8f3c 100644 --- a/stream/stream.c +++ b/stream/stream.c @@ -37,9 +37,9 @@ #include "config.h" -#include "mpvcore/mp_common.h" -#include "mpvcore/bstr.h" -#include "mpvcore/mp_msg.h" +#include "common/common.h" +#include "bstr/bstr.h" +#include "common/msg.h" #include "options/path.h" #include "osdep/timer.h" #include "stream.h" diff --git a/stream/stream.h b/stream/stream.h index cea45c5285..e1dc2a91d0 100644 --- a/stream/stream.h +++ b/stream/stream.h @@ -20,7 +20,7 @@ #define MPLAYER_STREAM_H #include "config.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include #include #include @@ -28,7 +28,7 @@ #include #include -#include "mpvcore/bstr.h" +#include "bstr/bstr.h" #ifndef O_BINARY #define O_BINARY 0 diff --git a/stream/stream_bluray.c b/stream/stream_bluray.c index 9f11a917d2..be7a846e56 100644 --- a/stream/stream_bluray.c +++ b/stream/stream_bluray.c @@ -37,7 +37,7 @@ #include "config.h" #include "talloc.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/m_option.h" #include "stream.h" diff --git a/stream/stream_cdda.c b/stream/stream_cdda.c index 48f5a7b465..bc026843c8 100644 --- a/stream/stream_cdda.c +++ b/stream/stream_cdda.c @@ -48,7 +48,7 @@ #include "cdd.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" typedef struct { cdrom_drive_t *cd; diff --git a/stream/stream_dvd.c b/stream/stream_dvd.c index b3be35fd27..b57e4d9e7e 100644 --- a/stream/stream_dvd.c +++ b/stream/stream_dvd.c @@ -27,7 +27,7 @@ #include "config.h" #include "talloc.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include #include diff --git a/stream/stream_dvd_common.c b/stream/stream_dvd_common.c index 8cf3f5e4b1..31d045ae5b 100644 --- a/stream/stream_dvd_common.c +++ b/stream/stream_dvd_common.c @@ -41,7 +41,7 @@ #include "osdep/io.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "stream_dvd_common.h" const char * const dvd_audio_stream_types[8] = { "ac3","unknown","mpeg1","mpeg2ext","lpcm","unknown","dts" }; diff --git a/stream/stream_dvdnav.c b/stream/stream_dvdnav.c index 168091155d..b9339e70e0 100644 --- a/stream/stream_dvdnav.c +++ b/stream/stream_dvdnav.c @@ -29,7 +29,7 @@ #include #include "options/options.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "input/input.h" #include "options/m_option.h" #include "osdep/timer.h" diff --git a/stream/stream_file.c b/stream/stream_file.c index 73de4c266d..9f88e5bf6e 100644 --- a/stream/stream_file.c +++ b/stream/stream_file.c @@ -29,7 +29,7 @@ #include "osdep/io.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "stream.h" #include "options/m_option.h" diff --git a/stream/stream_lavf.c b/stream/stream_lavf.c index d3aaf52d85..5a14cbdeb5 100644 --- a/stream/stream_lavf.c +++ b/stream/stream_lavf.c @@ -22,13 +22,13 @@ #include "config.h" #include "options/options.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "stream.h" #include "options/m_option.h" #include "cookies.h" -#include "mpvcore/bstr.h" +#include "bstr/bstr.h" #include "talloc.h" static int open_f(stream_t *stream, int mode); diff --git a/stream/stream_pvr.c b/stream/stream_pvr.c index a89e70b2c6..29ea354293 100644 --- a/stream/stream_pvr.c +++ b/stream/stream_pvr.c @@ -44,7 +44,7 @@ #include "osdep/io.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "stream.h" #include "pvr.h" diff --git a/stream/stream_radio.c b/stream/stream_radio.c index b3fd501e33..754b217720 100644 --- a/stream/stream_radio.c +++ b/stream/stream_radio.c @@ -43,7 +43,7 @@ #include "stream.h" #include "options/m_option.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "stream_radio.h" #include "osdep/io.h" diff --git a/stream/stream_rar.c b/stream/stream_rar.c index 1cab4a8f48..5b6880fbe1 100644 --- a/stream/stream_rar.c +++ b/stream/stream_rar.c @@ -33,7 +33,7 @@ #include "osdep/io.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "stream.h" #include "options/m_option.h" #include "rar.h" diff --git a/stream/stream_smb.c b/stream/stream_smb.c index 2ec3c83d8d..804c5e9df4 100644 --- a/stream/stream_smb.c +++ b/stream/stream_smb.c @@ -23,7 +23,7 @@ #include #include -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "stream.h" #include "options/m_option.h" diff --git a/stream/stream_vcd.c b/stream/stream_vcd.c index 4b591aba46..2460bc65b6 100644 --- a/stream/stream_vcd.c +++ b/stream/stream_vcd.c @@ -24,7 +24,7 @@ #include #endif -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "stream.h" #include "options/m_option.h" diff --git a/stream/tv.c b/stream/tv.c index 49d69b7865..594af4fd30 100644 --- a/stream/tv.c +++ b/stream/tv.c @@ -35,7 +35,7 @@ #include "config.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "stream.h" #include "demux/demux.h" diff --git a/stream/tvi_v4l2.c b/stream/tvi_v4l2.c index 88c78b7965..6132ad7708 100644 --- a/stream/tvi_v4l2.c +++ b/stream/tvi_v4l2.c @@ -57,7 +57,7 @@ known issues: #if HAVE_LIBV4L2 #include #endif -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "video/img_fourcc.h" #include "audio/format.h" #include "tv.h" diff --git a/stream/vcd_read.h b/stream/vcd_read.h index 9a1965e459..85a58fcf61 100644 --- a/stream/vcd_read.h +++ b/stream/vcd_read.h @@ -26,7 +26,7 @@ #include -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "stream.h" //=================== VideoCD ========================== diff --git a/stream/vcd_read_darwin.h b/stream/vcd_read_darwin.h index 795e0567b5..a81d9c481d 100644 --- a/stream/vcd_read_darwin.h +++ b/stream/vcd_read_darwin.h @@ -33,7 +33,7 @@ #include #include #include "compat/mpbswap.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "stream.h" //=================== VideoCD ========================== diff --git a/stream/vcd_read_fbsd.h b/stream/vcd_read_fbsd.h index 489c969505..0765163b35 100644 --- a/stream/vcd_read_fbsd.h +++ b/stream/vcd_read_fbsd.h @@ -41,7 +41,7 @@ #define TOCADDR(te) ((te).entry.addr) #define READ_TOC CDIOREADTOCENTRY #endif -#include "mpvcore/mp_msg.h" +#include "common/msg.h" //=================== VideoCD ========================== #define CDROM_LEADOUT 0xAA diff --git a/stream/vcd_read_win32.h b/stream/vcd_read_win32.h index 10ca833574..d5d4032050 100644 --- a/stream/vcd_read_win32.h +++ b/stream/vcd_read_win32.h @@ -23,7 +23,7 @@ #include #include #include -#include "mpvcore/mp_msg.h" +#include "common/msg.h" typedef struct mp_vcd_priv_st mp_vcd_priv_t; diff --git a/sub/ass_mp.c b/sub/ass_mp.c index 75178d804d..cdf302f959 100644 --- a/sub/ass_mp.c +++ b/sub/ass_mp.c @@ -30,7 +30,7 @@ #include #include "config.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/path.h" #include "ass_mp.h" #include "osd.h" diff --git a/sub/dec_sub.c b/sub/dec_sub.c index c5d45f81df..9a948cd036 100644 --- a/sub/dec_sub.c +++ b/sub/dec_sub.c @@ -27,8 +27,8 @@ #include "sd.h" #include "dec_sub.h" #include "options/options.h" -#include "mpvcore/mp_msg.h" -#include "mpvcore/charset_conv.h" +#include "common/msg.h" +#include "misc/charset_conv.h" extern const struct sd_functions sd_ass; extern const struct sd_functions sd_lavc; diff --git a/sub/draw_bmp.c b/sub/draw_bmp.c index 2b91befe50..2e92bdaaa5 100644 --- a/sub/draw_bmp.c +++ b/sub/draw_bmp.c @@ -25,7 +25,7 @@ #include #include -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "draw_bmp.h" #include "img_convert.h" #include "video/mp_image.h" diff --git a/sub/find_subfiles.c b/sub/find_subfiles.c index ce23bd50c4..d5f3078793 100644 --- a/sub/find_subfiles.c +++ b/sub/find_subfiles.c @@ -6,10 +6,10 @@ #include "osdep/io.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/options.h" #include "options/path.h" -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "sub/find_subfiles.h" static const char *sub_exts[] = {"utf", "utf8", "utf-8", "idx", "sub", "srt", diff --git a/sub/osd.c b/sub/osd.c index 2432859782..ac2b40499a 100644 --- a/sub/osd.c +++ b/sub/osd.c @@ -23,7 +23,7 @@ #include -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "stream/stream.h" @@ -31,7 +31,7 @@ #include "talloc.h" #include "options/options.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "osd.h" #include "dec_sub.h" #include "img_convert.h" diff --git a/sub/osd_libass.c b/sub/osd_libass.c index 16e90eea1e..3e6efe6667 100644 --- a/sub/osd_libass.c +++ b/sub/osd_libass.c @@ -25,8 +25,8 @@ #include "config.h" #include "talloc.h" -#include "mpvcore/mp_common.h" -#include "mpvcore/mp_msg.h" +#include "common/common.h" +#include "common/msg.h" #include "osd.h" static const char osd_font_pfb[] = diff --git a/sub/sd_ass.c b/sub/sd_ass.c index a8d5be633d..93a3c7e380 100644 --- a/sub/sd_ass.c +++ b/sub/sd_ass.c @@ -26,8 +26,8 @@ #include "talloc.h" #include "options/options.h" -#include "mpvcore/mp_common.h" -#include "mpvcore/mp_msg.h" +#include "common/common.h" +#include "common/msg.h" #include "video/csputils.h" #include "video/mp_image.h" #include "dec_sub.h" diff --git a/sub/sd_lavc.c b/sub/sd_lavc.c index 0e7121a279..1977ca3fff 100644 --- a/sub/sd_lavc.c +++ b/sub/sd_lavc.c @@ -22,8 +22,8 @@ #include #include "talloc.h" -#include "mpvcore/mp_msg.h" -#include "mpvcore/av_common.h" +#include "common/msg.h" +#include "common/av_common.h" #include "options/options.h" #include "video/mp_image.h" #include "sd.h" diff --git a/sub/sd_lavc_conv.c b/sub/sd_lavc_conv.c index 24ea2c10c6..0fa3986e3d 100644 --- a/sub/sd_lavc_conv.c +++ b/sub/sd_lavc_conv.c @@ -25,9 +25,9 @@ #include "config.h" #include "talloc.h" -#include "mpvcore/mp_msg.h" -#include "mpvcore/av_common.h" -#include "mpvcore/bstr.h" +#include "common/msg.h" +#include "common/av_common.h" +#include "bstr/bstr.h" #include "sd.h" #if LIBAVCODEC_VERSION_MICRO >= 100 diff --git a/sub/sd_lavf_srt.c b/sub/sd_lavf_srt.c index 3e2ebefab2..0a48afa990 100644 --- a/sub/sd_lavf_srt.c +++ b/sub/sd_lavf_srt.c @@ -21,7 +21,7 @@ #include #include -#include "mpvcore/bstr.h" +#include "bstr/bstr.h" #include "sd.h" /* diff --git a/sub/sd_microdvd.c b/sub/sd_microdvd.c index c0e9fa1d61..e9c7a788bc 100644 --- a/sub/sd_microdvd.c +++ b/sub/sd_microdvd.c @@ -27,8 +27,8 @@ #include #include -#include "mpvcore/mp_msg.h" -#include "mpvcore/bstr.h" +#include "common/msg.h" +#include "bstr/bstr.h" #include "sd.h" struct line { diff --git a/sub/sd_srt.c b/sub/sd_srt.c index 343f218190..c08f927c4a 100644 --- a/sub/sd_srt.c +++ b/sub/sd_srt.c @@ -27,8 +27,8 @@ #include #include -#include "mpvcore/mp_msg.h" -#include "mpvcore/bstr.h" +#include "common/msg.h" +#include "bstr/bstr.h" #include "sd.h" struct line { diff --git a/sub/spudec.c b/sub/spudec.c index 5a2c094be9..79b0b2eb93 100644 --- a/sub/spudec.c +++ b/sub/spudec.c @@ -40,11 +40,11 @@ #include #include "config.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "spudec.h" #include "osd.h" -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "video/csputils.h" typedef struct spu_packet_t packet_t; diff --git a/video/decode/dec_video.c b/video/decode/dec_video.c index 06b00be84f..b150816a90 100644 --- a/video/decode/dec_video.c +++ b/video/decode/dec_video.c @@ -24,14 +24,14 @@ #include #include -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "osdep/timer.h" #include "stream/stream.h" #include "demux/packet.h" -#include "mpvcore/codecs.h" +#include "common/codecs.h" #include "video/out/vo.h" #include "video/csputils.h" diff --git a/video/decode/vaapi.c b/video/decode/vaapi.c index f1a270a7c7..8a9ff4ae50 100644 --- a/video/decode/vaapi.c +++ b/video/decode/vaapi.c @@ -28,8 +28,8 @@ #include #include "lavc.h" -#include "mpvcore/mp_common.h" -#include "mpvcore/av_common.h" +#include "common/common.h" +#include "common/av_common.h" #include "video/fmt-conversion.h" #include "video/vaapi.h" #include "video/mp_image_pool.h" diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c index 506481cf1c..8a8d2b6abc 100644 --- a/video/decode/vd_lavc.c +++ b/video/decode/vd_lavc.c @@ -32,12 +32,12 @@ #include "talloc.h" #include "config.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/options.h" -#include "mpvcore/bstr.h" -#include "mpvcore/av_opts.h" -#include "mpvcore/av_common.h" -#include "mpvcore/codecs.h" +#include "bstr/bstr.h" +#include "common/av_opts.h" +#include "common/av_common.h" +#include "common/codecs.h" #include "compat/mpbswap.h" #include "video/fmt-conversion.h" diff --git a/video/decode/vda.c b/video/decode/vda.c index c20bdc9b5f..7a21c5e10a 100644 --- a/video/decode/vda.c +++ b/video/decode/vda.c @@ -20,8 +20,8 @@ #include #include -#include "mpvcore/av_common.h" -#include "mpvcore/mp_msg.h" +#include "common/av_common.h" +#include "common/msg.h" #include "video/mp_image.h" #include "video/decode/lavc.h" #include "config.h" diff --git a/video/decode/vdpau.c b/video/decode/vdpau.c index 02eab84a0c..c7a5361c15 100644 --- a/video/decode/vdpau.c +++ b/video/decode/vdpau.c @@ -23,8 +23,8 @@ #include #include "lavc.h" -#include "mpvcore/mp_common.h" -#include "mpvcore/av_common.h" +#include "common/common.h" +#include "common/av_common.h" #include "video/fmt-conversion.h" #include "video/vdpau.h" #include "video/hwdec.h" diff --git a/video/filter/pullup.c b/video/filter/pullup.c index 2421720d70..14c31dc365 100644 --- a/video/filter/pullup.c +++ b/video/filter/pullup.c @@ -21,8 +21,8 @@ #include #include "config.h" #include "pullup.h" -#include "mpvcore/cpudetect.h" -#include "mpvcore/mp_common.h" +#include "common/cpudetect.h" +#include "common/common.h" diff --git a/video/filter/vf.c b/video/filter/vf.c index 4143a835b1..77a86501ad 100644 --- a/video/filter/vf.c +++ b/video/filter/vf.c @@ -26,7 +26,7 @@ #include "config.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/m_option.h" #include "options/m_config.h" diff --git a/video/filter/vf.h b/video/filter/vf.h index 5892247556..96f4aaef7e 100644 --- a/video/filter/vf.h +++ b/video/filter/vf.h @@ -22,7 +22,7 @@ #include #include "video/mp_image.h" -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "video/vfcap.h" diff --git a/video/filter/vf_crop.c b/video/filter/vf_crop.c index dde297f910..cd286910ab 100644 --- a/video/filter/vf_crop.c +++ b/video/filter/vf_crop.c @@ -21,7 +21,7 @@ #include #include "config.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/options.h" #include "video/img_format.h" diff --git a/video/filter/vf_delogo.c b/video/filter/vf_delogo.c index 0c80bec057..d1e7ea1c4a 100644 --- a/video/filter/vf_delogo.c +++ b/video/filter/vf_delogo.c @@ -28,8 +28,8 @@ #include #include -#include "mpvcore/mp_msg.h" -#include "mpvcore/cpudetect.h" +#include "common/msg.h" +#include "common/cpudetect.h" #include "video/img_format.h" #include "video/mp_image.h" #include "vf.h" diff --git a/video/filter/vf_divtc.c b/video/filter/vf_divtc.c index 6c8574039d..bf0b7426b4 100644 --- a/video/filter/vf_divtc.c +++ b/video/filter/vf_divtc.c @@ -23,8 +23,8 @@ #include #include "config.h" -#include "mpvcore/mp_msg.h" -#include "mpvcore/cpudetect.h" +#include "common/msg.h" +#include "common/cpudetect.h" #include "options/m_option.h" #include "libavutil/common.h" #include "compat/mpbswap.h" diff --git a/video/filter/vf_dlopen.c b/video/filter/vf_dlopen.c index 4b7551167b..dedafda85c 100644 --- a/video/filter/vf_dlopen.c +++ b/video/filter/vf_dlopen.c @@ -22,7 +22,7 @@ #include #include "config.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "video/img_format.h" #include "video/mp_image.h" diff --git a/video/filter/vf_dsize.c b/video/filter/vf_dsize.c index ed4d3ef871..158b1825cc 100644 --- a/video/filter/vf_dsize.c +++ b/video/filter/vf_dsize.c @@ -23,7 +23,7 @@ #include #include "config.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/m_option.h" #include "video/img_format.h" diff --git a/video/filter/vf_eq.c b/video/filter/vf_eq.c index 542627cb3b..b5a898a58f 100644 --- a/video/filter/vf_eq.c +++ b/video/filter/vf_eq.c @@ -30,8 +30,8 @@ #include #include "config.h" -#include "mpvcore/mp_msg.h" -#include "mpvcore/cpudetect.h" +#include "common/msg.h" +#include "common/cpudetect.h" #include "options/m_option.h" #include "video/img_format.h" diff --git a/video/filter/vf_expand.c b/video/filter/vf_expand.c index fe4b8baccb..e4d9f2dd33 100644 --- a/video/filter/vf_expand.c +++ b/video/filter/vf_expand.c @@ -24,7 +24,7 @@ #include #include "config.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/options.h" #include "video/img_format.h" diff --git a/video/filter/vf_flip.c b/video/filter/vf_flip.c index 7c652e1138..2dde098c51 100644 --- a/video/filter/vf_flip.c +++ b/video/filter/vf_flip.c @@ -21,7 +21,7 @@ #include #include "config.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "video/mp_image.h" #include "vf.h" diff --git a/video/filter/vf_format.c b/video/filter/vf_format.c index bdbefec542..9ac6fa9119 100644 --- a/video/filter/vf_format.c +++ b/video/filter/vf_format.c @@ -22,7 +22,7 @@ #include #include "config.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "video/img_format.h" #include "video/mp_image.h" diff --git a/video/filter/vf_gradfun.c b/video/filter/vf_gradfun.c index ea3b615caa..87464d5bb6 100644 --- a/video/filter/vf_gradfun.c +++ b/video/filter/vf_gradfun.c @@ -36,7 +36,7 @@ #include #include "config.h" -#include "mpvcore/cpudetect.h" +#include "common/cpudetect.h" #include "video/img_format.h" #include "video/mp_image.h" #include "vf.h" diff --git a/video/filter/vf_hqdn3d.c b/video/filter/vf_hqdn3d.c index 07cea5ad28..883c495f22 100644 --- a/video/filter/vf_hqdn3d.c +++ b/video/filter/vf_hqdn3d.c @@ -24,7 +24,7 @@ #include #include -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/m_option.h" #include "video/img_format.h" #include "video/mp_image.h" diff --git a/video/filter/vf_ilpack.c b/video/filter/vf_ilpack.c index d79f557652..2ae129f6de 100644 --- a/video/filter/vf_ilpack.c +++ b/video/filter/vf_ilpack.c @@ -22,8 +22,8 @@ #include #include "config.h" -#include "mpvcore/mp_msg.h" -#include "mpvcore/cpudetect.h" +#include "common/msg.h" +#include "common/cpudetect.h" #include "options/m_option.h" #include "video/img_format.h" diff --git a/video/filter/vf_lavfi.c b/video/filter/vf_lavfi.c index 98216c08e4..b20383881a 100644 --- a/video/filter/vf_lavfi.c +++ b/video/filter/vf_lavfi.c @@ -36,9 +36,9 @@ #include #include -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/m_option.h" -#include "mpvcore/av_opts.h" +#include "common/av_opts.h" #include "video/img_format.h" #include "video/mp_image.h" diff --git a/video/filter/vf_lavfi.h b/video/filter/vf_lavfi.h index aef8a93448..48b658041d 100644 --- a/video/filter/vf_lavfi.h +++ b/video/filter/vf_lavfi.h @@ -3,7 +3,7 @@ #include "config.h" -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "vf.h" struct vf_lw_opts; diff --git a/video/filter/vf_mirror.c b/video/filter/vf_mirror.c index 36232f7f2b..2cf9e4a78d 100644 --- a/video/filter/vf_mirror.c +++ b/video/filter/vf_mirror.c @@ -22,7 +22,7 @@ #include #include "config.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "video/img_format.h" #include "video/mp_image.h" diff --git a/video/filter/vf_noformat.c b/video/filter/vf_noformat.c index 50f9f7f26f..1529cfadfc 100644 --- a/video/filter/vf_noformat.c +++ b/video/filter/vf_noformat.c @@ -22,7 +22,7 @@ #include #include "config.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "video/img_format.h" #include "video/mp_image.h" diff --git a/video/filter/vf_noise.c b/video/filter/vf_noise.c index 0f20cfc353..72c02b22ad 100644 --- a/video/filter/vf_noise.c +++ b/video/filter/vf_noise.c @@ -25,8 +25,8 @@ #include #include "config.h" -#include "mpvcore/mp_msg.h" -#include "mpvcore/cpudetect.h" +#include "common/msg.h" +#include "common/cpudetect.h" #include "options/m_option.h" #include "video/img_format.h" diff --git a/video/filter/vf_phase.c b/video/filter/vf_phase.c index 2a8b9dfc61..38668f6d8e 100644 --- a/video/filter/vf_phase.c +++ b/video/filter/vf_phase.c @@ -22,7 +22,7 @@ #include #include "config.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/m_option.h" #include "video/img_format.h" diff --git a/video/filter/vf_pp.c b/video/filter/vf_pp.c index c49ed218b5..111ab798ef 100644 --- a/video/filter/vf_pp.c +++ b/video/filter/vf_pp.c @@ -24,8 +24,8 @@ #include #include "config.h" -#include "mpvcore/mp_msg.h" -#include "mpvcore/cpudetect.h" +#include "common/msg.h" +#include "common/cpudetect.h" #include "options/m_option.h" #include "video/img_format.h" diff --git a/video/filter/vf_pullup.c b/video/filter/vf_pullup.c index a0d2c7da26..4fb51fe9d0 100644 --- a/video/filter/vf_pullup.c +++ b/video/filter/vf_pullup.c @@ -21,8 +21,8 @@ #include #include "config.h" -#include "mpvcore/mp_msg.h" -#include "mpvcore/cpudetect.h" +#include "common/msg.h" +#include "common/cpudetect.h" #include "options/m_option.h" #include "video/img_format.h" diff --git a/video/filter/vf_rotate.c b/video/filter/vf_rotate.c index bbb02647d1..b767d37c4b 100644 --- a/video/filter/vf_rotate.c +++ b/video/filter/vf_rotate.c @@ -22,7 +22,7 @@ #include #include "config.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/m_option.h" #include "video/img_format.h" diff --git a/video/filter/vf_scale.c b/video/filter/vf_scale.c index c80113f6fd..7d935462a0 100644 --- a/video/filter/vf_scale.c +++ b/video/filter/vf_scale.c @@ -25,7 +25,7 @@ #include #include "config.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/options.h" #include "video/img_format.h" diff --git a/video/filter/vf_softpulldown.c b/video/filter/vf_softpulldown.c index 4e713bd47f..f2dbba29bf 100644 --- a/video/filter/vf_softpulldown.c +++ b/video/filter/vf_softpulldown.c @@ -21,7 +21,7 @@ #include #include "config.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "video/img_format.h" #include "video/mp_image.h" diff --git a/video/filter/vf_stereo3d.c b/video/filter/vf_stereo3d.c index b9d97756fe..c896b4a73b 100644 --- a/video/filter/vf_stereo3d.c +++ b/video/filter/vf_stereo3d.c @@ -24,7 +24,7 @@ #include #include "config.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/options.h" #include "video/img_format.h" diff --git a/video/filter/vf_sub.c b/video/filter/vf_sub.c index e9f056e113..d2b97d8e30 100644 --- a/video/filter/vf_sub.c +++ b/video/filter/vf_sub.c @@ -28,7 +28,7 @@ #include #include "config.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/options.h" #include "video/img_format.h" diff --git a/video/filter/vf_swapuv.c b/video/filter/vf_swapuv.c index 8233d6cab5..eabc5f1ed3 100644 --- a/video/filter/vf_swapuv.c +++ b/video/filter/vf_swapuv.c @@ -24,7 +24,7 @@ #include #include -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "video/img_format.h" #include "video/mp_image.h" #include "vf.h" diff --git a/video/filter/vf_unsharp.c b/video/filter/vf_unsharp.c index 582449ad53..179e9b78ae 100644 --- a/video/filter/vf_unsharp.c +++ b/video/filter/vf_unsharp.c @@ -25,8 +25,8 @@ #include #include "config.h" -#include "mpvcore/mp_msg.h" -#include "mpvcore/cpudetect.h" +#include "common/msg.h" +#include "common/cpudetect.h" #include "options/m_option.h" #include "video/img_format.h" diff --git a/video/filter/vf_yadif.c b/video/filter/vf_yadif.c index 46e59bf741..3eeca30021 100644 --- a/video/filter/vf_yadif.c +++ b/video/filter/vf_yadif.c @@ -25,10 +25,10 @@ #include #include "config.h" -#include "mpvcore/cpudetect.h" +#include "common/cpudetect.h" #include "options/options.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "video/img_format.h" #include "video/mp_image.h" #include "vf.h" diff --git a/video/fmt-conversion.c b/video/fmt-conversion.c index ab115b0010..2dbbd026bc 100644 --- a/video/fmt-conversion.c +++ b/video/fmt-conversion.c @@ -16,7 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "libavutil/avutil.h" #include #include "video/img_format.h" diff --git a/video/img_format.h b/video/img_format.h index e7b6fc5566..10268febaa 100644 --- a/video/img_format.h +++ b/video/img_format.h @@ -21,7 +21,7 @@ #include #include -#include "mpvcore/bstr.h" +#include "bstr/bstr.h" #if BYTE_ORDER == BIG_ENDIAN #define MP_SELECT_LE_BE(LE, BE) BE diff --git a/video/mp_image.h b/video/mp_image.h index f7e7353475..dfb83b3bb1 100644 --- a/video/mp_image.h +++ b/video/mp_image.h @@ -24,7 +24,7 @@ #include #include #include -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "csputils.h" #include "video/img_format.h" diff --git a/video/mp_image_pool.c b/video/mp_image_pool.c index d7f992483e..07cbc94e45 100644 --- a/video/mp_image_pool.c +++ b/video/mp_image_pool.c @@ -25,7 +25,7 @@ #include "talloc.h" -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "video/mp_image.h" #include "mp_image_pool.h" diff --git a/video/out/aspect.c b/video/out/aspect.c index 33cf5ebfef..e7167dacde 100644 --- a/video/out/aspect.c +++ b/video/out/aspect.c @@ -21,7 +21,7 @@ /* Stuff for correct aspect scaling. */ #include "aspect.h" #include "vo.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/options.h" #include "vo.h" diff --git a/video/out/bitmap_packer.c b/video/out/bitmap_packer.c index ff76e70315..35e4f4c176 100644 --- a/video/out/bitmap_packer.c +++ b/video/out/bitmap_packer.c @@ -26,8 +26,8 @@ #include "talloc.h" #include "bitmap_packer.h" -#include "mpvcore/mp_msg.h" -#include "mpvcore/mp_common.h" +#include "common/msg.h" +#include "common/common.h" #include "sub/dec_sub.h" #include "video/memcpy_pic.h" diff --git a/video/out/gl_common.h b/video/out/gl_common.h index f9d4685a6b..45ff9a0110 100644 --- a/video/out/gl_common.h +++ b/video/out/gl_common.h @@ -29,8 +29,8 @@ #include #include "config.h" -#include "mpvcore/mp_msg.h" -#include "mpvcore/bstr.h" +#include "common/msg.h" +#include "bstr/bstr.h" #include "vo.h" #include "video/csputils.h" diff --git a/video/out/gl_lcms.c b/video/out/gl_lcms.c index 919ab2e657..f6d01948e8 100644 --- a/video/out/gl_lcms.c +++ b/video/out/gl_lcms.c @@ -27,9 +27,9 @@ #include "config.h" #include "stream/stream.h" -#include "mpvcore/mp_common.h" -#include "mpvcore/bstr.h" -#include "mpvcore/mp_msg.h" +#include "common/common.h" +#include "bstr/bstr.h" +#include "common/msg.h" #include "options/m_option.h" #include "options/path.h" diff --git a/video/out/gl_video.c b/video/out/gl_video.c index b3728eef44..b27638b904 100644 --- a/video/out/gl_video.c +++ b/video/out/gl_video.c @@ -30,7 +30,7 @@ #include "gl_video.h" -#include "mpvcore/bstr.h" +#include "bstr/bstr.h" #include "gl_common.h" #include "gl_osd.h" #include "filter_kernels.h" diff --git a/video/out/vo.c b/video/out/vo.c index ab8a92fd9e..5b29becbef 100644 --- a/video/out/vo.c +++ b/video/out/vo.c @@ -33,13 +33,13 @@ #include "config.h" #include "osdep/timer.h" #include "options/options.h" -#include "mpvcore/bstr.h" +#include "bstr/bstr.h" #include "vo.h" #include "aspect.h" #include "input/input.h" #include "options/m_config.h" -#include "mpvcore/mp_msg.h" -#include "mpvcore/mpv_global.h" +#include "common/msg.h" +#include "common/global.h" #include "video/mp_image.h" #include "video/vfcap.h" #include "sub/osd.h" diff --git a/video/out/vo.h b/video/out/vo.h index 2c9eec4849..e2881155df 100644 --- a/video/out/vo.h +++ b/video/out/vo.h @@ -27,7 +27,7 @@ #include #include "video/img_format.h" -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "options/options.h" #define VO_EVENT_EXPOSE 1 diff --git a/video/out/vo_caca.c b/video/out/vo_caca.c index 89f52a8937..13885b510e 100644 --- a/video/out/vo_caca.c +++ b/video/out/vo_caca.c @@ -42,7 +42,7 @@ #include "input/keycodes.h" #include "input/input.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "input/input.h" /* caca stuff */ diff --git a/video/out/vo_direct3d.c b/video/out/vo_direct3d.c index 52627d3d32..6e189bc660 100644 --- a/video/out/vo_direct3d.c +++ b/video/out/vo_direct3d.c @@ -37,7 +37,7 @@ #include "video/mp_image.h" #include "video/img_format.h" #include "video/memcpy_pic.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "w32_common.h" #include "libavutil/common.h" #include "sub/osd.h" diff --git a/video/out/vo_image.c b/video/out/vo_image.c index b08f3018b0..2bbdbcd543 100644 --- a/video/out/vo_image.c +++ b/video/out/vo_image.c @@ -25,11 +25,11 @@ #include #include "config.h" -#include "mpvcore/bstr.h" +#include "bstr/bstr.h" #include "osdep/io.h" #include "options/path.h" #include "talloc.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "video/out/vo.h" #include "video/csputils.h" #include "video/vfcap.h" diff --git a/video/out/vo_lavc.c b/video/out/vo_lavc.c index 81a4280def..56933e2309 100644 --- a/video/out/vo_lavc.c +++ b/video/out/vo_lavc.c @@ -23,7 +23,7 @@ #include #include #include "compat/libav.h" -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "options/options.h" #include "video/fmt-conversion.h" #include "video/mp_image.h" @@ -31,7 +31,7 @@ #include "talloc.h" #include "vo.h" -#include "mpvcore/encode_lavc.h" +#include "common/encode_lavc.h" #include "sub/osd.h" diff --git a/video/out/vo_null.c b/video/out/vo_null.c index bb20945728..b59eb13e81 100644 --- a/video/out/vo_null.c +++ b/video/out/vo_null.c @@ -25,7 +25,7 @@ #include #include #include "config.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "vo.h" #include "video/vfcap.h" #include "video/mp_image.h" diff --git a/video/out/vo_opengl.c b/video/out/vo_opengl.c index d1e0f3d2f0..5f24c7d65e 100644 --- a/video/out/vo_opengl.c +++ b/video/out/vo_opengl.c @@ -35,9 +35,9 @@ #include "config.h" #include "talloc.h" -#include "mpvcore/mp_common.h" -#include "mpvcore/bstr.h" -#include "mpvcore/mp_msg.h" +#include "common/common.h" +#include "bstr/bstr.h" +#include "common/msg.h" #include "options/m_config.h" #include "vo.h" #include "video/vfcap.h" diff --git a/video/out/vo_opengl_old.c b/video/out/vo_opengl_old.c index 9e39a6197c..351ac05417 100644 --- a/video/out/vo_opengl_old.c +++ b/video/out/vo_opengl_old.c @@ -33,7 +33,7 @@ #include "config.h" #include "talloc.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/m_option.h" #include "vo.h" #include "video/vfcap.h" diff --git a/video/out/vo_sdl.c b/video/out/vo_sdl.c index 574b453a6f..cff02731cb 100644 --- a/video/out/vo_sdl.c +++ b/video/out/vo_sdl.c @@ -33,7 +33,7 @@ #include "input/input.h" #include "input/keycodes.h" #include "input/input.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/options.h" #include "osdep/timer.h" diff --git a/video/out/vo_vaapi.c b/video/out/vo_vaapi.c index c2d2bb9602..de5e05e4ec 100644 --- a/video/out/vo_vaapi.c +++ b/video/out/vo_vaapi.c @@ -29,7 +29,7 @@ #include #include "config.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "video/out/vo.h" #include "video/memcpy_pic.h" #include "sub/osd.h" diff --git a/video/out/vo_vdpau.c b/video/out/vo_vdpau.c index 1343b54b65..07bb151e88 100644 --- a/video/out/vo_vdpau.c +++ b/video/out/vo_vdpau.c @@ -37,7 +37,7 @@ #include "config.h" #include "video/vdpau.h" #include "video/hwdec.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/options.h" #include "talloc.h" #include "vo.h" diff --git a/video/out/vo_wayland.c b/video/out/vo_wayland.c index 293b3081eb..db73d79a74 100644 --- a/video/out/vo_wayland.c +++ b/video/out/vo_wayland.c @@ -33,7 +33,7 @@ #include "sub/osd.h" #include "video/vfcap.h" #include "video/mp_image.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "video/sws_utils.h" #include "wayland_common.h" diff --git a/video/out/vo_x11.c b/video/out/vo_x11.c index ead41c51c8..35ca4cda0e 100644 --- a/video/out/vo_x11.c +++ b/video/out/vo_x11.c @@ -52,7 +52,7 @@ #include "video/sws_utils.h" #include "video/fmt-conversion.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "options/options.h" #include "osdep/timer.h" diff --git a/video/out/vo_xv.c b/video/out/vo_xv.c index 1fa4323beb..7cd63fe965 100644 --- a/video/out/vo_xv.c +++ b/video/out/vo_xv.c @@ -45,7 +45,7 @@ #include "options/options.h" #include "talloc.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "vo.h" #include "video/vfcap.h" #include "video/mp_image.h" diff --git a/video/out/w32_common.c b/video/out/w32_common.c index b8fe0309af..c4fb227601 100644 --- a/video/out/w32_common.c +++ b/video/out/w32_common.c @@ -25,8 +25,8 @@ #include "options/options.h" #include "input/keycodes.h" #include "input/input.h" -#include "mpvcore/mp_msg.h" -#include "mpvcore/mp_common.h" +#include "common/msg.h" +#include "common/common.h" #include "vo.h" #include "aspect.h" #include "w32_common.h" diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c index 5a078b775e..e45483c5f2 100644 --- a/video/out/wayland_common.c +++ b/video/out/wayland_common.c @@ -31,9 +31,9 @@ #include #include "config.h" -#include "mpvcore/bstr.h" +#include "bstr/bstr.h" #include "options/options.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "libavutil/common.h" #include "talloc.h" diff --git a/video/out/x11_common.c b/video/out/x11_common.c index adc5ac1b21..a042bd0968 100644 --- a/video/out/x11_common.c +++ b/video/out/x11_common.c @@ -23,9 +23,9 @@ #include #include "config.h" -#include "mpvcore/bstr.h" +#include "bstr/bstr.h" #include "options/options.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "input/input.h" #include "libavutil/common.h" #include "x11_common.h" diff --git a/video/sws_utils.c b/video/sws_utils.c index 3bc6bc4910..5455c7d51b 100644 --- a/video/sws_utils.c +++ b/video/sws_utils.c @@ -24,12 +24,12 @@ #include "sws_utils.h" -#include "mpvcore/mp_common.h" +#include "common/common.h" #include "video/mp_image.h" #include "video/img_format.h" #include "fmt-conversion.h" #include "csputils.h" -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #include "video/filter/vf.h" //global sws_flags from the command line diff --git a/video/vaapi.c b/video/vaapi.c index 4607be9052..3bc54b69db 100644 --- a/video/vaapi.c +++ b/video/vaapi.c @@ -18,8 +18,8 @@ #include #include "vaapi.h" -#include "mpvcore/mp_common.h" -#include "mpvcore/mp_msg.h" +#include "common/common.h" +#include "common/msg.h" #include "mp_image.h" #include "img_format.h" #include "mp_image_pool.h" diff --git a/video/vdpau.h b/video/vdpau.h index 9b67025347..069b9a0f55 100644 --- a/video/vdpau.h +++ b/video/vdpau.h @@ -7,7 +7,7 @@ #include #include -#include "mpvcore/mp_msg.h" +#include "common/msg.h" #define CHECK_ST_ERROR(message) \ do { \ diff --git a/wscript_build.py b/wscript_build.py index 16668f8c36..d2495d3b68 100644 --- a/wscript_build.py +++ b/wscript_build.py @@ -162,22 +162,22 @@ def build(ctx): ( "audio/out/ao_sndio.c", "sndio" ), ( "audio/out/ao_wasapi.c", "wasapi" ), + ## Bstr + ( "bstr/bstr.c" ), + ## Core - ( "mpvcore/asxparser.c" ), - ( "mpvcore/av_common.c" ), - ( "mpvcore/av_log.c" ), - ( "mpvcore/av_opts.c" ), - ( "mpvcore/bstr.c" ), - ( "mpvcore/charset_conv.c" ), - ( "mpvcore/codecs.c" ), - ( "mpvcore/cpudetect.c" ), - ( "mpvcore/encode_lavc.c", "encoding" ), - ( "mpvcore/mp_common.c" ), - ( "mpvcore/mp_msg.c" ), - ( "mpvcore/mp_ring.c" ), - ( "mpvcore/playlist.c" ), - ( "mpvcore/playlist_parser.c" ), - ( "mpvcore/version.c" ), + ( "common/asxparser.c" ), + ( "common/av_common.c" ), + ( "common/av_log.c" ), + ( "common/av_opts.c" ), + ( "common/codecs.c" ), + ( "common/cpudetect.c" ), + ( "common/encode_lavc.c", "encoding" ), + ( "common/common.c" ), + ( "common/msg.c" ), + ( "common/playlist.c" ), + ( "common/playlist_parser.c" ), + ( "common/version.c" ), ## Demuxers ( "demux/codec_tags.c" ), @@ -199,6 +199,10 @@ def build(ctx): ( "input/joystick.c", "joystick" ), ( "input/lirc.c", "lirc" ), + ## Misc + ( "misc/ring.c" ), + ( "misc/charset_conv.c" ), + ## Options ( "options/m_config.c" ), ( "options/m_option.c" ), -- cgit v1.2.3