doc/src/examples/videowidget.qdoc
branchRCL_3
changeset 7 3f74d0d4af4c
equal deleted inserted replaced
6:dee5afe5301f 7:3f74d0d4af4c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the documentation of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 /*!
       
    43     \example multimedia/videowidget
       
    44     \title Video Widget Example
       
    45 
       
    46     The Video Widget example shows how to implement a video widget using
       
    47     QtMultimedia's QAbstractVideoSurface
       
    48 
       
    49     \image video-videowidget.png
       
    50 
       
    51     \section1 VideoWidgetSurface Class Definition
       
    52 
       
    53     \snippet examples/multimedia/videowidget/videowidgetsurface.h 0
       
    54 
       
    55     The VideoWidgetSurface class inherits QAbstractVideoSurface and paints
       
    56     video frames on a QWidget.  This is a separate class to VideoWidget as both
       
    57     QAbstractVideoSurface and QWidget inherit QObject.
       
    58 
       
    59     In addition to the functions from QAbstractVideoSurface, VideoWidgetSurface
       
    60     has functions for determining the video display rectangle, and painting
       
    61     the video.
       
    62 
       
    63     \section1 VideoWidgetSurface Class Implementation
       
    64 
       
    65     \snippet examples/multimedia/videowidget/videowidgetsurface.cpp 0
       
    66 
       
    67     From the supportedPixelFormats() function we return a list of pixel formats
       
    68     the surface can paint. The order of the list hints at which formats are
       
    69     preferred by the surface.  Assuming a 32-bit RGB backbuffer, we'd expect
       
    70     that a 32-bit RGB type with no alpha to be fastest to paint so
       
    71     QVideoFrame::Image_RGB32 is first in the list.
       
    72 
       
    73     Since we don't support rendering using any special frame handles we don't
       
    74     return any pixel formats if handleType is not
       
    75     QAbstractVideoBuffer::NoHandle.
       
    76 
       
    77     \snippet examples/multimedia/videowidget/videowidgetsurface.cpp 1
       
    78 
       
    79     In isFormatSupported() we test if the frame type of a surface format maps
       
    80     to a valid QImage format, that the frame size is not empty, and the handle
       
    81     type is QAbstractVideoBuffer::NoHandle.  Note that the
       
    82     QAbstractVideoSurface implementation of isFormatSupported() will verify
       
    83     that the list of supported pixel formats returned by
       
    84     \c supportedPixelFormats(format.handleType()) contains the pixel format and
       
    85     that the size is not empty so a reimplementation wasn't strictly necessary
       
    86     in this case.
       
    87 
       
    88     \snippet examples/multimedia/videowidget/videowidgetsurface.cpp 2
       
    89 
       
    90     To start our surface we'll extract the image format and size from the
       
    91     selected video format and save it for use in the paint() function.  If the
       
    92     image format, or size are invalid then we'll set an error and return false.
       
    93     Otherwise we'll save the format and confirm the surface has been started,
       
    94     by calling QAbstractVideoSurface::start(). Finally since the video size may
       
    95     have changed we'll trigger an update of the widget, and video geometry.
       
    96 
       
    97     \snippet examples/multimedia/videowidget/videowidgetsurface.cpp 5
       
    98 
       
    99     The updateVideoRect() function calculates the region within the widget the
       
   100     video occupies.  The \l {QVideoSurfaceFormat::sizeHint()}{size hint} of the
       
   101     video format gives a suggested size for the video calculated from the
       
   102     \l {QVideoSurfaceFormat::viewport()}{viewport} and
       
   103     \l {QVideoSurfaceFormat::pixelAspectRatio()}{pixel aspect ratio}.  If the
       
   104     suggested size fits within the widget then we create a new rect of that
       
   105     size in the center of the widget.  Otherwise we shrink the size maintaining
       
   106     the aspect ratio so that it does fit.
       
   107 
       
   108     \snippet examples/multimedia/videowidget/videowidgetsurface.cpp 4
       
   109 
       
   110     We can't paint from outside a paint event, so when a new frame is received
       
   111     in present() we save a reference to it and force an immediate repaint of
       
   112     the video region.  We retain the saved reference to the frame after the
       
   113     repaint so that the widget can be repainted between frame changes if
       
   114     necessary.
       
   115 
       
   116     If the format of the frame doesn't match the surface format we can't paint
       
   117     it or very likely any future frames.  So we set an
       
   118     \l {QAbstractVideoSurface::UnsupportedFormatError}{UnsupportedFormatError}
       
   119     on our surface and stop it immediately.
       
   120 
       
   121     \snippet examples/multimedia/videowidget/videowidgetsurface.cpp 6
       
   122 
       
   123     The paint() function is called by the video widget to paint the current
       
   124     video frame.  Before we draw the frame first we'll check the format for
       
   125     the scan line direction and if the scan lines are arranged from bottom to
       
   126     top we'll flip the painter so the frame isn't drawn upside down.  Then
       
   127     using the image format information saved in the start() function we'll
       
   128     construct a new QImage from the current video frame, and draw it to the
       
   129     the widget.
       
   130 
       
   131     \snippet examples/multimedia/videowidget/videowidgetsurface.cpp 3
       
   132 
       
   133     When the surface is stopped we need to release the current frame and
       
   134     invalidate the video region.   Then we confirm the surface has been
       
   135     stopped by calling QAbstractVideoSurface::stop() which sets the started
       
   136     state to false and finally we update so the video widget so paints over
       
   137     the last frame.
       
   138 
       
   139     \section1 VideoWidget Class Definition
       
   140 
       
   141     The VideoWidget class uses the VideoWidgetSurface class to implement a
       
   142     video widget.
       
   143 
       
   144     \snippet examples/multimedia/videowidget/videowidget.h 0
       
   145 
       
   146     The VideoWidget QWidget implementation is minimal with just the sizeHint(),
       
   147     paintEvent(), and resizeEvent() functions in addition to the constructor,
       
   148     destructor and an instance of VideoWidgetSurface.
       
   149 
       
   150     \section1 VideoWidget Class Implementation
       
   151 
       
   152     \snippet examples/multimedia/videowidget/videowidget.cpp 0
       
   153 
       
   154     In the VideoWidget constructor we set some flags to speed up re-paints a
       
   155     little.  Setting the Qt::WA_NoSystemBackground flag and disabling automatic
       
   156     background fills will stop Qt from a painting a background that'll be
       
   157     completely obscured by the video.  The Qt::WA_PaintOnScreen flag will
       
   158     allow us to paint to the screen instead of the back buffer where supported.
       
   159 
       
   160     Next we set the background color to black, so that any borders around the
       
   161     video are filled in black rather the default background color.
       
   162 
       
   163     Finally we construct an instance of the VideoWidgetSurface class.
       
   164 
       
   165     \snippet examples/multimedia/videowidget/videowidget.cpp 1
       
   166 
       
   167     In the destructor we simply delete the VideoWidgetSurface instance.
       
   168 
       
   169     \snippet examples/multimedia/videowidget/videowidget.cpp 2
       
   170 
       
   171     We get the size hint for the widget from the video format of the surface
       
   172     which is calculated from viewport and pixel aspect ratio of the video
       
   173     format.
       
   174 
       
   175     \snippet examples/multimedia/videowidget/videowidget.cpp 3
       
   176 
       
   177     When the video widget receives a paint event we first check if the surface
       
   178     is started,  if not then we simply fill the widget with the background
       
   179     color.  If it is then we draw a border around the video region clipped
       
   180     by the paint region, before calling paint on the video surface to draw the
       
   181     current frame.
       
   182 
       
   183     \snippet examples/multimedia/videowidget/videowidget.cpp 4
       
   184 
       
   185     The resizeEvent() function is reimplemented to trigger an update of the
       
   186     video region when the widget is resized.
       
   187 */