45 gst_init(
nullptr,
nullptr);
62 return media::Player::PlaybackStatus::playing;
63 else if (state.
new_state == GST_STATE_PAUSED)
64 return media::Player::PlaybackStatus::paused;
65 else if (state.
new_state == GST_STATE_READY)
66 return media::Player::PlaybackStatus::ready;
67 else if (state.
new_state == GST_STATE_NULL)
68 return media::Player::PlaybackStatus::null;
70 return media::Player::PlaybackStatus::stopped;
74 const QByteArray &source)
78 if (source ==
"playbin")
80 MH_INFO(
"State changed on playbin: %s",
81 gst_element_state_get_name(state.
new_state));
87 if (status == media::Player::PlaybackStatus::paused &&
89 MH_ERROR(
"** Cannot play: some codecs are missing");
91 const media::Player::Error e = media::Player::Error::format_error;
92 Q_EMIT q->errorOccurred(e);
93 }
else if (status == media::Player::PlaybackStatus::paused &&
99 q->setPlaybackStatus(status);
107 media::Player::Error ret_error = media::Player::Error::no_error;
109 if (g_strcmp0(g_quark_to_string(ewi.
error->domain),
"gst-core-error-quark") == 0)
111 switch (ewi.
error->code)
113 case GST_CORE_ERROR_FAILED:
114 MH_ERROR(
"** Encountered a GST_CORE_ERROR_FAILED");
115 ret_error = media::Player::Error::resource_error;
117 case GST_CORE_ERROR_NEGOTIATION:
118 MH_ERROR(
"** Encountered a GST_CORE_ERROR_NEGOTIATION");
119 ret_error = media::Player::Error::resource_error;
121 case GST_CORE_ERROR_MISSING_PLUGIN:
122 MH_ERROR(
"** Encountered a GST_CORE_ERROR_MISSING_PLUGIN");
123 ret_error = media::Player::Error::format_error;
126 MH_ERROR(
"** Encountered an unhandled core error: '%s' (code: %d)",
128 ret_error = media::Player::Error::no_error;
132 else if (g_strcmp0(g_quark_to_string(ewi.
error->domain),
"gst-resource-error-quark") == 0)
134 switch (ewi.
error->code)
136 case GST_RESOURCE_ERROR_FAILED:
137 MH_ERROR(
"** Encountered a GST_RESOURCE_ERROR_FAILED");
138 ret_error = media::Player::Error::resource_error;
140 case GST_RESOURCE_ERROR_NOT_FOUND:
141 MH_ERROR(
"** Encountered a GST_RESOURCE_ERROR_NOT_FOUND");
142 ret_error = media::Player::Error::resource_error;
144 case GST_RESOURCE_ERROR_OPEN_READ:
145 MH_ERROR(
"** Encountered a GST_RESOURCE_ERROR_OPEN_READ");
146 ret_error = media::Player::Error::resource_error;
148 case GST_RESOURCE_ERROR_OPEN_WRITE:
149 MH_ERROR(
"** Encountered a GST_RESOURCE_ERROR_OPEN_WRITE");
150 ret_error = media::Player::Error::resource_error;
152 case GST_RESOURCE_ERROR_READ:
153 MH_ERROR(
"** Encountered a GST_RESOURCE_ERROR_READ");
154 ret_error = media::Player::Error::resource_error;
156 case GST_RESOURCE_ERROR_WRITE:
157 MH_ERROR(
"** Encountered a GST_RESOURCE_ERROR_WRITE");
158 ret_error = media::Player::Error::resource_error;
160 case GST_RESOURCE_ERROR_NOT_AUTHORIZED:
161 MH_ERROR(
"** Encountered a GST_RESOURCE_ERROR_NOT_AUTHORIZED");
162 ret_error = media::Player::Error::access_denied_error;
165 MH_ERROR(
"** Encountered an unhandled resource error: '%s' (code: %d)",
167 ret_error = media::Player::Error::no_error;
171 else if (g_strcmp0(g_quark_to_string(ewi.
error->domain),
"gst-stream-error-quark") == 0)
173 switch (ewi.
error->code)
175 case GST_STREAM_ERROR_FAILED:
176 MH_ERROR(
"** Encountered a GST_STREAM_ERROR_FAILED");
177 ret_error = media::Player::Error::resource_error;
179 case GST_STREAM_ERROR_CODEC_NOT_FOUND:
180 MH_ERROR(
"** Encountered a GST_STREAM_ERROR_CODEC_NOT_FOUND");
182 ret_error = media::Player::Error::no_error;
184 case GST_STREAM_ERROR_DECODE:
185 MH_ERROR(
"** Encountered a GST_STREAM_ERROR_DECODE");
186 ret_error = media::Player::Error::format_error;
189 MH_ERROR(
"** Encountered an unhandled stream error: '%s' code(%d)",
191 ret_error = media::Player::Error::no_error;
196 if (ret_error != media::Player::Error::no_error) {
197 MH_ERROR(
"Resetting playbin pipeline after unrecoverable error: %s", ewi.
debug);
207 if (e != media::Player::Error::no_error)
208 Q_EMIT q->errorOccurred(e);
215 if (e != media::Player::Error::no_error)
216 Q_EMIT q->errorOccurred(e);
221 MH_DEBUG(
"Got a playbin info message (no action taken): %s", ewi.
debug);
227 media::Track::MetaData md;
230 auto pair = q->trackMetadata();
235 q->setTrackMetadata(qMakePair(
playbin.
uri(), md));
272 const QByteArray &source) {
281 q, [q](media::Player::Orientation o) {
285 q, [q](
const QSize &size) {
308 const auto fileType = d->playbin.mediaFileType();
309 using ft = Playbin::MediaFileType;
310 setIsVideoSource(fileType == ft::MEDIA_FILE_TYPE_VIDEO);
311 setIsAudioSource(fileType == ft::MEDIA_FILE_TYPE_AUDIO);
318 setState(media::Engine::State::no_media);
322 bool do_pipeline_reset)
325 d->playbin.set_uri(uri, media::Player::HeadersType{}, do_pipeline_reset);
333 d->playbin.set_uri(uri, headers);
340 d->playbin.create_video_sink(texture_id);
346 const auto result = d->playbin.set_state(GST_STATE_PLAYING);
350 setState(media::Engine::State::playing);
351 MH_INFO(
"Engine: playing uri: %s", qUtf8Printable(d->playbin.uri().toString()));
361 if (state() == media::Engine::State::stopped)
363 MH_DEBUG(
"Current player state is already stopped - no need to change state to stopped");
367 const auto result = d->playbin.set_state(GST_STATE_NULL);
370 setState(media::Engine::State::stopped);
372 setPlaybackStatus(media::Player::stopped);
381 const auto result = d->playbin.set_state(GST_STATE_PAUSED);
385 setState(media::Engine::State::paused);
395 return d->playbin.seek(ts);
401 return d->playbin.position();
407 return d->playbin.duration();
419 d->playbin.set_audio_stream_role(role);
425 d->playbin.set_lifetime(lifetime);
431 d->playbin.set_volume(volume);
void on_playbin_info(const gstreamer::Bus::Message::Detail::ErrorWarningInfo &ewi)
gstreamer::Playbin playbin
void on_tag_available(const gstreamer::Bus::Message::Detail::Tag &tag)
void on_playbin_error(const gstreamer::Bus::Message::Detail::ErrorWarningInfo &ewi)
void on_playbin_warning(const gstreamer::Bus::Message::Detail::ErrorWarningInfo &ewi)
void on_playbin_state_changed(const gstreamer::Bus::Message::Detail::StateChanged &state, const QByteArray &source)
media::Player::PlaybackStatus gst_state_to_player_status(const gstreamer::Bus::Message::Detail::StateChanged &state)
media::Player::Error from_gst_errorwarning(const gstreamer::Bus::Message::Detail::ErrorWarningInfo &ewi)
EnginePrivate(const lomiri::MediaHubService::Player::PlayerKey key, Engine *q)
void doSetAudioStreamRole(lomiri::MediaHubService::Player::AudioStreamRole role) override
uint64_t duration() const
void doSetVolume(double volume) override
Engine(const lomiri::MediaHubService::Player::PlayerKey key)
bool open_resource_for_uri(const QUrl &uri, bool do_pipeline_reset)
void doSetLifetime(lomiri::MediaHubService::Player::Lifetime lifetime) override
void create_video_sink(uint32_t texture_id)
bool seek_to(const std::chrono::microseconds &ts)
uint64_t position() const
void stateChanged(const Bus::Message::Detail::StateChanged &state, const QByteArray &source)
void tagAvailable(Bus::Message::Detail::Tag tag)
bool can_play_streams() const
void bufferingChanged(int progress)
void orientationChanged(lomiri::MediaHubService::Player::Orientation o)
void clientDisconnected()
void videoDimensionChanged(const QSize &size)
void warningOccurred(const Bus::Message::Detail::ErrorWarningInfo &)
void errorOccurred(const Bus::Message::Detail::ErrorWarningInfo &)
void mediaFileTypeChanged()
void seekedTo(uint64_t offset)
void infoOccurred(const Bus::Message::Detail::ErrorWarningInfo &)
struct gstreamer::Init init