mirror of
https://github.com/Rafostar/clapper.git
synced 2025-08-31 16:31:58 +02:00
Compare commits
39 Commits
0.5.0
...
experiment
Author | SHA1 | Date | |
---|---|---|---|
|
08216528cf | ||
|
44db8c0d3b | ||
|
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 |
4
.gitattributes
vendored
4
.gitattributes
vendored
@@ -1,5 +1,3 @@
|
||||
extras/**/* linguist-vendored
|
||||
lib/**/* linguist-vendored
|
||||
lib/**/**/* linguist-vendored
|
||||
lib/gst/clapper/* linguist-vendored
|
||||
lib/gst/clapper/gstclapper-mpris* linguist-vendored=false
|
||||
lib/gst/clapper/gtk4/* linguist-vendored=false
|
||||
|
4
.github/workflows/flatpak-nightly.yml
vendored
4
.github/workflows/flatpak-nightly.yml
vendored
@@ -29,8 +29,8 @@ jobs:
|
||||
platforms: arm64
|
||||
- name: Prepare Runtime
|
||||
run: |
|
||||
flatpak --system install -y --noninteractive flathub org.freedesktop.Sdk.Extension.rust-nightly/${{ matrix.arch }}/21.08
|
||||
flatpak --system install -y --noninteractive flathub org.freedesktop.Sdk.Extension.llvm13/${{ matrix.arch }}/21.08
|
||||
flatpak --system install -y --noninteractive flathub org.freedesktop.Sdk.Extension.rust-nightly/${{ matrix.arch }}/22.08
|
||||
flatpak --system install -y --noninteractive flathub org.freedesktop.Sdk.Extension.llvm14/${{ matrix.arch }}/22.08
|
||||
- uses: bilelmoussaoui/flatpak-github-actions/flatpak-builder@v4
|
||||
name: Build
|
||||
with:
|
||||
|
2
.github/workflows/flatpak.yml
vendored
2
.github/workflows/flatpak.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 600
|
||||
container:
|
||||
image: bilelmoussaoui/flatpak-github-actions:gnome-42
|
||||
image: bilelmoussaoui/flatpak-github-actions:gnome-43
|
||||
options: --privileged
|
||||
strategy:
|
||||
matrix:
|
||||
|
@@ -48,6 +48,27 @@
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<releases>
|
||||
<release version="0.5.2" date="2022-06-24">
|
||||
<description>
|
||||
<p>Fixes:</p>
|
||||
<ul>
|
||||
<li>Fix time labels display on RTL languages</li>
|
||||
<li>Improved GL/GLES context automatic selection</li>
|
||||
</ul>
|
||||
<p>New translations:</p>
|
||||
<ul>
|
||||
<li>Hebrew</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.5.1" date="2022-05-29">
|
||||
<description>
|
||||
<p>
|
||||
A quick hotfix release. Fixes problems with new video sink on displays with non-100% scaling applied.
|
||||
See 0.5.0 version release notes for full recent changelog.
|
||||
</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.5.0" date="2022-05-28">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
|
@@ -3,7 +3,7 @@ iconsdir = join_paths(datadir, 'icons', 'hicolor')
|
||||
appstream_util = find_program('appstream-util', required: false)
|
||||
if appstream_util.found()
|
||||
test('Validate appstream file', appstream_util, args: [
|
||||
'validate-relax',
|
||||
'validate-relax', '--nonet',
|
||||
join_paths(meson.current_source_dir(), 'com.github.rafostar.Clapper.metainfo.xml')
|
||||
])
|
||||
endif
|
||||
|
16
lib/gst/clapper/gstclapper.c
vendored
16
lib/gst/clapper/gstclapper.c
vendored
@@ -3166,26 +3166,16 @@ static void
|
||||
element_setup_cb (GstElement * playbin, GstElement * element, GstClapper * self)
|
||||
{
|
||||
GstElementFactory *factory;
|
||||
GParamSpec *prop;
|
||||
|
||||
factory = gst_element_get_factory (element);
|
||||
if (factory) {
|
||||
if ((factory = gst_element_get_factory (element))) {
|
||||
gchar *plugin_name = gst_object_get_name (GST_OBJECT_CAST (factory));
|
||||
if (plugin_name) {
|
||||
GST_INFO_OBJECT (self, "Plugin setup: %s", plugin_name);
|
||||
|
||||
/* TODO: Set plugin props */
|
||||
|
||||
g_free (plugin_name);
|
||||
}
|
||||
g_free (plugin_name);
|
||||
}
|
||||
|
||||
prop = g_object_class_find_property (G_OBJECT_GET_CLASS (element), "user-agent");
|
||||
if (prop && prop->value_type == G_TYPE_STRING) {
|
||||
const gchar *user_agent =
|
||||
"Mozilla/5.0 (X11; Linux x86_64; rv:86.0) Gecko/20100101 Firefox/86.0";
|
||||
|
||||
GST_INFO_OBJECT (self, "Setting element user-agent: %s", user_agent);
|
||||
g_object_set (element, "user-agent", user_agent, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
86
lib/gst/plugin/gstclappercontexthandler.c
Normal file
86
lib/gst/plugin/gstclappercontexthandler.c
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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 "gstclappercontexthandler.h"
|
||||
|
||||
#define parent_class gst_clapper_context_handler_parent_class
|
||||
G_DEFINE_TYPE (GstClapperContextHandler, gst_clapper_context_handler, GST_TYPE_OBJECT);
|
||||
|
||||
static gboolean
|
||||
_default_handle_context_query (GstClapperContextHandler *self,
|
||||
GstBaseSink *bsink, GstQuery *query)
|
||||
{
|
||||
GST_FIXME_OBJECT (self, "Need to handle context query");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_context_handler_init (GstClapperContextHandler *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_context_handler_finalize (GObject *object)
|
||||
{
|
||||
GstClapperContextHandler *self = GST_CLAPPER_CONTEXT_HANDLER_CAST (object);
|
||||
|
||||
GST_TRACE_OBJECT (self, "Finalize");
|
||||
|
||||
GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_context_handler_class_init (GstClapperContextHandlerClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
GstClapperContextHandlerClass *handler_class = (GstClapperContextHandlerClass *) klass;
|
||||
|
||||
gobject_class->finalize = gst_clapper_context_handler_finalize;
|
||||
|
||||
handler_class->handle_context_query = _default_handle_context_query;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_clapper_context_handler_handle_context_query (GstClapperContextHandler *self,
|
||||
GstBaseSink *bsink, GstQuery *query)
|
||||
{
|
||||
GstClapperContextHandlerClass *handler_class = GST_CLAPPER_CONTEXT_HANDLER_GET_CLASS (self);
|
||||
|
||||
return handler_class->handle_context_query (self, bsink, query);
|
||||
}
|
||||
|
||||
GstClapperContextHandler *
|
||||
gst_clapper_context_handler_obtain_with_type (GPtrArray *context_handlers, GType type)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < context_handlers->len; i++) {
|
||||
GstClapperContextHandler *handler = g_ptr_array_index (context_handlers, i);
|
||||
|
||||
if (G_TYPE_CHECK_INSTANCE_TYPE (handler, type))
|
||||
return gst_object_ref (handler);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
62
lib/gst/plugin/gstclappercontexthandler.h
Normal file
62
lib/gst/plugin/gstclappercontexthandler.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/base/gstbasesink.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_CLAPPER_CONTEXT_HANDLER (gst_clapper_context_handler_get_type())
|
||||
#define GST_IS_CLAPPER_CONTEXT_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_CLAPPER_CONTEXT_HANDLER))
|
||||
#define GST_IS_CLAPPER_CONTEXT_HANDLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_CLAPPER_CONTEXT_HANDLER))
|
||||
#define GST_CLAPPER_CONTEXT_HANDLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_CLAPPER_CONTEXT_HANDLER, GstClapperContextHandlerClass))
|
||||
#define GST_CLAPPER_CONTEXT_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_CLAPPER_CONTEXT_HANDLER, GstClapperContextHandler))
|
||||
#define GST_CLAPPER_CONTEXT_HANDLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_CLAPPER_CONTEXT_HANDLER, GstClapperContextHandlerClass))
|
||||
#define GST_CLAPPER_CONTEXT_HANDLER_CAST(obj) ((GstClapperContextHandler *)(obj))
|
||||
|
||||
typedef struct _GstClapperContextHandler GstClapperContextHandler;
|
||||
typedef struct _GstClapperContextHandlerClass GstClapperContextHandlerClass;
|
||||
|
||||
#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GstClapperContextHandler, gst_object_unref)
|
||||
#endif
|
||||
|
||||
struct _GstClapperContextHandler
|
||||
{
|
||||
GstObject parent;
|
||||
};
|
||||
|
||||
struct _GstClapperContextHandlerClass
|
||||
{
|
||||
GstObjectClass parent_class;
|
||||
|
||||
gboolean (* handle_context_query) (GstClapperContextHandler *handler,
|
||||
GstBaseSink *bsink,
|
||||
GstQuery *query);
|
||||
};
|
||||
|
||||
GType gst_clapper_context_handler_get_type (void);
|
||||
|
||||
gboolean gst_clapper_context_handler_handle_context_query (GstClapperContextHandler *handler, GstBaseSink *bsink, GstQuery *query);
|
||||
|
||||
GstClapperContextHandler * gst_clapper_context_handler_obtain_with_type (GPtrArray *context_handlers, GType type);
|
||||
|
||||
G_END_DECLS
|
@@ -89,6 +89,14 @@ _default_create_pool (GstClapperImporter *self, GstStructure **config)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_default_add_allocation_metas (GstClapperImporter *importer, GstQuery *query)
|
||||
{
|
||||
/* Importer base class handles GstVideoOverlayCompositionMeta */
|
||||
gst_query_add_allocation_meta (query, GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL);
|
||||
gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
|
||||
}
|
||||
|
||||
static GdkTexture *
|
||||
_default_generate_texture (GstClapperImporter *self,
|
||||
GstBuffer *buffer, GstVideoInfo *v_info)
|
||||
@@ -144,6 +152,7 @@ gst_clapper_importer_class_init (GstClapperImporterClass *klass)
|
||||
gobject_class->finalize = gst_clapper_importer_finalize;
|
||||
|
||||
importer_class->create_pool = _default_create_pool;
|
||||
importer_class->add_allocation_metas = _default_add_allocation_metas;
|
||||
importer_class->generate_texture = _default_generate_texture;
|
||||
}
|
||||
|
||||
@@ -295,30 +304,6 @@ gst_clapper_importer_prepare_overlays_locked (GstClapperImporter *self)
|
||||
GST_LOG_OBJECT (self, "Prepared overlays: %u", self->pending_overlays->len);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_clapper_importer_prepare (GstClapperImporter *self)
|
||||
{
|
||||
GstClapperImporterClass *importer_class = GST_CLAPPER_IMPORTER_GET_CLASS (self);
|
||||
|
||||
if (importer_class->prepare) {
|
||||
if (!importer_class->prepare (self))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Importer prepared");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
gst_clapper_importer_share_data (GstClapperImporter *self, GstClapperImporter *dest)
|
||||
{
|
||||
GstClapperImporterClass *importer_class = GST_CLAPPER_IMPORTER_GET_CLASS (self);
|
||||
|
||||
if (importer_class->share_data)
|
||||
importer_class->share_data (self, dest);
|
||||
}
|
||||
|
||||
void
|
||||
gst_clapper_importer_set_caps (GstClapperImporter *self, GstCaps *caps)
|
||||
{
|
||||
@@ -362,20 +347,7 @@ gst_clapper_importer_add_allocation_metas (GstClapperImporter *self, GstQuery *q
|
||||
{
|
||||
GstClapperImporterClass *importer_class = GST_CLAPPER_IMPORTER_GET_CLASS (self);
|
||||
|
||||
if (importer_class->add_allocation_metas)
|
||||
importer_class->add_allocation_metas (self, query);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_clapper_importer_handle_context_query (GstClapperImporter *self,
|
||||
GstBaseSink *bsink, GstQuery *query)
|
||||
{
|
||||
GstClapperImporterClass *importer_class = GST_CLAPPER_IMPORTER_GET_CLASS (self);
|
||||
|
||||
if (!importer_class->handle_context_query)
|
||||
return FALSE;
|
||||
|
||||
return importer_class->handle_context_query (self, bsink, query);
|
||||
importer_class->add_allocation_metas (self, query);
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -33,11 +33,11 @@ G_BEGIN_DECLS
|
||||
#define GST_CLAPPER_IMPORTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_CLAPPER_IMPORTER, GstClapperImporterClass))
|
||||
#define GST_CLAPPER_IMPORTER_CAST(obj) ((GstClapperImporter *)(obj))
|
||||
|
||||
#define GST_CLAPPER_IMPORTER_DEFINE(camel,lower,type) \
|
||||
G_DEFINE_TYPE (camel, lower, type) \
|
||||
G_MODULE_EXPORT GstClapperImporter *make_importer (void); \
|
||||
G_MODULE_EXPORT GstCaps *make_caps (gboolean is_template, \
|
||||
GstRank *rank, GStrv *context_types);
|
||||
#define GST_CLAPPER_IMPORTER_DEFINE(camel,lower,type) \
|
||||
G_DEFINE_TYPE (camel, lower, type) \
|
||||
G_MODULE_EXPORT GstClapperImporter *make_importer (GPtrArray *context_handlers); \
|
||||
G_MODULE_EXPORT GstCaps *make_caps (gboolean is_template, \
|
||||
GstRank *rank, GPtrArray *context_handlers);
|
||||
|
||||
typedef struct _GstClapperImporter GstClapperImporter;
|
||||
typedef struct _GstClapperImporterClass GstClapperImporterClass;
|
||||
@@ -65,18 +65,9 @@ struct _GstClapperImporterClass
|
||||
{
|
||||
GstObjectClass parent_class;
|
||||
|
||||
gboolean (* prepare) (GstClapperImporter *importer);
|
||||
|
||||
void (* share_data) (GstClapperImporter *src,
|
||||
GstClapperImporter *dest);
|
||||
|
||||
void (* set_caps) (GstClapperImporter *importer,
|
||||
GstCaps *caps);
|
||||
|
||||
gboolean (* handle_context_query) (GstClapperImporter *importer,
|
||||
GstBaseSink *bsink,
|
||||
GstQuery *query);
|
||||
|
||||
GstBufferPool * (* create_pool) (GstClapperImporter *importer,
|
||||
GstStructure **config);
|
||||
|
||||
@@ -90,9 +81,6 @@ struct _GstClapperImporterClass
|
||||
|
||||
GType gst_clapper_importer_get_type (void);
|
||||
|
||||
gboolean gst_clapper_importer_prepare (GstClapperImporter *importer);
|
||||
void gst_clapper_importer_share_data (GstClapperImporter *importer, GstClapperImporter *dest);
|
||||
gboolean gst_clapper_importer_handle_context_query (GstClapperImporter *importer, GstBaseSink *bsink, GstQuery *query);
|
||||
GstBufferPool * gst_clapper_importer_create_pool (GstClapperImporter *importer, GstStructure **config);
|
||||
void gst_clapper_importer_add_allocation_metas (GstClapperImporter *importer, GstQuery *query);
|
||||
|
||||
|
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "gstclapperimporterloader.h"
|
||||
#include "gstclapperimporter.h"
|
||||
#include "gstclappercontexthandler.h"
|
||||
|
||||
#define GST_CAT_DEFAULT gst_clapper_importer_loader_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
@@ -32,15 +33,14 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
#define parent_class gst_clapper_importer_loader_parent_class
|
||||
G_DEFINE_TYPE (GstClapperImporterLoader, gst_clapper_importer_loader, GST_TYPE_OBJECT);
|
||||
|
||||
typedef GstClapperImporter* (* MakeImporter) (void);
|
||||
typedef GstCaps* (* MakeCaps) (gboolean is_template, GstRank *rank, GStrv *context_types);
|
||||
typedef GstClapperImporter* (* MakeImporter) (GPtrArray *context_handlers);
|
||||
typedef GstCaps* (* MakeCaps) (gboolean is_template, GstRank *rank, GPtrArray *context_handlers);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GModule *module;
|
||||
GstCaps *caps;
|
||||
GstRank rank;
|
||||
GStrv context_types;
|
||||
} GstClapperImporterData;
|
||||
|
||||
static void
|
||||
@@ -49,16 +49,17 @@ gst_clapper_importer_data_free (GstClapperImporterData *data)
|
||||
GST_TRACE ("Freeing importer data: %" GST_PTR_FORMAT, data);
|
||||
|
||||
gst_clear_caps (&data->caps);
|
||||
g_strfreev (data->context_types);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static GstClapperImporterData *
|
||||
_obtain_importer_data (GModule *module, gboolean is_template)
|
||||
_obtain_importer_data (GModule *module, gboolean is_template, GPtrArray *context_handlers)
|
||||
{
|
||||
MakeCaps make_caps;
|
||||
GstClapperImporterData *data;
|
||||
|
||||
GST_DEBUG ("Found importer: %s", g_module_name (module));
|
||||
|
||||
if (!g_module_symbol (module, "make_caps", (gpointer *) &make_caps)
|
||||
|| make_caps == NULL) {
|
||||
GST_WARNING ("Make caps function missing in importer");
|
||||
@@ -67,26 +68,30 @@ _obtain_importer_data (GModule *module, gboolean is_template)
|
||||
|
||||
data = g_new0 (GstClapperImporterData, 1);
|
||||
data->module = module;
|
||||
data->caps = make_caps (is_template, &data->rank, &data->context_types);
|
||||
data->caps = make_caps (is_template, &data->rank, context_handlers);
|
||||
|
||||
GST_TRACE ("Created importer data: %" GST_PTR_FORMAT, data);
|
||||
|
||||
if (G_UNLIKELY (!data->caps)) {
|
||||
GST_ERROR ("Invalid importer without caps: %s",
|
||||
g_module_name (data->module));
|
||||
if (!is_template) {
|
||||
GST_ERROR ("Invalid importer without caps: %s",
|
||||
g_module_name (data->module));
|
||||
} else {
|
||||
/* When importer cannot be actually used, due to e.g. unsupported HW */
|
||||
GST_DEBUG ("No actual caps returned from importer");
|
||||
}
|
||||
gst_clapper_importer_data_free (data);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GST_DEBUG ("Found importer: %s, caps: %" GST_PTR_FORMAT,
|
||||
g_module_name (data->module), data->caps);
|
||||
GST_DEBUG ("Importer caps: %" GST_PTR_FORMAT, data->caps);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static GstClapperImporter *
|
||||
_obtain_importer_internal (GModule *module)
|
||||
_obtain_importer_internal (GModule *module, GPtrArray *context_handlers)
|
||||
{
|
||||
MakeImporter make_importer;
|
||||
GstClapperImporter *importer;
|
||||
@@ -97,7 +102,7 @@ _obtain_importer_internal (GModule *module)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
importer = make_importer ();
|
||||
importer = make_importer (context_handlers);
|
||||
GST_TRACE ("Created importer: %" GST_PTR_FORMAT, importer);
|
||||
|
||||
return importer;
|
||||
@@ -183,13 +188,14 @@ _sort_importers_cb (gconstpointer a, gconstpointer b)
|
||||
}
|
||||
|
||||
static GPtrArray *
|
||||
_obtain_available_importers (gboolean is_template)
|
||||
_obtain_importers (gboolean is_template, GPtrArray *context_handlers)
|
||||
{
|
||||
const GPtrArray *modules;
|
||||
GPtrArray *importers;
|
||||
guint i;
|
||||
|
||||
GST_DEBUG ("Checking available importers");
|
||||
GST_DEBUG ("Checking %s importers",
|
||||
(is_template) ? "available" : "usable");
|
||||
|
||||
modules = gst_clapper_importer_loader_get_available_modules ();
|
||||
importers = g_ptr_array_new_with_free_func (
|
||||
@@ -199,13 +205,14 @@ _obtain_available_importers (gboolean is_template)
|
||||
GModule *module = g_ptr_array_index (modules, i);
|
||||
GstClapperImporterData *data;
|
||||
|
||||
if ((data = _obtain_importer_data (module, is_template)))
|
||||
if ((data = _obtain_importer_data (module, is_template, context_handlers)))
|
||||
g_ptr_array_add (importers, data);
|
||||
}
|
||||
|
||||
g_ptr_array_sort (importers, (GCompareFunc) _sort_importers_cb);
|
||||
|
||||
GST_DEBUG ("Found %i available importers", importers->len);
|
||||
GST_DEBUG ("Found %i %s importers", importers->len,
|
||||
(is_template) ? "available" : "usable");
|
||||
|
||||
return importers;
|
||||
}
|
||||
@@ -244,7 +251,7 @@ gst_clapper_importer_loader_make_sink_pad_template (void)
|
||||
|
||||
GST_DEBUG ("Making sink pad template");
|
||||
|
||||
importers = _obtain_available_importers (TRUE);
|
||||
importers = _obtain_importers (TRUE, NULL);
|
||||
caps = _make_caps_for_importers (importers);
|
||||
g_ptr_array_unref (importers);
|
||||
|
||||
@@ -265,6 +272,22 @@ gst_clapper_importer_loader_make_actual_caps (GstClapperImporterLoader *self)
|
||||
return _make_caps_for_importers (self->importers);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_clapper_importer_loader_handle_context_query (GstClapperImporterLoader *self,
|
||||
GstBaseSink *bsink, GstQuery *query)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < self->context_handlers->len; i++) {
|
||||
GstClapperContextHandler *handler = g_ptr_array_index (self->context_handlers, i);
|
||||
|
||||
if (gst_clapper_context_handler_handle_context_query (handler, bsink, query))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static const GstClapperImporterData *
|
||||
_get_importer_data_for_caps (const GPtrArray *importers, const GstCaps *caps)
|
||||
{
|
||||
@@ -282,89 +305,41 @@ _get_importer_data_for_caps (const GPtrArray *importers, const GstCaps *caps)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const GstClapperImporterData *
|
||||
_get_importer_data_for_context_type (const GPtrArray *importers, const gchar *context_type)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < importers->len; i++) {
|
||||
GstClapperImporterData *data = g_ptr_array_index (importers, i);
|
||||
guint j;
|
||||
|
||||
if (!data->context_types)
|
||||
continue;
|
||||
|
||||
for (j = 0; data->context_types[j]; j++) {
|
||||
if (strcmp (context_type, data->context_types[j]))
|
||||
continue;
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_find_importer_internal (GstClapperImporterLoader *self,
|
||||
GstCaps *caps, GstQuery *query, GstClapperImporter **importer)
|
||||
gboolean
|
||||
gst_clapper_importer_loader_find_importer_for_caps (GstClapperImporterLoader *self,
|
||||
GstCaps *caps, GstClapperImporter **importer)
|
||||
{
|
||||
const GstClapperImporterData *data = NULL;
|
||||
GstClapperImporter *found_importer = NULL;
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
|
||||
if (caps) {
|
||||
GST_DEBUG_OBJECT (self, "Requested importer for caps: %" GST_PTR_FORMAT, caps);
|
||||
data = _get_importer_data_for_caps (self->importers, caps);
|
||||
} else if (query) {
|
||||
const gchar *context_type;
|
||||
|
||||
gst_query_parse_context_type (query, &context_type);
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Requested importer for context: %s", context_type);
|
||||
data = _get_importer_data_for_context_type (self->importers, context_type);
|
||||
}
|
||||
GST_DEBUG_OBJECT (self, "Requested importer for caps: %" GST_PTR_FORMAT, caps);
|
||||
data = _get_importer_data_for_caps (self->importers, caps);
|
||||
|
||||
GST_LOG_OBJECT (self, "Old importer path: %s, new path: %s",
|
||||
(self->last_module) ? g_module_name (self->last_module) : NULL,
|
||||
(data) ? g_module_name (data->module) : NULL);
|
||||
|
||||
if (!data) {
|
||||
/* In case of missing importer for context query, leave the old one.
|
||||
* We should allow some queries to go through unresponded */
|
||||
if (query)
|
||||
GST_DEBUG_OBJECT (self, "No importer for query, leaving old one");
|
||||
else
|
||||
gst_clear_object (importer);
|
||||
|
||||
if (G_UNLIKELY (!data)) {
|
||||
gst_clear_object (importer);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (*importer && (self->last_module == data->module)) {
|
||||
GST_DEBUG_OBJECT (self, "No importer change");
|
||||
|
||||
if (caps)
|
||||
gst_clapper_importer_set_caps (*importer, caps);
|
||||
|
||||
gst_clapper_importer_set_caps (*importer, caps);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
found_importer = _obtain_importer_internal (data->module);
|
||||
|
||||
if (*importer && found_importer)
|
||||
gst_clapper_importer_share_data (*importer, found_importer);
|
||||
|
||||
found_importer = _obtain_importer_internal (data->module, self->context_handlers);
|
||||
gst_clear_object (importer);
|
||||
|
||||
if (!found_importer || !gst_clapper_importer_prepare (found_importer)) {
|
||||
gst_clear_object (&found_importer);
|
||||
|
||||
if (!found_importer)
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (caps)
|
||||
gst_clapper_importer_set_caps (found_importer, caps);
|
||||
gst_clapper_importer_set_caps (found_importer, caps);
|
||||
|
||||
*importer = found_importer;
|
||||
|
||||
@@ -378,33 +353,12 @@ finish:
|
||||
return (*importer != NULL);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_clapper_importer_loader_find_importer_for_caps (GstClapperImporterLoader *self,
|
||||
GstCaps *caps, GstClapperImporter **importer)
|
||||
{
|
||||
return _find_importer_internal (self, caps, NULL, importer);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_clapper_importer_loader_find_importer_for_context_query (GstClapperImporterLoader *self,
|
||||
GstQuery *query, GstClapperImporter **importer)
|
||||
{
|
||||
return _find_importer_internal (self, NULL, query, importer);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_importer_loader_init (GstClapperImporterLoader *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_importer_loader_constructed (GObject *object)
|
||||
{
|
||||
GstClapperImporterLoader *self = GST_CLAPPER_IMPORTER_LOADER_CAST (object);
|
||||
|
||||
self->importers = _obtain_available_importers (FALSE);
|
||||
|
||||
GST_CALL_PARENT (G_OBJECT_CLASS, constructed, (object));
|
||||
self->context_handlers = g_ptr_array_new_with_free_func (
|
||||
(GDestroyNotify) gst_object_unref);
|
||||
self->importers = _obtain_importers (FALSE, self->context_handlers);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -414,7 +368,10 @@ gst_clapper_importer_loader_finalize (GObject *object)
|
||||
|
||||
GST_TRACE ("Finalize");
|
||||
|
||||
g_ptr_array_unref (self->importers);
|
||||
if (self->importers)
|
||||
g_ptr_array_unref (self->importers);
|
||||
|
||||
g_ptr_array_unref (self->context_handlers);
|
||||
|
||||
GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
|
||||
}
|
||||
@@ -424,6 +381,5 @@ gst_clapper_importer_loader_class_init (GstClapperImporterLoaderClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
|
||||
gobject_class->constructed = gst_clapper_importer_loader_constructed;
|
||||
gobject_class->finalize = gst_clapper_importer_loader_finalize;
|
||||
}
|
||||
|
@@ -20,6 +20,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/base/gstbasesink.h>
|
||||
|
||||
#include "gstclapperimporter.h"
|
||||
|
||||
@@ -35,7 +36,9 @@ struct _GstClapperImporterLoader
|
||||
GstObject parent;
|
||||
|
||||
GModule *last_module;
|
||||
|
||||
GPtrArray *importers;
|
||||
GPtrArray *context_handlers;
|
||||
};
|
||||
|
||||
GstClapperImporterLoader * gst_clapper_importer_loader_new (void);
|
||||
@@ -44,8 +47,8 @@ GstPadTemplate * gst_clapper_importer_loader_make_sink_pad_template
|
||||
|
||||
GstCaps * gst_clapper_importer_loader_make_actual_caps (GstClapperImporterLoader *loader);
|
||||
|
||||
gboolean gst_clapper_importer_loader_handle_context_query (GstClapperImporterLoader *loader, GstBaseSink *bsink, GstQuery *query);
|
||||
|
||||
gboolean gst_clapper_importer_loader_find_importer_for_caps (GstClapperImporterLoader *loader, GstCaps *caps, GstClapperImporter **importer);
|
||||
|
||||
gboolean gst_clapper_importer_loader_find_importer_for_context_query (GstClapperImporterLoader *loader, GstQuery *query, GstClapperImporter **importer);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -376,11 +376,8 @@ gst_clapper_paintable_snapshot (GdkPaintable *paintable,
|
||||
gint widget_width = 0, widget_height = 0;
|
||||
|
||||
if ((widget = g_weak_ref_get (&self->widget))) {
|
||||
gint scale_factor;
|
||||
|
||||
scale_factor = gtk_widget_get_scale_factor (widget);
|
||||
widget_width = gtk_widget_get_width (widget) * scale_factor;
|
||||
widget_height = gtk_widget_get_height (widget) * scale_factor;
|
||||
widget_width = gtk_widget_get_width (widget);
|
||||
widget_height = gtk_widget_get_height (widget);
|
||||
|
||||
g_object_unref (widget);
|
||||
}
|
||||
|
@@ -279,8 +279,15 @@ gst_clapper_sink_get_widget (GstClapperSink *self)
|
||||
gst_clapper_paintable_set_widget (self->paintable, self->widget);
|
||||
|
||||
/* Set earlier remembered property */
|
||||
#if GTK_CHECK_VERSION(4,8,0)
|
||||
if (self->force_aspect_ratio)
|
||||
gtk_picture_set_content_fit (GTK_PICTURE (self->widget), GTK_CONTENT_FIT_CONTAIN);
|
||||
else
|
||||
gtk_picture_set_content_fit (GTK_PICTURE (self->widget), GTK_CONTENT_FIT_FILL);
|
||||
#else
|
||||
gtk_picture_set_keep_aspect_ratio (GTK_PICTURE (self->widget),
|
||||
self->force_aspect_ratio);
|
||||
#endif
|
||||
|
||||
gtk_picture_set_paintable (GTK_PICTURE (self->widget), GDK_PAINTABLE (self->paintable));
|
||||
|
||||
@@ -358,8 +365,15 @@ gst_clapper_sink_set_property (GObject *object, guint prop_id,
|
||||
self->force_aspect_ratio = g_value_get_boolean (value);
|
||||
|
||||
if (self->widget) {
|
||||
#if GTK_CHECK_VERSION(4,8,0)
|
||||
if (self->force_aspect_ratio)
|
||||
gtk_picture_set_content_fit (GTK_PICTURE (self->widget), GTK_CONTENT_FIT_CONTAIN);
|
||||
else
|
||||
gtk_picture_set_content_fit (GTK_PICTURE (self->widget), GTK_CONTENT_FIT_FILL);
|
||||
#else
|
||||
gtk_picture_set_keep_aspect_ratio (GTK_PICTURE (self->widget),
|
||||
self->force_aspect_ratio);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case PROP_PIXEL_ASPECT_RATIO:
|
||||
@@ -480,25 +494,12 @@ gst_clapper_sink_query (GstBaseSink *bsink, GstQuery *query)
|
||||
GstClapperSink *self = GST_CLAPPER_SINK_CAST (bsink);
|
||||
gboolean res = FALSE;
|
||||
|
||||
GST_CLAPPER_SINK_LOCK (self);
|
||||
|
||||
if (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT) {
|
||||
gboolean is_inactive;
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
is_inactive = (GST_STATE (self) < GST_STATE_PAUSED);
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
/* Some random context query in the middle of playback
|
||||
* should not trigger importer replacement */
|
||||
if (is_inactive)
|
||||
gst_clapper_importer_loader_find_importer_for_context_query (self->loader, query, &self->importer);
|
||||
if (self->importer)
|
||||
res = gst_clapper_importer_handle_context_query (self->importer, bsink, query);
|
||||
GST_CLAPPER_SINK_LOCK (self);
|
||||
res = gst_clapper_importer_loader_handle_context_query (self->loader, bsink, query);
|
||||
GST_CLAPPER_SINK_UNLOCK (self);
|
||||
}
|
||||
|
||||
GST_CLAPPER_SINK_UNLOCK (self);
|
||||
|
||||
if (res)
|
||||
return TRUE;
|
||||
|
||||
@@ -890,7 +891,7 @@ gst_clapper_sink_class_init (GstClapperSinkClass *klass)
|
||||
gstvideosink_class->set_info = gst_clapper_sink_set_info;
|
||||
gstvideosink_class->show_frame = gst_clapper_sink_show_frame;
|
||||
|
||||
gst_element_class_set_metadata (gstelement_class,
|
||||
gst_element_class_set_static_metadata (gstelement_class,
|
||||
"Clapper video sink",
|
||||
"Sink/Video", "A GTK4 video sink used by Clapper media player",
|
||||
"Rafał Dzięgiel <rafostar.github@gmail.com>");
|
||||
|
@@ -21,43 +21,41 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gstclapperglbaseimporter.h"
|
||||
#include "gstclapperglcontexthandler.h"
|
||||
#include "gst/plugin/gstgdkformats.h"
|
||||
#include "gst/plugin/gstgtkutils.h"
|
||||
|
||||
#include <gst/gl/gstglfuncs.h>
|
||||
|
||||
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WAYLAND
|
||||
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WAYLAND
|
||||
#include <gdk/wayland/gdkwayland.h>
|
||||
#include <gst/gl/wayland/gstgldisplay_wayland.h>
|
||||
#endif
|
||||
|
||||
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11
|
||||
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11
|
||||
#include <gdk/x11/gdkx.h>
|
||||
#endif
|
||||
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11_GLX
|
||||
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11_GLX
|
||||
#include <gst/gl/x11/gstgldisplay_x11.h>
|
||||
#endif
|
||||
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11_EGL || GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WIN32_EGL
|
||||
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11_EGL || GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WIN32_EGL
|
||||
#include <gst/gl/egl/gstgldisplay_egl.h>
|
||||
#endif
|
||||
|
||||
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WIN32
|
||||
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WIN32
|
||||
#include <gdk/win32/gdkwin32.h>
|
||||
#endif
|
||||
|
||||
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_MACOS
|
||||
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_MACOS
|
||||
#include <gdk/macos/gdkmacos.h>
|
||||
#endif
|
||||
|
||||
#define GST_CAT_DEFAULT gst_clapper_gl_base_importer_debug
|
||||
#define GST_CAT_DEFAULT gst_clapper_gl_context_handler_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
||||
#define parent_class gst_clapper_gl_base_importer_parent_class
|
||||
G_DEFINE_TYPE (GstClapperGLBaseImporter, gst_clapper_gl_base_importer, GST_TYPE_CLAPPER_IMPORTER);
|
||||
#define parent_class gst_clapper_gl_context_handler_parent_class
|
||||
G_DEFINE_TYPE (GstClapperGLContextHandler, gst_clapper_gl_context_handler, GST_TYPE_OBJECT);
|
||||
|
||||
static GstGLContext *
|
||||
wrap_current_gl (GstGLDisplay *display, GdkGLAPI gdk_gl_api, GstGLPlatform platform)
|
||||
_wrap_current_gl (GstGLDisplay *display, GdkGLAPI gdk_gl_api, GstGLPlatform platform)
|
||||
{
|
||||
GstGLAPI gst_gl_api = GST_GL_API_NONE;
|
||||
|
||||
@@ -86,380 +84,19 @@ wrap_current_gl (GstGLDisplay *display, GdkGLAPI gdk_gl_api, GstGLPlatform platf
|
||||
}
|
||||
|
||||
static gboolean
|
||||
retrieve_gl_context_on_main (GstClapperGLBaseImporter *self)
|
||||
{
|
||||
GstClapperGLBaseImporterClass *gl_bi_class = GST_CLAPPER_GL_BASE_IMPORTER_GET_CLASS (self);
|
||||
GdkDisplay *gdk_display;
|
||||
GdkGLContext *gdk_context;
|
||||
GError *error = NULL;
|
||||
GdkGLAPI gdk_gl_api;
|
||||
GstGLPlatform platform = GST_GL_PLATFORM_NONE;
|
||||
gint gl_major = 0, gl_minor = 0;
|
||||
|
||||
if (!gtk_init_check ()) {
|
||||
GST_ERROR_OBJECT (self, "Could not ensure GTK initialization");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Make sure we are clean here, otherwise data sharing
|
||||
* between GL-based importers may lead to leaks */
|
||||
gst_clear_object (&self->wrapped_context);
|
||||
g_clear_object (&self->gdk_context);
|
||||
gst_clear_object (&self->gst_display);
|
||||
|
||||
gdk_display = gdk_display_get_default ();
|
||||
|
||||
if (G_UNLIKELY (!gdk_display)) {
|
||||
GST_ERROR_OBJECT (self, "Could not retrieve Gdk display");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!(gdk_context = gdk_display_create_gl_context (gdk_display, &error))) {
|
||||
GST_ERROR_OBJECT (self, "Error creating Gdk GL context: %s",
|
||||
error ? error->message : "No error set by Gdk");
|
||||
g_clear_error (&error);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gl_bi_class->gdk_context_realize (self, gdk_context)) {
|
||||
GST_ERROR_OBJECT (self, "Could not realize Gdk context: %" GST_PTR_FORMAT,
|
||||
gdk_context);
|
||||
g_object_unref (gdk_context);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
gdk_gl_api = gdk_gl_context_get_api (gdk_context);
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_LOCK (self);
|
||||
|
||||
self->gdk_context = gdk_context;
|
||||
|
||||
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WAYLAND
|
||||
if (GDK_IS_WAYLAND_DISPLAY (gdk_display)) {
|
||||
struct wl_display *wayland_display =
|
||||
gdk_wayland_display_get_wl_display (gdk_display);
|
||||
self->gst_display = (GstGLDisplay *)
|
||||
gst_gl_display_wayland_new_with_display (wayland_display);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11
|
||||
if (GDK_IS_X11_DISPLAY (gdk_display)) {
|
||||
gpointer display_ptr;
|
||||
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11_EGL
|
||||
display_ptr = gdk_x11_display_get_egl_display (gdk_display);
|
||||
if (display_ptr) {
|
||||
self->gst_display = (GstGLDisplay *)
|
||||
gst_gl_display_egl_new_with_egl_display (display_ptr);
|
||||
}
|
||||
#endif
|
||||
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11_GLX
|
||||
if (!self->gst_display) {
|
||||
display_ptr = gdk_x11_display_get_xdisplay (gdk_display);
|
||||
self->gst_display = (GstGLDisplay *)
|
||||
gst_gl_display_x11_new_with_display (display_ptr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WIN32
|
||||
if (GDK_IS_WIN32_DISPLAY (gdk_display)) {
|
||||
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WIN32_EGL
|
||||
gpointer display_ptr = gdk_win32_display_get_egl_display (gdk_display);
|
||||
if (display_ptr) {
|
||||
self->gst_display = (GstGLDisplay *)
|
||||
gst_gl_display_egl_new_with_egl_display (display_ptr);
|
||||
}
|
||||
#endif
|
||||
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WIN32_WGL
|
||||
if (!self->gst_display) {
|
||||
self->gst_display =
|
||||
gst_gl_display_new_with_type (GST_GL_DISPLAY_TYPE_WIN32);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_MACOS
|
||||
if (GDK_IS_MACOS_DISPLAY (gdk_display)) {
|
||||
self->gst_display =
|
||||
gst_gl_display_new_with_type (GST_GL_DISPLAY_TYPE_COCOA);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Fallback to generic display */
|
||||
if (G_UNLIKELY (!self->gst_display)) {
|
||||
GST_WARNING_OBJECT (self, "Unknown Gdk display!");
|
||||
self->gst_display = gst_gl_display_new ();
|
||||
}
|
||||
|
||||
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WAYLAND
|
||||
if (GST_IS_GL_DISPLAY_WAYLAND (self->gst_display)) {
|
||||
platform = GST_GL_PLATFORM_EGL;
|
||||
GST_INFO_OBJECT (self, "Using EGL on Wayland");
|
||||
goto have_display;
|
||||
}
|
||||
#endif
|
||||
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11_EGL
|
||||
if (GST_IS_GL_DISPLAY_EGL (self->gst_display)
|
||||
&& GDK_IS_X11_DISPLAY (gdk_display)) {
|
||||
platform = GST_GL_PLATFORM_EGL;
|
||||
GST_INFO_OBJECT (self, "Using EGL on x11");
|
||||
goto have_display;
|
||||
}
|
||||
#endif
|
||||
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11_GLX
|
||||
if (GST_IS_GL_DISPLAY_X11 (self->gst_display)) {
|
||||
platform = GST_GL_PLATFORM_GLX;
|
||||
GST_INFO_OBJECT (self, "Using GLX on x11");
|
||||
goto have_display;
|
||||
}
|
||||
#endif
|
||||
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WIN32_EGL
|
||||
if (GST_IS_GL_DISPLAY_EGL (self->gst_display)
|
||||
&& GDK_IS_WIN32_DISPLAY (gdk_display)) {
|
||||
platform = GST_GL_PLATFORM_EGL;
|
||||
GST_INFO_OBJECT (self, "Using EGL on Win32");
|
||||
goto have_display;
|
||||
}
|
||||
#endif
|
||||
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WIN32_WGL
|
||||
if (gst_gl_display_get_handle_type (self->gst_display) == GST_GL_DISPLAY_TYPE_WIN32) {
|
||||
platform = GST_GL_PLATFORM_WGL;
|
||||
GST_INFO_OBJECT (self, "Using WGL on Win32");
|
||||
goto have_display;
|
||||
}
|
||||
#endif
|
||||
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_MACOS
|
||||
if (gst_gl_display_get_handle_type (self->gst_display) == GST_GL_DISPLAY_TYPE_COCOA) {
|
||||
platform = GST_GL_PLATFORM_CGL;
|
||||
GST_INFO_OBJECT (self, "Using CGL on macOS");
|
||||
goto have_display;
|
||||
}
|
||||
#endif
|
||||
|
||||
g_clear_object (&self->gdk_context);
|
||||
gst_clear_object (&self->gst_display);
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self);
|
||||
|
||||
GST_ERROR_OBJECT (self, "Unsupported GL platform");
|
||||
return FALSE;
|
||||
|
||||
have_display:
|
||||
gdk_gl_context_make_current (self->gdk_context);
|
||||
|
||||
self->wrapped_context = wrap_current_gl (self->gst_display, gdk_gl_api, platform);
|
||||
if (!self->wrapped_context) {
|
||||
GST_ERROR ("Could not retrieve Gdk OpenGL context");
|
||||
gdk_gl_context_clear_current ();
|
||||
|
||||
g_clear_object (&self->gdk_context);
|
||||
gst_clear_object (&self->gst_display);
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GST_INFO ("Retrieved Gdk OpenGL context %" GST_PTR_FORMAT, self->wrapped_context);
|
||||
gst_gl_context_activate (self->wrapped_context, TRUE);
|
||||
|
||||
if (!gst_gl_context_fill_info (self->wrapped_context, &error)) {
|
||||
GST_ERROR ("Failed to fill Gdk context info: %s", error->message);
|
||||
g_clear_error (&error);
|
||||
|
||||
gst_gl_context_activate (self->wrapped_context, FALSE);
|
||||
|
||||
gst_clear_object (&self->wrapped_context);
|
||||
g_clear_object (&self->gdk_context);
|
||||
gst_clear_object (&self->gst_display);
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gst_gl_context_get_gl_version (self->wrapped_context, &gl_major, &gl_minor);
|
||||
GST_INFO ("Using OpenGL%s %i.%i", (gdk_gl_api == GDK_GL_API_GLES) ? " ES" : "",
|
||||
gl_major, gl_minor);
|
||||
|
||||
/* Deactivate in both places */
|
||||
gst_gl_context_activate (self->wrapped_context, FALSE);
|
||||
gdk_gl_context_clear_current ();
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
retrieve_gst_context (GstClapperGLBaseImporter *self)
|
||||
{
|
||||
GstGLDisplay *gst_display = NULL;
|
||||
GstGLContext *gst_context = NULL;
|
||||
GError *error = NULL;
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_LOCK (self);
|
||||
|
||||
gst_display = gst_object_ref (self->gst_display);
|
||||
|
||||
/* GstGLDisplay operations require display object lock to be held */
|
||||
GST_OBJECT_LOCK (gst_display);
|
||||
|
||||
if (!self->gst_context) {
|
||||
GST_TRACE_OBJECT (self, "Creating new GstGLContext");
|
||||
|
||||
if (!gst_gl_display_create_context (gst_display, self->wrapped_context,
|
||||
&self->gst_context, &error)) {
|
||||
GST_WARNING ("Could not create OpenGL context: %s",
|
||||
error ? error->message : "Unknown");
|
||||
g_clear_error (&error);
|
||||
|
||||
GST_OBJECT_UNLOCK (gst_display);
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
gst_context = gst_object_ref (self->gst_context);
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self);
|
||||
|
||||
gst_gl_display_add_context (gst_display, gst_context);
|
||||
|
||||
GST_OBJECT_UNLOCK (gst_display);
|
||||
|
||||
gst_object_unref (gst_display);
|
||||
gst_object_unref (gst_context);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_clapper_gl_base_importer_prepare (GstClapperImporter *importer)
|
||||
{
|
||||
GstClapperGLBaseImporter *self = GST_CLAPPER_GL_BASE_IMPORTER_CAST (importer);
|
||||
gboolean need_invoke;
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_LOCK (self);
|
||||
need_invoke = (!self->gdk_context || !self->gst_display || !self->wrapped_context);
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self);
|
||||
|
||||
if (need_invoke) {
|
||||
if (!(! !gst_gtk_invoke_on_main ((GThreadFunc) (GCallback)
|
||||
retrieve_gl_context_on_main, self)))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!retrieve_gst_context (self))
|
||||
return FALSE;
|
||||
|
||||
if (!GST_CLAPPER_IMPORTER_CLASS (parent_class)->prepare)
|
||||
return TRUE;
|
||||
|
||||
return GST_CLAPPER_IMPORTER_CLASS (parent_class)->prepare (importer);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gl_base_importer_share_data (GstClapperImporter *importer, GstClapperImporter *dest_importer)
|
||||
{
|
||||
GstClapperGLBaseImporter *self = GST_CLAPPER_GL_BASE_IMPORTER (importer);
|
||||
|
||||
if (GST_IS_CLAPPER_GL_BASE_IMPORTER (dest_importer)) {
|
||||
GstClapperGLBaseImporter *dest = GST_CLAPPER_GL_BASE_IMPORTER (dest_importer);
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_LOCK (self);
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_LOCK (dest);
|
||||
|
||||
/* Successfully prepared GL importer should have all three */
|
||||
if (self->gdk_context && self->gst_display && self->wrapped_context) {
|
||||
g_clear_object (&dest->gdk_context);
|
||||
dest->gdk_context = g_object_ref (self->gdk_context);
|
||||
|
||||
gst_clear_object (&dest->gst_display);
|
||||
dest->gst_display = gst_object_ref (self->gst_display);
|
||||
|
||||
gst_clear_object (&dest->wrapped_context);
|
||||
dest->wrapped_context = gst_object_ref (self->wrapped_context);
|
||||
}
|
||||
|
||||
/* This context is not required, we can create it ourselves
|
||||
* using gst_display and wrapped_context */
|
||||
if (self->gst_context) {
|
||||
gst_clear_object (&dest->gst_context);
|
||||
dest->gst_context = gst_object_ref (self->gst_context);
|
||||
}
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (dest);
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self);
|
||||
}
|
||||
|
||||
if (GST_CLAPPER_IMPORTER_CLASS (parent_class)->share_data)
|
||||
GST_CLAPPER_IMPORTER_CLASS (parent_class)->share_data (importer, dest_importer);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_clapper_gl_base_importer_handle_context_query (GstClapperImporter *importer,
|
||||
GstBaseSink *bsink, GstQuery *query)
|
||||
{
|
||||
GstClapperGLBaseImporter *self = GST_CLAPPER_GL_BASE_IMPORTER_CAST (importer);
|
||||
gboolean res;
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_LOCK (self);
|
||||
res = gst_gl_handle_context_query (GST_ELEMENT_CAST (bsink), query,
|
||||
self->gst_display, self->gst_context, self->wrapped_context);
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static GstBufferPool *
|
||||
gst_clapper_gl_base_importer_create_pool (GstClapperImporter *importer, GstStructure **config)
|
||||
{
|
||||
GstClapperGLBaseImporter *self = GST_CLAPPER_GL_BASE_IMPORTER_CAST (importer);
|
||||
GstBufferPool *pool;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Creating new GL buffer pool");
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_LOCK (self);
|
||||
pool = gst_gl_buffer_pool_new (self->gst_context);
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self);
|
||||
|
||||
*config = gst_buffer_pool_get_config (pool);
|
||||
|
||||
gst_buffer_pool_config_add_option (*config, GST_BUFFER_POOL_OPTION_VIDEO_META);
|
||||
gst_buffer_pool_config_add_option (*config, GST_BUFFER_POOL_OPTION_GL_SYNC_META);
|
||||
|
||||
return pool;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gl_base_importer_add_allocation_metas (GstClapperImporter *importer, GstQuery *query)
|
||||
{
|
||||
GstClapperGLBaseImporter *self = GST_CLAPPER_GL_BASE_IMPORTER_CAST (importer);
|
||||
|
||||
gst_query_add_allocation_meta (query, GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL);
|
||||
gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_LOCK (self);
|
||||
if (self->gst_context->gl_vtable->FenceSync)
|
||||
gst_query_add_allocation_meta (query, GST_GL_SYNC_META_API_TYPE, NULL);
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_realize_gdk_context_with_api (GdkGLContext *gdk_context, GdkGLAPI api)
|
||||
_realize_gdk_context_with_api (GdkGLContext *gdk_context, GdkGLAPI api, gint maj, gint min)
|
||||
{
|
||||
GError *error = NULL;
|
||||
gboolean success;
|
||||
|
||||
gdk_gl_context_set_allowed_apis (gdk_context, api);
|
||||
gdk_gl_context_set_required_version (gdk_context, maj, min);
|
||||
|
||||
GST_DEBUG ("Trying to realize %s context, min ver: %i.%i",
|
||||
(api & GDK_GL_API_GL) ? "GL" : "GLES", maj, min);
|
||||
|
||||
if (!(success = gdk_gl_context_realize (gdk_context, &error))) {
|
||||
GST_WARNING ("Could not realize Gdk context with %s: %s",
|
||||
GST_DEBUG ("Could not realize Gdk context with %s: %s",
|
||||
(api & GDK_GL_API_GL) ? "GL" : "GLES", error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
@@ -468,7 +105,7 @@ _realize_gdk_context_with_api (GdkGLContext *gdk_context, GdkGLAPI api)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_clapper_gl_base_importer_gdk_context_realize (GstClapperGLBaseImporter *self, GdkGLContext *gdk_context)
|
||||
_gl_context_handler_context_realize (GstClapperGLContextHandler *self, GdkGLContext *gdk_context)
|
||||
{
|
||||
GdkGLAPI preferred_api = GDK_GL_API_GL;
|
||||
GdkDisplay *gdk_display;
|
||||
@@ -486,7 +123,7 @@ gst_clapper_gl_base_importer_gdk_context_realize (GstClapperGLBaseImporter *self
|
||||
: GDK_GL_API_GL | GDK_GL_API_GLES;
|
||||
|
||||
/* With requested by user API, we either use it or give up */
|
||||
return _realize_gdk_context_with_api (gdk_context, preferred_api);
|
||||
return _realize_gdk_context_with_api (gdk_context, preferred_api, 0, 0);
|
||||
}
|
||||
|
||||
gdk_display = gdk_gl_context_get_display (gdk_context);
|
||||
@@ -496,15 +133,15 @@ gst_clapper_gl_base_importer_gdk_context_realize (GstClapperGLBaseImporter *self
|
||||
/* Apple decoder uses rectangle texture-target, which GLES does not support.
|
||||
* For Linux we prefer EGL + GLES in order to get direct HW colorspace conversion.
|
||||
* Windows will try EGL + GLES setup first and auto fallback to WGL. */
|
||||
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WAYLAND
|
||||
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WAYLAND
|
||||
if (GDK_IS_WAYLAND_DISPLAY (gdk_display))
|
||||
preferred_api = GDK_GL_API_GLES;
|
||||
#endif
|
||||
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11_EGL
|
||||
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11_EGL
|
||||
if (GDK_IS_X11_DISPLAY (gdk_display) && gdk_x11_display_get_egl_display (gdk_display))
|
||||
preferred_api = GDK_GL_API_GLES;
|
||||
#endif
|
||||
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WIN32_EGL
|
||||
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WIN32_EGL
|
||||
if (GDK_IS_WIN32_DISPLAY (gdk_display) && gdk_win32_display_get_egl_display (gdk_display))
|
||||
preferred_api = GDK_GL_API_GLES;
|
||||
#endif
|
||||
@@ -513,34 +150,318 @@ gst_clapper_gl_base_importer_gdk_context_realize (GstClapperGLBaseImporter *self
|
||||
* "scrambled" image on Linux with Intel GPUs that are mostly used together with
|
||||
* x86 CPUs at the expense of using slightly slower non-direct DMABuf import.
|
||||
* See: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1236 */
|
||||
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WAYLAND || GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11_EGL
|
||||
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WAYLAND || GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11_EGL
|
||||
#if !defined(HAVE_GST_PATCHES) && (defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64))
|
||||
preferred_api = GDK_GL_API_GL;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (!(success = _realize_gdk_context_with_api (gdk_context, preferred_api))) {
|
||||
/* Continue with GLES only if it should have "GL_EXT_texture_norm16"
|
||||
* extension, as we need it to handle P010_10LE, etc. */
|
||||
if ((preferred_api == GDK_GL_API_GLES)
|
||||
&& _realize_gdk_context_with_api (gdk_context, GDK_GL_API_GLES, 3, 1))
|
||||
return TRUE;
|
||||
|
||||
/* If not using GLES 3.1, try with core GL 3.2 that GTK4 defaults to */
|
||||
if (_realize_gdk_context_with_api (gdk_context, GDK_GL_API_GL, 3, 2))
|
||||
return TRUE;
|
||||
|
||||
/* Try with what we normally prefer first, otherwise use fallback */
|
||||
if (!(success = _realize_gdk_context_with_api (gdk_context, preferred_api, 0, 0))) {
|
||||
GdkGLAPI fallback_api;
|
||||
|
||||
fallback_api = (GDK_GL_API_GL | GDK_GL_API_GLES);
|
||||
fallback_api &= ~preferred_api;
|
||||
|
||||
success = _realize_gdk_context_with_api (gdk_context, fallback_api);
|
||||
success = _realize_gdk_context_with_api (gdk_context, fallback_api, 0, 0);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gl_base_importer_init (GstClapperGLBaseImporter *self)
|
||||
static gboolean
|
||||
_retrieve_gl_context_on_main (GstClapperGLContextHandler *self)
|
||||
{
|
||||
g_mutex_init (&self->lock);
|
||||
GdkDisplay *gdk_display;
|
||||
GdkGLContext *gdk_context;
|
||||
GError *error = NULL;
|
||||
GdkGLAPI gdk_gl_api;
|
||||
GstGLPlatform platform = GST_GL_PLATFORM_NONE;
|
||||
gint gl_major = 0, gl_minor = 0;
|
||||
|
||||
if (!gtk_init_check ()) {
|
||||
GST_ERROR_OBJECT (self, "Could not ensure GTK initialization");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gdk_display = gdk_display_get_default ();
|
||||
|
||||
if (G_UNLIKELY (!gdk_display)) {
|
||||
GST_ERROR_OBJECT (self, "Could not retrieve Gdk display");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!(gdk_context = gdk_display_create_gl_context (gdk_display, &error))) {
|
||||
GST_ERROR_OBJECT (self, "Error creating Gdk GL context: %s",
|
||||
error ? error->message : "No error set by Gdk");
|
||||
g_clear_error (&error);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!_gl_context_handler_context_realize (self, gdk_context)) {
|
||||
GST_ERROR_OBJECT (self, "Could not realize Gdk context: %" GST_PTR_FORMAT,
|
||||
gdk_context);
|
||||
g_object_unref (gdk_context);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
gdk_gl_api = gdk_gl_context_get_api (gdk_context);
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
|
||||
self->gdk_context = gdk_context;
|
||||
|
||||
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WAYLAND
|
||||
if (GDK_IS_WAYLAND_DISPLAY (gdk_display)) {
|
||||
struct wl_display *wayland_display =
|
||||
gdk_wayland_display_get_wl_display (gdk_display);
|
||||
self->gst_display = (GstGLDisplay *)
|
||||
gst_gl_display_wayland_new_with_display (wayland_display);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11
|
||||
if (GDK_IS_X11_DISPLAY (gdk_display)) {
|
||||
gpointer display_ptr;
|
||||
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11_EGL
|
||||
display_ptr = gdk_x11_display_get_egl_display (gdk_display);
|
||||
if (display_ptr) {
|
||||
self->gst_display = (GstGLDisplay *)
|
||||
gst_gl_display_egl_new_with_egl_display (display_ptr);
|
||||
}
|
||||
#endif
|
||||
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11_GLX
|
||||
if (!self->gst_display) {
|
||||
display_ptr = gdk_x11_display_get_xdisplay (gdk_display);
|
||||
self->gst_display = (GstGLDisplay *)
|
||||
gst_gl_display_x11_new_with_display (display_ptr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WIN32
|
||||
if (GDK_IS_WIN32_DISPLAY (gdk_display)) {
|
||||
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WIN32_EGL
|
||||
gpointer display_ptr = gdk_win32_display_get_egl_display (gdk_display);
|
||||
if (display_ptr) {
|
||||
self->gst_display = (GstGLDisplay *)
|
||||
gst_gl_display_egl_new_with_egl_display (display_ptr);
|
||||
}
|
||||
#endif
|
||||
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WIN32_WGL
|
||||
if (!self->gst_display) {
|
||||
self->gst_display =
|
||||
gst_gl_display_new_with_type (GST_GL_DISPLAY_TYPE_WIN32);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_MACOS
|
||||
if (GDK_IS_MACOS_DISPLAY (gdk_display)) {
|
||||
self->gst_display =
|
||||
gst_gl_display_new_with_type (GST_GL_DISPLAY_TYPE_COCOA);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Fallback to generic display */
|
||||
if (G_UNLIKELY (!self->gst_display)) {
|
||||
GST_WARNING_OBJECT (self, "Unknown Gdk display!");
|
||||
self->gst_display = gst_gl_display_new ();
|
||||
}
|
||||
|
||||
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WAYLAND
|
||||
if (GST_IS_GL_DISPLAY_WAYLAND (self->gst_display)) {
|
||||
platform = GST_GL_PLATFORM_EGL;
|
||||
GST_INFO_OBJECT (self, "Using EGL on Wayland");
|
||||
goto have_display;
|
||||
}
|
||||
#endif
|
||||
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11_EGL
|
||||
if (GST_IS_GL_DISPLAY_EGL (self->gst_display)
|
||||
&& GDK_IS_X11_DISPLAY (gdk_display)) {
|
||||
platform = GST_GL_PLATFORM_EGL;
|
||||
GST_INFO_OBJECT (self, "Using EGL on x11");
|
||||
goto have_display;
|
||||
}
|
||||
#endif
|
||||
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11_GLX
|
||||
if (GST_IS_GL_DISPLAY_X11 (self->gst_display)) {
|
||||
platform = GST_GL_PLATFORM_GLX;
|
||||
GST_INFO_OBJECT (self, "Using GLX on x11");
|
||||
goto have_display;
|
||||
}
|
||||
#endif
|
||||
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WIN32_EGL
|
||||
if (GST_IS_GL_DISPLAY_EGL (self->gst_display)
|
||||
&& GDK_IS_WIN32_DISPLAY (gdk_display)) {
|
||||
platform = GST_GL_PLATFORM_EGL;
|
||||
GST_INFO_OBJECT (self, "Using EGL on Win32");
|
||||
goto have_display;
|
||||
}
|
||||
#endif
|
||||
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WIN32_WGL
|
||||
if (gst_gl_display_get_handle_type (self->gst_display) == GST_GL_DISPLAY_TYPE_WIN32) {
|
||||
platform = GST_GL_PLATFORM_WGL;
|
||||
GST_INFO_OBJECT (self, "Using WGL on Win32");
|
||||
goto have_display;
|
||||
}
|
||||
#endif
|
||||
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_MACOS
|
||||
if (gst_gl_display_get_handle_type (self->gst_display) == GST_GL_DISPLAY_TYPE_COCOA) {
|
||||
platform = GST_GL_PLATFORM_CGL;
|
||||
GST_INFO_OBJECT (self, "Using CGL on macOS");
|
||||
goto have_display;
|
||||
}
|
||||
#endif
|
||||
|
||||
g_clear_object (&self->gdk_context);
|
||||
gst_clear_object (&self->gst_display);
|
||||
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
GST_ERROR_OBJECT (self, "Unsupported GL platform");
|
||||
return FALSE;
|
||||
|
||||
have_display:
|
||||
gdk_gl_context_make_current (self->gdk_context);
|
||||
|
||||
self->wrapped_context = _wrap_current_gl (self->gst_display, gdk_gl_api, platform);
|
||||
if (!self->wrapped_context) {
|
||||
GST_ERROR ("Could not retrieve Gdk OpenGL context");
|
||||
gdk_gl_context_clear_current ();
|
||||
|
||||
g_clear_object (&self->gdk_context);
|
||||
gst_clear_object (&self->gst_display);
|
||||
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GST_INFO ("Retrieved Gdk OpenGL context %" GST_PTR_FORMAT, self->wrapped_context);
|
||||
gst_gl_context_activate (self->wrapped_context, TRUE);
|
||||
|
||||
if (!gst_gl_context_fill_info (self->wrapped_context, &error)) {
|
||||
GST_ERROR ("Failed to fill Gdk context info: %s", error->message);
|
||||
g_clear_error (&error);
|
||||
|
||||
gst_gl_context_activate (self->wrapped_context, FALSE);
|
||||
|
||||
gst_clear_object (&self->wrapped_context);
|
||||
g_clear_object (&self->gdk_context);
|
||||
gst_clear_object (&self->gst_display);
|
||||
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gst_gl_context_get_gl_version (self->wrapped_context, &gl_major, &gl_minor);
|
||||
GST_INFO ("Using OpenGL%s %i.%i", (gdk_gl_api == GDK_GL_API_GLES) ? " ES" : "",
|
||||
gl_major, gl_minor);
|
||||
|
||||
/* Deactivate in both places */
|
||||
gst_gl_context_activate (self->wrapped_context, FALSE);
|
||||
gdk_gl_context_clear_current ();
|
||||
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_retrieve_gst_context (GstClapperGLContextHandler *self)
|
||||
{
|
||||
GstGLDisplay *gst_display = NULL;
|
||||
GstGLContext *gst_context = NULL;
|
||||
GError *error = NULL;
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
|
||||
gst_display = gst_object_ref (self->gst_display);
|
||||
GST_TRACE_OBJECT (self, "Creating new GstGLContext");
|
||||
|
||||
/* GstGLDisplay operations require display object lock to be held */
|
||||
GST_OBJECT_LOCK (gst_display);
|
||||
|
||||
if (!gst_gl_display_create_context (gst_display, self->wrapped_context,
|
||||
&self->gst_context, &error)) {
|
||||
GST_WARNING ("Could not create OpenGL context: %s",
|
||||
error ? error->message : "Unknown");
|
||||
g_clear_error (&error);
|
||||
|
||||
GST_OBJECT_UNLOCK (gst_display);
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gst_context = gst_object_ref (self->gst_context);
|
||||
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
gst_gl_display_add_context (gst_display, gst_context);
|
||||
|
||||
GST_OBJECT_UNLOCK (gst_display);
|
||||
|
||||
gst_object_unref (gst_display);
|
||||
gst_object_unref (gst_context);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_clapper_gl_context_handler_handle_context_query (GstClapperContextHandler *handler,
|
||||
GstBaseSink *bsink, GstQuery *query)
|
||||
{
|
||||
GstClapperGLContextHandler *self = GST_CLAPPER_GL_CONTEXT_HANDLER_CAST (handler);
|
||||
gboolean res;
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
res = gst_gl_handle_context_query (GST_ELEMENT_CAST (bsink), query,
|
||||
self->gst_display, self->gst_context, self->wrapped_context);
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gl_base_importer_finalize (GObject *object)
|
||||
gst_clapper_gl_context_handler_init (GstClapperGLContextHandler *self)
|
||||
{
|
||||
GstClapperGLBaseImporter *self = GST_CLAPPER_GL_BASE_IMPORTER_CAST (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gl_context_handler_constructed (GObject *object)
|
||||
{
|
||||
GstClapperGLContextHandler *self = GST_CLAPPER_GL_CONTEXT_HANDLER_CAST (object);
|
||||
|
||||
if (! !gst_gtk_invoke_on_main ((GThreadFunc) (GCallback)
|
||||
_retrieve_gl_context_on_main, self)) {
|
||||
_retrieve_gst_context (self);
|
||||
}
|
||||
|
||||
GST_CALL_PARENT (G_OBJECT_CLASS, constructed, (object));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gl_context_handler_finalize (GObject *object)
|
||||
{
|
||||
GstClapperGLContextHandler *self = GST_CLAPPER_GL_CONTEXT_HANDLER_CAST (object);
|
||||
|
||||
GST_TRACE ("Finalize");
|
||||
|
||||
g_clear_object (&self->gdk_context);
|
||||
|
||||
@@ -548,70 +469,74 @@ gst_clapper_gl_base_importer_finalize (GObject *object)
|
||||
gst_clear_object (&self->wrapped_context);
|
||||
gst_clear_object (&self->gst_context);
|
||||
|
||||
g_mutex_clear (&self->lock);
|
||||
|
||||
GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gl_base_importer_class_init (GstClapperGLBaseImporterClass *klass)
|
||||
gst_clapper_gl_context_handler_class_init (GstClapperGLContextHandlerClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
GstClapperImporterClass *importer_class = (GstClapperImporterClass *) klass;
|
||||
GstClapperGLBaseImporterClass *gl_bi_class = (GstClapperGLBaseImporterClass *) klass;
|
||||
GstClapperContextHandlerClass *handler_class = (GstClapperContextHandlerClass *) klass;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clapperglbaseimporter", 0,
|
||||
"Clapper GL Base Importer");
|
||||
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clapperglcontexthandler", 0,
|
||||
"Clapper GL Context Handler");
|
||||
|
||||
gobject_class->finalize = gst_clapper_gl_base_importer_finalize;
|
||||
gobject_class->constructed = gst_clapper_gl_context_handler_constructed;
|
||||
gobject_class->finalize = gst_clapper_gl_context_handler_finalize;
|
||||
|
||||
importer_class->prepare = gst_clapper_gl_base_importer_prepare;
|
||||
importer_class->share_data = gst_clapper_gl_base_importer_share_data;
|
||||
importer_class->handle_context_query = gst_clapper_gl_base_importer_handle_context_query;
|
||||
importer_class->create_pool = gst_clapper_gl_base_importer_create_pool;
|
||||
importer_class->add_allocation_metas = gst_clapper_gl_base_importer_add_allocation_metas;
|
||||
handler_class->handle_context_query = gst_clapper_gl_context_handler_handle_context_query;
|
||||
}
|
||||
|
||||
gl_bi_class->gdk_context_realize = gst_clapper_gl_base_importer_gdk_context_realize;
|
||||
void
|
||||
gst_clapper_gl_context_handler_add_handler (GPtrArray *context_handlers)
|
||||
{
|
||||
guint i;
|
||||
gboolean found = FALSE;
|
||||
|
||||
for (i = 0; i < context_handlers->len; i++) {
|
||||
GstClapperContextHandler *handler = g_ptr_array_index (context_handlers, i);
|
||||
|
||||
if ((found = GST_IS_CLAPPER_GL_CONTEXT_HANDLER (handler)))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
GstClapperGLContextHandler *handler = g_object_new (
|
||||
GST_TYPE_CLAPPER_GL_CONTEXT_HANDLER, NULL);
|
||||
|
||||
g_ptr_array_add (context_handlers, handler);
|
||||
GST_DEBUG ("Added GL context handler to handlers array");
|
||||
}
|
||||
}
|
||||
|
||||
GstCaps *
|
||||
gst_clapper_gl_base_importer_make_supported_gdk_gl_caps (void)
|
||||
gst_clapper_gl_context_handler_make_gdk_gl_caps (const gchar *features, gboolean only_2d)
|
||||
{
|
||||
GstCaps *caps, *tmp;
|
||||
|
||||
tmp = gst_caps_from_string (
|
||||
GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_GL_MEMORY,
|
||||
"{ " GST_GDK_GL_TEXTURE_FORMATS " }") ", "
|
||||
"texture-target = (string) { " GST_GL_TEXTURE_TARGET_2D_STR " }");
|
||||
if (only_2d) {
|
||||
tmp = gst_caps_from_string (GST_VIDEO_CAPS_MAKE (
|
||||
"{ " GST_GDK_GL_TEXTURE_FORMATS " }") ", "
|
||||
"texture-target = (string) { " GST_GL_TEXTURE_TARGET_2D_STR " }");
|
||||
} else {
|
||||
tmp = gst_caps_from_string (GST_VIDEO_CAPS_MAKE (
|
||||
"{ " GST_GDK_GL_TEXTURE_FORMATS " }"));
|
||||
}
|
||||
|
||||
caps = gst_caps_copy (tmp);
|
||||
|
||||
gst_caps_set_features_simple (tmp, gst_caps_features_new (
|
||||
features, NULL));
|
||||
gst_caps_set_features_simple (caps, gst_caps_features_new (
|
||||
GST_CAPS_FEATURE_MEMORY_GL_MEMORY,
|
||||
GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, NULL));
|
||||
features, GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, NULL));
|
||||
|
||||
gst_caps_append (caps, tmp);
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
GStrv
|
||||
gst_clapper_gl_base_importer_make_gl_context_types (void)
|
||||
{
|
||||
GStrv context_types;
|
||||
GStrvBuilder *builder = g_strv_builder_new ();
|
||||
|
||||
g_strv_builder_add (builder, GST_GL_DISPLAY_CONTEXT_TYPE);
|
||||
g_strv_builder_add (builder, "gst.gl.app_context");
|
||||
g_strv_builder_add (builder, "gst.gl.local_context");
|
||||
|
||||
context_types = g_strv_builder_end (builder);
|
||||
g_strv_builder_unref (builder);
|
||||
|
||||
return context_types;
|
||||
}
|
||||
|
||||
GdkTexture *
|
||||
gst_clapper_gl_base_importer_make_gl_texture (GstClapperGLBaseImporter *self,
|
||||
gst_clapper_gl_context_handler_make_gl_texture (GstClapperGLContextHandler *self,
|
||||
GstBuffer *buffer, GstVideoInfo *v_info)
|
||||
{
|
||||
GdkTexture *texture;
|
||||
@@ -623,7 +548,7 @@ gst_clapper_gl_base_importer_make_gl_texture (GstClapperGLBaseImporter *self,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_LOCK (self);
|
||||
GST_OBJECT_LOCK (self);
|
||||
|
||||
/* Must have context active here for both sync meta
|
||||
* and Gdk texture format auto-detection to work */
|
||||
@@ -650,7 +575,7 @@ gst_clapper_gl_base_importer_make_gl_texture (GstClapperGLBaseImporter *self,
|
||||
gst_gl_context_activate (self->wrapped_context, FALSE);
|
||||
gdk_gl_context_clear_current ();
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self);
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
gst_video_frame_unmap (&frame);
|
||||
|
64
lib/gst/plugin/handlers/gl/gstclapperglcontexthandler.h
Normal file
64
lib/gst/plugin/handlers/gl/gstclapperglcontexthandler.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/video/video.h>
|
||||
#include <gst/gl/gl.h>
|
||||
#include <gst/gl/gstglfuncs.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "gst/plugin/gstclappercontexthandler.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_CLAPPER_GL_CONTEXT_HANDLER (gst_clapper_gl_context_handler_get_type())
|
||||
G_DECLARE_FINAL_TYPE (GstClapperGLContextHandler, gst_clapper_gl_context_handler, GST, CLAPPER_GL_CONTEXT_HANDLER, GstClapperContextHandler)
|
||||
|
||||
#define GST_CLAPPER_GL_CONTEXT_HANDLER_CAST(obj) ((GstClapperGLContextHandler *)(obj))
|
||||
|
||||
#define GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WAYLAND (GST_GL_HAVE_WINDOW_WAYLAND && defined (GDK_WINDOWING_WAYLAND))
|
||||
#define GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11 (GST_GL_HAVE_WINDOW_X11 && defined (GDK_WINDOWING_X11))
|
||||
#define GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11_GLX (GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11 && GST_GL_HAVE_PLATFORM_GLX)
|
||||
#define GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11_EGL (GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11 && GST_GL_HAVE_PLATFORM_EGL)
|
||||
#define GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WIN32 (GST_GL_HAVE_WINDOW_WIN32 && defined (GDK_WINDOWING_WIN32))
|
||||
#define GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WIN32_WGL (GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WIN32 && GST_GL_HAVE_PLATFORM_WGL)
|
||||
#define GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WIN32_EGL (GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WIN32 && GST_GL_HAVE_PLATFORM_EGL)
|
||||
#define GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_MACOS (GST_GL_HAVE_WINDOW_COCOA && defined (GDK_WINDOWING_MACOS) && GST_GL_HAVE_PLATFORM_CGL)
|
||||
|
||||
struct _GstClapperGLContextHandler
|
||||
{
|
||||
GstClapperContextHandler parent;
|
||||
|
||||
GdkGLContext *gdk_context;
|
||||
|
||||
GstGLDisplay *gst_display;
|
||||
GstGLContext *wrapped_context;
|
||||
GstGLContext *gst_context;
|
||||
};
|
||||
|
||||
void gst_clapper_gl_context_handler_add_handler (GPtrArray *context_handlers);
|
||||
|
||||
GstCaps * gst_clapper_gl_context_handler_make_gdk_gl_caps (const gchar *features, gboolean only_2d);
|
||||
|
||||
GdkTexture * gst_clapper_gl_context_handler_make_gl_texture (GstClapperGLContextHandler *handler, GstBuffer *buffer, GstVideoInfo *v_info);
|
||||
|
||||
G_END_DECLS
|
83
lib/gst/plugin/handlers/gl/meson.build
Normal file
83
lib/gst/plugin/handlers/gl/meson.build
Normal file
@@ -0,0 +1,83 @@
|
||||
gst_clapper_gl_ch_dep = dependency('', required: false)
|
||||
|
||||
build_gl_ch = (
|
||||
not get_option('glimporter').disabled()
|
||||
or not get_option('gluploader').disabled()
|
||||
)
|
||||
gl_support_required = (
|
||||
get_option('glimporter').enabled()
|
||||
or get_option('gluploader').enabled()
|
||||
)
|
||||
|
||||
gst_plugin_gl_ch_deps = [gst_clapper_sink_dep, gstgl_dep, gstglproto_dep]
|
||||
have_gtk_gl_windowing = false
|
||||
|
||||
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()
|
||||
gst_plugin_gl_ch_deps += gtk_x11_dep
|
||||
if gst_gl_have_platform_glx
|
||||
gst_plugin_gl_ch_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()
|
||||
gst_plugin_gl_ch_deps += [gtk_wayland_dep, gstglwayland_dep]
|
||||
have_gtk_gl_windowing = true
|
||||
endif
|
||||
endif
|
||||
|
||||
if gst_gl_have_window_win32 and (gst_gl_have_platform_egl or gst_gl_have_platform_wgl)
|
||||
gtk_win32_dep = dependency('gtk4-win32', required: false)
|
||||
if gtk_win32_dep.found()
|
||||
gst_plugin_gl_ch_deps += gtk_win32_dep
|
||||
have_gtk_gl_windowing = true
|
||||
endif
|
||||
endif
|
||||
|
||||
if gst_gl_have_window_cocoa and gst_gl_have_platform_cgl
|
||||
gtk_macos_dep = dependency('gtk4-macos', required: false)
|
||||
if gtk_macos_dep.found()
|
||||
gst_plugin_gl_ch_deps += gtk_macos_dep
|
||||
have_gtk_gl_windowing = true
|
||||
endif
|
||||
endif
|
||||
|
||||
if not have_gtk_gl_windowing
|
||||
if gl_support_required
|
||||
error('GL-based importer was enabled, but support for current GL windowing is missing')
|
||||
endif
|
||||
build_gl_ch = false
|
||||
endif
|
||||
|
||||
if gst_gl_have_platform_egl
|
||||
gst_plugin_gl_ch_deps += gstglegl_dep
|
||||
endif
|
||||
|
||||
foreach dep : gst_plugin_gl_ch_deps
|
||||
if not dep.found()
|
||||
if gl_support_required
|
||||
error('GL-based importer was enabled, but required dependencies were not found')
|
||||
endif
|
||||
build_gl_ch = false
|
||||
endif
|
||||
endforeach
|
||||
|
||||
if build_gl_ch
|
||||
gst_clapper_gl_ch_dep = declare_dependency(
|
||||
link_with: library('gstclapperglcontexthandler',
|
||||
'gstclapperglcontexthandler.c',
|
||||
c_args: gst_clapper_plugin_args,
|
||||
include_directories: configinc,
|
||||
dependencies: gst_plugin_gl_ch_deps,
|
||||
version: libversion,
|
||||
install: true,
|
||||
),
|
||||
include_directories: configinc,
|
||||
dependencies: gst_plugin_gl_ch_deps,
|
||||
)
|
||||
endif
|
1
lib/gst/plugin/handlers/meson.build
Normal file
1
lib/gst/plugin/handlers/meson.build
Normal file
@@ -0,0 +1 @@
|
||||
subdir('gl')
|
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gst/gl/gl.h>
|
||||
|
||||
#include "gst/plugin/gstclapperimporter.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_CLAPPER_GL_BASE_IMPORTER (gst_clapper_gl_base_importer_get_type())
|
||||
#define GST_IS_CLAPPER_GL_BASE_IMPORTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_CLAPPER_GL_BASE_IMPORTER))
|
||||
#define GST_IS_CLAPPER_GL_BASE_IMPORTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_CLAPPER_GL_BASE_IMPORTER))
|
||||
#define GST_CLAPPER_GL_BASE_IMPORTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_CLAPPER_GL_BASE_IMPORTER, GstClapperGLBaseImporterClass))
|
||||
#define GST_CLAPPER_GL_BASE_IMPORTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_CLAPPER_GL_BASE_IMPORTER, GstClapperGLBaseImporter))
|
||||
#define GST_CLAPPER_GL_BASE_IMPORTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_CLAPPER_GL_BASE_IMPORTER, GstClapperGLBaseImporterClass))
|
||||
#define GST_CLAPPER_GL_BASE_IMPORTER_CAST(obj) ((GstClapperGLBaseImporter *)(obj))
|
||||
|
||||
#define GST_CLAPPER_GL_BASE_IMPORTER_GET_LOCK(obj) (&GST_CLAPPER_GL_BASE_IMPORTER_CAST(obj)->lock)
|
||||
#define GST_CLAPPER_GL_BASE_IMPORTER_LOCK(obj) g_mutex_lock (GST_CLAPPER_GL_BASE_IMPORTER_GET_LOCK(obj))
|
||||
#define GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK(obj) g_mutex_unlock (GST_CLAPPER_GL_BASE_IMPORTER_GET_LOCK(obj))
|
||||
|
||||
#define GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WAYLAND (GST_GL_HAVE_WINDOW_WAYLAND && defined (GDK_WINDOWING_WAYLAND))
|
||||
#define GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11 (GST_GL_HAVE_WINDOW_X11 && defined (GDK_WINDOWING_X11))
|
||||
#define GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11_GLX (GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11 && GST_GL_HAVE_PLATFORM_GLX)
|
||||
#define GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11_EGL (GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11 && GST_GL_HAVE_PLATFORM_EGL)
|
||||
#define GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WIN32 (GST_GL_HAVE_WINDOW_WIN32 && defined (GDK_WINDOWING_WIN32))
|
||||
#define GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WIN32_WGL (GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WIN32 && GST_GL_HAVE_PLATFORM_WGL)
|
||||
#define GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WIN32_EGL (GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WIN32 && GST_GL_HAVE_PLATFORM_EGL)
|
||||
#define GST_CLAPPER_GL_BASE_IMPORTER_HAVE_MACOS (GST_GL_HAVE_WINDOW_COCOA && defined (GDK_WINDOWING_MACOS) && GST_GL_HAVE_PLATFORM_CGL)
|
||||
|
||||
typedef struct _GstClapperGLBaseImporter GstClapperGLBaseImporter;
|
||||
typedef struct _GstClapperGLBaseImporterClass GstClapperGLBaseImporterClass;
|
||||
|
||||
#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GstClapperGLBaseImporter, gst_object_unref)
|
||||
#endif
|
||||
|
||||
struct _GstClapperGLBaseImporter
|
||||
{
|
||||
GstClapperImporter parent;
|
||||
|
||||
GMutex lock;
|
||||
|
||||
GdkGLContext *gdk_context;
|
||||
|
||||
GstGLDisplay *gst_display;
|
||||
GstGLContext *wrapped_context;
|
||||
GstGLContext *gst_context;
|
||||
};
|
||||
|
||||
struct _GstClapperGLBaseImporterClass
|
||||
{
|
||||
GstClapperImporterClass parent_class;
|
||||
|
||||
gboolean (* gdk_context_realize) (GstClapperGLBaseImporter *gl_bi,
|
||||
GdkGLContext *gdk_context);
|
||||
};
|
||||
|
||||
GType gst_clapper_gl_base_importer_get_type (void);
|
||||
|
||||
GstCaps * gst_clapper_gl_base_importer_make_supported_gdk_gl_caps (void);
|
||||
|
||||
GStrv gst_clapper_gl_base_importer_make_gl_context_types (void);
|
||||
|
||||
GdkTexture * gst_clapper_gl_base_importer_make_gl_texture (GstClapperGLBaseImporter *self, GstBuffer *buffer, GstVideoInfo *v_info);
|
||||
|
||||
G_END_DECLS
|
@@ -27,15 +27,45 @@
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
||||
#define parent_class gst_clapper_gl_importer_parent_class
|
||||
GST_CLAPPER_IMPORTER_DEFINE (GstClapperGLImporter, gst_clapper_gl_importer, GST_TYPE_CLAPPER_GL_BASE_IMPORTER);
|
||||
GST_CLAPPER_IMPORTER_DEFINE (GstClapperGLImporter, gst_clapper_gl_importer, GST_TYPE_CLAPPER_IMPORTER);
|
||||
|
||||
static GstBufferPool *
|
||||
gst_clapper_gl_importer_create_pool (GstClapperImporter *importer, GstStructure **config)
|
||||
{
|
||||
GstClapperGLImporter *self = GST_CLAPPER_GL_IMPORTER_CAST (importer);
|
||||
GstBufferPool *pool;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Creating new GL buffer pool");
|
||||
|
||||
pool = gst_gl_buffer_pool_new (self->gl_handler->gst_context);
|
||||
*config = gst_buffer_pool_get_config (pool);
|
||||
|
||||
gst_buffer_pool_config_add_option (*config, GST_BUFFER_POOL_OPTION_VIDEO_META);
|
||||
gst_buffer_pool_config_add_option (*config, GST_BUFFER_POOL_OPTION_GL_SYNC_META);
|
||||
|
||||
return pool;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gl_importer_add_allocation_metas (GstClapperImporter *importer, GstQuery *query)
|
||||
{
|
||||
GstClapperGLImporter *self = GST_CLAPPER_GL_IMPORTER_CAST (importer);
|
||||
|
||||
/* We can support GL sync meta */
|
||||
if (self->gl_handler->gst_context->gl_vtable->FenceSync)
|
||||
gst_query_add_allocation_meta (query, GST_GL_SYNC_META_API_TYPE, NULL);
|
||||
|
||||
/* Also add base importer class supported meta */
|
||||
GST_CLAPPER_IMPORTER_CLASS (parent_class)->add_allocation_metas (importer, query);
|
||||
}
|
||||
|
||||
static GdkTexture *
|
||||
gst_clapper_gl_importer_generate_texture (GstClapperImporter *importer,
|
||||
GstBuffer *buffer, GstVideoInfo *v_info)
|
||||
{
|
||||
GstClapperGLBaseImporter *gl_bi = GST_CLAPPER_GL_BASE_IMPORTER_CAST (importer);
|
||||
GstClapperGLImporter *self = GST_CLAPPER_GL_IMPORTER_CAST (importer);
|
||||
|
||||
return gst_clapper_gl_base_importer_make_gl_texture (gl_bi, buffer, v_info);
|
||||
return gst_clapper_gl_context_handler_make_gl_texture (self->gl_handler, buffer, v_info);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -43,28 +73,58 @@ gst_clapper_gl_importer_init (GstClapperGLImporter *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gl_importer_finalize (GObject *object)
|
||||
{
|
||||
GstClapperGLImporter *self = GST_CLAPPER_GL_IMPORTER_CAST (object);
|
||||
|
||||
gst_clear_object (&self->gl_handler);
|
||||
|
||||
GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_gl_importer_class_init (GstClapperGLImporterClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
GstClapperImporterClass *importer_class = (GstClapperImporterClass *) klass;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clapperglimporter", 0,
|
||||
"Clapper GL Importer");
|
||||
|
||||
gobject_class->finalize = gst_clapper_gl_importer_finalize;
|
||||
|
||||
importer_class->create_pool = gst_clapper_gl_importer_create_pool;
|
||||
importer_class->add_allocation_metas = gst_clapper_gl_importer_add_allocation_metas;
|
||||
importer_class->generate_texture = gst_clapper_gl_importer_generate_texture;
|
||||
}
|
||||
|
||||
GstClapperImporter *
|
||||
make_importer (void)
|
||||
make_importer (GPtrArray *context_handlers)
|
||||
{
|
||||
return g_object_new (GST_TYPE_CLAPPER_GL_IMPORTER, NULL);
|
||||
GstClapperGLImporter *self;
|
||||
GstClapperContextHandler *handler;
|
||||
|
||||
handler = gst_clapper_context_handler_obtain_with_type (context_handlers,
|
||||
GST_TYPE_CLAPPER_GL_CONTEXT_HANDLER);
|
||||
|
||||
if (G_UNLIKELY (!handler))
|
||||
return NULL;
|
||||
|
||||
self = g_object_new (GST_TYPE_CLAPPER_GL_IMPORTER, NULL);
|
||||
self->gl_handler = GST_CLAPPER_GL_CONTEXT_HANDLER_CAST (handler);
|
||||
|
||||
return GST_CLAPPER_IMPORTER_CAST (self);
|
||||
}
|
||||
|
||||
GstCaps *
|
||||
make_caps (gboolean is_template, GstRank *rank, GStrv *context_types)
|
||||
make_caps (gboolean is_template, GstRank *rank, GPtrArray *context_handlers)
|
||||
{
|
||||
*rank = GST_RANK_SECONDARY;
|
||||
*context_types = gst_clapper_gl_base_importer_make_gl_context_types ();
|
||||
|
||||
return gst_clapper_gl_base_importer_make_supported_gdk_gl_caps ();
|
||||
if (!is_template && context_handlers)
|
||||
gst_clapper_gl_context_handler_add_handler (context_handlers);
|
||||
|
||||
return gst_clapper_gl_context_handler_make_gdk_gl_caps (
|
||||
GST_CAPS_FEATURE_MEMORY_GL_MEMORY, TRUE);
|
||||
}
|
||||
|
@@ -19,18 +19,21 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gstclapperglbaseimporter.h"
|
||||
#include "gst/plugin/gstclapperimporter.h"
|
||||
#include "gst/plugin/handlers/gl/gstclapperglcontexthandler.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_CLAPPER_GL_IMPORTER (gst_clapper_gl_importer_get_type())
|
||||
G_DECLARE_FINAL_TYPE (GstClapperGLImporter, gst_clapper_gl_importer, GST, CLAPPER_GL_IMPORTER, GstClapperGLBaseImporter)
|
||||
G_DECLARE_FINAL_TYPE (GstClapperGLImporter, gst_clapper_gl_importer, GST, CLAPPER_GL_IMPORTER, GstClapperImporter)
|
||||
|
||||
#define GST_CLAPPER_GL_IMPORTER_CAST(obj) ((GstClapperGLImporter *)(obj))
|
||||
|
||||
struct _GstClapperGLImporter
|
||||
{
|
||||
GstClapperGLBaseImporter parent;
|
||||
GstClapperImporter parent;
|
||||
|
||||
GstClapperGLContextHandler *gl_handler;
|
||||
};
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -22,40 +22,38 @@
|
||||
#endif
|
||||
|
||||
#include "gstclappergluploader.h"
|
||||
#include "gst/plugin/gstgtkutils.h"
|
||||
|
||||
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11
|
||||
#include <gdk/x11/gdkx.h>
|
||||
#endif
|
||||
|
||||
#define GST_CAT_DEFAULT gst_clapper_gl_uploader_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
||||
#define parent_class gst_clapper_gl_uploader_parent_class
|
||||
GST_CLAPPER_IMPORTER_DEFINE (GstClapperGLUploader, gst_clapper_gl_uploader, GST_TYPE_CLAPPER_GL_BASE_IMPORTER);
|
||||
GST_CLAPPER_IMPORTER_DEFINE (GstClapperGLUploader, gst_clapper_gl_uploader, GST_TYPE_CLAPPER_IMPORTER);
|
||||
|
||||
static void
|
||||
_update_elements_caps_locked (GstClapperGLUploader *self, GstCaps *upload_sink_caps)
|
||||
{
|
||||
GstClapperGLBaseImporter *gl_bi = GST_CLAPPER_GL_BASE_IMPORTER_CAST (self);
|
||||
GstGLContext *gst_context;
|
||||
GstCaps *upload_src_caps, *color_sink_caps, *color_src_caps, *gdk_sink_caps;
|
||||
|
||||
gst_context = self->gl_handler->gst_context;
|
||||
|
||||
GST_INFO_OBJECT (self, "Input caps: %" GST_PTR_FORMAT, upload_sink_caps);
|
||||
|
||||
upload_src_caps = gst_gl_upload_transform_caps (self->upload, gl_bi->gst_context,
|
||||
upload_src_caps = gst_gl_upload_transform_caps (self->upload, gst_context,
|
||||
GST_PAD_SINK, upload_sink_caps, NULL);
|
||||
upload_src_caps = gst_caps_fixate (upload_src_caps);
|
||||
|
||||
GST_INFO_OBJECT (self, "GLUpload caps: %" GST_PTR_FORMAT, upload_src_caps);
|
||||
gst_gl_upload_set_caps (self->upload, upload_sink_caps, upload_src_caps);
|
||||
|
||||
gdk_sink_caps = gst_clapper_gl_base_importer_make_supported_gdk_gl_caps ();
|
||||
color_sink_caps = gst_gl_color_convert_transform_caps (gl_bi->gst_context,
|
||||
gdk_sink_caps = gst_clapper_gl_context_handler_make_gdk_gl_caps (
|
||||
GST_CAPS_FEATURE_MEMORY_GL_MEMORY, TRUE);
|
||||
color_sink_caps = gst_gl_color_convert_transform_caps (gst_context,
|
||||
GST_PAD_SRC, upload_src_caps, gdk_sink_caps);
|
||||
gst_caps_unref (gdk_sink_caps);
|
||||
|
||||
/* Second caps arg is transfer-full */
|
||||
color_src_caps = gst_gl_color_convert_fixate_caps (gl_bi->gst_context,
|
||||
color_src_caps = gst_gl_color_convert_fixate_caps (gst_context,
|
||||
GST_PAD_SINK, upload_src_caps, color_sink_caps);
|
||||
|
||||
GST_INFO_OBJECT (self, "GLColorConvert caps: %" GST_PTR_FORMAT, color_src_caps);
|
||||
@@ -72,9 +70,9 @@ gst_clapper_gl_uploader_set_caps (GstClapperImporter *importer, GstCaps *caps)
|
||||
{
|
||||
GstClapperGLUploader *self = GST_CLAPPER_GL_UPLOADER_CAST (importer);
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_LOCK (self);
|
||||
GST_CLAPPER_GL_UPLOADER_LOCK (self);
|
||||
_update_elements_caps_locked (self, caps);
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self);
|
||||
GST_CLAPPER_GL_UPLOADER_UNLOCK (self);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -92,28 +90,6 @@ _uploader_reconfigure_locked (GstClapperGLUploader *self)
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_clapper_gl_uploader_prepare (GstClapperImporter *importer)
|
||||
{
|
||||
gboolean res = GST_CLAPPER_IMPORTER_CLASS (parent_class)->prepare (importer);
|
||||
|
||||
if (res) {
|
||||
GstClapperGLUploader *self = GST_CLAPPER_GL_UPLOADER_CAST (importer);
|
||||
GstClapperGLBaseImporter *gl_bi = GST_CLAPPER_GL_BASE_IMPORTER_CAST (importer);
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_LOCK (self);
|
||||
|
||||
if (!self->upload)
|
||||
self->upload = gst_gl_upload_new (gl_bi->gst_context);
|
||||
if (!self->color_convert)
|
||||
self->color_convert = gst_gl_color_convert_new (gl_bi->gst_context);
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static GstBuffer *
|
||||
_upload_perform_locked (GstClapperGLUploader *self, GstBuffer *buffer)
|
||||
{
|
||||
@@ -152,13 +128,19 @@ gst_clapper_gl_uploader_add_allocation_metas (GstClapperImporter *importer, GstQ
|
||||
GstClapperGLUploader *self = GST_CLAPPER_GL_UPLOADER_CAST (importer);
|
||||
GstGLUpload *upload;
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_LOCK (self);
|
||||
GST_CLAPPER_GL_UPLOADER_LOCK (self);
|
||||
upload = gst_object_ref (self->upload);
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self);
|
||||
GST_CLAPPER_GL_UPLOADER_UNLOCK (self);
|
||||
|
||||
/* Add glupload supported meta */
|
||||
gst_gl_upload_propose_allocation (upload, NULL, query);
|
||||
gst_object_unref (upload);
|
||||
|
||||
/* We can support GL sync meta */
|
||||
if (self->gl_handler->gst_context->gl_vtable->FenceSync)
|
||||
gst_query_add_allocation_meta (query, GST_GL_SYNC_META_API_TYPE, NULL);
|
||||
|
||||
/* Also add base importer class supported meta */
|
||||
GST_CLAPPER_IMPORTER_CLASS (parent_class)->add_allocation_metas (importer, query);
|
||||
}
|
||||
|
||||
@@ -167,7 +149,6 @@ gst_clapper_gl_uploader_generate_texture (GstClapperImporter *importer,
|
||||
GstBuffer *buffer, GstVideoInfo *v_info)
|
||||
{
|
||||
GstClapperGLUploader *self = GST_CLAPPER_GL_UPLOADER_CAST (importer);
|
||||
GstClapperGLBaseImporter *gl_bi = GST_CLAPPER_GL_BASE_IMPORTER_CAST (importer);
|
||||
GstBuffer *upload_buf, *color_buf;
|
||||
GdkTexture *texture;
|
||||
|
||||
@@ -177,13 +158,13 @@ gst_clapper_gl_uploader_generate_texture (GstClapperImporter *importer,
|
||||
|
||||
GST_LOG_OBJECT (self, "Uploading %" GST_PTR_FORMAT, buffer);
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_LOCK (self);
|
||||
GST_CLAPPER_GL_UPLOADER_LOCK (self);
|
||||
|
||||
upload_buf = _upload_perform_locked (self, buffer);
|
||||
|
||||
if (G_UNLIKELY (!upload_buf)) {
|
||||
GST_ERROR_OBJECT (self, "Could not perform upload on input buffer");
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self);
|
||||
GST_CLAPPER_GL_UPLOADER_UNLOCK (self);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -198,7 +179,7 @@ gst_clapper_gl_uploader_generate_texture (GstClapperImporter *importer,
|
||||
self->has_pending_v_info = FALSE;
|
||||
}
|
||||
|
||||
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self);
|
||||
GST_CLAPPER_GL_UPLOADER_UNLOCK (self);
|
||||
|
||||
if (G_UNLIKELY (!color_buf)) {
|
||||
GST_ERROR_OBJECT (self, "Could not perform color conversion on input buffer");
|
||||
@@ -206,7 +187,7 @@ gst_clapper_gl_uploader_generate_texture (GstClapperImporter *importer,
|
||||
}
|
||||
GST_LOG_OBJECT (self, "Color converted into %" GST_PTR_FORMAT, color_buf);
|
||||
|
||||
texture = gst_clapper_gl_base_importer_make_gl_texture (gl_bi, color_buf, &self->v_info);
|
||||
texture = gst_clapper_gl_context_handler_make_gl_texture (self->gl_handler, color_buf, &self->v_info);
|
||||
gst_buffer_unref (color_buf);
|
||||
|
||||
return texture;
|
||||
@@ -215,6 +196,8 @@ gst_clapper_gl_uploader_generate_texture (GstClapperImporter *importer,
|
||||
static void
|
||||
gst_clapper_gl_uploader_init (GstClapperGLUploader *self)
|
||||
{
|
||||
g_mutex_init (&self->lock);
|
||||
|
||||
gst_video_info_init (&self->pending_v_info);
|
||||
gst_video_info_init (&self->v_info);
|
||||
}
|
||||
@@ -227,6 +210,10 @@ gst_clapper_gl_uploader_finalize (GObject *object)
|
||||
gst_clear_object (&self->upload);
|
||||
gst_clear_object (&self->color_convert);
|
||||
|
||||
gst_clear_object (&self->gl_handler);
|
||||
|
||||
g_mutex_clear (&self->lock);
|
||||
|
||||
GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
|
||||
}
|
||||
|
||||
@@ -241,7 +228,6 @@ gst_clapper_gl_uploader_class_init (GstClapperGLUploaderClass *klass)
|
||||
|
||||
gobject_class->finalize = gst_clapper_gl_uploader_finalize;
|
||||
|
||||
importer_class->prepare = gst_clapper_gl_uploader_prepare;
|
||||
importer_class->set_caps = gst_clapper_gl_uploader_set_caps;
|
||||
importer_class->create_pool = gst_clapper_gl_uploader_create_pool;
|
||||
importer_class->add_allocation_metas = gst_clapper_gl_uploader_add_allocation_metas;
|
||||
@@ -249,64 +235,94 @@ gst_clapper_gl_uploader_class_init (GstClapperGLUploaderClass *klass)
|
||||
}
|
||||
|
||||
GstClapperImporter *
|
||||
make_importer (void)
|
||||
make_importer (GPtrArray *context_handlers)
|
||||
{
|
||||
return g_object_new (GST_TYPE_CLAPPER_GL_UPLOADER, NULL);
|
||||
GstClapperGLUploader *self;
|
||||
GstClapperContextHandler *handler;
|
||||
|
||||
handler = gst_clapper_context_handler_obtain_with_type (context_handlers,
|
||||
GST_TYPE_CLAPPER_GL_CONTEXT_HANDLER);
|
||||
|
||||
if (G_UNLIKELY (!handler))
|
||||
return NULL;
|
||||
|
||||
self = g_object_new (GST_TYPE_CLAPPER_GL_UPLOADER, NULL);
|
||||
self->gl_handler = GST_CLAPPER_GL_CONTEXT_HANDLER_CAST (handler);
|
||||
self->upload = gst_gl_upload_new (self->gl_handler->gst_context);
|
||||
self->color_convert = gst_gl_color_convert_new (self->gl_handler->gst_context);
|
||||
|
||||
return GST_CLAPPER_IMPORTER_CAST (self);
|
||||
}
|
||||
|
||||
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11_GLX
|
||||
static gboolean
|
||||
_filter_glx_caps_cb (GstCapsFeatures *features,
|
||||
GstStructure *structure, gpointer user_data)
|
||||
static GstCaps *
|
||||
_make_actual_caps (GstClapperGLContextHandler *gl_handler)
|
||||
{
|
||||
return !gst_caps_features_contains (features, "memory:DMABuf");
|
||||
GstGLUpload *upload;
|
||||
GstCaps *gdk_sink_caps, *color_sink_caps, *upload_sink_caps, *actual;
|
||||
guint i;
|
||||
|
||||
/* Having "gst_context" means we also have all other contexts and
|
||||
* display as they are used to create it, so no need to check */
|
||||
if (!gl_handler->gst_context)
|
||||
return NULL;
|
||||
|
||||
gdk_sink_caps = gst_clapper_gl_context_handler_make_gdk_gl_caps (
|
||||
GST_CAPS_FEATURE_MEMORY_GL_MEMORY, TRUE);
|
||||
|
||||
color_sink_caps = gst_gl_color_convert_transform_caps (gl_handler->gst_context,
|
||||
GST_PAD_SRC, gdk_sink_caps, NULL);
|
||||
gst_caps_unref (gdk_sink_caps);
|
||||
|
||||
upload = gst_gl_upload_new (NULL);
|
||||
|
||||
upload_sink_caps = gst_gl_upload_transform_caps (upload, gl_handler->gst_context,
|
||||
GST_PAD_SRC, color_sink_caps, NULL);
|
||||
gst_caps_unref (color_sink_caps);
|
||||
|
||||
gst_object_unref (upload);
|
||||
|
||||
/* Check for existence and remove duplicated structures,
|
||||
* they may contain unsupported by our GL context formats */
|
||||
actual = gst_caps_new_empty ();
|
||||
for (i = 0; i < gst_caps_get_size (upload_sink_caps); i++) {
|
||||
GstCaps *tmp = gst_caps_copy_nth (upload_sink_caps, i);
|
||||
|
||||
if (!gst_caps_can_intersect (actual, tmp))
|
||||
gst_caps_append (actual, tmp);
|
||||
else
|
||||
gst_caps_unref (tmp);
|
||||
}
|
||||
gst_caps_unref (upload_sink_caps);
|
||||
|
||||
if (G_UNLIKELY (gst_caps_is_empty (actual)))
|
||||
gst_clear_caps (&actual);
|
||||
|
||||
return actual;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_update_glx_caps_on_main (GstCaps *caps)
|
||||
GstCaps *
|
||||
make_caps (gboolean is_template, GstRank *rank, GPtrArray *context_handlers)
|
||||
{
|
||||
GdkDisplay *gdk_display;
|
||||
GstCaps *caps = NULL;
|
||||
|
||||
if (!gtk_init_check ())
|
||||
return FALSE;
|
||||
if (is_template) {
|
||||
caps = gst_gl_upload_get_input_template_caps ();
|
||||
} else if (context_handlers) {
|
||||
GstClapperGLContextHandler *gl_handler;
|
||||
|
||||
gdk_display = gdk_display_get_default ();
|
||||
if (G_UNLIKELY (!gdk_display))
|
||||
return FALSE;
|
||||
/* Add GL context handler if not already present */
|
||||
gst_clapper_gl_context_handler_add_handler (context_handlers);
|
||||
|
||||
if (GDK_IS_X11_DISPLAY (gdk_display)) {
|
||||
gboolean using_glx = TRUE;
|
||||
|
||||
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11_EGL
|
||||
using_glx = (gdk_x11_display_get_egl_display (gdk_display) == NULL);
|
||||
#endif
|
||||
|
||||
if (using_glx) {
|
||||
gst_caps_filter_and_map_in_place (caps,
|
||||
(GstCapsFilterMapFunc) _filter_glx_caps_cb, NULL);
|
||||
if ((gl_handler = GST_CLAPPER_GL_CONTEXT_HANDLER_CAST (
|
||||
gst_clapper_context_handler_obtain_with_type (context_handlers,
|
||||
GST_TYPE_CLAPPER_GL_CONTEXT_HANDLER)))) {
|
||||
caps = _make_actual_caps (gl_handler);
|
||||
gst_object_unref (gl_handler);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
GstCaps *
|
||||
make_caps (gboolean is_template, GstRank *rank, GStrv *context_types)
|
||||
{
|
||||
GstCaps *caps = gst_gl_upload_get_input_template_caps ();
|
||||
|
||||
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11_GLX
|
||||
if (!is_template && !(! !gst_gtk_invoke_on_main ((GThreadFunc) (GCallback)
|
||||
_update_glx_caps_on_main, caps)))
|
||||
gst_clear_caps (&caps);
|
||||
#endif
|
||||
|
||||
if (G_UNLIKELY (!caps))
|
||||
return NULL;
|
||||
|
||||
*rank = GST_RANK_MARGINAL + 1;
|
||||
*context_types = gst_clapper_gl_base_importer_make_gl_context_types ();
|
||||
if (caps)
|
||||
*rank = GST_RANK_MARGINAL + 1;
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
@@ -19,18 +19,27 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gstclapperglbaseimporter.h"
|
||||
#include "gst/plugin/gstclapperimporter.h"
|
||||
#include "gst/plugin/handlers/gl/gstclapperglcontexthandler.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_CLAPPER_GL_UPLOADER (gst_clapper_gl_uploader_get_type())
|
||||
G_DECLARE_FINAL_TYPE (GstClapperGLUploader, gst_clapper_gl_uploader, GST, CLAPPER_GL_UPLOADER, GstClapperGLBaseImporter)
|
||||
G_DECLARE_FINAL_TYPE (GstClapperGLUploader, gst_clapper_gl_uploader, GST, CLAPPER_GL_UPLOADER, GstClapperImporter)
|
||||
|
||||
#define GST_CLAPPER_GL_UPLOADER_CAST(obj) ((GstClapperGLUploader *)(obj))
|
||||
|
||||
#define GST_CLAPPER_GL_UPLOADER_GET_LOCK(obj) (&GST_CLAPPER_GL_UPLOADER_CAST(obj)->lock)
|
||||
#define GST_CLAPPER_GL_UPLOADER_LOCK(obj) g_mutex_lock (GST_CLAPPER_GL_UPLOADER_GET_LOCK(obj))
|
||||
#define GST_CLAPPER_GL_UPLOADER_UNLOCK(obj) g_mutex_unlock (GST_CLAPPER_GL_UPLOADER_GET_LOCK(obj))
|
||||
|
||||
struct _GstClapperGLUploader
|
||||
{
|
||||
GstClapperGLBaseImporter parent;
|
||||
GstClapperImporter parent;
|
||||
|
||||
GMutex lock;
|
||||
|
||||
GstClapperGLContextHandler *gl_handler;
|
||||
|
||||
GstGLUpload *upload;
|
||||
GstGLColorConvert *color_convert;
|
||||
|
@@ -47,13 +47,6 @@ gst_clapper_raw_importer_create_pool (GstClapperImporter *importer, GstStructure
|
||||
return pool;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clapper_raw_importer_add_allocation_metas (GstClapperImporter *importer, GstQuery *query)
|
||||
{
|
||||
gst_query_add_allocation_meta (query, GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL);
|
||||
gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
|
||||
}
|
||||
|
||||
static GdkTexture *
|
||||
gst_clapper_raw_importer_generate_texture (GstClapperImporter *importer,
|
||||
GstBuffer *buffer, GstVideoInfo *v_info)
|
||||
@@ -86,18 +79,17 @@ gst_clapper_raw_importer_class_init (GstClapperRawImporterClass *klass)
|
||||
"Clapper RAW Importer");
|
||||
|
||||
importer_class->create_pool = gst_clapper_raw_importer_create_pool;
|
||||
importer_class->add_allocation_metas = gst_clapper_raw_importer_add_allocation_metas;
|
||||
importer_class->generate_texture = gst_clapper_raw_importer_generate_texture;
|
||||
}
|
||||
|
||||
GstClapperImporter *
|
||||
make_importer (void)
|
||||
make_importer (GPtrArray *context_handlers)
|
||||
{
|
||||
return g_object_new (GST_TYPE_CLAPPER_RAW_IMPORTER, NULL);
|
||||
}
|
||||
|
||||
GstCaps *
|
||||
make_caps (gboolean is_template, GstRank *rank, GStrv *context_types)
|
||||
make_caps (gboolean is_template, GstRank *rank, GPtrArray *context_handlers)
|
||||
{
|
||||
*rank = GST_RANK_MARGINAL;
|
||||
|
||||
|
@@ -1,20 +1,9 @@
|
||||
gst_clapper_gl_base_importer_dep = dependency('', required: false)
|
||||
|
||||
all_importers = [
|
||||
'glimporter',
|
||||
'gluploader',
|
||||
'rawimporter',
|
||||
]
|
||||
|
||||
build_glbase = (
|
||||
not get_option('glimporter').disabled()
|
||||
or not get_option('gluploader').disabled()
|
||||
)
|
||||
gl_support_required = (
|
||||
get_option('glimporter').enabled()
|
||||
or get_option('gluploader').enabled()
|
||||
)
|
||||
|
||||
# We cannot build any importers without sink that they depend on
|
||||
if not gst_clapper_sink_dep.found()
|
||||
foreach imp : all_importers
|
||||
@@ -24,89 +13,16 @@ if not gst_clapper_sink_dep.found()
|
||||
endforeach
|
||||
endif
|
||||
|
||||
gst_plugin_gl_base_deps = [gst_clapper_sink_dep, gstgl_dep, gstglproto_dep]
|
||||
have_gtk_gl_windowing = false
|
||||
|
||||
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()
|
||||
gst_plugin_gl_base_deps += gtk_x11_dep
|
||||
if gst_gl_have_platform_glx
|
||||
gst_plugin_gl_base_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()
|
||||
gst_plugin_gl_base_deps += [gtk_wayland_dep, gstglwayland_dep]
|
||||
have_gtk_gl_windowing = true
|
||||
endif
|
||||
endif
|
||||
|
||||
if gst_gl_have_window_win32 and (gst_gl_have_platform_egl or gst_gl_have_platform_wgl)
|
||||
gtk_win32_dep = dependency('gtk4-win32', required: false)
|
||||
if gtk_win32_dep.found()
|
||||
gst_plugin_gl_base_deps += gtk_win32_dep
|
||||
have_gtk_gl_windowing = true
|
||||
endif
|
||||
endif
|
||||
|
||||
if gst_gl_have_window_cocoa and gst_gl_have_platform_cgl
|
||||
gtk_macos_dep = dependency('gtk4-macos', required: false)
|
||||
if gtk_macos_dep.found()
|
||||
gst_plugin_gl_base_deps += gtk_macos_dep
|
||||
have_gtk_gl_windowing = true
|
||||
endif
|
||||
endif
|
||||
|
||||
if not have_gtk_gl_windowing
|
||||
if gl_support_required
|
||||
error('GL-based importer was enabled, but support for current GL windowing is missing')
|
||||
endif
|
||||
build_glbase = false
|
||||
endif
|
||||
|
||||
if gst_gl_have_platform_egl
|
||||
gst_plugin_gl_base_deps += gstglegl_dep
|
||||
endif
|
||||
|
||||
foreach dep : gst_plugin_gl_base_deps
|
||||
if not dep.found()
|
||||
if gl_support_required
|
||||
error('GL-based importer was enabled, but required dependencies were not found')
|
||||
endif
|
||||
build_glbase = false
|
||||
endif
|
||||
endforeach
|
||||
|
||||
if build_glbase
|
||||
gst_clapper_gl_base_importer_dep = declare_dependency(
|
||||
link_with: library('gstclapperglbaseimporter',
|
||||
'gstclapperglbaseimporter.c',
|
||||
c_args: gst_clapper_plugin_args,
|
||||
include_directories: configinc,
|
||||
dependencies: gst_plugin_gl_base_deps,
|
||||
version: libversion,
|
||||
install: true,
|
||||
),
|
||||
include_directories: configinc,
|
||||
dependencies: gst_plugin_gl_base_deps,
|
||||
)
|
||||
endif
|
||||
|
||||
build_glimporter = (
|
||||
not get_option('glimporter').disabled()
|
||||
and gst_clapper_gl_base_importer_dep.found()
|
||||
and gst_clapper_gl_ch_dep.found()
|
||||
)
|
||||
|
||||
if build_glimporter
|
||||
library(
|
||||
'gstclapperglimporter',
|
||||
'gstclapperglimporter.c',
|
||||
dependencies: gst_clapper_gl_base_importer_dep,
|
||||
dependencies: gst_clapper_gl_ch_dep,
|
||||
include_directories: configinc,
|
||||
c_args: gst_clapper_plugin_args,
|
||||
install: true,
|
||||
@@ -116,14 +32,14 @@ endif
|
||||
|
||||
build_gluploader = (
|
||||
not get_option('gluploader').disabled()
|
||||
and gst_clapper_gl_base_importer_dep.found()
|
||||
and gst_clapper_gl_ch_dep.found()
|
||||
)
|
||||
|
||||
if build_gluploader
|
||||
library(
|
||||
'gstclappergluploader',
|
||||
'gstclappergluploader.c',
|
||||
dependencies: gst_clapper_gl_base_importer_dep,
|
||||
dependencies: gst_clapper_gl_ch_dep,
|
||||
include_directories: configinc,
|
||||
c_args: gst_clapper_plugin_args,
|
||||
install: true,
|
||||
|
@@ -41,6 +41,7 @@ gst_clapper_plugin_sources = [
|
||||
'gstclapperpaintable.c',
|
||||
'gstgtkutils.c',
|
||||
'gstplugin.c',
|
||||
'gstclappercontexthandler.c',
|
||||
'gstclapperimporter.c',
|
||||
'gstclapperimporterloader.c',
|
||||
]
|
||||
@@ -60,4 +61,5 @@ if build_gst_plugin
|
||||
)
|
||||
endif
|
||||
|
||||
subdir('handlers')
|
||||
subdir('importers')
|
||||
|
@@ -1,5 +1,5 @@
|
||||
project('com.github.rafostar.Clapper', 'c', 'cpp',
|
||||
version: '0.5.0',
|
||||
version: '0.5.2',
|
||||
meson_version: '>= 0.50.0',
|
||||
license: 'GPL-3.0-or-later',
|
||||
default_options: [
|
||||
|
@@ -5,7 +5,7 @@
|
||||
"sdk": "org.gnome.Sdk",
|
||||
"sdk-extensions": [
|
||||
"org.freedesktop.Sdk.Extension.rust-nightly",
|
||||
"org.freedesktop.Sdk.Extension.llvm13"
|
||||
"org.freedesktop.Sdk.Extension.llvm14"
|
||||
],
|
||||
"command": "com.github.rafostar.Clapper",
|
||||
"finish-args": [
|
||||
@@ -18,20 +18,18 @@
|
||||
"--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.*",
|
||||
"--talk-name=org.gnome.Shell",
|
||||
"--env=GST_PLUGIN_SYSTEM_PATH=/app/lib/gstreamer-1.0",
|
||||
"--env=GST_VAAPI_ALL_DRIVERS=1"
|
||||
"--env=GST_PLUGIN_SYSTEM_PATH=/app/lib/gstreamer-1.0"
|
||||
],
|
||||
"build-options": {
|
||||
"append-path": "/usr/lib/sdk/rust-nightly/bin:/usr/lib/sdk/llvm13/bin",
|
||||
"prepend-ld-library-path": "/usr/lib/sdk/llvm13/lib"
|
||||
"append-path": "/usr/lib/sdk/rust-nightly/bin:/usr/lib/sdk/llvm14/bin",
|
||||
"prepend-ld-library-path": "/usr/lib/sdk/llvm14/lib"
|
||||
},
|
||||
"modules": [
|
||||
"flathub/shared-modules/gudev/gudev.json",
|
||||
"flathub/lib/libsass.json",
|
||||
"flathub/lib/sassc.json",
|
||||
"flathub/lib/libadwaita.json",
|
||||
"flathub/lib/liba52.json",
|
||||
"flathub/lib/libmpeg2.json",
|
||||
"flathub/lib/libdv.json",
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"app-id": "com.github.rafostar.Clapper",
|
||||
"runtime": "org.gnome.Platform",
|
||||
"runtime-version": "42",
|
||||
"runtime-version": "43",
|
||||
"sdk": "org.gnome.Sdk",
|
||||
"command": "com.github.rafostar.Clapper",
|
||||
"finish-args": [
|
||||
@@ -14,10 +14,11 @@
|
||||
"--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.*",
|
||||
"--talk-name=org.gnome.Shell",
|
||||
"--env=GST_PLUGIN_SYSTEM_PATH=/app/lib/gstreamer-1.0",
|
||||
"--env=GST_VAAPI_ALL_DRIVERS=1"
|
||||
"--env=GST_PLUGIN_SYSTEM_PATH=/app/lib/gstreamer-1.0"
|
||||
],
|
||||
"modules": [
|
||||
"flathub/shared-modules/gudev/gudev.json",
|
||||
@@ -39,6 +40,9 @@
|
||||
{
|
||||
"name": "clapper",
|
||||
"buildsystem": "meson",
|
||||
"config-opts": [
|
||||
"-Dc_args=\"-DHAVE_GST_PATCHES=1\""
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "dir",
|
||||
|
Submodule pkgs/flatpak/flathub updated: 4f3bee93b7...58a22acfc4
@@ -1,6 +1,9 @@
|
||||
{
|
||||
"name": "gst-plugins-rs",
|
||||
"buildsystem": "simple",
|
||||
"only-arches": [
|
||||
"x86_64"
|
||||
],
|
||||
"build-options": {
|
||||
"build-args": [
|
||||
"--share=network"
|
||||
|
@@ -0,0 +1,13 @@
|
||||
diff --git a/meson.build b/meson.build
|
||||
index 38d23ed61c..68dea864a0 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -799,7 +799,7 @@ subdir('docs/tools')
|
||||
subdir('docs/reference')
|
||||
|
||||
if not meson.is_cross_build()
|
||||
- if meson.version().version_compare('>=0.57.0')
|
||||
+ if false
|
||||
gnome.post_install(
|
||||
glib_compile_schemas: true,
|
||||
gio_querymodules: gio_module_dirs,
|
114
pkgs/flatpak/testing/gtk4-latest-gcc-fix.patch
Normal file
114
pkgs/flatpak/testing/gtk4-latest-gcc-fix.patch
Normal file
@@ -0,0 +1,114 @@
|
||||
From 4dcd02e85315f487310e2e01fe9412706a77dc35 Mon Sep 17 00:00:00 2001
|
||||
From: Emmanuele Bassi <ebassi@gnome.org>
|
||||
Date: Tue, 19 Apr 2022 15:33:21 +0100
|
||||
Subject: [PATCH] Quench the anger of GCC
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Direct access of the fields of the union trips compiler warnings with
|
||||
GCC 12, such as:
|
||||
|
||||
../gtk/gtkimagedefinition.c:135:13: error: array subscript
|
||||
‘GtkImageDefinition {aka union _GtkImageDefinition}[0]’ is partly
|
||||
outside array bounds of ‘GtkImageDefinitionEmpty[1]’ {aka
|
||||
‘struct _GtkImageDefinitionEmpty[1]’} [-Werror=array-bounds]
|
||||
---
|
||||
gtk/gtkimagedefinition.c | 38 ++++++++++++++++++++++++++++----------
|
||||
1 file changed, 28 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/gtk/gtkimagedefinition.c b/gtk/gtkimagedefinition.c
|
||||
index 1b7c9e51d9..3cf785b01c 100644
|
||||
--- a/gtk/gtkimagedefinition.c
|
||||
+++ b/gtk/gtkimagedefinition.c
|
||||
@@ -132,7 +132,9 @@ gtk_image_definition_new_paintable (GdkPaintable *paintable)
|
||||
GtkImageDefinition *
|
||||
gtk_image_definition_ref (GtkImageDefinition *def)
|
||||
{
|
||||
- def->empty.ref_count++;
|
||||
+ GtkImageDefinitionEmpty *empty = (GtkImageDefinitionEmpty *) def;
|
||||
+
|
||||
+ empty->ref_count++;
|
||||
|
||||
return def;
|
||||
}
|
||||
@@ -140,9 +142,11 @@ gtk_image_definition_ref (GtkImageDefinition *def)
|
||||
void
|
||||
gtk_image_definition_unref (GtkImageDefinition *def)
|
||||
{
|
||||
- def->empty.ref_count--;
|
||||
+ GtkImageDefinitionEmpty *empty = (GtkImageDefinitionEmpty *) def;
|
||||
+
|
||||
+ empty->ref_count--;
|
||||
|
||||
- if (def->empty.ref_count > 0)
|
||||
+ if (empty->ref_count > 0)
|
||||
return;
|
||||
|
||||
switch (def->type)
|
||||
@@ -152,13 +156,22 @@ gtk_image_definition_unref (GtkImageDefinition *def)
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
case GTK_IMAGE_PAINTABLE:
|
||||
- g_object_unref (def->paintable.paintable);
|
||||
+ {
|
||||
+ GtkImageDefinitionPaintable *paintable = (GtkImageDefinitionPaintable *) def;
|
||||
+ g_object_unref (paintable->paintable);
|
||||
+ }
|
||||
break;
|
||||
case GTK_IMAGE_ICON_NAME:
|
||||
- g_free (def->icon_name.icon_name);
|
||||
+ {
|
||||
+ GtkImageDefinitionIconName *icon_name = (GtkImageDefinitionIconName *) def;
|
||||
+ g_free (icon_name->icon_name);
|
||||
+ }
|
||||
break;
|
||||
case GTK_IMAGE_GICON:
|
||||
- g_object_unref (def->gicon.gicon);
|
||||
+ {
|
||||
+ GtkImageDefinitionGIcon *gicon = (GtkImageDefinitionGIcon *) def;
|
||||
+ g_object_unref (gicon->gicon);
|
||||
+ }
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -189,27 +202,32 @@ gtk_image_definition_get_scale (const GtkImageDefinition *def)
|
||||
const char *
|
||||
gtk_image_definition_get_icon_name (const GtkImageDefinition *def)
|
||||
{
|
||||
+ const GtkImageDefinitionIconName *icon_name = (const GtkImageDefinitionIconName *) def;
|
||||
+
|
||||
if (def->type != GTK_IMAGE_ICON_NAME)
|
||||
return NULL;
|
||||
|
||||
- return def->icon_name.icon_name;
|
||||
+ return icon_name->icon_name;
|
||||
}
|
||||
|
||||
GIcon *
|
||||
gtk_image_definition_get_gicon (const GtkImageDefinition *def)
|
||||
{
|
||||
+ const GtkImageDefinitionGIcon *gicon = (const GtkImageDefinitionGIcon *) def;
|
||||
+
|
||||
if (def->type != GTK_IMAGE_GICON)
|
||||
return NULL;
|
||||
|
||||
- return def->gicon.gicon;
|
||||
+ return gicon->gicon;
|
||||
}
|
||||
|
||||
GdkPaintable *
|
||||
gtk_image_definition_get_paintable (const GtkImageDefinition *def)
|
||||
{
|
||||
+ const GtkImageDefinitionPaintable *paintable = (const GtkImageDefinitionPaintable *) def;
|
||||
+
|
||||
if (def->type != GTK_IMAGE_PAINTABLE)
|
||||
return NULL;
|
||||
|
||||
- return def->paintable.paintable;
|
||||
+ return paintable->paintable;
|
||||
}
|
||||
-
|
||||
--
|
||||
GitLab
|
||||
|
31
pkgs/flatpak/testing/gtk4-popover-unrealize.patch
Normal file
31
pkgs/flatpak/testing/gtk4-popover-unrealize.patch
Normal file
@@ -0,0 +1,31 @@
|
||||
From b413ee2c7d458c7005d3d3d1da8822cd86893ac0 Mon Sep 17 00:00:00 2001
|
||||
From: Rafostar <40623528+Rafostar@users.noreply.github.com>
|
||||
Date: Fri, 4 Dec 2020 19:25:34 +0100
|
||||
Subject: [PATCH] popover: Call unrealize on hide
|
||||
|
||||
When popover is shown "realize" method is called which creates a new
|
||||
surface for popup. Unfortunately this causes performance drop on Wayland until that
|
||||
surface is destroyed what happens inside "unrealize" method during popover destruction.
|
||||
|
||||
This commit changes default behavior in a way that surface will be destroyed
|
||||
when popover is closed and app will ragain the performance it lost when
|
||||
popover was shown.
|
||||
---
|
||||
gtk/gtkpopover.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/gtk/gtkpopover.c b/gtk/gtkpopover.c
|
||||
index 504dcd6cc1..a7a764d483 100644
|
||||
--- a/gtk/gtkpopover.c
|
||||
+++ b/gtk/gtkpopover.c
|
||||
@@ -951,6 +951,7 @@ gtk_popover_hide (GtkWidget *widget)
|
||||
|
||||
gtk_popover_set_mnemonics_visible (GTK_POPOVER (widget), FALSE);
|
||||
_gtk_widget_set_visible_flag (widget, FALSE);
|
||||
+ gtk_widget_unrealize (widget);
|
||||
gtk_widget_unmap (widget);
|
||||
g_signal_emit (widget, signals[CLOSED], 0);
|
||||
}
|
||||
--
|
||||
GitLab
|
||||
|
@@ -1,14 +1,11 @@
|
||||
{
|
||||
"name": "gtk",
|
||||
"buildsystem": "meson",
|
||||
"build-options": {
|
||||
"build-args": [
|
||||
"--share=network"
|
||||
]
|
||||
},
|
||||
"config-opts": [
|
||||
"--buildtype=release",
|
||||
"--wrap-mode=nodownload",
|
||||
|
||||
"-Dbroadway-backend=true",
|
||||
"-Dwin32-backend=false",
|
||||
"-Dmacos-backend=false",
|
||||
"-Dmedia-ffmpeg=disabled",
|
||||
@@ -26,8 +23,19 @@
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://gitlab.gnome.org/GNOME/gtk.git",
|
||||
"tag": "4.6.4",
|
||||
"commit": "1e6bad6c4f412dc0eb7b2f508cb4465929a04303"
|
||||
"branch": "gtk-4-4"
|
||||
},
|
||||
{
|
||||
"type": "patch",
|
||||
"path": "gtk4-popover-unrealize.patch"
|
||||
},
|
||||
{
|
||||
"type": "patch",
|
||||
"path": "gtk4-disable-meson-gnome-post-install.patch"
|
||||
},
|
||||
{
|
||||
"type": "patch",
|
||||
"path": "gtk4-latest-gcc-fix.patch"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@@ -14,8 +14,8 @@
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://gitlab.gnome.org/GNOME/libadwaita.git",
|
||||
"tag": "1.1.1",
|
||||
"commit": "5ec9f624b23bf78b29dd708e77ccdfcee0a9867a"
|
||||
"tag": "1.0.0.alpha.4",
|
||||
"commit": "6b447fde8f270001a0dc29ef59d3e9bf6d32dae9"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@@ -1 +1 @@
|
||||
ar ca cs de es eu fr hu it ja nl pl pt pt_BR ru sv tr zh_CN
|
||||
ar ast ca cs de es eu fa fr he hu it ja nl pl pt pt_BR ru sv tr zh_CN
|
||||
|
438
po/ast.po
Normal file
438
po/ast.po
Normal file
@@ -0,0 +1,438 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-05-26 18:41+0200\n"
|
||||
"PO-Revision-Date: 2022-06-26 22:43\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Asturian\n"
|
||||
"Language: ast_ES\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Crowdin-Project: clapper\n"
|
||||
"X-Crowdin-Project-ID: 473374\n"
|
||||
"X-Crowdin-Language: ast\n"
|
||||
"X-Crowdin-File: /master/po/com.github.rafostar.Clapper.pot\n"
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files…"
|
||||
msgstr "Abrir ficheros…"
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI…"
|
||||
msgstr "Abrir un URI…"
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
msgid "Preferences"
|
||||
msgstr "Preferencies"
|
||||
|
||||
#: ui/clapper.ui:20
|
||||
msgid "Shortcuts"
|
||||
msgstr "Atayos"
|
||||
|
||||
#: ui/clapper.ui:26
|
||||
msgid "About Clapper"
|
||||
msgstr "Tocante a Clapper"
|
||||
|
||||
#: ui/elapsed-time-button.ui:27
|
||||
msgid "Speed"
|
||||
msgstr "Velocidá"
|
||||
|
||||
#: ui/elapsed-time-button.ui:41 ui/preferences-window.ui:82
|
||||
msgid "Normal"
|
||||
msgstr "Normal"
|
||||
|
||||
#: ui/help-overlay.ui:10 ui/preferences-window.ui:11
|
||||
msgid "General"
|
||||
msgstr "Xenerales"
|
||||
|
||||
#: ui/help-overlay.ui:13
|
||||
msgid "Show shortcuts"
|
||||
msgstr "Amosar los atayos"
|
||||
|
||||
#: ui/help-overlay.ui:19
|
||||
msgid "Toggle fullscreen"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:20
|
||||
msgid "Double tap | Double click"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:26
|
||||
msgid "Leave fullscreen"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:32
|
||||
msgid "Reveal OSD (fullscreen only)"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:33
|
||||
msgid "Tap"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:39
|
||||
msgid "Quit"
|
||||
msgstr "Colar"
|
||||
|
||||
#: ui/help-overlay.ui:47
|
||||
msgid "Media"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:50
|
||||
msgid "Open files"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:56 src/dialogs.js:137
|
||||
msgid "Open URI"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:64
|
||||
msgid "Playlist"
|
||||
msgstr "Llista de reproducción"
|
||||
|
||||
#: ui/help-overlay.ui:67
|
||||
msgid "Next item"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:68
|
||||
msgid "Double tap (right side)"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:74
|
||||
msgid "Previous item"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:75
|
||||
msgid "Double tap (left side)"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:81
|
||||
msgid "Change repeat mode"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:87
|
||||
msgid "Export to file"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:95 ui/preferences-window.ui:118
|
||||
msgid "Playback"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:98
|
||||
msgid "Toggle play"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:99
|
||||
msgid "Long press | Right click"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:105
|
||||
msgid "Seek forward"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:106
|
||||
msgid "Swipe right | Scroll right"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:112
|
||||
msgid "Seek backward"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:113
|
||||
msgid "Swipe left | Scroll left"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:119
|
||||
msgid "Volume up"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:120
|
||||
msgid "Swipe up | Scroll up"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:126
|
||||
msgid "Volume down"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:127
|
||||
msgid "Swipe down | Scroll down"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:133
|
||||
msgid "Toggle mute"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:139
|
||||
msgid "Next chapter"
|
||||
msgstr ""
|
||||
|
||||
#: ui/help-overlay.ui:145
|
||||
msgid "Previous chapter"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-plugin-ranking-subpage.ui:11
|
||||
msgid "Decoders"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-plugin-ranking-subpage.ui:18
|
||||
msgid "Return to the preferences"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:15
|
||||
msgid "Behavior"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:18
|
||||
msgid "Auto fullscreen"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:19
|
||||
msgid "Enter fullscreen when playlist is replaced except floating mode"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:25
|
||||
msgid "Ask to resume recent media"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:31
|
||||
msgid "Float on all workspaces"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:32
|
||||
msgid "This option only works on GNOME"
|
||||
msgstr "Esta opción namái funciona en GNOME"
|
||||
|
||||
#: ui/preferences-window.ui:38
|
||||
msgid "After playback"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:43
|
||||
msgid "Do nothing"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:44
|
||||
msgid "Freeze last frame"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:45
|
||||
msgid "Close the app"
|
||||
msgstr "Zarrar l’aplicación"
|
||||
|
||||
#: ui/preferences-window.ui:55
|
||||
msgid "Volume"
|
||||
msgstr "Volume"
|
||||
|
||||
#: ui/preferences-window.ui:58
|
||||
msgid "Custom initial value"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:59
|
||||
msgid "Set custom volume at startup instead of restoring it"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:63
|
||||
msgid "Volume percentage"
|
||||
msgstr "Porcentaxe de volume"
|
||||
|
||||
#: ui/preferences-window.ui:74
|
||||
msgid "Seeking"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:77
|
||||
msgid "Mode"
|
||||
msgstr "Mou"
|
||||
|
||||
#: ui/preferences-window.ui:83
|
||||
msgid "Accurate"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:84
|
||||
msgid "Fast"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:92
|
||||
msgid "Unit"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:97
|
||||
msgid "Second"
|
||||
msgstr "Segundu"
|
||||
|
||||
#: ui/preferences-window.ui:98
|
||||
msgid "Minute"
|
||||
msgstr "Minutu"
|
||||
|
||||
#: ui/preferences-window.ui:99
|
||||
msgid "Percentage"
|
||||
msgstr "Porcentaxe"
|
||||
|
||||
#: ui/preferences-window.ui:107
|
||||
msgid "Value"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:122
|
||||
msgid "Audio"
|
||||
msgstr "Audio"
|
||||
|
||||
#: ui/preferences-window.ui:125
|
||||
msgid "Offset in milliseconds"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:132
|
||||
msgid "Only native audio formats"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:140
|
||||
msgid "Subtitles"
|
||||
msgstr "Sotítulos"
|
||||
|
||||
#: ui/preferences-window.ui:143
|
||||
msgid "Default font"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:153
|
||||
msgid "Network"
|
||||
msgstr "Rede"
|
||||
|
||||
#: ui/preferences-window.ui:157
|
||||
msgid "Client"
|
||||
msgstr "Veceru"
|
||||
|
||||
#: ui/preferences-window.ui:160
|
||||
msgid "Progressive download buffering"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:168
|
||||
msgid "Server"
|
||||
msgstr "Sirvidor"
|
||||
|
||||
#: ui/preferences-window.ui:171
|
||||
msgid "Control player remotely"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:175
|
||||
msgid "Listening port"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:188
|
||||
msgid "Tweaks"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:192
|
||||
msgid "Appearance"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:195
|
||||
msgid "Dark theme"
|
||||
msgstr "Tema escuru"
|
||||
|
||||
#: ui/preferences-window.ui:201
|
||||
msgid "Render window shadows"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:202
|
||||
msgid "Disable to increase performance when windowed"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:213
|
||||
msgid "Plugin ranking"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:214
|
||||
msgid "Alter default ranks of GStreamer plugins"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:219
|
||||
msgid "Use playbin3"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:220 ui/preferences-window.ui:229
|
||||
msgid "Requires player restart"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:222 ui/preferences-window.ui:231
|
||||
msgid "Experimental"
|
||||
msgstr ""
|
||||
|
||||
#: ui/preferences-window.ui:228
|
||||
msgid "Use PipeWire for audio output"
|
||||
msgstr ""
|
||||
|
||||
#: src/buttons.js:201
|
||||
#, javascript-format
|
||||
msgid "Decoder: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:152
|
||||
msgid "Enter or drop URI here"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs.js:157
|
||||
msgid "Cancel"
|
||||
msgstr "Encaboxar"
|
||||
|
||||
#: src/dialogs.js:158
|
||||
msgid "Open"
|
||||
msgstr "Abrir"
|
||||
|
||||
#: src/dialogs.js:226
|
||||
msgid "Title"
|
||||
msgstr "Títulu"
|
||||
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr "Completáu al"
|
||||
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr "¿Quies siguir cola reproducción?"
|
||||
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr "Versión de GTK: %s"
|
||||
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr "Versión d’Adwaita: %s"
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr "Versión de GStreamer: %s"
|
||||
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr "Versión de GJS: %s"
|
||||
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr "Adolfo Jayme Barrientos <fitojb@ubuntu.com>, 2022"
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:226 src/widget.js:235 src/widget.js:241 src/widget.js:247
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:242
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
|
||||
#: src/widget.js:260
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
|
4
po/de.po
4
po/de.po
@@ -3,7 +3,7 @@ msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-05-26 18:41+0200\n"
|
||||
"PO-Revision-Date: 2022-05-27 16:27\n"
|
||||
"PO-Revision-Date: 2022-06-24 17:27\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: German\n"
|
||||
"Language: de_DE\n"
|
||||
@@ -163,7 +163,7 @@ msgstr "Nach unten wischen bzw. scrollen"
|
||||
|
||||
#: ui/help-overlay.ui:133
|
||||
msgid "Toggle mute"
|
||||
msgstr "In Vollbildmodus wechseln"
|
||||
msgstr "Stummschaltung umschalten"
|
||||
|
||||
#: ui/help-overlay.ui:139
|
||||
msgid "Next chapter"
|
||||
|
438
po/fa.po
Normal file
438
po/fa.po
Normal file
@@ -0,0 +1,438 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-05-26 18:41+0200\n"
|
||||
"PO-Revision-Date: 2022-07-23 14:14\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Persian\n"
|
||||
"Language: fa_IR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Crowdin-Project: clapper\n"
|
||||
"X-Crowdin-Project-ID: 473374\n"
|
||||
"X-Crowdin-Language: fa\n"
|
||||
"X-Crowdin-File: /master/po/com.github.rafostar.Clapper.pot\n"
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files…"
|
||||
msgstr "گشودن پروندهها…"
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI…"
|
||||
msgstr "گشودن نشانی…"
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
msgid "Preferences"
|
||||
msgstr "ترجیحات"
|
||||
|
||||
#: ui/clapper.ui:20
|
||||
msgid "Shortcuts"
|
||||
msgstr "میانبرها"
|
||||
|
||||
#: ui/clapper.ui:26
|
||||
msgid "About Clapper"
|
||||
msgstr "دربارهٔ کلَپِر"
|
||||
|
||||
#: ui/elapsed-time-button.ui:27
|
||||
msgid "Speed"
|
||||
msgstr "سرعت"
|
||||
|
||||
#: ui/elapsed-time-button.ui:41 ui/preferences-window.ui:82
|
||||
msgid "Normal"
|
||||
msgstr "معمولی"
|
||||
|
||||
#: ui/help-overlay.ui:10 ui/preferences-window.ui:11
|
||||
msgid "General"
|
||||
msgstr "عمومی"
|
||||
|
||||
#: ui/help-overlay.ui:13
|
||||
msgid "Show shortcuts"
|
||||
msgstr "نمایش میانبرها"
|
||||
|
||||
#: ui/help-overlay.ui:19
|
||||
msgid "Toggle fullscreen"
|
||||
msgstr "تغییر حالت تمامصفحه"
|
||||
|
||||
#: ui/help-overlay.ui:20
|
||||
msgid "Double tap | Double click"
|
||||
msgstr "دو بار ضربه | دو بار کلیک"
|
||||
|
||||
#: ui/help-overlay.ui:26
|
||||
msgid "Leave fullscreen"
|
||||
msgstr "خروج از تمامصفحه"
|
||||
|
||||
#: ui/help-overlay.ui:32
|
||||
msgid "Reveal OSD (fullscreen only)"
|
||||
msgstr "نمایش OSD (فقط تمامصفحه)"
|
||||
|
||||
#: ui/help-overlay.ui:33
|
||||
msgid "Tap"
|
||||
msgstr "ضربه"
|
||||
|
||||
#: ui/help-overlay.ui:39
|
||||
msgid "Quit"
|
||||
msgstr "خروج"
|
||||
|
||||
#: ui/help-overlay.ui:47
|
||||
msgid "Media"
|
||||
msgstr "رسانه"
|
||||
|
||||
#: ui/help-overlay.ui:50
|
||||
msgid "Open files"
|
||||
msgstr "گشودن پروندهها"
|
||||
|
||||
#: ui/help-overlay.ui:56 src/dialogs.js:137
|
||||
msgid "Open URI"
|
||||
msgstr "گشودن نشانی"
|
||||
|
||||
#: ui/help-overlay.ui:64
|
||||
msgid "Playlist"
|
||||
msgstr "سیاههٔ پخش"
|
||||
|
||||
#: ui/help-overlay.ui:67
|
||||
msgid "Next item"
|
||||
msgstr "مورد بعدی"
|
||||
|
||||
#: ui/help-overlay.ui:68
|
||||
msgid "Double tap (right side)"
|
||||
msgstr "ضربه دوتایی (سمت راست)"
|
||||
|
||||
#: ui/help-overlay.ui:74
|
||||
msgid "Previous item"
|
||||
msgstr "مورد قبل"
|
||||
|
||||
#: ui/help-overlay.ui:75
|
||||
msgid "Double tap (left side)"
|
||||
msgstr "ضربه دوتایی (سمت چپ)"
|
||||
|
||||
#: ui/help-overlay.ui:81
|
||||
msgid "Change repeat mode"
|
||||
msgstr "تغییر حالت تکرار"
|
||||
|
||||
#: ui/help-overlay.ui:87
|
||||
msgid "Export to file"
|
||||
msgstr "خروجی گرفتن در فایل"
|
||||
|
||||
#: ui/help-overlay.ui:95 ui/preferences-window.ui:118
|
||||
msgid "Playback"
|
||||
msgstr "بازپخش"
|
||||
|
||||
#: ui/help-overlay.ui:98
|
||||
msgid "Toggle play"
|
||||
msgstr "تغییر پخش"
|
||||
|
||||
#: ui/help-overlay.ui:99
|
||||
msgid "Long press | Right click"
|
||||
msgstr "فشار طولانی | کلیک راست"
|
||||
|
||||
#: ui/help-overlay.ui:105
|
||||
msgid "Seek forward"
|
||||
msgstr "پیمایش به جلو"
|
||||
|
||||
#: ui/help-overlay.ui:106
|
||||
msgid "Swipe right | Scroll right"
|
||||
msgstr "کشیدن به راست | اسکرول به راست"
|
||||
|
||||
#: ui/help-overlay.ui:112
|
||||
msgid "Seek backward"
|
||||
msgstr "پیمایش به عقب"
|
||||
|
||||
#: ui/help-overlay.ui:113
|
||||
msgid "Swipe left | Scroll left"
|
||||
msgstr "کشیدن به چپ | اسکرول به چپ"
|
||||
|
||||
#: ui/help-overlay.ui:119
|
||||
msgid "Volume up"
|
||||
msgstr "افزایش صدا"
|
||||
|
||||
#: ui/help-overlay.ui:120
|
||||
msgid "Swipe up | Scroll up"
|
||||
msgstr "کشیدن به بالا | اسکرول به بالا"
|
||||
|
||||
#: ui/help-overlay.ui:126
|
||||
msgid "Volume down"
|
||||
msgstr "کاهش صدا"
|
||||
|
||||
#: ui/help-overlay.ui:127
|
||||
msgid "Swipe down | Scroll down"
|
||||
msgstr "کشیدن به پایین | اسکرول به پایین"
|
||||
|
||||
#: ui/help-overlay.ui:133
|
||||
msgid "Toggle mute"
|
||||
msgstr "تغییر وضعیت بیصدا"
|
||||
|
||||
#: ui/help-overlay.ui:139
|
||||
msgid "Next chapter"
|
||||
msgstr "فصل بعدی"
|
||||
|
||||
#: ui/help-overlay.ui:145
|
||||
msgid "Previous chapter"
|
||||
msgstr "بخش قبلی"
|
||||
|
||||
#: ui/preferences-plugin-ranking-subpage.ui:11
|
||||
msgid "Decoders"
|
||||
msgstr "کد گشاها"
|
||||
|
||||
#: ui/preferences-plugin-ranking-subpage.ui:18
|
||||
msgid "Return to the preferences"
|
||||
msgstr "بازگشت به تنظیمات"
|
||||
|
||||
#: ui/preferences-window.ui:15
|
||||
msgid "Behavior"
|
||||
msgstr "رفتار"
|
||||
|
||||
#: ui/preferences-window.ui:18
|
||||
msgid "Auto fullscreen"
|
||||
msgstr "تمام صفحه خودکار"
|
||||
|
||||
#: ui/preferences-window.ui:19
|
||||
msgid "Enter fullscreen when playlist is replaced except floating mode"
|
||||
msgstr "ورود به تمام صفحه وقتی لیست پخش جایگزین شود به جز حالت شناور"
|
||||
|
||||
#: ui/preferences-window.ui:25
|
||||
msgid "Ask to resume recent media"
|
||||
msgstr "پرسش برای ادامه پخش مدیا"
|
||||
|
||||
#: ui/preferences-window.ui:31
|
||||
msgid "Float on all workspaces"
|
||||
msgstr "حالت شناور روی همهی صفحاتکاری"
|
||||
|
||||
#: ui/preferences-window.ui:32
|
||||
msgid "This option only works on GNOME"
|
||||
msgstr "این مورد تنها بر روی GNOME کار میکند"
|
||||
|
||||
#: ui/preferences-window.ui:38
|
||||
msgid "After playback"
|
||||
msgstr "پس از بازپخش"
|
||||
|
||||
#: ui/preferences-window.ui:43
|
||||
msgid "Do nothing"
|
||||
msgstr "کاری انجام نشود"
|
||||
|
||||
#: ui/preferences-window.ui:44
|
||||
msgid "Freeze last frame"
|
||||
msgstr "بیحرکت کردن ةخرین قاب"
|
||||
|
||||
#: ui/preferences-window.ui:45
|
||||
msgid "Close the app"
|
||||
msgstr "بستن برنامه"
|
||||
|
||||
#: ui/preferences-window.ui:55
|
||||
msgid "Volume"
|
||||
msgstr "درجه صدا"
|
||||
|
||||
#: ui/preferences-window.ui:58
|
||||
msgid "Custom initial value"
|
||||
msgstr "مقدار اولیه سفارشی"
|
||||
|
||||
#: ui/preferences-window.ui:59
|
||||
msgid "Set custom volume at startup instead of restoring it"
|
||||
msgstr "تنظیم صدای سفارشی در هنگام راه اندازی به جای بازیابی آن"
|
||||
|
||||
#: ui/preferences-window.ui:63
|
||||
msgid "Volume percentage"
|
||||
msgstr "درصد صدا"
|
||||
|
||||
#: ui/preferences-window.ui:74
|
||||
msgid "Seeking"
|
||||
msgstr "پوییدن"
|
||||
|
||||
#: ui/preferences-window.ui:77
|
||||
msgid "Mode"
|
||||
msgstr "حالت"
|
||||
|
||||
#: ui/preferences-window.ui:83
|
||||
msgid "Accurate"
|
||||
msgstr "دقت"
|
||||
|
||||
#: ui/preferences-window.ui:84
|
||||
msgid "Fast"
|
||||
msgstr "تند"
|
||||
|
||||
#: ui/preferences-window.ui:92
|
||||
msgid "Unit"
|
||||
msgstr "واحد"
|
||||
|
||||
#: ui/preferences-window.ui:97
|
||||
msgid "Second"
|
||||
msgstr "ثانیه"
|
||||
|
||||
#: ui/preferences-window.ui:98
|
||||
msgid "Minute"
|
||||
msgstr "دقیقه"
|
||||
|
||||
#: ui/preferences-window.ui:99
|
||||
msgid "Percentage"
|
||||
msgstr "درصد"
|
||||
|
||||
#: ui/preferences-window.ui:107
|
||||
msgid "Value"
|
||||
msgstr "مقدار"
|
||||
|
||||
#: ui/preferences-window.ui:122
|
||||
msgid "Audio"
|
||||
msgstr "صوتی"
|
||||
|
||||
#: ui/preferences-window.ui:125
|
||||
msgid "Offset in milliseconds"
|
||||
msgstr "جابجایی بر اساس میلیثانیه"
|
||||
|
||||
#: ui/preferences-window.ui:132
|
||||
msgid "Only native audio formats"
|
||||
msgstr "فقط فرمتهای صوتی بومی"
|
||||
|
||||
#: ui/preferences-window.ui:140
|
||||
msgid "Subtitles"
|
||||
msgstr "زیرنویسها"
|
||||
|
||||
#: ui/preferences-window.ui:143
|
||||
msgid "Default font"
|
||||
msgstr "قلم پیش فرض"
|
||||
|
||||
#: ui/preferences-window.ui:153
|
||||
msgid "Network"
|
||||
msgstr "شبکه"
|
||||
|
||||
#: ui/preferences-window.ui:157
|
||||
msgid "Client"
|
||||
msgstr "مشتری"
|
||||
|
||||
#: ui/preferences-window.ui:160
|
||||
msgid "Progressive download buffering"
|
||||
msgstr "بافرینگ دانلود مترقی"
|
||||
|
||||
#: ui/preferences-window.ui:168
|
||||
msgid "Server"
|
||||
msgstr "سرور"
|
||||
|
||||
#: ui/preferences-window.ui:171
|
||||
msgid "Control player remotely"
|
||||
msgstr "کنترل پخشکننده از راه دور"
|
||||
|
||||
#: ui/preferences-window.ui:175
|
||||
msgid "Listening port"
|
||||
msgstr "شنود پورت"
|
||||
|
||||
#: ui/preferences-window.ui:188
|
||||
msgid "Tweaks"
|
||||
msgstr "دستكاري"
|
||||
|
||||
#: ui/preferences-window.ui:192
|
||||
msgid "Appearance"
|
||||
msgstr "ظاهر"
|
||||
|
||||
#: ui/preferences-window.ui:195
|
||||
msgid "Dark theme"
|
||||
msgstr "پوسته تیره"
|
||||
|
||||
#: ui/preferences-window.ui:201
|
||||
msgid "Render window shadows"
|
||||
msgstr "رندر سایه پنجرهها"
|
||||
|
||||
#: ui/preferences-window.ui:202
|
||||
msgid "Disable to increase performance when windowed"
|
||||
msgstr "غیر فعال سازی برای افزایش کارایی در حالت پنجره ای"
|
||||
|
||||
#: ui/preferences-window.ui:213
|
||||
msgid "Plugin ranking"
|
||||
msgstr "پیکربندی پلاگین"
|
||||
|
||||
#: ui/preferences-window.ui:214
|
||||
msgid "Alter default ranks of GStreamer plugins"
|
||||
msgstr "تغییر پیکربندی پیش فرض پلاگین های GStreamer"
|
||||
|
||||
#: ui/preferences-window.ui:219
|
||||
msgid "Use playbin3"
|
||||
msgstr "استفاده از playbin3"
|
||||
|
||||
#: ui/preferences-window.ui:220 ui/preferences-window.ui:229
|
||||
msgid "Requires player restart"
|
||||
msgstr "نیازمند به بازشروع برنامه"
|
||||
|
||||
#: ui/preferences-window.ui:222 ui/preferences-window.ui:231
|
||||
msgid "Experimental"
|
||||
msgstr "آزمایشی"
|
||||
|
||||
#: ui/preferences-window.ui:228
|
||||
msgid "Use PipeWire for audio output"
|
||||
msgstr "استفاده از PipeWire برای خروجی صدا"
|
||||
|
||||
#: src/buttons.js:201
|
||||
#, javascript-format
|
||||
msgid "Decoder: %s"
|
||||
msgstr "کدگشا: %s"
|
||||
|
||||
#: src/dialogs.js:152
|
||||
msgid "Enter or drop URI here"
|
||||
msgstr "رها کردن یا واردکردن URI"
|
||||
|
||||
#: src/dialogs.js:157
|
||||
msgid "Cancel"
|
||||
msgstr "لغو"
|
||||
|
||||
#: src/dialogs.js:158
|
||||
msgid "Open"
|
||||
msgstr "گشودن"
|
||||
|
||||
#: src/dialogs.js:226
|
||||
msgid "Title"
|
||||
msgstr "عنوان"
|
||||
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr "کامل شده"
|
||||
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr "ادامه بازپخش?"
|
||||
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr "نسخه GTK: %s"
|
||||
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr "نسخه Adwita: %s"
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr "نسخه GStreamer: %s"
|
||||
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr "نسخه GJS: %s"
|
||||
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr "یک پخشکننده رسانه GNOME قدرت گرفته از GStreamer"
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr "سجاد موسوی نژاد <ssmns@outlook.com>"
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr "پایان در: %s"
|
||||
|
||||
#: src/widget.js:226 src/widget.js:235 src/widget.js:241 src/widget.js:247
|
||||
msgid "Undetermined"
|
||||
msgstr "نامشخص"
|
||||
|
||||
#: src/widget.js:242
|
||||
msgid "Channels"
|
||||
msgstr "کانالها"
|
||||
|
||||
#: src/widget.js:260
|
||||
msgid "Disabled"
|
||||
msgstr "غیرفعال"
|
||||
|
208
po/he.po
208
po/he.po
@@ -3,7 +3,7 @@ msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-05-26 18:41+0200\n"
|
||||
"PO-Revision-Date: 2022-05-26 16:50\n"
|
||||
"PO-Revision-Date: 2022-06-01 08:42\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Hebrew\n"
|
||||
"Language: he_IL\n"
|
||||
@@ -19,420 +19,420 @@ msgstr ""
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files…"
|
||||
msgstr ""
|
||||
msgstr "פתיחת קבצים…"
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI…"
|
||||
msgstr ""
|
||||
msgstr "פתיחת כתובת…"
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
msgid "Preferences"
|
||||
msgstr ""
|
||||
msgstr "העדפות"
|
||||
|
||||
#: ui/clapper.ui:20
|
||||
msgid "Shortcuts"
|
||||
msgstr ""
|
||||
msgstr "צירופי מקשים"
|
||||
|
||||
#: ui/clapper.ui:26
|
||||
msgid "About Clapper"
|
||||
msgstr ""
|
||||
msgstr "על אודות Clapper"
|
||||
|
||||
#: ui/elapsed-time-button.ui:27
|
||||
msgid "Speed"
|
||||
msgstr ""
|
||||
msgstr "מהירות"
|
||||
|
||||
#: ui/elapsed-time-button.ui:41 ui/preferences-window.ui:82
|
||||
msgid "Normal"
|
||||
msgstr ""
|
||||
msgstr "רגילה"
|
||||
|
||||
#: ui/help-overlay.ui:10 ui/preferences-window.ui:11
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
msgstr "כללי"
|
||||
|
||||
#: ui/help-overlay.ui:13
|
||||
msgid "Show shortcuts"
|
||||
msgstr ""
|
||||
msgstr "הצגת צירופי מקשים"
|
||||
|
||||
#: ui/help-overlay.ui:19
|
||||
msgid "Toggle fullscreen"
|
||||
msgstr ""
|
||||
msgstr "שינוי מצב מסך מלא"
|
||||
|
||||
#: ui/help-overlay.ui:20
|
||||
msgid "Double tap | Double click"
|
||||
msgstr ""
|
||||
msgstr "נגיעה כפולה | לחיצה כפולה"
|
||||
|
||||
#: ui/help-overlay.ui:26
|
||||
msgid "Leave fullscreen"
|
||||
msgstr ""
|
||||
msgstr "יציאה ממסך מלא"
|
||||
|
||||
#: ui/help-overlay.ui:32
|
||||
msgid "Reveal OSD (fullscreen only)"
|
||||
msgstr ""
|
||||
msgstr "הצגת מידע וכפתורים (מסך מלא בלבד)"
|
||||
|
||||
#: ui/help-overlay.ui:33
|
||||
msgid "Tap"
|
||||
msgstr ""
|
||||
msgstr "נגיעה"
|
||||
|
||||
#: ui/help-overlay.ui:39
|
||||
msgid "Quit"
|
||||
msgstr ""
|
||||
msgstr "יציאה"
|
||||
|
||||
#: ui/help-overlay.ui:47
|
||||
msgid "Media"
|
||||
msgstr ""
|
||||
msgstr "מדיה"
|
||||
|
||||
#: ui/help-overlay.ui:50
|
||||
msgid "Open files"
|
||||
msgstr ""
|
||||
msgstr "פתיחת קבצים"
|
||||
|
||||
#: ui/help-overlay.ui:56 src/dialogs.js:137
|
||||
msgid "Open URI"
|
||||
msgstr ""
|
||||
msgstr "פתיחת כתובת"
|
||||
|
||||
#: ui/help-overlay.ui:64
|
||||
msgid "Playlist"
|
||||
msgstr ""
|
||||
msgstr "רשימת השמעה"
|
||||
|
||||
#: ui/help-overlay.ui:67
|
||||
msgid "Next item"
|
||||
msgstr ""
|
||||
msgstr "פריט הבא"
|
||||
|
||||
#: ui/help-overlay.ui:68
|
||||
msgid "Double tap (right side)"
|
||||
msgstr ""
|
||||
msgstr "נגיעה כפולה (צד ימין)"
|
||||
|
||||
#: ui/help-overlay.ui:74
|
||||
msgid "Previous item"
|
||||
msgstr ""
|
||||
msgstr "פריט קודם"
|
||||
|
||||
#: ui/help-overlay.ui:75
|
||||
msgid "Double tap (left side)"
|
||||
msgstr ""
|
||||
msgstr "נגיעה כפולה (צד שמאל)"
|
||||
|
||||
#: ui/help-overlay.ui:81
|
||||
msgid "Change repeat mode"
|
||||
msgstr ""
|
||||
msgstr "שינוי מצב חזרה"
|
||||
|
||||
#: ui/help-overlay.ui:87
|
||||
msgid "Export to file"
|
||||
msgstr ""
|
||||
msgstr "ייצוא לקובץ"
|
||||
|
||||
#: ui/help-overlay.ui:95 ui/preferences-window.ui:118
|
||||
msgid "Playback"
|
||||
msgstr ""
|
||||
msgstr "השמעה"
|
||||
|
||||
#: ui/help-overlay.ui:98
|
||||
msgid "Toggle play"
|
||||
msgstr ""
|
||||
msgstr "הפעלה/השהיה"
|
||||
|
||||
#: ui/help-overlay.ui:99
|
||||
msgid "Long press | Right click"
|
||||
msgstr ""
|
||||
msgstr "לחיצה ארוכה | לחצן ימני"
|
||||
|
||||
#: ui/help-overlay.ui:105
|
||||
msgid "Seek forward"
|
||||
msgstr ""
|
||||
msgstr "דילוג קדימה"
|
||||
|
||||
#: ui/help-overlay.ui:106
|
||||
msgid "Swipe right | Scroll right"
|
||||
msgstr ""
|
||||
msgstr "החלקה ימינה | גלילה ימינה"
|
||||
|
||||
#: ui/help-overlay.ui:112
|
||||
msgid "Seek backward"
|
||||
msgstr ""
|
||||
msgstr "דילוג לאחור"
|
||||
|
||||
#: ui/help-overlay.ui:113
|
||||
msgid "Swipe left | Scroll left"
|
||||
msgstr ""
|
||||
msgstr "החלקה שמאלה | גלילה שמאלה"
|
||||
|
||||
#: ui/help-overlay.ui:119
|
||||
msgid "Volume up"
|
||||
msgstr ""
|
||||
msgstr "הגברת עצמת השמע"
|
||||
|
||||
#: ui/help-overlay.ui:120
|
||||
msgid "Swipe up | Scroll up"
|
||||
msgstr ""
|
||||
msgstr "החלקה למעלה | גלילה למעלה"
|
||||
|
||||
#: ui/help-overlay.ui:126
|
||||
msgid "Volume down"
|
||||
msgstr ""
|
||||
msgstr "הנמכת עצמת השמע"
|
||||
|
||||
#: ui/help-overlay.ui:127
|
||||
msgid "Swipe down | Scroll down"
|
||||
msgstr ""
|
||||
msgstr "החלקה למעלה | גלילה למעלה"
|
||||
|
||||
#: ui/help-overlay.ui:133
|
||||
msgid "Toggle mute"
|
||||
msgstr ""
|
||||
msgstr "השתקה/ביטול השתקה"
|
||||
|
||||
#: ui/help-overlay.ui:139
|
||||
msgid "Next chapter"
|
||||
msgstr ""
|
||||
msgstr "פרק הבא"
|
||||
|
||||
#: ui/help-overlay.ui:145
|
||||
msgid "Previous chapter"
|
||||
msgstr ""
|
||||
msgstr "פרק קודם"
|
||||
|
||||
#: ui/preferences-plugin-ranking-subpage.ui:11
|
||||
msgid "Decoders"
|
||||
msgstr ""
|
||||
msgstr "מפענחים"
|
||||
|
||||
#: ui/preferences-plugin-ranking-subpage.ui:18
|
||||
msgid "Return to the preferences"
|
||||
msgstr ""
|
||||
msgstr "חזרה להגדרות"
|
||||
|
||||
#: ui/preferences-window.ui:15
|
||||
msgid "Behavior"
|
||||
msgstr ""
|
||||
msgstr "התנהגות"
|
||||
|
||||
#: ui/preferences-window.ui:18
|
||||
msgid "Auto fullscreen"
|
||||
msgstr ""
|
||||
msgstr "מסך מלא אוטומטי"
|
||||
|
||||
#: ui/preferences-window.ui:19
|
||||
msgid "Enter fullscreen when playlist is replaced except floating mode"
|
||||
msgstr ""
|
||||
msgstr "כניסה למצב מסך מלא עם החלפת רשימת השמעה מלבד במצב ציפה"
|
||||
|
||||
#: ui/preferences-window.ui:25
|
||||
msgid "Ask to resume recent media"
|
||||
msgstr ""
|
||||
msgstr "לשאול אם להפעיל מחדש את המדיה האחרונה"
|
||||
|
||||
#: ui/preferences-window.ui:31
|
||||
msgid "Float on all workspaces"
|
||||
msgstr ""
|
||||
msgstr "ציפה בכל מרחבי העבודה"
|
||||
|
||||
#: ui/preferences-window.ui:32
|
||||
msgid "This option only works on GNOME"
|
||||
msgstr ""
|
||||
msgstr "אפשרות זו פועלת רק ב־GNOME"
|
||||
|
||||
#: ui/preferences-window.ui:38
|
||||
msgid "After playback"
|
||||
msgstr ""
|
||||
msgstr "בסיום צפייה"
|
||||
|
||||
#: ui/preferences-window.ui:43
|
||||
msgid "Do nothing"
|
||||
msgstr ""
|
||||
msgstr "לא לעשות דבר"
|
||||
|
||||
#: ui/preferences-window.ui:44
|
||||
msgid "Freeze last frame"
|
||||
msgstr ""
|
||||
msgstr "הקפאת התמונה האחרונה"
|
||||
|
||||
#: ui/preferences-window.ui:45
|
||||
msgid "Close the app"
|
||||
msgstr ""
|
||||
msgstr "סגירת היישום"
|
||||
|
||||
#: ui/preferences-window.ui:55
|
||||
msgid "Volume"
|
||||
msgstr ""
|
||||
msgstr "עצמת שמע"
|
||||
|
||||
#: ui/preferences-window.ui:58
|
||||
msgid "Custom initial value"
|
||||
msgstr ""
|
||||
msgstr "התאמת ערך התחלתי"
|
||||
|
||||
#: ui/preferences-window.ui:59
|
||||
msgid "Set custom volume at startup instead of restoring it"
|
||||
msgstr ""
|
||||
msgstr "הגדרת עצמת השמע עם ההפעלה במקום שחזור"
|
||||
|
||||
#: ui/preferences-window.ui:63
|
||||
msgid "Volume percentage"
|
||||
msgstr ""
|
||||
msgstr "עצמת שמע באחוזים"
|
||||
|
||||
#: ui/preferences-window.ui:74
|
||||
msgid "Seeking"
|
||||
msgstr ""
|
||||
msgstr "דילוג"
|
||||
|
||||
#: ui/preferences-window.ui:77
|
||||
msgid "Mode"
|
||||
msgstr ""
|
||||
msgstr "מצב"
|
||||
|
||||
#: ui/preferences-window.ui:83
|
||||
msgid "Accurate"
|
||||
msgstr ""
|
||||
msgstr "מדויק"
|
||||
|
||||
#: ui/preferences-window.ui:84
|
||||
msgid "Fast"
|
||||
msgstr ""
|
||||
msgstr "מהיר"
|
||||
|
||||
#: ui/preferences-window.ui:92
|
||||
msgid "Unit"
|
||||
msgstr ""
|
||||
msgstr "יחידה"
|
||||
|
||||
#: ui/preferences-window.ui:97
|
||||
msgid "Second"
|
||||
msgstr ""
|
||||
msgstr "שניה"
|
||||
|
||||
#: ui/preferences-window.ui:98
|
||||
msgid "Minute"
|
||||
msgstr ""
|
||||
msgstr "דקה"
|
||||
|
||||
#: ui/preferences-window.ui:99
|
||||
msgid "Percentage"
|
||||
msgstr ""
|
||||
msgstr "אחוז"
|
||||
|
||||
#: ui/preferences-window.ui:107
|
||||
msgid "Value"
|
||||
msgstr ""
|
||||
msgstr "ערך"
|
||||
|
||||
#: ui/preferences-window.ui:122
|
||||
msgid "Audio"
|
||||
msgstr ""
|
||||
msgstr "שמע"
|
||||
|
||||
#: ui/preferences-window.ui:125
|
||||
msgid "Offset in milliseconds"
|
||||
msgstr ""
|
||||
msgstr "היסט במילי־שניות"
|
||||
|
||||
#: ui/preferences-window.ui:132
|
||||
msgid "Only native audio formats"
|
||||
msgstr ""
|
||||
msgstr "תבניות שמע רגילות בלבד"
|
||||
|
||||
#: ui/preferences-window.ui:140
|
||||
msgid "Subtitles"
|
||||
msgstr ""
|
||||
msgstr "כתוביות"
|
||||
|
||||
#: ui/preferences-window.ui:143
|
||||
msgid "Default font"
|
||||
msgstr ""
|
||||
msgstr "גופן ברירת מחדל"
|
||||
|
||||
#: ui/preferences-window.ui:153
|
||||
msgid "Network"
|
||||
msgstr ""
|
||||
msgstr "רשת"
|
||||
|
||||
#: ui/preferences-window.ui:157
|
||||
msgid "Client"
|
||||
msgstr ""
|
||||
msgstr "לקוח"
|
||||
|
||||
#: ui/preferences-window.ui:160
|
||||
msgid "Progressive download buffering"
|
||||
msgstr ""
|
||||
msgstr "שימוש בחוצץ הורדה"
|
||||
|
||||
#: ui/preferences-window.ui:168
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
msgstr "שרת"
|
||||
|
||||
#: ui/preferences-window.ui:171
|
||||
msgid "Control player remotely"
|
||||
msgstr ""
|
||||
msgstr "שליטה בנגן מרחוק"
|
||||
|
||||
#: ui/preferences-window.ui:175
|
||||
msgid "Listening port"
|
||||
msgstr ""
|
||||
msgstr "פתחת האזנה"
|
||||
|
||||
#: ui/preferences-window.ui:188
|
||||
msgid "Tweaks"
|
||||
msgstr ""
|
||||
msgstr "התאמות"
|
||||
|
||||
#: ui/preferences-window.ui:192
|
||||
msgid "Appearance"
|
||||
msgstr ""
|
||||
msgstr "מראה"
|
||||
|
||||
#: ui/preferences-window.ui:195
|
||||
msgid "Dark theme"
|
||||
msgstr ""
|
||||
msgstr "מראה כהה"
|
||||
|
||||
#: ui/preferences-window.ui:201
|
||||
msgid "Render window shadows"
|
||||
msgstr ""
|
||||
msgstr "עיבוד צל לחלון"
|
||||
|
||||
#: ui/preferences-window.ui:202
|
||||
msgid "Disable to increase performance when windowed"
|
||||
msgstr ""
|
||||
msgstr "השבתה לצמצום צריכת החלונות"
|
||||
|
||||
#: ui/preferences-window.ui:213
|
||||
msgid "Plugin ranking"
|
||||
msgstr ""
|
||||
msgstr "דרגות תוספים"
|
||||
|
||||
#: ui/preferences-window.ui:214
|
||||
msgid "Alter default ranks of GStreamer plugins"
|
||||
msgstr ""
|
||||
msgstr "שינוי דירוג ברירת המחדל של תוספי GStreamer"
|
||||
|
||||
#: ui/preferences-window.ui:219
|
||||
msgid "Use playbin3"
|
||||
msgstr ""
|
||||
msgstr "שימוש ב־playbin3"
|
||||
|
||||
#: ui/preferences-window.ui:220 ui/preferences-window.ui:229
|
||||
msgid "Requires player restart"
|
||||
msgstr ""
|
||||
msgstr "דורש הפעלה מחדש של הנגן"
|
||||
|
||||
#: ui/preferences-window.ui:222 ui/preferences-window.ui:231
|
||||
msgid "Experimental"
|
||||
msgstr ""
|
||||
msgstr "ניסיוני"
|
||||
|
||||
#: ui/preferences-window.ui:228
|
||||
msgid "Use PipeWire for audio output"
|
||||
msgstr ""
|
||||
msgstr "שימוש ב־PipeWire לפלט השמע"
|
||||
|
||||
#: src/buttons.js:201
|
||||
#, javascript-format
|
||||
msgid "Decoder: %s"
|
||||
msgstr ""
|
||||
msgstr "מפענח: %s"
|
||||
|
||||
#: src/dialogs.js:152
|
||||
msgid "Enter or drop URI here"
|
||||
msgstr ""
|
||||
msgstr "יש להזין או להשליך כתובת לכאן"
|
||||
|
||||
#: src/dialogs.js:157
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
msgstr "ביטול"
|
||||
|
||||
#: src/dialogs.js:158
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
msgstr "פתיחה"
|
||||
|
||||
#: src/dialogs.js:226
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
msgstr "כותרת"
|
||||
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr ""
|
||||
msgstr "הושלם"
|
||||
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr ""
|
||||
msgstr "להמשיך בצפייה?"
|
||||
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr ""
|
||||
msgstr "גרסת GTK: %s"
|
||||
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr ""
|
||||
msgstr "גרסת Adwaita: %s"
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr ""
|
||||
msgstr "גרסת GStreamer: %s"
|
||||
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr ""
|
||||
msgstr "גרסת GJS: %s"
|
||||
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
msgstr "נגן מדיה עבור GNOME המופעל על ידי GStreamer"
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr ""
|
||||
msgstr "יוסף אור בוצ׳קו <yoseforb@gnome.org>"
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr ""
|
||||
msgstr "שעת סיום: %s"
|
||||
|
||||
#: src/widget.js:226 src/widget.js:235 src/widget.js:241 src/widget.js:247
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
msgstr "לא מוגדר"
|
||||
|
||||
#: src/widget.js:242
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
msgstr "ערוצים"
|
||||
|
||||
#: src/widget.js:260
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
msgstr "מושבת"
|
||||
|
||||
|
136
po/tr.po
136
po/tr.po
@@ -3,7 +3,7 @@ msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-05-26 18:41+0200\n"
|
||||
"PO-Revision-Date: 2022-05-26 16:50\n"
|
||||
"PO-Revision-Date: 2022-06-25 12:42\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Turkish\n"
|
||||
"Language: tr_TR\n"
|
||||
@@ -19,7 +19,7 @@ msgstr ""
|
||||
|
||||
#: ui/clapper.ui:6
|
||||
msgid "Open Files…"
|
||||
msgstr "Dosya Aç…"
|
||||
msgstr "Dosyaları Aç…"
|
||||
|
||||
#: ui/clapper.ui:10
|
||||
msgid "Open URI…"
|
||||
@@ -55,7 +55,7 @@ msgstr "Kısayolları göster"
|
||||
|
||||
#: ui/help-overlay.ui:19
|
||||
msgid "Toggle fullscreen"
|
||||
msgstr "Tam ekran"
|
||||
msgstr "Tam ekranı aç/kapat"
|
||||
|
||||
#: ui/help-overlay.ui:20
|
||||
msgid "Double tap | Double click"
|
||||
@@ -83,7 +83,7 @@ msgstr "Ortam"
|
||||
|
||||
#: ui/help-overlay.ui:50
|
||||
msgid "Open files"
|
||||
msgstr "Dosyaları Aç"
|
||||
msgstr "Dosyaları aç"
|
||||
|
||||
#: ui/help-overlay.ui:56 src/dialogs.js:137
|
||||
msgid "Open URI"
|
||||
@@ -111,11 +111,11 @@ msgstr "Çift tıkla (sol tarafa)"
|
||||
|
||||
#: ui/help-overlay.ui:81
|
||||
msgid "Change repeat mode"
|
||||
msgstr "Tekrarlı oynatma modunu değiştir"
|
||||
msgstr "Yineleme kipini değiştir"
|
||||
|
||||
#: ui/help-overlay.ui:87
|
||||
msgid "Export to file"
|
||||
msgstr "Dosyaya aktar"
|
||||
msgstr "Dosyaya dışa aktar"
|
||||
|
||||
#: ui/help-overlay.ui:95 ui/preferences-window.ui:118
|
||||
msgid "Playback"
|
||||
@@ -123,7 +123,7 @@ msgstr "Oynatma"
|
||||
|
||||
#: ui/help-overlay.ui:98
|
||||
msgid "Toggle play"
|
||||
msgstr "Oynatmayı başlat"
|
||||
msgstr "Oynatmayı başlat/durdur"
|
||||
|
||||
#: ui/help-overlay.ui:99
|
||||
msgid "Long press | Right click"
|
||||
@@ -163,7 +163,7 @@ msgstr "Aşağı sürükle | Aşağı kaydır"
|
||||
|
||||
#: ui/help-overlay.ui:133
|
||||
msgid "Toggle mute"
|
||||
msgstr "Sesi kapat"
|
||||
msgstr "Sesi kapat/aç"
|
||||
|
||||
#: ui/help-overlay.ui:139
|
||||
msgid "Next chapter"
|
||||
@@ -191,248 +191,248 @@ msgstr "Otomatik tam ekran"
|
||||
|
||||
#: ui/preferences-window.ui:19
|
||||
msgid "Enter fullscreen when playlist is replaced except floating mode"
|
||||
msgstr ""
|
||||
msgstr "Yüzen kip dışında oynatma listesi değiştirildiğinde tam ekrana geç"
|
||||
|
||||
#: ui/preferences-window.ui:25
|
||||
msgid "Ask to resume recent media"
|
||||
msgstr ""
|
||||
msgstr "Son ortamı devam ettirmeyi sor"
|
||||
|
||||
#: ui/preferences-window.ui:31
|
||||
msgid "Float on all workspaces"
|
||||
msgstr ""
|
||||
msgstr "Tüm çalışma alanlarının üstünde yüz"
|
||||
|
||||
#: ui/preferences-window.ui:32
|
||||
msgid "This option only works on GNOME"
|
||||
msgstr ""
|
||||
msgstr "Bu seçenek sadece GNOME'da çalışır"
|
||||
|
||||
#: ui/preferences-window.ui:38
|
||||
msgid "After playback"
|
||||
msgstr ""
|
||||
msgstr "Oynatma sonrası"
|
||||
|
||||
#: ui/preferences-window.ui:43
|
||||
msgid "Do nothing"
|
||||
msgstr ""
|
||||
msgstr "Hiçbir şey yapma"
|
||||
|
||||
#: ui/preferences-window.ui:44
|
||||
msgid "Freeze last frame"
|
||||
msgstr ""
|
||||
msgstr "Son kareyi dondur"
|
||||
|
||||
#: ui/preferences-window.ui:45
|
||||
msgid "Close the app"
|
||||
msgstr ""
|
||||
msgstr "Uygulamayı kapat"
|
||||
|
||||
#: ui/preferences-window.ui:55
|
||||
msgid "Volume"
|
||||
msgstr ""
|
||||
msgstr "Ses"
|
||||
|
||||
#: ui/preferences-window.ui:58
|
||||
msgid "Custom initial value"
|
||||
msgstr ""
|
||||
msgstr "Özel başlangıç değeri"
|
||||
|
||||
#: ui/preferences-window.ui:59
|
||||
msgid "Set custom volume at startup instead of restoring it"
|
||||
msgstr ""
|
||||
msgstr "Başlangıçta sesi geri yüklemek yerine özel ses ayarla"
|
||||
|
||||
#: ui/preferences-window.ui:63
|
||||
msgid "Volume percentage"
|
||||
msgstr ""
|
||||
msgstr "Ses yüzdesi"
|
||||
|
||||
#: ui/preferences-window.ui:74
|
||||
msgid "Seeking"
|
||||
msgstr ""
|
||||
msgstr "Sarma"
|
||||
|
||||
#: ui/preferences-window.ui:77
|
||||
msgid "Mode"
|
||||
msgstr ""
|
||||
msgstr "Kip"
|
||||
|
||||
#: ui/preferences-window.ui:83
|
||||
msgid "Accurate"
|
||||
msgstr ""
|
||||
msgstr "Hatasız"
|
||||
|
||||
#: ui/preferences-window.ui:84
|
||||
msgid "Fast"
|
||||
msgstr ""
|
||||
msgstr "Hızlı"
|
||||
|
||||
#: ui/preferences-window.ui:92
|
||||
msgid "Unit"
|
||||
msgstr ""
|
||||
msgstr "Birim"
|
||||
|
||||
#: ui/preferences-window.ui:97
|
||||
msgid "Second"
|
||||
msgstr ""
|
||||
msgstr "Saniye"
|
||||
|
||||
#: ui/preferences-window.ui:98
|
||||
msgid "Minute"
|
||||
msgstr ""
|
||||
msgstr "Dakika"
|
||||
|
||||
#: ui/preferences-window.ui:99
|
||||
msgid "Percentage"
|
||||
msgstr ""
|
||||
msgstr "Yüzde"
|
||||
|
||||
#: ui/preferences-window.ui:107
|
||||
msgid "Value"
|
||||
msgstr ""
|
||||
msgstr "Değer"
|
||||
|
||||
#: ui/preferences-window.ui:122
|
||||
msgid "Audio"
|
||||
msgstr ""
|
||||
msgstr "Ses"
|
||||
|
||||
#: ui/preferences-window.ui:125
|
||||
msgid "Offset in milliseconds"
|
||||
msgstr ""
|
||||
msgstr "Milisaniye cinsinden solma süresi"
|
||||
|
||||
#: ui/preferences-window.ui:132
|
||||
msgid "Only native audio formats"
|
||||
msgstr ""
|
||||
msgstr "Yalnızca yerel ses biçimleri"
|
||||
|
||||
#: ui/preferences-window.ui:140
|
||||
msgid "Subtitles"
|
||||
msgstr ""
|
||||
msgstr "Altyazılar"
|
||||
|
||||
#: ui/preferences-window.ui:143
|
||||
msgid "Default font"
|
||||
msgstr ""
|
||||
msgstr "Öntanımlı yazı tipi"
|
||||
|
||||
#: ui/preferences-window.ui:153
|
||||
msgid "Network"
|
||||
msgstr ""
|
||||
msgstr "Ağ"
|
||||
|
||||
#: ui/preferences-window.ui:157
|
||||
msgid "Client"
|
||||
msgstr ""
|
||||
msgstr "İstemci"
|
||||
|
||||
#: ui/preferences-window.ui:160
|
||||
msgid "Progressive download buffering"
|
||||
msgstr ""
|
||||
msgstr "Aşamalı indirme arabelleğe alma"
|
||||
|
||||
#: ui/preferences-window.ui:168
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
msgstr "Sunucu"
|
||||
|
||||
#: ui/preferences-window.ui:171
|
||||
msgid "Control player remotely"
|
||||
msgstr ""
|
||||
msgstr "Oynatıcıyı uzaktan denetle"
|
||||
|
||||
#: ui/preferences-window.ui:175
|
||||
msgid "Listening port"
|
||||
msgstr ""
|
||||
msgstr "Dinleme portu"
|
||||
|
||||
#: ui/preferences-window.ui:188
|
||||
msgid "Tweaks"
|
||||
msgstr ""
|
||||
msgstr "İnce Ayarlar"
|
||||
|
||||
#: ui/preferences-window.ui:192
|
||||
msgid "Appearance"
|
||||
msgstr ""
|
||||
msgstr "Görünüm"
|
||||
|
||||
#: ui/preferences-window.ui:195
|
||||
msgid "Dark theme"
|
||||
msgstr ""
|
||||
msgstr "Koyu tema"
|
||||
|
||||
#: ui/preferences-window.ui:201
|
||||
msgid "Render window shadows"
|
||||
msgstr ""
|
||||
msgstr "Pencere gölgelerini işle"
|
||||
|
||||
#: ui/preferences-window.ui:202
|
||||
msgid "Disable to increase performance when windowed"
|
||||
msgstr ""
|
||||
msgstr "Pencere açıldığında performansı artırmak için devre dışı bırak"
|
||||
|
||||
#: ui/preferences-window.ui:213
|
||||
msgid "Plugin ranking"
|
||||
msgstr ""
|
||||
msgstr "Eklenti puanı"
|
||||
|
||||
#: ui/preferences-window.ui:214
|
||||
msgid "Alter default ranks of GStreamer plugins"
|
||||
msgstr ""
|
||||
msgstr "GStreamer eklentilerinin öntanımlı sıralarını değiştir"
|
||||
|
||||
#: ui/preferences-window.ui:219
|
||||
msgid "Use playbin3"
|
||||
msgstr ""
|
||||
msgstr "Playbin3 kullan"
|
||||
|
||||
#: ui/preferences-window.ui:220 ui/preferences-window.ui:229
|
||||
msgid "Requires player restart"
|
||||
msgstr ""
|
||||
msgstr "Çalıcının yeniden başlatılmasını gerektirir"
|
||||
|
||||
#: ui/preferences-window.ui:222 ui/preferences-window.ui:231
|
||||
msgid "Experimental"
|
||||
msgstr ""
|
||||
msgstr "Deneysel"
|
||||
|
||||
#: ui/preferences-window.ui:228
|
||||
msgid "Use PipeWire for audio output"
|
||||
msgstr ""
|
||||
msgstr "Ses çıktısı için PipeWire kullan"
|
||||
|
||||
#: src/buttons.js:201
|
||||
#, javascript-format
|
||||
msgid "Decoder: %s"
|
||||
msgstr ""
|
||||
msgstr "Çözücü: %s"
|
||||
|
||||
#: src/dialogs.js:152
|
||||
msgid "Enter or drop URI here"
|
||||
msgstr ""
|
||||
msgstr "Bağlantıyı buraya gir veya sürükle"
|
||||
|
||||
#: src/dialogs.js:157
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
msgstr "İptal Et"
|
||||
|
||||
#: src/dialogs.js:158
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
msgstr "Aç"
|
||||
|
||||
#: src/dialogs.js:226
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
msgstr "Başlık"
|
||||
|
||||
#: src/dialogs.js:227
|
||||
msgid "Completed"
|
||||
msgstr ""
|
||||
msgstr "Tamamlandı"
|
||||
|
||||
#: src/dialogs.js:235
|
||||
msgid "Resume playback?"
|
||||
msgstr ""
|
||||
msgstr "Oynatmaya devam edilsin mi?"
|
||||
|
||||
#: src/dialogs.js:289
|
||||
#, javascript-format
|
||||
msgid "GTK version: %s"
|
||||
msgstr ""
|
||||
msgstr "GTK sürümü: %s"
|
||||
|
||||
#: src/dialogs.js:290
|
||||
#, javascript-format
|
||||
msgid "Adwaita version: %s"
|
||||
msgstr ""
|
||||
msgstr "Adwaita sürümü: %s"
|
||||
|
||||
#: src/dialogs.js:291
|
||||
#, javascript-format
|
||||
msgid "GStreamer version: %s"
|
||||
msgstr ""
|
||||
msgstr "GStreamer sürümü: %s"
|
||||
|
||||
#: src/dialogs.js:292
|
||||
#, javascript-format
|
||||
msgid "GJS version: %s"
|
||||
msgstr ""
|
||||
msgstr "GJS sürümü: %s"
|
||||
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
msgstr "GStreamer'dan gücünü alan bir GNOME ortam oynatıcısı"
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr ""
|
||||
msgstr "Clapper Çevirilerine Katkıda Bulunan Herkese Çok Teşekkür Ederiz"
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
msgid "Ends at: %s"
|
||||
msgstr ""
|
||||
msgstr "Bitiş: %s"
|
||||
|
||||
#: src/widget.js:226 src/widget.js:235 src/widget.js:241 src/widget.js:247
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
msgstr "Belirsiz"
|
||||
|
||||
#: src/widget.js:242
|
||||
msgid "Channels"
|
||||
msgstr ""
|
||||
msgstr "Kanallar"
|
||||
|
||||
#: src/widget.js:260
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
msgstr "Devre dışı"
|
||||
|
||||
|
51
po/zh_CN.po
51
po/zh_CN.po
@@ -3,7 +3,7 @@ msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-05-26 18:41+0200\n"
|
||||
"PO-Revision-Date: 2022-05-26 16:50\n"
|
||||
"PO-Revision-Date: 2022-07-18 08:48\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Chinese Simplified\n"
|
||||
"Language: zh_CN\n"
|
||||
@@ -27,7 +27,7 @@ msgstr "打开 URI…"
|
||||
|
||||
#: ui/clapper.ui:16 ui/preferences-window.ui:4
|
||||
msgid "Preferences"
|
||||
msgstr "选项"
|
||||
msgstr "首选项"
|
||||
|
||||
#: ui/clapper.ui:20
|
||||
msgid "Shortcuts"
|
||||
@@ -59,7 +59,7 @@ msgstr "切换全屏"
|
||||
|
||||
#: ui/help-overlay.ui:20
|
||||
msgid "Double tap | Double click"
|
||||
msgstr ""
|
||||
msgstr "轻击两次 | 双击"
|
||||
|
||||
#: ui/help-overlay.ui:26
|
||||
msgid "Leave fullscreen"
|
||||
@@ -71,7 +71,7 @@ msgstr "显示 OSD(仅全屏)"
|
||||
|
||||
#: ui/help-overlay.ui:33
|
||||
msgid "Tap"
|
||||
msgstr ""
|
||||
msgstr "轻击"
|
||||
|
||||
#: ui/help-overlay.ui:39
|
||||
msgid "Quit"
|
||||
@@ -99,7 +99,7 @@ msgstr "下一项"
|
||||
|
||||
#: ui/help-overlay.ui:68
|
||||
msgid "Double tap (right side)"
|
||||
msgstr ""
|
||||
msgstr "双击(右侧)"
|
||||
|
||||
#: ui/help-overlay.ui:74
|
||||
msgid "Previous item"
|
||||
@@ -107,7 +107,7 @@ msgstr "上一项"
|
||||
|
||||
#: ui/help-overlay.ui:75
|
||||
msgid "Double tap (left side)"
|
||||
msgstr ""
|
||||
msgstr "双击(左侧)"
|
||||
|
||||
#: ui/help-overlay.ui:81
|
||||
msgid "Change repeat mode"
|
||||
@@ -123,7 +123,7 @@ msgstr "播放"
|
||||
|
||||
#: ui/help-overlay.ui:98
|
||||
msgid "Toggle play"
|
||||
msgstr ""
|
||||
msgstr "切换播放"
|
||||
|
||||
#: ui/help-overlay.ui:99
|
||||
msgid "Long press | Right click"
|
||||
@@ -135,7 +135,7 @@ msgstr "快进"
|
||||
|
||||
#: ui/help-overlay.ui:106
|
||||
msgid "Swipe right | Scroll right"
|
||||
msgstr ""
|
||||
msgstr "向右滑动 | 向右滚动"
|
||||
|
||||
#: ui/help-overlay.ui:112
|
||||
msgid "Seek backward"
|
||||
@@ -143,7 +143,7 @@ msgstr "快退"
|
||||
|
||||
#: ui/help-overlay.ui:113
|
||||
msgid "Swipe left | Scroll left"
|
||||
msgstr ""
|
||||
msgstr "向左滑动 | 向左滚动"
|
||||
|
||||
#: ui/help-overlay.ui:119
|
||||
msgid "Volume up"
|
||||
@@ -167,11 +167,11 @@ msgstr "切换静音"
|
||||
|
||||
#: ui/help-overlay.ui:139
|
||||
msgid "Next chapter"
|
||||
msgstr ""
|
||||
msgstr "下一章节"
|
||||
|
||||
#: ui/help-overlay.ui:145
|
||||
msgid "Previous chapter"
|
||||
msgstr ""
|
||||
msgstr "上一章节"
|
||||
|
||||
#: ui/preferences-plugin-ranking-subpage.ui:11
|
||||
msgid "Decoders"
|
||||
@@ -191,15 +191,15 @@ msgstr "自动全屏"
|
||||
|
||||
#: ui/preferences-window.ui:19
|
||||
msgid "Enter fullscreen when playlist is replaced except floating mode"
|
||||
msgstr ""
|
||||
msgstr "在播放列表被替换时进入全屏模式,除非悬浮模式"
|
||||
|
||||
#: ui/preferences-window.ui:25
|
||||
msgid "Ask to resume recent media"
|
||||
msgstr ""
|
||||
msgstr "询问恢复播放最近的媒体"
|
||||
|
||||
#: ui/preferences-window.ui:31
|
||||
msgid "Float on all workspaces"
|
||||
msgstr ""
|
||||
msgstr "悬浮于所有工作区"
|
||||
|
||||
#: ui/preferences-window.ui:32
|
||||
msgid "This option only works on GNOME"
|
||||
@@ -231,7 +231,7 @@ msgstr "自定义初始值"
|
||||
|
||||
#: ui/preferences-window.ui:59
|
||||
msgid "Set custom volume at startup instead of restoring it"
|
||||
msgstr ""
|
||||
msgstr "设置启动时的自定义音量而非恢复先前"
|
||||
|
||||
#: ui/preferences-window.ui:63
|
||||
msgid "Volume percentage"
|
||||
@@ -279,11 +279,11 @@ msgstr "音频"
|
||||
|
||||
#: ui/preferences-window.ui:125
|
||||
msgid "Offset in milliseconds"
|
||||
msgstr ""
|
||||
msgstr "以毫秒为单位的偏移"
|
||||
|
||||
#: ui/preferences-window.ui:132
|
||||
msgid "Only native audio formats"
|
||||
msgstr ""
|
||||
msgstr "仅原生音频格式"
|
||||
|
||||
#: ui/preferences-window.ui:140
|
||||
msgid "Subtitles"
|
||||
@@ -303,7 +303,7 @@ msgstr "客户端"
|
||||
|
||||
#: ui/preferences-window.ui:160
|
||||
msgid "Progressive download buffering"
|
||||
msgstr ""
|
||||
msgstr "渐进式下载缓存"
|
||||
|
||||
#: ui/preferences-window.ui:168
|
||||
msgid "Server"
|
||||
@@ -335,15 +335,15 @@ msgstr "渲染窗口阴影"
|
||||
|
||||
#: ui/preferences-window.ui:202
|
||||
msgid "Disable to increase performance when windowed"
|
||||
msgstr ""
|
||||
msgstr "禁用以提升窗口模式时的性能"
|
||||
|
||||
#: ui/preferences-window.ui:213
|
||||
msgid "Plugin ranking"
|
||||
msgstr ""
|
||||
msgstr "插件等级"
|
||||
|
||||
#: ui/preferences-window.ui:214
|
||||
msgid "Alter default ranks of GStreamer plugins"
|
||||
msgstr ""
|
||||
msgstr "更改 GStreamer 插件的默认等级"
|
||||
|
||||
#: ui/preferences-window.ui:219
|
||||
msgid "Use playbin3"
|
||||
@@ -368,7 +368,7 @@ msgstr "解码器:%s"
|
||||
|
||||
#: src/dialogs.js:152
|
||||
msgid "Enter or drop URI here"
|
||||
msgstr ""
|
||||
msgstr "输入或拖放 URI 到这里"
|
||||
|
||||
#: src/dialogs.js:157
|
||||
msgid "Cancel"
|
||||
@@ -412,12 +412,13 @@ msgstr "GJS 版本:%s"
|
||||
|
||||
#: src/dialogs.js:300
|
||||
msgid "A GNOME media player powered by GStreamer"
|
||||
msgstr ""
|
||||
msgstr "一款基于 GStreamer 的 GNOME 媒体播放器"
|
||||
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/dialogs.js:305
|
||||
msgid "translator-credits"
|
||||
msgstr "刘韬"
|
||||
msgstr "刘韬\n"
|
||||
"Tommy He"
|
||||
|
||||
#: src/revealers.js:170
|
||||
#, javascript-format
|
||||
@@ -426,7 +427,7 @@ msgstr "结束于:%s"
|
||||
|
||||
#: src/widget.js:226 src/widget.js:235 src/widget.js:241 src/widget.js:247
|
||||
msgid "Undetermined"
|
||||
msgstr ""
|
||||
msgstr "未确定"
|
||||
|
||||
#: src/widget.js:242
|
||||
msgid "Channels"
|
||||
|
@@ -165,7 +165,7 @@ class ClapperElapsedTimeButton extends PopoverButtonBase
|
||||
|
||||
setInitialState()
|
||||
{
|
||||
this.label = '00∶00∕00∶00';
|
||||
this.label = `00${Misc.timeColon}00∕00${Misc.timeColon}00`;
|
||||
}
|
||||
|
||||
setFullscreenMode(isFullscreen, isMobileMonitor)
|
||||
|
2
src/controls.js
vendored
2
src/controls.js
vendored
@@ -27,7 +27,7 @@ class ClapperControls extends Gtk.Box
|
||||
this.isMobile = false;
|
||||
|
||||
this.showHours = false;
|
||||
this.durationFormatted = '00∶00';
|
||||
this.durationFormatted = `00${Misc.timeColon}00`;
|
||||
this.revealersArr = [];
|
||||
this.chapters = null;
|
||||
|
||||
|
@@ -10,6 +10,7 @@ Debug.debug('imports');
|
||||
|
||||
const { GstClapper, Gtk, Adw } = imports.gi;
|
||||
const { App } = imports.src.app;
|
||||
const Misc = imports.src.misc;
|
||||
|
||||
function main(argv)
|
||||
{
|
||||
@@ -19,6 +20,10 @@ function main(argv)
|
||||
Gtk.init();
|
||||
Adw.init();
|
||||
|
||||
/* U+2236 seems to break RTL languages, use U+003A instead */
|
||||
if(Gtk.Widget.get_default_direction() === Gtk.TextDirection.RTL)
|
||||
Misc.timeColon = ':';
|
||||
|
||||
Debug.debug('initialized');
|
||||
|
||||
new App().run(argv);
|
||||
|
@@ -9,6 +9,7 @@ var subsMimes = [
|
||||
'application/x-subrip',
|
||||
'text/x-ssa',
|
||||
];
|
||||
var timeColon = '∶';
|
||||
|
||||
var settings = new Gio.Settings({
|
||||
schema_id: appId,
|
||||
@@ -161,8 +162,8 @@ function getFormattedTime(time, showHours)
|
||||
time -= minutes * 60;
|
||||
const seconds = ('0' + Math.floor(time)).slice(-2);
|
||||
|
||||
const parsed = (hours) ? `${hours}∶` : '';
|
||||
return parsed + `${minutes}∶${seconds}`;
|
||||
const parsed = (hours) ? `${hours}${timeColon}` : '';
|
||||
return parsed + `${minutes}${timeColon}${seconds}`;
|
||||
}
|
||||
|
||||
function parsePlaylistFiles(filesArray)
|
||||
|
@@ -59,8 +59,8 @@ class ClapperRevealerTop extends CustomRevealer
|
||||
|
||||
const initTime = GLib.DateTime.new_now_local().format('%X');
|
||||
this.timeFormat = (initTime.length > 8)
|
||||
? '%I∶%M %p'
|
||||
: '%H∶%M';
|
||||
? `%I${Misc.timeColon}%M %p`
|
||||
: `%H${Misc.timeColon}%M`;
|
||||
|
||||
this.mediaTitle = new Gtk.Label({
|
||||
ellipsize: Pango.EllipsizeMode.END,
|
||||
|
Reference in New Issue
Block a user