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 #if defined(MEDIA_HUB_HAVE_HYBRIS_MEDIA_COMPAT_LAYER)
22 // Hybris
23 #include <hybris/media/media_codec_layer.h>
24 #include <hybris/media/surface_texture_client_hybris.h>
25 
26 namespace media = core::ubuntu::media;
28 
29 struct video::HybrisGlSink::Private
30 {
31  static void on_frame_available_callback(GLConsumerWrapperHybris, void* context)
32  {
33  if (not context)
34  return;
35 
36  auto thiz = static_cast<Private*>(context);
37 
38  thiz->frame_available();
39  }
40 
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)}
45  {
46  if (not graphics_buffer_consumer) throw std::runtime_error
47  {
48  "video::HybrisGlSink: Could not connect to remote buffer queue."
49  };
50 
51  if (not gl_texture_consumer) throw std::runtime_error
52  {
53  "video::HybrisGlSink: Could not associate local texture id with remote buffer streak."
54  };
55 
56  gl_consumer_set_frame_available_cb(gl_texture_consumer, Private::on_frame_available_callback, this);
57  }
58 
59  ~Private()
60  {
61  gl_consumer_set_frame_available_cb(gl_texture_consumer, Private::on_frame_available_callback, nullptr);
62  }
63 
64  std::uint32_t gl_texture;
65  core::Signal<void> frame_available;
66  IGBCWrapperHybris graphics_buffer_consumer;
67  GLConsumerWrapperHybris gl_texture_consumer;
68 };
69 
70 std::function<video::Sink::Ptr(std::uint32_t)> video::HybrisGlSink::factory_for_key(const media::Player::PlayerKey& key)
71 {
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;
76 
77  // Scoping access to the lut to ensure that the lock is kept for as short as possible.
78  {
79  std::lock_guard<std::mutex> lg{lut_guard};
80  if (lut.count(key) == 0)
81  lut[key] = decoding_service_create_session(key);
82  }
83 
84  return [](std::uint32_t texture)
85  {
86  return video::Sink::Ptr{new video::HybrisGlSink{texture}};
87  };
88 }
89 
90 video::HybrisGlSink::HybrisGlSink(std::uint32_t gl_texture) : d{new Private{gl_texture}}
91 {
92 }
93 
95 {
96 }
97 
98 const core::Signal<void>& video::HybrisGlSink::frame_available() const
99 {
100  return d->frame_available;
101 }
102 
103 bool video::HybrisGlSink::transformation_matrix(float* matrix) const
104 {
105  // TODO: The underlying API really should tell us if everything is ok.
106  gl_consumer_get_transformation_matrix(d->gl_texture_consumer, matrix);
107  return true;
108 }
109 
111 {
112  // TODO: The underlying API really should tell us if everything is ok.
113  gl_consumer_update_texture(d->gl_texture_consumer);
114  return true;
115 }
116 #endif // MEDIA_HUB_HAVE_HYBRIS_MEDIA_COMPAT_LAYER
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 'matrix'...
static std::function< video::Sink::Ptr(std::uint32_t)> factory_for_key(const media::Player::PlayerKey &)
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...