mirror of
https://github.com/Rafostar/clapper.git
synced 2025-08-29 23:32:04 +02:00
Compare commits
475 Commits
gstplaylis
...
0.6.0
Author | SHA1 | Date | |
---|---|---|---|
|
f0f4801819 | ||
|
b9f3cbef7f | ||
|
772191a396 | ||
|
f4a766ea9d | ||
|
c928e601bf | ||
|
8fb62d773f | ||
|
f299e1be57 | ||
|
9f38f527be | ||
|
10f626637b | ||
|
22c93c00f7 | ||
|
7a38b605b3 | ||
|
5c41c3a8c7 | ||
|
51e1dd8493 | ||
|
654e6be72a | ||
|
681da9e2f3 | ||
|
36c166813e | ||
|
2aecd65735 | ||
|
a46846c24d | ||
|
fab168283d | ||
|
1b38a169dd | ||
|
a00aea50b0 | ||
|
6fc2c78d59 | ||
|
85038a669f | ||
|
484f2402a3 | ||
|
1a0158e775 | ||
|
1d92539b76 | ||
|
bab3d34349 | ||
|
e751428d6c | ||
|
a9769f9537 | ||
|
fe6b3fcf29 | ||
|
6447944b21 | ||
|
42fa31cc4b | ||
|
4baade3b32 | ||
|
bcd8e470ad | ||
|
3841a906fd | ||
|
5e7305516e | ||
|
f1ef299c10 | ||
|
1606a165e4 | ||
|
87f51c6755 | ||
|
ca73b3a3ef | ||
|
6f1277a2e6 | ||
|
76f830fa6e | ||
|
a63d92601f | ||
|
0c9973ef85 | ||
|
65c974d539 | ||
|
43e2e88a4c | ||
|
c327734ca6 | ||
|
48b5a7c12a | ||
|
1dd47ad2a9 | ||
|
fbeafbccd1 | ||
|
f391e2ea87 | ||
|
37bf374283 | ||
|
1327dc23e4 | ||
|
6e17996691 | ||
|
606b9c5170 | ||
|
e4814877de | ||
|
6b135d51f3 | ||
|
1a52576be3 | ||
|
cc004a8144 | ||
|
675ddc85a1 | ||
|
d7f069d6c3 | ||
|
edaba00658 | ||
|
8cf3e57d51 | ||
|
32723c49ad | ||
|
058844c010 | ||
|
b4aaea1940 | ||
|
2dd08b7b33 | ||
|
086b134483 | ||
|
9da04c549b | ||
|
ac7ec5fc12 | ||
|
6e705485f5 | ||
|
18caee32d7 | ||
|
c7590b653b | ||
|
dce74148a7 | ||
|
5ed9861530 | ||
|
3f86b236d9 | ||
|
e275c3017a | ||
|
4e250c8f2a | ||
|
7fc93fbebc | ||
|
bf52197896 | ||
|
9556ec4da2 | ||
|
bd8f0280e2 | ||
|
40b6f4c724 | ||
|
456d621ee3 | ||
|
263d3f8196 | ||
|
44db8c0d3b | ||
|
272e3a036c | ||
|
540c294b2a | ||
|
6c5753db53 | ||
|
a25bfa5418 | ||
|
aaa3f6c4da | ||
|
845de1db8b | ||
|
301e1f2ade | ||
|
ff5091e7d3 | ||
|
0d74fbb3e6 | ||
|
9d6ec43b0a | ||
|
cbc3061714 | ||
|
d8b02824f3 | ||
|
dd255dd337 | ||
|
447c6f30d0 | ||
|
afa06d4579 | ||
|
b04bf11c42 | ||
|
939f75763d | ||
|
d4c44049ca | ||
|
11c27eccaa | ||
|
823cb0a894 | ||
|
b27db1ac22 | ||
|
564c6e7299 | ||
|
6f4632d940 | ||
|
23bb253ca2 | ||
|
8ebf4e3b2f | ||
|
04a028d689 | ||
|
0920914b89 | ||
|
2343e84a41 | ||
|
c288223321 | ||
|
2ba6645462 | ||
|
adcbb5d827 | ||
|
9885a2f424 | ||
|
66b2d8c7de | ||
|
2c5d65d0b3 | ||
|
e37f2a0a30 | ||
|
387bc7a2f3 | ||
|
495a59a07a | ||
|
e5723cd25a | ||
|
e7808df7cc | ||
|
8f22b36045 | ||
|
dc257846ce | ||
|
af77873205 | ||
|
5289b2f0a4 | ||
|
87b3fbc15a | ||
|
59ff5bc006 | ||
|
91efc4ecdb | ||
|
713449b4ab | ||
|
3f7ba0674f | ||
|
5b89879031 | ||
|
2385af9b94 | ||
|
54e4644236 | ||
|
3c248250f3 | ||
|
51619cbd2a | ||
|
f9e84ac99b | ||
|
1bd371dabd | ||
|
5f6c0922c0 | ||
|
041deb559c | ||
|
fce8ec59b8 | ||
|
306505dc4d | ||
|
60234419c2 | ||
|
c395c6b9be | ||
|
8301cded2f | ||
|
34386bc96c | ||
|
2b85afc03e | ||
|
bb56efa705 | ||
|
82922e51f9 | ||
|
ca64d9d2ee | ||
|
2a18c6a374 | ||
|
af6cf01c98 | ||
|
85bdbb1132 | ||
|
8e89b0d8ca | ||
|
4e3cc3e23f | ||
|
c6c43346fa | ||
|
be58af2256 | ||
|
343eef5894 | ||
|
04657017f9 | ||
|
1cdaa36559 | ||
|
f351982067 | ||
|
ae531db2b7 | ||
|
66fb8d4a1f | ||
|
8f0ad12795 | ||
|
908a388f68 | ||
|
7f33db4159 | ||
|
288b829139 | ||
|
aa6d21973c | ||
|
e506063409 | ||
|
e679430d3e | ||
|
4b93d4d132 | ||
|
b7b99c20cf | ||
|
5775738f67 | ||
|
7159459160 | ||
|
00650a596f | ||
|
6a995e2143 | ||
|
01b3feb213 | ||
|
5b9e7eacba | ||
|
b37ab432d7 | ||
|
0410c6e9b5 | ||
|
3e0a0e0555 | ||
|
5b7b7085e4 | ||
|
044710f97e | ||
|
b83d500352 | ||
|
3fadf13125 | ||
|
f8fe49a809 | ||
|
264f0abb64 | ||
|
b330aa1ccd | ||
|
de8ecb8f82 | ||
|
a2bb927502 | ||
|
df728f383b | ||
|
c80d2e9fd6 | ||
|
5a00301935 | ||
|
46b5a6df96 | ||
|
f771e0320c | ||
|
72a64a41d9 | ||
|
2818d3c91b | ||
|
ffb481b52b | ||
|
c5c289d466 | ||
|
3074051b3d | ||
|
980e1d9e1a | ||
|
045e4fc2c4 | ||
|
4f27739287 | ||
|
52aa7710dc | ||
|
0e49eaec7e | ||
|
62a923a3c1 | ||
|
f59b937316 | ||
|
8c914d0555 | ||
|
d2fab16093 | ||
|
67e877af0f | ||
|
c825649a71 | ||
|
5101fce5a7 | ||
|
e0daf8435a | ||
|
9f18295728 | ||
|
8ce977505e | ||
|
8ac839c9aa | ||
|
8fa2036265 | ||
|
1d5bb1e6aa | ||
|
9ec87c1b58 | ||
|
16c0f8baae | ||
|
c94d21fc53 | ||
|
159f96c984 | ||
|
96ad4fa3db | ||
|
b2e7bef8d4 | ||
|
40a1dc6960 | ||
|
c4bd604e17 | ||
|
83c0e3b598 | ||
|
54715023c0 | ||
|
95046ceba8 | ||
|
b189e24b5e | ||
|
cb9e2ac979 | ||
|
545d8826e0 | ||
|
c2160198b9 | ||
|
aa7eae2417 | ||
|
3192a32845 | ||
|
706c783498 | ||
|
8ba3ca4af6 | ||
|
38efa7ab9f | ||
|
d19ddbcaca | ||
|
615f1553fb | ||
|
09c9e7560b | ||
|
f40ce756ad | ||
|
23d51be185 | ||
|
0db2a4a045 | ||
|
469c06d22b | ||
|
3feaf225b5 | ||
|
fc8d881efd | ||
|
ac76836fd7 | ||
|
f6a1aaf1dc | ||
|
000dca82d9 | ||
|
7a508fef39 | ||
|
d465d9f150 | ||
|
5e4dfb322c | ||
|
0c561ab4b3 | ||
|
46ce261524 | ||
|
50aac8cdd8 | ||
|
810aea476f | ||
|
24905f1d60 | ||
|
82e3c9a52f | ||
|
654b8aaf60 | ||
|
3c0e33e4a4 | ||
|
d2df1c3bd8 | ||
|
af24073590 | ||
|
44cee14eb2 | ||
|
b853685dd4 | ||
|
15461dd38a | ||
|
1c1989bc32 | ||
|
e9c9ae073f | ||
|
22d2c40b0f | ||
|
5301c8b368 | ||
|
e910978590 | ||
|
3b99f0ee0c | ||
|
f93a0fed98 | ||
|
6b8c35b16e | ||
|
5fdb6e64be | ||
|
60d4b5aec1 | ||
|
f5258889cf | ||
|
31eddf5dd2 | ||
|
89f7304e0e | ||
|
3c918bda73 | ||
|
2a8ef2559f | ||
|
7676e18eee | ||
|
00b05b460d | ||
|
62f02cf2a3 | ||
|
9fc1d9b8c4 | ||
|
45a5ebb4b6 | ||
|
2500a42286 | ||
|
bafffa59b9 | ||
|
201cb6f64c | ||
|
636098182b | ||
|
5442b0b70a | ||
|
67d1b9f5bc | ||
|
a62483fda9 | ||
|
c825385a8f | ||
|
02a7419d66 | ||
|
e727b8fb50 | ||
|
3cbfd1a57c | ||
|
75b728457c | ||
|
b293a84df6 | ||
|
928244dc32 | ||
|
11caafe847 | ||
|
dbeb4cb0b7 | ||
|
3e04139288 | ||
|
c41b77a14b | ||
|
3c500e0be9 | ||
|
6cddb1a16d | ||
|
b5007d12a1 | ||
|
0d7274fb03 | ||
|
94be4c08c5 | ||
|
bfcc468528 | ||
|
98d2b80103 | ||
|
fa39c45773 | ||
|
b2a6e19fe1 | ||
|
e8c44dc400 | ||
|
5cc9c17632 | ||
|
35d359daf9 | ||
|
637fa75484 | ||
|
8733610a9b | ||
|
873e724bf2 | ||
|
7aa03f3e72 | ||
|
99acd36cc0 | ||
|
cd7d99606d | ||
|
574e084383 | ||
|
d49df86397 | ||
|
3483c94913 | ||
|
a99abc652a | ||
|
a9173bb481 | ||
|
a16444cefb | ||
|
65673dbf4f | ||
|
dea67e4712 | ||
|
3c765e9f17 | ||
|
a77eb5352e | ||
|
ca168f34ed | ||
|
d0304d4ded | ||
|
cd479f3bb4 | ||
|
70942ba419 | ||
|
ad0c6151a9 | ||
|
cccc584961 | ||
|
38e721be03 | ||
|
cf6d41b725 | ||
|
b68c1a62b2 | ||
|
dc25ec976a | ||
|
914292612b | ||
|
e34b164f5a | ||
|
2e0a455f92 | ||
|
3aab01d35c | ||
|
e264304c9d | ||
|
a145890f9d | ||
|
0323c816ad | ||
|
4f1d9be423 | ||
|
82557df7c4 | ||
|
c457158541 | ||
|
451711b9c6 | ||
|
bbada8fb4e | ||
|
04122d46a7 | ||
|
347d90b1ad | ||
|
27ffb65d8f | ||
|
9328a7af75 | ||
|
1f6e439632 | ||
|
97c1207b40 | ||
|
833559a208 | ||
|
9a8655b0a2 | ||
|
d2a03d40a3 | ||
|
66998ff6c6 | ||
|
7cdd905d73 | ||
|
10eb5102c1 | ||
|
9e8854c5e2 | ||
|
16a9546c97 | ||
|
2686c2ca03 | ||
|
ad563d16d0 | ||
|
12ce95b664 | ||
|
2dbabe52bb | ||
|
2c35ceb35a | ||
|
5eac1aa675 | ||
|
0e6a68665d | ||
|
86fe1628c3 | ||
|
a427817e53 | ||
|
7a767c34eb | ||
|
a7298e371e | ||
|
f6393a177d | ||
|
45decb8563 | ||
|
2e12e52730 | ||
|
ffbd8c35e1 | ||
|
01277f4a71 | ||
|
a54c3e4bcc | ||
|
17b2aec170 | ||
|
75bc0d6b69 | ||
|
edef26fc0e | ||
|
0edab83f86 | ||
|
9681d0eea1 | ||
|
b6559ee50f | ||
|
ce183595cd | ||
|
71f50ba414 | ||
|
0de8ee2d54 | ||
|
8be49f25b4 | ||
|
69bef3d174 | ||
|
d429e9105c | ||
|
a1ce04edfa | ||
|
8ca4c30beb | ||
|
9b53a3e387 | ||
|
f31682624f | ||
|
5874db45ea | ||
|
87a0dd473e | ||
|
c50df5f2a3 | ||
|
a72a8057e5 | ||
|
f29ec78b92 | ||
|
10f54c7c3d | ||
|
2b91056543 | ||
|
2656762cbc | ||
|
f5ff59f786 | ||
|
e4fe7844c4 | ||
|
b7d9a22d33 | ||
|
c8a5277908 | ||
|
62fab289b7 | ||
|
56ca13b370 | ||
|
ce46905319 | ||
|
5fe5f89e5d | ||
|
9ba6f5d09e | ||
|
4c0fc1dac2 | ||
|
13a792c0a9 | ||
|
02b0d5f03f | ||
|
b577dd762d | ||
|
d798539dce | ||
|
19e159d1bd | ||
|
c3cdabb050 | ||
|
c53cde4d78 | ||
|
b308ae367f | ||
|
b2005fd34f | ||
|
a6dfeeca37 | ||
|
90844e49ad | ||
|
eb60d036db | ||
|
6e20a5fa12 | ||
|
cf370961b4 | ||
|
6db36d6ac2 | ||
|
4738673f7f | ||
|
1004000ba2 | ||
|
e40f11def5 | ||
|
5378facb46 | ||
|
c6b252f261 | ||
|
0f1447b14e | ||
|
cfd6e1bd23 | ||
|
0cb89d3a84 | ||
|
3bf636d46b | ||
|
8f79a76a51 | ||
|
0efe9144d8 | ||
|
2e776ddf7b | ||
|
2eea3b05b1 | ||
|
e647cdc8c6 | ||
|
1f3ddab566 | ||
|
a38480c46b | ||
|
562587846a | ||
|
c6cd829e7b | ||
|
9b31581aac | ||
|
5018b3a28a | ||
|
bad836cc6d | ||
|
e1845a212f | ||
|
f86e32ed88 | ||
|
af2c74a4b1 | ||
|
1c414ef36b | ||
|
11e89dab26 | ||
|
37d2f7aebd | ||
|
f2ac3b20a3 | ||
|
ade60b93a4 | ||
|
48bc96f074 | ||
|
0d9cb91705 | ||
|
21ccab1cc2 | ||
|
bea3b1670d | ||
|
0d4d3f1a8c | ||
|
fc525ffcb1 | ||
|
6f1a5626bc | ||
|
fbe6a8804c | ||
|
c0b92c190b |
5
.gitattributes
vendored
5
.gitattributes
vendored
@@ -1,5 +0,0 @@
|
||||
extras/**/* linguist-vendored
|
||||
lib/**/* linguist-vendored
|
||||
lib/**/**/* linguist-vendored
|
||||
lib/gst/clapper/gstclapper-mpris* linguist-vendored=false
|
||||
lib/gst/clapper/gtk4/* linguist-vendored=false
|
43
.github/workflows/flatpak-nightly.yml
vendored
Normal file
43
.github/workflows/flatpak-nightly.yml
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "0 0 * * *"
|
||||
name: "Flatpak Nightly"
|
||||
jobs:
|
||||
flatpak:
|
||||
name: "Flatpak"
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 600
|
||||
container:
|
||||
image: bilelmoussaoui/flatpak-github-actions:gnome-nightly
|
||||
options: --privileged
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [x86_64, aarch64]
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Install Docker
|
||||
run: |
|
||||
dnf -y install docker
|
||||
- name: Setup QEMU
|
||||
id: qemu
|
||||
uses: docker/setup-qemu-action@v3
|
||||
with:
|
||||
platforms: arm64
|
||||
- name: Prepare Runtime
|
||||
run: |
|
||||
flatpak --system install -y --noninteractive flathub org.freedesktop.Sdk.Extension.rust-nightly/${{ matrix.arch }}/23.08
|
||||
flatpak --system install -y --noninteractive flathub org.freedesktop.Sdk.Extension.llvm16/${{ matrix.arch }}/23.08
|
||||
- name: Build
|
||||
uses: bilelmoussaoui/flatpak-github-actions/flatpak-builder@v6
|
||||
with:
|
||||
bundle: com.github.rafostar.Clapper.flatpak
|
||||
manifest-path: pkgs/flatpak/com.github.rafostar.Clapper-nightly.json
|
||||
repository-name: gnome-nightly
|
||||
repository-url: https://nightly.gnome.org/gnome-nightly.flatpakrepo
|
||||
cache-key: flatpak-builder-${{ github.sha }}-testing-${{ github.run_number }}
|
||||
arch: ${{ matrix.arch }}
|
41
.github/workflows/flatpak.yml
vendored
Normal file
41
.github/workflows/flatpak.yml
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
name: "Flatpak"
|
||||
jobs:
|
||||
flatpak:
|
||||
name: "Flatpak"
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 600
|
||||
container:
|
||||
image: bilelmoussaoui/flatpak-github-actions:gnome-45
|
||||
options: --privileged
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [x86_64, aarch64]
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Install Docker
|
||||
run: |
|
||||
dnf -y install docker
|
||||
- name: Setup QEMU
|
||||
id: qemu
|
||||
uses: docker/setup-qemu-action@v3
|
||||
with:
|
||||
platforms: arm64
|
||||
- name: Build
|
||||
uses: bilelmoussaoui/flatpak-github-actions/flatpak-builder@v6
|
||||
with:
|
||||
bundle: com.github.rafostar.Clapper.flatpak
|
||||
manifest-path: pkgs/flatpak/com.github.rafostar.Clapper.json
|
||||
cache-key: flatpak-builder-${{ github.sha }}
|
||||
arch: ${{ matrix.arch }}
|
3
.gitignore
vendored
3
.gitignore
vendored
@@ -2,3 +2,6 @@
|
||||
build/
|
||||
install/
|
||||
builddir/
|
||||
|
||||
# flatpak
|
||||
.flatpak-builder/
|
||||
|
10
.obs/workflows.yml
Normal file
10
.obs/workflows.yml
Normal file
@@ -0,0 +1,10 @@
|
||||
rebuild_master:
|
||||
steps:
|
||||
- trigger_services:
|
||||
project: home:Rafostar
|
||||
package: clapper
|
||||
filters:
|
||||
event: push
|
||||
branches:
|
||||
only:
|
||||
- master
|
@@ -55,7 +55,7 @@ modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
@@ -111,7 +111,7 @@ modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
@@ -158,7 +158,7 @@ Library.
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
@@ -216,7 +216,7 @@ instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
@@ -267,7 +267,7 @@ Library will still fall under Section 6.)
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
@@ -329,7 +329,7 @@ restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
@@ -370,7 +370,7 @@ subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
@@ -422,7 +422,7 @@ conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
@@ -456,7 +456,7 @@ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
@@ -485,7 +485,8 @@ convey the exclusion of warranty; and each file should have at least the
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
@@ -494,7 +495,8 @@ school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
library `Frob' (a library for tweaking knobs) written by James Random
|
||||
Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
93
README.md
93
README.md
@@ -1,71 +1,72 @@
|
||||
# Clapper
|
||||
A GNOME media player build using [GJS](https://gitlab.gnome.org/GNOME/gjs) with [GTK4](https://www.gtk.org) toolkit.
|
||||
The media player is using [GStreamer](https://gstreamer.freedesktop.org/) as a media backend and renders everything via [OpenGL](https://www.opengl.org).
|
||||
[](https://github.com/Rafostar/clapper/actions/workflows/flatpak.yml)
|
||||
[](https://github.com/Rafostar/clapper/actions/workflows/flatpak-nightly.yml)
|
||||
[](https://crowdin.com/project/clapper)
|
||||
[](https://matrix.to/#/#clapper-player:matrix.org)
|
||||
[](https://liberapay.com/Clapper)
|
||||
|
||||
Clapper is a modern media player designed for simplicity and ease of use. Powered by [GStreamer](https://gstreamer.freedesktop.org/) and built for the GNOME
|
||||
desktop environment using [GTK4](https://www.gtk.org/) toolkit, it has a clean and stylish interface that lets you focus on enjoying your favorite videos.
|
||||
|
||||
This application aim is to offer all the essentials features you'd expect from a video player in a simple form.
|
||||
|
||||
<p align="center">
|
||||
<img src="https://raw.githubusercontent.com/wiki/Rafostar/clapper/media/screenshot-windowed.png"><br>
|
||||
<b>Windowed Mode</b>
|
||||
<img src="https://raw.githubusercontent.com/wiki/Rafostar/clapper/media/screenshot_03.png">
|
||||
</p>
|
||||
|
||||
Clapper uses a playback queue where you can add multiple media files. Think of it like a playlist that you can build.
|
||||
You can easily reorder items or remove them from the queue with a simple drag and drop operation.
|
||||
|
||||
<p align="center">
|
||||
<img src="https://raw.githubusercontent.com/wiki/Rafostar/clapper/media/screenshot-fullscreen.png"><br>
|
||||
<b>Fullscreen Mode</b>
|
||||
<img src="https://raw.githubusercontent.com/wiki/Rafostar/clapper/media/screenshot_04.png">
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<img src="https://raw.githubusercontent.com/wiki/Rafostar/clapper/media/screenshot-floating.png"><br>
|
||||
<b>Floating Mode</b>
|
||||
</p>
|
||||
### Components
|
||||
Clapper's codebase consists of 2 libraries using which main application is built:
|
||||
* [Clapper](https://rafostar.github.io/clapper/doc/clapper/) - a playback library
|
||||
* [ClapperGtk](https://rafostar.github.io/clapper/doc/clapper-gtk/) - a GTK integration library
|
||||
|
||||
### Features:
|
||||
* [Hardware acceleration](https://github.com/Rafostar/clapper/wiki/Hardware-acceleration)
|
||||
* [Floating mode](https://github.com/Rafostar/clapper/wiki/Floating-mode)
|
||||
* [Adaptive UI](https://raw.githubusercontent.com/wiki/Rafostar/clapper/media/screenshot-mobile.png)
|
||||
* [Playlist from file](https://github.com/Rafostar/clapper/wiki/Playlists)
|
||||
* Chapters on progress bar
|
||||
Both libraries support *GObject Introspection* bindings. A simple application example can be found [here](https://github.com/Rafostar/clapper-vala-test).
|
||||
|
||||
Above libraries are licensed under `LGPL-2.1-or-later`. You are free to use them in your own projects as long as you comply with license terms.
|
||||
Please note that until version 1.0 they should be considered as an unstable API (some things may change without prior notice).
|
||||
|
||||
## Installation from Flatpak
|
||||
The `Flatpak` package includes all required dependencies and codecs.
|
||||
Additionally it also has a few patches, thus some functionalities work better (or are only available) in `Flatpak` version (until my changes are accepted upstream). List of patches used in this version can be found [here](https://github.com/Rafostar/clapper/issues/35).
|
||||
Additionally it also has a few patches, thus some functionalities work better in `Flatpak` version (until my changes are accepted upstream).
|
||||
List of patches used in this version can be found [here](https://github.com/Rafostar/clapper/issues/35).
|
||||
|
||||
<a href='https://flathub.org/apps/details/com.github.rafostar.Clapper'><img width='240' alt='Download on Flathub' src='https://flathub.org/assets/badges/flathub-badge-en.png'/></a>
|
||||
<a href='https://flathub.org/apps/details/com.github.rafostar.Clapper'>
|
||||
<img width='240' alt='Download on Flathub' src='https://flathub.org/assets/badges/flathub-badge-en.png'/>
|
||||
</a>
|
||||
|
||||
**Important:** If you have been using the flatpak package from my custom 3rd party repo, please remove it and replace your installation with version from Flathub. That repository will not be maintained any longer. Thank you for understanding.
|
||||
## Packages in Linux Distributions
|
||||
[](https://repology.org/project/clapper/versions)
|
||||
|
||||
## Packages
|
||||
The [pkgs folder](https://github.com/Rafostar/clapper/tree/master/pkgs) in this repository contains build scripts for various package formats. You can use them to build package yourself or download one of pre-built packages:
|
||||
Pre-built RPM packages are also available in [my repo](https://software.opensuse.org//download.html?project=home%3ARafostar&package=clapper) ([see status](https://build.opensuse.org/package/show/home:Rafostar/clapper)).<br>
|
||||
Those are automatically built on each git commit, thus are considered unstable.
|
||||
|
||||
#### Debian, Fedora & openSUSE
|
||||
Pre-built packages are available in [my repo](https://software.opensuse.org//download.html?project=home%3ARafostar&package=clapper) ([see status](https://build.opensuse.org/package/show/home:Rafostar/clapper)).<br>
|
||||
Those are automatically build on each git commit, thus are considered unstable.
|
||||
|
||||
#### Arch Linux
|
||||
You can get Clapper from the AUR:
|
||||
* [clapper](https://aur.archlinux.org/packages/clapper) (stable version)
|
||||
* [clapper-git](https://aur.archlinux.org/packages/clapper-git)
|
||||
|
||||
## Installation from source code
|
||||
## Installation from Source Code
|
||||
```sh
|
||||
meson builddir --prefix=/usr/local
|
||||
sudo meson install -C builddir
|
||||
meson setup builddir
|
||||
cd builddir
|
||||
meson compile
|
||||
sudo meson install
|
||||
```
|
||||
|
||||
## Q&A
|
||||
**Q:** Does using `GJS` negatively impact video performance?<br>
|
||||
**A:** Absolutely not. `GJS` here is used to put together the GUI during startup.
|
||||
It has nothing to do with video rendering. All used `GTK4` and `GStreamer` libraries are in C.
|
||||
Even the custom video widget that I prepared for this player (based on original `GTK3` implementation) is a compiled C code.
|
||||
All these libs are acting "on their own" and no function calls from `GJS` related to video decoding and rendering are performed during playback.
|
||||
|
||||
**Q:** What settings should I set to maximize performance?<br>
|
||||
**A:** As of now, player works best on `Wayland` session. `Wayland` users can try enabling highly experimental `vah264dec` plugin for improved performance (this plugin does not work on `Xorg` right now) for standard (8-bit) `H.264` videos.
|
||||
It can be enabled from inside player preferences dialog inside `Advanced -> GStreamer` tab using customizable `Plugin Ranking` feature.
|
||||
Since the whole app is rendered using your GPU, users of VERY weak GPUs might want to disable the "render window shadows" option to have more GPU power available for non-fullscreen video rendering.
|
||||
|
||||
## Other Questions?
|
||||
## Questions?
|
||||
Feel free to ask me any questions. Come and talk on Matrix: [#clapper-player:matrix.org](https://matrix.to/#/#clapper-player:matrix.org)
|
||||
|
||||
## Translations
|
||||
Preferred translation method is to use [Clapper Crowdin](https://crowdin.com/project/clapper) web page.
|
||||
|
||||
Crowdin does not require any additional tools and translating can be done through web browser.
|
||||
You can login using GitHub account or create a new one. Only I can add new languages to this project,
|
||||
so if your language is not available, please contact me first.
|
||||
|
||||
## Special Thanks
|
||||
Many thanks to [sp1ritCS](https://github.com/sp1ritCS) for creating and maintaining package build files.
|
||||
Big thanks to [bridadan](https://github.com/bridadan) and [Uniformbuffer3](https://github.com/Uniformbuffer3) for helping
|
||||
with testing V4L2 and NVDEC hardware acceleration methods.
|
||||
|
||||
Thanks a lot to all the people who are supporting the development with their anonymous donations through [Liberapay](https://liberapay.com/Clapper/). I :heart: U.
|
||||
|
46
TODO.md
46
TODO.md
@@ -1,46 +0,0 @@
|
||||
- [X] Implement GstPlayer API
|
||||
- [X] Update to custom GstClapper API
|
||||
- [X] Inhibit screen locking
|
||||
- [X] Hide cursor on video window
|
||||
- Adaptive GUI:
|
||||
- [X] Darker and bigger in fullscreen
|
||||
- [X] Mobile/narrow widths transitions
|
||||
- [ ] Mobile friendly other windows e.g. prefs window (libadwaita)
|
||||
- [X] Dragging player by video (MPV)
|
||||
- [X] Switching video/audio/subtitles tracks from bottom bar (MPV)
|
||||
- [X] Over-amplification supported by default (VLC)
|
||||
- [X] Audio visualizations (VLC)
|
||||
- [X] Clock with current hour and "Ends at" time on top overlay (Kodi)
|
||||
- [ ] Auto select subtitles matching OS language (Totem)
|
||||
- [X] Picture-in-Picture mode window (floating window)
|
||||
- [ ] Touch gestures/swipes support
|
||||
- Media playlists:
|
||||
- [X] Add more items to playlist via D&D
|
||||
- [X] Select video from playlist
|
||||
- [ ] Reorder playlist items via D&D
|
||||
- [X] Load special playlist file (.claps)
|
||||
- [X] Save to playlist file from GUI
|
||||
- Seeking:
|
||||
- [X] Customizable seek time
|
||||
- [X] Set seek mode (default, accurate, fast)
|
||||
- [ ] Statistics and codec info page (VLC)
|
||||
- [X] Resume playback from last position
|
||||
- [X] Chapters support
|
||||
- [ ] Set tracks time offset
|
||||
- [ ] Subtitles offset
|
||||
- [X] Audio offset
|
||||
- [ ] MDNS and UPNP (discovering media in local network)
|
||||
- [X] DND files from Nautilus to play (ignore incompatible ones)
|
||||
- [X] Support dropping whole folders
|
||||
- [ ] Search for subtitles, download and activate (SMplayer)
|
||||
- [ ] Auto add subtitles from same folder
|
||||
- [ ] Set global subtitles folders
|
||||
- [X] RSTP streaming
|
||||
- [X] Playback speed
|
||||
- [X] Remote playback controls via HTTP (VLC) + WebSockets
|
||||
- [ ] Expand available API
|
||||
- [ ] API documentation
|
||||
- [ ] Integration with the top bar
|
||||
- [ ] MPRIS support
|
||||
- [ ] Controls in the notifications panel
|
||||
- [ ] Progress bar in the notifications panel (maybe via extension)
|
15
_service
15
_service
@@ -1,15 +0,0 @@
|
||||
<services>
|
||||
<service name="obs_scm">
|
||||
<param name="scm">git</param>
|
||||
<param name="url">https://github.com/Rafostar/clapper.git</param>
|
||||
<param name="extract">pkgs/rpm/clapper.spec</param>
|
||||
<param name="extract">pkgs/rpm/clapper.rpmlintrc</param>
|
||||
<param name="extract">pkgs/deb/clapper.dsc</param>
|
||||
</service>
|
||||
<service name="tar" mode="buildtime"/>
|
||||
<service name="recompress" mode="buildtime">
|
||||
<param name="compression">xz</param>
|
||||
<param name="file">*.tar</param>
|
||||
</service>
|
||||
<service name="set_version" mode="buildtime"/>
|
||||
</services>
|
@@ -1,17 +0,0 @@
|
||||
#!@GJS@
|
||||
|
||||
/* pkg init enforces the imports path to the folder
|
||||
* named after the pkg name, but I would prefer to have
|
||||
* the bundled subprocess stored in the same directory */
|
||||
imports.searchPath.unshift('@datadir@/@PACKAGE_NAME@');
|
||||
|
||||
const Package = imports.package;
|
||||
|
||||
Package.init({
|
||||
name: '@PACKAGE_NAME@.@ID_POSTFIX@',
|
||||
version: '@PACKAGE_VERSION@',
|
||||
prefix: '@prefix@',
|
||||
libdir: '@libdir@',
|
||||
datadir: '@datadir@',
|
||||
});
|
||||
Package.run(imports.src.main@ID_POSTFIX@);
|
@@ -1,12 +0,0 @@
|
||||
#!@GJS@
|
||||
|
||||
const Package = imports.package;
|
||||
|
||||
Package.init({
|
||||
name: '@PACKAGE_NAME@',
|
||||
version: '@PACKAGE_VERSION@',
|
||||
prefix: '@prefix@',
|
||||
libdir: '@libdir@',
|
||||
datadir: '@datadir@',
|
||||
});
|
||||
Package.run(imports.src.main);
|
@@ -1,24 +0,0 @@
|
||||
clapper_apps = ['', 'Remote', 'Daemon']
|
||||
|
||||
foreach id_postfix : clapper_apps
|
||||
app_postfix = (id_postfix != '') ? '.' + id_postfix : ''
|
||||
template_type = (id_postfix != '') ? '.Subprocess' : ''
|
||||
|
||||
bin_conf = configuration_data()
|
||||
bin_conf.set('GJS', find_program('gjs').path())
|
||||
bin_conf.set('PACKAGE_NAME', meson.project_name())
|
||||
bin_conf.set('PACKAGE_VERSION', meson.project_version())
|
||||
bin_conf.set('ID_POSTFIX', id_postfix)
|
||||
bin_conf.set('prefix', get_option('prefix'))
|
||||
bin_conf.set('libdir', join_paths(get_option('prefix'), get_option('libdir')))
|
||||
bin_conf.set('datadir', join_paths(get_option('prefix'), get_option('datadir')))
|
||||
|
||||
configure_file(
|
||||
input: 'com.github.rafostar.Clapper' + template_type + '.in',
|
||||
output: 'com.github.rafostar.Clapper' + app_postfix,
|
||||
configuration: bin_conf,
|
||||
install: true,
|
||||
install_dir: get_option('bindir'),
|
||||
install_mode: 'rwxr-xr-x'
|
||||
)
|
||||
endforeach
|
@@ -1,22 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from os import environ, path
|
||||
from subprocess import call
|
||||
|
||||
prefix = environ.get('MESON_INSTALL_PREFIX', '/usr/local')
|
||||
sharedir = path.join(prefix, 'share')
|
||||
destdir = environ.get('DESTDIR', '')
|
||||
|
||||
# Package managers set this so we don't need to run
|
||||
if not destdir:
|
||||
print('Updating icon cache...')
|
||||
call(['gtk4-update-icon-cache', '-qtf', path.join(sharedir, 'icons', 'hicolor')])
|
||||
|
||||
print('Updating mime database...')
|
||||
call(['update-mime-database', path.join(sharedir, 'mime')])
|
||||
|
||||
print('Updating desktop database...')
|
||||
call(['update-desktop-database', '-q', path.join(sharedir, 'applications')])
|
||||
|
||||
print('Compiling GSettings schemas...')
|
||||
call(['glib-compile-schemas', path.join(sharedir, 'glib-2.0', 'schemas')])
|
5
crowdin.yml
Normal file
5
crowdin.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
files:
|
||||
- source: /src/lib/clapper-gtk/po/clapper-gtk.pot
|
||||
translation: /src/lib/clapper-gtk/po/%osx_locale%.po
|
||||
- source: /src/bin/clapper-app/po/clapper-app.pot
|
||||
translation: /src/bin/clapper-app/po/%osx_locale%.po
|
324
css/styles.css
324
css/styles.css
@@ -1,324 +0,0 @@
|
||||
/* Defaults */
|
||||
scale marks {
|
||||
color: currentColor;
|
||||
}
|
||||
radio {
|
||||
margin-left: -2px;
|
||||
}
|
||||
/* Adwaita is missing osd ListBox */
|
||||
.osd list {
|
||||
background: none;
|
||||
}
|
||||
.osd list row image {
|
||||
-gtk-icon-shadow: none;
|
||||
}
|
||||
.gtk402 trough highlight {
|
||||
border-color: transparent;
|
||||
}
|
||||
.gtk402 .osd trough highlight {
|
||||
border-color: inherit;
|
||||
}
|
||||
.osdheaderbar {
|
||||
background: transparent;
|
||||
}
|
||||
.osdheaderbar button {
|
||||
border: transparent;
|
||||
}
|
||||
.linkseparator {
|
||||
background: rgba(24,24,24,0.72);
|
||||
min-width: 1px;
|
||||
}
|
||||
.linkedleft image {
|
||||
margin-left: 2px;
|
||||
}
|
||||
.linkedright image {
|
||||
margin-right: 2px;
|
||||
}
|
||||
/* Non-osd style for popover menu */
|
||||
.menupopover label {
|
||||
color: @theme_text_color;
|
||||
}
|
||||
.menupopover arrow {
|
||||
background: @theme_base_color;
|
||||
border-color: @insensitive_base_color;
|
||||
}
|
||||
.menupopover contents {
|
||||
background: @theme_base_color;
|
||||
border-color: @insensitive_base_color;
|
||||
}
|
||||
.adwrounded.csd {
|
||||
border-radius: 8px;
|
||||
}
|
||||
.adwrounded.fullscreen,
|
||||
.adwrounded.maximized,
|
||||
.adwrounded.tiled,
|
||||
.adwrounded.tiled-top,
|
||||
.adwrounded.tiled-left,
|
||||
.adwrounded.tiled-right,
|
||||
.adwrounded.tiled-bottom {
|
||||
border-radius: 0px;
|
||||
}
|
||||
.roundedcorners {
|
||||
border-radius: 8px;
|
||||
}
|
||||
.adwthemedark scale trough highlight {
|
||||
filter: brightness(120%);
|
||||
}
|
||||
|
||||
.videowidget {
|
||||
min-width: 320px;
|
||||
min-height: 180px;
|
||||
}
|
||||
|
||||
.fullscreen.tvmode popover box {
|
||||
text-shadow: none;
|
||||
font-size: 21px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.adwicons .playercontrols {
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
.playercontrols {
|
||||
margin-left: 2px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
.playercontrols button {
|
||||
margin: 3px;
|
||||
margin-left: 1px;
|
||||
margin-right: 1px;
|
||||
}
|
||||
.fullscreen.tvmode .playercontrols button {
|
||||
min-width: 32px;
|
||||
min-height: 32px;
|
||||
margin: 5px;
|
||||
margin-left: 3px;
|
||||
margin-right: 3px;
|
||||
}
|
||||
.fullscreen.tvmode button image {
|
||||
-gtk-icon-shadow: none;
|
||||
}
|
||||
.fullscreen.tvmode radio {
|
||||
margin-left: 0px;
|
||||
margin-right: 4px;
|
||||
border: 2px solid;
|
||||
min-width: 17px;
|
||||
min-height: 17px;
|
||||
}
|
||||
|
||||
.fullscreen.tvmode .playercontrols button image {
|
||||
-gtk-icon-size: 24px;
|
||||
}
|
||||
.adwicons .playbackicon {
|
||||
-gtk-icon-size: 20px;
|
||||
}
|
||||
.adwicons.fullscreen.tvmode .playbackicon {
|
||||
-gtk-icon-size: 28px;
|
||||
}
|
||||
.labelbuttonlabel {
|
||||
margin-left: -4px;
|
||||
margin-right: -4px;
|
||||
min-width: 8px;
|
||||
font-family: 'Cantarell', sans-serif;
|
||||
font-variant-numeric: tabular-nums;
|
||||
font-weight: 600;
|
||||
}
|
||||
.fullscreen.tvmode .labelbuttonlabel {
|
||||
font-size: 22px;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
/* Top Revealer */
|
||||
.fullscreen.tvmode .revealertopgrid {
|
||||
font-family: 'Cantarell', sans-serif;
|
||||
}
|
||||
.fullscreen.tvmode .tvtitle {
|
||||
font-size: 28px;
|
||||
font-weight: 500;
|
||||
text-shadow: none;
|
||||
}
|
||||
.fullscreen.tvmode .tvtime {
|
||||
margin-top: -2px;
|
||||
margin-bottom: -2px;
|
||||
min-height: 4px;
|
||||
font-size: 38px;
|
||||
font-weight: 700;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
.fullscreen.tvmode .tvendtime {
|
||||
margin-top: -4px;
|
||||
margin-bottom: 2px;
|
||||
min-height: 6px;
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
/* Button Inside Popover */
|
||||
.popoverbutton {
|
||||
min-width: 24px;
|
||||
min-height: 24px;
|
||||
}
|
||||
|
||||
/* Position Scale */
|
||||
.positionscale {
|
||||
margin: -2px;
|
||||
margin-left: -4px;
|
||||
margin-right: -4px;
|
||||
}
|
||||
.positionscale trough highlight {
|
||||
min-height: 4px;
|
||||
}
|
||||
.osd .positionscale trough highlight {
|
||||
min-height: 6px;
|
||||
}
|
||||
.fullscreen.tvmode .positionscale trough slider {
|
||||
color: transparent;
|
||||
background: transparent;
|
||||
border-color: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
.positionscale mark indicator {
|
||||
min-height: 6px;
|
||||
}
|
||||
.positionscale.fine-tune mark indicator {
|
||||
min-height: 6px;
|
||||
}
|
||||
.fullscreen.tvmode .positionscale mark indicator {
|
||||
min-height: 7px;
|
||||
min-width: 2px;
|
||||
}
|
||||
.fullscreen.tvmode .positionscale.fine-tune mark indicator {
|
||||
min-height: 7px;
|
||||
min-width: 2px;
|
||||
}
|
||||
.positionscale marks.top {
|
||||
margin-top: -6px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.positionscale marks.bottom {
|
||||
margin-top: 4px;
|
||||
margin-bottom: -6px;
|
||||
}
|
||||
.fullscreen.tvmode .positionscale marks.top {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.fullscreen.tvmode .positionscale marks.bottom {
|
||||
margin-top: 2px;
|
||||
}
|
||||
.fullscreen.tvmode .positionscale trough highlight {
|
||||
border-radius: 3px;
|
||||
min-height: 20px;
|
||||
}
|
||||
.fullscreen.tvmode .positionscale.fine-tune trough highlight {
|
||||
border-radius: 3px;
|
||||
min-height: 20px;
|
||||
}
|
||||
|
||||
/* Volume Scale */
|
||||
.volumescale {
|
||||
margin: -2px;
|
||||
margin-left: -8px;
|
||||
margin-right: -6px;
|
||||
min-height: 180px;
|
||||
}
|
||||
.fullscreen.tvmode .volumescale {
|
||||
margin: 2px;
|
||||
margin-left: -6px;
|
||||
margin-right: -4px;
|
||||
min-height: 260px;
|
||||
}
|
||||
.volumescale marks label {
|
||||
margin-right: 4px;
|
||||
margin-top: -4px;
|
||||
margin-bottom: -6px;
|
||||
}
|
||||
.fullscreen.tvmode .volumescale trough highlight {
|
||||
min-width: 6px;
|
||||
}
|
||||
.overamp trough highlight {
|
||||
background: @error_color;
|
||||
}
|
||||
|
||||
/* Elapsed Popover */
|
||||
.elapsedpopoverbox {
|
||||
min-width: 260px;
|
||||
}
|
||||
.elapsedpopoverbox box separator {
|
||||
background: @insensitive_fg_color;
|
||||
}
|
||||
.fullscreen.tvmode .elapsedpopoverbox {
|
||||
min-width: 360px;
|
||||
}
|
||||
.fullscreen.tvmode .speedscale trough highlight {
|
||||
min-height: 6px;
|
||||
}
|
||||
|
||||
.narrowbutton {
|
||||
min-width: 8px;
|
||||
}
|
||||
@keyframes halfrotation {
|
||||
to { transform: rotate(0.5turn); }
|
||||
}
|
||||
.halfrotate {
|
||||
animation-name: halfrotation;
|
||||
animation-duration: 200ms;
|
||||
animation-delay: 280ms;
|
||||
animation-timing-function: linear;
|
||||
animation-fill-mode: forwards;
|
||||
animation-iteration-count: 1;
|
||||
}
|
||||
|
||||
/* Chapters */
|
||||
.chapterlabel {
|
||||
min-width: 32px;
|
||||
}
|
||||
.fullscreen.tvmode .chapterlabel {
|
||||
min-width: 40px;
|
||||
text-shadow: none;
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Preferences */
|
||||
.prefsnotebook grid {
|
||||
margin: 10px;
|
||||
}
|
||||
.prefssubpage header {
|
||||
background: none;
|
||||
}
|
||||
.prefssubpage header tabs tab {
|
||||
box-shadow: none;
|
||||
margin: 0px;
|
||||
margin-right: 1px;
|
||||
}
|
||||
.prefssubpage header tabs tab:checked {
|
||||
color: initial;
|
||||
background: @theme_selected_bg_color;
|
||||
}
|
||||
|
||||
/* Open URI Dialog */
|
||||
.uridialogbox {
|
||||
margin: 12px;
|
||||
}
|
||||
|
||||
/* Tweaks */
|
||||
.nobackground {
|
||||
background: none;
|
||||
}
|
||||
.noborder {
|
||||
border: none;
|
||||
}
|
||||
.controlsbox {
|
||||
background: @theme_bg_color;
|
||||
}
|
||||
.gpufriendly {
|
||||
box-shadow: -8px -8px transparent, 8px 8px transparent;
|
||||
}
|
||||
.fullscreen.gpufriendlyfs {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/* Error BG */
|
||||
.blackbackground {
|
||||
background: black;
|
||||
}
|
@@ -1,122 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<schemalist gettext-domain="com.github.rafostar.Clapper">
|
||||
<schema id="com.github.rafostar.Clapper" path="/com/github/rafostar/Clapper/">
|
||||
<!-- General -->
|
||||
<key name="fullscreen-auto" type="b">
|
||||
<default>false</default>
|
||||
<summary>Automatically enter fullscreen when first file is loaded</summary>
|
||||
</key>
|
||||
<key name="volume-initial" type="s">
|
||||
<default>"restore"</default>
|
||||
<summary>Mode used for startup volume value</summary>
|
||||
</key>
|
||||
<key name="volume-value" type="i">
|
||||
<default>100</default>
|
||||
<summary>Custom initial volume value in percentage after startup</summary>
|
||||
</key>
|
||||
<key name="close-auto" type="b">
|
||||
<default>false</default>
|
||||
<summary>Automatically close the app after playback finishes</summary>
|
||||
</key>
|
||||
|
||||
<!-- Behaviour -->
|
||||
<key name="seeking-mode" type="s">
|
||||
<default>"normal"</default>
|
||||
<summary>Mode used for seeking</summary>
|
||||
</key>
|
||||
<key name="seeking-value" type="i">
|
||||
<default>10</default>
|
||||
<summary>Time amount to seek with single press of arrow keys</summary>
|
||||
</key>
|
||||
<key name="seeking-unit" type="s">
|
||||
<default>"second"</default>
|
||||
<summary>Unit to use with seeking value</summary>
|
||||
</key>
|
||||
<key name="resume-enabled" type="b">
|
||||
<default>true</default>
|
||||
<summary>Ask to resume unfinished video</summary>
|
||||
</key>
|
||||
<key name="resume-database" type="s">
|
||||
<default>'[]'</default>
|
||||
<summary>Data storing unfinished videos resume info</summary>
|
||||
</key>
|
||||
<key name="floating-stick" type="b">
|
||||
<default>false</default>
|
||||
<summary>Auto stick floating window to all workspaces</summary>
|
||||
</key>
|
||||
|
||||
<!-- Audio -->
|
||||
<key name="audio-offset" type="d">
|
||||
<default>0</default>
|
||||
<summary>Offset time for audio tracks relative to video (milliseconds)</summary>
|
||||
</key>
|
||||
|
||||
<!-- Subtitles -->
|
||||
<key name="subtitle-offset" type="d">
|
||||
<default>0</default>
|
||||
<summary>Offset time for subtitle tracks relative to video (milliseconds)</summary>
|
||||
</key>
|
||||
<key name="subtitle-font" type="s">
|
||||
<default>"Sans 12"</default>
|
||||
<summary>The subtitles font description</summary>
|
||||
</key>
|
||||
|
||||
<!-- Network -->
|
||||
<key name="webserver-enabled" type="b">
|
||||
<default>false</default>
|
||||
<summary>Enable WebSocket server for remote playback control</summary>
|
||||
</key>
|
||||
<key name="webserver-port" type="i">
|
||||
<default>6446</default>
|
||||
<summary>Listening port to use for incoming WebSocket connections</summary>
|
||||
</key>
|
||||
<key name="webapp-enabled" type="b">
|
||||
<default>false</default>
|
||||
<summary>Run built-in broadway based web application</summary>
|
||||
</key>
|
||||
<key name="webapp-port" type="i">
|
||||
<default>8086</default>
|
||||
<summary>Port for running broadwayd service</summary>
|
||||
</key>
|
||||
|
||||
<!-- Tweaks -->
|
||||
<key name="dark-theme" type="b">
|
||||
<default>true</default>
|
||||
<summary>Enable to force the app to use dark theme variant</summary>
|
||||
</key>
|
||||
<key name="render-shadows" type="b">
|
||||
<default>true</default>
|
||||
<summary>Enable rendering window shadows (only if theme has them)</summary>
|
||||
</key>
|
||||
|
||||
<!-- GStreamer -->
|
||||
<key name="plugin-ranking" type="s">
|
||||
<default>'[{"apply":false,"name":"vah264dec","rank":300}]'</default>
|
||||
<summary>Custom values for GStreamer plugin ranking</summary>
|
||||
</key>
|
||||
<key name="play-flags" type="i">
|
||||
<default>1687</default>
|
||||
<summary>Set PlayFlags for playbin</summary>
|
||||
</key>
|
||||
|
||||
<!-- YouTube -->
|
||||
<key name="yt-adaptive-enabled" type="b">
|
||||
<default>false</default>
|
||||
<summary>Enable to use adaptive streaming for YouTube</summary>
|
||||
</key>
|
||||
<key name="yt-quality-type" type="s">
|
||||
<default>"hfr"</default>
|
||||
<summary>Max YouTube video quality type</summary>
|
||||
</key>
|
||||
|
||||
<!-- Other -->
|
||||
<key name="window-size" type="s">
|
||||
<default>'[800, 490]'</default>
|
||||
<summary>Stores window size to restore on next launch</summary>
|
||||
</key>
|
||||
<key name="volume-last" type="d">
|
||||
<default>1</default>
|
||||
<summary>Stores last linear volume value to apply on startup</summary>
|
||||
</key>
|
||||
</schema>
|
||||
</schemalist>
|
@@ -1,109 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop-application">
|
||||
<id>com.github.rafostar.Clapper</id>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>GPL-3.0-or-later</project_license>
|
||||
<name>Clapper</name>
|
||||
<summary>Simple and modern GNOME media player</summary>
|
||||
<translation type="gettext">com.github.rafostar.Clapper</translation>
|
||||
<launchable type="desktop-id">com.github.rafostar.Clapper.desktop</launchable>
|
||||
<description>
|
||||
<p>
|
||||
Clapper is a GNOME media player build using GJS with GTK4 toolkit.
|
||||
The media player is using GStreamer as a media backend and renders
|
||||
everything via OpenGL. Player works natively on both Xorg and Wayland.
|
||||
It also supports VA-API on AMD/Intel GPUs.
|
||||
</p>
|
||||
<p>
|
||||
The media player has an adaptive GUI. When viewing videos in "Windowed Mode",
|
||||
Clapper will use mostly unmodified GTK widgets to match your OS look nicely.
|
||||
When player enters "Fullscreen Mode" all GUI elements will become darker, bigger
|
||||
and semi-transparent for your viewing comfort. It also has a "Floating Mode" which
|
||||
displays video only on top of all other windows for a PiP-like viewing experience.
|
||||
Mobile friendly transitions are also supported.
|
||||
</p>
|
||||
<p>
|
||||
For best stability Wayland session is recommended. Wayland users with AMD/Intel GPUs
|
||||
can try enabling HIGHLY EXPERIMENTAL "vah264dec" plugin inside player preferences
|
||||
for reduced CPU and GPU usage on standard (8-bit) H.264 videos.
|
||||
</p>
|
||||
</description>
|
||||
<developer_name>Rafał Dzięgiel</developer_name>
|
||||
<url type="homepage">https://rafostar.github.io/clapper</url>
|
||||
<url type="bugtracker">https://github.com/Rafostar/clapper/issues</url>
|
||||
<url type="donation">https://liberapay.com/Clapper</url>
|
||||
<url type="help">https://github.com/Rafostar/clapper/wiki</url>
|
||||
<categories>
|
||||
<category>AudioVideo</category>
|
||||
<category>Video</category>
|
||||
</categories>
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<image type="source">https://raw.githubusercontent.com/wiki/Rafostar/clapper/media/screenshot-windowed.png</image>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<image type="source">https://raw.githubusercontent.com/wiki/Rafostar/clapper/media/screenshot-fullscreen.png</image>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<image type="source">https://raw.githubusercontent.com/wiki/Rafostar/clapper/media/screenshot-floating.png</image>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<image type="source">https://raw.githubusercontent.com/wiki/Rafostar/clapper/media/screenshot-mobile.png</image>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<releases>
|
||||
<release version="0.2.1" date="2021-04-19">
|
||||
<description>
|
||||
<p>Player:</p>
|
||||
<ul>
|
||||
<li>Fix missing top left menu buttons on some system configurations</li>
|
||||
<li>Fix potential video sink deadlock</li>
|
||||
<li>Do not show mobile controls transition on launch</li>
|
||||
<li>Show tooltip with full playlist item text on hover</li>
|
||||
</ul>
|
||||
<p>YouTube:</p>
|
||||
<ul>
|
||||
<li>Auto select best matching resolution for used monitor</li>
|
||||
<li>Added some YouTube related preferences</li>
|
||||
<li>Added support for live HLS videos</li>
|
||||
<li>Added support for non-adaptive live HLS streaming</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.2.0" date="2021-04-13">
|
||||
<description>
|
||||
<p>New features:</p>
|
||||
<ul>
|
||||
<li>YouTube support - drag and drop videos from youtube or use open URI dialog to play them</li>
|
||||
<li>Added convenient ways of opening external subtitles</li>
|
||||
</ul>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Few GUI layout improvements</li>
|
||||
<li>Simplified video sink code</li>
|
||||
<li>Fixed missing Ctrl+O common keybinding</li>
|
||||
<li>Fixed error when playback finishes during controls reveal animation</li>
|
||||
<li>Fixed startup window size on Xorg</li>
|
||||
<li>Fixed top time not showing up on fullscreen startup</li>
|
||||
<li>Fixed missing file extensions in online URIs</li>
|
||||
<li>Fixed some error messages not being displayed</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.1.0" date="2021-02-26">
|
||||
<description>
|
||||
<p>First stable release</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.0.0" date="2020-10-31">
|
||||
<description>
|
||||
<p>GitHub version</p>
|
||||
</description>
|
||||
</release>
|
||||
</releases>
|
||||
<content_rating type="oars-1.1" />
|
||||
<custom>
|
||||
<value key="Purism::form_factor">workstation</value>
|
||||
<value key="Purism::form_factor">mobile</value>
|
||||
</custom>
|
||||
</component>
|
@@ -1,29 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 256 256" width="256" height="256">
|
||||
<defs>
|
||||
<path d="M27.2 243.52C27.2 236.16 27.2 199.83 27.2 134.22C47.64 134.22 211.12 134.22 231.56 134.22C231.56 199.83 231.56 236.16 231.56 243.52C231.56 250.4 225.96 256 218.92 256C183.07 256 57.77 256 39.84 256C32.8 256 27.2 250.4 27.2 243.52Z" id="b1nGq5BrLC"></path>
|
||||
<path d="M24.32 103.65C24.32 106.22 24.32 127.02 24.32 129.58C24.32 132.78 26.72 135.18 29.92 135.18C50.41 135.18 215.08 135.18 235.72 135.18C238.76 135.18 241.32 132.78 241.32 129.58C241.32 127.02 241.32 106.22 241.32 103.65C241.32 100.45 238.76 98.05 235.72 98.05C194.59 98.05 50.41 98.05 29.92 98.05C26.72 98.05 24.32 100.45 24.32 103.65Z" id="a3jkaoNn4k"></path>
|
||||
<path d="M174.59 135.18L211.87 98.05L171.07 98.05L133.78 135.18L174.59 135.18Z" id="atpVQ8mnd"></path>
|
||||
<path d="M76.81 135.18L114.1 98.05L73.13 98.05L35.84 135.18L76.81 135.18Z" id="bMtYoNHu0"></path>
|
||||
<path d="M19.04 69.41C19.84 71.97 25.92 91.97 26.72 94.37C27.68 97.41 30.72 99.01 33.76 98.05C54.09 91.81 216.68 42.04 237 35.8C240.04 35 241.64 31.8 240.84 28.92C240.04 26.36 233.96 6.36 233.16 3.96C232.2 0.92 229.16 -0.68 226.12 0.28C185.47 12.6 43.21 56.29 22.88 62.53C19.84 63.33 18.24 66.53 19.04 69.41Z" id="b5oP0Glp4"></path>
|
||||
<path d="M176.51 54.37L129.94 29.4L169.15 17.56L215.72 42.52L176.51 54.37Z" id="lwBgev6DR"></path>
|
||||
<path d="M81.61 83.49L35.04 58.69L74.25 46.69L120.82 71.49L81.61 83.49Z" id="cUsjEMRUu"></path>
|
||||
<path d="M14.72 66.69C14.72 72.93 14.72 123.02 14.72 129.26C14.72 132.62 17.44 135.18 20.64 135.18C26.56 135.18 74.09 135.18 80.01 135.18C84.33 135.18 87.21 130.86 85.61 127.02C82.89 120.78 61.45 70.53 58.73 64.29C57.77 62.05 55.69 60.77 53.29 60.77C46.73 60.77 24 60.77 20.64 60.77C17.44 60.77 14.72 63.33 14.72 66.69Z" id="c1bcHZGXe"></path>
|
||||
<path d="M32.64 60.61C31.52 60.61 21.92 60.61 20.64 60.61C17.44 60.61 14.72 63.33 14.72 66.53C14.72 72.77 14.72 123.02 14.72 129.26C14.72 132.46 17.44 135.18 20.64 135.18C21.92 135.18 31.52 135.18 32.64 135.18C29.44 135.18 26.72 132.46 26.72 129.26C26.72 116.62 26.72 72.77 26.72 66.53C26.72 63.33 29.44 60.61 32.64 60.61Z" id="f2PtH0V1vC"></path>
|
||||
<path d="M231.56 135.18C231.56 143.82 231.56 148.46 231.56 149.42C231.56 149.42 231.56 149.42 231.56 149.42C108.98 149.42 40.8 149.42 27.2 149.42C27.2 149.42 27.2 149.42 27.2 149.42C27.2 140.94 27.2 136.14 27.2 135.18C27.2 135.18 27.2 135.18 27.2 135.18C149.78 135.18 217.96 135.18 231.56 135.18C231.56 135.18 231.56 135.18 231.56 135.18Z" id="a1SvrrkqVm"></path>
|
||||
<path d="M104.22 162.46L104.22 234.46L163.22 198.54L104.22 162.46Z" id="agXcvKqh8"></path>
|
||||
</defs>
|
||||
<g>
|
||||
<g><use xlink:href="#b1nGq5BrLC" fill="#4747d1"></use></g>
|
||||
<g><use xlink:href="#a3jkaoNn4k" fill="#4747d1"></use></g>
|
||||
<g><use xlink:href="#atpVQ8mnd" fill="#f1f1f1"></use></g>
|
||||
<g><use xlink:href="#bMtYoNHu0" fill="#f1f1f1"></use></g>
|
||||
<g><use xlink:href="#b5oP0Glp4" fill="#4747d1"></use></g>
|
||||
<g><use xlink:href="#lwBgev6DR" fill="#f1f1f1"></use></g>
|
||||
<g><use xlink:href="#cUsjEMRUu" fill="#f1f1f1"></use></g>
|
||||
<g><use xlink:href="#c1bcHZGXe" fill="#a9a9a9"></use></g>
|
||||
<g><use xlink:href="#f2PtH0V1vC" opacity="0.2" fill="#000000"></use></g>
|
||||
<g><use xlink:href="#a1SvrrkqVm" opacity="0.2" fill="#000000"></use></g>
|
||||
<g><use xlink:href="#agXcvKqh8" fill="#f1f1f1"></use></g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 3.4 KiB |
@@ -1,18 +0,0 @@
|
||||
sharedir = join_paths(get_option('prefix'), 'share')
|
||||
iconsdir = join_paths(sharedir, 'icons', 'hicolor')
|
||||
|
||||
install_data('com.github.rafostar.Clapper.svg',
|
||||
install_dir: join_paths(iconsdir, 'scalable', 'apps')
|
||||
)
|
||||
install_data('com.github.rafostar.Clapper.gschema.xml',
|
||||
install_dir: join_paths(sharedir, 'glib-2.0', 'schemas')
|
||||
)
|
||||
install_data('com.github.rafostar.Clapper.xml',
|
||||
install_dir: join_paths(sharedir, 'mime', 'packages')
|
||||
)
|
||||
install_data('com.github.rafostar.Clapper.desktop',
|
||||
install_dir: join_paths(sharedir, 'applications')
|
||||
)
|
||||
install_data('com.github.rafostar.Clapper.metainfo.xml',
|
||||
install_dir: join_paths(sharedir, 'metainfo')
|
||||
)
|
10
doc/meson.build
Normal file
10
doc/meson.build
Normal file
@@ -0,0 +1,10 @@
|
||||
gi_docgen = find_program('gi-docgen', required: get_option('doc'))
|
||||
dot = find_program('dot', required: get_option('doc')) # Class hierarchy generation
|
||||
build_doc = (gi_docgen.found() and dot.found() and get_option('doc'))
|
||||
|
||||
if build_doc
|
||||
if not build_gir
|
||||
error('Building documentation requires introspection to be compiled')
|
||||
endif
|
||||
subdir('reference')
|
||||
endif
|
63
doc/reference/clapper-gtk/clapper-gtk.toml.in
Normal file
63
doc/reference/clapper-gtk/clapper-gtk.toml.in
Normal file
@@ -0,0 +1,63 @@
|
||||
[library]
|
||||
version = "@CLAPPER_VERSION@"
|
||||
browse_url = "https://github.com/Rafostar/clapper/"
|
||||
repository_url = "https://github.com/Rafostar/clapper.git"
|
||||
website_url = "https://rafostar.github.io/clapper/"
|
||||
docs_url = "https://rafostar.github.io/clapper/doc/clapper-gtk/"
|
||||
authors = "Rafał Dzięgiel"
|
||||
logo_url = "clapper-logo.svg"
|
||||
license = "LGPL-2.1-or-later"
|
||||
description = "Clapper GTK integration library"
|
||||
devhelp = true
|
||||
search_index = true
|
||||
|
||||
dependencies = ["Clapper@CLAPPER_VERSION_SUFFIX@", "Gtk-4.0"]
|
||||
|
||||
[dependencies."Clapper@CLAPPER_VERSION_SUFFIX@"]
|
||||
name = "Clapper"
|
||||
description = "Clapper playback library"
|
||||
docs_url = "https://rafostar.github.io/clapper/doc/clapper/"
|
||||
|
||||
[dependencies."Gtk-4.0"]
|
||||
name = "Gtk"
|
||||
description = "The GTK toolkit"
|
||||
docs_url = "https://docs.gtk.org/gtk4/"
|
||||
|
||||
related = ["GLib-2.0", "GObject-2.0", "Gio-2.0", "Gst-1.0"]
|
||||
|
||||
[related."GLib-2.0"]
|
||||
name = "GLib"
|
||||
description = "A general-purpose, portable utility library"
|
||||
docs_url = "https://docs.gtk.org/glib/"
|
||||
|
||||
[related."GObject-2.0"]
|
||||
name = "GObject"
|
||||
description = "The base type system library"
|
||||
docs_url = "https://docs.gtk.org/gobject/"
|
||||
|
||||
[related."Gio-2.0"]
|
||||
name = "Gio"
|
||||
description = "GObject Interfaces and Objects, Networking, IPC, and I/O"
|
||||
docs_url = "https://docs.gtk.org/gio/"
|
||||
|
||||
[related."Gst-1.0"]
|
||||
name = "Gst"
|
||||
description = "GStreamer core library"
|
||||
docs_url = "https://gstreamer.freedesktop.org/documentation/gstreamer/gi-index.html"
|
||||
|
||||
[theme]
|
||||
name = "basic"
|
||||
show_index_summary = true
|
||||
show_class_hierarchy = true
|
||||
|
||||
[source-location]
|
||||
base_url = "https://github.com/Rafostar/clapper/tree/master/"
|
||||
|
||||
[extra]
|
||||
# The same order will be used when generating the index
|
||||
content_files = [
|
||||
]
|
||||
content_images = [
|
||||
"images/clapper-logo.svg",
|
||||
]
|
||||
urlmap_file = "urlmap.js"
|
29
doc/reference/clapper-gtk/images/clapper-logo.svg
Normal file
29
doc/reference/clapper-gtk/images/clapper-logo.svg
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 256 256" width="256" height="256">
|
||||
<defs>
|
||||
<path id="b1nGq5BrLC" d="M27.2 243.52C27.2 236.16 27.2 199.83 27.2 134.22C47.64 134.22 211.12 134.22 231.56 134.22C231.56 199.83 231.56 236.16 231.56 243.52C231.56 250.4 225.96 256 218.92 256C183.07 256 57.77 256 39.84 256C32.8 256 27.2 250.4 27.2 243.52Z"></path>
|
||||
<path id="a3jkaoNn4k" d="M24.32 103.65C24.32 106.22 24.32 127.02 24.32 129.58C24.32 132.78 26.72 135.18 29.92 135.18C50.41 135.18 215.08 135.18 235.72 135.18C238.76 135.18 241.32 132.78 241.32 129.58C241.32 127.02 241.32 106.22 241.32 103.65C241.32 100.45 238.76 98.05 235.72 98.05C194.59 98.05 50.41 98.05 29.92 98.05C26.72 98.05 24.32 100.45 24.32 103.65Z"></path>
|
||||
<path id="atpVQ8mnd" d="M174.59 135.18L211.87 98.05L171.07 98.05L133.78 135.18L174.59 135.18Z"></path>
|
||||
<path id="bMtYoNHu0" d="M76.81 135.18L114.1 98.05L73.13 98.05L35.84 135.18L76.81 135.18Z"></path>
|
||||
<path id="b5oP0Glp4" d="M19.04 69.41C19.84 71.97 25.92 91.97 26.72 94.37C27.68 97.41 30.72 99.01 33.76 98.05C54.09 91.81 216.68 42.04 237 35.8C240.04 35 241.64 31.8 240.84 28.92C240.04 26.36 233.96 6.36 233.16 3.96C232.2 0.92 229.16 -0.68 226.12 0.28C185.47 12.6 43.21 56.29 22.88 62.53C19.84 63.33 18.24 66.53 19.04 69.41Z"></path>
|
||||
<path id="lwBgev6DR" d="M176.51 54.37L129.94 29.4L169.15 17.56L215.72 42.52L176.51 54.37Z"></path>
|
||||
<path id="cUsjEMRUu" d="M81.61 83.49L35.04 58.69L74.25 46.69L120.82 71.49L81.61 83.49Z"></path>
|
||||
<path id="c1bcHZGXe" d="M14.72 66.69C14.72 72.93 14.72 123.02 14.72 129.26C14.72 132.62 17.44 135.18 20.64 135.18C26.56 135.18 74.09 135.18 80.01 135.18C84.33 135.18 87.21 130.86 85.61 127.02C82.89 120.78 61.45 70.53 58.73 64.29C57.77 62.05 55.69 60.77 53.29 60.77C46.73 60.77 24 60.77 20.64 60.77C17.44 60.77 14.72 63.33 14.72 66.69Z"></path>
|
||||
<path id="f2PtH0V1vC" d="M32.64 60.61C31.52 60.61 21.92 60.61 20.64 60.61C17.44 60.61 14.72 63.33 14.72 66.53C14.72 72.77 14.72 123.02 14.72 129.26C14.72 132.46 17.44 135.18 20.64 135.18C21.92 135.18 31.52 135.18 32.64 135.18C29.44 135.18 26.72 132.46 26.72 129.26C26.72 116.62 26.72 72.77 26.72 66.53C26.72 63.33 29.44 60.61 32.64 60.61Z"></path>
|
||||
<path id="a1SvrrkqVm" d="M231.56 135.18C231.56 143.82 231.56 148.46 231.56 149.42C231.56 149.42 231.56 149.42 231.56 149.42C108.98 149.42 40.8 149.42 27.2 149.42C27.2 149.42 27.2 149.42 27.2 149.42C27.2 140.94 27.2 136.14 27.2 135.18C27.2 135.18 27.2 135.18 27.2 135.18C149.78 135.18 217.96 135.18 231.56 135.18C231.56 135.18 231.56 135.18 231.56 135.18Z"></path>
|
||||
<path id="agXcvKqh8" d="M104.22 162.46L104.22 234.46L163.22 198.54L104.22 162.46Z"></path>
|
||||
</defs>
|
||||
<g>
|
||||
<g><use xlink:href="#b1nGq5BrLC" fill="#4747d1" transform="matrix(1, 0, 0, 0.97, 0, 0)"></use></g>
|
||||
<g><use xlink:href="#a3jkaoNn4k" fill="#4747d1" transform="matrix(1, 0, 0, 0.97, 0, 0)"></use></g>
|
||||
<g><use xlink:href="#atpVQ8mnd" fill="#f1f1f1" transform="matrix(1, 0, 0, 0.97, 0, 0)"></use></g>
|
||||
<g><use xlink:href="#bMtYoNHu0" fill="#f1f1f1" transform="matrix(1, 0, 0, 0.97, 0, 0)"></use></g>
|
||||
<g><use xlink:href="#b5oP0Glp4" fill="#4747d1" transform="matrix(1, 0, 0, 0.97, 0, 0)"></use></g>
|
||||
<g><use xlink:href="#lwBgev6DR" fill="#f1f1f1" transform="matrix(1, 0, 0, 0.97, 0, 0)"></use></g>
|
||||
<g><use xlink:href="#cUsjEMRUu" fill="#f1f1f1" transform="matrix(1, 0, 0, 0.97, 0, 0)"></use></g>
|
||||
<g><use xlink:href="#c1bcHZGXe" fill="#a9a9a9" transform="matrix(1, 0, 0, 0.97, 0, 0)"></use></g>
|
||||
<g><use xlink:href="#f2PtH0V1vC" opacity="0.2" fill="#000000" transform="matrix(1, 0, 0, 0.97, 0, 0)"></use></g>
|
||||
<g><use xlink:href="#a1SvrrkqVm" opacity="0.2" fill="#000000" transform="matrix(1, 0, 0, 0.97, 0, 0)"></use></g>
|
||||
<g><use xlink:href="#agXcvKqh8" fill="#f1f1f1" transform="matrix(1, 0, 0, 0.97, 0, 0)"></use></g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.8 KiB |
29
doc/reference/clapper-gtk/meson.build
Normal file
29
doc/reference/clapper-gtk/meson.build
Normal file
@@ -0,0 +1,29 @@
|
||||
clappergtk_toml = configure_file(
|
||||
input: 'clapper-gtk.toml.in',
|
||||
output: 'clapper-gtk.toml',
|
||||
configuration: doc_version_conf,
|
||||
install: true,
|
||||
install_dir: join_paths(datadir, 'doc', 'clapper-gtk'),
|
||||
)
|
||||
|
||||
custom_target('clapper-gtk-doc',
|
||||
input: [
|
||||
clappergtk_toml,
|
||||
clappergtk_gir[0],
|
||||
],
|
||||
output: 'clapper-gtk',
|
||||
command: [
|
||||
gi_docgen,
|
||||
'generate',
|
||||
gi_docgen_common_args,
|
||||
'--add-include-path=@0@'.format(join_paths(meson.project_build_root(), 'src', 'lib', 'clapper-gtk')),
|
||||
'--config=@INPUT0@',
|
||||
'--output-dir=@OUTPUT@',
|
||||
'--content-dir=@0@'.format(meson.current_build_dir()),
|
||||
'--content-dir=@0@'.format(meson.current_source_dir()),
|
||||
'@INPUT1@',
|
||||
],
|
||||
build_by_default: true,
|
||||
install: true,
|
||||
install_dir: join_paths(datadir, 'doc'),
|
||||
)
|
8
doc/reference/clapper-gtk/urlmap.js
Normal file
8
doc/reference/clapper-gtk/urlmap.js
Normal file
@@ -0,0 +1,8 @@
|
||||
baseURLs = [
|
||||
['GLib', 'https://docs.gtk.org/glib/'],
|
||||
['GObject', 'https://docs.gtk.org/gobject/'],
|
||||
['Gio', 'https://docs.gtk.org/gio/'],
|
||||
['Gtk', 'https://docs.gtk.org/gtk4/'],
|
||||
['Gst', 'https://gstreamer.freedesktop.org/documentation/gstreamer/gi-index.html?'],
|
||||
['Clapper', 'https://rafostar.github.io/clapper/doc/clapper/'],
|
||||
]
|
73
doc/reference/clapper/clapper.toml.in
Normal file
73
doc/reference/clapper/clapper.toml.in
Normal file
@@ -0,0 +1,73 @@
|
||||
[library]
|
||||
version = "@CLAPPER_VERSION@"
|
||||
browse_url = "https://github.com/Rafostar/clapper/"
|
||||
repository_url = "https://github.com/Rafostar/clapper.git"
|
||||
website_url = "https://rafostar.github.io/clapper/"
|
||||
docs_url = "https://rafostar.github.io/clapper/doc/clapper/"
|
||||
authors = "Rafał Dzięgiel"
|
||||
logo_url = "clapper-logo.svg"
|
||||
license = "LGPL-2.1-or-later"
|
||||
description = "Clapper playback library"
|
||||
devhelp = true
|
||||
search_index = true
|
||||
|
||||
dependencies = ["GLib-2.0", "GObject-2.0", "Gio-2.0", "Gst-1.0", "GstBase-1.0", "GstAudio-1.0", "GstTag-1.0", "GstPbutils-1.0"]
|
||||
|
||||
[dependencies."GLib-2.0"]
|
||||
name = "GLib"
|
||||
description = "A general-purpose, portable utility library"
|
||||
docs_url = "https://docs.gtk.org/glib/"
|
||||
|
||||
[dependencies."GObject-2.0"]
|
||||
name = "GObject"
|
||||
description = "The base type system library"
|
||||
docs_url = "https://docs.gtk.org/gobject/"
|
||||
|
||||
[dependencies."Gio-2.0"]
|
||||
name = "Gio"
|
||||
description = "GObject Interfaces and Objects, Networking, IPC, and I/O"
|
||||
docs_url = "https://docs.gtk.org/gio/"
|
||||
|
||||
[dependencies."Gst-1.0"]
|
||||
name = "Gst"
|
||||
description = "GStreamer core library"
|
||||
docs_url = "https://gstreamer.freedesktop.org/documentation/gstreamer/gi-index.html"
|
||||
|
||||
[dependencies."GstBase-1.0"]
|
||||
name = "GstBase"
|
||||
description = "GStreamer base and utility classes"
|
||||
docs_url = "https://gstreamer.freedesktop.org/documentation/base/"
|
||||
|
||||
[dependencies."GstAudio-1.0"]
|
||||
name = "GstAudio"
|
||||
description = "GStreamer audio library"
|
||||
docs_url = "https://gstreamer.freedesktop.org/documentation/audio/"
|
||||
|
||||
[dependencies."GstTag-1.0"]
|
||||
name = "GstTag"
|
||||
description = "GStreamer tag support library"
|
||||
docs_url = "https://gstreamer.freedesktop.org/documentation/tag/"
|
||||
|
||||
[dependencies."GstPbutils-1.0"]
|
||||
name = "GstPbutils"
|
||||
description = "GStreamer base utils library"
|
||||
docs_url = "https://gstreamer.freedesktop.org/documentation/pbutils/"
|
||||
|
||||
related = []
|
||||
|
||||
[theme]
|
||||
name = "basic"
|
||||
show_index_summary = true
|
||||
show_class_hierarchy = true
|
||||
|
||||
[source-location]
|
||||
base_url = "https://github.com/Rafostar/clapper/tree/master/"
|
||||
|
||||
[extra]
|
||||
# The same order will be used when generating the index
|
||||
content_files = [
|
||||
]
|
||||
content_images = [
|
||||
"images/clapper-logo.svg",
|
||||
]
|
||||
urlmap_file = "urlmap.js"
|
29
doc/reference/clapper/images/clapper-logo.svg
Normal file
29
doc/reference/clapper/images/clapper-logo.svg
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 256 256" width="256" height="256">
|
||||
<defs>
|
||||
<path id="b1nGq5BrLC" d="M27.2 243.52C27.2 236.16 27.2 199.83 27.2 134.22C47.64 134.22 211.12 134.22 231.56 134.22C231.56 199.83 231.56 236.16 231.56 243.52C231.56 250.4 225.96 256 218.92 256C183.07 256 57.77 256 39.84 256C32.8 256 27.2 250.4 27.2 243.52Z"></path>
|
||||
<path id="a3jkaoNn4k" d="M24.32 103.65C24.32 106.22 24.32 127.02 24.32 129.58C24.32 132.78 26.72 135.18 29.92 135.18C50.41 135.18 215.08 135.18 235.72 135.18C238.76 135.18 241.32 132.78 241.32 129.58C241.32 127.02 241.32 106.22 241.32 103.65C241.32 100.45 238.76 98.05 235.72 98.05C194.59 98.05 50.41 98.05 29.92 98.05C26.72 98.05 24.32 100.45 24.32 103.65Z"></path>
|
||||
<path id="atpVQ8mnd" d="M174.59 135.18L211.87 98.05L171.07 98.05L133.78 135.18L174.59 135.18Z"></path>
|
||||
<path id="bMtYoNHu0" d="M76.81 135.18L114.1 98.05L73.13 98.05L35.84 135.18L76.81 135.18Z"></path>
|
||||
<path id="b5oP0Glp4" d="M19.04 69.41C19.84 71.97 25.92 91.97 26.72 94.37C27.68 97.41 30.72 99.01 33.76 98.05C54.09 91.81 216.68 42.04 237 35.8C240.04 35 241.64 31.8 240.84 28.92C240.04 26.36 233.96 6.36 233.16 3.96C232.2 0.92 229.16 -0.68 226.12 0.28C185.47 12.6 43.21 56.29 22.88 62.53C19.84 63.33 18.24 66.53 19.04 69.41Z"></path>
|
||||
<path id="lwBgev6DR" d="M176.51 54.37L129.94 29.4L169.15 17.56L215.72 42.52L176.51 54.37Z"></path>
|
||||
<path id="cUsjEMRUu" d="M81.61 83.49L35.04 58.69L74.25 46.69L120.82 71.49L81.61 83.49Z"></path>
|
||||
<path id="c1bcHZGXe" d="M14.72 66.69C14.72 72.93 14.72 123.02 14.72 129.26C14.72 132.62 17.44 135.18 20.64 135.18C26.56 135.18 74.09 135.18 80.01 135.18C84.33 135.18 87.21 130.86 85.61 127.02C82.89 120.78 61.45 70.53 58.73 64.29C57.77 62.05 55.69 60.77 53.29 60.77C46.73 60.77 24 60.77 20.64 60.77C17.44 60.77 14.72 63.33 14.72 66.69Z"></path>
|
||||
<path id="f2PtH0V1vC" d="M32.64 60.61C31.52 60.61 21.92 60.61 20.64 60.61C17.44 60.61 14.72 63.33 14.72 66.53C14.72 72.77 14.72 123.02 14.72 129.26C14.72 132.46 17.44 135.18 20.64 135.18C21.92 135.18 31.52 135.18 32.64 135.18C29.44 135.18 26.72 132.46 26.72 129.26C26.72 116.62 26.72 72.77 26.72 66.53C26.72 63.33 29.44 60.61 32.64 60.61Z"></path>
|
||||
<path id="a1SvrrkqVm" d="M231.56 135.18C231.56 143.82 231.56 148.46 231.56 149.42C231.56 149.42 231.56 149.42 231.56 149.42C108.98 149.42 40.8 149.42 27.2 149.42C27.2 149.42 27.2 149.42 27.2 149.42C27.2 140.94 27.2 136.14 27.2 135.18C27.2 135.18 27.2 135.18 27.2 135.18C149.78 135.18 217.96 135.18 231.56 135.18C231.56 135.18 231.56 135.18 231.56 135.18Z"></path>
|
||||
<path id="agXcvKqh8" d="M104.22 162.46L104.22 234.46L163.22 198.54L104.22 162.46Z"></path>
|
||||
</defs>
|
||||
<g>
|
||||
<g><use xlink:href="#b1nGq5BrLC" fill="#4747d1" transform="matrix(1, 0, 0, 0.97, 0, 0)"></use></g>
|
||||
<g><use xlink:href="#a3jkaoNn4k" fill="#4747d1" transform="matrix(1, 0, 0, 0.97, 0, 0)"></use></g>
|
||||
<g><use xlink:href="#atpVQ8mnd" fill="#f1f1f1" transform="matrix(1, 0, 0, 0.97, 0, 0)"></use></g>
|
||||
<g><use xlink:href="#bMtYoNHu0" fill="#f1f1f1" transform="matrix(1, 0, 0, 0.97, 0, 0)"></use></g>
|
||||
<g><use xlink:href="#b5oP0Glp4" fill="#4747d1" transform="matrix(1, 0, 0, 0.97, 0, 0)"></use></g>
|
||||
<g><use xlink:href="#lwBgev6DR" fill="#f1f1f1" transform="matrix(1, 0, 0, 0.97, 0, 0)"></use></g>
|
||||
<g><use xlink:href="#cUsjEMRUu" fill="#f1f1f1" transform="matrix(1, 0, 0, 0.97, 0, 0)"></use></g>
|
||||
<g><use xlink:href="#c1bcHZGXe" fill="#a9a9a9" transform="matrix(1, 0, 0, 0.97, 0, 0)"></use></g>
|
||||
<g><use xlink:href="#f2PtH0V1vC" opacity="0.2" fill="#000000" transform="matrix(1, 0, 0, 0.97, 0, 0)"></use></g>
|
||||
<g><use xlink:href="#a1SvrrkqVm" opacity="0.2" fill="#000000" transform="matrix(1, 0, 0, 0.97, 0, 0)"></use></g>
|
||||
<g><use xlink:href="#agXcvKqh8" fill="#f1f1f1" transform="matrix(1, 0, 0, 0.97, 0, 0)"></use></g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.8 KiB |
29
doc/reference/clapper/meson.build
Normal file
29
doc/reference/clapper/meson.build
Normal file
@@ -0,0 +1,29 @@
|
||||
clapper_toml = configure_file(
|
||||
input: 'clapper.toml.in',
|
||||
output: 'clapper.toml',
|
||||
configuration: doc_version_conf,
|
||||
install: true,
|
||||
install_dir: join_paths(datadir, 'doc', 'clapper'),
|
||||
)
|
||||
|
||||
custom_target('clapper-doc',
|
||||
input: [
|
||||
clapper_toml,
|
||||
clapper_gir[0],
|
||||
],
|
||||
output: 'clapper',
|
||||
command: [
|
||||
gi_docgen,
|
||||
'generate',
|
||||
gi_docgen_common_args,
|
||||
'--add-include-path=@0@'.format(join_paths(meson.project_build_root(), 'src', 'lib', 'clapper')),
|
||||
'--config=@INPUT0@',
|
||||
'--output-dir=@OUTPUT@',
|
||||
'--content-dir=@0@'.format(meson.current_build_dir()),
|
||||
'--content-dir=@0@'.format(meson.current_source_dir()),
|
||||
'@INPUT1@',
|
||||
],
|
||||
build_by_default: true,
|
||||
install: true,
|
||||
install_dir: join_paths(datadir, 'doc'),
|
||||
)
|
10
doc/reference/clapper/urlmap.js
Normal file
10
doc/reference/clapper/urlmap.js
Normal file
@@ -0,0 +1,10 @@
|
||||
baseURLs = [
|
||||
['GLib', 'https://docs.gtk.org/glib/'],
|
||||
['GObject', 'https://docs.gtk.org/gobject/'],
|
||||
['Gio', 'https://docs.gtk.org/gio/'],
|
||||
['Gst', 'https://gstreamer.freedesktop.org/documentation/gstreamer/gi-index.html?'],
|
||||
['GstBase', 'https://gstreamer.freedesktop.org/documentation/base/?'],
|
||||
['GstAudio', 'https://gstreamer.freedesktop.org/documentation/audio/?'],
|
||||
['GstTag', 'https://gstreamer.freedesktop.org/documentation/tag/?'],
|
||||
['GstPbutils', 'https://gstreamer.freedesktop.org/documentation/pbutils/?'],
|
||||
]
|
18
doc/reference/meson.build
Normal file
18
doc/reference/meson.build
Normal file
@@ -0,0 +1,18 @@
|
||||
doc_version_conf = configuration_data()
|
||||
doc_version_conf.set('CLAPPER_VERSION', meson.project_version())
|
||||
doc_version_conf.set('CLAPPER_VERSION_SUFFIX', clapper_version_suffix)
|
||||
|
||||
gi_docgen_common_args = [
|
||||
'--quiet',
|
||||
'--no-namespace-dir',
|
||||
]
|
||||
if get_option('werror')
|
||||
gi_docgen_common_args += ['--fatal-warnings']
|
||||
endif
|
||||
|
||||
if build_clapper
|
||||
subdir('clapper')
|
||||
endif
|
||||
if build_clappergtk
|
||||
subdir('clapper-gtk')
|
||||
endif
|
@@ -1,183 +0,0 @@
|
||||
const { GLib } = imports.gi;
|
||||
|
||||
let ink = { Ink: null };
|
||||
try {
|
||||
ink = imports.ink;
|
||||
} catch(e) {}
|
||||
const { Ink } = ink;
|
||||
|
||||
const DEBUG_ENV = GLib.getenv('DEBUG');
|
||||
|
||||
var Debugger = class
|
||||
{
|
||||
constructor(name, opts)
|
||||
{
|
||||
opts = (opts && typeof opts === 'object')
|
||||
? opts : {};
|
||||
|
||||
this.name = (name && typeof name === 'string')
|
||||
? name : 'GJS';
|
||||
|
||||
this.print_state = (opts.print_state)
|
||||
? true : false;
|
||||
|
||||
this.json_space = (typeof opts.json_space === 'number')
|
||||
? opts.json_space : 2;
|
||||
|
||||
this.name_printer = opts.name_printer || this._getInkPrinter(true);
|
||||
this.message_printer = opts.message_printer || this._getDefaultPrinter();
|
||||
this.time_printer = opts.time_printer || this._getInkPrinter();
|
||||
this.high_precision = opts.high_precision || false;
|
||||
|
||||
if(typeof opts.color !== 'undefined')
|
||||
this.color = opts.color;
|
||||
|
||||
this._isEnabled = false;
|
||||
this._lastDebug = GLib.get_monotonic_time();
|
||||
|
||||
this.enabled = (typeof opts.enabled !== 'undefined')
|
||||
? opts.enabled : this._enabledAtStart;
|
||||
}
|
||||
|
||||
get enabled()
|
||||
{
|
||||
return this._isEnabled;
|
||||
}
|
||||
|
||||
set enabled(value)
|
||||
{
|
||||
if(this._isEnabled === value)
|
||||
return;
|
||||
|
||||
this._isEnabled = (value) ? true : false;
|
||||
|
||||
if(!this.print_state)
|
||||
return;
|
||||
|
||||
let state = (this.enabled) ? 'en' : 'dis';
|
||||
this._runDebug(`debug ${state}abled`);
|
||||
}
|
||||
|
||||
get color()
|
||||
{
|
||||
return this.name_printer.color;
|
||||
}
|
||||
|
||||
set color(value)
|
||||
{
|
||||
this.name_printer.color = value;
|
||||
this.time_printer.color = this.name_printer.color;
|
||||
}
|
||||
|
||||
get debug()
|
||||
{
|
||||
return message => this._debug(message);
|
||||
}
|
||||
|
||||
get _enabledAtStart()
|
||||
{
|
||||
if(!DEBUG_ENV)
|
||||
return false;
|
||||
|
||||
let envArr = DEBUG_ENV.split(',');
|
||||
|
||||
return envArr.some(el => {
|
||||
if(el === this.name || el === '*')
|
||||
return true;
|
||||
|
||||
let searchType;
|
||||
let offset = 0;
|
||||
|
||||
if(el.startsWith('*')) {
|
||||
searchType = 'ends';
|
||||
} else if(el.endsWith('*')) {
|
||||
searchType = 'starts';
|
||||
offset = 1;
|
||||
}
|
||||
|
||||
if(!searchType)
|
||||
return false;
|
||||
|
||||
return this.name[searchType + 'With'](
|
||||
el.substring(1 - offset, el.length - offset)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
_getInkPrinter(isBold)
|
||||
{
|
||||
if(!Ink)
|
||||
return this._getDefaultPrinter();
|
||||
|
||||
let printer = new Ink.Printer({
|
||||
color: Ink.colorFromText(this.name)
|
||||
});
|
||||
|
||||
if(isBold)
|
||||
printer.font = Ink.Font.BOLD;
|
||||
|
||||
return printer;
|
||||
}
|
||||
|
||||
_getDefaultPrinter()
|
||||
{
|
||||
return {
|
||||
getPainted: function() {
|
||||
return Object.values(arguments);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
_debug(message)
|
||||
{
|
||||
if(!this.enabled)
|
||||
return;
|
||||
|
||||
this._runDebug(message);
|
||||
}
|
||||
|
||||
_runDebug(message)
|
||||
{
|
||||
switch(typeof message) {
|
||||
case 'string':
|
||||
break;
|
||||
case 'object':
|
||||
if(
|
||||
message !== null
|
||||
&& (message.constructor === Object
|
||||
|| message.constructor === Array)
|
||||
) {
|
||||
message = JSON.stringify(message, null, this.json_space);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
message = String(message);
|
||||
break;
|
||||
}
|
||||
|
||||
let time = GLib.get_monotonic_time() - this._lastDebug;
|
||||
|
||||
if(!this.high_precision) {
|
||||
time = (time < 1000)
|
||||
? '+0ms'
|
||||
: (time < 1000000)
|
||||
? '+' + Math.floor(time / 1000) + 'ms'
|
||||
: '+' + Math.floor(time / 1000000) + 's';
|
||||
}
|
||||
else {
|
||||
time = (time < 1000)
|
||||
? '+' + time + 'µs'
|
||||
: (time < 1000000)
|
||||
? '+' + (time / 1000).toFixed(3) + 'ms'
|
||||
: '+' + (time / 1000000).toFixed(3) + 's';
|
||||
}
|
||||
|
||||
printerr(
|
||||
this.name_printer.getPainted(this.name),
|
||||
this.message_printer.getPainted(message),
|
||||
this.time_printer.getPainted(time)
|
||||
);
|
||||
|
||||
this._lastDebug = GLib.get_monotonic_time();
|
||||
}
|
||||
}
|
@@ -1,322 +0,0 @@
|
||||
const TERM_ESC = '\x1B[';
|
||||
const TERM_RESET = '0m';
|
||||
|
||||
var maxTransparency = 128;
|
||||
|
||||
var Font = {
|
||||
VARIOUS: null,
|
||||
REGULAR: 0,
|
||||
BOLD: 1,
|
||||
DIM: 2,
|
||||
ITALIC: 3,
|
||||
UNDERLINE: 4,
|
||||
BLINK: 5,
|
||||
REVERSE: 7,
|
||||
HIDDEN: 8,
|
||||
STRIKEOUT: 9,
|
||||
};
|
||||
|
||||
var Color = {
|
||||
VARIOUS: null,
|
||||
DEFAULT: 39,
|
||||
BLACK: 30,
|
||||
RED: 31,
|
||||
GREEN: 32,
|
||||
YELLOW: 33,
|
||||
BLUE: 34,
|
||||
MAGENTA: 35,
|
||||
CYAN: 36,
|
||||
LIGHT_GRAY: 37,
|
||||
DARK_GRAY: 90,
|
||||
LIGHT_RED: 91,
|
||||
LIGHT_GREEN: 92,
|
||||
LIGHT_YELLOW: 93,
|
||||
LIGHT_BLUE: 94,
|
||||
LIGHT_MAGENTA: 95,
|
||||
LIGHT_CYAN: 96,
|
||||
WHITE: 97,
|
||||
BROWN: colorFrom256(52),
|
||||
LIGHT_BROWN: colorFrom256(130),
|
||||
PINK: colorFrom256(205),
|
||||
LIGHT_PINK: colorFrom256(211),
|
||||
ORANGE: colorFrom256(208),
|
||||
LIGHT_ORANGE: colorFrom256(214),
|
||||
SALMON: colorFrom256(209),
|
||||
LIGHT_SALMON: colorFrom256(216),
|
||||
};
|
||||
|
||||
function colorFrom256(number)
|
||||
{
|
||||
if(typeof number === 'undefined')
|
||||
number = Math.floor(Math.random() * 256) + 1;
|
||||
|
||||
return `38;5;${number || 0}`;
|
||||
}
|
||||
|
||||
function colorFromRGB(R, G, B, A)
|
||||
{
|
||||
if(typeof R === 'undefined') {
|
||||
R = Math.floor(Math.random() * 256);
|
||||
G = Math.floor(Math.random() * 256);
|
||||
B = Math.floor(Math.random() * 256);
|
||||
}
|
||||
else if(typeof G === 'undefined' && Array.isArray(R)) {
|
||||
A = (R.length > 3) ? R[3] : 255;
|
||||
B = (R.length > 2) ? R[2] : 0;
|
||||
G = (R.length > 1) ? R[1] : 0;
|
||||
R = (R.length > 0) ? R[0] : 0;
|
||||
}
|
||||
|
||||
if(_getIsTransparent(A))
|
||||
return Color.DEFAULT;
|
||||
|
||||
R = R || 0;
|
||||
G = G || 0;
|
||||
B = B || 0;
|
||||
|
||||
return `38;2;${R};${G};${B}`;
|
||||
}
|
||||
|
||||
function colorFromHex(R, G, B, A)
|
||||
{
|
||||
if((Array.isArray(R)))
|
||||
R = R.join('');
|
||||
|
||||
let str = (typeof G === 'undefined')
|
||||
? String(R)
|
||||
: (typeof A !== 'undefined')
|
||||
? String(R) + String(G) + String(B) + String(A)
|
||||
: (typeof B !== 'undefined')
|
||||
? String(R) + String(G) + String(B)
|
||||
: String(R) + String(G);
|
||||
|
||||
let offset = (str[0] === '#') ? 1 : 0;
|
||||
let alphaIndex = 6 + offset;
|
||||
|
||||
while(str.length < alphaIndex)
|
||||
str += '0';
|
||||
|
||||
A = (str.length > alphaIndex)
|
||||
? parseInt(str.substring(alphaIndex, alphaIndex + 2), 16)
|
||||
: 255;
|
||||
str = str.substring(offset, alphaIndex);
|
||||
|
||||
let colorInt = parseInt(str, 16);
|
||||
let u8arr = new Uint8Array(3);
|
||||
|
||||
u8arr[2] = colorInt;
|
||||
u8arr[1] = colorInt >> 8;
|
||||
u8arr[0] = colorInt >> 16;
|
||||
|
||||
return colorFromRGB(u8arr[0], u8arr[1], u8arr[2], A);
|
||||
}
|
||||
|
||||
function colorFromText(text)
|
||||
{
|
||||
let value = _stringToDec(text);
|
||||
|
||||
/* Returns color from 1 to 221 every 10 */
|
||||
return colorFrom256((value % 23) * 10 + 1);
|
||||
}
|
||||
|
||||
function fontFromText(text)
|
||||
{
|
||||
let arr = Object.keys(Font);
|
||||
let value = _stringToDec(text);
|
||||
|
||||
/* Return a font excluding first (null) */
|
||||
return Font[arr[value % (arr.length - 1) + 1]];
|
||||
}
|
||||
|
||||
function _getIsImage(args)
|
||||
{
|
||||
if(args.length !== 1)
|
||||
return false;
|
||||
|
||||
let arg = args[0];
|
||||
let argType = (typeof arg);
|
||||
|
||||
if(argType === 'string' || argType === 'number')
|
||||
return false;
|
||||
|
||||
if(!Array.isArray(arg))
|
||||
return false;
|
||||
|
||||
let depth = 2;
|
||||
while(depth--) {
|
||||
arg = arg[0];
|
||||
if(!Array.isArray(arg))
|
||||
return false;
|
||||
}
|
||||
|
||||
return arg.some(val => val !== 'number');
|
||||
}
|
||||
|
||||
function _getIsTransparent(A)
|
||||
{
|
||||
return (typeof A !== 'undefined' && A <= maxTransparency);
|
||||
}
|
||||
|
||||
function _stringToDec(str)
|
||||
{
|
||||
str = str || '';
|
||||
|
||||
let len = str.length;
|
||||
let total = 0;
|
||||
|
||||
while(len--)
|
||||
total += Number(str.charCodeAt(len).toString(10));
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
var Printer = class
|
||||
{
|
||||
constructor(opts)
|
||||
{
|
||||
opts = opts || {};
|
||||
|
||||
const defaults = {
|
||||
font: Font.REGULAR,
|
||||
color: Color.DEFAULT,
|
||||
background: Color.DEFAULT
|
||||
};
|
||||
|
||||
for(let def in defaults) {
|
||||
this[def] = (typeof opts[def] !== 'undefined')
|
||||
? opts[def] : defaults[def];
|
||||
}
|
||||
}
|
||||
|
||||
print()
|
||||
{
|
||||
(_getIsImage(arguments))
|
||||
? this._printImage(arguments[0], 'stdout')
|
||||
: print(this._getPaintedArgs(arguments));
|
||||
}
|
||||
|
||||
printerr()
|
||||
{
|
||||
(_getIsImage(arguments))
|
||||
? this._printImage(arguments[0], 'stderr')
|
||||
: printerr(this._getPaintedArgs(arguments));
|
||||
}
|
||||
|
||||
getPainted()
|
||||
{
|
||||
return (_getIsImage(arguments))
|
||||
? this._printImage(arguments[0], 'return')
|
||||
: this._getPaintedArgs(arguments);
|
||||
}
|
||||
|
||||
get background()
|
||||
{
|
||||
return this._background;
|
||||
}
|
||||
|
||||
set background(value)
|
||||
{
|
||||
let valueType = (typeof value);
|
||||
|
||||
if(valueType === 'string') {
|
||||
value = (value[2] === ';')
|
||||
? '4' + value.substring(1)
|
||||
: Number(value);
|
||||
}
|
||||
this._background = (valueType === 'object')
|
||||
? null
|
||||
: (value < 40 || value >= 90 && value < 100)
|
||||
? value + 10
|
||||
: value;
|
||||
}
|
||||
|
||||
_getPaintedArgs(args)
|
||||
{
|
||||
let str = '';
|
||||
|
||||
for(let arg of args) {
|
||||
if(Array.isArray(arg))
|
||||
arg = arg.join(',');
|
||||
|
||||
let painted = this._getPaintedString(arg);
|
||||
str += (str.length) ? ' ' + painted : painted;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
_getPaintedString(text, noReset)
|
||||
{
|
||||
let str = TERM_ESC;
|
||||
|
||||
for(let option of ['font', 'color', '_background']) {
|
||||
let optionType = (typeof this[option]);
|
||||
str += (optionType === 'number' || optionType === 'string')
|
||||
? this[option]
|
||||
: (option === 'font' && Array.isArray(this[option]))
|
||||
? this[option].join(';')
|
||||
: (option === 'font')
|
||||
? fontFromText(text)
|
||||
: colorFromText(text);
|
||||
|
||||
str += (option !== '_background') ? ';' : 'm';
|
||||
}
|
||||
str += text;
|
||||
|
||||
return (noReset)
|
||||
? str
|
||||
: (str + TERM_ESC + TERM_RESET);
|
||||
}
|
||||
|
||||
_printImage(pixelsArr, output)
|
||||
{
|
||||
let total = '';
|
||||
let prevColor = this.color;
|
||||
let prevBackground = this._background;
|
||||
|
||||
for(let row of pixelsArr) {
|
||||
let paintedLine = '';
|
||||
let block = ' ';
|
||||
|
||||
for(let i = 0; i < row.length; i++) {
|
||||
let pixel = row[i];
|
||||
let nextPixel = (i < row.length - 1) ? row[i + 1] : null;
|
||||
|
||||
if(nextPixel && pixel.every((value, index) =>
|
||||
value === nextPixel[index]
|
||||
)) {
|
||||
block += ' ';
|
||||
continue;
|
||||
}
|
||||
/* Do not use predefined functions here (it would impact performance) */
|
||||
let isTransparent = (pixel.length >= 3) ? _getIsTransparent(pixel[3]) : false;
|
||||
this.color = (isTransparent)
|
||||
? Color.DEFAULT
|
||||
: `38;2;${pixel[0]};${pixel[1]};${pixel[2]}`;
|
||||
this._background = (isTransparent)
|
||||
? Color.DEFAULT
|
||||
: `48;2;${pixel[0]};${pixel[1]};${pixel[2]}`;
|
||||
paintedLine += `${TERM_ESC}0;${this.color};${this._background}m${block}`;
|
||||
block = ' ';
|
||||
}
|
||||
paintedLine += TERM_ESC + TERM_RESET;
|
||||
|
||||
switch(output) {
|
||||
case 'stderr':
|
||||
printerr(paintedLine);
|
||||
break;
|
||||
case 'return':
|
||||
total += paintedLine + '\n';
|
||||
break;
|
||||
default:
|
||||
print(paintedLine);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.color = prevColor;
|
||||
this._background = prevBackground;
|
||||
|
||||
return total;
|
||||
}
|
||||
}
|
@@ -1,42 +0,0 @@
|
||||
/* GStreamer
|
||||
* Copyright (C) 2018 GStreamer developers
|
||||
* Copyright (C) 2021 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_CLAPPER_PRELUDE_H__
|
||||
#define __GST_CLAPPER_PRELUDE_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#ifndef GST_CLAPPER_API
|
||||
# ifdef BUILDING_GST_CLAPPER
|
||||
# define GST_CLAPPER_API GST_API_EXPORT /* from config.h */
|
||||
# else
|
||||
# define GST_CLAPPER_API GST_API_IMPORT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef GST_DISABLE_DEPRECATED
|
||||
#define GST_CLAPPER_DEPRECATED GST_CLAPPER_API
|
||||
#define GST_CLAPPER_DEPRECATED_FOR(f) GST_CLAPPER_API
|
||||
#else
|
||||
#define GST_CLAPPER_DEPRECATED G_DEPRECATED GST_CLAPPER_API
|
||||
#define GST_CLAPPER_DEPRECATED_FOR(f) G_DEPRECATED_FOR(f) GST_CLAPPER_API
|
||||
#endif
|
||||
|
||||
#endif /* __GST_CLAPPER_PRELUDE_H__ */
|
@@ -1,34 +0,0 @@
|
||||
/* GStreamer
|
||||
*
|
||||
* Copyright (C) 2014 Sebastian Dröge <sebastian@centricular.com>
|
||||
* Copyright (C) 2021 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __CLAPPER_H__
|
||||
#define __CLAPPER_H__
|
||||
|
||||
#include <gst/clapper/clapper-prelude.h>
|
||||
#include <gst/clapper/gstclapper.h>
|
||||
#include <gst/clapper/gstclapper-media-info.h>
|
||||
#include <gst/clapper/gstclapper-g-main-context-signal-dispatcher.h>
|
||||
#include <gst/clapper/gstclapper-video-overlay-video-renderer.h>
|
||||
#include <gst/clapper/gstclapper-visualization.h>
|
||||
#include <gst/clapper/gstclapper-mpris.h>
|
||||
#include <gst/clapper/gstclapper-gtk4-plugin.h>
|
||||
|
||||
#endif /* __CLAPPER_H__ */
|
@@ -1,214 +0,0 @@
|
||||
/* GStreamer
|
||||
*
|
||||
* Copyright (C) 2014-2015 Sebastian Dröge <sebastian@centricular.com>
|
||||
* Copyright (C) 2021 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:gstclapper-gmaincontextsignaldispatcher
|
||||
* @title: GstClapperGMainContextSignalDispatcher
|
||||
* @short_description: Clapper GLib MainContext dispatcher
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gstclapper-g-main-context-signal-dispatcher.h"
|
||||
|
||||
struct _GstClapperGMainContextSignalDispatcher
|
||||
{
|
||||
GObject parent;
|
||||
GMainContext *application_context;
|
||||
};
|
||||
|
||||
struct _GstClapperGMainContextSignalDispatcherClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
static void
|
||||
gst_clapper_g_main_context_signal_dispatcher_interface_init
|
||||
(GstClapperSignalDispatcherInterface * iface);
|
||||
|
||||
enum
|
||||
{
|
||||
G_MAIN_CONTEXT_SIGNAL_DISPATCHER_PROP_0,
|
||||
G_MAIN_CONTEXT_SIGNAL_DISPATCHER_PROP_APPLICATION_CONTEXT,
|
||||
G_MAIN_CONTEXT_SIGNAL_DISPATCHER_PROP_LAST
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GstClapperGMainContextSignalDispatcher,
|
||||
gst_clapper_g_main_context_signal_dispatcher, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (GST_TYPE_CLAPPER_SIGNAL_DISPATCHER,
|
||||
gst_clapper_g_main_context_signal_dispatcher_interface_init));
|
||||
|
||||
static GParamSpec
|
||||
* g_main_context_signal_dispatcher_param_specs
|
||||
[G_MAIN_CONTEXT_SIGNAL_DISPATCHER_PROP_LAST] = { NULL, };
|
||||
|
||||
static void
|
||||
gst_clapper_g_main_context_signal_dispatcher_finalize (GObject * object)
|
||||
{
|
||||
GstClapperGMainContextSignalDispatcher *self =
|
||||
GST_CLAPPER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER (object);
|
||||
|
||||
if (self->application_context)
|
||||
g_main_context_unref (self->application_context);
|
||||
|
||||
G_OBJECT_CLASS
|
||||
(gst_clapper_g_main_context_signal_dispatcher_parent_class)->finalize
|
||||
(object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_g_main_context_signal_dispatcher_set_property (GObject * object,
|
||||
guint prop_id, const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstClapperGMainContextSignalDispatcher *self =
|
||||
GST_CLAPPER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case G_MAIN_CONTEXT_SIGNAL_DISPATCHER_PROP_APPLICATION_CONTEXT:
|
||||
self->application_context = g_value_dup_boxed (value);
|
||||
if (!self->application_context)
|
||||
self->application_context = g_main_context_ref_thread_default ();
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_g_main_context_signal_dispatcher_get_property (GObject * object,
|
||||
guint prop_id, GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstClapperGMainContextSignalDispatcher *self =
|
||||
GST_CLAPPER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case G_MAIN_CONTEXT_SIGNAL_DISPATCHER_PROP_APPLICATION_CONTEXT:
|
||||
g_value_set_boxed (value, self->application_context);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_g_main_context_signal_dispatcher_class_init
|
||||
(GstClapperGMainContextSignalDispatcherClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->finalize =
|
||||
gst_clapper_g_main_context_signal_dispatcher_finalize;
|
||||
gobject_class->set_property =
|
||||
gst_clapper_g_main_context_signal_dispatcher_set_property;
|
||||
gobject_class->get_property =
|
||||
gst_clapper_g_main_context_signal_dispatcher_get_property;
|
||||
|
||||
g_main_context_signal_dispatcher_param_specs
|
||||
[G_MAIN_CONTEXT_SIGNAL_DISPATCHER_PROP_APPLICATION_CONTEXT] =
|
||||
g_param_spec_boxed ("application-context", "Application Context",
|
||||
"Application GMainContext to dispatch signals to", G_TYPE_MAIN_CONTEXT,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (gobject_class,
|
||||
G_MAIN_CONTEXT_SIGNAL_DISPATCHER_PROP_LAST,
|
||||
g_main_context_signal_dispatcher_param_specs);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_g_main_context_signal_dispatcher_init
|
||||
(G_GNUC_UNUSED GstClapperGMainContextSignalDispatcher * self)
|
||||
{
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void (*emitter) (gpointer data);
|
||||
gpointer data;
|
||||
GDestroyNotify destroy;
|
||||
} GMainContextSignalDispatcherData;
|
||||
|
||||
static gboolean
|
||||
g_main_context_signal_dispatcher_dispatch_gsourcefunc (gpointer user_data)
|
||||
{
|
||||
GMainContextSignalDispatcherData *data = user_data;
|
||||
|
||||
data->emitter (data->data);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
g_main_context_signal_dispatcher_dispatch_destroy (gpointer user_data)
|
||||
{
|
||||
GMainContextSignalDispatcherData *data = user_data;
|
||||
|
||||
if (data->destroy)
|
||||
data->destroy (data->data);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_g_main_context_signal_dispatcher_dispatch (GstClapperSignalDispatcher
|
||||
* iface, G_GNUC_UNUSED GstClapper * clapper, void (*emitter) (gpointer data),
|
||||
gpointer data, GDestroyNotify destroy)
|
||||
{
|
||||
GstClapperGMainContextSignalDispatcher *self =
|
||||
GST_CLAPPER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER (iface);
|
||||
GMainContextSignalDispatcherData *gsourcefunc_data =
|
||||
g_new (GMainContextSignalDispatcherData, 1);
|
||||
|
||||
gsourcefunc_data->emitter = emitter;
|
||||
gsourcefunc_data->data = data;
|
||||
gsourcefunc_data->destroy = destroy;
|
||||
|
||||
g_main_context_invoke_full (self->application_context,
|
||||
G_PRIORITY_DEFAULT, g_main_context_signal_dispatcher_dispatch_gsourcefunc,
|
||||
gsourcefunc_data, g_main_context_signal_dispatcher_dispatch_destroy);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_g_main_context_signal_dispatcher_interface_init
|
||||
(GstClapperSignalDispatcherInterface * iface)
|
||||
{
|
||||
iface->dispatch = gst_clapper_g_main_context_signal_dispatcher_dispatch;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_g_main_context_signal_dispatcher_new:
|
||||
* @application_context: (allow-none): GMainContext to use or %NULL
|
||||
*
|
||||
* Creates a new GstClapperSignalDispatcher that uses @application_context,
|
||||
* or the thread default one if %NULL is used. See gst_clapper_new().
|
||||
*
|
||||
* Returns: (transfer full): the new GstClapperSignalDispatcher
|
||||
*/
|
||||
GstClapperSignalDispatcher *
|
||||
gst_clapper_g_main_context_signal_dispatcher_new (GMainContext *
|
||||
application_context)
|
||||
{
|
||||
return g_object_new (GST_TYPE_CLAPPER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER,
|
||||
"application-context", application_context, NULL);
|
||||
}
|
@@ -1,51 +0,0 @@
|
||||
/* GStreamer
|
||||
*
|
||||
* Copyright (C) 2014-2015 Sebastian Dröge <sebastian@centricular.com>
|
||||
* Copyright (C) 2021 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_CLAPPER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER_H__
|
||||
#define __GST_CLAPPER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER_H__
|
||||
|
||||
#include <gst/clapper/gstclapper-types.h>
|
||||
#include <gst/clapper/gstclapper-signal-dispatcher.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstClapperGMainContextSignalDispatcher
|
||||
GstClapperGMainContextSignalDispatcher;
|
||||
typedef struct _GstClapperGMainContextSignalDispatcherClass
|
||||
GstClapperGMainContextSignalDispatcherClass;
|
||||
|
||||
#define GST_TYPE_CLAPPER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER (gst_clapper_g_main_context_signal_dispatcher_get_type ())
|
||||
#define GST_IS_CLAPPER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_CLAPPER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER))
|
||||
#define GST_IS_CLAPPER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_CLAPPER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER))
|
||||
#define GST_CLAPPER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_CLAPPER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER, GstClapperGMainContextSignalDispatcherClass))
|
||||
#define GST_CLAPPER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_CLAPPER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER, GstClapperGMainContextSignalDispatcher))
|
||||
#define GST_CLAPPER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_CLAPPER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER, GstClapperGMainContextSignalDispatcherClass))
|
||||
#define GST_CLAPPER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER_CAST(obj) ((GstClapperGMainContextSignalDispatcher*)(obj))
|
||||
|
||||
GST_CLAPPER_API
|
||||
GType gst_clapper_g_main_context_signal_dispatcher_get_type (void);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GstClapperSignalDispatcher * gst_clapper_g_main_context_signal_dispatcher_new (GMainContext * application_context);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_CLAPPER_G_MAIN_CONTEXT_SIGNAL_DISPATCHER_H__ */
|
@@ -1,123 +0,0 @@
|
||||
/* GStreamer
|
||||
*
|
||||
* Copyright (C) 2021 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:gstclapper-gtk4plugin
|
||||
* @title: GstClapperGtk4Plugin
|
||||
* @short_description: Clapper GTK4 plugin
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gstclapper-gtk4-plugin.h"
|
||||
#include "gtk4/gstclapperglsink.h"
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_VIDEO_SINK,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
#define parent_class gst_clapper_gtk4_plugin_parent_class
|
||||
G_DEFINE_TYPE_WITH_CODE (GstClapperGtk4Plugin, gst_clapper_gtk4_plugin,
|
||||
G_TYPE_OBJECT, NULL);
|
||||
|
||||
static GParamSpec *param_specs[PROP_LAST] = { NULL, };
|
||||
|
||||
static void gst_clapper_gtk4_plugin_constructed (GObject * object);
|
||||
static void gst_clapper_gtk4_plugin_finalize (GObject * object);
|
||||
static void gst_clapper_gtk4_plugin_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static void gst_clapper_gtk4_plugin_init
|
||||
(G_GNUC_UNUSED GstClapperGtk4Plugin * self)
|
||||
{
|
||||
}
|
||||
|
||||
static void gst_clapper_gtk4_plugin_class_init
|
||||
(G_GNUC_UNUSED GstClapperGtk4PluginClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
|
||||
gobject_class->constructed = gst_clapper_gtk4_plugin_constructed;
|
||||
gobject_class->get_property = gst_clapper_gtk4_plugin_get_property;
|
||||
gobject_class->finalize = gst_clapper_gtk4_plugin_finalize;
|
||||
|
||||
param_specs[PROP_VIDEO_SINK] =
|
||||
g_param_spec_object ("video-sink",
|
||||
"Video Sink", "Video sink to use with video renderer",
|
||||
GST_TYPE_ELEMENT, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (gobject_class, PROP_LAST, param_specs);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gtk4_plugin_constructed (GObject * object)
|
||||
{
|
||||
GstClapperGtk4Plugin *self = GST_CLAPPER_GTK4_PLUGIN (object);
|
||||
|
||||
self->video_sink = g_object_new (GST_TYPE_CLAPPER_GL_SINK, NULL);
|
||||
gst_object_ref_sink (self->video_sink);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->constructed (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gtk4_plugin_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstClapperGtk4Plugin *self = GST_CLAPPER_GTK4_PLUGIN (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_VIDEO_SINK:
|
||||
g_value_set_object (value, self->video_sink);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gtk4_plugin_finalize (GObject * object)
|
||||
{
|
||||
GstClapperGtk4Plugin *self = GST_CLAPPER_GTK4_PLUGIN (object);
|
||||
|
||||
gst_object_unref (self->video_sink);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_gtk4_plugin_new:
|
||||
*
|
||||
* Creates a new GTK4 plugin.
|
||||
*
|
||||
* Returns: (transfer full): the new GstClapperGtk4Plugin
|
||||
*/
|
||||
GstClapperGtk4Plugin *
|
||||
gst_clapper_gtk4_plugin_new (void)
|
||||
{
|
||||
return g_object_new (GST_TYPE_CLAPPER_GTK4_PLUGIN, NULL);
|
||||
}
|
@@ -1,72 +0,0 @@
|
||||
/* GStreamer
|
||||
*
|
||||
* Copyright (C) 2021 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_CLAPPER_GTK4_PLUGIN_H__
|
||||
#define __GST_CLAPPER_GTK4_PLUGIN_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/clapper/clapper-prelude.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_CLAPPER_GTK4_PLUGIN (gst_clapper_gtk4_plugin_get_type ())
|
||||
#define GST_IS_CLAPPER_GTK4_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_CLAPPER_GTK4_PLUGIN))
|
||||
#define GST_IS_CLAPPER_GTK4_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_CLAPPER_GTK4_PLUGIN))
|
||||
#define GST_CLAPPER_GTK4_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_CLAPPER_GTK4_PLUGIN, GstClapperGtk4PluginClass))
|
||||
#define GST_CLAPPER_GTK4_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_CLAPPER_GTK4_PLUGIN, GstClapperGtk4Plugin))
|
||||
#define GST_CLAPPER_GTK4_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_CLAPPER_GTK4_PLUGIN, GstClapperGtk4PluginClass))
|
||||
#define GST_CLAPPER_GTK4_PLUGIN_CAST(obj) ((GstClapperGtk4Plugin*)(obj))
|
||||
|
||||
typedef struct _GstClapperGtk4Plugin GstClapperGtk4Plugin;
|
||||
typedef struct _GstClapperGtk4PluginClass GstClapperGtk4PluginClass;
|
||||
|
||||
/**
|
||||
* GstClapperGtk4Plugin:
|
||||
*
|
||||
* Opaque #GstClapperGtk4Plugin object
|
||||
*/
|
||||
struct _GstClapperGtk4Plugin
|
||||
{
|
||||
/* <private> */
|
||||
GObject parent;
|
||||
|
||||
GstElement *video_sink;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstClapperGtk4PluginClass:
|
||||
*
|
||||
* The #GstClapperGtk4PluginClass struct only contains private data
|
||||
*/
|
||||
struct _GstClapperGtk4PluginClass
|
||||
{
|
||||
/* <private> */
|
||||
GstElementClass parent_class;
|
||||
};
|
||||
|
||||
GST_CLAPPER_API
|
||||
GType gst_clapper_gtk4_plugin_get_type (void);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GstClapperGtk4Plugin * gst_clapper_gtk4_plugin_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_CLAPPER_GTK4_PLUGIN__ */
|
@@ -1,125 +0,0 @@
|
||||
/* GStreamer
|
||||
*
|
||||
* Copyright (C) 2015 Brijesh Singh <brijesh.ksingh@gmail.com>
|
||||
* Copyright (C) 2021 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "gstclapper-media-info.h"
|
||||
|
||||
#ifndef __GST_CLAPPER_MEDIA_INFO_PRIVATE_H__
|
||||
#define __GST_CLAPPER_MEDIA_INFO_PRIVATE_H__
|
||||
|
||||
struct _GstClapperStreamInfo
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
gchar *codec;
|
||||
|
||||
GstCaps *caps;
|
||||
gint stream_index;
|
||||
GstTagList *tags;
|
||||
gchar *stream_id;
|
||||
};
|
||||
|
||||
struct _GstClapperStreamInfoClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
struct _GstClapperSubtitleInfo
|
||||
{
|
||||
GstClapperStreamInfo parent;
|
||||
|
||||
gchar *title;
|
||||
gchar *language;
|
||||
};
|
||||
|
||||
struct _GstClapperSubtitleInfoClass
|
||||
{
|
||||
GstClapperStreamInfoClass parent_class;
|
||||
};
|
||||
|
||||
struct _GstClapperAudioInfo
|
||||
{
|
||||
GstClapperStreamInfo parent;
|
||||
|
||||
gint channels;
|
||||
gint sample_rate;
|
||||
|
||||
guint bitrate;
|
||||
guint max_bitrate;
|
||||
|
||||
gchar *language;
|
||||
};
|
||||
|
||||
struct _GstClapperAudioInfoClass
|
||||
{
|
||||
GstClapperStreamInfoClass parent_class;
|
||||
};
|
||||
|
||||
struct _GstClapperVideoInfo
|
||||
{
|
||||
GstClapperStreamInfo parent;
|
||||
|
||||
gint width;
|
||||
gint height;
|
||||
gint framerate_num;
|
||||
gint framerate_denom;
|
||||
gint par_num;
|
||||
gint par_denom;
|
||||
|
||||
guint bitrate;
|
||||
guint max_bitrate;
|
||||
};
|
||||
|
||||
struct _GstClapperVideoInfoClass
|
||||
{
|
||||
GstClapperStreamInfoClass parent_class;
|
||||
};
|
||||
|
||||
struct _GstClapperMediaInfo
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
gchar *uri;
|
||||
gchar *title;
|
||||
gchar *container;
|
||||
gboolean seekable, is_live;
|
||||
GstTagList *tags;
|
||||
GstToc *toc;
|
||||
GstSample *image_sample;
|
||||
|
||||
GList *stream_list;
|
||||
GList *audio_stream_list;
|
||||
GList *video_stream_list;
|
||||
GList *subtitle_stream_list;
|
||||
|
||||
GstClockTime duration;
|
||||
};
|
||||
|
||||
struct _GstClapperMediaInfoClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
G_GNUC_INTERNAL GstClapperMediaInfo * gst_clapper_media_info_new (const gchar *uri);
|
||||
G_GNUC_INTERNAL GstClapperMediaInfo * gst_clapper_media_info_copy (GstClapperMediaInfo *ref);
|
||||
G_GNUC_INTERNAL GstClapperStreamInfo * gst_clapper_stream_info_new (gint stream_index, GType type);
|
||||
G_GNUC_INTERNAL GstClapperStreamInfo * gst_clapper_stream_info_copy (GstClapperStreamInfo *ref);
|
||||
|
||||
#endif /* __GST_CLAPPER_MEDIA_INFO_PRIVATE_H__ */
|
@@ -1,885 +0,0 @@
|
||||
/* GStreamer
|
||||
*
|
||||
* Copyright (C) 2015 Brijesh Singh <brijesh.ksingh@gmail.com>
|
||||
* Copyright (C) 2021 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:gstclapper-mediainfo
|
||||
* @title: GstClapperMediaInfo
|
||||
* @short_description: Clapper Media Information
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gstclapper-media-info.h"
|
||||
#include "gstclapper-media-info-private.h"
|
||||
|
||||
/* Per-stream information */
|
||||
G_DEFINE_ABSTRACT_TYPE (GstClapperStreamInfo, gst_clapper_stream_info,
|
||||
G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
gst_clapper_stream_info_init (GstClapperStreamInfo * sinfo)
|
||||
{
|
||||
sinfo->stream_index = -1;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_stream_info_finalize (GObject * object)
|
||||
{
|
||||
GstClapperStreamInfo *sinfo = GST_CLAPPER_STREAM_INFO (object);
|
||||
|
||||
g_free (sinfo->codec);
|
||||
g_free (sinfo->stream_id);
|
||||
|
||||
if (sinfo->caps)
|
||||
gst_caps_unref (sinfo->caps);
|
||||
|
||||
if (sinfo->tags)
|
||||
gst_tag_list_unref (sinfo->tags);
|
||||
|
||||
G_OBJECT_CLASS (gst_clapper_stream_info_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_stream_info_class_init (GstClapperStreamInfoClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
|
||||
gobject_class->finalize = gst_clapper_stream_info_finalize;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_stream_info_get_index:
|
||||
* @info: a #GstClapperStreamInfo
|
||||
*
|
||||
* Function to get stream index from #GstClapperStreamInfo instance.
|
||||
*
|
||||
* Returns: the stream index of this stream.
|
||||
*/
|
||||
gint
|
||||
gst_clapper_stream_info_get_index (const GstClapperStreamInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_STREAM_INFO (info), -1);
|
||||
|
||||
return info->stream_index;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_stream_info_get_stream_type:
|
||||
* @info: a #GstClapperStreamInfo
|
||||
*
|
||||
* Function to return human readable name for the stream type
|
||||
* of the given @info (ex: "audio", "video", "subtitle")
|
||||
*
|
||||
* Returns: a human readable name
|
||||
*/
|
||||
const gchar *
|
||||
gst_clapper_stream_info_get_stream_type (const GstClapperStreamInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_STREAM_INFO (info), NULL);
|
||||
|
||||
if (GST_IS_CLAPPER_VIDEO_INFO (info))
|
||||
return "video";
|
||||
else if (GST_IS_CLAPPER_AUDIO_INFO (info))
|
||||
return "audio";
|
||||
else
|
||||
return "subtitle";
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_stream_info_get_tags:
|
||||
* @info: a #GstClapperStreamInfo
|
||||
*
|
||||
* Returns: (transfer none): the tags contained in this stream.
|
||||
*/
|
||||
GstTagList *
|
||||
gst_clapper_stream_info_get_tags (const GstClapperStreamInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_STREAM_INFO (info), NULL);
|
||||
|
||||
return info->tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_stream_info_get_codec:
|
||||
* @info: a #GstClapperStreamInfo
|
||||
*
|
||||
* A string describing codec used in #GstClapperStreamInfo.
|
||||
*
|
||||
* Returns: codec string or NULL on unknown.
|
||||
*/
|
||||
const gchar *
|
||||
gst_clapper_stream_info_get_codec (const GstClapperStreamInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_STREAM_INFO (info), NULL);
|
||||
|
||||
return info->codec;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_stream_info_get_caps:
|
||||
* @info: a #GstClapperStreamInfo
|
||||
*
|
||||
* Returns: (transfer none): the #GstCaps of the stream.
|
||||
*/
|
||||
GstCaps *
|
||||
gst_clapper_stream_info_get_caps (const GstClapperStreamInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_STREAM_INFO (info), NULL);
|
||||
|
||||
return info->caps;
|
||||
}
|
||||
|
||||
/* Video information */
|
||||
G_DEFINE_TYPE (GstClapperVideoInfo, gst_clapper_video_info,
|
||||
GST_TYPE_CLAPPER_STREAM_INFO);
|
||||
|
||||
static void
|
||||
gst_clapper_video_info_init (GstClapperVideoInfo * info)
|
||||
{
|
||||
info->width = -1;
|
||||
info->height = -1;
|
||||
info->framerate_num = 0;
|
||||
info->framerate_denom = 1;
|
||||
info->par_num = 1;
|
||||
info->par_denom = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_video_info_class_init (G_GNUC_UNUSED GstClapperVideoInfoClass * klass)
|
||||
{
|
||||
/* nothing to do here */
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_video_info_get_width:
|
||||
* @info: a #GstClapperVideoInfo
|
||||
*
|
||||
* Returns: the width of video in #GstClapperVideoInfo.
|
||||
*/
|
||||
gint
|
||||
gst_clapper_video_info_get_width (const GstClapperVideoInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_VIDEO_INFO (info), -1);
|
||||
|
||||
return info->width;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_video_info_get_height:
|
||||
* @info: a #GstClapperVideoInfo
|
||||
*
|
||||
* Returns: the height of video in #GstClapperVideoInfo.
|
||||
*/
|
||||
gint
|
||||
gst_clapper_video_info_get_height (const GstClapperVideoInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_VIDEO_INFO (info), -1);
|
||||
|
||||
return info->height;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_video_info_get_framerate:
|
||||
* @info: a #GstClapperVideoInfo
|
||||
* @fps_n: (out): Numerator of frame rate
|
||||
* @fps_d: (out): Denominator of frame rate
|
||||
*
|
||||
*/
|
||||
void
|
||||
gst_clapper_video_info_get_framerate (const GstClapperVideoInfo * info,
|
||||
gint * fps_n, gint * fps_d)
|
||||
{
|
||||
g_return_if_fail (GST_IS_CLAPPER_VIDEO_INFO (info));
|
||||
|
||||
*fps_n = info->framerate_num;
|
||||
*fps_d = info->framerate_denom;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_video_info_get_pixel_aspect_ratio:
|
||||
* @info: a #GstClapperVideoInfo
|
||||
* @par_n: (out): numerator
|
||||
* @par_d: (out): denominator
|
||||
*
|
||||
* Returns the pixel aspect ratio in @par_n and @par_d
|
||||
*
|
||||
*/
|
||||
void
|
||||
gst_clapper_video_info_get_pixel_aspect_ratio (const GstClapperVideoInfo * info,
|
||||
guint * par_n, guint * par_d)
|
||||
{
|
||||
g_return_if_fail (GST_IS_CLAPPER_VIDEO_INFO (info));
|
||||
|
||||
*par_n = info->par_num;
|
||||
*par_d = info->par_denom;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_video_info_get_bitrate:
|
||||
* @info: a #GstClapperVideoInfo
|
||||
*
|
||||
* Returns: the current bitrate of video in #GstClapperVideoInfo.
|
||||
*/
|
||||
gint
|
||||
gst_clapper_video_info_get_bitrate (const GstClapperVideoInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_VIDEO_INFO (info), -1);
|
||||
|
||||
return info->bitrate;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_video_info_get_max_bitrate:
|
||||
* @info: a #GstClapperVideoInfo
|
||||
*
|
||||
* Returns: the maximum bitrate of video in #GstClapperVideoInfo.
|
||||
*/
|
||||
gint
|
||||
gst_clapper_video_info_get_max_bitrate (const GstClapperVideoInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_VIDEO_INFO (info), -1);
|
||||
|
||||
return info->max_bitrate;
|
||||
}
|
||||
|
||||
/* Audio information */
|
||||
G_DEFINE_TYPE (GstClapperAudioInfo, gst_clapper_audio_info,
|
||||
GST_TYPE_CLAPPER_STREAM_INFO);
|
||||
|
||||
static void
|
||||
gst_clapper_audio_info_init (GstClapperAudioInfo * info)
|
||||
{
|
||||
info->channels = 0;
|
||||
info->sample_rate = 0;
|
||||
info->bitrate = -1;
|
||||
info->max_bitrate = -1;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_audio_info_finalize (GObject * object)
|
||||
{
|
||||
GstClapperAudioInfo *info = GST_CLAPPER_AUDIO_INFO (object);
|
||||
|
||||
g_free (info->language);
|
||||
|
||||
G_OBJECT_CLASS (gst_clapper_audio_info_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_audio_info_class_init (GstClapperAudioInfoClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
|
||||
gobject_class->finalize = gst_clapper_audio_info_finalize;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_audio_info_get_language:
|
||||
* @info: a #GstClapperAudioInfo
|
||||
*
|
||||
* Returns: the language of the stream, or NULL if unknown.
|
||||
*/
|
||||
const gchar *
|
||||
gst_clapper_audio_info_get_language (const GstClapperAudioInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_AUDIO_INFO (info), NULL);
|
||||
|
||||
return info->language;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_audio_info_get_channels:
|
||||
* @info: a #GstClapperAudioInfo
|
||||
*
|
||||
* Returns: the number of audio channels in #GstClapperAudioInfo.
|
||||
*/
|
||||
gint
|
||||
gst_clapper_audio_info_get_channels (const GstClapperAudioInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_AUDIO_INFO (info), 0);
|
||||
|
||||
return info->channels;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_audio_info_get_sample_rate:
|
||||
* @info: a #GstClapperAudioInfo
|
||||
*
|
||||
* Returns: the audio sample rate in #GstClapperAudioInfo.
|
||||
*/
|
||||
gint
|
||||
gst_clapper_audio_info_get_sample_rate (const GstClapperAudioInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_AUDIO_INFO (info), 0);
|
||||
|
||||
return info->sample_rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_audio_info_get_bitrate:
|
||||
* @info: a #GstClapperAudioInfo
|
||||
*
|
||||
* Returns: the audio bitrate in #GstClapperAudioInfo.
|
||||
*/
|
||||
gint
|
||||
gst_clapper_audio_info_get_bitrate (const GstClapperAudioInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_AUDIO_INFO (info), -1);
|
||||
|
||||
return info->bitrate;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_audio_info_get_max_bitrate:
|
||||
* @info: a #GstClapperAudioInfo
|
||||
*
|
||||
* Returns: the audio maximum bitrate in #GstClapperAudioInfo.
|
||||
*/
|
||||
gint
|
||||
gst_clapper_audio_info_get_max_bitrate (const GstClapperAudioInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_AUDIO_INFO (info), -1);
|
||||
|
||||
return info->max_bitrate;
|
||||
}
|
||||
|
||||
/* Subtitle information */
|
||||
G_DEFINE_TYPE (GstClapperSubtitleInfo, gst_clapper_subtitle_info,
|
||||
GST_TYPE_CLAPPER_STREAM_INFO);
|
||||
|
||||
static void
|
||||
gst_clapper_subtitle_info_init (G_GNUC_UNUSED GstClapperSubtitleInfo * info)
|
||||
{
|
||||
/* nothing to do */
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_subtitle_info_finalize (GObject * object)
|
||||
{
|
||||
GstClapperSubtitleInfo *info = GST_CLAPPER_SUBTITLE_INFO (object);
|
||||
|
||||
g_free (info->title);
|
||||
g_free (info->language);
|
||||
|
||||
G_OBJECT_CLASS (gst_clapper_subtitle_info_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_subtitle_info_class_init (GstClapperSubtitleInfoClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
|
||||
gobject_class->finalize = gst_clapper_subtitle_info_finalize;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_subtitle_info_get_title:
|
||||
* @info: a #GstClapperSubtitleInfo
|
||||
*
|
||||
* Returns: the title of the stream, or NULL if unknown.
|
||||
*/
|
||||
const gchar *
|
||||
gst_clapper_subtitle_info_get_title (const GstClapperSubtitleInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_SUBTITLE_INFO (info), NULL);
|
||||
|
||||
return info->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_subtitle_info_get_language:
|
||||
* @info: a #GstClapperSubtitleInfo
|
||||
*
|
||||
* Returns: the language of the stream, or NULL if unknown.
|
||||
*/
|
||||
const gchar *
|
||||
gst_clapper_subtitle_info_get_language (const GstClapperSubtitleInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_SUBTITLE_INFO (info), NULL);
|
||||
|
||||
return info->language;
|
||||
}
|
||||
|
||||
/* Global media information */
|
||||
G_DEFINE_TYPE (GstClapperMediaInfo, gst_clapper_media_info, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
gst_clapper_media_info_init (GstClapperMediaInfo * info)
|
||||
{
|
||||
info->duration = -1;
|
||||
info->is_live = FALSE;
|
||||
info->seekable = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_media_info_finalize (GObject * object)
|
||||
{
|
||||
GstClapperMediaInfo *info = GST_CLAPPER_MEDIA_INFO (object);
|
||||
|
||||
g_free (info->uri);
|
||||
g_free (info->title);
|
||||
g_free (info->container);
|
||||
|
||||
if (info->tags)
|
||||
gst_tag_list_unref (info->tags);
|
||||
if (info->toc)
|
||||
gst_toc_unref (info->toc);
|
||||
if (info->image_sample)
|
||||
gst_sample_unref (info->image_sample);
|
||||
if (info->audio_stream_list)
|
||||
g_list_free (info->audio_stream_list);
|
||||
if (info->video_stream_list)
|
||||
g_list_free (info->video_stream_list);
|
||||
if (info->subtitle_stream_list)
|
||||
g_list_free (info->subtitle_stream_list);
|
||||
if (info->stream_list)
|
||||
g_list_free_full (info->stream_list, g_object_unref);
|
||||
|
||||
G_OBJECT_CLASS (gst_clapper_media_info_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_media_info_class_init (GstClapperMediaInfoClass * klass)
|
||||
{
|
||||
GObjectClass *oclass = (GObjectClass *) klass;
|
||||
|
||||
oclass->finalize = gst_clapper_media_info_finalize;
|
||||
}
|
||||
|
||||
static GstClapperVideoInfo *
|
||||
gst_clapper_video_info_new (void)
|
||||
{
|
||||
return g_object_new (GST_TYPE_CLAPPER_VIDEO_INFO, NULL);
|
||||
}
|
||||
|
||||
static GstClapperAudioInfo *
|
||||
gst_clapper_audio_info_new (void)
|
||||
{
|
||||
return g_object_new (GST_TYPE_CLAPPER_AUDIO_INFO, NULL);
|
||||
}
|
||||
|
||||
static GstClapperSubtitleInfo *
|
||||
gst_clapper_subtitle_info_new (void)
|
||||
{
|
||||
return g_object_new (GST_TYPE_CLAPPER_SUBTITLE_INFO, NULL);
|
||||
}
|
||||
|
||||
static GstClapperStreamInfo *
|
||||
gst_clapper_video_info_copy (GstClapperVideoInfo * ref)
|
||||
{
|
||||
GstClapperVideoInfo *ret;
|
||||
|
||||
ret = gst_clapper_video_info_new ();
|
||||
|
||||
ret->width = ref->width;
|
||||
ret->height = ref->height;
|
||||
ret->framerate_num = ref->framerate_num;
|
||||
ret->framerate_denom = ref->framerate_denom;
|
||||
ret->par_num = ref->par_num;
|
||||
ret->par_denom = ref->par_denom;
|
||||
ret->bitrate = ref->bitrate;
|
||||
ret->max_bitrate = ref->max_bitrate;
|
||||
|
||||
return (GstClapperStreamInfo *) ret;
|
||||
}
|
||||
|
||||
static GstClapperStreamInfo *
|
||||
gst_clapper_audio_info_copy (GstClapperAudioInfo * ref)
|
||||
{
|
||||
GstClapperAudioInfo *ret;
|
||||
|
||||
ret = gst_clapper_audio_info_new ();
|
||||
|
||||
ret->sample_rate = ref->sample_rate;
|
||||
ret->channels = ref->channels;
|
||||
ret->bitrate = ref->bitrate;
|
||||
ret->max_bitrate = ref->max_bitrate;
|
||||
|
||||
if (ref->language)
|
||||
ret->language = g_strdup (ref->language);
|
||||
|
||||
return (GstClapperStreamInfo *) ret;
|
||||
}
|
||||
|
||||
static GstClapperStreamInfo *
|
||||
gst_clapper_subtitle_info_copy (GstClapperSubtitleInfo * ref)
|
||||
{
|
||||
GstClapperSubtitleInfo *ret;
|
||||
|
||||
ret = gst_clapper_subtitle_info_new ();
|
||||
if (ref->title)
|
||||
ret->title = g_strdup (ref->title);
|
||||
if (ref->language)
|
||||
ret->language = g_strdup (ref->language);
|
||||
|
||||
return (GstClapperStreamInfo *) ret;
|
||||
}
|
||||
|
||||
GstClapperStreamInfo *
|
||||
gst_clapper_stream_info_copy (GstClapperStreamInfo * ref)
|
||||
{
|
||||
GstClapperStreamInfo *info = NULL;
|
||||
|
||||
if (!ref)
|
||||
return NULL;
|
||||
|
||||
if (GST_IS_CLAPPER_VIDEO_INFO (ref))
|
||||
info = gst_clapper_video_info_copy ((GstClapperVideoInfo *) ref);
|
||||
else if (GST_IS_CLAPPER_AUDIO_INFO (ref))
|
||||
info = gst_clapper_audio_info_copy ((GstClapperAudioInfo *) ref);
|
||||
else
|
||||
info = gst_clapper_subtitle_info_copy ((GstClapperSubtitleInfo *) ref);
|
||||
|
||||
info->stream_index = ref->stream_index;
|
||||
if (ref->tags)
|
||||
info->tags = gst_tag_list_ref (ref->tags);
|
||||
if (ref->caps)
|
||||
info->caps = gst_caps_copy (ref->caps);
|
||||
if (ref->codec)
|
||||
info->codec = g_strdup (ref->codec);
|
||||
if (ref->stream_id)
|
||||
info->stream_id = g_strdup (ref->stream_id);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
GstClapperMediaInfo *
|
||||
gst_clapper_media_info_copy (GstClapperMediaInfo * ref)
|
||||
{
|
||||
GList *l;
|
||||
GstClapperMediaInfo *info;
|
||||
|
||||
if (!ref)
|
||||
return NULL;
|
||||
|
||||
info = gst_clapper_media_info_new (ref->uri);
|
||||
info->duration = ref->duration;
|
||||
info->seekable = ref->seekable;
|
||||
info->is_live = ref->is_live;
|
||||
if (ref->tags)
|
||||
info->tags = gst_tag_list_ref (ref->tags);
|
||||
if (ref->toc)
|
||||
info->toc = gst_toc_ref (ref->toc);
|
||||
if (ref->title)
|
||||
info->title = g_strdup (ref->title);
|
||||
if (ref->container)
|
||||
info->container = g_strdup (ref->container);
|
||||
if (ref->image_sample)
|
||||
info->image_sample = gst_sample_ref (ref->image_sample);
|
||||
|
||||
for (l = ref->stream_list; l != NULL; l = l->next) {
|
||||
GstClapperStreamInfo *s;
|
||||
|
||||
s = gst_clapper_stream_info_copy ((GstClapperStreamInfo *) l->data);
|
||||
info->stream_list = g_list_append (info->stream_list, s);
|
||||
|
||||
if (GST_IS_CLAPPER_AUDIO_INFO (s))
|
||||
info->audio_stream_list = g_list_append (info->audio_stream_list, s);
|
||||
else if (GST_IS_CLAPPER_VIDEO_INFO (s))
|
||||
info->video_stream_list = g_list_append (info->video_stream_list, s);
|
||||
else
|
||||
info->subtitle_stream_list =
|
||||
g_list_append (info->subtitle_stream_list, s);
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
GstClapperStreamInfo *
|
||||
gst_clapper_stream_info_new (gint stream_index, GType type)
|
||||
{
|
||||
GstClapperStreamInfo *info = NULL;
|
||||
|
||||
if (type == GST_TYPE_CLAPPER_AUDIO_INFO)
|
||||
info = (GstClapperStreamInfo *) gst_clapper_audio_info_new ();
|
||||
else if (type == GST_TYPE_CLAPPER_VIDEO_INFO)
|
||||
info = (GstClapperStreamInfo *) gst_clapper_video_info_new ();
|
||||
else
|
||||
info = (GstClapperStreamInfo *) gst_clapper_subtitle_info_new ();
|
||||
|
||||
info->stream_index = stream_index;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
GstClapperMediaInfo *
|
||||
gst_clapper_media_info_new (const gchar * uri)
|
||||
{
|
||||
GstClapperMediaInfo *info;
|
||||
|
||||
g_return_val_if_fail (uri != NULL, NULL);
|
||||
|
||||
info = g_object_new (GST_TYPE_CLAPPER_MEDIA_INFO, NULL);
|
||||
info->uri = g_strdup (uri);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_media_info_get_uri:
|
||||
* @info: a #GstClapperMediaInfo
|
||||
*
|
||||
* Returns: the URI associated with #GstClapperMediaInfo.
|
||||
*/
|
||||
const gchar *
|
||||
gst_clapper_media_info_get_uri (const GstClapperMediaInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_MEDIA_INFO (info), NULL);
|
||||
|
||||
return info->uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_media_info_is_seekable:
|
||||
* @info: a #GstClapperMediaInfo
|
||||
*
|
||||
* Returns: %TRUE if the media is seekable.
|
||||
*/
|
||||
gboolean
|
||||
gst_clapper_media_info_is_seekable (const GstClapperMediaInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_MEDIA_INFO (info), FALSE);
|
||||
|
||||
return info->seekable;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_media_info_is_live:
|
||||
* @info: a #GstClapperMediaInfo
|
||||
*
|
||||
* Returns: %TRUE if the media is live.
|
||||
*/
|
||||
gboolean
|
||||
gst_clapper_media_info_is_live (const GstClapperMediaInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_MEDIA_INFO (info), FALSE);
|
||||
|
||||
return info->is_live;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_media_info_get_stream_list:
|
||||
* @info: a #GstClapperMediaInfo
|
||||
*
|
||||
* Returns: (transfer none) (element-type GstClapperStreamInfo): A #GList of
|
||||
* matching #GstClapperStreamInfo.
|
||||
*/
|
||||
GList *
|
||||
gst_clapper_media_info_get_stream_list (const GstClapperMediaInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_MEDIA_INFO (info), NULL);
|
||||
|
||||
return info->stream_list;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_media_info_get_video_streams:
|
||||
* @info: a #GstClapperMediaInfo
|
||||
*
|
||||
* Returns: (transfer none) (element-type GstClapperVideoInfo): A #GList of
|
||||
* matching #GstClapperVideoInfo.
|
||||
*/
|
||||
GList *
|
||||
gst_clapper_media_info_get_video_streams (const GstClapperMediaInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_MEDIA_INFO (info), NULL);
|
||||
|
||||
return info->video_stream_list;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_media_info_get_subtitle_streams:
|
||||
* @info: a #GstClapperMediaInfo
|
||||
*
|
||||
* Returns: (transfer none) (element-type GstClapperSubtitleInfo): A #GList of
|
||||
* matching #GstClapperSubtitleInfo.
|
||||
*/
|
||||
GList *
|
||||
gst_clapper_media_info_get_subtitle_streams (const GstClapperMediaInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_MEDIA_INFO (info), NULL);
|
||||
|
||||
return info->subtitle_stream_list;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_media_info_get_audio_streams:
|
||||
* @info: a #GstClapperMediaInfo
|
||||
*
|
||||
* Returns: (transfer none) (element-type GstClapperAudioInfo): A #GList of
|
||||
* matching #GstClapperAudioInfo.
|
||||
*/
|
||||
GList *
|
||||
gst_clapper_media_info_get_audio_streams (const GstClapperMediaInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_MEDIA_INFO (info), NULL);
|
||||
|
||||
return info->audio_stream_list;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_media_info_get_duration:
|
||||
* @info: a #GstClapperMediaInfo
|
||||
*
|
||||
* Returns: duration of the media.
|
||||
*/
|
||||
GstClockTime
|
||||
gst_clapper_media_info_get_duration (const GstClapperMediaInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_MEDIA_INFO (info), -1);
|
||||
|
||||
return info->duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_media_info_get_tags:
|
||||
* @info: a #GstClapperMediaInfo
|
||||
*
|
||||
* Returns: (transfer none): the tags contained in media info.
|
||||
*/
|
||||
GstTagList *
|
||||
gst_clapper_media_info_get_tags (const GstClapperMediaInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_MEDIA_INFO (info), NULL);
|
||||
|
||||
return info->tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_media_info_get_toc:
|
||||
* @info: a #GstClapperMediaInfo
|
||||
*
|
||||
* Returns: (transfer none): the toc contained in media info.
|
||||
*/
|
||||
GstToc *
|
||||
gst_clapper_media_info_get_toc (const GstClapperMediaInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_MEDIA_INFO (info), NULL);
|
||||
|
||||
return info->toc;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_media_info_get_title:
|
||||
* @info: a #GstClapperMediaInfo
|
||||
*
|
||||
* Returns: the media title. When metadata does not contain title,
|
||||
* returns title parsed from URI.
|
||||
*/
|
||||
const gchar *
|
||||
gst_clapper_media_info_get_title (const GstClapperMediaInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_MEDIA_INFO (info), NULL);
|
||||
|
||||
return info->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_media_info_get_container_format:
|
||||
* @info: a #GstClapperMediaInfo
|
||||
*
|
||||
* Returns: the container format.
|
||||
*/
|
||||
const gchar *
|
||||
gst_clapper_media_info_get_container_format (const GstClapperMediaInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_MEDIA_INFO (info), NULL);
|
||||
|
||||
return info->container;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_media_info_get_image_sample:
|
||||
* @info: a #GstClapperMediaInfo
|
||||
*
|
||||
* Function to get the image (or preview-image) stored in taglist.
|
||||
* Application can use `gst_sample_*_()` API's to get caps, buffer etc.
|
||||
*
|
||||
* Returns: (transfer none): GstSample or NULL.
|
||||
*/
|
||||
GstSample *
|
||||
gst_clapper_media_info_get_image_sample (const GstClapperMediaInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_MEDIA_INFO (info), NULL);
|
||||
|
||||
return info->image_sample;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_media_info_get_number_of_streams:
|
||||
* @info: a #GstClapperMediaInfo
|
||||
*
|
||||
* Returns: number of total streams.
|
||||
*/
|
||||
guint
|
||||
gst_clapper_media_info_get_number_of_streams (const GstClapperMediaInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_MEDIA_INFO (info), 0);
|
||||
|
||||
return g_list_length (info->stream_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_media_info_get_number_of_video_streams:
|
||||
* @info: a #GstClapperMediaInfo
|
||||
*
|
||||
* Returns: number of video streams.
|
||||
*/
|
||||
guint
|
||||
gst_clapper_media_info_get_number_of_video_streams (const GstClapperMediaInfo *
|
||||
info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_MEDIA_INFO (info), 0);
|
||||
|
||||
return g_list_length (info->video_stream_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_media_info_get_number_of_audio_streams:
|
||||
* @info: a #GstClapperMediaInfo
|
||||
*
|
||||
* Returns: number of audio streams.
|
||||
*/
|
||||
guint
|
||||
gst_clapper_media_info_get_number_of_audio_streams (const GstClapperMediaInfo *
|
||||
info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_MEDIA_INFO (info), 0);
|
||||
|
||||
return g_list_length (info->audio_stream_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_media_info_get_number_of_subtitle_streams:
|
||||
* @info: a #GstClapperMediaInfo
|
||||
*
|
||||
* Returns: number of subtitle streams.
|
||||
*/
|
||||
guint gst_clapper_media_info_get_number_of_subtitle_streams
|
||||
(const GstClapperMediaInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_MEDIA_INFO (info), 0);
|
||||
|
||||
return g_list_length (info->subtitle_stream_list);
|
||||
}
|
@@ -1,253 +0,0 @@
|
||||
/* GStreamer
|
||||
*
|
||||
* Copyright (C) 2015 Brijesh Singh <brijesh.ksingh@gmail.com>
|
||||
* Copyright (C) 2021 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_CLAPPER_MEDIA_INFO_H__
|
||||
#define __GST_CLAPPER_MEDIA_INFO_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/clapper/clapper-prelude.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_CLAPPER_STREAM_INFO \
|
||||
(gst_clapper_stream_info_get_type ())
|
||||
#define GST_CLAPPER_STREAM_INFO(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CLAPPER_STREAM_INFO,GstClapperStreamInfo))
|
||||
#define GST_CLAPPER_STREAM_INFO_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_CLAPPER_STREAM_INFO,GstClapperStreamInfo))
|
||||
#define GST_IS_CLAPPER_STREAM_INFO(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_CLAPPER_STREAM_INFO))
|
||||
#define GST_IS_CLAPPER_STREAM_INFO_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CLAPPER_STREAM_INFO))
|
||||
|
||||
/**
|
||||
* GstClapperStreamInfo:
|
||||
*
|
||||
* Base structure for information concerning a media stream. Depending on
|
||||
* the stream type, one can find more media-specific information in
|
||||
* #GstClapperVideoInfo, #GstClapperAudioInfo, #GstClapperSubtitleInfo.
|
||||
*/
|
||||
typedef struct _GstClapperStreamInfo GstClapperStreamInfo;
|
||||
typedef struct _GstClapperStreamInfoClass GstClapperStreamInfoClass;
|
||||
|
||||
GST_CLAPPER_API
|
||||
GType gst_clapper_stream_info_get_type (void);
|
||||
|
||||
GST_CLAPPER_API
|
||||
gint gst_clapper_stream_info_get_index (const GstClapperStreamInfo *info);
|
||||
|
||||
GST_CLAPPER_API
|
||||
const gchar* gst_clapper_stream_info_get_stream_type (const GstClapperStreamInfo *info);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GstTagList* gst_clapper_stream_info_get_tags (const GstClapperStreamInfo *info);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GstCaps* gst_clapper_stream_info_get_caps (const GstClapperStreamInfo *info);
|
||||
|
||||
GST_CLAPPER_API
|
||||
const gchar* gst_clapper_stream_info_get_codec (const GstClapperStreamInfo *info);
|
||||
|
||||
#define GST_TYPE_CLAPPER_VIDEO_INFO \
|
||||
(gst_clapper_video_info_get_type ())
|
||||
#define GST_CLAPPER_VIDEO_INFO(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CLAPPER_VIDEO_INFO, GstClapperVideoInfo))
|
||||
#define GST_CLAPPER_VIDEO_INFO_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((obj),GST_TYPE_CLAPPER_VIDEO_INFO, GstClapperVideoInfoClass))
|
||||
#define GST_IS_CLAPPER_VIDEO_INFO(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_CLAPPER_VIDEO_INFO))
|
||||
#define GST_IS_CLAPPER_VIDEO_INFO_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((obj),GST_TYPE_CLAPPER_VIDEO_INFO))
|
||||
|
||||
/**
|
||||
* GstClapperVideoInfo:
|
||||
*
|
||||
* #GstClapperStreamInfo specific to video streams.
|
||||
*/
|
||||
typedef struct _GstClapperVideoInfo GstClapperVideoInfo;
|
||||
typedef struct _GstClapperVideoInfoClass GstClapperVideoInfoClass;
|
||||
|
||||
GST_CLAPPER_API
|
||||
GType gst_clapper_video_info_get_type (void);
|
||||
|
||||
GST_CLAPPER_API
|
||||
gint gst_clapper_video_info_get_bitrate (const GstClapperVideoInfo * info);
|
||||
|
||||
GST_CLAPPER_API
|
||||
gint gst_clapper_video_info_get_max_bitrate (const GstClapperVideoInfo * info);
|
||||
|
||||
GST_CLAPPER_API
|
||||
gint gst_clapper_video_info_get_width (const GstClapperVideoInfo * info);
|
||||
|
||||
GST_CLAPPER_API
|
||||
gint gst_clapper_video_info_get_height (const GstClapperVideoInfo * info);
|
||||
|
||||
GST_CLAPPER_API
|
||||
void gst_clapper_video_info_get_framerate (const GstClapperVideoInfo * info,
|
||||
gint * fps_n,
|
||||
gint * fps_d);
|
||||
|
||||
GST_CLAPPER_API
|
||||
void gst_clapper_video_info_get_pixel_aspect_ratio (const GstClapperVideoInfo * info,
|
||||
guint * par_n,
|
||||
guint * par_d);
|
||||
|
||||
#define GST_TYPE_CLAPPER_AUDIO_INFO \
|
||||
(gst_clapper_audio_info_get_type ())
|
||||
#define GST_CLAPPER_AUDIO_INFO(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CLAPPER_AUDIO_INFO, GstClapperAudioInfo))
|
||||
#define GST_CLAPPER_AUDIO_INFO_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_CLAPPER_AUDIO_INFO, GstClapperAudioInfoClass))
|
||||
#define GST_IS_CLAPPER_AUDIO_INFO(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_CLAPPER_AUDIO_INFO))
|
||||
#define GST_IS_CLAPPER_AUDIO_INFO_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CLAPPER_AUDIO_INFO))
|
||||
|
||||
/**
|
||||
* GstClapperAudioInfo:
|
||||
*
|
||||
* #GstClapperStreamInfo specific to audio streams.
|
||||
*/
|
||||
typedef struct _GstClapperAudioInfo GstClapperAudioInfo;
|
||||
typedef struct _GstClapperAudioInfoClass GstClapperAudioInfoClass;
|
||||
|
||||
GST_CLAPPER_API
|
||||
GType gst_clapper_audio_info_get_type (void);
|
||||
|
||||
GST_CLAPPER_API
|
||||
gint gst_clapper_audio_info_get_channels (const GstClapperAudioInfo* info);
|
||||
|
||||
GST_CLAPPER_API
|
||||
gint gst_clapper_audio_info_get_sample_rate (const GstClapperAudioInfo* info);
|
||||
|
||||
GST_CLAPPER_API
|
||||
gint gst_clapper_audio_info_get_bitrate (const GstClapperAudioInfo* info);
|
||||
|
||||
GST_CLAPPER_API
|
||||
gint gst_clapper_audio_info_get_max_bitrate (const GstClapperAudioInfo* info);
|
||||
|
||||
GST_CLAPPER_API
|
||||
const gchar* gst_clapper_audio_info_get_language (const GstClapperAudioInfo* info);
|
||||
|
||||
#define GST_TYPE_CLAPPER_SUBTITLE_INFO \
|
||||
(gst_clapper_subtitle_info_get_type ())
|
||||
#define GST_CLAPPER_SUBTITLE_INFO(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CLAPPER_SUBTITLE_INFO, GstClapperSubtitleInfo))
|
||||
#define GST_CLAPPER_SUBTITLE_INFO_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_CLAPPER_SUBTITLE_INFO,GstClapperSubtitleInfoClass))
|
||||
#define GST_IS_CLAPPER_SUBTITLE_INFO(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_CLAPPER_SUBTITLE_INFO))
|
||||
#define GST_IS_CLAPPER_SUBTITLE_INFO_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CLAPPER_SUBTITLE_INFO))
|
||||
|
||||
/**
|
||||
* GstClapperSubtitleInfo:
|
||||
*
|
||||
* #GstClapperStreamInfo specific to subtitle streams.
|
||||
*/
|
||||
typedef struct _GstClapperSubtitleInfo GstClapperSubtitleInfo;
|
||||
typedef struct _GstClapperSubtitleInfoClass GstClapperSubtitleInfoClass;
|
||||
|
||||
GST_CLAPPER_API
|
||||
GType gst_clapper_subtitle_info_get_type (void);
|
||||
|
||||
GST_CLAPPER_API
|
||||
const gchar * gst_clapper_subtitle_info_get_title (const GstClapperSubtitleInfo *info);
|
||||
|
||||
GST_CLAPPER_API
|
||||
const gchar * gst_clapper_subtitle_info_get_language (const GstClapperSubtitleInfo *info);
|
||||
|
||||
#define GST_TYPE_CLAPPER_MEDIA_INFO \
|
||||
(gst_clapper_media_info_get_type())
|
||||
#define GST_CLAPPER_MEDIA_INFO(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CLAPPER_MEDIA_INFO,GstClapperMediaInfo))
|
||||
#define GST_CLAPPER_MEDIA_INFO_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_CLAPPER_MEDIA_INFO,GstClapperMediaInfoClass))
|
||||
#define GST_IS_CLAPPER_MEDIA_INFO(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_CLAPPER_MEDIA_INFO))
|
||||
#define GST_IS_CLAPPER_MEDIA_INFO_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CLAPPER_MEDIA_INFO))
|
||||
|
||||
/**
|
||||
* GstClapperMediaInfo:
|
||||
*
|
||||
* Structure containing the media information of a URI.
|
||||
*/
|
||||
typedef struct _GstClapperMediaInfo GstClapperMediaInfo;
|
||||
typedef struct _GstClapperMediaInfoClass GstClapperMediaInfoClass;
|
||||
|
||||
GST_CLAPPER_API
|
||||
GType gst_clapper_media_info_get_type (void);
|
||||
|
||||
GST_CLAPPER_API
|
||||
const gchar * gst_clapper_media_info_get_uri (const GstClapperMediaInfo *info);
|
||||
|
||||
GST_CLAPPER_API
|
||||
gboolean gst_clapper_media_info_is_seekable (const GstClapperMediaInfo *info);
|
||||
|
||||
GST_CLAPPER_API
|
||||
gboolean gst_clapper_media_info_is_live (const GstClapperMediaInfo *info);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GstClockTime gst_clapper_media_info_get_duration (const GstClapperMediaInfo *info);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GList * gst_clapper_media_info_get_stream_list (const GstClapperMediaInfo *info);
|
||||
|
||||
GST_CLAPPER_API
|
||||
guint gst_clapper_media_info_get_number_of_streams (const GstClapperMediaInfo *info);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GList * gst_clapper_media_info_get_video_streams (const GstClapperMediaInfo *info);
|
||||
|
||||
GST_CLAPPER_API
|
||||
guint gst_clapper_media_info_get_number_of_video_streams (const GstClapperMediaInfo *info);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GList * gst_clapper_media_info_get_audio_streams (const GstClapperMediaInfo *info);
|
||||
|
||||
GST_CLAPPER_API
|
||||
guint gst_clapper_media_info_get_number_of_audio_streams (const GstClapperMediaInfo *info);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GList * gst_clapper_media_info_get_subtitle_streams (const GstClapperMediaInfo *info);
|
||||
|
||||
GST_CLAPPER_API
|
||||
guint gst_clapper_media_info_get_number_of_subtitle_streams (const GstClapperMediaInfo *info);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GstTagList * gst_clapper_media_info_get_tags (const GstClapperMediaInfo *info);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GstToc * gst_clapper_media_info_get_toc (const GstClapperMediaInfo *info);
|
||||
|
||||
GST_CLAPPER_API
|
||||
const gchar * gst_clapper_media_info_get_title (const GstClapperMediaInfo *info);
|
||||
|
||||
GST_CLAPPER_API
|
||||
const gchar * gst_clapper_media_info_get_container_format (const GstClapperMediaInfo *info);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GstSample * gst_clapper_media_info_get_image_sample (const GstClapperMediaInfo *info);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_CLAPPER_MEDIA_INFO_H */
|
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_CLAPPER_MPRIS_PRIVATE_H__
|
||||
#define __GST_CLAPPER_MPRIS_PRIVATE_H__
|
||||
|
||||
#include <gst/clapper/gstclapper-mpris.h>
|
||||
#include <gst/clapper/gstclapper.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void gst_clapper_mpris_set_clapper (GstClapperMpris *self, GstClapper *clapper,
|
||||
GstClapperSignalDispatcher *signal_dispatcher);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void gst_clapper_mpris_set_media_info (GstClapperMpris *self, GstClapperMediaInfo *info);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void gst_clapper_mpris_set_playback_status (GstClapperMpris *self, const gchar *status);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void gst_clapper_mpris_set_position (GstClapperMpris *self, gint64 position);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_CLAPPER_MPRIS_PRIVATE_H__ */
|
@@ -1,782 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gstclapper-mpris-gdbus.h"
|
||||
#include "gstclapper-mpris.h"
|
||||
#include "gstclapper-mpris-private.h"
|
||||
#include "gstclapper-signal-dispatcher-private.h"
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (gst_clapper_mpris_debug);
|
||||
#define GST_CAT_DEFAULT gst_clapper_mpris_debug
|
||||
|
||||
#define MPRIS_DEFAULT_VOLUME 1.0
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_OWN_NAME,
|
||||
PROP_ID_PATH,
|
||||
PROP_IDENTITY,
|
||||
PROP_DESKTOP_ENTRY,
|
||||
PROP_DEFAULT_ART_URL,
|
||||
PROP_VOLUME,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
struct _GstClapperMpris
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
GstClapperMprisMediaPlayer2 *base_skeleton;
|
||||
GstClapperMprisMediaPlayer2Player *player_skeleton;
|
||||
|
||||
GstClapperSignalDispatcher *signal_dispatcher;
|
||||
GstClapperMediaInfo *media_info;
|
||||
|
||||
guint name_id;
|
||||
|
||||
/* Properties */
|
||||
gchar *own_name;
|
||||
gchar *id_path;
|
||||
gchar *identity;
|
||||
gchar *desktop_entry;
|
||||
gchar *default_art_url;
|
||||
|
||||
gboolean parse_media_info;
|
||||
|
||||
/* Current status */
|
||||
gchar *playback_status;
|
||||
gboolean can_play;
|
||||
guint64 position;
|
||||
|
||||
GThread *thread;
|
||||
GMutex lock;
|
||||
GCond cond;
|
||||
GMainContext *context;
|
||||
GMainLoop *loop;
|
||||
};
|
||||
|
||||
struct _GstClapperMprisClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
#define parent_class gst_clapper_mpris_parent_class
|
||||
G_DEFINE_TYPE (GstClapperMpris, gst_clapper_mpris, G_TYPE_OBJECT);
|
||||
|
||||
static GParamSpec *param_specs[PROP_LAST] = { NULL, };
|
||||
|
||||
static void gst_clapper_mpris_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_clapper_mpris_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
static void gst_clapper_mpris_dispose (GObject * object);
|
||||
static void gst_clapper_mpris_finalize (GObject * object);
|
||||
static void gst_clapper_mpris_constructed (GObject * object);
|
||||
static gpointer gst_clapper_mpris_main (gpointer data);
|
||||
|
||||
static void unregister (GstClapperMpris * self);
|
||||
|
||||
static void
|
||||
gst_clapper_mpris_init (GstClapperMpris * self)
|
||||
{
|
||||
GST_DEBUG_CATEGORY_INIT (gst_clapper_mpris_debug, "ClapperMpris", 0,
|
||||
"GstClapperMpris");
|
||||
GST_TRACE_OBJECT (self, "Initializing");
|
||||
|
||||
self = gst_clapper_mpris_get_instance_private (self);
|
||||
|
||||
g_mutex_init (&self->lock);
|
||||
g_cond_init (&self->cond);
|
||||
|
||||
self->context = g_main_context_new ();
|
||||
self->loop = g_main_loop_new (self->context, FALSE);
|
||||
|
||||
self->base_skeleton = gst_clapper_mpris_media_player2_skeleton_new ();
|
||||
self->player_skeleton = gst_clapper_mpris_media_player2_player_skeleton_new ();
|
||||
|
||||
self->name_id = 0;
|
||||
self->own_name = NULL;
|
||||
self->id_path = NULL;
|
||||
self->identity = NULL;
|
||||
self->desktop_entry = NULL;
|
||||
self->default_art_url = NULL;
|
||||
|
||||
self->signal_dispatcher = NULL;
|
||||
self->media_info = NULL;
|
||||
self->parse_media_info = FALSE;
|
||||
|
||||
self->playback_status = g_strdup ("Stopped");
|
||||
self->can_play = FALSE;
|
||||
self->position = 0;
|
||||
|
||||
GST_TRACE_OBJECT (self, "Initialized");
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_mpris_class_init (GstClapperMprisClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
|
||||
gobject_class->set_property = gst_clapper_mpris_set_property;
|
||||
gobject_class->get_property = gst_clapper_mpris_get_property;
|
||||
gobject_class->dispose = gst_clapper_mpris_dispose;
|
||||
gobject_class->finalize = gst_clapper_mpris_finalize;
|
||||
gobject_class->constructed = gst_clapper_mpris_constructed;
|
||||
|
||||
param_specs[PROP_OWN_NAME] =
|
||||
g_param_spec_string ("own-name", "DBus own name",
|
||||
"DBus name to own on connection",
|
||||
NULL, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
param_specs[PROP_ID_PATH] =
|
||||
g_param_spec_string ("id-path", "DBus id path",
|
||||
"A valid D-Bus path describing this player",
|
||||
NULL, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
param_specs[PROP_IDENTITY] =
|
||||
g_param_spec_string ("identity", "Player name",
|
||||
"A friendly name to identify the media player",
|
||||
NULL, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
param_specs[PROP_DESKTOP_ENTRY] =
|
||||
g_param_spec_string ("desktop-entry", "Desktop entry filename",
|
||||
"The basename of an installed .desktop file",
|
||||
NULL, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
param_specs[PROP_DEFAULT_ART_URL] =
|
||||
g_param_spec_string ("default-art-url", "Default Art URL",
|
||||
"Default art to show when media does not provide one",
|
||||
NULL, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
param_specs[PROP_VOLUME] =
|
||||
g_param_spec_double ("volume", "Volume", "Volume",
|
||||
0, 1.5, MPRIS_DEFAULT_VOLUME, G_PARAM_READWRITE |
|
||||
G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (gobject_class, PROP_LAST, param_specs);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_mpris_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstClapperMpris *self = GST_CLAPPER_MPRIS (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_OWN_NAME:
|
||||
self->own_name = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_ID_PATH:
|
||||
self->id_path = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_IDENTITY:
|
||||
self->identity = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_DESKTOP_ENTRY:
|
||||
self->desktop_entry = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_DEFAULT_ART_URL:
|
||||
self->default_art_url = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_VOLUME:
|
||||
g_object_set_property (G_OBJECT (self->player_skeleton), "volume", value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_mpris_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstClapperMpris *self = GST_CLAPPER_MPRIS (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_VOLUME:
|
||||
g_object_get_property (G_OBJECT (self->player_skeleton), "volume", value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_mpris_dispose (GObject * object)
|
||||
{
|
||||
GstClapperMpris *self = GST_CLAPPER_MPRIS (object);
|
||||
|
||||
GST_TRACE_OBJECT (self, "Stopping main thread");
|
||||
|
||||
if (self->loop) {
|
||||
g_main_loop_quit (self->loop);
|
||||
|
||||
if (self->thread != g_thread_self ())
|
||||
g_thread_join (self->thread);
|
||||
else
|
||||
g_thread_unref (self->thread);
|
||||
self->thread = NULL;
|
||||
|
||||
g_main_loop_unref (self->loop);
|
||||
self->loop = NULL;
|
||||
|
||||
g_main_context_unref (self->context);
|
||||
self->context = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_mpris_finalize (GObject * object)
|
||||
{
|
||||
GstClapperMpris *self = GST_CLAPPER_MPRIS (object);
|
||||
|
||||
GST_TRACE_OBJECT (self, "Finalize");
|
||||
|
||||
g_free (self->own_name);
|
||||
g_free (self->id_path);
|
||||
g_free (self->identity);
|
||||
g_free (self->desktop_entry);
|
||||
g_free (self->default_art_url);
|
||||
g_free (self->playback_status);
|
||||
|
||||
if (self->base_skeleton)
|
||||
g_object_unref (self->base_skeleton);
|
||||
if (self->player_skeleton)
|
||||
g_object_unref (self->player_skeleton);
|
||||
if (self->signal_dispatcher)
|
||||
g_object_unref (self->signal_dispatcher);
|
||||
if (self->media_info)
|
||||
g_object_unref (self->media_info);
|
||||
|
||||
g_mutex_clear (&self->lock);
|
||||
g_cond_clear (&self->cond);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_mpris_constructed (GObject * object)
|
||||
{
|
||||
GstClapperMpris *self = GST_CLAPPER_MPRIS (object);
|
||||
|
||||
GST_TRACE_OBJECT (self, "Constructed");
|
||||
|
||||
g_mutex_lock (&self->lock);
|
||||
self->thread = g_thread_new ("GstClapperMpris",
|
||||
gst_clapper_mpris_main, self);
|
||||
while (!self->loop || !g_main_loop_is_running (self->loop))
|
||||
g_cond_wait (&self->cond, &self->lock);
|
||||
g_mutex_unlock (&self->lock);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->constructed (object);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
main_loop_running_cb (gpointer user_data)
|
||||
{
|
||||
GstClapperMpris *self = GST_CLAPPER_MPRIS (user_data);
|
||||
|
||||
GST_TRACE_OBJECT (self, "Main loop running now");
|
||||
|
||||
g_mutex_lock (&self->lock);
|
||||
g_cond_signal (&self->cond);
|
||||
g_mutex_unlock (&self->lock);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_play_cb (GstClapperMprisMediaPlayer2Player * player_skeleton,
|
||||
GDBusMethodInvocation * invocation, gpointer user_data)
|
||||
{
|
||||
GstClapper *clapper = GST_CLAPPER (user_data);
|
||||
|
||||
GST_DEBUG ("Handle Play");
|
||||
|
||||
gst_clapper_play (clapper);
|
||||
gst_clapper_mpris_media_player2_player_complete_play (player_skeleton, invocation);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_pause_cb (GstClapperMprisMediaPlayer2Player * player_skeleton,
|
||||
GDBusMethodInvocation * invocation, gpointer user_data)
|
||||
{
|
||||
GstClapper *clapper = GST_CLAPPER (user_data);
|
||||
|
||||
GST_DEBUG ("Handle Pause");
|
||||
|
||||
gst_clapper_pause (clapper);
|
||||
gst_clapper_mpris_media_player2_player_complete_pause (player_skeleton, invocation);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_play_pause_cb (GstClapperMprisMediaPlayer2Player * player_skeleton,
|
||||
GDBusMethodInvocation * invocation, gpointer user_data)
|
||||
{
|
||||
GstClapper *clapper = GST_CLAPPER (user_data);
|
||||
|
||||
GST_DEBUG ("Handle PlayPause");
|
||||
|
||||
gst_clapper_toggle_play (clapper);
|
||||
gst_clapper_mpris_media_player2_player_complete_play_pause (player_skeleton, invocation);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_seek_cb (GstClapperMprisMediaPlayer2Player * player_skeleton,
|
||||
GDBusMethodInvocation * invocation, gint64 offset, gpointer user_data)
|
||||
{
|
||||
GstClapper *clapper = GST_CLAPPER (user_data);
|
||||
|
||||
GST_DEBUG ("Handle Seek");
|
||||
|
||||
gst_clapper_seek_offset (clapper, offset * GST_USECOND);
|
||||
gst_clapper_mpris_media_player2_player_complete_seek (player_skeleton, invocation);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_set_position_cb (GstClapperMprisMediaPlayer2Player * player_skeleton,
|
||||
GDBusMethodInvocation * invocation, const gchar * track_id,
|
||||
gint64 position, gpointer user_data)
|
||||
{
|
||||
GstClapper *clapper = GST_CLAPPER (user_data);
|
||||
|
||||
GST_DEBUG ("Handle SetPosition");
|
||||
|
||||
gst_clapper_seek (clapper, position * GST_USECOND);
|
||||
gst_clapper_mpris_media_player2_player_complete_set_position (player_skeleton, invocation);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_open_uri_cb (GstClapperMprisMediaPlayer2Player * player_skeleton,
|
||||
GDBusMethodInvocation * invocation, const gchar * uri,
|
||||
gpointer user_data)
|
||||
{
|
||||
GstClapper *clapper = GST_CLAPPER (user_data);
|
||||
|
||||
GST_DEBUG ("Handle OpenUri");
|
||||
|
||||
/* FIXME: set one item playlist instead */
|
||||
gst_clapper_set_uri (clapper, uri);
|
||||
gst_clapper_mpris_media_player2_player_complete_open_uri (player_skeleton, invocation);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
volume_notify_dispatch (gpointer user_data)
|
||||
{
|
||||
GstClapperMpris *self = user_data;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), param_specs[PROP_VOLUME]);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_volume_notify_cb (G_GNUC_UNUSED GObject * obj,
|
||||
G_GNUC_UNUSED GParamSpec * pspec, GstClapperMpris * self)
|
||||
{
|
||||
gst_clapper_signal_dispatcher_dispatch (self->signal_dispatcher, NULL,
|
||||
volume_notify_dispatch, g_object_ref (self),
|
||||
(GDestroyNotify) g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
unregister (GstClapperMpris * self)
|
||||
{
|
||||
if (!self->name_id)
|
||||
return;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Unregister");
|
||||
g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (self->base_skeleton));
|
||||
g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (self->player_skeleton));
|
||||
g_bus_unown_name (self->name_id);
|
||||
self->name_id = 0;
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
_get_mpris_trackid (GstClapperMpris * self)
|
||||
{
|
||||
/* TODO: Support more tracks */
|
||||
return g_strdup_printf ("%s%s%i", self->id_path, "/Track/", 0);
|
||||
}
|
||||
|
||||
static void
|
||||
_set_supported_uri_schemes (GstClapperMpris * self)
|
||||
{
|
||||
const gchar *uri_schemes[96] = {};
|
||||
GList *elements, *el;
|
||||
guint index = 0;
|
||||
|
||||
elements = gst_element_factory_list_get_elements (
|
||||
GST_ELEMENT_FACTORY_TYPE_SRC, GST_RANK_NONE);
|
||||
|
||||
for (el = elements; el != NULL; el = el->next) {
|
||||
const gchar *const *protocols;
|
||||
GstElementFactory *factory = GST_ELEMENT_FACTORY (el->data);
|
||||
|
||||
if (gst_element_factory_get_uri_type (factory) != GST_URI_SRC)
|
||||
continue;
|
||||
|
||||
protocols = gst_element_factory_get_uri_protocols (factory);
|
||||
if (protocols == NULL || *protocols == NULL)
|
||||
continue;
|
||||
|
||||
while (*protocols != NULL) {
|
||||
guint j = index;
|
||||
|
||||
while (j--) {
|
||||
if (strcmp (uri_schemes[j], *protocols) == 0)
|
||||
goto next;
|
||||
}
|
||||
uri_schemes[index] = *protocols;
|
||||
GST_DEBUG_OBJECT (self, "Added supported URI scheme: %s", *protocols);
|
||||
++index;
|
||||
next:
|
||||
++protocols;
|
||||
}
|
||||
}
|
||||
gst_plugin_feature_list_free (elements);
|
||||
|
||||
gst_clapper_mpris_media_player2_set_supported_uri_schemes (
|
||||
self->base_skeleton, uri_schemes);
|
||||
}
|
||||
|
||||
static void
|
||||
name_acquired_cb (GDBusConnection * connection,
|
||||
const gchar *name, gpointer user_data)
|
||||
{
|
||||
GstClapperMpris *self = GST_CLAPPER_MPRIS (user_data);
|
||||
GVariantBuilder builder;
|
||||
|
||||
g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (self->base_skeleton),
|
||||
connection, "/org/mpris/MediaPlayer2", NULL);
|
||||
g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (self->player_skeleton),
|
||||
connection, "/org/mpris/MediaPlayer2", NULL);
|
||||
|
||||
if (self->identity)
|
||||
gst_clapper_mpris_media_player2_set_identity (self->base_skeleton, self->identity);
|
||||
if (self->desktop_entry)
|
||||
gst_clapper_mpris_media_player2_set_desktop_entry (self->base_skeleton, self->desktop_entry);
|
||||
|
||||
_set_supported_uri_schemes (self);
|
||||
|
||||
gst_clapper_mpris_media_player2_player_set_playback_status (self->player_skeleton, "Stopped");
|
||||
gst_clapper_mpris_media_player2_player_set_minimum_rate (self->player_skeleton, 0.01);
|
||||
gst_clapper_mpris_media_player2_player_set_maximum_rate (self->player_skeleton, 2.0);
|
||||
gst_clapper_mpris_media_player2_player_set_can_seek (self->player_skeleton, TRUE);
|
||||
gst_clapper_mpris_media_player2_player_set_can_control (self->player_skeleton, TRUE);
|
||||
|
||||
g_object_bind_property (self->player_skeleton, "can-play",
|
||||
self->player_skeleton, "can-pause", G_BINDING_DEFAULT);
|
||||
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
|
||||
g_variant_builder_add (&builder, "{sv}", "mpris:trackid", g_variant_new_string (_get_mpris_trackid (self)));
|
||||
g_variant_builder_add (&builder, "{sv}", "mpris:length", g_variant_new_uint64 (0));
|
||||
if (self->default_art_url)
|
||||
g_variant_builder_add (&builder, "{sv}", "mpris:artUrl", g_variant_new_string (self->default_art_url));
|
||||
gst_clapper_mpris_media_player2_player_set_metadata (self->player_skeleton, g_variant_builder_end (&builder));
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Ready");
|
||||
}
|
||||
|
||||
static void
|
||||
name_lost_cb (GDBusConnection * connection,
|
||||
const gchar * name, gpointer user_data)
|
||||
{
|
||||
GstClapperMpris *self = GST_CLAPPER_MPRIS (user_data);
|
||||
|
||||
unregister (self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
mpris_update_props_dispatch (gpointer user_data)
|
||||
{
|
||||
GstClapperMpris *self = GST_CLAPPER_MPRIS (user_data);
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Updating MPRIS props");
|
||||
g_mutex_lock (&self->lock);
|
||||
|
||||
if (self->parse_media_info) {
|
||||
GVariantBuilder builder;
|
||||
guint64 duration;
|
||||
const gchar *track_id, *uri, *title;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Parsing media info");
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
|
||||
|
||||
track_id = _get_mpris_trackid (self);
|
||||
uri = gst_clapper_media_info_get_uri (self->media_info);
|
||||
title = gst_clapper_media_info_get_title (self->media_info);
|
||||
|
||||
if (track_id) {
|
||||
g_variant_builder_add (&builder, "{sv}", "mpris:trackid",
|
||||
g_variant_new_string (track_id));
|
||||
GST_DEBUG_OBJECT (self, "mpris:trackid: %s", track_id);
|
||||
}
|
||||
if (uri) {
|
||||
g_variant_builder_add (&builder, "{sv}", "xesam:url",
|
||||
g_variant_new_string (uri));
|
||||
GST_DEBUG_OBJECT (self, "xesam:url: %s", uri);
|
||||
}
|
||||
if (title) {
|
||||
g_variant_builder_add (&builder, "{sv}", "xesam:title",
|
||||
g_variant_new_string (title));
|
||||
GST_DEBUG_OBJECT (self, "xesam:title: %s", title);
|
||||
}
|
||||
|
||||
duration = gst_clapper_media_info_get_duration (self->media_info);
|
||||
duration = (duration != GST_CLOCK_TIME_NONE) ? duration / GST_USECOND : 0;
|
||||
g_variant_builder_add (&builder, "{sv}", "mpris:length", g_variant_new_uint64 (duration));
|
||||
GST_DEBUG_OBJECT (self, "mpris:length: %ld", duration);
|
||||
|
||||
/* TODO: Check for image sample */
|
||||
if (self->default_art_url) {
|
||||
g_variant_builder_add (&builder, "{sv}", "mpris:artUrl", g_variant_new_string (self->default_art_url));
|
||||
GST_DEBUG_OBJECT (self, "mpris:artUrl: %s", self->default_art_url);
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Media info parsed");
|
||||
self->parse_media_info = FALSE;
|
||||
|
||||
gst_clapper_mpris_media_player2_player_set_metadata (
|
||||
self->player_skeleton, g_variant_builder_end (&builder));
|
||||
}
|
||||
if (gst_clapper_mpris_media_player2_player_get_can_play (
|
||||
self->player_skeleton) != self->can_play) {
|
||||
/* "can-play" is bound with "can-pause" */
|
||||
gst_clapper_mpris_media_player2_player_set_can_play (
|
||||
self->player_skeleton, self->can_play);
|
||||
GST_DEBUG_OBJECT (self, "CanPlay/CanPause: %s", self->can_play ? "yes" : "no");
|
||||
}
|
||||
if (strcmp (gst_clapper_mpris_media_player2_player_get_playback_status (
|
||||
self->player_skeleton), self->playback_status) != 0) {
|
||||
gst_clapper_mpris_media_player2_player_set_playback_status (
|
||||
self->player_skeleton, self->playback_status);
|
||||
GST_DEBUG_OBJECT (self, "PlaybackStatus: %s", self->playback_status);
|
||||
}
|
||||
if (gst_clapper_mpris_media_player2_player_get_position (
|
||||
self->player_skeleton) != self->position) {
|
||||
gst_clapper_mpris_media_player2_player_set_position (
|
||||
self->player_skeleton, self->position);
|
||||
GST_DEBUG_OBJECT (self, "Position: %ld", self->position);
|
||||
}
|
||||
|
||||
g_mutex_unlock (&self->lock);
|
||||
GST_DEBUG_OBJECT (self, "MPRIS props updated");
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
mpris_dispatcher_update_dispatch (GstClapperMpris * self)
|
||||
{
|
||||
if (!self->name_id)
|
||||
return;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Queued update props dispatch");
|
||||
|
||||
g_main_context_invoke_full (self->context,
|
||||
G_PRIORITY_DEFAULT, mpris_update_props_dispatch,
|
||||
g_object_ref (self), g_object_unref);
|
||||
}
|
||||
|
||||
static gpointer
|
||||
gst_clapper_mpris_main (gpointer data)
|
||||
{
|
||||
GstClapperMpris *self = GST_CLAPPER_MPRIS (data);
|
||||
|
||||
GDBusConnectionFlags flags;
|
||||
GDBusConnection *connection;
|
||||
GSource *source;
|
||||
gchar *address;
|
||||
|
||||
GST_TRACE_OBJECT (self, "Starting main thread");
|
||||
|
||||
g_main_context_push_thread_default (self->context);
|
||||
|
||||
source = g_idle_source_new ();
|
||||
g_source_set_callback (source, (GSourceFunc) main_loop_running_cb, self,
|
||||
NULL);
|
||||
g_source_attach (source, self->context);
|
||||
g_source_unref (source);
|
||||
|
||||
address = g_dbus_address_get_for_bus_sync (G_BUS_TYPE_SESSION, NULL, NULL);
|
||||
if (!address) {
|
||||
GST_WARNING_OBJECT (self, "No MPRIS bus address");
|
||||
goto no_mpris;
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Obtained MPRIS DBus address");
|
||||
|
||||
flags = G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
|
||||
G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION;
|
||||
connection = g_dbus_connection_new_for_address_sync (address,
|
||||
flags, NULL, NULL, NULL);
|
||||
g_free (address);
|
||||
|
||||
if (!connection) {
|
||||
GST_WARNING_OBJECT (self, "No MPRIS bus connection");
|
||||
goto no_mpris;
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Obtained MPRIS DBus connection");
|
||||
|
||||
self->name_id = g_bus_own_name_on_connection (connection, self->own_name,
|
||||
G_BUS_NAME_OWNER_FLAGS_NONE,
|
||||
(GBusNameAcquiredCallback) name_acquired_cb,
|
||||
(GBusNameLostCallback) name_lost_cb,
|
||||
self, NULL);
|
||||
g_object_unref (connection);
|
||||
goto done;
|
||||
|
||||
no_mpris:
|
||||
g_warning ("GstClapperMpris: failed to create DBus connection");
|
||||
|
||||
done:
|
||||
GST_TRACE_OBJECT (self, "Starting main loop");
|
||||
g_main_loop_run (self->loop);
|
||||
GST_TRACE_OBJECT (self, "Stopped main loop");
|
||||
|
||||
unregister (self);
|
||||
g_main_context_pop_thread_default (self->context);
|
||||
|
||||
GST_TRACE_OBJECT (self, "Stopped main thread");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
gst_clapper_mpris_set_clapper (GstClapperMpris * self, GstClapper * clapper,
|
||||
GstClapperSignalDispatcher * signal_dispatcher)
|
||||
{
|
||||
if (signal_dispatcher)
|
||||
self->signal_dispatcher = g_object_ref (signal_dispatcher);
|
||||
|
||||
g_signal_connect (self->player_skeleton, "handle-play",
|
||||
G_CALLBACK (handle_play_cb), clapper);
|
||||
g_signal_connect (self->player_skeleton, "handle-pause",
|
||||
G_CALLBACK (handle_pause_cb), clapper);
|
||||
g_signal_connect (self->player_skeleton, "handle-play-pause",
|
||||
G_CALLBACK (handle_play_pause_cb), clapper);
|
||||
g_signal_connect (self->player_skeleton, "handle-seek",
|
||||
G_CALLBACK (handle_seek_cb), clapper);
|
||||
g_signal_connect (self->player_skeleton, "handle-set-position",
|
||||
G_CALLBACK (handle_set_position_cb), clapper);
|
||||
g_signal_connect (self->player_skeleton, "handle-open-uri",
|
||||
G_CALLBACK (handle_open_uri_cb), clapper);
|
||||
|
||||
g_object_bind_property (clapper, "volume", self, "volume", G_BINDING_BIDIRECTIONAL);
|
||||
g_signal_connect (self->player_skeleton, "notify::volume",
|
||||
G_CALLBACK (handle_volume_notify_cb), self);
|
||||
}
|
||||
|
||||
void
|
||||
gst_clapper_mpris_set_playback_status (GstClapperMpris * self, const gchar * status)
|
||||
{
|
||||
g_mutex_lock (&self->lock);
|
||||
if (strcmp (self->playback_status, status) == 0) {
|
||||
g_mutex_unlock (&self->lock);
|
||||
return;
|
||||
}
|
||||
g_free (self->playback_status);
|
||||
self->playback_status = g_strdup (status);
|
||||
self->can_play = strcmp (status, "Stopped") != 0;
|
||||
g_mutex_unlock (&self->lock);
|
||||
|
||||
mpris_dispatcher_update_dispatch (self);
|
||||
}
|
||||
|
||||
void
|
||||
gst_clapper_mpris_set_position (GstClapperMpris * self, gint64 position)
|
||||
{
|
||||
position /= GST_USECOND;
|
||||
|
||||
g_mutex_lock (&self->lock);
|
||||
if (self->position == position) {
|
||||
g_mutex_unlock (&self->lock);
|
||||
return;
|
||||
}
|
||||
self->position = position;
|
||||
g_mutex_unlock (&self->lock);
|
||||
|
||||
mpris_dispatcher_update_dispatch (self);
|
||||
}
|
||||
|
||||
void
|
||||
gst_clapper_mpris_set_media_info (GstClapperMpris *self, GstClapperMediaInfo *info)
|
||||
{
|
||||
g_mutex_lock (&self->lock);
|
||||
if (self->media_info)
|
||||
g_object_unref (self->media_info);
|
||||
self->media_info = info;
|
||||
self->parse_media_info = TRUE;
|
||||
g_mutex_unlock (&self->lock);
|
||||
|
||||
mpris_dispatcher_update_dispatch (self);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_mpris_new:
|
||||
* @own_name: DBus own name
|
||||
* @id_path: DBus id path used for prefix
|
||||
* @identity: (allow-none): friendly name
|
||||
* @desktop_entry: (allow-none): Desktop entry filename
|
||||
* @default_art_url: (allow-none): filepath to default art
|
||||
*
|
||||
* Creates a new #GstClapperMpris instance.
|
||||
*
|
||||
* Returns: (transfer full): a new #GstClapperMpris instance
|
||||
*/
|
||||
GstClapperMpris *
|
||||
gst_clapper_mpris_new (const gchar * own_name, const gchar * id_path,
|
||||
const gchar * identity, const gchar * desktop_entry,
|
||||
const gchar * default_art_url)
|
||||
{
|
||||
GstClapperMpris *self;
|
||||
|
||||
self = g_object_new (GST_TYPE_CLAPPER,
|
||||
"own-name", own_name, "id_path", id_path,
|
||||
"identity", identity, "desktop-entry", desktop_entry,
|
||||
"default-art-url", default_art_url, NULL);
|
||||
|
||||
return self;
|
||||
}
|
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_CLAPPER_MPRIS_H__
|
||||
#define __GST_CLAPPER_MPRIS_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include <gst/clapper/clapper-prelude.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstClapperMpris GstClapperMpris;
|
||||
typedef struct _GstClapperMprisClass GstClapperMprisClass;
|
||||
|
||||
#define GST_TYPE_CLAPPER_MPRIS (gst_clapper_mpris_get_type ())
|
||||
#define GST_IS_CLAPPER_MPRIS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_CLAPPER_MPRIS))
|
||||
#define GST_IS_CLAPPER_MPRIS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_CLAPPER_MPRIS))
|
||||
#define GST_CLAPPER_MPRIS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_CLAPPER_MPRIS, GstClapperMprisClass))
|
||||
#define GST_CLAPPER_MPRIS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_CLAPPER_MPRIS, GstClapperMpris))
|
||||
#define GST_CLAPPER_MPRIS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_CLAPPER_MPRIS, GstClapperMprisClass))
|
||||
#define GST_CLAPPER_MPRIS_CAST(obj) ((GstClapperMpris*)(obj))
|
||||
|
||||
#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstClapperMpris, g_object_unref)
|
||||
#endif
|
||||
|
||||
GST_CLAPPER_API
|
||||
GType gst_clapper_mpris_get_type (void);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GstClapperMpris * gst_clapper_mpris_new (const gchar *own_name, const gchar *id_path, const gchar *identity,
|
||||
const gchar *desktop_entry, const gchar *default_art_url);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_CLAPPER_MPRIS_H__ */
|
@@ -1,58 +0,0 @@
|
||||
/* GStreamer
|
||||
*
|
||||
* Copyright (C) 2014-2015 Sebastian Dröge <sebastian@centricular.com>
|
||||
* Copyright (C) 2021 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gstclapper-signal-dispatcher.h"
|
||||
#include "gstclapper-signal-dispatcher-private.h"
|
||||
|
||||
G_DEFINE_INTERFACE (GstClapperSignalDispatcher, gst_clapper_signal_dispatcher,
|
||||
G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
gst_clapper_signal_dispatcher_default_init (G_GNUC_UNUSED
|
||||
GstClapperSignalDispatcherInterface * iface)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
gst_clapper_signal_dispatcher_dispatch (GstClapperSignalDispatcher * self,
|
||||
GstClapper * clapper, GstClapperSignalDispatcherFunc emitter, gpointer data,
|
||||
GDestroyNotify destroy)
|
||||
{
|
||||
GstClapperSignalDispatcherInterface *iface;
|
||||
|
||||
if (!self) {
|
||||
emitter (data);
|
||||
if (destroy)
|
||||
destroy (data);
|
||||
return;
|
||||
}
|
||||
|
||||
g_return_if_fail (GST_IS_CLAPPER_SIGNAL_DISPATCHER (self));
|
||||
iface = GST_CLAPPER_SIGNAL_DISPATCHER_GET_INTERFACE (self);
|
||||
g_return_if_fail (iface->dispatch != NULL);
|
||||
|
||||
iface->dispatch (self, clapper, emitter, data, destroy);
|
||||
}
|
@@ -1,53 +0,0 @@
|
||||
/* GStreamer
|
||||
*
|
||||
* Copyright (C) 2014-2015 Sebastian Dröge <sebastian@centricular.com>
|
||||
* Copyright (C) 2021 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_CLAPPER_SIGNAL_DISPATCHER_H__
|
||||
#define __GST_CLAPPER_SIGNAL_DISPATCHER_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/clapper/gstclapper-types.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstClapperSignalDispatcher GstClapperSignalDispatcher;
|
||||
typedef struct _GstClapperSignalDispatcherInterface GstClapperSignalDispatcherInterface;
|
||||
|
||||
#define GST_TYPE_CLAPPER_SIGNAL_DISPATCHER (gst_clapper_signal_dispatcher_get_type ())
|
||||
#define GST_CLAPPER_SIGNAL_DISPATCHER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_CLAPPER_SIGNAL_DISPATCHER, GstClapperSignalDispatcher))
|
||||
#define GST_IS_CLAPPER_SIGNAL_DISPATCHER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_CLAPPER_SIGNAL_DISPATCHER))
|
||||
#define GST_CLAPPER_SIGNAL_DISPATCHER_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_CLAPPER_SIGNAL_DISPATCHER, GstClapperSignalDispatcherInterface))
|
||||
|
||||
typedef void (*GstClapperSignalDispatcherFunc) (gpointer data);
|
||||
|
||||
struct _GstClapperSignalDispatcherInterface {
|
||||
GTypeInterface parent_iface;
|
||||
|
||||
void (*dispatch) (GstClapperSignalDispatcher * self, GstClapper * clapper,
|
||||
GstClapperSignalDispatcherFunc emitter, gpointer data,
|
||||
GDestroyNotify destroy);
|
||||
};
|
||||
|
||||
GST_CLAPPER_API
|
||||
GType gst_clapper_signal_dispatcher_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_CLAPPER_SIGNAL_DISPATCHER_H__ */
|
@@ -1,345 +0,0 @@
|
||||
/* GStreamer
|
||||
*
|
||||
* Copyright (C) 2014-2015 Sebastian Dröge <sebastian@centricular.com>
|
||||
* Copyright (C) 2021 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:gstclapper-videooverlayvideorenderer
|
||||
* @title: GstClapperVideoOverlayVideoRenderer
|
||||
* @short_description: Clapper Video Overlay Video Renderer
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gstclapper-video-overlay-video-renderer.h"
|
||||
#include "gstclapper.h"
|
||||
|
||||
#include <gst/video/video.h>
|
||||
|
||||
struct _GstClapperVideoOverlayVideoRenderer
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
GstVideoOverlay *video_overlay;
|
||||
gpointer window_handle;
|
||||
gint x, y, width, height;
|
||||
|
||||
GstElement *video_sink; /* configured video sink, or NULL */
|
||||
};
|
||||
|
||||
struct _GstClapperVideoOverlayVideoRendererClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
static void
|
||||
gst_clapper_video_overlay_video_renderer_interface_init
|
||||
(GstClapperVideoRendererInterface * iface);
|
||||
|
||||
enum
|
||||
{
|
||||
VIDEO_OVERLAY_VIDEO_RENDERER_PROP_0,
|
||||
VIDEO_OVERLAY_VIDEO_RENDERER_PROP_WINDOW_HANDLE,
|
||||
VIDEO_OVERLAY_VIDEO_RENDERER_PROP_VIDEO_SINK,
|
||||
VIDEO_OVERLAY_VIDEO_RENDERER_PROP_LAST
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GstClapperVideoOverlayVideoRenderer,
|
||||
gst_clapper_video_overlay_video_renderer, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (GST_TYPE_CLAPPER_VIDEO_RENDERER,
|
||||
gst_clapper_video_overlay_video_renderer_interface_init));
|
||||
|
||||
static GParamSpec
|
||||
* video_overlay_video_renderer_param_specs
|
||||
[VIDEO_OVERLAY_VIDEO_RENDERER_PROP_LAST] = { NULL, };
|
||||
|
||||
static void
|
||||
gst_clapper_video_overlay_video_renderer_set_property (GObject * object,
|
||||
guint prop_id, const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstClapperVideoOverlayVideoRenderer *self =
|
||||
GST_CLAPPER_VIDEO_OVERLAY_VIDEO_RENDERER (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case VIDEO_OVERLAY_VIDEO_RENDERER_PROP_WINDOW_HANDLE:
|
||||
self->window_handle = g_value_get_pointer (value);
|
||||
if (self->video_overlay)
|
||||
gst_video_overlay_set_window_handle (self->video_overlay,
|
||||
(guintptr) self->window_handle);
|
||||
break;
|
||||
case VIDEO_OVERLAY_VIDEO_RENDERER_PROP_VIDEO_SINK:
|
||||
self->video_sink = gst_object_ref_sink (g_value_get_object (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_video_overlay_video_renderer_get_property (GObject * object,
|
||||
guint prop_id, GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstClapperVideoOverlayVideoRenderer *self =
|
||||
GST_CLAPPER_VIDEO_OVERLAY_VIDEO_RENDERER (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case VIDEO_OVERLAY_VIDEO_RENDERER_PROP_WINDOW_HANDLE:
|
||||
g_value_set_pointer (value, self->window_handle);
|
||||
break;
|
||||
case VIDEO_OVERLAY_VIDEO_RENDERER_PROP_VIDEO_SINK:
|
||||
g_value_set_object (value, self->video_sink);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_video_overlay_video_renderer_finalize (GObject * object)
|
||||
{
|
||||
GstClapperVideoOverlayVideoRenderer *self =
|
||||
GST_CLAPPER_VIDEO_OVERLAY_VIDEO_RENDERER (object);
|
||||
|
||||
if (self->video_overlay)
|
||||
gst_object_unref (self->video_overlay);
|
||||
|
||||
if (self->video_sink)
|
||||
gst_object_unref (self->video_sink);
|
||||
|
||||
G_OBJECT_CLASS
|
||||
(gst_clapper_video_overlay_video_renderer_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_video_overlay_video_renderer_class_init
|
||||
(GstClapperVideoOverlayVideoRendererClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->set_property =
|
||||
gst_clapper_video_overlay_video_renderer_set_property;
|
||||
gobject_class->get_property =
|
||||
gst_clapper_video_overlay_video_renderer_get_property;
|
||||
gobject_class->finalize = gst_clapper_video_overlay_video_renderer_finalize;
|
||||
|
||||
video_overlay_video_renderer_param_specs
|
||||
[VIDEO_OVERLAY_VIDEO_RENDERER_PROP_WINDOW_HANDLE] =
|
||||
g_param_spec_pointer ("window-handle", "Window Handle",
|
||||
"Window handle to embed the video into",
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
video_overlay_video_renderer_param_specs
|
||||
[VIDEO_OVERLAY_VIDEO_RENDERER_PROP_VIDEO_SINK] =
|
||||
g_param_spec_object ("video-sink", "Video Sink",
|
||||
"the video output element to use (NULL = default sink)",
|
||||
GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (gobject_class,
|
||||
VIDEO_OVERLAY_VIDEO_RENDERER_PROP_LAST,
|
||||
video_overlay_video_renderer_param_specs);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_video_overlay_video_renderer_init
|
||||
(GstClapperVideoOverlayVideoRenderer * self)
|
||||
{
|
||||
self->x = self->y = self->width = self->height = -1;
|
||||
self->video_sink = NULL;
|
||||
}
|
||||
|
||||
static GstElement *gst_clapper_video_overlay_video_renderer_create_video_sink
|
||||
(GstClapperVideoRenderer * iface, GstClapper * clapper)
|
||||
{
|
||||
GstElement *video_overlay;
|
||||
GstClapperVideoOverlayVideoRenderer *self =
|
||||
GST_CLAPPER_VIDEO_OVERLAY_VIDEO_RENDERER (iface);
|
||||
|
||||
if (self->video_overlay)
|
||||
gst_object_unref (self->video_overlay);
|
||||
|
||||
video_overlay = gst_clapper_get_pipeline (clapper);
|
||||
g_return_val_if_fail (GST_IS_VIDEO_OVERLAY (video_overlay), NULL);
|
||||
|
||||
self->video_overlay = GST_VIDEO_OVERLAY (video_overlay);
|
||||
|
||||
gst_video_overlay_set_window_handle (self->video_overlay,
|
||||
(guintptr) self->window_handle);
|
||||
if (self->width != -1 || self->height != -1)
|
||||
gst_video_overlay_set_render_rectangle (self->video_overlay, self->x,
|
||||
self->y, self->width, self->height);
|
||||
|
||||
return self->video_sink;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_video_overlay_video_renderer_interface_init
|
||||
(GstClapperVideoRendererInterface * iface)
|
||||
{
|
||||
iface->create_video_sink =
|
||||
gst_clapper_video_overlay_video_renderer_create_video_sink;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_video_overlay_video_renderer_new:
|
||||
* @window_handle: (allow-none): Window handle to use or %NULL
|
||||
*
|
||||
* Returns: (transfer full):
|
||||
*/
|
||||
GstClapperVideoRenderer *
|
||||
gst_clapper_video_overlay_video_renderer_new (gpointer window_handle)
|
||||
{
|
||||
return g_object_new (GST_TYPE_CLAPPER_VIDEO_OVERLAY_VIDEO_RENDERER,
|
||||
"window-handle", window_handle, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_video_overlay_video_renderer_new_with_sink:
|
||||
* @window_handle: (allow-none): Window handle to use or %NULL
|
||||
* @video_sink: (transfer floating): the custom video_sink element to be set for the video renderer
|
||||
*
|
||||
* Returns: (transfer full): clapper video renderer
|
||||
*/
|
||||
GstClapperVideoRenderer *
|
||||
gst_clapper_video_overlay_video_renderer_new_with_sink (gpointer window_handle,
|
||||
GstElement * video_sink)
|
||||
{
|
||||
return g_object_new (GST_TYPE_CLAPPER_VIDEO_OVERLAY_VIDEO_RENDERER,
|
||||
"window-handle", window_handle, "video-sink", video_sink, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_video_overlay_video_renderer_set_window_handle:
|
||||
* @self: #GstClapperVideoRenderer instance
|
||||
* @window_handle: handle referencing to the platform specific window
|
||||
*
|
||||
* Sets the platform specific window handle into which the video
|
||||
* should be rendered
|
||||
**/
|
||||
void gst_clapper_video_overlay_video_renderer_set_window_handle
|
||||
(GstClapperVideoOverlayVideoRenderer * self, gpointer window_handle)
|
||||
{
|
||||
g_return_if_fail (GST_IS_CLAPPER_VIDEO_OVERLAY_VIDEO_RENDERER (self));
|
||||
|
||||
g_object_set (self, "window-handle", window_handle, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_video_overlay_video_renderer_get_window_handle:
|
||||
* @self: #GstClapperVideoRenderer instance
|
||||
*
|
||||
* Returns: (transfer none): The currently set, platform specific window
|
||||
* handle
|
||||
*/
|
||||
gpointer
|
||||
gst_clapper_video_overlay_video_renderer_get_window_handle
|
||||
(GstClapperVideoOverlayVideoRenderer * self) {
|
||||
gpointer window_handle;
|
||||
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_VIDEO_OVERLAY_VIDEO_RENDERER (self),
|
||||
NULL);
|
||||
|
||||
g_object_get (self, "window-handle", &window_handle, NULL);
|
||||
|
||||
return window_handle;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_video_overlay_video_renderer_expose:
|
||||
* @self: a #GstClapperVideoOverlayVideoRenderer instance.
|
||||
*
|
||||
* Tell an overlay that it has been exposed. This will redraw the current frame
|
||||
* in the drawable even if the pipeline is PAUSED.
|
||||
*/
|
||||
void gst_clapper_video_overlay_video_renderer_expose
|
||||
(GstClapperVideoOverlayVideoRenderer * self)
|
||||
{
|
||||
g_return_if_fail (GST_IS_CLAPPER_VIDEO_OVERLAY_VIDEO_RENDERER (self));
|
||||
|
||||
if (self->video_overlay)
|
||||
gst_video_overlay_expose (self->video_overlay);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_video_overlay_video_renderer_set_render_rectangle:
|
||||
* @self: a #GstClapperVideoOverlayVideoRenderer instance
|
||||
* @x: the horizontal offset of the render area inside the window
|
||||
* @y: the vertical offset of the render area inside the window
|
||||
* @width: the width of the render area inside the window
|
||||
* @height: the height of the render area inside the window
|
||||
*
|
||||
* Configure a subregion as a video target within the window set by
|
||||
* gst_clapper_video_overlay_video_renderer_set_window_handle(). If this is not
|
||||
* used or not supported the video will fill the area of the window set as the
|
||||
* overlay to 100%. By specifying the rectangle, the video can be overlaid to
|
||||
* a specific region of that window only. After setting the new rectangle one
|
||||
* should call gst_clapper_video_overlay_video_renderer_expose() to force a
|
||||
* redraw. To unset the region pass -1 for the @width and @height parameters.
|
||||
*
|
||||
* This method is needed for non fullscreen video overlay in UI toolkits that
|
||||
* do not support subwindows.
|
||||
*
|
||||
*/
|
||||
void gst_clapper_video_overlay_video_renderer_set_render_rectangle
|
||||
(GstClapperVideoOverlayVideoRenderer * self, gint x, gint y, gint width,
|
||||
gint height)
|
||||
{
|
||||
g_return_if_fail (GST_IS_CLAPPER_VIDEO_OVERLAY_VIDEO_RENDERER (self));
|
||||
|
||||
self->x = x;
|
||||
self->y = y;
|
||||
self->width = width;
|
||||
self->height = height;
|
||||
|
||||
if (self->video_overlay)
|
||||
gst_video_overlay_set_render_rectangle (self->video_overlay,
|
||||
x, y, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_video_overlay_video_renderer_get_render_rectangle:
|
||||
* @self: a #GstClapperVideoOverlayVideoRenderer instance
|
||||
* @x: (out) (allow-none): the horizontal offset of the render area inside the window
|
||||
* @y: (out) (allow-none): the vertical offset of the render area inside the window
|
||||
* @width: (out) (allow-none): the width of the render area inside the window
|
||||
* @height: (out) (allow-none): the height of the render area inside the window
|
||||
*
|
||||
* Return the currently configured render rectangle. See gst_clapper_video_overlay_video_renderer_set_render_rectangle()
|
||||
* for details.
|
||||
*
|
||||
*/
|
||||
void gst_clapper_video_overlay_video_renderer_get_render_rectangle
|
||||
(GstClapperVideoOverlayVideoRenderer * self, gint * x, gint * y,
|
||||
gint * width, gint * height)
|
||||
{
|
||||
g_return_if_fail (GST_IS_CLAPPER_VIDEO_OVERLAY_VIDEO_RENDERER (self));
|
||||
|
||||
if (x)
|
||||
*x = self->x;
|
||||
if (y)
|
||||
*y = self->y;
|
||||
if (width)
|
||||
*width = self->width;
|
||||
if (height)
|
||||
*height = self->height;
|
||||
}
|
@@ -1,71 +0,0 @@
|
||||
/* GStreamer
|
||||
*
|
||||
* Copyright (C) 2014-2015 Sebastian Dröge <sebastian@centricular.com>
|
||||
* Copyright (C) 2021 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_CLAPPER_VIDEO_OVERLAY_VIDEO_RENDERER_H__
|
||||
#define __GST_CLAPPER_VIDEO_OVERLAY_VIDEO_RENDERER_H__
|
||||
|
||||
#include <gst/clapper/gstclapper-types.h>
|
||||
#include <gst/clapper/gstclapper-video-renderer.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstClapperVideoOverlayVideoRenderer
|
||||
GstClapperVideoOverlayVideoRenderer;
|
||||
typedef struct _GstClapperVideoOverlayVideoRendererClass
|
||||
GstClapperVideoOverlayVideoRendererClass;
|
||||
|
||||
#define GST_TYPE_CLAPPER_VIDEO_OVERLAY_VIDEO_RENDERER (gst_clapper_video_overlay_video_renderer_get_type ())
|
||||
#define GST_IS_CLAPPER_VIDEO_OVERLAY_VIDEO_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_CLAPPER_VIDEO_OVERLAY_VIDEO_RENDERER))
|
||||
#define GST_IS_CLAPPER_VIDEO_OVERLAY_VIDEO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_CLAPPER_VIDEO_OVERLAY_VIDEO_RENDERER))
|
||||
#define GST_CLAPPER_VIDEO_OVERLAY_VIDEO_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_CLAPPER_VIDEO_OVERLAY_VIDEO_RENDERER, GstClapperVideoOverlayVideoRendererClass))
|
||||
#define GST_CLAPPER_VIDEO_OVERLAY_VIDEO_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_CLAPPER_VIDEO_OVERLAY_VIDEO_RENDERER, GstClapperVideoOverlayVideoRenderer))
|
||||
#define GST_CLAPPER_VIDEO_OVERLAY_VIDEO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_CLAPPER_VIDEO_OVERLAY_VIDEO_RENDERER, GstClapperVideoOverlayVideoRendererClass))
|
||||
#define GST_CLAPPER_VIDEO_OVERLAY_VIDEO_RENDERER_CAST(obj) ((GstClapperVideoOverlayVideoRenderer*)(obj))
|
||||
|
||||
GST_CLAPPER_API
|
||||
GType gst_clapper_video_overlay_video_renderer_get_type (void);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GstClapperVideoRenderer *
|
||||
gst_clapper_video_overlay_video_renderer_new (gpointer window_handle);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GstClapperVideoRenderer *
|
||||
gst_clapper_video_overlay_video_renderer_new_with_sink (gpointer window_handle, GstElement *video_sink);
|
||||
|
||||
GST_CLAPPER_API
|
||||
void gst_clapper_video_overlay_video_renderer_set_window_handle (GstClapperVideoOverlayVideoRenderer *self, gpointer window_handle);
|
||||
|
||||
GST_CLAPPER_API
|
||||
gpointer gst_clapper_video_overlay_video_renderer_get_window_handle (GstClapperVideoOverlayVideoRenderer *self);
|
||||
|
||||
GST_CLAPPER_API
|
||||
void gst_clapper_video_overlay_video_renderer_expose (GstClapperVideoOverlayVideoRenderer *self);
|
||||
|
||||
GST_CLAPPER_API
|
||||
void gst_clapper_video_overlay_video_renderer_set_render_rectangle (GstClapperVideoOverlayVideoRenderer *self, gint x, gint y, gint width, gint height);
|
||||
|
||||
GST_CLAPPER_API
|
||||
void gst_clapper_video_overlay_video_renderer_get_render_rectangle (GstClapperVideoOverlayVideoRenderer *self, gint *x, gint *y, gint *width, gint *height);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_CLAPPER_VIDEO_OVERLAY_VIDEO_RENDERER_H__ */
|
@@ -1,50 +0,0 @@
|
||||
/* GStreamer
|
||||
*
|
||||
* Copyright (C) 2014-2015 Sebastian Dröge <sebastian@centricular.com>
|
||||
* Copyright (C) 2021 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gstclapper-video-renderer.h"
|
||||
#include "gstclapper-video-renderer-private.h"
|
||||
|
||||
G_DEFINE_INTERFACE (GstClapperVideoRenderer, gst_clapper_video_renderer,
|
||||
G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
gst_clapper_video_renderer_default_init (G_GNUC_UNUSED
|
||||
GstClapperVideoRendererInterface * iface)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
GstElement *
|
||||
gst_clapper_video_renderer_create_video_sink (GstClapperVideoRenderer * self,
|
||||
GstClapper * clapper)
|
||||
{
|
||||
GstClapperVideoRendererInterface *iface;
|
||||
|
||||
g_return_val_if_fail (GST_IS_CLAPPER_VIDEO_RENDERER (self), NULL);
|
||||
iface = GST_CLAPPER_VIDEO_RENDERER_GET_INTERFACE (self);
|
||||
g_return_val_if_fail (iface->create_video_sink != NULL, NULL);
|
||||
|
||||
return iface->create_video_sink (self, clapper);
|
||||
}
|
@@ -1,49 +0,0 @@
|
||||
/* GStreamer
|
||||
*
|
||||
* Copyright (C) 2014-2015 Sebastian Dröge <sebastian@centricular.com>
|
||||
* Copyright (C) 2021 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_CLAPPER_VIDEO_RENDERER_H__
|
||||
#define __GST_CLAPPER_VIDEO_RENDERER_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/clapper/gstclapper-types.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstClapperVideoRenderer GstClapperVideoRenderer;
|
||||
typedef struct _GstClapperVideoRendererInterface GstClapperVideoRendererInterface;
|
||||
|
||||
#define GST_TYPE_CLAPPER_VIDEO_RENDERER (gst_clapper_video_renderer_get_type ())
|
||||
#define GST_CLAPPER_VIDEO_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_CLAPPER_VIDEO_RENDERER, GstClapperVideoRenderer))
|
||||
#define GST_IS_CLAPPER_VIDEO_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_CLAPPER_VIDEO_RENDERER))
|
||||
#define GST_CLAPPER_VIDEO_RENDERER_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_CLAPPER_VIDEO_RENDERER, GstClapperVideoRendererInterface))
|
||||
|
||||
struct _GstClapperVideoRendererInterface {
|
||||
GTypeInterface parent_iface;
|
||||
|
||||
GstElement * (*create_video_sink) (GstClapperVideoRenderer * self, GstClapper * clapper);
|
||||
};
|
||||
|
||||
GST_CLAPPER_API
|
||||
GType gst_clapper_video_renderer_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_CLAPPER_VIDEO_RENDERER_H__ */
|
@@ -1,180 +0,0 @@
|
||||
/* GStreamer
|
||||
*
|
||||
* Copyright (C) 2014-2015 Sebastian Dröge <sebastian@centricular.com>
|
||||
* Copyright (C) 2015 Brijesh Singh <brijesh.ksingh@gmail.com>
|
||||
* Copyright (C) 2021 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:gstclapper-visualization
|
||||
* @title: GstClapperVisualization
|
||||
* @short_description: Clapper Visualization
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gstclapper-visualization.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static GMutex vis_lock;
|
||||
static GQueue vis_list = G_QUEUE_INIT;
|
||||
static guint32 vis_cookie;
|
||||
|
||||
G_DEFINE_BOXED_TYPE (GstClapperVisualization, gst_clapper_visualization,
|
||||
(GBoxedCopyFunc) gst_clapper_visualization_copy,
|
||||
(GBoxedFreeFunc) gst_clapper_visualization_free);
|
||||
|
||||
/**
|
||||
* gst_clapper_visualization_free:
|
||||
* @vis: #GstClapperVisualization instance
|
||||
*
|
||||
* Frees a #GstClapperVisualization.
|
||||
*/
|
||||
void
|
||||
gst_clapper_visualization_free (GstClapperVisualization * vis)
|
||||
{
|
||||
g_return_if_fail (vis != NULL);
|
||||
|
||||
g_free (vis->name);
|
||||
g_free (vis->description);
|
||||
g_free (vis);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_visualization_copy:
|
||||
* @vis: #GstClapperVisualization instance
|
||||
*
|
||||
* Makes a copy of the #GstClapperVisualization. The result must be
|
||||
* freed using gst_clapper_visualization_free().
|
||||
*
|
||||
* Returns: (transfer full): an allocated copy of @vis.
|
||||
*/
|
||||
GstClapperVisualization *
|
||||
gst_clapper_visualization_copy (const GstClapperVisualization * vis)
|
||||
{
|
||||
GstClapperVisualization *ret;
|
||||
|
||||
g_return_val_if_fail (vis != NULL, NULL);
|
||||
|
||||
ret = g_new0 (GstClapperVisualization, 1);
|
||||
ret->name = vis->name ? g_strdup (vis->name) : NULL;
|
||||
ret->description = vis->description ? g_strdup (vis->description) : NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_visualizations_free:
|
||||
* @viss: a %NULL terminated array of #GstClapperVisualization to free
|
||||
*
|
||||
* Frees a %NULL terminated array of #GstClapperVisualization.
|
||||
*/
|
||||
void
|
||||
gst_clapper_visualizations_free (GstClapperVisualization ** viss)
|
||||
{
|
||||
GstClapperVisualization **p;
|
||||
|
||||
g_return_if_fail (viss != NULL);
|
||||
|
||||
p = viss;
|
||||
while (*p) {
|
||||
g_free ((*p)->name);
|
||||
g_free ((*p)->description);
|
||||
g_free (*p);
|
||||
p++;
|
||||
}
|
||||
g_free (viss);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_update_visualization_list (void)
|
||||
{
|
||||
GList *features;
|
||||
GList *l;
|
||||
guint32 cookie;
|
||||
GstClapperVisualization *vis;
|
||||
|
||||
g_mutex_lock (&vis_lock);
|
||||
|
||||
/* check if we need to update the list */
|
||||
cookie = gst_registry_get_feature_list_cookie (gst_registry_get ());
|
||||
if (vis_cookie == cookie) {
|
||||
g_mutex_unlock (&vis_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
/* if update is needed then first free the existing list */
|
||||
while ((vis = g_queue_pop_head (&vis_list)))
|
||||
gst_clapper_visualization_free (vis);
|
||||
|
||||
features = gst_registry_get_feature_list (gst_registry_get (),
|
||||
GST_TYPE_ELEMENT_FACTORY);
|
||||
|
||||
for (l = features; l; l = l->next) {
|
||||
GstPluginFeature *feature = l->data;
|
||||
const gchar *klass;
|
||||
|
||||
klass = gst_element_factory_get_metadata (GST_ELEMENT_FACTORY (feature),
|
||||
GST_ELEMENT_METADATA_KLASS);
|
||||
|
||||
if (strstr (klass, "Visualization")) {
|
||||
vis = g_new0 (GstClapperVisualization, 1);
|
||||
|
||||
vis->name = g_strdup (gst_plugin_feature_get_name (feature));
|
||||
vis->description =
|
||||
g_strdup (gst_element_factory_get_metadata (GST_ELEMENT_FACTORY
|
||||
(feature), GST_ELEMENT_METADATA_DESCRIPTION));
|
||||
g_queue_push_tail (&vis_list, vis);
|
||||
}
|
||||
}
|
||||
gst_plugin_feature_list_free (features);
|
||||
|
||||
vis_cookie = cookie;
|
||||
|
||||
g_mutex_unlock (&vis_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_clapper_visualizations_get:
|
||||
*
|
||||
* Returns: (transfer full) (array zero-terminated=1) (element-type GstClapperVisualization):
|
||||
* a %NULL terminated array containing all available
|
||||
* visualizations. Use gst_clapper_visualizations_free() after
|
||||
* usage.
|
||||
*/
|
||||
GstClapperVisualization **
|
||||
gst_clapper_visualizations_get (void)
|
||||
{
|
||||
gint i = 0;
|
||||
GList *l;
|
||||
GstClapperVisualization **ret;
|
||||
|
||||
gst_clapper_update_visualization_list ();
|
||||
|
||||
g_mutex_lock (&vis_lock);
|
||||
ret = g_new0 (GstClapperVisualization *, g_queue_get_length (&vis_list) + 1);
|
||||
for (l = vis_list.head; l; l = l->next)
|
||||
ret[i++] = gst_clapper_visualization_copy (l->data);
|
||||
g_mutex_unlock (&vis_lock);
|
||||
|
||||
return ret;
|
||||
}
|
@@ -1,61 +0,0 @@
|
||||
/* GStreamer
|
||||
*
|
||||
* Copyright (C) 2014-2015 Sebastian Dröge <sebastian@centricular.com>
|
||||
* Copyright (C) 2015 Brijesh Singh <brijesh.ksingh@gmail.com>
|
||||
* Copyright (C) 2021 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_CLAPPER_VISUALIZATION_H__
|
||||
#define __GST_CLAPPER_VISUALIZATION_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/clapper/clapper-prelude.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstClapperVisualization GstClapperVisualization;
|
||||
/**
|
||||
* GstClapperVisualization:
|
||||
* @name: name of the visualization.
|
||||
* @description: description of the visualization.
|
||||
*
|
||||
* A #GstClapperVisualization descriptor.
|
||||
*/
|
||||
struct _GstClapperVisualization {
|
||||
gchar *name;
|
||||
gchar *description;
|
||||
};
|
||||
|
||||
GST_CLAPPER_API
|
||||
GType gst_clapper_visualization_get_type (void);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GstClapperVisualization * gst_clapper_visualization_copy (const GstClapperVisualization *vis);
|
||||
|
||||
GST_CLAPPER_API
|
||||
void gst_clapper_visualization_free (GstClapperVisualization *vis);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GstClapperVisualization ** gst_clapper_visualizations_get (void);
|
||||
|
||||
GST_CLAPPER_API
|
||||
void gst_clapper_visualizations_free (GstClapperVisualization **viss);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_CLAPPER_VISUALIZATION_H__ */
|
File diff suppressed because it is too large
Load Diff
@@ -1,315 +0,0 @@
|
||||
/* GStreamer
|
||||
*
|
||||
* Copyright (C) 2014-2015 Sebastian Dröge <sebastian@centricular.com>
|
||||
* Copyright (C) 2021 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_CLAPPER_H__
|
||||
#define __GST_CLAPPER_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/video/video.h>
|
||||
|
||||
#include <gst/clapper/clapper-prelude.h>
|
||||
#include <gst/clapper/gstclapper-types.h>
|
||||
#include <gst/clapper/gstclapper-signal-dispatcher.h>
|
||||
#include <gst/clapper/gstclapper-video-renderer.h>
|
||||
#include <gst/clapper/gstclapper-media-info.h>
|
||||
#include <gst/clapper/gstclapper-mpris.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* ClapperState */
|
||||
GST_CLAPPER_API
|
||||
GType gst_clapper_state_get_type (void);
|
||||
#define GST_TYPE_CLAPPER_STATE (gst_clapper_state_get_type ())
|
||||
|
||||
/**
|
||||
* GstClapperState:
|
||||
* @GST_CLAPPER_STATE_STOPPED: clapper is stopped.
|
||||
* @GST_CLAPPER_STATE_BUFFERING: clapper is buffering.
|
||||
* @GST_CLAPPER_STATE_PAUSED: clapper is paused.
|
||||
* @GST_CLAPPER_STATE_PLAYING: clapper is currently playing a stream.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GST_CLAPPER_STATE_STOPPED,
|
||||
GST_CLAPPER_STATE_BUFFERING,
|
||||
GST_CLAPPER_STATE_PAUSED,
|
||||
GST_CLAPPER_STATE_PLAYING
|
||||
} GstClapperState;
|
||||
|
||||
GST_CLAPPER_API
|
||||
const gchar * gst_clapper_state_get_name (GstClapperState state);
|
||||
|
||||
/* ClapperSeekMode */
|
||||
GST_CLAPPER_API
|
||||
GType gst_clapper_seek_mode_get_type (void);
|
||||
#define GST_TYPE_CLAPPER_SEEK_MODE (gst_clapper_seek_mode_get_type ())
|
||||
|
||||
/**
|
||||
* GstClapperSeekMode:
|
||||
* @GST_CLAPPER_SEEK_MODE_DEFAULT: default seek method (flush only).
|
||||
* @GST_CLAPPER_SEEK_MODE_ACCURATE: accurate seek method.
|
||||
* @GST_CLAPPER_SEEK_MODE_FAST: fast seek method (next keyframe).
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GST_CLAPPER_SEEK_MODE_DEFAULT,
|
||||
GST_CLAPPER_SEEK_MODE_ACCURATE,
|
||||
GST_CLAPPER_SEEK_MODE_FAST,
|
||||
} GstClapperSeekMode;
|
||||
|
||||
/* ClapperError */
|
||||
GST_CLAPPER_API
|
||||
GQuark gst_clapper_error_quark (void);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GType gst_clapper_error_get_type (void);
|
||||
#define GST_CLAPPER_ERROR (gst_clapper_error_quark ())
|
||||
#define GST_TYPE_CLAPPER_ERROR (gst_clapper_error_get_type ())
|
||||
|
||||
/**
|
||||
* GstClapperError:
|
||||
* @GST_CLAPPER_ERROR_FAILED: generic error.
|
||||
*/
|
||||
typedef enum {
|
||||
GST_CLAPPER_ERROR_FAILED = 0
|
||||
} GstClapperError;
|
||||
|
||||
GST_CLAPPER_API
|
||||
const gchar * gst_clapper_error_get_name (GstClapperError error);
|
||||
|
||||
/* ClapperColorBalanceType */
|
||||
GST_CLAPPER_API
|
||||
GType gst_clapper_color_balance_type_get_type (void);
|
||||
#define GST_TYPE_CLAPPER_COLOR_BALANCE_TYPE (gst_clapper_color_balance_type_get_type ())
|
||||
|
||||
/**
|
||||
* GstClapperColorBalanceType:
|
||||
* @GST_CLAPPER_COLOR_BALANCE_BRIGHTNESS: brightness or black level.
|
||||
* @GST_CLAPPER_COLOR_BALANCE_CONTRAST: contrast or luma gain.
|
||||
* @GST_CLAPPER_COLOR_BALANCE_SATURATION: color saturation or chroma
|
||||
* gain.
|
||||
* @GST_CLAPPER_COLOR_BALANCE_HUE: hue or color balance.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GST_CLAPPER_COLOR_BALANCE_BRIGHTNESS,
|
||||
GST_CLAPPER_COLOR_BALANCE_CONTRAST,
|
||||
GST_CLAPPER_COLOR_BALANCE_SATURATION,
|
||||
GST_CLAPPER_COLOR_BALANCE_HUE,
|
||||
} GstClapperColorBalanceType;
|
||||
|
||||
GST_CLAPPER_API
|
||||
const gchar * gst_clapper_color_balance_type_get_name (GstClapperColorBalanceType type);
|
||||
|
||||
/* ClapperSnapshotFormat */
|
||||
|
||||
/**
|
||||
* GstClapperSnapshotFormat:
|
||||
* @GST_CLAPPER_THUMBNAIL_RAW_NATIVE: RAW Native.
|
||||
* @GST_CLAPPER_THUMBNAIL_RAW_xRGB: RAW xRGB.
|
||||
* @GST_CLAPPER_THUMBNAIL_RAW_BGRx: RAW BGRx.
|
||||
* @GST_CLAPPER_THUMBNAIL_JPG: JPG.
|
||||
* @GST_CLAPPER_THUMBNAIL_PNG: PNG.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GST_CLAPPER_THUMBNAIL_RAW_NATIVE = 0,
|
||||
GST_CLAPPER_THUMBNAIL_RAW_xRGB,
|
||||
GST_CLAPPER_THUMBNAIL_RAW_BGRx,
|
||||
GST_CLAPPER_THUMBNAIL_JPG,
|
||||
GST_CLAPPER_THUMBNAIL_PNG
|
||||
} GstClapperSnapshotFormat;
|
||||
|
||||
#define GST_TYPE_CLAPPER (gst_clapper_get_type ())
|
||||
#define GST_IS_CLAPPER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_CLAPPER))
|
||||
#define GST_IS_CLAPPER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_CLAPPER))
|
||||
#define GST_CLAPPER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_CLAPPER, GstClapperClass))
|
||||
#define GST_CLAPPER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_CLAPPER, GstClapper))
|
||||
#define GST_CLAPPER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_CLAPPER, GstClapperClass))
|
||||
#define GST_CLAPPER_CAST(obj) ((GstClapper*)(obj))
|
||||
|
||||
#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstClapper, gst_object_unref)
|
||||
#endif
|
||||
|
||||
GST_CLAPPER_API
|
||||
GType gst_clapper_get_type (void);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GstClapper * gst_clapper_new (GstClapperVideoRenderer *video_renderer, GstClapperSignalDispatcher *signal_dispatcher,
|
||||
GstClapperMpris *mpris);
|
||||
|
||||
GST_CLAPPER_API
|
||||
void gst_clapper_play (GstClapper *clapper);
|
||||
|
||||
GST_CLAPPER_API
|
||||
void gst_clapper_pause (GstClapper *clapper);
|
||||
|
||||
GST_CLAPPER_API
|
||||
void gst_clapper_toggle_play (GstClapper *clapper);
|
||||
|
||||
GST_CLAPPER_API
|
||||
void gst_clapper_stop (GstClapper *clapper);
|
||||
|
||||
GST_CLAPPER_API
|
||||
void gst_clapper_seek (GstClapper *clapper, GstClockTime position);
|
||||
|
||||
GST_CLAPPER_API
|
||||
void gst_clapper_seek_offset (GstClapper *clapper, GstClockTime offset);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GstClapperState
|
||||
gst_clapper_get_state (GstClapper *clapper);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GstClapperSeekMode
|
||||
gst_clapper_get_seek_mode (GstClapper *clapper);
|
||||
|
||||
GST_CLAPPER_API
|
||||
void gst_clapper_set_seek_mode (GstClapper *clapper, GstClapperSeekMode mode);
|
||||
|
||||
GST_CLAPPER_API
|
||||
void gst_clapper_set_rate (GstClapper *clapper, gdouble rate);
|
||||
|
||||
GST_CLAPPER_API
|
||||
gdouble gst_clapper_get_rate (GstClapper *clapper);
|
||||
|
||||
GST_CLAPPER_API
|
||||
gchar * gst_clapper_get_uri (GstClapper *clapper);
|
||||
|
||||
GST_CLAPPER_API
|
||||
void gst_clapper_set_uri (GstClapper *clapper, const gchar *uri);
|
||||
|
||||
GST_CLAPPER_API
|
||||
gchar * gst_clapper_get_subtitle_uri (GstClapper *clapper);
|
||||
|
||||
GST_CLAPPER_API
|
||||
void gst_clapper_set_subtitle_uri (GstClapper *clapper, const gchar *uri);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GstClockTime gst_clapper_get_position (GstClapper *clapper);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GstClockTime gst_clapper_get_duration (GstClapper *clapper);
|
||||
|
||||
GST_CLAPPER_API
|
||||
gdouble gst_clapper_get_volume (GstClapper *clapper);
|
||||
|
||||
GST_CLAPPER_API
|
||||
void gst_clapper_set_volume (GstClapper *clapper, gdouble val);
|
||||
|
||||
GST_CLAPPER_API
|
||||
gboolean gst_clapper_get_mute (GstClapper *clapper);
|
||||
|
||||
GST_CLAPPER_API
|
||||
void gst_clapper_set_mute (GstClapper *clapper, gboolean val);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GstElement * gst_clapper_get_pipeline (GstClapper *clapper);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GstClapperMpris *
|
||||
gst_clapper_get_mpris (GstClapper *clapper);
|
||||
|
||||
GST_CLAPPER_API
|
||||
void gst_clapper_set_video_track_enabled (GstClapper *clapper, gboolean enabled);
|
||||
|
||||
GST_CLAPPER_API
|
||||
void gst_clapper_set_audio_track_enabled (GstClapper *clapper, gboolean enabled);
|
||||
|
||||
GST_CLAPPER_API
|
||||
void gst_clapper_set_subtitle_track_enabled (GstClapper *clapper, gboolean enabled);
|
||||
|
||||
GST_CLAPPER_API
|
||||
gboolean gst_clapper_set_audio_track (GstClapper *clapper, gint stream_index);
|
||||
|
||||
GST_CLAPPER_API
|
||||
gboolean gst_clapper_set_video_track (GstClapper *clapper, gint stream_index);
|
||||
|
||||
GST_CLAPPER_API
|
||||
gboolean gst_clapper_set_subtitle_track (GstClapper *clapper, gint stream_index);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GstClapperMediaInfo *
|
||||
gst_clapper_get_media_info (GstClapper *clapper);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GstClapperAudioInfo *
|
||||
gst_clapper_get_current_audio_track (GstClapper *clapper);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GstClapperVideoInfo *
|
||||
gst_clapper_get_current_video_track (GstClapper *clapper);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GstClapperSubtitleInfo *
|
||||
gst_clapper_get_current_subtitle_track (GstClapper *clapper);
|
||||
|
||||
GST_CLAPPER_API
|
||||
gboolean gst_clapper_set_visualization (GstClapper *clapper, const gchar *name);
|
||||
|
||||
GST_CLAPPER_API
|
||||
void gst_clapper_set_visualization_enabled (GstClapper *clapper, gboolean enabled);
|
||||
|
||||
GST_CLAPPER_API
|
||||
gchar * gst_clapper_get_current_visualization (GstClapper *clapper);
|
||||
|
||||
GST_CLAPPER_API
|
||||
gboolean gst_clapper_has_color_balance (GstClapper *clapper);
|
||||
|
||||
GST_CLAPPER_API
|
||||
void gst_clapper_set_color_balance (GstClapper *clapper, GstClapperColorBalanceType type, gdouble value);
|
||||
|
||||
GST_CLAPPER_API
|
||||
gdouble gst_clapper_get_color_balance (GstClapper *clapper, GstClapperColorBalanceType type);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GstVideoMultiviewFramePacking
|
||||
gst_clapper_get_multiview_mode (GstClapper *clapper);
|
||||
|
||||
GST_CLAPPER_API
|
||||
void gst_clapper_set_multiview_mode (GstClapper *clapper, GstVideoMultiviewFramePacking mode);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GstVideoMultiviewFlags
|
||||
gst_clapper_get_multiview_flags (GstClapper *clapper);
|
||||
|
||||
GST_CLAPPER_API
|
||||
void gst_clapper_set_multiview_flags (GstClapper *clapper, GstVideoMultiviewFlags flags);
|
||||
|
||||
GST_CLAPPER_API
|
||||
gint64 gst_clapper_get_audio_video_offset (GstClapper *clapper);
|
||||
|
||||
GST_CLAPPER_API
|
||||
void gst_clapper_set_audio_video_offset (GstClapper *clapper, gint64 offset);
|
||||
|
||||
GST_CLAPPER_API
|
||||
gint64 gst_clapper_get_subtitle_video_offset (GstClapper *clapper);
|
||||
|
||||
GST_CLAPPER_API
|
||||
void gst_clapper_set_subtitle_video_offset (GstClapper *clapper, gint64 offset);
|
||||
|
||||
GST_CLAPPER_API
|
||||
GstSample * gst_clapper_get_video_snapshot (GstClapper *clapper, GstClapperSnapshotFormat format, const GstStructure *config);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_CLAPPER_H__ */
|
@@ -1,732 +0,0 @@
|
||||
/*
|
||||
* GStreamer
|
||||
* Copyright (C) 2015 Matthew Waters <matthew@centricular.com>
|
||||
* Copyright (C) 2020 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:gstclapperglsink
|
||||
* @title: GstClapperGLSink
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <gst/gl/gstglfuncs.h>
|
||||
|
||||
#include "gstclapperglsink.h"
|
||||
#include "gstgtkutils.h"
|
||||
|
||||
GST_DEBUG_CATEGORY (gst_debug_clapper_gl_sink);
|
||||
#define GST_CAT_DEFAULT gst_debug_clapper_gl_sink
|
||||
|
||||
#define DEFAULT_FORCE_ASPECT_RATIO TRUE
|
||||
#define DEFAULT_PAR_N 0
|
||||
#define DEFAULT_PAR_D 1
|
||||
|
||||
static GstStaticPadTemplate gst_clapper_gl_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
|
||||
(GST_CAPS_FEATURE_MEMORY_GL_MEMORY, "RGBA") "; "
|
||||
GST_VIDEO_CAPS_MAKE_WITH_FEATURES
|
||||
(GST_CAPS_FEATURE_MEMORY_GL_MEMORY ", "
|
||||
GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, "RGBA")));
|
||||
|
||||
static void gst_clapper_gl_sink_finalize (GObject * object);
|
||||
static void gst_clapper_gl_sink_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * param_spec);
|
||||
static void gst_clapper_gl_sink_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * param_spec);
|
||||
|
||||
static gboolean gst_clapper_gl_sink_propose_allocation (GstBaseSink * bsink,
|
||||
GstQuery * query);
|
||||
static gboolean gst_clapper_gl_sink_query (GstBaseSink * bsink, GstQuery * query);
|
||||
static gboolean gst_clapper_gl_sink_start (GstBaseSink * bsink);
|
||||
static gboolean gst_clapper_gl_sink_stop (GstBaseSink * bsink);
|
||||
|
||||
static GstStateChangeReturn
|
||||
gst_clapper_gl_sink_change_state (GstElement * element,
|
||||
GstStateChange transition);
|
||||
|
||||
static void gst_clapper_gl_sink_get_times (GstBaseSink * bsink, GstBuffer * buf,
|
||||
GstClockTime * start, GstClockTime * end);
|
||||
static GstCaps *gst_clapper_gl_sink_get_caps (GstBaseSink * bsink,
|
||||
GstCaps * filter);
|
||||
static gboolean gst_clapper_gl_sink_set_caps (GstBaseSink * bsink,
|
||||
GstCaps * caps);
|
||||
static GstFlowReturn gst_clapper_gl_sink_show_frame (GstVideoSink * bsink,
|
||||
GstBuffer * buf);
|
||||
|
||||
static void
|
||||
gst_clapper_gl_sink_navigation_interface_init (GstNavigationInterface * iface);
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_WIDGET,
|
||||
PROP_FORCE_ASPECT_RATIO,
|
||||
PROP_PIXEL_ASPECT_RATIO,
|
||||
};
|
||||
|
||||
#define gst_clapper_gl_sink_parent_class parent_class
|
||||
G_DEFINE_TYPE_WITH_CODE (GstClapperGLSink, gst_clapper_gl_sink,
|
||||
GST_TYPE_VIDEO_SINK,
|
||||
G_IMPLEMENT_INTERFACE (GST_TYPE_NAVIGATION,
|
||||
gst_clapper_gl_sink_navigation_interface_init);
|
||||
GST_DEBUG_CATEGORY_INIT (gst_debug_clapper_gl_sink,
|
||||
"clapperglsink", 0, "Clapper GL Sink"));
|
||||
|
||||
static void
|
||||
gst_clapper_gl_sink_class_init (GstClapperGLSinkClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
GstBaseSinkClass *gstbasesink_class;
|
||||
GstVideoSinkClass *gstvideosink_class;
|
||||
GstClapperGLSinkClass *gstclapperglsink_class;
|
||||
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
gstbasesink_class = (GstBaseSinkClass *) klass;
|
||||
gstvideosink_class = (GstVideoSinkClass *) klass;
|
||||
gstclapperglsink_class = (GstClapperGLSinkClass *) klass;
|
||||
|
||||
gobject_class->set_property = gst_clapper_gl_sink_set_property;
|
||||
gobject_class->get_property = gst_clapper_gl_sink_get_property;
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_WIDGET,
|
||||
g_param_spec_object ("widget", "GTK Widget",
|
||||
"The GtkWidget to place in the widget hierarchy "
|
||||
"(must only be get from the GTK main thread)",
|
||||
GTK_TYPE_WIDGET, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_FORCE_ASPECT_RATIO,
|
||||
g_param_spec_boolean ("force-aspect-ratio",
|
||||
"Force aspect ratio",
|
||||
"When enabled, scaling will respect original aspect ratio",
|
||||
DEFAULT_FORCE_ASPECT_RATIO,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_PIXEL_ASPECT_RATIO,
|
||||
gst_param_spec_fraction ("pixel-aspect-ratio", "Pixel Aspect Ratio",
|
||||
"The pixel aspect ratio of the device", DEFAULT_PAR_N, DEFAULT_PAR_D,
|
||||
G_MAXINT, 1, 1, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
gobject_class->finalize = gst_clapper_gl_sink_finalize;
|
||||
|
||||
gstelement_class->change_state = gst_clapper_gl_sink_change_state;
|
||||
|
||||
gstbasesink_class->get_caps = gst_clapper_gl_sink_get_caps;
|
||||
gstbasesink_class->set_caps = gst_clapper_gl_sink_set_caps;
|
||||
gstbasesink_class->get_times = gst_clapper_gl_sink_get_times;
|
||||
gstbasesink_class->propose_allocation = gst_clapper_gl_sink_propose_allocation;
|
||||
gstbasesink_class->query = gst_clapper_gl_sink_query;
|
||||
gstbasesink_class->start = gst_clapper_gl_sink_start;
|
||||
gstbasesink_class->stop = gst_clapper_gl_sink_stop;
|
||||
|
||||
gstvideosink_class->show_frame = gst_clapper_gl_sink_show_frame;
|
||||
|
||||
gstclapperglsink_class->create_widget = gtk_clapper_gl_widget_new;
|
||||
gstclapperglsink_class->window_title = "GTK4 GL Renderer";
|
||||
|
||||
gst_element_class_set_metadata (gstelement_class,
|
||||
"GTK4 GL Video Sink",
|
||||
"Sink/Video", "A video sink that renders to a GtkWidget using OpenGL",
|
||||
"Matthew Waters <matthew@centricular.com>, "
|
||||
"Rafał Dzięgiel <rafostar.github@gmail.com>");
|
||||
|
||||
gst_element_class_add_static_pad_template (gstelement_class,
|
||||
&gst_clapper_gl_sink_template);
|
||||
|
||||
gst_type_mark_as_plugin_api (GST_TYPE_CLAPPER_GL_SINK, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gl_sink_init (GstClapperGLSink * clapper_sink)
|
||||
{
|
||||
clapper_sink->force_aspect_ratio = DEFAULT_FORCE_ASPECT_RATIO;
|
||||
clapper_sink->par_n = DEFAULT_PAR_N;
|
||||
clapper_sink->par_d = DEFAULT_PAR_D;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gl_sink_finalize (GObject * object)
|
||||
{
|
||||
GstClapperGLSink *clapper_sink = GST_CLAPPER_GL_SINK (object);
|
||||
|
||||
GST_DEBUG ("Finalizing Clapper GL sink");
|
||||
|
||||
GST_OBJECT_LOCK (clapper_sink);
|
||||
if (clapper_sink->window && clapper_sink->window_destroy_id)
|
||||
g_signal_handler_disconnect (clapper_sink->window, clapper_sink->window_destroy_id);
|
||||
if (clapper_sink->widget && clapper_sink->widget_destroy_id)
|
||||
g_signal_handler_disconnect (clapper_sink->widget, clapper_sink->widget_destroy_id);
|
||||
|
||||
g_clear_object (&clapper_sink->widget);
|
||||
GST_OBJECT_UNLOCK (clapper_sink);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
widget_destroy_cb (GtkWidget * widget, GstClapperGLSink * clapper_sink)
|
||||
{
|
||||
GST_OBJECT_LOCK (clapper_sink);
|
||||
g_clear_object (&clapper_sink->widget);
|
||||
GST_OBJECT_UNLOCK (clapper_sink);
|
||||
}
|
||||
|
||||
static void
|
||||
window_destroy_cb (GtkWidget * widget, GstClapperGLSink * clapper_sink)
|
||||
{
|
||||
GST_OBJECT_LOCK (clapper_sink);
|
||||
if (clapper_sink->widget) {
|
||||
if (clapper_sink->widget_destroy_id) {
|
||||
g_signal_handler_disconnect (clapper_sink->widget,
|
||||
clapper_sink->widget_destroy_id);
|
||||
clapper_sink->widget_destroy_id = 0;
|
||||
}
|
||||
g_clear_object (&clapper_sink->widget);
|
||||
}
|
||||
clapper_sink->window = NULL;
|
||||
GST_OBJECT_UNLOCK (clapper_sink);
|
||||
}
|
||||
|
||||
static GtkClapperGLWidget *
|
||||
gst_clapper_gl_sink_get_widget (GstClapperGLSink * clapper_sink)
|
||||
{
|
||||
if (clapper_sink->widget != NULL)
|
||||
return clapper_sink->widget;
|
||||
|
||||
/* Ensure GTK is initialized, this has no side effect if it was already
|
||||
* initialized. Also, we do that lazily, so the application can be first */
|
||||
if (!gtk_init_check ()) {
|
||||
GST_ERROR_OBJECT (clapper_sink, "Could not ensure GTK initialization.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_assert (GST_CLAPPER_GL_SINK_GET_CLASS (clapper_sink)->create_widget);
|
||||
clapper_sink->widget = (GtkClapperGLWidget *)
|
||||
GST_CLAPPER_GL_SINK_GET_CLASS (clapper_sink)->create_widget ();
|
||||
|
||||
clapper_sink->bind_aspect_ratio =
|
||||
g_object_bind_property (clapper_sink, "force-aspect-ratio", clapper_sink->widget,
|
||||
"force-aspect-ratio", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
|
||||
clapper_sink->bind_pixel_aspect_ratio =
|
||||
g_object_bind_property (clapper_sink, "pixel-aspect-ratio", clapper_sink->widget,
|
||||
"pixel-aspect-ratio", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
|
||||
|
||||
/* Take the floating ref, other wise the destruction of the container will
|
||||
* make this widget disappear possibly before we are done. */
|
||||
gst_object_ref_sink (clapper_sink->widget);
|
||||
|
||||
clapper_sink->widget_destroy_id = g_signal_connect (clapper_sink->widget, "destroy",
|
||||
G_CALLBACK (widget_destroy_cb), clapper_sink);
|
||||
|
||||
/* back pointer */
|
||||
gtk_clapper_gl_widget_set_element (GTK_CLAPPER_GL_WIDGET (clapper_sink->widget),
|
||||
GST_ELEMENT (clapper_sink));
|
||||
|
||||
return clapper_sink->widget;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gl_sink_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstClapperGLSink *clapper_sink = GST_CLAPPER_GL_SINK (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_WIDGET:
|
||||
{
|
||||
GObject *widget = NULL;
|
||||
|
||||
GST_OBJECT_LOCK (clapper_sink);
|
||||
if (clapper_sink->widget != NULL)
|
||||
widget = G_OBJECT (clapper_sink->widget);
|
||||
GST_OBJECT_UNLOCK (clapper_sink);
|
||||
|
||||
if (!widget)
|
||||
widget =
|
||||
gst_gtk_invoke_on_main ((GThreadFunc) gst_clapper_gl_sink_get_widget,
|
||||
clapper_sink);
|
||||
|
||||
g_value_set_object (value, widget);
|
||||
break;
|
||||
}
|
||||
case PROP_FORCE_ASPECT_RATIO:
|
||||
g_value_set_boolean (value, clapper_sink->force_aspect_ratio);
|
||||
break;
|
||||
case PROP_PIXEL_ASPECT_RATIO:
|
||||
gst_value_set_fraction (value, clapper_sink->par_n, clapper_sink->par_d);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gl_sink_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstClapperGLSink *clapper_sink = GST_CLAPPER_GL_SINK (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_FORCE_ASPECT_RATIO:
|
||||
clapper_sink->force_aspect_ratio = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_PIXEL_ASPECT_RATIO:
|
||||
clapper_sink->par_n = gst_value_get_fraction_numerator (value);
|
||||
clapper_sink->par_d = gst_value_get_fraction_denominator (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gl_sink_navigation_send_event (GstNavigation * navigation,
|
||||
GstStructure * structure)
|
||||
{
|
||||
GstClapperGLSink *sink = GST_CLAPPER_GL_SINK (navigation);
|
||||
GstEvent *event;
|
||||
GstPad *pad;
|
||||
|
||||
event = gst_event_new_navigation (structure);
|
||||
pad = gst_pad_get_peer (GST_VIDEO_SINK_PAD (sink));
|
||||
|
||||
GST_TRACE_OBJECT (sink, "navigation event %" GST_PTR_FORMAT, structure);
|
||||
|
||||
if (GST_IS_PAD (pad) && GST_IS_EVENT (event)) {
|
||||
if (!gst_pad_send_event (pad, gst_event_ref (event))) {
|
||||
/* If upstream didn't handle the event we'll post a message with it
|
||||
* for the application in case it wants to do something with it */
|
||||
gst_element_post_message (GST_ELEMENT_CAST (sink),
|
||||
gst_navigation_message_new_event (GST_OBJECT_CAST (sink), event));
|
||||
}
|
||||
gst_event_unref (event);
|
||||
gst_object_unref (pad);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gl_sink_navigation_interface_init (GstNavigationInterface * iface)
|
||||
{
|
||||
iface->send_event = gst_clapper_gl_sink_navigation_send_event;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_clapper_gl_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
|
||||
{
|
||||
GstClapperGLSink *clapper_sink = GST_CLAPPER_GL_SINK (bsink);
|
||||
GstBufferPool *pool = NULL;
|
||||
GstStructure *config;
|
||||
GstCaps *caps;
|
||||
GstVideoInfo info;
|
||||
guint size;
|
||||
gboolean need_pool;
|
||||
GstStructure *allocation_meta = NULL;
|
||||
gint display_width, display_height;
|
||||
|
||||
if (!clapper_sink->display || !clapper_sink->context)
|
||||
return FALSE;
|
||||
|
||||
gst_query_parse_allocation (query, &caps, &need_pool);
|
||||
|
||||
if (caps == NULL)
|
||||
goto no_caps;
|
||||
|
||||
if (!gst_video_info_from_caps (&info, caps))
|
||||
goto invalid_caps;
|
||||
|
||||
/* the normal size of a frame */
|
||||
size = info.size;
|
||||
|
||||
if (need_pool) {
|
||||
GST_DEBUG_OBJECT (clapper_sink, "create new pool");
|
||||
pool = gst_gl_buffer_pool_new (clapper_sink->context);
|
||||
|
||||
config = gst_buffer_pool_get_config (pool);
|
||||
gst_buffer_pool_config_set_params (config, caps, size, 0, 0);
|
||||
gst_buffer_pool_config_add_option (config,
|
||||
GST_BUFFER_POOL_OPTION_GL_SYNC_META);
|
||||
|
||||
if (!gst_buffer_pool_set_config (pool, config))
|
||||
goto config_failed;
|
||||
}
|
||||
|
||||
/* we need at least 2 buffer because we hold on to the last one */
|
||||
gst_query_add_allocation_pool (query, pool, size, 2, 0);
|
||||
if (pool)
|
||||
gst_object_unref (pool);
|
||||
|
||||
GST_OBJECT_LOCK (clapper_sink);
|
||||
display_width = clapper_sink->display_width;
|
||||
display_height = clapper_sink->display_height;
|
||||
GST_OBJECT_UNLOCK (clapper_sink);
|
||||
|
||||
if (display_width != 0 && display_height != 0) {
|
||||
GST_DEBUG_OBJECT (clapper_sink, "sending alloc query with size %dx%d",
|
||||
display_width, display_height);
|
||||
allocation_meta = gst_structure_new ("GstVideoOverlayCompositionMeta",
|
||||
"width", G_TYPE_UINT, display_width,
|
||||
"height", G_TYPE_UINT, display_height, NULL);
|
||||
}
|
||||
|
||||
gst_query_add_allocation_meta (query,
|
||||
GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, allocation_meta);
|
||||
|
||||
if (allocation_meta)
|
||||
gst_structure_free (allocation_meta);
|
||||
|
||||
/* we also support various metadata */
|
||||
gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, 0);
|
||||
|
||||
if (clapper_sink->context->gl_vtable->FenceSync)
|
||||
gst_query_add_allocation_meta (query, GST_GL_SYNC_META_API_TYPE, 0);
|
||||
|
||||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
no_caps:
|
||||
{
|
||||
GST_DEBUG_OBJECT (bsink, "no caps specified");
|
||||
return FALSE;
|
||||
}
|
||||
invalid_caps:
|
||||
{
|
||||
GST_DEBUG_OBJECT (bsink, "invalid caps specified");
|
||||
return FALSE;
|
||||
}
|
||||
config_failed:
|
||||
{
|
||||
GST_DEBUG_OBJECT (bsink, "failed setting config");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_clapper_gl_sink_query (GstBaseSink * bsink, GstQuery * query)
|
||||
{
|
||||
GstClapperGLSink *clapper_sink = GST_CLAPPER_GL_SINK (bsink);
|
||||
gboolean res = FALSE;
|
||||
|
||||
switch (GST_QUERY_TYPE (query)) {
|
||||
case GST_QUERY_CONTEXT:
|
||||
{
|
||||
if (gst_gl_handle_context_query ((GstElement *) clapper_sink, query,
|
||||
clapper_sink->display, clapper_sink->context, clapper_sink->gtk_context))
|
||||
return TRUE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
res = GST_BASE_SINK_CLASS (parent_class)->query (bsink, query);
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_clapper_gl_sink_start_on_main (GstBaseSink * bsink)
|
||||
{
|
||||
GstClapperGLSink *gst_sink = GST_CLAPPER_GL_SINK (bsink);
|
||||
GstClapperGLSinkClass *klass = GST_CLAPPER_GL_SINK_GET_CLASS (bsink);
|
||||
GtkWidget *toplevel;
|
||||
GtkRoot *root;
|
||||
|
||||
if (gst_clapper_gl_sink_get_widget (gst_sink) == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* After this point, clapper_sink->widget will always be set */
|
||||
|
||||
root = gtk_widget_get_root (GTK_WIDGET (gst_sink->widget));
|
||||
if (!GTK_IS_ROOT (root)) {
|
||||
GtkWidget *parent = gtk_widget_get_parent (GTK_WIDGET (gst_sink->widget));
|
||||
if (parent) {
|
||||
GtkWidget *temp_parent;
|
||||
while ((temp_parent = gtk_widget_get_parent (parent)))
|
||||
parent = temp_parent;
|
||||
}
|
||||
toplevel = (parent) ? parent : GTK_WIDGET (gst_sink->widget);
|
||||
|
||||
/* sanity check */
|
||||
g_assert (klass->window_title);
|
||||
|
||||
/* User did not add widget its own UI, let's popup a new GtkWindow to
|
||||
* make gst-launch-1.0 work. */
|
||||
gst_sink->window = gtk_window_new ();
|
||||
gtk_window_set_default_size (GTK_WINDOW (gst_sink->window), 640, 480);
|
||||
gtk_window_set_title (GTK_WINDOW (gst_sink->window), klass->window_title);
|
||||
gtk_window_set_child (GTK_WINDOW (gst_sink->window), toplevel);
|
||||
|
||||
gst_sink->window_destroy_id = g_signal_connect (
|
||||
GTK_WINDOW (gst_sink->window),
|
||||
"destroy", G_CALLBACK (window_destroy_cb), gst_sink);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_clapper_gl_sink_start (GstBaseSink * bsink)
|
||||
{
|
||||
GstClapperGLSink *clapper_sink = GST_CLAPPER_GL_SINK (bsink);
|
||||
GtkClapperGLWidget *clapper_widget;
|
||||
|
||||
if (!(! !gst_gtk_invoke_on_main ((GThreadFunc) (GCallback)
|
||||
gst_clapper_gl_sink_start_on_main, bsink)))
|
||||
return FALSE;
|
||||
|
||||
/* After this point, clapper_sink->widget will always be set */
|
||||
clapper_widget = GTK_CLAPPER_GL_WIDGET (clapper_sink->widget);
|
||||
|
||||
if (!gtk_clapper_gl_widget_init_winsys (clapper_widget)) {
|
||||
GST_ELEMENT_ERROR (bsink, RESOURCE, NOT_FOUND, ("%s",
|
||||
"Failed to initialize OpenGL with GTK"), (NULL));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!clapper_sink->display)
|
||||
clapper_sink->display = gtk_clapper_gl_widget_get_display (clapper_widget);
|
||||
if (!clapper_sink->context)
|
||||
clapper_sink->context = gtk_clapper_gl_widget_get_context (clapper_widget);
|
||||
if (!clapper_sink->gtk_context)
|
||||
clapper_sink->gtk_context = gtk_clapper_gl_widget_get_gtk_context (clapper_widget);
|
||||
|
||||
if (!clapper_sink->display || !clapper_sink->context || !clapper_sink->gtk_context) {
|
||||
GST_ELEMENT_ERROR (bsink, RESOURCE, NOT_FOUND, ("%s",
|
||||
"Failed to retrieve OpenGL context from GTK"), (NULL));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gst_gl_element_propagate_display_context (GST_ELEMENT (bsink),
|
||||
clapper_sink->display);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_clapper_gl_sink_stop_on_main (GstBaseSink * bsink)
|
||||
{
|
||||
GstClapperGLSink *gst_sink = GST_CLAPPER_GL_SINK (bsink);
|
||||
|
||||
if (gst_sink->window) {
|
||||
gtk_window_destroy (GTK_WINDOW (gst_sink->window));
|
||||
gst_sink->window = NULL;
|
||||
gst_sink->widget = NULL;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_clapper_gl_sink_stop (GstBaseSink * bsink)
|
||||
{
|
||||
GstClapperGLSink *clapper_sink = GST_CLAPPER_GL_SINK (bsink);
|
||||
|
||||
if (clapper_sink->display) {
|
||||
gst_object_unref (clapper_sink->display);
|
||||
clapper_sink->display = NULL;
|
||||
}
|
||||
if (clapper_sink->context) {
|
||||
gst_object_unref (clapper_sink->context);
|
||||
clapper_sink->context = NULL;
|
||||
}
|
||||
if (clapper_sink->gtk_context) {
|
||||
gst_object_unref (clapper_sink->gtk_context);
|
||||
clapper_sink->gtk_context = NULL;
|
||||
}
|
||||
if (clapper_sink->window)
|
||||
return ! !gst_gtk_invoke_on_main ((GThreadFunc) (GCallback)
|
||||
gst_clapper_gl_sink_stop_on_main, bsink);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gtk_window_show_all_and_unref (GtkWidget * window)
|
||||
{
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
g_object_unref (window);
|
||||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
gst_clapper_gl_sink_change_state (GstElement * element, GstStateChange transition)
|
||||
{
|
||||
GstClapperGLSink *clapper_sink = GST_CLAPPER_GL_SINK (element);
|
||||
GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
|
||||
|
||||
GST_DEBUG_OBJECT (element, "changing state: %s => %s",
|
||||
gst_element_state_get_name (GST_STATE_TRANSITION_CURRENT (transition)),
|
||||
gst_element_state_get_name (GST_STATE_TRANSITION_NEXT (transition)));
|
||||
|
||||
ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
||||
if (ret == GST_STATE_CHANGE_FAILURE)
|
||||
return ret;
|
||||
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||
GST_OBJECT_LOCK (clapper_sink);
|
||||
if (clapper_sink->widget) {
|
||||
GTK_CLAPPER_GL_WIDGET_LOCK (clapper_sink->widget);
|
||||
clapper_sink->widget->ignore_buffers = FALSE;
|
||||
GTK_CLAPPER_GL_WIDGET_UNLOCK (clapper_sink->widget);
|
||||
}
|
||||
GST_OBJECT_UNLOCK (clapper_sink);
|
||||
break;
|
||||
case GST_STATE_CHANGE_READY_TO_PAUSED:{
|
||||
GtkWindow *window = NULL;
|
||||
|
||||
GST_OBJECT_LOCK (clapper_sink);
|
||||
if (clapper_sink->window)
|
||||
window = g_object_ref (GTK_WINDOW (clapper_sink->window));
|
||||
GST_OBJECT_UNLOCK (clapper_sink);
|
||||
|
||||
if (window) {
|
||||
gst_gtk_invoke_on_main ((GThreadFunc) (GCallback)
|
||||
gst_gtk_window_show_all_and_unref, window);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GST_STATE_CHANGE_READY_TO_NULL:
|
||||
GST_OBJECT_LOCK (clapper_sink);
|
||||
if (clapper_sink->widget) {
|
||||
GTK_CLAPPER_GL_WIDGET_LOCK (clapper_sink->widget);
|
||||
clapper_sink->widget->ignore_buffers = TRUE;
|
||||
GTK_CLAPPER_GL_WIDGET_UNLOCK (clapper_sink->widget);
|
||||
}
|
||||
GST_OBJECT_UNLOCK (clapper_sink);
|
||||
/* Fall through to render black bg */
|
||||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||
GST_OBJECT_LOCK (clapper_sink);
|
||||
if (clapper_sink->widget)
|
||||
gtk_clapper_gl_widget_set_buffer (clapper_sink->widget, NULL);
|
||||
GST_OBJECT_UNLOCK (clapper_sink);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gl_sink_get_times (GstBaseSink * bsink, GstBuffer * buf,
|
||||
GstClockTime * start, GstClockTime * end)
|
||||
{
|
||||
GstClapperGLSink *clapper_sink = GST_CLAPPER_GL_SINK (bsink);
|
||||
|
||||
if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
|
||||
*start = GST_BUFFER_TIMESTAMP (buf);
|
||||
if (GST_BUFFER_DURATION_IS_VALID (buf))
|
||||
*end = *start + GST_BUFFER_DURATION (buf);
|
||||
else {
|
||||
if (GST_VIDEO_INFO_FPS_N (&clapper_sink->v_info) > 0) {
|
||||
*end = *start +
|
||||
gst_util_uint64_scale_int (GST_SECOND,
|
||||
GST_VIDEO_INFO_FPS_D (&clapper_sink->v_info),
|
||||
GST_VIDEO_INFO_FPS_N (&clapper_sink->v_info));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_clapper_gl_sink_get_caps (GstBaseSink * bsink, GstCaps * filter)
|
||||
{
|
||||
GstCaps *tmp = NULL;
|
||||
GstCaps *result = NULL;
|
||||
|
||||
tmp = gst_pad_get_pad_template_caps (GST_BASE_SINK_PAD (bsink));
|
||||
|
||||
if (filter) {
|
||||
GST_DEBUG_OBJECT (bsink, "intersecting with filter caps %" GST_PTR_FORMAT,
|
||||
filter);
|
||||
|
||||
result = gst_caps_intersect_full (filter, tmp, GST_CAPS_INTERSECT_FIRST);
|
||||
gst_caps_unref (tmp);
|
||||
} else {
|
||||
result = tmp;
|
||||
}
|
||||
|
||||
result = gst_gl_overlay_compositor_add_caps (result);
|
||||
|
||||
GST_DEBUG_OBJECT (bsink, "returning caps: %" GST_PTR_FORMAT, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_clapper_gl_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
|
||||
{
|
||||
GstClapperGLSink *clapper_sink = GST_CLAPPER_GL_SINK (bsink);
|
||||
|
||||
GST_DEBUG ("set caps with %" GST_PTR_FORMAT, caps);
|
||||
|
||||
if (!gst_video_info_from_caps (&clapper_sink->v_info, caps))
|
||||
return FALSE;
|
||||
|
||||
GST_OBJECT_LOCK (clapper_sink);
|
||||
|
||||
if (clapper_sink->widget == NULL) {
|
||||
GST_OBJECT_UNLOCK (clapper_sink);
|
||||
GST_ELEMENT_ERROR (clapper_sink, RESOURCE, NOT_FOUND,
|
||||
("%s", "Output widget was destroyed"), (NULL));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gtk_clapper_gl_widget_set_format (clapper_sink->widget, &clapper_sink->v_info)) {
|
||||
GST_OBJECT_UNLOCK (clapper_sink);
|
||||
return FALSE;
|
||||
}
|
||||
GST_OBJECT_UNLOCK (clapper_sink);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_clapper_gl_sink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
|
||||
{
|
||||
GstClapperGLSink *clapper_sink;
|
||||
|
||||
GST_TRACE ("rendering buffer:%p", buf);
|
||||
|
||||
clapper_sink = GST_CLAPPER_GL_SINK (vsink);
|
||||
|
||||
GST_OBJECT_LOCK (clapper_sink);
|
||||
|
||||
if (clapper_sink->widget == NULL) {
|
||||
GST_OBJECT_UNLOCK (clapper_sink);
|
||||
GST_ELEMENT_ERROR (clapper_sink, RESOURCE, NOT_FOUND,
|
||||
("%s", "Output widget was destroyed"), (NULL));
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
gtk_clapper_gl_widget_set_buffer (clapper_sink->widget, buf);
|
||||
|
||||
GST_OBJECT_UNLOCK (clapper_sink);
|
||||
|
||||
return GST_FLOW_OK;
|
||||
}
|
@@ -1,106 +0,0 @@
|
||||
/*
|
||||
* GStreamer
|
||||
* Copyright (C) 2015 Matthew Waters <matthew@centricular.com>
|
||||
* Copyright (C) 2020 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_CLAPPER_GL_SINK_H__
|
||||
#define __GST_CLAPPER_GL_SINK_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gst/gst.h>
|
||||
#include <gst/video/gstvideosink.h>
|
||||
#include <gst/video/video.h>
|
||||
#include <gst/gl/gl.h>
|
||||
|
||||
#include "gtkclapperglwidget.h"
|
||||
|
||||
#define GST_TYPE_CLAPPER_GL_SINK (gst_clapper_gl_sink_get_type())
|
||||
#define GST_CLAPPER_GL_SINK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CLAPPER_GL_SINK,GstClapperGLSink))
|
||||
#define GST_CLAPPER_GL_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_CLAPPER_GL_SINK,GstClapperGLClass))
|
||||
#define GST_CLAPPER_GL_SINK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_CLAPPER_GL_SINK, GstClapperGLSinkClass))
|
||||
#define GST_IS_CLAPPER_GL_SINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_CLAPPER_GL_SINK))
|
||||
#define GST_IS_CLAPPER_GL_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CLAPPER_GL_SINK))
|
||||
#define GST_CLAPPER_GL_SINK_CAST(obj) ((GstClapperGLSink*)(obj))
|
||||
|
||||
G_BEGIN_DECLS
|
||||
typedef struct _GstClapperGLSink GstClapperGLSink;
|
||||
typedef struct _GstClapperGLSinkClass GstClapperGLSinkClass;
|
||||
|
||||
GType gst_clapper_gl_sink_get_type (void);
|
||||
|
||||
/**
|
||||
* GstClapperGLSink:
|
||||
*
|
||||
* Opaque #GstClapperGLSink object
|
||||
*/
|
||||
struct _GstClapperGLSink
|
||||
{
|
||||
/* <private> */
|
||||
GstVideoSink parent;
|
||||
|
||||
GstVideoInfo v_info;
|
||||
|
||||
GtkClapperGLWidget *widget;
|
||||
|
||||
/* properties */
|
||||
gboolean force_aspect_ratio;
|
||||
GBinding *bind_aspect_ratio;
|
||||
|
||||
gint par_n, par_d;
|
||||
GBinding *bind_pixel_aspect_ratio;
|
||||
|
||||
gboolean ignore_textures;
|
||||
GBinding *bind_ignore_textures;
|
||||
|
||||
GtkWidget *window;
|
||||
gulong widget_destroy_id;
|
||||
gulong window_destroy_id;
|
||||
|
||||
GstGLDisplay *display;
|
||||
GstGLContext *context;
|
||||
GstGLContext *gtk_context;
|
||||
|
||||
GstGLUpload *upload;
|
||||
GstBuffer *uploaded_buffer;
|
||||
|
||||
/* read/write with object lock */
|
||||
gint display_width, display_height;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstClapperGLSinkClass:
|
||||
*
|
||||
* The #GstClapperGLSinkClass struct only contains private data
|
||||
*/
|
||||
struct _GstClapperGLSinkClass
|
||||
{
|
||||
GstVideoSinkClass object_class;
|
||||
|
||||
/* metadata */
|
||||
const gchar *window_title;
|
||||
|
||||
/* virtuals */
|
||||
GtkWidget* (*create_widget) (void);
|
||||
};
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GstClapperGLSink, gst_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_CLAPPER_GL_SINK_H__ */
|
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* GStreamer
|
||||
* Copyright (C) 2015 Matthew Waters <matthew@centricular.com>
|
||||
* Copyright (C) 2015 Thibault Saunier <tsaunier@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "gstgtkutils.h"
|
||||
|
||||
struct invoke_context
|
||||
{
|
||||
GThreadFunc func;
|
||||
gpointer data;
|
||||
GMutex lock;
|
||||
GCond cond;
|
||||
gboolean fired;
|
||||
|
||||
gpointer res;
|
||||
};
|
||||
|
||||
static gboolean
|
||||
gst_gtk_invoke_func (struct invoke_context *info)
|
||||
{
|
||||
g_mutex_lock (&info->lock);
|
||||
info->res = info->func (info->data);
|
||||
info->fired = TRUE;
|
||||
g_cond_signal (&info->cond);
|
||||
g_mutex_unlock (&info->lock);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
gpointer
|
||||
gst_gtk_invoke_on_main (GThreadFunc func, gpointer data)
|
||||
{
|
||||
GMainContext *main_context = g_main_context_default ();
|
||||
struct invoke_context info;
|
||||
|
||||
g_mutex_init (&info.lock);
|
||||
g_cond_init (&info.cond);
|
||||
info.fired = FALSE;
|
||||
info.func = func;
|
||||
info.data = data;
|
||||
|
||||
g_main_context_invoke (main_context, (GSourceFunc) gst_gtk_invoke_func,
|
||||
&info);
|
||||
|
||||
g_mutex_lock (&info.lock);
|
||||
while (!info.fired)
|
||||
g_cond_wait (&info.cond, &info.lock);
|
||||
g_mutex_unlock (&info.lock);
|
||||
|
||||
g_mutex_clear (&info.lock);
|
||||
g_cond_clear (&info.cond);
|
||||
|
||||
return info.res;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -1,111 +0,0 @@
|
||||
/*
|
||||
* GStreamer
|
||||
* Copyright (C) 2015 Matthew Waters <matthew@centricular.com>
|
||||
* Copyright (C) 2020 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_CLAPPER_GL_WIDGET_H__
|
||||
#define __GTK_CLAPPER_GL_WIDGET_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gst/gst.h>
|
||||
#include <gst/video/video.h>
|
||||
#include <gst/gl/gl.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GType gtk_clapper_gl_widget_get_type (void);
|
||||
#define GTK_TYPE_CLAPPER_GL_WIDGET (gtk_clapper_gl_widget_get_type())
|
||||
#define GTK_CLAPPER_GL_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GTK_TYPE_CLAPPER_GL_WIDGET,GtkClapperGLWidget))
|
||||
#define GTK_CLAPPER_GL_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GTK_TYPE_CLAPPER_GL_WIDGET,GtkClapperGLWidgetClass))
|
||||
#define GTK_IS_CLAPPER_GL_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GTK_TYPE_CLAPPER_GL_WIDGET))
|
||||
#define GTK_IS_CLAPPER_GL_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GTK_TYPE_CLAPPER_GL_WIDGET))
|
||||
#define GTK_CLAPPER_GL_WIDGET_CAST(obj) ((GtkClapperGLWidget*)(obj))
|
||||
#define GTK_CLAPPER_GL_WIDGET_LOCK(w) g_mutex_lock(&((GtkClapperGLWidget*)(w))->lock)
|
||||
#define GTK_CLAPPER_GL_WIDGET_UNLOCK(w) g_mutex_unlock(&((GtkClapperGLWidget*)(w))->lock)
|
||||
|
||||
typedef struct _GtkClapperGLWidget GtkClapperGLWidget;
|
||||
typedef struct _GtkClapperGLWidgetClass GtkClapperGLWidgetClass;
|
||||
typedef struct _GtkClapperGLWidgetPrivate GtkClapperGLWidgetPrivate;
|
||||
|
||||
struct _GtkClapperGLWidget
|
||||
{
|
||||
/* <private> */
|
||||
GtkGLArea parent;
|
||||
GtkClapperGLWidgetPrivate *priv;
|
||||
|
||||
/* properties */
|
||||
gboolean force_aspect_ratio;
|
||||
gint par_n, par_d;
|
||||
|
||||
gint display_width;
|
||||
gint display_height;
|
||||
|
||||
/* Widget dimensions */
|
||||
gint scaled_width;
|
||||
gint scaled_height;
|
||||
|
||||
/* Position coords */
|
||||
gdouble last_pos_x;
|
||||
gdouble last_pos_y;
|
||||
|
||||
gboolean negotiated;
|
||||
gboolean ignore_buffers;
|
||||
GstBuffer *pending_buffer;
|
||||
GstBuffer *buffer;
|
||||
GstVideoInfo v_info;
|
||||
|
||||
/* resize */
|
||||
gboolean pending_resize;
|
||||
GstVideoInfo pending_v_info;
|
||||
guint display_ratio_num;
|
||||
guint display_ratio_den;
|
||||
|
||||
/*< private >*/
|
||||
GMutex lock;
|
||||
GWeakRef element;
|
||||
|
||||
/* event controllers */
|
||||
GtkEventController *key_controller;
|
||||
GtkEventController *motion_controller;
|
||||
GtkGesture *click_gesture;
|
||||
|
||||
/* Pending draw idles callback */
|
||||
guint draw_id;
|
||||
};
|
||||
|
||||
struct _GtkClapperGLWidgetClass
|
||||
{
|
||||
GtkGLAreaClass parent_class;
|
||||
};
|
||||
|
||||
/* API */
|
||||
gboolean gtk_clapper_gl_widget_set_format (GtkClapperGLWidget * widget, GstVideoInfo * v_info);
|
||||
void gtk_clapper_gl_widget_set_buffer (GtkClapperGLWidget * widget, GstBuffer * buffer);
|
||||
void gtk_clapper_gl_widget_set_element (GtkClapperGLWidget * widget, GstElement * element);
|
||||
|
||||
GtkWidget * gtk_clapper_gl_widget_new (void);
|
||||
|
||||
gboolean gtk_clapper_gl_widget_init_winsys (GtkClapperGLWidget * widget);
|
||||
GstGLDisplay * gtk_clapper_gl_widget_get_display (GtkClapperGLWidget * widget);
|
||||
GstGLContext * gtk_clapper_gl_widget_get_context (GtkClapperGLWidget * widget);
|
||||
GstGLContext * gtk_clapper_gl_widget_get_gtk_context (GtkClapperGLWidget * widget);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CLAPPER_GL_WIDGET_H__ */
|
@@ -1,107 +0,0 @@
|
||||
gnome = import('gnome')
|
||||
|
||||
gstclapper_sources = [
|
||||
'gstclapper.c',
|
||||
'gstclapper-signal-dispatcher.c',
|
||||
'gstclapper-video-renderer.c',
|
||||
'gstclapper-media-info.c',
|
||||
'gstclapper-g-main-context-signal-dispatcher.c',
|
||||
'gstclapper-video-overlay-video-renderer.c',
|
||||
'gstclapper-visualization.c',
|
||||
'gstclapper-mpris.c',
|
||||
'gstclapper-gtk4-plugin.c',
|
||||
|
||||
'gtk4/gstclapperglsink.c',
|
||||
'gtk4/gstgtkutils.c',
|
||||
'gtk4/gtkclapperglwidget.c',
|
||||
]
|
||||
gstclapper_headers = [
|
||||
'clapper.h',
|
||||
'clapper-prelude.h',
|
||||
'gstclapper.h',
|
||||
'gstclapper-types.h',
|
||||
'gstclapper-signal-dispatcher.h',
|
||||
'gstclapper-video-renderer.h',
|
||||
'gstclapper-media-info.h',
|
||||
'gstclapper-g-main-context-signal-dispatcher.h',
|
||||
'gstclapper-video-overlay-video-renderer.h',
|
||||
'gstclapper-visualization.h',
|
||||
'gstclapper-mpris.h',
|
||||
'gstclapper-gtk4-plugin.h',
|
||||
]
|
||||
gstclapper_defines = [
|
||||
'-DHAVE_CONFIG_H',
|
||||
'-DBUILDING_GST_CLAPPER',
|
||||
'-DGST_USE_UNSTABLE_API',
|
||||
'-DHAVE_GTK_GL',
|
||||
]
|
||||
gtk_deps = [gstgl_dep, gstglproto_dep]
|
||||
have_gtk_gl_windowing = false
|
||||
|
||||
gtk4_dep = dependency('gtk4', required : true)
|
||||
|
||||
if not gtk4_dep.version().version_compare('>=4.0.0')
|
||||
error('GTK4 version on this system is too old')
|
||||
endif
|
||||
|
||||
if gst_gl_have_window_x11 and (gst_gl_have_platform_egl or gst_gl_have_platform_glx)
|
||||
gtk_x11_dep = dependency('gtk4-x11', required : false)
|
||||
if gtk_x11_dep.found()
|
||||
gtk_deps += gtk_x11_dep
|
||||
if gst_gl_have_platform_glx
|
||||
gtk_deps += gstglx11_dep
|
||||
endif
|
||||
have_gtk_gl_windowing = true
|
||||
endif
|
||||
endif
|
||||
|
||||
if gst_gl_have_window_wayland and gst_gl_have_platform_egl
|
||||
gtk_wayland_dep = dependency('gtk4-wayland', required : false)
|
||||
if gtk_wayland_dep.found()
|
||||
gtk_deps += [gtk_wayland_dep, gstglwayland_dep]
|
||||
have_gtk_gl_windowing = true
|
||||
endif
|
||||
endif
|
||||
|
||||
if gst_gl_have_platform_egl
|
||||
gtk_deps += gstglegl_dep
|
||||
endif
|
||||
|
||||
if not have_gtk_gl_windowing
|
||||
error('GTK4 widget requires GL windowing')
|
||||
endif
|
||||
|
||||
gstclapper_mpris_gdbus = gnome.gdbus_codegen('gstclapper-mpris-gdbus',
|
||||
sources: '../../../data/gstclapper-mpris-gdbus.xml',
|
||||
interface_prefix: 'org.mpris.',
|
||||
namespace: 'GstClapperMpris'
|
||||
)
|
||||
|
||||
gstclapper = library('gstclapper-' + api_version,
|
||||
gstclapper_sources + gstclapper_mpris_gdbus,
|
||||
c_args : gstclapper_defines,
|
||||
link_args : noseh_link_args,
|
||||
include_directories : [configinc, libsinc],
|
||||
version : libversion,
|
||||
install : true,
|
||||
install_dir : clapper_libdir,
|
||||
dependencies : [gtk4_dep, glib_dep, gio_dep,
|
||||
gstbase_dep, gstvideo_dep, gstaudio_dep,
|
||||
gsttag_dep, gstpbutils_dep, libm] + gtk_deps,
|
||||
)
|
||||
|
||||
clapper_gir = gnome.generate_gir(gstclapper,
|
||||
sources : gstclapper_sources + gstclapper_headers,
|
||||
namespace : 'GstClapper',
|
||||
nsversion : api_version,
|
||||
identifier_prefix : 'Gst',
|
||||
symbol_prefix : 'gst',
|
||||
export_packages : 'gstreamer-clapper-1.0',
|
||||
includes : ['Gst-1.0', 'GstPbutils-1.0', 'GstBase-1.0', 'GstVideo-1.0',
|
||||
'GstAudio-1.0', 'GstTag-1.0'],
|
||||
install : true,
|
||||
install_dir_typelib : join_paths(clapper_libdir, 'girepository-1.0'),
|
||||
extra_args : gir_init_section + ['-DGST_USE_UNSTABLE_API'],
|
||||
dependencies : [gstbase_dep, gstvideo_dep, gstaudio_dep,
|
||||
gsttag_dep, gstpbutils_dep]
|
||||
)
|
@@ -1 +0,0 @@
|
||||
subdir('clapper')
|
284
lib/meson.build
284
lib/meson.build
@@ -1,284 +0,0 @@
|
||||
glib_req = '>= 2.56.0'
|
||||
gst_req = '>= 1.18.0'
|
||||
|
||||
api_version = '1.0'
|
||||
libversion = meson.project_version()
|
||||
|
||||
cc = meson.get_compiler('c')
|
||||
cxx = meson.get_compiler('cpp')
|
||||
|
||||
clapper_libdir = join_paths(
|
||||
get_option('prefix'), get_option('libdir'), meson.project_name()
|
||||
)
|
||||
|
||||
cdata = configuration_data()
|
||||
|
||||
if cc.get_id() == 'msvc'
|
||||
msvc_args = [
|
||||
# Ignore several spurious warnings for things gstreamer does very commonly
|
||||
# If a warning is completely useless and spammy, use '/wdXXXX' to suppress it
|
||||
# If a warning is harmless but hard to fix, use '/woXXXX' so it's shown once
|
||||
# NOTE: Only add warnings here if you are sure they're spurious
|
||||
'/wd4018', # implicit signed/unsigned conversion
|
||||
'/wd4146', # unary minus on unsigned (beware INT_MIN)
|
||||
'/wd4244', # lossy type conversion (e.g. double -> int)
|
||||
'/wd4305', # truncating type conversion (e.g. double -> float)
|
||||
cc.get_supported_arguments(['/utf-8']), # set the input encoding to utf-8
|
||||
|
||||
# Enable some warnings on MSVC to match GCC/Clang behaviour
|
||||
'/w14062', # enumerator 'identifier' in switch of enum 'enumeration' is not handled
|
||||
'/w14101', # 'identifier' : unreferenced local variable
|
||||
'/w14189', # 'identifier' : local variable is initialized but not referenced
|
||||
]
|
||||
add_project_arguments(msvc_args, language: ['c', 'cpp'])
|
||||
noseh_link_args = ['/SAFESEH:NO']
|
||||
else
|
||||
if cxx.has_argument('-Wno-non-virtual-dtor')
|
||||
add_project_arguments('-Wno-non-virtual-dtor', language: 'cpp')
|
||||
endif
|
||||
noseh_link_args = []
|
||||
endif
|
||||
|
||||
if cc.has_link_argument('-Wl,-Bsymbolic-functions')
|
||||
add_project_link_arguments('-Wl,-Bsymbolic-functions', language : 'c')
|
||||
endif
|
||||
|
||||
# Symbol visibility
|
||||
if cc.get_id() == 'msvc'
|
||||
export_define = '__declspec(dllexport) extern'
|
||||
elif cc.has_argument('-fvisibility=hidden')
|
||||
add_project_arguments('-fvisibility=hidden', language: 'c')
|
||||
add_project_arguments('-fvisibility=hidden', language: 'cpp')
|
||||
export_define = 'extern __attribute__ ((visibility ("default")))'
|
||||
else
|
||||
export_define = 'extern'
|
||||
endif
|
||||
|
||||
# Passing this through the command line would be too messy
|
||||
cdata.set('GST_API_EXPORT', export_define)
|
||||
|
||||
# Disable strict aliasing
|
||||
if cc.has_argument('-fno-strict-aliasing')
|
||||
add_project_arguments('-fno-strict-aliasing', language: 'c')
|
||||
endif
|
||||
if cxx.has_argument('-fno-strict-aliasing')
|
||||
add_project_arguments('-fno-strict-aliasing', language: 'cpp')
|
||||
endif
|
||||
|
||||
if not get_option('deprecated-glib-api')
|
||||
message('Disabling deprecated GLib API')
|
||||
add_project_arguments('-DG_DISABLE_DEPRECATED', language: 'c')
|
||||
endif
|
||||
|
||||
if not get_option('devel-checks')
|
||||
message('Disabling GLib cast checks')
|
||||
add_project_arguments('-DG_DISABLE_CAST_CHECKS', language: 'c')
|
||||
|
||||
message('Disabling GLib asserts')
|
||||
add_project_arguments('-DG_DISABLE_ASSERT', language: 'c')
|
||||
|
||||
message('Disabling GLib checks')
|
||||
add_project_arguments('-DG_DISABLE_CHECKS', language: 'c')
|
||||
endif
|
||||
|
||||
check_headers = [
|
||||
['HAVE_DLFCN_H', 'dlfcn.h'],
|
||||
['HAVE_FCNTL_H', 'fcntl.h'],
|
||||
['HAVE_INTTYPES_H', 'inttypes.h'],
|
||||
['HAVE_MEMORY_H', 'memory.h'],
|
||||
['HAVE_NETINET_IN_H', 'netinet/in.h'],
|
||||
['HAVE_NETINET_IP_H', 'netinet/ip.h'],
|
||||
['HAVE_NETINET_TCP_H', 'netinet/tcp.h'],
|
||||
['HAVE_PTHREAD_H', 'pthread.h'],
|
||||
['HAVE_STDINT_H', 'stdint.h'],
|
||||
['HAVE_STDLIB_H', 'stdlib.h'],
|
||||
['HAVE_STRINGS_H', 'strings.h'],
|
||||
['HAVE_STRING_H', 'string.h'],
|
||||
['HAVE_SYS_PARAM_H', 'sys/param.h'],
|
||||
['HAVE_SYS_SOCKET_H', 'sys/socket.h'],
|
||||
['HAVE_SYS_STAT_H', 'sys/stat.h'],
|
||||
['HAVE_SYS_TIME_H', 'sys/time.h'],
|
||||
['HAVE_SYS_TYPES_H', 'sys/types.h'],
|
||||
['HAVE_SYS_UTSNAME_H', 'sys/utsname.h'],
|
||||
['HAVE_UNISTD_H', 'unistd.h'],
|
||||
]
|
||||
|
||||
foreach h : check_headers
|
||||
if cc.has_header(h.get(1))
|
||||
cdata.set(h.get(0), 1)
|
||||
endif
|
||||
endforeach
|
||||
|
||||
check_functions = [
|
||||
['HAVE_DCGETTEXT', 'dcgettext'],
|
||||
['HAVE_GETPAGESIZE', 'getpagesize'],
|
||||
['HAVE_GMTIME_R', 'gmtime_r'],
|
||||
['HAVE_MEMFD_CREATE', 'memfd_create'],
|
||||
['HAVE_MMAP', 'mmap'],
|
||||
['HAVE_PIPE2', 'pipe2'],
|
||||
['HAVE_GETRUSAGE', 'getrusage', '#include<sys/resource.h>'],
|
||||
]
|
||||
|
||||
foreach f : check_functions
|
||||
prefix = ''
|
||||
if f.length() == 3
|
||||
prefix = f.get(2)
|
||||
endif
|
||||
if cc.has_function(f.get(1), prefix: prefix)
|
||||
cdata.set(f.get(0), 1)
|
||||
endif
|
||||
endforeach
|
||||
|
||||
cdata.set('SIZEOF_CHAR', cc.sizeof('char'))
|
||||
cdata.set('SIZEOF_INT', cc.sizeof('int'))
|
||||
cdata.set('SIZEOF_LONG', cc.sizeof('long'))
|
||||
cdata.set('SIZEOF_SHORT', cc.sizeof('short'))
|
||||
cdata.set('SIZEOF_VOIDP', cc.sizeof('void*'))
|
||||
|
||||
cdata.set_quoted('VERSION', libversion)
|
||||
cdata.set_quoted('PACKAGE', 'gst-plugins-clapper')
|
||||
cdata.set_quoted('PACKAGE_VERSION', libversion)
|
||||
cdata.set_quoted('PACKAGE_BUGREPORT', 'https://github.com/Rafostar/clapper/issues/new')
|
||||
cdata.set_quoted('PACKAGE_NAME', 'GStreamer Clapper Libs')
|
||||
cdata.set_quoted('GST_API_VERSION', api_version)
|
||||
cdata.set_quoted('GST_LICENSE', 'LGPL')
|
||||
cdata.set_quoted('LIBDIR', clapper_libdir)
|
||||
cdata.set_quoted('LOCALEDIR', join_paths(get_option('prefix'), get_option('localedir')))
|
||||
|
||||
warning_flags = [
|
||||
'-Wmissing-declarations',
|
||||
'-Wredundant-decls',
|
||||
'-Wwrite-strings',
|
||||
'-Wformat',
|
||||
'-Wformat-security',
|
||||
'-Winit-self',
|
||||
'-Wmissing-include-dirs',
|
||||
'-Waddress',
|
||||
'-Wno-multichar',
|
||||
'-Wvla',
|
||||
'-Wpointer-arith',
|
||||
]
|
||||
warning_c_flags = [
|
||||
'-Wmissing-prototypes',
|
||||
'-Wdeclaration-after-statement',
|
||||
'-Wold-style-definition',
|
||||
]
|
||||
warning_cxx_flags = [
|
||||
'-Wformat-nonliteral',
|
||||
]
|
||||
|
||||
foreach extra_arg : warning_c_flags
|
||||
if cc.has_argument (extra_arg)
|
||||
add_project_arguments([extra_arg], language: 'c')
|
||||
endif
|
||||
endforeach
|
||||
|
||||
foreach extra_arg : warning_cxx_flags
|
||||
if cxx.has_argument (extra_arg)
|
||||
add_project_arguments([extra_arg], language: 'cpp')
|
||||
endif
|
||||
endforeach
|
||||
|
||||
foreach extra_arg : warning_flags
|
||||
if cc.has_argument (extra_arg)
|
||||
add_project_arguments([extra_arg], language: 'c')
|
||||
endif
|
||||
if cxx.has_argument (extra_arg)
|
||||
add_project_arguments([extra_arg], language: 'cpp')
|
||||
endif
|
||||
endforeach
|
||||
|
||||
cdata.set_quoted('GST_PACKAGE_NAME', 'GStreamer Plugins Clapper')
|
||||
cdata.set_quoted('GST_PACKAGE_ORIGIN', 'https://github.com/Rafostar/clapper')
|
||||
|
||||
# Mandatory GST deps
|
||||
gst_dep = dependency('gstreamer-1.0', version : gst_req,
|
||||
fallback : ['gstreamer', 'gst_dep'])
|
||||
gstbase_dep = dependency('gstreamer-base-1.0', version : gst_req,
|
||||
fallback : ['gstreamer', 'gst_base_dep'])
|
||||
gstpbutils_dep = dependency('gstreamer-pbutils-1.0', version : gst_req,
|
||||
fallback : ['gst-plugins-base', 'pbutils_dep'])
|
||||
gstaudio_dep = dependency('gstreamer-audio-1.0', version : gst_req,
|
||||
fallback : ['gst-plugins-base', 'audio_dep'])
|
||||
gsttag_dep = dependency('gstreamer-tag-1.0', version : gst_req,
|
||||
fallback : ['gst-plugins-base', 'tag_dep'])
|
||||
gstvideo_dep = dependency('gstreamer-video-1.0', version : gst_req,
|
||||
fallback : ['gst-plugins-base', 'video_dep'])
|
||||
|
||||
# GStreamer OpenGL
|
||||
gstgl_dep = dependency('gstreamer-gl-1.0', version : gst_req,
|
||||
fallback : ['gst-plugins-base', 'gstgl_dep'], required: true)
|
||||
gstglx11_dep = dependency('', required : false)
|
||||
gstglwayland_dep = dependency('', required : false)
|
||||
gstglegl_dep = dependency('', required : false)
|
||||
|
||||
gst_gl_apis = gstgl_dep.get_pkgconfig_variable('gl_apis')
|
||||
gst_gl_winsys = gstgl_dep.get_pkgconfig_variable('gl_winsys')
|
||||
gst_gl_platforms = gstgl_dep.get_pkgconfig_variable('gl_platforms')
|
||||
|
||||
message('GStreamer OpenGL window systems: @0@'.format(gst_gl_winsys))
|
||||
message('GStreamer OpenGL platforms: @0@'.format(gst_gl_platforms))
|
||||
message('GStreamer OpenGL apis: @0@'.format(gst_gl_apis))
|
||||
|
||||
foreach ws : ['x11', 'wayland', 'android', 'cocoa', 'eagl', 'win32', 'dispmanx', 'viv_fb']
|
||||
set_variable('gst_gl_have_window_@0@'.format(ws), gst_gl_winsys.contains(ws))
|
||||
endforeach
|
||||
|
||||
foreach p : ['glx', 'egl', 'cgl', 'eagl', 'wgl']
|
||||
set_variable('gst_gl_have_platform_@0@'.format(p), gst_gl_platforms.contains(p))
|
||||
endforeach
|
||||
|
||||
foreach api : ['gl', 'gles2']
|
||||
set_variable('gst_gl_have_api_@0@'.format(api), gst_gl_apis.contains(api))
|
||||
endforeach
|
||||
|
||||
gstglproto_dep = dependency('gstreamer-gl-prototypes-1.0', version : gst_req,
|
||||
fallback : ['gst-plugins-base', 'gstglproto_dep'], required: true)
|
||||
if gst_gl_have_window_x11
|
||||
gstglx11_dep = dependency('gstreamer-gl-x11-1.0', version : gst_req,
|
||||
fallback : ['gst-plugins-base', 'gstglx11_dep'], required: true)
|
||||
endif
|
||||
if gst_gl_have_window_wayland
|
||||
gstglwayland_dep = dependency('gstreamer-gl-wayland-1.0', version : gst_req,
|
||||
fallback : ['gst-plugins-base', 'gstglwayland_dep'], required: true)
|
||||
endif
|
||||
if gst_gl_have_platform_egl
|
||||
gstglegl_dep = dependency('gstreamer-gl-egl-1.0', version : gst_req,
|
||||
fallback : ['gst-plugins-base', 'gstglegl_dep'], required: true)
|
||||
endif
|
||||
|
||||
libm = cc.find_library('m', required : false)
|
||||
glib_dep = dependency('glib-2.0', version : glib_req, fallback: ['glib', 'libglib_dep'])
|
||||
gmodule_dep = dependency('gmodule-2.0', fallback: ['glib', 'libgmodule_dep'])
|
||||
gio_dep = dependency('gio-2.0', fallback: ['glib', 'libgio_dep'])
|
||||
|
||||
cdata.set('DISABLE_ORC', 1)
|
||||
cdata.set('GST_ENABLE_EXTRA_CHECKS', get_option('devel-checks'))
|
||||
cdata.set_quoted('GST_PACKAGE_RELEASE_DATETIME', 'Unknown')
|
||||
|
||||
message('GStreamer debug system is disabled')
|
||||
if cc.has_argument('-Wno-unused')
|
||||
add_project_arguments('-Wno-unused', language: 'c')
|
||||
endif
|
||||
if cxx.has_argument ('-Wno-unused')
|
||||
add_project_arguments('-Wno-unused', language: 'cpp')
|
||||
endif
|
||||
|
||||
configinc = include_directories('.')
|
||||
libsinc = include_directories('gst')
|
||||
|
||||
gnome = import('gnome')
|
||||
gir = find_program('g-ir-scanner', required : true)
|
||||
|
||||
if not gir.found()
|
||||
error('Clapper requires GI bindings to be compiled')
|
||||
endif
|
||||
|
||||
gir_init_section = ['--add-init-section=extern void gst_init(gint*,gchar**);' + \
|
||||
'g_setenv("GST_REGISTRY_1.0", "@0@", TRUE);'.format(meson.current_build_dir() + '/gir_empty_registry.reg') + \
|
||||
'g_setenv("GST_PLUGIN_PATH_1_0", "", TRUE);' + \
|
||||
'g_setenv("GST_PLUGIN_SYSTEM_PATH_1_0", "", TRUE);' + \
|
||||
'gst_init(NULL,NULL);', '--quiet'
|
||||
]
|
||||
subdir('gst')
|
||||
configure_file(output : 'config.h', configuration : cdata)
|
164
meson.build
164
meson.build
@@ -1,33 +1,151 @@
|
||||
project('com.github.rafostar.Clapper', 'c', 'cpp',
|
||||
version: '0.2.1',
|
||||
meson_version: '>= 0.50.0',
|
||||
license: 'GPL3',
|
||||
project('clapper', 'c',
|
||||
version: '0.6.0',
|
||||
meson_version: '>= 0.64.0',
|
||||
license: 'LGPL-2.1-or-later AND GPL-3.0-or-later', # LGPL-2.1+ for libs and gst-plugin, GPL-3.0+ for app
|
||||
default_options: [
|
||||
'warning_level=1',
|
||||
'buildtype=debugoptimized'
|
||||
]
|
||||
'buildtype=debugoptimized',
|
||||
],
|
||||
)
|
||||
|
||||
python = import('python')
|
||||
python_bin = python.find_installation('python3')
|
||||
glib_req = '>= 2.76.0'
|
||||
gst_req = '>= 1.20.0'
|
||||
gtk4_req = '>= 4.10.0'
|
||||
adw_req = '>= 1.4.0'
|
||||
|
||||
if not python_bin.found()
|
||||
error('No valid python3 binary found')
|
||||
clapper_version = meson.project_version().split('-')[0]
|
||||
version_array = clapper_version.split('.')
|
||||
clapper_version_suffix = '-' + version_array[0] + '.0'
|
||||
|
||||
clapper_api_name = meson.project_name() + clapper_version_suffix
|
||||
|
||||
devenv = environment()
|
||||
|
||||
gnome = import('gnome')
|
||||
pkgconfig = import('pkgconfig')
|
||||
i18n = import('i18n')
|
||||
|
||||
prefix = get_option('prefix')
|
||||
bindir = get_option('bindir')
|
||||
datadir = get_option('datadir')
|
||||
libdir = get_option('libdir')
|
||||
localedir = get_option('localedir')
|
||||
includedir = get_option('includedir')
|
||||
optimization = get_option('optimization')
|
||||
|
||||
clapper_libdir = join_paths(prefix, libdir, clapper_api_name)
|
||||
build_optimized = optimization in ['2', '3', 's']
|
||||
|
||||
gst_dep = dependency('gstreamer-1.0',
|
||||
version: gst_req,
|
||||
required: false,
|
||||
)
|
||||
gst_base_dep = dependency('gstreamer-base-1.0',
|
||||
version: gst_req,
|
||||
required: false,
|
||||
)
|
||||
gst_video_dep = dependency('gstreamer-video-1.0',
|
||||
version: gst_req,
|
||||
required: false,
|
||||
)
|
||||
gst_audio_dep = dependency('gstreamer-audio-1.0',
|
||||
version: gst_req,
|
||||
required: false,
|
||||
)
|
||||
gst_pbutils_dep = dependency('gstreamer-pbutils-1.0',
|
||||
version: gst_req,
|
||||
required: false,
|
||||
)
|
||||
gst_tag_dep = dependency('gstreamer-tag-1.0',
|
||||
version: gst_req,
|
||||
required: false,
|
||||
)
|
||||
glib_dep = dependency('glib-2.0',
|
||||
version: glib_req,
|
||||
required: false,
|
||||
)
|
||||
gobject_dep = dependency('gobject-2.0',
|
||||
version: glib_req,
|
||||
required: false,
|
||||
)
|
||||
gio_dep = dependency('gio-2.0',
|
||||
version: glib_req,
|
||||
required: false,
|
||||
)
|
||||
gmodule_dep = dependency('gmodule-2.0',
|
||||
version: glib_req,
|
||||
required: false,
|
||||
)
|
||||
gtk4_dep = dependency('gtk4',
|
||||
version: gtk4_req,
|
||||
required: false,
|
||||
)
|
||||
libadwaita_dep = dependency('libadwaita-1',
|
||||
version: adw_req,
|
||||
required: false,
|
||||
)
|
||||
|
||||
cc = meson.get_compiler('c')
|
||||
libm = cc.find_library('m', required: false)
|
||||
|
||||
warning_flags = [
|
||||
'-Wmissing-declarations',
|
||||
'-Wredundant-decls',
|
||||
'-Wwrite-strings',
|
||||
'-Wformat',
|
||||
'-Wformat-security',
|
||||
'-Winit-self',
|
||||
'-Wmissing-include-dirs',
|
||||
'-Waddress',
|
||||
'-Wno-multichar',
|
||||
'-Wvla',
|
||||
'-Wpointer-arith',
|
||||
'-Wmissing-prototypes',
|
||||
'-Wdeclaration-after-statement',
|
||||
'-Wold-style-definition',
|
||||
'-Wsign-compare',
|
||||
]
|
||||
|
||||
foreach extra_arg : warning_flags
|
||||
if cc.has_argument (extra_arg)
|
||||
add_project_arguments([extra_arg], language: 'c')
|
||||
endif
|
||||
endforeach
|
||||
|
||||
if build_optimized
|
||||
message('Disabling GLib cast checks')
|
||||
add_project_arguments('-DG_DISABLE_CAST_CHECKS', language: 'c')
|
||||
|
||||
message('Disabling GLib asserts')
|
||||
add_project_arguments('-DG_DISABLE_ASSERT', language: 'c')
|
||||
|
||||
message('Disabling GLib checks')
|
||||
add_project_arguments('-DG_DISABLE_CHECKS', language: 'c')
|
||||
endif
|
||||
|
||||
if get_option('clapper-lib')
|
||||
subdir('lib')
|
||||
endif
|
||||
subdir('src')
|
||||
subdir('doc')
|
||||
|
||||
if get_option('clapper-player')
|
||||
subdir('bin')
|
||||
subdir('data')
|
||||
meson.add_devenv(devenv)
|
||||
|
||||
installdir = join_paths(get_option('prefix'), 'share', meson.project_name())
|
||||
install_subdir('src', install_dir : installdir)
|
||||
install_subdir('extras', install_dir : installdir)
|
||||
install_subdir('css', install_dir : installdir)
|
||||
install_subdir('ui', install_dir : installdir)
|
||||
summary({
|
||||
'prefix': prefix,
|
||||
'bindir': bindir,
|
||||
'datadir': datadir,
|
||||
'libdir': libdir,
|
||||
'localedir': localedir,
|
||||
'includedir': includedir,
|
||||
'optimization': optimization,
|
||||
}, section: 'Directories')
|
||||
|
||||
meson.add_install_script('build-aux/meson/postinstall.py')
|
||||
endif
|
||||
summary('clapper', build_clapper ? 'Yes' : 'No', section: 'Build')
|
||||
summary('clapper-gtk', build_clappergtk ? 'Yes' : 'No', section: 'Build')
|
||||
summary('clapper-app', build_clapperapp ? 'Yes' : 'No', section: 'Build')
|
||||
summary('gst-plugin', build_gst_plugin ? 'Yes' : 'No', section: 'Build')
|
||||
summary('introspection', build_gir ? 'Yes' : 'No', section: 'Build')
|
||||
summary('vapi', build_vapi ? 'Yes' : 'No', section: 'Build')
|
||||
summary('doc', build_doc ? 'Yes' : 'No', section: 'Build')
|
||||
|
||||
foreach name : clapper_possible_features
|
||||
summary(name, clapper_available_features.contains(name) ? 'Yes' : 'No', section: 'Features')
|
||||
endforeach
|
||||
|
@@ -1,20 +1,70 @@
|
||||
option('clapper-player',
|
||||
type : 'boolean',
|
||||
value : true,
|
||||
description: 'Build Clapper player'
|
||||
# Build
|
||||
option('clapper',
|
||||
type: 'feature',
|
||||
value: 'auto',
|
||||
description: 'Build Clapper library'
|
||||
)
|
||||
option('clapper-lib',
|
||||
type : 'boolean',
|
||||
value : true,
|
||||
description: 'Build Clapper libs (including API)'
|
||||
option('clapper-gtk',
|
||||
type: 'feature',
|
||||
value: 'auto',
|
||||
description: 'Build Clapper GTK integration library'
|
||||
)
|
||||
option('devel-checks',
|
||||
type : 'boolean',
|
||||
value : false,
|
||||
description: 'GStreamer GLib checks and asserts such as API guards (disable for stable releases)'
|
||||
option('clapper-app',
|
||||
type: 'feature',
|
||||
value: 'auto',
|
||||
description: 'Build Clapper application'
|
||||
)
|
||||
option('deprecated-glib-api',
|
||||
type : 'boolean',
|
||||
value : true,
|
||||
description: 'Allow using of deprecated GLib API'
|
||||
option('gst-plugin',
|
||||
type: 'feature',
|
||||
value: 'auto',
|
||||
description: 'Build GStreamer plugin (includes GTK video sink element)'
|
||||
)
|
||||
option('introspection',
|
||||
type: 'feature',
|
||||
value: 'auto',
|
||||
description: 'Build GObject Introspection data'
|
||||
)
|
||||
option('vapi',
|
||||
type: 'feature',
|
||||
value: 'auto',
|
||||
description: 'Build Vala bindings'
|
||||
)
|
||||
option('doc',
|
||||
type: 'boolean',
|
||||
value: false,
|
||||
description: 'Build documentation'
|
||||
)
|
||||
|
||||
# Features
|
||||
option('discoverer',
|
||||
type: 'feature',
|
||||
value: 'auto',
|
||||
description: 'Build Clapper Discoverer feature'
|
||||
)
|
||||
option('mpris',
|
||||
type: 'feature',
|
||||
value: 'auto',
|
||||
description: 'Build Clapper MPRIS feature'
|
||||
)
|
||||
option('server',
|
||||
type: 'feature',
|
||||
value: 'auto',
|
||||
description: 'Build Clapper Server feature'
|
||||
)
|
||||
|
||||
# GStreamer plugin options
|
||||
option('glimporter',
|
||||
type: 'feature',
|
||||
value: 'auto',
|
||||
description: 'Build GL memory importer for clappersink'
|
||||
)
|
||||
option('gluploader',
|
||||
type: 'feature',
|
||||
value: 'auto',
|
||||
description: 'Build GL uploader for clappersink'
|
||||
)
|
||||
option('rawimporter',
|
||||
type: 'feature',
|
||||
value: 'auto',
|
||||
description: 'Build RAW system memory importer for clappersink'
|
||||
)
|
||||
|
@@ -1,29 +0,0 @@
|
||||
pkgbase = clapper-git
|
||||
pkgdesc = A GNOME media player built using GJS with GTK4 toolkit and powered by GStreamer with OpenGL rendering.
|
||||
pkgver = r393.bf04af2
|
||||
pkgrel = 1
|
||||
url = https://github.com/Rafostar/clapper
|
||||
arch = any
|
||||
license = GPL-3.0
|
||||
makedepends = meson>=0.50
|
||||
makedepends = git
|
||||
depends = gtk4
|
||||
depends = gjs
|
||||
depends = glib2>=2.56.0
|
||||
depends = gobject-introspection
|
||||
depends = wayland-protocols
|
||||
depends = hicolor-icon-theme
|
||||
depends = gstreamer>=1.18.0
|
||||
depends = gst-plugins-base-libs>=1.18.0
|
||||
depends = gst-plugins-good>=1.18.0
|
||||
depends = gst-plugins-bad-libs>=1.18.0
|
||||
optdepends = gst-libav>=1.18.0: Popular video decoders
|
||||
optdepends = gstreamer-vaapi>=1.18.0: Intel/AMD video acceleration
|
||||
provides = clapper
|
||||
conflicts = clapper
|
||||
replaces = clapper
|
||||
source = clapper::git+https://github.com/Rafostar/clapper.git
|
||||
md5sums = SKIP
|
||||
|
||||
pkgname = clapper-git
|
||||
|
4
pkgs/arch/.gitignore
vendored
4
pkgs/arch/.gitignore
vendored
@@ -1,4 +0,0 @@
|
||||
clapper-*/
|
||||
clapper-*.pkg.tar.*
|
||||
pkg/
|
||||
src/
|
@@ -1,74 +0,0 @@
|
||||
#
|
||||
# PKGBUILD file for package clapper
|
||||
#
|
||||
# Copyright (C) 2020/21 sp1rit
|
||||
# Copyright (C) 2020 Rafostar
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# Maintainer: sp1rit <sp1ritCS@protonmail.com>
|
||||
|
||||
_basename=clapper
|
||||
pkgname="${_basename}-git"
|
||||
pkgver=r393.bf04af2
|
||||
pkgrel=1
|
||||
pkgdesc="A GNOME media player built using GJS with GTK4 toolkit and powered by GStreamer with OpenGL rendering."
|
||||
arch=(any)
|
||||
url="https://github.com/Rafostar/clapper"
|
||||
license=("GPL-3.0")
|
||||
depends=(
|
||||
"gtk4"
|
||||
"gjs"
|
||||
"glib2>=2.56.0" # glib-2.0, gmodule-2.0, gio-2.0
|
||||
"gobject-introspection" # /usr/sbin/g-ir-scanner
|
||||
"wayland-protocols" # gtk4 non-default runtime dep
|
||||
"hicolor-icon-theme"
|
||||
"gstreamer>=1.18.0" # gstreamer-1.0, gstreamer-base-1.0
|
||||
"gst-plugins-base-libs>=1.18.0" # gstreamer-pbutils-1.0, gstreamer-audio-1.0, gstreamer-tag-1.0, gstreamer-video-1.0, gstreamer-gl-1.0, gstreamer-gl-prototypes-1.0, gstreamer-gl-x11-1.0, gstreamer-gl-wayland-1.0, gstreamer-gl-egl-1.0,
|
||||
"gst-plugins-good>=1.18.0"
|
||||
"gst-plugins-bad-libs>=1.18.0"
|
||||
)
|
||||
makedepends=(
|
||||
"meson>=0.50"
|
||||
"git"
|
||||
)
|
||||
optdepends=(
|
||||
"gst-libav>=1.18.0: Popular video decoders"
|
||||
"gstreamer-vaapi>=1.18.0: Intel/AMD video acceleration"
|
||||
)
|
||||
source=("${_basename}::git+https://github.com/Rafostar/${_basename}.git")
|
||||
provides=("${_basename}")
|
||||
replaces=("${_basename}")
|
||||
conflicts=("${_basename}")
|
||||
md5sums=("SKIP")
|
||||
|
||||
pkgver() {
|
||||
cd "${srcdir}/${_basename}"
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}/${_basename}"
|
||||
arch-meson . _build
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/${_basename}"
|
||||
ninja -C _build
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "${srcdir}/${_basename}"
|
||||
DESTDIR="$pkgdir" meson install -C _build/
|
||||
}
|
@@ -1,28 +0,0 @@
|
||||
Format: 3.0 (quilt)
|
||||
Source: clapper
|
||||
Binary: clapper
|
||||
Architecture: any
|
||||
Version: 0.2.1
|
||||
Maintainer: Rafostar <rafostar.github@gmail.com>
|
||||
Build-Depends: debhelper (>= 10),
|
||||
meson (>= 0.50),
|
||||
gjs,
|
||||
gobject-introspection,
|
||||
libgtk-4-dev (>= 4.0.0),
|
||||
libgstreamer1.0-dev (>= 1.18),
|
||||
libgstreamer-plugins-base1.0-dev (>= 1.18),
|
||||
libgstreamer-gl1.0-0 (>= 1.18),
|
||||
libgles-dev,
|
||||
libglib2.0-dev,
|
||||
libglib2.0-bin,
|
||||
desktop-file-utils,
|
||||
hicolor-icon-theme,
|
||||
brz,
|
||||
libfontconfig1-dev,
|
||||
libpam-systemd
|
||||
Package-List:
|
||||
clapper deb gnome optional arch=any
|
||||
Files:
|
||||
0 0 debian.tar.xz
|
||||
Description: Simple and modern GNOME media player
|
||||
A GNOME media player built using GJS with GTK4 toolkit and powered by GStreamer with OpenGL rendering.
|
@@ -1,5 +0,0 @@
|
||||
clapper (0.2.1) unstable; urgency=low
|
||||
|
||||
* New version
|
||||
|
||||
-- Rafostar <rafostar.github@gmail.com> Mon, 19 Apr 2021 09:39:00 +0100
|
@@ -1 +0,0 @@
|
||||
10
|
@@ -1,37 +0,0 @@
|
||||
Source: clapper
|
||||
Section: gnome
|
||||
Priority: optional
|
||||
Maintainer: Rafostar <rafostar.github@gmail.com>
|
||||
Standards-Version: 4.4.0
|
||||
Build-Depends: debhelper (>= 10),
|
||||
meson (>= 0.50),
|
||||
gjs,
|
||||
gobject-introspection,
|
||||
libgtk-4-dev (>= 4.0.0),
|
||||
libgstreamer1.0-dev (>= 1.18),
|
||||
libgstreamer-plugins-base1.0-dev (>= 1.18),
|
||||
libgstreamer-gl1.0-0 (>= 1.18),
|
||||
libgles-dev,
|
||||
libglib2.0-dev,
|
||||
libglib2.0-bin,
|
||||
desktop-file-utils,
|
||||
hicolor-icon-theme
|
||||
|
||||
Package: clapper
|
||||
Architecture: any
|
||||
Depends: gjs,
|
||||
gir1.2-gtk-4.0 (>= 4.0.0),
|
||||
hicolor-icon-theme,
|
||||
libgstreamer1.0-0 (>= 1.18),
|
||||
gstreamer1.0-plugins-base (>= 1.18),
|
||||
gstreamer1.0-plugins-good (>= 1.18),
|
||||
gstreamer1.0-plugins-bad (>= 1.18),
|
||||
gstreamer1.0-gl (>= 1.18)
|
||||
Recommends: gstreamer1.0-libav,
|
||||
gstreamer1.0-pulseaudio
|
||||
Suggests: gstreamer1.0-plugins-ugly,
|
||||
gstreamer1.0-vaapi
|
||||
Description: Simple and modern GNOME media player
|
||||
A GNOME media player built using GJS with GTK4 toolkit and powered by GStreamer with OpenGL rendering.
|
||||
.
|
||||
More codecs/features and video acceleration can be enabled by installing the suggested packages.
|
@@ -1,27 +0,0 @@
|
||||
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: clapper
|
||||
Source: https://github.com/Rafostar/clapper
|
||||
|
||||
Files: *
|
||||
Copyright: 2020 Rafostar <rafostar.github@gmail.com>
|
||||
License: GPL-3.0+
|
||||
|
||||
Files: debian/*
|
||||
Copyright: 2020 Rafostar <rafostar.github@gmail.com>
|
||||
License: GPL-3.0+
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General Public License
|
||||
Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
|
@@ -1,4 +0,0 @@
|
||||
#!/usr/bin/make -f
|
||||
|
||||
%:
|
||||
dh $@
|
@@ -1 +0,0 @@
|
||||
3.0 (quilt)
|
69
pkgs/flatpak/com.github.rafostar.Clapper-nightly.json
Normal file
69
pkgs/flatpak/com.github.rafostar.Clapper-nightly.json
Normal file
@@ -0,0 +1,69 @@
|
||||
{
|
||||
"app-id": "com.github.rafostar.Clapper",
|
||||
"runtime": "org.gnome.Platform",
|
||||
"runtime-version": "master",
|
||||
"sdk": "org.gnome.Sdk",
|
||||
"sdk-extensions": [
|
||||
"org.freedesktop.Sdk.Extension.rust-nightly",
|
||||
"org.freedesktop.Sdk.Extension.llvm16"
|
||||
],
|
||||
"add-extensions": {
|
||||
"org.freedesktop.Platform.ffmpeg-full": {
|
||||
"version": "23.08",
|
||||
"directory": "lib/ffmpeg",
|
||||
"add-ld-path": ".",
|
||||
"no-autodownload": false,
|
||||
"autodelete": false
|
||||
}
|
||||
},
|
||||
"command": "clapper",
|
||||
"separate-locales": false,
|
||||
"finish-args": [
|
||||
"--share=ipc",
|
||||
"--socket=fallback-x11",
|
||||
"--socket=wayland",
|
||||
"--device=dri",
|
||||
"--socket=pulseaudio",
|
||||
"--share=network",
|
||||
"--device=all",
|
||||
"--filesystem=xdg-run/pipewire-0:ro",
|
||||
"--filesystem=xdg-videos",
|
||||
"--filesystem=xdg-run/gvfsd",
|
||||
"--own-name=org.mpris.MediaPlayer2.Clapper",
|
||||
"--talk-name=org.gtk.vfs.*",
|
||||
"--env=GST_PLUGIN_SYSTEM_PATH=/app/lib/gstreamer-1.0"
|
||||
],
|
||||
"build-options": {
|
||||
"append-path": "/usr/lib/sdk/rust-nightly/bin:/usr/lib/sdk/llvm16/bin",
|
||||
"prepend-ld-library-path": "/usr/lib/sdk/llvm16/lib"
|
||||
},
|
||||
"modules": [
|
||||
"flathub/shared-modules/gudev/gudev.json",
|
||||
"testing/liba52.json",
|
||||
"flathub/lib/libmpeg2.json",
|
||||
"flathub/lib/libdv.json",
|
||||
"flathub/lib/libdvdcss.json",
|
||||
"flathub/lib/libdvdread.json",
|
||||
"flathub/lib/libdvdnav.json",
|
||||
"flathub/lib/libass.json",
|
||||
"testing/libmicrodns.json",
|
||||
"testing/dav1d.json",
|
||||
"testing/gstreamer.json",
|
||||
"testing/gst-plugins-rs.json",
|
||||
"testing/gtuber.json",
|
||||
{
|
||||
"name": "clapper",
|
||||
"buildsystem": "meson",
|
||||
"sources": [
|
||||
{
|
||||
"type": "dir",
|
||||
"path": "../../."
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"cleanup-commands": [
|
||||
"mkdir -p /app/lib/ffmpeg",
|
||||
"ln -s /lib/$FLATPAK_ARCH-linux-*/gstreamer-1.0/libgstpipewire.so /app/lib/gstreamer-1.0/"
|
||||
]
|
||||
}
|
@@ -1,9 +1,19 @@
|
||||
{
|
||||
"app-id": "com.github.rafostar.Clapper",
|
||||
"runtime": "org.gnome.Platform",
|
||||
"runtime-version": "40",
|
||||
"runtime-version": "45",
|
||||
"sdk": "org.gnome.Sdk",
|
||||
"command": "com.github.rafostar.Clapper",
|
||||
"add-extensions": {
|
||||
"org.freedesktop.Platform.ffmpeg-full": {
|
||||
"version": "23.08",
|
||||
"directory": "lib/ffmpeg",
|
||||
"add-ld-path": ".",
|
||||
"no-autodownload": false,
|
||||
"autodelete": false
|
||||
}
|
||||
},
|
||||
"command": "clapper",
|
||||
"separate-locales": false,
|
||||
"finish-args": [
|
||||
"--share=ipc",
|
||||
"--socket=fallback-x11",
|
||||
@@ -12,37 +22,32 @@
|
||||
"--socket=pulseaudio",
|
||||
"--share=network",
|
||||
"--device=all",
|
||||
"--filesystem=xdg-run/pipewire-0:ro",
|
||||
"--filesystem=xdg-videos",
|
||||
"--filesystem=xdg-run/gvfsd",
|
||||
"--own-name=org.mpris.MediaPlayer2.Clapper",
|
||||
"--talk-name=org.gnome.Shell",
|
||||
"--env=GST_PLUGIN_SYSTEM_PATH=/app/lib/gstreamer-1.0",
|
||||
"--env=GST_VAAPI_ALL_DRIVERS=1"
|
||||
"--talk-name=org.gtk.vfs.*",
|
||||
"--env=GST_PLUGIN_SYSTEM_PATH=/app/lib/gstreamer-1.0"
|
||||
],
|
||||
"modules": [
|
||||
"flathub/lib/glib-networking.json",
|
||||
"flathub/shared-modules/gudev/gudev.json",
|
||||
"flathub/lib/pango.json",
|
||||
"flathub/lib/libsass.json",
|
||||
"flathub/lib/sassc.json",
|
||||
"flathub/lib/gtk4.json",
|
||||
"flathub/lib/liba52.json",
|
||||
"testing/liba52.json",
|
||||
"flathub/lib/libmpeg2.json",
|
||||
"flathub/lib/libdv.json",
|
||||
"flathub/lib/libdvdcss.json",
|
||||
"flathub/lib/libdvdread.json",
|
||||
"flathub/lib/libdvdnav.json",
|
||||
"flathub/lib/libass.json",
|
||||
"flathub/lib/ffmpeg.json",
|
||||
"flathub/lib/uchardet.json",
|
||||
"testing/libmicrodns.json",
|
||||
"flathub/gstreamer-1.0/gstreamer.json",
|
||||
"flathub/gstreamer-1.0/gst-plugins-base.json",
|
||||
"flathub/gstreamer-1.0/gst-plugins-good.json",
|
||||
"flathub/gstreamer-1.0/gst-plugins-bad.json",
|
||||
"flathub/gstreamer-1.0/gst-plugins-ugly.json",
|
||||
"flathub/gstreamer-1.0/gst-libav.json",
|
||||
"flathub/gstreamer-1.0/gstreamer-vaapi.json",
|
||||
"testing/gtuber.json",
|
||||
{
|
||||
"name": "clapper",
|
||||
"buildsystem": "meson",
|
||||
"config-opts": [
|
||||
"-Dc_args=\"-DHAVE_GST_PATCHES=1\""
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "dir",
|
||||
@@ -50,5 +55,9 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"cleanup-commands": [
|
||||
"mkdir -p /app/lib/ffmpeg",
|
||||
"ln -s /lib/$FLATPAK_ARCH-linux-*/gstreamer-1.0/libgstpipewire.so /app/lib/gstreamer-1.0/"
|
||||
]
|
||||
}
|
||||
|
Submodule pkgs/flatpak/flathub updated: 2a3ed05245...017cf7b263
23
pkgs/flatpak/testing/a52dec-configure-optflags.patch
Normal file
23
pkgs/flatpak/testing/a52dec-configure-optflags.patch
Normal file
@@ -0,0 +1,23 @@
|
||||
--- ./configure~ 2002-07-28 06:50:42.000000000 +0300
|
||||
+++ ./configure 2003-04-13 17:20:53.000000000 +0300
|
||||
@@ -5366,13 +5366,13 @@
|
||||
|
||||
case "$host" in
|
||||
i?86-* | k?-*)
|
||||
- case "$host" in
|
||||
- i386-*) TRY_CFLAGS="$OPT_CFLAGS -mcpu=i386";;
|
||||
- i486-*) TRY_CFLAGS="$OPT_CFLAGS -mcpu=i486";;
|
||||
- i586-*) TRY_CFLAGS="$OPT_CFLAGS -mcpu=pentium";;
|
||||
- i686-*) TRY_CFLAGS="$OPT_CFLAGS -mcpu=pentiumpro";;
|
||||
- k6-*) TRY_CFLAGS="$OPT_CFLAGS -mcpu=k6";;
|
||||
- esac
|
||||
+# case "$host" in
|
||||
+# i386-*) TRY_CFLAGS="$OPT_CFLAGS -mcpu=i386";;
|
||||
+# i486-*) TRY_CFLAGS="$OPT_CFLAGS -mcpu=i486";;
|
||||
+# i586-*) TRY_CFLAGS="$OPT_CFLAGS -mcpu=pentium";;
|
||||
+# i686-*) TRY_CFLAGS="$OPT_CFLAGS -mcpu=pentiumpro";;
|
||||
+# k6-*) TRY_CFLAGS="$OPT_CFLAGS -mcpu=k6";;
|
||||
+# esac
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports $TRY_CFLAGS $CFLAGS flags" >&5
|
||||
printf %s "checking if $CC supports $TRY_CFLAGS $CFLAGS flags... " >&6; }
|
||||
SAVE_CFLAGS="$CFLAGS"
|
25
pkgs/flatpak/testing/dav1d.json
Normal file
25
pkgs/flatpak/testing/dav1d.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "dav1d",
|
||||
"buildsystem": "meson",
|
||||
"only-arches": [
|
||||
"x86_64"
|
||||
],
|
||||
"config-opts": [
|
||||
"-Denable_tools=false",
|
||||
"-Denable_examples=false",
|
||||
"-Denable_tests=false",
|
||||
"-Denable_docs=false",
|
||||
"-Dlogging=false"
|
||||
],
|
||||
"cleanup": [
|
||||
"/include",
|
||||
"/lib/pkgconfig"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://code.videolan.org/videolan/dav1d.git",
|
||||
"branch": "master"
|
||||
}
|
||||
]
|
||||
}
|
26
pkgs/flatpak/testing/gst-plugins-rs.json
Normal file
26
pkgs/flatpak/testing/gst-plugins-rs.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "gst-plugins-rs",
|
||||
"buildsystem": "simple",
|
||||
"only-arches": [
|
||||
"x86_64"
|
||||
],
|
||||
"build-options": {
|
||||
"build-args": [
|
||||
"--share=network"
|
||||
],
|
||||
"env": {
|
||||
"CARGO_HOME": "/run/build/gst-plugins-rs/cargo"
|
||||
}
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git",
|
||||
"branch": "main"
|
||||
}
|
||||
],
|
||||
"build-commands": [
|
||||
"cargo install cargo-c",
|
||||
"cargo cinstall --prefix=/app -p gst-plugin-dav1d"
|
||||
]
|
||||
}
|
56
pkgs/flatpak/testing/gstreamer.json
Normal file
56
pkgs/flatpak/testing/gstreamer.json
Normal file
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"name": "gstreamer",
|
||||
"buildsystem": "meson",
|
||||
"config-opts": [
|
||||
"--wrap-mode=nodownload",
|
||||
|
||||
"-Dbase=enabled",
|
||||
"-Dgood=enabled",
|
||||
"-Dbad=enabled",
|
||||
"-Dugly=enabled",
|
||||
"-Dlibav=enabled",
|
||||
"-Dvaapi=enabled",
|
||||
"-Dsharp=disabled",
|
||||
"-Drs=disabled",
|
||||
"-Dpython=disabled",
|
||||
"-Ddevtools=disabled",
|
||||
"-Dges=disabled",
|
||||
"-Drtsp_server=disabled",
|
||||
"-Dgst-examples=disabled",
|
||||
"-Dqt5=disabled",
|
||||
"-Dtests=disabled",
|
||||
"-Dexamples=disabled",
|
||||
"-Dintrospection=enabled",
|
||||
"-Ddoc=disabled",
|
||||
"-Dgtk_doc=disabled",
|
||||
"-Dgpl=enabled",
|
||||
|
||||
"-Dgstreamer:benchmarks=disabled",
|
||||
|
||||
"-Dgst-plugins-base:gl_api=opengl,gles2",
|
||||
"-Dgst-plugins-base:gl_platform=egl,glx",
|
||||
|
||||
"-Dgst-plugins-good:gtk3=disabled",
|
||||
|
||||
"-Dgst-plugins-bad:vulkan=disabled",
|
||||
"-Dgst-plugins-bad:webrtc=disabled",
|
||||
"-Dgst-plugins-bad:wasapi=disabled",
|
||||
"-Dgst-plugins-bad:wasapi2=disabled",
|
||||
"-Dgst-plugins-bad:winks=disabled",
|
||||
"-Dgst-plugins-bad:winscreencap=disabled",
|
||||
"-Dgst-plugins-bad:assrender=enabled",
|
||||
"-Dgst-plugins-bad:nvcodec=enabled",
|
||||
"-Dgst-plugins-bad:v4l2codecs=enabled",
|
||||
"-Dgst-plugins-bad:va=enabled",
|
||||
|
||||
"-Dgst-plugins-ugly:mpeg2dec=enabled"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://gitlab.freedesktop.org/gstreamer/gstreamer.git",
|
||||
"branch": "main",
|
||||
"disable-submodules": true
|
||||
}
|
||||
]
|
||||
}
|
20
pkgs/flatpak/testing/gtuber.json
Normal file
20
pkgs/flatpak/testing/gtuber.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "gtuber",
|
||||
"buildsystem": "meson",
|
||||
"config-opts": [
|
||||
"-Dintrospection=disabled",
|
||||
"-Dvapi=disabled",
|
||||
"-Dgst-gtuber=enabled"
|
||||
],
|
||||
"cleanup": [
|
||||
"/include",
|
||||
"/lib/pkgconfig"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/Rafostar/gtuber.git",
|
||||
"branch": "main"
|
||||
}
|
||||
]
|
||||
}
|
24
pkgs/flatpak/testing/liba52.json
Normal file
24
pkgs/flatpak/testing/liba52.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "liba52",
|
||||
"config-opts": [ "--enable-shared", "--disable-static" ],
|
||||
"rm-configure": true,
|
||||
"cleanup": [ "/bin/*a52*" ],
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://distfiles.adelielinux.org/source/a52dec/a52dec-0.8.0.tar.gz",
|
||||
"sha256": "03c181ce9c3fe0d2f5130de18dab9bd8bc63c354071515aa56983c74a9cffcc9"
|
||||
},
|
||||
{
|
||||
"type": "patch",
|
||||
"path": "a52dec-configure-optflags.patch"
|
||||
},
|
||||
{
|
||||
"type": "script",
|
||||
"commands": [
|
||||
"autoreconf -fiv"
|
||||
],
|
||||
"dest-filename": "autogen.sh"
|
||||
}
|
||||
]
|
||||
}
|
21
pkgs/flatpak/testing/libmicrodns.json
Normal file
21
pkgs/flatpak/testing/libmicrodns.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "libmicrodns",
|
||||
"buildsystem": "meson",
|
||||
"config-opts": [
|
||||
"--buildtype=release",
|
||||
"-Dtests=disabled",
|
||||
"-Dexamples=disabled"
|
||||
],
|
||||
"cleanup": [
|
||||
"/include",
|
||||
"/lib/pkgconfig"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/videolabs/libmicrodns.git",
|
||||
"tag": "0.2.0",
|
||||
"commit": "deb7ed7bf05dc26802a0ca1987049b31405b8930"
|
||||
}
|
||||
]
|
||||
}
|
3
pkgs/rpm/.gitignore
vendored
3
pkgs/rpm/.gitignore
vendored
@@ -1,3 +0,0 @@
|
||||
.osc/
|
||||
clapper/
|
||||
.lock
|
@@ -1 +0,0 @@
|
||||
addFilter("explicit-lib-dependency")
|
@@ -1,166 +0,0 @@
|
||||
#
|
||||
# spec file for package clapper
|
||||
#
|
||||
# Copyright (C) 2020 sp1rit
|
||||
# Copyright (C) 2020-21 Rafostar
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
%define debug_package %{nil}
|
||||
|
||||
%global appname com.github.rafostar.Clapper
|
||||
%global gst_version 1.18.0
|
||||
%global gtk4_version 4.0.0
|
||||
%global meson_version 0.50
|
||||
%global glib2_version 2.56.0
|
||||
|
||||
Name: clapper
|
||||
Version: 0.2.1
|
||||
Release: 1%{?dist}
|
||||
Summary: Simple and modern GNOME media player
|
||||
|
||||
License: GPL-3.0
|
||||
URL: https://github.com/Rafostar/clapper
|
||||
BuildRoot: %{_builddir}/%{name}-%{version}-build
|
||||
Source0: _service
|
||||
|
||||
BuildRequires: meson >= %{meson_version}
|
||||
BuildRequires: gtk4-devel >= %{gtk4_version}
|
||||
BuildRequires: glib2-devel >= %{glib2_version}
|
||||
BuildRequires: gobject-introspection-devel
|
||||
BuildRequires: gjs
|
||||
BuildRequires: gcc-c++
|
||||
BuildRequires: desktop-file-utils
|
||||
BuildRequires: hicolor-icon-theme
|
||||
|
||||
Requires: gjs
|
||||
Requires: gtk4 >= %{gtk4_version}
|
||||
Requires: hicolor-icon-theme
|
||||
|
||||
%if 0%{?suse_version}
|
||||
# SUSE recommends group tag, while Fedora discourages their use
|
||||
Group: Productivity/Multimedia/Video/Players
|
||||
|
||||
BuildRequires: update-desktop-files
|
||||
BuildRequires: gstreamer-devel >= %{gst_version}
|
||||
BuildRequires: gstreamer-plugins-base-devel >= %{gst_version}
|
||||
BuildRequires: Mesa-libGLESv2-devel
|
||||
BuildRequires: Mesa-libGLESv3-devel
|
||||
|
||||
Requires: gstreamer >= %{gst_version}
|
||||
Requires: gstreamer-plugins-base >= %{gst_version}
|
||||
Requires: gstreamer-plugins-good >= %{gst_version}
|
||||
Requires: gstreamer-plugins-bad >= %{gst_version}
|
||||
|
||||
# Popular video decoders
|
||||
Recommends: gstreamer-plugins-libav >= %{gst_version}
|
||||
|
||||
# CD Playback
|
||||
Suggests: gstreamer-plugins-ugly
|
||||
# Intel/AMD video acceleration
|
||||
Suggests: gstreamer-plugins-vaapi
|
||||
%else
|
||||
BuildRequires: glibc-all-langpacks
|
||||
BuildRequires: gstreamer1-devel >= %{gst_version}
|
||||
BuildRequires: gstreamer1-plugins-base-devel >= %{gst_version}
|
||||
BuildRequires: mesa-libGL-devel
|
||||
BuildRequires: mesa-libGLES-devel
|
||||
BuildRequires: mesa-libGLU-devel
|
||||
BuildRequires: mesa-libEGL-devel
|
||||
|
||||
Requires: gstreamer1 >= %{gst_version}
|
||||
Requires: gstreamer1-plugins-base >= %{gst_version}
|
||||
Requires: gstreamer1-plugins-good >= %{gst_version}
|
||||
Requires: gstreamer1-plugins-bad-free >= %{gst_version}
|
||||
|
||||
# ASS subtitles (assrender)
|
||||
Recommends: gstreamer1-plugins-bad-free-extras >= %{gst_version}
|
||||
|
||||
# CD Playback
|
||||
Suggests: gstreamer1-plugins-ugly-free
|
||||
# Intel/AMD video acceleration
|
||||
Suggests: gstreamer1-vaapi
|
||||
%endif
|
||||
|
||||
%description
|
||||
A GNOME media player built using GJS with GTK4 toolkit and powered by GStreamer with OpenGL rendering.
|
||||
|
||||
%prep
|
||||
%setup -q -n %{_sourcedir}/%{name}-%{version} -T -D
|
||||
|
||||
%build
|
||||
%meson
|
||||
%meson_build
|
||||
|
||||
%install
|
||||
%meson_install
|
||||
%if 0%{?suse_version}
|
||||
%suse_update_desktop_file %{appname}
|
||||
%endif
|
||||
|
||||
%check
|
||||
desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop
|
||||
|
||||
%files
|
||||
%license COPYING
|
||||
%doc README.md
|
||||
%{_bindir}/%{appname}*
|
||||
%{_datadir}/%{appname}/
|
||||
%{_datadir}/icons/hicolor/*/apps/*.svg
|
||||
%{_datadir}/glib-2.0/schemas/%{appname}.gschema.xml
|
||||
%{_datadir}/mime/packages/%{appname}.xml
|
||||
%{_datadir}/applications/*.desktop
|
||||
%{_datadir}/metainfo/*.metainfo.xml
|
||||
%{_datadir}/gir-1.0/GstClapper-1.0.gir
|
||||
%{_libdir}/%{appname}/
|
||||
|
||||
%changelog
|
||||
* Mon Apr 19 2021 Rafostar <rafostar.github@gmail.com> - 0.2.1-1
|
||||
- New version
|
||||
|
||||
* Tue Apr 13 2021 Rafostar <rafostar.github@gmail.com> - 0.2.0-1
|
||||
- New version
|
||||
|
||||
* Fri Feb 25 2021 Rafostar <rafostar.github@gmail.com> - 0.1.0-1
|
||||
- New version
|
||||
|
||||
* Sun Feb 7 2021 Rafostar <rafostar.github@gmail.com> - 0.0.0-10
|
||||
- Install gstclapper libs to app named subdirectory
|
||||
|
||||
* Fri Feb 5 2021 Rafostar <rafostar.github@gmail.com> - 0.0.0-9
|
||||
- Update build with gstclapper libs support
|
||||
|
||||
* Thu Jan 21 2021 Rafostar <rafostar.github@gmail.com> - 0.0.0-8
|
||||
- Use metainfo instead of deprecated appdata
|
||||
|
||||
* Mon Jan 18 2021 Rafostar <rafostar.github@gmail.com> - 0.0.0-7
|
||||
- Remove gjs-1.0 files
|
||||
|
||||
* Sun Dec 20 2020 Rafostar <rafostar.github@gmail.com> - 0.0.0-6
|
||||
- Include additional app binaries
|
||||
|
||||
* Sat Oct 31 2020 Rafostar <rafostar.github@gmail.com> - 0.0.0-5
|
||||
- Added metainfo
|
||||
|
||||
* Sun Oct 25 2020 Rafostar <rafostar.github@gmail.com> - 0.0.0-4
|
||||
- Added gschema
|
||||
|
||||
* Wed Oct 14 2020 Rafostar <rafostar.github@gmail.com> - 0.0.0-3
|
||||
- Update to GTK4
|
||||
|
||||
* Sat Sep 19 22:02:00 CEST 2020 sp1rit - 0.0.0-2
|
||||
- Added suse_update_desktop_file macro for SuSE packages
|
||||
|
||||
* Fri Sep 18 2020 Rafostar <rafostar.github@gmail.com> - 0.0.0-1
|
||||
- Initial package
|
105
src/actions.js
105
src/actions.js
@@ -1,105 +0,0 @@
|
||||
const { Gtk } = imports.gi;
|
||||
const Dialogs = imports.src.dialogs;
|
||||
const Misc = imports.src.misc;
|
||||
|
||||
var actions = {
|
||||
open_local: ['<Ctrl>O'],
|
||||
export_playlist: ['<Ctrl>E'],
|
||||
open_uri: ['<Ctrl>U'],
|
||||
prefs: null,
|
||||
shortcuts: ['F1', '<Ctrl>question'],
|
||||
about: null,
|
||||
progress_forward: ['Right'],
|
||||
progress_backward: ['Left'],
|
||||
next_chapter: ['<Shift>Right'],
|
||||
prev_chapter: ['<Shift>Left'],
|
||||
next_track: ['<Ctrl>Right'],
|
||||
prev_track: ['<Ctrl>Left'],
|
||||
volume_up: ['Up'],
|
||||
volume_down: ['Down'],
|
||||
toggle_play: ['space'],
|
||||
change_repeat: ['<Ctrl>r'],
|
||||
reveal_controls: ['Return'],
|
||||
toggle_fullscreen: ['F11', 'f'],
|
||||
quit: ['<Ctrl>q', 'q'],
|
||||
};
|
||||
|
||||
function handleAction(action, window)
|
||||
{
|
||||
const clapperWidget = window.child;
|
||||
if(!clapperWidget) return;
|
||||
|
||||
const { player } = clapperWidget;
|
||||
let bool = false;
|
||||
|
||||
switch(action.name) {
|
||||
case 'open_local':
|
||||
case 'export_playlist':
|
||||
new Dialogs.FileChooser(window, action.name);
|
||||
break;
|
||||
case 'open_uri':
|
||||
new Dialogs.UriDialog(window);
|
||||
break;
|
||||
case 'prefs':
|
||||
new Dialogs.PrefsDialog(window);
|
||||
break;
|
||||
case 'shortcuts':
|
||||
if(!window.get_help_overlay()) {
|
||||
const clapperPath = Misc.getClapperPath();
|
||||
const helpBuilder = Gtk.Builder.new_from_file(
|
||||
`${clapperPath}/ui/help-overlay.ui`
|
||||
);
|
||||
window.set_help_overlay(helpBuilder.get_object('help_overlay'));
|
||||
}
|
||||
clapperWidget.activate_action('win.show-help-overlay', null);
|
||||
break;
|
||||
case 'about':
|
||||
new Dialogs.AboutDialog(window);
|
||||
break;
|
||||
case 'progress_forward':
|
||||
bool = true;
|
||||
case 'progress_backward':
|
||||
player.adjust_position(bool);
|
||||
if(
|
||||
clapperWidget.isReleaseKeyEnabled
|
||||
&& clapperWidget.isFullscreenMode
|
||||
)
|
||||
clapperWidget.revealControls();
|
||||
/* Actual seek is handled on release */
|
||||
clapperWidget.isReleaseKeyEnabled = true;
|
||||
if(!clapperWidget.has_focus)
|
||||
clapperWidget.grab_focus();
|
||||
break;
|
||||
case 'volume_up':
|
||||
bool = true;
|
||||
case 'volume_down':
|
||||
player.adjust_volume(bool);
|
||||
break;
|
||||
case 'next_track':
|
||||
player.playlistWidget.nextTrack();
|
||||
break;
|
||||
case 'prev_track':
|
||||
player.playlistWidget.prevTrack();
|
||||
break;
|
||||
case 'reveal_controls':
|
||||
if(clapperWidget.isFullscreenMode)
|
||||
clapperWidget.revealControls();
|
||||
break;
|
||||
case 'toggle_fullscreen':
|
||||
clapperWidget.toggleFullscreen();
|
||||
break;
|
||||
case 'change_repeat':
|
||||
player.playlistWidget.changeRepeatMode();
|
||||
break;
|
||||
case 'quit':
|
||||
clapperWidget.activate_action('window.close', null);
|
||||
break;
|
||||
case 'toggle_play':
|
||||
case 'next_chapter':
|
||||
case 'prev_chapter':
|
||||
player[action.name]();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
51
src/app.js
51
src/app.js
@@ -1,51 +0,0 @@
|
||||
const { Gio, GObject, Gtk } = imports.gi;
|
||||
const { AppBase } = imports.src.appBase;
|
||||
const { Widget } = imports.src.widget;
|
||||
const Debug = imports.src.debug;
|
||||
|
||||
const { debug } = Debug;
|
||||
|
||||
var App = GObject.registerClass(
|
||||
class ClapperApp extends AppBase
|
||||
{
|
||||
_init()
|
||||
{
|
||||
super._init();
|
||||
|
||||
this.flags |= Gio.ApplicationFlags.HANDLES_OPEN;
|
||||
}
|
||||
|
||||
vfunc_startup()
|
||||
{
|
||||
super.vfunc_startup();
|
||||
|
||||
const window = this.active_window;
|
||||
const clapperWidget = new Widget();
|
||||
const dummyHeaderbar = new Gtk.Box({
|
||||
can_focus: false,
|
||||
focusable: false,
|
||||
visible: false,
|
||||
});
|
||||
|
||||
window.add_css_class('nobackground');
|
||||
window.set_child(clapperWidget);
|
||||
window.set_titlebar(dummyHeaderbar);
|
||||
|
||||
this.mapSignal = window.connect('map', this._onWindowMap.bind(this));
|
||||
}
|
||||
|
||||
vfunc_open(files, hint)
|
||||
{
|
||||
super.vfunc_open(files, hint);
|
||||
|
||||
this._openFilesAsync(files).then(() => this.activate()).catch(debug);
|
||||
}
|
||||
|
||||
_onWindowMap(window)
|
||||
{
|
||||
window.disconnect(this.mapSignal);
|
||||
this.mapSignal = null;
|
||||
|
||||
window.child._onWindowMap(window);
|
||||
}
|
||||
});
|
158
src/appBase.js
158
src/appBase.js
@@ -1,158 +0,0 @@
|
||||
const { Gio, GLib, GObject, Gtk } = imports.gi;
|
||||
const Debug = imports.src.debug;
|
||||
const FileOps = imports.src.fileOps;
|
||||
const Misc = imports.src.misc;
|
||||
const Actions = imports.src.actions;
|
||||
|
||||
const { debug } = Debug;
|
||||
const { settings } = Misc;
|
||||
|
||||
var AppBase = GObject.registerClass(
|
||||
class ClapperAppBase extends Gtk.Application
|
||||
{
|
||||
_init()
|
||||
{
|
||||
super._init({
|
||||
application_id: Misc.appId,
|
||||
});
|
||||
|
||||
this.doneFirstActivate = false;
|
||||
this.isFileAppend = false;
|
||||
}
|
||||
|
||||
vfunc_startup()
|
||||
{
|
||||
super.vfunc_startup();
|
||||
|
||||
const window = new Gtk.ApplicationWindow({
|
||||
application: this,
|
||||
title: Misc.appName,
|
||||
});
|
||||
|
||||
if(Gtk.MINOR_VERSION > 0 || Gtk.MICRO_VERSION > 1)
|
||||
window.add_css_class('gtk402');
|
||||
|
||||
if(!settings.get_boolean('render-shadows'))
|
||||
window.add_css_class('gpufriendly');
|
||||
|
||||
window.add_css_class('gpufriendlyfs');
|
||||
}
|
||||
|
||||
vfunc_activate()
|
||||
{
|
||||
super.vfunc_activate();
|
||||
|
||||
if(!this.doneFirstActivate)
|
||||
this._onFirstActivate();
|
||||
|
||||
this.active_window.present_with_time(
|
||||
Math.floor(GLib.get_monotonic_time() / 1000)
|
||||
);
|
||||
}
|
||||
|
||||
async _openFilesAsync(files)
|
||||
{
|
||||
const urisArr = [];
|
||||
|
||||
for(let file of files) {
|
||||
const uri = file.get_uri();
|
||||
if(!uri.startsWith('file:')) {
|
||||
urisArr.push(uri);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If file is not a dir its URI will be returned in an array */
|
||||
const uris = await FileOps.getDirFilesUrisPromise(file).catch(debug);
|
||||
if(uris && uris.length)
|
||||
urisArr.push(...uris);
|
||||
}
|
||||
|
||||
const [playlist, subs] = Misc.parsePlaylistFiles(urisArr);
|
||||
const { player } = this.active_window.get_child();
|
||||
const action = (this.isFileAppend) ? 'append' : 'set';
|
||||
|
||||
if(playlist && playlist.length)
|
||||
player[`${action}_playlist`](playlist);
|
||||
if(subs)
|
||||
player.set_subtitles(subs);
|
||||
|
||||
/* Restore default behavior */
|
||||
this.isFileAppend = false;
|
||||
}
|
||||
|
||||
_onFirstActivate()
|
||||
{
|
||||
for(let name in Actions.actions) {
|
||||
const simpleAction = new Gio.SimpleAction({ name });
|
||||
simpleAction.connect('activate', (action) =>
|
||||
Actions.handleAction(action, this.active_window)
|
||||
);
|
||||
this.add_action(simpleAction);
|
||||
|
||||
const accels = Actions.actions[name];
|
||||
if(accels)
|
||||
this.set_accels_for_action(`app.${name}`, accels);
|
||||
}
|
||||
|
||||
const gtkSettings = Gtk.Settings.get_default();
|
||||
settings.bind(
|
||||
'dark-theme', gtkSettings,
|
||||
'gtk-application-prefer-dark-theme',
|
||||
Gio.SettingsBindFlags.GET
|
||||
);
|
||||
this._onThemeChanged(gtkSettings);
|
||||
this._onIconThemeChanged(gtkSettings);
|
||||
gtkSettings.connect('notify::gtk-theme-name', this._onThemeChanged.bind(this));
|
||||
gtkSettings.connect('notify::gtk-icon-theme-name', this._onIconThemeChanged.bind(this));
|
||||
this.doneFirstActivate = true;
|
||||
}
|
||||
|
||||
_onThemeChanged(gtkSettings)
|
||||
{
|
||||
const theme = gtkSettings.gtk_theme_name;
|
||||
const window = this.active_window;
|
||||
const hasAdwThemeDark = window.has_css_class('adwthemedark');
|
||||
|
||||
debug(`user selected theme: ${theme}`);
|
||||
|
||||
/* FIXME: AFAIK there is no way to detect theme rounded corners.
|
||||
Having 2/4 corners rounded in floating mode is not good. */
|
||||
if(!window.has_css_class('adwrounded'))
|
||||
window.add_css_class('adwrounded');
|
||||
|
||||
if(theme.startsWith('Adwaita') || theme.startsWith('Default')) {
|
||||
const isDarkTheme = settings.get_boolean('dark-theme');
|
||||
|
||||
if(isDarkTheme && !hasAdwThemeDark)
|
||||
window.add_css_class('adwthemedark');
|
||||
else if(!isDarkTheme && hasAdwThemeDark)
|
||||
window.remove_css_class('adwthemedark');
|
||||
}
|
||||
else if(hasAdwThemeDark)
|
||||
window.remove_css_class('adwthemedark');
|
||||
|
||||
if(!theme.endsWith('-dark'))
|
||||
return;
|
||||
|
||||
/* We need to request a default theme with optional dark variant
|
||||
to make the "gtk_application_prefer_dark_theme" setting work */
|
||||
const parsedTheme = theme.substring(0, theme.lastIndexOf('-'));
|
||||
|
||||
gtkSettings.gtk_theme_name = parsedTheme;
|
||||
debug(`set theme: ${parsedTheme}`);
|
||||
}
|
||||
|
||||
_onIconThemeChanged(gtkSettings)
|
||||
{
|
||||
const iconTheme = gtkSettings.gtk_icon_theme_name;
|
||||
const window = this.active_window;
|
||||
const hasAdwIcons = window.has_css_class('adwicons');
|
||||
|
||||
if(iconTheme === 'Adwaita' || iconTheme === 'Default') {
|
||||
if(!hasAdwIcons)
|
||||
window.add_css_class('adwicons');
|
||||
}
|
||||
else if(hasAdwIcons)
|
||||
window.remove_css_class('adwicons');
|
||||
}
|
||||
});
|
@@ -1,23 +0,0 @@
|
||||
const { GObject } = imports.gi;
|
||||
const { AppBase } = imports.src.appBase;
|
||||
const { HeaderBarRemote } = imports.src.headerbarRemote;
|
||||
const { WidgetRemote } = imports.src.widgetRemote;
|
||||
|
||||
var AppRemote = GObject.registerClass(
|
||||
class ClapperAppRemote extends AppBase
|
||||
{
|
||||
vfunc_startup()
|
||||
{
|
||||
super.vfunc_startup();
|
||||
|
||||
const window = this.active_window;
|
||||
|
||||
const clapperWidget = new WidgetRemote();
|
||||
window.set_child(clapperWidget);
|
||||
|
||||
const headerBar = new HeaderBarRemote();
|
||||
window.set_titlebar(headerBar);
|
||||
|
||||
window.maximize();
|
||||
}
|
||||
});
|
@@ -1,151 +0,0 @@
|
||||
/* Copyright (C) 2012-present by fent
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
const jsVarStr = '[a-zA-Z_\\$][a-zA-Z_0-9]*';
|
||||
const jsSingleQuoteStr = `'[^'\\\\]*(:?\\\\[\\s\\S][^'\\\\]*)*'`;
|
||||
const jsDoubleQuoteStr = `"[^"\\\\]*(:?\\\\[\\s\\S][^"\\\\]*)*"`;
|
||||
const jsQuoteStr = `(?:${jsSingleQuoteStr}|${jsDoubleQuoteStr})`;
|
||||
const jsKeyStr = `(?:${jsVarStr}|${jsQuoteStr})`;
|
||||
const jsPropStr = `(?:\\.${jsVarStr}|\\[${jsQuoteStr}\\])`;
|
||||
const jsEmptyStr = `(?:''|"")`;
|
||||
const reverseStr = ':function\\(a\\)\\{' +
|
||||
'(?:return )?a\\.reverse\\(\\)' +
|
||||
'\\}';
|
||||
const sliceStr = ':function\\(a,b\\)\\{' +
|
||||
'return a\\.slice\\(b\\)' +
|
||||
'\\}';
|
||||
const spliceStr = ':function\\(a,b\\)\\{' +
|
||||
'a\\.splice\\(0,b\\)' +
|
||||
'\\}';
|
||||
const swapStr = ':function\\(a,b\\)\\{' +
|
||||
'var c=a\\[0\\];a\\[0\\]=a\\[b(?:%a\\.length)?\\];a\\[b(?:%a\\.length)?\\]=c(?:;return a)?' +
|
||||
'\\}';
|
||||
const actionsObjRegexp = new RegExp(
|
||||
`var (${jsVarStr})=\\{((?:(?:${
|
||||
jsKeyStr}${reverseStr}|${
|
||||
jsKeyStr}${sliceStr}|${
|
||||
jsKeyStr}${spliceStr}|${
|
||||
jsKeyStr}${swapStr
|
||||
}),?\\r?\\n?)+)\\};`);
|
||||
const actionsFuncRegexp = new RegExp(`${`function(?: ${jsVarStr})?\\(a\\)\\{` +
|
||||
`a=a\\.split\\(${jsEmptyStr}\\);\\s*` +
|
||||
`((?:(?:a=)?${jsVarStr}`}${
|
||||
jsPropStr
|
||||
}\\(a,\\d+\\);)+)` +
|
||||
`return a\\.join\\(${jsEmptyStr}\\)` +
|
||||
`\\}`);
|
||||
const reverseRegexp = new RegExp(`(?:^|,)(${jsKeyStr})${reverseStr}`, 'm');
|
||||
const sliceRegexp = new RegExp(`(?:^|,)(${jsKeyStr})${sliceStr}`, 'm');
|
||||
const spliceRegexp = new RegExp(`(?:^|,)(${jsKeyStr})${spliceStr}`, 'm');
|
||||
const swapRegexp = new RegExp(`(?:^|,)(${jsKeyStr})${swapStr}`, 'm');
|
||||
|
||||
const swapHeadAndPosition = (arr, position) => {
|
||||
const first = arr[0];
|
||||
arr[0] = arr[position % arr.length];
|
||||
arr[position] = first;
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
function decipher(sig, tokens) {
|
||||
sig = sig.split('');
|
||||
tokens = tokens.split(',');
|
||||
|
||||
for(let i = 0, len = tokens.length; i < len; i++) {
|
||||
let token = tokens[i], pos;
|
||||
switch (token[0]) {
|
||||
case 'r':
|
||||
sig = sig.reverse();
|
||||
break;
|
||||
case 'w':
|
||||
pos = ~~token.slice(1);
|
||||
sig = swapHeadAndPosition(sig, pos);
|
||||
break;
|
||||
case 's':
|
||||
pos = ~~token.slice(1);
|
||||
sig = sig.slice(pos);
|
||||
break;
|
||||
case 'p':
|
||||
pos = ~~token.slice(1);
|
||||
sig.splice(0, pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return sig.join('');
|
||||
};
|
||||
|
||||
function extractActions(body) {
|
||||
const objResult = actionsObjRegexp.exec(body);
|
||||
const funcResult = actionsFuncRegexp.exec(body);
|
||||
|
||||
if(!objResult || !funcResult)
|
||||
return null;
|
||||
|
||||
const obj = objResult[1].replace(/\$/g, '\\$');
|
||||
const objBody = objResult[2].replace(/\$/g, '\\$');
|
||||
const funcBody = funcResult[1].replace(/\$/g, '\\$');
|
||||
|
||||
let result = reverseRegexp.exec(objBody);
|
||||
const reverseKey = result && result[1]
|
||||
.replace(/\$/g, '\\$')
|
||||
.replace(/\$|^'|^"|'$|"$/g, '');
|
||||
result = sliceRegexp.exec(objBody);
|
||||
const sliceKey = result && result[1]
|
||||
.replace(/\$/g, '\\$')
|
||||
.replace(/\$|^'|^"|'$|"$/g, '');
|
||||
result = spliceRegexp.exec(objBody);
|
||||
const spliceKey = result && result[1]
|
||||
.replace(/\$/g, '\\$')
|
||||
.replace(/\$|^'|^"|'$|"$/g, '');
|
||||
result = swapRegexp.exec(objBody);
|
||||
const swapKey = result && result[1]
|
||||
.replace(/\$/g, '\\$')
|
||||
.replace(/\$|^'|^"|'$|"$/g, '');
|
||||
|
||||
const keys = `(${[reverseKey, sliceKey, spliceKey, swapKey].join('|')})`;
|
||||
const myreg = `(?:a=)?${obj
|
||||
}(?:\\.${keys}|\\['${keys}'\\]|\\["${keys}"\\])` +
|
||||
`\\(a,(\\d+)\\)`;
|
||||
const tokenizeRegexp = new RegExp(myreg, 'g');
|
||||
const tokens = [];
|
||||
|
||||
while((result = tokenizeRegexp.exec(funcBody)) !== null) {
|
||||
const key = result[1] || result[2] || result[3];
|
||||
const pos = result[4];
|
||||
switch (key) {
|
||||
case swapKey:
|
||||
tokens.push(`w${result[4]}`);
|
||||
break;
|
||||
case reverseKey:
|
||||
tokens.push('r');
|
||||
break;
|
||||
case sliceKey:
|
||||
tokens.push(`s${result[4]}`);
|
||||
break;
|
||||
case spliceKey:
|
||||
tokens.push(`p${result[4]}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return tokens.join(',');
|
||||
}
|
69
src/bin/clapper-app/clapper-app-about-window.c
Normal file
69
src/bin/clapper-app/clapper-app-about-window.c
Normal file
@@ -0,0 +1,69 @@
|
||||
/* Clapper Application
|
||||
* Copyright (C) 2024 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gst/gst.h>
|
||||
#include <adwaita.h>
|
||||
|
||||
#include "clapper-app-about-window.h"
|
||||
|
||||
GtkWidget *
|
||||
clapper_app_about_window_new (GtkApplication *gtk_app)
|
||||
{
|
||||
AdwAboutWindow *about;
|
||||
GtkWindow *window;
|
||||
GString *string;
|
||||
gchar *gst_ver, *debug_info;
|
||||
|
||||
about = ADW_ABOUT_WINDOW (adw_about_window_new_from_appdata (
|
||||
CLAPPER_APP_RESOURCE_PREFIX "/data/metainfo/" CLAPPER_APP_ID ".metainfo.xml",
|
||||
NULL));
|
||||
window = gtk_application_get_active_window (gtk_app);
|
||||
|
||||
gtk_window_set_modal (GTK_WINDOW (about), TRUE);
|
||||
gtk_window_set_transient_for (GTK_WINDOW (about), window);
|
||||
|
||||
/* TRANSLATORS: Put your name(s) here for credits or leave untranslated */
|
||||
adw_about_window_set_translator_credits (about, _("translator-credits"));
|
||||
|
||||
string = g_string_new (NULL);
|
||||
|
||||
g_string_append_printf (string, "GLib %u.%u.%u\n",
|
||||
glib_major_version,
|
||||
glib_minor_version,
|
||||
glib_micro_version);
|
||||
g_string_append_printf (string, "GTK %u.%u.%u\n",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
g_string_append_printf (string, "Adwaita %u.%u.%u\n",
|
||||
adw_get_major_version (),
|
||||
adw_get_minor_version (),
|
||||
adw_get_micro_version ());
|
||||
|
||||
gst_ver = gst_version_string ();
|
||||
g_string_append (string, gst_ver);
|
||||
g_free (gst_ver);
|
||||
|
||||
debug_info = g_string_free_and_steal (string);
|
||||
adw_about_window_set_debug_info (about, debug_info);
|
||||
g_free (debug_info);
|
||||
|
||||
return GTK_WIDGET (about);
|
||||
}
|
29
src/bin/clapper-app/clapper-app-about-window.h
Normal file
29
src/bin/clapper-app/clapper-app-about-window.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/* Clapper Application
|
||||
* Copyright (C) 2024 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GtkWidget * clapper_app_about_window_new (GtkApplication *gtk_app);
|
||||
|
||||
G_END_DECLS
|
585
src/bin/clapper-app/clapper-app-application.c
Normal file
585
src/bin/clapper-app/clapper-app-application.c
Normal file
@@ -0,0 +1,585 @@
|
||||
/* Clapper Application
|
||||
* Copyright (C) 2024 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <gst/gst.h>
|
||||
#include <clapper-gtk/clapper-gtk.h>
|
||||
|
||||
#include "clapper-app-application.h"
|
||||
#include "clapper-app-window.h"
|
||||
#include "clapper-app-file-dialog.h"
|
||||
#include "clapper-app-uri-dialog.h"
|
||||
#include "clapper-app-info-window.h"
|
||||
#include "clapper-app-preferences-window.h"
|
||||
#include "clapper-app-about-window.h"
|
||||
#include "clapper-app-utils.h"
|
||||
|
||||
#define PERCENTAGE_ROUND(a) (round ((gdouble) a / 0.01) * 0.01)
|
||||
|
||||
#define GST_CAT_DEFAULT clapper_app_application_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
||||
struct _ClapperAppApplication
|
||||
{
|
||||
GtkApplication parent;
|
||||
|
||||
GSettings *settings;
|
||||
|
||||
gboolean need_init_state;
|
||||
};
|
||||
|
||||
struct ClapperPluginFeatureData
|
||||
{
|
||||
const gchar *name;
|
||||
GstRank rank;
|
||||
};
|
||||
|
||||
struct ClapperPluginData
|
||||
{
|
||||
const gchar *name;
|
||||
guint skip_version[3];
|
||||
struct ClapperPluginFeatureData features[10];
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const gchar *action;
|
||||
const gchar *accels[3];
|
||||
} ClapperAppShortcut;
|
||||
|
||||
#define parent_class clapper_app_application_parent_class
|
||||
G_DEFINE_TYPE (ClapperAppApplication, clapper_app_application, GTK_TYPE_APPLICATION);
|
||||
|
||||
static inline void
|
||||
_set_initial_plugin_feature_ranks (void)
|
||||
{
|
||||
GstRegistry *registry = gst_registry_get ();
|
||||
guint i;
|
||||
|
||||
const struct ClapperPluginData plugins_data[] = {
|
||||
{
|
||||
.name = "va",
|
||||
.skip_version = { 1, 24, 0 },
|
||||
.features = {
|
||||
{ "vah264dec", GST_RANK_PRIMARY + 24 },
|
||||
{ "vah265dec", GST_RANK_PRIMARY + 24 },
|
||||
{ "vavp8dec", GST_RANK_PRIMARY + 24 },
|
||||
{ "vavp9dec", GST_RANK_PRIMARY + 24 },
|
||||
{ "vaav1dec", GST_RANK_PRIMARY + 24 },
|
||||
{ NULL, 0 }
|
||||
}
|
||||
},
|
||||
{
|
||||
.name = "nvcodec",
|
||||
.skip_version = { 1, 24, 0 },
|
||||
.features = {
|
||||
{ "nvh264dec", GST_RANK_PRIMARY + 28 },
|
||||
{ "nvh265dec", GST_RANK_PRIMARY + 28 },
|
||||
{ "nvvp8dec", GST_RANK_PRIMARY + 28 },
|
||||
{ "nvvp9dec", GST_RANK_PRIMARY + 28 },
|
||||
{ "nvav1dec", GST_RANK_PRIMARY + 28 },
|
||||
{ NULL, 0 }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (plugins_data); ++i) {
|
||||
GList *features;
|
||||
|
||||
if (!(features = gst_registry_get_feature_list_by_plugin (
|
||||
registry, plugins_data[i].name)))
|
||||
continue;
|
||||
|
||||
if (g_list_length (features) > 0) {
|
||||
guint j;
|
||||
|
||||
for (j = 0; G_N_ELEMENTS (plugins_data[i].features); ++j) {
|
||||
GstPluginFeature *feature;
|
||||
|
||||
if (!plugins_data[i].features[j].name)
|
||||
break;
|
||||
|
||||
if (!(feature = gst_registry_lookup_feature (registry,
|
||||
plugins_data[i].features[j].name)))
|
||||
continue;
|
||||
|
||||
if (!gst_plugin_feature_check_version (feature,
|
||||
plugins_data[i].skip_version[0],
|
||||
plugins_data[i].skip_version[1],
|
||||
plugins_data[i].skip_version[2])) {
|
||||
gst_plugin_feature_set_rank (feature,
|
||||
plugins_data[i].features[j].rank);
|
||||
GST_DEBUG ("Initially set \"%s\" rank to: %i",
|
||||
plugins_data[i].features[j].name,
|
||||
plugins_data[i].features[j].rank);
|
||||
}
|
||||
gst_object_unref (feature);
|
||||
}
|
||||
}
|
||||
|
||||
gst_plugin_feature_list_free (features);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_iter_ranks_func (const gchar *feature_name, GstRank rank,
|
||||
gboolean from_env, gpointer user_data G_GNUC_UNUSED)
|
||||
{
|
||||
GstPluginFeature *feature;
|
||||
|
||||
if ((feature = gst_registry_find_feature (gst_registry_get (),
|
||||
feature_name, GST_TYPE_ELEMENT_FACTORY))) {
|
||||
gst_plugin_feature_set_rank (feature, rank);
|
||||
GST_INFO ("Set \"%s\" rank to: %i", feature_name, rank);
|
||||
|
||||
gst_object_unref (feature);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
plugin_feature_ranks_settings_changed_cb (GSettings *settings,
|
||||
gchar *key G_GNUC_UNUSED, gpointer user_data G_GNUC_UNUSED)
|
||||
{
|
||||
clapper_app_utils_iterate_plugin_feature_ranks (settings,
|
||||
(ClapperAppUtilsIterRanks) _iter_ranks_func, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
_assemble_initial_state (GtkWindow *window)
|
||||
{
|
||||
GtkWidget *stack = gtk_window_get_child (window);
|
||||
GtkBuilder *builder = gtk_builder_new_from_resource (
|
||||
CLAPPER_APP_RESOURCE_PREFIX "/ui/clapper-app-initial-state.ui");
|
||||
GtkWidget *initial_state = GTK_WIDGET (gtk_builder_get_object (builder, "initial_state"));
|
||||
|
||||
gtk_stack_add_named (GTK_STACK (stack), initial_state, "initial_state");
|
||||
gtk_stack_set_visible_child (GTK_STACK (stack), initial_state);
|
||||
|
||||
g_object_unref (builder);
|
||||
}
|
||||
|
||||
static void
|
||||
add_files (GSimpleAction *action, GVariant *param, gpointer user_data)
|
||||
{
|
||||
GtkApplication *gtk_app = GTK_APPLICATION (user_data);
|
||||
|
||||
clapper_app_file_dialog_open_files (gtk_app);
|
||||
}
|
||||
|
||||
static void
|
||||
add_uri (GSimpleAction *action, GVariant *param, gpointer user_data)
|
||||
{
|
||||
GtkApplication *gtk_app = GTK_APPLICATION (user_data);
|
||||
|
||||
clapper_app_uri_dialog_open_uri (gtk_app);
|
||||
}
|
||||
|
||||
static void
|
||||
show_preferences (GSimpleAction *action, GVariant *param, gpointer user_data)
|
||||
{
|
||||
GtkApplication *gtk_app = GTK_APPLICATION (user_data);
|
||||
GtkWidget *preferences_window;
|
||||
|
||||
preferences_window = clapper_app_preferences_window_new (gtk_app);
|
||||
gtk_window_present (GTK_WINDOW (preferences_window));
|
||||
}
|
||||
|
||||
static void
|
||||
show_info (GSimpleAction *action, GVariant *param, gpointer user_data)
|
||||
{
|
||||
GtkApplication *gtk_app = GTK_APPLICATION (user_data);
|
||||
GtkWidget *info_window;
|
||||
GtkWindow *window;
|
||||
ClapperPlayer *player;
|
||||
|
||||
window = gtk_application_get_active_window (gtk_app);
|
||||
player = clapper_app_window_get_player (CLAPPER_APP_WINDOW (window));
|
||||
|
||||
info_window = clapper_app_info_window_new (gtk_app, player);
|
||||
gtk_window_present (GTK_WINDOW (info_window));
|
||||
}
|
||||
|
||||
static void
|
||||
show_about (GSimpleAction *action, GVariant *param, gpointer user_data)
|
||||
{
|
||||
GtkApplication *gtk_app = GTK_APPLICATION (user_data);
|
||||
GtkWidget *about_window;
|
||||
|
||||
about_window = clapper_app_about_window_new (gtk_app);
|
||||
gtk_window_present (GTK_WINDOW (about_window));
|
||||
}
|
||||
|
||||
static inline void
|
||||
_restore_settings_to_window (ClapperAppApplication *self, ClapperAppWindow *app_window)
|
||||
{
|
||||
ClapperPlayer *player = clapper_app_window_get_player (app_window);
|
||||
ClapperQueue *queue = clapper_player_get_queue (player);
|
||||
|
||||
GST_DEBUG ("Restoring saved GSettings values to: %" GST_PTR_FORMAT, app_window);
|
||||
|
||||
clapper_player_set_volume (player, PERCENTAGE_ROUND (g_settings_get_double (self->settings, "volume")));
|
||||
clapper_player_set_mute (player, g_settings_get_boolean (self->settings, "mute"));
|
||||
clapper_player_set_speed (player, PERCENTAGE_ROUND (g_settings_get_double (self->settings, "speed")));
|
||||
clapper_player_set_subtitles_enabled (player, g_settings_get_boolean (self->settings, "subtitles-enabled"));
|
||||
clapper_queue_set_progression_mode (queue, g_settings_get_int (self->settings, "progression-mode"));
|
||||
|
||||
if (g_settings_get_boolean (self->settings, "fullscreened"))
|
||||
gtk_window_fullscreen (GTK_WINDOW (app_window));
|
||||
else if (g_settings_get_boolean (self->settings, "maximized"))
|
||||
gtk_window_maximize (GTK_WINDOW (app_window));
|
||||
|
||||
GST_DEBUG ("Configuration restored");
|
||||
}
|
||||
|
||||
static inline void
|
||||
_store_settings_from_window (ClapperAppApplication *self, ClapperAppWindow *app_window)
|
||||
{
|
||||
ClapperPlayer *player = clapper_app_window_get_player (app_window);
|
||||
ClapperQueue *queue = clapper_player_get_queue (player);
|
||||
GtkWindow *window = GTK_WINDOW (app_window);
|
||||
|
||||
GST_DEBUG ("Storing current configuration to GSettings");
|
||||
|
||||
g_settings_set_double (self->settings, "volume", clapper_player_get_volume (player));
|
||||
g_settings_set_boolean (self->settings, "mute", clapper_player_get_mute (player));
|
||||
g_settings_set_double (self->settings, "speed", clapper_player_get_speed (player));
|
||||
g_settings_set_boolean (self->settings, "subtitles-enabled", clapper_player_get_subtitles_enabled (player));
|
||||
g_settings_set_int (self->settings, "progression-mode", clapper_queue_get_progression_mode (queue));
|
||||
|
||||
g_settings_set_boolean (self->settings, "maximized", gtk_window_is_maximized (window));
|
||||
g_settings_set_boolean (self->settings, "fullscreened", gtk_window_is_fullscreen (window));
|
||||
|
||||
GST_DEBUG ("Configuration stored");
|
||||
}
|
||||
|
||||
GApplication *
|
||||
clapper_app_application_new (void)
|
||||
{
|
||||
return g_object_new (CLAPPER_APP_TYPE_APPLICATION,
|
||||
"application-id", CLAPPER_APP_ID,
|
||||
"flags", G_APPLICATION_HANDLES_OPEN,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_app_application_window_removed (GtkApplication *gtk_app, GtkWindow *window)
|
||||
{
|
||||
ClapperAppApplication *self = CLAPPER_APP_APPLICATION_CAST (gtk_app);
|
||||
|
||||
if (CLAPPER_APP_IS_WINDOW (window)) {
|
||||
GList *win, *windows = gtk_application_get_windows (gtk_app);
|
||||
gboolean has_player_windows = FALSE;
|
||||
|
||||
for (win = windows; win != NULL; win = win->next) {
|
||||
GtkWindow *rem_window = GTK_WINDOW (win->data);
|
||||
|
||||
if ((has_player_windows = (rem_window != window
|
||||
&& CLAPPER_APP_IS_WINDOW (rem_window))))
|
||||
break;
|
||||
}
|
||||
|
||||
/* Last player window is closing, time to store settings */
|
||||
if (!has_player_windows)
|
||||
_store_settings_from_window (self, CLAPPER_APP_WINDOW_CAST (window));
|
||||
}
|
||||
|
||||
GTK_APPLICATION_CLASS (parent_class)->window_removed (gtk_app, window);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_app_application_activate (GApplication *app)
|
||||
{
|
||||
ClapperAppApplication *self = CLAPPER_APP_APPLICATION_CAST (app);
|
||||
GtkWindow *window;
|
||||
|
||||
GST_INFO ("Activate");
|
||||
G_APPLICATION_CLASS (parent_class)->activate (app);
|
||||
|
||||
if (!(window = gtk_application_get_active_window (GTK_APPLICATION (app)))) {
|
||||
window = GTK_WINDOW (clapper_app_window_new (GTK_APPLICATION (app)));
|
||||
_restore_settings_to_window (self, CLAPPER_APP_WINDOW_CAST (window));
|
||||
}
|
||||
|
||||
if (self->need_init_state) {
|
||||
_assemble_initial_state (window);
|
||||
self->need_init_state = FALSE;
|
||||
}
|
||||
|
||||
gtk_window_present (window);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clapper_app_application_local_command_line (GApplication *app,
|
||||
gchar ***arguments, gint *exit_status)
|
||||
{
|
||||
gchar **argv = *arguments;
|
||||
guint i;
|
||||
|
||||
/* NOTE: argv is never NULL, so no need to check */
|
||||
|
||||
for (i = 0; argv[i]; ++i) {
|
||||
/* Handle "-" special case as URI */
|
||||
if (strlen (argv[i]) == 1 && argv[i][0] == '-') {
|
||||
g_free (argv[i]);
|
||||
argv[i] = g_strdup ("fd://0");
|
||||
}
|
||||
}
|
||||
|
||||
return G_APPLICATION_CLASS (parent_class)->local_command_line (app, arguments, exit_status);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_is_claps_file (GFile *file)
|
||||
{
|
||||
gchar *basename = g_file_get_basename (file);
|
||||
gboolean is_claps;
|
||||
|
||||
is_claps = (basename && g_str_has_suffix (basename, ".claps"));
|
||||
g_free (basename);
|
||||
|
||||
return is_claps;
|
||||
}
|
||||
|
||||
static void
|
||||
add_item_from_file (GFile *file, ClapperQueue *queue)
|
||||
{
|
||||
ClapperMediaItem *item = clapper_media_item_new_from_file (file);
|
||||
|
||||
GST_DEBUG ("Adding media item with URI: %s",
|
||||
clapper_media_item_get_uri (item));
|
||||
clapper_queue_add_item (queue, item);
|
||||
|
||||
gst_object_unref (item);
|
||||
}
|
||||
|
||||
static void
|
||||
add_items_from_claps_file (GFile *file, ClapperQueue *queue)
|
||||
{
|
||||
GDataInputStream *dstream = NULL;
|
||||
GFileInputStream *stream;
|
||||
GError *error = NULL;
|
||||
gchar *line;
|
||||
|
||||
if (!(stream = g_file_read (file, NULL, &error)))
|
||||
goto finish;
|
||||
|
||||
dstream = g_data_input_stream_new (G_INPUT_STREAM (stream));
|
||||
|
||||
while ((line = g_data_input_stream_read_line (
|
||||
dstream, NULL, NULL, &error))) {
|
||||
g_strstrip (line);
|
||||
|
||||
if (strlen (line) > 0) {
|
||||
GFile *tmp_file = gst_uri_is_valid (line)
|
||||
? g_file_new_for_uri (line)
|
||||
: g_file_new_for_path (line);
|
||||
|
||||
if (_is_claps_file (tmp_file))
|
||||
add_items_from_claps_file (tmp_file, queue);
|
||||
else
|
||||
add_item_from_file (tmp_file, queue);
|
||||
|
||||
g_object_unref (tmp_file);
|
||||
}
|
||||
|
||||
g_free (line);
|
||||
}
|
||||
|
||||
finish:
|
||||
if (error) {
|
||||
GST_ERROR ("Could not read \".claps\" file, reason: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
if (stream) {
|
||||
g_input_stream_close (G_INPUT_STREAM (stream), NULL, NULL);
|
||||
g_object_unref (stream);
|
||||
}
|
||||
g_clear_object (&dstream);
|
||||
}
|
||||
|
||||
static void
|
||||
add_item_with_subtitles (GFile *media_file,
|
||||
GFile *subs_file, ClapperQueue *queue)
|
||||
{
|
||||
ClapperMediaItem *item = clapper_media_item_new_from_file (media_file);
|
||||
gchar *suburi = g_file_get_uri (subs_file);
|
||||
|
||||
GST_DEBUG ("Adding media item with URI: %s, SUBURI: %s",
|
||||
clapper_media_item_get_uri (item), GST_STR_NULL (suburi));
|
||||
clapper_media_item_set_suburi (item, suburi);
|
||||
clapper_queue_add_item (queue, item);
|
||||
|
||||
gst_object_unref (item);
|
||||
g_free (suburi);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_app_application_open (GApplication *app,
|
||||
GFile **files, gint n_files, const gchar *hint)
|
||||
{
|
||||
ClapperAppApplication *self = CLAPPER_APP_APPLICATION_CAST (app);
|
||||
GtkWindow *window;
|
||||
ClapperPlayer *player;
|
||||
ClapperQueue *queue;
|
||||
guint n_before;
|
||||
gboolean add_only, handled = FALSE;
|
||||
|
||||
GST_INFO ("Open");
|
||||
|
||||
/* Since we startup with media,
|
||||
* no need to show initial state */
|
||||
self->need_init_state = FALSE;
|
||||
|
||||
g_application_activate (app);
|
||||
g_application_mark_busy (app);
|
||||
|
||||
window = gtk_application_get_active_window (GTK_APPLICATION (app));
|
||||
while (window && !CLAPPER_APP_IS_WINDOW (window))
|
||||
window = gtk_window_get_transient_for (window);
|
||||
|
||||
clapper_app_window_ensure_no_initial_state (CLAPPER_APP_WINDOW (window));
|
||||
|
||||
player = clapper_app_window_get_player (CLAPPER_APP_WINDOW (window));
|
||||
queue = clapper_player_get_queue (player);
|
||||
|
||||
n_before = clapper_queue_get_n_items (queue);
|
||||
|
||||
/* Special path for opening video with subtitles at once */
|
||||
if (n_files == 2) {
|
||||
gboolean first_subs, second_subs;
|
||||
|
||||
first_subs = clapper_app_utils_is_subtitles_file (files[0]);
|
||||
second_subs = clapper_app_utils_is_subtitles_file (files[1]);
|
||||
|
||||
if ((handled = first_subs != second_subs)) {
|
||||
guint media_index, subs_index;
|
||||
|
||||
media_index = (second_subs) ? 0 : 1;
|
||||
subs_index = (media_index + 1) % 2;
|
||||
|
||||
add_item_with_subtitles (
|
||||
files[media_index], files[subs_index], queue);
|
||||
}
|
||||
}
|
||||
|
||||
if (!handled) {
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < n_files; ++i) {
|
||||
if (_is_claps_file (files[i]))
|
||||
add_items_from_claps_file (files[i], queue);
|
||||
else
|
||||
add_item_from_file (files[i], queue);
|
||||
}
|
||||
}
|
||||
|
||||
add_only = (g_strcmp0 (hint, "add-only") == 0);
|
||||
|
||||
/* Select first thing from added item to play (behave like "open" should),
|
||||
* when queue was empty first item is automatically selected */
|
||||
if (!add_only && n_before > 0)
|
||||
clapper_queue_select_index (queue, n_before);
|
||||
|
||||
g_application_unmark_busy (app);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_app_application_init (ClapperAppApplication *self)
|
||||
{
|
||||
self->need_init_state = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_app_application_constructed (GObject *object)
|
||||
{
|
||||
ClapperAppApplication *self = CLAPPER_APP_APPLICATION_CAST (object);
|
||||
GApplication *app = G_APPLICATION (self);
|
||||
guint i;
|
||||
|
||||
static const GActionEntry app_entries[] = {
|
||||
{ "add-files", add_files, NULL, NULL, NULL },
|
||||
{ "add-uri", add_uri, NULL, NULL, NULL },
|
||||
{ "info", show_info, NULL, NULL, NULL },
|
||||
{ "preferences", show_preferences, NULL, NULL, NULL },
|
||||
{ "about", show_about, NULL, NULL, NULL },
|
||||
};
|
||||
static const ClapperAppShortcut app_shortcuts[] = {
|
||||
{ "app.add-files", { "<Control>o", NULL, NULL }},
|
||||
{ "app.add-uri", { "<Control>u", NULL, NULL }},
|
||||
{ "app.info", { "<Control>i", NULL, NULL }},
|
||||
{ "app.preferences", { "<Control>comma", NULL, NULL }},
|
||||
{ "app.about", { "F1", NULL, NULL }},
|
||||
{ "win.toggle-fullscreen", { "F11", "f", NULL }},
|
||||
{ "win.show-help-overlay", { "<Control>question", NULL, NULL }},
|
||||
{ "window.close", { "<Control>q", "q", NULL }},
|
||||
};
|
||||
|
||||
/* Override initial ranks, they will be updated
|
||||
* from both stored settings and env below */
|
||||
_set_initial_plugin_feature_ranks ();
|
||||
|
||||
self->settings = g_settings_new (CLAPPER_APP_ID);
|
||||
|
||||
g_signal_connect (self->settings,
|
||||
"changed::plugin-feature-ranks",
|
||||
G_CALLBACK (plugin_feature_ranks_settings_changed_cb), self);
|
||||
plugin_feature_ranks_settings_changed_cb (self->settings, NULL, NULL);
|
||||
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (app),
|
||||
app_entries, G_N_ELEMENTS (app_entries), app);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (app_shortcuts); ++i)
|
||||
gtk_application_set_accels_for_action (GTK_APPLICATION (app), app_shortcuts[i].action, app_shortcuts[i].accels);
|
||||
|
||||
g_application_add_option_group (app, gst_init_get_option_group ());
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->constructed (object);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_app_application_finalize (GObject *object)
|
||||
{
|
||||
ClapperAppApplication *self = CLAPPER_APP_APPLICATION_CAST (object);
|
||||
|
||||
GST_TRACE ("Finalize");
|
||||
|
||||
g_object_unref (self->settings);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_app_application_class_init (ClapperAppApplicationClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
GApplicationClass *application_class = (GApplicationClass *) klass;
|
||||
GtkApplicationClass *gtk_application_class = (GtkApplicationClass *) klass;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clapperappapplication", 0,
|
||||
"Clapper App Application");
|
||||
|
||||
gobject_class->constructed = clapper_app_application_constructed;
|
||||
gobject_class->finalize = clapper_app_application_finalize;
|
||||
|
||||
gtk_application_class->window_removed = clapper_app_application_window_removed;
|
||||
|
||||
application_class->activate = clapper_app_application_activate;
|
||||
application_class->local_command_line = clapper_app_application_local_command_line;
|
||||
application_class->open = clapper_app_application_open;
|
||||
}
|
34
src/bin/clapper-app/clapper-app-application.h
Normal file
34
src/bin/clapper-app/clapper-app-application.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/* Clapper Application
|
||||
* Copyright (C) 2024 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLAPPER_APP_TYPE_APPLICATION (clapper_app_application_get_type())
|
||||
#define CLAPPER_APP_APPLICATION_CAST(obj) ((ClapperAppApplication *)(obj))
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ClapperAppApplication, clapper_app_application, CLAPPER_APP, APPLICATION, GtkApplication)
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GApplication * clapper_app_application_new (void);
|
||||
|
||||
G_END_DECLS
|
131
src/bin/clapper-app/clapper-app-file-dialog.c
Normal file
131
src/bin/clapper-app/clapper-app-file-dialog.c
Normal file
@@ -0,0 +1,131 @@
|
||||
/* Clapper Application
|
||||
* Copyright (C) 2024 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "clapper-app-file-dialog.h"
|
||||
#include "clapper-app-utils.h"
|
||||
|
||||
static inline void
|
||||
_open_files_from_model (GtkApplication *gtk_app, GListModel *files_model)
|
||||
{
|
||||
GFile **files = NULL;
|
||||
gint n_files = 0;
|
||||
|
||||
if (clapper_app_utils_files_from_list_model (files_model, &files, &n_files)) {
|
||||
g_application_open (G_APPLICATION (gtk_app), files, n_files, "add-only");
|
||||
clapper_app_utils_files_free (files);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_open_files_cb (GtkFileDialog *dialog, GAsyncResult *result, GtkApplication *gtk_app)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GListModel *files_model = gtk_file_dialog_open_multiple_finish (dialog, result, &error);
|
||||
|
||||
if (G_LIKELY (error == NULL)) {
|
||||
_open_files_from_model (gtk_app, files_model);
|
||||
} else {
|
||||
if (error->domain != GTK_DIALOG_ERROR || error->code != GTK_DIALOG_ERROR_DISMISSED) {
|
||||
g_printerr ("Error: %s\n",
|
||||
(error->message) ? error->message : "Could not open file dialog");
|
||||
}
|
||||
g_error_free (error);
|
||||
}
|
||||
g_clear_object (&files_model);
|
||||
}
|
||||
|
||||
static void
|
||||
_open_subtitles_cb (GtkFileDialog *dialog, GAsyncResult *result, ClapperMediaItem *item)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GFile *file = gtk_file_dialog_open_finish (dialog, result, &error);
|
||||
|
||||
if (G_LIKELY (error == NULL)) {
|
||||
gchar *suburi = g_file_get_uri (file);
|
||||
|
||||
clapper_media_item_set_suburi (item, suburi);
|
||||
g_free (suburi);
|
||||
} else {
|
||||
if (error->domain != GTK_DIALOG_ERROR || error->code != GTK_DIALOG_ERROR_DISMISSED) {
|
||||
g_printerr ("Error: %s\n",
|
||||
(error->message) ? error->message : "Could not open file dialog");
|
||||
}
|
||||
g_error_free (error);
|
||||
}
|
||||
g_clear_object (&file);
|
||||
gst_object_unref (item); // Borrowed reference
|
||||
}
|
||||
|
||||
static void
|
||||
_dialog_add_mime_types (GtkFileDialog *dialog, const gchar *filter_name,
|
||||
const gchar *const *mime_types)
|
||||
{
|
||||
GListStore *filters = g_list_store_new (GTK_TYPE_FILE_FILTER);
|
||||
GtkFileFilter *filter = gtk_file_filter_new ();
|
||||
guint i;
|
||||
|
||||
for (i = 0; mime_types[i]; ++i)
|
||||
gtk_file_filter_add_mime_type (filter, mime_types[i]);
|
||||
|
||||
gtk_file_filter_set_name (filter, filter_name);
|
||||
g_list_store_append (filters, filter);
|
||||
|
||||
gtk_file_dialog_set_filters (dialog, G_LIST_MODEL (filters));
|
||||
|
||||
g_object_unref (filters);
|
||||
g_object_unref (filter);
|
||||
}
|
||||
|
||||
void
|
||||
clapper_app_file_dialog_open_files (GtkApplication *gtk_app)
|
||||
{
|
||||
GtkWindow *window = gtk_application_get_active_window (gtk_app);
|
||||
GtkFileDialog *dialog = gtk_file_dialog_new ();
|
||||
|
||||
_dialog_add_mime_types (dialog, "Media Files",
|
||||
clapper_app_utils_get_mime_types ());
|
||||
|
||||
gtk_file_dialog_set_modal (dialog, TRUE);
|
||||
gtk_file_dialog_set_title (dialog, "Add Files");
|
||||
|
||||
gtk_file_dialog_open_multiple (dialog, window, NULL,
|
||||
(GAsyncReadyCallback) _open_files_cb,
|
||||
gtk_app);
|
||||
|
||||
g_object_unref (dialog);
|
||||
}
|
||||
|
||||
void
|
||||
clapper_app_file_dialog_open_subtitles (GtkApplication *gtk_app, ClapperMediaItem *item)
|
||||
{
|
||||
GtkWindow *window = gtk_application_get_active_window (gtk_app);
|
||||
GtkFileDialog *dialog = gtk_file_dialog_new ();
|
||||
|
||||
_dialog_add_mime_types (dialog, "Subtitles",
|
||||
clapper_app_utils_get_subtitles_mime_types ());
|
||||
|
||||
gtk_file_dialog_set_modal (dialog, TRUE);
|
||||
gtk_file_dialog_set_title (dialog, "Open Subtitles");
|
||||
|
||||
gtk_file_dialog_open (dialog, window, NULL,
|
||||
(GAsyncReadyCallback) _open_subtitles_cb,
|
||||
gst_object_ref (item));
|
||||
|
||||
g_object_unref (dialog);
|
||||
}
|
32
src/bin/clapper-app/clapper-app-file-dialog.h
Normal file
32
src/bin/clapper-app/clapper-app-file-dialog.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/* Clapper Application
|
||||
* Copyright (C) 2024 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <clapper/clapper.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_app_file_dialog_open_files (GtkApplication *gtk_app);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_app_file_dialog_open_subtitles (GtkApplication *gtk_app, ClapperMediaItem *item);
|
||||
|
||||
G_END_DECLS
|
185
src/bin/clapper-app/clapper-app-headerbar.c
Normal file
185
src/bin/clapper-app/clapper-app-headerbar.c
Normal file
@@ -0,0 +1,185 @@
|
||||
/* Clapper Application
|
||||
* Copyright (C) 2024 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#include "clapper-app-headerbar.h"
|
||||
#include "clapper-app-utils.h"
|
||||
|
||||
#define GST_CAT_DEFAULT clapper_app_headerbar_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
||||
struct _ClapperAppHeaderbar
|
||||
{
|
||||
ClapperGtkContainer parent;
|
||||
|
||||
GtkWidget *queue_revealer;
|
||||
GtkWidget *previous_item_revealer;
|
||||
GtkWidget *next_item_revealer;
|
||||
GtkWidget *win_buttons_revealer;
|
||||
|
||||
GtkDropTarget *drop_target;
|
||||
|
||||
gboolean adapt;
|
||||
};
|
||||
|
||||
#define parent_class clapper_app_headerbar_parent_class
|
||||
G_DEFINE_TYPE (ClapperAppHeaderbar, clapper_app_headerbar, CLAPPER_GTK_TYPE_CONTAINER);
|
||||
|
||||
static void
|
||||
_determine_win_buttons_reveal (ClapperAppHeaderbar *self)
|
||||
{
|
||||
gboolean queue_reveal = gtk_revealer_get_reveal_child (GTK_REVEALER (self->queue_revealer));
|
||||
|
||||
gtk_revealer_set_reveal_child (GTK_REVEALER (self->win_buttons_revealer),
|
||||
(queue_reveal) ? !self->adapt : TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
container_adapt_cb (ClapperGtkContainer *container, gboolean adapt,
|
||||
ClapperAppHeaderbar *self)
|
||||
{
|
||||
GST_DEBUG_OBJECT (self, "Width adapted: %s", (adapt) ? "yes" : "no");
|
||||
self->adapt = adapt;
|
||||
|
||||
gtk_revealer_set_reveal_child (GTK_REVEALER (self->previous_item_revealer), !adapt);
|
||||
gtk_revealer_set_reveal_child (GTK_REVEALER (self->next_item_revealer), !adapt);
|
||||
|
||||
_determine_win_buttons_reveal (self);
|
||||
}
|
||||
|
||||
static void
|
||||
queue_reveal_cb (GtkRevealer *revealer,
|
||||
GParamSpec *pspec G_GNUC_UNUSED, ClapperAppHeaderbar *self)
|
||||
{
|
||||
_determine_win_buttons_reveal (self);
|
||||
}
|
||||
|
||||
static void
|
||||
reveal_queue_button_clicked_cb (GtkButton *button, ClapperAppHeaderbar *self)
|
||||
{
|
||||
gboolean reveal;
|
||||
|
||||
GST_INFO_OBJECT (self, "Reveal queue button clicked");
|
||||
|
||||
reveal = gtk_revealer_get_reveal_child (GTK_REVEALER (self->queue_revealer));
|
||||
gtk_revealer_set_reveal_child (GTK_REVEALER (self->queue_revealer), !reveal);
|
||||
}
|
||||
|
||||
static void
|
||||
drop_value_notify_cb (GtkDropTarget *drop_target,
|
||||
GParamSpec *pspec G_GNUC_UNUSED, ClapperAppHeaderbar *self)
|
||||
{
|
||||
const GValue *value = gtk_drop_target_get_value (drop_target);
|
||||
|
||||
if (value && !clapper_app_utils_value_for_item_is_valid (value))
|
||||
gtk_drop_target_reject (drop_target);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
drop_cb (GtkDropTarget *drop_target, const GValue *value,
|
||||
gdouble x, gdouble y, ClapperAppHeaderbar *self)
|
||||
{
|
||||
GFile **files = NULL;
|
||||
gint n_files = 0;
|
||||
gboolean success = FALSE;
|
||||
|
||||
if (clapper_app_utils_files_from_value (value, &files, &n_files)) {
|
||||
ClapperPlayer *player;
|
||||
|
||||
if ((player = clapper_gtk_get_player_from_ancestor (GTK_WIDGET (self)))) {
|
||||
ClapperQueue *queue = clapper_player_get_queue (player);
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < n_files; ++i) {
|
||||
ClapperMediaItem *item = clapper_media_item_new_from_file (files[i]);
|
||||
|
||||
clapper_queue_add_item (queue, item);
|
||||
if (i == 0) // Select first added item for playback
|
||||
clapper_queue_select_item (queue, item);
|
||||
|
||||
gst_object_unref (item);
|
||||
}
|
||||
|
||||
success = TRUE;
|
||||
}
|
||||
|
||||
clapper_app_utils_files_free (files);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_app_headerbar_init (ClapperAppHeaderbar *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
gtk_drop_target_set_gtypes (self->drop_target,
|
||||
(GType[3]) { GDK_TYPE_FILE_LIST, G_TYPE_FILE, G_TYPE_STRING }, 3);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_app_headerbar_dispose (GObject *object)
|
||||
{
|
||||
gtk_widget_dispose_template (GTK_WIDGET (object), CLAPPER_APP_TYPE_HEADERBAR);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_app_headerbar_finalize (GObject *object)
|
||||
{
|
||||
ClapperAppHeaderbar *self = CLAPPER_APP_HEADERBAR_CAST (object);
|
||||
|
||||
GST_TRACE_OBJECT (self, "Finalize");
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_app_headerbar_class_init (ClapperAppHeaderbarClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
GtkWidgetClass *widget_class = (GtkWidgetClass *) klass;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clapperappheaderbar", 0,
|
||||
"Clapper App Headerbar");
|
||||
|
||||
gobject_class->dispose = clapper_app_headerbar_dispose;
|
||||
gobject_class->finalize = clapper_app_headerbar_finalize;
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class,
|
||||
CLAPPER_APP_RESOURCE_PREFIX "/ui/clapper-app-headerbar.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, ClapperAppHeaderbar, queue_revealer);
|
||||
gtk_widget_class_bind_template_child (widget_class, ClapperAppHeaderbar, previous_item_revealer);
|
||||
gtk_widget_class_bind_template_child (widget_class, ClapperAppHeaderbar, next_item_revealer);
|
||||
gtk_widget_class_bind_template_child (widget_class, ClapperAppHeaderbar, win_buttons_revealer);
|
||||
gtk_widget_class_bind_template_child (widget_class, ClapperAppHeaderbar, drop_target);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, container_adapt_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, reveal_queue_button_clicked_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, queue_reveal_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, drop_value_notify_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, drop_cb);
|
||||
|
||||
gtk_widget_class_set_css_name (widget_class, "clapper-app-headerbar");
|
||||
}
|
31
src/bin/clapper-app/clapper-app-headerbar.h
Normal file
31
src/bin/clapper-app/clapper-app-headerbar.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/* Clapper Application
|
||||
* Copyright (C) 2024 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <clapper-gtk/clapper-gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLAPPER_APP_TYPE_HEADERBAR (clapper_app_headerbar_get_type())
|
||||
#define CLAPPER_APP_HEADERBAR_CAST(obj) ((ClapperAppHeaderbar *)(obj))
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ClapperAppHeaderbar, clapper_app_headerbar, CLAPPER_APP, HEADERBAR, ClapperGtkContainer)
|
||||
|
||||
G_END_DECLS
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user