Merge lp:~alfonsosanchezbeato/media-hub/get-selected-streams into lp:media-hub

Proposed by Alfonso Sanchez-Beato
Status: Merged
Merged at revision: 156
Proposed branch: lp:~alfonsosanchezbeato/media-hub/get-selected-streams
Merge into: lp:media-hub
Diff against target: 291 lines (+119/-11) (has conflicts)
6 files modified
debian/changelog (+15/-4)
debian/control (+1/-0)
src/core/media/CMakeLists.txt (+2/-0)
src/core/media/gstreamer/engine.cpp (+22/-5)
src/core/media/gstreamer/playbin.cpp (+72/-2)
src/core/media/gstreamer/playbin.h (+7/-0)
Text conflict in debian/changelog
To merge this branch: bzr merge lp:~alfonsosanchezbeato/media-hub/get-selected-streams
Reviewer Review Type Date Requested Status
Jim Hodapp (community) code Approve
Review via email: mp+266251@code.launchpad.net

Commit message

Gather information about missing codecs and selected streams from gstreamer
so we have more information on whether we should play the video or not (LP: #1417950).

Description of the change

Gather information about missing codecs and selected streams from gstreamer
so we have more information on whether we should play the video or not (LP: #1417950).

To post a comment you must log in.
Revision history for this message
Jim Hodapp (jhodapp) wrote :

A few suggestions below. I like the general direction of this approach. Are you planning on adding anything else to it or is this it?

review: Needs Fixing (code)
Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

Comments addressed. @Jim, yes, for the moment this is it until we modify media-hub's DBus interface so we can transmit more information to the client like:

* Available tracks with type and description
* Information on which tracks can be played and which not due to missing codecs
* A way to select the tracks to play
* An intermediate state in which we can access to this information but we are still not playing (gstreamer state for the stream would be "paused"). Maybe we can move to that state when media is set instead of moving from the initial gstreamer state to playing when the DBus play() method is invoked.

Revision history for this message
Jim Hodapp (jhodapp) wrote :

See my comments below.

review: Needs Fixing (code)
Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

Comments addressed

Revision history for this message
Jim Hodapp (jhodapp) wrote :

Looks great, thanks. Let me know when you have this in a silo and I'll help test this well.

review: Approve (code)
149. By Alfonso Sanchez-Beato

Gather information about missing codecs and selected streams from gstreamer
so we have more information on whether we should play the video or not.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2015-07-24 14:54:21 +0000
3+++ debian/changelog 2015-08-10 13:09:04 +0000
4@@ -1,3 +1,4 @@
5+<<<<<<< TREE
6 media-hub (3.1.0+15.10.20150724-0ubuntu1) wily; urgency=medium
7
8 [ Alfonso Sanchez-Beato (email Canonical) ]
9@@ -7,6 +8,16 @@
10 -- CI Train Bot <ci-train-bot@canonical.com> Fri, 24 Jul 2015 14:54:21 +0000
11
12 media-hub (3.1.0+15.10.20150710-0ubuntu1) wily; urgency=medium
13+=======
14+media-hub (3.1.0+15.04.20150810-0ubuntu1) UNRELEASED; urgency=medium
15+
16+ * Gather information about missing codecs and selected streams from gstreamer
17+ so we have more information on whether we should play the video or not.
18+
19+ -- Alfonso Sanchez-Beato (email Canonical) <alfonso.sanchez-beato@canonical.com> Mon, 10 Aug 2015 15:04:18 +0200
20+
21+media-hub (3.1.0+15.04.20150710-0ubuntu1) vivid; urgency=medium
22+>>>>>>> MERGE-SOURCE
23
24 [ CI Train Bot ]
25 * New rebuild forced.
26@@ -17,7 +28,7 @@
27
28 -- CI Train Bot <ci-train-bot@canonical.com> Fri, 10 Jul 2015 18:12:21 +0000
29
30-media-hub (3.1.0+15.10.20150604-0ubuntu1) wily; urgency=medium
31+media-hub (3.1.0+15.04.20150604-0ubuntu1) vivid; urgency=medium
32
33 [ CI Train Bot ]
34 * New rebuild forced.
35@@ -28,7 +39,7 @@
36
37 -- CI Train Bot <ci-train-bot@canonical.com> Thu, 04 Jun 2015 14:18:22 +0000
38
39-media-hub (3.1.0+15.10.20150601-0ubuntu1) wily; urgency=medium
40+media-hub (3.1.0+15.04.20150601-0ubuntu1) vivid; urgency=medium
41
42 [ CI Train Bot ]
43 * New rebuild forced.
44@@ -39,7 +50,7 @@
45
46 -- CI Train Bot <ci-train-bot@canonical.com> Mon, 01 Jun 2015 16:31:53 +0000
47
48-media-hub (3.1.0+15.10.20150527.1-0ubuntu1) wily; urgency=medium
49+media-hub (3.1.0+15.04.20150527.1-0ubuntu1) vivid; urgency=medium
50
51 [ CI Train Bot ]
52 * New rebuild forced.
53@@ -50,7 +61,7 @@
54
55 -- CI Train Bot <ci-train-bot@canonical.com> Wed, 27 May 2015 18:38:16 +0000
56
57-media-hub (3.1.0+15.10.20150522-0ubuntu1) wily; urgency=medium
58+media-hub (3.1.0+15.04.20150522-0ubuntu1) vivid; urgency=medium
59
60 [ Jim Hodapp ]
61 * Fix issues with not reporting failed decoding error to the client.
62
63=== modified file 'debian/control'
64--- debian/control 2015-03-12 11:38:32 +0000
65+++ debian/control 2015-08-10 13:09:04 +0000
66@@ -25,6 +25,7 @@
67 libprocess-cpp-dev,
68 libproperties-cpp-dev,
69 libgstreamer1.0-dev,
70+ libgstreamer-plugins-base1.0-dev,
71 pkg-config,
72 libpulse-dev,
73 qtbase5-dev,
74
75=== modified file 'src/core/media/CMakeLists.txt'
76--- src/core/media/CMakeLists.txt 2015-02-24 15:22:19 +0000
77+++ src/core/media/CMakeLists.txt 2015-08-10 13:09:04 +0000
78@@ -1,4 +1,5 @@
79 pkg_check_modules(PC_GSTREAMER_1_0 REQUIRED gstreamer-1.0)
80+pkg_check_modules(PC_GSTREAMER_PBUTILS_1_0 REQUIRED gstreamer-pbutils-1.0)
81 pkg_check_modules(PC_PULSE_AUDIO REQUIRED libpulse)
82 include_directories(${PC_GSTREAMER_1_0_INCLUDE_DIRS} ${HYBRIS_MEDIA_CFLAGS} ${PC_PULSE_AUDIO_INCLUDE_DIRS})
83
84@@ -126,6 +127,7 @@
85 ${DBUS_CPP_LDFLAGS}
86 ${GLog_LIBRARY}
87 ${PC_GSTREAMER_1_0_LIBRARIES}
88+ ${PC_GSTREAMER_PBUTILS_1_0_LIBRARIES}
89 ${PROCESS_CPP_LDFLAGS}
90 ${GIO_LIBRARIES}
91 ${HYBRIS_MEDIA_LIBRARIES}
92
93=== modified file 'src/core/media/gstreamer/engine.cpp'
94--- src/core/media/gstreamer/engine.cpp 2015-06-01 16:30:59 +0000
95+++ src/core/media/gstreamer/engine.cpp 2015-08-10 13:09:04 +0000
96@@ -67,8 +67,22 @@
97 {
98 if (p.second == "playbin")
99 {
100- std::cout << "State changed on playbin: " << p.first.new_state << std::endl;
101- playback_status_changed(gst_state_to_player_status(p.first));
102+ std::cout << "State changed on playbin: "
103+ << gst_element_state_get_name(p.first.new_state) << std::endl;
104+ const auto status = gst_state_to_player_status(p.first);
105+ /*
106+ * When state moves to "paused" the pipeline is already set. We check that we
107+ * have streams to play.
108+ */
109+ if (status == media::Player::PlaybackStatus::paused &&
110+ !playbin.can_play_streams()) {
111+ std::cerr << "** Cannot play: some codecs are missing" << std::endl;
112+ playbin.reset();
113+ const media::Player::Error e = media::Player::Error::format_error;
114+ error(e);
115+ } else {
116+ playback_status_changed(status);
117+ }
118 }
119 }
120
121@@ -149,7 +163,8 @@
122 break;
123 case GST_STREAM_ERROR_CODEC_NOT_FOUND:
124 std::cerr << "** Encountered a GST_STREAM_ERROR_CODEC_NOT_FOUND" << std::endl;
125- ret_error = media::Player::Error::format_error;
126+ // Missing codecs are handled later, when state switches to "paused"
127+ ret_error = media::Player::Error::no_error;
128 break;
129 case GST_STREAM_ERROR_DECODE:
130 std::cerr << "** Encountered a GST_STREAM_ERROR_DECODE" << std::endl;
131@@ -163,8 +178,10 @@
132 }
133 }
134
135- std::cout << "Resetting playbin pipeline after unrecoverable error" << std::endl;
136- playbin.reset();
137+ if (ret_error != media::Player::Error::no_error) {
138+ std::cerr << "Resetting playbin pipeline after unrecoverable error" << std::endl;
139+ playbin.reset();
140+ }
141 return ret_error;
142 }
143
144
145=== modified file 'src/core/media/gstreamer/playbin.cpp'
146--- src/core/media/gstreamer/playbin.cpp 2015-07-24 14:54:19 +0000
147+++ src/core/media/gstreamer/playbin.cpp 2015-08-10 13:09:04 +0000
148@@ -1,5 +1,5 @@
149 /*
150- * Copyright © 2013 Canonical Ltd.
151+ * Copyright © 2013-2015 Canonical Ltd.
152 *
153 * This program is free software: you can redistribute it and/or modify it
154 * under the terms of the GNU Lesser General Public License version 3,
155@@ -20,6 +20,8 @@
156
157 #include <core/media/gstreamer/engine.h>
158
159+#include <gst/pbutils/missing-plugins.h>
160+
161 #if defined(MEDIA_HUB_HAVE_HYBRIS_MEDIA_COMPAT_LAYER)
162 #include <hybris/media/surface_texture_client_hybris.h>
163 #include <hybris/media/media_codec_layer.h>
164@@ -112,7 +114,11 @@
165 core::ubuntu::media::video::Width{0}},
166 player_lifetime(media::Player::Lifetime::normal),
167 about_to_finish_handler_id(0),
168- source_setup_handler_id(0)
169+ source_setup_handler_id(0),
170+ is_missing_audio_codec(false),
171+ is_missing_video_codec(false),
172+ audio_stream_id(-1),
173+ video_stream_id(-1)
174 {
175 if (!pipeline)
176 throw std::runtime_error("Could not create pipeline for playbin.");
177@@ -177,6 +183,44 @@
178 std::cout << "Failed to reset the pipeline state. Client reconnect may not function properly." << std::endl;
179 }
180 file_type = MEDIA_FILE_TYPE_NONE;
181+ is_missing_audio_codec = false;
182+ is_missing_video_codec = false;
183+ audio_stream_id = -1;
184+ video_stream_id = -1;
185+}
186+
187+void gstreamer::Playbin::process_message_element(GstMessage *message)
188+{
189+ if (!gst_is_missing_plugin_message(message))
190+ return;
191+
192+ gchar *desc = gst_missing_plugin_message_get_description(message);
193+ std::cerr << "Missing plugin: " << desc << std::endl;
194+ g_free(desc);
195+
196+ const GstStructure *msg_data = gst_message_get_structure(message);
197+ if (g_strcmp0("decoder", gst_structure_get_string(msg_data, "type")) != 0)
198+ return;
199+
200+ GstCaps *caps;
201+ if (!gst_structure_get(msg_data, "detail", GST_TYPE_CAPS, &caps, NULL)) {
202+ std::cerr << __PRETTY_FUNCTION__ << ": No detail" << std::endl;
203+ return;
204+ }
205+
206+ GstStructure *caps_data = gst_caps_get_structure(caps, 0);
207+ if (!caps_data) {
208+ std::cerr << __PRETTY_FUNCTION__ << ": No caps data" << std::endl;
209+ return;
210+ }
211+
212+ const gchar *mime = gst_structure_get_name(caps_data);
213+ if (strstr(mime, "audio"))
214+ is_missing_audio_codec = true;
215+ else if (strstr(mime, "video"))
216+ is_missing_video_codec = true;
217+
218+ std::cerr << "Missing decoder for " << mime << std::endl;
219 }
220
221 void gstreamer::Playbin::on_new_message_async(const Bus::Message& message)
222@@ -193,8 +237,15 @@
223 signals.on_info(message.detail.error_warning_info);
224 break;
225 case GST_MESSAGE_STATE_CHANGED:
226+ if (message.source == "playbin") {
227+ g_object_get(G_OBJECT(pipeline), "current-audio", &audio_stream_id, NULL);
228+ g_object_get(G_OBJECT(pipeline), "current-video", &video_stream_id, NULL);
229+ }
230 signals.on_state_changed(std::make_pair(message.detail.state_changed, message.source));
231 break;
232+ case GST_MESSAGE_ELEMENT:
233+ process_message_element(message.message);
234+ break;
235 case GST_MESSAGE_TAG:
236 {
237 gchar *orientation;
238@@ -598,3 +649,22 @@
239 {
240 return file_type;
241 }
242+
243+bool gstreamer::Playbin::can_play_streams() const
244+{
245+ /*
246+ * We do not consider that we can play the video when
247+ * 1. No audio stream selected due to missing decoder
248+ * 2. No video stream selected due to missing decoder
249+ * 3. No stream selected at all
250+ * Note that if there are several, say, audio streams, we will play the file
251+ * provided that we can decode just one of them, even if there are missing
252+ * audio codecs. We will also play files with only one type of stream.
253+ */
254+ if ((is_missing_audio_codec && audio_stream_id == -1) ||
255+ (is_missing_video_codec && video_stream_id == -1) ||
256+ (audio_stream_id == -1 && video_stream_id == -1))
257+ return false;
258+ else
259+ return true;
260+}
261
262=== modified file 'src/core/media/gstreamer/playbin.h'
263--- src/core/media/gstreamer/playbin.h 2015-06-12 18:14:05 +0000
264+++ src/core/media/gstreamer/playbin.h 2015-08-10 13:09:04 +0000
265@@ -72,6 +72,7 @@
266
267 void on_new_message(const Bus::Message& message);
268 void on_new_message_async(const Bus::Message& message);
269+ void process_message_element(GstMessage *message);
270
271 gstreamer::Bus& message_bus();
272
273@@ -110,6 +111,8 @@
274
275 MediaFileType media_file_type() const;
276
277+ bool can_play_streams() const;
278+
279 GstElement* pipeline;
280 gstreamer::Bus bus;
281 MediaFileType file_type;
282@@ -137,6 +140,10 @@
283 core::Signal<core::ubuntu::media::video::Dimensions> on_video_dimensions_changed;
284 core::Signal<void> client_disconnected;
285 } signals;
286+ bool is_missing_audio_codec;
287+ bool is_missing_video_codec;
288+ gint audio_stream_id;
289+ gint video_stream_id;
290 };
291 }
292

Subscribers

People subscribed via source and target branches