diff --git a/.gitignore b/.gitignore index f6ff86e..8538e7f 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ Thumbs.db # what the panel writes into the plugin folder while it runs .eternal2x_* +.upflow2x_* # the RIFE network's model is downloaded here on first use models/ diff --git a/Installer/Eternal2x.lua b/Installer/Eternal2x.lua index 73fb427..cf02183 100644 --- a/Installer/Eternal2x.lua +++ b/Installer/Eternal2x.lua @@ -207,7 +207,7 @@ local STOP_PATH = join_path(REPO_ROOT ~= "" and REPO_ROOT or root, ".eternal2x_s -- The frames marked on the clip go to the stage in this file. A long clip's -- list does not fit on a Windows command line. local MARKS_PATH = join_path(REPO_ROOT ~= "" and REPO_ROOT or root, ".eternal2x_marks.txt") -local LOG_PATH = join_path(REPO_ROOT ~= "" and REPO_ROOT or root, ".eternal2x_last_run.log") +local LOG_PATH = join_path(REPO_ROOT ~= "" and REPO_ROOT or root, ".upflow2x_last_run.log") -- The update check runs each time the panel opens, so it logs apart from -- renders. Sharing a log wiped the render's, the one worth sending in. local UPDATE_LOG_PATH = join_path(REPO_ROOT ~= "" and REPO_ROOT or root, ".eternal2x_update.log") @@ -323,7 +323,7 @@ local function stem_of(path) end -- What a render is called: its folder for a sequence of frames, its file --- name for one file. nil for a path Eternal2x does not write. +-- name for one file. nil for a path Upflow2x does not write. local function render_name(path) return path:match("([^/\\]+)[/\\]frame_[%d%[%]%-]+%.png$") or path:match("([^/\\]+)%.mkv$") or path:match("([^/\\]+)%.mp4$") @@ -459,7 +459,7 @@ local function find_clip_path() if not timeline then return nil, "No timeline is open." end -- Resolve's API has no timeline selection. GetCurrentVideoItem is the clip - -- under the playhead, so that is the one Eternal2x works on. + -- under the playhead, so that is the one Upflow2x works on. local item = nil if timeline.GetCurrentVideoItem then item = timeline:GetCurrentVideoItem() @@ -1130,7 +1130,7 @@ local function refresh_source(keep) return true end --- Eternal2x's own markers carry this, so analysing again replaces them and +-- Upflow2x's own markers carry this, so analysing again replaces them and -- leaves every marker the editor placed. local MARK_TAG = "eternal2x" @@ -1978,7 +1978,7 @@ win:Show() if REPO_ROOT == "" then items.Meta.Text = "Plugin folder not configured." - set_status("Run Installer/install_eternal2x.py, then restart Resolve.") + set_status("Run Installer/install_upflow2x.py, then restart Resolve.") else refresh_source() start_polling() diff --git a/Installer/Eternal2xLauncher.lua b/Installer/Eternal2xLauncher.lua index 8436a33..f54a8c1 100644 --- a/Installer/Eternal2xLauncher.lua +++ b/Installer/Eternal2xLauncher.lua @@ -50,7 +50,7 @@ local function file_exists(path) return true end --- Where Installer/install_eternal2x.py puts this script, for when Resolve +-- Where Installer/install_upflow2x.py puts this script, for when Resolve -- reports the running script under a path map such as Scripts: that io.open -- cannot follow. local function installed_dir() diff --git a/Installer/gui_installer.py b/Installer/gui_installer.py index d6c0080..6ed93de 100644 --- a/Installer/gui_installer.py +++ b/Installer/gui_installer.py @@ -28,11 +28,11 @@ # drift. This runs standalone and from a PyInstaller bundle, where the repo # root is not on the path, so fall back to importing the sibling module. try: - from Installer.install_eternal2x import ( + from Installer.install_upflow2x import ( _resolve_scripts_dir, remove_old_install, write_config) except ImportError: # pragma: no cover - depends on how this was launched sys.path.insert(0, str(Path(__file__).resolve().parent)) - from install_eternal2x import ( + from install_upflow2x import ( _resolve_scripts_dir, remove_old_install, write_config) # --------------------------------------------------------------------------- diff --git a/Installer/install_eternal2x.py b/Installer/install_upflow2x.py similarity index 100% rename from Installer/install_eternal2x.py rename to Installer/install_upflow2x.py diff --git a/Pipeline/config.py b/Pipeline/config.py index 6e27772..f7013f6 100644 --- a/Pipeline/config.py +++ b/Pipeline/config.py @@ -6,7 +6,7 @@ @dataclass -class Eternal2xConfig: +class Upflow2xConfig: """Everything the pipeline needs, in one place. Defaults are tuned for hand-drawn animation, which is typically drawn on @@ -53,10 +53,10 @@ def to_dict(self) -> dict: return asdict(self) @classmethod - def from_dict(cls, data: dict) -> "Eternal2xConfig": + def from_dict(cls, data: dict) -> "Upflow2xConfig": known = {f for f in cls.__dataclass_fields__} return cls(**{k: v for k, v in (data or {}).items() if k in known}) # Kept so older saved settings and the previous CLI flags still load. -UpscaleConfig = Eternal2xConfig +UpscaleConfig = Upflow2xConfig diff --git a/Pipeline/render.py b/Pipeline/render.py index 837aa5c..2aab97e 100644 --- a/Pipeline/render.py +++ b/Pipeline/render.py @@ -26,7 +26,7 @@ import cv2 import numpy as np -from Pipeline.config import Eternal2xConfig +from Pipeline.config import Upflow2xConfig from Pipeline.dedupe import DedupePlan, noise_threshold, plan_from_scores, output_time_map from Pipeline.interpolate import frames_are_a_cut, is_a_cut, shot_change, upscale @@ -246,7 +246,7 @@ def _require_constant_rate(cap: _ClipReader, fps: float, path: Path) -> None: def frame_difference_scores( path: Path, - cfg: Eternal2xConfig, + cfg: Upflow2xConfig, *, progress: Optional[ProgressFn] = None, frames: FrameRange = None, @@ -303,7 +303,7 @@ def frame_difference_scores( def analyse_video( path: Path, - cfg: Eternal2xConfig, + cfg: Upflow2xConfig, *, progress: Optional[ProgressFn] = None, frames: FrameRange = None, @@ -407,7 +407,7 @@ def render_plan( source: Path, plan: DedupePlan, output: Path, - cfg: Eternal2xConfig, + cfg: Upflow2xConfig, *, progress: Optional[ProgressFn] = None, sequence: Optional[bool] = None, diff --git a/README.md b/README.md index afc31a1..d258583 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,7 @@ install below, which does the same job. ``` python -m pip install numpy opencv-python -python Installer/install_eternal2x.py +python Installer/install_upflow2x.py ``` Use `python3` on macOS. The installer records the Python that runs it, so @@ -132,7 +132,7 @@ Markers on the timeline's ruler do not, so beat markers are safe there. You can skip Analyse and mark the frames yourself. A clip with no markers at all is rendered from the drawings Upflow2x finds on its own. -![The Upflow2x panel in DaVinci Resolve Studio after a render. The rebuilt clip sits on V2, lined up above the original on V1.](https://upflow2x.com/assets/demo/resolve.jpg) +![The Upflow2x panel open in DaVinci Resolve Studio, with Hero walk.mp4 on V1 and its render on V2.](https://upflow2x.com/assets/demo/resolve.jpg) The render runs in the background and the panel shows progress and the time left, so Resolve stays usable while it works. **Stop** ends it early. When it finishes, the rebuilt @@ -220,7 +220,7 @@ afterwards. | Problem | Fix | |---|---| | Resolve says you need Studio | Since 19.1 the free edition blocks script panels. Upflow2x needs Studio. | -| Clicking Upflow2x does nothing, or "Plugin folder not configured" | The plugin folder moved after installing, and Workspace → Console says `UI script not found`. Re-run `python Installer/install_eternal2x.py` from where it is now. | +| Clicking Upflow2x does nothing, or "Plugin folder not configured" | The plugin folder moved after installing, and Workspace → Console says `UI script not found`. Re-run `python Installer/install_upflow2x.py` from where it is now. | | "Could not reach Resolve" | Open the panel from Workspace → Scripts, not from a terminal. | | "No clip under the playhead" | Move the playhead over the clip, and the panel picks it up. | | "No duplicate frames. This clip is already on 1s." | The clip has no duplicated frames. It is live action, or already on 1s. | @@ -229,7 +229,7 @@ afterwards. | Progress seems stuck | Press **Refresh Progress**. If Python stopped, the panel says so and shows its last error. If a run was interrupted, press **Reset**. | | Resolve would not import the render | The render still finished. The panel prints where it is, so drag it into your media pool. Switching Output to `Image sequence` usually avoids this. | | Upscale skipped | Without a GPU the upscale is Super Scale, which needs Resolve Studio. | -| Something else | Email the panel's status text and the `.eternal2x_last_run.log` file from the plugin folder. | +| Something else | Email the panel's status text and the `.upflow2x_last_run.log` file from the plugin folder. | ## Development @@ -251,7 +251,7 @@ the environment variables from Blackmagic's scripting README, then run To cut a release, bump `VERSION` and push a matching tag: ``` -git tag v0.3.1 && git push origin v0.3.1 +git tag v0.5.0 && git push origin v0.5.0 ``` The release workflow builds the archives, publishes them, checks the published diff --git a/Stages/resolve_smooth.py b/Stages/resolve_smooth.py index b828629..428b88d 100644 --- a/Stages/resolve_smooth.py +++ b/Stages/resolve_smooth.py @@ -20,7 +20,7 @@ # able to tell the panel so, or the panel waits on a run that never started. try: from Pipeline import resolve_bridge as bridge - from Pipeline.config import Eternal2xConfig + from Pipeline.config import Upflow2xConfig from Pipeline.dedupe import plan_from_marks from Pipeline.render import SourceError, analyse_video, probe_video, render_plan except ImportError as exc: @@ -276,8 +276,8 @@ def build_parser() -> argparse.ArgumentParser: return parser -def config_from_args(args) -> Eternal2xConfig: - cfg = Eternal2xConfig() +def config_from_args(args) -> Upflow2xConfig: + cfg = Upflow2xConfig() if args.threshold is not None: cfg.duplicate_threshold = args.threshold if args.base_hold: diff --git a/VERSION b/VERSION index 1d0ba9e..8f0916f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.0 +0.5.0 diff --git a/docs/assets/demo/frames.jpg b/docs/assets/demo/frames.jpg index bb6bfe7..1b73577 100644 Binary files a/docs/assets/demo/frames.jpg and b/docs/assets/demo/frames.jpg differ diff --git a/docs/assets/demo/resolve.jpg b/docs/assets/demo/resolve.jpg index 94e76e6..3010936 100644 Binary files a/docs/assets/demo/resolve.jpg and b/docs/assets/demo/resolve.jpg differ diff --git a/docs/contact.html b/docs/contact.html index c45e58d..87c48c6 100644 --- a/docs/contact.html +++ b/docs/contact.html @@ -70,7 +70,7 @@

Contact

Many errors already have a fix under Troubleshooting.

- +
diff --git a/docs/help.html b/docs/help.html index c60310f..21b2bd9 100644 --- a/docs/help.html +++ b/docs/help.html @@ -91,7 +91,7 @@

Open it in Resolve

If the installer window doesn't open

Your Python was built without Tk. These two commands do the same job from the same folder, without a window. Then restart Resolve.

python -m pip install numpy opencv-python
-
python Installer/install_eternal2x.py
+
python Installer/install_upflow2x.py
@@ -122,7 +122,7 @@

Open it in Resolve

If the installer window doesn't open

Run these from the same folder instead, then restart Resolve.

python3 -m pip install numpy opencv-python
-
python3 Installer/install_eternal2x.py
+
python3 Installer/install_upflow2x.py
@@ -231,7 +231,7 @@

Troubleshooting

Progress seems stuck

Press Refresh Progress. If the panel says Python hasn't started, or that there's been no progress for a few minutes, the run stopped. Press Reset and run it again.

-

For anything else, email us the panel's status text and the .eternal2x_last_run.log file from the plugin folder.

+

For anything else, email us the panel's status text and the .upflow2x_last_run.log file from the plugin folder.

diff --git a/promo/film/meta.json b/promo/film/meta.json index 4f31108..512405b 100644 --- a/promo/film/meta.json +++ b/promo/film/meta.json @@ -1,5 +1,5 @@ { - "id": "eternal2x-brag", - "name": "eternal2x-brag", + "id": "upflow2x-brag", + "name": "upflow2x-brag", "createdAt": "2026-10-24T20:41:42.478Z" } \ No newline at end of file diff --git a/promo/film/package.json b/promo/film/package.json index ad5d480..d770ccc 100644 --- a/promo/film/package.json +++ b/promo/film/package.json @@ -1,5 +1,5 @@ { - "name": "eternal2x-brag", + "name": "upflow2x-brag", "private": true, "type": "module", "scripts": { diff --git a/public/logo/Eternal 2x logo 01.png b/public/logo/Eternal 2x logo 01.png deleted file mode 100644 index 8977cf7..0000000 Binary files a/public/logo/Eternal 2x logo 01.png and /dev/null differ diff --git a/release/upflow2x-mac/Installer/Eternal2x.lua b/release/upflow2x-mac/Installer/Eternal2x.lua index 73fb427..cf02183 100644 --- a/release/upflow2x-mac/Installer/Eternal2x.lua +++ b/release/upflow2x-mac/Installer/Eternal2x.lua @@ -207,7 +207,7 @@ local STOP_PATH = join_path(REPO_ROOT ~= "" and REPO_ROOT or root, ".eternal2x_s -- The frames marked on the clip go to the stage in this file. A long clip's -- list does not fit on a Windows command line. local MARKS_PATH = join_path(REPO_ROOT ~= "" and REPO_ROOT or root, ".eternal2x_marks.txt") -local LOG_PATH = join_path(REPO_ROOT ~= "" and REPO_ROOT or root, ".eternal2x_last_run.log") +local LOG_PATH = join_path(REPO_ROOT ~= "" and REPO_ROOT or root, ".upflow2x_last_run.log") -- The update check runs each time the panel opens, so it logs apart from -- renders. Sharing a log wiped the render's, the one worth sending in. local UPDATE_LOG_PATH = join_path(REPO_ROOT ~= "" and REPO_ROOT or root, ".eternal2x_update.log") @@ -323,7 +323,7 @@ local function stem_of(path) end -- What a render is called: its folder for a sequence of frames, its file --- name for one file. nil for a path Eternal2x does not write. +-- name for one file. nil for a path Upflow2x does not write. local function render_name(path) return path:match("([^/\\]+)[/\\]frame_[%d%[%]%-]+%.png$") or path:match("([^/\\]+)%.mkv$") or path:match("([^/\\]+)%.mp4$") @@ -459,7 +459,7 @@ local function find_clip_path() if not timeline then return nil, "No timeline is open." end -- Resolve's API has no timeline selection. GetCurrentVideoItem is the clip - -- under the playhead, so that is the one Eternal2x works on. + -- under the playhead, so that is the one Upflow2x works on. local item = nil if timeline.GetCurrentVideoItem then item = timeline:GetCurrentVideoItem() @@ -1130,7 +1130,7 @@ local function refresh_source(keep) return true end --- Eternal2x's own markers carry this, so analysing again replaces them and +-- Upflow2x's own markers carry this, so analysing again replaces them and -- leaves every marker the editor placed. local MARK_TAG = "eternal2x" @@ -1978,7 +1978,7 @@ win:Show() if REPO_ROOT == "" then items.Meta.Text = "Plugin folder not configured." - set_status("Run Installer/install_eternal2x.py, then restart Resolve.") + set_status("Run Installer/install_upflow2x.py, then restart Resolve.") else refresh_source() start_polling() diff --git a/release/upflow2x-mac/Installer/Eternal2xLauncher.lua b/release/upflow2x-mac/Installer/Eternal2xLauncher.lua index 8436a33..f54a8c1 100644 --- a/release/upflow2x-mac/Installer/Eternal2xLauncher.lua +++ b/release/upflow2x-mac/Installer/Eternal2xLauncher.lua @@ -50,7 +50,7 @@ local function file_exists(path) return true end --- Where Installer/install_eternal2x.py puts this script, for when Resolve +-- Where Installer/install_upflow2x.py puts this script, for when Resolve -- reports the running script under a path map such as Scripts: that io.open -- cannot follow. local function installed_dir() diff --git a/release/upflow2x-mac/Installer/gui_installer.py b/release/upflow2x-mac/Installer/gui_installer.py index d6c0080..6ed93de 100644 --- a/release/upflow2x-mac/Installer/gui_installer.py +++ b/release/upflow2x-mac/Installer/gui_installer.py @@ -28,11 +28,11 @@ # drift. This runs standalone and from a PyInstaller bundle, where the repo # root is not on the path, so fall back to importing the sibling module. try: - from Installer.install_eternal2x import ( + from Installer.install_upflow2x import ( _resolve_scripts_dir, remove_old_install, write_config) except ImportError: # pragma: no cover - depends on how this was launched sys.path.insert(0, str(Path(__file__).resolve().parent)) - from install_eternal2x import ( + from install_upflow2x import ( _resolve_scripts_dir, remove_old_install, write_config) # --------------------------------------------------------------------------- diff --git a/release/upflow2x-mac/Installer/install_eternal2x.py b/release/upflow2x-mac/Installer/install_upflow2x.py similarity index 100% rename from release/upflow2x-mac/Installer/install_eternal2x.py rename to release/upflow2x-mac/Installer/install_upflow2x.py diff --git a/release/upflow2x-mac/Pipeline/config.py b/release/upflow2x-mac/Pipeline/config.py index 6e27772..f7013f6 100644 --- a/release/upflow2x-mac/Pipeline/config.py +++ b/release/upflow2x-mac/Pipeline/config.py @@ -6,7 +6,7 @@ @dataclass -class Eternal2xConfig: +class Upflow2xConfig: """Everything the pipeline needs, in one place. Defaults are tuned for hand-drawn animation, which is typically drawn on @@ -53,10 +53,10 @@ def to_dict(self) -> dict: return asdict(self) @classmethod - def from_dict(cls, data: dict) -> "Eternal2xConfig": + def from_dict(cls, data: dict) -> "Upflow2xConfig": known = {f for f in cls.__dataclass_fields__} return cls(**{k: v for k, v in (data or {}).items() if k in known}) # Kept so older saved settings and the previous CLI flags still load. -UpscaleConfig = Eternal2xConfig +UpscaleConfig = Upflow2xConfig diff --git a/release/upflow2x-mac/Pipeline/render.py b/release/upflow2x-mac/Pipeline/render.py index 837aa5c..2aab97e 100644 --- a/release/upflow2x-mac/Pipeline/render.py +++ b/release/upflow2x-mac/Pipeline/render.py @@ -26,7 +26,7 @@ import cv2 import numpy as np -from Pipeline.config import Eternal2xConfig +from Pipeline.config import Upflow2xConfig from Pipeline.dedupe import DedupePlan, noise_threshold, plan_from_scores, output_time_map from Pipeline.interpolate import frames_are_a_cut, is_a_cut, shot_change, upscale @@ -246,7 +246,7 @@ def _require_constant_rate(cap: _ClipReader, fps: float, path: Path) -> None: def frame_difference_scores( path: Path, - cfg: Eternal2xConfig, + cfg: Upflow2xConfig, *, progress: Optional[ProgressFn] = None, frames: FrameRange = None, @@ -303,7 +303,7 @@ def frame_difference_scores( def analyse_video( path: Path, - cfg: Eternal2xConfig, + cfg: Upflow2xConfig, *, progress: Optional[ProgressFn] = None, frames: FrameRange = None, @@ -407,7 +407,7 @@ def render_plan( source: Path, plan: DedupePlan, output: Path, - cfg: Eternal2xConfig, + cfg: Upflow2xConfig, *, progress: Optional[ProgressFn] = None, sequence: Optional[bool] = None, diff --git a/release/upflow2x-mac/README.md b/release/upflow2x-mac/README.md index afc31a1..d258583 100644 --- a/release/upflow2x-mac/README.md +++ b/release/upflow2x-mac/README.md @@ -87,7 +87,7 @@ install below, which does the same job. ``` python -m pip install numpy opencv-python -python Installer/install_eternal2x.py +python Installer/install_upflow2x.py ``` Use `python3` on macOS. The installer records the Python that runs it, so @@ -132,7 +132,7 @@ Markers on the timeline's ruler do not, so beat markers are safe there. You can skip Analyse and mark the frames yourself. A clip with no markers at all is rendered from the drawings Upflow2x finds on its own. -![The Upflow2x panel in DaVinci Resolve Studio after a render. The rebuilt clip sits on V2, lined up above the original on V1.](https://upflow2x.com/assets/demo/resolve.jpg) +![The Upflow2x panel open in DaVinci Resolve Studio, with Hero walk.mp4 on V1 and its render on V2.](https://upflow2x.com/assets/demo/resolve.jpg) The render runs in the background and the panel shows progress and the time left, so Resolve stays usable while it works. **Stop** ends it early. When it finishes, the rebuilt @@ -220,7 +220,7 @@ afterwards. | Problem | Fix | |---|---| | Resolve says you need Studio | Since 19.1 the free edition blocks script panels. Upflow2x needs Studio. | -| Clicking Upflow2x does nothing, or "Plugin folder not configured" | The plugin folder moved after installing, and Workspace → Console says `UI script not found`. Re-run `python Installer/install_eternal2x.py` from where it is now. | +| Clicking Upflow2x does nothing, or "Plugin folder not configured" | The plugin folder moved after installing, and Workspace → Console says `UI script not found`. Re-run `python Installer/install_upflow2x.py` from where it is now. | | "Could not reach Resolve" | Open the panel from Workspace → Scripts, not from a terminal. | | "No clip under the playhead" | Move the playhead over the clip, and the panel picks it up. | | "No duplicate frames. This clip is already on 1s." | The clip has no duplicated frames. It is live action, or already on 1s. | @@ -229,7 +229,7 @@ afterwards. | Progress seems stuck | Press **Refresh Progress**. If Python stopped, the panel says so and shows its last error. If a run was interrupted, press **Reset**. | | Resolve would not import the render | The render still finished. The panel prints where it is, so drag it into your media pool. Switching Output to `Image sequence` usually avoids this. | | Upscale skipped | Without a GPU the upscale is Super Scale, which needs Resolve Studio. | -| Something else | Email the panel's status text and the `.eternal2x_last_run.log` file from the plugin folder. | +| Something else | Email the panel's status text and the `.upflow2x_last_run.log` file from the plugin folder. | ## Development @@ -251,7 +251,7 @@ the environment variables from Blackmagic's scripting README, then run To cut a release, bump `VERSION` and push a matching tag: ``` -git tag v0.3.1 && git push origin v0.3.1 +git tag v0.5.0 && git push origin v0.5.0 ``` The release workflow builds the archives, publishes them, checks the published diff --git a/release/upflow2x-mac/Stages/resolve_smooth.py b/release/upflow2x-mac/Stages/resolve_smooth.py index b828629..428b88d 100644 --- a/release/upflow2x-mac/Stages/resolve_smooth.py +++ b/release/upflow2x-mac/Stages/resolve_smooth.py @@ -20,7 +20,7 @@ # able to tell the panel so, or the panel waits on a run that never started. try: from Pipeline import resolve_bridge as bridge - from Pipeline.config import Eternal2xConfig + from Pipeline.config import Upflow2xConfig from Pipeline.dedupe import plan_from_marks from Pipeline.render import SourceError, analyse_video, probe_video, render_plan except ImportError as exc: @@ -276,8 +276,8 @@ def build_parser() -> argparse.ArgumentParser: return parser -def config_from_args(args) -> Eternal2xConfig: - cfg = Eternal2xConfig() +def config_from_args(args) -> Upflow2xConfig: + cfg = Upflow2xConfig() if args.threshold is not None: cfg.duplicate_threshold = args.threshold if args.base_hold: diff --git a/release/upflow2x-mac/VERSION b/release/upflow2x-mac/VERSION index 1d0ba9e..8f0916f 100644 --- a/release/upflow2x-mac/VERSION +++ b/release/upflow2x-mac/VERSION @@ -1 +1 @@ -0.4.0 +0.5.0 diff --git a/release/upflow2x-win/Installer/Eternal2x.lua b/release/upflow2x-win/Installer/Eternal2x.lua index 73fb427..cf02183 100644 --- a/release/upflow2x-win/Installer/Eternal2x.lua +++ b/release/upflow2x-win/Installer/Eternal2x.lua @@ -207,7 +207,7 @@ local STOP_PATH = join_path(REPO_ROOT ~= "" and REPO_ROOT or root, ".eternal2x_s -- The frames marked on the clip go to the stage in this file. A long clip's -- list does not fit on a Windows command line. local MARKS_PATH = join_path(REPO_ROOT ~= "" and REPO_ROOT or root, ".eternal2x_marks.txt") -local LOG_PATH = join_path(REPO_ROOT ~= "" and REPO_ROOT or root, ".eternal2x_last_run.log") +local LOG_PATH = join_path(REPO_ROOT ~= "" and REPO_ROOT or root, ".upflow2x_last_run.log") -- The update check runs each time the panel opens, so it logs apart from -- renders. Sharing a log wiped the render's, the one worth sending in. local UPDATE_LOG_PATH = join_path(REPO_ROOT ~= "" and REPO_ROOT or root, ".eternal2x_update.log") @@ -323,7 +323,7 @@ local function stem_of(path) end -- What a render is called: its folder for a sequence of frames, its file --- name for one file. nil for a path Eternal2x does not write. +-- name for one file. nil for a path Upflow2x does not write. local function render_name(path) return path:match("([^/\\]+)[/\\]frame_[%d%[%]%-]+%.png$") or path:match("([^/\\]+)%.mkv$") or path:match("([^/\\]+)%.mp4$") @@ -459,7 +459,7 @@ local function find_clip_path() if not timeline then return nil, "No timeline is open." end -- Resolve's API has no timeline selection. GetCurrentVideoItem is the clip - -- under the playhead, so that is the one Eternal2x works on. + -- under the playhead, so that is the one Upflow2x works on. local item = nil if timeline.GetCurrentVideoItem then item = timeline:GetCurrentVideoItem() @@ -1130,7 +1130,7 @@ local function refresh_source(keep) return true end --- Eternal2x's own markers carry this, so analysing again replaces them and +-- Upflow2x's own markers carry this, so analysing again replaces them and -- leaves every marker the editor placed. local MARK_TAG = "eternal2x" @@ -1978,7 +1978,7 @@ win:Show() if REPO_ROOT == "" then items.Meta.Text = "Plugin folder not configured." - set_status("Run Installer/install_eternal2x.py, then restart Resolve.") + set_status("Run Installer/install_upflow2x.py, then restart Resolve.") else refresh_source() start_polling() diff --git a/release/upflow2x-win/Installer/Eternal2xLauncher.lua b/release/upflow2x-win/Installer/Eternal2xLauncher.lua index 8436a33..f54a8c1 100644 --- a/release/upflow2x-win/Installer/Eternal2xLauncher.lua +++ b/release/upflow2x-win/Installer/Eternal2xLauncher.lua @@ -50,7 +50,7 @@ local function file_exists(path) return true end --- Where Installer/install_eternal2x.py puts this script, for when Resolve +-- Where Installer/install_upflow2x.py puts this script, for when Resolve -- reports the running script under a path map such as Scripts: that io.open -- cannot follow. local function installed_dir() diff --git a/release/upflow2x-win/Installer/gui_installer.py b/release/upflow2x-win/Installer/gui_installer.py index d6c0080..6ed93de 100644 --- a/release/upflow2x-win/Installer/gui_installer.py +++ b/release/upflow2x-win/Installer/gui_installer.py @@ -28,11 +28,11 @@ # drift. This runs standalone and from a PyInstaller bundle, where the repo # root is not on the path, so fall back to importing the sibling module. try: - from Installer.install_eternal2x import ( + from Installer.install_upflow2x import ( _resolve_scripts_dir, remove_old_install, write_config) except ImportError: # pragma: no cover - depends on how this was launched sys.path.insert(0, str(Path(__file__).resolve().parent)) - from install_eternal2x import ( + from install_upflow2x import ( _resolve_scripts_dir, remove_old_install, write_config) # --------------------------------------------------------------------------- diff --git a/release/upflow2x-win/Installer/install_eternal2x.py b/release/upflow2x-win/Installer/install_upflow2x.py similarity index 100% rename from release/upflow2x-win/Installer/install_eternal2x.py rename to release/upflow2x-win/Installer/install_upflow2x.py diff --git a/release/upflow2x-win/Pipeline/config.py b/release/upflow2x-win/Pipeline/config.py index 6e27772..f7013f6 100644 --- a/release/upflow2x-win/Pipeline/config.py +++ b/release/upflow2x-win/Pipeline/config.py @@ -6,7 +6,7 @@ @dataclass -class Eternal2xConfig: +class Upflow2xConfig: """Everything the pipeline needs, in one place. Defaults are tuned for hand-drawn animation, which is typically drawn on @@ -53,10 +53,10 @@ def to_dict(self) -> dict: return asdict(self) @classmethod - def from_dict(cls, data: dict) -> "Eternal2xConfig": + def from_dict(cls, data: dict) -> "Upflow2xConfig": known = {f for f in cls.__dataclass_fields__} return cls(**{k: v for k, v in (data or {}).items() if k in known}) # Kept so older saved settings and the previous CLI flags still load. -UpscaleConfig = Eternal2xConfig +UpscaleConfig = Upflow2xConfig diff --git a/release/upflow2x-win/Pipeline/render.py b/release/upflow2x-win/Pipeline/render.py index 837aa5c..2aab97e 100644 --- a/release/upflow2x-win/Pipeline/render.py +++ b/release/upflow2x-win/Pipeline/render.py @@ -26,7 +26,7 @@ import cv2 import numpy as np -from Pipeline.config import Eternal2xConfig +from Pipeline.config import Upflow2xConfig from Pipeline.dedupe import DedupePlan, noise_threshold, plan_from_scores, output_time_map from Pipeline.interpolate import frames_are_a_cut, is_a_cut, shot_change, upscale @@ -246,7 +246,7 @@ def _require_constant_rate(cap: _ClipReader, fps: float, path: Path) -> None: def frame_difference_scores( path: Path, - cfg: Eternal2xConfig, + cfg: Upflow2xConfig, *, progress: Optional[ProgressFn] = None, frames: FrameRange = None, @@ -303,7 +303,7 @@ def frame_difference_scores( def analyse_video( path: Path, - cfg: Eternal2xConfig, + cfg: Upflow2xConfig, *, progress: Optional[ProgressFn] = None, frames: FrameRange = None, @@ -407,7 +407,7 @@ def render_plan( source: Path, plan: DedupePlan, output: Path, - cfg: Eternal2xConfig, + cfg: Upflow2xConfig, *, progress: Optional[ProgressFn] = None, sequence: Optional[bool] = None, diff --git a/release/upflow2x-win/README.md b/release/upflow2x-win/README.md index afc31a1..d258583 100644 --- a/release/upflow2x-win/README.md +++ b/release/upflow2x-win/README.md @@ -87,7 +87,7 @@ install below, which does the same job. ``` python -m pip install numpy opencv-python -python Installer/install_eternal2x.py +python Installer/install_upflow2x.py ``` Use `python3` on macOS. The installer records the Python that runs it, so @@ -132,7 +132,7 @@ Markers on the timeline's ruler do not, so beat markers are safe there. You can skip Analyse and mark the frames yourself. A clip with no markers at all is rendered from the drawings Upflow2x finds on its own. -![The Upflow2x panel in DaVinci Resolve Studio after a render. The rebuilt clip sits on V2, lined up above the original on V1.](https://upflow2x.com/assets/demo/resolve.jpg) +![The Upflow2x panel open in DaVinci Resolve Studio, with Hero walk.mp4 on V1 and its render on V2.](https://upflow2x.com/assets/demo/resolve.jpg) The render runs in the background and the panel shows progress and the time left, so Resolve stays usable while it works. **Stop** ends it early. When it finishes, the rebuilt @@ -220,7 +220,7 @@ afterwards. | Problem | Fix | |---|---| | Resolve says you need Studio | Since 19.1 the free edition blocks script panels. Upflow2x needs Studio. | -| Clicking Upflow2x does nothing, or "Plugin folder not configured" | The plugin folder moved after installing, and Workspace → Console says `UI script not found`. Re-run `python Installer/install_eternal2x.py` from where it is now. | +| Clicking Upflow2x does nothing, or "Plugin folder not configured" | The plugin folder moved after installing, and Workspace → Console says `UI script not found`. Re-run `python Installer/install_upflow2x.py` from where it is now. | | "Could not reach Resolve" | Open the panel from Workspace → Scripts, not from a terminal. | | "No clip under the playhead" | Move the playhead over the clip, and the panel picks it up. | | "No duplicate frames. This clip is already on 1s." | The clip has no duplicated frames. It is live action, or already on 1s. | @@ -229,7 +229,7 @@ afterwards. | Progress seems stuck | Press **Refresh Progress**. If Python stopped, the panel says so and shows its last error. If a run was interrupted, press **Reset**. | | Resolve would not import the render | The render still finished. The panel prints where it is, so drag it into your media pool. Switching Output to `Image sequence` usually avoids this. | | Upscale skipped | Without a GPU the upscale is Super Scale, which needs Resolve Studio. | -| Something else | Email the panel's status text and the `.eternal2x_last_run.log` file from the plugin folder. | +| Something else | Email the panel's status text and the `.upflow2x_last_run.log` file from the plugin folder. | ## Development @@ -251,7 +251,7 @@ the environment variables from Blackmagic's scripting README, then run To cut a release, bump `VERSION` and push a matching tag: ``` -git tag v0.3.1 && git push origin v0.3.1 +git tag v0.5.0 && git push origin v0.5.0 ``` The release workflow builds the archives, publishes them, checks the published diff --git a/release/upflow2x-win/Stages/resolve_smooth.py b/release/upflow2x-win/Stages/resolve_smooth.py index b828629..428b88d 100644 --- a/release/upflow2x-win/Stages/resolve_smooth.py +++ b/release/upflow2x-win/Stages/resolve_smooth.py @@ -20,7 +20,7 @@ # able to tell the panel so, or the panel waits on a run that never started. try: from Pipeline import resolve_bridge as bridge - from Pipeline.config import Eternal2xConfig + from Pipeline.config import Upflow2xConfig from Pipeline.dedupe import plan_from_marks from Pipeline.render import SourceError, analyse_video, probe_video, render_plan except ImportError as exc: @@ -276,8 +276,8 @@ def build_parser() -> argparse.ArgumentParser: return parser -def config_from_args(args) -> Eternal2xConfig: - cfg = Eternal2xConfig() +def config_from_args(args) -> Upflow2xConfig: + cfg = Upflow2xConfig() if args.threshold is not None: cfg.duplicate_threshold = args.threshold if args.base_hold: diff --git a/release/upflow2x-win/VERSION b/release/upflow2x-win/VERSION index 1d0ba9e..8f0916f 100644 --- a/release/upflow2x-win/VERSION +++ b/release/upflow2x-win/VERSION @@ -1 +1 @@ -0.4.0 +0.5.0 diff --git a/test.sh b/test.sh index 178e988..0cc184e 100755 --- a/test.sh +++ b/test.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Run the whole Eternal2x test suite without opening DaVinci Resolve. +# Run the whole Upflow2x test suite without opening DaVinci Resolve. # # ./test.sh run everything # ./test.sh -k markers run tests matching an expression diff --git a/tests/README.md b/tests/README.md index 867291f..0fab95d 100644 --- a/tests/README.md +++ b/tests/README.md @@ -1,4 +1,4 @@ -# Eternal2x test suite +# Upflow2x test suite Runs the whole plugin without opening DaVinci Resolve. diff --git a/tests/test_edge_cases.py b/tests/test_edge_cases.py index 3a7240b..0de3eb0 100644 --- a/tests/test_edge_cases.py +++ b/tests/test_edge_cases.py @@ -8,13 +8,13 @@ import numpy as np import pytest -from Pipeline.config import Eternal2xConfig +from Pipeline.config import Upflow2xConfig from Pipeline.dedupe import plan_from_scores from Pipeline.render import SourceError, analyse_video, render_plan def cfg(**kw): - c = Eternal2xConfig(upscale_enabled=False) + c = Upflow2xConfig(upscale_enabled=False) for k, v in kw.items(): setattr(c, k, v) return c diff --git a/tests/test_end_to_end.py b/tests/test_end_to_end.py index 42bddbf..a3b5586 100644 --- a/tests/test_end_to_end.py +++ b/tests/test_end_to_end.py @@ -20,7 +20,7 @@ pytest.importorskip("lupa", reason="lupa provides the Lua runtime") from lupa import LuaRuntime # noqa: E402 -from Installer.install_eternal2x import write_config # noqa: E402 +from Installer.install_upflow2x import write_config # noqa: E402 from tests import fake_rife # noqa: E402 HARNESS = Path(__file__).resolve().parent / "lua_harness.lua" @@ -94,7 +94,7 @@ def finish(H, timeout: float = FINISH_TIMEOUT): time.sleep(0.05) # Say what actually happened, rather than just that time ran out. - log = root / ".eternal2x_last_run.log" + log = root / ".upflow2x_last_run.log" detail = log.read_text(errors="replace")[-2000:] if log.exists() else "(no log written)" raise AssertionError( f"the render did not finish within {timeout}s.\n" diff --git a/tests/test_installer.py b/tests/test_installer.py index 0d80fea..d64bcce 100644 --- a/tests/test_installer.py +++ b/tests/test_installer.py @@ -10,7 +10,7 @@ import pytest -from Installer import install_eternal2x as inst +from Installer import install_upflow2x as inst def read_conf(path: Path) -> dict: @@ -265,7 +265,7 @@ def test_falls_back_to_a_system_interpreter(tmp_path, monkeypatch): @pytest.mark.parametrize("platform", ["win32", "darwin"]) def test_without_a_venv_the_python_running_the_installer_is_used(tmp_path, monkeypatch, platform): - """`py Installer\\install_eternal2x.py` must not record whatever `python` is + """`py Installer\\install_upflow2x.py` must not record whatever `python` is on PATH, which on Windows can be the Microsoft Store stub.""" monkeypatch.setattr(sys, "platform", platform) monkeypatch.setattr(sys, "executable", "/chosen/python3") @@ -336,7 +336,7 @@ def test_reinstall_is_idempotent(fake_home, monkeypatch): assert conf_path.read_text() == first -@pytest.mark.parametrize("module", ["Installer.install_eternal2x", +@pytest.mark.parametrize("module", ["Installer.install_upflow2x", "Installer.gui_installer"]) def test_a_reinstall_keeps_the_users_settings(tmp_path, module): """The panel saves its settings in this file. A reinstall that put back diff --git a/tests/test_lua_ui.py b/tests/test_lua_ui.py index 0f993cb..e2050b3 100644 --- a/tests/test_lua_ui.py +++ b/tests/test_lua_ui.py @@ -392,7 +392,7 @@ def test_the_command_the_panel_builds_actually_runs(lua, direct): cmd = H.last_command() subprocess.run(cmd, shell=True, capture_output=True, text=True) - log = (direct / ".eternal2x_last_run.log") + log = (direct / ".upflow2x_last_run.log") assert log.exists(), "the panel's command produced no log" text = log.read_text() for missing in ("No module named 'Stages'", "No module named 'Pipeline'"): @@ -604,7 +604,7 @@ def test_the_background_command_redirects_into_the_log(lua, direct): H = load(lua, ui_script(direct)) H.click("SmoothBtn") cmd = H.last_command() - assert ".eternal2x_last_run.log" in cmd + assert ".upflow2x_last_run.log" in cmd assert "2>&1" in cmd @@ -1408,7 +1408,7 @@ def test_a_throwing_api_does_not_stop_the_panel_opening(lua, direct): def test_a_run_that_died_without_a_status_is_reported(lua, direct): H = load(lua, ui_script(direct)) H.click("SmoothBtn") - (direct / ".eternal2x_last_run.log").write_text( + (direct / ".upflow2x_last_run.log").write_text( "Traceback (most recent call last):\nModuleNotFoundError: No module named 'cv2'\n") (direct / ".eternal2x_exit").write_text("1\n") H.click("RefreshStatusBtn") @@ -1544,7 +1544,7 @@ def test_opening_the_panel_keeps_the_render_log(lua, direct): H = load(lua, ui_script(direct)) cmd = H.last_command() assert "Stages.resolve_update" in cmd - assert ".eternal2x_update.log" in cmd and ".eternal2x_last_run.log" not in cmd + assert ".eternal2x_update.log" in cmd and ".upflow2x_last_run.log" not in cmd @pytest.mark.parametrize("old", [ diff --git a/tests/test_release_build.py b/tests/test_release_build.py index c818245..9eb472c 100644 --- a/tests/test_release_build.py +++ b/tests/test_release_build.py @@ -120,7 +120,7 @@ def test_the_payload_carries_what_the_plugin_needs(built): "Pipeline/dedupe.py", "Pipeline/interpolate.py", "Pipeline/render.py", "Pipeline/resolve_bridge.py", "Installer/Eternal2x.lua", "Installer/Eternal2xLauncher.lua", - "Installer/install_eternal2x.py", "VERSION", "requirements.txt"): + "Installer/install_upflow2x.py", "VERSION", "requirements.txt"): assert (folder / needed).exists(), f"the release is missing {needed}" diff --git a/tests/test_render.py b/tests/test_render.py index d99a1b4..33e077d 100644 --- a/tests/test_render.py +++ b/tests/test_render.py @@ -5,12 +5,12 @@ import numpy as np import pytest -from Pipeline.config import Eternal2xConfig +from Pipeline.config import Upflow2xConfig from Pipeline.render import SourceError, analyse_video, render_plan -def cfg(**kw) -> Eternal2xConfig: - c = Eternal2xConfig(upscale_enabled=False) +def cfg(**kw) -> Upflow2xConfig: + c = Upflow2xConfig(upscale_enabled=False) for k, v in kw.items(): setattr(c, k, v) return c @@ -633,8 +633,8 @@ def spy(self, a, b, times, **kw): monkeypatch.setattr(rife.Rife, "interpolate_pair", spy) src = make_anime(holds=(30, 2)) - plan, _, _ = analyse_video(src, Eternal2xConfig()) + plan, _, _ = analyse_video(src, Upflow2xConfig()) marked = plan_from_marks([0, 30], plan.source_frames, plan.fps) - result = render_plan(src, marked, tmp_path / "out", Eternal2xConfig(), sequence=True) + result = render_plan(src, marked, tmp_path / "out", Upflow2xConfig(), sequence=True) assert result.frames_written == 32 assert max(asked) <= BATCH and sum(asked) >= 29 diff --git a/tests/test_resolve_update.py b/tests/test_resolve_update.py index 82e7b06..1bcc6c2 100644 --- a/tests/test_resolve_update.py +++ b/tests/test_resolve_update.py @@ -62,7 +62,7 @@ def make_payload_zip(www: Path, name: str, version: str, extra_files=None) -> st zf.writestr("eternal2x/README.md", f"# Eternal2x {version}\n") zf.writestr("eternal2x/Pipeline/config.py", "# updated config\n") zf.writestr("eternal2x/Stages/motion_score.py", "# updated stage\n") - zf.writestr("eternal2x/Installer/install_eternal2x.py", "# updated installer\n") + zf.writestr("eternal2x/Installer/install_upflow2x.py", "# updated installer\n") for rel, content in (extra_files or {}).items(): zf.writestr(f"eternal2x/{rel}", content) return hashlib.sha256(zip_path.read_bytes()).hexdigest() @@ -364,7 +364,7 @@ def test_an_update_that_fails_partway_says_nothing_changed(http_server, repo, mo assert "nothing was changed" in capsys.readouterr().out.strip().splitlines()[-1] assert repo.joinpath("VERSION").read_text().strip() == "0.2.0" assert repo.joinpath("README.md").read_text() == "# old\n" - assert not repo.joinpath("Installer/install_eternal2x.py").exists() + assert not repo.joinpath("Installer/install_upflow2x.py").exists() def test_missing_platform_package_is_reported(http_server, repo, capsys): diff --git a/tests/test_rife.py b/tests/test_rife.py index 49cea8e..a2a2571 100644 --- a/tests/test_rife.py +++ b/tests/test_rife.py @@ -10,7 +10,7 @@ import pytest from Pipeline import rife -from Pipeline.config import Eternal2xConfig +from Pipeline.config import Upflow2xConfig from Pipeline.interpolate import (ALWAYS_A_CUT, PALETTE_CUT, UNRELATED_DISAGREEMENT, frames_are_a_cut, frames_are_unrelated, is_a_cut, palette_change, shot_change) @@ -358,9 +358,9 @@ def interpolate_pair(self, a, b, times, **_): monkeypatch.setattr(rife, "Rife", Shrinking) src = make_anime(holds=(2,) * 6) - plan, _, _ = analyse_video(src, Eternal2xConfig()) + plan, _, _ = analyse_video(src, Upflow2xConfig()) with pytest.raises(SourceError, match="came out"): - render_plan(src, plan, tmp_path / "out.mkv", Eternal2xConfig()) + render_plan(src, plan, tmp_path / "out.mkv", Upflow2xConfig()) def test_the_runtime_is_installed_into_this_python(monkeypatch): @@ -464,14 +464,14 @@ def interpolate_pair(self, a, b, times, **_): def test_the_network_draws_the_in_betweens(monkeypatch, make_anime, tmp_path, read_frames): monkeypatch.setattr(rife, "Rife", _FakeRife) src = make_anime(holds=(2,) * 6) - plan, _, _ = analyse_video(src, Eternal2xConfig()) + plan, _, _ = analyse_video(src, Upflow2xConfig()) _FakeRife.made = 0 - out = read_frames(render_plan(src, plan, tmp_path / "ai.avi", Eternal2xConfig()).output) + out = read_frames(render_plan(src, plan, tmp_path / "ai.avi", Upflow2xConfig()).output) assert _FakeRife.made == 1, "the model should load once per render" assert any(np.all(f == 77) for f in out), "the network's in-betweens were not used" - render_plan(src, plan, tmp_path / "off.avi", Eternal2xConfig(interpolate_enabled=False)) + render_plan(src, plan, tmp_path / "off.avi", Upflow2xConfig(interpolate_enabled=False)) assert _FakeRife.made == 1, "Interpolate off still loaded the network" @@ -484,9 +484,9 @@ def broken(progress=None): monkeypatch.setattr(rife, "Rife", broken) src = make_anime(holds=(2,) * 6) - plan, _, _ = analyse_video(src, Eternal2xConfig()) - smooth = render_plan(src, plan, tmp_path / "out", Eternal2xConfig(), sequence=True) - plain = render_plan(src, plan, tmp_path / "plain", Eternal2xConfig(interpolate_enabled=False), + plan, _, _ = analyse_video(src, Upflow2xConfig()) + smooth = render_plan(src, plan, tmp_path / "out", Upflow2xConfig(), sequence=True) + plain = render_plan(src, plan, tmp_path / "plain", Upflow2xConfig(interpolate_enabled=False), sequence=True) assert "kept as drawn" in smooth.note and "offline" in smooth.note assert all(np.array_equal(x, y) for x, y in zip(read_frames(smooth.output), diff --git a/tests/test_upscaler.py b/tests/test_upscaler.py index 09f212b..b6a9977 100644 --- a/tests/test_upscaler.py +++ b/tests/test_upscaler.py @@ -11,7 +11,7 @@ import pytest from Pipeline import upscaler -from Pipeline.config import Eternal2xConfig +from Pipeline.config import Upflow2xConfig from Pipeline.render import SourceError, analyse_video, render_plan from Pipeline.rife import AIUnavailable from tests.drawings import cel @@ -176,8 +176,8 @@ def twice_as_big(monkeypatch): def _render(make_anime, tmp_path, **cfg): src = make_anime(holds=(2,) * 6) - plan, _, _ = analyse_video(src, Eternal2xConfig()) - return render_plan(src, plan, tmp_path / "out", Eternal2xConfig(**cfg), sequence=True) + plan, _, _ = analyse_video(src, Upflow2xConfig()) + return render_plan(src, plan, tmp_path / "out", Upflow2xConfig(**cfg), sequence=True) def test_the_render_comes_out_at_2x(twice_as_big, make_anime, tmp_path, read_frames): @@ -191,7 +191,7 @@ def test_the_network_and_lanczos_never_both_scale(twice_as_big, monkeypatch, mak tmp_path): """Lanczos is on by default, and on top of the network it made 4x. Where the network cannot run, the render stays 1x for Super Scale.""" - assert Eternal2xConfig().upscale_enabled + assert Upflow2xConfig().upscale_enabled assert _render(make_anime, tmp_path / "a", network_upscale=True).width == 400 def no_gpu(progress=None): @@ -223,8 +223,8 @@ def upscale(self, frame): monkeypatch.setattr(upscaler, "Upscaler", GivesOut) stages = [] src = make_anime(holds=(2,) * 6) - plan, _, _ = analyse_video(src, Eternal2xConfig()) - render_plan(src, plan, tmp_path / "out", Eternal2xConfig(network_upscale=True, + plan, _, _ = analyse_video(src, Upflow2xConfig()) + render_plan(src, plan, tmp_path / "out", Upflow2xConfig(network_upscale=True, upscale_enabled=False), sequence=True, progress=lambda stage, fraction: stages.append(stage)) assert stages[:3] == ["Interpolating and upscaling"] * 3 @@ -235,8 +235,8 @@ def test_an_upscale_alone_says_upscaling(monkeypatch, make_anime, tmp_path): monkeypatch.setattr(upscaler, "Upscaler", _TwiceAsBig) stages = [] src = make_anime(holds=(2,) * 6) - plan, _, _ = analyse_video(src, Eternal2xConfig()) - render_plan(src, plan, tmp_path / "out", Eternal2xConfig(network_upscale=True, + plan, _, _ = analyse_video(src, Upflow2xConfig()) + render_plan(src, plan, tmp_path / "out", Upflow2xConfig(network_upscale=True, upscale_enabled=False, interpolate_enabled=False), sequence=True, progress=lambda stage, fraction: stages.append(stage)) assert set(stages) == {"Upscaling"}