1 /******************************************************************************
2     QtAV:  Multimedia framework based on Qt and FFmpeg
3     Copyright (C) 2012-2016 Wang Bin <wbsecg1@gmail.com>
4 
5 *   This file is part of QtAV
6 
7     This library is free software; you can redistribute it and/or
8     modify it under the terms of the GNU Lesser General Public
9     License as published by the Free Software Foundation; either
10     version 2.1 of the License, or (at your option) any later version.
11 
12     This library is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15     Lesser General Public License for more details.
16 
17     You should have received a copy of the GNU Lesser General Public
18     License along with this library; if not, write to the Free Software
19     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20 ******************************************************************************/
21 
22 #ifndef QTAV_VIDEOFORMAT_H
23 #define QTAV_VIDEOFORMAT_H
24 
25 #include <QtCore/QSharedDataPointer>
26 #include <QtCore/QString>
27 #include <QtGui/QImage>
28 #include <QtAV/QtAV_Global.h>
29 
30 QT_BEGIN_NAMESPACE
31 class QDebug;
32 QT_END_NAMESPACE
33 namespace QtAV {
34 class VideoFormatPrivate;
35 /*!
36  * \brief The VideoFormat class
37  * Describes the layout of video data. Some properties like display aspect ratio, color space and color range, which describes how to display the video frame, should be in VideoFrame class.
38 + */
39 class Q_AV_EXPORT VideoFormat
40 {
41 public:
42     /*!
43      * \brief The PixelFormat enum
44      * 32 bit rgba format enum name indicates it's channel layout. For example,
45      * Format_ARGB32 byte layout is AARRGGBB, it's integer value is 0xAARRGGBB on big endian platforms
46      * and 0xBBGGRRAA on little endian platforms
47      * Format_RGB32 and QImage::Format_ARGB32 are the same.
48      * TODO: 0RGB, XRGB, not native endia use R8 or R16. ffmpeg does not have native endian format
49      * currently 0rgb xrgb use rgba formats and check hasAlpha() is required
50      */
51     enum PixelFormat {
52         Format_Invalid = -1,
53         Format_ARGB32, // AARRGGBB or 00RRGGBB, check hasAlpha is required
54         Format_BGRA32, //BBGGRRAA
55         Format_ABGR32, // QImage.RGBA8888 le
56         Format_RGBA32, // QImage. no
57         Format_RGB32, // 0xAARRGGBB native endian. same as QImage::Format_ARGB32. be: ARGB32, le: BGRA32
58         Format_BGR32, // 0xAABBGGRR native endian
59         Format_RGB24,
60         Format_BGR24,
61         Format_RGB565,
62         Format_BGR565,
63         Format_RGB555,
64         Format_BGR555,
65 
66         //http://www.fourcc.org/yuv.php
67         Format_AYUV444,
68         Format_YUV444P,
69         Format_YUV422P,
70         Format_YUV420P,
71         Format_YUV411P,
72         Format_YUV410P,
73         Format_YV12,
74         Format_UYVY, //422
75         Format_VYUY, //not in ffmpeg. OMX_COLOR_FormatCrYCbY
76         Format_YUYV, //422, aka yuy2
77         Format_YVYU, //422
78         Format_NV12,
79         Format_NV21,
80         Format_IMC1,
81         Format_IMC2,
82         Format_IMC3, //same as IMC1, swap U V
83         Format_IMC4, //same as IMC2, swap U V
84         Format_Y8, //GREY. single 8 bit Y plane
85         Format_Y16, //single 16 bit Y plane. LE
86 
87         Format_Jpeg, //yuvj
88 
89         //Format_CameraRaw,
90         //Format_AdobeDng,
91 
92         Format_YUV420P9LE,
93         Format_YUV422P9LE,
94         Format_YUV444P9LE,
95         Format_YUV420P10LE,
96         Format_YUV422P10LE,
97         Format_YUV444P10LE,
98         Format_YUV420P12LE,
99         Format_YUV422P12LE,
100         Format_YUV444P12LE,
101         Format_YUV420P14LE,
102         Format_YUV422P14LE,
103         Format_YUV444P14LE,
104         Format_YUV420P16LE,
105         Format_YUV422P16LE,
106         Format_YUV444P16LE,
107         Format_YUV420P9BE,
108         Format_YUV422P9BE,
109         Format_YUV444P9BE,
110         Format_YUV420P10BE,
111         Format_YUV422P10BE,
112         Format_YUV444P10BE,
113         Format_YUV420P12BE,
114         Format_YUV422P12BE,
115         Format_YUV444P12BE,
116         Format_YUV420P14BE,
117         Format_YUV422P14BE,
118         Format_YUV444P14BE,
119         Format_YUV420P16BE,
120         Format_YUV422P16BE,
121         Format_YUV444P16BE,
122 
123         Format_RGB48, // native endian
124         Format_RGB48LE,
125         Format_RGB48BE,
126         Format_BGR48,
127         Format_BGR48LE,
128         Format_BGR48BE,
129         Format_RGBA64, //native endian
130         Format_RGBA64LE,
131         Format_RGBA64BE,
132         Format_BGRA64, //native endian
133         Format_BGRA64LE,
134         Format_BGRA64BE,
135 
136         Format_VYU, // for rgb422_apple texture, the layout is like rgb24: (v, y, u, )
137         Format_XYZ12,
138         Format_XYZ12LE,
139         Format_XYZ12BE,
140         Format_User
141     };
142 
143     static PixelFormat pixelFormatFromImageFormat(QImage::Format format);
144     /*!
145      * \brief imageFormatFromPixelFormat
146      * If returns a negative value, the QImage format is the positive one but R/G components are swapped because no direct support by QImage. QImage can swap R/G very fast.
147      */
148     static QImage::Format imageFormatFromPixelFormat(PixelFormat format);
149     static PixelFormat pixelFormatFromFFmpeg(int ff); //AVPixelFormat
150     static int pixelFormatToFFmpeg(PixelFormat fmt);
151     static QVector<int> pixelFormatsFFmpeg();
152 
153     VideoFormat(PixelFormat format = Format_Invalid);
154     VideoFormat(int formatFF);
155     VideoFormat(QImage::Format fmt);
156     VideoFormat(const QString& name);
157     VideoFormat(const VideoFormat &other);
158     ~VideoFormat();
159 
160     VideoFormat& operator=(const VideoFormat &other);
161     VideoFormat& operator=(VideoFormat::PixelFormat pixfmt);
162     VideoFormat& operator=(QImage::Format qpixfmt);
163     VideoFormat& operator=(int ffpixfmt);
164     bool operator==(const VideoFormat &other) const;
165     bool operator==(VideoFormat::PixelFormat pixfmt) const;
166     bool operator==(QImage::Format qpixfmt) const;
167     bool operator==(int ffpixfmt) const;
168     bool operator!=(const VideoFormat &other) const;
169     bool operator!=(VideoFormat::PixelFormat pixfmt) const;
170     bool operator!=(QImage::Format qpixfmt) const;
171     bool operator!=(int ffpixfmt) const;
172 
173     bool isValid() const;
174 
175     PixelFormat pixelFormat() const;
176     int pixelFormatFFmpeg() const;
177     QImage::Format imageFormat() const;
178     QString name() const;
179     /*!
180      * \brief setPixelFormat set pixel format to format. other information like bpp will be updated
181      * \param format
182      */
183     void setPixelFormat(PixelFormat format);
184     void setPixelFormatFFmpeg(int format);
185 
186     /*!
187      * \brief channels
188      * \return number of channels(components) the the format. e.g. RGBA has 4 channels, NV12 is 3
189      */
190     int channels() const;
191     /*!
192      * \brief channels
193      * \param plane
194      * \return number of channels in a plane
195      */
196     int channels(int plane) const;
197     /*!
198      * \brief planeCount
199      * \return -1 if not a valid format
200      */
201     int planeCount() const;
202     /*!
203      * https://wiki.videolan.org/YUV
204      * bytesPerPixel()
205      *  YUV420P: 1pix = 4Y+U+V, (4*8+8+8)/4 = 12
206      * bytesPerPixel(plane) is different, for example
207      * uyvy422 bytesPerPixel(0) = 8+8+8 = 24, while bytesPerPixel() = (2*8+8+8)/2 = 16
208      */
209     int bitsPerPixel() const;
210     /// nv12: 16 for uv plane
211     int bitsPerPixel(int plane) const;
212     /// bgr24 is 24 not 32
213     int bitsPerPixelPadded() const;
214     int bytesPerPixel() const;
215     int bytesPerPixel(int plane) const;
216     /*!
217      * \brief bitsPerComponent
218      * \return number of bits per component (0 if uneven)
219      */
220     int bitsPerComponent() const;
221 
222     // return line size with given width
223     int bytesPerLine(int width, int plane) const;
224     /*!
225      * \brief chromaWidth
226      * \param lumaWidth
227      * \return U, V component (or channel) width for the given luma width.
228      */
229     int chromaWidth(int lumaWidth) const;
230     int chromaHeight(int lumaHeight) const;
231     /*!
232      * \brief width
233      * plane width for given lumaWidth in current format
234      * \return lumaWidth if plane <= 0. otherwise chromaWidth
235      */
236     int width(int lumaWidth, int plane) const;
237     int height(int lumaHeight, int plane) const;
238     /*!
239      * \brief normalizedWidth
240      * \return 1.0 for plane <= 0. otherwise chroma width
241      */
242     qreal normalizedWidth(int plane) const;
243     qreal normalizedHeight(int plane) const;
244     //TODO: add planeWidth()/planeHeight()
245     // test AV_PIX_FMT_FLAG_XXX
246     bool isBigEndian() const;
247     bool hasPalette() const;
248     bool isPseudoPaletted() const;
249     /**
250      * All values of a component are bit-wise packed end to end.
251      */
252     bool isBitStream() const;
253     /**
254      * Pixel format is an HW accelerated format.
255      */
256     bool isHWAccelerated() const;
257     /*!
258      * \brief isPlanar
259      * \return true if is planar or semi planar
260      *
261      * Semi-planar: 2 planes instead of 3, one plane for luminance, and one plane for both chrominance components.
262      * They are also sometimes referred to as biplanar formats also
263      * Packed: 1 plane
264      * Planar: 1 plane for each component (channel)
265      */
266     bool isPlanar() const;
267     bool isRGB() const;
268     bool isXYZ() const;
269     bool hasAlpha() const;
270 
271     static bool isPlanar(PixelFormat pixfmt);
272     static bool isRGB(PixelFormat pixfmt);
273     static bool hasAlpha(PixelFormat pixfmt);
274 
275 private:
276     QSharedDataPointer<VideoFormatPrivate> d;
277 };
278 
279 #ifndef QT_NO_DEBUG_STREAM
280 Q_AV_EXPORT QDebug operator<<(QDebug debug, const VideoFormat &fmt);
281 Q_AV_EXPORT QDebug operator<<(QDebug debug, VideoFormat::PixelFormat pixFmt);
282 #endif
283 
284 } //namespace QtAV
285 
286 Q_DECLARE_METATYPE(QtAV::VideoFormat)
287 Q_DECLARE_METATYPE(QtAV::VideoFormat::PixelFormat)
288 
289 #endif // QTAV_VIDEOFORMAT_H
290