Bug 305028 - phonon-vlc's Phonon::MediaObject fails to transition from StoppedState to PausedState
Summary: phonon-vlc's Phonon::MediaObject fails to transition from StoppedState to Pau...
Status: RESOLVED FIXED
Alias: None
Product: phonon-backend-vlc
Classification: Frameworks and Libraries
Component: general (show other bugs)
Version: 0.6
Platform: unspecified Linux
: NOR normal
Target Milestone: 0.7
Assignee: Harald Sitter
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-08-12 15:35 UTC by Matěj Laitl
Modified: 2012-11-13 19:52 UTC (History)
5 users (show)

See Also:
Latest Commit:
Version Fixed In: 0.6.1
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Matěj Laitl 2012-08-12 15:35:33 UTC
This breaks implementation of "resume playback at saved position upon start" in Amarok.

Reproducible: Always

Steps to Reproduce:
1. Phonon::MediaObject *obj = new Phonon::MediaObject();
2. obj->setCurrentSource( "path/to/source.mp3" );
3. obj->pause();
Actual Results:  
stateChanged() with newState Phonon::LoadingState is emitted, then
stateChanged() with newState Phonon::StoppedState is emitted, then noting happens

Expected Results:  
stateChanged() with newState Phonon::PausedState it emitted at some point, so that media can be seeked before playback is started.

Showcase: https://git.reviewboard.kde.org/r/105995/

There's no documentation whether setCurrentSource() is asynchronous or not, so I assume that calling pause() just after it is valid.
Comment 1 Harald Sitter 2012-08-14 09:56:46 UTC
vlc does not like being paused while not having been played (which is perfectly sane TBH). given that the phonon api however does not suggest any such behavior it should work which in turn means a hacky work around in phonon vlc probably is in order.

essentially we need to intercept the playing state change callback discard the state emission and instead set the vlc player instance to paused

as there is no specification as to when the callback is sent this is nothing more than an appropximation to the desired behavior on phonon level as of course the callback could be done after the first samples were delivered to the output device. But even so the amount of samples would be less than what ends up being processed if we were to change phonon behavior (as phonon signals are all queued the delay between callback and actual pause call is obviously greater)
Comment 2 Harald Sitter 2012-08-22 11:31:38 UTC
Git commit 67d64a1623c6c2167f6e131e036611aab32bfb92 by Harald Sitter.
Committed on 22/08/2012 at 13:30.
Pushed by sitter into branch 'master'.

implement pausedplay mechanic

phonon's api suggest that pausing before playing is possible (through
naming of the interfaces) however vlc does not provide any such
functionality so once again we do a nasty intercept-hack.

pausedPlay issues a regular play but then intercepts the VLC playing
event and directly switches to paused.
nothing outside MediaPlayer ever knows that VLC actually was in playing
state and a completely transparent switch from non-playing to paused
becomes possible.

please note that this does not in any way guarantee that no audio/video
samples are already sent to the output. it merely tries to reduce the
chance of this happening by calling pause in the event callback, which
is of course threaded from the pipeline so anything can happen between
us getting the signal and asking VLC to pause.

verification for backport pending.

M  +17   -8    src/mediaobject.cpp
M  +1    -1    src/mediaobject.h
M  +18   -2    src/mediaplayer.cpp
M  +3    -0    src/mediaplayer.h

http://commits.kde.org/phonon-vlc/67d64a1623c6c2167f6e131e036611aab32bfb92
Comment 3 Matěj Laitl 2012-08-24 16:33:59 UTC
I confirm this fixes the bug. (using Amarok and https://git.reviewboard.kde.org/r/105995/ patch)
Comment 4 Harald Sitter 2012-09-09 10:53:53 UTC
Git commit 9600492eae50d48c93bed167afae1669f08459f1 by Harald Sitter.
Committed on 22/08/2012 at 13:30.
Pushed by sitter into branch '0.6'.

implement pausedplay mechanic

phonon's api suggest that pausing before playing is possible (through
naming of the interfaces) however vlc does not provide any such
functionality so once again we do a nasty intercept-hack.

pausedPlay issues a regular play but then intercepts the VLC playing
event and directly switches to paused.
nothing outside MediaPlayer ever knows that VLC actually was in playing
state and a completely transparent switch from non-playing to paused
becomes possible.

please note that this does not in any way guarantee that no audio/video
samples are already sent to the output. it merely tries to reduce the
chance of this happening by calling pause in the event callback, which
is of course threaded from the pipeline so anything can happen between
us getting the signal and asking VLC to pause.

verification for backport pending.

M  +17   -8    src/mediaobject.cpp
M  +1    -1    src/mediaobject.h
M  +18   -2    src/mediaplayer.cpp
M  +3    -0    src/mediaplayer.h

http://commits.kde.org/phonon-vlc/9600492eae50d48c93bed167afae1669f08459f1