Music Hub  ..
A session-wide music playback service
hybris_gl_sink.cpp
Go to the documentation of this file.
1 /*
2  * Copyright © 2014 Canonical Ltd.
3  *
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.
7  *
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.
12  *
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/>.
15  *
16  * Authored by: Thomas Voß <thomas.voss@canonical.com>
17  */
18 
20 
21 // Hybris
22 #include <hybris/media/media_codec_layer.h>
23 #include <hybris/media/surface_texture_client_hybris.h>
24 
25 namespace media = core::ubuntu::media;
27 
29 {
30  static void on_frame_available_callback(GLConsumerWrapperHybris, void* context)
31  {
32  if (not context)
33  return;
34 
35  auto thiz = static_cast<Private*>(context);
36 
37  thiz->frame_available();
38  }
39 
40  Private(std::uint32_t gl_texture)
41  : gl_texture{gl_texture},
42  graphics_buffer_consumer{decoding_service_get_igraphicbufferconsumer()},
43  gl_texture_consumer{gl_consumer_create_by_id_with_igbc(gl_texture, graphics_buffer_consumer)}
44  {
45  if (not graphics_buffer_consumer) throw std::runtime_error
46  {
47  "video::HybrisGlSink: Could not connect to remote buffer queue."
48  };
49 
50  if (not gl_texture_consumer) throw std::runtime_error
51  {
52  "video::HybrisGlSink: Could not associate local texture id with remote buffer streak."
53  };
54 
55  gl_consumer_set_frame_available_cb(gl_texture_consumer, Private::on_frame_available_callback, this);
56  }
57 
59  {
60  gl_consumer_set_frame_available_cb(gl_texture_consumer, Private::on_frame_available_callback, nullptr);
61  }
62 
63  std::uint32_t gl_texture;
64  core::Signal<void> frame_available;
65  IGBCWrapperHybris graphics_buffer_consumer;
66  GLConsumerWrapperHybris gl_texture_consumer;
67 };
68 
69 std::function<video::Sink::Ptr(std::uint32_t)> video::HybrisGlSink::factory_for_key(const media::Player::PlayerKey& key)
70 {
71  // It's okay-ish to use static map here. Point being that we currently have no way
72  // of terminating the session with the decoding service anyway.
73  static std::map<media::Player::PlayerKey, DSSessionWrapperHybris> lut;
74  static std::mutex lut_guard;
75 
76  // Scoping access to the lut to ensure that the lock is kept for as short as possible.
77  {
78  std::lock_guard<std::mutex> lg{lut_guard};
79  if (lut.count(key) == 0)
80  lut[key] = decoding_service_create_session(key);
81  }
82 
83  return [](std::uint32_t texture)
84  {
85  return video::Sink::Ptr{new video::HybrisGlSink{texture}};
86  };
87 }
88 
89 video::HybrisGlSink::HybrisGlSink(std::uint32_t gl_texture) : d{new Private{gl_texture}}
90 {
91 }
92 
94 {
95 }
96 
97 const core::Signal<void>& video::HybrisGlSink::frame_available() const
98 {
99  return d->frame_available;
100 }
101 
102 bool video::HybrisGlSink::transformation_matrix(float* matrix) const
103 {
104  // TODO: The underlying API really should tell us if everything is ok.
105  gl_consumer_get_transformation_matrix(d->gl_texture_consumer, matrix);
106  return true;
107 }
108 
110 {
111  // TODO: The underlying API really should tell us if everything is ok.
112  gl_consumer_update_texture(d->gl_texture_consumer);
113  return true;
114 }
Private(std::uint32_t gl_texture)
static void on_frame_available_callback(GLConsumerWrapperHybris, void *context)
GLConsumerWrapperHybris gl_texture_consumer
std::shared_ptr< Sink > Ptr
To save us some typing.
Definition: sink.h:39
bool transformation_matrix(float *matrix) const override
Queries the 4x4 transformation matrix for the current frame, placing the data into &#39;matrix&#39;...
static std::function< video::Sink::Ptr(std::uint32_t)> factory_for_key(const media::Player::PlayerKey &)
IGBCWrapperHybris graphics_buffer_consumer
core::Signal< void > frame_available
const core::Signal< void > & frame_available() const override
The signal is emitted whenever a new frame is available and a subsequent call to swap_buffers will no...
bool swap_buffers() const override
Releases the current buffer, and consumes the next buffer in the queue, making it available for consu...