diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b3b21b7a14ecf..6318ad91cfa57 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,6 +6,8 @@ on: - master - ci - 'release/**' + tags: + - 'v0.*' paths-ignore: - 'DOCS/**' - 'TOOLS/lua/**' @@ -129,6 +131,66 @@ jobs: path: ${{ env.CCACHE_DIR }} key: ${{ env.TARGET }}-${{ steps.get_time.outputs.timestamp }} + mingw64-full: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + target: [win64, winarm64] + variant: [gpl, lgpl] + container: + image: ghcr.io/btbn/ffmpeg-builds/${{ matrix.target }}-${{ matrix.variant }}:latest + env: + WINEPREFIX: /tmp/wine + steps: + - uses: actions/checkout@v7 + + - name: Build + id: build + run: | + ./ci/build-mingw64-full.sh + + - name: Print meson log + if: ${{ failure() && steps.build.outcome == 'failure' }} + run: | + cat ./build/meson-logs/meson-log.txt + + - name: Functional test + if: ${{ matrix.target == 'win64' }} + run: | + cd artifact && wine ./mpv.com -v --no-config + + - name: Run meson tests + if: ${{ matrix.target == 'win64' }} + id: tests + run: | + meson test -C build + + - name: Print meson test log + if: ${{ failure() && steps.tests.outcome == 'failure' }} + run: | + cat ./build/meson-logs/testlog.txt + + - name: Artifact name + id: artifact + run: | + VERSION_FILE=$(find . -path "*/common/version.h" -type f | head -n 1) + VER=$(grep VERSION "$VERSION_FILE" | cut -d'"' -f2) + PR=${{ github.event.pull_request.number && format('-pr{0}', github.event.pull_request.number) || '' }} + echo "mpv=mpv-$VER$PR-${{ github.run_id }}-$FFBUILD_TOOLCHAIN-full" >> "$GITHUB_OUTPUT" + echo "libmpv=libmpv-$VER$PR-${{ github.run_id }}-$FFBUILD_TOOLCHAIN-${{ matrix.variant }}" >> "$GITHUB_OUTPUT" + + - uses: actions/upload-artifact@v7 + if: ${{ matrix.variant == 'gpl' }} + with: + name: ${{ steps.artifact.outputs.mpv }} + path: artifact/* + + - uses: actions/upload-artifact@v7 + with: + name: ${{ steps.artifact.outputs.libmpv }} + path: artifact-libmpv/* + win32: runs-on: ${{ matrix.os }} strategy: @@ -729,108 +791,26 @@ jobs: cat ./build/meson-logs/testlog.txt publish: - name: Publish git release - needs: [mingw, win32, macos] - if: github.event_name == 'push' && github.ref == 'refs/heads/master' && - github.repository == 'mpv-player/mpv' + name: Publish release + needs: [mingw, mingw64-full, win32, macos] + if: github.event_name == 'push' && github.repository == 'mpv-player/mpv' && + (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/v0.')) runs-on: ubuntu-slim permissions: contents: write actions: read concurrency: - group: publish-git + group: publish cancel-in-progress: false steps: - uses: actions/checkout@v7 with: fetch-depth: 0 + fetch-tags: true - - name: Publish to git release + - name: Publish env: GH_REPO: ${{ github.repository }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - set -eu - tag=git-release - base_url="https://github.com/$GH_REPO/releases/download/$tag" - - artifacts=$(gh api "repos/{owner}/{repo}/actions/runs/${{ github.run_id }}/artifacts") - - # Attach every build artifact unchanged; the notes link to them with - # labels derived from the verbose names. - mkdir -p release - jq -r '.artifacts[] | "\(.id)\t\(.name)"' <<< "$artifacts" | - while IFS=$'\t' read -r id name; do - gh api "repos/{owner}/{repo}/actions/artifacts/$id/zip" > "release/$name.zip" - done - - section() { - jq -r --arg url "$base_url" --arg re "$1" ' - def pretty: - (if test("i686") then "i686" - elif test("aarch64") then "arm64" - elif test("-arm$") then "arm64" - elif test("intel") then "x86_64" - else "x86_64" end) as $arch - | [ (if test("mingw") then "GCC" elif test("msvc") then "Clang" else empty end), - (if test("macos") then "macOS " + capture("macos-(?[0-9]+)").v else empty end), - (if test("-pdb") then "debug symbols" else empty end) ] as $q - | $arch + (if ($q | length) > 0 then " (" + ($q | join(", ")) + ")" else "" end); - # primary builds first (x86_64, arm64, i686; Clang before GCC), debug symbols last - def rank: - [ (if test("-pdb") then 1 else 0 end), - (if test("x86_64|intel") then 0 elif test("i686") then 2 else 1 end), - (if test("mingw") then 1 else 0 end), - (if test("macos") then (capture("macos-(?[0-9]+)").v | tonumber) else 0 end) ]; - [ .artifacts[] | select(.name | test($re)) ] | sort_by(.name | rank) - | map("* [\(.name | pretty)](\($url)/\(.name).zip)") | join("\n") - ' <<< "$artifacts" - } - - # Match the version string baked into the build (see common/meson.build). - version=$(git describe --abbrev=9 --tags --dirty --match "v0.*") - notes=$(cat < [!WARNING] - > These are untested development builds of the very latest \`master\`. - > They are **not** official releases. For stable builds see the - > [latest release](https://github.com/$GH_REPO/releases/latest). - EOF - ) - - # Create the release once (which also creates the tag), then only edit - # it in place so watchers aren't notified on every master push. Stale - # assets are dropped first since their names embed the run id. - if gh release view "$tag" >/dev/null 2>&1; then - gh release view "$tag" --json assets --jq '.assets[].name' | - while read -r asset; do - gh release delete-asset "$tag" "$asset" --yes - done - gh release edit "$tag" \ - --prerelease \ - --latest=false \ - --title "mpv development build" \ - --notes "$notes" - gh release upload "$tag" release/* - else - gh release create "$tag" \ - --target "$GITHUB_SHA" \ - --prerelease \ - --latest=false \ - --title "mpv development build" \ - --notes "$notes" \ - release/* - fi + ./ci/publish-release.sh diff --git a/DOCS/compile-windows.md b/DOCS/compile-windows.md index 705271ecc8718..a53de28bc1564 100644 --- a/DOCS/compile-windows.md +++ b/DOCS/compile-windows.md @@ -30,6 +30,16 @@ cross-compiling environment. For a basic example, please refer to Alternatively, consider using [mpv-winbuild-cmake](https://github.com/shinchiro/mpv-winbuild-cmake), which bootstraps a MinGW-w64 toolchain and builds mpv along with its dependencies. +The full Windows builds on the [release page](https://github.com/mpv-player/mpv/releases) +are cross-compiled in the [FFmpeg-Builds](https://github.com/BtbN/FFmpeg-Builds) +container images, which provide a toolchain and all dependencies as static +libraries. [ci/build-mingw64-full.sh](https://github.com/mpv-player/mpv/blob/master/ci/build-mingw64-full.sh) +reproduces such a build from the mpv source tree: + +``` bash +docker run --rm -v "$PWD:/mpv" -w /mpv ghcr.io/btbn/ffmpeg-builds/win64-gpl:latest ./ci/build-mingw64-full.sh +``` + ### Example with Meson 1. Create ``cross-file.txt`` with definitions for your toolchain and target platform. diff --git a/audio/out/ao_lavc.c b/audio/out/ao_lavc.c index 4bba27de3a3b1..0771062d167e6 100644 --- a/audio/out/ao_lavc.c +++ b/audio/out/ao_lavc.c @@ -98,7 +98,7 @@ static int init(struct ao *ao) { struct priv *ac = ao->priv; - ac->enc = encoder_context_alloc(ao->encode_lavc_ctx, STREAM_AUDIO, ao->log); + ac->enc = mp_encoder_context_alloc(ao->encode_lavc_ctx, STREAM_AUDIO, ao->log); if (!ac->enc) return -1; talloc_steal(ac, ac->enc); @@ -137,10 +137,10 @@ static int init(struct ao *ao) encoder->sample_fmt = af_to_avformat(ao->format); encoder->bits_per_raw_sample = ac->sample_size * 8; - if (!encoder_init_codec_and_muxer(ac->enc)) + if (!mp_encoder_init_codec_and_muxer(ac->enc)) goto fail; - ac->worst_time_base = encoder_get_mux_timebase_unlocked(ac->enc); + ac->worst_time_base = mp_encoder_get_mux_timebase_unlocked(ac->enc); ac->pcmhack = 0; if (encoder->frame_size <= 1) ac->pcmhack = av_get_bits_per_sample(encoder->codec_id) / 8; @@ -183,7 +183,7 @@ static void uninit(struct ao *ao) if (!ac->shutdown) { if (!write_frame(ao, MP_EOF_FRAME)) MP_WARN(ao, "could not flush last frame\n"); - encoder_encode(ac->enc, NULL); + mp_encoder_encode(ac->enc, NULL); } talloc_free(ac->filter_root); @@ -217,7 +217,7 @@ static void encode(struct ao *ao, struct mp_aframe *af) ac->lastpts = frame_pts; frame->quality = encoder->global_quality; - encoder_encode(ac->enc, frame); + mp_encoder_encode(ac->enc, frame); av_frame_free(&frame); } diff --git a/ci/build-mingw64-full.sh b/ci/build-mingw64-full.sh new file mode 100755 index 0000000000000..eaace16c060bd --- /dev/null +++ b/ci/build-mingw64-full.sh @@ -0,0 +1,128 @@ +#!/usr/bin/env bash +# +# Static mpv and libmpv builds on top of the FFmpeg-Builds container images +# (ghcr.io/btbn/ffmpeg-builds/-, see +# https://github.com/BtbN/FFmpeg-Builds). The image ships the cross toolchain, +# a matching /cross.meson and every FFmpeg dependency as static library in +# $FFBUILD_PREFIX, so only FFmpeg itself and the things FFmpeg does not need +# are built here. Run it from the mpv source tree inside the container: +# +# docker run --rm -v "$PWD:/mpv" -w /mpv \ +# ghcr.io/btbn/ffmpeg-builds/win64-gpl:latest ./ci/build-mingw64-full.sh +# +# The mpv binaries end up in artifact/, the libmpv package in artifact-libmpv/. +set -euo pipefail + +: "${FFBUILD_PREFIX:?not running in a FFmpeg-Builds image}" +: "${VARIANT:?not running in a FFmpeg-Builds image}" + +. ./ci/build-common.sh + +# The dependency headers are not ours to fix, keep --werror to mpv's own code. +CFLAGS="${CFLAGS/-I${FFBUILD_PREFIX}\/include/-isystem${FFBUILD_PREFIX}/include}" +CXXFLAGS="${CXXFLAGS/-I${FFBUILD_PREFIX}\/include/-isystem${FFBUILD_PREFIX}/include}" + +gpl=false +[[ $VARIANT == gpl* ]] && gpl=true + +gitclone="git clone --depth=1 --recursive --shallow-submodules" +group() { echo "::group::$1"; } +endgroup() { echo "::endgroup::"; } + +group "Building FFmpeg" +$gitclone https://github.com/FFmpeg/FFmpeg.git ffmpeg +pushd ffmpeg +# rav1e and librsvg bring their own Rust runtime, which clashes with subrandr's. +./configure --prefix="$FFBUILD_PREFIX" --pkg-config-flags="--static" \ + $FFBUILD_TARGET_FLAGS $FF_CONFIGURE \ + --extra-cflags="$FF_CFLAGS" --extra-cxxflags="$FF_CXXFLAGS" \ + --extra-libs="$FF_LIBS" --extra-ldflags="$FF_LDFLAGS" \ + --extra-ldexeflags="$FF_LDEXEFLAGS" \ + --cc="$CC" --cxx="$CXX" --ar="$AR" --ranlib="$RANLIB" --nm="$NM" \ + --enable-static --disable-shared --disable-{doc,programs} \ + --disable-{librav1e,librsvg,openal} || { cat ffbuild/config.log; exit 1; } +make -j"$(nproc)" +make install +popd +endgroup + +group "Building LuaJIT" +$gitclone -b v2.1 https://github.com/LuaJIT/LuaJIT.git +pushd LuaJIT +# Strip -ldl, not needed for Windows. +sed -i "/^Libs\.private/d" etc/luajit.pc +# FILE_T and INSTALL_DEP are only needed to glue install target. +make TARGET_SYS=Windows PREFIX="$FFBUILD_PREFIX" HOST_CC="$HOST_CC" \ + CFLAGS="$HOST_CFLAGS" CROSS="$FFBUILD_CROSS_PREFIX" TARGET_CFLAGS="$CFLAGS" \ + BUILDMODE=static XCFLAGS=-DLUAJIT_ENABLE_LUA52COMPAT FILE_T=luajit.exe \ + INSTALL_DEP=src/luajit.exe amalg install +popd +endgroup + +group "Building subrandr" +build_subrandr "$FFBUILD_PREFIX" --target "$FFBUILD_RUST_TARGET" \ + --static-library true --shared-library false +endgroup + +group "Building cppwinrt" +# win32-smtc needs the C++/WinRT projection headers, generated from the +# Windows metadata that windows-rs carries. +cppwinrt_ver=2.0.250303.1 +windows_rs_ver=73 +wget -q "https://github.com/microsoft/cppwinrt/archive/${cppwinrt_ver}.tar.gz" -O - | tar -xz +git clone --depth=1 --filter=blob:none --sparse -b "$windows_rs_ver" \ + https://github.com/microsoft/windows-rs.git +git -C windows-rs sparse-checkout set crates/libs/bindgen/default +mkdir -p "cppwinrt-$cppwinrt_ver/build" +pushd "cppwinrt-$cppwinrt_ver/build" +CFLAGS="$HOST_CFLAGS" CXXFLAGS="$HOST_CXXFLAGS" LDFLAGS= \ + cmake -GNinja -DCMAKE_CXX_COMPILER="$HOST_CXX" -DCMAKE_BUILD_TYPE=Release \ + -DCPPWINRT_BUILD_VERSION="$cppwinrt_ver" .. +ninja cppwinrt +./cppwinrt -input ../../windows-rs/crates/libs/bindgen/default \ + -output "$FFBUILD_PREFIX/include" +popd +endgroup + +group "Building mpv" +mkdir -p subprojects +meson wrap install mujs +meson subprojects download + +mpv_args=( + --cross-file /cross.meson $common_args + --buildtype=release + --prefer-static + --default-library=shared + -Dc_link_args="$FF_LIBS" + -Dcpp_link_args="$FF_LIBS" + -Dgpl=$gpl + --force-fallback-for=mujs + -Dmujs:werror=false + -Dmujs:default_library=static + -Dlua=luajit + -D{amf,d3d11,javascript,lcms2,libbluray,libcurl,shaderc,spirv-cross}=enabled + -D{subrandr,vulkan,win32-smtc,zimg}=enabled +) +if $gpl; then + # Only the GPL image carries the dependencies of the GPL features. + mpv_args+=(-D{dvda,dvdnav,rubberband}=enabled) +fi +meson setup build "${mpv_args[@]}" +meson compile -C build +endgroup + +group "Packaging" +license=LICENSE.LGPL +if $gpl; then + license=LICENSE.GPL +fi +mkdir -p artifact artifact-libmpv/include/mpv +cp -p build/mpv.{exe,com} etc/mpv-*.bat "$license" artifact/ +cp -p build/libmpv*.dll build/libmpv*.dll.a "$license" artifact-libmpv/ +cp -p include/mpv/*.h artifact-libmpv/include/mpv/ +cp -p "$FFBUILD_PREFIX"/share/java/libbluray-*.jar artifact/ +cp -p "$FFBUILD_PREFIX"/share/java/libbluray-*.jar artifact-libmpv/ +"${FFBUILD_CROSS_PREFIX}strip" artifact/mpv.{exe,com} artifact-libmpv/libmpv*.dll +ls -l artifact artifact-libmpv +endgroup diff --git a/ci/publish-release.sh b/ci/publish-release.sh new file mode 100755 index 0000000000000..22bee115788ba --- /dev/null +++ b/ci/publish-release.sh @@ -0,0 +1,134 @@ +#!/usr/bin/env bash +# +# Attaches the artifacts of the current workflow run to a GitHub release. +# A push to master updates the rolling "git-release" pre-release along with +# its notes. A pushed release tag gets the assets attached to its release, +# which is created as a draft when it does not exist yet, so the notes can be +# filled in before publishing. +# +# Needs GH_REPO and GH_TOKEN on top of the GITHUB_* variables of the run. +set -euo pipefail + +artifacts=$(gh api "repos/{owner}/{repo}/actions/runs/$GITHUB_RUN_ID/artifacts") + +# Only the builds people are meant to download are published, the other +# artifacts exist for CI coverage. +windows='mingw32-full|i686-w64-mingw32|windows-msvc' +published="$windows|macos-|^libmpv-" + +if [[ $GITHUB_REF == refs/tags/* ]]; then + tag=$GITHUB_REF_NAME + # Release assets carry the version only, the run id is CI bookkeeping. + strip="-$GITHUB_RUN_ID" +else + tag=git-release + strip= +fi + +mkdir -p release +jq -r --arg re "$published" ' + .artifacts[] | select(.name | test($re)) | "\(.id)\t\(.name)" +' <<< "$artifacts" | +while IFS=$'\t' read -r id name; do + gh api "repos/{owner}/{repo}/actions/artifacts/$id/zip" > "release/${name/$strip/}.zip" +done + +if [[ $tag != git-release ]]; then + if gh release view "$tag" >/dev/null 2>&1; then + gh release upload "$tag" --clobber release/* + else + gh release create "$tag" --draft --title "$tag" --notes-file RELEASE_NOTES release/* + fi + exit 0 +fi + +base_url="https://github.com/$GH_REPO/releases/download/$tag" + +section() { + jq -r --arg url "$base_url" --arg re "$1" ' + def pretty: + (if test("i686") then "i686" + elif test("aarch64") then "arm64" + elif test("-arm$") then "arm64" + else "x86_64" end) as $arch + | [ (if test("mingw32-full") then "full" + elif test("mingw32$") then "GCC" + elif test("windows-msvc") then "Clang" + elif test("-lgpl$") then "LGPL" + elif test("-gpl$") then "GPL" + else empty end), + (if test("macos") then "macOS " + capture("macos-(?[0-9]+)").v else empty end), + (if test("-pdb$") then "debug symbols" else empty end) ] as $q + | $arch + (if ($q | length) > 0 then " (" + ($q | join(", ")) + ")" else "" end); + # x86_64, arm64, i686 in that order, full before Clang, GPL before LGPL, + # debug symbols last + def rank: + [ (if test("-pdb$") then 1 else 0 end), + (if test("x86_64|intel") then 0 elif test("i686") then 2 else 1 end), + (if test("windows-msvc|-lgpl$") then 1 else 0 end), + (if test("macos") then (capture("macos-(?[0-9]+)").v | tonumber) else 0 end) ]; + [ .artifacts[] | select(.name | test($re)) ] | sort_by(.name | rank) + | map("* [\(.name | pretty)](\($url)/\(.name).zip)") | join("\n") + ' <<< "$artifacts" +} + +# Match the version string baked into the build (see common/meson.build). +version=$(git describe --abbrev=9 --tags --dirty --match "v0.*") +notes=$(cat < [!WARNING] +> These are untested development builds of the very latest \`master\`. +> They are **not** official releases. For stable builds see the +> [latest release](https://github.com/$GH_REPO/releases/latest). +NOTES +) + +# Create the release once (which also creates the tag), then only edit it in +# place so watchers aren't notified on every master push. Stale assets are +# dropped first since their names embed the run id. +if gh release view "$tag" >/dev/null 2>&1; then + gh release view "$tag" --json assets --jq '.assets[].name' | + while read -r asset; do + gh release delete-asset "$tag" "$asset" --yes + done + gh release edit "$tag" \ + --prerelease \ + --latest=false \ + --title "mpv development build" \ + --notes "$notes" + gh release upload "$tag" release/* +else + gh release create "$tag" \ + --target "$GITHUB_SHA" \ + --prerelease \ + --latest=false \ + --title "mpv development build" \ + --notes "$notes" \ + release/* +fi diff --git a/common/encode_lavc.c b/common/encode_lavc.c index 4772759ee3a7d..512be0c4a83b0 100644 --- a/common/encode_lavc.c +++ b/common/encode_lavc.c @@ -424,7 +424,7 @@ static void encode_lavc_add_packet(struct mux_stream *dst, AVPacket *pkt) av_packet_unref(pkt); } -AVRational encoder_get_mux_timebase_unlocked(struct encoder_context *p) +AVRational mp_encoder_get_mux_timebase_unlocked(struct encoder_context *p) { return p->mux_stream->st->time_base; } @@ -746,7 +746,7 @@ bool encode_lavc_stream_type_ok(struct encode_lavc_context *ctx, return !!find_codec_for(ctx, type, &auto_codec) || !auto_codec; } -struct encoder_context *encoder_context_alloc(struct encode_lavc_context *ctx, +struct encoder_context *mp_encoder_context_alloc(struct encode_lavc_context *ctx, enum stream_type type, struct mp_log *log) { @@ -826,7 +826,7 @@ static void encoder_2pass_prepare(struct encoder_context *p) talloc_free(filename); } -bool encoder_init_codec_and_muxer(struct encoder_context *p) +bool mp_encoder_init_codec_and_muxer(struct encoder_context *p) { mp_assert(!avcodec_is_open(p->encoder)); @@ -893,7 +893,7 @@ bool encoder_init_codec_and_muxer(struct encoder_context *p) return false; } -bool encoder_encode(struct encoder_context *p, AVFrame *frame) +bool mp_encoder_encode(struct encoder_context *p, AVFrame *frame) { int status = avcodec_send_frame(p->encoder, frame); if (status < 0) { @@ -929,7 +929,7 @@ bool encoder_encode(struct encoder_context *p, AVFrame *frame) return false; } -void encoder_update_log(struct mpv_global *global) +void mp_encoder_update_log(struct mpv_global *global) { struct encode_opts *options = mp_get_config_group(NULL, global, &encode_config); if (options->file && (!strcmp(options->file, "-") || diff --git a/common/encode_lavc.h b/common/encode_lavc.h index 9dd8d5535958b..36c33bc2c3a68 100644 --- a/common/encode_lavc.h +++ b/common/encode_lavc.h @@ -59,7 +59,7 @@ struct encode_lavc_context { // Static information after encoder init. This never changes (even if there are // dynamic runtime changes, they have to work over AVPacket side data). // For use in encoder_context, most fields are copied from encoder_context.encoder -// by encoder_init_codec_and_muxer(). +// by mp_encoder_init_codec_and_muxer(). struct encoder_stream_info { AVRational timebase; // timebase used by the encoder (in frames/out packets) AVCodecParameters *codecpar; @@ -91,20 +91,20 @@ struct encoder_context { // Free with talloc_free(). (Keep in mind actual deinitialization requires // sending a flush packet.) // This can fail and return NULL. -struct encoder_context *encoder_context_alloc(struct encode_lavc_context *ctx, +struct encoder_context *mp_encoder_context_alloc(struct encode_lavc_context *ctx, enum stream_type type, struct mp_log *log); // After setting your codec parameters on p->encoder, you call this to "open" // the encoder. This also initializes p->mux_stream. Returns false on failure. -bool encoder_init_codec_and_muxer(struct encoder_context *p); +bool mp_encoder_init_codec_and_muxer(struct encoder_context *p); // Encode the frame and write the packet. frame is ref'ed as need. -bool encoder_encode(struct encoder_context *p, AVFrame *frame); +bool mp_encoder_encode(struct encoder_context *p, AVFrame *frame); // Return muxer timebase (only available if p->mux_stream is initialized). -AVRational encoder_get_mux_timebase_unlocked(struct encoder_context *p); +AVRational mp_encoder_get_mux_timebase_unlocked(struct encoder_context *p); -void encoder_update_log(struct mpv_global *global); +void mp_encoder_update_log(struct mpv_global *global); #endif diff --git a/player/main.c b/player/main.c index 0ef3d7f6d6581..5cc273c3ed74b 100644 --- a/player/main.c +++ b/player/main.c @@ -154,7 +154,7 @@ void mp_update_logging(struct MPContext *mpctx, bool preinit) terminal_setup_getch(mpctx->input); if (enabled) - encoder_update_log(mpctx->global); + mp_encoder_update_log(mpctx->global); } void mp_print_version(struct mp_log *log, int always) diff --git a/video/out/vo_lavc.c b/video/out/vo_lavc.c index a03901c71358f..54117dcf56fee 100644 --- a/video/out/vo_lavc.c +++ b/video/out/vo_lavc.c @@ -46,7 +46,7 @@ struct priv { static int preinit(struct vo *vo) { struct priv *vc = vo->priv; - vc->enc = encoder_context_alloc(vo->encode_lavc_ctx, STREAM_VIDEO, vo->log); + vc->enc = mp_encoder_context_alloc(vo->encode_lavc_ctx, STREAM_VIDEO, vo->log); if (!vc->enc) return -1; talloc_steal(vc, vc->enc); @@ -59,7 +59,7 @@ static void uninit(struct vo *vo) struct encoder_context *enc = vc->enc; if (!vc->shutdown) - encoder_encode(enc, NULL); // finish encoding + mp_encoder_encode(enc, NULL); // finish encoding } static int reconfig2(struct vo *vo, struct mp_image *img) @@ -143,7 +143,7 @@ static int reconfig2(struct vo *vo, struct mp_image *img) else encoder->framerate = (AVRational){ 240, 1 }; - if (!encoder_init_codec_and_muxer(vc->enc)) + if (!mp_encoder_init_codec_and_muxer(vc->enc)) goto error; return 0; @@ -232,7 +232,7 @@ static bool draw_frame(struct vo *vo, struct vo_frame *voframe) frame->pts = rint(outpts * av_q2d(av_inv_q(avc->time_base))); frame->pict_type = 0; // keep this at unknown/undefined frame->quality = avc->global_quality; - encoder_encode(enc, frame); + mp_encoder_encode(enc, frame); av_frame_free(&frame); done: diff --git a/video/out/vulkan/context_win.c b/video/out/vulkan/context_win.c index a05124347876d..a68a3ef51e807 100644 --- a/video/out/vulkan/context_win.c +++ b/video/out/vulkan/context_win.c @@ -97,7 +97,15 @@ static bool win_init(struct ra_ctx *ctx) }; VkInstance inst = vk->vkinst->instance; - VkResult res = vkCreateWin32SurfaceKHR(inst, &wininfo, NULL, &vk->surface); + mp_assert(vk->vkinst->get_proc_addr); + PFN_vkCreateWin32SurfaceKHR pCreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR) + vk->vkinst->get_proc_addr(inst, "vkCreateWin32SurfaceKHR"); + if (!pCreateWin32SurfaceKHR) { + MP_MSG(ctx, msgl, "Failed to load vkCreateWin32SurfaceKHR\n"); + goto error; + } + + VkResult res = pCreateWin32SurfaceKHR(inst, &wininfo, NULL, &vk->surface); if (res != VK_SUCCESS) { MP_MSG(ctx, msgl, "Failed creating Windows surface\n"); goto error; diff --git a/video/out/vulkan/utils.c b/video/out/vulkan/utils.c index d01fc3be0b883..c535291b1e750 100644 --- a/video/out/vulkan/utils.c +++ b/video/out/vulkan/utils.c @@ -34,7 +34,11 @@ void mpvk_uninit(struct mpvk_ctx *vk) { if (vk->surface) { mp_assert(vk->vkinst); - vkDestroySurfaceKHR(vk->vkinst->instance, vk->surface, NULL); + mp_assert(vk->vkinst->get_proc_addr); + PFN_vkDestroySurfaceKHR pDestroySurfaceKHR = (PFN_vkDestroySurfaceKHR) + vk->vkinst->get_proc_addr(vk->vkinst->instance, "vkDestroySurfaceKHR"); + if (pDestroySurfaceKHR) + pDestroySurfaceKHR(vk->vkinst->instance, vk->surface, NULL); vk->surface = VK_NULL_HANDLE; }