Merge lp:~phablet-team/media-hub/media-hub-desktop into lp:media-hub

Proposed by Jim Hodapp
Status: Merged
Approved by: Konrad Zapałowicz
Approved revision: 210
Merged at revision: 204
Proposed branch: lp:~phablet-team/media-hub/media-hub-desktop
Merge into: lp:media-hub
Diff against target: 1013 lines (+504/-61)
27 files modified
CMakeLists.txt (+8/-2)
debian/changelog (+6/-0)
include/core/media/player.h (+16/-0)
src/core/media/CMakeLists.txt (+42/-37)
src/core/media/backend.cpp (+43/-0)
src/core/media/client_death_observer.cpp (+18/-1)
src/core/media/codec.h (+43/-0)
src/core/media/engine.h (+1/-1)
src/core/media/gstreamer/engine.cpp (+3/-3)
src/core/media/gstreamer/engine.h (+2/-2)
src/core/media/mpris/player.h (+6/-1)
src/core/media/player_implementation.cpp (+1/-0)
src/core/media/player_skeleton.cpp (+10/-0)
src/core/media/player_skeleton.h (+2/-0)
src/core/media/player_stub.cpp (+11/-1)
src/core/media/player_stub.h (+1/-0)
src/core/media/recorder_observer.cpp (+18/-1)
src/core/media/server/server.cpp (+15/-2)
src/core/media/stub_client_death_observer.cpp (+66/-0)
src/core/media/stub_client_death_observer.h (+64/-0)
src/core/media/stub_recorder_observer.cpp (+40/-0)
src/core/media/stub_recorder_observer.h (+50/-0)
src/core/media/video/hybris_gl_sink.h (+1/-1)
src/core/media/video/platform_default_sink.cpp (+18/-2)
src/core/media/video/platform_default_sink.h (+2/-1)
tests/acceptance-tests/service.cpp (+8/-0)
tests/unit-tests/test-gstreamer-engine.cpp (+9/-6)
To merge this branch: bzr merge lp:~phablet-team/media-hub/media-hub-desktop
Reviewer Review Type Date Requested Status
Alfonso Sanchez-Beato Approve
Konrad Zapałowicz (community) Approve
Review via email: mp+302712@code.launchpad.net

Commit message

Make media-hub work on the desktop. Everything except for video playback works with this commit.

Description of the change

Make media-hub work on the desktop. Everything except for video playback works with this commit.

To post a comment you must log in.
206. By Jim Hodapp

Add simple unit test that ensures the service comes up.

Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

We need to decide how to detect the platform, see comment below.

review: Needs Information
Revision history for this message
Konrad Zapałowicz (kzapalowicz) wrote :

LGTM except that I need an explanation if it is possible to cache get_backend_type()

review: Needs Information (code)
Revision history for this message
Jim Hodapp (jhodapp) wrote :

Thanks for the very timely reviews guys. See my replies inline.

Revision history for this message
Konrad Zapałowicz (kzapalowicz) wrote :

LGTM

review: Approve
207. By Jim Hodapp

Dynamically detect hybris backend instead of setting environment variable

208. By Jim Hodapp

Cleanup and make sure to unref the plugin instance

209. By Jim Hodapp

Move debug message for hybris backend detection

210. By Jim Hodapp

Expose the backend selection to the stub side

Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

LGTM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2016-07-19 21:16:56 +0000
3+++ CMakeLists.txt 2016-08-15 19:28:06 +0000
4@@ -20,7 +20,7 @@
5 # we define the version to be 5.0.0
6 if (${DISTRO_CODENAME} STREQUAL "vivid")
7 set(UBUNTU_MEDIA_HUB_VERSION_MAJOR 4)
8- set(UBUNTU_MEDIA_HUB_VERSION_MINOR 5)
9+ set(UBUNTU_MEDIA_HUB_VERSION_MINOR 6)
10 set(UBUNTU_MEDIA_HUB_VERSION_PATCH 0)
11 else ()
12 set(UBUNTU_MEDIA_HUB_VERSION_MAJOR 5)
13@@ -53,7 +53,13 @@
14 pkg_check_modules(GIO gio-2.0 REQUIRED)
15 pkg_check_modules(HYBRIS_MEDIA libmedia REQUIRED)
16
17-add_definitions(-DMEDIA_HUB_HAVE_HYBRIS_MEDIA_COMPAT_LAYER)
18+include(CheckIncludeFiles)
19+check_include_files("hybris/media/media_codec_layer.h" MEDIA_HUB_HAVE_HYBRIS_MEDIA_COMPAT_LAYER)
20+if (DEFINED MEDIA_HUB_HAVE_HYBRIS_MEDIA_COMPAT_LAYER)
21+ add_definitions(-DMEDIA_HUB_HAVE_HYBRIS_MEDIA_COMPAT_LAYER)
22+else()
23+ MESSAGE(STATUS "*libhybris not found*")
24+endif()
25
26 #####################################################################
27 # Enable code coverage calculation with gcov/gcovr/lcov
28
29=== modified file 'debian/changelog'
30--- debian/changelog 2016-07-20 21:28:28 +0000
31+++ debian/changelog 2016-08-15 19:28:06 +0000
32@@ -1,3 +1,9 @@
33+media-hub (4.6.0+16.10.20160815-0ubuntu1) yakkety; urgency=medium
34+
35+ * Make media-hub work on the desktop with Unity7/Unity8 sessions.
36+
37+ -- Jim Hodapp <jim.hodapp@canonical.com> Fri, 12 Aug 2016 15:17:28 +0000
38+
39 media-hub (4.5.0+16.10.20160720-0ubuntu1) yakkety; urgency=medium
40
41 * Emit client side signal when the dbus connection between
42
43=== modified file 'include/core/media/player.h'
44--- include/core/media/player.h 2016-06-01 00:43:04 +0000
45+++ include/core/media/player.h 2016-08-15 19:28:06 +0000
46@@ -39,6 +39,21 @@
47 class Service;
48 class TrackList;
49
50+struct AVBackend
51+{
52+ enum Backend
53+ {
54+ none,
55+ hybris
56+ };
57+
58+ /**
59+ * @brief Returns the type of audio/video decoding/encoding backend being used.
60+ * @return Returns the current backend type.
61+ */
62+ static Backend get_backend_type();
63+};
64+
65 class Player : public std::enable_shared_from_this<Player>
66 {
67 public:
68@@ -162,6 +177,7 @@
69 virtual const core::Property<bool>& is_video_source() const = 0;
70 virtual const core::Property<bool>& is_audio_source() const = 0;
71 virtual const core::Property<PlaybackStatus>& playback_status() const = 0;
72+ virtual const core::Property<AVBackend::Backend>& backend() const = 0;
73 virtual const core::Property<LoopStatus>& loop_status() const = 0;
74 virtual const core::Property<PlaybackRate>& playback_rate() const = 0;
75 virtual const core::Property<bool>& shuffle() const = 0;
76
77=== modified file 'src/core/media/CMakeLists.txt'
78--- src/core/media/CMakeLists.txt 2016-06-15 17:49:49 +0000
79+++ src/core/media/CMakeLists.txt 2016-08-15 19:28:06 +0000
80@@ -17,6 +17,7 @@
81 add_library(
82 media-hub-common SHARED
83
84+ backend.cpp
85 the_session_bus.cpp
86 util/utils.cpp
87 )
88@@ -27,6 +28,7 @@
89 ${Boost_LIBRARIES}
90 ${DBUS_LIBRARIES}
91 ${DBUS_CPP_LDFLAGS}
92+ ${PC_GSTREAMER_1_0_LIBRARIES}
93 )
94 set_target_properties(
95 media-hub-common
96@@ -89,42 +91,44 @@
97 )
98
99 add_library(
100- media-hub-service
101-
102- ${MEDIA_HUB_HEADERS}
103- ${MPRIS_HEADERS}
104-
105- logger/logger.cpp
106-
107- client_death_observer.cpp
108- hashed_keyed_player_store.cpp
109- hybris_client_death_observer.cpp
110- cover_art_resolver.cpp
111- engine.cpp
112- metadata.cpp
113-
114- apparmor/context.cpp
115- apparmor/ubuntu.cpp
116-
117- audio/pulse_audio_output_observer.cpp
118- audio/ostream_reporter.cpp
119- audio/output_observer.cpp
120-
121- power/battery_observer.cpp
122- power/state_controller.cpp
123-
124- recorder_observer.cpp
125- hybris_recorder_observer.cpp
126-
127- gstreamer/engine.cpp
128- gstreamer/playbin.cpp
129-
130- player_skeleton.cpp
131- player_implementation.cpp
132- service_skeleton.cpp
133- service_implementation.cpp
134- track_list_skeleton.cpp
135- track_list_implementation.cpp
136+ media-hub-service
137+
138+ ${MEDIA_HUB_HEADERS}
139+ ${MPRIS_HEADERS}
140+
141+ logger/logger.cpp
142+
143+ client_death_observer.cpp
144+ hashed_keyed_player_store.cpp
145+ hybris_client_death_observer.cpp
146+ stub_client_death_observer.cpp
147+ cover_art_resolver.cpp
148+ engine.cpp
149+ metadata.cpp
150+
151+ apparmor/context.cpp
152+ apparmor/ubuntu.cpp
153+
154+ audio/pulse_audio_output_observer.cpp
155+ audio/ostream_reporter.cpp
156+ audio/output_observer.cpp
157+
158+ power/battery_observer.cpp
159+ power/state_controller.cpp
160+
161+ recorder_observer.cpp
162+ hybris_recorder_observer.cpp
163+ stub_recorder_observer.cpp
164+
165+ gstreamer/engine.cpp
166+ gstreamer/playbin.cpp
167+
168+ player_skeleton.cpp
169+ player_implementation.cpp
170+ service_skeleton.cpp
171+ service_implementation.cpp
172+ track_list_skeleton.cpp
173+ track_list_implementation.cpp
174 )
175
176 target_link_libraries(
177@@ -146,11 +150,12 @@
178 ${PC_PULSE_AUDIO_LIBRARIES}
179 )
180
181-include_directories(${PROJECT_SOURCE_DIR}/src/ ${HYBRIS_MEDIA_CFLAGS})
182+include_directories(${PROJECT_SOURCE_DIR}/src/ ${HYBRIS_MEDIA_CFLAGS} ${PC_GSTREAMER_1_0_INCLUDE_DIRS})
183
184 add_executable(
185 media-hub-server
186
187+ backend.cpp
188 server/server.cpp
189 )
190
191
192=== added file 'src/core/media/backend.cpp'
193--- src/core/media/backend.cpp 1970-01-01 00:00:00 +0000
194+++ src/core/media/backend.cpp 2016-08-15 19:28:06 +0000
195@@ -0,0 +1,43 @@
196+/*
197+ * Copyright (C) 2016 Canonical Ltd
198+ *
199+ * Licensed under the Apache License, Version 2.0 (the "License");
200+ * you may not use this file except in compliance with the License.
201+ * You may obtain a copy of the License at
202+ *
203+ * http://www.apache.org/licenses/LICENSE-2.0
204+ *
205+ * Unless required by applicable law or agreed to in writing, software
206+ * distributed under the License is distributed on an "AS IS" BASIS,
207+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
208+ * See the License for the specific language governing permissions and
209+ * limitations under the License.
210+ *
211+ * Authored by: Jim Hodapp <jim.hodapp@canonical.com>
212+ */
213+
214+#include <core/media/player.h>
215+#include "core/media/logger/logger.h"
216+
217+#include <gst/gst.h>
218+
219+namespace media = core::ubuntu::media;
220+
221+media::AVBackend::Backend media::AVBackend::get_backend_type()
222+{
223+ GstRegistry *registry;
224+ GstPlugin *plugin;
225+
226+ registry = gst_registry_get();
227+ if (not registry)
228+ return media::AVBackend::Backend::none;
229+
230+ plugin = gst_registry_lookup(registry, "libgstandroidmedia.so");
231+ if (plugin)
232+ {
233+ gst_object_unref(plugin);
234+ return media::AVBackend::Backend::hybris;
235+ }
236+
237+ return media::AVBackend::Backend::none;
238+}
239
240=== modified file 'src/core/media/client_death_observer.cpp'
241--- src/core/media/client_death_observer.cpp 2014-11-26 09:18:33 +0000
242+++ src/core/media/client_death_observer.cpp 2016-08-15 19:28:06 +0000
243@@ -16,7 +16,11 @@
244 * Authored by: Thomas Voß <thomas.voss@canonical.com>
245 */
246
247+#include "core/media/logger/logger.h"
248+
249 #include <core/media/client_death_observer.h>
250+#include <core/media/hybris_client_death_observer.h>
251+#include <core/media/stub_client_death_observer.h>
252
253 namespace media = core::ubuntu::media;
254
255@@ -26,7 +30,20 @@
256 // Accesses the default client death observer implementation for the platform.
257 media::ClientDeathObserver::Ptr media::platform_default_client_death_observer()
258 {
259- return media::HybrisClientDeathObserver::create();
260+ const media::AVBackend::Backend b {media::AVBackend::get_backend_type()};
261+ switch (b)
262+ {
263+ case media::AVBackend::Backend::hybris:
264+ return media::HybrisClientDeathObserver::create();
265+ case media::AVBackend::Backend::none:
266+ MH_WARNING(
267+ "No video backend selected. Client disconnect functionality won't work."
268+ );
269+ return media::StubClientDeathObserver::create();
270+ default:
271+ MH_INFO("Invalid or no A/V backend specified, using \"hybris\" as a default.");
272+ return media::HybrisClientDeathObserver::create();
273+ }
274 }
275 #else // MEDIA_HUB_HAVE_HYBRIS_MEDIA_COMPAT_LAYER
276 // Just throws a std::logic_error as we have not yet defined a default way to
277
278=== modified file 'src/core/media/codec.h'
279--- src/core/media/codec.h 2016-06-14 19:41:18 +0000
280+++ src/core/media/codec.h 2016-08-15 19:28:06 +0000
281@@ -192,6 +192,49 @@
282 in = static_cast<core::ubuntu::media::Player::PlaybackStatus>(out.pop_int16());
283 }
284 };
285+
286+namespace helper
287+{
288+template<>
289+struct TypeMapper<core::ubuntu::media::AVBackend::Backend>
290+{
291+ constexpr static ArgumentType type_value()
292+ {
293+ return core::dbus::ArgumentType::int16;
294+ }
295+ constexpr static bool is_basic_type()
296+ {
297+ return false;
298+ }
299+ constexpr static bool requires_signature()
300+ {
301+ return false;
302+ }
303+
304+ static std::string signature()
305+ {
306+ static const std::string s = TypeMapper<std::int16_t>::signature();
307+ return s;
308+ }
309+};
310+}
311+
312+template<>
313+struct Codec<core::ubuntu::media::AVBackend::Backend>
314+{
315+ static void encode_argument(core::dbus::Message::Writer& out,
316+ const core::ubuntu::media::AVBackend::Backend& in)
317+ {
318+ out.push_int16(static_cast<std::int16_t>(in));
319+ }
320+
321+ static void decode_argument(core::dbus::Message::Reader& out,
322+ core::ubuntu::media::AVBackend::Backend& in)
323+ {
324+ in = static_cast<core::ubuntu::media::AVBackend::Backend>(out.pop_int16());
325+ }
326+};
327+
328 namespace helper
329 {
330 template<>
331
332=== modified file 'src/core/media/engine.h'
333--- src/core/media/engine.h 2016-07-11 01:21:38 +0000
334+++ src/core/media/engine.h 2016-08-15 19:28:06 +0000
335@@ -82,7 +82,7 @@
336 // support this feature.
337 virtual void create_video_sink(uint32_t texture_id) = 0;
338
339- virtual bool play() = 0;
340+ virtual bool play(bool use_main_context = false) = 0;
341 virtual bool stop(bool use_main_context = false) = 0;
342 virtual bool pause() = 0;
343 virtual bool seek_to(const std::chrono::microseconds& ts) = 0;
344
345=== modified file 'src/core/media/gstreamer/engine.cpp'
346--- src/core/media/gstreamer/engine.cpp 2016-07-11 01:21:38 +0000
347+++ src/core/media/gstreamer/engine.cpp 2016-08-15 19:28:06 +0000
348@@ -445,9 +445,9 @@
349 d->playbin.create_video_sink(texture_id);
350 }
351
352-bool gstreamer::Engine::play()
353+bool gstreamer::Engine::play(bool use_main_thread /* = false */)
354 {
355- const auto result = d->playbin.set_state_and_wait(GST_STATE_PLAYING);
356+ const auto result = d->playbin.set_state_and_wait(GST_STATE_PLAYING, use_main_thread);
357
358 if (result)
359 {
360@@ -459,7 +459,7 @@
361 return result;
362 }
363
364-bool gstreamer::Engine::stop(bool use_main_thread)
365+bool gstreamer::Engine::stop(bool use_main_thread /* = false */)
366 {
367 // No need to wait, and we can immediately return.
368 if (d->state == media::Engine::State::stopped)
369
370=== modified file 'src/core/media/gstreamer/engine.h'
371--- src/core/media/gstreamer/engine.h 2016-07-11 01:21:38 +0000
372+++ src/core/media/gstreamer/engine.h 2016-08-15 19:28:06 +0000
373@@ -37,8 +37,8 @@
374 bool open_resource_for_uri(const core::ubuntu::media::Track::UriType& uri, const core::ubuntu::media::Player::HeadersType& headers);
375 void create_video_sink(uint32_t texture_id);
376
377- bool play();
378- // use_main_thread will set the pipeline's new_state in the main thread context
379+ // use_main_thread will set the pipeline's new state in the main thread context
380+ bool play(bool use_main_thread = false);
381 bool stop(bool use_main_thread = false);
382 bool pause();
383 bool seek_to(const std::chrono::microseconds& ts);
384
385=== modified file 'src/core/media/mpris/player.h'
386--- src/core/media/mpris/player.h 2016-06-16 02:34:40 +0000
387+++ src/core/media/mpris/player.h 2016-08-15 19:28:06 +0000
388@@ -166,7 +166,7 @@
389 {
390 DBUS_CPP_READABLE_PROPERTY_DEF(PlaybackStatus, Player, std::string)
391 DBUS_CPP_READABLE_PROPERTY_DEF(TypedPlaybackStatus, Player, core::ubuntu::media::Player::PlaybackStatus)
392-
393+ DBUS_CPP_WRITABLE_PROPERTY_DEF(TypedBackend, Player, core::ubuntu::media::AVBackend::Backend)
394 DBUS_CPP_WRITABLE_PROPERTY_DEF(LoopStatus, Player, std::string)
395 DBUS_CPP_WRITABLE_PROPERTY_DEF(TypedLoopStatus, Player, core::ubuntu::media::Player::LoopStatus)
396 DBUS_CPP_WRITABLE_PROPERTY_DEF(AudioStreamRole, Player, core::ubuntu::media::Player::AudioStreamRole)
397@@ -220,6 +220,7 @@
398 Properties::IsAudioSource::ValueType is_audio_source{true};
399 Properties::PlaybackStatus::ValueType playback_status{PlaybackStatus::stopped};
400 Properties::TypedPlaybackStatus::ValueType typed_playback_status{core::ubuntu::media::Player::PlaybackStatus::null};
401+ Properties::TypedBackend::ValueType typed_backend{core::ubuntu::media::AVBackend::Backend::none};
402 Properties::LoopStatus::ValueType loop_status{LoopStatus::none};
403 Properties::TypedLoopStatus::ValueType typed_loop_status{core::ubuntu::media::Player::LoopStatus::none};
404 Properties::PlaybackRate::ValueType playback_rate{1.f};
405@@ -248,6 +249,7 @@
406 configuration.object->template get_property<Properties::IsAudioSource>(),
407 configuration.object->template get_property<Properties::PlaybackStatus>(),
408 configuration.object->template get_property<Properties::TypedPlaybackStatus>(),
409+ configuration.object->template get_property<Properties::TypedBackend>(),
410 configuration.object->template get_property<Properties::LoopStatus>(),
411 configuration.object->template get_property<Properties::TypedLoopStatus>(),
412 configuration.object->template get_property<Properties::AudioStreamRole>(),
413@@ -284,6 +286,7 @@
414 properties.is_audio_source->set(configuration.defaults.is_audio_source);
415 properties.playback_status->set(configuration.defaults.playback_status);
416 properties.typed_playback_status->set(configuration.defaults.typed_playback_status);
417+ properties.typed_backend->set(configuration.defaults.typed_backend);
418 properties.loop_status->set(configuration.defaults.loop_status);
419 properties.typed_loop_status->set(configuration.defaults.typed_loop_status);
420 properties.audio_stream_role->set(core::ubuntu::media::Player::AudioStreamRole::multimedia);
421@@ -371,6 +374,7 @@
422 dict[Properties::CanGoPrevious::name()] = dbus::types::Variant::encode(properties.can_go_previous->get());
423 dict[Properties::PlaybackStatus::name()] = dbus::types::Variant::encode(properties.playback_status->get());
424 dict[Properties::TypedPlaybackStatus::name()] = dbus::types::Variant::encode(properties.typed_playback_status->get());
425+ dict[Properties::TypedBackend::name()] = dbus::types::Variant::encode(properties.typed_backend->get());
426 dict[Properties::LoopStatus::name()] = dbus::types::Variant::encode(properties.loop_status->get());
427 dict[Properties::TypedLoopStatus::name()] = dbus::types::Variant::encode(properties.typed_loop_status->get());
428 dict[Properties::AudioStreamRole::name()] = dbus::types::Variant::encode(properties.audio_stream_role->get());
429@@ -403,6 +407,7 @@
430
431 std::shared_ptr<core::dbus::Property<Properties::PlaybackStatus>> playback_status;
432 std::shared_ptr<core::dbus::Property<Properties::TypedPlaybackStatus>> typed_playback_status;
433+ std::shared_ptr<core::dbus::Property<Properties::TypedBackend>> typed_backend;
434 std::shared_ptr<core::dbus::Property<Properties::LoopStatus>> loop_status;
435 std::shared_ptr<core::dbus::Property<Properties::TypedLoopStatus>> typed_loop_status;
436 std::shared_ptr<core::dbus::Property<Properties::AudioStreamRole>> audio_stream_role;
437
438=== modified file 'src/core/media/player_implementation.cpp'
439--- src/core/media/player_implementation.cpp 2016-07-11 01:21:38 +0000
440+++ src/core/media/player_implementation.cpp 2016-08-15 19:28:06 +0000
441@@ -505,6 +505,7 @@
442 Parent::shuffle().set(false);
443 Parent::playback_rate().set(1.f);
444 Parent::playback_status().set(Player::PlaybackStatus::null);
445+ Parent::backend().set(media::AVBackend::get_backend_type());
446 Parent::loop_status().set(Player::LoopStatus::none);
447 Parent::position().set(0);
448 Parent::duration().set(0);
449
450=== modified file 'src/core/media/player_skeleton.cpp'
451--- src/core/media/player_skeleton.cpp 2016-06-16 02:34:40 +0000
452+++ src/core/media/player_skeleton.cpp 2016-08-15 19:28:06 +0000
453@@ -471,6 +471,11 @@
454 return *d->skeleton.properties.typed_playback_status;
455 }
456
457+const core::Property<media::AVBackend::Backend>& media::PlayerSkeleton::backend() const
458+{
459+ return *d->skeleton.properties.typed_backend;
460+}
461+
462 const core::Property<media::Player::LoopStatus>& media::PlayerSkeleton::loop_status() const
463 {
464 return *d->skeleton.properties.typed_loop_status;
465@@ -581,6 +586,11 @@
466 return *d->skeleton.properties.typed_playback_status;
467 }
468
469+core::Property<media::AVBackend::Backend>& media::PlayerSkeleton::backend()
470+{
471+ return *d->skeleton.properties.typed_backend;
472+}
473+
474 core::Property<bool>& media::PlayerSkeleton::can_play()
475 {
476 return *d->skeleton.properties.can_play;
477
478=== modified file 'src/core/media/player_skeleton.h'
479--- src/core/media/player_skeleton.h 2016-06-01 00:43:04 +0000
480+++ src/core/media/player_skeleton.h 2016-08-15 19:28:06 +0000
481@@ -75,6 +75,7 @@
482 virtual const core::Property<bool>& is_video_source() const;
483 virtual const core::Property<bool>& is_audio_source() const;
484 virtual const core::Property<PlaybackStatus>& playback_status() const;
485+ virtual const core::Property<AVBackend::Backend>& backend() const;
486 virtual const core::Property<LoopStatus>& loop_status() const;
487 virtual const core::Property<PlaybackRate>& playback_rate() const;
488 virtual const core::Property<bool>& shuffle() const;
489@@ -105,6 +106,7 @@
490 // These properties are not exposed to the client, but still need to be
491 // able to be settable from within the Player:
492 virtual core::Property<PlaybackStatus>& playback_status();
493+ virtual core::Property<AVBackend::Backend>& backend();
494 virtual core::Property<bool>& can_play();
495 virtual core::Property<bool>& can_pause();
496 virtual core::Property<bool>& can_seek();
497
498=== modified file 'src/core/media/player_stub.cpp'
499--- src/core/media/player_stub.cpp 2016-07-19 21:22:18 +0000
500+++ src/core/media/player_stub.cpp 2016-08-15 19:28:06 +0000
501@@ -54,7 +54,6 @@
502 object(object),
503 key(object->invoke_method_synchronously<mpris::Player::Key, media::Player::PlayerKey>().value()),
504 uuid(uuid),
505- sink_factory(media::video::make_platform_default_sink_factory(key)),
506 properties
507 {
508 // Link the properties from the server side to the client side over the bus
509@@ -67,6 +66,7 @@
510 object->get_property<mpris::Player::Properties::IsVideoSource>(),
511 object->get_property<mpris::Player::Properties::IsAudioSource>(),
512 object->get_property<mpris::Player::Properties::TypedPlaybackStatus>(),
513+ object->get_property<mpris::Player::Properties::TypedBackend>(),
514 object->get_property<mpris::Player::Properties::TypedLoopStatus>(),
515 object->get_property<mpris::Player::Properties::PlaybackRate>(),
516 object->get_property<mpris::Player::Properties::Shuffle>(),
517@@ -91,6 +91,8 @@
518 object->get_signal<mpris::Player::Signals::Error>()
519 }
520 {
521+ sink_factory = media::video::make_platform_default_sink_factory(key,
522+ properties.backend->get());
523 }
524
525 ~Private()
526@@ -116,6 +118,7 @@
527 std::shared_ptr<core::dbus::Property<mpris::Player::Properties::IsAudioSource>> is_audio_source;
528
529 std::shared_ptr<core::dbus::Property<mpris::Player::Properties::TypedPlaybackStatus>> playback_status;
530+ std::shared_ptr<core::dbus::Property<mpris::Player::Properties::TypedBackend>> backend;
531 std::shared_ptr<core::dbus::Property<mpris::Player::Properties::TypedLoopStatus>> loop_status;
532 std::shared_ptr<core::dbus::Property<mpris::Player::Properties::PlaybackRate>> playback_rate;
533 std::shared_ptr<core::dbus::Property<mpris::Player::Properties::Shuffle>> shuffle;
534@@ -237,10 +240,12 @@
535 const std::string& uuid)
536 : d(new Private{parent, service, object, uuid})
537 {
538+ MH_TRACE("");
539 }
540
541 media::PlayerStub::~PlayerStub()
542 {
543+ MH_TRACE("");
544 }
545
546 std::string media::PlayerStub::uuid() const
547@@ -412,6 +417,11 @@
548 return *d->properties.playback_status;
549 }
550
551+const core::Property<media::AVBackend::Backend>& media::PlayerStub::backend() const
552+{
553+ return *d->properties.backend;
554+}
555+
556 const core::Property<media::Player::LoopStatus>& media::PlayerStub::loop_status() const
557 {
558 return *d->properties.loop_status;
559
560=== modified file 'src/core/media/player_stub.h'
561--- src/core/media/player_stub.h 2016-06-01 00:43:04 +0000
562+++ src/core/media/player_stub.h 2016-08-15 19:28:06 +0000
563@@ -71,6 +71,7 @@
564 virtual const core::Property<bool>& is_video_source() const;
565 virtual const core::Property<bool>& is_audio_source() const;
566 virtual const core::Property<PlaybackStatus>& playback_status() const;
567+ virtual const core::Property<AVBackend::Backend>& backend() const;
568 virtual const core::Property<LoopStatus>& loop_status() const;
569 virtual const core::Property<PlaybackRate>& playback_rate() const;
570 virtual const core::Property<bool>& shuffle() const;
571
572=== modified file 'src/core/media/recorder_observer.cpp'
573--- src/core/media/recorder_observer.cpp 2014-11-26 09:36:44 +0000
574+++ src/core/media/recorder_observer.cpp 2016-08-15 19:28:06 +0000
575@@ -16,13 +16,30 @@
576 * Authored by: Thomas Voß <thomas.voss@canonical.com>
577 */
578
579+#include "core/media/logger/logger.h"
580+
581+#include <core/media/player.h>
582 #include <core/media/recorder_observer.h>
583
584 #include <core/media/hybris_recorder_observer.h>
585+#include <core/media/stub_recorder_observer.h>
586
587 namespace media = core::ubuntu::media;
588
589 media::RecorderObserver::Ptr media::make_platform_default_recorder_observer()
590 {
591- return media::HybrisRecorderObserver::create();
592+ const media::AVBackend::Backend b {media::AVBackend::get_backend_type()};
593+ switch (b)
594+ {
595+ case media::AVBackend::Backend::hybris:
596+ return media::HybrisRecorderObserver::create();
597+ case media::AVBackend::Backend::none:
598+ MH_WARNING(
599+ "No video backend selected. Video recording functionality won't work."
600+ );
601+ return media::StubRecorderObserver::create();
602+ default:
603+ MH_INFO("Invalid or no A/V backend specified, using \"hybris\" as a default.");
604+ return media::HybrisRecorderObserver::create();
605+ }
606 }
607
608=== modified file 'src/core/media/server/server.cpp'
609--- src/core/media/server/server.cpp 2016-04-05 19:34:22 +0000
610+++ src/core/media/server/server.cpp 2016-08-15 19:28:06 +0000
611@@ -58,7 +58,7 @@
612 severity = media::Logger::Severity::kFatal;
613 else
614 std::cerr << "Invalid log level \"" << level
615- << "\", setting to info. Valid options: [trace, debug, info, warning, error, fatal]. "
616+ << "\", setting to info. Valid options: [trace, debug, info, warning, error, fatal]."
617 << std::endl;
618 }
619 else
620@@ -71,7 +71,20 @@
621 // All platform-specific initialization routines go here.
622 void platform_init()
623 {
624- decoding_service_init();
625+ const media::AVBackend::Backend b {media::AVBackend::get_backend_type()};
626+ switch (b)
627+ {
628+ case media::AVBackend::Backend::hybris:
629+ MH_DEBUG("Found hybris backend");
630+ decoding_service_init();
631+ break;
632+ case media::AVBackend::Backend::none:
633+ MH_WARNING("No video backend selected. Video functionality won't work.");
634+ break;
635+ default:
636+ MH_INFO("Invalid or no A/V backend specified, using \"hybris\" as a default.");
637+ decoding_service_init();
638+ }
639 }
640 }
641 #else // MEDIA_HUB_HAVE_HYBRIS_MEDIA_COMPAT_LAYER
642
643=== added file 'src/core/media/stub_client_death_observer.cpp'
644--- src/core/media/stub_client_death_observer.cpp 1970-01-01 00:00:00 +0000
645+++ src/core/media/stub_client_death_observer.cpp 2016-08-15 19:28:06 +0000
646@@ -0,0 +1,66 @@
647+/*
648+ * Copyright © 2016 Canonical Ltd.
649+ *
650+ * This program is free software: you can redistribute it and/or modify it
651+ * under the terms of the GNU Lesser General Public License version 3,
652+ * as published by the Free Software Foundation.
653+ *
654+ * This program is distributed in the hope that it will be useful,
655+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
656+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
657+ * GNU Lesser General Public License for more details.
658+ *
659+ * You should have received a copy of the GNU Lesser General Public License
660+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
661+ *
662+ * Authored by: Jim Hodapp <jim.hodapp@canonical.com>
663+ */
664+
665+#include <core/media/stub_client_death_observer.h>
666+
667+namespace media = core::ubuntu::media;
668+
669+namespace
670+{
671+typedef std::pair<media::Player::PlayerKey, std::weak_ptr<media::StubClientDeathObserver>> Holder;
672+}
673+
674+void media::StubClientDeathObserver::on_client_died_cb(void* context)
675+{
676+ auto holder = static_cast<Holder*>(context);
677+
678+ if (not holder)
679+ return;
680+
681+ // We check if we are still alive or if we already got killed.
682+ if (auto sp = holder->second.lock())
683+ {
684+ sp->client_with_key_died(holder->first);
685+ }
686+
687+ // And with that, we have reached end of life for our holder object.
688+ delete holder;
689+}
690+
691+// Creates an instance of the StubClientDeathObserver.
692+media::ClientDeathObserver::Ptr media::StubClientDeathObserver::create()
693+{
694+ return media::ClientDeathObserver::Ptr{new media::StubClientDeathObserver{}};
695+}
696+
697+media::StubClientDeathObserver::StubClientDeathObserver()
698+{
699+}
700+
701+media::StubClientDeathObserver::~StubClientDeathObserver()
702+{
703+}
704+
705+void media::StubClientDeathObserver::register_for_death_notifications_with_key(const media::Player::PlayerKey&)
706+{
707+}
708+
709+const core::Signal<media::Player::PlayerKey>& media::StubClientDeathObserver::on_client_with_key_died() const
710+{
711+ return client_with_key_died;
712+}
713
714=== added file 'src/core/media/stub_client_death_observer.h'
715--- src/core/media/stub_client_death_observer.h 1970-01-01 00:00:00 +0000
716+++ src/core/media/stub_client_death_observer.h 2016-08-15 19:28:06 +0000
717@@ -0,0 +1,64 @@
718+/*
719+ * Copyright © 2016 Canonical Ltd.
720+ *
721+ * This program is free software: you can redistribute it and/or modify it
722+ * under the terms of the GNU Lesser General Public License version 3,
723+ * as published by the Free Software Foundation.
724+ *
725+ * This program is distributed in the hope that it will be useful,
726+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
727+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
728+ * GNU Lesser General Public License for more details.
729+ *
730+ * You should have received a copy of the GNU Lesser General Public License
731+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
732+ *
733+ * Authored by: Jim Hodapp <jim.hodapp@canonical.com>
734+ */
735+
736+#ifndef CORE_UBUNTU_MEDIA_STUB_CLIENT_DEATH_OBSERVER_H_
737+#define CORE_UBUNTU_MEDIA_STUB_CLIENT_DEATH_OBSERVER_H_
738+
739+#include <core/media/client_death_observer.h>
740+
741+namespace core
742+{
743+namespace ubuntu
744+{
745+namespace media
746+{
747+// Models functionality to be notified whenever a client
748+// of the service goes away, and thus allows us to clean
749+// up in that case.
750+// Generic empty implementation.
751+class StubClientDeathObserver : public ClientDeathObserver,
752+ public std::enable_shared_from_this<StubClientDeathObserver>
753+{
754+public:
755+ // Our static callback that we inject to the hybris world.
756+ static void on_client_died_cb(void* context);
757+
758+ // Creates an instance of the StubClientDeathObserver or throws
759+ // if the underlying platform does not support it.
760+ static ClientDeathObserver::Ptr create();
761+
762+ // Make std::unique_ptr happy for forward declared Private internals.
763+ ~StubClientDeathObserver();
764+
765+ // Registers the client with the given key for death notifications.
766+ void register_for_death_notifications_with_key(const Player::PlayerKey&) override;
767+
768+ // Emitted whenever a client dies, reporting the key under which the
769+ // respective client was known.
770+ const core::Signal<Player::PlayerKey>& on_client_with_key_died() const override;
771+
772+private:
773+ StubClientDeathObserver();
774+
775+ core::Signal<media::Player::PlayerKey> client_with_key_died;
776+};
777+}
778+}
779+}
780+
781+#endif // CORE_UBUNTU_MEDIA_STUB_CLIENT_DEATH_OBSERVER_H_
782
783=== added file 'src/core/media/stub_recorder_observer.cpp'
784--- src/core/media/stub_recorder_observer.cpp 1970-01-01 00:00:00 +0000
785+++ src/core/media/stub_recorder_observer.cpp 2016-08-15 19:28:06 +0000
786@@ -0,0 +1,40 @@
787+/*
788+ * Copyright © 2016 Canonical Ltd.
789+ *
790+ * This program is free software: you can redistribute it and/or modify it
791+ * under the terms of the GNU Lesser General Public License version 3,
792+ * as published by the Free Software Foundation.
793+ *
794+ * This program is distributed in the hope that it will be useful,
795+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
796+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
797+ * GNU Lesser General Public License for more details.
798+ *
799+ * You should have received a copy of the GNU Lesser General Public License
800+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
801+ *
802+ * Authored by: Jim Hodapp <jim.hodapp@canonical.com>
803+ */
804+
805+#include <core/media/stub_recorder_observer.h>
806+
807+namespace media = core::ubuntu::media;
808+
809+media::StubRecorderObserver::StubRecorderObserver()
810+ : current_recording_state(media::RecordingState::stopped)
811+{
812+}
813+
814+media::StubRecorderObserver::~StubRecorderObserver()
815+{
816+}
817+
818+const core::Property<media::RecordingState>& media::StubRecorderObserver::recording_state() const
819+{
820+ return current_recording_state;
821+}
822+
823+media::RecorderObserver::Ptr media::StubRecorderObserver::create()
824+{
825+ return media::RecorderObserver::Ptr{new media::StubRecorderObserver{}};
826+}
827
828=== added file 'src/core/media/stub_recorder_observer.h'
829--- src/core/media/stub_recorder_observer.h 1970-01-01 00:00:00 +0000
830+++ src/core/media/stub_recorder_observer.h 2016-08-15 19:28:06 +0000
831@@ -0,0 +1,50 @@
832+/*
833+ * Copyright © 2016 Canonical Ltd.
834+ *
835+ * This program is free software: you can redistribute it and/or modify it
836+ * under the terms of the GNU Lesser General Public License version 3,
837+ * as published by the Free Software Foundation.
838+ *
839+ * This program is distributed in the hope that it will be useful,
840+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
841+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
842+ * GNU Lesser General Public License for more details.
843+ *
844+ * You should have received a copy of the GNU Lesser General Public License
845+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
846+ *
847+ * Authored by: Jim Hodapp <jim.hodapp@canonical.com>
848+ */
849+
850+#ifndef CORE_UBUNTU_MEDIA_STUB_RECORDER_OBSERVER_H_
851+#define CORE_UBUNTU_MEDIA_STUB_RECORDER_OBSERVER_H_
852+
853+#include <core/media/recorder_observer.h>
854+
855+namespace core
856+{
857+namespace ubuntu
858+{
859+namespace media
860+{
861+class StubRecorderObserver : public RecorderObserver
862+{
863+public:
864+ // Creates a new instance of the StubRecorderObserver
865+ static RecorderObserver::Ptr create();
866+
867+ ~StubRecorderObserver();
868+
869+ // Getable/observable property describing the recording state of the system.
870+ const core::Property<RecordingState>& recording_state() const override;
871+
872+private:
873+ StubRecorderObserver();
874+
875+ core::Property<media::RecordingState> current_recording_state;
876+};
877+}
878+}
879+}
880+
881+#endif // CORE_UBUNTU_MEDIA_STUB_RECORDER_OBSERVER_H_
882
883=== modified file 'src/core/media/video/hybris_gl_sink.h'
884--- src/core/media/video/hybris_gl_sink.h 2015-01-29 12:12:43 +0000
885+++ src/core/media/video/hybris_gl_sink.h 2016-08-15 19:28:06 +0000
886@@ -34,7 +34,7 @@
887 {
888 class HybrisGlSink : public video::Sink
889 {
890-public:
891+public:
892 // Returns a factory functor that allows for creating actual sink instances.
893 static std::function<video::Sink::Ptr(std::uint32_t)> factory_for_key(const media::Player::PlayerKey&);
894
895
896=== modified file 'src/core/media/video/platform_default_sink.cpp'
897--- src/core/media/video/platform_default_sink.cpp 2016-04-05 14:40:47 +0000
898+++ src/core/media/video/platform_default_sink.cpp 2016-08-15 19:28:06 +0000
899@@ -16,6 +16,8 @@
900 * Authored by: Thomas Voß <thomas.voss@canonical.com>
901 */
902
903+#include "core/media/logger/logger.h"
904+
905 #include <core/media/video/platform_default_sink.h>
906
907 namespace media = core::ubuntu::media;
908@@ -56,9 +58,23 @@
909 #if defined(MEDIA_HUB_HAVE_HYBRIS_MEDIA_COMPAT_LAYER)
910 #include <core/media/video/hybris_gl_sink.h>
911
912-video::SinkFactory video::make_platform_default_sink_factory(const media::Player::PlayerKey& key)
913+video::SinkFactory video::make_platform_default_sink_factory(const media::Player::PlayerKey& key,
914+ const media::AVBackend::Backend b)
915 {
916- return video::HybrisGlSink::factory_for_key(key);
917+ switch (b)
918+ {
919+ case media::AVBackend::Backend::hybris:
920+ MH_DEBUG("Using hybris video sink");
921+ return video::HybrisGlSink::factory_for_key(key);
922+ case media::AVBackend::Backend::none:
923+ MH_WARNING(
924+ "No video backend selected. Video rendering functionality won't work."
925+ );
926+ return [](std::uint32_t) { return video::Sink::Ptr{}; };
927+ default:
928+ MH_INFO("Invalid or no A/V backend specified, using \"hybris\" as a default.");
929+ return video::HybrisGlSink::factory_for_key(key);
930+ }
931 }
932 #else // MEDIA_HUB_HAVE_HYBRIS_MEDIA_COMPAT_LAYER
933 video::SinkFactory video::make_platform_default_sink_factory(const media::Player::PlayerKey&)
934
935=== modified file 'src/core/media/video/platform_default_sink.h'
936--- src/core/media/video/platform_default_sink.h 2015-01-29 12:12:43 +0000
937+++ src/core/media/video/platform_default_sink.h 2016-08-15 19:28:06 +0000
938@@ -35,7 +35,8 @@
939 // A functor that allows for creating actual sinks given a texture id.
940 typedef std::function<Sink::Ptr(std::uint32_t)> SinkFactory;
941 // Returns the platform default sink factory for the player instance identified by the given key.
942-SinkFactory make_platform_default_sink_factory(const Player::PlayerKey& key);
943+SinkFactory make_platform_default_sink_factory(const Player::PlayerKey& key,
944+ const AVBackend::Backend b);
945 }
946 }
947 }
948
949=== modified file 'tests/acceptance-tests/service.cpp'
950--- tests/acceptance-tests/service.cpp 2015-11-02 21:14:29 +0000
951+++ tests/acceptance-tests/service.cpp 2016-08-15 19:28:06 +0000
952@@ -68,6 +68,14 @@
953 }
954 }
955
956+TEST(MediaService, service_is_running)
957+{
958+ auto service = media::Service::Client::instance();
959+ auto session = service->create_session(media::Player::Client::default_configuration());
960+ EXPECT_TRUE(service != nullptr);
961+ EXPECT_TRUE(session != nullptr);
962+}
963+
964 TEST(MediaService, move_track_in_tracklist_works)
965 {
966 auto service = media::Service::Client::instance();
967
968=== modified file 'tests/unit-tests/test-gstreamer-engine.cpp'
969--- tests/unit-tests/test-gstreamer-engine.cpp 2016-06-30 23:23:50 +0000
970+++ tests/unit-tests/test-gstreamer-engine.cpp 2016-08-15 19:28:06 +0000
971@@ -103,9 +103,10 @@
972 std::ref(wst),
973 std::placeholders::_1));
974
975- static const bool do_pipeline_reset = true;
976+ static const bool do_pipeline_reset = false;
977 EXPECT_TRUE(engine.open_resource_for_uri(test_file_uri, do_pipeline_reset));
978- EXPECT_TRUE(engine.play());
979+ static const bool use_main_context = true;
980+ EXPECT_TRUE(engine.play(use_main_context));
981 EXPECT_TRUE(wst.wait_for_state_for(
982 core::ubuntu::media::Engine::State::playing,
983 std::chrono::seconds{4}));
984@@ -145,15 +146,16 @@
985 std::ref(wst),
986 std::placeholders::_1));
987
988- static const bool do_pipeline_reset = true;
989+ static const bool do_pipeline_reset = false;
990 EXPECT_TRUE(engine.open_resource_for_uri(test_file_uri, do_pipeline_reset));
991- EXPECT_TRUE(engine.play());
992+ static const bool use_main_context = true;
993+ EXPECT_TRUE(engine.play(use_main_context));
994 EXPECT_TRUE(wst.wait_for_state_for(
995 core::ubuntu::media::Engine::State::playing,
996 std::chrono::milliseconds{4000}));
997
998 EXPECT_TRUE(wst.wait_for_state_for(
999- core::ubuntu::media::Engine::State::ready,
1000+ core::ubuntu::media::Engine::State::stopped,
1001 std::chrono::seconds{10}));
1002 }
1003
1004@@ -207,7 +209,8 @@
1005 std::placeholders::_1));
1006
1007 EXPECT_TRUE(engine.open_resource_for_uri(test_audio_uri, headers));
1008- EXPECT_TRUE(engine.play());
1009+ static const bool use_main_context = true;
1010+ EXPECT_TRUE(engine.play(use_main_context));
1011 EXPECT_TRUE(wst.wait_for_state_for(
1012 core::ubuntu::media::Engine::State::playing,
1013 std::chrono::seconds{10}));

Subscribers

People subscribed via source and target branches

to all changes: