Merge lp:~phablet-team/media-hub/pulse-output-change-pause into lp:media-hub

Proposed by Jim Hodapp
Status: Merged
Approved by: Ricardo Salveti
Approved revision: 108
Merged at revision: 97
Proposed branch: lp:~phablet-team/media-hub/pulse-output-change-pause
Merge into: lp:media-hub
Diff against target: 534 lines (+361/-8)
7 files modified
debian/control (+1/-0)
debian/media-hub.conf (+1/-1)
src/core/media/CMakeLists.txt (+3/-1)
src/core/media/service_implementation.cpp (+350/-2)
src/core/media/service_skeleton.cpp (+1/-0)
tests/unit-tests/CMakeLists.txt (+1/-0)
tests/unit-tests/test-gstreamer-engine.cpp (+4/-4)
To merge this branch: bzr merge lp:~phablet-team/media-hub/pulse-output-change-pause
Reviewer Review Type Date Requested Status
Jim Hodapp (community) code Approve
PS Jenkins bot continuous-integration Approve
Ricardo Salveti (community) Approve
Review via email: mp+241452@code.launchpad.net

Commit message

* Pause playback when a headphone is unplugged or an A2DP device is unpaired

Description of the change

* Pause playback when a headphone is unplugged or an A2DP device is unpaired

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Ricardo Salveti (rsalveti) wrote :

Comments inline.

Revision history for this message
Ricardo Salveti (rsalveti) :
review: Needs Fixing
98. By Ricardo Mendoza

Address comments and modify logic for deciding when to pause.

99. By Ricardo Mendoza

Merge trunk

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Ricardo Salveti (rsalveti) wrote :

Comments inline.

review: Needs Fixing
100. By Ricardo Mendoza

* Refactor to track sink and server changes, and initial setup.
* Keep track of new sinks and pause media accordingly if not fallbacks are in place.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
101. By Ricardo Mendoza

Address comments

102. By Ricardo Mendoza

Build warning.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Ricardo Salveti (rsalveti) wrote :

Comments inline.

review: Needs Information
103. By Ricardo Mendoza

Log to stdout, remove unwanted subscriptions

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
104. By Ricardo Mendoza

Disable broken tests for vivid. Test framework rework incoming to address flaky tests

105. By Ricardo Mendoza

Disable another test

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Ricardo Salveti (rsalveti) wrote :

Few things when testing with mako:
1) Without a headset and a2dp, it'll always trigger a pause when starting media-hub (at least on touch), as primary_idx starts with 0, which is indeed the primary sink (maybe we should handle the initial case differently?)
2) Media-hub starting at the same time as pulse, creating a race, and not necessarily having enough time to get a valid connection with pulse (I had "Unable to create a connection to the pulseaudio context" when testing, had to restart media-hub to get it to work as expected). Either we create an upstart override similar to the one we have for indicator-sound (waiting for pulseaudio started, touch specific), or we keep trying to create a pulseaudio context for a defined amount of time/tries before giving up

Other than that it looks fine, also worked as expected when an active call was in progress (but it still tried to pause when unplugging my wired headset, but as it was already paused, it didn't change anything).

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

Well the trying to pause is a bit misleading. It calls the function that enumerates through all of the Player instances and looks for one in the playing state that's part of the multimedia audio role. If it doesn't find one playing, it won't actually try to update the GStreamer pipeline state. That's why I say the output of media-hub looks a bit misleading. I do think the first case shouldn't happen though...we should even try to pause before ever playing anything. And #2 is certainly an issue that needs fixing.

106. By Ricardo Mendoza

* Catch uninitialized active sink and dont pause.
* Wait to connect to server in case its not yet available (race)

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
107. By Ricardo Mendoza

Track connection state and restore pulseaudio context if it goes away.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
108. By Ricardo Mendoza

Remove commented out code

Revision history for this message
Jim Hodapp (jhodapp) :
review: Needs Fixing (code)
Revision history for this message
Ricardo Salveti (rsalveti) wrote :

Code is looking good now, tested and works as expected as well.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Jim Hodapp (jhodapp) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/control'
2--- debian/control 2014-11-11 20:18:36 +0000
3+++ debian/control 2014-11-20 18:31:53 +0000
4@@ -28,6 +28,7 @@
5 gstreamer1.0-libav,
6 libgstreamer1.0-dev,
7 pkg-config,
8+ libpulse-dev,
9 qtbase5-dev,
10 libtelepathy-qt5-dev,
11 Standards-Version: 3.9.5
12
13=== modified file 'debian/media-hub.conf'
14--- debian/media-hub.conf 2014-05-20 09:53:23 +0000
15+++ debian/media-hub.conf 2014-11-20 18:31:53 +0000
16@@ -1,6 +1,6 @@
17 description "Starts the media-hub service"
18
19-start on started dbus and xsession SESSION=ubuntu-touch
20+start on started dbus and started pulseaudio and xsession SESSION=ubuntu-touch
21 stop on runlevel [06]
22
23 respawn
24
25=== modified file 'src/core/media/CMakeLists.txt'
26--- src/core/media/CMakeLists.txt 2014-11-03 00:56:55 +0000
27+++ src/core/media/CMakeLists.txt 2014-11-20 18:31:53 +0000
28@@ -1,5 +1,6 @@
29 pkg_check_modules(PC_GSTREAMER_1_0 REQUIRED gstreamer-1.0)
30-include_directories(${PC_GSTREAMER_1_0_INCLUDE_DIRS} ${HYBRIS_MEDIA_CFLAGS})
31+pkg_check_modules(PC_PULSE_AUDIO REQUIRED libpulse)
32+include_directories(${PC_GSTREAMER_1_0_INCLUDE_DIRS} ${HYBRIS_MEDIA_CFLAGS} ${PC_PULSE_AUDIO_INCLUDE_DIRS})
33
34 # We compile with all symbols visible by default. For the shipping library, we strip
35 # out all symbols that are not in core::ubuntu::media*
36@@ -100,6 +101,7 @@
37 ${PROCESS_CPP_LDFLAGS}
38 ${GIO_LIBRARIES}
39 ${HYBRIS_MEDIA_LIBRARIES}
40+ ${PC_PULSE_AUDIO_LIBRARIES}
41 )
42
43 include_directories(${PROJECT_SOURCE_DIR}/src/ ${HYBRIS_MEDIA_CFLAGS})
44
45=== modified file 'src/core/media/service_implementation.cpp'
46--- src/core/media/service_implementation.cpp 2014-11-03 00:56:55 +0000
47+++ src/core/media/service_implementation.cpp 2014-11-20 18:31:53 +0000
48@@ -15,6 +15,9 @@
49 *
50 * Authored by: Thomas Voß <thomas.voss@canonical.com>
51 * Jim Hodapp <jim.hodapp@canonical.com>
52+ * Ricardo Mendoza <ricardo.mendoza@canonical.com>
53+ *
54+ * Note: Some of the PulseAudio code was adapted from telepathy-ofono
55 */
56
57 #include "service_implementation.h"
58@@ -26,11 +29,15 @@
59
60 #include <boost/asio.hpp>
61
62+#include <string>
63 #include <cstdint>
64+#include <cstring>
65 #include <map>
66 #include <memory>
67 #include <thread>
68
69+#include <pulse/pulseaudio.h>
70+
71 #include "util/timeout.h"
72 #include "unity_screen_service.h"
73 #include <hybris/media/media_recorder_layer.h>
74@@ -45,6 +52,11 @@
75 : resume_key(std::numeric_limits<std::uint32_t>::max()),
76 keep_alive(io_service),
77 disp_cookie(0),
78+ pulse_mainloop_api(nullptr),
79+ pulse_context(nullptr),
80+ headphones_connected(false),
81+ a2dp_connected(false),
82+ primary_idx(-1),
83 call_monitor(new CallMonitor)
84 {
85 bus = std::shared_ptr<dbus::Bus>(new dbus::Bus(core::dbus::WellKnownBus::session));
86@@ -54,6 +66,67 @@
87 bus->run();
88 }));
89
90+ // Spawn pulse watchdog
91+ pulse_mainloop = nullptr;
92+ pulse_worker = std::move(std::thread([this]()
93+ {
94+ std::unique_lock<std::mutex> lk(pulse_mutex);
95+ pcv.wait(lk,
96+ [this]{
97+ if (pulse_mainloop != nullptr || pulse_context != nullptr)
98+ {
99+ // We come from instance death, destroy and create.
100+ if (pulse_context != nullptr)
101+ {
102+ pa_threaded_mainloop_lock(pulse_mainloop);
103+ pa_operation *o;
104+ o = pa_context_drain(pulse_context,
105+ [](pa_context *context, void *userdata)
106+ {
107+ (void) context;
108+
109+ Private *p = reinterpret_cast<Private*>(userdata);
110+ pa_threaded_mainloop_signal(p->mainloop(), 0);
111+ }, this);
112+
113+ if (o)
114+ {
115+ while (pa_operation_get_state(o) == PA_OPERATION_RUNNING)
116+ pa_threaded_mainloop_wait(pulse_mainloop);
117+
118+ pa_operation_unref(o);
119+ }
120+
121+ pa_context_set_state_callback(pulse_context, NULL, NULL);
122+ pa_context_set_subscribe_callback(pulse_context, NULL, NULL);
123+ pa_context_disconnect(pulse_context);
124+ pa_context_unref(pulse_context);
125+ pulse_context = nullptr;
126+ pa_threaded_mainloop_unlock(pulse_mainloop);
127+ }
128+ }
129+
130+ if (pulse_mainloop == nullptr)
131+ {
132+ pulse_mainloop = pa_threaded_mainloop_new();
133+
134+ if (pa_threaded_mainloop_start(pulse_mainloop) != 0)
135+ {
136+ std::cerr << "Unable to start pulseaudio mainloop, audio output detection will not function" << std::endl;
137+ pa_threaded_mainloop_free(pulse_mainloop);
138+ pulse_mainloop = nullptr;
139+ }
140+ }
141+
142+ do {
143+ create_pulse_context();
144+ } while (pulse_context == nullptr);
145+
146+ // Wait for next instance death.
147+ return false;
148+ });
149+ }));
150+
151 // Connect the property change signal that will allow media-hub to take appropriate action
152 // when the battery level reaches critical
153 auto stub_service = dbus::Service::use_service(bus, "com.canonical.indicator.power");
154@@ -74,10 +147,22 @@
155
156 ~Private()
157 {
158+ release_pulse_context();
159+
160+ if (pulse_mainloop != nullptr)
161+ {
162+ pa_threaded_mainloop_stop(pulse_mainloop);
163+ pa_threaded_mainloop_free(pulse_mainloop);
164+ pulse_mainloop = nullptr;
165+ }
166+
167 bus->stop();
168
169 if (worker.joinable())
170 worker.join();
171+
172+ if (pulse_worker.joinable())
173+ pulse_worker.join();
174 }
175
176 void media_recording_started(bool started)
177@@ -116,6 +201,249 @@
178 p->media_recording_started(started);
179 }
180
181+ pa_threaded_mainloop *mainloop()
182+ {
183+ return pulse_mainloop;
184+ }
185+
186+ bool is_port_available(pa_card_port_info **ports, uint32_t n_ports, const char *name)
187+ {
188+ bool ret = false;
189+
190+ if (ports != nullptr && n_ports > 0 && name != nullptr)
191+ {
192+ for (uint32_t i=0; i<n_ports; i++)
193+ {
194+ if (strstr(ports[i]->name, name) != nullptr && ports[i]->available != PA_PORT_AVAILABLE_NO)
195+ {
196+ ret = true;
197+ break;
198+ }
199+ }
200+ }
201+
202+ return ret;
203+ }
204+
205+ void update_wired_output()
206+ {
207+ const pa_operation *o = pa_context_get_card_info_by_index(pulse_context, primary_idx,
208+ [](pa_context *context, const pa_card_info *info, int eol, void *userdata)
209+ {
210+ (void) context;
211+ (void) eol;
212+
213+ if (info == nullptr || userdata == nullptr)
214+ return;
215+
216+ Private *p = reinterpret_cast<Private*>(userdata);
217+ if (p->is_port_available(info->ports, info->n_ports, "output-wired"))
218+ {
219+ if (!p->headphones_connected)
220+ std::cout << "Wired headphones connected" << std::endl;
221+ p->headphones_connected = true;
222+ }
223+ else if (p->headphones_connected == true)
224+ {
225+ std::cout << "Wired headphones disconnected" << std::endl;
226+ p->headphones_connected = false;
227+ p->pause_playback_if_necessary(std::get<0>(p->active_sink));
228+ }
229+ }, this);
230+ (void) o;
231+ }
232+
233+ void pause_playback_if_necessary(int index)
234+ {
235+ // Catch uninitialized case (active index == -1)
236+ if (std::get<0>(active_sink) == -1)
237+ return;
238+
239+ if (headphones_connected)
240+ return;
241+
242+ // No headphones/fallback on primary sink? Pause.
243+ if (index == primary_idx)
244+ pause_playback();
245+ }
246+
247+ void set_active_sink(const char *name)
248+ {
249+ const pa_operation *o = pa_context_get_sink_info_by_name(pulse_context, name,
250+ [](pa_context *context, const pa_sink_info *i, int eol, void *userdata)
251+ {
252+ (void) context;
253+
254+ if (eol)
255+ return;
256+
257+ Private *p = reinterpret_cast<Private*>(userdata);
258+ std::tuple<uint32_t, uint32_t, std::string> new_sink(std::make_tuple(i->index, i->card, i->name));
259+
260+ printf("pulsesink: active_sink=('%s',%d,%d) -> ('%s',%d,%d)\n",
261+ std::get<2>(p->active_sink).c_str(), std::get<0>(p->active_sink),
262+ std::get<1>(p->active_sink), i->name, i->index, i->card);
263+
264+ p->pause_playback_if_necessary(i->index);
265+ p->active_sink = new_sink;
266+ }, this);
267+
268+ (void) o;
269+ }
270+
271+ void update_active_sink()
272+ {
273+ const pa_operation *o = pa_context_get_server_info(pulse_context,
274+ [](pa_context *context, const pa_server_info *i, void *userdata)
275+ {
276+ (void) context;
277+
278+ Private *p = reinterpret_cast<Private*>(userdata);
279+ if (i->default_sink_name != std::get<2>(p->active_sink))
280+ p->set_active_sink(i->default_sink_name);
281+ p->update_wired_output();
282+ }, this);
283+
284+ (void) o;
285+ }
286+
287+ void create_pulse_context()
288+ {
289+ if (pulse_context != nullptr)
290+ return;
291+
292+ active_sink = std::make_tuple(-1, -1, "");
293+
294+ bool keep_going = true, ok = true;
295+
296+ pulse_mainloop_api = pa_threaded_mainloop_get_api(pulse_mainloop);
297+ pa_threaded_mainloop_lock(pulse_mainloop);
298+
299+ pulse_context = pa_context_new(pulse_mainloop_api, "MediaHubPulseContext");
300+ pa_context_set_state_callback(pulse_context,
301+ [](pa_context *context, void *userdata)
302+ {
303+ (void) context;
304+ Private *p = reinterpret_cast<Private*>(userdata);
305+ // Signals the pa_threaded_mainloop_wait below to proceed
306+ pa_threaded_mainloop_signal(p->mainloop(), 0);
307+ }, this);
308+
309+ if (pulse_context == nullptr)
310+ {
311+ std::cerr << "Unable to create new pulseaudio context" << std::endl;
312+ pa_threaded_mainloop_unlock(pulse_mainloop);
313+ return;
314+ }
315+
316+ pa_context_connect(pulse_context, nullptr, pa_context_flags_t((int) PA_CONTEXT_NOAUTOSPAWN | (int) PA_CONTEXT_NOFAIL), nullptr);
317+ pa_threaded_mainloop_wait(pulse_mainloop);
318+
319+ while (keep_going)
320+ {
321+ switch (pa_context_get_state(pulse_context))
322+ {
323+ case PA_CONTEXT_CONNECTING: // Wait for service to be available
324+ case PA_CONTEXT_AUTHORIZING:
325+ case PA_CONTEXT_SETTING_NAME:
326+ break;
327+
328+ case PA_CONTEXT_READY:
329+ std::cout << "Pulseaudio connection established." << std::endl;
330+ keep_going = false;
331+ break;
332+
333+ case PA_CONTEXT_FAILED:
334+ case PA_CONTEXT_TERMINATED:
335+ keep_going = false;
336+ ok = false;
337+ break;
338+
339+ default:
340+ std::cerr << "Pulseaudio connection failure: " << pa_strerror(pa_context_errno(pulse_context));
341+ keep_going = false;
342+ ok = false;
343+ }
344+
345+ if (keep_going)
346+ pa_threaded_mainloop_wait(pulse_mainloop);
347+ }
348+
349+ if (ok)
350+ {
351+ pa_context_set_state_callback(pulse_context,
352+ [](pa_context *context, void *userdata)
353+ {
354+ (void) context;
355+ (void) userdata;
356+ Private *p = reinterpret_cast<Private*>(userdata);
357+ std::unique_lock<std::mutex> lk(p->pulse_mutex);
358+ switch (pa_context_get_state(context))
359+ {
360+ case PA_CONTEXT_FAILED:
361+ case PA_CONTEXT_TERMINATED:
362+ p->pcv.notify_all();
363+ break;
364+ default:
365+ break;
366+ }
367+ }, this);
368+
369+ //FIXME: Get index for "sink.primary", the default onboard card on Touch.
370+ pa_context_get_sink_info_by_name(pulse_context, "sink.primary",
371+ [](pa_context *context, const pa_sink_info *i, int eol, void *userdata)
372+ {
373+ (void) context;
374+
375+ if (eol)
376+ return;
377+
378+ Private *p = reinterpret_cast<Private*>(userdata);
379+ p->primary_idx = i->index;
380+ p->update_wired_output();
381+ }, this);
382+
383+ update_active_sink();
384+
385+ pa_context_set_subscribe_callback(pulse_context,
386+ [](pa_context *context, pa_subscription_event_type_t t, uint32_t idx, void *userdata)
387+ {
388+ (void) context;
389+ (void) idx;
390+
391+ if (userdata == nullptr)
392+ return;
393+
394+ Private *p = reinterpret_cast<Private*>(userdata);
395+ if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK)
396+ {
397+ p->update_active_sink();
398+ }
399+ }, this);
400+ pa_context_subscribe(pulse_context, PA_SUBSCRIPTION_MASK_SINK, nullptr, this);
401+ }
402+ else
403+ {
404+ std::cerr << "Connection to pulseaudio failed or was dropped." << std::endl;
405+ pa_context_unref(pulse_context);
406+ pulse_context = nullptr;
407+ }
408+
409+ pa_threaded_mainloop_unlock(pulse_mainloop);
410+ }
411+
412+ void release_pulse_context()
413+ {
414+ if (pulse_context != nullptr)
415+ {
416+ pa_threaded_mainloop_lock(pulse_mainloop);
417+ pa_context_disconnect(pulse_context);
418+ pa_context_unref(pulse_context);
419+ pa_threaded_mainloop_unlock(pulse_mainloop);
420+ pulse_context = nullptr;
421+ }
422+ }
423+
424 // This holds the key of the multimedia role Player instance that was paused
425 // when the battery level reached 10% or 5%
426 media::Player::PlayerKey resume_key;
427@@ -129,14 +457,28 @@
428 int disp_cookie;
429 std::shared_ptr<dbus::Object> uscreen_session;
430 MediaRecorderObserver *observer;
431+
432+ // Pulse-specific
433+ pa_mainloop_api *pulse_mainloop_api;
434+ pa_threaded_mainloop *pulse_mainloop;
435+ pa_context *pulse_context;
436+ std::thread pulse_worker;
437+ std::mutex pulse_mutex;
438+ std::condition_variable pcv;
439+ bool headphones_connected;
440+ bool a2dp_connected;
441+ std::tuple<int, int, std::string> active_sink;
442+ int primary_idx;
443+
444+ // Gets signaled when both the headphone jack is removed or an A2DP device is
445+ // disconnected and playback needs pausing
446+ core::Signal<void> pause_playback;
447 std::unique_ptr<CallMonitor> call_monitor;
448 std::list<media::Player::PlayerKey> paused_sessions;
449 };
450
451 media::ServiceImplementation::ServiceImplementation() : d(new Private())
452 {
453- cout << __PRETTY_FUNCTION__ << endl;
454-
455 d->power_level->changed().connect([this](const core::IndicatorPower::PowerLevel::ValueType &level)
456 {
457 // When the battery level hits 10% or 5%, pause all multimedia sessions.
458@@ -153,6 +495,12 @@
459 resume_multimedia_session();
460 });
461
462+ d->pause_playback.connect([this]()
463+ {
464+ std::cout << "Got pause_playback signal, pausing all multimedia sessions" << std::endl;
465+ pause_all_multimedia_sessions();
466+ });
467+
468 d->call_monitor->on_change([this](CallMonitor::State state) {
469 switch (state) {
470 case CallMonitor::OffHook:
471
472=== modified file 'src/core/media/service_skeleton.cpp'
473--- src/core/media/service_skeleton.cpp 2014-10-14 16:21:47 +0000
474+++ src/core/media/service_skeleton.cpp 2014-11-20 18:31:53 +0000
475@@ -14,6 +14,7 @@
476 * along with this program. If not, see <http://www.gnu.org/licenses/>.
477 *
478 * Authored by: Thomas Voß <thomas.voss@canonical.com>
479+ * Jim Hodapp <jim.hodapp@canonical.com>
480 */
481
482 #include "service_skeleton.h"
483
484=== modified file 'tests/unit-tests/CMakeLists.txt'
485--- tests/unit-tests/CMakeLists.txt 2014-11-03 00:56:55 +0000
486+++ tests/unit-tests/CMakeLists.txt 2014-11-20 18:31:53 +0000
487@@ -36,6 +36,7 @@
488 ${PC_GSTREAMER_1_0_LIBRARIES}
489 ${PROCESS_CPP_LDFLAGS}
490 ${GIO_LIBRARIES}
491+ ${PC_PULSE_AUDIO_LIBRARIES}
492
493 gmock
494 gmock_main
495
496=== modified file 'tests/unit-tests/test-gstreamer-engine.cpp'
497--- tests/unit-tests/test-gstreamer-engine.cpp 2014-08-26 20:34:30 +0000
498+++ tests/unit-tests/test-gstreamer-engine.cpp 2014-11-20 18:31:53 +0000
499@@ -65,7 +65,7 @@
500 gstreamer::Engine engine;
501 }
502
503-TEST(GStreamerEngine, setting_uri_and_starting_audio_only_playback_works)
504+TEST(GStreamerEngine, DISABLED_setting_uri_and_starting_audio_only_playback_works)
505 {
506 const std::string test_file{"/tmp/test.ogg"};
507 const std::string test_file_uri{"file:///tmp/test.ogg"};
508@@ -110,7 +110,7 @@
509 std::chrono::seconds{10}));
510 }
511
512-TEST(GStreamerEngine, setting_uri_and_starting_video_playback_works)
513+TEST(GStreamerEngine, DISABLED_setting_uri_and_starting_video_playback_works)
514 {
515 const std::string test_file{"/tmp/h264.avi"};
516 const std::string test_file_uri{"file:///tmp/h264.avi"};
517@@ -152,7 +152,7 @@
518 std::chrono::seconds{10}));
519 }
520
521-TEST(GStreamerEngine, stop_pause_play_seek_audio_only_works)
522+TEST(GStreamerEngine, DISABLED_stop_pause_play_seek_audio_only_works)
523 {
524 const std::string test_file{"/tmp/test.ogg"};
525 const std::string test_file_uri{"file:///tmp/test.ogg"};
526@@ -198,7 +198,7 @@
527 std::chrono::seconds{40}));
528 }
529
530-TEST(GStreamerEngine, stop_pause_play_seek_video_works)
531+TEST(GStreamerEngine, DISABLED_stop_pause_play_seek_video_works)
532 {
533 const std::string test_file{"/tmp/h264.avi"};
534 const std::string test_file_uri{"file:///tmp/h264.avi"};

Subscribers

People subscribed via source and target branches

to all changes: