mirror of
https://gitlab.freedesktop.org/dabrain34/GstPipelineStudio.git
synced 2024-11-28 12:01:04 +00:00
pipeline: implement parse launch playback
Can now play/pause/stop a playback from a parse launch description GST pipeline. rename getters in pipeline.rs
This commit is contained in:
parent
52286ada4a
commit
f1149a6b5e
5 changed files with 277 additions and 243 deletions
237
Cargo.lock
generated
237
Cargo.lock
generated
|
@ -28,7 +28,7 @@ checksum = "9164355c892b026d6257e696dde5f3cb39beb3718297f0f161b562fe2ee3ab86"
|
|||
dependencies = [
|
||||
"bitflags",
|
||||
"cairo-sys-rs",
|
||||
"glib 0.14.8",
|
||||
"glib",
|
||||
"libc",
|
||||
"thiserror",
|
||||
]
|
||||
|
@ -39,7 +39,7 @@ version = "0.14.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7c9c3928781e8a017ece15eace05230f04b647457d170d2d9641c94a444ff80"
|
||||
dependencies = [
|
||||
"glib-sys 0.14.0",
|
||||
"glib-sys",
|
||||
"libc",
|
||||
"system-deps 3.2.0",
|
||||
]
|
||||
|
@ -116,19 +116,6 @@ version = "0.3.17"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"proc-macro-hack",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.17"
|
||||
|
@ -143,12 +130,9 @@ checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481"
|
|||
dependencies = [
|
||||
"autocfg",
|
||||
"futures-core",
|
||||
"futures-macro",
|
||||
"futures-task",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"proc-macro-hack",
|
||||
"proc-macro-nested",
|
||||
"slab",
|
||||
]
|
||||
|
||||
|
@ -160,7 +144,7 @@ checksum = "534192cb8f01daeb8fab2c8d4baa8f9aae5b7a39130525779f5c2608e235b10f"
|
|||
dependencies = [
|
||||
"gdk-pixbuf-sys",
|
||||
"gio",
|
||||
"glib 0.14.8",
|
||||
"glib",
|
||||
"libc",
|
||||
]
|
||||
|
||||
|
@ -171,8 +155,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "f097c0704201fbc8f69c1762dc58c6947c8bb188b8ed0bc7e65259f1894fe590"
|
||||
dependencies = [
|
||||
"gio-sys",
|
||||
"glib-sys 0.14.0",
|
||||
"gobject-sys 0.14.0",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"libc",
|
||||
"system-deps 3.2.0",
|
||||
]
|
||||
|
@ -188,7 +172,7 @@ dependencies = [
|
|||
"gdk-pixbuf",
|
||||
"gdk4-sys",
|
||||
"gio",
|
||||
"glib 0.14.8",
|
||||
"glib",
|
||||
"libc",
|
||||
"pango",
|
||||
]
|
||||
|
@ -202,8 +186,8 @@ dependencies = [
|
|||
"cairo-sys-rs",
|
||||
"gdk-pixbuf-sys",
|
||||
"gio-sys",
|
||||
"glib-sys 0.14.0",
|
||||
"gobject-sys 0.14.0",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"graphene-sys",
|
||||
"libc",
|
||||
"pango-sys",
|
||||
|
@ -221,7 +205,7 @@ dependencies = [
|
|||
"futures-core",
|
||||
"futures-io",
|
||||
"gio-sys",
|
||||
"glib 0.14.8",
|
||||
"glib",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"thiserror",
|
||||
|
@ -233,32 +217,13 @@ version = "0.14.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0a41df66e57fcc287c4bcf74fc26b884f31901ea9792ec75607289b456f48fa"
|
||||
dependencies = [
|
||||
"glib-sys 0.14.0",
|
||||
"gobject-sys 0.14.0",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"libc",
|
||||
"system-deps 3.2.0",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glib"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c685013b7515e668f1b57a165b009d4d28cb139a8a989bbd699c10dad29d0c5"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
"glib-macros 0.10.1",
|
||||
"glib-sys 0.10.1",
|
||||
"gobject-sys 0.10.0",
|
||||
"libc",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glib"
|
||||
version = "0.14.8"
|
||||
|
@ -270,30 +235,14 @@ dependencies = [
|
|||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-task",
|
||||
"glib-macros 0.14.1",
|
||||
"glib-sys 0.14.0",
|
||||
"gobject-sys 0.14.0",
|
||||
"glib-macros",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glib-macros"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41486a26d1366a8032b160b59065a59fb528530a46a49f627e7048fb8c064039"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"heck",
|
||||
"itertools 0.9.0",
|
||||
"proc-macro-crate 0.1.5",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glib-macros"
|
||||
version = "0.14.1"
|
||||
|
@ -302,23 +251,13 @@ checksum = "2aad66361f66796bfc73f530c51ef123970eb895ffba991a234fcf7bea89e518"
|
|||
dependencies = [
|
||||
"anyhow",
|
||||
"heck",
|
||||
"proc-macro-crate 1.1.0",
|
||||
"proc-macro-crate",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glib-sys"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7e9b997a66e9a23d073f2b1abb4dbfc3925e0b8952f67efd8d9b6e168e4cdc1"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"system-deps 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glib-sys"
|
||||
version = "0.14.0"
|
||||
|
@ -329,24 +268,13 @@ dependencies = [
|
|||
"system-deps 3.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gobject-sys"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "952133b60c318a62bf82ee75b93acc7e84028a093e06b9e27981c2b6fe68218c"
|
||||
dependencies = [
|
||||
"glib-sys 0.10.1",
|
||||
"libc",
|
||||
"system-deps 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gobject-sys"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa92cae29759dae34ab5921d73fff5ad54b3d794ab842c117e36cafc7994c3f5"
|
||||
dependencies = [
|
||||
"glib-sys 0.14.0",
|
||||
"glib-sys",
|
||||
"libc",
|
||||
"system-deps 3.2.0",
|
||||
]
|
||||
|
@ -357,7 +285,7 @@ version = "0.14.8"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3380f132530ef9eb9e0a2bac180e30390aa5e49892d20294f822a974117a563"
|
||||
dependencies = [
|
||||
"glib 0.14.8",
|
||||
"glib",
|
||||
"graphene-sys",
|
||||
"libc",
|
||||
]
|
||||
|
@ -368,7 +296,7 @@ version = "0.14.8"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a9ac7450b3aa80792513a3c029920a2ede419de13fb5169a4e51b07a5685332"
|
||||
dependencies = [
|
||||
"glib-sys 0.14.0",
|
||||
"glib-sys",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"system-deps 3.2.0",
|
||||
|
@ -383,7 +311,7 @@ dependencies = [
|
|||
"bitflags",
|
||||
"cairo-rs",
|
||||
"gdk4",
|
||||
"glib 0.14.8",
|
||||
"glib",
|
||||
"graphene-rs",
|
||||
"gsk4-sys",
|
||||
"libc",
|
||||
|
@ -398,8 +326,8 @@ checksum = "13aa53ce70234da02f9954339d988d5ab853d746a8f47a4ae17735ff873545b5"
|
|||
dependencies = [
|
||||
"cairo-sys-rs",
|
||||
"gdk4-sys",
|
||||
"glib-sys 0.14.0",
|
||||
"gobject-sys 0.14.0",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"graphene-sys",
|
||||
"libc",
|
||||
"pango-sys",
|
||||
|
@ -411,6 +339,7 @@ name = "gst_pipeline_studio"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"glib",
|
||||
"gstreamer",
|
||||
"gtk4",
|
||||
"log",
|
||||
|
@ -420,21 +349,20 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gstreamer"
|
||||
version = "0.16.7"
|
||||
version = "0.17.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ff5d0f7ff308ae37e6eb47b6ded17785bdea06e438a708cd09e0288c1862f33"
|
||||
checksum = "c6a255f142048ba2c4a4dce39106db1965abe355d23f4b5335edea43a553faa4"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"glib 0.10.3",
|
||||
"glib-sys 0.10.1",
|
||||
"gobject-sys 0.10.0",
|
||||
"glib",
|
||||
"gstreamer-sys",
|
||||
"libc",
|
||||
"muldiv",
|
||||
"num-integer",
|
||||
"num-rational",
|
||||
"once_cell",
|
||||
"paste",
|
||||
|
@ -444,14 +372,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gstreamer-sys"
|
||||
version = "0.9.1"
|
||||
version = "0.17.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc1f154082d01af5718c5f8a8eb4f565a4ea5586ad8833a8fc2c2aa6844b601d"
|
||||
checksum = "a81704feeb3e8599913bdd1e738455c2991a01ff4a1780cb62200993e454cc3e"
|
||||
dependencies = [
|
||||
"glib-sys 0.10.1",
|
||||
"gobject-sys 0.10.0",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"libc",
|
||||
"system-deps 1.3.2",
|
||||
"system-deps 3.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -467,7 +395,7 @@ dependencies = [
|
|||
"gdk-pixbuf",
|
||||
"gdk4",
|
||||
"gio",
|
||||
"glib 0.14.8",
|
||||
"glib",
|
||||
"graphene-rs",
|
||||
"gsk4",
|
||||
"gtk4-macros",
|
||||
|
@ -485,8 +413,8 @@ checksum = "5068d4354af02454f44687adc613100aa98ae11e273cdcac84f89dc08be2b4a1"
|
|||
dependencies = [
|
||||
"anyhow",
|
||||
"heck",
|
||||
"itertools 0.10.1",
|
||||
"proc-macro-crate 1.1.0",
|
||||
"itertools",
|
||||
"proc-macro-crate",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -503,8 +431,8 @@ dependencies = [
|
|||
"gdk-pixbuf-sys",
|
||||
"gdk4-sys",
|
||||
"gio-sys",
|
||||
"glib-sys 0.14.0",
|
||||
"gobject-sys 0.14.0",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"graphene-sys",
|
||||
"gsk4-sys",
|
||||
"libc",
|
||||
|
@ -521,15 +449,6 @@ dependencies = [
|
|||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.1"
|
||||
|
@ -565,9 +484,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "muldiv"
|
||||
version = "0.2.1"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0419348c027fa7be448d2ae7ea0e4e04c2334c31dc4e74ab29f00a2a7ca69204"
|
||||
checksum = "b5136edda114182728ccdedb9f5eda882781f35fa6e80cc360af12a8932507f3"
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
|
@ -581,9 +500,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.3.2"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07"
|
||||
checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
|
@ -612,7 +531,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "546fd59801e5ca735af82839007edd226fe7d3bb06433ec48072be4439c28581"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"glib 0.14.8",
|
||||
"glib",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"pango-sys",
|
||||
|
@ -624,8 +543,8 @@ version = "0.14.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2367099ca5e761546ba1d501955079f097caa186bb53ce0f718dca99ac1942fe"
|
||||
dependencies = [
|
||||
"glib-sys 0.14.0",
|
||||
"gobject-sys 0.14.0",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"libc",
|
||||
"system-deps 3.2.0",
|
||||
]
|
||||
|
@ -669,15 +588,6 @@ version = "0.2.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc5c99d529f0d30937f6f4b8a86d988047327bb88d04d2c4afc356de74722131"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-crate"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785"
|
||||
dependencies = [
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-crate"
|
||||
version = "1.1.0"
|
||||
|
@ -712,18 +622,6 @@ dependencies = [
|
|||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-hack"
|
||||
version = "0.5.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-nested"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.30"
|
||||
|
@ -787,30 +685,12 @@ version = "1.7.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57bd81eb48f4c437cadc685403cad539345bf703d78e63707418431cecd4522b"
|
||||
|
||||
[[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.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87c85aa3f8ea653bfd3ddf25f7ee357ee4d204731f6aa9ad04002306f6e2774c"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.21.1"
|
||||
|
@ -834,21 +714,6 @@ dependencies = [
|
|||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "system-deps"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f3ecc17269a19353b3558b313bba738b25d82993e30d62a18406a24aba4649b"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"pkg-config",
|
||||
"strum 0.18.0",
|
||||
"strum_macros 0.18.0",
|
||||
"thiserror",
|
||||
"toml",
|
||||
"version-compare 0.0.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "system-deps"
|
||||
version = "3.2.0"
|
||||
|
@ -858,13 +723,13 @@ dependencies = [
|
|||
"anyhow",
|
||||
"cfg-expr 0.8.1",
|
||||
"heck",
|
||||
"itertools 0.10.1",
|
||||
"itertools",
|
||||
"pkg-config",
|
||||
"strum 0.21.0",
|
||||
"strum_macros 0.21.1",
|
||||
"strum",
|
||||
"strum_macros",
|
||||
"thiserror",
|
||||
"toml",
|
||||
"version-compare 0.0.11",
|
||||
"version-compare",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -877,7 +742,7 @@ dependencies = [
|
|||
"heck",
|
||||
"pkg-config",
|
||||
"toml",
|
||||
"version-compare 0.0.11",
|
||||
"version-compare",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -927,12 +792,6 @@ version = "0.2.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "version-compare"
|
||||
version = "0.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d63556a25bae6ea31b52e640d7c41d1ab27faba4ccb600013837a3d0b3994ca1"
|
||||
|
||||
[[package]]
|
||||
name = "version-compare"
|
||||
version = "0.0.11"
|
||||
|
|
|
@ -8,7 +8,8 @@ edition = "2018"
|
|||
[dependencies]
|
||||
gtk = { version = "0.3", package = "gtk4" }
|
||||
anyhow = "1"
|
||||
gstreamer = "0.16"
|
||||
glib = "0.14"
|
||||
gstreamer = "0.17"
|
||||
log = "0.4.11"
|
||||
once_cell = "1.7.2"
|
||||
xml-rs = "0.8.4"
|
81
src/app.rs
81
src/app.rs
|
@ -26,7 +26,7 @@ use std::cell::RefCell;
|
|||
use std::rc::{Rc, Weak};
|
||||
use std::{error, ops};
|
||||
|
||||
use crate::pipeline::Pipeline;
|
||||
use crate::pipeline::{Pipeline, PipelineState};
|
||||
use crate::pluginlist;
|
||||
|
||||
use crate::graphmanager::{GraphView, Node};
|
||||
|
@ -113,6 +113,33 @@ impl GPSApp {
|
|||
app.drop();
|
||||
});
|
||||
}
|
||||
pub fn show_error_dialog(fatal: bool, message: &str) {
|
||||
let app = gio::Application::default()
|
||||
.expect("No default application")
|
||||
.downcast::<gtk::Application>()
|
||||
.expect("Default application has wrong type");
|
||||
|
||||
let dialog = gtk::MessageDialog::new(
|
||||
app.active_window().as_ref(),
|
||||
gtk::DialogFlags::MODAL,
|
||||
gtk::MessageType::Error,
|
||||
gtk::ButtonsType::Ok,
|
||||
message,
|
||||
);
|
||||
|
||||
dialog.connect_response(move |dialog, _| {
|
||||
let app = gio::Application::default().expect("No default application");
|
||||
|
||||
dialog.destroy();
|
||||
|
||||
if fatal {
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
|
||||
dialog.set_resizable(false);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
pub fn build_ui(&self, application: &Application) {
|
||||
let drawing_area_window: Viewport = self
|
||||
|
@ -236,8 +263,35 @@ impl GPSApp {
|
|||
let app_weak = self.downgrade();
|
||||
add_button.connect_clicked(glib::clone!(@weak window => move |_| {
|
||||
// entry.set_text("Clicked!");
|
||||
let _app = upgrade_weak!(app_weak);
|
||||
|
||||
let app = upgrade_weak!(app_weak);
|
||||
let graph_view = app.graphview.borrow();
|
||||
let pipeline = app.pipeline.borrow();
|
||||
if pipeline.state() == PipelineState::Stopped {
|
||||
pipeline.create_pipeline(&graph_view.render_gst()).expect("Unable to create the pipeline");
|
||||
pipeline.set_state(PipelineState::Playing).expect("Unable to change state");
|
||||
} else if pipeline.state() == PipelineState::Paused {
|
||||
pipeline.set_state(PipelineState::Playing).expect("Unable to change state");
|
||||
} else {
|
||||
pipeline.set_state(PipelineState::Paused).expect("Unable to change state");
|
||||
}
|
||||
}));
|
||||
let add_button: Button = self
|
||||
.builder
|
||||
.object("button-pause")
|
||||
.expect("Couldn't get app_button");
|
||||
let app_weak = self.downgrade();
|
||||
add_button.connect_clicked(glib::clone!(@weak window => move |_| {
|
||||
let app = upgrade_weak!(app_weak);
|
||||
let graph_view = app.graphview.borrow();
|
||||
let pipeline = app.pipeline.borrow();
|
||||
if pipeline.state() == PipelineState::Stopped {
|
||||
pipeline.create_pipeline(&graph_view.render_gst()).expect("Unable to create the pipeline");
|
||||
pipeline.set_state(PipelineState::Paused).expect("Unable to change state");
|
||||
} else if pipeline.state() == PipelineState::Paused {
|
||||
pipeline.set_state(PipelineState::Playing).expect("Unable to change state");
|
||||
} else {
|
||||
pipeline.set_state(PipelineState::Paused).expect("Unable to change state");
|
||||
}
|
||||
}));
|
||||
let add_button: Button = self
|
||||
.builder
|
||||
|
@ -246,21 +300,8 @@ impl GPSApp {
|
|||
let app_weak = self.downgrade();
|
||||
add_button.connect_clicked(glib::clone!(@weak window => move |_| {
|
||||
let app = upgrade_weak!(app_weak);
|
||||
let graph_view = app.graphview.borrow_mut();
|
||||
graph_view.remove_all_nodes();
|
||||
let node_id = graph_view.get_next_node_id();
|
||||
let element_name = String::from("appsink");
|
||||
let pads = Pipeline::get_pads(&element_name, false);
|
||||
graph_view.add_node_with_port(node_id, Node::new(node_id, &element_name, Pipeline::get_element_type(&element_name)), pads.0, pads.1);
|
||||
let node_id = graph_view.get_next_node_id();
|
||||
let element_name = String::from("videotestsrc");
|
||||
let pads = Pipeline::get_pads(&element_name, false);
|
||||
graph_view.add_node_with_port(node_id, Node::new(node_id, &element_name, Pipeline::get_element_type(&element_name)), pads.0, pads.1);
|
||||
let node_id = graph_view.get_next_node_id();
|
||||
let element_name = String::from("videoconvert");
|
||||
let pads = Pipeline::get_pads(&element_name, false);
|
||||
graph_view.add_node_with_port(node_id, Node::new(node_id, &element_name, Pipeline::get_element_type(&element_name)), pads.0, pads.1);
|
||||
|
||||
let pipeline = app.pipeline.borrow();
|
||||
pipeline.set_state(PipelineState::Stopped).expect("Unable to change state to STOP");
|
||||
}));
|
||||
let add_button: Button = self
|
||||
.builder
|
||||
|
@ -285,13 +326,13 @@ impl GPSApp {
|
|||
pub fn add_new_element(&self, element_name: String) {
|
||||
let graph_view = self.graphview.borrow_mut();
|
||||
let node_id = graph_view.next_node_id();
|
||||
let pads = Pipeline::get_pads(&element_name, false);
|
||||
let pads = Pipeline::pads(&element_name, false);
|
||||
graph_view.add_node_with_port(
|
||||
node_id,
|
||||
Node::new(
|
||||
node_id,
|
||||
&element_name,
|
||||
Pipeline::get_element_type(&element_name),
|
||||
Pipeline::element_type(&element_name),
|
||||
),
|
||||
pads.0,
|
||||
pads.1,
|
||||
|
|
|
@ -582,6 +582,11 @@ impl GraphView {
|
|||
}
|
||||
|
||||
// Render graph methods
|
||||
pub fn render_gst(&self) -> String {
|
||||
let description = String::from("videotestsrc ! videoconvert ! autovideosink");
|
||||
description
|
||||
}
|
||||
|
||||
pub fn render_xml(&self, filename: &str) -> anyhow::Result<(), Box<dyn error::Error>> {
|
||||
let mut file = File::create(filename).unwrap();
|
||||
let mut writer = EmitterConfig::new()
|
||||
|
|
192
src/pipeline.rs
192
src/pipeline.rs
|
@ -16,10 +16,15 @@
|
|||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
use crate::app::GPSApp;
|
||||
use crate::graphmanager::NodeType;
|
||||
use gst::prelude::*;
|
||||
use gstreamer as gst;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::error;
|
||||
use std::fmt;
|
||||
use std::ops;
|
||||
use std::rc::{Rc, Weak};
|
||||
|
||||
#[derive(Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||
pub struct ElementInfo {
|
||||
|
@ -38,38 +43,153 @@ impl Default for ElementInfo {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Pipeline {
|
||||
initialized: bool,
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum PipelineState {
|
||||
Playing,
|
||||
Paused,
|
||||
Stopped,
|
||||
}
|
||||
|
||||
impl Default for Pipeline {
|
||||
fn default() -> Pipeline {
|
||||
Pipeline { initialized: false }
|
||||
impl fmt::Display for PipelineState {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{:?}", self)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Pipeline(Rc<PipelineInner>);
|
||||
|
||||
// Deref into the contained struct to make usage a bit more ergonomic
|
||||
impl ops::Deref for Pipeline {
|
||||
type Target = PipelineInner;
|
||||
|
||||
fn deref(&self) -> &PipelineInner {
|
||||
&*self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PipelineWeak(Weak<PipelineInner>);
|
||||
|
||||
impl PipelineWeak {
|
||||
pub fn upgrade(&self) -> Option<Pipeline> {
|
||||
self.0.upgrade().map(Pipeline)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PipelineInner {
|
||||
initialized: bool,
|
||||
pipeline: RefCell<Option<gst::Pipeline>>,
|
||||
current_state: Cell<PipelineState>,
|
||||
}
|
||||
|
||||
impl Pipeline {
|
||||
pub fn new() -> Result<Self, Box<dyn error::Error>> {
|
||||
gst::init()?;
|
||||
Ok(Self { initialized: true })
|
||||
let pipeline = Pipeline(Rc::new(PipelineInner {
|
||||
initialized: true,
|
||||
pipeline: RefCell::new(None),
|
||||
current_state: Cell::new(PipelineState::Stopped),
|
||||
}));
|
||||
|
||||
Ok(pipeline)
|
||||
}
|
||||
|
||||
pub fn create_pipeline(&self, description: &str) -> Result<(), Box<dyn error::Error>> {
|
||||
println!("Creating pipeline {}", description);
|
||||
|
||||
/* create playbin */
|
||||
|
||||
let pipeline = gst::parse_launch(&description.to_string())?;
|
||||
let pipeline = pipeline
|
||||
.downcast::<gst::Pipeline>()
|
||||
.expect("Couldn't downcast pipeline");
|
||||
|
||||
//pipeline.set_property_message_forward(true);
|
||||
|
||||
let bus = pipeline.bus().expect("Pipeline had no bus");
|
||||
let pipeline_weak = self.downgrade();
|
||||
bus.add_watch_local(move |_bus, msg| {
|
||||
let pipeline = upgrade_weak!(pipeline_weak, glib::Continue(false));
|
||||
|
||||
pipeline.on_pipeline_message(msg);
|
||||
|
||||
glib::Continue(true)
|
||||
})?;
|
||||
|
||||
*self.pipeline.borrow_mut() = Some(pipeline);
|
||||
/* start playing */
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_state(&self, state: PipelineState) -> Result<(), Box<dyn error::Error>> {
|
||||
if let Some(pipeline) = self.pipeline.borrow().to_owned() {
|
||||
match state {
|
||||
PipelineState::Playing => pipeline.set_state(gst::State::Playing)?,
|
||||
PipelineState::Paused => pipeline.set_state(gst::State::Paused)?,
|
||||
PipelineState::Stopped => {
|
||||
pipeline.set_state(gst::State::Null)?;
|
||||
gst::StateChangeSuccess::Success
|
||||
}
|
||||
};
|
||||
self.current_state.set(state);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn state(&self) -> PipelineState {
|
||||
self.current_state.get()
|
||||
}
|
||||
|
||||
pub fn downgrade(&self) -> PipelineWeak {
|
||||
PipelineWeak(Rc::downgrade(&self.0))
|
||||
}
|
||||
|
||||
fn on_pipeline_message(&self, msg: &gst::MessageRef) {
|
||||
use gst::MessageView;
|
||||
match msg.view() {
|
||||
MessageView::Error(err) => {
|
||||
GPSApp::show_error_dialog(
|
||||
false,
|
||||
format!(
|
||||
"Error from {:?}: {} ({:?})",
|
||||
err.src().map(|s| s.path_string()),
|
||||
err.error(),
|
||||
err.debug()
|
||||
)
|
||||
.as_str(),
|
||||
);
|
||||
}
|
||||
MessageView::Application(msg) => match msg.structure() {
|
||||
// Here we can send ourselves messages from any thread and show them to the user in
|
||||
// the UI in case something goes wrong
|
||||
Some(s) if s.name() == "warning" => {
|
||||
let text = s.get::<&str>("text").expect("Warning message without text");
|
||||
GPSApp::show_error_dialog(false, text);
|
||||
}
|
||||
_ => (),
|
||||
},
|
||||
_ => (),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn elements_list() -> Result<Vec<ElementInfo>, Box<dyn error::Error>> {
|
||||
let registry = gst::Registry::get();
|
||||
let mut elements: Vec<ElementInfo> = Vec::new();
|
||||
let plugins = gst::Registry::get_plugin_list(®istry);
|
||||
let plugins = gst::Registry::plugin_list(®istry);
|
||||
for plugin in plugins {
|
||||
let plugin_name = gst::Plugin::get_plugin_name(&plugin);
|
||||
let features = gst::Registry::get_feature_list_by_plugin(®istry, &plugin_name);
|
||||
let plugin_name = gst::Plugin::plugin_name(&plugin);
|
||||
let features = gst::Registry::feature_list_by_plugin(®istry, &plugin_name);
|
||||
for feature in features {
|
||||
let mut element = ElementInfo::default();
|
||||
if let Ok(factory) = feature.downcast::<gst::ElementFactory>() {
|
||||
let feature = factory.upcast::<gst::PluginFeature>();
|
||||
|
||||
element.name = Some(gst::PluginFeature::get_name(&feature).as_str().to_owned());
|
||||
element.name = Some(gst::PluginFeature::name(&feature).as_str().to_owned());
|
||||
element.plugin_name =
|
||||
Some(gst::Plugin::get_plugin_name(&plugin).as_str().to_owned());
|
||||
Some(gst::Plugin::plugin_name(&plugin).as_str().to_owned());
|
||||
elements.push(element);
|
||||
}
|
||||
}
|
||||
|
@ -100,12 +220,12 @@ impl Pipeline {
|
|||
if let Ok(factory) = feature.downcast::<gst::ElementFactory>() {
|
||||
desc.push_str("<b>Factory details:</b>\n");
|
||||
desc.push_str("<b>Name:</b>");
|
||||
desc.push_str(&factory.get_name());
|
||||
desc.push_str(&factory.name());
|
||||
desc.push('\n');
|
||||
|
||||
let element_keys = factory.get_metadata_keys();
|
||||
let element_keys = factory.metadata_keys();
|
||||
for key in element_keys {
|
||||
let val = factory.get_metadata(&key);
|
||||
let val = factory.metadata(&key);
|
||||
if let Some(val) = val {
|
||||
desc.push_str("<b>");
|
||||
desc.push_str(&key);
|
||||
|
@ -115,52 +235,45 @@ impl Pipeline {
|
|||
}
|
||||
}
|
||||
let feature = factory.upcast::<gst::PluginFeature>();
|
||||
let plugin = gst::PluginFeature::get_plugin(&feature);
|
||||
let plugin = gst::PluginFeature::plugin(&feature);
|
||||
if let Some(plugin) = plugin {
|
||||
desc.push('\n');
|
||||
desc.push_str("<b>Plugin details:</b>");
|
||||
desc.push('\n');
|
||||
desc.push_str("<b>Name:");
|
||||
desc.push_str("</b>");
|
||||
desc.push_str(gst::Plugin::get_plugin_name(&plugin).as_str());
|
||||
desc.push_str(gst::Plugin::plugin_name(&plugin).as_str());
|
||||
desc.push('\n');
|
||||
desc.push_str("<b>Description:");
|
||||
desc.push_str("</b>");
|
||||
desc.push_str(
|
||||
>k::glib::markup_escape_text(&plugin.get_description()).to_string(),
|
||||
);
|
||||
desc.push_str(>k::glib::markup_escape_text(&plugin.description()).to_string());
|
||||
desc.push('\n');
|
||||
desc.push_str("<b>Filename:");
|
||||
desc.push_str("</b>");
|
||||
desc.push_str(
|
||||
>k::glib::markup_escape_text(
|
||||
&plugin
|
||||
.get_filename()
|
||||
.unwrap()
|
||||
.as_path()
|
||||
.display()
|
||||
.to_string(),
|
||||
&plugin.filename().unwrap().as_path().display().to_string(),
|
||||
)
|
||||
.to_string(),
|
||||
);
|
||||
desc.push('\n');
|
||||
desc.push_str("<b>Version:");
|
||||
desc.push_str("</b>");
|
||||
desc.push_str(>k::glib::markup_escape_text(&plugin.get_version()).to_string());
|
||||
desc.push_str(>k::glib::markup_escape_text(&plugin.version()).to_string());
|
||||
desc.push('\n');
|
||||
}
|
||||
}
|
||||
Ok(desc)
|
||||
}
|
||||
|
||||
pub fn get_pads(element_name: &str, include_on_request: bool) -> (u32, u32) {
|
||||
pub fn pads(element_name: &str, include_on_request: bool) -> (u32, u32) {
|
||||
let feature = Pipeline::element_feature(element_name).expect("Unable to get feature");
|
||||
let mut input = 0;
|
||||
let mut output = 0;
|
||||
|
||||
if let Ok(factory) = feature.downcast::<gst::ElementFactory>() {
|
||||
if factory.get_num_pad_templates() > 0 {
|
||||
let pads = factory.get_static_pad_templates();
|
||||
if factory.num_pad_templates() > 0 {
|
||||
let pads = factory.static_pad_templates();
|
||||
for pad in pads {
|
||||
if pad.presence() == gst::PadPresence::Always
|
||||
|| (include_on_request
|
||||
|
@ -179,8 +292,8 @@ impl Pipeline {
|
|||
(input, output)
|
||||
}
|
||||
|
||||
pub fn get_element_type(element_name: &str) -> NodeType {
|
||||
let pads = Pipeline::get_pads(element_name, true);
|
||||
pub fn element_type(element_name: &str) -> NodeType {
|
||||
let pads = Pipeline::pads(element_name, true);
|
||||
let mut element_type = NodeType::Source;
|
||||
if pads.0 > 0 {
|
||||
if pads.1 > 0 {
|
||||
|
@ -195,3 +308,18 @@ impl Pipeline {
|
|||
element_type
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for PipelineInner {
|
||||
fn drop(&mut self) {
|
||||
// TODO: If a recording is currently running we would like to finish that first
|
||||
// before quitting the pipeline and shutting down the pipeline.
|
||||
if let Some(pipeline) = self.pipeline.borrow().to_owned() {
|
||||
// We ignore any errors here
|
||||
let _ = pipeline.set_state(gst::State::Null);
|
||||
|
||||
// Remove the message watch from the bus
|
||||
let bus = pipeline.bus().expect("Pipeline had no bus");
|
||||
let _ = bus.remove_watch();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue