2
* Copyright © 2014 Canonical Ltd.
4
* This program is free software: you can redistribute it and/or modify it
5
* under the terms of the GNU Lesser General Public License version 3,
6
* as published by the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU Lesser General Public License for more details.
13
* You should have received a copy of the GNU Lesser General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16
* Authored by: Thomas Voß <thomas.voss@canonical.com>
19
#include <core/media/video/hybris_gl_sink.h>
21
#if defined(MEDIA_HUB_HAVE_HYBRIS_MEDIA_COMPAT_LAYER)
23
#include <hybris/media/media_codec_layer.h>
24
#include <hybris/media/surface_texture_client_hybris.h>
26
namespace media = core::ubuntu::media;
27
namespace video = core::ubuntu::media::video;
29
struct video::HybrisGlSink::Private
31
static void on_frame_available_callback(GLConsumerWrapperHybris, void* context)
36
auto thiz = static_cast<Private*>(context);
38
thiz->frame_available();
41
Private(std::uint32_t gl_texture)
42
: gl_texture{gl_texture},
43
graphics_buffer_consumer{decoding_service_get_igraphicbufferconsumer()},
44
gl_texture_consumer{gl_consumer_create_by_id_with_igbc(gl_texture, graphics_buffer_consumer)}
46
if (not graphics_buffer_consumer) throw std::runtime_error
48
"video::HybrisGlSink: Could not connect to remote buffer queue."
51
if (not gl_texture_consumer) throw std::runtime_error
53
"video::HybrisGlSink: Could not associate local texture id with remote buffer streak."
56
gl_consumer_set_frame_available_cb(gl_texture_consumer, Private::on_frame_available_callback, this);
61
gl_consumer_set_frame_available_cb(gl_texture_consumer, Private::on_frame_available_callback, nullptr);
64
std::uint32_t gl_texture;
65
core::Signal<void> frame_available;
66
IGBCWrapperHybris graphics_buffer_consumer;
67
GLConsumerWrapperHybris gl_texture_consumer;
70
std::function<video::Sink::Ptr(std::uint32_t)> video::HybrisGlSink::factory_for_key(const media::Player::PlayerKey& key)
72
// It's okay-ish to use static map here. Point being that we currently have no way
73
// of terminating the session with the decoding service anyway.
74
static std::map<media::Player::PlayerKey, DSSessionWrapperHybris> lut;
75
static std::mutex lut_guard;
77
// Scoping access to the lut to ensure that the lock is kept for as short as possible.
79
std::lock_guard<std::mutex> lg{lut_guard};
80
if (lut.count(key) == 0)
81
lut[key] = decoding_service_create_session(key);
84
return [](std::uint32_t texture)
86
return video::Sink::Ptr{new video::HybrisGlSink{texture}};
90
video::HybrisGlSink::HybrisGlSink(std::uint32_t gl_texture) : d{new Private{gl_texture}}
94
video::HybrisGlSink::~HybrisGlSink()
98
const core::Signal<void>& video::HybrisGlSink::frame_available() const
100
return d->frame_available;
103
bool video::HybrisGlSink::transformation_matrix(float* matrix) const
105
// TODO: The underlying API really should tell us if everything is ok.
106
gl_consumer_get_transformation_matrix(d->gl_texture_consumer, matrix);
110
bool video::HybrisGlSink::swap_buffers() const
112
// TODO: The underlying API really should tell us if everything is ok.
113
gl_consumer_update_texture(d->gl_texture_consumer);
116
#endif // MEDIA_HUB_HAVE_HYBRIS_MEDIA_COMPAT_LAYER