Music Hub  ..
A session-wide music playback service
engine.cpp
Go to the documentation of this file.
1 /*
2  * Copyright © 2013-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  * Jim Hodapp <jim.hodapp@canonical.com>
18  * Alfonso Sanchez-Beato <alfonso.sanchez-beato@canonical.com>
19  */
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 
24 #include "bus.h"
25 #include "engine.h"
26 #include "meta_data_extractor.h"
27 #include "playbin.h"
28 
30 
31 #include <cassert>
32 
33 namespace media = core::ubuntu::media;
34 
35 using namespace std;
36 
37 namespace gstreamer
38 {
39 struct Init
40 {
41  Init()
42  {
43  gst_init(nullptr, nullptr);
44  }
45 
47  {
48  gst_deinit();
49  }
50 } init;
51 }
52 
54 {
56  {
57  if (state.new_state == GST_STATE_PLAYING)
58  return media::Player::PlaybackStatus::playing;
59  else if (state.new_state == GST_STATE_PAUSED)
60  return media::Player::PlaybackStatus::paused;
61  else if (state.new_state == GST_STATE_READY)
62  return media::Player::PlaybackStatus::ready;
63  else if (state.new_state == GST_STATE_NULL)
64  return media::Player::PlaybackStatus::null;
65  else
66  return media::Player::PlaybackStatus::stopped;
67  }
68 
69  void on_playbin_state_changed(const std::pair<gstreamer::Bus::Message::Detail::StateChanged,std::string>& p)
70  {
71  if (p.second == "playbin")
72  {
73  MH_INFO("State changed on playbin: %s",
74  gst_element_state_get_name(p.first.new_state));
75  const auto status = gst_state_to_player_status(p.first);
76  /*
77  * When state moves to "paused" the pipeline is already set. We check that we
78  * have streams to play.
79  */
80  if (status == media::Player::PlaybackStatus::paused &&
81  !playbin.can_play_streams()) {
82  MH_ERROR("** Cannot play: some codecs are missing");
83  playbin.reset();
84  const media::Player::Error e = media::Player::Error::format_error;
85  error(e);
86  } else {
87  playback_status_changed(status);
88  }
89  }
90  }
91 
92  // Converts from a GStreamer GError to a media::Player:Error enum
94  {
95  media::Player::Error ret_error = media::Player::Error::no_error;
96 
97  if (g_strcmp0(g_quark_to_string(ewi.error->domain), "gst-core-error-quark") == 0)
98  {
99  switch (ewi.error->code)
100  {
101  case GST_CORE_ERROR_FAILED:
102  MH_ERROR("** Encountered a GST_CORE_ERROR_FAILED");
103  ret_error = media::Player::Error::resource_error;
104  break;
105  case GST_CORE_ERROR_NEGOTIATION:
106  MH_ERROR("** Encountered a GST_CORE_ERROR_NEGOTIATION");
107  ret_error = media::Player::Error::resource_error;
108  break;
109  case GST_CORE_ERROR_MISSING_PLUGIN:
110  MH_ERROR("** Encountered a GST_CORE_ERROR_MISSING_PLUGIN");
111  ret_error = media::Player::Error::format_error;
112  break;
113  default:
114  MH_ERROR("** Encountered an unhandled core error: '%s' (code: %d)",
115  ewi.debug, ewi.error->code);
116  ret_error = media::Player::Error::no_error;
117  break;
118  }
119  }
120  else if (g_strcmp0(g_quark_to_string(ewi.error->domain), "gst-resource-error-quark") == 0)
121  {
122  switch (ewi.error->code)
123  {
124  case GST_RESOURCE_ERROR_FAILED:
125  MH_ERROR("** Encountered a GST_RESOURCE_ERROR_FAILED");
126  ret_error = media::Player::Error::resource_error;
127  break;
128  case GST_RESOURCE_ERROR_NOT_FOUND:
129  MH_ERROR("** Encountered a GST_RESOURCE_ERROR_NOT_FOUND");
130  ret_error = media::Player::Error::resource_error;
131  break;
132  case GST_RESOURCE_ERROR_OPEN_READ:
133  MH_ERROR("** Encountered a GST_RESOURCE_ERROR_OPEN_READ");
134  ret_error = media::Player::Error::resource_error;
135  break;
136  case GST_RESOURCE_ERROR_OPEN_WRITE:
137  MH_ERROR("** Encountered a GST_RESOURCE_ERROR_OPEN_WRITE");
138  ret_error = media::Player::Error::resource_error;
139  break;
140  case GST_RESOURCE_ERROR_READ:
141  MH_ERROR("** Encountered a GST_RESOURCE_ERROR_READ");
142  ret_error = media::Player::Error::resource_error;
143  break;
144  case GST_RESOURCE_ERROR_WRITE:
145  MH_ERROR("** Encountered a GST_RESOURCE_ERROR_WRITE");
146  ret_error = media::Player::Error::resource_error;
147  break;
148  case GST_RESOURCE_ERROR_NOT_AUTHORIZED:
149  MH_ERROR("** Encountered a GST_RESOURCE_ERROR_NOT_AUTHORIZED");
150  ret_error = media::Player::Error::access_denied_error;
151  break;
152  default:
153  MH_ERROR("** Encountered an unhandled resource error: '%s' (code: %d)",
154  ewi.debug, ewi.error->code);
155  ret_error = media::Player::Error::no_error;
156  break;
157  }
158  }
159  else if (g_strcmp0(g_quark_to_string(ewi.error->domain), "gst-stream-error-quark") == 0)
160  {
161  switch (ewi.error->code)
162  {
163  case GST_STREAM_ERROR_FAILED:
164  MH_ERROR("** Encountered a GST_STREAM_ERROR_FAILED");
165  ret_error = media::Player::Error::resource_error;
166  break;
167  case GST_STREAM_ERROR_CODEC_NOT_FOUND:
168  MH_ERROR("** Encountered a GST_STREAM_ERROR_CODEC_NOT_FOUND");
169  // Missing codecs are handled later, when state switches to "paused"
170  ret_error = media::Player::Error::no_error;
171  break;
172  case GST_STREAM_ERROR_DECODE:
173  MH_ERROR("** Encountered a GST_STREAM_ERROR_DECODE");
174  ret_error = media::Player::Error::format_error;
175  break;
176  default:
177  MH_ERROR("** Encountered an unhandled stream error: '%s' code(%d)",
178  ewi.debug, ewi.error->code);
179  ret_error = media::Player::Error::no_error;
180  break;
181  }
182  }
183 
184  if (ret_error != media::Player::Error::no_error) {
185  MH_ERROR("Resetting playbin pipeline after unrecoverable error");
186  playbin.reset();
187  }
188  return ret_error;
189  }
190 
192  {
193  const media::Player::Error e = from_gst_errorwarning(ewi);
194  if (e != media::Player::Error::no_error)
195  error(e);
196  }
197 
199  {
200  const media::Player::Error e = from_gst_errorwarning(ewi);
201  if (e != media::Player::Error::no_error)
202  error(e);
203  }
204 
206  {
207  MH_DEBUG("Got a playbin info message (no action taken): %s", ewi.debug);
208  }
209 
211  {
212  media::Track::MetaData md;
213 
214  // We update instead of creating from scratch if same uri
215  auto &tuple = track_meta_data.get();
216  if (playbin.uri() == std::get<0>(tuple))
217  md = std::get<1>(tuple);
218 
220  track_meta_data.set(std::make_tuple(playbin.uri(), md));
221  }
222 
223  void on_volume_changed(const media::Engine::Volume& new_volume)
224  {
225  playbin.set_volume(new_volume.value);
226  }
227 
229  {
230  playbin.set_audio_stream_role(new_audio_role);
231  }
232 
234  {
235  // Update the local orientation Property, which should then update the Player
236  // orientation Property
237  orientation.set(o);
238  }
239 
241  {
242  playbin.set_lifetime(lifetime);
243  }
244 
246  {
247  state = Engine::State::ready;
248  about_to_finish();
249  }
250 
251  void on_seeked_to(uint64_t value)
252  {
253  seeked_to(value);
254  }
255 
257  {
258  client_disconnected();
259  }
260 
262  {
263  end_of_stream();
264  }
265 
267  {
268  video_dimension_changed(dimensions);
269  }
270 
271  void on_buffering_changed(int value)
272  {
273  buffering_changed(value);
274  }
275 
277  : playbin(key),
278  meta_data_extractor(new gstreamer::MetaDataExtractor()),
279  volume(media::Engine::Volume(1.)),
280  orientation(media::Player::Orientation::rotate0),
281  is_video_source(false),
282  is_audio_source(false),
283  about_to_finish_connection(
284  playbin.signals.about_to_finish.connect(
285  std::bind(
286  &Private::on_about_to_finish,
287  this))),
288  on_state_changed_connection(
289  playbin.signals.on_state_changed.connect(
290  std::bind(
291  &Private::on_playbin_state_changed,
292  this,
293  std::placeholders::_1))),
294  on_error_connection(
295  playbin.signals.on_error.connect(
296  std::bind(
297  &Private::on_playbin_error,
298  this,
299  std::placeholders::_1))),
300  on_warning_connection(
301  playbin.signals.on_warning.connect(
302  std::bind(
303  &Private::on_playbin_warning,
304  this,
305  std::placeholders::_1))),
306  on_info_connection(
307  playbin.signals.on_info.connect(
308  std::bind(
309  &Private::on_playbin_info,
310  this,
311  std::placeholders::_1))),
312  on_tag_available_connection(
313  playbin.signals.on_tag_available.connect(
314  std::bind(
315  &Private::on_tag_available,
316  this,
317  std::placeholders::_1))),
318  on_volume_changed_connection(
319  volume.changed().connect(
320  std::bind(
321  &Private::on_volume_changed,
322  this,
323  std::placeholders::_1))),
324  on_audio_stream_role_changed_connection(
325  audio_role.changed().connect(
326  std::bind(
327  &Private::on_audio_stream_role_changed,
328  this,
329  std::placeholders::_1))),
330  on_orientation_changed_connection(
331  playbin.signals.on_orientation_changed.connect(
332  std::bind(
333  &Private::on_orientation_changed,
334  this,
335  std::placeholders::_1))),
336  on_lifetime_changed_connection(
337  lifetime.changed().connect(
338  std::bind(
339  &Private::on_lifetime_changed,
340  this,
341  std::placeholders::_1))),
342  on_seeked_to_connection(
343  playbin.signals.on_seeked_to.connect(
344  std::bind(
345  &Private::on_seeked_to,
346  this,
347  std::placeholders::_1))),
348  client_disconnected_connection(
349  playbin.signals.client_disconnected.connect(
350  std::bind(
351  &Private::on_client_disconnected,
352  this))),
353  on_end_of_stream_connection(
354  playbin.signals.on_end_of_stream.connect(
355  std::bind(
356  &Private::on_end_of_stream,
357  this))),
358  on_video_dimension_changed_connection(
359  playbin.signals.on_video_dimensions_changed.connect(
360  std::bind(
361  &Private::on_video_dimension_changed,
362  this,
363  std::placeholders::_1))),
364  on_buffering_changed_connection(
365  playbin.signals.on_buffering_changed.connect(
366  std::bind(
367  &Private::on_buffering_changed,
368  this,
369  std::placeholders::_1)))
370  {
371  }
372 
373  // Ensure the playbin is the last item destroyed
374  // otherwise properties could try to access a dead playbin object
376 
377  std::shared_ptr<Engine::MetaDataExtractor> meta_data_extractor;
378  core::Property<Engine::State> state;
379  core::Property<std::tuple<media::Track::UriType, media::Track::MetaData>> track_meta_data;
380  core::Property<uint64_t> position;
381  core::Property<uint64_t> duration;
382  core::Property<media::Engine::Volume> volume;
383  core::Property<media::Player::AudioStreamRole> audio_role;
384  core::Property<media::Player::Orientation> orientation;
385  core::Property<media::Player::Lifetime> lifetime;
386  core::Property<bool> is_video_source;
387  core::Property<bool> is_audio_source;
388 
389  core::ScopedConnection about_to_finish_connection;
390  core::ScopedConnection on_state_changed_connection;
391  core::ScopedConnection on_error_connection;
392  core::ScopedConnection on_warning_connection;
393  core::ScopedConnection on_info_connection;
394  core::ScopedConnection on_tag_available_connection;
395  core::ScopedConnection on_volume_changed_connection;
397  core::ScopedConnection on_orientation_changed_connection;
398  core::ScopedConnection on_lifetime_changed_connection;
399  core::ScopedConnection on_seeked_to_connection;
400  core::ScopedConnection client_disconnected_connection;
401  core::ScopedConnection on_end_of_stream_connection;
403  core::ScopedConnection on_buffering_changed_connection;
404 
405  core::Signal<void> about_to_finish;
406  core::Signal<uint64_t> seeked_to;
407  core::Signal<void> client_disconnected;
408  core::Signal<void> end_of_stream;
409  core::Signal<media::Player::PlaybackStatus> playback_status_changed;
410  core::Signal<core::ubuntu::media::video::Dimensions> video_dimension_changed;
411  core::Signal<media::Player::Error> error;
412  core::Signal<int> buffering_changed;
413 };
414 
416  : d(new Private{key})
417 {
418  d->state = media::Engine::State::no_media;
419 }
420 
422 {
423  stop();
424  d->state = media::Engine::State::no_media;
425 }
426 
427 const std::shared_ptr<media::Engine::MetaDataExtractor>&
429 {
430  return d->meta_data_extractor;
431 }
432 
433 const core::Property<media::Engine::State>& gstreamer::Engine::state() const
434 {
435  return d->state;
436 }
437 
439  bool do_pipeline_reset)
440 {
441  d->playbin.set_uri(uri, core::ubuntu::media::Player::HeadersType{}, do_pipeline_reset);
442  return true;
443 }
444 
447 {
448  d->playbin.set_uri(uri, headers);
449  return true;
450 }
451 
452 void gstreamer::Engine::create_video_sink(uint32_t texture_id)
453 {
454  d->playbin.create_video_sink(texture_id);
455 }
456 
457 bool gstreamer::Engine::play(bool use_main_thread /* = false */)
458 {
459  const auto result = d->playbin.set_state_and_wait(GST_STATE_PLAYING, use_main_thread);
460 
461  if (result)
462  {
463  d->state = media::Engine::State::playing;
464  MH_INFO("Engine: playing uri: %s", d->playbin.uri());
465  d->playback_status_changed(media::Player::PlaybackStatus::playing);
466  }
467 
468  return result;
469 }
470 
471 bool gstreamer::Engine::stop(bool use_main_thread /* = false */)
472 {
473  // No need to wait, and we can immediately return.
474  if (d->state == media::Engine::State::stopped)
475  {
476  MH_DEBUG("Current player state is already stopped - no need to change state to stopped");
477  return true;
478  }
479 
480  const auto result = d->playbin.set_state_and_wait(GST_STATE_NULL, use_main_thread);
481  if (result)
482  {
483  d->state = media::Engine::State::stopped;
484  MH_TRACE("");
485  d->playback_status_changed(media::Player::PlaybackStatus::stopped);
486  }
487 
488  return result;
489 }
490 
492 {
493  const auto result = d->playbin.set_state_and_wait(GST_STATE_PAUSED);
494 
495  if (result)
496  {
497  d->state = media::Engine::State::paused;
498  MH_TRACE("");
499  d->playback_status_changed(media::Player::PlaybackStatus::paused);
500  }
501 
502  return result;
503 }
504 
505 bool gstreamer::Engine::seek_to(const std::chrono::microseconds& ts)
506 {
507  return d->playbin.seek(ts);
508 }
509 
510 const core::Property<bool>& gstreamer::Engine::is_video_source() const
511 {
512  gstreamer::Playbin::MediaFileType type = d->playbin.media_file_type();
513  if (type == gstreamer::Playbin::MediaFileType::MEDIA_FILE_TYPE_VIDEO)
514  d->is_video_source.set(true);
515  else
516  d->is_video_source.set(false);
517 
518  return d->is_video_source;
519 }
520 
521 const core::Property<bool>& gstreamer::Engine::is_audio_source() const
522 {
523  gstreamer::Playbin::MediaFileType type = d->playbin.media_file_type();
524  if (type == gstreamer::Playbin::MediaFileType::MEDIA_FILE_TYPE_AUDIO)
525  d->is_audio_source.set(true);
526  else
527  d->is_audio_source.set(false);
528 
529  return d->is_audio_source;
530 }
531 
532 const core::Property<uint64_t>& gstreamer::Engine::position() const
533 {
534  d->position.set(d->playbin.position());
535  return d->position;
536 }
537 
538 const core::Property<uint64_t>& gstreamer::Engine::duration() const
539 {
540  d->duration.set(d->playbin.duration());
541  return d->duration;
542 }
543 
544 const core::Property<core::ubuntu::media::Engine::Volume>& gstreamer::Engine::volume() const
545 {
546  return d->volume;
547 }
548 
549 core::Property<core::ubuntu::media::Engine::Volume>& gstreamer::Engine::volume()
550 {
551  return d->volume;
552 }
553 
554 const core::Property<core::ubuntu::media::Player::AudioStreamRole>& gstreamer::Engine::audio_stream_role() const
555 {
556  return d->audio_role;
557 }
558 
559 const core::Property<core::ubuntu::media::Player::Lifetime>& gstreamer::Engine::lifetime() const
560 {
561  return d->lifetime;
562 }
563 
564 core::Property<core::ubuntu::media::Player::AudioStreamRole>& gstreamer::Engine::audio_stream_role()
565 {
566  return d->audio_role;
567 }
568 
569 const core::Property<core::ubuntu::media::Player::Orientation>& gstreamer::Engine::orientation() const
570 {
571  return d->orientation;
572 }
573 
574 core::Property<core::ubuntu::media::Player::Lifetime>& gstreamer::Engine::lifetime()
575 {
576  return d->lifetime;
577 }
578 
579 const core::Property<std::tuple<media::Track::UriType, media::Track::MetaData>>&
581 {
582  return d->track_meta_data;
583 }
584 
585 const core::Signal<void>& gstreamer::Engine::about_to_finish_signal() const
586 {
587  return d->about_to_finish;
588 }
589 
590 const core::Signal<uint64_t>& gstreamer::Engine::seeked_to_signal() const
591 {
592  return d->seeked_to;
593 }
594 
595 const core::Signal<void>& gstreamer::Engine::client_disconnected_signal() const
596 {
597  return d->client_disconnected;
598 }
599 
600 const core::Signal<void>& gstreamer::Engine::end_of_stream_signal() const
601 {
602  return d->end_of_stream;
603 }
604 
605 const core::Signal<media::Player::PlaybackStatus>& gstreamer::Engine::playback_status_changed_signal() const
606 {
607  return d->playback_status_changed;
608 }
609 
610 const core::Signal<core::ubuntu::media::video::Dimensions>& gstreamer::Engine::video_dimension_changed_signal() const
611 {
612  return d->video_dimension_changed;
613 }
614 
615 const core::Signal<core::ubuntu::media::Player::Error>& gstreamer::Engine::error_signal() const
616 {
617  return d->error;
618 }
619 
620 const core::Signal<int>& gstreamer::Engine::on_buffering_changed_signal() const
621 {
622  return d->buffering_changed;
623 }
624 
626 {
627  d->playbin.reset();
628 }
void on_tag_available(const gstreamer::Bus::Message::Detail::Tag &tag)
Definition: engine.cpp:210
core::ScopedConnection on_state_changed_connection
Definition: engine.cpp:390
core::ScopedConnection on_video_dimension_changed_connection
Definition: engine.cpp:402
core::Signal< core::ubuntu::media::video::Dimensions > video_dimension_changed
Definition: engine.cpp:410
const core::Signal< void > & about_to_finish_signal() const
Definition: engine.cpp:585
Private(const core::ubuntu::media::Player::PlayerKey key)
Definition: engine.cpp:276
core::Property< bool > is_video_source
Definition: engine.cpp:386
std::tuple< Height, Width > Dimensions
Height and Width of a video.
Definition: dimensions.h:139
const core::Signal< void > & end_of_stream_signal() const
Definition: engine.cpp:600
const core::Property< core::ubuntu::media::Player::Orientation > & orientation() const
Definition: engine.cpp:569
core::ScopedConnection on_info_connection
Definition: engine.cpp:393
core::Signal< void > end_of_stream
Definition: engine.cpp:408
Definition: bus.h:33
core::ScopedConnection on_buffering_changed_connection
Definition: engine.cpp:403
core::ScopedConnection on_lifetime_changed_connection
Definition: engine.cpp:398
void on_seeked_to(uint64_t value)
Definition: engine.cpp:251
#define MH_INFO(...)
Definition: logger.h:125
void on_playbin_warning(const gstreamer::Bus::Message::Detail::ErrorWarningInfo &ewi)
Definition: engine.cpp:198
const core::Property< uint64_t > & position() const
Definition: engine.cpp:532
bool stop(bool use_main_thread=false)
Definition: engine.cpp:471
const core::Signal< core::ubuntu::media::Player::PlaybackStatus > & playback_status_changed_signal() const
Definition: engine.cpp:605
STL namespace.
const core::Property< uint64_t > & duration() const
Definition: engine.cpp:538
#define MH_ERROR(...)
Definition: logger.h:128
const core::Signal< void > & client_disconnected_signal() const
Definition: engine.cpp:595
core::ScopedConnection on_seeked_to_connection
Definition: engine.cpp:399
core::Signal< int > buffering_changed
Definition: engine.cpp:412
const core::Signal< uint64_t > & seeked_to_signal() const
Definition: engine.cpp:590
core::ScopedConnection on_end_of_stream_connection
Definition: engine.cpp:401
void on_orientation_changed(const media::Player::Orientation &o)
Definition: engine.cpp:233
core::Signal< media::Player::Error > error
Definition: engine.cpp:411
const core::Property< State > & state() const
Definition: engine.cpp:433
std::map< std::string, std::string > HeadersType
Definition: player.h:65
gstreamer::Playbin playbin
Definition: engine.cpp:375
bool seek_to(const std::chrono::microseconds &ts)
Definition: engine.cpp:505
#define MH_DEBUG(...)
Definition: logger.h:123
core::ScopedConnection on_warning_connection
Definition: engine.cpp:392
const core::Property< core::ubuntu::media::Engine::Volume > & volume() const
Definition: engine.cpp:544
const core::Signal< core::ubuntu::media::video::Dimensions > & video_dimension_changed_signal() const
Definition: engine.cpp:610
bool open_resource_for_uri(const core::ubuntu::media::Track::UriType &uri, bool do_pipeline_reset)
const core::Property< bool > & is_audio_source() const
Definition: engine.cpp:521
struct gstreamer::Init init
void create_video_sink(uint32_t texture_id)
Definition: engine.cpp:452
core::ScopedConnection client_disconnected_connection
Definition: engine.cpp:400
void on_playbin_error(const gstreamer::Bus::Message::Detail::ErrorWarningInfo &ewi)
Definition: engine.cpp:191
const core::Property< core::ubuntu::media::Player::Lifetime > & lifetime() const
Definition: engine.cpp:559
media::Player::Error from_gst_errorwarning(const gstreamer::Bus::Message::Detail::ErrorWarningInfo &ewi)
Definition: engine.cpp:93
void on_volume_changed(const media::Engine::Volume &new_volume)
Definition: engine.cpp:223
core::ScopedConnection on_volume_changed_connection
Definition: engine.cpp:395
core::Property< media::Player::Orientation > orientation
Definition: engine.cpp:384
core::Property< media::Player::AudioStreamRole > audio_role
Definition: engine.cpp:383
core::Signal< void > client_disconnected
Definition: engine.cpp:407
core::Signal< uint64_t > seeked_to
Definition: engine.cpp:406
bool play(bool use_main_thread=false)
Definition: engine.cpp:457
const core::Property< std::tuple< core::ubuntu::media::Track::UriType, core::ubuntu::media::Track::MetaData > > & track_meta_data() const
Definition: engine.cpp:580
void on_playbin_info(const gstreamer::Bus::Message::Detail::ErrorWarningInfo &ewi)
Definition: engine.cpp:205
const core::Signal< int > & on_buffering_changed_signal() const
Definition: engine.cpp:620
core::ScopedConnection on_error_connection
Definition: engine.cpp:391
#define MH_TRACE(...)
Definition: logger.h:121
core::Property< media::Player::Lifetime > lifetime
Definition: engine.cpp:385
std::shared_ptr< Engine::MetaDataExtractor > meta_data_extractor
Definition: engine.cpp:377
const std::shared_ptr< MetaDataExtractor > & meta_data_extractor() const
Definition: engine.cpp:428
static void on_tag_available(const gstreamer::Bus::Message::Detail::Tag &tag, core::ubuntu::media::Track::MetaData &md)
core::ScopedConnection on_tag_available_connection
Definition: engine.cpp:394
void on_buffering_changed(int value)
Definition: engine.cpp:271
core::Property< media::Engine::Volume > volume
Definition: engine.cpp:382
void on_playbin_state_changed(const std::pair< gstreamer::Bus::Message::Detail::StateChanged, std::string > &p)
Definition: engine.cpp:69
media::Player::PlaybackStatus gst_state_to_player_status(const gstreamer::Bus::Message::Detail::StateChanged &state)
Definition: engine.cpp:55
const core::Property< bool > & is_video_source() const
Definition: engine.cpp:510
std::string UriType
Definition: track.h:40
core::ScopedConnection about_to_finish_connection
Definition: engine.cpp:389
core::Property< Engine::State > state
Definition: engine.cpp:378
core::Property< uint64_t > position
Definition: engine.cpp:380
core::Property< std::tuple< media::Track::UriType, media::Track::MetaData > > track_meta_data
Definition: engine.cpp:379
core::Signal< void > about_to_finish
Definition: engine.cpp:405
const core::Property< core::ubuntu::media::Player::AudioStreamRole > & audio_stream_role() const
Definition: engine.cpp:554
core::Signal< media::Player::PlaybackStatus > playback_status_changed
Definition: engine.cpp:409
const core::Signal< core::ubuntu::media::Player::Error > & error_signal() const
Definition: engine.cpp:615
core::ScopedConnection on_orientation_changed_connection
Definition: engine.cpp:397
Engine(const core::ubuntu::media::Player::PlayerKey key)
Definition: engine.cpp:415
void on_audio_stream_role_changed(const media::Player::AudioStreamRole &new_audio_role)
Definition: engine.cpp:228
void on_video_dimension_changed(const media::video::Dimensions &dimensions)
Definition: engine.cpp:266
void on_lifetime_changed(const media::Player::Lifetime &lifetime)
Definition: engine.cpp:240
core::Property< bool > is_audio_source
Definition: engine.cpp:387
core::Property< uint64_t > duration
Definition: engine.cpp:381
core::ScopedConnection on_audio_stream_role_changed_connection
Definition: engine.cpp:396