/****************************************************************************
**
** Copyright (C) 2007-2007 Trolltech ASA. All rights reserved.
**
** This file is part of the documentation of the Qt Toolkit.
**
** This file may be used under the terms of the GNU General Public
** License version 2.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of
** this file.  Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
** http://trolltech.com/products/qt/licenses/licensing/opensource/
**
** If you are unsure which license is appropriate for your use, please
** review the following information:
** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
** or contact the sales department at sales@trolltech.com.
**
** In addition, as a special exception, Trolltech gives you certain
** additional rights. These rights are described in the Trolltech GPL
** Exception version 1.0, which can be found at
** http://www.trolltech.com/products/qt/gplexception/ and in the file
** GPL_EXCEPTION.txt in this package.
**
** In addition, as a special exception, Trolltech, as the sole copyright
** holder for Qt Designer, grants users of the Qt/Eclipse Integration
** plug-in the right for the Qt/Eclipse Integration to link to
** functionality provided by Qt Designer and its related libraries.
**
** Trolltech reserves all rights not expressly granted herein.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/

/*!
    \page phonon.html
    \title Phonon Overview
    \ingroup multimedia

    \tableofcontents

    \section1 Introduction

    Multimedia is media that contain multiple forms of information
    content, e.g., audio, text, animation, video, and interactivity.
    With the Qt multimedia framework, Phonon, Qt provides
    functionality to playback and manipulate the most common
    multimedia formats, also from physical storage media, e.g., CD and
    DVD. Many formats, such as mpeg and avi video files, can be
    played back.

    In this overview, we take a look at the main concepts of Phonon.
    We also explain each component of the architecture, examine the
    core API classes, and show examples on how to use the classes
    provided. The Phonon API documentation can be found in KDE's API
    reference:
    \l{http://api.kde.org/4.0-api/kdelibs-apidocs/phonon/html/index.html}.

    \section1 Architecture

    Phonon is a graph based framework. The nodes in the graph are
    simple objects; they inherit from QObject, take input, and give
    output. The input and output are data streams with multimedia
    content. The connections over which streams travel between nodes
    are called paths.
 
    Phonon has tree basic concepts: media objects, sinks, and paths.
    The media objects manages a media source, which, for instance, can
    be a file, DVD, or URL; it might be thought of as a minimal media
    player that outputs one or more streams that can be used by other
    nodes in the network. A sink is an output device, which can play
    back the media, for instance video on a widget using a graphics
    card, or sound using a sound card.

    Both the media object and sinks are nodes in the graph. All nodes
    in the graph take a media stream as input, process the stream,
    and possibly output it to another node in the graph. Below is an
    image of such a media graph for an audio stream.
   
    \image conceptauido.png 
    
    Audio playback is started and managed by the media object, which
    send the media stream to any sinks connected to it by a path. The
    sink then plays the stream back, usually though a sound card.

    All nodes in the graph are synchronized by the framework,
    meaning that if more that one sink is connected to the same
    media object, the framework will handle the synchronization
    between the sinks; this happens for instance when a media
    source containing video with sound is played back. More on
    this later.

    \section2 Media Objects

    A media object, an instance of the MediaObject class, is an
    interface for media playback. The object will be a source object
    in the graph, providing other nodes with the media.

    The media object itself knows how to playback the media, and
    inform other nodes of the media type of its source. The playback
    can be controlled by the user. For a video playback, for instance,
    a media object can start, stop, fast forward, and rewind,
    i.e., control the state of the playback. You may think of the
    object as a simple media player. It can also queue media for
    playback. Manipulation of the media is left for other nodes,
    e.g., sinks.

    The media data is provided by a media source, which is encapsulated
    by the media object. The media source itself is a separate object,
    an instance of \c MediaSource, in Phonon, and not part of the
    graph itself. The source will supply the media object with a raw
    data. The source can fetch its data from files, URLs, DVD/CD, and
    also any QIODevice. The contents of the source will be interpreted
    by the media object.

    A media object is always instantiated with the default
    constructor and then supplied with a media source. Concrete
    code examples are given later in this overview.

    As a complement to the media object, Phonon also provides \c
    MediaController, which provides control over features that are
    optional for a given media. For instance, for DVD playback,
    chapter, menus, and title will be features managed by a \c
    MediaController.

    \section2 Sinks
 
    A sink is a node that can output media, and is an output node
    in the graph, i.e., it does not send its output to other nodes. A
    sink is usually a rendering device.

    The input of sinks in a Phonon media graph comes from a \c
    MediaObject, though it might have been processed through other
    nodes on the way. 

    While the \c MediaObject controls the playback, the sink has basic
    controls for manipulation of the media. With a audio sink, for
    instance, you can control the volume and mute the sound, i.e., it
    represents a virtual audio device. Another example is the \c
    VideoWidget, which can render video on a QWidget and alter the
    brightness, hue, and scaling of the video.

    As an example we give an image of a graph used for playing back a
    video file with sound.

    \image conceptvideo.png

    \section2 Processors

    Phonon does not allow manipulation of media streams directly,
    i.e., one cannot alter a media streams bytes programmatically once
    they have been given to a media object. However, a back end can
    offer processors, which are nodes placed in the graph on the path
    somewhere between the media object and its sinks. In Phonon,
    processors are subclasses of the \c Effect class.

    The processor is inserted into the rendering process, altering the
    media stream, and will be active as long as it is part of the
    graph. To stop, it needs to be removed. 

    \omit \image conceptprossesor.png \endomit

    The \c {Effect}s may also have controls that allow control over
    how the media stream is manipulated. A processor applying a depth
    effect to audio, for instance, can have a value controlling the
    amount of depth. An \c Effect can be configured at any point in
    time.

    \section1 Playback

    In some common cases, it is not necessary to build a graph
    yourself to playback multimedia. 

    Phonon has convenience functions for building common graphs. For
    playing an audio file, you can use the
    \l{Phonon::}{createPlayer()} function. This will set up the
    necessary graph and return the media object node; the sound can
    then simply be started by calling its \l{MediaObject::}{play()}
    function. The code example below shows how trivial this is:

    \code
        using namespace Phonon;

        MediaObject *music =
            createPlayer(Phonon::MusicCategory, "/path/mysong.wav");
        music->play();
    \endcode

    Notice that we use the namespace Phonon, of which \c createPlayer()
    is a member.

    We have a similar solution for playing video files, the \c
    VideoPlayer. The coding necessary is also trivial:

    \code
        VideoPlayer *player =
            new VideoPlayer(Phonon::VideoCategory, parentWidget);
        player->play(url);
    \endcode

    The VideoPlayer is a widget onto which the video will be drawn. 

    The \c .pro file for a project needs adding of the following
    phonon specific line:

    \code
        QT += phonon
    \endcode

    Phonon comes with several widgets that provide functionality
    commonly associated with multimedia players - notably SeekSlider
    for controlling the position of the stream, VolumeSlider for
    controlling sound volume, and EffectWidget for controlling the
    parameters of an effect. You can learn about them in the API
    documentation.

    \section1 Building Graphs

    If you need more freedom than the convenience functions described
    in the previous sections offer you, you can build the media graphs
    yourself. We will take a look at how some common graphs built for
    playback of multimedia. We also give code snippets that create the
    graphs. Starting a graph up is a matter of calling the
    \l{MediaObject::}{play()} function of the media object.

    If the media source contains several types of media, for instance, a
    stream with both video and audio, the graph will contain two
    output nodes: one for the video and one for the audio. 

    We will now look at the code required to build the graphs discussed
    previously in the \l{Architecture} section.  All code examples
    assumes that the Phonon namespace is used, i.e., code is preceded
    by:

    \code
        using namespace Phonon;
    \endcode

    \section2 Audio

    When playing back audio, you create the media object and
    connect it to an audio output node - a node that inherits from
    AbstractAudioOutput. Currently, the only node provided is
    AudioOutput, which outputs audio to the sound card.

    The code to create the graph is straight forward:

    \code
        MediaObject *mediaObject = new MediaObject(this);
        mediaObject->setCurrentSource("/mymusic/barbiegirl.wav");
        AudioOutput *audioOutput =
            new AudioOutput(Phonon::MusicCategory, this);
        Path path = createPath(mediaObject, audioOutput);
    \endcode

    Notice that the type of media an input source has is resolved by
    Phonon, so you need not be concerned with this. If a source
    contains multiple media formats, this is also handled
    automatically.

    The media object is always created using the default constructor
    since it handles all multimedia formats.

    The setting of a Category, Phonon::MusicCategory in this case,
    does not affect the actual playback; the category can be used by
    KDE to control the playback through, for instance, the control
    panel. Users of KDE can often also choose to send sound with the
    CommunicationCategory, e.g., given to VoIP, to their headset,
    while sound with MusicCategory is sent to the sound card.

    The AudioOutput class outputs the audio media to a sound card,
    that is, one of the audio devices of the operating system. An
    audio device can be a sound card or a intermediate technology,
    such as \c DirectShow on windows. A default device will be chosen
    if one is not set with \l{AudioOutput::}{setOutputDevice()}.

    The AudioOutput node will work with all audio formats supported by
    the back end, so you don't need to know what format a specific
    media source has. 

    For a an extensive example of audio playback, see the \l{Music
    Player Example}{Phonon Music Player}.

    \section3 Audio Effects

    Since a media stream cannot be manipulated directly, the backend
    can produce nodes that can process the media streams. These nodes
    are inserted into the graph between a media object and an output
    node.

    Nodes that process media streams inherit from the Effect class.
    The effects available depends on the underlying system. Most of
    these effects will be supported by Phonon. See the \l{Querying
    Backends for Support} section for information on how to resolve
    the available effects on a particular system.

    We will now continue the example from above using the Path
    variable \c path to add an effect. The code is again trivial:

    \code
        Effect *effect = new Effect(availableAudioEffects()[0], this);
        path.insertEffect(effect);        
    \endcode

    Here we simply take the first available effect on the system.

    The effect will start immediately after being inserted into the
    graph if the media object is playing. To stop it, you have to
    detach it again using \l{Path::}{removeEffect()} of the Path. 

    \section2 Video

    For playing video, VideoWidget is provided. This class functions
    both as a node in the graph and as a widget upon which it draws
    the video stream. The widget will automatically chose an available
    device for playing the video, which is usually a technology
    between the Qt application and the graphics card, such as \c
    DirectShow on Windows.

    The video widget does not play the audio (if any) in the media
    stream. If you want to play the audio as well, you will need
    an AudioOutput node. You create and connect it to the graph as
    shown in the previous section.

    The code for creating this graph is given below, after which
    one can play the video with \l{MediaObject::}{play()}.

    \code
        MediaObject *media = new MediaObject(this);

        VideoWidget *videoWidget = new VideoWidget(this);
        createPath(media, videoWidget);

        AudioOutput *audioOutput =
            new AudioOutput(Phonon::VideoCategory, this);
        createPath(mediaObject, audioOutput);
    \endcode

    The VideoWidget does not need to be set to a Category, it is
    automatically classified to \l{Phonon::}{VideoCategory}, we only
    need to assure that the audio is also classified in the same
    category.

    The media object will split files with different media content
    into separate streams before sending them off to other nodes in
    the graph. It is the media object that determines the type of
    content appropriate for nodes that connect to it.

    \omit This section is from the future

    \section2 Multiple Audio Sources and Graph Outputs

    In this section, we take a look at a graph that contains multiple
    audio sources in addition to video. We have a video camera with
    some embarrassing home footage from last weekend's party, a
    microphone with which we intend to add commentary, and an audio
    music file to set the correct mood. It would be an advantage to
    write the graph output to a file for later viewing, but since this
    is not yet supported by Qt backends, we will play it back
    directly.

    <image of party graph>

    <code>

    <code walkthrough> 

    \endomit

    \section1 Backends

    The multimedia functionality is not implemented by Phonon itself,
    but by a back end - often also referred to as an engine. This
    includes connecting to, managing, and driving the underlying
    hardware or intermediate technology. For the programmer, this
    implies that the media nodes, e.g., media objects, processors, and
    sinks, are produced by the back end.  Also, it is responsible for
    building the graph, i.e., connecting the nodes. 

    Qt provides a back end for each of its platforms. The back ends in
    turn use the media systems DirectShow (which requires DirectX) on
    Windows, QuickTime on Mac, and GStreamer on Linux. The
    functionality provided on the different platforms are dependent on
    these underlying systems and may vary somewhat, e.g., in the media
    formats supported.

    Backends exposes information about the underlying system. It can
    tell which media formats are supported, e.g., \c AVI, \c mp3, or
    \c OGG. It will also inform what kind of nodes it can produce, and
    how they can be connected to each other. This also includes a
    textual description suitable for users of a Phonon application.

    A user can often add support for new formats and filters to the
    underlying system, by, for instance, installing the DivX codex. We
    can therefore not give an exact overview of which formats are
    available in the Qt backends.  

    Qt backends also handles threads and networking, so the programmer
    need not be concerned with this. Streaming over networks is also
    implemented.

    \omit Not sure I want a separate section for this
    \section2 Communication with the Backends

    We cooperate with backends through static functions in the
    Phonon namespace. We have already seen some of these functions
    in code examples. Their two main responsibilities are creating
    graph nodes and supplying information about the capabilities
    of the various nodes. The nodes uses the backend internally
    when created, so it is only connecting them in the graph that
    you need to use the backend directly.

    The main functions for graph building are:

    \list
        \o createPath(): This function creates a path between to
                         nodes, which it takes as arguments.
        \o 
    \endlist

    For more detailed information, please consult the API
    documentation.

    \endomit

    \section2 Querying Backends for Support    

    As mentioned, Phonon depends on the backend to provide its
    functionality. Depending on the individual backend, full support
    of the API may not be in place. Applications therefore need to
    check with the backend if functionality they require is
    implemented. In this section, we take look at how this is done.
    
    The backend provides the \c availableMimeTypes() and \c
    isMimeTypeAvailable() functions to query which MIME types the
    backend can produce nodes for. The types are listed as strings,
    which for any type is equal for any backend or platform. 

    The backend will emit a signal - Notifier::capabilitiesChanged() -
    if it's support have changed, e.g., if a USB headset is plugged
    into the system. 

    To query the actual audio devices possible, we have the \c
    availableAudioDevices() as mentioned in the \l{Sinks} section. To
    query information about the individual devices, you can examine
    its \c name(); this string is dependent on the operating system,
    and the Qt backends does not analyze the devices further.

    The sink for playback of video does not have a selection of
    devices. For convenience, the \c WideoWidget is both a node in the
    graph and a widget on which the video output is rendered. To query
    the various video formats available, use \c isMimeTypeAvailable().
    To add it to a path, you can use the \c Phonon::createPath()
    as usual. After creating a media object, it is also possible
    to call its \l{MediaObject::}{hasVideo()} function.

    See also the \l{Capabilities Example}.

    \section1 Installing Phonon

    \section2 Windows

    On Windows, Phonon requires DirectX version 9 or higher.

    For Phonon application development, the platform and DirectX SDKs
    must be installed. The name of the platform SDK may very between
    Windows versions; on Vista, it is called Windows SDK.

    Note that these SDKs must be placed before your compiler in the
    include path; though, this should be auto-detected and handled by
    Windows.

    \section2 Linux

    The Qt backend on Linux uses GStreamer (minimum version is 0.10),
    which must be installed on the system. It is a good idea to
    install every package available for GStreamer to get support for
    as many MIME types, and audio effects as possible. At a minimum,
    you need the GStreamer library and base plugins, which provides
    support for \c .ogg files. The package names may vary between
    Linux distributions; on Mandriva, they have the following names:
  
    \table
        \header
            \o Package
            \o Description
        \row
            \o libgstreamer0.10_0.10
            \o The GStreamer base library.
        \row
            \o libgstreamer0.10_0.10-devel
            \o Contains files for developing applications with
               GStreamer.
        \row
            \o libgstreamer-plugins-base0.10
            \o Contains the basic plugins for audio and video
               playback, and will enable support for \c ogg files.
        \row
            \o libgstreamer-plugins-base0.10-devel
            \o Makes it possible to develop applications using the
               base plugins.
    \endtable

    \omit Should go in troubleshooting (in for example README)
    alsasink backend for GStreamer
    \table
        \header
            \o Variable
            \o Description
        \row
            \o PHONON_GST_AUDIOSINK
            \o Sets the audio sink to be used. Possible values are
               ... alsasink.
        \row
            \o PHONON_GSTREAMER_DRIVER
            \o Sets the driver for GStreamer. This driver will
               usually be configured automatically when
               installing.
        \row
            \o PHONON_GST_VIDEOWIDGET
            \o This variable can be set to the name of a widget to
               use as the video widget??
        \row
            \o PHONON_GST_DEBUG
            \o Phonon will give debug information while running if
               this variable is set to a number between 1 and 3.
        \row
            \o PHONON_TESTURL
            \o ...
    \endtable
    \endomit

    \section2 Mac

    On the Mac, Qt uses QuickTime for its backend. The minimum
    supported version is 7.0.

    \section1 Work in Progress

    Phonon and its Qt backends is, albeit fully functional for
    multimedia playback is still under development. Functionality to
    come is the possibility to capture media and more processors for
    both music and video files.

    Another important consideration is to implement support for
    storing media to files, i.e., not playing back media directly.

    We also hope in the future to be able to support direct
    manipulation of media streams. This will give the programmer more
    freedom to manipulate streams than just through processors.

    Currently, the multimedia framework supports one input source,
    e.g,. a file or a CD. It will be possible to include several
    sources. This is useful in, for example, audio mixer
    applications where several audio sources can be sent,
    processed and output as a single audio stream.
*/
