Fixposition SDK 0.0.0-heads/main-0-g200d201
Collection of c++ libraries and apps for use with Fixposition products on Linux
Loading...
Searching...
No Matches
video.hpp
Go to the documentation of this file.
1/**
2 * \verbatim
3 * ___ ___
4 * \ \ / /
5 * \ \/ / Copyright (c) Fixposition AG (www.fixposition.com) and contributors
6 * / /\ \ License: see the LICENSE file
7 * /__/ \__\
8 * \endverbatim
9 *
10 * @file
11 * @brief Fixposition SDK: Video frame decoding
12 *
13 * @page FPSDK_COMMON_VIDEO Video frame decoding
14 *
15 * **API**: fpsdk_common/video.hpp and fpsdk::common::video
16 *
17 * @note This is only available if compiled with FFmpeg, see @ref FPSDK_BUILD_DEPS.
18 */
19#ifndef __FPSDK_COMMON_VIDEO_HPP__
20#define __FPSDK_COMMON_VIDEO_HPP__
21
22/* LIBC/STL */
23#include <cstdint>
24#include <memory>
25#include <optional>
26#include <string>
27
28/* EXTERNAL */
29
30/* PACKAGE */
31
32namespace fpsdk {
33namespace common {
34/**
35 * @brief Video frame decoding
36 */
37namespace video {
38/* ****************************************************************************************************************** */
39#if FPSDK_USE_FFMPEG || defined(_DOXYGEN_)
40
41/**
42 * @brief Video codec
43 */
44enum class VideoCodec : int
45{
46 UNSPECIFIED = 0, //!< Unspecified
47 H264, //!< H.264 Advanced Video Coding (AVC)
48 H265, //!< H.265 High Efficiency Video Coding (HEVC)
49};
50
51/**
52 * @brief Stringify video codec enum
53 *
54 * @param[in] codec Codec ID
55 *
56 * @returns the stringification of the codec, or "?" for bad enum values
57 */
58const char* VideoCodecToStr(const VideoCodec codec);
59
60/**
61 * @brief Convert codec ID string to enum
62 *
63 * @param[in] str Codec ID string
64 * @param[in] def Default codec ID, for bad str
65 *
66 * @returns the codec ID, or def if str was invalid
67 */
68VideoCodec VideoCodecFromStrOr(const char* str, const VideoCodec def);
69
70/**
71 * @brief Pixel format
72 */
73enum class PixelFmt : int
74{
75 UNSPECIFIED = 0, //!< Invalid
76 Y8, //!< Planar Y (greyscale), 8bpp (= FFmpeg AV_PIX_FMT_GRAY8)
77 RGB24, //!< Packed RGB 8:8:8, 24bpp, RGBRGB... (= FFmpeg AV_PIX_FMT_RGB24)
78 GBRP, //!< Planar GBR, 24bpp [R][R][R]...[G][G][G]...[B][B][B]... (~ FFmpeg AV_PIX_FMT_GBRP/AV_PIX_FMT_GBR24P)
79};
80
81/**
82 * @brief Stringify pixel format enum
83 *
84 * @param[in] fmt Pixel format
85 *
86 * @returns the stringification of the fmt, or "?" for bad enum values
87 */
88const char* PixelFmtToStr(const PixelFmt fmt);
89
90/**
91 * @brief Convert pixel format string to enum
92 *
93 * @param[in] str Pixel format string
94 * @param[in] def Default pixel format, for bad str
95 *
96 * @returns the pixel format, or def if str was invalid
97 */
98PixelFmt PixelFmtFromStrOr(const char* str, const PixelFmt def);
99
100/**
101 * @brief Scaling method (only for sw decoding)
102 */
103enum class ScalingQual : int
104{
105 UNSPECIFIED = 0, //!< Unspecified
106 BILINEAR, //!< Low quality, very fast
107 BICUBIC, //!< Medium/high quality, fast (B=0.0, C=0.5, "Catmull-Rom")
108 LANCZOS, //!< High quality, slower (radius=3.0)
109 SINC, //!< Very high quality, very slow (radius=3.0)
110};
111
112/**
113 * @brief Stringify scaling method enum
114 *
115 * @param[in] qual Scaling method
116 *
117 * @returns the stringification of the qual, or "?" for bad enum values
118 */
119const char* ScalingQualToStr(const ScalingQual qual);
120
121/**
122 * @brief Convert scaling method string to enum
123 *
124 * @param[in] str Scaling method string
125 * @param[in] def Default pixel format, for bad str
126 *
127 * @returns the scaling method, or def if str was invalid
128 */
129ScalingQual ScalingQualFromStrOr(const char* str, const ScalingQual def);
130
131/**
132 * @brief Hw acceleration
133 */
134enum class HwAccel : uint8_t
135{
136 UNSPECIFIED = 0, //!< Unspecified
137 AUTO = 1, //!< Use hw accel if possible, fallback to SW
138 SW = 2, //!< Do not use any hw acceleration, use pure software implementation
139 HW = 3, //!< Use hw acceleration (currently, Linux Video Acceleration API, VA-API)
140};
141
142/**
143 * @brief Stringify hw accel method enum
144 *
145 * @param[in] accel HW acceleration
146 *
147 * @returns the stringification of the accel, or "?" for bad enum values
148 */
149const char* HwAccelToStr(const HwAccel accel);
150
151/**
152 * @brief Convert scaling method string to enum
153 *
154 * @param[in] str HW acceleration string
155 * @param[in] def Default HW acceleration, for bad str
156 *
157 * @returns the HW acceleration, or def if str was invalid
158 */
159HwAccel HwAccelFromStrOr(const char* str, const HwAccel def);
160
161/**
162 * @brief VideoFrameDecoder params and their defaults
163 */
165{ // clang-format off
166 std::string name_; //!< Name (for debug logging)
168 PixelFmt fmt_ = PixelFmt::UNSPECIFIED; //!< Pixel format (of decoded image)
169 double scale_ = 1.0; //!< Scale factor (of decoded image), range 0.1-1.0
170 HwAccel accel_ = HwAccel::AUTO; //!< Hw acceleration
172}; // clang-format on
173
174// ---------------------------------------------------------------------------------------------------------------------
175
176/**
177 * @brief Decoded, converted and scaled image
178 */
180{
181 PixelFmt fmt_ = PixelFmt::UNSPECIFIED; //!< Pixel format (of data_)
182 int width_ = 0; //!< Width [px]
183 int height_ = 0; //!< Height [px]
184 std::vector<uint8_t> data_; //!< Image data, memory layout depends on fmt_
185
186# ifndef NDEBUG
187 double t_dec_ = 0.0;
188 double t_conv_ = 0.0;
189# endif
190};
191
192/**
193 * @brief Helper for decoding video frames
194 *
195 * @note This is only available if compiled with FFmpeg, see @ref FPSDK_BUILD_DEPS.
196 */
198{
199 public:
200 /**
201 * @brief Constructor
202 *
203 * Don't use, use the CreateVideoFrameDecoder() factory function.
204 *
205 * @param[in] params The parameters
206 */
207 explicit VideoFrameDecoder(const VideoDecoderParams& params);
208
209 /**
210 * @brief Destructor
211 */
213
214 /**
215 * @brief Decode one frame
216 *
217 * - This works for data that is available frame by frame. That is, it does not work for regular video streams where
218 * the data is chunked arbitrarily. Ideally, start by supplying an I frame incl. all the necessary NAL units
219 * (NALUs) to decode a first frame. After that, the following P frames should decode fine.
220 * - For example, for HEVC (H.265) a full set of data for a I frame should contain:
221 * - NALU type 32 (VPS, Video Parameter Set)
222 * - NALU type 33 (SPS, Sequence Parameter Set)
223 * - NALU type 34 (PPS, Picture Parameter Set)
224 * - NALU type 19 (IDR, Instantaneous Decoding Refresh, and RADL, Random Access Decodable Leading) (possibly other
225 * types 16-23 (IRAP, Intra Random Access Point) NALUs might work)
226 * - The video encoder should be configured accordingly (to repeat the VPS/SPS/PPS for each I-frame, and possibly to
227 * produce all/only I frames.
228 * - Separate instances of this should be used to process different video streams
229 *
230 * @param[in] data Data for one (not more, not less) video frame
231 * @param[in] size Size of data
232 *
233 * @returns the decoded, converted and scaled image, nullptr otherwise (not enough data, bad data, ...)
234 */
235 virtual std::optional<ImageData> DecodeFrame(const uint8_t* data, const std::size_t size) = 0;
236
237 /**
238 * @brief Decode video data
239 *
240 * @param[in] data Data for one (recommended) or more video frame(s)
241 *
242 * @returns the decoded, converted and scaled image, nullptr otherwise (not enough data, bad data, ...)
243 */
244 std::optional<ImageData> DecodeFrame(const std::vector<uint8_t>& data);
245
246 /**
247 * @brief Check if decoder is in error state
248 *
249 * This is useful to check when DecodeFrame() didn't return a frame. If the decoder is in error state, it cannot
250 * be used anymore and must be discarded.
251 *
252 * @returns true if the decoder is okay, false if it is in error state
253 */
254 virtual bool IsOkay() const = 0;
255
256 protected:
258};
259
260/**
261 * @brief Pointer to a VideoFrameDecoder instance, see CreateVideoFrameDecoder()
262 */
263using VideoFrameDecoderPtr = std::unique_ptr<VideoFrameDecoder>;
264
265/**
266 * @brief Create a video frame decoder
267 *
268 * @param[in] params The parameters
269 *
270 * @returns the video frame decoder instances, or nullptr if it failed (bad params)
271 */
273
274#endif // FPSDK_USE_FFMPEG
275/* ****************************************************************************************************************** */
276} // namespace video
277} // namespace common
278} // namespace fpsdk
279#endif // __FPSDK_COMMON_VIDEO_HPP__
std::optional< ImageData > DecodeFrame(const std::vector< uint8_t > &data)
Decode video data.
VideoDecoderParams params_
Params.
Definition video.hpp:257
virtual std::optional< ImageData > DecodeFrame(const uint8_t *data, const std::size_t size)=0
Decode one frame.
VideoFrameDecoder(const VideoDecoderParams &params)
Constructor.
virtual bool IsOkay() const =0
Check if decoder is in error state.
Video frame decoding.
Definition video.hpp:37
PixelFmt
Pixel format.
Definition video.hpp:74
@ RGB24
Packed RGB 8:8:8, 24bpp, RGBRGB... (= FFmpeg AV_PIX_FMT_RGB24).
Definition video.hpp:77
@ GBRP
Planar GBR, 24bpp [R][R][R]...[G][G][G]...[B][B][B]... (~ FFmpeg AV_PIX_FMT_GBRP/AV_PIX_FMT_GBR24P).
Definition video.hpp:78
@ Y8
Planar Y (greyscale), 8bpp (= FFmpeg AV_PIX_FMT_GRAY8).
Definition video.hpp:76
const char * ScalingQualToStr(const ScalingQual qual)
Stringify scaling method enum.
HwAccel HwAccelFromStrOr(const char *str, const HwAccel def)
Convert scaling method string to enum.
PixelFmt PixelFmtFromStrOr(const char *str, const PixelFmt def)
Convert pixel format string to enum.
ScalingQual ScalingQualFromStrOr(const char *str, const ScalingQual def)
Convert scaling method string to enum.
VideoCodec
Video codec.
Definition video.hpp:45
@ H265
H.265 High Efficiency Video Coding (HEVC).
Definition video.hpp:48
@ H264
H.264 Advanced Video Coding (AVC).
Definition video.hpp:47
const char * HwAccelToStr(const HwAccel accel)
Stringify hw accel method enum.
ScalingQual
Scaling method (only for sw decoding).
Definition video.hpp:104
@ LANCZOS
High quality, slower (radius=3.0).
Definition video.hpp:108
@ SINC
Very high quality, very slow (radius=3.0).
Definition video.hpp:109
@ BILINEAR
Low quality, very fast.
Definition video.hpp:106
@ BICUBIC
Medium/high quality, fast (B=0.0, C=0.5, "Catmull-Rom").
Definition video.hpp:107
std::unique_ptr< VideoFrameDecoder > VideoFrameDecoderPtr
Pointer to a VideoFrameDecoder instance, see CreateVideoFrameDecoder().
Definition video.hpp:263
const char * VideoCodecToStr(const VideoCodec codec)
Stringify video codec enum.
const char * PixelFmtToStr(const PixelFmt fmt)
Stringify pixel format enum.
VideoCodec VideoCodecFromStrOr(const char *str, const VideoCodec def)
Convert codec ID string to enum.
VideoFrameDecoderPtr CreateVideoFrameDecoder(const VideoDecoderParams &params)
Create a video frame decoder.
HwAccel
Hw acceleration.
Definition video.hpp:135
@ HW
Use hw acceleration (currently, Linux Video Acceleration API, VA-API).
Definition video.hpp:139
@ SW
Do not use any hw acceleration, use pure software implementation.
Definition video.hpp:138
@ AUTO
Use hw accel if possible, fallback to SW.
Definition video.hpp:137
Fixposition SDK: Common library.
Definition doc.hpp:21
Fixposition SDK.
Decoded, converted and scaled image.
Definition video.hpp:180
std::vector< uint8_t > data_
Image data, memory layout depends on fmt_.
Definition video.hpp:184
PixelFmt fmt_
Pixel format (of data_).
Definition video.hpp:181
VideoFrameDecoder params and their defaults.
Definition video.hpp:165
ScalingQual qual_
Scaling method.
Definition video.hpp:171
HwAccel accel_
Hw acceleration.
Definition video.hpp:170
PixelFmt fmt_
Pixel format (of decoded image).
Definition video.hpp:168
double scale_
Scale factor (of decoded image), range 0.1-1.0.
Definition video.hpp:169
std::string name_
Name (for debug logging).
Definition video.hpp:166