Merge lp:~phablet-team/media-hub/multiple-sessions into lp:media-hub
- multiple-sessions
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 28 |
Proposed branch: | lp:~phablet-team/media-hub/multiple-sessions |
Merge into: | lp:media-hub |
Prerequisite: | lp:~phablet-team/media-hub/video-support |
Diff against target: |
808 lines (+224/-40) 21 files modified
include/core/media/player.h (+3/-0) include/core/media/service.h (+1/-0) src/core/media/apparmor.h (+1/-1) src/core/media/engine.h (+2/-0) src/core/media/gstreamer/engine.cpp (+19/-0) src/core/media/gstreamer/engine.h (+1/-0) src/core/media/gstreamer/playbin.h (+5/-2) src/core/media/mpris/player.h (+2/-0) src/core/media/mpris/service.h (+1/-0) src/core/media/player_implementation.cpp (+25/-8) src/core/media/player_implementation.h (+3/-1) src/core/media/player_skeleton.cpp (+33/-5) src/core/media/player_skeleton.h (+1/-0) src/core/media/player_stub.cpp (+30/-5) src/core/media/player_stub.h (+2/-0) src/core/media/service_implementation.cpp (+57/-10) src/core/media/service_implementation.h (+5/-0) src/core/media/service_skeleton.cpp (+17/-1) src/core/media/service_skeleton.h (+1/-1) src/core/media/service_stub.cpp (+13/-5) src/core/media/service_stub.h (+2/-1) |
To merge this branch: | bzr merge lp:~phablet-team/media-hub/multiple-sessions |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Needs Fixing | |
Ubuntu Phablet Team | Pending | ||
Review via email: mp+217452@code.launchpad.net |
Commit message
* One Engine instance per PlayerImplement
* Pause other playing sessions when starting playback of a new foreground player
* Emit a PlaybackStatusC
* Use GST_SEEK_
Description of the change
* One Engine instance per PlayerImplement
* Pause other playing sessions when starting playback of a new foreground player
* Emit a PlaybackStatusC
* Use GST_SEEK_
PS Jenkins bot (ps-jenkins) wrote : | # |
Preview Diff
1 | === modified file 'include/core/media/player.h' |
2 | --- include/core/media/player.h 2014-04-28 14:20:04 +0000 |
3 | +++ include/core/media/player.h 2014-04-28 14:20:05 +0000 |
4 | @@ -39,6 +39,7 @@ |
5 | public: |
6 | typedef double PlaybackRate; |
7 | typedef double Volume; |
8 | + typedef uint32_t PlayerKey; |
9 | typedef void* GLConsumerWrapperHybris; |
10 | |
11 | /** Used to set a callback function to be called when a frame is ready to be rendered **/ |
12 | @@ -78,6 +79,7 @@ |
13 | bool operator==(const Player&) const = delete; |
14 | |
15 | virtual std::shared_ptr<TrackList> track_list() = 0; |
16 | + virtual PlayerKey key() const = 0; |
17 | |
18 | virtual bool open_uri(const Track::UriType& uri) = 0; |
19 | virtual void create_video_sink(uint32_t texture_id) = 0; |
20 | @@ -118,6 +120,7 @@ |
21 | |
22 | virtual const core::Signal<uint64_t>& seeked_to() const = 0; |
23 | virtual const core::Signal<void>& end_of_stream() const = 0; |
24 | + virtual core::Signal<PlaybackStatus>& playback_status_changed() = 0; |
25 | protected: |
26 | Player(); |
27 | |
28 | |
29 | === modified file 'include/core/media/service.h' |
30 | --- include/core/media/service.h 2014-01-13 21:51:14 +0000 |
31 | +++ include/core/media/service.h 2014-04-28 14:20:05 +0000 |
32 | @@ -43,6 +43,7 @@ |
33 | bool operator==(const Service&) const = delete; |
34 | |
35 | virtual std::shared_ptr<Player> create_session(const Player::Configuration&) = 0; |
36 | + virtual void pause_other_sessions(Player::PlayerKey) = 0; |
37 | |
38 | protected: |
39 | Service() = default; |
40 | |
41 | === modified file 'src/core/media/apparmor.h' |
42 | --- src/core/media/apparmor.h 2014-04-28 14:20:04 +0000 |
43 | +++ src/core/media/apparmor.h 2014-04-28 14:20:05 +0000 |
44 | @@ -13,7 +13,7 @@ |
45 | * You should have received a copy of the GNU Lesser General Public License |
46 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
47 | * |
48 | - * Author: Ricardo Mendoza <ricardo.mendoza@canonical.com> |
49 | + * Author: Jim Hodapp <jim.hodapp@canonical.com> |
50 | */ |
51 | |
52 | #ifndef APPARMOR_H_DBUS_ |
53 | |
54 | === modified file 'src/core/media/engine.h' |
55 | --- src/core/media/engine.h 2014-04-28 14:20:04 +0000 |
56 | +++ src/core/media/engine.h 2014-04-28 14:20:05 +0000 |
57 | @@ -18,6 +18,7 @@ |
58 | #ifndef CORE_UBUNTU_MEDIA_ENGINE_H_ |
59 | #define CORE_UBUNTU_MEDIA_ENGINE_H_ |
60 | |
61 | +#include <core/media/player.h> |
62 | #include <core/media/track.h> |
63 | |
64 | #include <core/property.h> |
65 | @@ -118,6 +119,7 @@ |
66 | virtual const core::Signal<void>& about_to_finish_signal() const = 0; |
67 | virtual const core::Signal<uint64_t>& seeked_to_signal() const = 0; |
68 | virtual const core::Signal<void>& end_of_stream_signal() const = 0; |
69 | + virtual const core::Signal<core::ubuntu::media::Player::PlaybackStatus>& playback_status_changed_signal() const = 0; |
70 | }; |
71 | } |
72 | } |
73 | |
74 | === modified file 'src/core/media/gstreamer/engine.cpp' |
75 | --- src/core/media/gstreamer/engine.cpp 2014-04-28 14:20:04 +0000 |
76 | +++ src/core/media/gstreamer/engine.cpp 2014-04-28 14:20:05 +0000 |
77 | @@ -28,6 +28,8 @@ |
78 | |
79 | namespace media = core::ubuntu::media; |
80 | |
81 | +using namespace std; |
82 | + |
83 | namespace gstreamer |
84 | { |
85 | struct Init |
86 | @@ -239,10 +241,12 @@ |
87 | core::Signal<void> about_to_finish; |
88 | core::Signal<uint64_t> seeked_to; |
89 | core::Signal<void> end_of_stream; |
90 | + core::Signal<media::Player::PlaybackStatus> playback_status_changed; |
91 | }; |
92 | |
93 | gstreamer::Engine::Engine() : d(new Private{}) |
94 | { |
95 | + cout << "Creating a new Engine instance in " << __PRETTY_FUNCTION__ << endl; |
96 | d->state = media::Engine::State::ready; |
97 | } |
98 | |
99 | @@ -279,8 +283,11 @@ |
100 | if (result) |
101 | { |
102 | d->state = media::Engine::State::playing; |
103 | + d->playback_status_changed(media::Player::PlaybackStatus::playing); |
104 | } |
105 | |
106 | + cout << "Engine: " << this << endl; |
107 | + |
108 | return result; |
109 | } |
110 | |
111 | @@ -289,7 +296,10 @@ |
112 | auto result = d->playbin.set_state_and_wait(GST_STATE_NULL); |
113 | |
114 | if (result) |
115 | + { |
116 | d->state = media::Engine::State::stopped; |
117 | + d->playback_status_changed(media::Player::PlaybackStatus::stopped); |
118 | + } |
119 | |
120 | return result; |
121 | } |
122 | @@ -299,7 +309,11 @@ |
123 | auto result = d->playbin.set_state_and_wait(GST_STATE_PAUSED); |
124 | |
125 | if (result) |
126 | + { |
127 | d->state = media::Engine::State::paused; |
128 | + cout << "pause" << endl; |
129 | + d->playback_status_changed(media::Player::PlaybackStatus::paused); |
130 | + } |
131 | |
132 | return result; |
133 | } |
134 | @@ -373,3 +387,8 @@ |
135 | { |
136 | return d->end_of_stream; |
137 | } |
138 | + |
139 | +const core::Signal<media::Player::PlaybackStatus>& gstreamer::Engine::playback_status_changed_signal() const |
140 | +{ |
141 | + return d->playback_status_changed; |
142 | +} |
143 | |
144 | === modified file 'src/core/media/gstreamer/engine.h' |
145 | --- src/core/media/gstreamer/engine.h 2014-04-28 14:20:04 +0000 |
146 | +++ src/core/media/gstreamer/engine.h 2014-04-28 14:20:05 +0000 |
147 | @@ -54,6 +54,7 @@ |
148 | const core::Signal<void>& about_to_finish_signal() const; |
149 | const core::Signal<uint64_t>& seeked_to_signal() const; |
150 | const core::Signal<void>& end_of_stream_signal() const; |
151 | + const core::Signal<core::ubuntu::media::Player::PlaybackStatus>& playback_status_changed_signal() const; |
152 | |
153 | private: |
154 | struct Private; |
155 | |
156 | === modified file 'src/core/media/gstreamer/playbin.h' |
157 | --- src/core/media/gstreamer/playbin.h 2014-04-28 14:20:04 +0000 |
158 | +++ src/core/media/gstreamer/playbin.h 2014-04-28 14:20:05 +0000 |
159 | @@ -20,6 +20,7 @@ |
160 | #define GSTREAMER_PLAYBIN_H_ |
161 | |
162 | #include "bus.h" |
163 | +#include "../mpris/player.h" |
164 | |
165 | #include <hybris/media/media_codec_layer.h> |
166 | #include <hybris/media/surface_texture_client_hybris.h> |
167 | @@ -30,6 +31,8 @@ |
168 | #include <chrono> |
169 | #include <string> |
170 | |
171 | +namespace media = core::ubuntu::media; |
172 | + |
173 | namespace gstreamer |
174 | { |
175 | struct Playbin |
176 | @@ -312,8 +315,7 @@ |
177 | return gst_element_seek_simple( |
178 | pipeline, |
179 | GST_FORMAT_TIME, |
180 | - (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT | |
181 | - GST_SEEK_FLAG_SNAP_BEFORE), |
182 | + (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT), |
183 | ms.count() * 1000); |
184 | } |
185 | |
186 | @@ -408,6 +410,7 @@ |
187 | core::Signal<Bus::Message::Detail::StateChanged> on_state_changed; |
188 | core::Signal<uint64_t> on_seeked_to; |
189 | core::Signal<void> on_end_of_stream; |
190 | + core::Signal<media::Player::PlaybackStatus> on_playback_status_changed; |
191 | } signals; |
192 | }; |
193 | } |
194 | |
195 | === modified file 'src/core/media/mpris/player.h' |
196 | --- src/core/media/mpris/player.h 2014-04-28 14:20:04 +0000 |
197 | +++ src/core/media/mpris/player.h 2014-04-28 14:20:05 +0000 |
198 | @@ -55,12 +55,14 @@ |
199 | METHOD(Seek, Player, std::chrono::seconds(1)) |
200 | METHOD(SetPosition, Player, std::chrono::seconds(1)) |
201 | METHOD(CreateVideoSink, Player, std::chrono::seconds(1)) |
202 | + METHOD(Key, Player, std::chrono::seconds(1)) |
203 | METHOD(OpenUri, Player, std::chrono::seconds(1)) |
204 | |
205 | struct Signals |
206 | { |
207 | SIGNAL(Seeked, Player, uint64_t) |
208 | SIGNAL(EndOfStream, Player, void) |
209 | + SIGNAL(PlaybackStatusChanged, Player, core::ubuntu::media::Player::PlaybackStatus) |
210 | }; |
211 | |
212 | struct Properties |
213 | |
214 | === modified file 'src/core/media/mpris/service.h' |
215 | --- src/core/media/mpris/service.h 2014-01-13 21:51:14 +0000 |
216 | +++ src/core/media/mpris/service.h 2014-04-28 14:20:05 +0000 |
217 | @@ -50,6 +50,7 @@ |
218 | }; |
219 | |
220 | METHOD(CreateSession, Service, std::chrono::seconds(1)) |
221 | + METHOD(PauseOtherSessions, Service, std::chrono::seconds(1)) |
222 | }; |
223 | } |
224 | |
225 | |
226 | === modified file 'src/core/media/player_implementation.cpp' |
227 | --- src/core/media/player_implementation.cpp 2014-04-28 14:20:04 +0000 |
228 | +++ src/core/media/player_implementation.cpp 2014-04-28 14:20:05 +0000 |
229 | @@ -22,24 +22,29 @@ |
230 | #include "engine.h" |
231 | #include "track_list_implementation.h" |
232 | |
233 | +#include "gstreamer/engine.h" |
234 | + |
235 | #define UNUSED __attribute__((unused)) |
236 | |
237 | namespace media = core::ubuntu::media; |
238 | |
239 | +using namespace std; |
240 | + |
241 | struct media::PlayerImplementation::Private |
242 | { |
243 | Private(PlayerImplementation* parent, |
244 | const dbus::types::ObjectPath& session_path, |
245 | const std::shared_ptr<media::Service>& service, |
246 | - const std::shared_ptr<media::Engine>& engine) |
247 | + PlayerImplementation::PlayerKey key) |
248 | : parent(parent), |
249 | service(service), |
250 | - engine(engine), |
251 | + engine(std::make_shared<gstreamer::Engine>()), |
252 | session_path(session_path), |
253 | track_list( |
254 | new media::TrackListImplementation( |
255 | session_path.as_string() + "/TrackList", |
256 | - engine->meta_data_extractor())) |
257 | + engine->meta_data_extractor())), |
258 | + key(key) |
259 | { |
260 | engine->state().changed().connect( |
261 | [parent](const Engine::State& state) |
262 | @@ -62,18 +67,19 @@ |
263 | std::shared_ptr<Engine> engine; |
264 | dbus::types::ObjectPath session_path; |
265 | std::shared_ptr<TrackListImplementation> track_list; |
266 | + PlayerImplementation::PlayerKey key; |
267 | }; |
268 | |
269 | media::PlayerImplementation::PlayerImplementation( |
270 | const dbus::types::ObjectPath& session_path, |
271 | const std::shared_ptr<Service>& service, |
272 | - const std::shared_ptr<Engine>& engine) |
273 | + PlayerKey key) |
274 | : media::PlayerSkeleton(session_path), |
275 | d(new Private( |
276 | this, |
277 | session_path, |
278 | service, |
279 | - engine)) |
280 | + key)) |
281 | { |
282 | // Initializing default values for properties |
283 | can_play().set(true); |
284 | @@ -118,7 +124,7 @@ |
285 | }; |
286 | is_audio_source().install(audio_type_getter); |
287 | |
288 | - engine->about_to_finish_signal().connect([this]() |
289 | + d->engine->about_to_finish_signal().connect([this]() |
290 | { |
291 | if (d->track_list->has_next()) |
292 | { |
293 | @@ -128,15 +134,20 @@ |
294 | } |
295 | }); |
296 | |
297 | - engine->seeked_to_signal().connect([this](uint64_t value) |
298 | + d->engine->seeked_to_signal().connect([this](uint64_t value) |
299 | { |
300 | seeked_to()(value); |
301 | }); |
302 | |
303 | - engine->end_of_stream_signal().connect([this]() |
304 | + d->engine->end_of_stream_signal().connect([this]() |
305 | { |
306 | end_of_stream()(); |
307 | }); |
308 | + |
309 | + d->engine->playback_status_changed_signal().connect([this](const Player::PlaybackStatus& status) |
310 | + { |
311 | + playback_status_changed()(status); |
312 | + }); |
313 | } |
314 | |
315 | media::PlayerImplementation::~PlayerImplementation() |
316 | @@ -148,6 +159,12 @@ |
317 | return d->track_list; |
318 | } |
319 | |
320 | +// TODO: Convert this to be a property instead of sync call |
321 | +media::Player::PlayerKey media::PlayerImplementation::key() const |
322 | +{ |
323 | + return d->key; |
324 | +} |
325 | + |
326 | bool media::PlayerImplementation::open_uri(const Track::UriType& uri) |
327 | { |
328 | return d->engine->open_resource_for_uri(uri); |
329 | |
330 | === modified file 'src/core/media/player_implementation.h' |
331 | --- src/core/media/player_implementation.h 2014-04-28 14:20:04 +0000 |
332 | +++ src/core/media/player_implementation.h 2014-04-28 14:20:05 +0000 |
333 | @@ -1,4 +1,5 @@ |
334 | /* |
335 | + * Copyright © 2013-2014 Canonical Ltd. |
336 | * |
337 | * This program is free software: you can redistribute it and/or modify it |
338 | * under the terms of the GNU Lesser General Public License version 3, |
339 | @@ -37,10 +38,11 @@ |
340 | PlayerImplementation( |
341 | const core::dbus::types::ObjectPath& session_path, |
342 | const std::shared_ptr<Service>& service, |
343 | - const std::shared_ptr<Engine>& engine); |
344 | + PlayerKey key); |
345 | ~PlayerImplementation(); |
346 | |
347 | virtual std::shared_ptr<TrackList> track_list(); |
348 | + virtual PlayerKey key() const; |
349 | |
350 | virtual bool open_uri(const Track::UriType& uri); |
351 | virtual void create_video_sink(uint32_t texture_id); |
352 | |
353 | === modified file 'src/core/media/player_skeleton.cpp' |
354 | --- src/core/media/player_skeleton.cpp 2014-04-28 14:20:04 +0000 |
355 | +++ src/core/media/player_skeleton.cpp 2014-04-28 14:20:05 +0000 |
356 | @@ -1,5 +1,5 @@ |
357 | /* |
358 | - * Copyright © 2013 Canonical Ltd. |
359 | + * Copyright © 2013-2014 Canonical Ltd. |
360 | * |
361 | * This program is free software: you can redistribute it and/or modify it |
362 | * under the terms of the GNU Lesser General Public License version 3, |
363 | @@ -63,7 +63,8 @@ |
364 | signals |
365 | { |
366 | object->get_signal<mpris::Player::Signals::Seeked>(), |
367 | - object->get_signal<mpris::Player::Signals::EndOfStream>() |
368 | + object->get_signal<mpris::Player::Signals::EndOfStream>(), |
369 | + object->get_signal<mpris::Player::Signals::PlaybackStatusChanged>() |
370 | } |
371 | { |
372 | } |
373 | @@ -219,6 +220,13 @@ |
374 | } |
375 | } |
376 | |
377 | + void handle_key(const core::dbus::Message::Ptr& in) |
378 | + { |
379 | + auto reply = dbus::Message::make_method_return(in); |
380 | + reply->writer() << impl->key(); |
381 | + impl->access_bus()->send(reply); |
382 | + } |
383 | + |
384 | void handle_open_uri(const core::dbus::Message::Ptr& in) |
385 | { |
386 | Track::UriType uri; |
387 | @@ -265,16 +273,20 @@ |
388 | { |
389 | typedef core::dbus::Signal<mpris::Player::Signals::Seeked, mpris::Player::Signals::Seeked::ArgumentType> DBusSeekedToSignal; |
390 | typedef core::dbus::Signal<mpris::Player::Signals::EndOfStream, mpris::Player::Signals::EndOfStream::ArgumentType> DBusEndOfStreamSignal; |
391 | + typedef core::dbus::Signal<mpris::Player::Signals::PlaybackStatusChanged, mpris::Player::Signals::PlaybackStatusChanged::ArgumentType> DBusPlaybackStatusChangedSignal; |
392 | |
393 | Signals(const std::shared_ptr<DBusSeekedToSignal>& seeked, |
394 | - const std::shared_ptr<DBusEndOfStreamSignal>& eos) |
395 | + const std::shared_ptr<DBusEndOfStreamSignal>& eos, |
396 | + const std::shared_ptr<DBusPlaybackStatusChangedSignal>& status) |
397 | : dbus |
398 | { |
399 | seeked, |
400 | - eos |
401 | + eos, |
402 | + status |
403 | }, |
404 | seeked_to(), |
405 | - end_of_stream() |
406 | + end_of_stream(), |
407 | + playback_status_changed() |
408 | { |
409 | seeked_to.connect([this](std::uint64_t value) |
410 | { |
411 | @@ -285,15 +297,22 @@ |
412 | { |
413 | dbus.end_of_stream->emit(); |
414 | }); |
415 | + |
416 | + playback_status_changed.connect([this](const media::Player::PlaybackStatus& status) |
417 | + { |
418 | + dbus.playback_status_changed->emit(status); |
419 | + }); |
420 | } |
421 | |
422 | struct DBus |
423 | { |
424 | std::shared_ptr<DBusSeekedToSignal> seeked_to; |
425 | std::shared_ptr<DBusEndOfStreamSignal> end_of_stream; |
426 | + std::shared_ptr<DBusPlaybackStatusChangedSignal> playback_status_changed; |
427 | } dbus; |
428 | core::Signal<uint64_t> seeked_to; |
429 | core::Signal<void> end_of_stream; |
430 | + core::Signal<media::Player::PlaybackStatus> playback_status_changed; |
431 | } signals; |
432 | |
433 | }; |
434 | @@ -335,6 +354,10 @@ |
435 | std::bind(&Private::handle_create_video_sink, |
436 | std::ref(d), |
437 | std::placeholders::_1)); |
438 | + d->object->install_method_handler<mpris::Player::Key>( |
439 | + std::bind(&Private::handle_key, |
440 | + std::ref(d), |
441 | + std::placeholders::_1)); |
442 | d->object->install_method_handler<mpris::Player::OpenUri>( |
443 | std::bind(&Private::handle_open_uri, |
444 | std::ref(d), |
445 | @@ -535,3 +558,8 @@ |
446 | { |
447 | return d->signals.end_of_stream; |
448 | } |
449 | + |
450 | +core::Signal<media::Player::PlaybackStatus>& media::PlayerSkeleton::playback_status_changed() |
451 | +{ |
452 | + return d->signals.playback_status_changed; |
453 | +} |
454 | |
455 | === modified file 'src/core/media/player_skeleton.h' |
456 | --- src/core/media/player_skeleton.h 2014-04-28 14:20:04 +0000 |
457 | +++ src/core/media/player_skeleton.h 2014-04-28 14:20:05 +0000 |
458 | @@ -68,6 +68,7 @@ |
459 | |
460 | virtual const core::Signal<uint64_t>& seeked_to() const; |
461 | virtual const core::Signal<void>& end_of_stream() const; |
462 | + virtual core::Signal<PlaybackStatus>& playback_status_changed(); |
463 | |
464 | protected: |
465 | PlayerSkeleton(const core::dbus::types::ObjectPath& session_path); |
466 | |
467 | === modified file 'src/core/media/player_stub.cpp' |
468 | --- src/core/media/player_stub.cpp 2014-04-28 14:20:04 +0000 |
469 | +++ src/core/media/player_stub.cpp 2014-04-28 14:20:05 +0000 |
470 | @@ -80,7 +80,8 @@ |
471 | signals |
472 | { |
473 | object->get_signal<mpris::Player::Signals::Seeked>(), |
474 | - object->get_signal<mpris::Player::Signals::EndOfStream>() |
475 | + object->get_signal<mpris::Player::Signals::EndOfStream>(), |
476 | + object->get_signal<mpris::Player::Signals::PlaybackStatusChanged>() |
477 | } |
478 | { |
479 | } |
480 | @@ -136,7 +137,7 @@ |
481 | |
482 | FrameAvailableCb frame_available_cb; |
483 | void *frame_available_context; |
484 | - |
485 | + |
486 | dbus::Bus::Ptr bus; |
487 | dbus::types::ObjectPath path; |
488 | dbus::Object::Ptr object; |
489 | @@ -168,18 +169,22 @@ |
490 | { |
491 | typedef core::dbus::Signal<mpris::Player::Signals::Seeked, mpris::Player::Signals::Seeked::ArgumentType> DBusSeekedToSignal; |
492 | typedef core::dbus::Signal<mpris::Player::Signals::EndOfStream, mpris::Player::Signals::EndOfStream::ArgumentType> DBusEndOfStreamSignal; |
493 | + typedef core::dbus::Signal<mpris::Player::Signals::PlaybackStatusChanged, mpris::Player::Signals::PlaybackStatusChanged::ArgumentType> DBusPlaybackStatusChangedSignal; |
494 | |
495 | Signals(const std::shared_ptr<DBusSeekedToSignal>& seeked, |
496 | - const std::shared_ptr<DBusEndOfStreamSignal>& eos) |
497 | + const std::shared_ptr<DBusEndOfStreamSignal>& eos, |
498 | + const std::shared_ptr<DBusPlaybackStatusChangedSignal>& status) |
499 | : dbus |
500 | { |
501 | seeked, |
502 | - eos |
503 | + eos, |
504 | + status |
505 | }, |
506 | playback_complete_cb(nullptr), |
507 | playback_complete_context(nullptr), |
508 | seeked_to(), |
509 | - end_of_stream() |
510 | + end_of_stream(), |
511 | + playback_status_changed() |
512 | { |
513 | dbus.seeked_to->connect([this](std::uint64_t value) |
514 | { |
515 | @@ -194,12 +199,19 @@ |
516 | playback_complete_cb(playback_complete_context); |
517 | end_of_stream(); |
518 | }); |
519 | + |
520 | + dbus.playback_status_changed->connect([this](const media::Player::PlaybackStatus& status) |
521 | + { |
522 | + std::cout << "PlaybackStatusChanged signal arrived via the bus." << std::endl; |
523 | + playback_status_changed(status); |
524 | + }); |
525 | } |
526 | |
527 | struct DBus |
528 | { |
529 | std::shared_ptr<DBusSeekedToSignal> seeked_to; |
530 | std::shared_ptr<DBusEndOfStreamSignal> end_of_stream; |
531 | + std::shared_ptr<DBusPlaybackStatusChangedSignal> playback_status_changed; |
532 | } dbus; |
533 | |
534 | void set_playback_complete_cb(PlaybackCompleteCb cb, void *context) |
535 | @@ -212,6 +224,7 @@ |
536 | void *playback_complete_context; |
537 | core::Signal<uint64_t> seeked_to; |
538 | core::Signal<void> end_of_stream; |
539 | + core::Signal<media::Player::PlaybackStatus> playback_status_changed; |
540 | } signals; |
541 | }; |
542 | |
543 | @@ -243,6 +256,13 @@ |
544 | return d->track_list; |
545 | } |
546 | |
547 | +media::Player::PlayerKey media::PlayerStub::key() const |
548 | +{ |
549 | + auto op = d->object->invoke_method_synchronously<mpris::Player::Key, media::Player::PlayerKey>(); |
550 | + |
551 | + return op.value(); |
552 | +} |
553 | + |
554 | bool media::PlayerStub::open_uri(const media::Track::UriType& uri) |
555 | { |
556 | auto op = d->object->invoke_method_synchronously<mpris::Player::OpenUri, bool>(uri); |
557 | @@ -437,3 +457,8 @@ |
558 | { |
559 | return d->signals.end_of_stream; |
560 | } |
561 | + |
562 | +core::Signal<media::Player::PlaybackStatus>& media::PlayerStub::playback_status_changed() |
563 | +{ |
564 | + return d->signals.playback_status_changed; |
565 | +} |
566 | |
567 | === modified file 'src/core/media/player_stub.h' |
568 | --- src/core/media/player_stub.h 2014-04-28 14:20:04 +0000 |
569 | +++ src/core/media/player_stub.h 2014-04-28 14:20:05 +0000 |
570 | @@ -43,6 +43,7 @@ |
571 | ~PlayerStub(); |
572 | |
573 | virtual std::shared_ptr<TrackList> track_list(); |
574 | + virtual PlayerKey key() const; |
575 | |
576 | virtual bool open_uri(const Track::UriType& uri); |
577 | virtual void create_video_sink(uint32_t texture_id); |
578 | @@ -82,6 +83,7 @@ |
579 | |
580 | virtual const core::Signal<uint64_t>& seeked_to() const; |
581 | virtual const core::Signal<void>& end_of_stream() const; |
582 | + virtual core::Signal<PlaybackStatus>& playback_status_changed(); |
583 | |
584 | private: |
585 | struct Private; |
586 | |
587 | === modified file 'src/core/media/service_implementation.cpp' |
588 | --- src/core/media/service_implementation.cpp 2014-01-13 21:51:14 +0000 |
589 | +++ src/core/media/service_implementation.cpp 2014-04-28 14:20:05 +0000 |
590 | @@ -21,21 +21,63 @@ |
591 | #include "player_configuration.h" |
592 | #include "player_implementation.h" |
593 | |
594 | -#include "gstreamer/engine.h" |
595 | +#include <map> |
596 | |
597 | namespace media = core::ubuntu::media; |
598 | |
599 | +using namespace std; |
600 | + |
601 | struct media::ServiceImplementation::Private |
602 | { |
603 | - Private() : engine(std::make_shared<gstreamer::Engine>()) |
604 | - { |
605 | - } |
606 | - std::shared_ptr<media::Engine> engine; |
607 | + Private() |
608 | + : key_(0) |
609 | + { |
610 | + } |
611 | + |
612 | + void track_player(const std::shared_ptr<media::Player>& player) |
613 | + { |
614 | + cout << __PRETTY_FUNCTION__ << endl; |
615 | + cout << "key: " << key_ << endl; |
616 | + player_map.insert( |
617 | + std::pair<media::Player::PlayerKey, |
618 | + std::shared_ptr<media::Player>>(key_, player)); |
619 | + |
620 | + ++key_; |
621 | + } |
622 | + |
623 | + inline media::Player::PlayerKey key() const |
624 | + { |
625 | + return key_; |
626 | + } |
627 | + |
628 | + void pause_other_sessions(media::Player::PlayerKey key) |
629 | + { |
630 | + cout << __PRETTY_FUNCTION__ << endl; |
631 | + cout << "key: " << key << endl; |
632 | + |
633 | + // TODO: Add a field to Player that is the type of player so that certain |
634 | + // types of playback aren't paused below. E.g. a camera click sound shouldn't |
635 | + // pause, nor should it pause background music sessions |
636 | + for (auto& player_pair : player_map) |
637 | + { |
638 | + if (player_pair.second->playback_status() == Player::playing |
639 | + && player_pair.first != key) |
640 | + { |
641 | + cout << "Pausing player with key: " << player_pair.first << endl; |
642 | + player_pair.second->pause(); |
643 | + } |
644 | + } |
645 | + } |
646 | + |
647 | + // Used for Player instance management |
648 | + std::map<media::Player::PlayerKey, std::shared_ptr<media::Player>> player_map; |
649 | + media::Player::PlayerKey key_; |
650 | + |
651 | }; |
652 | |
653 | media::ServiceImplementation::ServiceImplementation() : d(new Private()) |
654 | { |
655 | - |
656 | + cout << __PRETTY_FUNCTION__ << endl; |
657 | } |
658 | |
659 | media::ServiceImplementation::~ServiceImplementation() |
660 | @@ -45,8 +87,13 @@ |
661 | std::shared_ptr<media::Player> media::ServiceImplementation::create_session( |
662 | const media::Player::Configuration& conf) |
663 | { |
664 | - return std::make_shared<media::PlayerImplementation>( |
665 | - conf.object_path, |
666 | - shared_from_this(), |
667 | - d->engine); |
668 | + std::shared_ptr<media::Player> player = std::make_shared<media::PlayerImplementation>( |
669 | + conf.object_path, shared_from_this(), d->key()); |
670 | + d->track_player(player); |
671 | + return player; |
672 | +} |
673 | + |
674 | +void media::ServiceImplementation::pause_other_sessions(media::Player::PlayerKey key) |
675 | +{ |
676 | + d->pause_other_sessions(key); |
677 | } |
678 | |
679 | === modified file 'src/core/media/service_implementation.h' |
680 | --- src/core/media/service_implementation.h 2014-01-13 21:51:14 +0000 |
681 | +++ src/core/media/service_implementation.h 2014-04-28 14:20:05 +0000 |
682 | @@ -27,6 +27,9 @@ |
683 | { |
684 | namespace media |
685 | { |
686 | + |
687 | +class Player; |
688 | + |
689 | class ServiceImplementation : public ServiceSkeleton |
690 | { |
691 | public: |
692 | @@ -35,6 +38,8 @@ |
693 | |
694 | std::shared_ptr<Player> create_session(const Player::Configuration&); |
695 | |
696 | + void pause_other_sessions(Player::PlayerKey key); |
697 | + |
698 | private: |
699 | struct Private; |
700 | std::shared_ptr<Private> d; |
701 | |
702 | === modified file 'src/core/media/service_skeleton.cpp' |
703 | --- src/core/media/service_skeleton.cpp 2014-02-12 15:53:57 +0000 |
704 | +++ src/core/media/service_skeleton.cpp 2014-04-28 14:20:05 +0000 |
705 | @@ -1,5 +1,5 @@ |
706 | /* |
707 | - * Copyright © 2013 Canonical Ltd. |
708 | + * Copyright © 2013-2014 Canonical Ltd. |
709 | * |
710 | * This program is free software: you can redistribute it and/or modify it |
711 | * under the terms of the GNU Lesser General Public License version 3, |
712 | @@ -49,6 +49,11 @@ |
713 | &Private::handle_create_session, |
714 | this, |
715 | std::placeholders::_1)); |
716 | + object->install_method_handler<mpris::Service::PauseOtherSessions>( |
717 | + std::bind( |
718 | + &Private::handle_pause_other_sessions, |
719 | + this, |
720 | + std::placeholders::_1)); |
721 | } |
722 | |
723 | void handle_create_session(const core::dbus::Message::Ptr& msg) |
724 | @@ -86,6 +91,17 @@ |
725 | } |
726 | } |
727 | |
728 | + void handle_pause_other_sessions(const core::dbus::Message::Ptr& msg) |
729 | + { |
730 | + std::cout << __PRETTY_FUNCTION__ << std::endl; |
731 | + Player::PlayerKey key; |
732 | + msg->reader() >> key; |
733 | + impl->pause_other_sessions(key); |
734 | + |
735 | + auto reply = dbus::Message::make_method_return(msg); |
736 | + impl->access_bus()->send(reply); |
737 | + } |
738 | + |
739 | media::ServiceSkeleton* impl; |
740 | dbus::Object::Ptr object; |
741 | |
742 | |
743 | === modified file 'src/core/media/service_skeleton.h' |
744 | --- src/core/media/service_skeleton.h 2014-02-12 15:53:57 +0000 |
745 | +++ src/core/media/service_skeleton.h 2014-04-28 14:20:05 +0000 |
746 | @@ -1,5 +1,5 @@ |
747 | /* |
748 | - * Copyright © 2013 Canonical Ltd. |
749 | + * Copyright © 2013-2014 Canonical Ltd. |
750 | * |
751 | * This program is free software: you can redistribute it and/or modify it |
752 | * under the terms of the GNU Lesser General Public License version 3, |
753 | |
754 | === modified file 'src/core/media/service_stub.cpp' |
755 | --- src/core/media/service_stub.cpp 2014-02-12 15:53:57 +0000 |
756 | +++ src/core/media/service_stub.cpp 2014-04-28 14:20:05 +0000 |
757 | @@ -1,5 +1,5 @@ |
758 | /* |
759 | - * Copyright © 2013 Canonical Ltd. |
760 | + * Copyright © 2013-2014 Canonical Ltd. |
761 | * |
762 | * This program is free software: you can redistribute it and/or modify it |
763 | * under the terms of the GNU Lesser General Public License version 3, |
764 | @@ -47,13 +47,21 @@ |
765 | |
766 | std::shared_ptr<media::Player> media::ServiceStub::create_session(const media::Player::Configuration&) |
767 | { |
768 | - auto op |
769 | - = d->object->invoke_method_synchronously< |
770 | - mpris::Service::CreateSession, |
771 | - dbus::types::ObjectPath>(); |
772 | + auto op = d->object->invoke_method_synchronously<mpris::Service::CreateSession, |
773 | + dbus::types::ObjectPath>(); |
774 | |
775 | if (op.is_error()) |
776 | throw std::runtime_error("Problem creating session: " + op.error()); |
777 | |
778 | return std::shared_ptr<media::Player>(new media::PlayerStub(shared_from_this(), op.value())); |
779 | } |
780 | + |
781 | +void media::ServiceStub::pause_other_sessions(media::Player::PlayerKey key) |
782 | +{ |
783 | + std::cout << __PRETTY_FUNCTION__ << std::endl; |
784 | + auto op = d->object->invoke_method_synchronously<mpris::Service::PauseOtherSessions, |
785 | + void>(key); |
786 | + |
787 | + if (op.is_error()) |
788 | + throw std::runtime_error("Problem pausing other sessions: " + op.error()); |
789 | +} |
790 | |
791 | === modified file 'src/core/media/service_stub.h' |
792 | --- src/core/media/service_stub.h 2014-02-12 15:53:57 +0000 |
793 | +++ src/core/media/service_stub.h 2014-04-28 14:20:05 +0000 |
794 | @@ -1,5 +1,5 @@ |
795 | /* |
796 | - * Copyright © 2013 Canonical Ltd. |
797 | + * Copyright © 2013-2014 Canonical Ltd. |
798 | * |
799 | * This program is free software: you can redistribute it and/or modify it |
800 | * under the terms of the GNU Lesser General Public License version 3, |
801 | @@ -40,6 +40,7 @@ |
802 | ~ServiceStub(); |
803 | |
804 | std::shared_ptr<Player> create_session(const Player::Configuration&); |
805 | + void pause_other_sessions(Player::PlayerKey key); |
806 | |
807 | private: |
808 | struct Private; |
FAILED: Continuous integration, rev:60 jenkins. qa.ubuntu. com/job/ media-hub- ci/58/ jenkins. qa.ubuntu. com/job/ media-hub- trusty- amd64-ci/ 59/console jenkins. qa.ubuntu. com/job/ media-hub- trusty- armhf-ci/ 58/console jenkins. qa.ubuntu. com/job/ media-hub- trusty- i386-ci/ 58/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/media- hub-ci/ 58/rebuild
http://