diff --git a/.gitignore b/.gitignore index 41d7bf6cf..f1366d097 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ subprojects/avisynth subprojects/bestsource/ subprojects/boost*/ subprojects/cairo* +subprojects/dav1d subprojects/ffmpeg subprojects/ffms2 subprojects/fontconfig* diff --git a/README.md b/README.md index 8bcd14acc..6bd3d65f2 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,11 @@ Apart from the dependencies for the TSTools version, there are some additional d - `avisynth` (or `avisynthplus`): Optional run-time dependency for the Avisynth source - `vapoursynth`: Optional run-time dependency for the VapourSynth source + The following VapourSynth plugins are used by the default scripts set in the default configuration: + - [`lsmas`](https://github.com/AkarinVS/L-SMASH-Works): For LWLibavSource + - [`bas`](https://github.com/vapoursynth/bestaudiosource): For BestAudioSource + - [`wwxd`](https://github.com/dubhater/vapoursynth-wwxd) and [`scxvid`](https://github.com/dubhater/vapoursynth-scxvid) (depending on settings): For keyframe generation + # Aegisub diff --git a/libaegisub/common/vfr.cpp b/libaegisub/common/vfr.cpp index 377e29b34..27b31e4e7 100644 --- a/libaegisub/common/vfr.cpp +++ b/libaegisub/common/vfr.cpp @@ -143,7 +143,7 @@ Framerate::Framerate(double fps) Framerate::Framerate(int64_t numerator, int64_t denominator, bool drop) : denominator(denominator) , numerator(numerator) -, drop(drop && numerator % denominator != 0) +, drop(drop && denominator != 0 && numerator % denominator != 0) { if (numerator <= 0 || denominator <= 0) throw InvalidFramerate("Numerator and denominator must both be greater than zero"); diff --git a/libaegisub/windows/fs.cpp b/libaegisub/windows/fs.cpp index f626407e2..fbd28c7fe 100644 --- a/libaegisub/windows/fs.cpp +++ b/libaegisub/windows/fs.cpp @@ -35,7 +35,11 @@ namespace bfs = boost::filesystem; namespace agi { namespace fs { std::string ShortName(path const& p) { - std::wstring out(MAX_PATH + 1, 0); + DWORD length = GetShortPathName(p.c_str(), NULL, 0); + if (!length) + return p.string(); + + std::wstring out(length, 0); DWORD len = GetShortPathName(p.c_str(), &out[0], out.size()); if (!len) return p.string(); diff --git a/meson.build b/meson.build index f157ad876..e948710ac 100644 --- a/meson.build +++ b/meson.build @@ -408,14 +408,17 @@ aegisub_cpp_pch = ['src/include/agi_pre.h'] aegisub_c_pch = ['src/include/agi_pre_c.h'] link_args = [] +link_depends = [] if host_machine.system() == 'windows' manifest_file = configure_file(copy: true, input: 'src/res/aegisub.exe.manifest', output: 'aegisub.exe.manifest') link_args += ['/MANIFEST:EMBED', '/MANIFESTINPUT:@0@'.format(manifest_file)] + link_depends += manifest_file endif aegisub = executable('aegisub', aegisub_src, version_h, acconf, link_with: [libresrc, libluabins, libaegisub], link_args: link_args, + link_depends: link_depends, include_directories: [libaegisub_inc, libresrc_inc, version_inc, deps_inc, include_directories('src')], cpp_pch: aegisub_cpp_pch, c_pch: aegisub_c_pch, diff --git a/src/audio_provider_avs.cpp b/src/audio_provider_avs.cpp index fff0ed823..b5b1d0916 100644 --- a/src/audio_provider_avs.cpp +++ b/src/audio_provider_avs.cpp @@ -148,7 +148,6 @@ void AvisynthAudioProvider::FillBuffer(void *buf, int64_t start, int64_t count) } std::unique_ptr CreateAvisynthAudioProvider(agi::fs::path const& file, agi::BackgroundRunner *) { - agi::acs::CheckFileRead(file); return agi::make_unique(file); } #endif diff --git a/src/audio_provider_bestsource.cpp b/src/audio_provider_bestsource.cpp index 5390788dc..aa1bd1904 100644 --- a/src/audio_provider_bestsource.cpp +++ b/src/audio_provider_bestsource.cpp @@ -63,6 +63,7 @@ BSAudioProvider::BSAudioProvider(agi::fs::path const& filename, agi::BackgroundR LOG_D("bs") << "File cached and has exact samples."; } }); + BSCleanCache(); properties = bs.GetAudioProperties(); float_samples = properties.IsFloat; bytes_per_sample = properties.BytesPerSample; diff --git a/src/audio_timing_dialogue.cpp b/src/audio_timing_dialogue.cpp index 7762525f2..44e9c39b2 100644 --- a/src/audio_timing_dialogue.cpp +++ b/src/audio_timing_dialogue.cpp @@ -324,8 +324,8 @@ class AudioTimingControllerDialogue final : public AudioTimingController { /// The owning project context agi::Context *context; - /// The time which was clicked on for alt-dragging mode - int clicked_ms; + /// The time which was clicked on for alt-dragging mode, or INT_MIN if not in alt-draging mode + int clicked_ms = INT_MIN; /// Autocommit option const agi::OptionValue *auto_commit = OPT_GET("Audio/Auto/Commit"); diff --git a/src/base_grid.cpp b/src/base_grid.cpp index 225b80601..509474ddf 100644 --- a/src/base_grid.cpp +++ b/src/base_grid.cpp @@ -566,7 +566,9 @@ void BaseGrid::OnMouseEvent(wxMouseEvent &event) { if (event.GetWheelRotation() != 0) { if (ForwardMouseWheelEvent(this, event)) { int step = shift ? h / lineHeight - 2 : 3; - ScrollTo(yPos - step * event.GetWheelRotation() / event.GetWheelDelta()); + scrollWheelProgress += event.GetWheelRotation(); + ScrollTo(yPos - step * (scrollWheelProgress / event.GetWheelDelta())); + scrollWheelProgress %= event.GetWheelDelta(); } return; } diff --git a/src/base_grid.h b/src/base_grid.h index 9b68b1da3..3349b03c7 100644 --- a/src/base_grid.h +++ b/src/base_grid.h @@ -46,6 +46,7 @@ class BaseGrid final : public wxWindow { std::vector connections; int lineHeight = 1; ///< Height of a line in pixels in the current font bool holding = false; ///< Is a drag selection in process? + int scrollWheelProgress = 0; ///< How close we are to reaching a full mouse wheel step wxFont font; ///< Current grid font wxScrollBar *scrollBar; ///< The grid's scrollbar bool byFrame = false; ///< Should times be displayed as frame numbers diff --git a/src/bestsource_common.cpp b/src/bestsource_common.cpp index 69d627015..2cd478ef6 100644 --- a/src/bestsource_common.cpp +++ b/src/bestsource_common.cpp @@ -23,6 +23,7 @@ #include "bestsource_common.h" #include "options.h" +#include "utils.h" #include #include @@ -45,5 +46,11 @@ std::string GetBSCacheFile(agi::fs::path const& filename) { return result.string(); } +void BSCleanCache() { + CleanCache(config::path->Decode("?local/bsindex/"), + "*.json", + OPT_GET("Provider/BestSource/Cache/Size")->GetInt(), + OPT_GET("Provider/BestSource/Cache/Files")->GetInt()); +} #endif // WITH_BESTSOURCE diff --git a/src/bestsource_common.h b/src/bestsource_common.h index b93ccc815..53ab39fe4 100644 --- a/src/bestsource_common.h +++ b/src/bestsource_common.h @@ -1,4 +1,4 @@ -// Copyright (c) 2022, arch1t3cht > +// Copyright (c) 2022, arch1t3cht // // Permission to use, copy, modify, and distribute this software for any // purpose with or without fee is hereby granted, provided that the above @@ -24,5 +24,6 @@ #include std::string GetBSCacheFile(agi::fs::path const& filename); +void BSCleanCache(); #endif /* WITH_BESTSOURCE */ diff --git a/src/dialog_selection.cpp b/src/dialog_selection.cpp index 2adfa764c..1f821c80a 100644 --- a/src/dialog_selection.cpp +++ b/src/dialog_selection.cpp @@ -51,7 +51,7 @@ class DialogSelection final : public wxDialog { wxRadioBox *dialogue_field; ///< Which dialogue field to look at wxRadioBox *match_mode; - void Process(wxCommandEvent&); + void Process(wxCommandEvent& event); /// Dialogue/Comment check handler to ensure at least one is always checked /// @param chk The checkbox to check if both are clear @@ -150,7 +150,7 @@ wxDialog (c->parent, -1, _("Select"), wxDefaultPosition, wxDefaultSize, wxCAPTIO main_sizer->Add(selection_change_type = new wxRadioBox(this, -1, _("Action"), wxDefaultPosition, wxDefaultSize, 4, actions, 1), main_flags); } - main_sizer->Add(CreateButtonSizer(wxOK | wxCANCEL | wxHELP), main_flags); + main_sizer->Add(CreateButtonSizer(wxOK | wxCANCEL | wxAPPLY | wxHELP), main_flags); SetSizerAndFit(main_sizer); CenterOnParent(); @@ -165,6 +165,7 @@ wxDialog (c->parent, -1, _("Select"), wxDefaultPosition, wxDefaultSize, wxCAPTIO match_mode->SetSelection(OPT_GET("Tool/Select Lines/Mode")->GetInt()); Bind(wxEVT_BUTTON, &DialogSelection::Process, this, wxID_OK); + Bind(wxEVT_BUTTON, &DialogSelection::Process, this, wxID_APPLY); Bind(wxEVT_BUTTON, std::bind(&HelpButton::OpenPage, "Select Lines"), wxID_HELP); apply_to_comments->Bind(wxEVT_CHECKBOX, std::bind(&DialogSelection::OnDialogueCheckbox, this, apply_to_dialogue)); apply_to_dialogue->Bind(wxEVT_CHECKBOX, std::bind(&DialogSelection::OnDialogueCheckbox, this, apply_to_comments)); @@ -181,7 +182,7 @@ DialogSelection::~DialogSelection() { OPT_SET("Tool/Select Lines/Match/Comment")->SetBool(apply_to_comments->IsChecked()); } -void DialogSelection::Process(wxCommandEvent&) { +void DialogSelection::Process(wxCommandEvent& event) { std::set matches; try { @@ -192,7 +193,7 @@ void DialogSelection::Process(wxCommandEvent&) { dialogue_field->GetSelection(), con->ass.get()); } catch (agi::Exception const&) { - Close(); + if (event.GetId() == wxID_OK) Close(); return; } @@ -242,7 +243,7 @@ void DialogSelection::Process(wxCommandEvent&) { new_active = *new_sel.begin(); con->selectionController->SetSelectionAndActive(std::move(new_sel), new_active); - Close(); + if (event.GetId() == wxID_OK) Close(); } void DialogSelection::OnDialogueCheckbox(wxCheckBox *chk) { diff --git a/src/libresrc/default_config.json b/src/libresrc/default_config.json index bf79b75b0..4e7828d8c 100644 --- a/src/libresrc/default_config.json +++ b/src/libresrc/default_config.json @@ -365,6 +365,12 @@ "Index All Tracks" : true, "Log Level" : "quiet" }, + "BestSource" : { + "Cache" : { + "Files" : 100, + "Size" : 42 + } + }, "Video" : { "Cache" : { "Size" : 32 @@ -416,6 +422,7 @@ "Syntax" : true }, "Provider" : "libass", + "Show Original": false, "Time Edit" : { "Insert Mode" : true } diff --git a/src/libresrc/osx/default_config.json b/src/libresrc/osx/default_config.json index f806a15a5..5c40c5e52 100644 --- a/src/libresrc/osx/default_config.json +++ b/src/libresrc/osx/default_config.json @@ -365,6 +365,12 @@ "Index All Tracks" : true, "Log Level" : "quiet" }, + "BestSource" : { + "Cache" : { + "Files" : 100, + "Size" : 42 + } + }, "Video" : { "Cache" : { "Size" : 32 @@ -416,6 +422,7 @@ "Syntax" : true }, "Provider" : "libass", + "Show Original": false, "Time Edit" : { "Insert Mode" : true } diff --git a/src/project.cpp b/src/project.cpp index 63a341da0..89196b9e3 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -429,7 +429,7 @@ void Project::LoadList(std::vector const& files) { ".rm", ".rmvb", ".ts", - ".webm" + ".webm", ".wmv", ".y4m", ".yuv" diff --git a/src/res/aegisub.exe.manifest b/src/res/aegisub.exe.manifest index 9ea55ca4b..b792b90f8 100644 --- a/src/res/aegisub.exe.manifest +++ b/src/res/aegisub.exe.manifest @@ -19,6 +19,7 @@ True/PM PerMonitorV2,PerMonitor + true \ No newline at end of file diff --git a/src/subs_edit_box.cpp b/src/subs_edit_box.cpp index a7c3b5ea8..308023d6c 100644 --- a/src/subs_edit_box.cpp +++ b/src/subs_edit_box.cpp @@ -254,6 +254,12 @@ SubsEditBox::SubsEditBox(wxWindow *parent, agi::Context *context) context->textSelectionController->SetControl(edit_ctrl); edit_ctrl->SetFocus(); + + bool show_original = OPT_GET("Subtitle/Show Original")->GetBool(); + if (show_original) { + split_box->SetValue(true); + DoOnSplit(true); + } } SubsEditBox::~SubsEditBox() { @@ -588,15 +594,22 @@ void SubsEditBox::SetControlsState(bool state) { } void SubsEditBox::OnSplit(wxCommandEvent&) { + bool show_original = split_box->IsChecked(); + DoOnSplit(show_original); + OPT_SET("Subtitle/Show Original")->SetBool(show_original); +} + +void SubsEditBox::DoOnSplit(bool show_original) { Freeze(); - GetSizer()->Show(secondary_editor, split_box->IsChecked()); - GetSizer()->Show(bottom_sizer, split_box->IsChecked()); + GetSizer()->Show(secondary_editor, show_original); + GetSizer()->Show(bottom_sizer, show_original); Fit(); SetMinSize(GetSize()); - GetParent()->GetSizer()->Layout(); + wxSizer* parent_sizer = GetParent()->GetSizer(); + if (parent_sizer) parent_sizer->Layout(); Thaw(); - if (split_box->IsChecked()) + if (show_original) secondary_editor->SetValue(to_wx(c->initialLineState->GetInitialText())); } diff --git a/src/subs_edit_box.h b/src/subs_edit_box.h index 0443adbdc..06eb33d58 100644 --- a/src/subs_edit_box.h +++ b/src/subs_edit_box.h @@ -155,6 +155,7 @@ class SubsEditBox final : public wxPanel { void OnEffectChange(wxCommandEvent &); void OnSize(wxSizeEvent &event); void OnSplit(wxCommandEvent&); + void DoOnSplit(bool show_original); void SetPlaceholderCtrl(wxControl *ctrl, wxString const& value); diff --git a/src/video_provider_avs.cpp b/src/video_provider_avs.cpp index 263310675..0c824f264 100644 --- a/src/video_provider_avs.cpp +++ b/src/video_provider_avs.cpp @@ -324,7 +324,6 @@ void AvisynthVideoProvider::GetFrame(int n, VideoFrame &out) { namespace agi { class BackgroundRunner; } std::unique_ptr CreateAvisynthVideoProvider(agi::fs::path const& path, std::string const& colormatrix, agi::BackgroundRunner *) { - agi::acs::CheckFileRead(path); return agi::make_unique(path, colormatrix); } #endif // HAVE_AVISYNTH diff --git a/src/video_provider_bestsource.cpp b/src/video_provider_bestsource.cpp index a75a8c676..3853d2d73 100644 --- a/src/video_provider_bestsource.cpp +++ b/src/video_provider_bestsource.cpp @@ -84,7 +84,6 @@ public: std::string colormatrix_description(const AVFrame *frame) { // Assuming TV for unspecified std::string str = frame->color_range == AVCOL_RANGE_JPEG ? "PC" : "TV"; - LOG_D("bestsource") << frame->colorspace; switch (frame->colorspace) { case AVCOL_SPC_BT709: @@ -114,21 +113,16 @@ BSVideoProvider::BSVideoProvider(agi::fs::path const& filename, std::string cons has_audio = false; } + br->Run([&](agi::ProgressSink *ps) { + ps->SetTitle(from_wx(_("Exacting"))); + ps->SetMessage(from_wx(_("Creating cache... This can take a while!"))); + ps->SetIndeterminate(); + if (bs.GetExactDuration()) { + LOG_D("provider/video/bestsource") << "File cached and has exact samples."; + } + }); properties = bs.GetVideoProperties(); - if (properties.NumFrames == -1) { - LOG_D("bs") << "File not cached or varying samples, creating cache."; - br->Run([&](agi::ProgressSink *ps) { - ps->SetTitle(from_wx(_("Exacting"))); - ps->SetMessage(from_wx(_("Creating cache... This can take a while!"))); - ps->SetIndeterminate(); - if (bs.GetExactDuration()) { - LOG_D("bs") << "File cached and has exact samples."; - } - }); - properties = bs.GetVideoProperties(); - } - br->Run([&](agi::ProgressSink *ps) { ps->SetTitle(from_wx(_("Scanning"))); ps->SetMessage(from_wx(_("Finding Keyframes and Timecodes..."))); @@ -147,7 +141,7 @@ BSVideoProvider::BSVideoProvider(agi::fs::path const& filename, std::string cons Keyframes.push_back(n); } - TimecodesVector.push_back(frame->Pts * properties.TimeBase.Den / properties.TimeBase.Num); + TimecodesVector.push_back(1000 * frame->Pts * properties.TimeBase.Num / properties.TimeBase.Den); ps->SetProgress(n, properties.NumFrames); } @@ -158,6 +152,8 @@ BSVideoProvider::BSVideoProvider(agi::fs::path const& filename, std::string cons } }); + BSCleanCache(); + // Decode the first frame to get the color space std::unique_ptr frame(bs.GetFrame(0)); colorspace = colormatrix_description(frame->GetAVFrame()); diff --git a/src/video_provider_manager.cpp b/src/video_provider_manager.cpp index 917b923d5..a15df8b17 100644 --- a/src/video_provider_manager.cpp +++ b/src/video_provider_manager.cpp @@ -80,11 +80,6 @@ std::unique_ptr VideoProviderFactory::GetProvider(agi::fs::path c LOG_I("manager/video/provider") << factory->name << ": opened " << filename; return provider->WantsCaching() ? CreateCacheVideoProvider(std::move(provider)) : std::move(provider); } - catch (agi::fs::FileNotFound const&) { - err = "file not found."; - // Keep trying other providers as this one may just not be able to - // open a valid path - } catch (VideoNotSupported const&) { found = true; err = "video is not in a supported format."; diff --git a/subprojects/bestsource.wrap b/subprojects/bestsource.wrap index fa0e5ef45..67943fcb3 100644 --- a/subprojects/bestsource.wrap +++ b/subprojects/bestsource.wrap @@ -1,6 +1,6 @@ [wrap-git] url = https://github.com/vapoursynth/bestsource -revision = head +revision = ba1249c1f5443be6d0ec2be32490af5bbc96bf99 patch_directory = bestsource [provide] diff --git a/subprojects/dav1d.wrap b/subprojects/dav1d.wrap new file mode 100644 index 000000000..49251c463 --- /dev/null +++ b/subprojects/dav1d.wrap @@ -0,0 +1,8 @@ +[wrap-git] +directory = dav1d +url = https://github.com/videolan/dav1d.git +revision = 0.9.2 +patch_directory = dav1d + +[provide] +dav1d = dav1d_dep diff --git a/subprojects/ffms2.wrap b/subprojects/ffms2.wrap index b5e945a06..b65e713c8 100644 --- a/subprojects/ffms2.wrap +++ b/subprojects/ffms2.wrap @@ -1,5 +1,5 @@ [wrap-git] -url = https://github.com/FFMS/ffms2.git +url = https://github.com/arch1t3cht/ffms2.git revision = head patch_directory = ffms2 diff --git a/subprojects/packagefiles/dav1d/src/meson.build b/subprojects/packagefiles/dav1d/src/meson.build new file mode 100644 index 000000000..6886c775f --- /dev/null +++ b/subprojects/packagefiles/dav1d/src/meson.build @@ -0,0 +1,366 @@ +# Copyright © 2018-2019, VideoLAN and dav1d authors +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# +# Build definition for the dav1d library +# + +# libdav1d source files +libdav1d_sources = files( + 'cdf.c', + 'cpu.c', + 'data.c', + 'decode.c', + 'dequant_tables.c', + 'getbits.c', + 'intra_edge.c', + 'itx_1d.c', + 'lf_mask.c', + 'log.c', + 'mem.c', + 'msac.c', + 'obu.c', + 'picture.c', + 'qm.c', + 'ref.c', + 'refmvs.c', + 'scan.c', + 'tables.c', + 'warpmv.c', + 'wedge.c', +) + +# libdav1d bitdepth source files +# These files are compiled for each bitdepth with +# `BITDEPTH` defined to the currently built bitdepth. +libdav1d_tmpl_sources = files( + 'cdef_apply_tmpl.c', + 'cdef_tmpl.c', + 'fg_apply_tmpl.c', + 'film_grain_tmpl.c', + 'ipred_prepare_tmpl.c', + 'ipred_tmpl.c', + 'itx_tmpl.c', + 'lf_apply_tmpl.c', + 'loopfilter_tmpl.c', + 'looprestoration_tmpl.c', + 'lr_apply_tmpl.c', + 'mc_tmpl.c', + 'recon_tmpl.c', +) + +libdav1d_arch_tmpl_sources = [] + +libdav1d_bitdepth_objs = [] + +# libdav1d entrypoint source files +# These source files contain library entry points and are +# built with the stack-realign flag set, where necessary. +libdav1d_entrypoints_sources = files( + 'lib.c', + 'thread_task.c' +) + +# ASM specific sources +libdav1d_asm_objs = [] +# Arch-specific flags +arch_flags = [] +if is_asm_enabled + if (host_machine.cpu_family() == 'aarch64' or + host_machine.cpu_family().startswith('arm')) + + libdav1d_sources += files( + 'arm/cpu.c', + 'arm/refmvs_init.c', + ) + libdav1d_tmpl_sources += files( + 'arm/cdef_init_tmpl.c', + 'arm/film_grain_init_tmpl.c', + 'arm/ipred_init_tmpl.c', + 'arm/itx_init_tmpl.c', + 'arm/loopfilter_init_tmpl.c', + 'arm/looprestoration_init_tmpl.c', + 'arm/mc_init_tmpl.c', + ) + if (host_machine.cpu_family() == 'aarch64' or + host_machine.cpu() == 'arm64') + libdav1d_sources_asm = files( + # itx.S is used for both 8 and 16 bpc. + 'arm/64/itx.S', + 'arm/64/looprestoration_common.S', + 'arm/64/msac.S', + 'arm/64/refmvs.S', + ) + + if dav1d_bitdepths.contains('8') + libdav1d_sources_asm += files( + 'arm/64/cdef.S', + 'arm/64/film_grain.S', + 'arm/64/ipred.S', + 'arm/64/loopfilter.S', + 'arm/64/looprestoration.S', + 'arm/64/mc.S', + ) + endif + + if dav1d_bitdepths.contains('16') + libdav1d_sources_asm += files( + 'arm/64/cdef16.S', + 'arm/64/film_grain16.S', + 'arm/64/ipred16.S', + 'arm/64/itx16.S', + 'arm/64/loopfilter16.S', + 'arm/64/looprestoration16.S', + 'arm/64/mc16.S', + ) + endif + elif host_machine.cpu_family().startswith('arm') + libdav1d_sources_asm = files( + # itx.S is used for both 8 and 16 bpc. + 'arm/32/itx.S', + 'arm/32/looprestoration_common.S', + 'arm/32/msac.S', + 'arm/32/refmvs.S', + ) + + if dav1d_bitdepths.contains('8') + libdav1d_sources_asm += files( + 'arm/32/cdef.S', + 'arm/32/film_grain.S', + 'arm/32/ipred.S', + 'arm/32/loopfilter.S', + 'arm/32/looprestoration.S', + 'arm/32/mc.S', + ) + endif + + if dav1d_bitdepths.contains('16') + libdav1d_sources_asm += files( + 'arm/32/cdef16.S', + 'arm/32/film_grain16.S', + 'arm/32/ipred16.S', + 'arm/32/itx16.S', + 'arm/32/loopfilter16.S', + 'arm/32/looprestoration16.S', + 'arm/32/mc16.S', + ) + endif + endif + + if use_gaspp + libdav1d_asm_objs = gaspp_gen.process(libdav1d_sources_asm) + else + libdav1d_sources += libdav1d_sources_asm + endif + elif host_machine.cpu_family().startswith('x86') + + libdav1d_sources += files( + 'x86/cpu.c', + 'x86/msac_init.c', + 'x86/refmvs_init.c', + ) + + libdav1d_tmpl_sources += files( + 'x86/cdef_init_tmpl.c', + 'x86/film_grain_init_tmpl.c', + 'x86/ipred_init_tmpl.c', + 'x86/itx_init_tmpl.c', + 'x86/loopfilter_init_tmpl.c', + 'x86/looprestoration_init_tmpl.c', + 'x86/mc_init_tmpl.c', + ) + + # NASM source files + libdav1d_sources_asm = files( + 'x86/cpuid.asm', + 'x86/msac.asm', + 'x86/refmvs.asm', + 'x86/cdef_avx2.asm', + 'x86/itx_avx2.asm', + 'x86/looprestoration_avx2.asm', + 'x86/cdef_sse.asm', + 'x86/itx_sse.asm', + ) + + if dav1d_bitdepths.contains('8') + libdav1d_sources_asm += files( + 'x86/cdef_avx512.asm', + 'x86/mc_avx512.asm', + 'x86/mc_avx2.asm', + 'x86/film_grain_avx2.asm', + 'x86/ipred_avx2.asm', + 'x86/loopfilter_avx2.asm', + 'x86/film_grain_sse.asm', + 'x86/ipred_sse.asm', + 'x86/loopfilter_sse.asm', + 'x86/looprestoration_sse.asm', + 'x86/mc_sse.asm', + ) + endif + + if dav1d_bitdepths.contains('16') + libdav1d_sources_asm += files( + 'x86/cdef16_avx2.asm', + 'x86/film_grain16_avx2.asm', + 'x86/ipred16_avx2.asm', + 'x86/itx16_avx2.asm', + 'x86/loopfilter16_avx2.asm', + 'x86/looprestoration16_avx2.asm', + 'x86/mc16_avx2.asm', + 'x86/cdef16_sse.asm', + 'x86/film_grain16_sse.asm', + 'x86/ipred16_sse.asm', + 'x86/itx16_sse.asm', + 'x86/loopfilter16_sse.asm', + 'x86/looprestoration16_sse.asm', + 'x86/mc16_sse.asm', + ) + endif + + # Compile the ASM sources with NASM + libdav1d_asm_objs = nasm_gen.process(libdav1d_sources_asm) + elif host_machine.cpu() == 'ppc64le' + arch_flags = ['-maltivec', '-mvsx'] + libdav1d_sources += files( + 'ppc/cpu.c', + ) + libdav1d_arch_tmpl_sources += files( + 'ppc/cdef_init_tmpl.c', + 'ppc/looprestoration_init_tmpl.c', + ) + endif +endif + + + +api_export_flags = [] + +# +# Windows .rc file and API export flags +# + +if host_machine.system() == 'windows' and get_option('default_library') != 'static' + rc_file = configure_file( + input : 'dav1d.rc.in', + output : 'dav1d.rc', + configuration : rc_data + ) + + libdav1d_rc_obj = winmod.compile_resources(rc_file) + + api_export_flags = ['-DDAV1D_BUILDING_DLL'] +else + libdav1d_rc_obj = [] +endif + + + + +# +# Library definitions +# + +# Helper library for dav1d entrypoints +libdav1d_entrypoints_objs = static_library('dav1d_entrypoint', + libdav1d_entrypoints_sources, + rev_target, config_h_target, + + include_directories : dav1d_inc_dirs, + dependencies: [stdatomic_dependencies], + c_args : [stackalign_flag, stackrealign_flag, api_export_flags], + install : false, + build_by_default : false, +).extract_all_objects(recursive: true) + +# Helper library for each bitdepth +libdav1d_bitdepth_objs = [] +foreach bitdepth : dav1d_bitdepths + libdav1d_bitdepth_objs += static_library( + 'dav1d_bitdepth_@0@'.format(bitdepth), + libdav1d_tmpl_sources, config_h_target, + include_directories: dav1d_inc_dirs, + dependencies : [stdatomic_dependencies], + c_args : ['-DBITDEPTH=@0@'.format(bitdepth)] + stackalign_flag, + install : false, + build_by_default : false, + ).extract_all_objects(recursive: true) +endforeach + +# Helper library for each bitdepth and architecture-specific flags +foreach bitdepth : dav1d_bitdepths + libdav1d_bitdepth_objs += static_library( + 'dav1d_arch_bitdepth_@0@'.format(bitdepth), + libdav1d_arch_tmpl_sources, config_h_target, + include_directories: dav1d_inc_dirs, + dependencies : [stdatomic_dependencies], + c_args : ['-DBITDEPTH=@0@'.format(bitdepth)] + stackalign_flag + arch_flags, + install : false, + build_by_default : false, + ).extract_all_objects(recursive: true) +endforeach + +# The final dav1d library +if host_machine.system() == 'windows' + dav1d_soversion = '' +else + dav1d_soversion = dav1d_api_version_major +endif + +libdav1d = library('dav1d', + libdav1d_sources, + libdav1d_asm_objs, + libdav1d_rc_obj, + + objects : [ + libdav1d_bitdepth_objs, + libdav1d_entrypoints_objs + ], + + include_directories : dav1d_inc_dirs, + dependencies : [ + stdatomic_dependencies, + thread_dependency, + thread_compat_dep, + libdl_dependency, + ], + c_args : [stackalign_flag, api_export_flags], + version : dav1d_soname_version, + soversion : dav1d_soversion, + install : true, +) + +dav1d_dep = declare_dependency(link_with: libdav1d, + include_directories : include_directories('../include') +) + +# +# Generate pkg-config .pc file +# +# pkg_mod = import('pkgconfig') +# pkg_mod.generate(libraries: libdav1d, +# version: meson.project_version(), +# name: 'libdav1d', +# filebase: 'dav1d', +# description: 'AV1 decoding library' +# ) diff --git a/subprojects/packagefiles/ffmpeg/meson.build b/subprojects/packagefiles/ffmpeg/meson.build index b960f4ce4..1db65b5a8 100644 --- a/subprojects/packagefiles/ffmpeg/meson.build +++ b/subprojects/packagefiles/ffmpeg/meson.build @@ -1750,7 +1750,8 @@ foreach check : all_checks else dep = dependency(pkg_name, required : req) endif - found = dep.found() and dep.type_name() != 'internal' + found = dep.found() + skipchecks = dep.type_name() == 'internal' # same here, trust the meson dependency extra_deps += dep endif endif diff --git a/subprojects/packagefiles/ffms2/meson.build b/subprojects/packagefiles/ffms2/meson.build index 8c6a07851..91d649f68 100644 --- a/subprojects/packagefiles/ffms2/meson.build +++ b/subprojects/packagefiles/ffms2/meson.build @@ -2,12 +2,14 @@ project('ffms2', 'cpp', version: '2.40.0') deps = [] +opts = ['tests=disabled', 'libdav1d=enabled'] + deps += dependency('zlib') -deps += dependency('libavformat', default_options: ['tests=disabled']) -deps += dependency('libavcodec', default_options: ['tests=disabled']) -deps += dependency('libswscale', default_options: ['tests=disabled']) -deps += dependency('libavutil', default_options: ['tests=disabled']) -deps += dependency('libswresample', default_options: ['tests=disabled']) +deps += dependency('libavformat', default_options: opts) +deps += dependency('libavcodec', default_options: opts) +deps += dependency('libswscale', default_options: opts) +deps += dependency('libavutil', default_options: opts) +deps += dependency('libswresample', default_options: opts) args = ['-D_FILE_OFFSET_BITNS=64', '-DFFMS_EXPORTS', '-D__STDC_CONSTANT_MACROS'] usage_args = []