feat: Update iced_video_player to master
This commit is contained in:
231
Cargo.lock
generated
231
Cargo.lock
generated
@@ -1665,7 +1665,8 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "cryoglyph"
|
name = "cryoglyph"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/iced-rs/cryoglyph.git?rev=99b46959369f38a06c11353bf1be81d383b289fc#99b46959369f38a06c11353bf1be81d383b289fc"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "08bc795bdbccdbd461736fb163930a009da6597b226d6f6fce33e7a8eb6ec519"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cosmic-text 0.15.0",
|
"cosmic-text 0.15.0",
|
||||||
"etagere",
|
"etagere",
|
||||||
@@ -1858,47 +1859,9 @@ checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dpi"
|
name = "dpi"
|
||||||
version = "0.1.1"
|
version = "0.1.2"
|
||||||
source = "git+https://github.com/iced-rs/winit.git?rev=05b8ff17a06562f0a10bb46e6eaacbe2a95cb5ed#05b8ff17a06562f0a10bb46e6eaacbe2a95cb5ed"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "drm"
|
|
||||||
version = "0.12.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "98888c4bbd601524c11a7ed63f814b8825f420514f78e96f752c437ae9cbb5d1"
|
checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76"
|
||||||
dependencies = [
|
|
||||||
"bitflags 2.10.0",
|
|
||||||
"bytemuck",
|
|
||||||
"drm-ffi",
|
|
||||||
"drm-fourcc",
|
|
||||||
"rustix 0.38.44",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "drm-ffi"
|
|
||||||
version = "0.8.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "97c98727e48b7ccb4f4aea8cfe881e5b07f702d17b7875991881b41af7278d53"
|
|
||||||
dependencies = [
|
|
||||||
"drm-sys",
|
|
||||||
"rustix 0.38.44",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "drm-fourcc"
|
|
||||||
version = "2.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0aafbcdb8afc29c1a7ee5fbe53b5d62f4565b35a042a662ca9fecd0b54dae6f4"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "drm-sys"
|
|
||||||
version = "0.7.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fd39dde40b6e196c2e8763f23d119ddb1a8714534bf7d77fa97a65b0feda3986"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"linux-raw-sys 0.6.5",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dtor"
|
name = "dtor"
|
||||||
@@ -2557,15 +2520,15 @@ checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gio-sys"
|
name = "gio-sys"
|
||||||
version = "0.21.2"
|
version = "0.20.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "171ed2f6dd927abbe108cfd9eebff2052c335013f5879d55bab0dc1dee19b706"
|
checksum = "521e93a7e56fc89e84aea9a52cfc9436816a4b363b030260b699950ff1336c83"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glib-sys",
|
"glib-sys",
|
||||||
"gobject-sys",
|
"gobject-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"system-deps",
|
"system-deps",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2587,9 +2550,9 @@ checksum = "151665d9be52f9bb40fc7966565d39666f2d1e69233571b71b87791c7e0528b3"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glib"
|
name = "glib"
|
||||||
version = "0.21.4"
|
version = "0.20.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5b9dbecb1c33e483a98be4acfea2ab369e1c28f517c6eadb674537409c25c4b2"
|
checksum = "ffc4b6e352d4716d84d7dde562dd9aee2a7d48beb872dd9ece7f2d1515b2d683"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.10.0",
|
"bitflags 2.10.0",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
@@ -2608,9 +2571,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glib-macros"
|
name = "glib-macros"
|
||||||
version = "0.21.4"
|
version = "0.20.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "880e524e0085f3546cfb38532b2c202c0d64741d9977a6e4aa24704bfc9f19fb"
|
checksum = "e8084af62f09475a3f529b1629c10c429d7600ee1398ae12dd3bf175d74e7145"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck 0.5.0",
|
"heck 0.5.0",
|
||||||
"proc-macro-crate",
|
"proc-macro-crate",
|
||||||
@@ -2621,9 +2584,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glib-sys"
|
name = "glib-sys"
|
||||||
version = "0.21.2"
|
version = "0.20.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d09d3d0fddf7239521674e57b0465dfbd844632fec54f059f7f56112e3f927e1"
|
checksum = "8ab79e1ed126803a8fb827e3de0e2ff95191912b8db65cee467edb56fc4cc215"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"system-deps",
|
"system-deps",
|
||||||
@@ -2683,9 +2646,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gobject-sys"
|
name = "gobject-sys"
|
||||||
version = "0.21.2"
|
version = "0.20.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "538e41d8776173ec107e7b0f2aceced60abc368d7e1d81c1f0e2ecd35f59080d"
|
checksum = "ec9aca94bb73989e3cfdbf8f2e0f1f6da04db4d291c431f444838925c4c63eda"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glib-sys",
|
"glib-sys",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -3016,9 +2979,9 @@ checksum = "12101ecc8225ea6d675bc70263074eab6169079621c2186fe0c66590b2df9681"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gstreamer"
|
name = "gstreamer"
|
||||||
version = "0.24.3"
|
version = "0.23.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "69ac2f12970a2f85a681d2ceaa40c32fe86cc202ead315e0dfa2223a1217cd24"
|
checksum = "8757a87f3706560037a01a9f06a59fcc7bdb0864744dcf73546606e60c4316e1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
@@ -3027,13 +2990,13 @@ dependencies = [
|
|||||||
"glib",
|
"glib",
|
||||||
"gstreamer-sys",
|
"gstreamer-sys",
|
||||||
"itertools 0.14.0",
|
"itertools 0.14.0",
|
||||||
"kstring",
|
|
||||||
"libc",
|
"libc",
|
||||||
"muldiv",
|
"muldiv",
|
||||||
"num-integer",
|
"num-integer",
|
||||||
"num-rational",
|
"num-rational",
|
||||||
|
"once_cell",
|
||||||
"option-operations",
|
"option-operations",
|
||||||
"pastey",
|
"paste",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"thiserror 2.0.17",
|
"thiserror 2.0.17",
|
||||||
@@ -3041,9 +3004,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gstreamer-app"
|
name = "gstreamer-app"
|
||||||
version = "0.24.2"
|
version = "0.23.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0af5d403738faf03494dfd502d223444b4b44feb997ba28ab3f118ee6d40a0b2"
|
checksum = "2e9a883eb21aebcf1289158225c05f7aea5da6ecf71fa7f0ff1ce4d25baf004e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
@@ -3056,9 +3019,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gstreamer-app-sys"
|
name = "gstreamer-app-sys"
|
||||||
version = "0.24.0"
|
version = "0.23.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "aaf1a3af017f9493c34ccc8439cbce5c48f6ddff6ec0514c23996b374ff25f9a"
|
checksum = "94f7ef838306fe51852d503a14dc79ac42de005a59008a05098de3ecdaf05455"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glib-sys",
|
"glib-sys",
|
||||||
"gstreamer-base-sys",
|
"gstreamer-base-sys",
|
||||||
@@ -3069,9 +3032,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gstreamer-base"
|
name = "gstreamer-base"
|
||||||
version = "0.24.2"
|
version = "0.23.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "71ff9b0bbc8041f0c6c8a53b206a6542f86c7d9fa8a7dff3f27d9c374d9f39b4"
|
checksum = "f19a74fd04ffdcb847dd322640f2cf520897129d00a7bcb92fd62a63f3e27404"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atomic_refcell",
|
"atomic_refcell",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
@@ -3083,9 +3046,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gstreamer-base-sys"
|
name = "gstreamer-base-sys"
|
||||||
version = "0.24.2"
|
version = "0.23.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fed78852b92db1459b8f4288f86e6530274073c20be2f94ba642cddaca08b00e"
|
checksum = "87f2fb0037b6d3c5b51f60dea11e667910f33be222308ca5a101450018a09840"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glib-sys",
|
"glib-sys",
|
||||||
"gobject-sys",
|
"gobject-sys",
|
||||||
@@ -3096,17 +3059,47 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gstreamer-sys"
|
name = "gstreamer-sys"
|
||||||
version = "0.24.2"
|
version = "0.23.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a24ae2930e683665832a19ef02466094b09d1f2da5673f001515ed5486aa9377"
|
checksum = "feea73b4d92dbf9c24a203c9cd0bcc740d584f6b5960d5faf359febf288919b2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
|
||||||
"glib-sys",
|
"glib-sys",
|
||||||
"gobject-sys",
|
"gobject-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"system-deps",
|
"system-deps",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gstreamer-video"
|
||||||
|
version = "0.23.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1318b599d77ca4f7702ecbdeac1672d6304cb16b7e5752fabb3ee8260449a666"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"futures-channel",
|
||||||
|
"glib",
|
||||||
|
"gstreamer",
|
||||||
|
"gstreamer-base",
|
||||||
|
"gstreamer-video-sys",
|
||||||
|
"libc",
|
||||||
|
"once_cell",
|
||||||
|
"thiserror 2.0.17",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gstreamer-video-sys"
|
||||||
|
version = "0.23.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0a70f0947f12d253b9de9bc3fd92f981e4d025336c18389c7f08cdf388a99f5c"
|
||||||
|
dependencies = [
|
||||||
|
"glib-sys",
|
||||||
|
"gobject-sys",
|
||||||
|
"gstreamer-base-sys",
|
||||||
|
"gstreamer-sys",
|
||||||
|
"libc",
|
||||||
|
"system-deps",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "guillotiere"
|
name = "guillotiere"
|
||||||
version = "0.6.2"
|
version = "0.6.2"
|
||||||
@@ -3376,8 +3369,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced"
|
name = "iced"
|
||||||
version = "0.14.0-dev"
|
version = "0.14.0"
|
||||||
source = "git+https://github.com/iced-rs/iced#8bfd099c5929d927a3fdde666d4c645d0bd83cb7"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "000e01026c93ba643f8357a3db3ada0e6555265a377f6f9291c472f6dd701fb3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"iced_core",
|
"iced_core",
|
||||||
"iced_debug",
|
"iced_debug",
|
||||||
@@ -3393,8 +3387,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_beacon"
|
name = "iced_beacon"
|
||||||
version = "0.14.0-dev"
|
version = "0.14.0"
|
||||||
source = "git+https://github.com/iced-rs/iced#8bfd099c5929d927a3fdde666d4c645d0bd83cb7"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "02a48f970444257a5e8b19def673f14f0d79c159fa851055e2a861683c3f8845"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"futures",
|
"futures",
|
||||||
@@ -3408,8 +3403,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_core"
|
name = "iced_core"
|
||||||
version = "0.14.0-dev"
|
version = "0.14.0"
|
||||||
source = "git+https://github.com/iced-rs/iced#8bfd099c5929d927a3fdde666d4c645d0bd83cb7"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "91ab1937d699403e7e69252ae743a902bcee9f4ab2052cc4c9a46fcf34729d85"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.10.0",
|
"bitflags 2.10.0",
|
||||||
"bytes",
|
"bytes",
|
||||||
@@ -3426,8 +3422,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_debug"
|
name = "iced_debug"
|
||||||
version = "0.14.0-dev"
|
version = "0.14.0"
|
||||||
source = "git+https://github.com/iced-rs/iced#8bfd099c5929d927a3fdde666d4c645d0bd83cb7"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "25035ab0215a620e53f4103e36fc4e59a1fb2817e4bfc38a30ad27b4202ea0be"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"iced_beacon",
|
"iced_beacon",
|
||||||
"iced_core",
|
"iced_core",
|
||||||
@@ -3437,8 +3434,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_devtools"
|
name = "iced_devtools"
|
||||||
version = "0.14.0-dev"
|
version = "0.14.0"
|
||||||
source = "git+https://github.com/iced-rs/iced#8bfd099c5929d927a3fdde666d4c645d0bd83cb7"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "59b8e2a306ac5c583234b02f5404afdb7b7467c8f72a4a44ad3e7be30fc4b339"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"iced_debug",
|
"iced_debug",
|
||||||
"iced_program",
|
"iced_program",
|
||||||
@@ -3448,8 +3446,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_futures"
|
name = "iced_futures"
|
||||||
version = "0.14.0-dev"
|
version = "0.14.0"
|
||||||
source = "git+https://github.com/iced-rs/iced#8bfd099c5929d927a3fdde666d4c645d0bd83cb7"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8c0c85ccad42dfbec7293c36c018af0ea0dbcc52d137a4a9a0b0f6822a3fdf0a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures",
|
"futures",
|
||||||
"iced_core",
|
"iced_core",
|
||||||
@@ -3462,8 +3461,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_graphics"
|
name = "iced_graphics"
|
||||||
version = "0.14.0-dev"
|
version = "0.14.0"
|
||||||
source = "git+https://github.com/iced-rs/iced#8bfd099c5929d927a3fdde666d4c645d0bd83cb7"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "234ca1c2cec4155055f68fa5fad1b5242c496ac8238d80a259bca382fb44a102"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.10.0",
|
"bitflags 2.10.0",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
@@ -3483,8 +3483,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_program"
|
name = "iced_program"
|
||||||
version = "0.14.0-dev"
|
version = "0.14.0"
|
||||||
source = "git+https://github.com/iced-rs/iced#8bfd099c5929d927a3fdde666d4c645d0bd83cb7"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6dfafec2947cda688d8eb00dac337ba11aa60f9ef6335aed343e189d26e4a673"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"iced_graphics",
|
"iced_graphics",
|
||||||
"iced_runtime",
|
"iced_runtime",
|
||||||
@@ -3492,8 +3493,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_renderer"
|
name = "iced_renderer"
|
||||||
version = "0.14.0-dev"
|
version = "0.14.0"
|
||||||
source = "git+https://github.com/iced-rs/iced#8bfd099c5929d927a3fdde666d4c645d0bd83cb7"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "250cc0802408e8c077986ec56c7d07c65f423ee658a4b9fd795a1f2aae5dac05"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"iced_graphics",
|
"iced_graphics",
|
||||||
"iced_tiny_skia",
|
"iced_tiny_skia",
|
||||||
@@ -3504,8 +3506,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_runtime"
|
name = "iced_runtime"
|
||||||
version = "0.14.0-dev"
|
version = "0.14.0"
|
||||||
source = "git+https://github.com/iced-rs/iced#8bfd099c5929d927a3fdde666d4c645d0bd83cb7"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d1889b819ce4c06674183242e336c8d49465665441396914dc07cc86f44fa8d4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"iced_core",
|
"iced_core",
|
||||||
@@ -3517,8 +3520,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_tiny_skia"
|
name = "iced_tiny_skia"
|
||||||
version = "0.14.0-dev"
|
version = "0.14.0"
|
||||||
source = "git+https://github.com/iced-rs/iced#8bfd099c5929d927a3fdde666d4c645d0bd83cb7"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fe0acf8b75a3bc914aff5f2329fdffc1b36eeaea29dda0e4bd232f1c62e9cc3d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"cosmic-text 0.15.0",
|
"cosmic-text 0.15.0",
|
||||||
@@ -3539,17 +3543,19 @@ dependencies = [
|
|||||||
"gstreamer",
|
"gstreamer",
|
||||||
"gstreamer-app",
|
"gstreamer-app",
|
||||||
"gstreamer-base",
|
"gstreamer-base",
|
||||||
|
"gstreamer-video",
|
||||||
"iced",
|
"iced",
|
||||||
"iced_wgpu",
|
"iced_wgpu",
|
||||||
"log",
|
"log",
|
||||||
"thiserror 2.0.17",
|
"thiserror 1.0.69",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_wgpu"
|
name = "iced_wgpu"
|
||||||
version = "0.14.0-dev"
|
version = "0.14.0"
|
||||||
source = "git+https://github.com/iced-rs/iced#8bfd099c5929d927a3fdde666d4c645d0bd83cb7"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ff144a999b0ca0f8a10257934500060240825c42e950ec0ebee9c8ae30561c13"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.10.0",
|
"bitflags 2.10.0",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
@@ -3568,8 +3574,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_widget"
|
name = "iced_widget"
|
||||||
version = "0.14.0-dev"
|
version = "0.14.1"
|
||||||
source = "git+https://github.com/iced-rs/iced#8bfd099c5929d927a3fdde666d4c645d0bd83cb7"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f86f6948998a5e031849afae1bb852f3b100c71572befa0be70b19075dcb2163"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"iced_renderer",
|
"iced_renderer",
|
||||||
"log",
|
"log",
|
||||||
@@ -3581,8 +3588,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iced_winit"
|
name = "iced_winit"
|
||||||
version = "0.14.0-dev"
|
version = "0.14.0"
|
||||||
source = "git+https://github.com/iced-rs/iced#8bfd099c5929d927a3fdde666d4c645d0bd83cb7"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b7dbedc47562d1de3b9707d939f678b88c382004b7ab5a18f7a7dd723162d75"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"iced_debug",
|
"iced_debug",
|
||||||
"iced_program",
|
"iced_program",
|
||||||
@@ -4041,15 +4049,6 @@ version = "3.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
|
checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "kstring"
|
|
||||||
version = "2.0.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "558bf9508a558512042d3095138b1f7b8fe90c5467d94f9f1da28b3731c5dbd1"
|
|
||||||
dependencies = [
|
|
||||||
"static_assertions",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kurbo"
|
name = "kurbo"
|
||||||
version = "0.10.4"
|
version = "0.10.4"
|
||||||
@@ -4174,12 +4173,6 @@ version = "0.4.15"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
|
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "linux-raw-sys"
|
|
||||||
version = "0.6.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2a385b1be4e5c3e362ad2ffa73c392e53f031eaa5b7d648e64cd87f27f6063d7"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linux-raw-sys"
|
name = "linux-raw-sys"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
@@ -5309,11 +5302,11 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "option-operations"
|
name = "option-operations"
|
||||||
version = "0.6.0"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b31ce827892359f23d3cd1cc4c75a6c241772bbd2db17a92dcf27cbefdf52689"
|
checksum = "7c26d27bb1aeab65138e4bf7666045169d1717febcc9ff870166be8348b223d0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pastey",
|
"paste",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -6855,7 +6848,6 @@ dependencies = [
|
|||||||
"bytemuck",
|
"bytemuck",
|
||||||
"cfg_aliases",
|
"cfg_aliases",
|
||||||
"core-graphics 0.24.0",
|
"core-graphics 0.24.0",
|
||||||
"drm",
|
|
||||||
"fastrand 2.3.0",
|
"fastrand 2.3.0",
|
||||||
"foreign-types 0.5.0",
|
"foreign-types 0.5.0",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
@@ -8592,9 +8584,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "window_clipboard"
|
name = "window_clipboard"
|
||||||
version = "0.4.1"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f6d692d46038c433f9daee7ad8757e002a4248c20b0a3fbc991d99521d3bcb6d"
|
checksum = "5793d0b08c9e6a1240fe9ab2bd8db277487bf92436fd1a6321861a90a1b0cb7e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clipboard-win",
|
"clipboard-win",
|
||||||
"clipboard_macos",
|
"clipboard_macos",
|
||||||
@@ -9208,8 +9200,9 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winit"
|
name = "winit"
|
||||||
version = "0.30.8"
|
version = "0.30.12"
|
||||||
source = "git+https://github.com/iced-rs/winit.git?rev=05b8ff17a06562f0a10bb46e6eaacbe2a95cb5ed#05b8ff17a06562f0a10bb46e6eaacbe2a95cb5ed"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c66d4b9ed69c4009f6321f762d6e61ad8a2389cd431b97cb1e146812e9e6c732"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash",
|
||||||
"android-activity",
|
"android-activity",
|
||||||
|
|||||||
@@ -5,10 +5,12 @@ members = [
|
|||||||
"typegen",
|
"typegen",
|
||||||
"ui-gpui",
|
"ui-gpui",
|
||||||
"ui-iced",
|
"ui-iced",
|
||||||
"crates/iced_video_player", "store", "jello-types",
|
"crates/iced_video_player",
|
||||||
|
"store",
|
||||||
|
"jello-types",
|
||||||
]
|
]
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
iced = { git = "https://github.com/iced-rs/iced", features = [
|
iced = { version = "0.14.0", features = [
|
||||||
"advanced",
|
"advanced",
|
||||||
"canvas",
|
"canvas",
|
||||||
"image",
|
"image",
|
||||||
@@ -16,6 +18,7 @@ iced = { git = "https://github.com/iced-rs/iced", features = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
"debug",
|
"debug",
|
||||||
] }
|
] }
|
||||||
|
# iced_video_player = { git = "https://github.com/jazzfool/iced_video_player" }
|
||||||
iced_video_player = { path = "crates/iced_video_player" }
|
iced_video_player = { path = "crates/iced_video_player" }
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
|
|||||||
3
crates/iced_video_player/.gitignore
vendored
3
crates/iced_video_player/.gitignore
vendored
@@ -1,3 +1,2 @@
|
|||||||
/target
|
/target
|
||||||
.direnv
|
.direnv
|
||||||
.media
|
|
||||||
1999
crates/iced_video_player/Cargo.lock
generated
1999
crates/iced_video_player/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -8,24 +8,23 @@ keywords = ["gui", "iced", "video"]
|
|||||||
categories = ["gui", "multimedia"]
|
categories = ["gui", "multimedia"]
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
authors = ["jazzfool"]
|
authors = ["jazzfool"]
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
exclude = [".media/test.mp4"]
|
exclude = [
|
||||||
|
".media/test.mp4"
|
||||||
|
]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
iced = { git = "https://github.com/iced-rs/iced", features = [
|
iced = { version = "0.14", features = ["image", "advanced", "wgpu"] }
|
||||||
"image",
|
iced_wgpu = "0.14"
|
||||||
"advanced",
|
gstreamer = "0.23"
|
||||||
"wgpu",
|
gstreamer-app = "0.23" # appsink
|
||||||
] }
|
gstreamer-base = "0.23" # basesrc
|
||||||
iced_wgpu = { git = "https://github.com/iced-rs/iced" }
|
gstreamer-video = "0.23" # VideoMeta
|
||||||
gstreamer = { version = "0.24", features = ["v1_26"] }
|
glib = "0.20" # gobject traits and error type
|
||||||
gstreamer-app = { version = "0.24", features = ["v1_26"] } # appsink
|
|
||||||
gstreamer-base = { version = "0.24", features = ["v1_26"] } # basesrc
|
|
||||||
glib = "0.21" # gobject traits and error type
|
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
thiserror = "2"
|
thiserror = "1"
|
||||||
url = "2" # media uri
|
url = "2" # media uri
|
||||||
|
|
||||||
[package.metadata.nix]
|
[package.metadata.nix]
|
||||||
@@ -33,33 +32,15 @@ systems = ["x86_64-linux"]
|
|||||||
app = true
|
app = true
|
||||||
build = true
|
build = true
|
||||||
runtimeLibs = [
|
runtimeLibs = [
|
||||||
"vulkan-loader",
|
"vulkan-loader",
|
||||||
"wayland",
|
"wayland",
|
||||||
"wayland-protocols",
|
"wayland-protocols",
|
||||||
"libxkbcommon",
|
"libxkbcommon",
|
||||||
"xorg.libX11",
|
"xorg.libX11",
|
||||||
"xorg.libXrandr",
|
"xorg.libXrandr",
|
||||||
"xorg.libXi",
|
"xorg.libXi", "gst_all_1.gstreamer", "gst_all_1.gstreamermm", "gst_all_1.gst-plugins-bad", "gst_all_1.gst-plugins-ugly", "gst_all_1.gst-plugins-good", "gst_all_1.gst-plugins-base",
|
||||||
"gst_all_1.gstreamer",
|
|
||||||
"gst_all_1.gstreamermm",
|
|
||||||
"gst_all_1.gst-plugins-bad",
|
|
||||||
"gst_all_1.gst-plugins-ugly",
|
|
||||||
"gst_all_1.gst-plugins-good",
|
|
||||||
"gst_all_1.gst-plugins-base",
|
|
||||||
"glib",
|
|
||||||
"glib-networking",
|
|
||||||
]
|
|
||||||
buildInputs = [
|
|
||||||
"libxkbcommon",
|
|
||||||
"gst_all_1.gstreamer",
|
|
||||||
"gst_all_1.gstreamermm",
|
|
||||||
"gst_all_1.gst-plugins-bad",
|
|
||||||
"gst_all_1.gst-plugins-ugly",
|
|
||||||
"gst_all_1.gst-plugins-good",
|
|
||||||
"gst_all_1.gst-plugins-base",
|
|
||||||
"glib",
|
|
||||||
"glib-networking",
|
|
||||||
]
|
]
|
||||||
|
buildInputs = ["libxkbcommon", "gst_all_1.gstreamer", "gst_all_1.gstreamermm", "gst_all_1.gst-plugins-bad", "gst_all_1.gst-plugins-ugly", "gst_all_1.gst-plugins-good", "gst_all_1.gst-plugins-base"]
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
rustc-args = ["--cfg", "docsrs"]
|
rustc-args = ["--cfg", "docsrs"]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use iced::{
|
use iced::{
|
||||||
widget::{Button, Column, Container, Row, Slider, Text},
|
|
||||||
Element,
|
Element,
|
||||||
|
widget::{Button, Column, Container, Row, Slider, Text},
|
||||||
};
|
};
|
||||||
use iced_video_player::{Video, VideoPlayer};
|
use iced_video_player::{Video, VideoPlayer};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
@@ -29,10 +29,17 @@ impl Default for App {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
App {
|
App {
|
||||||
video: Video::new(
|
video: Video::new(
|
||||||
&url::Url::parse("https://jellyfin.tsuba.darksailor.dev/Videos/1d7e2012-e17d-edbb-25c3-2dbcc803d6b6/stream?static=true")
|
&url::Url::from_file_path(
|
||||||
.expect("Failed to parse URL"),
|
std::path::PathBuf::from(file!())
|
||||||
|
.parent()
|
||||||
|
.unwrap()
|
||||||
|
.join("../.media/test.mp4")
|
||||||
|
.canonicalize()
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
)
|
)
|
||||||
.expect("Failed to create video"),
|
.unwrap(),
|
||||||
position: 0.0,
|
position: 0.0,
|
||||||
dragging: false,
|
dragging: false,
|
||||||
}
|
}
|
||||||
|
|||||||
225
crates/iced_video_player/flake.lock
generated
225
crates/iced_video_player/flake.lock
generated
@@ -1,69 +1,28 @@
|
|||||||
{
|
{
|
||||||
"nodes": {
|
"nodes": {
|
||||||
"crane": {
|
"devshell": {
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1758758545,
|
"lastModified": 1629275356,
|
||||||
"narHash": "sha256-NU5WaEdfwF6i8faJ2Yh+jcK9vVFrofLcwlD/mP65JrI=",
|
"narHash": "sha256-R17M69EKXP6q8/mNHaK53ECwjFo1pdF+XaJC9Qq8zjg=",
|
||||||
"owner": "ipetkov",
|
"owner": "numtide",
|
||||||
"repo": "crane",
|
"repo": "devshell",
|
||||||
"rev": "95d528a5f54eaba0d12102249ce42f4d01f4e364",
|
"rev": "26f25a12265f030917358a9632cd600b51af1d97",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "ipetkov",
|
"owner": "numtide",
|
||||||
"ref": "v0.21.1",
|
"repo": "devshell",
|
||||||
"repo": "crane",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dream2nix": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": [
|
|
||||||
"nixCargoIntegration",
|
|
||||||
"nixpkgs"
|
|
||||||
],
|
|
||||||
"purescript-overlay": "purescript-overlay",
|
|
||||||
"pyproject-nix": "pyproject-nix"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1763413832,
|
|
||||||
"narHash": "sha256-dkqBwDXiv8MPoFyIvOuC4bVubAP+TlVZUkVMB78TTSg=",
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "dream2nix",
|
|
||||||
"rev": "5658fba3a0b6b7d5cb0460b949651f64f644a743",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "dream2nix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flake-compat": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1696426674,
|
|
||||||
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
|
|
||||||
"owner": "edolstra",
|
|
||||||
"repo": "flake-compat",
|
|
||||||
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "edolstra",
|
|
||||||
"repo": "flake-compat",
|
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flakeCompat": {
|
"flakeCompat": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1761588595,
|
"lastModified": 1627913399,
|
||||||
"narHash": "sha256-XKUZz9zewJNUj46b4AJdiRZJAvSZ0Dqj2BNfXvFlJC4=",
|
"narHash": "sha256-hY8g6H2KFL8ownSiFeMOjwPC8P0ueXpCVEbxgda3pko=",
|
||||||
"owner": "edolstra",
|
"owner": "edolstra",
|
||||||
"repo": "flake-compat",
|
"repo": "flake-compat",
|
||||||
"rev": "f387cd2afec9419c8ee37694406ca490c3f34ee5",
|
"rev": "12c64ca55c1014cdc1b16ed5a804aa8576601ff2",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -72,40 +31,20 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mk-naked-shell": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1681286841,
|
|
||||||
"narHash": "sha256-3XlJrwlR0nBiREnuogoa5i1b4+w/XPe0z8bbrJASw0g=",
|
|
||||||
"owner": "90-008",
|
|
||||||
"repo": "mk-naked-shell",
|
|
||||||
"rev": "7612f828dd6f22b7fb332cc69440e839d7ffe6bd",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "90-008",
|
|
||||||
"repo": "mk-naked-shell",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixCargoIntegration": {
|
"nixCargoIntegration": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"crane": "crane",
|
"devshell": "devshell",
|
||||||
"dream2nix": "dream2nix",
|
|
||||||
"mk-naked-shell": "mk-naked-shell",
|
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
],
|
],
|
||||||
"parts": "parts",
|
"rustOverlay": "rustOverlay"
|
||||||
"rust-overlay": "rust-overlay",
|
|
||||||
"treefmt": "treefmt"
|
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1763619566,
|
"lastModified": 1629871751,
|
||||||
"narHash": "sha256-92rSHIwh5qTXjcktVEWyKu5EPB3/7UdgjgjtWZ5ET6w=",
|
"narHash": "sha256-QjnDg34ApcnjmXlNLnbHswT9OroCPY7Wip6r9Zkgkfo=",
|
||||||
"owner": "yusdacra",
|
"owner": "yusdacra",
|
||||||
"repo": "nix-cargo-integration",
|
"repo": "nix-cargo-integration",
|
||||||
"rev": "ac45d8c0d6876e6547d62bc729654c7b9a79c760",
|
"rev": "4f164ecad242537d5893426eef02c47c9e5ced59",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -116,11 +55,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1763421233,
|
"lastModified": 1629618782,
|
||||||
"narHash": "sha256-Stk9ZYRkGrnnpyJ4eqt9eQtdFWRRIvMxpNRf4sIegnw=",
|
"narHash": "sha256-2K8SSXu3alo/URI3MClGdDSns6Gb4ZaW4LET53UWyKk=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "89c2b2330e733d6cdb5eae7b899326930c2c0648",
|
"rev": "870959c7fb3a42af1863bed9e1756086a74eb649",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -130,73 +69,6 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"parts": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs-lib": [
|
|
||||||
"nixCargoIntegration",
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1762980239,
|
|
||||||
"narHash": "sha256-8oNVE8TrD19ulHinjaqONf9QWCKK+w4url56cdStMpM=",
|
|
||||||
"owner": "hercules-ci",
|
|
||||||
"repo": "flake-parts",
|
|
||||||
"rev": "52a2caecc898d0b46b2b905f058ccc5081f842da",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "hercules-ci",
|
|
||||||
"repo": "flake-parts",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"purescript-overlay": {
|
|
||||||
"inputs": {
|
|
||||||
"flake-compat": "flake-compat",
|
|
||||||
"nixpkgs": [
|
|
||||||
"nixCargoIntegration",
|
|
||||||
"dream2nix",
|
|
||||||
"nixpkgs"
|
|
||||||
],
|
|
||||||
"slimlock": "slimlock"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1728546539,
|
|
||||||
"narHash": "sha256-Sws7w0tlnjD+Bjck1nv29NjC5DbL6nH5auL9Ex9Iz2A=",
|
|
||||||
"owner": "thomashoneyman",
|
|
||||||
"repo": "purescript-overlay",
|
|
||||||
"rev": "4ad4c15d07bd899d7346b331f377606631eb0ee4",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "thomashoneyman",
|
|
||||||
"repo": "purescript-overlay",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pyproject-nix": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": [
|
|
||||||
"nixCargoIntegration",
|
|
||||||
"dream2nix",
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1752481895,
|
|
||||||
"narHash": "sha256-luVj97hIMpCbwhx3hWiRwjP2YvljWy8FM+4W9njDhLA=",
|
|
||||||
"owner": "pyproject-nix",
|
|
||||||
"repo": "pyproject.nix",
|
|
||||||
"rev": "16ee295c25107a94e59a7fc7f2e5322851781162",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "pyproject-nix",
|
|
||||||
"repo": "pyproject.nix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flakeCompat": "flakeCompat",
|
"flakeCompat": "flakeCompat",
|
||||||
@@ -204,19 +76,14 @@
|
|||||||
"nixpkgs": "nixpkgs"
|
"nixpkgs": "nixpkgs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"rust-overlay": {
|
"rustOverlay": {
|
||||||
"inputs": {
|
"flake": false,
|
||||||
"nixpkgs": [
|
|
||||||
"nixCargoIntegration",
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1763606317,
|
"lastModified": 1629857564,
|
||||||
"narHash": "sha256-lsq4Urmb9Iyg2zyg2yG6oMQk9yuaoIgy+jgvYM4guxA=",
|
"narHash": "sha256-dClWiHkbaCDaIl520Miri66UOA8OecWbaVTWJBajHyM=",
|
||||||
"owner": "oxalica",
|
"owner": "oxalica",
|
||||||
"repo": "rust-overlay",
|
"repo": "rust-overlay",
|
||||||
"rev": "a5615abaf30cfaef2e32f1ff9bd5ca94e2911371",
|
"rev": "88848c36934318e16c86097f65dbf97a57968d81",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -224,50 +91,6 @@
|
|||||||
"repo": "rust-overlay",
|
"repo": "rust-overlay",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"slimlock": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": [
|
|
||||||
"nixCargoIntegration",
|
|
||||||
"dream2nix",
|
|
||||||
"purescript-overlay",
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1688756706,
|
|
||||||
"narHash": "sha256-xzkkMv3neJJJ89zo3o2ojp7nFeaZc2G0fYwNXNJRFlo=",
|
|
||||||
"owner": "thomashoneyman",
|
|
||||||
"repo": "slimlock",
|
|
||||||
"rev": "cf72723f59e2340d24881fd7bf61cb113b4c407c",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "thomashoneyman",
|
|
||||||
"repo": "slimlock",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"treefmt": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": [
|
|
||||||
"nixCargoIntegration",
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1762938485,
|
|
||||||
"narHash": "sha256-AlEObg0syDl+Spi4LsZIBrjw+snSVU4T8MOeuZJUJjM=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "treefmt-nix",
|
|
||||||
"rev": "5b4ee75aeefd1e2d5a1cc43cf6ba65eba75e83e4",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "treefmt-nix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root": "root",
|
"root": "root",
|
||||||
|
|||||||
@@ -11,28 +11,18 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = inputs: let
|
outputs = inputs:
|
||||||
pkgs = import inputs.nixpkgs {
|
inputs.nixCargoIntegration.lib.makeOutputs {
|
||||||
system = "x86_64-linux";
|
root = ./.;
|
||||||
|
overrides = {
|
||||||
|
shell = common: prev: {
|
||||||
|
env = prev.env ++ [
|
||||||
|
{
|
||||||
|
name = "GST_PLUGIN_PATH";
|
||||||
|
value = "${common.pkgs.gst_all_1.gstreamer}:${common.pkgs.gst_all_1.gst-plugins-bad}:${common.pkgs.gst_all_1.gst-plugins-ugly}:${common.pkgs.gst_all_1.gst-plugins-good}:${common.pkgs.gst_all_1.gst-plugins-base}";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
in {
|
|
||||||
devShells."x86_64-linux".default = pkgs.mkShell {
|
|
||||||
# "GST_PLUGIN_PATH" = "${pkgs.gst_all_1.gstreamer}:${pkgs.gst_all_1.gst-plugins-bad}:${pkgs.gst_all_1.gst-plugins-ugly}:${pkgs.gst_all_1.gst-plugins-good}:${pkgs.gst_all_1.gst-plugins-base}";
|
|
||||||
buildInputs = with pkgs; [
|
|
||||||
gst_all_1.gstreamer
|
|
||||||
gst_all_1.gst-plugins-bad
|
|
||||||
gst_all_1.gst-plugins-ugly
|
|
||||||
gst_all_1.gst-plugins-good
|
|
||||||
gst_all_1.gst-plugins-base
|
|
||||||
libxkbcommon
|
|
||||||
wayland
|
|
||||||
rustup
|
|
||||||
];
|
|
||||||
nativeBuildInputs = with pkgs; [
|
|
||||||
pkg-config
|
|
||||||
wayland
|
|
||||||
];
|
|
||||||
packages = with pkgs; [wayland];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
use crate::video::Frame;
|
use crate::video::Frame;
|
||||||
use iced_wgpu::primitive::Primitive;
|
use iced_wgpu::primitive::{Pipeline, Primitive};
|
||||||
use iced_wgpu::wgpu;
|
use iced_wgpu::wgpu;
|
||||||
use std::{
|
use std::{
|
||||||
collections::{btree_map::Entry, BTreeMap},
|
collections::{BTreeMap, btree_map::Entry},
|
||||||
num::NonZero,
|
num::NonZero,
|
||||||
sync::{
|
sync::{
|
||||||
atomic::{AtomicBool, AtomicUsize, Ordering},
|
|
||||||
Arc, Mutex,
|
Arc, Mutex,
|
||||||
|
atomic::{AtomicBool, AtomicUsize, Ordering},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -35,8 +35,8 @@ pub(crate) struct VideoPipeline {
|
|||||||
videos: BTreeMap<u64, VideoEntry>,
|
videos: BTreeMap<u64, VideoEntry>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VideoPipeline {
|
impl Pipeline for VideoPipeline {
|
||||||
fn new(device: &wgpu::Device, format: wgpu::TextureFormat) -> Self {
|
fn new(device: &wgpu::Device, _queue: &wgpu::Queue, format: wgpu::TextureFormat) -> Self {
|
||||||
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
||||||
label: Some("iced_video_player shader"),
|
label: Some("iced_video_player shader"),
|
||||||
source: wgpu::ShaderSource::Wgsl(include_str!("shader.wgsl").into()),
|
source: wgpu::ShaderSource::Wgsl(include_str!("shader.wgsl").into()),
|
||||||
@@ -97,7 +97,7 @@ impl VideoPipeline {
|
|||||||
module: &shader,
|
module: &shader,
|
||||||
entry_point: Some("vs_main"),
|
entry_point: Some("vs_main"),
|
||||||
buffers: &[],
|
buffers: &[],
|
||||||
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
compilation_options: Default::default(),
|
||||||
},
|
},
|
||||||
primitive: wgpu::PrimitiveState::default(),
|
primitive: wgpu::PrimitiveState::default(),
|
||||||
depth_stencil: None,
|
depth_stencil: None,
|
||||||
@@ -114,7 +114,7 @@ impl VideoPipeline {
|
|||||||
blend: None,
|
blend: None,
|
||||||
write_mask: wgpu::ColorWrites::ALL,
|
write_mask: wgpu::ColorWrites::ALL,
|
||||||
})],
|
})],
|
||||||
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
compilation_options: Default::default(),
|
||||||
}),
|
}),
|
||||||
multiview: None,
|
multiview: None,
|
||||||
cache: None,
|
cache: None,
|
||||||
@@ -143,6 +143,23 @@ impl VideoPipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn trim(&mut self) {
|
||||||
|
let ids: Vec<_> = self
|
||||||
|
.videos
|
||||||
|
.iter()
|
||||||
|
.filter_map(|(id, entry)| (!entry.alive.load(Ordering::SeqCst)).then_some(*id))
|
||||||
|
.collect();
|
||||||
|
for id in ids {
|
||||||
|
if let Some(video) = self.videos.remove(&id) {
|
||||||
|
video.texture_y.destroy();
|
||||||
|
video.texture_uv.destroy();
|
||||||
|
video.instances.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VideoPipeline {
|
||||||
fn upload(
|
fn upload(
|
||||||
&mut self,
|
&mut self,
|
||||||
device: &wgpu::Device,
|
device: &wgpu::Device,
|
||||||
@@ -151,7 +168,10 @@ impl VideoPipeline {
|
|||||||
alive: &Arc<AtomicBool>,
|
alive: &Arc<AtomicBool>,
|
||||||
(width, height): (u32, u32),
|
(width, height): (u32, u32),
|
||||||
frame: &[u8],
|
frame: &[u8],
|
||||||
|
stride: Option<u32>,
|
||||||
) {
|
) {
|
||||||
|
// Use stride from GStreamer's VideoMeta if available, otherwise assume stride == width
|
||||||
|
let stride = stride.unwrap_or(width);
|
||||||
if let Entry::Vacant(entry) = self.videos.entry(video_id) {
|
if let Entry::Vacant(entry) = self.videos.entry(video_id) {
|
||||||
let texture_y = device.create_texture(&wgpu::TextureDescriptor {
|
let texture_y = device.create_texture(&wgpu::TextureDescriptor {
|
||||||
label: Some("iced_video_player texture"),
|
label: Some("iced_video_player texture"),
|
||||||
@@ -192,7 +212,7 @@ impl VideoPipeline {
|
|||||||
mip_level_count: None,
|
mip_level_count: None,
|
||||||
base_array_layer: 0,
|
base_array_layer: 0,
|
||||||
array_layer_count: None,
|
array_layer_count: None,
|
||||||
usage: Some(wgpu::TextureUsages::empty()),
|
usage: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
let view_uv = texture_uv.create_view(&wgpu::TextureViewDescriptor {
|
let view_uv = texture_uv.create_view(&wgpu::TextureViewDescriptor {
|
||||||
@@ -204,7 +224,7 @@ impl VideoPipeline {
|
|||||||
mip_level_count: None,
|
mip_level_count: None,
|
||||||
base_array_layer: 0,
|
base_array_layer: 0,
|
||||||
array_layer_count: None,
|
array_layer_count: None,
|
||||||
usage: Some(wgpu::TextureUsages::empty()),
|
usage: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
let instances = device.create_buffer(&wgpu::BufferDescriptor {
|
let instances = device.create_buffer(&wgpu::BufferDescriptor {
|
||||||
@@ -266,10 +286,10 @@ impl VideoPipeline {
|
|||||||
origin: wgpu::Origin3d::ZERO,
|
origin: wgpu::Origin3d::ZERO,
|
||||||
aspect: wgpu::TextureAspect::All,
|
aspect: wgpu::TextureAspect::All,
|
||||||
},
|
},
|
||||||
&frame[..(width * height) as usize],
|
&frame[..(stride * height) as usize],
|
||||||
wgpu::TexelCopyBufferLayout {
|
wgpu::TexelCopyBufferLayout {
|
||||||
offset: 0,
|
offset: 0,
|
||||||
bytes_per_row: Some(width),
|
bytes_per_row: Some(stride),
|
||||||
rows_per_image: Some(height),
|
rows_per_image: Some(height),
|
||||||
},
|
},
|
||||||
wgpu::Extent3d {
|
wgpu::Extent3d {
|
||||||
@@ -286,10 +306,10 @@ impl VideoPipeline {
|
|||||||
origin: wgpu::Origin3d::ZERO,
|
origin: wgpu::Origin3d::ZERO,
|
||||||
aspect: wgpu::TextureAspect::All,
|
aspect: wgpu::TextureAspect::All,
|
||||||
},
|
},
|
||||||
&frame[(width * height) as usize..],
|
&frame[(stride * height) as usize..],
|
||||||
wgpu::TexelCopyBufferLayout {
|
wgpu::TexelCopyBufferLayout {
|
||||||
offset: 0,
|
offset: 0,
|
||||||
bytes_per_row: Some(width),
|
bytes_per_row: Some(stride),
|
||||||
rows_per_image: Some(height / 2),
|
rows_per_image: Some(height / 2),
|
||||||
},
|
},
|
||||||
wgpu::Extent3d {
|
wgpu::Extent3d {
|
||||||
@@ -300,21 +320,6 @@ impl VideoPipeline {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cleanup(&mut self) {
|
|
||||||
let ids: Vec<_> = self
|
|
||||||
.videos
|
|
||||||
.iter()
|
|
||||||
.filter_map(|(id, entry)| (!entry.alive.load(Ordering::SeqCst)).then_some(*id))
|
|
||||||
.collect();
|
|
||||||
for id in ids {
|
|
||||||
if let Some(video) = self.videos.remove(&id) {
|
|
||||||
video.texture_y.destroy();
|
|
||||||
video.texture_uv.destroy();
|
|
||||||
video.instances.destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn prepare(&mut self, queue: &wgpu::Queue, video_id: u64, bounds: &iced::Rectangle) {
|
fn prepare(&mut self, queue: &wgpu::Queue, video_id: u64, bounds: &iced::Rectangle) {
|
||||||
if let Some(video) = self.videos.get_mut(&video_id) {
|
if let Some(video) = self.videos.get_mut(&video_id) {
|
||||||
let uniforms = Uniforms {
|
let uniforms = Uniforms {
|
||||||
@@ -340,8 +345,6 @@ impl VideoPipeline {
|
|||||||
video.prepare_index.fetch_add(1, Ordering::Relaxed);
|
video.prepare_index.fetch_add(1, Ordering::Relaxed);
|
||||||
video.render_index.store(0, Ordering::Relaxed);
|
video.render_index.store(0, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.cleanup();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(
|
fn draw(
|
||||||
@@ -414,39 +417,33 @@ impl VideoPrimitive {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Primitive for VideoPrimitive {
|
impl Primitive for VideoPrimitive {
|
||||||
type Renderer = VideoPipeline;
|
type Pipeline = VideoPipeline;
|
||||||
|
|
||||||
fn initialize(
|
|
||||||
&self,
|
|
||||||
device: &wgpu::Device,
|
|
||||||
_queue: &wgpu::Queue,
|
|
||||||
format: wgpu::TextureFormat,
|
|
||||||
) -> Self::Renderer {
|
|
||||||
VideoPipeline::new(device, format)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn prepare(
|
fn prepare(
|
||||||
&self,
|
&self,
|
||||||
renderer: &mut Self::Renderer,
|
pipeline: &mut VideoPipeline,
|
||||||
device: &wgpu::Device,
|
device: &wgpu::Device,
|
||||||
queue: &wgpu::Queue,
|
queue: &wgpu::Queue,
|
||||||
bounds: &iced::Rectangle,
|
bounds: &iced::Rectangle,
|
||||||
viewport: &iced_wgpu::graphics::Viewport,
|
viewport: &iced_wgpu::graphics::Viewport,
|
||||||
) {
|
) {
|
||||||
if self.upload_frame {
|
if self.upload_frame {
|
||||||
if let Some(readable) = self.frame.lock().expect("lock frame mutex").readable() {
|
let frame_guard = self.frame.lock().expect("lock frame mutex");
|
||||||
renderer.upload(
|
let stride = frame_guard.stride();
|
||||||
|
if let Some(readable) = frame_guard.readable() {
|
||||||
|
pipeline.upload(
|
||||||
device,
|
device,
|
||||||
queue,
|
queue,
|
||||||
self.video_id,
|
self.video_id,
|
||||||
&self.alive,
|
&self.alive,
|
||||||
self.size,
|
self.size,
|
||||||
readable.as_slice(),
|
readable.as_slice(),
|
||||||
|
stride,
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer.prepare(
|
pipeline.prepare(
|
||||||
queue,
|
queue,
|
||||||
self.video_id,
|
self.video_id,
|
||||||
&(*bounds
|
&(*bounds
|
||||||
@@ -459,11 +456,11 @@ impl Primitive for VideoPrimitive {
|
|||||||
|
|
||||||
fn render(
|
fn render(
|
||||||
&self,
|
&self,
|
||||||
renderer: &Self::Renderer,
|
pipeline: &Self::Pipeline,
|
||||||
encoder: &mut wgpu::CommandEncoder,
|
encoder: &mut wgpu::CommandEncoder,
|
||||||
target: &wgpu::TextureView,
|
target: &wgpu::TextureView,
|
||||||
clip_bounds: &iced::Rectangle<u32>,
|
clip_bounds: &iced::Rectangle<u32>,
|
||||||
) {
|
) {
|
||||||
renderer.draw(target, encoder, clip_bounds, self.video_id);
|
pipeline.draw(target, encoder, clip_bounds, self.video_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,24 +38,19 @@ fn vs_main(@builtin(vertex_index) in_vertex_index: u32) -> VertexOutput {
|
|||||||
|
|
||||||
@fragment
|
@fragment
|
||||||
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||||
let yuv2r = vec3<f32>(1.164, 0.0, 1.596);
|
// BT.709 precomputed coefficents
|
||||||
let yuv2g = vec3<f32>(1.164, -0.391, -0.813);
|
let yuv2rgb = mat3x3<f32>(
|
||||||
let yuv2b = vec3<f32>(1.164, 2.018, 0.0);
|
1, 0, 1.5748,
|
||||||
|
1, -0.1873, -0.4681,
|
||||||
|
1, 1.8556, 0,
|
||||||
|
);
|
||||||
|
|
||||||
var yuv = vec3<f32>(0.0);
|
var yuv = vec3<f32>(0.0);
|
||||||
yuv.x = textureSample(tex_y, s, in.uv).r - 0.0625;
|
yuv.x = (textureSample(tex_y, s, in.uv).r - 0.0625) / 0.8588;
|
||||||
yuv.y = textureSample(tex_uv, s, in.uv).r - 0.5;
|
yuv.y = (textureSample(tex_uv, s, in.uv).r - 0.5) / 0.8784;
|
||||||
yuv.z = textureSample(tex_uv, s, in.uv).g - 0.5;
|
yuv.z = (textureSample(tex_uv, s, in.uv).g - 0.5) / 0.8784;
|
||||||
|
|
||||||
var rgb = vec3<f32>(0.0);
|
var rgb = clamp(yuv * yuv2rgb, vec3<f32>(0), vec3<f32>(1));
|
||||||
rgb.x = dot(yuv, yuv2r);
|
|
||||||
rgb.y = dot(yuv, yuv2g);
|
|
||||||
rgb.z = dot(yuv, yuv2b);
|
|
||||||
|
|
||||||
let threshold = rgb <= vec3<f32>(0.04045);
|
|
||||||
let hi = pow((rgb + vec3<f32>(0.055)) / vec3<f32>(1.055), vec3<f32>(2.4));
|
|
||||||
let lo = rgb * vec3<f32>(1.0 / 12.92);
|
|
||||||
rgb = select(hi, lo, threshold);
|
|
||||||
|
|
||||||
return vec4<f32>(rgb, 1.0);
|
return vec4<f32>(rgb, 1.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ use crate::Error;
|
|||||||
use gstreamer as gst;
|
use gstreamer as gst;
|
||||||
use gstreamer_app as gst_app;
|
use gstreamer_app as gst_app;
|
||||||
use gstreamer_app::prelude::*;
|
use gstreamer_app::prelude::*;
|
||||||
|
use gstreamer_video::VideoMeta;
|
||||||
use iced::widget::image as img;
|
use iced::widget::image as img;
|
||||||
use std::num::NonZeroU8;
|
use std::num::NonZeroU8;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
@@ -49,9 +50,19 @@ impl Frame {
|
|||||||
Self(gst::Sample::builder().build())
|
Self(gst::Sample::builder().build())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn readable(&self) -> Option<gst::BufferMap<'_, gst::buffer::Readable>> {
|
pub fn readable(&self) -> Option<gst::BufferMap<gst::buffer::Readable>> {
|
||||||
self.0.buffer().and_then(|x| x.map_readable().ok())
|
self.0.buffer().and_then(|x| x.map_readable().ok())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the Y-plane stride (line pitch) in bytes from the frame's VideoMeta.
|
||||||
|
/// This is critical for proper NV12 decoding, as the stride may differ from width.
|
||||||
|
pub fn stride(&self) -> Option<u32> {
|
||||||
|
self.0.buffer().and_then(|buffer| {
|
||||||
|
buffer
|
||||||
|
.meta::<VideoMeta>()
|
||||||
|
.map(|meta| meta.stride()[0] as u32)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -284,8 +295,6 @@ impl Video {
|
|||||||
let s = cleanup!(caps.structure(0).ok_or(Error::Caps))?;
|
let s = cleanup!(caps.structure(0).ok_or(Error::Caps))?;
|
||||||
let width = cleanup!(s.get::<i32>("width").map_err(|_| Error::Caps))?;
|
let width = cleanup!(s.get::<i32>("width").map_err(|_| Error::Caps))?;
|
||||||
let height = cleanup!(s.get::<i32>("height").map_err(|_| Error::Caps))?;
|
let height = cleanup!(s.get::<i32>("height").map_err(|_| Error::Caps))?;
|
||||||
// resolution should be mod4
|
|
||||||
let width = ((width + 4 - 1) / 4) * 4;
|
|
||||||
let framerate = cleanup!(s.get::<gst::Fraction>("framerate").map_err(|_| Error::Caps))?;
|
let framerate = cleanup!(s.get::<gst::Fraction>("framerate").map_err(|_| Error::Caps))?;
|
||||||
let framerate = framerate.numer() as f64 / framerate.denom() as f64;
|
let framerate = framerate.numer() as f64 / framerate.denom() as f64;
|
||||||
|
|
||||||
@@ -305,7 +314,7 @@ impl Video {
|
|||||||
.unwrap_or(0),
|
.unwrap_or(0),
|
||||||
);
|
);
|
||||||
|
|
||||||
let sync_av = pipeline.has_property("av-offset");
|
let sync_av = pipeline.has_property("av-offset", None);
|
||||||
|
|
||||||
// NV12 = 12bpp
|
// NV12 = 12bpp
|
||||||
let frame = Arc::new(Mutex::new(Frame::empty()));
|
let frame = Arc::new(Mutex::new(Frame::empty()));
|
||||||
@@ -612,11 +621,12 @@ impl Video {
|
|||||||
}
|
}
|
||||||
let frame_guard = inner.frame.lock().map_err(|_| Error::Lock)?;
|
let frame_guard = inner.frame.lock().map_err(|_| Error::Lock)?;
|
||||||
let frame = frame_guard.readable().ok_or(Error::Lock)?;
|
let frame = frame_guard.readable().ok_or(Error::Lock)?;
|
||||||
|
let stride = frame_guard.stride();
|
||||||
|
|
||||||
Ok(img::Handle::from_rgba(
|
Ok(img::Handle::from_rgba(
|
||||||
inner.width as u32 / downscale,
|
inner.width as u32 / downscale,
|
||||||
inner.height as u32 / downscale,
|
inner.height as u32 / downscale,
|
||||||
yuv_to_rgba(frame.as_slice(), width as _, height as _, downscale),
|
yuv_to_rgba(frame.as_slice(), width as _, height as _, downscale, stride),
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
@@ -630,8 +640,17 @@ impl Video {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn yuv_to_rgba(yuv: &[u8], width: u32, height: u32, downscale: u32) -> Vec<u8> {
|
fn yuv_to_rgba(
|
||||||
let uv_start = width * height;
|
yuv: &[u8],
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
downscale: u32,
|
||||||
|
stride: Option<u32>,
|
||||||
|
) -> Vec<u8> {
|
||||||
|
// Use stride from VideoMeta if available, otherwise assume stride == width
|
||||||
|
let stride = stride.unwrap_or(width);
|
||||||
|
|
||||||
|
let uv_start = stride * height;
|
||||||
let mut rgba = vec![];
|
let mut rgba = vec![];
|
||||||
|
|
||||||
for y in 0..height / downscale {
|
for y in 0..height / downscale {
|
||||||
@@ -639,11 +658,16 @@ fn yuv_to_rgba(yuv: &[u8], width: u32, height: u32, downscale: u32) -> Vec<u8> {
|
|||||||
let x_src = x * downscale;
|
let x_src = x * downscale;
|
||||||
let y_src = y * downscale;
|
let y_src = y * downscale;
|
||||||
|
|
||||||
let uv_i = uv_start + width * (y_src / 2) + x_src / 2 * 2;
|
// NV12 memory layout with stride:
|
||||||
|
// Y plane: stride bytes per row, starting at offset 0
|
||||||
|
// UV plane: stride bytes per row (same stride), starting at offset stride * height
|
||||||
|
// Each pixel is 1 byte Y, and every 2x2 block shares 2 bytes (U, V)
|
||||||
|
let y_offset = (y_src * stride + x_src) as usize;
|
||||||
|
let uv_offset = (uv_start + (y_src / 2) * stride + (x_src / 2) * 2) as usize;
|
||||||
|
|
||||||
let y = yuv[(y_src * width + x_src) as usize] as f32;
|
let y = yuv[y_offset] as f32;
|
||||||
let u = yuv[uv_i as usize] as f32;
|
let u = yuv[uv_offset] as f32;
|
||||||
let v = yuv[(uv_i + 1) as usize] as f32;
|
let v = yuv[uv_offset + 1] as f32;
|
||||||
|
|
||||||
let r = 1.164 * (y - 16.0) + 1.596 * (v - 128.0);
|
let r = 1.164 * (y - 16.0) + 1.596 * (v - 128.0);
|
||||||
let g = 1.164 * (y - 16.0) - 0.813 * (v - 128.0) - 0.391 * (u - 128.0);
|
let g = 1.164 * (y - 16.0) - 0.813 * (v - 128.0) - 0.391 * (u - 128.0);
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
use crate::{pipeline::VideoPrimitive, video::Video};
|
use crate::{pipeline::VideoPrimitive, video::Video};
|
||||||
use gstreamer as gst;
|
use gstreamer as gst;
|
||||||
use iced::{
|
use iced::{
|
||||||
advanced::{self, layout, widget, Widget},
|
|
||||||
Element,
|
Element,
|
||||||
|
advanced::{self, Widget, layout, widget},
|
||||||
};
|
};
|
||||||
use iced_wgpu::primitive::Renderer as PrimitiveRenderer;
|
use iced_wgpu::primitive::Renderer as PrimitiveRenderer;
|
||||||
use log::error;
|
use log::error;
|
||||||
use std::{marker::PhantomData, sync::atomic::Ordering};
|
use std::{marker::PhantomData, sync::atomic::Ordering, time::Duration};
|
||||||
use std::{sync::Arc, time::Instant};
|
use std::{sync::Arc, time::Instant};
|
||||||
|
|
||||||
/// Video player widget which displays the current frame of a [`Video`](crate::Video).
|
/// Video player widget which displays the current frame of a [`Video`](crate::Video).
|
||||||
@@ -214,7 +214,7 @@ where
|
|||||||
|
|
||||||
fn update(
|
fn update(
|
||||||
&mut self,
|
&mut self,
|
||||||
_state: &mut widget::Tree,
|
_tree: &mut widget::Tree,
|
||||||
event: &iced::Event,
|
event: &iced::Event,
|
||||||
_layout: advanced::Layout<'_>,
|
_layout: advanced::Layout<'_>,
|
||||||
_cursor: advanced::mouse::Cursor,
|
_cursor: advanced::mouse::Cursor,
|
||||||
@@ -228,6 +228,7 @@ where
|
|||||||
if let iced::Event::Window(iced::window::Event::RedrawRequested(_)) = event {
|
if let iced::Event::Window(iced::window::Event::RedrawRequested(_)) = event {
|
||||||
if inner.restart_stream || (!inner.is_eos && !inner.paused()) {
|
if inner.restart_stream || (!inner.is_eos && !inner.paused()) {
|
||||||
let mut restart_stream = false;
|
let mut restart_stream = false;
|
||||||
|
let emit_eos = !inner.restart_stream;
|
||||||
if inner.restart_stream {
|
if inner.restart_stream {
|
||||||
restart_stream = true;
|
restart_stream = true;
|
||||||
// Set flag to false to avoid potentially multiple seeks
|
// Set flag to false to avoid potentially multiple seeks
|
||||||
@@ -247,7 +248,9 @@ where
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
gst::MessageView::Eos(_eos) => {
|
gst::MessageView::Eos(_eos) => {
|
||||||
if let Some(on_end_of_stream) = self.on_end_of_stream.clone() {
|
if emit_eos
|
||||||
|
&& let Some(on_end_of_stream) = self.on_end_of_stream.clone()
|
||||||
|
{
|
||||||
shell.publish(on_end_of_stream);
|
shell.publish(on_end_of_stream);
|
||||||
}
|
}
|
||||||
if inner.looping {
|
if inner.looping {
|
||||||
@@ -285,8 +288,11 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
shell.request_redraw();
|
shell.request_redraw();
|
||||||
|
shell.capture_event();
|
||||||
} else {
|
} else {
|
||||||
shell.request_redraw();
|
shell.request_redraw_at(iced::window::RedrawRequest::At(
|
||||||
|
Instant::now() + Duration::from_millis(32),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
3
justfile
3
justfile
@@ -3,4 +3,7 @@ typegen:
|
|||||||
cd typegen && cargo run
|
cd typegen && cargo run
|
||||||
cp typegen/jellyfin.rs api/src/jellyfin.rs
|
cp typegen/jellyfin.rs api/src/jellyfin.rs
|
||||||
rm typegen/jellyfin.rs
|
rm typegen/jellyfin.rs
|
||||||
|
|
||||||
|
playbin:
|
||||||
|
gst-launch-1.0 playbin uri=https://gstreamer.freedesktop.org/data/media/sintel_trailer-480p.webm text-sink="appsink name=iced_text sync=true drop=true" video-sink="videoscale ! videoconvert ! appsink name=iced_video drop=true caps=video/x-raw,format=NV12,pixel-aspect-ratio=1/1"
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ fn main() -> Result<()> {
|
|||||||
let args = <cli::Cli as clap::Parser>::parse();
|
let args = <cli::Cli as clap::Parser>::parse();
|
||||||
tracing_subscriber::fmt()
|
tracing_subscriber::fmt()
|
||||||
.with_max_level(args.verbosity)
|
.with_max_level(args.verbosity)
|
||||||
|
.with_file(true)
|
||||||
|
.with_line_number(true)
|
||||||
.init();
|
.init();
|
||||||
ui_iced::ui().change_context(Error)?;
|
ui_iced::ui().change_context(Error)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Borrow,
|
borrow::Borrow,
|
||||||
collections::VecDeque,
|
collections::VecDeque,
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
|
|||||||
@@ -17,16 +17,24 @@ pub fn update(state: &mut State, message: VideoMessage) -> Task<Message> {
|
|||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
VideoMessage::Open(url) => {
|
VideoMessage::Open(url) => {
|
||||||
state.video = Video::new(&url)
|
match Video::new(&url)
|
||||||
.inspect_err(|err| {
|
.inspect_err(|err| {
|
||||||
tracing::error!("Failed to play video at {}: {:?}", url, err);
|
tracing::error!("Failed to play video at {}: {:?}", url, err);
|
||||||
})
|
})
|
||||||
.inspect(|video| {
|
.inspect(|video| {
|
||||||
tracing::info!("Framerate {}", video.framerate());
|
tracing::error!("Framerate is {}", video.framerate());
|
||||||
})
|
})
|
||||||
.ok()
|
.map(Arc::new)
|
||||||
.map(Arc::new);
|
{
|
||||||
Task::none()
|
Ok(video) => {
|
||||||
|
state.video = Some(video);
|
||||||
|
Task::none()
|
||||||
|
}
|
||||||
|
Err(err) => Task::done(Message::Error(format!(
|
||||||
|
"Error opening video at {}: {:?}",
|
||||||
|
url, err
|
||||||
|
))),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
VideoMessage::Pause => {
|
VideoMessage::Pause => {
|
||||||
if let Some(video) = state.video.as_mut().and_then(Arc::get_mut) {
|
if let Some(video) = state.video.as_mut().and_then(Arc::get_mut) {
|
||||||
@@ -56,14 +64,8 @@ pub fn update(state: &mut State, message: VideoMessage) -> Task<Message> {
|
|||||||
"https://gstreamer.freedesktop.org/data/media/sintel_trailer-480p.webm",
|
"https://gstreamer.freedesktop.org/data/media/sintel_trailer-480p.webm",
|
||||||
// "https://www.youtube.com/watch?v=QbUUaXGA3C4",
|
// "https://www.youtube.com/watch?v=QbUUaXGA3C4",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.expect("Impossible: Failed to parse hardcoded URL");
|
||||||
state.video = Video::new(&url)
|
Task::done(Message::Video(VideoMessage::Open(url)))
|
||||||
.inspect_err(|err| {
|
|
||||||
tracing::error!("{err:?}");
|
|
||||||
})
|
|
||||||
.ok()
|
|
||||||
.map(Arc::new);
|
|
||||||
Task::none()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user