diff --git a/tools/chatgui/build.sh b/tools/chatgui/build.sh index fcd17d75..0e4fc41b 100755 --- a/tools/chatgui/build.sh +++ b/tools/chatgui/build.sh @@ -50,6 +50,12 @@ fi source "$SRC_DIR/compiler_runtime.sh" if [ "${MSYSTEM:-}" = UCRT64 ]; then chatgui_refresh_compiler_runtime "$BUILD_DIR" "$RUNTIME_PREFIX/bin" 2>&1 | tee -a "$LOG_FILE" + if [ -f "$SRC_DIR/ffmpeg/ffmpeg_build/install/lib/pkgconfig/libavcodec.pc" ]; then + log "Checking bundled FFmpeg profile (including MJPEG video previews)..." + bash "$SRC_DIR/ffmpeg/build_ffmpeg.sh" 2>&1 | tee -a "$LOG_FILE" || { + log " ERROR: bundled FFmpeg profile update failed"; exit 1; + } + fi log "Preparing bundled rlottie..." cmake -S "$SRC_DIR/rlottie_src" -B "$SRC_DIR/rlottie_build" -G Ninja \ -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON 2>&1 | tee -a "$LOG_FILE" || { diff --git a/tools/chatgui/ffmpeg/build_ffmpeg.sh b/tools/chatgui/ffmpeg/build_ffmpeg.sh index b97e3c01..8a75f9b4 100755 --- a/tools/chatgui/ffmpeg/build_ffmpeg.sh +++ b/tools/chatgui/ffmpeg/build_ffmpeg.sh @@ -7,7 +7,7 @@ SRC_DIR="$BUILD_DIR/src" INSTALL_DIR="$BUILD_DIR/install" JOBS=$(nproc 2>/dev/null || echo 4) AMF_HEADERS_VERSION="${AMF_HEADERS_VERSION:-1.5.3}" -FFMPEG_PROFILE_MARKER="$INSTALL_DIR/share/utun-chatgui-ffmpeg-minimal-v6" +FFMPEG_PROFILE_MARKER="$INSTALL_DIR/share/utun-chatgui-ffmpeg-minimal-v7" case "$(uname -s)" in Linux) PLATFORM=linux ;; @@ -264,7 +264,7 @@ fi DECODERS=(h264 hevc av1 vp8 vp9 mpeg4 mpeg2video mpeg1video mjpeg h263 msmpeg4v3 wmv1 wmv2 vc1 aac mp3 opus vorbis flac ac3 eac3 alac wmav1 wmav2 pcm_s16le pcm_s24le pcm_s32le pcm_u8 pcm_f32le) -ENCODERS=(libx264 libx265 libvpx_vp9 libaom_av1 h264_nvenc hevc_nvenc av1_nvenc +ENCODERS=(mjpeg libx264 libx265 libvpx_vp9 libaom_av1 h264_nvenc hevc_nvenc av1_nvenc h264_qsv hevc_qsv vp9_qsv av1_qsv) for decoder in "${DECODERS[@]}"; do CONFIGURE_ARGS+=("--enable-decoder=$decoder"); done @@ -291,6 +291,8 @@ fi grep -Eq '^#define CONFIG_CBS_H265 1$' config.h || die "FFmpeg configure did not enable the HEVC header parser" grep -Eq '^#define CONFIG_TRACE_HEADERS_BSF 1$' config_components.h || die "FFmpeg configure did not enable trace_headers" +grep -Eq '^#define CONFIG_MJPEG_ENCODER 1$' config_components.h || die "FFmpeg configure did not enable MJPEG encoder required for video previews" +log "MJPEG encoder enabled for first-frame JPEG previews" if [ "$PLATFORM" = "windows" ]; then grep -Eq '^#define CONFIG_H264_D3D11VA_HWACCEL 1$' config_components.h || die "H.264 D3D11VA implementation object unavailable" grep -Eq '^#define CONFIG_HEVC_D3D11VA_HWACCEL 1$' config_components.h || die "HEVC D3D11VA implementation object unavailable" diff --git a/tools/chatgui/tests/test_windows_installer.py b/tools/chatgui/tests/test_windows_installer.py index 418f02d9..3c85d13b 100644 --- a/tools/chatgui/tests/test_windows_installer.py +++ b/tools/chatgui/tests/test_windows_installer.py @@ -223,6 +223,14 @@ printf '%s\\n' "$*" >> "$CMAKE_CALLS" original_exe += f'DLL Name: {name}\n' write(build / 'vibechat.exe', original_exe) calls = root / 'cmake-calls.log' + ffmpeg_calls = root / 'ffmpeg-calls.log' + write(gui / 'ffmpeg/ffmpeg_build/install/lib/pkgconfig/libavcodec.pc', 'fixture FFmpeg\n') + write(gui / 'ffmpeg/build_ffmpeg.sh', '''#!/bin/bash +set -eu +printf 'profile update\\n' >> "$FFMPEG_CALLS" +if [[ ${FFMPEG_FAIL:-0} = 1 ]]; then exit 1; fi +''') + environment['FFMPEG_CALLS'] = str(ffmpeg_calls) (build / 'wintun.dll').unlink() built = subprocess.run(['bash', str(gui / 'build.sh'), '--installer', '-j2'], cwd=gui, env={**environment, 'CMAKE_CALLS': str(calls)}, text=True, capture_output=True) @@ -230,6 +238,13 @@ printf '%s\\n' "$*" >> "$CMAKE_CALLS" assert '-DCMAKE_BUILD_TYPE=Release' in calls.read_text() assert 'installer created:' in built.stdout and 'Build SUCCESS' in built.stdout assert (build / 'wintun.dll').read_bytes() == (case / 'lib/wintun.dll').read_bytes() + assert ffmpeg_calls.read_text().splitlines() == ['profile update'] + cmake_before_failure = calls.read_text() + codec_failed = subprocess.run(['bash', str(gui / 'build.sh'), '--installer', '-j2'], cwd=gui, + env={**environment, 'CMAKE_CALLS': str(calls), 'FFMPEG_FAIL': '1'}, text=True, capture_output=True) + assert codec_failed.returncode != 0 and 'bundled FFmpeg profile update failed' in codec_failed.stdout + assert calls.read_text() == cmake_before_failure, 'CMake ran after a failed FFmpeg profile update' + print('PASS: Windows GUI build updates bundled FFmpeg before CMake and stops on update failure') failed = subprocess.run(['bash', str(gui / 'build.sh'), '--installer'], cwd=gui, env={**environment, 'CMAKE_CALLS': str(calls), 'COMPILER_FAIL': '1'}, text=True, capture_output=True) assert failed.returncode != 0 and 'Build SUCCESS' not in failed.stdout