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

Proposed by Robert Bruce Park
Status: Merged
Approved by: Robert Bruce Park
Approved revision: 151
Merged at revision: 153
Proposed branch: lp:~robru/media-hub/get-selected-streams
Merge into: lp:media-hub/stable
Diff against target: 256 lines (+111/-13)
6 files modified
debian/changelog (+7/-6)
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)
To merge this branch: bzr merge lp:~robru/media-hub/get-selected-streams
Reviewer Review Type Date Requested Status
Ubuntu Phablet Team Pending
Review via email: mp+270210@code.launchpad.net
To post a comment you must log in.

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

Subscribers

People subscribed via source and target branches