The Chocolatey and WinGet publish workflows triggered on
release: [released], which fires simultaneously with the release
build. Since MSIs take ~45 minutes to build, the publish workflows
failed with 404 errors.
Switch both to workflow_run trigger so they wait for the "Upload
releases" workflow to complete before attempting to publish.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The CCExtractor/sample-platform test runner does exact string matching
on artifact names to find builds for testing. If these names are changed
without updating Artifact_names in sample-platform, CI tests silently
stop running.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The lazy OCR initialization in write_dvb_sub() ran on the prev decoder
context, which is destroyed and recreated every frame. Each frame
therefore allocated a new Tesseract instance (~15-30 MB for language
models) that was never freed — plain free() on the DVBSubContext struct
does not call delete_ocr() on the embedded OCR pointer.
Move the lazy init to dvbsub_handle_display_segment() on the main
(non-prev) context, before it is memcpy'd into prev. This way:
- Tesseract is initialized exactly once (on first subtitle frame)
- All prev copies inherit the same OCR pointer via memcpy
- The single instance is properly freed in dvbsub_close_decoder()
For a 2-hour film with dense subtitles this reduces peak memory from
~28 GB to ~50 MB.
Fixes#2114
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
After memcpy, the copy shares all pointers with the original context.
The function NULLs out pointers it will deep-copy, but missed two:
- dtvcc_rust: Rust-allocated opaque pointer freed via ccxr_dtvcc_free()
in dinit_cc_decode(). The copy must not hold this pointer since
free_decoder_context() doesn't know about Rust allocations, and having
two contexts point to the same Rust object causes use-after-free.
- prev: linked-list pointer to the previous decoder context. The copy
should not inherit this link as it creates a corrupted list where
multiple contexts share the same predecessor.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
$(VCToolsRedistDir) resolves to empty in MSBuild's PostBuildEvent
context, so the xcopy commands silently fail with "File not found".
Switch to %VCToolsRedistDir% (batch environment variable syntax) which
is expanded by cmd.exe at runtime, where the variable is set by the
MSVC developer environment.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The committed DLLs in windows/dll/ are x86-64 only, causing the Win32
build to ship 64-bit vcruntime140.dll alongside a 32-bit exe. This made
ccextractor silently fail on 32-bit Windows (reported in #2116).
Source vcruntime DLLs from $(VCToolsRedistDir) instead, which provides
the correct architecture (x86 or x64) matching the build target.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
upload-artifact rejects '.' in paths. Use "x64/" and "" instead so
paths resolve to ./windows/x64/Release-Full and ./windows/Release-Full.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
MSBuild places Win32 output in windows/Release-Full/ (no platform
prefix), while x64 goes to windows/x64/Release-Full/. Use matrix
outdir variable to reference the correct output location.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
On 64-bit Windows, choco install gpac --forcex86 installs to
C:\Program Files (x86)\GPAC, not C:\Program Files\GPAC.
- Add configurable GpacDir MSBuild property (defaults to C:\Program Files\GPAC)
- Replace all hardcoded GPAC paths with $(GpacDir)
- Pass correct GpacDir from CI matrix for x86 builds
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Re-introduce Win32 platform configurations to support 32-bit Windows,
which was dropped in 2023. This enables CCExtractor to run on 32-bit
Windows 10 systems.
Changes:
- Add Win32 (x86) platform to VS solution and project configs
- Make vcpkg triplet conditional (x86-windows-static for Win32)
- Update rust.bat to support i686-pc-windows-msvc via RUST_TARGET env var
- Add preprocessor conditional in installer.wxs for ProgramFilesFolder
- Convert CI build workflow to matrix strategy (x64 + x86)
- Update release workflow to produce both x64 and x86 installers
Closes#2116
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
save_sub_track() was missing two things:
1. No check on the return value of open(). If open() failed,
desc would be -1, and the subsequent write_wrapped() calls
would trigger a fatal error with a confusing message.
2. The file descriptor was never closed at the end of the function,
leaking it on every call. The neighboring save_vobsub_track()
already handles both correctly — this brings save_sub_track()
in line with it.
In save_sub_track(), the length argument for writing timestamp_end
was incorrectly using strlen(timestamp_start) instead of
strlen(timestamp_end). This affected WebVTT, SRT, and ASS/SSA
output paths for Matroska subtitle extraction.