Merge lp:~jhodapp/media-hub/orientation into lp:media-hub
- orientation
- Merge into trunk
Status: | Approved |
---|---|
Approved by: | Ricardo Salveti |
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ricardo Salveti (community) | Approve | ||
PS Jenkins bot | continuous-integration | Approve | |
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.
PS Jenkins bot (ps-jenkins) wrote : | # |
- 71. By Jim Hodapp
-
Merged with trunk
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:71
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 72. By Jim Hodapp
-
Only get the video dimensions and signal the client of the dimensions changing when playing a video.
Unmerged revisions
- 72. By Jim Hodapp
-
Only get the video dimensions and signal the client of the dimensions changing when playing a video.
Preview Diff
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 | ¤t, |
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; |
FAILED: Continuous integration, rev:70 jenkins. qa.ubuntu. com/job/ media-hub- ci/142/ jenkins. qa.ubuntu. com/job/ media-hub- utopic- amd64-ci/ 84 jenkins. qa.ubuntu. com/job/ media-hub- utopic- armhf-ci/ 83 jenkins. qa.ubuntu. com/job/ media-hub- utopic- armhf-ci/ 83/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ media-hub- utopic- i386-ci/ 82/console
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/media- hub-ci/ 142/rebuild
http://