Merge lp:~jhodapp/media-hub/orientation into lp:media-hub

Proposed by Jim Hodapp on 2014-10-14
Status: Approved
Approved by: Ricardo Salveti on 2014-10-16
Approved revision: 71
Proposed branch: lp:~jhodapp/media-hub/orientation
Merge into: lp:media-hub
Diff against target: 882 lines (+290/-22)
14 files modified
include/core/media/player.h (+14/-0)
src/core/media/codec.h (+40/-0)
src/core/media/engine.h (+3/-0)
src/core/media/gstreamer/bus.h (+1/-1)
src/core/media/gstreamer/engine.cpp (+41/-1)
src/core/media/gstreamer/engine.h (+3/-0)
src/core/media/gstreamer/meta_data_extractor.h (+1/-1)
src/core/media/gstreamer/playbin.h (+79/-5)
src/core/media/mpris/player.h (+17/-2)
src/core/media/player_implementation.cpp (+17/-1)
src/core/media/player_skeleton.cpp (+35/-7)
src/core/media/player_skeleton.h (+6/-0)
src/core/media/player_stub.cpp (+30/-4)
src/core/media/player_stub.h (+3/-0)
To merge this branch: bzr merge lp:~jhodapp/media-hub/orientation
Reviewer Review Type Date Requested Status
Ricardo Salveti (community) 2014-10-14 Approve on 2014-10-16
PS Jenkins bot continuous-integration Approve on 2014-10-15
Review via email: mp+238355@code.launchpad.net

Commit message

* Add an Orientation property which will indicate how the video should be rotated for playback vs how it was recorded.
* Get the video frame height/width from mirsink and pass it to the media-hub client via a Signal.

Description of the change

* Add an Orientation property which will indicate how the video should be rotated for playback vs how it was recorded.
* Get the video frame height/width from mirsink and pass it to the media-hub client via a Signal.

To post a comment you must log in.
lp:~jhodapp/media-hub/orientation updated on 2014-10-15
71. By Jim Hodapp on 2014-10-15

Merged with trunk

Ricardo Salveti (rsalveti) wrote :

LGTM

review: Approve
lp:~jhodapp/media-hub/orientation updated on 2014-10-22
72. By Jim Hodapp on 2014-10-22

Only get the video dimensions and signal the client of the dimensions changing when playing a video.

Unmerged revisions

72. By Jim Hodapp on 2014-10-22

Only get the video dimensions and signal the client of the dimensions changing when playing a video.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/core/media/player.h'
2--- include/core/media/player.h 2014-09-08 10:16:38 +0000
3+++ include/core/media/player.h 2014-10-22 16:15:30 +0000
4@@ -86,6 +86,14 @@
5 phone
6 };
7
8+ enum Orientation
9+ {
10+ rotate0,
11+ rotate90,
12+ rotate180,
13+ rotate270
14+ };
15+
16 Player(const Player&) = delete;
17 virtual ~Player();
18
19@@ -127,6 +135,7 @@
20 virtual const core::Property<int64_t>& position() const = 0;
21 virtual const core::Property<int64_t>& duration() const = 0;
22 virtual const core::Property<AudioStreamRole>& audio_stream_role() const = 0;
23+ virtual const core::Property<Orientation>& orientation() const = 0;
24
25 virtual core::Property<LoopStatus>& loop_status() = 0;
26 virtual core::Property<PlaybackRate>& playback_rate() = 0;
27@@ -137,6 +146,11 @@
28 virtual const core::Signal<int64_t>& seeked_to() const = 0;
29 virtual const core::Signal<void>& end_of_stream() const = 0;
30 virtual core::Signal<PlaybackStatus>& playback_status_changed() = 0;
31+ /**
32+ * Called when the video height/width change. Passes height and width as a bitmask with
33+ * height in the upper 32 bits and width in the lower 32 bits (both unsigned values)
34+ */
35+ virtual const core::Signal<uint64_t>& video_dimension_changed() const = 0;
36 protected:
37 Player();
38
39
40=== modified file 'src/core/media/codec.h'
41--- src/core/media/codec.h 2014-08-29 14:03:42 +0000
42+++ src/core/media/codec.h 2014-10-22 16:15:30 +0000
43@@ -190,6 +190,46 @@
44 }
45 };
46
47+namespace helper
48+{
49+template<>
50+struct TypeMapper<core::ubuntu::media::Player::Orientation>
51+{
52+ constexpr static ArgumentType type_value()
53+ {
54+ return core::dbus::ArgumentType::int16;
55+ }
56+ constexpr static bool is_basic_type()
57+ {
58+ return false;
59+ }
60+ constexpr static bool requires_signature()
61+ {
62+ return false;
63+ }
64+
65+ static std::string signature()
66+ {
67+ static const std::string s = TypeMapper<std::int16_t>::signature();
68+ return s;
69+ }
70+};
71+}
72+
73+template<>
74+struct Codec<core::ubuntu::media::Player::Orientation>
75+{
76+ static void encode_argument(core::dbus::Message::Writer& out, const core::ubuntu::media::Player::Orientation& in)
77+ {
78+ out.push_int16(static_cast<std::int16_t>(in));
79+ }
80+
81+ static void decode_argument(core::dbus::Message::Reader& out, core::ubuntu::media::Player::Orientation& in)
82+ {
83+ in = static_cast<core::ubuntu::media::Player::Orientation>(out.pop_int16());
84+ }
85+};
86+
87 }
88 }
89
90
91=== modified file 'src/core/media/engine.h'
92--- src/core/media/engine.h 2014-09-08 10:16:38 +0000
93+++ src/core/media/engine.h 2014-10-22 16:15:30 +0000
94@@ -95,6 +95,8 @@
95 virtual const core::Property<core::ubuntu::media::Player::AudioStreamRole>& audio_stream_role() const = 0;
96 virtual core::Property<core::ubuntu::media::Player::AudioStreamRole>& audio_stream_role() = 0;
97
98+ virtual const core::Property<core::ubuntu::media::Player::Orientation>& orientation() const = 0;
99+
100 virtual const core::Property<std::tuple<Track::UriType, Track::MetaData>>& track_meta_data() const = 0;
101
102 virtual const core::Signal<void>& about_to_finish_signal() const = 0;
103@@ -102,6 +104,7 @@
104 virtual const core::Signal<void>& client_disconnected_signal() const = 0;
105 virtual const core::Signal<void>& end_of_stream_signal() const = 0;
106 virtual const core::Signal<core::ubuntu::media::Player::PlaybackStatus>& playback_status_changed_signal() const = 0;
107+ virtual const core::Signal<uint32_t, uint32_t>& video_dimension_changed_signal() const = 0;
108 };
109 }
110 }
111
112=== modified file 'src/core/media/gstreamer/bus.h'
113--- src/core/media/gstreamer/bus.h 2014-07-21 23:14:55 +0000
114+++ src/core/media/gstreamer/bus.h 2014-10-22 16:15:30 +0000
115@@ -93,7 +93,7 @@
116 &detail.tag.tag_list);
117 cleanup = [this]()
118 {
119- gst_tag_list_free(detail.tag.tag_list);
120+ gst_tag_list_unref(detail.tag.tag_list);
121 };
122 break;
123 case GST_MESSAGE_BUFFERING:
124
125=== modified file 'src/core/media/gstreamer/engine.cpp'
126--- src/core/media/gstreamer/engine.cpp 2014-10-08 00:09:21 +0000
127+++ src/core/media/gstreamer/engine.cpp 2014-10-22 16:15:30 +0000
128@@ -72,6 +72,13 @@
129 playbin.set_audio_stream_role(new_audio_role);
130 }
131
132+ void on_orientation_changed(const media::Player::Orientation& o)
133+ {
134+ // Update the local orientation Property, which should then update the Player
135+ // orientation Property
136+ orientation.set(o);
137+ }
138+
139 void on_about_to_finish()
140 {
141 state = Engine::State::ready;
142@@ -93,9 +100,15 @@
143 end_of_stream();
144 }
145
146+ void on_video_dimension_changed(uint32_t height, uint32_t width)
147+ {
148+ video_dimension_changed(height, width);
149+ }
150+
151 Private()
152 : meta_data_extractor(new gstreamer::MetaDataExtractor()),
153 volume(media::Engine::Volume(1.)),
154+ orientation(media::Player::Orientation::rotate0),
155 is_video_source(false),
156 is_audio_source(false),
157 about_to_finish_connection(
158@@ -127,6 +140,12 @@
159 &Private::on_audio_stream_role_changed,
160 this,
161 std::placeholders::_1))),
162+ on_orientation_changed_connection(
163+ playbin.signals.on_orientation_changed.connect(
164+ std::bind(
165+ &Private::on_orientation_changed,
166+ this,
167+ std::placeholders::_1))),
168 on_seeked_to_connection(
169 playbin.signals.on_seeked_to.connect(
170 std::bind(
171@@ -142,7 +161,14 @@
172 playbin.signals.on_end_of_stream.connect(
173 std::bind(
174 &Private::on_end_of_stream,
175- this)))
176+ this))),
177+ on_video_dimension_changed_connection(
178+ playbin.signals.on_add_frame_dimension.connect(
179+ std::bind(
180+ &Private::on_video_dimension_changed,
181+ this,
182+ std::placeholders::_1,
183+ std::placeholders::_2)))
184 {
185 }
186
187@@ -157,6 +183,7 @@
188 core::Property<uint64_t> duration;
189 core::Property<media::Engine::Volume> volume;
190 core::Property<media::Player::AudioStreamRole> audio_role;
191+ core::Property<media::Player::Orientation> orientation;
192 core::Property<bool> is_video_source;
193 core::Property<bool> is_audio_source;
194
195@@ -165,15 +192,18 @@
196 core::ScopedConnection on_tag_available_connection;
197 core::ScopedConnection on_volume_changed_connection;
198 core::ScopedConnection on_audio_stream_role_changed_connection;
199+ core::ScopedConnection on_orientation_changed_connection;
200 core::ScopedConnection on_seeked_to_connection;
201 core::ScopedConnection client_disconnected_connection;
202 core::ScopedConnection on_end_of_stream_connection;
203+ core::ScopedConnection on_video_dimension_changed_connection;
204
205 core::Signal<void> about_to_finish;
206 core::Signal<uint64_t> seeked_to;
207 core::Signal<void> client_disconnected;
208 core::Signal<void> end_of_stream;
209 core::Signal<media::Player::PlaybackStatus> playback_status_changed;
210+ core::Signal<uint32_t, uint32_t> video_dimension_changed;
211 };
212
213 gstreamer::Engine::Engine() : d(new Private{})
214@@ -313,6 +343,11 @@
215 return d->audio_role;
216 }
217
218+const core::Property<core::ubuntu::media::Player::Orientation>& gstreamer::Engine::orientation() const
219+{
220+ return d->orientation;
221+}
222+
223 const core::Property<std::tuple<media::Track::UriType, media::Track::MetaData>>&
224 gstreamer::Engine::track_meta_data() const
225 {
226@@ -343,3 +378,8 @@
227 {
228 return d->playback_status_changed;
229 }
230+
231+const core::Signal<uint32_t, uint32_t>& gstreamer::Engine::video_dimension_changed_signal() const
232+{
233+ return d->video_dimension_changed;
234+}
235
236=== modified file 'src/core/media/gstreamer/engine.h'
237--- src/core/media/gstreamer/engine.h 2014-08-29 14:03:42 +0000
238+++ src/core/media/gstreamer/engine.h 2014-10-22 16:15:30 +0000
239@@ -53,6 +53,8 @@
240 const core::Property<core::ubuntu::media::Player::AudioStreamRole>& audio_stream_role() const;
241 core::Property<core::ubuntu::media::Player::AudioStreamRole>& audio_stream_role();
242
243+ const core::Property<core::ubuntu::media::Player::Orientation>& orientation() const;
244+
245 const core::Property<std::tuple<core::ubuntu::media::Track::UriType, core::ubuntu::media::Track::MetaData>>& track_meta_data() const;
246
247 const core::Signal<void>& about_to_finish_signal() const;
248@@ -60,6 +62,7 @@
249 const core::Signal<void>& client_disconnected_signal() const;
250 const core::Signal<void>& end_of_stream_signal() const;
251 const core::Signal<core::ubuntu::media::Player::PlaybackStatus>& playback_status_changed_signal() const;
252+ const core::Signal<uint32_t, uint32_t>& video_dimension_changed_signal() const;
253
254 private:
255 struct Private;
256
257=== modified file 'src/core/media/gstreamer/meta_data_extractor.h'
258--- src/core/media/gstreamer/meta_data_extractor.h 2014-08-26 20:34:30 +0000
259+++ src/core/media/gstreamer/meta_data_extractor.h 2014-10-22 16:15:30 +0000
260@@ -216,7 +216,7 @@
261 }
262
263 gst_object_unref (sinkpad);
264- }
265+ }
266
267 GstElement* pipe;
268 GstElement* decoder;
269
270=== modified file 'src/core/media/gstreamer/playbin.h'
271--- src/core/media/gstreamer/playbin.h 2014-10-10 16:03:24 +0000
272+++ src/core/media/gstreamer/playbin.h 2014-10-22 16:15:30 +0000
273@@ -31,6 +31,12 @@
274 #include <chrono>
275 #include <string>
276
277+// Uncomment to generate a dot file at the time that the pipeline
278+// goes to the PLAYING state. Make sure to export GST_DEBUG_DUMP_DOT_DIR
279+// before starting media-hub-server. To convert the dot file to something
280+// other image format, use: dot pipeline.dot -Tpng -o pipeline.png
281+//#define DEBUG_GST_PIPELINE
282+
283 namespace media = core::ubuntu::media;
284
285 namespace gstreamer
286@@ -68,6 +74,9 @@
287 : pipeline(gst_element_factory_make("playbin", pipeline_name().c_str())),
288 bus{gst_element_get_bus(pipeline)},
289 file_type(MEDIA_FILE_TYPE_NONE),
290+ video_sink(nullptr),
291+ video_height(0),
292+ video_width(0),
293 on_new_message_connection(
294 bus.on_new_message.connect(
295 std::bind(
296@@ -153,7 +162,17 @@
297 signals.on_info(message.detail.error_warning_info);
298 break;
299 case GST_MESSAGE_TAG:
300- signals.on_tag_available(message.detail.tag);
301+ {
302+ gchar *orientation;
303+ if (gst_tag_list_get_string(message.detail.tag.tag_list, "image-orientation", &orientation))
304+ {
305+ // If the image-orientation tag is in the GstTagList, signal the Engine
306+ signals.on_orientation_changed(orientation_lut(orientation));
307+ g_free (orientation);
308+ }
309+
310+ signals.on_tag_available(message.detail.tag);
311+ }
312 break;
313 case GST_MESSAGE_STATE_CHANGED:
314 signals.on_state_changed(message.detail.state_changed);
315@@ -204,9 +223,9 @@
316
317 if (::getenv("CORE_UBUNTU_MEDIA_SERVICE_VIDEO_SINK_NAME") != nullptr)
318 {
319- auto video_sink = gst_element_factory_make (
320- ::getenv("CORE_UBUNTU_MEDIA_SERVICE_VIDEO_SINK_NAME"),
321- "video-sink");
322+ video_sink = gst_element_factory_make (
323+ ::getenv("CORE_UBUNTU_MEDIA_SERVICE_VIDEO_SINK_NAME"),
324+ "video-sink");
325
326 std::cout << "video_sink: " << ::getenv("CORE_UBUNTU_MEDIA_SERVICE_VIDEO_SINK_NAME") << std::endl;
327
328@@ -224,7 +243,6 @@
329
330 if (::getenv("CORE_UBUNTU_MEDIA_SERVICE_VIDEO_SINK_NAME") != nullptr)
331 {
332- GstElement *video_sink = NULL;
333 g_object_get (pipeline, "video_sink", &video_sink, NULL);
334
335 // Get the service-side BufferQueue (IGraphicBufferProducer) and associate it with
336@@ -265,6 +283,20 @@
337 }
338 }
339
340+ media::Player::Orientation orientation_lut(const gchar *orientation)
341+ {
342+ if (g_strcmp0(orientation, "rotate-0") == 0)
343+ return media::Player::Orientation::rotate0;
344+ else if (g_strcmp0(orientation, "rotate-90") == 0)
345+ return media::Player::Orientation::rotate90;
346+ else if (g_strcmp0(orientation, "rotate-180") == 0)
347+ return media::Player::Orientation::rotate180;
348+ else if (g_strcmp0(orientation, "rotate-270") == 0)
349+ return media::Player::Orientation::rotate270;
350+ else
351+ return media::Player::Orientation::rotate0;
352+ }
353+
354 /** Sets the new audio stream role on the pulsesink in playbin */
355 void set_audio_stream_role(media::Player::AudioStreamRole new_audio_role)
356 {
357@@ -350,6 +382,20 @@
358 &current,
359 &pending,
360 state_change_timeout.count());
361+
362+ if (new_state == GST_STATE_PLAYING)
363+ {
364+ // Only do this for video playback
365+ if (media_file_type() == MEDIA_FILE_TYPE_VIDEO)
366+ {
367+ // Get the video height/width from the video sink
368+ get_video_dimensions();
369+ }
370+#ifdef DEBUG_GST_PIPELINE
371+ std::cout << "Dumping pipeline dot file" << std::endl;
372+ GST_DEBUG_BIN_TO_DOT_FILE((GstBin*)pipeline, GST_DEBUG_GRAPH_SHOW_ALL, "pipeline");
373+#endif
374+ }
375 break;
376 }
377
378@@ -366,6 +412,29 @@
379 ms.count() * 1000);
380 }
381
382+ void get_video_dimensions()
383+ {
384+ if (video_sink != nullptr && g_strcmp0(::getenv("CORE_UBUNTU_MEDIA_SERVICE_VIDEO_SINK_NAME"), "mirsink") == 0)
385+ {
386+ g_object_get (video_sink, "height", &video_height, nullptr);
387+ g_object_get (video_sink, "width", &video_width, nullptr);
388+ std::cout << "video_height: " << video_height << ", video_width: " << video_width << std::endl;
389+ signals.on_add_frame_dimension(video_height, video_width);
390+ }
391+ else
392+ std::cerr << "Could not get the height/width of each video frame" << std::endl;
393+ }
394+
395+ int get_video_height() const
396+ {
397+ return video_height;
398+ }
399+
400+ int get_video_width() const
401+ {
402+ return video_width;
403+ }
404+
405 std::string get_file_content_type(const std::string& uri) const
406 {
407 if (uri.empty())
408@@ -445,6 +514,9 @@
409 gstreamer::Bus bus;
410 MediaFileType file_type;
411 SurfaceTextureClientHybris stc_hybris;
412+ GstElement* video_sink;
413+ uint32_t video_height;
414+ uint32_t video_width;
415 core::Connection on_new_message_connection;
416 bool is_seeking;
417 struct
418@@ -458,6 +530,8 @@
419 core::Signal<uint64_t> on_seeked_to;
420 core::Signal<void> on_end_of_stream;
421 core::Signal<media::Player::PlaybackStatus> on_playback_status_changed;
422+ core::Signal<media::Player::Orientation> on_orientation_changed;
423+ core::Signal<uint32_t, uint32_t> on_add_frame_dimension;
424 core::Signal<void> client_disconnected;
425 } signals;
426 };
427
428=== modified file 'src/core/media/mpris/player.h'
429--- src/core/media/mpris/player.h 2014-09-10 21:05:34 +0000
430+++ src/core/media/mpris/player.h 2014-10-22 16:15:30 +0000
431@@ -122,6 +122,7 @@
432 DBUS_CPP_SIGNAL_DEF(Seeked, Player, std::int64_t)
433 DBUS_CPP_SIGNAL_DEF(EndOfStream, Player, void)
434 DBUS_CPP_SIGNAL_DEF(PlaybackStatusChanged, Player, core::ubuntu::media::Player::PlaybackStatus)
435+ DBUS_CPP_SIGNAL_DEF(VideoDimensionChanged, Player, std::uint64_t)
436 };
437
438 struct Properties
439@@ -132,6 +133,7 @@
440 DBUS_CPP_WRITABLE_PROPERTY_DEF(LoopStatus, Player, std::string)
441 DBUS_CPP_WRITABLE_PROPERTY_DEF(TypedLoopStatus, Player, core::ubuntu::media::Player::LoopStatus)
442 DBUS_CPP_WRITABLE_PROPERTY_DEF(AudioStreamRole, Player, core::ubuntu::media::Player::AudioStreamRole)
443+ DBUS_CPP_READABLE_PROPERTY_DEF(Orientation, Player, core::ubuntu::media::Player::Orientation)
444 DBUS_CPP_WRITABLE_PROPERTY_DEF(PlaybackRate, Player, double)
445 DBUS_CPP_WRITABLE_PROPERTY_DEF(Rate, Player, double)
446 DBUS_CPP_WRITABLE_PROPERTY_DEF(Shuffle, Player, bool)
447@@ -191,6 +193,7 @@
448 Properties::Duration::ValueType duration{0};
449 Properties::MinimumRate::ValueType minimum_rate{1.f};
450 Properties::MaximumRate::ValueType maximum_rate{1.f};
451+ Properties::Orientation::ValueType orientation{core::ubuntu::media::Player::Orientation::rotate0};
452 } defaults;
453 };
454
455@@ -211,6 +214,7 @@
456 configuration.object->template get_property<Properties::LoopStatus>(),
457 configuration.object->template get_property<Properties::TypedLoopStatus>(),
458 configuration.object->template get_property<Properties::AudioStreamRole>(),
459+ configuration.object->template get_property<Properties::Orientation>(),
460 configuration.object->template get_property<Properties::PlaybackRate>(),
461 configuration.object->template get_property<Properties::Shuffle>(),
462 configuration.object->template get_property<Properties::TypedMetaData>(),
463@@ -225,6 +229,7 @@
464 configuration.object->template get_signal<Signals::Seeked>(),
465 configuration.object->template get_signal<Signals::EndOfStream>(),
466 configuration.object->template get_signal<Signals::PlaybackStatusChanged>(),
467+ configuration.object->template get_signal<Signals::VideoDimensionChanged>(),
468 configuration.object->template get_signal<core::dbus::interfaces::Properties::Signals::PropertiesChanged>()
469 }
470 {
471@@ -241,12 +246,19 @@
472 properties.loop_status->set(configuration.defaults.loop_status);
473 properties.typed_loop_status->set(configuration.defaults.typed_loop_status);
474 properties.audio_stream_role->set(core::ubuntu::media::Player::AudioStreamRole::multimedia);
475+ properties.orientation->set(core::ubuntu::media::Player::Orientation::rotate0);
476 properties.playback_rate->set(configuration.defaults.playback_rate);
477 properties.is_shuffle->set(configuration.defaults.shuffle);
478 properties.position->set(configuration.defaults.position);
479 properties.duration->set(configuration.defaults.duration);
480 properties.minimum_playback_rate->set(configuration.defaults.minimum_rate);
481- properties.maximum_playback_rate->set(configuration.defaults.maximum_rate);
482+ properties.maximum_playback_rate->set(configuration.defaults.maximum_rate);
483+
484+ // Make sure the Orientation Property gets sent over DBus to the client
485+ properties.orientation->changed().connect([this](const core::ubuntu::media::Player::Orientation& o)
486+ {
487+ on_property_value_changed<Properties::Orientation>(o);
488+ });
489
490 properties.position->changed().connect([this](std::int64_t position)
491 {
492@@ -266,7 +278,7 @@
493 properties.loop_status->changed().connect([this](const std::string& status)
494 {
495 on_property_value_changed<Properties::LoopStatus>(status);
496- });
497+ });
498 }
499
500 template<typename Property>
501@@ -294,6 +306,7 @@
502 dict[Properties::LoopStatus::name()] = dbus::types::Variant::encode(properties.loop_status->get());
503 dict[Properties::TypedLoopStatus::name()] = dbus::types::Variant::encode(properties.typed_loop_status->get());
504 dict[Properties::AudioStreamRole::name()] = dbus::types::Variant::encode(properties.audio_stream_role->get());
505+ dict[Properties::Orientation::name()] = dbus::types::Variant::encode(properties.orientation->get());
506 dict[Properties::PlaybackRate::name()] = dbus::types::Variant::encode(properties.playback_rate->get());
507 dict[Properties::Shuffle::name()] = dbus::types::Variant::encode(properties.is_shuffle->get());
508 dict[Properties::Duration::name()] = dbus::types::Variant::encode(properties.duration->get());
509@@ -323,6 +336,7 @@
510 std::shared_ptr<core::dbus::Property<Properties::LoopStatus>> loop_status;
511 std::shared_ptr<core::dbus::Property<Properties::TypedLoopStatus>> typed_loop_status;
512 std::shared_ptr<core::dbus::Property<Properties::AudioStreamRole>> audio_stream_role;
513+ std::shared_ptr<core::dbus::Property<Properties::Orientation>> orientation;
514 std::shared_ptr<core::dbus::Property<Properties::PlaybackRate>> playback_rate;
515 std::shared_ptr<core::dbus::Property<Properties::Shuffle>> is_shuffle;
516 std::shared_ptr<core::dbus::Property<Properties::TypedMetaData>> typed_meta_data_for_current_track;
517@@ -338,6 +352,7 @@
518 typename core::dbus::Signal<Signals::Seeked, Signals::Seeked::ArgumentType>::Ptr seeked_to;
519 typename core::dbus::Signal<Signals::EndOfStream, Signals::EndOfStream::ArgumentType>::Ptr end_of_stream;
520 typename core::dbus::Signal<Signals::PlaybackStatusChanged, Signals::PlaybackStatusChanged::ArgumentType>::Ptr playback_status_changed;
521+ typename core::dbus::Signal<Signals::VideoDimensionChanged, Signals::VideoDimensionChanged::ArgumentType>::Ptr video_dimension_changed;
522
523 dbus::Signal
524 <
525
526=== modified file 'src/core/media/player_implementation.cpp'
527--- src/core/media/player_implementation.cpp 2014-10-08 03:06:14 +0000
528+++ src/core/media/player_implementation.cpp 2014-10-22 16:15:30 +0000
529@@ -297,7 +297,7 @@
530 service,
531 key))
532 {
533- // Initializing default values for properties
534+ // Initialize default values for Player interface properties
535 can_play().set(true);
536 can_pause().set(true);
537 can_seek().set(true);
538@@ -313,6 +313,7 @@
539 duration().set(0);
540 audio_stream_role().set(Player::AudioStreamRole::multimedia);
541 d->engine->audio_stream_role().set(Player::AudioStreamRole::multimedia);
542+ orientation().set(Player::Orientation::rotate0);
543
544 // Make sure that the Position property gets updated from the Engine
545 // every time the client requests position
546@@ -349,6 +350,13 @@
547 d->engine->audio_stream_role().set(new_role);
548 });
549
550+ // When the value of the orientation Property is changed in the Engine by playbin,
551+ // update the Player's cached value
552+ d->engine->orientation().changed().connect([this](const Player::Orientation& o)
553+ {
554+ orientation().set(o);
555+ });
556+
557 d->engine->about_to_finish_signal().connect([this]()
558 {
559 if (d->track_list->has_next())
560@@ -382,6 +390,14 @@
561 {
562 playback_status_changed()(status);
563 });
564+
565+ d->engine->video_dimension_changed_signal().connect([this](uint32_t height, uint32_t width)
566+ {
567+ uint64_t mask = 0;
568+ // Left most 32 bits are for height, right most 32 bits are for width
569+ mask = (static_cast<uint64_t>(height) << 32) | static_cast<uint64_t>(width);
570+ video_dimension_changed()(mask);
571+ });
572 }
573
574 media::PlayerImplementation::~PlayerImplementation()
575
576=== modified file 'src/core/media/player_skeleton.cpp'
577--- src/core/media/player_skeleton.cpp 2014-10-08 00:31:41 +0000
578+++ src/core/media/player_skeleton.cpp 2014-10-22 16:15:30 +0000
579@@ -57,10 +57,11 @@
580 {
581 skeleton.signals.seeked_to,
582 skeleton.signals.end_of_stream,
583- skeleton.signals.playback_status_changed
584+ skeleton.signals.playback_status_changed,
585+ skeleton.signals.video_dimension_changed
586 }
587 {
588- }
589+ }
590
591 void handle_next(const core::dbus::Message::Ptr& msg)
592 {
593@@ -138,7 +139,7 @@
594
595 auto reply = dbus::Message::make_method_return(in);
596 bus->send(reply);
597- }
598+ }
599
600 bool does_client_have_access(const std::string& context, const std::string& uri)
601 {
602@@ -224,7 +225,7 @@
603 }
604
605 void handle_open_uri(const core::dbus::Message::Ptr& in)
606- {
607+ {
608 dbus_stub.get_connection_app_armor_security_async(in->sender(), [this, in](const std::string& profile)
609 {
610 Track::UriType uri;
611@@ -268,17 +269,19 @@
612
613 org::freedesktop::dbus::DBus::Stub dbus_stub;
614
615- mpris::Player::Skeleton skeleton;
616+ mpris::Player::Skeleton skeleton;
617
618 struct Signals
619 {
620 typedef core::dbus::Signal<mpris::Player::Signals::Seeked, mpris::Player::Signals::Seeked::ArgumentType> DBusSeekedToSignal;
621 typedef core::dbus::Signal<mpris::Player::Signals::EndOfStream, mpris::Player::Signals::EndOfStream::ArgumentType> DBusEndOfStreamSignal;
622 typedef core::dbus::Signal<mpris::Player::Signals::PlaybackStatusChanged, mpris::Player::Signals::PlaybackStatusChanged::ArgumentType> DBusPlaybackStatusChangedSignal;
623+ typedef core::dbus::Signal<mpris::Player::Signals::VideoDimensionChanged, mpris::Player::Signals::VideoDimensionChanged::ArgumentType> DBusVideoDimensionChangedSignal;
624
625 Signals(const std::shared_ptr<DBusSeekedToSignal>& remote_seeked,
626 const std::shared_ptr<DBusEndOfStreamSignal>& remote_eos,
627- const std::shared_ptr<DBusPlaybackStatusChangedSignal>& remote_playback_status_changed)
628+ const std::shared_ptr<DBusPlaybackStatusChangedSignal>& remote_playback_status_changed,
629+ const std::shared_ptr<DBusVideoDimensionChangedSignal>& remote_video_dimension_changed)
630 {
631 seeked_to.connect([remote_seeked](std::uint64_t value)
632 {
633@@ -294,11 +297,17 @@
634 {
635 remote_playback_status_changed->emit(status);
636 });
637+
638+ video_dimension_changed.connect([remote_video_dimension_changed](uint64_t mask)
639+ {
640+ remote_video_dimension_changed->emit(mask);
641+ });
642 }
643
644 core::Signal<int64_t> seeked_to;
645 core::Signal<void> end_of_stream;
646 core::Signal<media::Player::PlaybackStatus> playback_status_changed;
647+ core::Signal<uint64_t> video_dimension_changed;
648 } signals;
649
650 };
651@@ -443,6 +452,11 @@
652 return *d->skeleton.properties.audio_stream_role;
653 }
654
655+const core::Property<media::Player::Orientation>& media::PlayerSkeleton::orientation() const
656+{
657+ return *d->skeleton.properties.orientation;
658+}
659+
660 const core::Property<media::Player::PlaybackRate>& media::PlayerSkeleton::minimum_playback_rate() const
661 {
662 return *d->skeleton.properties.minimum_playback_rate;
663@@ -488,6 +502,11 @@
664 return *d->skeleton.properties.audio_stream_role;
665 }
666
667+core::Property<media::Player::Orientation>& media::PlayerSkeleton::orientation()
668+{
669+ return *d->skeleton.properties.orientation;
670+}
671+
672 core::Property<media::Player::PlaybackStatus>& media::PlayerSkeleton::playback_status()
673 {
674 return *d->skeleton.properties.typed_playback_status;
675@@ -528,7 +547,6 @@
676 return *d->skeleton.properties.is_audio_source;
677 }
678
679-
680 core::Property<media::Track::MetaData>& media::PlayerSkeleton::meta_data_for_current_track()
681 {
682 return *d->skeleton.properties.typed_meta_data_for_current_track;
683@@ -568,3 +586,13 @@
684 {
685 return d->signals.playback_status_changed;
686 }
687+
688+const core::Signal<uint64_t>& media::PlayerSkeleton::video_dimension_changed() const
689+{
690+ return d->signals.video_dimension_changed;
691+}
692+
693+core::Signal<uint64_t>& media::PlayerSkeleton::video_dimension_changed()
694+{
695+ return d->signals.video_dimension_changed;
696+}
697
698=== modified file 'src/core/media/player_skeleton.h'
699--- src/core/media/player_skeleton.h 2014-09-09 14:02:52 +0000
700+++ src/core/media/player_skeleton.h 2014-10-22 16:15:30 +0000
701@@ -62,6 +62,7 @@
702 virtual const core::Property<int64_t>& position() const;
703 virtual const core::Property<int64_t>& duration() const;
704 virtual const core::Property<AudioStreamRole>& audio_stream_role() const;
705+ virtual const core::Property<Orientation>& orientation() const;
706
707 virtual core::Property<LoopStatus>& loop_status();
708 virtual core::Property<PlaybackRate>& playback_rate();
709@@ -72,6 +73,7 @@
710 virtual const core::Signal<int64_t>& seeked_to() const;
711 virtual const core::Signal<void>& end_of_stream() const;
712 virtual core::Signal<PlaybackStatus>& playback_status_changed();
713+ virtual const core::Signal<uint64_t>& video_dimension_changed() const;
714
715 protected:
716 // All creation time arguments go here.
717@@ -88,6 +90,8 @@
718
719 PlayerSkeleton(const Configuration& configuration);
720
721+ // These properties are not exposed to the client, but still need to be
722+ // able to be settable from within the Player:
723 virtual core::Property<PlaybackStatus>& playback_status();
724 virtual core::Property<bool>& can_play();
725 virtual core::Property<bool>& can_pause();
726@@ -101,9 +105,11 @@
727 virtual core::Property<PlaybackRate>& maximum_playback_rate();
728 virtual core::Property<int64_t>& position();
729 virtual core::Property<int64_t>& duration();
730+ virtual core::Property<Orientation>& orientation();
731
732 virtual core::Signal<int64_t>& seeked_to();
733 virtual core::Signal<void>& end_of_stream();
734+ virtual core::Signal<uint64_t>& video_dimension_changed();
735
736 private:
737 struct Private;
738
739=== modified file 'src/core/media/player_stub.cpp'
740--- src/core/media/player_stub.cpp 2014-10-16 15:30:44 +0000
741+++ src/core/media/player_stub.cpp 2014-10-22 16:15:30 +0000
742@@ -57,6 +57,7 @@
743 object(object),
744 properties
745 {
746+ // Link the properties from the server side to the client side over the bus
747 object->get_property<mpris::Player::Properties::CanPlay>(),
748 object->get_property<mpris::Player::Properties::CanPause>(),
749 object->get_property<mpris::Player::Properties::CanSeek>(),
750@@ -74,6 +75,7 @@
751 object->get_property<mpris::Player::Properties::Position>(),
752 object->get_property<mpris::Player::Properties::Duration>(),
753 object->get_property<mpris::Player::Properties::AudioStreamRole>(),
754+ object->get_property<mpris::Player::Properties::Orientation>(),
755 object->get_property<mpris::Player::Properties::MinimumRate>(),
756 object->get_property<mpris::Player::Properties::MaximumRate>()
757 },
758@@ -81,7 +83,8 @@
759 {
760 object->get_signal<mpris::Player::Signals::Seeked>(),
761 object->get_signal<mpris::Player::Signals::EndOfStream>(),
762- object->get_signal<mpris::Player::Signals::PlaybackStatusChanged>()
763+ object->get_signal<mpris::Player::Signals::PlaybackStatusChanged>(),
764+ object->get_signal<mpris::Player::Signals::VideoDimensionChanged>()
765 }
766 {
767 }
768@@ -160,6 +163,7 @@
769 std::shared_ptr<core::dbus::Property<mpris::Player::Properties::Position>> position;
770 std::shared_ptr<core::dbus::Property<mpris::Player::Properties::Duration>> duration;
771 std::shared_ptr<core::dbus::Property<mpris::Player::Properties::AudioStreamRole>> audio_role;
772+ std::shared_ptr<core::dbus::Property<mpris::Player::Properties::Orientation>> orientation;
773 std::shared_ptr<core::dbus::Property<mpris::Player::Properties::MinimumRate>> minimum_playback_rate;
774 std::shared_ptr<core::dbus::Property<mpris::Player::Properties::MaximumRate>> maximum_playback_rate;
775 } properties;
776@@ -169,21 +173,25 @@
777 typedef core::dbus::Signal<mpris::Player::Signals::Seeked, mpris::Player::Signals::Seeked::ArgumentType> DBusSeekedToSignal;
778 typedef core::dbus::Signal<mpris::Player::Signals::EndOfStream, mpris::Player::Signals::EndOfStream::ArgumentType> DBusEndOfStreamSignal;
779 typedef core::dbus::Signal<mpris::Player::Signals::PlaybackStatusChanged, mpris::Player::Signals::PlaybackStatusChanged::ArgumentType> DBusPlaybackStatusChangedSignal;
780+ typedef core::dbus::Signal<mpris::Player::Signals::VideoDimensionChanged, mpris::Player::Signals::VideoDimensionChanged::ArgumentType> DBusVideoDimensionChangedSignal;
781
782 Signals(const std::shared_ptr<DBusSeekedToSignal>& seeked,
783 const std::shared_ptr<DBusEndOfStreamSignal>& eos,
784- const std::shared_ptr<DBusPlaybackStatusChangedSignal>& status)
785+ const std::shared_ptr<DBusPlaybackStatusChangedSignal>& status,
786+ const std::shared_ptr<DBusVideoDimensionChangedSignal>& d)
787 : dbus
788 {
789 seeked,
790 eos,
791- status
792+ status,
793+ d
794 },
795 playback_complete_cb(nullptr),
796 playback_complete_context(nullptr),
797 seeked_to(),
798 end_of_stream(),
799- playback_status_changed()
800+ playback_status_changed(),
801+ video_dimension_changed()
802 {
803 dbus.seeked_to->connect([this](std::uint64_t value)
804 {
805@@ -204,6 +212,12 @@
806 std::cout << "PlaybackStatusChanged signal arrived via the bus." << std::endl;
807 playback_status_changed(status);
808 });
809+
810+ dbus.video_dimension_changed->connect([this](uint64_t mask)
811+ {
812+ std::cout << "VideoDimensionChanged signal arrived via the bus." << std::endl;
813+ video_dimension_changed(mask);
814+ });
815 }
816
817 struct DBus
818@@ -211,6 +225,7 @@
819 std::shared_ptr<DBusSeekedToSignal> seeked_to;
820 std::shared_ptr<DBusEndOfStreamSignal> end_of_stream;
821 std::shared_ptr<DBusPlaybackStatusChangedSignal> playback_status_changed;
822+ std::shared_ptr<DBusVideoDimensionChangedSignal> video_dimension_changed;
823 } dbus;
824
825 void set_playback_complete_cb(PlaybackCompleteCb cb, void *context)
826@@ -224,6 +239,7 @@
827 core::Signal<int64_t> seeked_to;
828 core::Signal<void> end_of_stream;
829 core::Signal<media::Player::PlaybackStatus> playback_status_changed;
830+ core::Signal<uint64_t> video_dimension_changed;
831 } signals;
832 };
833
834@@ -416,6 +432,11 @@
835 return *d->properties.audio_role;
836 }
837
838+const core::Property<media::Player::Orientation>& media::PlayerStub::orientation() const
839+{
840+ return *d->properties.orientation;
841+}
842+
843 const core::Property<media::Player::PlaybackRate>& media::PlayerStub::minimum_playback_rate() const
844 {
845 return *d->properties.minimum_playback_rate;
846@@ -465,3 +486,8 @@
847 {
848 return d->signals.playback_status_changed;
849 }
850+
851+const core::Signal<uint64_t>& media::PlayerStub::video_dimension_changed() const
852+{
853+ return d->signals.video_dimension_changed;
854+}
855
856=== modified file 'src/core/media/player_stub.h'
857--- src/core/media/player_stub.h 2014-10-16 15:30:44 +0000
858+++ src/core/media/player_stub.h 2014-10-22 16:15:30 +0000
859@@ -14,6 +14,7 @@
860 * along with this program. If not, see <http://www.gnu.org/licenses/>.
861 *
862 * Authored by: Thomas Voß <thomas.voss@canonical.com>
863+ * Jim Hodapp <jim.hodapp@canonical.com>
864 */
865
866 #ifndef CORE_UBUNTU_MEDIA_PLAYER_STUB_H_
867@@ -76,6 +77,7 @@
868 virtual const core::Property<int64_t>& position() const;
869 virtual const core::Property<int64_t>& duration() const;
870 virtual const core::Property<AudioStreamRole>& audio_stream_role() const;
871+ virtual const core::Property<Orientation>& orientation() const;
872
873 virtual core::Property<LoopStatus>& loop_status();
874 virtual core::Property<PlaybackRate>& playback_rate();
875@@ -86,6 +88,7 @@
876 virtual const core::Signal<int64_t>& seeked_to() const;
877 virtual const core::Signal<void>& end_of_stream() const;
878 virtual core::Signal<PlaybackStatus>& playback_status_changed();
879+ virtual const core::Signal<uint64_t>& video_dimension_changed() const;
880
881 private:
882 struct Private;

Subscribers

People subscribed via source and target branches