source: trunk/doc/src/examples/videowidget.qdoc@ 561

Last change on this file since 561 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

  • Property svn:eol-style set to native
File size: 8.5 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 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** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
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** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at qt-info@nokia.com.
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*/
Note: See TracBrowser for help on using the repository browser.