1/****************************************************************************
2**
3** Copyright (C) 2015 The Qt Company Ltd.
4** Contact: http://www.qt.io/licensing/
5**
6** This file is part of the documentation of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:FDL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Free Documentation License Usage
18** Alternatively, this file may be used under the terms of the GNU Free
19** Documentation License version 1.3 as published by the Free Software
20** Foundation and appearing in the file included in the packaging of
21** this file. Please review the following information to ensure
22** the GNU Free Documentation License version 1.3 requirements
23** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
24** $QT_END_LICENSE$
25**
26****************************************************************************/
27
28/*!
29\example multimedia/video/qmlvideofx
30\title QML Video Shader Effects Example
31\ingroup multimedia_examples
32
33\brief Applying shader effects on video and camera viewfinder content.
34
35\include examples-run.qdocinc
36
37\section1 Overview
38
39\e{QML Video Shader Effects} demonstrates how a \l ShaderEffect can be used to
40apply postprocessing effects, expressed in GLSL, to QML \l VideoOutput type.
41
42It also shows how native code can be combined with QML to implement more
43advanced functionality - in this case, C++ code is used to calculate the QML
44frame rate.  This value is rendered in QML in a semi-transparent item
45overlaid on the video content.
46
47The following screenshots show shader effects being applied. In each case,
48the effect is implemented using a fragment shader.
49
50Here we see an edge detection algorithm being applied to a video clip
51(\l{http://durian.blender.org/}{Sintel from blender.org}).
52\image qmlvideofx-video-edgedetection.jpg
53
54This image shows a page curl effect, applied to the same video clip.
55\image qmlvideofx-video-pagecurl.jpg
56
57Here we see a 'glow' effect (edge detection plus colour quantization) being
58applied to the camera viewfinder.
59\image qmlvideofx-camera-glow.jpg
60
61This image shows a 'wobble' effect applied to the viewfinder.
62\image qmlvideofx-camera-wobble.jpg
63
64The application includes many more effects than the ones shown here - look
65for Effect*.qml files in the list of files below to see the full range.
66
67\section1 Application Structure
68
69Shader effects can be applied to video or viewfinder content using
70\l{ShaderEffect}, as shown in the following example, which applies
71a wiggly effect to the content:
72
73\qml
74import QtQuick 2.0
75import QtMultimedia 5.0
76
77Rectangle {
78    width: 300
79    height: 300
80    color: "black"
81
82    MediaPlayer {
83        id: mediaPlayer
84        source: "test.mp4"
85        playing: true
86    }
87
88    VideoOutput {
89        id: video
90        anchors.fill: parent
91        source: mediaPlayer
92    }
93
94    ShaderEffect {
95        property variant source: ShaderEffectSource { sourceItem: video; hideSource: true }
96        property real wiggleAmount: 0.005
97        anchors.fill: video
98
99        fragmentShader: "
100            varying highp vec2 qt_TexCoord0;
101            uniform sampler2D source;
102            uniform highp float wiggleAmount;
103            void main(void)
104            {
105                highp vec2 wiggledTexCoord = qt_TexCoord0;
106                wiggledTexCoord.s += sin(4.0 * 3.141592653589 * wiggledTexCoord.t) * wiggleAmount;
107                gl_FragColor = texture2D(source, wiggledTexCoord.st);
108            }
109        "
110    }
111}
112\endqml
113
114In this application, the usage of the \l{ShaderEffect} and \l{VideoOutput}
115types is a bit more complicated, for the following reasons:
116
117\list
118    \li Each effect can be applied to either a \l{VideoOutput} or an
119       \l{Image} item, so the type of the source item must be abstracted away
120       from the effect implementation
121    \li For some effects (such as the edge detection and glow examples shown in
122       the screenshots above), the transformation is applied only to pixels to
123       the left of a dividing line - this allows the effect to be easily
124       compared with the untransformed image on the right
125    \li Most effects have one or more parameters which can be modified by the
126       user - these are controlled by sliders in the UI which are connected
127       to uniform values passed into the GLSL code
128\endlist
129
130The abstraction of source item type is achieved by the \c Content, which uses a
131\l[QML]{Loader} to create either a \l[QML]{MediaPlayer}, \l[QML]{Camera}, or an
132\l[QML]{Image}:
133
134\quotefromfile multimedia/video/qmlvideofx/qml/qmlvideofx/Content.qml
135\skipto import
136\printuntil {
137\dots
138\skipto Loader {
139\printuntil }
140\dots
141\skipto function openImage
142\printuntil "ContentImage.qml"
143\skipto contentLoader.item.source
144\printuntil path
145\skipto }
146\printuntil }
147\skipto function openVideo
148\printuntil "ContentVideo.qml"
149\skipto contentLoader.item.mediaSource
150\printuntil path
151\skipto }
152\printuntil }
153\skipto function openCamera
154\printuntil "ContentCamera.qml"
155\skipto }
156\printuntil }
157\skipto /^\}/
158\printuntil }
159
160Each effect is implemented as a QML item which is based on the \c Effect, which in
161turn is based on the \l[QML]{ShaderEffect}:
162
163\quotefromfile multimedia/video/qmlvideofx/qml/qmlvideofx/Effect.qml
164\skipto import
165\printuntil /^\}/
166
167The interface of Effect allows for derived effects to specify the
168number of parameters which they support (and therefore the number of sliders
169which should be displayed), and whether a vertical dividing line should be drawn
170between transformed and untransformed image regions.  As an example, here is the
171implementation of the pixelation effect.  As you can see, the pixelation effect
172supports one parameter (which controls the pixelation granularity), and states
173that the divider should be displayed.
174
175\quotefromfile multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPixelate.qml
176\skipto import
177\printuntil /^\}/
178
179The main.qml file shows a \c FileOpen item, which allows
180the user to select the input source and an \c EffectSelectionList
181item, which lists each of the available shader effects.  As described above, a
182\c Content item is used to load the appropriate input and effect type.  A
183\c Divider item draws the vertical dividing line, which can be dragged left or
184right by the user.  Finally, a \c ParameterPanel item renders the sliders
185corresponding to each effect parameter.
186
187\image qmlvideofx-effects-menu.jpg
188\caption The effect selection menu
189
190\section1 Calculating and Displaying QML Painting Rate
191
192\input multimedia/doc/src/examples/video-qml-paint-rate.qdocinc
193
194All that remains is to connect the afterRendering() signal of the QQuickView
195object to a JavaScript function, which will eventually call frequencyItem.notify():
196
197\quotefromfile multimedia/video/qmlvideofx/main.cpp
198\skipto QGuiApplication
199\printuntil ;
200\dots
201\skipto QQuickItem
202\printuntil ;
203\dots
204\skipto QObject::connect
205\printuntil SLOT(qmlFramePainted()));
206
207*/
208