Phonon
TODO
- API to allow applications to implement their own effects (independent from the backend)
- encoding to files (or any QIODevice)
- Hardware Mixer API
- kded module to handle tasks like:
- react on plugged new (never seen before) media device
- manage software volume controls
- implement policy like muting/lowering volume of selected applications/categories depending on special events (e.g. incoming call)
- Let applications request specific audio capture formats (32 bit, 8 bit, little endian, etc)
- Documentation!
Junior Jobs
- Exchange K_D with Q_D since they are absolutely the same (except for a stinky whitespace in Q_D ;))
Done as GSoCs
- High level capture API (needs maturing for Phonon proper)
- Low level PCM I/O
GStreamer
- Ensure streamreader works
- Implemenation of Phonon changes for spitfire
- Cleanup MO (maybe introduce statemachine?)
- Support for more capture sources, such as ximagesrc
VLC
- Ensure streamreader works
- Implementation of Phonon changes for spitfire
- Merge VLC* classes (leftover from MPlayer times)
Standing Issues
Effects API returning random identifier namers
Amarok finds an Equalizer by looking at the names of the available effects, for xine that would be KEqualizer (which is what Amarok looks for), Gstreamer however uses completely different names...
3 Approaches suggested:
- Introduce categories - does not resolve original problem, since a consumer still needs a way to differ between devices, introduces additional complexity
- Fixed Enum - not very dynamic WRT additional magic supported by specific backends. The capabilities would just return enum values and the consumer then issues creation of e.g. Phonon::Effect::Equalizer
- Standardize on names.
Apps switching on backend switch
This issue is difficult to describe since it has multiple incarnations. The most occurring one is that at backend switch we can only partially destruct the path, leaving it in an inconsistent state from our POV and implicitly depend on the backend to nuke all nodes (only xine does that). In general the whole backend switching business is difficult to support because at every point in time different parts are (or needed) to be responsible for path deconstruction leading to multiple issues.
In an IRC discussion it was concluded that the backend switching is not a terribly important usecase and that we will stop supporting it.
- The KCM's part for switching needs to be moved to an own KCM that is not listed in systemettings
- Switching will only take effect on app restart, the KCM needs to tell the user about this
DVD Menus (how Dragon should not link against xine)
Currently Phonon does not provide the means for a video player to access the menu of its media (think DVD). This lead to a situation where dragonplayer links against xine to provide (primitive abilities of menu switching). A situation that can easily be prevented. The following implementation was considered: have MediaController get an enum of menus, introduce an interface to allow players to query what menus are available (neverminding if the backend or the medium does not support one). The player can then query what menus are there, since there is a fixed amount of supported menus it then can map the supported ones to (e.g.) QActions and upon action issues MC to instruct the backend to switch the menu. Possible menu types: main, title, root, audio, angle, chapter, subtitle.
State mess
States are a mess right now, not very well defined and attached to some very weird signals (like aboutToFinish)... nothing is reliable and it causes crappy implementations (see Amarok EngineController why that is bad). In particular discussion with some of our major API consumers should be conducted to find a solution. Suggested discussion partners: Amarok, Dragon, Bangerang
Graph destruction & Monster nodes
Amarok's enginecontroller has a function called initializePhonon which gets executed when phonon enters error state (in case of missing codec for example). This function deletes all phonon objects held by amarok and reconstructs the whole thing. While this is not a very good practise at all it raises the general concern that Phonon can not administer global graph destruction and instead depends on the backends to handle this (we also see this issue with runtime backend switches). This is a problem as the logic is only implemented in the xine backend and ends up in undefined behaviour land with other backends (mostly resulting in a segfault at some point). Harald suggested the introduction of a Phonon::MonsterNode which then ought to be used as base for the backend's media nodes. Within the ctor of the MonsterNode it can then register with some sort of global node tracker. Upon destruction the MonsterNode unregisters and takes care of path destruction etc. That way it can be ensured globally that the graph is always in a consistent state.
Signals, Threads and Deletes
All signals that get forwarded by Phonon from the backend to the consumer should be queued. This is to "simulate" threading, as signal within the same thread context (i.e. the main app one) would get executed right away ontop of the currently present stack. If a backend emits statechange to error without queuing this will directly end up in a slot call in for example Amarok (note: no stack unwinding happened at this point, in fact it grew), Amarok then does things to it (at the time of writing: reinitialize everything by deleting all Phonon objects), once Amarok is done the stack unwinds to the emission in the backend, and the backend continues excuting statements (if any). At this point the presen stack operates on not allocated memory! To prevent this all signals must be queued, so that a backend can finish whatever it is doing, and only once the stack returned to the mainloop the slot on Amarok's side of things actually gets called. This allows both the backend and the consumer to do whatever they want to do. General note: it should be enforced that backends must not be running in a different thread context or if they do they must ensure that all used contexts are cleaned up properly (i.e. the dtors must only return once all threads are cleaned up).
Release Schedule
4.4.4 (git 4.4) - dev name: iguanos
Estimated release: soonish
Changes
- New build system magic to facilitate independent backend building
- GStreamer and Xine released independently with build system changes
- GStreamer to fix gst-codec-install support
- GStreamer to fix AudioDataOutput synchronization issues
- Otherwise only bug fixes
4.5.0 (git master) - dev name: spitfire
Estimated release: before Randa 2011 dev sprint (first week of june or so)
Changes
- AbstractMediaStreams used for all URLs except file: (i.e. KIO streaming)
- Ensure AbstractMedia works across all backends
- Ensure QIODevice streams work as expected (readyRead?)
- Stabilize effects API to resolve random-naming issue (see above)
- Eliminate runtime backend switching (see above)
- Add DVD menu support (see above)
- Add subtitle support
- Mature Capturing API to move out of experimental
- Fix states (see above)
- Possibly MonsterNodes (see above)
- Subtitle!!
- All signal forwarding queued
- Inspect global threading for Phonon or at least assure that threading is possible without running into context errors with parenting
Getting Involved
If you want to get involved with Phonon backend development please subscribe to [email protected]. If you want to contribute, make comments or useful suggestions you can also write to the KDE Multimedia mailinglist. You can join the mailinglist using the web interface or take a look at the archives.
There's also a #phonon channel on freenode where you may find developers.