Merge lp:~thomas-voss/media-hub/make-video-size-a-proper-type into lp:media-hub
- make-video-size-a-proper-type
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Ricardo Mendoza |
Approved revision: | 107 |
Merged at revision: | 115 |
Proposed branch: | lp:~thomas-voss/media-hub/make-video-size-a-proper-type |
Merge into: | lp:media-hub |
Prerequisite: | lp:~thomas-voss/media-hub/introduce-video-sink-interface |
Diff against target: |
611 lines (+250/-66) 13 files modified
include/core/media/player.h (+3/-6) include/core/media/video/dimensions.h (+145/-0) src/core/media/codec.h (+44/-1) src/core/media/engine.h (+1/-1) src/core/media/gstreamer/engine.cpp (+6/-7) src/core/media/gstreamer/engine.h (+1/-1) src/core/media/gstreamer/playbin.h (+30/-32) src/core/media/mpris/player.h (+5/-1) src/core/media/player_implementation.cpp (+2/-5) src/core/media/player_skeleton.cpp (+6/-5) src/core/media/player_skeleton.h (+2/-2) src/core/media/player_stub.cpp (+4/-4) src/core/media/player_stub.h (+1/-1) |
To merge this branch: | bzr merge lp:~thomas-voss/media-hub/make-video-size-a-proper-type |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Approve | |
Jim Hodapp (community) | code | Needs Fixing | |
Review via email: mp+242879@code.launchpad.net |
Commit message
Replace home-grown mask type for the video size with a std::tuple, i.e., media::
Introduce a simple TaggedInteger class to distinguish between Width, Height and other dimensions.
Adjust interfaces of media::Player to rely on the new type.
Adjust implementation classes to account for interface changes.
Adjust Codec implementation for sending the tagged integer via the bus.
Adjust gstreamer::Engine and gstreamer::Playbin to hand out the correct types.
Description of the change
Replace home-grown mask type for the video size with a std::tuple, i.e., media::
Introduce a simple TaggedInteger class to distinguish between Width, Height and other dimensions.
Adjust interfaces of media::Player to rely on the new type.
Adjust implementation classes to account for interface changes.
Adjust Codec implementation for sending the tagged integer via the bus.
Adjust gstreamer::Engine and gstreamer::Playbin to hand out the correct types.
PS Jenkins bot (ps-jenkins) wrote : | # |
- 101. By Thomas Voß
-
Remerge prereq branch.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:101
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Jim Hodapp (jhodapp) wrote : | # |
A few inline comments below. Please make sure to rebase with trunk.
- 102. By Thomas Voß
-
[ Jim Hodapp ]
* Resubmitting with prerequisite branch (LP: #1331041)
[ Justin McPherson ]
* Resubmitting with prerequisite branch (LP: #1331041) - 103. By Thomas Voß
-
Address reviewer comments.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:103
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 104. By Thomas Voß
-
[ Jim Hodapp ]
* Error reporting all the way up to the app level from the playbin
pipeline.
[ Ubuntu daily release ]
* New rebuild forced
[ Jim Hodapp ]
* Don't auto-resume playback of videos after a phone call ends. (LP:
#1411273)
[ Ubuntu daily release ]
* New rebuild forced
[ Ricardo Salveti de Araujo ]
* service_implementation: adding debug for call started/ended signals.
Make sure account and connection are available when setting up
account manager (patch from Gustavo Boiko). call_monitor: don't
check caps when hooking up on/off signals, until bug 1409125 is
fixed. Enable parallel building . (LP: #1409125)
[ Jim Hodapp ]
* Pause playback when recording begins. (LP: #1398047)
[ Ricardo Salveti de Araujo ]
* call_monitor.cpp: waiting for bridge to be up, and also protecting
the on_change call (LP: #1408137)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:104
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 105. By Thomas Voß
-
Merge prereq branch.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:105
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
deb: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Francis Ginther (fginther) wrote : | # |
The jenkins node for the i386 build failed, I've restarted a new ci run.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:105
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 106. By Thomas Voß
-
Merge prereq branch.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:106
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 107. By Thomas Voß
-
* debian/control:
- Removing pre-depends that are not required
- Bumping standards-version to 3.9.6
[ Ricardo Salveti de Araujo ]
* Migrating tests to use ogg instead of mp3/avi removed:
tests/h264.avi tests/test.mp3 added: tests/test-audio-1. ogg
tests/test-video. ogg tests/test.mp3 renamed: tests/test.ogg =>
tests/test-audio. ogg
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:107
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'include/core/media/player.h' | |||
2 | --- include/core/media/player.h 2015-03-12 11:39:32 +0000 | |||
3 | +++ include/core/media/player.h 2015-03-12 11:39:32 +0000 | |||
4 | @@ -20,6 +20,8 @@ | |||
5 | 20 | #define CORE_UBUNTU_MEDIA_PLAYER_H_ | 20 | #define CORE_UBUNTU_MEDIA_PLAYER_H_ |
6 | 21 | 21 | ||
7 | 22 | #include <core/media/track.h> | 22 | #include <core/media/track.h> |
8 | 23 | |||
9 | 24 | #include <core/media/video/dimensions.h> | ||
10 | 23 | #include <core/media/video/sink.h> | 25 | #include <core/media/video/sink.h> |
11 | 24 | 26 | ||
12 | 25 | #include <core/property.h> | 27 | #include <core/property.h> |
13 | @@ -168,14 +170,9 @@ | |||
14 | 168 | virtual const core::Signal<int64_t>& seeked_to() const = 0; | 170 | virtual const core::Signal<int64_t>& seeked_to() const = 0; |
15 | 169 | virtual const core::Signal<void>& end_of_stream() const = 0; | 171 | virtual const core::Signal<void>& end_of_stream() const = 0; |
16 | 170 | virtual core::Signal<PlaybackStatus>& playback_status_changed() = 0; | 172 | virtual core::Signal<PlaybackStatus>& playback_status_changed() = 0; |
22 | 171 | /** | 173 | virtual const core::Signal<video::Dimensions>& video_dimension_changed() const = 0; |
18 | 172 | * Called when the video height/width change. Passes height and width as a bitmask with | ||
19 | 173 | * height in the upper 32 bits and width in the lower 32 bits (both unsigned values) | ||
20 | 174 | */ | ||
21 | 175 | virtual const core::Signal<uint64_t>& video_dimension_changed() const = 0; | ||
23 | 176 | /** Signals all errors and warnings (typically from GStreamer and below) */ | 174 | /** Signals all errors and warnings (typically from GStreamer and below) */ |
24 | 177 | virtual const core::Signal<Error>& error() const = 0; | 175 | virtual const core::Signal<Error>& error() const = 0; |
25 | 178 | |||
26 | 179 | protected: | 176 | protected: |
27 | 180 | Player(); | 177 | Player(); |
28 | 181 | 178 | ||
29 | 182 | 179 | ||
30 | === added file 'include/core/media/video/dimensions.h' | |||
31 | --- include/core/media/video/dimensions.h 1970-01-01 00:00:00 +0000 | |||
32 | +++ include/core/media/video/dimensions.h 2015-03-12 11:39:32 +0000 | |||
33 | @@ -0,0 +1,145 @@ | |||
34 | 1 | /* | ||
35 | 2 | * Copyright © 2014 Canonical Ltd. | ||
36 | 3 | * | ||
37 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
38 | 5 | * under the terms of the GNU Lesser General Public License version 3, | ||
39 | 6 | * as published by the Free Software Foundation. | ||
40 | 7 | * | ||
41 | 8 | * This program is distributed in the hope that it will be useful, | ||
42 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
43 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
44 | 11 | * GNU Lesser General Public License for more details. | ||
45 | 12 | * | ||
46 | 13 | * You should have received a copy of the GNU Lesser General Public License | ||
47 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
48 | 15 | * | ||
49 | 16 | * Authored by: Thomas Voß <thomas.voss@canonical.com> | ||
50 | 17 | */ | ||
51 | 18 | #ifndef CORE_UBUNTU_MEDIA_VIDEO_DIMENSIONS_H_ | ||
52 | 19 | #define CORE_UBUNTU_MEDIA_VIDEO_DIMENSIONS_H_ | ||
53 | 20 | |||
54 | 21 | #include <cstdint> | ||
55 | 22 | |||
56 | 23 | #include <tuple> | ||
57 | 24 | |||
58 | 25 | namespace core | ||
59 | 26 | { | ||
60 | 27 | namespace ubuntu | ||
61 | 28 | { | ||
62 | 29 | namespace media | ||
63 | 30 | { | ||
64 | 31 | namespace video | ||
65 | 32 | { | ||
66 | 33 | namespace detail | ||
67 | 34 | { | ||
68 | 35 | enum class DimensionTag { width, height }; | ||
69 | 36 | |||
70 | 37 | /** | ||
71 | 38 | * @brief IntWrapper is a type-safe integer that allows for encoding/enforcing semantics by means of tags. | ||
72 | 39 | * @tparam Tag Hint for the compiler on the semantics of the underlying integer. | ||
73 | 40 | * @tparam IntegerType The underlying integer type. | ||
74 | 41 | * | ||
75 | 42 | * Handling dimensions like width and height with raw integer values is tedious and error prone | ||
76 | 43 | * as the compiler has no way of distinguishing a width from a height, or an x coordinate from a | ||
77 | 44 | * y coordinate. The problem is solvable with the tagged integer type presented here. Consider | ||
78 | 45 | * the following example: | ||
79 | 46 | * | ||
80 | 47 | * @code{.cpp} | ||
81 | 48 | * typedef IntWrapper<DimensionTag::width, std::uint32_t> Width; | ||
82 | 49 | * typedef IntWrapper<DimensionTag::height, std::uint32_t> Height; | ||
83 | 50 | * | ||
84 | 51 | * void an_unsafe_function_expecting_width_and_height(std::uint32_t width, std::uint32_t height); | ||
85 | 52 | * void a_safe_function_expecting_width_and_height(Width width, Height height); | ||
86 | 53 | * | ||
87 | 54 | * int main() | ||
88 | 55 | * { | ||
89 | 56 | * std::uint unsafe_width{640}, unsafe_height{480}; | ||
90 | 57 | * Width width{640}; Height height{480}; | ||
91 | 58 | * // This will compile but is still wrong | ||
92 | 59 | * an_unsafe_function_expecting_width_and_height(unsafe_height, unsafe_width); | ||
93 | 60 | * | ||
94 | 61 | * // This will not compile | ||
95 | 62 | * a_safe_function_expecting_width_and_height(height, width); | ||
96 | 63 | * | ||
97 | 64 | * } | ||
98 | 65 | * @endcode | ||
99 | 66 | */ | ||
100 | 67 | template<DimensionTag Tag, typename IntegerType> | ||
101 | 68 | class IntWrapper | ||
102 | 69 | { | ||
103 | 70 | public: | ||
104 | 71 | static_assert(std::is_integral<IntegerType>::value, "IntWrapper<> only supports integral types."); | ||
105 | 72 | typedef IntegerType ValueType; | ||
106 | 73 | |||
107 | 74 | IntWrapper() : value{0} {} | ||
108 | 75 | template<typename AnyInteger> | ||
109 | 76 | explicit IntWrapper(AnyInteger value) : value{static_cast<ValueType>(value)} {} | ||
110 | 77 | |||
111 | 78 | template<typename T = IntegerType> | ||
112 | 79 | T as() const | ||
113 | 80 | { | ||
114 | 81 | static_assert(std::is_arithmetic<T>::value, "as() only supports arithmetic types."); | ||
115 | 82 | return static_cast<T>(value); | ||
116 | 83 | } | ||
117 | 84 | |||
118 | 85 | private: | ||
119 | 86 | ValueType value; | ||
120 | 87 | }; | ||
121 | 88 | |||
122 | 89 | template<DimensionTag Tag, typename IntegerType> | ||
123 | 90 | std::ostream& operator<<(std::ostream& out, IntWrapper<Tag, IntegerType> const& value) | ||
124 | 91 | { | ||
125 | 92 | out << value.template as<>(); | ||
126 | 93 | return out; | ||
127 | 94 | } | ||
128 | 95 | |||
129 | 96 | template<DimensionTag Tag, typename IntegerType> | ||
130 | 97 | inline bool operator == (IntWrapper<Tag, IntegerType> const& lhs, IntWrapper<Tag, IntegerType> const& rhs) | ||
131 | 98 | { | ||
132 | 99 | return lhs.template as<>() == rhs.template as<>(); | ||
133 | 100 | } | ||
134 | 101 | |||
135 | 102 | template<DimensionTag Tag, typename IntegerType> | ||
136 | 103 | inline bool operator != (IntWrapper<Tag, IntegerType> const& lhs, IntWrapper<Tag, IntegerType> const& rhs) | ||
137 | 104 | { | ||
138 | 105 | return lhs.template as<>() != rhs.template as<>(); | ||
139 | 106 | } | ||
140 | 107 | |||
141 | 108 | template<DimensionTag Tag, typename IntegerType> | ||
142 | 109 | inline bool operator <= (IntWrapper<Tag, IntegerType> const& lhs, IntWrapper<Tag, IntegerType> const& rhs) | ||
143 | 110 | { | ||
144 | 111 | return lhs.template as<>() <= rhs.template as<>(); | ||
145 | 112 | } | ||
146 | 113 | |||
147 | 114 | template<DimensionTag Tag, typename IntegerType> | ||
148 | 115 | inline bool operator >= (IntWrapper<Tag, IntegerType> const& lhs, IntWrapper<Tag, IntegerType> const& rhs) | ||
149 | 116 | { | ||
150 | 117 | return lhs.template as<>() >= rhs.template as<>(); | ||
151 | 118 | } | ||
152 | 119 | |||
153 | 120 | template<DimensionTag Tag, typename IntegerType> | ||
154 | 121 | inline bool operator < (IntWrapper<Tag, IntegerType> const& lhs, IntWrapper<Tag, IntegerType> const& rhs) | ||
155 | 122 | { | ||
156 | 123 | return lhs.template as<>() < rhs.template as<>(); | ||
157 | 124 | } | ||
158 | 125 | |||
159 | 126 | template<DimensionTag Tag, typename IntegerType> | ||
160 | 127 | inline bool operator > (IntWrapper<Tag, IntegerType> const& lhs, IntWrapper<Tag, IntegerType> const& rhs) | ||
161 | 128 | { | ||
162 | 129 | return lhs.template as<>() > rhs.template as<>(); | ||
163 | 130 | } | ||
164 | 131 | } // namespace detail | ||
165 | 132 | |||
166 | 133 | /** @brief The integer Height of a video. */ | ||
167 | 134 | typedef detail::IntWrapper<detail::DimensionTag::height, std::uint32_t> Height; | ||
168 | 135 | /** @brief The integer Width of a video. */ | ||
169 | 136 | typedef detail::IntWrapper<detail::DimensionTag::width, std::uint32_t> Width; | ||
170 | 137 | |||
171 | 138 | /** @brief Height and Width of a video. */ | ||
172 | 139 | typedef std::tuple<Height, Width> Dimensions; | ||
173 | 140 | } | ||
174 | 141 | } | ||
175 | 142 | } | ||
176 | 143 | } | ||
177 | 144 | |||
178 | 145 | #endif // CORE_UBUNTU_MEDIA_VIDEO_DIMENSIONS_H_ | ||
179 | 0 | 146 | ||
180 | === modified file 'src/core/media/codec.h' | |||
181 | --- src/core/media/codec.h 2015-01-13 14:18:59 +0000 | |||
182 | +++ src/core/media/codec.h 2015-03-12 11:39:32 +0000 | |||
183 | @@ -232,6 +232,31 @@ | |||
184 | 232 | 232 | ||
185 | 233 | namespace helper | 233 | namespace helper |
186 | 234 | { | 234 | { |
187 | 235 | template<core::ubuntu::media::video::detail::DimensionTag tag, typename IntegerType> | ||
188 | 236 | struct TypeMapper<core::ubuntu::media::video::detail::IntWrapper<tag, IntegerType>> | ||
189 | 237 | { | ||
190 | 238 | constexpr static ArgumentType type_value() | ||
191 | 239 | { | ||
192 | 240 | return core::dbus::ArgumentType::uint32; | ||
193 | 241 | } | ||
194 | 242 | |||
195 | 243 | constexpr static bool is_basic_type() | ||
196 | 244 | { | ||
197 | 245 | return true; | ||
198 | 246 | } | ||
199 | 247 | |||
200 | 248 | constexpr static bool requires_signature() | ||
201 | 249 | { | ||
202 | 250 | return false; | ||
203 | 251 | } | ||
204 | 252 | |||
205 | 253 | static std::string signature() | ||
206 | 254 | { | ||
207 | 255 | static const std::string s = TypeMapper<std::uint32_t>::signature(); | ||
208 | 256 | return s; | ||
209 | 257 | } | ||
210 | 258 | }; | ||
211 | 259 | |||
212 | 235 | template<> | 260 | template<> |
213 | 236 | struct TypeMapper<core::ubuntu::media::Player::Lifetime> | 261 | struct TypeMapper<core::ubuntu::media::Player::Lifetime> |
214 | 237 | { | 262 | { |
215 | @@ -239,10 +264,12 @@ | |||
216 | 239 | { | 264 | { |
217 | 240 | return core::dbus::ArgumentType::int16; | 265 | return core::dbus::ArgumentType::int16; |
218 | 241 | } | 266 | } |
219 | 267 | |||
220 | 242 | constexpr static bool is_basic_type() | 268 | constexpr static bool is_basic_type() |
221 | 243 | { | 269 | { |
223 | 244 | return false; | 270 | return true; |
224 | 245 | } | 271 | } |
225 | 272 | |||
226 | 246 | constexpr static bool requires_signature() | 273 | constexpr static bool requires_signature() |
227 | 247 | { | 274 | { |
228 | 248 | return false; | 275 | return false; |
229 | @@ -256,14 +283,30 @@ | |||
230 | 256 | }; | 283 | }; |
231 | 257 | } | 284 | } |
232 | 258 | 285 | ||
233 | 286 | template<core::ubuntu::media::video::detail::DimensionTag tag, typename IntegerType> | ||
234 | 287 | struct Codec<core::ubuntu::media::video::detail::IntWrapper<tag, IntegerType>> | ||
235 | 288 | { | ||
236 | 289 | static void encode_argument(core::dbus::Message::Writer& out, const core::ubuntu::media::video::detail::IntWrapper<tag, IntegerType>& in) | ||
237 | 290 | { | ||
238 | 291 | out.push_uint32(in.template as<std::uint32_t>()); | ||
239 | 292 | } | ||
240 | 293 | |||
241 | 294 | static void decode_argument(core::dbus::Message::Reader& out, core::ubuntu::media::video::detail::IntWrapper<tag, IntegerType>& in) | ||
242 | 295 | { | ||
243 | 296 | in = core::ubuntu::media::video::detail::IntWrapper<tag, IntegerType>{out.pop_uint32()}; | ||
244 | 297 | } | ||
245 | 298 | }; | ||
246 | 299 | |||
247 | 259 | template<> | 300 | template<> |
248 | 260 | struct Codec<core::ubuntu::media::Player::Lifetime> | 301 | struct Codec<core::ubuntu::media::Player::Lifetime> |
249 | 261 | { | 302 | { |
250 | 303 | |||
251 | 262 | static void encode_argument(core::dbus::Message::Writer& out, const core::ubuntu::media::Player::Lifetime& in) | 304 | static void encode_argument(core::dbus::Message::Writer& out, const core::ubuntu::media::Player::Lifetime& in) |
252 | 263 | { | 305 | { |
253 | 264 | out.push_int16(static_cast<std::int16_t>(in)); | 306 | out.push_int16(static_cast<std::int16_t>(in)); |
254 | 265 | } | 307 | } |
255 | 266 | 308 | ||
256 | 309 | |||
257 | 267 | static void decode_argument(core::dbus::Message::Reader& out, core::ubuntu::media::Player::Lifetime& in) | 310 | static void decode_argument(core::dbus::Message::Reader& out, core::ubuntu::media::Player::Lifetime& in) |
258 | 268 | { | 311 | { |
259 | 269 | in = static_cast<core::ubuntu::media::Player::Lifetime>(out.pop_int16()); | 312 | in = static_cast<core::ubuntu::media::Player::Lifetime>(out.pop_int16()); |
260 | 270 | 313 | ||
261 | === modified file 'src/core/media/engine.h' | |||
262 | --- src/core/media/engine.h 2015-03-12 11:39:32 +0000 | |||
263 | +++ src/core/media/engine.h 2015-03-12 11:39:32 +0000 | |||
264 | @@ -110,7 +110,7 @@ | |||
265 | 110 | virtual const core::Signal<void>& client_disconnected_signal() const = 0; | 110 | virtual const core::Signal<void>& client_disconnected_signal() const = 0; |
266 | 111 | virtual const core::Signal<void>& end_of_stream_signal() const = 0; | 111 | virtual const core::Signal<void>& end_of_stream_signal() const = 0; |
267 | 112 | virtual const core::Signal<core::ubuntu::media::Player::PlaybackStatus>& playback_status_changed_signal() const = 0; | 112 | virtual const core::Signal<core::ubuntu::media::Player::PlaybackStatus>& playback_status_changed_signal() const = 0; |
269 | 113 | virtual const core::Signal<uint32_t, uint32_t>& video_dimension_changed_signal() const = 0; | 113 | virtual const core::Signal<video::Dimensions>& video_dimension_changed_signal() const = 0; |
270 | 114 | virtual const core::Signal<core::ubuntu::media::Player::Error>& error_signal() const = 0; | 114 | virtual const core::Signal<core::ubuntu::media::Player::Error>& error_signal() const = 0; |
271 | 115 | 115 | ||
272 | 116 | virtual void reset() = 0; | 116 | virtual void reset() = 0; |
273 | 117 | 117 | ||
274 | === modified file 'src/core/media/gstreamer/engine.cpp' | |||
275 | --- src/core/media/gstreamer/engine.cpp 2015-01-19 21:48:01 +0000 | |||
276 | +++ src/core/media/gstreamer/engine.cpp 2015-03-12 11:39:32 +0000 | |||
277 | @@ -175,9 +175,9 @@ | |||
278 | 175 | end_of_stream(); | 175 | end_of_stream(); |
279 | 176 | } | 176 | } |
280 | 177 | 177 | ||
282 | 178 | void on_video_dimension_changed(uint32_t height, uint32_t width) | 178 | void on_video_dimension_changed(const media::video::Dimensions& dimensions) |
283 | 179 | { | 179 | { |
285 | 180 | video_dimension_changed(height, width); | 180 | video_dimension_changed(dimensions); |
286 | 181 | } | 181 | } |
287 | 182 | 182 | ||
288 | 183 | Private() | 183 | Private() |
289 | @@ -262,12 +262,11 @@ | |||
290 | 262 | &Private::on_end_of_stream, | 262 | &Private::on_end_of_stream, |
291 | 263 | this))), | 263 | this))), |
292 | 264 | on_video_dimension_changed_connection( | 264 | on_video_dimension_changed_connection( |
294 | 265 | playbin.signals.on_add_frame_dimension.connect( | 265 | playbin.signals.on_video_dimensions_changed.connect( |
295 | 266 | std::bind( | 266 | std::bind( |
296 | 267 | &Private::on_video_dimension_changed, | 267 | &Private::on_video_dimension_changed, |
297 | 268 | this, | 268 | this, |
300 | 269 | std::placeholders::_1, | 269 | std::placeholders::_1))) |
299 | 270 | std::placeholders::_2))) | ||
301 | 271 | { | 270 | { |
302 | 272 | } | 271 | } |
303 | 273 | 272 | ||
304 | @@ -307,7 +306,7 @@ | |||
305 | 307 | core::Signal<void> client_disconnected; | 306 | core::Signal<void> client_disconnected; |
306 | 308 | core::Signal<void> end_of_stream; | 307 | core::Signal<void> end_of_stream; |
307 | 309 | core::Signal<media::Player::PlaybackStatus> playback_status_changed; | 308 | core::Signal<media::Player::PlaybackStatus> playback_status_changed; |
309 | 310 | core::Signal<uint32_t, uint32_t> video_dimension_changed; | 309 | core::Signal<core::ubuntu::media::video::Dimensions> video_dimension_changed; |
310 | 311 | core::Signal<media::Player::Error> error; | 310 | core::Signal<media::Player::Error> error; |
311 | 312 | }; | 311 | }; |
312 | 313 | 312 | ||
313 | @@ -500,7 +499,7 @@ | |||
314 | 500 | return d->playback_status_changed; | 499 | return d->playback_status_changed; |
315 | 501 | } | 500 | } |
316 | 502 | 501 | ||
318 | 503 | const core::Signal<uint32_t, uint32_t>& gstreamer::Engine::video_dimension_changed_signal() const | 502 | const core::Signal<core::ubuntu::media::video::Dimensions>& gstreamer::Engine::video_dimension_changed_signal() const |
319 | 504 | { | 503 | { |
320 | 505 | return d->video_dimension_changed; | 504 | return d->video_dimension_changed; |
321 | 506 | } | 505 | } |
322 | 507 | 506 | ||
323 | === modified file 'src/core/media/gstreamer/engine.h' | |||
324 | --- src/core/media/gstreamer/engine.h 2015-01-13 14:18:59 +0000 | |||
325 | +++ src/core/media/gstreamer/engine.h 2015-03-12 11:39:32 +0000 | |||
326 | @@ -66,7 +66,7 @@ | |||
327 | 66 | const core::Signal<void>& client_disconnected_signal() const; | 66 | const core::Signal<void>& client_disconnected_signal() const; |
328 | 67 | const core::Signal<void>& end_of_stream_signal() const; | 67 | const core::Signal<void>& end_of_stream_signal() const; |
329 | 68 | const core::Signal<core::ubuntu::media::Player::PlaybackStatus>& playback_status_changed_signal() const; | 68 | const core::Signal<core::ubuntu::media::Player::PlaybackStatus>& playback_status_changed_signal() const; |
331 | 69 | const core::Signal<uint32_t, uint32_t>& video_dimension_changed_signal() const; | 69 | const core::Signal<core::ubuntu::media::video::Dimensions>& video_dimension_changed_signal() const; |
332 | 70 | const core::Signal<core::ubuntu::media::Player::Error>& error_signal() const; | 70 | const core::Signal<core::ubuntu::media::Player::Error>& error_signal() const; |
333 | 71 | 71 | ||
334 | 72 | void reset(); | 72 | void reset(); |
335 | 73 | 73 | ||
336 | === modified file 'src/core/media/gstreamer/playbin.h' | |||
337 | --- src/core/media/gstreamer/playbin.h 2014-11-11 23:59:07 +0000 | |||
338 | +++ src/core/media/gstreamer/playbin.h 2015-03-12 11:39:32 +0000 | |||
339 | @@ -85,8 +85,6 @@ | |||
340 | 85 | bus{gst_element_get_bus(pipeline)}, | 85 | bus{gst_element_get_bus(pipeline)}, |
341 | 86 | file_type(MEDIA_FILE_TYPE_NONE), | 86 | file_type(MEDIA_FILE_TYPE_NONE), |
342 | 87 | video_sink(nullptr), | 87 | video_sink(nullptr), |
343 | 88 | video_height(0), | ||
344 | 89 | video_width(0), | ||
345 | 90 | on_new_message_connection( | 88 | on_new_message_connection( |
346 | 91 | bus.on_new_message.connect( | 89 | bus.on_new_message.connect( |
347 | 92 | std::bind( | 90 | std::bind( |
348 | @@ -425,19 +423,22 @@ | |||
349 | 425 | pipeline, | 423 | pipeline, |
350 | 426 | ¤t, | 424 | ¤t, |
351 | 427 | &pending, | 425 | &pending, |
353 | 428 | state_change_timeout.count()); | 426 | state_change_timeout.count()); |
354 | 427 | break; | ||
355 | 428 | } | ||
356 | 429 | 429 | ||
358 | 430 | if (new_state == GST_STATE_PLAYING) | 430 | // The state change has to have been successful to make |
359 | 431 | // sure that we indeed reached the requested new state. | ||
360 | 432 | if (result && new_state == GST_STATE_PLAYING) | ||
361 | 431 | { | 433 | { |
362 | 432 | // Get the video height/width from the video sink | 434 | // Get the video height/width from the video sink |
364 | 433 | get_video_dimensions(); | 435 | if (has_video_sink_with_height_and_width()) |
365 | 436 | signals.on_video_dimensions_changed(get_video_dimensions()); | ||
366 | 434 | #ifdef DEBUG_GST_PIPELINE | 437 | #ifdef DEBUG_GST_PIPELINE |
367 | 435 | std::cout << "Dumping pipeline dot file" << std::endl; | 438 | std::cout << "Dumping pipeline dot file" << std::endl; |
368 | 436 | GST_DEBUG_BIN_TO_DOT_FILE((GstBin*)pipeline, GST_DEBUG_GRAPH_SHOW_ALL, "pipeline"); | 439 | GST_DEBUG_BIN_TO_DOT_FILE((GstBin*)pipeline, GST_DEBUG_GRAPH_SHOW_ALL, "pipeline"); |
369 | 437 | #endif | 440 | #endif |
370 | 438 | } | 441 | } |
371 | 439 | break; | ||
372 | 440 | } | ||
373 | 441 | 442 | ||
374 | 442 | return result; | 443 | return result; |
375 | 443 | } | 444 | } |
376 | @@ -452,27 +453,26 @@ | |||
377 | 452 | ms.count() * 1000); | 453 | ms.count() * 1000); |
378 | 453 | } | 454 | } |
379 | 454 | 455 | ||
383 | 455 | void get_video_dimensions() | 456 | bool has_video_sink_with_height_and_width() |
384 | 456 | { | 457 | { |
385 | 457 | if (video_sink != nullptr && g_strcmp0(::getenv("CORE_UBUNTU_MEDIA_SERVICE_VIDEO_SINK_NAME"), "mirsink") == 0) | 458 | return video_sink != nullptr && g_strcmp0(::getenv("CORE_UBUNTU_MEDIA_SERVICE_VIDEO_SINK_NAME"), "mirsink") == 0; |
386 | 459 | } | ||
387 | 460 | |||
388 | 461 | core::ubuntu::media::video::Dimensions get_video_dimensions() | ||
389 | 462 | { | ||
390 | 463 | if (not has_video_sink_with_height_and_width()) | ||
391 | 464 | throw std::runtime_error{"Could not get the height/width of each video frame"}; | ||
392 | 465 | |||
393 | 466 | uint32_t video_height = 0, video_width = 0; | ||
394 | 467 | g_object_get (video_sink, "height", &video_height, nullptr); | ||
395 | 468 | g_object_get (video_sink, "width", &video_width, nullptr); | ||
396 | 469 | std::cout << "video_height: " << video_height << ", video_width: " << video_width << std::endl; | ||
397 | 470 | |||
398 | 471 | return core::ubuntu::media::video::Dimensions | ||
399 | 458 | { | 472 | { |
417 | 459 | g_object_get (video_sink, "height", &video_height, nullptr); | 473 | core::ubuntu::media::video::Height{video_height}, |
418 | 460 | g_object_get (video_sink, "width", &video_width, nullptr); | 474 | core::ubuntu::media::video::Width{video_width} |
419 | 461 | std::cout << "video_height: " << video_height << ", video_width: " << video_width << std::endl; | 475 | }; |
403 | 462 | signals.on_add_frame_dimension(video_height, video_width); | ||
404 | 463 | } | ||
405 | 464 | else | ||
406 | 465 | std::cerr << "Could not get the height/width of each video frame" << std::endl; | ||
407 | 466 | } | ||
408 | 467 | |||
409 | 468 | int get_video_height() const | ||
410 | 469 | { | ||
411 | 470 | return video_height; | ||
412 | 471 | } | ||
413 | 472 | |||
414 | 473 | int get_video_width() const | ||
415 | 474 | { | ||
416 | 475 | return video_width; | ||
420 | 476 | } | 476 | } |
421 | 477 | 477 | ||
422 | 478 | std::string get_file_content_type(const std::string& uri) const | 478 | std::string get_file_content_type(const std::string& uri) const |
423 | @@ -555,8 +555,6 @@ | |||
424 | 555 | MediaFileType file_type; | 555 | MediaFileType file_type; |
425 | 556 | SurfaceTextureClientHybris stc_hybris; | 556 | SurfaceTextureClientHybris stc_hybris; |
426 | 557 | GstElement* video_sink; | 557 | GstElement* video_sink; |
427 | 558 | uint32_t video_height; | ||
428 | 559 | uint32_t video_width; | ||
429 | 560 | core::Connection on_new_message_connection; | 558 | core::Connection on_new_message_connection; |
430 | 561 | bool is_seeking; | 559 | bool is_seeking; |
431 | 562 | core::ubuntu::media::Player::HeadersType request_headers; | 560 | core::ubuntu::media::Player::HeadersType request_headers; |
432 | @@ -571,9 +569,9 @@ | |||
433 | 571 | core::Signal<Bus::Message::Detail::StateChanged> on_state_changed; | 569 | core::Signal<Bus::Message::Detail::StateChanged> on_state_changed; |
434 | 572 | core::Signal<uint64_t> on_seeked_to; | 570 | core::Signal<uint64_t> on_seeked_to; |
435 | 573 | core::Signal<void> on_end_of_stream; | 571 | core::Signal<void> on_end_of_stream; |
439 | 574 | core::Signal<media::Player::PlaybackStatus> on_playback_status_changed; | 572 | core::Signal<core::ubuntu::media::Player::PlaybackStatus> on_playback_status_changed; |
440 | 575 | core::Signal<media::Player::Orientation> on_orientation_changed; | 573 | core::Signal<core::ubuntu::media::Player::Orientation> on_orientation_changed; |
441 | 576 | core::Signal<uint32_t, uint32_t> on_add_frame_dimension; | 574 | core::Signal<core::ubuntu::media::video::Dimensions> on_video_dimensions_changed; |
442 | 577 | core::Signal<void> client_disconnected; | 575 | core::Signal<void> client_disconnected; |
443 | 578 | } signals; | 576 | } signals; |
444 | 579 | }; | 577 | }; |
445 | 580 | 578 | ||
446 | === modified file 'src/core/media/mpris/player.h' | |||
447 | --- src/core/media/mpris/player.h 2015-03-12 11:39:32 +0000 | |||
448 | +++ src/core/media/mpris/player.h 2015-03-12 11:39:32 +0000 | |||
449 | @@ -34,12 +34,16 @@ | |||
450 | 34 | #include <core/dbus/types/object_path.h> | 34 | #include <core/dbus/types/object_path.h> |
451 | 35 | #include <core/dbus/types/variant.h> | 35 | #include <core/dbus/types/variant.h> |
452 | 36 | 36 | ||
453 | 37 | #include <core/dbus/types/stl/tuple.h> | ||
454 | 38 | |||
455 | 37 | #include <boost/utility/identity_type.hpp> | 39 | #include <boost/utility/identity_type.hpp> |
456 | 38 | 40 | ||
457 | 39 | #include <string> | 41 | #include <string> |
458 | 40 | #include <tuple> | 42 | #include <tuple> |
459 | 41 | #include <vector> | 43 | #include <vector> |
460 | 42 | 44 | ||
461 | 45 | #include <cstdint> | ||
462 | 46 | |||
463 | 43 | namespace dbus = core::dbus; | 47 | namespace dbus = core::dbus; |
464 | 44 | 48 | ||
465 | 45 | namespace mpris | 49 | namespace mpris |
466 | @@ -134,7 +138,7 @@ | |||
467 | 134 | DBUS_CPP_SIGNAL_DEF(Seeked, Player, std::int64_t) | 138 | DBUS_CPP_SIGNAL_DEF(Seeked, Player, std::int64_t) |
468 | 135 | DBUS_CPP_SIGNAL_DEF(EndOfStream, Player, void) | 139 | DBUS_CPP_SIGNAL_DEF(EndOfStream, Player, void) |
469 | 136 | DBUS_CPP_SIGNAL_DEF(PlaybackStatusChanged, Player, core::ubuntu::media::Player::PlaybackStatus) | 140 | DBUS_CPP_SIGNAL_DEF(PlaybackStatusChanged, Player, core::ubuntu::media::Player::PlaybackStatus) |
471 | 137 | DBUS_CPP_SIGNAL_DEF(VideoDimensionChanged, Player, std::uint64_t) | 141 | DBUS_CPP_SIGNAL_DEF(VideoDimensionChanged, Player, core::ubuntu::media::video::Dimensions) |
472 | 138 | DBUS_CPP_SIGNAL_DEF(Error, Player, core::ubuntu::media::Player::Error) | 142 | DBUS_CPP_SIGNAL_DEF(Error, Player, core::ubuntu::media::Player::Error) |
473 | 139 | }; | 143 | }; |
474 | 140 | 144 | ||
475 | 141 | 145 | ||
476 | === modified file 'src/core/media/player_implementation.cpp' | |||
477 | --- src/core/media/player_implementation.cpp 2015-03-12 11:39:32 +0000 | |||
478 | +++ src/core/media/player_implementation.cpp 2015-03-12 11:39:32 +0000 | |||
479 | @@ -415,12 +415,9 @@ | |||
480 | 415 | playback_status_changed()(status); | 415 | playback_status_changed()(status); |
481 | 416 | }); | 416 | }); |
482 | 417 | 417 | ||
484 | 418 | d->engine->video_dimension_changed_signal().connect([this](uint32_t height, uint32_t width) | 418 | d->engine->video_dimension_changed_signal().connect([this](const media::video::Dimensions& dimensions) |
485 | 419 | { | 419 | { |
490 | 420 | uint64_t mask = 0; | 420 | video_dimension_changed()(dimensions); |
487 | 421 | // Left most 32 bits are for height, right most 32 bits are for width | ||
488 | 422 | mask = (static_cast<uint64_t>(height) << 32) | static_cast<uint64_t>(width); | ||
489 | 423 | video_dimension_changed()(mask); | ||
491 | 424 | }); | 421 | }); |
492 | 425 | 422 | ||
493 | 426 | d->engine->error_signal().connect([this](const Player::Error& e) | 423 | d->engine->error_signal().connect([this](const Player::Error& e) |
494 | 427 | 424 | ||
495 | === modified file 'src/core/media/player_skeleton.cpp' | |||
496 | --- src/core/media/player_skeleton.cpp 2015-03-12 11:39:32 +0000 | |||
497 | +++ src/core/media/player_skeleton.cpp 2015-03-12 11:39:32 +0000 | |||
498 | @@ -19,6 +19,7 @@ | |||
499 | 19 | 19 | ||
500 | 20 | #include "apparmor.h" | 20 | #include "apparmor.h" |
501 | 21 | #include "codec.h" | 21 | #include "codec.h" |
502 | 22 | #include "engine.h" | ||
503 | 22 | #include "player_skeleton.h" | 23 | #include "player_skeleton.h" |
504 | 23 | #include "player_traits.h" | 24 | #include "player_traits.h" |
505 | 24 | #include "property_stub.h" | 25 | #include "property_stub.h" |
506 | @@ -338,9 +339,9 @@ | |||
507 | 338 | remote_playback_status_changed->emit(status); | 339 | remote_playback_status_changed->emit(status); |
508 | 339 | }); | 340 | }); |
509 | 340 | 341 | ||
511 | 341 | video_dimension_changed.connect([remote_video_dimension_changed](uint64_t mask) | 342 | video_dimension_changed.connect([remote_video_dimension_changed](const media::video::Dimensions& dimensions) |
512 | 342 | { | 343 | { |
514 | 343 | remote_video_dimension_changed->emit(mask); | 344 | remote_video_dimension_changed->emit(dimensions); |
515 | 344 | }); | 345 | }); |
516 | 345 | 346 | ||
517 | 346 | error.connect([remote_error](const media::Player::Error& e) | 347 | error.connect([remote_error](const media::Player::Error& e) |
518 | @@ -352,7 +353,7 @@ | |||
519 | 352 | core::Signal<int64_t> seeked_to; | 353 | core::Signal<int64_t> seeked_to; |
520 | 353 | core::Signal<void> end_of_stream; | 354 | core::Signal<void> end_of_stream; |
521 | 354 | core::Signal<media::Player::PlaybackStatus> playback_status_changed; | 355 | core::Signal<media::Player::PlaybackStatus> playback_status_changed; |
523 | 355 | core::Signal<uint64_t> video_dimension_changed; | 356 | core::Signal<media::video::Dimensions> video_dimension_changed; |
524 | 356 | core::Signal<media::Player::Error> error; | 357 | core::Signal<media::Player::Error> error; |
525 | 357 | } signals; | 358 | } signals; |
526 | 358 | 359 | ||
527 | @@ -649,12 +650,12 @@ | |||
528 | 649 | return d->signals.playback_status_changed; | 650 | return d->signals.playback_status_changed; |
529 | 650 | } | 651 | } |
530 | 651 | 652 | ||
532 | 652 | const core::Signal<uint64_t>& media::PlayerSkeleton::video_dimension_changed() const | 653 | const core::Signal<media::video::Dimensions>& media::PlayerSkeleton::video_dimension_changed() const |
533 | 653 | { | 654 | { |
534 | 654 | return d->signals.video_dimension_changed; | 655 | return d->signals.video_dimension_changed; |
535 | 655 | } | 656 | } |
536 | 656 | 657 | ||
538 | 657 | core::Signal<uint64_t>& media::PlayerSkeleton::video_dimension_changed() | 658 | core::Signal<media::video::Dimensions>& media::PlayerSkeleton::video_dimension_changed() |
539 | 658 | { | 659 | { |
540 | 659 | return d->signals.video_dimension_changed; | 660 | return d->signals.video_dimension_changed; |
541 | 660 | } | 661 | } |
542 | 661 | 662 | ||
543 | === modified file 'src/core/media/player_skeleton.h' | |||
544 | --- src/core/media/player_skeleton.h 2015-01-13 14:18:59 +0000 | |||
545 | +++ src/core/media/player_skeleton.h 2015-03-12 11:39:32 +0000 | |||
546 | @@ -75,7 +75,7 @@ | |||
547 | 75 | virtual const core::Signal<int64_t>& seeked_to() const; | 75 | virtual const core::Signal<int64_t>& seeked_to() const; |
548 | 76 | virtual const core::Signal<void>& end_of_stream() const; | 76 | virtual const core::Signal<void>& end_of_stream() const; |
549 | 77 | virtual core::Signal<PlaybackStatus>& playback_status_changed(); | 77 | virtual core::Signal<PlaybackStatus>& playback_status_changed(); |
551 | 78 | virtual const core::Signal<uint64_t>& video_dimension_changed() const; | 78 | virtual const core::Signal<video::Dimensions>& video_dimension_changed() const; |
552 | 79 | virtual const core::Signal<Error>& error() const; | 79 | virtual const core::Signal<Error>& error() const; |
553 | 80 | 80 | ||
554 | 81 | protected: | 81 | protected: |
555 | @@ -112,7 +112,7 @@ | |||
556 | 112 | 112 | ||
557 | 113 | virtual core::Signal<int64_t>& seeked_to(); | 113 | virtual core::Signal<int64_t>& seeked_to(); |
558 | 114 | virtual core::Signal<void>& end_of_stream(); | 114 | virtual core::Signal<void>& end_of_stream(); |
560 | 115 | virtual core::Signal<uint64_t>& video_dimension_changed(); | 115 | virtual core::Signal<video::Dimensions>& video_dimension_changed(); |
561 | 116 | virtual core::Signal<Error>& error(); | 116 | virtual core::Signal<Error>& error(); |
562 | 117 | 117 | ||
563 | 118 | private: | 118 | private: |
564 | 119 | 119 | ||
565 | === modified file 'src/core/media/player_stub.cpp' | |||
566 | --- src/core/media/player_stub.cpp 2015-03-12 11:39:32 +0000 | |||
567 | +++ src/core/media/player_stub.cpp 2015-03-12 11:39:32 +0000 | |||
568 | @@ -168,10 +168,10 @@ | |||
569 | 168 | playback_status_changed(status); | 168 | playback_status_changed(status); |
570 | 169 | }); | 169 | }); |
571 | 170 | 170 | ||
573 | 171 | dbus.video_dimension_changed->connect([this](uint64_t mask) | 171 | dbus.video_dimension_changed->connect([this](const media::video::Dimensions dimensions) |
574 | 172 | { | 172 | { |
575 | 173 | std::cout << "VideoDimensionChanged signal arrived via the bus." << std::endl; | 173 | std::cout << "VideoDimensionChanged signal arrived via the bus." << std::endl; |
577 | 174 | video_dimension_changed(mask); | 174 | video_dimension_changed(dimensions); |
578 | 175 | }); | 175 | }); |
579 | 176 | 176 | ||
580 | 177 | dbus.error->connect([this](const media::Player::Error& e) | 177 | dbus.error->connect([this](const media::Player::Error& e) |
581 | @@ -184,7 +184,7 @@ | |||
582 | 184 | core::Signal<int64_t> seeked_to; | 184 | core::Signal<int64_t> seeked_to; |
583 | 185 | core::Signal<void> end_of_stream; | 185 | core::Signal<void> end_of_stream; |
584 | 186 | core::Signal<media::Player::PlaybackStatus> playback_status_changed; | 186 | core::Signal<media::Player::PlaybackStatus> playback_status_changed; |
586 | 187 | core::Signal<uint64_t> video_dimension_changed; | 187 | core::Signal<media::video::Dimensions> video_dimension_changed; |
587 | 188 | core::Signal<media::Player::Error> error; | 188 | core::Signal<media::Player::Error> error; |
588 | 189 | 189 | ||
589 | 190 | struct DBus | 190 | struct DBus |
590 | @@ -448,7 +448,7 @@ | |||
591 | 448 | return d->signals.playback_status_changed; | 448 | return d->signals.playback_status_changed; |
592 | 449 | } | 449 | } |
593 | 450 | 450 | ||
595 | 451 | const core::Signal<uint64_t>& media::PlayerStub::video_dimension_changed() const | 451 | const core::Signal<media::video::Dimensions>& media::PlayerStub::video_dimension_changed() const |
596 | 452 | { | 452 | { |
597 | 453 | return d->signals.video_dimension_changed; | 453 | return d->signals.video_dimension_changed; |
598 | 454 | } | 454 | } |
599 | 455 | 455 | ||
600 | === modified file 'src/core/media/player_stub.h' | |||
601 | --- src/core/media/player_stub.h 2015-03-12 11:39:32 +0000 | |||
602 | +++ src/core/media/player_stub.h 2015-03-12 11:39:32 +0000 | |||
603 | @@ -88,7 +88,7 @@ | |||
604 | 88 | virtual const core::Signal<int64_t>& seeked_to() const; | 88 | virtual const core::Signal<int64_t>& seeked_to() const; |
605 | 89 | virtual const core::Signal<void>& end_of_stream() const; | 89 | virtual const core::Signal<void>& end_of_stream() const; |
606 | 90 | virtual core::Signal<PlaybackStatus>& playback_status_changed(); | 90 | virtual core::Signal<PlaybackStatus>& playback_status_changed(); |
608 | 91 | virtual const core::Signal<uint64_t>& video_dimension_changed() const; | 91 | virtual const core::Signal<video::Dimensions>& video_dimension_changed() const; |
609 | 92 | virtual const core::Signal<Error>& error() const; | 92 | virtual const core::Signal<Error>& error() const; |
610 | 93 | 93 | ||
611 | 94 | private: | 94 | private: |
FAILED: Continuous integration, rev:100 jenkins. qa.ubuntu. com/job/ media-hub- ci/177/ jenkins. qa.ubuntu. com/job/ media-hub- vivid-amd64- ci/17/console jenkins. qa.ubuntu. com/job/ media-hub- vivid-armhf- ci/17/console jenkins. qa.ubuntu. com/job/ media-hub- vivid-i386- ci/17/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/media- hub-ci/ 177/rebuild
http://