1 /* Webcamoid, webcam capture application.
2  * Copyright (C) 2016  Gonzalo Exequiel Pedone
3  *
4  * Webcamoid is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * Webcamoid is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with Webcamoid. If not, see <http://www.gnu.org/licenses/>.
16  *
17  * Web-Site: http://webcamoid.github.io/
18  */
19 
20 #include <QDataStream>
21 #include <QDebug>
22 #include <QMetaEnum>
23 #include <QSize>
24 #include <QVector>
25 
26 #include "akvideocaps.h"
27 #include "akfrac.h"
28 #include "akcaps.h"
29 
30 class VideoFormat
31 {
32     public:
33         AkVideoCaps::PixelFormat format;
34         int bpp;
35         quint32 fourCC;
36         QVector<int> planes;
37         QVector<int> planes_div;
38 
formats()39         static inline const QVector<VideoFormat> &formats()
40         {
41             static const QVector<VideoFormat> videoFormats = {
42                 {AkVideoCaps::Format_none          ,   0, AK_FOURCC_NULL           , {}              , {}          },
43                 {AkVideoCaps::Format_rgb444be      ,  12, AkFourCCS("\xcBGR")      , {16}            , {1}         },
44                 {AkVideoCaps::Format_rgb444le      ,  12, AkFourCCS("RGB\xc")      , {16}            , {1}         },
45                 {AkVideoCaps::Format_argb444be     ,  16, AK_FOURCC_NULL           , {16}            , {1}         },
46                 {AkVideoCaps::Format_argb444le     ,  16, AK_FOURCC_NULL           , {16}            , {1}         },
47                 {AkVideoCaps::Format_rgb555be      ,  15, AkFourCCS("\xfBGR")      , {16}            , {1}         },
48                 {AkVideoCaps::Format_rgb555le      ,  15, AkFourCCS("RGB\xf")      , {16}            , {1}         },
49                 {AkVideoCaps::Format_argb555be     ,  16, AK_FOURCC_NULL           , {16}            , {1}         },
50                 {AkVideoCaps::Format_argb555le     ,  16, AK_FOURCC_NULL           , {16}            , {1}         },
51                 {AkVideoCaps::Format_rgb565be      ,  16, AkFourCCS("\x10""BGR")   , {16}            , {1}         },
52                 {AkVideoCaps::Format_rgb565le      ,  16, AkFourCCS("RGB\x10")     , {16}            , {1}         },
53                 {AkVideoCaps::Format_rgb0          ,  24, AkFourCCS("RGB\x0")      , {32}            , {1}         },
54                 {AkVideoCaps::Format_rgb24         ,  24, AkFourCCS("RGB\x18")     , {24}            , {1}         },
55                 {AkVideoCaps::Format_rgb48be       ,  48, AkFourCCS("0RGB")        , {48}            , {1}         },
56                 {AkVideoCaps::Format_rgb48le       ,  48, AkFourCCS("RGB0")        , {48}            , {1}         },
57                 {AkVideoCaps::Format_bgr444be      ,  12, AkFourCCS("\xcRGB")      , {16}            , {1}         },
58                 {AkVideoCaps::Format_bgr444le      ,  12, AkFourCCS("BGR\xc")      , {16}            , {1}         },
59                 {AkVideoCaps::Format_bgr555be      ,  15, AkFourCCS("\xfRGB")      , {16}            , {1}         },
60                 {AkVideoCaps::Format_bgr555le      ,  15, AkFourCCS("BGR\xf")      , {16}            , {1}         },
61                 {AkVideoCaps::Format_bgr565be      ,  16, AkFourCCS("\x10RGB")     , {16}            , {1}         },
62                 {AkVideoCaps::Format_bgr565le      ,  16, AkFourCCS("BGR\x10")     , {16}            , {1}         },
63                 {AkVideoCaps::Format_rgb666        ,  18, AK_FOURCC_NULL           , {24}            , {1}         },
64                 {AkVideoCaps::Format_argb1665      ,  18, AK_FOURCC_NULL           , {24}            , {1}         },
65                 {AkVideoCaps::Format_argb1666      ,  19, AK_FOURCC_NULL           , {24}            , {1}         },
66                 {AkVideoCaps::Format_bgr666        ,  18, AK_FOURCC_NULL           , {24}            , {1}         },
67                 {AkVideoCaps::Format_argb6666      ,  24, AK_FOURCC_NULL           , {24}            , {1}         },
68                 {AkVideoCaps::Format_abgr6666      ,  24, AK_FOURCC_NULL           , {24}            , {1}         },
69                 {AkVideoCaps::Format_0bgr          ,  32, AkFourCCS("\x0BGR")      , {32}            , {1}         },
70                 {AkVideoCaps::Format_0rgb          ,  32, AkFourCCS("\x0RGB")      , {32}            , {1}         },
71                 {AkVideoCaps::Format_abgr          ,  32, AkFourCCS("ABGR")        , {32}            , {1}         },
72                 {AkVideoCaps::Format_argb          ,  32, AkFourCCS("ARGB")        , {32}            , {1}         },
73                 {AkVideoCaps::Format_bgr0          ,  32, AkFourCCS("BGR\x0")      , {32}            , {1}         },
74                 {AkVideoCaps::Format_bgr24         ,  32, AkFourCCS("BGR\x18")     , {24}            , {1}         },
75                 {AkVideoCaps::Format_bgr48be       ,  48, AkFourCCS("0BGR")        , {48}            , {1}         },
76                 {AkVideoCaps::Format_bgr48le       ,  48, AkFourCCS("BGR0")        , {48}            , {1}         },
77                 {AkVideoCaps::Format_rgba          ,  32, AkFourCCS("RGBA")        , {32}            , {1}         },
78                 {AkVideoCaps::Format_rgba64be      ,  64, AkFourCCS("\x40RBA")     , {64}            , {1}         },
79                 {AkVideoCaps::Format_rgba64le      ,  64, AkFourCCS("RBA\x40")     , {64}            , {1}         },
80                 {AkVideoCaps::Format_bgra          ,  32, AkFourCCS("BGRA")        , {32}            , {1}         },
81                 {AkVideoCaps::Format_bgra64be      ,  64, AkFourCCS("\x40""BRA")   , {64}            , {1}         },
82                 {AkVideoCaps::Format_bgra64le      ,  64, AkFourCCS("BRA\x40")     , {64}            , {1}         },
83                 {AkVideoCaps::Format_argb1887      ,  24, AK_FOURCC_NULL           , {24}            , {1}         },
84                 {AkVideoCaps::Format_bgra1888      ,  25, AK_FOURCC_NULL           , {32}            , {1}         },
85                 {AkVideoCaps::Format_monob         ,   1, AkFourCCS("B0W1")        , { 1}            , {1}         },
86                 {AkVideoCaps::Format_monow         ,   1, AkFourCCS("B1W0")        , { 1}            , {1}         },
87                 {AkVideoCaps::Format_rgb4          ,   4, AkFourCCS("RGB\x4")      , { 4}            , {1}         },
88                 {AkVideoCaps::Format_rgb4_byte     ,   4, AkFourCCS("B4BY")        , { 8}            , {1}         },
89                 {AkVideoCaps::Format_rgb8          ,   8, AkFourCCS("RGB\x8")      , { 8}            , {1}         },
90                 {AkVideoCaps::Format_bgr4          ,   4, AkFourCCS("BGR\x4")      , { 4}            , {1}         },
91                 {AkVideoCaps::Format_bgr4_byte     ,   4, AkFourCCS("R4BY")        , { 8}            , {1}         },
92                 {AkVideoCaps::Format_bgr8          ,   8, AkFourCCS("BGR\x8")      , { 8}            , {1}         },
93                 {AkVideoCaps::Format_gray2         ,   2, AK_FOURCC_NULL           , { 8}            , {1}         },
94                 {AkVideoCaps::Format_gray4         ,   4, AK_FOURCC_NULL           , { 8}            , {1}         },
95                 {AkVideoCaps::Format_gray24        ,  24, AK_FOURCC_NULL           , {32}            , {1}         },
96                 {AkVideoCaps::Format_gray32        ,  32, AK_FOURCC_NULL           , {32}            , {1}         },
97                 {AkVideoCaps::Format_gray          ,   8, AkFourCCS("Y800")        , { 8}            , {1}         },
98                 {AkVideoCaps::Format_gray9be       ,   9, AkFourCCS("\x9\x01Y")    , {16}            , {1}         },
99                 {AkVideoCaps::Format_gray9le       ,   9, AkFourCCS("Y1\x0\x9")    , {16}            , {1}         },
100                 {AkVideoCaps::Format_gray10be      ,  10, AkFourCCS("\xa\x01Y")    , {16}            , {1}         },
101                 {AkVideoCaps::Format_gray10le      ,  10, AkFourCCS("Y1\x0\xa")    , {16}            , {1}         },
102                 {AkVideoCaps::Format_gray12be      ,  12, AkFourCCS("\xc\x01Y")    , {16}            , {1}         },
103                 {AkVideoCaps::Format_gray12le      ,  12, AkFourCCS("Y1\x0\xc")    , {16}            , {1}         },
104                 {AkVideoCaps::Format_gray14be      ,  14, AkFourCCS("\xe\x01Y")    , {16}            , {1}         },
105                 {AkVideoCaps::Format_gray14le      ,  14, AkFourCCS("Y1\x0\xe")    , {16}            , {1}         },
106                 {AkVideoCaps::Format_gray16be      ,  16, AkFourCCS("\x10\x01Y")   , {16}            , {1}         },
107                 {AkVideoCaps::Format_gray16le      ,  16, AkFourCCS("Y1\x0\x10")   , {16}            , {1}         },
108                 {AkVideoCaps::Format_grayf32be     ,  32, AK_FOURCC_NULL           , {32}            , {1}         },
109                 {AkVideoCaps::Format_grayf32le     ,  32, AK_FOURCC_NULL           , {32}            , {1}         },
110                 {AkVideoCaps::Format_bayer_bggr8   ,   8, AkFourCCS("\xba""BG\x8") , { 8}            , {1}         },
111                 {AkVideoCaps::Format_bayer_gbrg8   ,   8, AkFourCCS("\xbaGB\x8")   , { 8}            , {1}         },
112                 {AkVideoCaps::Format_bayer_grbg8   ,   8, AkFourCCS("\xbaGR\x8")   , { 8}            , {1}         },
113                 {AkVideoCaps::Format_bayer_rggb8   ,   8, AkFourCCS("\xbaRG\x8")   , { 8}            , {1}         },
114                 {AkVideoCaps::Format_bayer_bggr16be,  16, AkFourCCS("\x10GB\xba")  , {16}            , {1}         },
115                 {AkVideoCaps::Format_bayer_bggr16le,  16, AkFourCCS("\xba""BG\x10"), {16}            , {1}         },
116                 {AkVideoCaps::Format_bayer_gbrg16be,  16, AkFourCCS("\x10""BG\xba"), {16}            , {1}         },
117                 {AkVideoCaps::Format_bayer_gbrg16le,  16, AkFourCCS("\xbaGB\x10")  , {16}            , {1}         },
118                 {AkVideoCaps::Format_bayer_grbg16be,  16, AkFourCCS("\x10RG\xba")  , {16}            , {1}         },
119                 {AkVideoCaps::Format_bayer_grbg16le,  16, AkFourCCS("\xbaGR\x10")  , {16}            , {1}         },
120                 {AkVideoCaps::Format_bayer_rggb16be,  16, AkFourCCS("\x10GR\xba")  , {16}            , {1}         },
121                 {AkVideoCaps::Format_bayer_rggb16le,  16, AkFourCCS("\xbaRG\x10")  , {16}            , {1}         },
122                 {AkVideoCaps::Format_ayuv64be      ,  64, AK_FOURCC_NULL           , {64}            , {1}         },
123                 {AkVideoCaps::Format_ayuv64le      ,  64, AK_FOURCC_NULL           , {64}            , {1}         },
124                 {AkVideoCaps::Format_uyvy422       ,  16, AkFourCCS("UYVY")        , {16}            , {1}         },
125                 {AkVideoCaps::Format_vyuy422       ,  16, AK_FOURCC_NULL           , {16}            , {1}         },
126                 {AkVideoCaps::Format_uyyvyy411     ,  12, AkFourCCS("Y411")        , {12}            , {1}         },
127                 {AkVideoCaps::Format_ya16be        ,  32, AK_FOURCC_NULL           , {32}            , {1}         },
128                 {AkVideoCaps::Format_ya16le        ,  32, AK_FOURCC_NULL           , {32}            , {1}         },
129                 {AkVideoCaps::Format_ya8           ,  16, AkFourCCS("Y2\x0\x8")    , {16}            , {1}         },
130                 {AkVideoCaps::Format_yuyv422       ,  16, AkFourCCS("YUY2")        , {16}            , {1}         },
131                 {AkVideoCaps::Format_yvyu422       ,  16, AkFourCCS("YVYU")        , {16}            , {1}         },
132                 {AkVideoCaps::Format_xyz12be       ,  36, AkFourCCS("\x24ZYX")     , {48}            , {1}         },
133                 {AkVideoCaps::Format_xyz12le       ,  36, AkFourCCS("XYZ\x24")     , {48}            , {1}         },
134                 {AkVideoCaps::Format_nv12          ,  12, AkFourCCS("NV12")        , { 8,  8}        , {1, 2}      },
135                 {AkVideoCaps::Format_nv16          ,  16, AK_FOURCC_NULL           , { 8,  8}        , {1, 1}      },
136                 {AkVideoCaps::Format_nv20be        ,  20, AK_FOURCC_NULL           , {16, 16}        , {1, 1}      },
137                 {AkVideoCaps::Format_nv20le        ,  20, AK_FOURCC_NULL           , {16, 16}        , {1, 1}      },
138                 {AkVideoCaps::Format_nv21          ,  12, AkFourCCS("NV21")        , { 8,  8}        , {1, 2}      },
139                 {AkVideoCaps::Format_p010be        ,  15, AK_FOURCC_NULL           , {16, 16}        , {1, 2}      },
140                 {AkVideoCaps::Format_p010le        ,  15, AK_FOURCC_NULL           , {16, 16}        , {1, 2}      },
141                 {AkVideoCaps::Format_p016be        ,  24, AK_FOURCC_NULL           , {16, 16}        , {1, 2}      },
142                 {AkVideoCaps::Format_p016le        ,  24, AK_FOURCC_NULL           , {16, 16}        , {1, 2}      },
143                 {AkVideoCaps::Format_yuv410p       ,   9, AkFourCCS("YUV9")        , { 8,  2,  2}    , {1, 4, 4}   },
144                 {AkVideoCaps::Format_yuv411p       ,  12, AkFourCCS("Y41B")        , { 8,  2,  2}    , {1, 1, 1}   },
145                 {AkVideoCaps::Format_yuv420p       ,  12, AkFourCCS("I420")        , { 8,  4,  4}    , {1, 2, 2}   },
146                 {AkVideoCaps::Format_yvu420p       ,  12, AK_FOURCC_NULL           , { 8,  4,  4}    , {1, 2, 2}   },
147                 {AkVideoCaps::Format_yuv422p       ,  16, AkFourCCS("Y42B")        , { 8,  4,  4}    , {1, 1, 1}   },
148                 {AkVideoCaps::Format_yuv440p       ,  16, AkFourCCS("440P")        , { 8,  8,  8}    , {1, 2, 2}   },
149                 {AkVideoCaps::Format_yuv444p       ,  24, AkFourCCS("444P")        , { 8,  8,  8}    , {1, 1, 1}   },
150                 {AkVideoCaps::Format_yuvj411p      ,  12, AK_FOURCC_NULL           , { 8,  2,  2}    , {1, 1, 1}   },
151                 {AkVideoCaps::Format_yuvj420p      ,  12, AkFourCCS("I420")        , { 8,  4,  4}    , {1, 2, 2}   },
152                 {AkVideoCaps::Format_yuvj422p      ,  16, AkFourCCS("Y42B")        , { 8,  4,  4}    , {1, 1, 1}   },
153                 {AkVideoCaps::Format_yuvj440p      ,  16, AkFourCCS("440P")        , { 8,  8,  8}    , {1, 2, 2}   },
154                 {AkVideoCaps::Format_yuvj444p      ,  24, AkFourCCS("444P")        , { 8,  8,  8}    , {1, 1, 1}   },
155                 {AkVideoCaps::Format_yuv420p9be    ,  13, AkFourCCS("\x9\xb3Y")    , {16,  8,  8}    , {1, 2, 2}   },
156                 {AkVideoCaps::Format_yuv420p9le    ,  13, AkFourCCS("Y3\xb\x9")    , {16,  8,  8}    , {1, 2, 2}   },
157                 {AkVideoCaps::Format_yuv420p10be   ,  15, AkFourCCS("\xa\xb3Y")    , {16,  8,  8}    , {1, 2, 2}   },
158                 {AkVideoCaps::Format_yuv420p10le   ,  15, AkFourCCS("Y3\xb\xa")    , {16,  8,  8}    , {1, 2, 2}   },
159                 {AkVideoCaps::Format_yuv420p12be   ,  18, AkFourCCS("\xc\xb3Y")    , {16,  8,  8}    , {1, 2, 2}   },
160                 {AkVideoCaps::Format_yuv420p12le   ,  18, AkFourCCS("Y3\xb\xc")    , {16,  8,  8}    , {1, 2, 2}   },
161                 {AkVideoCaps::Format_yuv420p14be   ,  21, AkFourCCS("\xe\xb3Y")    , {16,  8,  8}    , {1, 2, 2}   },
162                 {AkVideoCaps::Format_yuv420p14le   ,  21, AkFourCCS("Y3\xb\xe")    , {16,  8,  8}    , {1, 2, 2}   },
163                 {AkVideoCaps::Format_yuv420p16be   ,  24, AkFourCCS("\x10\xb3Y")   , {16,  8,  8}    , {1, 2, 2}   },
164                 {AkVideoCaps::Format_yuv420p16le   ,  24, AkFourCCS("Y3\xb\x10")   , {16,  8,  8}    , {1, 2, 2}   },
165                 {AkVideoCaps::Format_yuv422p9be    ,  18, AkFourCCS("\x9\xa3Y")    , {16,  8,  8}    , {1, 1, 1}   },
166                 {AkVideoCaps::Format_yuv422p9le    ,  18, AkFourCCS("Y3\xa\x9")    , {16,  8,  8}    , {1, 1, 1}   },
167                 {AkVideoCaps::Format_yuv422p10be   ,  20, AkFourCCS("\xa\xa3Y")    , {16,  8,  8}    , {1, 1, 1}   },
168                 {AkVideoCaps::Format_yuv422p10le   ,  20, AkFourCCS("Y3\xa\xa")    , {16,  8,  8}    , {1, 1, 1}   },
169                 {AkVideoCaps::Format_yuv422p12be   ,  24, AkFourCCS("\xc\xa3Y")    , {16,  8,  8}    , {1, 1, 1}   },
170                 {AkVideoCaps::Format_yuv422p12le   ,  24, AkFourCCS("Y3\xa\xc")    , {16,  8,  8}    , {1, 1, 1}   },
171                 {AkVideoCaps::Format_yuv422p14be   ,  28, AkFourCCS("\xe\xa3Y")    , {16,  8,  8}    , {1, 1, 1}   },
172                 {AkVideoCaps::Format_yuv422p14le   ,  28, AkFourCCS("Y3\xa\xe")    , {16,  8,  8}    , {1, 1, 1}   },
173                 {AkVideoCaps::Format_yuv422p16be   ,  32, AkFourCCS("\x10\xa3Y")   , {16,  8,  8}    , {1, 1, 1}   },
174                 {AkVideoCaps::Format_yuv422p16le   ,  32, AkFourCCS("Y3\xa\x10")   , {16,  8,  8}    , {1, 1, 1}   },
175                 {AkVideoCaps::Format_yuv440p10be   ,  20, AK_FOURCC_NULL           , {16, 16, 16}    , {1, 2, 2}   },
176                 {AkVideoCaps::Format_yuv440p10le   ,  20, AK_FOURCC_NULL           , {16, 16, 16}    , {1, 2, 2}   },
177                 {AkVideoCaps::Format_yuv440p12be   ,  24, AK_FOURCC_NULL           , {16, 16, 16}    , {1, 2, 2}   },
178                 {AkVideoCaps::Format_yuv440p12le   ,  24, AK_FOURCC_NULL           , {16, 16, 16}    , {1, 2, 2}   },
179                 {AkVideoCaps::Format_yuv444p9be    ,  27, AkFourCCS("\x9\x03Y")    , {16, 16, 16}    , {1, 1, 1}   },
180                 {AkVideoCaps::Format_yuv444p9le    ,  27, AkFourCCS("Y3\x0\x9")    , {16, 16, 16}    , {1, 1, 1}   },
181                 {AkVideoCaps::Format_yuv444p10be   ,  30, AkFourCCS("\xa\x03Y")    , {16, 16, 16}    , {1, 1, 1}   },
182                 {AkVideoCaps::Format_yuv444p10le   ,  30, AkFourCCS("Y3\x0\xa")    , {16, 16, 16}    , {1, 1, 1}   },
183                 {AkVideoCaps::Format_yuv444p12be   ,  36, AkFourCCS("\xc\x03Y")    , {16, 16, 16}    , {1, 1, 1}   },
184                 {AkVideoCaps::Format_yuv444p12le   ,  36, AkFourCCS("Y3\x0\xc")    , {16, 16, 16}    , {1, 1, 1}   },
185                 {AkVideoCaps::Format_yuv444p14be   ,  42, AkFourCCS("\xe\x03Y")    , {16, 16, 16}    , {1, 1, 1}   },
186                 {AkVideoCaps::Format_yuv444p14le   ,  42, AkFourCCS("Y3\x0\xe")    , {16, 16, 16}    , {1, 1, 1}   },
187                 {AkVideoCaps::Format_yuv444p16be   ,  48, AkFourCCS("\x10\x03Y")   , {16, 16, 16}    , {1, 1, 1}   },
188                 {AkVideoCaps::Format_yuv444p16le   ,  48, AkFourCCS("Y3\x0\x10")   , {16, 16, 16}    , {1, 1, 1}   },
189                 {AkVideoCaps::Format_yuva420p      ,  20, AkFourCCS("Y4\xb\x8")    , { 8,  4,  4,  8}, {1, 2, 2, 1}},
190                 {AkVideoCaps::Format_yuva422p      ,  24, AkFourCCS("Y4\xa\x8")    , { 8,  4,  4,  8}, {1, 1, 1, 1}},
191                 {AkVideoCaps::Format_yuv444        ,  24, AK_FOURCC_NULL           , {24}            , {1}         },
192                 {AkVideoCaps::Format_yuva444p      ,  32, AkFourCCS("Y4\x0\x8")    , { 8,  8,  8,  8}, {1, 1, 1, 1}},
193                 {AkVideoCaps::Format_yuva420p9be   ,  22, AkFourCCS("\x9\xb4Y")    , {16,  8,  8, 16}, {1, 2, 2, 1}},
194                 {AkVideoCaps::Format_yuva420p9le   ,  22, AkFourCCS("Y4\xb\x9")    , {16,  8,  8, 16}, {1, 2, 2, 1}},
195                 {AkVideoCaps::Format_yuva420p10be  ,  25, AkFourCCS("\xa\xb4Y")    , {16,  8,  8, 16}, {1, 2, 2, 1}},
196                 {AkVideoCaps::Format_yuva420p10le  ,  25, AkFourCCS("Y4\xb\xa")    , {16,  8,  8, 16}, {1, 2, 2, 1}},
197                 {AkVideoCaps::Format_yuva420p16be  ,  40, AkFourCCS("\x10\xb4Y")   , {16,  8,  8, 16}, {1, 2, 2, 1}},
198                 {AkVideoCaps::Format_yuva420p16le  ,  40, AkFourCCS("Y4\xb\x10")   , {16,  8,  8, 16}, {1, 2, 2, 1}},
199                 {AkVideoCaps::Format_yuva422p9be   ,  27, AkFourCCS("\x9\xa4Y")    , {16,  8,  8, 16}, {1, 1, 1, 1}},
200                 {AkVideoCaps::Format_yuva422p9le   ,  27, AkFourCCS("Y4\xa\x9")    , {16,  8,  8, 16}, {1, 1, 1, 1}},
201                 {AkVideoCaps::Format_yuva422p10be  ,  30, AkFourCCS("\xa\xa4Y")    , {16,  8,  8, 16}, {1, 1, 1, 1}},
202                 {AkVideoCaps::Format_yuva422p10le  ,  30, AkFourCCS("Y4\xa\xa")    , {16,  8,  8, 16}, {1, 1, 1, 1}},
203                 {AkVideoCaps::Format_yuva422p16be  ,  48, AkFourCCS("\x10\xa4Y")   , {16,  8,  8, 16}, {1, 1, 1, 1}},
204                 {AkVideoCaps::Format_yuva422p16le  ,  48, AkFourCCS("Y4\xa\x10")   , {16,  8,  8, 16}, {1, 1, 1, 1}},
205                 {AkVideoCaps::Format_yuva444p9be   ,  36, AkFourCCS("\x9\x04Y")    , {16, 16, 16, 16}, {1, 1, 1, 1}},
206                 {AkVideoCaps::Format_yuva444p9le   ,  36, AkFourCCS("Y4\x0\x9")    , {16, 16, 16, 16}, {1, 1, 1, 1}},
207                 {AkVideoCaps::Format_yuva444p10be  ,  40, AkFourCCS("\xa\x04Y")    , {16, 16, 16, 16}, {1, 1, 1, 1}},
208                 {AkVideoCaps::Format_yuva444p10le  ,  40, AkFourCCS("Y4\x0\xa")    , {16, 16, 16, 16}, {1, 1, 1, 1}},
209                 {AkVideoCaps::Format_yuva444p16be  ,  64, AkFourCCS("\x10\x04Y")   , {16, 16, 16, 16}, {1, 1, 1, 1}},
210                 {AkVideoCaps::Format_yuva444p16le  ,  64, AkFourCCS("Y4\x0\x10")   , {16, 16, 16, 16}, {1, 1, 1, 1}},
211                 {AkVideoCaps::Format_gbrp          ,  24, AkFourCCS("G3\x0\x8")    , { 8,  8,  8}    , {1, 1, 1}   },
212                 {AkVideoCaps::Format_gbrp9be       ,  27, AkFourCCS("\x9\x03G")    , {16, 16, 16}    , {1, 1, 1}   },
213                 {AkVideoCaps::Format_gbrp9le       ,  27, AkFourCCS("G3\x0\x9")    , {16, 16, 16}    , {1, 1, 1}   },
214                 {AkVideoCaps::Format_gbrp10be      ,  30, AkFourCCS("\xa\x03G")    , {16, 16, 16}    , {1, 1, 1}   },
215                 {AkVideoCaps::Format_gbrp10le      ,  30, AkFourCCS("G3\x0\xa")    , {16, 16, 16}    , {1, 1, 1}   },
216                 {AkVideoCaps::Format_gbrp12be      ,  36, AkFourCCS("\xc\x03G")    , {16, 16, 16}    , {1, 1, 1}   },
217                 {AkVideoCaps::Format_gbrp12le      ,  36, AkFourCCS("G3\x0\xc")    , {16, 16, 16}    , {1, 1, 1}   },
218                 {AkVideoCaps::Format_gbrp14be      ,  42, AkFourCCS("\xe\x03G")    , {16, 16, 16}    , {1, 1, 1}   },
219                 {AkVideoCaps::Format_gbrp14le      ,  42, AkFourCCS("G3\x0\xe")    , {16, 16, 16}    , {1, 1, 1}   },
220                 {AkVideoCaps::Format_gbrp16be      ,  48, AkFourCCS("\x10\x03G")   , {16, 16, 16}    , {1, 1, 1}   },
221                 {AkVideoCaps::Format_gbrp16le      ,  48, AkFourCCS("G3\x0\x10")   , {16, 16, 16}    , {1, 1, 1}   },
222                 {AkVideoCaps::Format_gbrpf32be     ,  96, AK_FOURCC_NULL           , {32, 32, 32}    , {1, 1, 1}   },
223                 {AkVideoCaps::Format_gbrpf32le     ,  96, AK_FOURCC_NULL           , {32, 32, 32}    , {1, 1, 1}   },
224                 {AkVideoCaps::Format_rgbp          ,  24, AK_FOURCC_NULL           , { 8,  8,  8}    , {1, 1, 1}   },
225                 {AkVideoCaps::Format_rgbap         ,  32, AK_FOURCC_NULL           , { 8,  8,  8,  8}, {1, 1, 1, 1}},
226                 {AkVideoCaps::Format_gbrap         ,  32, AkFourCCS("G4\x0\x8")    , { 8,  8,  8,  8}, {1, 1, 1, 1}},
227                 {AkVideoCaps::Format_gbrap10be     ,  40, AkFourCCS("\xa\x04G")    , {16, 16, 16, 16}, {1, 1, 1, 1}},
228                 {AkVideoCaps::Format_gbrap10le     ,  40, AkFourCCS("G4\x0\xa")    , {16, 16, 16, 16}, {1, 1, 1, 1}},
229                 {AkVideoCaps::Format_gbrap12be     ,  48, AkFourCCS("\xc\x04G")    , {16, 16, 16, 16}, {1, 1, 1, 1}},
230                 {AkVideoCaps::Format_gbrap12le     ,  48, AkFourCCS("G4\x0\xc")    , {16, 16, 16, 16}, {1, 1, 1, 1}},
231                 {AkVideoCaps::Format_gbrap16be     ,  64, AkFourCCS("\x10\x04G")   , {16, 16, 16, 16}, {1, 1, 1, 1}},
232                 {AkVideoCaps::Format_gbrap16le     ,  64, AkFourCCS("G4\x0\x10")   , {16, 16, 16, 16}, {1, 1, 1, 1}},
233                 {AkVideoCaps::Format_gbrapf32be    , 128, AK_FOURCC_NULL           , {32, 32, 32, 32}, {1, 1, 1, 1}},
234                 {AkVideoCaps::Format_gbrapf32le    , 128, AK_FOURCC_NULL           , {32, 32, 32, 32}, {1, 1, 1, 1}},
235             };
236 
237             return videoFormats;
238         }
239 
byFormat(AkVideoCaps::PixelFormat format)240         static inline const VideoFormat *byFormat(AkVideoCaps::PixelFormat format)
241         {
242             for (auto &format_: formats())
243                 if (format_.format == format)
244                     return &format_;
245 
246             return &formats().front();
247         }
248 
byBpp(int bpp)249         static inline const VideoFormat *byBpp(int bpp)
250         {
251             for (auto &format: formats())
252                 if (format.bpp == bpp)
253                     return &format;
254 
255             return &formats().front();
256         }
257 
byFourCC(quint32 fourCC)258         static inline const VideoFormat *byFourCC(quint32 fourCC)
259         {
260             for (auto &format: formats())
261                 if (format.fourCC == fourCC)
262                     return &format;
263 
264             return &formats().front();
265         }
266 
267         template<typename T>
alignUp(const T & value,const T & align)268         static inline T alignUp(const T &value, const T &align)
269         {
270             return (value + align - 1) & ~(align - 1);
271         }
272 };
273 
274 class AkVideoCapsPrivate
275 {
276     public:
277         AkVideoCaps::PixelFormat m_format {AkVideoCaps::Format_none};
278         int m_width {0};
279         int m_height {0};
280         int m_align {1};
281         AkFrac m_fps;
282         const QVector<int> *m_planes_div;
283         QVector<size_t> m_bypl;
284         QVector<size_t> m_offset;
285 
286         void updateParams();
287 };
288 
AkVideoCaps(QObject * parent)289 AkVideoCaps::AkVideoCaps(QObject *parent):
290     QObject(parent)
291 {
292     this->d = new AkVideoCapsPrivate();
293 }
294 
AkVideoCaps(AkVideoCaps::PixelFormat format,int width,int height,const AkFrac & fps,int align)295 AkVideoCaps::AkVideoCaps(AkVideoCaps::PixelFormat format,
296                          int width,
297                          int height,
298                          const AkFrac &fps,
299                          int align)
300 {
301     this->d = new AkVideoCapsPrivate();
302     this->d->m_format = format;
303     this->d->m_width = width;
304     this->d->m_height = height;
305     this->d->m_fps = fps;
306     this->d->m_align = align;
307     this->d->updateParams();
308 }
309 
AkVideoCaps(AkVideoCaps::PixelFormat format,const QSize & size,const AkFrac & fps,int align)310 AkVideoCaps::AkVideoCaps(AkVideoCaps::PixelFormat format,
311                          const QSize &size,
312                          const AkFrac &fps,
313                          int align)
314 {
315     AkVideoCaps(format, size.width(), size.height(), fps, align);
316 }
317 
318 
AkVideoCaps(const AkCaps & caps)319 AkVideoCaps::AkVideoCaps(const AkCaps &caps)
320 {
321     this->d = new AkVideoCapsPrivate();
322 
323     if (caps.mimeType() == "video/x-raw")
324         this->update(caps);
325 }
326 
AkVideoCaps(const AkVideoCaps & other)327 AkVideoCaps::AkVideoCaps(const AkVideoCaps &other):
328     QObject()
329 {
330     this->d = new AkVideoCapsPrivate();
331     this->d->m_format = other.d->m_format;
332     this->d->m_width = other.d->m_width;
333     this->d->m_height = other.d->m_height;
334     this->d->m_fps = other.d->m_fps;
335     this->d->m_align = other.d->m_align;
336     this->d->m_planes_div = other.d->m_planes_div;
337     this->d->m_bypl = other.d->m_bypl;
338     this->d->m_offset = other.d->m_offset;
339     auto properties = other.dynamicPropertyNames();
340 
341     for (auto &property: properties)
342         this->setProperty(property, other.property(property));
343 }
344 
~AkVideoCaps()345 AkVideoCaps::~AkVideoCaps()
346 {
347     delete this->d;
348 }
349 
operator =(const AkVideoCaps & other)350 AkVideoCaps &AkVideoCaps::operator =(const AkVideoCaps &other)
351 {
352     if (this != &other) {
353         this->d->m_format = other.d->m_format;
354         this->d->m_width = other.d->m_width;
355         this->d->m_height = other.d->m_height;
356         this->d->m_fps = other.d->m_fps;
357         this->d->m_align = other.d->m_align;
358         this->d->m_planes_div = other.d->m_planes_div;
359         this->d->m_bypl = other.d->m_bypl;
360         this->d->m_offset = other.d->m_offset;
361 
362         this->clear();
363         auto properties = other.dynamicPropertyNames();
364 
365         for (auto &property: properties)
366             this->setProperty(property, other.property(property));
367 
368         this->d->updateParams();
369     }
370 
371     return *this;
372 }
373 
operator =(const AkCaps & caps)374 AkVideoCaps &AkVideoCaps::operator =(const AkCaps &caps)
375 {
376     if (caps.mimeType() == "video/x-raw") {
377         this->update(caps);
378     } else {
379         this->d->m_format = AkVideoCaps::Format_none;
380         this->d->m_width = 0;
381         this->d->m_height = 0;
382         this->d->m_fps = AkFrac();
383         this->d->m_align = 1;
384     }
385 
386     return *this;
387 }
388 
operator ==(const AkVideoCaps & other) const389 bool AkVideoCaps::operator ==(const AkVideoCaps &other) const
390 {
391     if (this->dynamicPropertyNames() != other.dynamicPropertyNames())
392         return false;
393 
394     for (auto &property: this->dynamicPropertyNames())
395         if (this->property(property) != other.property(property))
396             return false;
397 
398     return this->d->m_format == other.d->m_format
399             && this->d->m_width == other.d->m_width
400             && this->d->m_height == other.d->m_height
401             && this->d->m_fps == other.d->m_fps
402             && this->d->m_align == other.d->m_align;
403 }
404 
operator !=(const AkVideoCaps & other) const405 bool AkVideoCaps::operator !=(const AkVideoCaps &other) const
406 {
407     return !(*this == other);
408 }
409 
operator AkCaps() const410 AkVideoCaps::operator AkCaps() const
411 {
412     AkCaps caps("video/x-raw");
413     caps.setProperty("format", this->d->m_format);
414     caps.setProperty("width" , this->d->m_width);
415     caps.setProperty("height", this->d->m_height);
416     caps.setProperty("fps"   , QVariant::fromValue(this->d->m_fps));
417     caps.setProperty("align" , this->d->m_align);
418 
419     return caps;
420 }
421 
operator bool() const422 AkVideoCaps::operator bool() const
423 {
424     return this->pictureSize() > 0;
425 }
426 
format() const427 AkVideoCaps::PixelFormat AkVideoCaps::format() const
428 {
429     return this->d->m_format;
430 }
431 
fourCC() const432 quint32 AkVideoCaps::fourCC() const
433 {
434     return AkVideoCaps::fourCC(this->d->m_format);
435 }
436 
bpp() const437 int AkVideoCaps::bpp() const
438 {
439     return VideoFormat::byFormat(this->d->m_format)->bpp;
440 }
441 
size() const442 QSize AkVideoCaps::size() const
443 {
444     return {this->d->m_width, this->d->m_height};
445 }
446 
width() const447 int AkVideoCaps::width() const
448 {
449     return this->d->m_width;
450 }
451 
height() const452 int AkVideoCaps::height() const
453 {
454     return this->d->m_height;
455 }
456 
fps() const457 AkFrac AkVideoCaps::fps() const
458 {
459     return this->d->m_fps;
460 }
461 
fps()462 AkFrac &AkVideoCaps::fps()
463 {
464     return this->d->m_fps;
465 }
466 
align() const467 int AkVideoCaps::align() const
468 {
469     return this->d->m_align;
470 }
471 
pictureSize() const472 size_t AkVideoCaps::pictureSize() const
473 {
474     auto vf = VideoFormat::byFormat(this->d->m_format);
475 
476     if (!vf)
477         return 0;
478 
479     size_t size = 0;
480 
481     for (int i = 0; i < vf->planes.size(); i++)
482         size += this->planeSize(i);
483 
484     return size;
485 }
486 
fromMap(const QVariantMap & caps)487 AkVideoCaps AkVideoCaps::fromMap(const QVariantMap &caps)
488 {
489     AkVideoCaps videoCaps;
490 
491     if (!caps.contains("mimeType") || caps["mimeType"] != "video/x-raw")
492         return videoCaps;
493 
494     for (auto it = caps.begin(); it != caps.end(); it++) {
495         auto value = it.value();
496 
497         if (it.key() == "mimeType")
498             continue;
499 
500         videoCaps.setProperty(it.key().toStdString().c_str(), value);
501     }
502 
503     return videoCaps;
504 }
505 
toMap() const506 QVariantMap AkVideoCaps::toMap() const
507 {
508     QVariantMap map {
509         {"mimeType", "video/x-raw"                      },
510         {"format"  , this->d->m_format                  },
511         {"width"   , this->d->m_width                   },
512         {"height"  , this->d->m_height                  },
513         {"fps"     , QVariant::fromValue(this->d->m_fps)},
514         {"align"   , this->d->m_align                   },
515     };
516 
517     for (auto &property: this->dynamicPropertyNames()) {
518         auto key = QString::fromUtf8(property.constData());
519         map[key] = this->property(property);
520     }
521 
522     return map;
523 }
524 
update(const AkCaps & caps)525 AkVideoCaps &AkVideoCaps::update(const AkCaps &caps)
526 {
527     if (caps.mimeType() != "video/x-raw")
528         return *this;
529 
530     this->clear();
531 
532     for (auto &property: caps.dynamicPropertyNames()) {
533         int i = this->metaObject()->indexOfProperty(property);
534 
535         if (this->metaObject()->property(i).isWritable())
536             this->setProperty(property, caps.property(property));
537     }
538 
539     this->d->updateParams();
540 
541     return *this;
542 }
543 
planeOffset(int plane) const544 size_t AkVideoCaps::planeOffset(int plane) const
545 {
546     return this->d->m_offset[plane];
547 }
548 
lineOffset(int plane,int y) const549 size_t AkVideoCaps::lineOffset(int plane, int y) const
550 {
551     y /= (*this->d->m_planes_div)[plane];
552 
553     return this->planeOffset(plane) + this->bytesPerLine(plane) *  size_t(y);
554 }
555 
bytesPerLine(int plane) const556 size_t AkVideoCaps::bytesPerLine(int plane) const
557 {
558     return this->d->m_bypl.value(plane, 0);
559 }
560 
planes() const561 int AkVideoCaps::planes() const
562 {
563     auto vf = VideoFormat::byFormat(this->d->m_format);
564 
565     return vf? vf->planes.size(): 0;
566 }
567 
planeSize(int plane) const568 size_t AkVideoCaps::planeSize(int plane) const
569 {
570     auto bypl = this->bytesPerLine(plane);
571 
572     if (bypl < 1)
573         return 0;
574 
575     auto vf = VideoFormat::byFormat(this->d->m_format);
576 
577     return bypl
578             * size_t(this->d->m_height)
579             / size_t(vf->planes_div[plane]);
580 }
581 
bitsPerPixel(AkVideoCaps::PixelFormat pixelFormat)582 int AkVideoCaps::bitsPerPixel(AkVideoCaps::PixelFormat pixelFormat)
583 {
584     return VideoFormat::byFormat(pixelFormat)->bpp;
585 }
586 
bitsPerPixel(const QString & pixelFormat)587 int AkVideoCaps::bitsPerPixel(const QString &pixelFormat)
588 {
589     return AkVideoCaps::bitsPerPixel(AkVideoCaps::pixelFormatFromString(pixelFormat));
590 }
591 
pixelFormatToString(AkVideoCaps::PixelFormat pixelFormat)592 QString AkVideoCaps::pixelFormatToString(AkVideoCaps::PixelFormat pixelFormat)
593 {
594     AkVideoCaps caps;
595     int formatIndex = caps.metaObject()->indexOfEnumerator("PixelFormat");
596     QMetaEnum formatEnum = caps.metaObject()->enumerator(formatIndex);
597     QString format(formatEnum.valueToKey(pixelFormat));
598     format.remove("Format_");
599 
600     return format;
601 }
602 
pixelFormatFromString(const QString & pixelFormat)603 AkVideoCaps::PixelFormat AkVideoCaps::pixelFormatFromString(const QString &pixelFormat)
604 {
605     AkVideoCaps caps;
606     QString format = "Format_" + pixelFormat;
607     int enumIndex = caps.metaObject()->indexOfEnumerator("PixelFormat");
608     QMetaEnum enumType = caps.metaObject()->enumerator(enumIndex);
609     int enumValue = enumType.keyToValue(format.toStdString().c_str());
610 
611     return static_cast<PixelFormat>(enumValue);
612 }
613 
fourCC(AkVideoCaps::PixelFormat pixelFormat)614 quint32 AkVideoCaps::fourCC(AkVideoCaps::PixelFormat pixelFormat)
615 {
616     return VideoFormat::byFormat(pixelFormat)->fourCC;
617 }
618 
fourCC(const QString & pixelFormat)619 quint32 AkVideoCaps::fourCC(const QString &pixelFormat)
620 {
621     return AkVideoCaps::fourCC(AkVideoCaps::pixelFormatFromString(pixelFormat));
622 }
623 
setFormat(AkVideoCaps::PixelFormat format)624 void AkVideoCaps::setFormat(AkVideoCaps::PixelFormat format)
625 {
626     if (this->d->m_format == format)
627         return;
628 
629     this->d->m_format = format;
630     this->d->updateParams();
631     emit this->formatChanged(format);
632 }
633 
setSize(const QSize & size)634 void AkVideoCaps::setSize(const QSize &size)
635 {
636     QSize curSize(this->d->m_width, this->d->m_height);
637 
638     if (curSize == size)
639         return;
640 
641     this->d->m_width = size.width();
642     this->d->m_height = size.height();
643     this->d->updateParams();
644     emit this->widthChanged(size.width());
645     emit this->heightChanged(size.height());
646     emit sizeChanged(size);
647 }
648 
setWidth(int width)649 void AkVideoCaps::setWidth(int width)
650 {
651     if (this->d->m_width == width)
652         return;
653 
654     this->d->m_width = width;
655     this->d->updateParams();
656     emit this->widthChanged(width);
657 }
658 
setHeight(int height)659 void AkVideoCaps::setHeight(int height)
660 {
661     if (this->d->m_height == height)
662         return;
663 
664     this->d->m_height = height;
665     this->d->updateParams();
666     emit this->heightChanged(height);
667 }
668 
setFps(const AkFrac & fps)669 void AkVideoCaps::setFps(const AkFrac &fps)
670 {
671     if (this->d->m_fps == fps)
672         return;
673 
674     this->d->m_fps = fps;
675     emit this->fpsChanged(fps);
676 }
677 
setAlign(int align)678 void AkVideoCaps::setAlign(int align)
679 {
680     if (this->d->m_align == align)
681         return;
682 
683     this->d->m_align = align;
684     this->d->updateParams();
685     emit this->alignChanged(align);
686 }
687 
resetFormat()688 void AkVideoCaps::resetFormat()
689 {
690     this->setFormat(AkVideoCaps::Format_none);
691 }
692 
resetSize()693 void AkVideoCaps::resetSize()
694 {
695     this->setSize(QSize());
696 }
697 
resetWidth()698 void AkVideoCaps::resetWidth()
699 {
700     this->setWidth(0);
701 }
702 
resetHeight()703 void AkVideoCaps::resetHeight()
704 {
705     this->setHeight(0);
706 }
707 
resetFps()708 void AkVideoCaps::resetFps()
709 {
710     this->setFps(AkFrac());
711 }
712 
resetAlign()713 void AkVideoCaps::resetAlign()
714 {
715     this->setAlign(1);
716 }
717 
clear()718 void AkVideoCaps::clear()
719 {
720     for (auto &property: this->dynamicPropertyNames())
721         this->setProperty(property.constData(), {});
722 }
723 
updateParams()724 void AkVideoCapsPrivate::updateParams()
725 {
726     auto vf = VideoFormat::byFormat(this->m_format);
727 
728     if (!vf) {
729         this->m_planes_div = nullptr;
730         this->m_offset.clear();
731         this->m_bypl.clear();
732 
733         return;
734     }
735 
736     this->m_planes_div = &vf->planes_div;
737     this->m_offset.clear();
738     this->m_bypl.clear();
739     size_t offset = 0;
740 
741     for (int i = 0; i < vf->planes_div.size(); i++) {
742         this->m_offset << offset;
743         auto bypl = VideoFormat::alignUp(size_t(vf->planes[i]
744                                                 * this->m_width
745                                                 / 8),
746                                          size_t(this->m_align));
747         this->m_bypl << bypl;
748         offset += bypl * size_t(this->m_height) / size_t(vf->planes_div[i]);
749     }
750 }
751 
operator <<(QDebug debug,const AkVideoCaps & caps)752 QDebug operator <<(QDebug debug, const AkVideoCaps &caps)
753 {
754     debug.nospace() << "AkVideoCaps("
755                     << "format="
756                     << caps.format()
757                     << ",width="
758                     << caps.width()
759                     << ",height="
760                     << caps.height()
761                     << ",fps="
762                     << caps.fps()
763                     << ",align="
764                     << caps.align();
765 
766     QStringList properties;
767 
768     for (auto &property: caps.dynamicPropertyNames())
769         properties << QString::fromUtf8(property.constData());
770 
771     properties.sort();
772 
773     for (auto &property: properties)
774         debug.nospace() << ","
775                         << property.toStdString().c_str()
776                         << "="
777                         << caps.property(property.toStdString().c_str());
778 
779     debug.nospace() << ")";
780 
781     return debug.space();
782 }
783 
operator <<(QDebug debug,AkVideoCaps::PixelFormat format)784 QDebug operator <<(QDebug debug, AkVideoCaps::PixelFormat format)
785 {
786     debug.nospace() << AkVideoCaps::pixelFormatToString(format).toStdString().c_str();
787 
788     return debug.space();
789 }
790 
operator >>(QDataStream & istream,AkVideoCaps & caps)791 QDataStream &operator >>(QDataStream &istream, AkVideoCaps &caps)
792 {
793     int nProperties;
794     istream >> nProperties;
795 
796     for (int i = 0; i < nProperties; i++) {
797         QByteArray key;
798         QVariant value;
799         istream >> key;
800         istream >> value;
801 
802         caps.setProperty(key.toStdString().c_str(), value);
803     }
804 
805     return istream;
806 }
807 
operator <<(QDataStream & ostream,const AkVideoCaps & caps)808 QDataStream &operator <<(QDataStream &ostream, const AkVideoCaps &caps)
809 {
810     QVariantMap staticProperties {
811         {"format", caps.format()                  },
812         {"width" , caps.width()                   },
813         {"height", caps.height()                  },
814         {"fps"   , QVariant::fromValue(caps.fps())},
815         {"align" , caps.align()                   },
816     };
817 
818     int nProperties =
819             staticProperties.size() + caps.dynamicPropertyNames().size();
820     ostream << nProperties;
821 
822     for (auto &key: caps.dynamicPropertyNames()) {
823         ostream << key;
824         ostream << caps.property(key);
825     }
826 
827     return ostream;
828 }
829 
830 #include "moc_akvideocaps.cpp"
831