Compare commits

...

19 commits

Author SHA1 Message Date
Rémi Bernon
4a3731c3d9 update wine 2023-02-02 09:22:51 +01:00
Arkadiusz Hiler
f4c090a221 update wine 2023-01-20 14:36:35 +02:00
Anna Lasky
c5ad95671c proton: Remove LOST EMBER from MFDXGI hack
CW-Bug-Id: #21097
2022-12-16 20:40:44 +01:00
Arkadiusz Hiler
c703fadb78
update wine 2022-12-12 13:43:56 +01:00
Esme Povirk
40bfcf80d1 Update Wine Mono to 7.4.0. 2022-12-06 19:21:57 +02:00
Arkadiusz Hiler
2c632b6b7f update dxvk-nvapi to v0.6 2022-12-06 19:21:57 +02:00
Paul Gofman
fd7c705a69 proton: Enable gamedrive compat option for As Dusk Fails.
CW-Bug-Id: #21485
2022-12-06 19:21:57 +02:00
Arkadiusz Hiler
ad1a597368 media-converter: Use the test pattern video even without dump/transcoded files.
So the game won't trip over lack of media when shader pre-cacheing is
disabled in Steam.

CW-Bug-Id: #21524
2022-12-06 19:21:57 +02:00
Shaun Ren
4793830e64 media-converter: Set stream ID as the video hash.
If a stream ID is not set, gstreamer will generate random stream IDs for
the streams in downstream elements. This can cause decodebin to generate
its source pads in a non-deterministic order, as decodebin takes into
account the stream IDs when sorting the source pads.

This patch includes some changes from Arek Hiler.

CW-Bug-Id: #21192
2022-12-06 19:21:57 +02:00
Rémi Bernon
64729f7842 docker: Add autoconf-archive dependency.
For OpenFST.
2022-12-06 19:21:57 +02:00
Simon McVittie
11336323c1 proton: Don't crash if sys.stderr is not usable
If a Steam user runs Steam from a terminal, puts it in the background
and then exits from that terminal, or if they restart their desktop
session from a terminal (as in ValveSoftware/Proton#6277) and then exit
from that terminal, then we can inherit a stdout and/or stderr file
descriptor pointing to an invalid file descriptor. Writing to such a
file descriptor fails with EIO. Similarly, we could get write errors
as a result of OS state, such as ENOSPC if we are writing to a disk
that is full, or EPIPE if a stream to a logging framework such as the
systemd journal has been shut down.

In sufficiently pathological situations, the file descriptor could even
become invalid while the `proton` script is running, so even checking
for validity on startup would not be enough to prevent this.

The ability to log to stderr is important but not functionally critical,
and it's not like there is anything we can usefully do about a write
failure here (or even anywhere we can usefully put a warning message),
so just ignore write errors. This is similar to the behaviour of the
`logging` framework in the Python standard library (which writes to
`stderr` if a user-defined handler fails, but takes no other action)
and also similar to the approach taken to solve
ValveSoftware/steam-for-linux#8069.

Signed-off-by: Simon McVittie <smcv@collabora.com>
Link: https://github.com/ValveSoftware/Proton/pull/6341
2022-12-06 19:21:57 +02:00
Arkadiusz Hiler
07ef25e563 docker: Bump Rust to 1.65.
For let-else statements and generic associated types.
2022-12-06 19:21:57 +02:00
Arkadiusz Hiler
0341fce653 docker: Don't specify the image tag in --cache-from
The option is badly documented. Apparently the image name is enough.
Specifying the tag breaks podman/buildah build.
2022-12-06 19:21:57 +02:00
Rémi Bernon
4b473d106e
docker: Add python3-mako to the SDK images. 2022-12-06 13:51:33 +01:00
Rémi Bernon
39b7a1e58e
docker: Add OpenBLAS dependency.
For Kaldi / Vosk.
2022-12-06 13:51:30 +01:00
Anna Lasky
0dc2944e43 proton: Reorganize games in MFDXGI hack and add missing titles
This separates out the games that only need shared resources in order to
play video correctly without the MFDXGI hack.  El Hijo (853050) and
Labyrinth City: Pierre the Maze Detective (1421790) were also added.
2022-11-23 11:45:47 -06:00
Arkadiusz Hiler
babce20fc2 media-converter: Create a tag file when placeholder media are used.
CW-Bug-Id: #21473
2022-11-23 14:06:19 +02:00
Arkadiusz Hiler
f053d6da15 media-converter: Apply cargo clippy suggestions. 2022-11-23 14:06:19 +02:00
Arkadiusz Hiler
5713bfc7b0 media-converter: Update to the newest gst bindings.
1. ElementImpl trait requires GstObjectImpl

2. gst logging macros are no longer globals prefixed with gst_, they
   live inside gst:: instead

3. element is not longer passed around in many places, it can be
   accessed as self.obj() or self.instance()

4. query_default is now a part of gst::Pad and takes the pad as an argument

5. some constructors were changed to use from_$type()

6. query.view_mut() returns QueryViewMut

7. ElementFactory::make now returns a builder that we have to .build()

There are some extra cleanups as well:

1. spurious 'mut' and '&' are removed, a lot of that can be infered or
   were turned into a dereference by the compiler anyway

2. !bla.is_ok() are now bla.is_err()

3. some unneeded imports were removed
2022-11-23 14:06:19 +02:00
13 changed files with 400 additions and 250 deletions

View file

@ -195,7 +195,7 @@ GECKO_VER := 2.47.3
GECKO32_TARBALL := wine-gecko-$(GECKO_VER)-x86.tar.xz GECKO32_TARBALL := wine-gecko-$(GECKO_VER)-x86.tar.xz
GECKO64_TARBALL := wine-gecko-$(GECKO_VER)-x86_64.tar.xz GECKO64_TARBALL := wine-gecko-$(GECKO_VER)-x86_64.tar.xz
WINEMONO_VER := 7.3.1 WINEMONO_VER := 7.4.0
WINEMONO_TARBALL := wine-mono-$(WINEMONO_VER)-x86.tar.xz WINEMONO_TARBALL := wine-mono-$(WINEMONO_VER)-x86.tar.xz
FONTS := $(SRCDIR)/fonts FONTS := $(SRCDIR)/fonts

View file

@ -13,7 +13,7 @@ BASE_IMAGE_x86_64 = docker.io/amd64/ubuntu:18.04
BINUTILS_VERSION = 2.37 BINUTILS_VERSION = 2.37
GCC_VERSION = 10.3.0 GCC_VERSION = 10.3.0
MINGW_VERSION = 9.0.0 MINGW_VERSION = 9.0.0
RUST_VERSION = 1.63.0 RUST_VERSION = 1.65.0
SOURCES_URLBASE = https://repo.steampowered.com/proton-sdk SOURCES_URLBASE = https://repo.steampowered.com/proton-sdk
BINUTILS_URLBASE = $(SOURCES_URLBASE) BINUTILS_URLBASE = $(SOURCES_URLBASE)
@ -30,8 +30,8 @@ RUST_SOURCE_i686 = rust-$(RUST_VERSION)-i686-unknown-linux-gnu.tar.gz
BINUTILS_SHA256 = 820d9724f020a3e69cb337893a0b63c2db161dadcb0e06fc11dc29eb1e84a32c BINUTILS_SHA256 = 820d9724f020a3e69cb337893a0b63c2db161dadcb0e06fc11dc29eb1e84a32c
GCC_SHA256 = 64f404c1a650f27fc33da242e1f2df54952e3963a49e06e73f6940f3223ac344 GCC_SHA256 = 64f404c1a650f27fc33da242e1f2df54952e3963a49e06e73f6940f3223ac344
MINGW_SHA256 = 1929b94b402f5ff4d7d37a9fe88daa9cc55515a6134805c104d1794ae22a4181 MINGW_SHA256 = 1929b94b402f5ff4d7d37a9fe88daa9cc55515a6134805c104d1794ae22a4181
RUST_SHA256_x86_64 = 536bcf16807a4ff49b7b29af6e573a2f1821055bfad72c275c60e56edc693984 RUST_SHA256_x86_64 = 8f754fdd5af783fe9020978c64e414cb45f3ad0a6f44d045219bbf2210ca3cb9
RUST_SHA256_i686 = 6ac6ca18f119e099749d67c6dc25ce3f70542b43cc05062d5138fc1052e44c54 RUST_SHA256_i686 = b29869f8e2c7029150a929b2c4e26843f363846ad99253a25be6abcfa8e84f46
DOCKER = docker DOCKER = docker
@ -84,7 +84,7 @@ build-base-$(1): BASE_IMAGE = $(BASE_IMAGE_$(1))
build-base-$(1): build-base-$(1).Dockerfile build-base-$(1): build-base-$(1).Dockerfile
rm -rf build; mkdir -p build rm -rf build; mkdir -p build
$(DOCKER) build -f $$< \ $(DOCKER) build -f $$< \
--cache-from=$(PROTONSDK_URLBASE)/build-base-$(1):latest \ --cache-from=$(PROTONSDK_URLBASE)/build-base-$(1) \
-t $(PROTONSDK_URLBASE)/build-base-$(1):latest \ -t $(PROTONSDK_URLBASE)/build-base-$(1):latest \
build build
pull:: pull::
@ -102,7 +102,7 @@ all binutils: binutils-$(1)-$(2)
binutils-$(1)-$(2): binutils-$(1)-$(2).Dockerfile | build-base binutils-$(1)-$(2): binutils-$(1)-$(2).Dockerfile | build-base
rm -rf build; mkdir -p build rm -rf build; mkdir -p build
$(DOCKER) build -f $$< \ $(DOCKER) build -f $$< \
--cache-from=$(PROTONSDK_URLBASE)/binutils-$(1)-$(2):$(BINUTILS_VERSION) \ --cache-from=$(PROTONSDK_URLBASE)/binutils-$(1)-$(2) \
-t $(PROTONSDK_URLBASE)/binutils-$(1)-$(2):$(BINUTILS_VERSION) \ -t $(PROTONSDK_URLBASE)/binutils-$(1)-$(2):$(BINUTILS_VERSION) \
-t $(PROTONSDK_URLBASE)/binutils-$(1)-$(2):latest \ -t $(PROTONSDK_URLBASE)/binutils-$(1)-$(2):latest \
build build
@ -124,7 +124,7 @@ all mingw: mingw-$(2)-$(1)
mingw-$(2)-$(1): mingw-$(2)-$(1).Dockerfile | binutils mingw-$(2)-$(1): mingw-$(2)-$(1).Dockerfile | binutils
rm -rf build; mkdir -p build rm -rf build; mkdir -p build
$(DOCKER) build -f $$< \ $(DOCKER) build -f $$< \
--cache-from=$(PROTONSDK_URLBASE)/mingw-$(2)-$(1):$(MINGW_VERSION) \ --cache-from=$(PROTONSDK_URLBASE)/mingw-$(2)-$(1) \
-t $(PROTONSDK_URLBASE)/mingw-$(2)-$(1):$(MINGW_VERSION) \ -t $(PROTONSDK_URLBASE)/mingw-$(2)-$(1):$(MINGW_VERSION) \
-t $(PROTONSDK_URLBASE)/mingw-$(2)-$(1):latest \ -t $(PROTONSDK_URLBASE)/mingw-$(2)-$(1):latest \
build build
@ -156,7 +156,7 @@ gcc-$(1)-$(2): TARGET_FLAGS = $(GCC_TARGET_FLAGS_$(2))
gcc-$(1)-$(2): gcc-$(1)-$(2).Dockerfile | mingw gcc-$(1)-$(2): gcc-$(1)-$(2).Dockerfile | mingw
rm -rf build; mkdir -p build rm -rf build; mkdir -p build
$(DOCKER) build -f $$< \ $(DOCKER) build -f $$< \
--cache-from=$(PROTONSDK_URLBASE)/gcc-$(1)-$(2):$(GCC_VERSION) \ --cache-from=$(PROTONSDK_URLBASE)/gcc-$(1)-$(2) \
-t $(PROTONSDK_URLBASE)/gcc-$(1)-$(2):$(GCC_VERSION) \ -t $(PROTONSDK_URLBASE)/gcc-$(1)-$(2):$(GCC_VERSION) \
-t $(PROTONSDK_URLBASE)/gcc-$(1)-$(2):latest \ -t $(PROTONSDK_URLBASE)/gcc-$(1)-$(2):latest \
build build
@ -179,7 +179,7 @@ proton: BASE_IMAGE = $(STEAMRT_URLBASE)/steamrt/soldier/sdk:$(STEAMRT_VERSION)
proton: proton.Dockerfile | gcc proton: proton.Dockerfile | gcc
rm -rf build; mkdir -p build rm -rf build; mkdir -p build
$(DOCKER) build -f $$< \ $(DOCKER) build -f $$< \
--cache-from=$(PROTONSDK_URLBASE):$(PROTONSDK_VERSION) \ --cache-from=$(PROTONSDK_URLBASE) \
-t $(PROTONSDK_URLBASE):$(PROTONSDK_VERSION) \ -t $(PROTONSDK_URLBASE):$(PROTONSDK_VERSION) \
-t $(PROTONSDK_URLBASE):latest \ -t $(PROTONSDK_URLBASE):latest \
build build

View file

@ -52,10 +52,14 @@ RUN bash -c 'mkdir -p /usr/lib/ccache && ls /usr/bin/{,*-}{cc,c++,gcc,g++}{,-[0-
ENV PATH=/usr/lib/ccache:$PATH ENV PATH=/usr/lib/ccache:$PATH
RUN apt-get install -y \ RUN apt-get install -y \
autoconf-archive \
fontforge \ fontforge \
fonttools \ fonttools \
libxpresent-dev \ libxpresent-dev \
libxpresent-dev:i386 \ libxpresent-dev:i386 \
libopenblas-dev \
libopenblas-dev:i386 \
python3-mako \
python3-pefile \ python3-pefile \
libcapstone-dev \ libcapstone-dev \
libcapstone-dev:i386 \ libcapstone-dev:i386 \

@ -1 +1 @@
Subproject commit ac312ac21bb1ca108a149849adba9fd1c77e3a9d Subproject commit 5fe4a73eddb938ce6f866944e502e9209bd7020e

View file

@ -23,6 +23,12 @@ version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfb6d71005dc22a708c7496eee5c8dc0300ee47355de6256c3b35b12b5fef596" checksum = "bfb6d71005dc22a708c7496eee5c8dc0300ee47355de6256c3b35b12b5fef596"
[[package]]
name = "atomic_refcell"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73b5e5f48b927f04e952dedc932f31995a65a0bf65ec971c74436e51bf6e970d"
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.1.0" version = "1.1.0"
@ -43,9 +49,9 @@ checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d"
[[package]] [[package]]
name = "cfg-expr" name = "cfg-expr"
version = "0.8.1" version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b412e83326147c2bb881f8b40edfbf9905b9b8abaebd0e47ca190ba62fda8f0e" checksum = "b0357a6402b295ca3a86bc148e84df46c02e41f41fef186bda662557ef6328aa"
dependencies = [ dependencies = [
"smallvec", "smallvec",
] ]
@ -84,10 +90,16 @@ dependencies = [
] ]
[[package]] [[package]]
name = "either" name = "filetime"
version = "1.8.0" version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" checksum = "4b9663d381d07ae25dc88dbdf27df458faa83a9b25336bcac83d5e452b5fc9d3"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"windows-sys",
]
[[package]] [[package]]
name = "futures-channel" name = "futures-channel"
@ -115,6 +127,17 @@ dependencies = [
"futures-util", "futures-util",
] ]
[[package]]
name = "futures-macro"
version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42cd15d1c7456c04dbdf7e88bcd69760d74f3a798d6444e16974b505b0e62f17"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "futures-task" name = "futures-task"
version = "0.3.24" version = "0.3.24"
@ -128,6 +151,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90" checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"futures-macro",
"futures-task", "futures-task",
"pin-project-lite", "pin-project-lite",
"pin-utils", "pin-utils",
@ -135,29 +159,45 @@ dependencies = [
] ]
[[package]] [[package]]
name = "glib" name = "gio-sys"
version = "0.14.8" version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c515f1e62bf151ef6635f528d05b02c11506de986e43b34a5c920ef0b3796a4" checksum = "6da1bba9d3f2ab13a6e9932c40f240dc99ebc9f0bdc35cfb130d1a3df36f374c"
dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"system-deps",
"winapi",
]
[[package]]
name = "glib"
version = "0.16.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5abffa711471e015eb93d65d6ea20e7e9f6f7951fc0a1042280439319b2de06"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"futures-channel", "futures-channel",
"futures-core", "futures-core",
"futures-executor", "futures-executor",
"futures-task", "futures-task",
"futures-util",
"gio-sys",
"glib-macros", "glib-macros",
"glib-sys", "glib-sys",
"gobject-sys", "gobject-sys",
"libc", "libc",
"once_cell", "once_cell",
"smallvec", "smallvec",
"thiserror",
] ]
[[package]] [[package]]
name = "glib-macros" name = "glib-macros"
version = "0.14.1" version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2aad66361f66796bfc73f530c51ef123970eb895ffba991a234fcf7bea89e518" checksum = "e195c1311fa6b04d7b896ea39385f6bd60ef5d25bf74a7c11c8c3f94f6c1a572"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"heck", "heck",
@ -170,9 +210,9 @@ dependencies = [
[[package]] [[package]]
name = "glib-sys" name = "glib-sys"
version = "0.14.0" version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c1d60554a212445e2a858e42a0e48cece1bd57b311a19a9468f70376cf554ae" checksum = "b33357bb421a77bd849f6a0bfcaf3b4b256a2577802971bb5dd522d530f27021"
dependencies = [ dependencies = [
"libc", "libc",
"system-deps", "system-deps",
@ -180,9 +220,9 @@ dependencies = [
[[package]] [[package]]
name = "gobject-sys" name = "gobject-sys"
version = "0.14.0" version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa92cae29759dae34ab5921d73fff5ad54b3d794ab842c117e36cafc7994c3f5" checksum = "63ca11a57400f3d4fda594e002844be47900c9fb8b29e2155c6e37a1f24e51b3"
dependencies = [ dependencies = [
"glib-sys", "glib-sys",
"libc", "libc",
@ -191,18 +231,18 @@ dependencies = [
[[package]] [[package]]
name = "gst-plugin-version-helper" name = "gst-plugin-version-helper"
version = "0.7.3" version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a6a4dd1cb931cc6b49af354a68f21b3aee46b5b07370215d942f3a71542123f" checksum = "747ffe0e4067acfb98d6f7cbbe0a1901794587a93ab2b36c4652bc75c28d865d"
dependencies = [ dependencies = [
"chrono", "chrono",
] ]
[[package]] [[package]]
name = "gstreamer" name = "gstreamer"
version = "0.17.4" version = "0.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6a255f142048ba2c4a4dce39106db1965abe355d23f4b5335edea43a553faa4" checksum = "7e428081934c617115320750b7827f8f13131d9c3ae90b647c14a5d6019f47b4"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"cfg-if", "cfg-if",
@ -216,6 +256,7 @@ dependencies = [
"num-integer", "num-integer",
"num-rational", "num-rational",
"once_cell", "once_cell",
"option-operations",
"paste", "paste",
"pretty-hex", "pretty-hex",
"thiserror", "thiserror",
@ -223,11 +264,10 @@ dependencies = [
[[package]] [[package]]
name = "gstreamer-audio" name = "gstreamer-audio"
version = "0.17.2" version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "420b6bcb1759231f01172751da094e7afa5cd9edf40bee7475f5bc86df433c57" checksum = "affbf8dd22eb301f21a3ae659358a6e069850b35cab6522d40738c9500f85b17"
dependencies = [ dependencies = [
"array-init",
"bitflags", "bitflags",
"cfg-if", "cfg-if",
"glib", "glib",
@ -240,9 +280,9 @@ dependencies = [
[[package]] [[package]]
name = "gstreamer-audio-sys" name = "gstreamer-audio-sys"
version = "0.17.0" version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d066ddfd05f63836f35ac4a5830d5bb2f7f3d6c33c870e9b15c667d20f65d7f6" checksum = "f6d6a3ad336150faf2125e29ac025b1fa152dca08b4cb2496f1e7d9c83b51e8b"
dependencies = [ dependencies = [
"glib-sys", "glib-sys",
"gobject-sys", "gobject-sys",
@ -254,10 +294,11 @@ dependencies = [
[[package]] [[package]]
name = "gstreamer-base" name = "gstreamer-base"
version = "0.17.2" version = "0.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c0c1d8c62eb5d08fb80173609f2eea71d385393363146e4e78107facbd67715" checksum = "326674197c010e91a98d0f55a032abe22b1fd932456dbcdc3415450b4b653817"
dependencies = [ dependencies = [
"atomic_refcell",
"bitflags", "bitflags",
"cfg-if", "cfg-if",
"glib", "glib",
@ -268,9 +309,9 @@ dependencies = [
[[package]] [[package]]
name = "gstreamer-base-sys" name = "gstreamer-base-sys"
version = "0.17.0" version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28169a7b58edb93ad8ac766f0fa12dcd36a2af4257a97ee10194c7103baf3e27" checksum = "cd55d3858fa65a99286c1cbe8db001f4ce5cff6a038f1c1253f5d99f840970de"
dependencies = [ dependencies = [
"glib-sys", "glib-sys",
"gobject-sys", "gobject-sys",
@ -281,9 +322,9 @@ dependencies = [
[[package]] [[package]]
name = "gstreamer-sys" name = "gstreamer-sys"
version = "0.17.3" version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a81704feeb3e8599913bdd1e738455c2991a01ff4a1780cb62200993e454cc3e" checksum = "fbaafc66df32b334d4aa28025fd5d83cadc971e1910205e140ea070f4ac4834f"
dependencies = [ dependencies = [
"glib-sys", "glib-sys",
"gobject-sys", "gobject-sys",
@ -293,9 +334,9 @@ dependencies = [
[[package]] [[package]]
name = "gstreamer-video" name = "gstreamer-video"
version = "0.17.2" version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3447ee95c8e79daec0b163260cf6a3de9bc19ff47a01b533787f900074a3476" checksum = "a9b96daff8a3d853588e61207afac81a4879f3972430f6609721601ab757d7fd"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"cfg-if", "cfg-if",
@ -310,9 +351,9 @@ dependencies = [
[[package]] [[package]]
name = "gstreamer-video-sys" name = "gstreamer-video-sys"
version = "0.17.0" version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b81608f4182bdddd5bd33aaaa341d5544eda12b067a3dab75b1b7d2de01a3ba7" checksum = "066ee44cd8d84f19a18c646128c1890878c034d3fb9f34d8d5f07311bbd9f41f"
dependencies = [ dependencies = [
"glib-sys", "glib-sys",
"gobject-sys", "gobject-sys",
@ -324,12 +365,9 @@ dependencies = [
[[package]] [[package]]
name = "heck" name = "heck"
version = "0.3.3" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
dependencies = [
"unicode-segmentation",
]
[[package]] [[package]]
name = "iana-time-zone" name = "iana-time-zone"
@ -344,15 +382,6 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "itertools"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
dependencies = [
"either",
]
[[package]] [[package]]
name = "js-sys" name = "js-sys"
version = "0.3.60" version = "0.3.60"
@ -419,6 +448,15 @@ version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1"
[[package]]
name = "option-operations"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c26d27bb1aeab65138e4bf7666045169d1717febcc9ff870166be8348b223d0"
dependencies = [
"paste",
]
[[package]] [[package]]
name = "paste" name = "paste"
version = "1.0.9" version = "1.0.9"
@ -445,9 +483,9 @@ checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
[[package]] [[package]]
name = "pretty-hex" name = "pretty-hex"
version = "0.2.1" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc5c99d529f0d30937f6f4b8a86d988047327bb88d04d2c4afc356de74722131" checksum = "c6fa0831dd7cc608c38a5e323422a0077678fa5744aa2be4ad91c4ece8eec8d5"
[[package]] [[package]]
name = "proc-macro-crate" name = "proc-macro-crate"
@ -499,6 +537,7 @@ version = "7.0.0"
dependencies = [ dependencies = [
"array-init", "array-init",
"crc32fast", "crc32fast",
"filetime",
"glib", "glib",
"gst-plugin-version-helper", "gst-plugin-version-helper",
"gstreamer", "gstreamer",
@ -517,6 +556,15 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "redox_syscall"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
dependencies = [
"bitflags",
]
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.145" version = "1.0.145"
@ -538,24 +586,6 @@ version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1"
[[package]]
name = "strum"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aaf86bbcfd1fa9670b7a129f64fc0c9fcbbfe4f1bc4210e9e98fe71ffc12cde2"
[[package]]
name = "strum_macros"
version = "0.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d06aaeeee809dbc59eb4556183dd927df67db1540de5be8d3ec0b6636358a5ec"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.101" version = "1.0.101"
@ -569,18 +599,13 @@ dependencies = [
[[package]] [[package]]
name = "system-deps" name = "system-deps"
version = "3.2.0" version = "6.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "480c269f870722b3b08d2f13053ce0c2ab722839f472863c3e2d61ff3a1c2fa6" checksum = "2955b1fe31e1fa2fbd1976b71cc69a606d7d4da16f6de3333d0c92d51419aeff"
dependencies = [ dependencies = [
"anyhow",
"cfg-expr", "cfg-expr",
"heck", "heck",
"itertools",
"pkg-config", "pkg-config",
"strum",
"strum_macros",
"thiserror",
"toml", "toml",
"version-compare", "version-compare",
] ]
@ -620,17 +645,11 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd" checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd"
[[package]]
name = "unicode-segmentation"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a"
[[package]] [[package]]
name = "version-compare" name = "version-compare"
version = "0.0.11" version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c18c859eead79d8b95d09e4678566e8d70105c4e7b251f707a03df32442661b" checksum = "fe88247b92c1df6b6de80ddc290f3976dbdf2f5f5d3fd049a9fb598c6dd5ca73"
[[package]] [[package]]
name = "version_check" name = "version_check"
@ -713,3 +732,60 @@ name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"
[[package]]
name = "windows_i686_gnu"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"
[[package]]
name = "windows_i686_msvc"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"

View file

@ -8,18 +8,19 @@ edition = "2021"
description = "Proton media converter" description = "Proton media converter"
[dependencies] [dependencies]
glib = "0.14" glib = "0.16"
gstreamer = "0.17.4" gstreamer = "0.19.1"
# the versions are not in sync, the submodules below haven't seen any changes # the versions are not in sync, the submodules below haven't seen any changes
# since 0.17.2 release so .3 and .4 releases haven't happened # since 0.19.0 release so .1 release haven't happened for them
gstreamer-base = "0.17.2" gstreamer-base = "0.19.1"
gstreamer-video = "0.17.2" gstreamer-video = "0.19.0"
gstreamer-audio = "0.17.2" gstreamer-audio = "0.19.0"
once_cell = "1.9" once_cell = "1.9"
crc32fast = "1.3" crc32fast = "1.3"
array-init = "2.0" array-init = "2.0"
filetime = "0.2"
[lib] [lib]
name = "protonmediaconverter" name = "protonmediaconverter"
@ -27,7 +28,7 @@ crate-type = ["cdylib"]
path = "src/lib.rs" path = "src/lib.rs"
[build-dependencies] [build-dependencies]
gst-plugin-version-helper = "0.7.2" gst-plugin-version-helper = "0.7.4"
[profile.release] [profile.release]
lto = true lto = true

View file

@ -31,14 +31,14 @@
use crate::format_hash; use crate::format_hash;
use crate::HASH_SEED; use crate::HASH_SEED;
use crate::discarding_disabled; use crate::discarding_disabled;
use crate::steam_compat_shader_path;
use crate::touch_file;
use gst;
use gst::glib; use gst::glib;
use gst::prelude::*; use gst::prelude::*;
use gst::subclass::prelude::*; use gst::subclass::prelude::*;
use gst::EventView; use gst::EventView;
use gst::QueryView; use gst::QueryViewMut;
use gst_audio;
use std::sync::Mutex; use std::sync::Mutex;
use std::io; use std::io;
@ -302,7 +302,7 @@ static DUMPING_DISABLED: Lazy<bool> = Lazy::new(|| {
Err(_) => { return false; }, Err(_) => { return false; },
Ok(c) => c, Ok(c) => c,
}; };
return v != "0"; v != "0"
}); });
#[derive(Clone)] #[derive(Clone)]
@ -463,16 +463,16 @@ impl StreamState {
offs += 16; offs += 16;
} }
gst_trace!(CAT, "stream id {} is a subset of {}, so not recording stream", self.cur_hash, *stream_id); gst::trace!(CAT, "stream id {} is a subset of {}, so not recording stream", self.cur_hash, *stream_id);
return true; true
}); });
} }
if !found { if !found {
if *DUMPING_DISABLED { if *DUMPING_DISABLED {
gst_trace!(CAT, "dumping disabled, so not recording stream id {}", self.cur_hash); gst::trace!(CAT, "dumping disabled, so not recording stream id {}", self.cur_hash);
} else { } else {
gst_trace!(CAT, "recording stream id {}", self.cur_hash); gst::trace!(CAT, "recording stream id {}", self.cur_hash);
db.write_entry(AUDIOCONV_FOZ_TAG_CODECINFO, db.write_entry(AUDIOCONV_FOZ_TAG_CODECINFO,
self.buffers[0].0, self.buffers[0].0,
&mut self.codec_info.as_ref().unwrap().serialize().as_slice(), &mut self.codec_info.as_ref().unwrap().serialize().as_slice(),
@ -594,9 +594,9 @@ impl AudioConvState {
let buf_len = mapped.size(); let buf_len = mapped.size();
let hash = hash_data(mapped.as_slice(), buf_len, &mut self.hash_state) let hash = hash_data(mapped.as_slice(), buf_len, &mut self.hash_state)
.map_err(|e|{ gst_warning!(CAT, "Hashing buffer failed! {}", e); io::ErrorKind::Other })?; .map_err(|e|{ gst::warning!(CAT, "Hashing buffer failed! {}", e); io::ErrorKind::Other })?;
let loop_hash = hash_data(mapped.as_slice(), buf_len, &mut self.loop_hash_state) let loop_hash = hash_data(mapped.as_slice(), buf_len, &mut self.loop_hash_state)
.map_err(|e|{ gst_warning!(CAT, "Hashing buffer failed! {}", e); io::ErrorKind::Other })?; .map_err(|e|{ gst::warning!(CAT, "Hashing buffer failed! {}", e); io::ErrorKind::Other })?;
let try_loop = match self.stream_state.record_buffer(hash, loop_hash, mapped, Some(self.codec_data.as_ref().unwrap()))? { let try_loop = match self.stream_state.record_buffer(hash, loop_hash, mapped, Some(self.codec_data.as_ref().unwrap()))? {
LoopState::NoLoop => { self.loop_hash_state.reset(); false }, LoopState::NoLoop => { self.loop_hash_state.reset(); false },
@ -605,9 +605,9 @@ impl AudioConvState {
}; };
if try_loop { if try_loop {
gst_log!(CAT, "Buffer hash: {} (loop: {})", format_hash(hash), format_hash(loop_hash)); gst::log!(CAT, "Buffer hash: {} (loop: {})", format_hash(hash), format_hash(loop_hash));
}else{ }else{
gst_log!(CAT, "Buffer hash: {}", format_hash(hash)); gst::log!(CAT, "Buffer hash: {}", format_hash(hash));
} }
/* try to read transcoded data */ /* try to read transcoded data */
@ -635,6 +635,14 @@ impl AudioConvState {
let buf = Box::new(*include_bytes!("../../blank.ptna")); let buf = Box::new(*include_bytes!("../../blank.ptna"));
match steam_compat_shader_path() {
None => gst::log!(CAT, "env STEAM_COMPAT_SHADER_PATH not set"),
Some(mut path) => {
path.push("placeholder-audio-used");
if let Err(e) = touch_file(path) { gst::log!(CAT, "Failed to touch placeholder-audio-used file: {:?}", e) }
},
};
Ok(buf) Ok(buf)
} }
} }
@ -658,14 +666,14 @@ impl ObjectSubclass for AudioConv {
AudioConv::catch_panic_pad_function( AudioConv::catch_panic_pad_function(
parent, parent,
|| Err(gst::FlowError::Error), || Err(gst::FlowError::Error),
|audioconv, element| audioconv.chain(pad, element, buffer) |audioconv| audioconv.chain(pad, buffer)
) )
}) })
.event_function(|pad, parent, event| { .event_function(|pad, parent, event| {
AudioConv::catch_panic_pad_function( AudioConv::catch_panic_pad_function(
parent, parent,
|| false, || false,
|audioconv, element| audioconv.sink_event(pad, element, event) |audioconv| audioconv.sink_event(pad, event)
) )
}).build(); }).build();
@ -675,14 +683,14 @@ impl ObjectSubclass for AudioConv {
AudioConv::catch_panic_pad_function( AudioConv::catch_panic_pad_function(
parent, parent,
|| false, || false,
|audioconv, element| audioconv.src_query(pad, element, query) |audioconv| audioconv.src_query(pad, query)
) )
}) })
.activatemode_function(|pad, parent, mode, active| { .activatemode_function(|pad, parent, mode, active| {
AudioConv::catch_panic_pad_function( AudioConv::catch_panic_pad_function(
parent, parent,
|| Err(loggable_error!(CAT, "Panic activating srcpad with mode")), || Err(loggable_error!(CAT, "Panic activating srcpad with mode")),
|audioconv, element| audioconv.src_activatemode(pad, element, mode, active) |audioconv| audioconv.src_activatemode(pad, mode, active)
) )
}).build(); }).build();
@ -695,14 +703,18 @@ impl ObjectSubclass for AudioConv {
} }
impl ObjectImpl for AudioConv { impl ObjectImpl for AudioConv {
fn constructed(&self, obj: &Self::Type) { fn constructed(&self) {
self.parent_constructed(obj); self.parent_constructed();
let obj = self.obj();
obj.add_pad(&self.sinkpad).unwrap(); obj.add_pad(&self.sinkpad).unwrap();
obj.add_pad(&self.srcpad).unwrap(); obj.add_pad(&self.srcpad).unwrap();
} }
} }
impl GstObjectImpl for AudioConv { }
impl ElementImpl for AudioConv { impl ElementImpl for AudioConv {
fn metadata() -> Option<&'static gst::subclass::ElementMetadata> { fn metadata() -> Option<&'static gst::subclass::ElementMetadata> {
static ELEMENT_METADATA: Lazy<gst::subclass::ElementMetadata> = Lazy::new(|| { static ELEMENT_METADATA: Lazy<gst::subclass::ElementMetadata> = Lazy::new(|| {
@ -744,11 +756,10 @@ impl ElementImpl for AudioConv {
fn change_state( fn change_state(
&self, &self,
element: &super::AudioConv,
transition: gst::StateChange transition: gst::StateChange
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> { ) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
gst_log!(CAT, obj: element, "State transition: {:?}", transition); gst::log!(CAT, imp: self, "State transition: {:?}", transition);
match transition { match transition {
gst::StateChange::NullToReady => { gst::StateChange::NullToReady => {
@ -762,14 +773,14 @@ impl ElementImpl for AudioConv {
let db = &mut (*DUMP_FOZDB).lock().unwrap(); let db = &mut (*DUMP_FOZDB).lock().unwrap();
let db = &mut db.open(true).fozdb; let db = &mut db.open(true).fozdb;
if db.is_none() { if db.is_none() {
gst_error!(CAT, "Failed to open fossilize db!"); gst::error!(CAT, "Failed to open fossilize db!");
return Err(gst::StateChangeError); return Err(gst::StateChangeError);
} }
} }
let new_state = AudioConvState::new().map_err(|err| { let new_state = AudioConvState::new().map_err(|err| {
err.log(); err.log();
return gst::StateChangeError; gst::StateChangeError
})?; })?;
let mut state = self.state.lock().unwrap(); let mut state = self.state.lock().unwrap();
@ -783,7 +794,7 @@ impl ElementImpl for AudioConv {
let old_state = self.state.lock().unwrap().take(); // dispose of state let old_state = self.state.lock().unwrap().take(); // dispose of state
if let Some(old_state) = old_state { if let Some(old_state) = old_state {
if old_state.stream_state.write_to_foz().is_err() { if old_state.stream_state.write_to_foz().is_err() {
gst_warning!(CAT, "Error writing out stream data!"); gst::warning!(CAT, "Error writing out stream data!");
} }
} }
}, },
@ -791,7 +802,7 @@ impl ElementImpl for AudioConv {
_ => (), _ => (),
}; };
self.parent_change_state(element, transition) self.parent_change_state(transition)
/* XXX on ReadyToNull, sodium drops state _again_ here... why? */ /* XXX on ReadyToNull, sodium drops state _again_ here... why? */
} }
@ -802,10 +813,9 @@ impl AudioConv {
fn chain( fn chain(
&self, &self,
_pad: &gst::Pad, _pad: &gst::Pad,
_element: &super::AudioConv,
buffer: gst::Buffer buffer: gst::Buffer
) -> Result<gst::FlowSuccess, gst::FlowError> { ) -> Result<gst::FlowSuccess, gst::FlowError> {
gst_log!(CAT, "Handling buffer {:?}", buffer); gst::log!(CAT, "Handling buffer {:?}", buffer);
let mut state = self.state.lock().unwrap(); let mut state = self.state.lock().unwrap();
let mut state = match &mut *state { let mut state = match &mut *state {
@ -814,7 +824,7 @@ impl AudioConv {
}; };
let ptnadata = state.open_transcode_file(buffer).map_err(|_| { let ptnadata = state.open_transcode_file(buffer).map_err(|_| {
gst_error!(CAT, "ERROR! Failed to read transcoded audio! Things will go badly..."); gst::FlowError::Error gst::error!(CAT, "ERROR! Failed to read transcoded audio! Things will go badly..."); gst::FlowError::Error
})?; })?;
let mut offs: usize = 0; let mut offs: usize = 0;
@ -825,7 +835,7 @@ impl AudioConv {
} }
if offs + 4 >= ptnadata.len() { if offs + 4 >= ptnadata.len() {
gst_warning!(CAT, "Short read on ptna header?"); gst::warning!(CAT, "Short read on ptna header?");
break; break;
} }
@ -838,7 +848,7 @@ impl AudioConv {
(packet_hdr & AUDIOCONV_ENCODED_LENGTH_MASK) as usize); (packet_hdr & AUDIOCONV_ENCODED_LENGTH_MASK) as usize);
if offs + encoded_len > ptnadata.len() { if offs + encoded_len > ptnadata.len() {
gst_warning!(CAT, "Short read on ptna data?"); gst::warning!(CAT, "Short read on ptna data?");
break; break;
} }
@ -854,14 +864,16 @@ impl AudioConv {
let mut buffer = gst::Buffer::with_size(encoded_len as usize).unwrap(); let mut buffer = gst::Buffer::with_size(encoded_len as usize).unwrap();
if !pkt_is_header && padding_len > 0 { if !pkt_is_header && padding_len > 0 {
gst_audio::AudioClippingMeta::add(buffer.get_mut().unwrap(), gst::format::Default(0), gst::format::Default(padding_len as u64)); gst_audio::AudioClippingMeta::add(buffer.get_mut().unwrap(),
gst::format::Default::ZERO,
gst::format::Default::from_u64(padding_len as u64));
} }
let mut writable = buffer.into_mapped_buffer_writable().unwrap(); let mut writable = buffer.into_mapped_buffer_writable().unwrap();
writable.as_mut_slice().copy_from_slice(&ptnadata[offs..offs + encoded_len]); writable.as_mut_slice().copy_from_slice(&ptnadata[offs..offs + encoded_len]);
gst_log!(CAT, "pushing one packet of len {}", encoded_len); gst::log!(CAT, "pushing one packet of len {}", encoded_len);
self.srcpad.push(writable.into_buffer())?; self.srcpad.push(writable.into_buffer())?;
if pkt_is_header { if pkt_is_header {
@ -877,19 +889,18 @@ impl AudioConv {
fn sink_event( fn sink_event(
&self, &self,
pad: &gst::Pad, pad: &gst::Pad,
element: &super::AudioConv,
event: gst::Event event: gst::Event
) -> bool { ) -> bool {
gst_log!(CAT, obj:pad, "Got an event {:?}", event); gst::log!(CAT, obj:pad, "Got an event {:?}", event);
match event.view() { match event.view() {
EventView::Caps(event_caps) => { EventView::Caps(event_caps) => {
let mut state = self.state.lock().unwrap(); let mut state = self.state.lock().unwrap();
if let Some(state) = &mut *state { if let Some(state) = &mut *state {
let head = match NeedTranscodeHead::new_from_caps(&event_caps.caps()){ let head = match NeedTranscodeHead::new_from_caps(event_caps.caps()){
Ok(h) => h, Ok(h) => h,
Err(e) => { Err(e) => {
gst_error!(CAT, "Invalid WMA caps!"); gst::error!(CAT, "Invalid WMA caps!");
e.log(); e.log();
return false; return false;
}, },
@ -916,21 +927,20 @@ impl AudioConv {
}; };
drop(state); drop(state);
pad.event_default(Some(element), event) gst::Pad::event_default(pad, Some(&*self.obj()), event)
}, },
_ => pad.event_default(Some(element), event) _ => gst::Pad::event_default(pad, Some(&*self.obj()), event)
} }
} }
fn src_query( fn src_query(
&self, &self,
pad: &gst::Pad, pad: &gst::Pad,
element: &super::AudioConv,
query: &mut gst::QueryRef) -> bool query: &mut gst::QueryRef) -> bool
{ {
gst_log!(CAT, obj: pad, "got query: {:?}", query); gst::log!(CAT, obj: pad, "got query: {:?}", query);
match query.view_mut() { match query.view_mut() {
QueryView::Scheduling(mut q) => { QueryViewMut::Scheduling(q) => {
let mut peer_query = gst::query::Scheduling::new(); let mut peer_query = gst::query::Scheduling::new();
let res = self.sinkpad.peer_query(&mut peer_query); let res = self.sinkpad.peer_query(&mut peer_query);
if ! res { if ! res {
@ -942,14 +952,13 @@ impl AudioConv {
q.set(flags, min, max, align); q.set(flags, min, max, align);
true true
}, },
_ => pad.query_default(Some(element), query) _ => gst::Pad::query_default(pad, Some(&*self.obj()), query)
} }
} }
fn src_activatemode( fn src_activatemode(
&self, &self,
_pad: &gst::Pad, _pad: &gst::Pad,
_element: &super::AudioConv,
mode: gst::PadMode, mode: gst::PadMode,
active: bool active: bool
) -> Result<(), gst::LoggableError> { ) -> Result<(), gst::LoggableError> {

View file

@ -28,7 +28,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
use gst;
use gst::glib; use gst::glib;
use gst::prelude::*; use gst::prelude::*;
use gst::subclass::prelude::*; use gst::subclass::prelude::*;
@ -86,13 +85,13 @@ impl ObjectSubclass for AudioConvBin {
AudioConvBin::catch_panic_pad_function( AudioConvBin::catch_panic_pad_function(
parent, parent,
|| false, || false,
|audioconvbin, element| audioconvbin.sink_event(pad, element, event) |audioconvbin| audioconvbin.sink_event(pad, event)
) )
}).build(); }).build();
let audioconv = gst::ElementFactory::make("protonaudioconverter", None).unwrap(); let audioconv = gst::ElementFactory::make("protonaudioconverter").build().unwrap();
let opusdec = gst::ElementFactory::make("opusdec", None).unwrap(); let opusdec = gst::ElementFactory::make("opusdec").build().unwrap();
let capssetter = gst::ElementFactory::make("capssetter", None).unwrap(); let capssetter = gst::ElementFactory::make("capssetter").build().unwrap();
AudioConvBin { AudioConvBin {
audioconv, audioconv,
@ -105,8 +104,10 @@ impl ObjectSubclass for AudioConvBin {
} }
impl ObjectImpl for AudioConvBin { impl ObjectImpl for AudioConvBin {
fn constructed(&self, obj: &Self::Type) { fn constructed(&self) {
self.parent_constructed(obj); self.parent_constructed();
let obj = self.obj();
obj.add(&self.audioconv).unwrap(); obj.add(&self.audioconv).unwrap();
obj.add(&self.opusdec).unwrap(); obj.add(&self.opusdec).unwrap();
@ -127,6 +128,8 @@ impl ObjectImpl for AudioConvBin {
} }
} }
impl GstObjectImpl for AudioConvBin { }
impl BinImpl for AudioConvBin { } impl BinImpl for AudioConvBin { }
impl ElementImpl for AudioConvBin { impl ElementImpl for AudioConvBin {
@ -175,7 +178,6 @@ impl AudioConvBin {
fn sink_event( fn sink_event(
&self, &self,
pad: &gst::GhostPad, pad: &gst::GhostPad,
element: &super::AudioConvBin,
event: gst::Event event: gst::Event
) -> bool { ) -> bool {
match event.view() { match event.view() {
@ -193,20 +195,19 @@ impl AudioConvBin {
.build(); .build();
rate_caps.append_structure(s); rate_caps.append_structure(s);
} }
self.capssetter.set_property("caps", self.capssetter.set_property("caps", &rate_caps);
&rate_caps).unwrap();
}else{ }else{
gst_warning!(CAT, "event has no rate"); gst::warning!(CAT, "event has no rate");
} }
} else { } else {
gst_warning!(CAT, "event has no structure"); gst::warning!(CAT, "event has no structure");
} }
/* forward on to the real pad */ /* forward on to the real pad */
self.audioconv.static_pad("sink").unwrap() self.audioconv.static_pad("sink").unwrap()
.send_event(event) .send_event(event)
}, },
_ => pad.event_default(Some(element), event) _ => gst::Pad::event_default(pad, Some(&*self.obj()), event)
} }
} }
} }

View file

@ -50,7 +50,6 @@ use std::io::Seek;
use std::fs::OpenOptions; use std::fs::OpenOptions;
use std::convert::From; use std::convert::From;
use std::collections::HashMap; use std::collections::HashMap;
use crc32fast;
use crate::*; use crate::*;
@ -96,7 +95,7 @@ const _FOSSILIZE_COMPRESSION_DEFLATE: u32 = 2;
#[derive(Debug)] #[derive(Debug)]
pub enum Error { pub enum Error {
NotImplemented, NotImplemented,
IOError(io::Error), IO(io::Error),
CorruptDatabase, CorruptDatabase,
DataTooLarge, DataTooLarge,
InvalidTag, InvalidTag,
@ -106,7 +105,7 @@ pub enum Error {
impl From<io::Error> for Error { impl From<io::Error> for Error {
fn from(e: io::Error) -> Error { fn from(e: io::Error) -> Error {
Error::IOError(e) Error::IO(e)
} }
} }
@ -241,9 +240,7 @@ impl StreamArchive {
let version = magic_and_version[15]; let version = magic_and_version[15];
if magic_and_version[0..12] != FOSSILIZE_MAGIC || if magic_and_version[0..12] != FOSSILIZE_MAGIC || !(FOSSILIZE_MIN_COMPAT_VERSION..=FOSSILIZE_VERSION).contains(&version) {
version < FOSSILIZE_MIN_COMPAT_VERSION ||
version > FOSSILIZE_VERSION {
return Err(Error::CorruptDatabase); return Err(Error::CorruptDatabase);
} }
@ -257,7 +254,7 @@ impl StreamArchive {
if fail.kind() == io::ErrorKind::UnexpectedEof { if fail.kind() == io::ErrorKind::UnexpectedEof {
break; break;
} }
return Err(Error::IOError(fail)); return Err(Error::IO(fail));
} }
let name = &name_and_header[0..PAYLOAD_NAME_LEN_BYTES]; let name = &name_and_header[0..PAYLOAD_NAME_LEN_BYTES];
@ -284,7 +281,7 @@ impl StreamArchive {
Err(e) => { Err(e) => {
/* truncated chunk is not fatal */ /* truncated chunk is not fatal */
if e.kind() != io::ErrorKind::UnexpectedEof { if e.kind() != io::ErrorKind::UnexpectedEof {
return Err(Error::IOError(e)); return Err(Error::IO(e));
} }
}, },
} }
@ -340,7 +337,7 @@ impl StreamArchive {
let to_copy = std::cmp::min(entry.payload_info.full_size as usize - offset as usize, buf.len()); let to_copy = std::cmp::min(entry.payload_info.full_size as usize - offset as usize, buf.len());
self.file.read_exact(&mut buf[0..to_copy]) self.file.read_exact(&mut buf[0..to_copy])
.map_err(Error::IOError)?; .map_err(Error::IO)?;
if entry.payload_info.crc != 0 { if entry.payload_info.crc != 0 {
if let CRCCheck::WithCRC = crc_opt { if let CRCCheck::WithCRC = crc_opt {
@ -435,20 +432,18 @@ impl StreamArchive {
} }
/* rewrites the database, discarding entries listed in 'to_discard' */ /* rewrites the database, discarding entries listed in 'to_discard' */
pub fn discard_entries(&mut self, to_discard: &Vec<(FossilizeTag, FossilizeHash)>) -> Result<(), Error> { pub fn discard_entries(&mut self, to_discard: &[(FossilizeTag, FossilizeHash)]) -> Result<(), Error> {
self.write_pos = self.file.seek(io::SeekFrom::Start(0))?; self.write_pos = self.file.seek(io::SeekFrom::Start(0))?;
for v in self.seen_blobs.iter_mut() { for v in self.seen_blobs.iter_mut() {
v.clear(); v.clear();
} }
let mut magic_and_version = [0 as u8; MAGIC_LEN_BYTES]; let mut magic_and_version = [0_u8; MAGIC_LEN_BYTES];
self.file.read_exact(&mut magic_and_version)?; self.file.read_exact(&mut magic_and_version)?;
let version = magic_and_version[15]; let version = magic_and_version[15];
if magic_and_version[0..12] != FOSSILIZE_MAGIC || if magic_and_version[0..12] != FOSSILIZE_MAGIC || !(FOSSILIZE_MIN_COMPAT_VERSION..=FOSSILIZE_VERSION).contains(&version) {
version < FOSSILIZE_MIN_COMPAT_VERSION ||
version > FOSSILIZE_VERSION {
return Err(Error::CorruptDatabase); return Err(Error::CorruptDatabase);
} }
@ -462,7 +457,7 @@ impl StreamArchive {
if fail.kind() == io::ErrorKind::UnexpectedEof { if fail.kind() == io::ErrorKind::UnexpectedEof {
break; break;
} }
return Err(Error::IOError(fail)); return Err(Error::IO(fail));
} }
let name = &name_and_header[0..PAYLOAD_NAME_LEN_BYTES]; let name = &name_and_header[0..PAYLOAD_NAME_LEN_BYTES];
@ -485,7 +480,7 @@ impl StreamArchive {
Err(e) => { Err(e) => {
/* truncated chunk is not fatal */ /* truncated chunk is not fatal */
if e.kind() != io::ErrorKind::UnexpectedEof { if e.kind() != io::ErrorKind::UnexpectedEof {
return Err(Error::IOError(e)); return Err(Error::IO(e));
} }
}, },
} }
@ -502,7 +497,7 @@ impl StreamArchive {
Err(e) => { Err(e) => {
/* truncated chunk is not fatal */ /* truncated chunk is not fatal */
if e.kind() != io::ErrorKind::UnexpectedEof { if e.kind() != io::ErrorKind::UnexpectedEof {
return Err(Error::IOError(e)); return Err(Error::IO(e));
} }
}, },
} }

View file

@ -35,8 +35,14 @@ extern crate gstreamer_video as gst_video;
extern crate gstreamer_audio as gst_audio; extern crate gstreamer_audio as gst_audio;
extern crate once_cell; extern crate once_cell;
use std::fs::File;
use std::io; use std::io;
use std::io::Read; use std::io::Read;
use std::path::Path;
use std::path::PathBuf;
use filetime::FileTime;
use filetime::set_file_handle_times;
#[cfg(target_arch = "x86")] #[cfg(target_arch = "x86")]
mod murmur3_x86_128; mod murmur3_x86_128;
@ -76,6 +82,24 @@ where
a a
} }
fn touch_file<P>(p: P) -> io::Result<()>
where
P: AsRef<Path> + std::fmt::Debug
{
let f = File::create(p)?;
let now = FileTime::now();
set_file_handle_times(&f, Some(now), Some(now))?;
Ok(())
}
fn steam_compat_shader_path() -> Option<PathBuf>
{
match std::env::var("STEAM_COMPAT_SHADER_PATH") {
Err(_) => None,
Ok(c) => Some(Path::new(&c).to_path_buf()),
}
}
/* rust has a hard time with large heap allocations. below macro works around that. /* rust has a hard time with large heap allocations. below macro works around that.
* *
* by @simias from https://github.com/rust-lang/rust/issues/53827 */ * by @simias from https://github.com/rust-lang/rust/issues/53827 */
@ -97,7 +121,7 @@ macro_rules! box_array {
/* you MUST use this to consistently format the hash bytes into a string */ /* you MUST use this to consistently format the hash bytes into a string */
fn format_hash(hash: u128) -> String { fn format_hash(hash: u128) -> String {
return format!("{:032x}", hash); format!("{:032x}", hash)
} }
/* changing this will invalidate the cache. you MUST clear it. */ /* changing this will invalidate the cache. you MUST clear it. */
@ -144,7 +168,7 @@ fn discarding_disabled() -> bool {
Err(_) => { return false; }, Err(_) => { return false; },
Ok(c) => c, Ok(c) => c,
}; };
return v != "0"; v != "0"
} }
fn plugin_init(plugin: &gst::Plugin) -> Result<(), glib::BoolError> { fn plugin_init(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {

View file

@ -34,13 +34,14 @@ use crate::box_array;
use crate::copy_into_array; use crate::copy_into_array;
use crate::BufferedReader; use crate::BufferedReader;
use crate::discarding_disabled; use crate::discarding_disabled;
use crate::steam_compat_shader_path;
use crate::touch_file;
use gst;
use gst::glib; use gst::glib;
use gst::prelude::*; use gst::prelude::*;
use gst::subclass::prelude::*; use gst::subclass::prelude::*;
use gst::EventView; use gst::EventView;
use gst::QueryView; use gst::QueryViewMut;
use std::sync::Mutex; use std::sync::Mutex;
use std::fs; use std::fs;
@ -297,21 +298,33 @@ struct VideoConvState {
our_duration: Option<u64>, our_duration: Option<u64>,
transcoded_tag: u32, transcoded_tag: u32,
need_stream_start: bool,
} }
impl VideoConvState { impl VideoConvState {
fn new() -> Result<VideoConvState, gst::LoggableError> { fn new() -> VideoConvState {
let read_fozdb_path = std::env::var("MEDIACONV_VIDEO_TRANSCODED_FILE").map_err(|_| { let read_fozdb_path = std::env::var("MEDIACONV_VIDEO_TRANSCODED_FILE");
loggable_error!(CAT, "MEDIACONV_VIDEO_TRANSCODED_FILE is not set!")
})?;
let read_fozdb = match fossilize::StreamArchive::new(&read_fozdb_path, OpenOptions::new().read(true), true /* read-only? */, VIDEOCONV_FOZ_NUM_TAGS) { if read_fozdb_path.is_err() {
Ok(s) => Some(s), gst::error!(CAT, "MEDIACONV_VIDEO_TRANSCODED_FILE is not set!")
Err(_) => None, }
let read_fozdb = match read_fozdb_path {
Ok(path) => match fossilize::StreamArchive::new(&path,
OpenOptions::new().read(true),
true /* read-only? */,
VIDEOCONV_FOZ_NUM_TAGS)
{
Ok(s) => Some(s),
Err(_) => None
},
Err(_) => None
}; };
Ok(VideoConvState {
VideoConvState {
transcode_hash: None, transcode_hash: None,
read_fozdb, read_fozdb,
@ -320,21 +333,23 @@ impl VideoConvState {
our_duration: None, our_duration: None,
transcoded_tag: VIDEOCONV_FOZ_TAG_MKVDATA, transcoded_tag: VIDEOCONV_FOZ_TAG_MKVDATA,
})
need_stream_start: true,
}
} }
/* true if the file is transcoded; false if not */ /* true if the file is transcoded; false if not */
fn begin_transcode(&mut self, hash: u128) -> bool { fn begin_transcode(&mut self, hash: u128) -> bool {
if let Some(read_fozdb) = &mut self.read_fozdb { if let Some(read_fozdb) = &mut self.read_fozdb {
if let Ok(transcoded_size) = read_fozdb.entry_size(VIDEOCONV_FOZ_TAG_MKVDATA, hash) { if let Ok(transcoded_size) = read_fozdb.entry_size(VIDEOCONV_FOZ_TAG_MKVDATA, hash) {
gst_log!(CAT, "Found an MKV video for hash {}", format_hash(hash)); gst::log!(CAT, "Found an MKV video for hash {}", format_hash(hash));
self.transcode_hash = Some(hash); self.transcode_hash = Some(hash);
self.our_duration = Some(transcoded_size as u64); self.our_duration = Some(transcoded_size as u64);
self.transcoded_tag = VIDEOCONV_FOZ_TAG_MKVDATA; self.transcoded_tag = VIDEOCONV_FOZ_TAG_MKVDATA;
return true; return true;
} }
if let Ok(transcoded_size) = read_fozdb.entry_size(VIDEOCONV_FOZ_TAG_OGVDATA, hash) { if let Ok(transcoded_size) = read_fozdb.entry_size(VIDEOCONV_FOZ_TAG_OGVDATA, hash) {
gst_log!(CAT, "Found an OGV video for hash {}", format_hash(hash)); gst::log!(CAT, "Found an OGV video for hash {}", format_hash(hash));
self.transcode_hash = Some(hash); self.transcode_hash = Some(hash);
self.our_duration = Some(transcoded_size as u64); self.our_duration = Some(transcoded_size as u64);
self.transcoded_tag = VIDEOCONV_FOZ_TAG_OGVDATA; self.transcoded_tag = VIDEOCONV_FOZ_TAG_OGVDATA;
@ -342,11 +357,19 @@ impl VideoConvState {
} }
} }
gst_log!(CAT, "No transcoded video for {}. Substituting a blank video.", format_hash(hash)); gst::log!(CAT, "No transcoded video for {}. Substituting a blank video.", format_hash(hash));
self.transcode_hash = None; self.transcode_hash = None;
self.our_duration = Some(include_bytes!("../../blank.mkv").len() as u64); self.our_duration = Some(include_bytes!("../../blank.mkv").len() as u64);
match steam_compat_shader_path() {
None => gst::log!(CAT, "env STEAM_COMPAT_SHADER_PATH not set"),
Some(mut path) => {
path.push("placeholder-video-used");
if let Err(e) = touch_file(path) { gst::log!(CAT, "Failed to touch placeholder-video-used file: {:?}", e) }
},
};
false false
} }
@ -390,7 +413,7 @@ impl ObjectSubclass for VideoConv {
VideoConv::catch_panic_pad_function( VideoConv::catch_panic_pad_function(
parent, parent,
|| false, || false,
|videoconv, element| videoconv.sink_event(pad, element, event) |videoconv| videoconv.sink_event(pad, event)
) )
}).build(); }).build();
@ -400,21 +423,21 @@ impl ObjectSubclass for VideoConv {
VideoConv::catch_panic_pad_function( VideoConv::catch_panic_pad_function(
parent, parent,
|| Err(gst::FlowError::Error), || Err(gst::FlowError::Error),
|videoconv, element| videoconv.range(pad, element, offset, in_buf, size) |videoconv| videoconv.range(pad, offset, in_buf, size)
) )
}) })
.query_function(|pad, parent, query| { .query_function(|pad, parent, query| {
VideoConv::catch_panic_pad_function( VideoConv::catch_panic_pad_function(
parent, parent,
|| false, || false,
|videoconv, element| videoconv.src_query(pad, element, query) |videoconv| videoconv.src_query(pad, query)
) )
}) })
.activatemode_function(|pad, parent, mode, active| { .activatemode_function(|pad, parent, mode, active| {
VideoConv::catch_panic_pad_function( VideoConv::catch_panic_pad_function(
parent, parent,
|| Err(loggable_error!(CAT, "Panic activating srcpad with mode")), || Err(loggable_error!(CAT, "Panic activating srcpad with mode")),
|videoconv, element| videoconv.src_activatemode(pad, element, mode, active) |videoconv| videoconv.src_activatemode(pad, mode, active)
) )
}).build(); }).build();
@ -427,14 +450,18 @@ impl ObjectSubclass for VideoConv {
} }
impl ObjectImpl for VideoConv { impl ObjectImpl for VideoConv {
fn constructed(&self, obj: &Self::Type) { fn constructed(&self) {
self.parent_constructed(obj); self.parent_constructed();
let obj = self.obj();
obj.add_pad(&self.sinkpad).unwrap(); obj.add_pad(&self.sinkpad).unwrap();
obj.add_pad(&self.srcpad).unwrap(); obj.add_pad(&self.srcpad).unwrap();
} }
} }
impl GstObjectImpl for VideoConv { }
impl ElementImpl for VideoConv { impl ElementImpl for VideoConv {
fn metadata() -> Option<&'static gst::subclass::ElementMetadata> { fn metadata() -> Option<&'static gst::subclass::ElementMetadata> {
static ELEMENT_METADATA: Lazy<gst::subclass::ElementMetadata> = Lazy::new(|| { static ELEMENT_METADATA: Lazy<gst::subclass::ElementMetadata> = Lazy::new(|| {
@ -485,20 +512,16 @@ impl ElementImpl for VideoConv {
fn change_state( fn change_state(
&self, &self,
element: &super::VideoConv,
transition: gst::StateChange transition: gst::StateChange
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> { ) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
gst_log!(CAT, obj: element, "State transition: {:?}", transition); gst::log!(CAT, imp: self, "State transition: {:?}", transition);
match transition { match transition {
gst::StateChange::NullToReady => { gst::StateChange::NullToReady => {
/* do runtime setup */ /* do runtime setup */
let new_state = VideoConvState::new().map_err(|err| { let new_state = VideoConvState::new();
err.log();
return gst::StateChangeError;
})?;
let mut state = self.state.lock().unwrap(); let mut state = self.state.lock().unwrap();
assert!((*state).is_none()); assert!((*state).is_none());
@ -514,7 +537,7 @@ impl ElementImpl for VideoConv {
_ => (), _ => (),
}; };
self.parent_change_state(element, transition) self.parent_change_state(transition)
/* XXX on ReadyToNull, sodium drops state _again_ here... why? */ /* XXX on ReadyToNull, sodium drops state _again_ here... why? */
} }
@ -551,7 +574,6 @@ impl VideoConv {
fn range( fn range(
&self, &self,
_pad: &gst::Pad, _pad: &gst::Pad,
_element: &super::VideoConv,
offset: u64, offset: u64,
in_buf: Option<&mut gst::BufferRef>, in_buf: Option<&mut gst::BufferRef>,
requested_size: u32, requested_size: u32,
@ -559,17 +581,17 @@ impl VideoConv {
let mut state = self.state.lock().unwrap(); let mut state = self.state.lock().unwrap();
let mut state = match &mut *state { let state = match &mut *state {
Some(s) => s, Some(s) => s,
None => { return Err(gst::FlowError::Error); } None => { return Err(gst::FlowError::Error); }
}; };
if state.upstream_duration.is_none() { if state.upstream_duration.is_none() {
self.query_upstream_duration(&mut state); self.query_upstream_duration(state);
} }
let ups_offset = self.duration_ours_to_upstream(&state, offset).unwrap(); let ups_offset = self.duration_ours_to_upstream(state, offset).unwrap();
let ups_requested_size = self.duration_ours_to_upstream(&state, requested_size as u64).unwrap() as u32; let ups_requested_size = self.duration_ours_to_upstream(state, requested_size as u64).unwrap() as u32;
/* read and ignore upstream bytes */ /* read and ignore upstream bytes */
self.sinkpad.pull_range(ups_offset, ups_requested_size)?; self.sinkpad.pull_range(ups_offset, ups_requested_size)?;
@ -617,10 +639,9 @@ impl VideoConv {
fn sink_event( fn sink_event(
&self, &self,
pad: &gst::Pad, pad: &gst::Pad,
element: &super::VideoConv,
event: gst::Event event: gst::Event
) -> bool { ) -> bool {
gst_log!(CAT, obj:pad, "Got an event {:?}", event); gst::log!(CAT, obj:pad, "Got an event {:?}", event);
match event.view() { match event.view() {
EventView::Caps(_) => { EventView::Caps(_) => {
@ -629,20 +650,17 @@ impl VideoConv {
let caps = { let caps = {
let mut state = self.state.lock().unwrap(); let mut state = self.state.lock().unwrap();
let mut state = match &mut *state { let state = match &mut *state {
Some(s) => s, Some(s) => s,
None => { gst_error!(CAT, "VideoConv not yet in READY state?"); return false; }, None => { gst::error!(CAT, "VideoConv not yet in READY state?"); return false; },
}; };
if !self.sinkpad.activate_mode(gst::PadMode::Pull, true).is_ok() { if self.sinkpad.activate_mode(gst::PadMode::Pull, true).is_err() {
gst_error!(CAT, "Failed to activate sinkpad in pull mode"); gst::error!(CAT, "Failed to activate sinkpad in pull mode");
return false; return false;
} }
if !self.init_transcode(&mut state).is_ok() { self.init_transcode(state);
gst_error!(CAT, "Failed to init transcode");
return false;
}
match state.transcoded_tag { match state.transcoded_tag {
VIDEOCONV_FOZ_TAG_MKVDATA => gst::Caps::builder("video/x-matroska").build(), VIDEOCONV_FOZ_TAG_MKVDATA => gst::Caps::builder("video/x-matroska").build(),
@ -653,7 +671,7 @@ impl VideoConv {
self.srcpad.push_event(gst::event::Caps::new(&caps)) self.srcpad.push_event(gst::event::Caps::new(&caps))
} }
_ => pad.event_default(Some(element), event) _ => gst::Pad::event_default(pad, Some(&*self.obj()), event)
} }
} }
@ -661,12 +679,12 @@ impl VideoConv {
let mut query = gst::query::Duration::new(gst::Format::Bytes); let mut query = gst::query::Duration::new(gst::Format::Bytes);
if self.sinkpad.peer_query(&mut query) { if self.sinkpad.peer_query(&mut query) {
state.upstream_duration = match query.result().try_into().unwrap() { state.upstream_duration = match query.result() {
Some(gst::format::Bytes(size)) => Some(size), gst::GenericFormattedValue::Bytes(Some(size)) => Some(*size),
_ => None, _ => None,
} }
}else{ }else{
gst_warning!(CAT, "upstream duration query failure"); gst::warning!(CAT, "upstream duration query failure");
} }
} }
@ -682,12 +700,11 @@ impl VideoConv {
fn src_query( fn src_query(
&self, &self,
pad: &gst::Pad, pad: &gst::Pad,
element: &super::VideoConv,
query: &mut gst::QueryRef) -> bool query: &mut gst::QueryRef) -> bool
{ {
gst_log!(CAT, obj: pad, "got query: {:?}", query); gst::log!(CAT, obj: pad, "got query: {:?}", query);
match query.view_mut() { match query.view_mut() {
QueryView::Scheduling(mut q) => { QueryViewMut::Scheduling(q) => {
let mut peer_query = gst::query::Scheduling::new(); let mut peer_query = gst::query::Scheduling::new();
let res = self.sinkpad.peer_query(&mut peer_query); let res = self.sinkpad.peer_query(&mut peer_query);
if ! res { if ! res {
@ -700,29 +717,29 @@ impl VideoConv {
q.add_scheduling_modes(&[gst::PadMode::Pull]); q.add_scheduling_modes(&[gst::PadMode::Pull]);
true true
}, },
QueryView::Duration(ref mut q) => { QueryViewMut::Duration(ref mut q) => {
let mut state = self.state.lock().unwrap(); let mut state = self.state.lock().unwrap();
let mut state = match &mut *state { let state = match &mut *state {
Some(s) => s, Some(s) => s,
None => { return false; } None => { return false; }
}; };
if state.upstream_duration.is_none() { if state.upstream_duration.is_none() {
self.query_upstream_duration(&mut state); self.query_upstream_duration(state);
} }
if let Some(sz) = state.our_duration { if let Some(sz) = state.our_duration {
if q.format() == gst::Format::Bytes { if q.format() == gst::Format::Bytes {
q.set(gst::format::Bytes(sz)); q.set(gst::format::Bytes::from_u64(sz));
return true return true
} }
} }
false false
} }
_ => pad.query_default(Some(element), query) _ => gst::Pad::query_default(pad, Some(&*self.obj()), query)
} }
} }
@ -736,7 +753,7 @@ impl VideoConv {
let mut db = &mut db.open(true).fozdb; let mut db = &mut db.open(true).fozdb;
let db = match &mut db { let db = match &mut db {
Some(d) => d, Some(d) => d,
None => { gst_error!(CAT, "Unable to open fozdb!"); return Err(io::Error::new(io::ErrorKind::Other, "unable to open fozdb")); }, None => { gst::error!(CAT, "Unable to open fozdb!"); return Err(io::Error::new(io::ErrorKind::Other, "unable to open fozdb")); },
}; };
let mut chunks = Vec::<u128>::new(); let mut chunks = Vec::<u128>::new();
@ -754,19 +771,16 @@ impl VideoConv {
chunks.push(chunk_hash); chunks.push(chunk_hash);
db.write_entry(VIDEOCONV_FOZ_TAG_VIDEODATA, chunk_hash, &mut BufferedReader::new(&*buf, readed), fossilize::CRCCheck::WithCRC) db.write_entry(VIDEOCONV_FOZ_TAG_VIDEODATA, chunk_hash, &mut BufferedReader::new(&*buf, readed), fossilize::CRCCheck::WithCRC)
.map_err(|e| { gst_warning!(CAT, "Error writing video data to fozdb: {:?}", e); io::Error::new(io::ErrorKind::Other, "error writing video data to fozdb") } )?; .map_err(|e| { gst::warning!(CAT, "Error writing video data to fozdb: {:?}", e); io::Error::new(io::ErrorKind::Other, "error writing video data to fozdb") } )?;
} }
db.write_entry(VIDEOCONV_FOZ_TAG_STREAM, hash, &mut StreamSerializer::new(&chunks), fossilize::CRCCheck::WithCRC) db.write_entry(VIDEOCONV_FOZ_TAG_STREAM, hash, &mut StreamSerializer::new(&chunks), fossilize::CRCCheck::WithCRC)
.map_err(|e| { gst_warning!(CAT, "Error writing stream data to fozdb: {:?}", e); io::Error::new(io::ErrorKind::Other, "error writing stream data to fozdb") } )?; .map_err(|e| { gst::warning!(CAT, "Error writing stream data to fozdb: {:?}", e); io::Error::new(io::ErrorKind::Other, "error writing stream data to fozdb") } )?;
Ok(()) Ok(())
} }
fn init_transcode( fn init_transcode(&self, state: &mut VideoConvState) {
&self,
state: &mut VideoConvState
) -> Result<(), gst::LoggableError> {
if state.transcode_hash.is_none() { if state.transcode_hash.is_none() {
(*DUMP_FOZDB).lock().unwrap().discard_transcoded(); (*DUMP_FOZDB).lock().unwrap().discard_transcoded();
@ -775,18 +789,18 @@ impl VideoConv {
if let Ok(hash) = hash { if let Ok(hash) = hash {
if !state.begin_transcode(hash) { if !state.begin_transcode(hash) {
self.dump_upstream_data(hash).map_err(|_| loggable_error!(CAT, "Dumping file to disk failed"))?; match self.dump_upstream_data(hash) {
Ok(_) => { },
Err(e) => { gst::error!(CAT, "{}", e.to_string())}
}
} }
} }
} }
Ok(())
} }
fn src_activatemode( fn src_activatemode(
&self, &self,
_pad: &gst::Pad, _pad: &gst::Pad,
_element: &super::VideoConv,
mode: gst::PadMode, mode: gst::PadMode,
active: bool active: bool
) -> Result<(), gst::LoggableError> { ) -> Result<(), gst::LoggableError> {
@ -794,15 +808,29 @@ impl VideoConv {
.activate_mode(mode, active)?; .activate_mode(mode, active)?;
if mode == gst::PadMode::Pull { if mode == gst::PadMode::Pull {
let mut state = self.state.lock().unwrap(); let need_stream_start;
let hash;
let mut state = match &mut *state { /* push_event, below, can also grab state and cause a deadlock, so make sure it's
Some(s) => s, * released before calling */
match &mut *self.state.lock().unwrap() {
Some(state) => {
self.init_transcode(state);
need_stream_start = state.need_stream_start;
hash = state.transcode_hash;
},
None => { return Err(loggable_error!(CAT, "VideoConv not yet in READY state?")); } None => { return Err(loggable_error!(CAT, "VideoConv not yet in READY state?")); }
}; };
/* once we're initted in pull mode, we can start transcoding */ if need_stream_start && active && hash.is_some() {
self.init_transcode(&mut state)?; let stream_id = format!("{:032x}", hash.unwrap());
self.srcpad.push_event(gst::event::StreamStart::new(&stream_id));
match &mut *self.state.lock().unwrap() {
Some(state) => { state.need_stream_start = false },
None => { return Err(loggable_error!(CAT, "VideoConv not yet in READY state?")); }
};
}
} }
Ok(()) Ok(())

24
proton
View file

@ -68,8 +68,14 @@ def append_to_env_str(env, variable, append_str, separator):
env[variable] = env[variable] + separator + append_str env[variable] = env[variable] + separator + append_str
def log(msg): def log(msg):
sys.stderr.write(PFX + msg + os.linesep) try:
sys.stderr.flush() sys.stderr.write(PFX + msg + os.linesep)
sys.stderr.flush()
except OSError:
# e.g. see https://github.com/ValveSoftware/Proton/issues/6277
# There's not much we can usefully do about this: printing a
# warning to stderr isn't going to work any better the second time
pass
def file_is_wine_builtin_dll(path): def file_is_wine_builtin_dll(path):
if os.path.islink(path): if os.path.islink(path):
@ -986,17 +992,20 @@ def default_compat_config():
if appid in [ if appid in [
#affected by CW bug 19126 #affected by CW bug 19126
"536280", #Disintegration "536280", #Disintegration
"563840", #LOST EMBER
"707030", #POSTAL 4: No Regerts "707030", #POSTAL 4: No Regerts
"1331440", #FUSER
"1359980", #POSTAL: Brain Damaged
"1766430", #POSTAL Brain Damaged Demo
#fixed by shared resources
"853050", #El Hijo - A Wild West Tale
"1102190", #Monster Train "1102190", #Monster Train
"1110100", #Power Rangers: Battle for the Grid "1110100", #Power Rangers: Battle for the Grid
"1311070", #Greak: Memories of Azur "1311070", #Greak: Memories of Azur
"1331440", #FUSER
"1359980", #POSTAL: Brain Damaged
"1361320", #The Room 4: Old Sins "1361320", #The Room 4: Old Sins
"1421790", #Labyrinth City: Pierre the Maze Detective
"1569550", #Dread X Collection: The Hunt "1569550", #Dread X Collection: The Hunt
"1642370", #Terra Nil Demo "1642370", #Terra Nil Demo
"1766430", #POSTAL Brain Damaged Demo
"1913910", #Nine Sols Demo "1913910", #Nine Sols Demo
#affected by CW bug 19741 #affected by CW bug 19741
@ -1049,6 +1058,9 @@ def default_compat_config():
if appid == "1621680": if appid == "1621680":
ret.add("noforcelgadd") ret.add("noforcelgadd")
if appid == "1341820":
ret.add("gamedrive")
if appid in [ if appid in [
"202990", #Call of Duty: Black Ops II - Multiplayer "202990", #Call of Duty: Black Ops II - Multiplayer
"212910", #Call of Duty: Black Ops II - Zombies "212910", #Call of Duty: Black Ops II - Zombies

2
wine

@ -1 +1 @@
Subproject commit 492470267af486cb24ad0deaa028168eb94618a4 Subproject commit f497ac98efbb3c924a7ab9630963b88e20385ca4