Music Hub  ..
A session-wide music playback service
hybris_video_sink.cpp
Go to the documentation of this file.
1 /*
2  * Copyright © 2021-2022 UBports Foundation.
3  *
4  * Contact: Alberto Mardegan <mardy@users.sourceforge.net>
5  *
6  * This program is free software: you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License version 3,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include "hybris_video_sink.h"
20 
21 #include "logging.h"
22 
23 #include <QMutex>
24 #include <QMutexLocker>
25 
26 #include <hybris/media/media_codec_layer.h>
27 #include <hybris/media/surface_texture_client_hybris.h>
28 
29 using namespace lomiri::MediaHub;
30 
31 namespace lomiri {
32 namespace MediaHub {
33 
35 {
36  friend class HybrisVideoSink;
37 
38  static void on_frame_available_callback(GLConsumerWrapperHybris, void* context)
39  {
40  if (not context)
41  return;
42 
43  auto thiz = static_cast<HybrisVideoSink*>(context);
44  thiz->onFrameAvailable();
45  }
46 
47 public:
48  HybrisVideoSinkPrivate(uint32_t gl_texture, HybrisVideoSink *q):
49  gl_texture{gl_texture},
50  graphics_buffer_consumer{decoding_service_get_igraphicbufferconsumer()},
51  gl_texture_consumer{gl_consumer_create_by_id_with_igbc(gl_texture, graphics_buffer_consumer)}
52  {
53  if (not graphics_buffer_consumer) {
54  MH_ERROR("video::HybrisGlSink: Could not connect to remote buffer queue.");
55  return;
56  };
57 
58  if (not gl_texture_consumer) {
59  MH_ERROR("video::HybrisGlSink: Could not associate local texture id with remote buffer streak.");
60  return;
61  };
62 
63  gl_consumer_set_frame_available_cb(gl_texture_consumer,
64  HybrisVideoSinkPrivate::on_frame_available_callback,
65  q);
66 
67  }
68 
70  {
71  gl_consumer_set_frame_available_cb(gl_texture_consumer,
72  HybrisVideoSinkPrivate::on_frame_available_callback,
73  nullptr);
74  }
75 
77  // TODO: The underlying API really should tell us if everything is ok.
78  gl_consumer_get_transformation_matrix(gl_texture_consumer,
79  m_transformationMatrix.data());
80  }
81 
82  uint32_t gl_texture;
83  IGBCWrapperHybris graphics_buffer_consumer;
85 };
86 
87 } // namespace MediaHub
88 } // namespace lomiri
89 
90 HybrisVideoSink::HybrisVideoSink(uint32_t gl_texture,
91  QObject *parent):
92  VideoSink(new HybrisVideoSinkPrivate(gl_texture, this), parent)
93 {
94 }
95 
97 {
98 }
99 
100 void HybrisVideoSink::onFrameAvailable()
101 {
102  Q_D(HybrisVideoSink);
103  d->updateTransformationMatrix();
104  Q_EMIT frameAvailable();
105 }
106 
108 {
109  // It's okay-ish to use static map here. Point being that we currently have no way
110  // of terminating the session with the decoding service anyway.
111  static QHash<PlayerKey, DSSessionWrapperHybris> lut;
112  static QMutex lut_guard;
113 
114  // Scoping access to the lut to ensure that the lock is kept for as short as possible.
115  {
116  QMutexLocker lg(&lut_guard);
117  if (!lut.contains(key))
118  lut[key] = decoding_service_create_session(key);
119  }
120 
121  return [](uint32_t textureId, QObject *parent) {
122  return new HybrisVideoSink(textureId, parent);
123  };
124 }
125 
127 {
128  Q_D(HybrisVideoSink);
129 
130  // TODO: The underlying API really should tell us if everything is ok.
131  gl_consumer_update_texture(d->gl_texture_consumer);
132  return true;
133 }
lomiri::MediaHub
Definition: dbus_utils.h:25
lomiri::MediaHub::HybrisVideoSinkPrivate::graphics_buffer_consumer
IGBCWrapperHybris graphics_buffer_consumer
Definition: hybris_video_sink.cpp:83
QObject
lomiri::MediaHub::HybrisVideoSinkPrivate::updateTransformationMatrix
void updateTransformationMatrix()
Definition: hybris_video_sink.cpp:76
lomiri::MediaHub::GLConsumerWrapperHybris
void * GLConsumerWrapperHybris
Definition: hybris_video_sink.h:26
lomiri::MediaHub::VideoSink::frameAvailable
void frameAvailable()
The signal is emitted whenever a new frame is available and a subsequent call to swapBuffers() will n...
lomiri::MediaHub::HybrisVideoSink
Definition: hybris_video_sink.h:29
hybris_video_sink.h
lomiri::MediaHub::VideoSink
A video sink abstracts a queue of buffers, that receives a stream of decoded video buffers from an ar...
Definition: video_sink.h:34
lomiri::MediaHub::VideoSinkFactory
std::function< VideoSink *(uint32_t textureId, QObject *parent)> VideoSinkFactory
Definition: video_sink_p.h:43
lomiri::MediaHub::HybrisVideoSinkPrivate::HybrisVideoSinkPrivate
HybrisVideoSinkPrivate(uint32_t gl_texture, HybrisVideoSink *q)
Definition: hybris_video_sink.cpp:48
lomiri::MediaHub::HybrisVideoSinkPrivate
Definition: hybris_video_sink.cpp:34
MH_ERROR
#define MH_ERROR(...)
Definition: logging.h:41
lomiri::MediaHub::HybrisVideoSink::~HybrisVideoSink
virtual ~HybrisVideoSink()
Definition: hybris_video_sink.cpp:96
lomiri::MediaHub::HybrisVideoSink::swapBuffers
bool swapBuffers() override
Releases the current buffer, and consumes the next buffer in the queue, making it available for consu...
Definition: hybris_video_sink.cpp:126
lomiri::MediaHub::PlayerKey
uint32_t PlayerKey
Definition: video_sink_p.h:44
lomiri::MediaHub::HybrisVideoSinkPrivate::gl_texture
uint32_t gl_texture
Definition: hybris_video_sink.cpp:82
lomiri::MediaHub::HybrisVideoSinkPrivate::~HybrisVideoSinkPrivate
~HybrisVideoSinkPrivate()
Definition: hybris_video_sink.cpp:69
lomiri::MediaHub::HybrisVideoSinkPrivate::gl_texture_consumer
GLConsumerWrapperHybris gl_texture_consumer
Definition: hybris_video_sink.cpp:84
lomiri
Definition: dbus_utils.h:24
lomiri::MediaHub::VideoSinkPrivate
Definition: video_sink_p.h:49
logging.h
lomiri::MediaHub::HybrisVideoSink::createFactory
static VideoSinkFactory createFactory(PlayerKey playerKey)
Definition: hybris_video_sink.cpp:107